@@ -7,7 +7,7 @@ import { DisclaimerPathConfig } from '../utils/themeContext';
7
7
const props = defineProps <{
8
8
content? : string
9
9
}>()
10
-
10
+ const DEFAULT_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000 // 7 days
11
11
const route = useRoute ()
12
12
const { theme } = useData <PjtsThemeConfig >()
13
13
@@ -56,9 +56,9 @@ const shouldRender = computed(() => {
56
56
if (! theme .value ?.enableDisclaimer ) {
57
57
return false
58
58
}
59
- // if (route.data?.frontmatter?.hideDisclaimer) {
60
- // return false
61
- // }
59
+ // if (route.data?.frontmatter?.hideDisclaimer) {
60
+ // return false
61
+ // }
62
62
63
63
// Check if a valid configuration is found for the current path
64
64
return !! currentDisclaimerConfig .value
@@ -70,14 +70,22 @@ const placeholderHeight = computed(() => {
70
70
return shouldRender .value && ! isHidden .value ? disclaimerHeight .value : 0
71
71
})
72
72
73
- // Toggle the hidden state
73
+ // Toggle the hidden state and update local storage with timestamp if enabled
74
74
const toggleHiddenState = () => {
75
+ const localHiddenEnabled = !! theme .value ?.disclaimerStatusKey
76
+
75
77
if (isHidden .value ) {
76
78
// Show the disclaimer
77
79
isHidden .value = false
80
+ if (localHiddenEnabled ) {
81
+ localStorage .removeItem (theme .value ?.disclaimerStatusKey ! )
82
+ }
78
83
} else {
79
84
// Hide the disclaimer
80
85
isHidden .value = true
86
+ if (localHiddenEnabled ) {
87
+ localStorage .setItem (theme .value ?.disclaimerStatusKey ! , Date .now ().toString ())
88
+ }
81
89
}
82
90
}
83
91
@@ -89,13 +97,37 @@ const calculateHeight = () => {
89
97
// Only update if the disclaimer is collapsed OR if we haven't captured a height yet.
90
98
// This prevents overwriting the collapsed height when it expands.
91
99
if (! isExpanded .value || disclaimerHeight .value === 0 ) {
92
- disclaimerHeight .value = currentHeight
100
+ disclaimerHeight .value = currentHeight
93
101
}
94
102
}
95
103
// No need for an else to set height to 0, the computed property handles that.
96
104
}
97
105
98
106
onMounted (() => {
107
+ // Check local storage for hidden state if the feature is enabled
108
+ const localHiddenEnabled = !! theme .value ?.disclaimerStatusKey
109
+ if (localHiddenEnabled ) {
110
+ const storedTimestampStr = localStorage .getItem (theme .value ?.disclaimerStatusKey ! )
111
+ if (storedTimestampStr ) {
112
+ try {
113
+ const storedTimestamp = parseInt (storedTimestampStr , 10 )
114
+ const expirationMs = theme .value ?.disclaimerStatusExpiration ?? DEFAULT_EXPIRATION_MS
115
+ const now = Date .now ()
116
+
117
+ if (now - storedTimestamp <= expirationMs ) {
118
+ // Timestamp is valid and not expired
119
+ isHidden .value = true
120
+ } else {
121
+ // Timestamp expired, remove it
122
+ localStorage .removeItem (theme .value ?.disclaimerStatusKey ! )
123
+ }
124
+ }
125
+ catch {
126
+ localStorage .removeItem (theme .value ?.disclaimerStatusKey ! )
127
+ }
128
+ }
129
+ }
130
+
99
131
// Calculate initial height after component mounts and renders
100
132
nextTick (calculateHeight )
101
133
})
@@ -113,25 +145,19 @@ watch([isExpanded, currentDisclaimerText], () => {
113
145
114
146
<template >
115
147
<!-- Placeholder div to reserve space when the disclaimer is fixed -->
116
- <div
117
- v-if =" shouldRender && !isHidden"
118
- class =" disclaimer-placeholder"
119
- :style =" { height: placeholderHeight + 'px' }"
120
- ></div >
148
+ <div v-if =" shouldRender && !isHidden" class =" disclaimer-placeholder" :style =" { height: placeholderHeight + 'px' }" >
149
+ </div >
121
150
122
151
<!-- The actual disclaimer element -->
123
- <div
124
- v-if =" shouldRender"
125
- ref =" disclaimerElement"
126
- :class =" [
127
- 'disclaimer',
128
- { 'is-expanded': isExpanded },
129
- { 'is-hidden': isHidden }
130
- ]"
131
- >
152
+ <div v-if =" shouldRender" ref =" disclaimerElement" :class =" [
153
+ 'disclaimer',
154
+ { 'is-expanded': isExpanded },
155
+ { 'is-hidden': isHidden }
156
+ ]" >
132
157
<div class =" disclaimer-content" >
133
158
<!-- Use v-html for rich text content -->
134
- <div class =" disclaimer-text" :class =" { 'expanded': isExpanded && !isHidden }" v-html =" currentDisclaimerText" ></div >
159
+ <div class =" disclaimer-text" :class =" { 'expanded': isExpanded && !isHidden }" v-html =" currentDisclaimerText" >
160
+ </div >
135
161
<div class =" disclaimer-actions" >
136
162
<button v-if =" showToggleButton && !isHidden" @click =" isExpanded = !isExpanded" class =" disclaimer-toggle" >
137
163
{{ isExpanded ? collapseText : expandText }}
@@ -160,6 +186,8 @@ watch([isExpanded, currentDisclaimerText], () => {
160
186
.disclaimer.is-hidden {
161
187
position : static ;
162
188
margin-top : 2rem ;
189
+ border : 1px solid transparent ;
190
+ border-radius : 8px ;
163
191
}
164
192
165
193
.disclaimer-content {
@@ -212,7 +240,7 @@ watch([isExpanded, currentDisclaimerText], () => {
212
240
}
213
241
214
242
.disclaimer-actions {
215
- margin-top : 0.5rem ; /* Add some space when stacked */
243
+ margin-top : 0.5rem ;
216
244
width : 100% ;
217
245
justify-content : flex-end ;
218
246
}
@@ -222,8 +250,8 @@ watch([isExpanded, currentDisclaimerText], () => {
222
250
.disclaimer-placeholder {
223
251
position : relative ;
224
252
width : 100% ;
225
- display : block ;
253
+ display : block ;
226
254
margin : 0 ;
227
255
padding : 0 ;
228
256
}
229
- </style >
257
+ </style >
0 commit comments