mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-08 18:54:22 -04:00
Fix prefetch
This commit is contained in:
parent
7ee6c2e666
commit
176d76b246
@ -1,6 +1,6 @@
|
||||
import { HydrationBoundary } from "@tanstack/react-query";
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||
import { Slot } from "one";
|
||||
import { Slot, getServerData } from "one";
|
||||
import { useServerHeadInsertion } from "one";
|
||||
import { StyleRegistryProvider, createStyleRegistry, useTheme } from "yoshiki/web";
|
||||
import { Providers } from "~/providers";
|
||||
@ -63,6 +63,8 @@ export default function Layout() {
|
||||
const registry = createStyleRegistry();
|
||||
useServerHeadInsertion(() => registry.flushToComponent());
|
||||
|
||||
const queryState = getServerData("queryState");
|
||||
|
||||
// TODO: change this lang attr
|
||||
return (
|
||||
<html lang="en-US">
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useYoshiki } from "yoshiki/native";
|
||||
import { type LibraryItem, LibraryItemP } from "~/models";
|
||||
import { P } from "~/primitives";
|
||||
import { Fetch, type QueryIdentifier } from "~/query";
|
||||
import { Fetch, type QueryIdentifier, prefetch } from "~/query";
|
||||
|
||||
export async function loader() {
|
||||
await prefetchQuery(Header.query());
|
||||
await prefetch(Header.query());
|
||||
}
|
||||
|
||||
export default function Header() {
|
||||
|
@ -4,6 +4,7 @@
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@expo/html-elements": "^0.11.2",
|
||||
"@material-symbols/svg-400": "^0.28.1",
|
||||
"@tanstack/react-query": "^5.66.0",
|
||||
"caniuse-api": "^3.0.0",
|
||||
"expo": "~52.0.28",
|
||||
@ -18,6 +19,7 @@
|
||||
"react-native-reanimated": "~3.16.7",
|
||||
"react-native-safe-area-context": "5.1.0",
|
||||
"react-native-screens": "4.6.0",
|
||||
"react-native-svg": "^15.11.1",
|
||||
"react-native-web": "^0.19.13",
|
||||
"yoshiki": "1.2.14",
|
||||
"zod": "^3.24.1",
|
||||
@ -470,6 +472,8 @@
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||
|
||||
"@material-symbols/svg-400": ["@material-symbols/svg-400@0.28.1", "", {}, "sha512-lup10XPj7rzxJ4pCQICSG5iILEymcamtv+uveOm9bhgVBZq1KrZOse7VERYfIv5FYqwrP8GheUGkRAURPNc6KQ=="],
|
||||
|
||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.6", "", { "dependencies": { "@emnapi/core": "^1.3.1", "@emnapi/runtime": "^1.3.1", "@tybys/wasm-util": "^0.9.0" } }, "sha512-z8YVS3XszxFTO73iwvFDNpQIzdMmSDTP/mB3E/ucR37V3Sx57hSExcXyMoNwaucWxnsWf4xfbZv0iZ30jr0M4Q=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
@ -830,6 +834,8 @@
|
||||
|
||||
"bippy": ["bippy@0.0.25", "", {}, "sha512-+rvlmS7vbv704MjmpMLaSNKezGkc7xux7/DbhTp61RFQZAYwH8V0pbxGYiDWxA9a+7RxNFhHtsSIu9uoB+eK0Q=="],
|
||||
|
||||
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
|
||||
|
||||
"bplist-creator": ["bplist-creator@0.0.7", "", { "dependencies": { "stream-buffers": "~2.2.0" } }, "sha512-xp/tcaV3T5PCiaY04mXga7o/TE+t95gqeLmADeBI1CvZtdWTbgBt3uLpvh4UWtenKeBhCV6oVxGk38yZr2uYEA=="],
|
||||
|
||||
"bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="],
|
||||
@ -956,6 +962,12 @@
|
||||
|
||||
"css-in-js-utils": ["css-in-js-utils@3.1.0", "", { "dependencies": { "hyphenate-style-name": "^1.0.3" } }, "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A=="],
|
||||
|
||||
"css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="],
|
||||
|
||||
"css-tree": ["css-tree@1.1.3", "", { "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q=="],
|
||||
|
||||
"css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="],
|
||||
|
||||
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
@ -996,6 +1008,14 @@
|
||||
|
||||
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
||||
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||
|
||||
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
|
||||
|
||||
"dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
|
||||
@ -1012,6 +1032,8 @@
|
||||
|
||||
"end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="],
|
||||
|
||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"env-editor": ["env-editor@0.4.2", "", {}, "sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA=="],
|
||||
|
||||
"eol": ["eol@0.9.1", "", {}, "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg=="],
|
||||
@ -1382,6 +1404,8 @@
|
||||
|
||||
"md5-file": ["md5-file@3.2.3", "", { "dependencies": { "buffer-alloc": "^1.1.0" }, "bin": { "md5-file": "cli.js" } }, "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw=="],
|
||||
|
||||
"mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="],
|
||||
|
||||
"memoize-one": ["memoize-one@5.2.1", "", {}, "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="],
|
||||
|
||||
"merge": ["merge@2.1.1", "", {}, "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w=="],
|
||||
@ -1484,6 +1508,8 @@
|
||||
|
||||
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
|
||||
|
||||
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
||||
|
||||
"nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="],
|
||||
|
||||
"ob1": ["ob1@0.81.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ=="],
|
||||
@ -1656,6 +1682,8 @@
|
||||
|
||||
"react-native-screens": ["react-native-screens@4.6.0", "", { "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-PqGtR/moJLiTMSavhfo5spKXNHZrlxffq3g5UUVPmyuu7MmazFlPvYqiAYnR2iB9tkJYgvZO6sbjYAE7619M0A=="],
|
||||
|
||||
"react-native-svg": ["react-native-svg@15.11.1", "", { "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-Qmwx/yJKt+AHUr4zjxx/Q69qwKtRfr1+uIfFMQoq3WFRhqU76aL9db1DyvPiY632DAsVGba1pHf92OZPkpjrdQ=="],
|
||||
|
||||
"react-native-web": ["react-native-web@0.19.13", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^6.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", "react-dom": "^18.0.0" } }, "sha512-etv3bN8rJglrRCp/uL4p7l8QvUNUC++QwDbdZ8CB7BvZiMvsxfFIRM1j04vxNldG3uo2puRd6OSWR3ibtmc29A=="],
|
||||
|
||||
"react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
|
||||
@ -2134,6 +2162,8 @@
|
||||
|
||||
"cpy/p-map": ["p-map@7.0.3", "", {}, "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA=="],
|
||||
|
||||
"css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"default-gateway/execa": ["execa@1.0.0", "", { "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" } }, "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA=="],
|
||||
|
||||
"del/globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="],
|
||||
|
@ -14,6 +14,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/html-elements": "^0.11.2",
|
||||
"@material-symbols/svg-400": "^0.28.1",
|
||||
"@tanstack/react-query": "^5.66.0",
|
||||
"caniuse-api": "^3.0.0",
|
||||
"expo": "~52.0.28",
|
||||
@ -28,6 +29,7 @@
|
||||
"react-native-reanimated": "~3.16.7",
|
||||
"react-native-safe-area-context": "5.1.0",
|
||||
"react-native-screens": "4.6.0",
|
||||
"react-native-svg": "^15.11.1",
|
||||
"react-native-web": "^0.19.13",
|
||||
"yoshiki": "1.2.14",
|
||||
"zod": "^3.24.1"
|
||||
|
@ -20,25 +20,25 @@
|
||||
|
||||
export { Header, Main, Nav, Footer, UL } from "@expo/html-elements";
|
||||
export * from "./text";
|
||||
export * from "./themes";
|
||||
export * from "./theme";
|
||||
export * from "./icons";
|
||||
export * from "./links";
|
||||
export * from "./avatar";
|
||||
export * from "./image";
|
||||
export * from "./skeleton";
|
||||
export * from "./tooltip";
|
||||
export * from "./container";
|
||||
export * from "./divider";
|
||||
export * from "./progress";
|
||||
export * from "./slider";
|
||||
export * from "./snackbar";
|
||||
export * from "./alert";
|
||||
export * from "./menu";
|
||||
export * from "./popup";
|
||||
export * from "./select";
|
||||
export * from "./input";
|
||||
// export * from "./avatar";
|
||||
// export * from "./image";
|
||||
// export * from "./skeleton";
|
||||
// export * from "./tooltip";
|
||||
// export * from "./container";
|
||||
// export * from "./divider";
|
||||
// export * from "./progress";
|
||||
// export * from "./slider";
|
||||
// export * from "./snackbar";
|
||||
// export * from "./alert";
|
||||
// export * from "./menu";
|
||||
// export * from "./popup";
|
||||
// export * from "./select";
|
||||
// export * from "./input";
|
||||
export * from "./button";
|
||||
export * from "./chip";
|
||||
// export * from "./chip";
|
||||
|
||||
export * from "./utils";
|
||||
export * from "./constants";
|
||||
|
@ -28,10 +28,10 @@ import {
|
||||
type TextProps,
|
||||
type View,
|
||||
} from "react-native";
|
||||
import { TextLink, useLink } from "solito/link";
|
||||
import { parseNextPath } from "solito/router";
|
||||
// import { TextLink, useLink } from "solito/link";
|
||||
// import { parseNextPath } from "solito/router";
|
||||
import { useTheme, useYoshiki } from "yoshiki/native";
|
||||
import { alpha } from "./themes";
|
||||
import { alpha } from "./theme";
|
||||
|
||||
export const A = ({
|
||||
href,
|
||||
|
@ -1 +1,2 @@
|
||||
export * from "./theme";
|
||||
export * from "./catppuccin";
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export * from "./theme";
|
||||
export * from "./catppuccin";
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { useWindowDimensions } from "react-native";
|
||||
import { type Breakpoints as YoshikiBreakpoint, breakpoints, isBreakpoints } from "yoshiki/native";
|
||||
|
||||
type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
|
||||
export type Breakpoint<T> = T | AtLeastOne<YoshikiBreakpoint<T>>;
|
||||
|
||||
// copied from yoshiki.
|
||||
const useBreakpoint = () => {
|
||||
const { width } = useWindowDimensions();
|
||||
const idx = Object.values(breakpoints).findIndex((x) => width <= x);
|
||||
if (idx === -1) return 0;
|
||||
return idx - 1;
|
||||
};
|
||||
|
||||
const getBreakpointValue = <T>(value: Breakpoint<T>, breakpoint: number): T => {
|
||||
if (!isBreakpoints(value)) return value;
|
||||
const bpKeys = Object.keys(breakpoints) as Array<keyof YoshikiBreakpoint<T>>;
|
||||
for (let i = breakpoint; i >= 0; i--) {
|
||||
if (bpKeys[i] in value) {
|
||||
const val = value[bpKeys[i]];
|
||||
if (val) return val;
|
||||
}
|
||||
}
|
||||
// This should never be reached.
|
||||
return undefined!;
|
||||
};
|
||||
|
||||
export const useBreakpointValue = <T>(value: Breakpoint<T>): T => {
|
||||
const breakpoint = useBreakpoint();
|
||||
return getBreakpointValue(value, breakpoint);
|
||||
};
|
||||
|
||||
export const useBreakpointMap = <T extends Record<string, unknown>>(
|
||||
value: T,
|
||||
): { [key in keyof T]: T[key] extends Breakpoint<infer V> ? V : T } => {
|
||||
const breakpoint = useBreakpoint();
|
||||
// @ts-ignore
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).map(([key, val]) => [key, getBreakpointValue(val, breakpoint)]),
|
||||
);
|
||||
};
|
@ -18,7 +18,7 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import NextHead from "next/head";
|
||||
// import NextHead from "next/head";
|
||||
|
||||
export const Head = ({
|
||||
title,
|
||||
|
@ -18,7 +18,6 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export * from "./breakpoints";
|
||||
export * from "./nojs";
|
||||
export * from "./head";
|
||||
export * from "./spacing";
|
||||
|
@ -8,9 +8,9 @@ import { removeAccounts, updateAccount } from "./account-store";
|
||||
import { useSetError } from "./error-provider";
|
||||
import { useStoreValue } from "./settings";
|
||||
|
||||
const AccountContext = createContext<{
|
||||
export const AccountContext = createContext<{
|
||||
apiUrl: string;
|
||||
authToken: Token | undefined;
|
||||
authToken: Token | null;
|
||||
selectedAccount?: Account;
|
||||
accounts: (Account & { select: () => void; remove: () => void })[];
|
||||
}>(undefined!);
|
||||
@ -23,7 +23,7 @@ export const AccountProvider = ({ children }: { children: ReactNode }) => {
|
||||
const acc = accounts.find((x) => x.selected);
|
||||
return {
|
||||
apiUrl: Platform.OS === "web" ? "/api" : acc?.apiUrl!,
|
||||
authToken: acc?.token,
|
||||
authToken: acc?.token ?? null,
|
||||
selectedAccount: acc,
|
||||
accounts: accounts.map((account) => ({
|
||||
...account,
|
||||
|
@ -3,8 +3,8 @@ import { type ReactNode, useState } from "react";
|
||||
// import { useUserTheme } from "@kyoo/models";
|
||||
import { ThemeSelector } from "~/primitives/theme";
|
||||
import { createQueryClient } from "~/query";
|
||||
import { ErrorConsumer, ErrorProvider } from "./error-provider";
|
||||
import { AccountProvider } from "./account-provider";
|
||||
import { ErrorConsumer, ErrorProvider } from "./error-provider";
|
||||
|
||||
const QueryProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [queryClient] = useState(() => createQueryClient());
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { QueryClient, useInfiniteQuery, useQuery } from "@tanstack/react-query";
|
||||
import { QueryClient, dehydrate, useInfiniteQuery, useQuery } from "@tanstack/react-query";
|
||||
import { setServerData } from "one";
|
||||
import { type ComponentType, type ReactElement, useContext } from "react";
|
||||
import type { z } from "zod";
|
||||
import { type KyooError, type Page, Paged } from "~/models";
|
||||
import { AccountContext } from "~/providers/account-provider";
|
||||
|
||||
const cleanSlash = (str: string | null, keepFirst = false) => {
|
||||
if (!str) return null;
|
||||
@ -30,7 +32,7 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(context: {
|
||||
? context.formData
|
||||
: undefined,
|
||||
headers: {
|
||||
...(context.authToken ? { Authorization: context.authToken } : {}),
|
||||
...(context.authToken ? { Authorization: `Bearer ${context.authToken}` } : {}),
|
||||
...("body" in context ? { "Content-Type": "application/json" } : {}),
|
||||
},
|
||||
signal: context.signal,
|
||||
@ -157,7 +159,7 @@ export const toQueryKey = (query: {
|
||||
};
|
||||
|
||||
export const useFetch = <Data,>(query: QueryIdentifier<Data>) => {
|
||||
const { apiUrl, authToken } = useContext(QueryContext);
|
||||
const { apiUrl, authToken } = useContext(AccountContext);
|
||||
const key = toQueryKey({ apiUrl, path: query.path, params: query.params });
|
||||
|
||||
return useQuery<Data, KyooError>({
|
||||
@ -167,7 +169,7 @@ export const useFetch = <Data,>(query: QueryIdentifier<Data>) => {
|
||||
url: key.join("/").replace("/?", "?"),
|
||||
parser: query.parser,
|
||||
signal: ctx.signal,
|
||||
authToken,
|
||||
authToken: authToken?.access_token ?? null,
|
||||
...query.options,
|
||||
}),
|
||||
placeholderData: query.placeholderData as any,
|
||||
@ -176,7 +178,7 @@ export const useFetch = <Data,>(query: QueryIdentifier<Data>) => {
|
||||
};
|
||||
|
||||
export const useInfiniteFetch = <Data, Ret>(query: QueryIdentifier<Data, Ret>) => {
|
||||
const { apiUrl, authToken } = useContext(QueryContext);
|
||||
const { apiUrl, authToken } = useContext(AccountContext);
|
||||
const key = toQueryKey({ apiUrl, path: query.path, params: query.params });
|
||||
|
||||
const ret = useInfiniteQuery<Page<Data>, KyooError>({
|
||||
@ -186,7 +188,7 @@ export const useInfiniteFetch = <Data, Ret>(query: QueryIdentifier<Data, Ret>) =
|
||||
url: (ctx.pageParam as string) ?? key.join("/").replace("/?", "?"),
|
||||
parser: Paged(query.parser),
|
||||
signal: ctx.signal,
|
||||
authToken,
|
||||
authToken: authToken?.access_token ?? null,
|
||||
...query.options,
|
||||
}),
|
||||
getNextPageParam: (page: Page<Data>) => page?.next || undefined,
|
||||
@ -204,22 +206,41 @@ export const useInfiniteFetch = <Data, Ret>(query: QueryIdentifier<Data, Ret>) =
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchQuery = async (queries: QueryIdentifier[], authToken?: string | null) => {
|
||||
export const prefetch = async (...queries: QueryIdentifier[]) => {
|
||||
const client = createQueryClient();
|
||||
const authToken = undefined;
|
||||
|
||||
await Promise.all(
|
||||
queries.map((query) => {
|
||||
const key = toQueryKey({ apiUrl: "/api", path: query.path, params: query.params });
|
||||
|
||||
if (query.infinite) {
|
||||
return client.prefetchInfiniteQuery({
|
||||
queryKey: toQueryKey(query),
|
||||
queryFn: (ctx) => queryFn(ctx, Paged(query.parser), authToken),
|
||||
queryKey: key,
|
||||
queryFn: (ctx) =>
|
||||
queryFn({
|
||||
url: key.join("/").replace("/?", "?"),
|
||||
parser: Paged(query.parser),
|
||||
signal: ctx.signal,
|
||||
authToken: authToken?.access_token ?? null,
|
||||
...query.options,
|
||||
}),
|
||||
initialPageParam: undefined,
|
||||
});
|
||||
}
|
||||
return client.prefetchQuery({
|
||||
queryKey: toQueryKey(query),
|
||||
queryFn: (ctx) => queryFn(ctx, query.parser, authToken),
|
||||
queryKey: key,
|
||||
queryFn: (ctx) =>
|
||||
queryFn({
|
||||
url: key.join("/").replace("/?", "?"),
|
||||
parser: query.parser,
|
||||
signal: ctx.signal,
|
||||
authToken: authToken?.access_token ?? null,
|
||||
...query.options,
|
||||
}),
|
||||
});
|
||||
}),
|
||||
);
|
||||
setServerData("queryState", dehydrate(client));
|
||||
return client;
|
||||
};
|
||||
|
@ -1,48 +1,48 @@
|
||||
import { Main } from "@expo/html-elements";
|
||||
import { type QueryPage, SetupStep } from "@kyoo/models";
|
||||
import { Button, Icon, Link, P, ts } from "@kyoo/primitives";
|
||||
import Register from "@material-symbols/svg-400/rounded/app_registration.svg";
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useRouter } from "solito/router";
|
||||
import { useYoshiki } from "yoshiki/native";
|
||||
import { Navbar, NavbarProfile } from "../../../packages/ui/src/navbar";
|
||||
import { KyooLongLogo } from "../../../packages/ui/src/navbar/icon";
|
||||
|
||||
export const SetupPage: QueryPage<{ step: SetupStep }> = ({ step }) => {
|
||||
const { css } = useYoshiki();
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const isValid = Object.values(SetupStep).includes(step) && step !== SetupStep.Done;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isValid) router.replace("/");
|
||||
}, [isValid, router]);
|
||||
|
||||
if (!isValid) return <P>Loading...</P>;
|
||||
|
||||
return (
|
||||
<Main {...css({ flexGrow: 1, flexShrink: 1, justifyContent: "center", alignItems: "center" })}>
|
||||
<P>{t(`errors.setup.${step}`)}</P>
|
||||
{step === SetupStep.MissingAdminAccount && (
|
||||
<Button
|
||||
as={Link}
|
||||
href={"/register"}
|
||||
text={t("login.register")}
|
||||
licon={<Icon icon={Register} {...css({ marginRight: ts(2) })} />}
|
||||
/>
|
||||
)}
|
||||
</Main>
|
||||
);
|
||||
};
|
||||
|
||||
SetupPage.getLayout = ({ page }) => {
|
||||
const { css } = useYoshiki();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar left={<KyooLongLogo {...css({ marginX: ts(2) })} />} right={<NavbarProfile />} />
|
||||
{page}
|
||||
</>
|
||||
);
|
||||
};
|
||||
// import { Main } from "@expo/html-elements";
|
||||
// import { type QueryPage, SetupStep } from "@kyoo/models";
|
||||
// import { Button, Icon, Link, P, ts } from "@kyoo/primitives";
|
||||
// import Register from "@material-symbols/svg-400/rounded/app_registration.svg";
|
||||
// import { useEffect } from "react";
|
||||
// import { useTranslation } from "react-i18next";
|
||||
// import { useRouter } from "solito/router";
|
||||
// import { useYoshiki } from "yoshiki/native";
|
||||
// import { Navbar, NavbarProfile } from "../../../packages/ui/src/navbar";
|
||||
// import { KyooLongLogo } from "../../../packages/ui/src/navbar/icon";
|
||||
//
|
||||
// export const SetupPage: QueryPage<{ step: SetupStep }> = ({ step }) => {
|
||||
// const { css } = useYoshiki();
|
||||
// const { t } = useTranslation();
|
||||
// const router = useRouter();
|
||||
// const isValid = Object.values(SetupStep).includes(step) && step !== SetupStep.Done;
|
||||
//
|
||||
// useEffect(() => {
|
||||
// if (!isValid) router.replace("/");
|
||||
// }, [isValid, router]);
|
||||
//
|
||||
// if (!isValid) return <P>Loading...</P>;
|
||||
//
|
||||
// return (
|
||||
// <Main {...css({ flexGrow: 1, flexShrink: 1, justifyContent: "center", alignItems: "center" })}>
|
||||
// <P>{t(`errors.setup.${step}`)}</P>
|
||||
// {step === SetupStep.MissingAdminAccount && (
|
||||
// <Button
|
||||
// as={Link}
|
||||
// href={"/register"}
|
||||
// text={t("login.register")}
|
||||
// licon={<Icon icon={Register} {...css({ marginRight: ts(2) })} />}
|
||||
// />
|
||||
// )}
|
||||
// </Main>
|
||||
// );
|
||||
// };
|
||||
//
|
||||
// SetupPage.getLayout = ({ page }) => {
|
||||
// const { css } = useYoshiki();
|
||||
//
|
||||
// return (
|
||||
// <>
|
||||
// <Navbar left={<KyooLongLogo {...css({ marginX: ts(2) })} />} right={<NavbarProfile />} />
|
||||
// {page}
|
||||
// </>
|
||||
// );
|
||||
// };
|
||||
|
Loading…
x
Reference in New Issue
Block a user