From febbd7d45d2f76225dfbf06b7582c89e57babce7 Mon Sep 17 00:00:00 2001 From: Spedon <70063177+Sped0n@users.noreply.github.com> Date: Thu, 22 Feb 2024 01:18:29 +0800 Subject: [PATCH] feat: migrate to Solid.js (#282) * refactor: change hires loader function name * feat: add loading transition animation and improve performance * refactor: refactor gallery creation and update functions * feat: update dependencies, configuration, and input file for solidjs - Update dependencies in package.json - Modify the input file in rollup.config.mjs - Update tsconfig.json with new configuration options * feat: update ESLint config for TypeScript and Solid integration - Add `plugin:solid/typescript` to the ESLint config - Add `prettier`, `@typescript-eslint`, and `solid` plugins to the ESLint config - Remove the `overrides` and `plugins` properties from the ESLint config - Modify the `memberSyntaxSortOrder` property in the ESLint config * feat: update build scripts and configuration for Vite * GitButler Integration Commit This is an integration commit for the virtual branches that GitButler is tracking. Due to GitButler managing multiple virtual branches, you cannot switch back and forth between git branches and virtual branches easily. If you switch to another branch, GitButler will need to be reinitialized. If you commit on this branch, GitButler will throw it away. Here are the branches that are currently applied: - solid (refs/gitbutler/solid) branch head: dc6860991c960a50b27ad010f9831f248e1bceae - .eslintrc.json - assets/ts/main.tsx - assets/ts/desktop/stage.tsx - static/bundled/js/main.js - rollup.config.mjs - pnpm-lock.yaml - vite.config.ts - package.json - tsconfig.json - assets/ts/globalState.ts - assets/ts/mobile/collection.ts - assets/ts/container.ts - assets/ts/mobile/init.ts - assets/ts/mobile/gallery.ts - assets/ts/desktop/customCursor.ts - assets/ts/mobile/state.ts - assets/ts/globalUtils.ts - static/bundled/js/zXhbFx.js - static/bundled/js/EY5BO_.js - static/bundled/js/bBHMTk.js - assets/ts/nav.tsx - assets/ts/utils.ts - assets/ts/desktop/stageNav.ts - assets/ts/mobile/utils.ts - assets/ts/main.ts - assets/ts/desktop/state.ts - assets/ts/desktop/init.ts - assets/ts/state.tsx - assets/ts/desktop/utils.ts - assets/ts/nav.ts - assets/ts/resources.ts - assets/ts/desktop/stage.ts - static/bundled/js/GAHquF.js Your previous branch was: refs/heads/solid The sha for that commit was: dc6860991c960a50b27ad010f9831f248e1bceae For more information about what we're doing here, check out our docs: https://docs.gitbutler.com/features/virtual-branches/integration-branch * refactor: remove .hide class from _base.scss file * feat: migrate to Solid.js * refactor: change i18n loading text with trailing dots * fix: fix broken pnpm lock file * chore: update eslint configuration for better code organization - Update the eslint plugins array by removing newlines and maintaining plugins order - Disable the rule "@typescript-eslint/non-nullable-type-assertion-style" - Change the configuration of "sort-imports" rule * feat: add tiny-invariant and eslint-plugin-solid to deps * refactor: fix multiple eslint warnings --------- Co-authored-by: GitButler --- .eslintrc.json | 20 +- assets/scss/_core/_base.scss | 4 - assets/ts/container.ts | 29 - assets/ts/desktop/customCursor.ts | 48 -- assets/ts/desktop/customCursor.tsx | 52 ++ assets/ts/desktop/init.ts | 15 - assets/ts/desktop/layout.tsx | 89 +++ assets/ts/{nav.ts => desktop/nav.tsx} | 66 +- assets/ts/desktop/stage.ts | 406 ---------- assets/ts/desktop/stage.tsx | 476 +++++++++++ assets/ts/desktop/stageNav.ts | 194 ----- assets/ts/desktop/stageNav.tsx | 92 +++ assets/ts/desktop/state.ts | 20 - assets/ts/desktop/utils.ts | 33 - assets/ts/globalState.ts | 91 --- assets/ts/main.ts | 54 -- assets/ts/main.tsx | 81 ++ assets/ts/mobile/collection.ts | 103 --- assets/ts/mobile/collection.tsx | 133 ++++ assets/ts/mobile/gallery.ts | 312 -------- assets/ts/mobile/gallery.tsx | 268 +++++++ assets/ts/mobile/galleryNav.tsx | 74 ++ assets/ts/mobile/init.ts | 9 - assets/ts/mobile/layout.tsx | 50 ++ assets/ts/mobile/state.ts | 3 - assets/ts/mobile/utils.ts | 42 - assets/ts/resources.ts | 2 +- assets/ts/state.tsx | 136 ++++ assets/ts/{globalUtils.ts => utils.ts} | 42 +- i18n/de.toml | 2 +- i18n/en.toml | 2 +- i18n/es.toml | 2 +- i18n/fr.toml | 2 +- i18n/it.toml | 2 +- i18n/ja.toml | 2 +- i18n/ko.toml | 2 +- i18n/zh-cn.toml | 2 +- i18n/zh-hk.toml | 2 +- i18n/zh-mo.toml | 2 +- i18n/zh-sg.toml | 2 +- i18n/zh-tw.toml | 2 +- package.json | 25 +- pnpm-lock.yaml | 1000 ++++++++++++++++++++---- rollup.config.mjs | 28 - tsconfig.json | 4 +- vite.config.ts | 30 + 46 files changed, 2402 insertions(+), 1653 deletions(-) delete mode 100644 assets/ts/container.ts delete mode 100644 assets/ts/desktop/customCursor.ts create mode 100644 assets/ts/desktop/customCursor.tsx delete mode 100644 assets/ts/desktop/init.ts create mode 100644 assets/ts/desktop/layout.tsx rename assets/ts/{nav.ts => desktop/nav.tsx} (51%) delete mode 100644 assets/ts/desktop/stage.ts create mode 100644 assets/ts/desktop/stage.tsx delete mode 100644 assets/ts/desktop/stageNav.ts create mode 100644 assets/ts/desktop/stageNav.tsx delete mode 100644 assets/ts/desktop/state.ts delete mode 100644 assets/ts/desktop/utils.ts delete mode 100644 assets/ts/globalState.ts delete mode 100644 assets/ts/main.ts create mode 100644 assets/ts/main.tsx delete mode 100644 assets/ts/mobile/collection.ts create mode 100644 assets/ts/mobile/collection.tsx delete mode 100644 assets/ts/mobile/gallery.ts create mode 100644 assets/ts/mobile/gallery.tsx create mode 100644 assets/ts/mobile/galleryNav.tsx delete mode 100644 assets/ts/mobile/init.ts create mode 100644 assets/ts/mobile/layout.tsx delete mode 100644 assets/ts/mobile/state.ts delete mode 100644 assets/ts/mobile/utils.ts create mode 100644 assets/ts/state.tsx rename assets/ts/{globalUtils.ts => utils.ts} (51%) delete mode 100644 rollup.config.mjs create mode 100644 vite.config.ts diff --git a/.eslintrc.json b/.eslintrc.json index 8f5e1d1..3d2cbbe 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,10 +8,11 @@ "prettier", "eslint:recommended", "plugin:prettier/recommended", - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "plugin:solid/typescript" ], - "overrides": [], - "plugins": ["prettier", "@typescript-eslint"], + "parser": "@typescript-eslint/parser", + "plugins": ["prettier", "@typescript-eslint", "solid"], "parserOptions": { "ecmaVersion": "latest", "project": "./tsconfig.json", @@ -22,13 +23,12 @@ "arrow-body-style": "off", "prefer-arrow-callback": "off", "import/no-cycle": "error", - "@typescript-eslint/non-nullable-type-assertion-style": "off", "sort-imports": [ "error", { "ignoreCase": false, "ignoreDeclarationSort": true, - "ignoreMemberSort": false, + "ignoreMemberSort": true, "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], "allowSeparatedGroups": true } @@ -37,7 +37,15 @@ "import/order": [ "error", { - "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], + "groups": [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index", + "unknown" + ], "newlines-between": "always", "alphabetize": { "order": "asc", diff --git a/assets/scss/_core/_base.scss b/assets/scss/_core/_base.scss index d8e8a82..eb48cd7 100644 --- a/assets/scss/_core/_base.scss +++ b/assets/scss/_core/_base.scss @@ -17,7 +17,3 @@ a, button { cursor: pointer; } - -.hide { - display: none; -} diff --git a/assets/ts/container.ts b/assets/ts/container.ts deleted file mode 100644 index 01b80c2..0000000 --- a/assets/ts/container.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Watchable } from './globalUtils' - -export const scrollable = new Watchable(true) - -export let container: Container - -/** - * interfaces - */ - -export interface Container extends HTMLDivElement { - dataset: { - next: string - close: string - prev: string - loading: string - } -} - -export function initContainer(): void { - container = document.getElementsByClassName('container').item(0) as Container - scrollable.addWatcher((o) => { - if (o) { - container.classList.remove('disableScroll') - } else { - container.classList.add('disableScroll') - } - }) -} diff --git a/assets/ts/desktop/customCursor.ts b/assets/ts/desktop/customCursor.ts deleted file mode 100644 index 283de88..0000000 --- a/assets/ts/desktop/customCursor.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { container } from '../container' - -import { active } from './state' - -/** - * variables - */ - -const cursor = document.createElement('div') -const cursorInner = document.createElement('div') - -/** - * main functions - */ - -function onMouse(e: MouseEvent): void { - const x = e.clientX - const y = e.clientY - cursor.style.transform = `translate3d(${x}px, ${y}px, 0)` -} - -export function setCustomCursor(text: string): void { - cursorInner.innerText = text -} - -/** - * init - */ -export function initCustomCursor(): void { - // cursor class name - cursor.className = 'cursor' - // cursor inner class name - cursorInner.className = 'cursorInner' - // append cursor inner to cursor - cursor.append(cursorInner) - // append cursor to main - container.append(cursor) - // bind mousemove event to window - window.addEventListener('mousemove', onMouse, { passive: true }) - // add active callback - active.addWatcher((o) => { - if (o) { - cursor.classList.add('active') - } else { - cursor.classList.remove('active') - } - }) -} diff --git a/assets/ts/desktop/customCursor.tsx b/assets/ts/desktop/customCursor.tsx new file mode 100644 index 0000000..d131beb --- /dev/null +++ b/assets/ts/desktop/customCursor.tsx @@ -0,0 +1,52 @@ +import { createSignal, onCleanup, onMount, type Accessor, type JSX } from 'solid-js' + +export function CustomCursor(props: { + children?: JSX.Element + active: Accessor + cursorText: Accessor + isOpen: Accessor +}): JSX.Element { + // types + interface XY { + x: number + y: number + } + + // variables + let controller: AbortController | undefined + + // states + const [xy, setXy] = createSignal({ x: 0, y: 0 }) + + // helper functions + const onMouse: (e: MouseEvent) => void = (e) => { + const { clientX, clientY } = e + setXy({ x: clientX, y: clientY }) + } + + // effects + onMount(() => { + controller = new AbortController() + const abortSignal = controller.signal + window.addEventListener('mousemove', onMouse, { + passive: true, + signal: abortSignal + }) + }) + + onCleanup(() => { + controller?.abort() + }) + + return ( + <> +
+
{props.cursorText()}
+
+ + ) +} diff --git a/assets/ts/desktop/init.ts b/assets/ts/desktop/init.ts deleted file mode 100644 index 1ee7a64..0000000 --- a/assets/ts/desktop/init.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { type ImageJSON } from '../resources' - -import { initCustomCursor } from './customCursor' -import { initStage } from './stage' -import { initStageNav } from './stageNav' - -/** - * main functions - */ - -export function initDesktop(ijs: ImageJSON[]): void { - initCustomCursor() - initStage(ijs) - initStageNav() -} diff --git a/assets/ts/desktop/layout.tsx b/assets/ts/desktop/layout.tsx new file mode 100644 index 0000000..f74a3b7 --- /dev/null +++ b/assets/ts/desktop/layout.tsx @@ -0,0 +1,89 @@ +// eslint-disable-next-line sort-imports +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' + +/** + * interfaces and types + */ + +export interface DesktopImage extends HTMLImageElement { + dataset: { + hiUrl: string + hiImgH: string + hiImgW: string + loUrl: string + loImgH: string + loImgW: string + } +} + +export interface HistoryItem { + i: number + x: number + y: number +} + +/** + * components + */ + +export default function Desktop(props: { + children?: JSX.Element + ijs: ImageJSON[] + prevText: string + closeText: string + nextText: string + loadingText: string +}): JSX.Element { + const [cordHist, setCordHist] = createSignal([]) + const [isLoading, setIsLoading] = createSignal(false) + const [isOpen, setIsOpen] = createSignal(false) + const [isAnimating, setIsAnimating] = createSignal(false) + const [hoverText, setHoverText] = createSignal('') + const [navVector, setNavVector] = createSignal('none') + + const active = createMemo(() => isOpen() && !isAnimating()) + const cursorText = createMemo(() => (isLoading() ? props.loadingText : hoverText())) + + return ( + <> +