Rework entry and item grids

This commit is contained in:
Zoe Roux
2026-02-03 00:21:47 +01:00
parent ef8d4a9281
commit 2e1699c75a
15 changed files with 164 additions and 304 deletions
+11 -12
View File
@@ -87,22 +87,21 @@ export const expo: ExpoConfig = {
fontFamily: "Poppins",
fontDefinitions: [
{
fontFamily: "Poppins",
fontStyle: "normal",
fontWeight: "300",
file: "./node_modules/@expo-google-fonts/poppins/300Light/Poppins_300Light.ttf",
path: "./node_modules/@expo-google-fonts/poppins/300Light/Poppins_300Light.ttf",
weight: "300",
},
{
fontFamily: "Poppins",
fontStyle: "normal",
fontWeight: "500",
file: "./node_modules/@expo-google-fonts/poppins/500Medium/Poppins_500Medium.ttf",
path: "./node_modules/@expo-google-fonts/poppins/500Medium/Poppins_500Medium.ttf",
weight: "500",
},
],
},
{
fontFamily: "Sora",
fontDefinitions: [
{
fontFamily: "Sora",
fontStyle: "normal",
fontWeight: "800",
file: "./node_modules/@expo-google-fonts/sora/800ExtraBold/Sora_800ExtraBold.ttf",
path: "./node_modules/@expo-google-fonts/sora/800ExtraBold/Sora_800ExtraBold.ttf",
weight: "800",
},
],
},
+9 -11
View File
@@ -20,7 +20,7 @@
"@tanstack/react-query-devtools": "^5.91.2",
"@types/langmap": "^0.0.3",
"clsx": "^2.1.1",
"expo": "~54.0.31",
"expo": "~54.0.33",
"expo-build-properties": "~1.0.10",
"expo-constants": "~18.0.13",
"expo-dev-client": "~6.0.20",
@@ -29,7 +29,7 @@
"expo-linear-gradient": "~15.0.8",
"expo-linking": "~8.0.11",
"expo-localization": "~17.0.8",
"expo-router": "~6.0.21",
"expo-router": "~6.0.23",
"expo-splash-screen": "~31.0.13",
"expo-status-bar": "~3.0.9",
"expo-updates": "~29.0.16",
@@ -53,7 +53,7 @@
"react-native-svg-transformer": "^1.5.2",
"react-native-video": "zoriya/react-native-video#build",
"react-native-web": "^0.21.2",
"react-native-worklets": "^0.5.1",
"react-native-worklets": "0.5.1",
"react-tooltip": "^5.29.1",
"react-use-websocket": "^4.13.0",
"sweetalert2": "^11.26.17",
@@ -344,7 +344,7 @@
"@expo-google-fonts/sora": ["@expo-google-fonts/sora@0.4.2", "", {}, "sha512-X86Kl1cfObcSUzTLIbtmrPCLRlIbCNh0uBOo8bjmXb8gWgVVhnI8CZJEK2btsdq85JPn5k4P6sbV9JLbAm7dqQ=="],
"@expo/cli": ["@expo/cli@54.0.21", "", { "dependencies": { "@0no-co/graphql.web": "^1.0.8", "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devcert": "^1.2.1", "@expo/env": "~2.0.8", "@expo/image-utils": "^0.8.8", "@expo/json-file": "^10.0.8", "@expo/metro": "~54.2.0", "@expo/metro-config": "~54.0.13", "@expo/osascript": "^2.3.8", "@expo/package-manager": "^1.9.9", "@expo/plist": "^0.4.8", "@expo/prebuild-config": "^54.0.8", "@expo/schema-utils": "^0.1.8", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.3.0", "@react-native/dev-middleware": "0.81.5", "@urql/core": "^5.0.6", "@urql/exchange-retry": "^1.3.0", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "env-editor": "^0.4.1", "expo-server": "^1.0.5", "freeport-async": "^2.0.0", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.1.6", "minimatch": "^9.0.0", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^3.0.1", "pretty-bytes": "^5.6.0", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "qrcode-terminal": "0.11.0", "require-from-string": "^2.0.2", "requireg": "^0.2.2", "resolve": "^1.22.2", "resolve-from": "^5.0.0", "resolve.exports": "^2.0.3", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "tar": "^7.5.2", "terminal-link": "^2.1.1", "undici": "^6.18.2", "wrap-ansi": "^7.0.0", "ws": "^8.12.1" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "build/bin/cli" } }, "sha512-L/FdpyZDsg/Nq6xW6kfiyF9DUzKfLZCKFXEVZcDqCNar6bXxQVotQyvgexRvtUF5nLinuT/UafLOdC3FUALUmA=="],
"@expo/cli": ["@expo/cli@54.0.23", "", { "dependencies": { "@0no-co/graphql.web": "^1.0.8", "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devcert": "^1.2.1", "@expo/env": "~2.0.8", "@expo/image-utils": "^0.8.8", "@expo/json-file": "^10.0.8", "@expo/metro": "~54.2.0", "@expo/metro-config": "~54.0.14", "@expo/osascript": "^2.3.8", "@expo/package-manager": "^1.9.10", "@expo/plist": "^0.4.8", "@expo/prebuild-config": "^54.0.8", "@expo/schema-utils": "^0.1.8", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.3.0", "@react-native/dev-middleware": "0.81.5", "@urql/core": "^5.0.6", "@urql/exchange-retry": "^1.3.0", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "env-editor": "^0.4.1", "expo-server": "^1.0.5", "freeport-async": "^2.0.0", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.1.6", "minimatch": "^9.0.0", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^3.0.1", "pretty-bytes": "^5.6.0", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "qrcode-terminal": "0.11.0", "require-from-string": "^2.0.2", "requireg": "^0.2.2", "resolve": "^1.22.2", "resolve-from": "^5.0.0", "resolve.exports": "^2.0.3", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "tar": "^7.5.2", "terminal-link": "^2.1.1", "undici": "^6.18.2", "wrap-ansi": "^7.0.0", "ws": "^8.12.1" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "build/bin/cli" } }, "sha512-km0h72SFfQCmVycH/JtPFTVy69w6Lx1cHNDmfLfQqgKFYeeHTjx7LVDP4POHCtNxFP2UeRazrygJhlh4zz498g=="],
"@expo/code-signing-certificates": ["@expo/code-signing-certificates@0.0.6", "", { "dependencies": { "node-forge": "^1.3.3" } }, "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w=="],
@@ -370,7 +370,7 @@
"@expo/metro": ["@expo/metro@54.2.0", "", { "dependencies": { "metro": "0.83.3", "metro-babel-transformer": "0.83.3", "metro-cache": "0.83.3", "metro-cache-key": "0.83.3", "metro-config": "0.83.3", "metro-core": "0.83.3", "metro-file-map": "0.83.3", "metro-minify-terser": "0.83.3", "metro-resolver": "0.83.3", "metro-runtime": "0.83.3", "metro-source-map": "0.83.3", "metro-symbolicate": "0.83.3", "metro-transform-plugins": "0.83.3", "metro-transform-worker": "0.83.3" } }, "sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w=="],
"@expo/metro-config": ["@expo/metro-config@54.0.13", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@expo/config": "~12.0.13", "@expo/env": "~2.0.8", "@expo/json-file": "~10.0.8", "@expo/metro": "~54.2.0", "@expo/spawn-async": "^1.7.2", "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0", "glob": "^13.0.0", "hermes-parser": "^0.29.1", "jsc-safe-url": "^0.2.4", "lightningcss": "^1.30.1", "minimatch": "^9.0.0", "postcss": "~8.4.32", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" }, "optionalPeers": ["expo"] }, "sha512-RRufMCgLR2Za1WGsh02OatIJo5qZFt31yCnIOSfoubNc3Qqe92Z41pVsbrFnmw5CIaisv1NgdBy05DHe7pEyuw=="],
"@expo/metro-config": ["@expo/metro-config@54.0.14", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@expo/config": "~12.0.13", "@expo/env": "~2.0.8", "@expo/json-file": "~10.0.8", "@expo/metro": "~54.2.0", "@expo/spawn-async": "^1.7.2", "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0", "glob": "^13.0.0", "hermes-parser": "^0.29.1", "jsc-safe-url": "^0.2.4", "lightningcss": "^1.30.1", "minimatch": "^9.0.0", "postcss": "~8.4.32", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" }, "optionalPeers": ["expo"] }, "sha512-hxpLyDfOR4L23tJ9W1IbJJsG7k4lv2sotohBm/kTYyiG+pe1SYCAWsRmgk+H42o/wWf/HQjE5k45S5TomGLxNA=="],
"@expo/metro-runtime": ["@expo/metro-runtime@6.1.2", "", { "dependencies": { "anser": "^1.4.9", "pretty-format": "^29.7.0", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-dom": "*", "react-native": "*" }, "optionalPeers": ["react-dom"] }, "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g=="],
@@ -720,7 +720,7 @@
"babel-preset-current-node-syntax": ["babel-preset-current-node-syntax@1.2.0", "", { "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-import-attributes": "^7.24.7", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg=="],
"babel-preset-expo": ["babel-preset-expo@54.0.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-react": "^7.22.15", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-preset": "0.81.5", "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.29.1", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4", "resolve-from": "^5.0.0" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo"] }, "sha512-8J6hRdgEC2eJobjoft6mKJ294cLxmi3khCUy2JJQp4htOYYkllSLUq6vudWJkTJiIuGdVR4bR6xuz2EvJLWHNg=="],
"babel-preset-expo": ["babel-preset-expo@54.0.10", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-react": "^7.22.15", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-preset": "0.81.5", "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.29.1", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4", "resolve-from": "^5.0.0" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo"] }, "sha512-wTt7POavLFypLcPW/uC5v8y+mtQKDJiyGLzYCjqr9tx0Qc3vCXcDKk1iCFIj/++Iy5CWhhTflEa7VvVPNWeCfw=="],
"babel-preset-jest": ["babel-preset-jest@29.6.3", "", { "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA=="],
@@ -900,7 +900,7 @@
"exec-async": ["exec-async@2.2.0", "", {}, "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw=="],
"expo": ["expo@54.0.31", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.21", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devtools": "0.1.8", "@expo/fingerprint": "0.15.4", "@expo/metro": "~54.2.0", "@expo/metro-config": "54.0.13", "@expo/vector-icons": "^15.0.3", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~54.0.9", "expo-asset": "~12.0.12", "expo-constants": "~18.0.13", "expo-file-system": "~19.0.21", "expo-font": "~14.0.10", "expo-keep-awake": "~15.0.8", "expo-modules-autolinking": "3.0.24", "expo-modules-core": "3.0.29", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-kQ3RDqA/a59I7y+oqQGyrPbbYlgPMUdKBOgvFLpoHbD2bCM+F75i4N0mUijy7dG5F/CUCu2qHmGGUCXBbMDkCg=="],
"expo": ["expo@54.0.33", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.23", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devtools": "0.1.8", "@expo/fingerprint": "0.15.4", "@expo/metro": "~54.2.0", "@expo/metro-config": "54.0.14", "@expo/vector-icons": "^15.0.3", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~54.0.10", "expo-asset": "~12.0.12", "expo-constants": "~18.0.13", "expo-file-system": "~19.0.21", "expo-font": "~14.0.11", "expo-keep-awake": "~15.0.8", "expo-modules-autolinking": "3.0.24", "expo-modules-core": "3.0.29", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-3yOEfAKqo+gqHcV8vKcnq0uA5zxlohnhA3fu4G43likN8ct5ZZ3LjAh9wDdKteEkoad3tFPvwxmXW711S5OHUw=="],
"expo-asset": ["expo-asset@12.0.12", "", { "dependencies": { "@expo/image-utils": "^0.8.8", "expo-constants": "~18.0.12" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-CsXFCQbx2fElSMn0lyTdRIyKlSXOal6ilLJd+yeZ6xaC7I9AICQgscY5nj0QcwgA+KYYCCEQEBndMsmj7drOWQ=="],
@@ -940,7 +940,7 @@
"expo-modules-core": ["expo-modules-core@3.0.29", "", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-LzipcjGqk8gvkrOUf7O2mejNWugPkf3lmd9GkqL9WuNyeN2fRwU0Dn77e3ZUKI3k6sI+DNwjkq4Nu9fNN9WS7Q=="],
"expo-router": ["expo-router@6.0.21", "", { "dependencies": { "@expo/metro-runtime": "^6.1.2", "@expo/schema-utils": "^0.1.8", "@radix-ui/react-slot": "1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/native": "^7.1.8", "@react-navigation/native-stack": "^7.3.16", "client-only": "^0.0.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-server": "^1.0.5", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.1.6", "semver": "~7.6.3", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "use-latest-callback": "^0.2.1", "vaul": "^1.1.2" }, "peerDependencies": { "@react-navigation/drawer": "^7.5.0", "@testing-library/react-native": ">= 12.0.0", "expo": "*", "expo-constants": "^18.0.12", "expo-linking": "^8.0.11", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-screens": "*", "react-native-web": "*", "react-server-dom-webpack": "~19.0.3 || ~19.1.4 || ~19.2.3" }, "optionalPeers": ["@react-navigation/drawer", "@testing-library/react-native", "react-dom", "react-native-gesture-handler", "react-native-reanimated", "react-native-web", "react-server-dom-webpack"] }, "sha512-wjTUjrnWj6gRYjaYl1kYfcRnNE4ZAQ0kz0+sQf6/mzBd/OU6pnOdD7WrdAW3pTTpm52Q8sMoeX98tNQEddg2uA=="],
"expo-router": ["expo-router@6.0.23", "", { "dependencies": { "@expo/metro-runtime": "^6.1.2", "@expo/schema-utils": "^0.1.8", "@radix-ui/react-slot": "1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/native": "^7.1.8", "@react-navigation/native-stack": "^7.3.16", "client-only": "^0.0.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-server": "^1.0.5", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.1.6", "semver": "~7.6.3", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "use-latest-callback": "^0.2.1", "vaul": "^1.1.2" }, "peerDependencies": { "@react-navigation/drawer": "^7.5.0", "@testing-library/react-native": ">= 12.0.0", "expo": "*", "expo-constants": "^18.0.13", "expo-linking": "^8.0.11", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-screens": "*", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, "optionalPeers": ["@react-navigation/drawer", "@testing-library/react-native", "react-dom", "react-native-gesture-handler", "react-native-reanimated", "react-native-web", "react-server-dom-webpack"] }, "sha512-qCxVAiCrCyu0npky6azEZ6dJDMt77OmCzEbpF6RbUTlfkaCA417LvY14SBkk0xyGruSxy/7pvJOI6tuThaUVCA=="],
"expo-server": ["expo-server@1.0.5", "", {}, "sha512-IGR++flYH70rhLyeXF0Phle56/k4cee87WeQ4mamS+MkVAVP+dDlOHf2nN06Z9Y2KhU0Gp1k+y61KkghF7HdhA=="],
@@ -1390,7 +1390,7 @@
"react-native-web": ["react-native-web@0.21.2", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^7.0.1", "memoize-one": "^6.0.0", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "styleq": "^0.1.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg=="],
"react-native-worklets": ["react-native-worklets@0.5.2", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", "@babel/plugin-transform-classes": "^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", "@babel/plugin-transform-optional-chaining": "^7.0.0-0", "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", "@babel/plugin-transform-template-literals": "^7.0.0-0", "@babel/plugin-transform-unicode-regex": "^7.0.0-0", "@babel/preset-typescript": "^7.16.7", "convert-source-map": "^2.0.0", "semver": "7.7.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, "sha512-lCzmuIPAK/UaOJYEPgYpVqrsxby1I54f7PyyZUMEO04nwc00CDrCvv9lCTY1daLHYTF8lS3f9zlzErfVsIKqkA=="],
"react-native-worklets": ["react-native-worklets@0.5.1", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", "@babel/plugin-transform-classes": "^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", "@babel/plugin-transform-optional-chaining": "^7.0.0-0", "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", "@babel/plugin-transform-template-literals": "^7.0.0-0", "@babel/plugin-transform-unicode-regex": "^7.0.0-0", "@babel/preset-typescript": "^7.16.7", "convert-source-map": "^2.0.0", "semver": "7.7.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w=="],
"react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
@@ -1748,8 +1748,6 @@
"error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
"expo/expo-font": ["expo-font@14.0.10", "", { "dependencies": { "fontfaceobserver": "^2.1.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-UqyNaaLKRpj4pKAP4HZSLnuDQqueaO5tB1c/NWu5vh1/LF9ulItyyg2kF/IpeOp0DeOLk0GY0HrIXaKUMrwB+Q=="],
"expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
"expo-router/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w=="],
+3 -3
View File
@@ -30,7 +30,7 @@
"@tanstack/react-query-devtools": "^5.91.2",
"@types/langmap": "^0.0.3",
"clsx": "^2.1.1",
"expo": "~54.0.31",
"expo": "~54.0.33",
"expo-build-properties": "~1.0.10",
"expo-constants": "~18.0.13",
"expo-dev-client": "~6.0.20",
@@ -39,7 +39,7 @@
"expo-linear-gradient": "~15.0.8",
"expo-linking": "~8.0.11",
"expo-localization": "~17.0.8",
"expo-router": "~6.0.21",
"expo-router": "~6.0.23",
"expo-splash-screen": "~31.0.13",
"expo-status-bar": "~3.0.9",
"expo-updates": "~29.0.16",
@@ -63,7 +63,7 @@
"react-native-svg-transformer": "^1.5.2",
"react-native-video": "zoriya/react-native-video#build",
"react-native-web": "^0.21.2",
"react-native-worklets": "^0.5.1",
"react-native-worklets": "0.5.1",
"react-tooltip": "^5.29.1",
"react-use-websocket": "^4.13.0",
"sweetalert2": "^11.26.17",
+14 -14
View File
@@ -4,6 +4,7 @@ import Home from "@material-symbols/svg-400/rounded/home-fill.svg";
import { Tabs } from "expo-router";
import { useTranslation } from "react-i18next";
import { Icon } from "~/primitives";
import { cn } from "~/utils";
export default function TabsLayout() {
const { t } = useTranslation();
@@ -18,29 +19,28 @@ export default function TabsLayout() {
name="index"
options={{
tabBarLabel: t("navbar.home"),
tabBarIcon: ({ color, size }) => (
<Icon icon={Home} color={color} size={size} />
),
tabBarIcon: ({ focused }) => {
return (
<Icon
icon={Home}
className={cn(focused && "fill-accent dark:fill-accent")}
/>
);
},
}}
/>
<Tabs.Screen
name="browse"
options={{
tabBarLabel: t("navbar.browse"),
tabBarIcon: ({ color, size }) => (
<Icon icon={Browse} color={color} size={size} />
tabBarIcon: ({ focused }) => (
<Icon
icon={Browse}
className={cn(focused && "fill-accent dark:fill-accent")}
/>
),
}}
/>
{/* <Tabs.Screen */}
{/* name="downloads" */}
{/* options={{ */}
{/* tabBarLabel: t("navbar.download"), */}
{/* tabBarIcon: ({ color, size }) => ( */}
{/* <Icon icon={Downloading} color={color} size={size} /> */}
{/* ), */}
{/* }} */}
{/* /> */}
</Tabs>
);
}
+3 -3
View File
@@ -1,12 +1,12 @@
import { Stack } from "expo-router";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useTheme } from "yoshiki/native";
import { useCSSVariable } from "uniwind";
import { ErrorConsumer } from "~/providers/error-consumer";
import { NavbarProfile, NavbarTitle } from "~/ui/navbar";
export default function Layout() {
const insets = useSafeAreaInsets();
const theme = useTheme();
const accent = useCSSVariable("--color-accent");
return (
<ErrorConsumer scope="login">
@@ -19,7 +19,7 @@ export default function Layout() {
paddingRight: insets.right,
},
headerStyle: {
backgroundColor: theme.accent,
backgroundColor: accent as string,
},
}}
/>
+37 -88
View File
@@ -1,16 +1,8 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import type { KImage, WatchStatusV } from "~/models";
import {
percent,
rem,
type Stylable,
type Theme,
useYoshiki,
} from "yoshiki/native";
import type { KImage } from "~/models";
import {
focusReset,
Image,
ImageBackground,
Link,
@@ -20,6 +12,9 @@ import {
ts,
} from "~/primitives";
import type { Layout } from "~/query";
import { cn } from "~/utils";
import { EntryContext } from "../items/context-menus";
import { ItemProgress } from "../items/item-grid";
export const EntryBox = ({
slug,
@@ -29,9 +24,10 @@ export const EntryBox = ({
thumbnail,
href,
watchedPercent,
// watchedStatus,
watchedStatus,
className,
...props
}: Stylable & {
}: {
slug: string;
// if serie slug is null, disable "Go to serie" in the context menu
serieSlug: string | null;
@@ -40,107 +36,60 @@ export const EntryBox = ({
href: string;
thumbnail: KImage | null;
watchedPercent: number | null;
// watchedStatus: WatchStatusV | null;
watchedStatus: WatchStatusV | null;
className?: string;
}) => {
const [moreOpened, setMoreOpened] = useState(false);
const { css } = useYoshiki("episodebox");
const { t } = useTranslation();
return (
<Link
href={moreOpened ? undefined : href}
onLongPress={() => setMoreOpened(true)}
{...css(
{
alignItems: "center",
width: EntryBox.layout.size,
child: {
poster: {
borderColor: (theme) => theme.background,
borderWidth: ts(0.5),
borderStyle: "solid",
borderRadius: 6,
},
more: {
opacity: 0,
},
},
fover: {
self: focusReset,
poster: {
borderColor: (theme: Theme) => theme.accent,
},
title: {
textDecorationLine: "underline",
},
more: {
opacity: 1,
},
},
},
props,
)}
className={cn("group w-[350px] items-center outline-0", className)}
{...props}
>
<ImageBackground
src={thumbnail}
quality="low"
alt=""
layout={{ width: percent(100), aspectRatio: 16 / 9 }}
{...(css("poster") as any)}
className={cn(
"aspect-video w-full rounded",
"ring-accent group-hover:ring-3 group-focus-visible:ring-3",
)}
>
{/* {(watchedPercent || watchedStatus === "completed") && ( */}
{/* <ItemProgress watchPercent={watchedPercent ?? 100} /> */}
{/* )} */}
{/* <EntryContext */}
{/* slug={slug} */}
{/* serieSlug={serieSlug} */}
{/* status={watchedStatus} */}
{/* isOpen={moreOpened} */}
{/* setOpen={(v) => setMoreOpened(v)} */}
{/* {...css([ */}
{/* { */}
{/* position: "absolute", */}
{/* top: 0, */}
{/* right: 0, */}
{/* bg: (theme) => theme.darkOverlay, */}
{/* }, */}
{/* "more", */}
{/* Platform.OS === "web" && */}
{/* moreOpened && { display: important("flex") }, */}
{/* ])} */}
{/* /> */}
{(watchedPercent || watchedStatus === "completed") && (
<ItemProgress watchPercent={watchedPercent ?? 100} />
)}
<EntryContext
slug={slug}
serieSlug={serieSlug}
isOpen={moreOpened}
setOpen={(v) => setMoreOpened(v)}
className={cn(
"absolute top-0 right-0 bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800",
"native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
moreOpened && "opacity-100",
)}
iconClassName="fill-slate-200 dark:fill-slate-200"
/>
</ImageBackground>
<P {...css([{ marginY: 0, textAlign: "center" }, "title"])}>
<P className="text-center group-focus-within:underline group-hover:underline">
{name ?? t("show.episodeNoMetadata")}
</P>
<SubP
numberOfLines={3}
{...css({
marginTop: 0,
textAlign: "center",
})}
>
<SubP numberOfLines={3} className="text-center">
{description}
</SubP>
</Link>
);
};
EntryBox.Loader = (props: Stylable) => {
const { css } = useYoshiki();
EntryBox.Loader = ({ className, ...props }: { className?: string }) => {
return (
<View
{...css(
{
alignItems: "center",
},
props,
)}
>
<Image.Loader layout={{ width: percent(100), aspectRatio: 16 / 9 }} />
<Skeleton {...css({ width: percent(50) })} />
<Skeleton {...css({ width: percent(75), height: rem(0.8) })} />
<View className={cn("items-center", className)} {...props}>
<Image.Loader className="aspect-video w-full" />
<Skeleton className="w-1/2" />
<Skeleton className="h-3 w-4/5" />
</View>
);
};
+1 -1
View File
@@ -74,7 +74,7 @@ export const EntryLine = ({
className={cn(
"mr-1 w-1/5 shrink-0 rounded",
poster ? "aspect-2/3" : "aspect-video",
"group-hover:ring-3 group-hover:ring-accent group-focus-visible:ring-3 group-focus-visible:ring-accent",
"ring-accent group-hover:ring-3 group-focus-visible:ring-3",
)}
>
{(watchedPercent ?? 0) > 0 && (
+8 -6
View File
@@ -4,8 +4,6 @@ import MoreVert from "@material-symbols/svg-400/rounded/more_vert.svg";
import MovieInfo from "@material-symbols/svg-400/rounded/movie_info.svg";
import type { ComponentProps } from "react";
import { useTranslation } from "react-i18next";
import { Platform } from "react-native";
import { useYoshiki } from "yoshiki/native";
import { WatchStatusV } from "~/models";
import { IconButton, Menu, tooltip } from "~/primitives";
import { useAccount } from "~/providers/account-context";
@@ -23,7 +21,8 @@ export const EntryContext = ({
serieSlug: string | null;
slug: string;
className?: string;
} & Partial<ComponentProps<typeof Menu<typeof IconButton>>>) => {
} & Partial<ComponentProps<typeof Menu>> &
Partial<ComponentProps<typeof IconButton>>) => {
// const downloader = useDownloader();
const { t } = useTranslation();
@@ -60,15 +59,17 @@ export const ItemContext = ({
kind,
slug,
status,
className,
...props
}: {
kind: "movie" | "serie";
slug: string;
status: WatchStatusV | null;
} & Partial<ComponentProps<typeof Menu<typeof IconButton>>>) => {
className?: string;
} & Partial<ComponentProps<typeof Menu>> &
Partial<ComponentProps<typeof IconButton>>) => {
const account = useAccount();
// const downloader = useDownloader();
const { css } = useYoshiki();
const { t } = useTranslation();
const mutation = useMutation({
@@ -90,8 +91,9 @@ export const ItemContext = ({
<Menu
Trigger={IconButton}
icon={MoreVert}
className={cn("not:web:hidden", className)}
{...tooltip(t("misc.more"))}
{...(css([Platform.OS !== "web" && { display: "none" }], props) as any)}
{...(props as any)}
>
<Menu.Sub
label={account ? t("show.watchlistEdit") : t("show.watchlistLogin")}
+28 -93
View File
@@ -1,10 +1,7 @@
import { useState } from "react";
import { type ImageStyle, Platform, View } from "react-native";
import { percent, type Stylable, type Theme, useYoshiki } from "yoshiki/native";
import { View } from "react-native";
import type { KImage, WatchStatusV } from "~/models";
import {
focusReset,
important,
Link,
P,
Poster,
@@ -14,31 +11,17 @@ import {
ts,
} from "~/primitives";
import type { Layout } from "~/query";
import { cn } from "~/utils";
import { ItemContext } from "./context-menus";
import { ItemWatchStatus } from "./item-helpers";
export const ItemProgress = ({ watchPercent }: { watchPercent: number }) => {
const { css } = useYoshiki("episodebox");
return (
<>
<View className="absolute bottom-0 h-1 w-full bg-slate-400" />
<View
{...css({
backgroundColor: (theme) => theme.user.overlay0,
width: percent(100),
height: ts(0.5),
position: "absolute",
bottom: 0,
})}
/>
<View
{...css({
backgroundColor: (theme) => theme.user.accent,
width: percent(watchPercent),
height: ts(0.5),
position: "absolute",
bottom: 0,
})}
className="absolute bottom-0 h-1 bg-accent"
style={{ width: `${watchPercent}%` }}
/>
</>
);
@@ -55,6 +38,7 @@ export const ItemGrid = ({
watchPercent,
unseenEpisodesCount,
horizontal = false,
className,
...props
}: {
href: string;
@@ -67,52 +51,29 @@ export const ItemGrid = ({
kind: "movie" | "serie" | "collection";
unseenEpisodesCount: number | null;
horizontal: boolean;
} & Stylable<"text">) => {
className?: string;
}) => {
const [moreOpened, setMoreOpened] = useState(false);
const { css } = useYoshiki("grid");
return (
<Link
href={moreOpened ? undefined : href}
onLongPress={() => setMoreOpened(true)}
{...css(
{
flexDirection: "column",
alignItems: "center",
width: horizontal ? ItemGrid.layout.size : percent(100),
height: horizontal ? percent(100) : undefined,
child: {
poster: {
borderColor: (theme) => theme.background,
borderWidth: ts(0.5),
borderStyle: "solid",
},
more: {
display: "none",
},
},
fover: {
self: focusReset,
poster: {
borderColor: (theme: Theme) => theme.accent,
},
title: {
textDecorationLine: "underline",
},
more: {
display: "flex",
},
},
},
props,
className={cn(
"group items-center outline-0",
horizontal && "h-full w-[200px]",
className,
)}
{...props}
>
<PosterBackground
src={poster}
alt={name}
quality="low"
layout={{ width: percent(100) }}
{...(css("poster") as { style: ImageStyle })}
className={cn(
"w-full",
"ring-accent group-hover:ring-3 group-focus-visible:ring-3",
)}
>
<ItemWatchStatus
watchStatus={watchStatus}
@@ -128,64 +89,38 @@ export const ItemGrid = ({
status={watchStatus}
isOpen={moreOpened}
setOpen={(v) => setMoreOpened(v)}
{...css([
{
position: "absolute",
top: 0,
right: 0,
bg: (theme) => theme.dark.background,
},
"more",
Platform.OS === "web" &&
moreOpened && { display: important("flex") },
])}
className={cn(
"absolute top-0 right-0 bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800",
"native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
moreOpened && "opacity-100",
)}
iconClassName="fill-slate-200 dark:fill-slate-200"
/>
)}
</PosterBackground>
<P
numberOfLines={subtitle ? 1 : 2}
{...css([{ marginY: 0, textAlign: "center" }, "title"])}
className="text-center group-focus-within:underline group-hover:underline"
>
{name}
</P>
{subtitle && (
<SubP
{...css({
marginTop: 0,
textAlign: "center",
})}
>
{subtitle}
</SubP>
)}
{subtitle && <SubP className="text-center">{subtitle}</SubP>}
</Link>
);
};
ItemGrid.Loader = (props: object) => {
const { css } = useYoshiki();
return (
<View
{...css(
{
flexDirection: "column",
alignItems: "center",
width: percent(100),
},
props,
)}
>
<Poster.Loader layout={{ width: percent(100) }} />
<View className="w-full items-center" {...props}>
<Poster.Loader className="w-full" />
<Skeleton />
<Skeleton {...css({ width: percent(50) })} />
<Skeleton className="w-1/2" />
</View>
);
};
ItemGrid.layout = {
size: 200,
// size: { xs: 150, md: 200, xl: 210 },
numColumns: { xs: 3, sm: 4, md: 5, lg: 6, xl: 8 },
gap: { xs: ts(1), sm: ts(2), md: ts(4) },
layout: "grid",
+5 -6
View File
@@ -69,12 +69,12 @@ export const IconButton = <AsProps = PressableProps>({
icon,
as,
className,
iconProps,
iconClassName,
...asProps
}: {
as?: ComponentType<AsProps>;
icon: Icon;
iconProps?: Omit<ComponentProps<typeof Icon>, "icon">;
iconClassName?: string;
className?: string;
} & AsProps) => {
const Container = as ?? PressableFeedback;
@@ -89,7 +89,7 @@ export const IconButton = <AsProps = PressableProps>({
)}
{...(asProps as AsProps)}
>
<Icon icon={icon} {...iconProps} />
<Icon icon={icon} className={iconClassName} />
</Container>
);
};
@@ -99,7 +99,7 @@ const Pressable = Animated.createAnimatedComponent(PressableFeedback);
export const IconFab = <AsProps = PressableProps>({
icon,
className,
iconProps,
iconClassName,
...props
}: ComponentProps<typeof IconButton<AsProps>>) => {
const [hover, setHover] = useState(false);
@@ -123,11 +123,10 @@ export const IconFab = <AsProps = PressableProps>({
>
<Icon
icon={icon}
{...iconProps}
className={cn(
"fill-slate-300",
(hover || focus) && "fill-slate-200",
iconProps?.className,
iconClassName,
)}
/>
</Pressable>
-1
View File
@@ -74,7 +74,6 @@ const RnTheme = ({ children }: { children: ReactNode }) => {
Uniwind.updateInsets(insets);
}}
>
{" "}
{children}
</SafeAreaListener>
</RNThemeProvider>
+1 -1
View File
@@ -18,7 +18,7 @@ const LegendList = withUniwind(RLegendList) as typeof RLegendList;
export const InfiniteFetch = <Data, Type extends string = string>({
query,
placeholderCount = 2,
placeholderCount = 4,
incremental = false,
getItemType,
getItemSizeMult,
+33 -45
View File
@@ -10,7 +10,6 @@ import All from "@material-symbols/svg-400/rounded/view_headline.svg";
import ViewList from "@material-symbols/svg-400/rounded/view_list.svg";
import { useTranslation } from "react-i18next";
import { type PressableProps, View } from "react-native";
import { useYoshiki } from "yoshiki/native";
import {
HR,
Icon,
@@ -19,23 +18,24 @@ import {
P,
PressableFeedback,
tooltip,
ts,
} from "~/primitives";
import { cn } from "~/utils";
import { availableSorts, type SortBy, type SortOrd } from "./types";
const SortTrigger = ({
sortBy,
className,
...props
}: { sortBy: SortBy } & PressableProps) => {
const { css } = useYoshiki();
const { t } = useTranslation();
return (
<PressableFeedback
{...css({ flexDirection: "row", alignItems: "center" }, props as any)}
className={cn("flex-row items-center", className)}
{...tooltip(t("browse.sortby-tt"))}
{...props}
>
<Icon icon={Sort} {...css({ paddingX: ts(0.5) })} />
<Icon icon={Sort} className="mx-1" />
<P>{t(`browse.sortkey.${sortBy}`)}</P>
</PressableFeedback>
);
@@ -50,20 +50,18 @@ const MediaTypeIcons = {
const MediaTypeTrigger = ({
mediaType,
className,
...props
}: PressableProps & { mediaType: keyof typeof MediaTypeIcons }) => {
const { css } = useYoshiki();
const { t } = useTranslation();
return (
<PressableFeedback
{...css({ flexDirection: "row", alignItems: "center" }, props as any)}
className={cn("flex-row items-center", className)}
{...tooltip(t("browse.mediatype-tt"))}
{...props}
>
<Icon
icon={MediaTypeIcons[mediaType] ?? FilterList}
{...css({ paddingX: ts(0.5) })}
/>
<Icon icon={MediaTypeIcons[mediaType] ?? FilterList} className="mx-1" />
<P>
{t(
mediaType !== "all"
@@ -92,7 +90,6 @@ export const BrowseSettings = ({
layout: "grid" | "list";
setLayout: (layout: "grid" | "list") => void;
}) => {
const { css, theme } = useYoshiki();
const { t } = useTranslation();
// TODO: have a proper filter frontend
@@ -101,15 +98,22 @@ export const BrowseSettings = ({
setFilter(kind !== "all" ? `kind eq ${kind}` : "");
return (
<View
{...css({
flexDirection: "row-reverse",
alignItems: "center",
marginX: ts(4),
marginY: ts(1),
})}
>
<View {...css({ flexDirection: "row" })}>
<View className="mx-8 my-2 flex-row items-center justify-between">
<Menu
Trigger={MediaTypeTrigger}
mediaType={mediaType as keyof typeof MediaTypeIcons}
>
{Object.keys(MediaTypeIcons).map((x) => (
<Menu.Item
key={x}
label={t(`browse.mediatypekey.${x as keyof typeof MediaTypeIcons}`)}
selected={mediaType === x}
icon={MediaTypeIcons[x as keyof typeof MediaTypeIcons]}
onSelect={() => setMediaType(x)}
/>
))}
</Menu>
<View className="flex-row">
<Menu Trigger={SortTrigger} sortBy={sortBy}>
{availableSorts.map((x) => (
<Menu.Item
@@ -127,38 +131,22 @@ export const BrowseSettings = ({
<IconButton
icon={GridView}
onPress={() => setLayout("grid")}
color={layout === "grid" ? theme.accent : undefined}
className="m-1"
iconClassName={cn(
layout === "grid" && "fill-accent dark:fill-accent",
)}
{...tooltip(t("browse.switchToGrid"))}
{...css({ padding: ts(0.5), marginY: "auto" })}
/>
<IconButton
icon={ViewList}
onPress={() => setLayout("list")}
color={layout === "list" ? theme.accent : undefined}
className="m-1"
iconClassName={cn(
layout === "list" && "fill-accent dark:fill-accent",
)}
{...tooltip(t("browse.switchToList"))}
{...css({ padding: ts(0.5), marginY: "auto" })}
/>
</View>
<View
{...css({ flexGrow: 1, flexDirection: "row", alignItems: "center" })}
>
<Menu
Trigger={MediaTypeTrigger}
mediaType={mediaType as keyof typeof MediaTypeIcons}
>
{Object.keys(MediaTypeIcons).map((x) => (
<Menu.Item
key={x}
label={t(
`browse.mediatypekey.${x as keyof typeof MediaTypeIcons}`,
)}
selected={mediaType === x}
icon={MediaTypeIcons[x as keyof typeof MediaTypeIcons]}
onSelect={() => setMediaType(x)}
/>
))}
</Menu>
</View>
</View>
);
};
+10 -19
View File
@@ -82,7 +82,7 @@ const ButtonList = ({
icon={PlayArrow}
as={Link}
href={playHref}
iconProps={{ className: "dark:fill-slate-200" }}
iconClassName="dark:fill-slate-200"
{...tooltip(t("show.play"))}
/>
)}
@@ -92,7 +92,7 @@ const ButtonList = ({
as={Link}
href={trailerUrl}
target="_blank"
iconProps={{ className: iconsClassName }}
iconClassName={iconsClassName}
{...tooltip(t("show.trailer"))}
/>
)}
@@ -101,14 +101,14 @@ const ButtonList = ({
kind={kind}
slug={slug}
status={watchStatus}
iconProps={{ className: iconsClassName }}
iconClassName={iconsClassName}
/>
)}
{(kind === "movie" || account?.isAdmin === true) && (
<Menu
Trigger={IconButton}
icon={MoreHoriz}
iconProps={{ className: iconsClassName }}
iconClassName={iconsClassName}
{...tooltip(t("misc.more"))}
>
{kind === "movie" && (
@@ -241,19 +241,10 @@ TitleLine.Loader = ({
<Skeleton variant="custom" className="h-10 w-2/5 max-sm:text-center" />
<Skeleton className="h-6 w-4/5 max-sm:text-center" />
<View className="flex-warp flex-row items-center max-sm:justify-center sm:mt-8">
<IconFab
icon={PlayArrow}
iconProps={{ className: "lg:fill-slate-200" }}
/>
<IconButton
icon={Theaters}
iconProps={{ className: "lg:fill-slate-200" }}
/>
<IconFab icon={PlayArrow} iconClassName="lg:fill-slate-200" />
<IconButton icon={Theaters} iconClassName="lg:fill-slate-200" />
{kind !== "collection" && (
<IconButton
icon={BookmarkAdd}
iconProps={{ className: "lg:fill-slate-200" }}
/>
<IconButton icon={BookmarkAdd} iconClassName="lg:fill-slate-200" />
)}
{kind === "movie" && <IconButton icon={MoreHoriz} />}
<DottedSeparator className="lg:text-slate-200" />
@@ -326,12 +317,12 @@ const Description = ({
<P className="my-5 flex-row flex-wrap items-center">
<P className="mr-1">{t("show.studios")}:</P>
{studios.map((x, i) => (
<>
<Fragment key={x.id}>
{i !== 0 && ","}
<A key={x.id} href={x.slug} className="ml-2">
<A href={x.slug} className="ml-2">
{x.name}
</A>
</>
</Fragment>
))}
</P>
<View className="flex-row flex-wrap items-center">
+1 -1
View File
@@ -39,7 +39,7 @@ import { KyooLongLogo } from "./icon";
export const NavbarTitle = ({
className,
...props
}: ComponentProps<typeof A>) => {
}: Partial<ComponentProps<typeof A>>) => {
const { t } = useTranslation();
return (