Skip to content

Commit 91b6485

Browse files
committed
fixed first time visitor popover
1 parent 029387c commit 91b6485

3 files changed

Lines changed: 28 additions & 33 deletions

File tree

src/lib/components/VideoControls.svelte

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88
type CaptionSize,
99
type CaptionBackground
1010
} from '$lib/stores/captionSettings.svelte';
11+
import { userPreferences } from '$lib/stores/userPreferences.svelte';
1112
1213
function handleLevelChange(event: Event) {
1314
const target = event.target as HTMLSelectElement;
1415
comprehension.setLevel(target.value as ComprehensionLevel);
16+
// Auto-dismiss hint when user changes level
17+
if (showAudienceHint) {
18+
dismissAudienceHint();
19+
}
1520
}
1621
1722
// Caption color options
@@ -89,31 +94,29 @@
8994
let showVolumeSlider = $state(false);
9095
let showSettings = $state(false);
9196
let labelOffsets = $state<boolean[]>([]);
92-
let showAudienceHint = $state(false);
9397
let hintHiding = $state(false);
98+
let hintShownThisSession = $state(false);
99+
let hintDismissed = $state(false);
100+
101+
// Derive hint visibility: show if not visited, shown this session, and not fully dismissed
102+
let showAudienceHint = $derived(!userPreferences.hasVisited && hintShownThisSession && !hintDismissed);
94103
95-
// Check if first-time visitor on mount
104+
// Show hint after delay for first-time visitors
96105
$effect(() => {
97-
if (typeof window !== 'undefined') {
98-
const hasVisited = localStorage.getItem('react2shell-visited');
99-
if (!hasVisited) {
100-
// Show hint after a short delay so it doesn't appear immediately
101-
setTimeout(() => {
102-
showAudienceHint = true;
103-
}, 1500);
104-
}
106+
if (!userPreferences.hasVisited && !hintShownThisSession) {
107+
setTimeout(() => {
108+
hintShownThisSession = true;
109+
}, 1500);
105110
}
106111
});
107112
108113
function dismissAudienceHint() {
109114
hintHiding = true;
110-
if (typeof window !== 'undefined') {
111-
localStorage.setItem('react2shell-visited', 'true');
112-
}
113-
// Wait for animation to complete before hiding
115+
userPreferences.markVisited();
116+
// Wait for animation to complete before fully hiding
114117
setTimeout(() => {
115-
showAudienceHint = false;
116118
hintHiding = false;
119+
hintDismissed = true;
117120
}, 300);
118121
}
119122
@@ -306,7 +309,7 @@
306309
id="comprehension-select"
307310
class="comprehension-select"
308311
value={comprehension.level}
309-
onchange={(e) => { handleLevelChange(e); dismissAudienceHint(); }}
312+
onchange={handleLevelChange}
310313
title="Explanation Level"
311314
>
312315
<option value="expert">{LEVEL_LABELS.expert}</option>
@@ -886,6 +889,8 @@
886889
background: #1a1a2e;
887890
transform: rotate(45deg);
888891
z-index: 5;
892+
border-right: 2px solid var(--accent-orange);
893+
border-bottom: 2px solid var(--accent-red);
889894
}
890895
891896
.hint-content {
@@ -895,13 +900,11 @@
895900
border-radius: var(--radius-md);
896901
min-width: 240px;
897902
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
898-
z-index: 1;
899903
background: #1a1a2e;
900-
border: 2px solid transparent;
901-
background-clip: padding-box;
904+
margin-bottom: 2px;
902905
}
903906
904-
/* Animated gradient border using outline trick */
907+
/* Animated gradient border - outer layer */
905908
.hint-content::before {
906909
content: '';
907910
position: absolute;
@@ -913,17 +916,17 @@
913916
var(--accent-orange),
914917
var(--accent-red)
915918
);
916-
z-index: -1;
919+
z-index: -2;
917920
animation: gradient-rotate 3s linear infinite;
918921
}
919922
920-
/* Inner background to cover the gradient */
923+
/* Inner background to cover the gradient, leaving only border visible */
921924
.hint-content::after {
922925
content: '';
923926
position: absolute;
924927
inset: 0;
925928
background: #1a1a2e;
926-
border-radius: calc(var(--radius-md) - 1px);
929+
border-radius: var(--radius-md);
927930
z-index: -1;
928931
}
929932

src/lib/stores/userPreferences.svelte.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ function loadFromStorage(): UserPreferences {
4747
if (stored) {
4848
const parsed = JSON.parse(stored);
4949
// Merge with defaults to handle missing keys from older versions
50-
return { ...DEFAULT_PREFERENCES, ...parsed, hasVisited: true };
50+
// Preserve the actual hasVisited value from storage
51+
return { ...DEFAULT_PREFERENCES, ...parsed };
5152
}
5253
} catch (e) {
5354
console.warn('Failed to load preferences from localStorage:', e);

src/routes/+page.svelte

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@
77
import FixStep from '$lib/components/steps/FixStep.svelte';
88
import LessonsStep from '$lib/components/steps/LessonsStep.svelte';
99
import { navigation } from '$lib/stores/navigation.svelte';
10-
import { userPreferences } from '$lib/stores/userPreferences.svelte';
11-
import { onMount } from 'svelte';
12-
13-
// Mark user as visited on first load
14-
onMount(() => {
15-
if (!userPreferences.hasVisited) {
16-
userPreferences.markVisited();
17-
}
18-
});
1910
</script>
2011

2112
<Header />

0 commit comments

Comments
 (0)