From e081e139fcd264c033dafceb79c621c1bef69a70 Mon Sep 17 00:00:00 2001 From: Spedon <70063177+Sped0n@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:59:32 +0800 Subject: [PATCH] refactor: reduce amount of createEffect and improve imports (#284) * refactor: update import syntax * feat: add GalleryImage component for simplicity * refactor: replace createEffect in GalleryNav with createMemo * refactor: refactor Gallery component logic and improve imports --- assets/ts/desktop/customCursor.tsx | 2 +- assets/ts/desktop/layout.tsx | 8 ++-- assets/ts/desktop/nav.tsx | 2 +- assets/ts/desktop/stage.tsx | 2 +- assets/ts/desktop/stageNav.tsx | 2 +- assets/ts/mobile/collection.tsx | 2 +- assets/ts/mobile/gallery.tsx | 72 ++++++++++-------------------- assets/ts/mobile/galleryImage.tsx | 69 ++++++++++++++++++++++++++++ assets/ts/mobile/galleryNav.tsx | 52 +++++---------------- assets/ts/mobile/layout.tsx | 4 +- 10 files changed, 115 insertions(+), 100 deletions(-) create mode 100644 assets/ts/mobile/galleryImage.tsx diff --git a/assets/ts/desktop/customCursor.tsx b/assets/ts/desktop/customCursor.tsx index d131beb..2894bcb 100644 --- a/assets/ts/desktop/customCursor.tsx +++ b/assets/ts/desktop/customCursor.tsx @@ -1,6 +1,6 @@ import { createSignal, onCleanup, onMount, type Accessor, type JSX } from 'solid-js' -export function CustomCursor(props: { +export default function CustomCursor(props: { children?: JSX.Element active: Accessor cursorText: Accessor diff --git a/assets/ts/desktop/layout.tsx b/assets/ts/desktop/layout.tsx index 9a6a011..2375d45 100644 --- a/assets/ts/desktop/layout.tsx +++ b/assets/ts/desktop/layout.tsx @@ -4,10 +4,10 @@ import { Show, createMemo, createSignal, type JSX } from 'solid-js' import type { ImageJSON } from '../resources' import type { Vector } from '../utils' -import { CustomCursor } from './customCursor' -import { Nav } from './nav' -import { Stage } from './stage' -import { StageNav } from './stageNav' +import CustomCursor from './customCursor' +import Nav from './nav' +import Stage from './stage' +import StageNav from './stageNav' /** * interfaces and types diff --git a/assets/ts/desktop/nav.tsx b/assets/ts/desktop/nav.tsx index f6e3038..de02fc5 100644 --- a/assets/ts/desktop/nav.tsx +++ b/assets/ts/desktop/nav.tsx @@ -51,7 +51,7 @@ function updateIndexText(indexValue: string, indexLength: string): void { * Nav component */ -export function Nav(): null { +export default function Nav(): null { const [state, { incThreshold, decThreshold }] = useState() createEffect(() => { diff --git a/assets/ts/desktop/stage.tsx b/assets/ts/desktop/stage.tsx index 496deff..41da089 100644 --- a/assets/ts/desktop/stage.tsx +++ b/assets/ts/desktop/stage.tsx @@ -90,7 +90,7 @@ function onMutation( * Stage component */ -export function Stage(props: { +export default function Stage(props: { ijs: ImageJSON[] setIsLoading: Setter isOpen: Accessor diff --git a/assets/ts/desktop/stageNav.tsx b/assets/ts/desktop/stageNav.tsx index c9bfa59..d3cf4c7 100644 --- a/assets/ts/desktop/stageNav.tsx +++ b/assets/ts/desktop/stageNav.tsx @@ -5,7 +5,7 @@ import { decrement, increment, type Vector } from '../utils' import type { HistoryItem } from './layout' -export function StageNav(props: { +export default function StageNav(props: { children?: JSX.Element prevText: string closeText: string diff --git a/assets/ts/mobile/collection.tsx b/assets/ts/mobile/collection.tsx index c671085..fd34c8d 100644 --- a/assets/ts/mobile/collection.tsx +++ b/assets/ts/mobile/collection.tsx @@ -31,7 +31,7 @@ function onIntersection( }).observe(element) } -export function Collection(props: { +export default function Collection(props: { children?: JSX.Element ijs: ImageJSON[] isAnimating: Accessor diff --git a/assets/ts/mobile/gallery.tsx b/assets/ts/mobile/gallery.tsx index 870ff1d..13768d3 100644 --- a/assets/ts/mobile/gallery.tsx +++ b/assets/ts/mobile/gallery.tsx @@ -1,13 +1,16 @@ import { type gsap } from 'gsap' import { createEffect, + createSignal, For, on, onMount, + Show, type Accessor, type JSX, type Setter } from 'solid-js' +import { createStore } from 'solid-js/store' import { type Swiper } from 'swiper' import invariant from 'tiny-invariant' @@ -15,8 +18,8 @@ import { type ImageJSON } from '../resources' import { useState } from '../state' import { loadGsap, type Vector } from '../utils' -import { capitalizeFirstLetter, GalleryNav } from './galleryNav' -import type { MobileImage } from './layout' +import GalleryImage from './galleryImage' +import GalleryNav, { capitalizeFirstLetter } from './galleryNav' function removeDuplicates(arr: T[]): T[] { if (arr.length < 2) return arr // optimization @@ -28,7 +31,7 @@ async function loadSwiper(): Promise { return s.Swiper } -export function Gallery(props: { +export default function Gallery(props: { children?: JSX.Element ijs: ImageJSON[] closeText: string @@ -43,10 +46,6 @@ export function Gallery(props: { let _gsap: typeof gsap let _swiper: Swiper - // eslint-disable-next-line solid/reactivity - const imgs: MobileImage[] = Array(props.ijs.length) - // eslint-disable-next-line solid/reactivity - const loadingDivs: HTMLDivElement[] = Array(props.ijs.length) let curtain: HTMLDivElement | undefined let gallery: HTMLDivElement | undefined let galleryInner: HTMLDivElement | undefined @@ -56,16 +55,18 @@ export function Gallery(props: { // states let lastIndex = -1 - let libLoaded = false let mounted = false let navigateVector: Vector = 'none' const [state, { setIndex }] = useState() + const [libLoaded, setLibLoaded] = createSignal(false) + // eslint-disable-next-line solid/reactivity + const [loads, setLoads] = createStore(Array(props.ijs.length).fill(false)) // helper functions const slideUp: () => void = () => { // isAnimating is prechecked in isOpen effect - if (!libLoaded || !mounted) return + if (!libLoaded() || !mounted) return props.setIsAnimating(true) invariant(curtain, 'curtain is not defined') @@ -133,11 +134,7 @@ export function Gallery(props: { activeImagesIndex = [currentIndex, nextIndex, prevIndex] break } - removeDuplicates(activeImagesIndex).forEach((i) => { - const e = imgs[i] - if (e.src === e.dataset.src) return // already loaded - e.src = e.dataset.src - }) + setLoads(removeDuplicates(activeImagesIndex), true) } const changeSlide: (slide: number) => void = (slide) => { @@ -149,22 +146,6 @@ export function Gallery(props: { // effects onMount(() => { - imgs.forEach((img, i) => { - const loadingDiv = loadingDivs[i] - img.addEventListener( - 'load', - () => { - if (state().index !== parseInt(img.dataset.index)) { - _gsap.set(img, { opacity: 1 }) - _gsap.set(loadingDiv, { opacity: 0 }) - } else { - _gsap.to(img, { opacity: 1, delay: 0.5, duration: 0.5, ease: 'power3.out' }) - _gsap.to(loadingDiv, { opacity: 0, duration: 0.5, ease: 'power3.in' }) - } - }, - { once: true, passive: true } - ) - }) window.addEventListener( 'touchstart', () => { @@ -186,7 +167,7 @@ export function Gallery(props: { .catch((e) => { console.log(e) }) - libLoaded = true + setLibLoaded(true) }, { once: true, passive: true } ) @@ -234,26 +215,19 @@ export function Gallery(props: {