|
1 | 1 | <script lang="ts">
|
| 2 | + import { getUiVisibilityContext } from '$lib/stores/ui-visibility.store'; |
| 3 | + import classNames from 'classnames'; |
| 4 | + import { ChevronRight } from 'radix-icons-svelte'; |
| 5 | + import { createEventDispatcher, tick } from 'svelte'; |
| 6 | + import { get, type Readable, type Writable } from 'svelte/store'; |
2 | 7 | import Container from '../Container.svelte';
|
3 |
| - import HeroBackground from './HeroBackground.svelte'; |
4 | 8 | import IconButton from '../FloatingIconButton.svelte';
|
5 |
| - import { ChevronRight, ChevronUp } from 'radix-icons-svelte'; |
6 | 9 | import PageDots from '../HeroShowcase/PageDots.svelte';
|
7 |
| - import type { Readable, Writable } from 'svelte/store'; |
8 |
| - import { createEventDispatcher } from 'svelte'; |
9 |
| - import classNames from 'classnames'; |
| 10 | + import HeroBackground from './HeroBackground.svelte'; |
| 11 | + import { Selectable } from '$lib/selectable'; |
| 12 | + import { localSettings } from '$lib/stores/localstorage.store'; |
| 13 | + import { getScrollContext } from '$lib/stores/scroll.store'; |
10 | 14 |
|
11 | 15 | const dispatch = createEventDispatcher();
|
| 16 | + const { visibleStyle, visible } = getUiVisibilityContext(); |
| 17 | + const { topVisible } = getScrollContext(); |
12 | 18 |
|
13 | 19 | export let items: Promise<{ backdropUrl: string; videoUrl?: string }[]>;
|
14 | 20 | export let index = 0;
|
15 |
| - export let hideInterface = false; |
| 21 | + export let hasFocus = false; |
| 22 | +
|
| 23 | + let selectable: Selectable; |
16 | 24 |
|
17 | 25 | let length = 0;
|
18 | 26 |
|
|
44 | 52 |
|
45 | 53 | let heroHasFocusWithin: Readable<boolean>;
|
46 | 54 | let focusIndex: Writable<number>;
|
47 |
| - $: backgroundHasFocus = $heroHasFocusWithin && $focusIndex === 0; |
| 55 | + $: hasFocus = $heroHasFocusWithin && $focusIndex === 0; |
| 56 | + $: visible?.set(!hasFocus || !$topVisible); |
| 57 | +
|
| 58 | + let focusedObject: Selectable | undefined = undefined; |
| 59 | + topVisible?.subscribe((v) => !v && handleClickFocus(true)); |
| 60 | + function handleClickFocus(unfocusOnly = false) { |
| 61 | + if (hasFocus && focusedObject) { |
| 62 | + tick().then(() => focusedObject?.focus()); |
| 63 | + } else if (!unfocusOnly) { |
| 64 | + focusedObject = get(Selectable.focusedObject); |
| 65 | + selectable?.focusChild(0); |
| 66 | + } |
| 67 | + } |
48 | 68 | </script>
|
49 | 69 |
|
50 | 70 | <Container
|
|
53 | 73 | on:select
|
54 | 74 | on:navigate={(event) => {
|
55 | 75 | const detail = event.detail;
|
56 |
| - if (!backgroundHasFocus) return; |
| 76 | + if (!hasFocus) return; |
57 | 77 | if (detail.direction === 'right') {
|
58 | 78 | if (onNext()) {
|
59 | 79 | detail.preventNavigation();
|
|
70 | 90 | }}
|
71 | 91 | bind:hasFocusWithin={heroHasFocusWithin}
|
72 | 92 | bind:focusIndex
|
| 93 | + bind:selectable |
73 | 94 | >
|
74 | 95 | <HeroBackground
|
75 | 96 | {items}
|
76 | 97 | {index}
|
77 |
| - hasFocus={backgroundHasFocus} |
78 |
| - heroHasFocus={$heroHasFocusWithin} |
79 |
| - {hideInterface} |
| 98 | + {hasFocus} |
| 99 | + videoVisible={$localSettings.autoplayTrailers ? $topVisible ?? true : !$visible} |
80 | 100 | />
|
81 |
| - <div |
82 |
| - class={classNames('flex flex-1 z-10 transition-opacity', { |
83 |
| - 'opacity-0': hideInterface |
84 |
| - })} |
85 |
| - > |
86 |
| - <slot /> |
| 101 | + <div class={classNames('flex flex-1 z-10')}> |
| 102 | + <!-- svelte-ignore a11y-click-events-have-key-events --> |
| 103 | + <div class="flex-1 flex flex-col justify-end" on:click|self={() => handleClickFocus()}> |
| 104 | + <div style={$visibleStyle}> |
| 105 | + <slot /> |
| 106 | + </div> |
| 107 | + </div> |
87 | 108 | <!-- <div
|
88 | 109 | class="absolute inset-x-1/2 -translate-x-1/2 top-16 min-w-fit flex flex-col items-center justify-center"
|
89 | 110 | >
|
90 | 111 | <ChevronUp size={38} />
|
91 | 112 | <div class="whitespace-nowrap">View Trailer</div>
|
92 | 113 | </div> -->
|
93 |
| - <div class="flex flex-col justify-end ml-4"> |
| 114 | + <div class="flex flex-col justify-end ml-4" style={$visibleStyle}> |
94 | 115 | <div class="flex flex-1 justify-end items-center">
|
95 | 116 | <IconButton on:click={onNext}>
|
96 | 117 | <ChevronRight size={38} />
|
|
0 commit comments