style: setup prettier & husky (#23)

This commit is contained in:
BoYanZh
2022-11-29 12:42:07 +08:00
committed by GitHub
parent 1e6d489acb
commit 436ab40334
121 changed files with 10603 additions and 3066 deletions

View File

@@ -3,8 +3,7 @@ name: release
on:
push:
tags:
- '*'
- "*"
jobs:
changelog:

1
.husky/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
_

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged

5
.prettierignore Normal file
View File

@@ -0,0 +1,5 @@
dist/
solid-router/
pnpm-lock.yaml
.husky
.prettierignore

View File

@@ -27,7 +27,8 @@
"start": "vite",
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
"serve": "vite preview",
"prepare": "husky install"
},
"license": "MIT",
"devDependencies": {
@@ -35,6 +36,9 @@
"@types/node": "^18.7.5",
"@types/streamsaver": "^2.0.1",
"@vitejs/plugin-legacy": "^2.0.1",
"husky": "^8.0.2",
"lint-staged": "^13.0.4",
"prettier": "2.8.0",
"terser": "^5.14.2",
"typescript": "^4.7.4",
"vite": "^3.0.8",
@@ -65,5 +69,8 @@
"solid-markdown": "^1.2.0",
"solid-transition-group": "^0.0.12",
"streamsaver": "^2.0.6"
},
"lint-staged": {
"**/*": "prettier --write"
}
}

1188
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,12 +13,12 @@
// This will prevent the sw from restarting
let keepAlive = () => {
keepAlive = () => {}
var ping = location.href.substr(0, location.href.lastIndexOf('/')) + '/ping'
var ping = location.href.substr(0, location.href.lastIndexOf("/")) + "/ping"
var interval = setInterval(() => {
if (sw) {
sw.postMessage('ping')
sw.postMessage("ping")
} else {
fetch(ping).then(res => res.text(!res.ok && clearInterval(interval)))
fetch(ping).then((res) => res.text(!res.ok && clearInterval(interval)))
}
}, 10000)
}
@@ -29,28 +29,39 @@
// but since we need to wait for the Service Worker registration, we store the
// message for later
let messages = []
window.onmessage = evt => messages.push(evt)
window.onmessage = (evt) => messages.push(evt)
let sw = null
let scope = ''
let scope = ""
function registerWorker() {
return navigator.serviceWorker.getRegistration('./').then(swReg => {
return swReg || navigator.serviceWorker.register('sw.js', { scope: './' })
}).then(swReg => {
return navigator.serviceWorker
.getRegistration("./")
.then((swReg) => {
return (
swReg || navigator.serviceWorker.register("sw.js", { scope: "./" })
)
})
.then((swReg) => {
const swRegTmp = swReg.installing || swReg.waiting
scope = swReg.scope
return (sw = swReg.active) || new Promise(resolve => {
swRegTmp.addEventListener('statechange', fn = () => {
if (swRegTmp.state === 'activated') {
swRegTmp.removeEventListener('statechange', fn)
return (
(sw = swReg.active) ||
new Promise((resolve) => {
swRegTmp.addEventListener(
"statechange",
(fn = () => {
if (swRegTmp.state === "activated") {
swRegTmp.removeEventListener("statechange", fn)
sw = swReg.active
resolve()
}
})
)
})
)
})
}
@@ -64,7 +75,7 @@
throw new TypeError("[StreamSaver] You didn't send a messageChannel")
}
if (typeof data !== 'object') {
if (typeof data !== "object") {
throw new TypeError("[StreamSaver] You didn't send a object")
}
@@ -77,15 +88,19 @@
data.referrer = data.referrer || document.referrer || origin
// pass along version for possible backwards compatibility in sw.js
data.streamSaverVersion = new URLSearchParams(location.search).get('version')
data.streamSaverVersion = new URLSearchParams(location.search).get(
"version"
)
if (data.streamSaverVersion === '1.2.0') {
console.warn('[StreamSaver] please update streamsaver')
if (data.streamSaverVersion === "1.2.0") {
console.warn("[StreamSaver] please update streamsaver")
}
/** @since v2.0.0 */
if (!data.headers) {
console.warn("[StreamSaver] pass `data.headers` that you would like to pass along to the service worker\nit should be a 2D array or a key/val object that fetch's Headers api accepts")
console.warn(
"[StreamSaver] pass `data.headers` that you would like to pass along to the service worker\nit should be a 2D array or a key/val object that fetch's Headers api accepts"
)
} else {
// test if it's correct
// should thorw a typeError if not
@@ -93,39 +108,47 @@
}
/** @since v2.0.0 */
if (typeof data.filename === 'string') {
console.warn("[StreamSaver] You shouldn't send `data.filename` anymore. It should be included in the Content-Disposition header option")
if (typeof data.filename === "string") {
console.warn(
"[StreamSaver] You shouldn't send `data.filename` anymore. It should be included in the Content-Disposition header option"
)
// Do what File constructor do with fileNames
data.filename = data.filename.replace(/\//g, ':')
data.filename = data.filename.replace(/\//g, ":")
}
/** @since v2.0.0 */
if (data.size) {
console.warn("[StreamSaver] You shouldn't send `data.size` anymore. It should be included in the content-length header option")
console.warn(
"[StreamSaver] You shouldn't send `data.size` anymore. It should be included in the content-length header option"
)
}
/** @since v2.0.0 */
if (data.readableStream) {
console.warn("[StreamSaver] You should send the readableStream in the messageChannel, not through mitm")
console.warn(
"[StreamSaver] You should send the readableStream in the messageChannel, not through mitm"
)
}
/** @since v2.0.0 */
if (!data.pathname) {
console.warn("[StreamSaver] Please send `data.pathname` (eg: /pictures/summer.jpg)")
data.pathname = Math.random().toString().slice(-6) + '/' + data.filename
console.warn(
"[StreamSaver] Please send `data.pathname` (eg: /pictures/summer.jpg)"
)
data.pathname = Math.random().toString().slice(-6) + "/" + data.filename
}
// remove all leading slashes
data.pathname = data.pathname.replace(/^\/+/g, '')
data.pathname = data.pathname.replace(/^\/+/g, "")
// remove protocol
let org = origin.replace(/(^\w+:|^)\/\//, '')
let org = origin.replace(/(^\w+:|^)\/\//, "")
// set the absolute pathname to the download url.
data.url = new URL(`${scope + org}/${data.pathname}`).toString()
if (!data.url.startsWith(`${scope + org}/`)) {
throw new TypeError('[StreamSaver] bad `data.pathname`')
throw new TypeError("[StreamSaver] bad `data.pathname`")
}
// This sends the message data as well as transferring
@@ -147,7 +170,7 @@
if (window.opener) {
// The opener can't listen to onload event, so we need to help em out!
// (telling them that we are ready to accept postMessage's)
window.opener.postMessage('StreamSaver::loadedPopup', '*')
window.opener.postMessage("StreamSaver::loadedPopup", "*")
}
if (navigator.serviceWorker) {
@@ -160,5 +183,4 @@
// shouldn't really be possible?
keepAlive()
}
</script>

View File

@@ -1,10 +1,10 @@
/* global self ReadableStream Response */
self.addEventListener('install', () => {
self.addEventListener("install", () => {
self.skipWaiting()
})
self.addEventListener('activate', event => {
self.addEventListener("activate", (event) => {
event.waitUntil(self.clients.claim())
})
@@ -12,15 +12,20 @@ const map = new Map()
// This should be called once per download
// Each event has a dataChannel that the data will be piped through
self.onmessage = event => {
self.onmessage = (event) => {
// We send a heartbeat every x second to keep the
// service worker alive if a transferable stream is not sent
if (event.data === 'ping') {
if (event.data === "ping") {
return
}
const data = event.data
const downloadUrl = data.url || self.registration.scope + Math.random() + '/' + (typeof data === 'string' ? data : data.filename)
const downloadUrl =
data.url ||
self.registration.scope +
Math.random() +
"/" +
(typeof data === "string" ? data : data.filename)
const port = event.ports[0]
const metadata = new Array(3) // [stream, data, port]
@@ -33,7 +38,7 @@ self.onmessage = event => {
if (event.data.readableStream) {
metadata[0] = event.data.readableStream
} else if (event.data.transferringReadable) {
port.onmessage = evt => {
port.onmessage = (evt) => {
port.onmessage = null
metadata[0] = evt.data.readableStream
}
@@ -51,12 +56,12 @@ function createStream (port) {
start(controller) {
// When we receive data on the messageChannel, we write
port.onmessage = ({ data }) => {
if (data === 'end') {
if (data === "end") {
return controller.close()
}
if (data === 'abort') {
controller.error('Aborted the download')
if (data === "abort") {
controller.error("Aborted the download")
return
}
@@ -64,17 +69,17 @@ function createStream (port) {
}
},
cancel() {
console.log('user aborted')
}
console.log("user aborted")
},
})
}
self.onfetch = event => {
self.onfetch = (event) => {
const url = event.request.url
// this only works for Firefox
if (url.endsWith('/ping')) {
return event.respondWith(new Response('pong'))
if (url.endsWith("/ping")) {
return event.respondWith(new Response("pong"))
}
const hijacke = map.get(url)
@@ -88,41 +93,49 @@ self.onfetch = event => {
// Not comfortable letting any user control all headers
// so we only copy over the length & disposition
const responseHeaders = new Headers({
'Content-Type': 'application/octet-stream; charset=utf-8',
"Content-Type": "application/octet-stream; charset=utf-8",
// To be on the safe side, The link can be opened in a iframe.
// but octet-stream should stop it.
'Content-Security-Policy': "default-src 'none'",
'X-Content-Security-Policy': "default-src 'none'",
'X-WebKit-CSP': "default-src 'none'",
'X-XSS-Protection': '1; mode=block'
"Content-Security-Policy": "default-src 'none'",
"X-Content-Security-Policy": "default-src 'none'",
"X-WebKit-CSP": "default-src 'none'",
"X-XSS-Protection": "1; mode=block",
})
let headers = new Headers(data.headers || {})
if (headers.has('Content-Length')) {
responseHeaders.set('Content-Length', headers.get('Content-Length'))
if (headers.has("Content-Length")) {
responseHeaders.set("Content-Length", headers.get("Content-Length"))
}
if (headers.has('Content-Disposition')) {
responseHeaders.set('Content-Disposition', headers.get('Content-Disposition'))
if (headers.has("Content-Disposition")) {
responseHeaders.set(
"Content-Disposition",
headers.get("Content-Disposition")
)
}
// data, data.filename and size should not be used anymore
if (data.size) {
console.warn('Depricated')
responseHeaders.set('Content-Length', data.size)
console.warn("Depricated")
responseHeaders.set("Content-Length", data.size)
}
let fileName = typeof data === 'string' ? data : data.filename
let fileName = typeof data === "string" ? data : data.filename
if (fileName) {
console.warn('Depricated')
console.warn("Depricated")
// Make filename RFC5987 compatible
fileName = encodeURIComponent(fileName).replace(/['()]/g, escape).replace(/\*/g, '%2A')
responseHeaders.set('Content-Disposition', "attachment; filename*=UTF-8''" + fileName)
fileName = encodeURIComponent(fileName)
.replace(/['()]/g, escape)
.replace(/\*/g, "%2A")
responseHeaders.set(
"Content-Disposition",
"attachment; filename*=UTF-8''" + fileName
)
}
event.respondWith(new Response(stream, { headers: responseHeaders }))
port.postMessage({ debug: 'Download started' })
port.postMessage({ debug: "Download started" })
}

View File

@@ -1,6 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
"extends": ["config:base"]
}

View File

@@ -1,11 +1,11 @@
import fs from "fs";
import path from "path";
import fs from "fs"
import path from "path"
const root = "./src/lang";
const entry = "entry.ts";
const langs = fs.readdirSync(root);
const root = "./src/lang"
const entry = "entry.ts"
const langs = fs.readdirSync(root)
langs
.filter((lang) => lang !== "en")
.forEach((lang) => {
fs.copyFileSync(path.join(root, "en", entry), path.join(root, lang, entry));
});
fs.copyFileSync(path.join(root, "en", entry), path.join(root, lang, entry))
})

View File

@@ -1,5 +1,5 @@
import { Progress, ProgressIndicator } from "@hope-ui/solid";
import { Route, Routes, useIsRouting } from "@solidjs/router";
import { Progress, ProgressIndicator } from "@hope-ui/solid"
import { Route, Routes, useIsRouting } from "@solidjs/router"
import {
Component,
createSignal,
@@ -7,54 +7,54 @@ import {
Match,
onCleanup,
Switch,
} from "solid-js";
import { Portal } from "solid-js/web";
import { useLoading, useRouter } from "~/hooks";
import { globalStyles } from "./theme";
import { bus, r, handleRespWithoutAuthAndNotify, base_path } from "~/utils";
import { setSettings } from "~/store";
import { Error, FullScreenLoading } from "~/components";
import { MustUser } from "./MustUser";
import "./index.css";
import { useI18n } from "@solid-primitives/i18n";
import { initialLang, langMap, loadedLangs } from "./i18n";
import { Resp } from "~/types";
} from "solid-js"
import { Portal } from "solid-js/web"
import { useLoading, useRouter } from "~/hooks"
import { globalStyles } from "./theme"
import { bus, r, handleRespWithoutAuthAndNotify, base_path } from "~/utils"
import { setSettings } from "~/store"
import { Error, FullScreenLoading } from "~/components"
import { MustUser } from "./MustUser"
import "./index.css"
import { useI18n } from "@solid-primitives/i18n"
import { initialLang, langMap, loadedLangs } from "./i18n"
import { Resp } from "~/types"
const Home = lazy(() => import("~/pages/home/Layout"));
const Manage = lazy(() => import("~/pages/manage"));
const Login = lazy(() => import("~/pages/login"));
const Test = lazy(() => import("~/pages/test"));
const Home = lazy(() => import("~/pages/home/Layout"))
const Manage = lazy(() => import("~/pages/manage"))
const Login = lazy(() => import("~/pages/login"))
const Test = lazy(() => import("~/pages/test"))
const App: Component = () => {
globalStyles();
const [, { add }] = useI18n();
const isRouting = useIsRouting();
const { to } = useRouter();
globalStyles()
const [, { add }] = useI18n()
const isRouting = useIsRouting()
const { to } = useRouter()
const onTo = (path: string) => {
to(path);
};
bus.on("to", onTo);
to(path)
}
bus.on("to", onTo)
onCleanup(() => {
bus.off("to", onTo);
});
bus.off("to", onTo)
})
const [err, setErr] = createSignal<string>();
const [err, setErr] = createSignal<string>()
const [loading, data] = useLoading(() =>
Promise.all([
(async () => {
add(initialLang, (await langMap[initialLang]()).default);
loadedLangs.add(initialLang);
add(initialLang, (await langMap[initialLang]()).default)
loadedLangs.add(initialLang)
})(),
(async () => {
handleRespWithoutAuthAndNotify(
(await r.get("/public/settings")) as Resp<Record<string, string>>,
setSettings,
setErr
);
)
})(),
])
);
data();
)
data()
return (
<>
<Portal>
@@ -103,7 +103,7 @@ const App: Component = () => {
</Match>
</Switch>
</>
);
};
)
}
export default App;
export default App

View File

@@ -1,22 +1,22 @@
import { createI18nContext } from "@solid-primitives/i18n";
import { createSignal } from "solid-js";
import { createI18nContext } from "@solid-primitives/i18n"
import { createSignal } from "solid-js"
interface Language {
code: string;
lang: string;
code: string
lang: string
}
const langs = import.meta.glob("~/lang/*/index.json", {
eager: true,
import: "lang",
});
const languages: Language[] = [];
})
const languages: Language[] = []
for (const path in langs) {
const name = path.split("/")[3];
const name = path.split("/")[3]
languages.push({
code: name,
lang: langs[path] as string,
});
})
}
const defaultLang =
languages.find(
@@ -27,25 +27,25 @@ const defaultLang =
lang.code.toLowerCase().split("_")[0] ===
navigator.language.toLowerCase().split("_")[0]
)?.code ||
"en";
"en"
export let initialLang = localStorage.getItem("lang") ?? "";
export let initialLang = localStorage.getItem("lang") ?? ""
if (!initialLang || !languages.find((lang) => lang.code === initialLang)) {
initialLang = defaultLang;
initialLang = defaultLang
}
// store lang and import
export const langMap: Record<string, any> = {};
const imports = import.meta.glob("~/lang/*/entry.ts");
export const langMap: Record<string, any> = {}
const imports = import.meta.glob("~/lang/*/entry.ts")
for (const path in imports) {
const name = path.split("/")[3];
langMap[name] = imports[path];
const name = path.split("/")[3]
langMap[name] = imports[path]
}
export const loadedLangs = new Set<string>();
export const loadedLangs = new Set<string>()
const i18n = createI18nContext({}, initialLang);
const i18n = createI18nContext({}, initialLang)
const [currentLang, setLang] = createSignal(initialLang);
const [currentLang, setLang] = createSignal(initialLang)
export { languages, i18n, currentLang, setLang };
export { languages, i18n, currentLang, setLang }

View File

@@ -26,7 +26,6 @@
background-color: rgba(0, 0, 0, 0.38);
}
/* dark */
.hope-ui-dark ::-webkit-scrollbar-corner,

View File

@@ -1,19 +1,19 @@
import { HopeProvider, NotificationsProvider } from "@hope-ui/solid";
import { I18nContext } from "@solid-primitives/i18n";
import { ErrorBoundary, Suspense } from "solid-js";
import { Error, FullScreenLoading } from "~/components";
import App from "./App";
import { i18n } from "./i18n";
import { globalStyles, theme } from "./theme";
import { HopeProvider, NotificationsProvider } from "@hope-ui/solid"
import { I18nContext } from "@solid-primitives/i18n"
import { ErrorBoundary, Suspense } from "solid-js"
import { Error, FullScreenLoading } from "~/components"
import App from "./App"
import { i18n } from "./i18n"
import { globalStyles, theme } from "./theme"
const Index = () => {
globalStyles();
globalStyles()
return (
<HopeProvider config={theme}>
<ErrorBoundary
fallback={(err) => {
console.error("error", err);
return <Error msg={`System error: ${err}`} h="100vh" />;
console.error("error", err)
return <Error msg={`System error: ${err}`} h="100vh" />
}}
>
<I18nContext.Provider value={i18n}>
@@ -25,7 +25,7 @@ const Index = () => {
</I18nContext.Provider>
</ErrorBoundary>
</HopeProvider>
);
};
)
}
export { Index };
export { Index }

View File

@@ -1,5 +1,5 @@
import { globalCss, HopeThemeConfig } from "@hope-ui/solid";
import { hoverColor } from "~/utils";
import { globalCss, HopeThemeConfig } from "@hope-ui/solid"
import { hoverColor } from "~/utils"
const theme: HopeThemeConfig = {
initialColorMode: "system",
@@ -157,7 +157,7 @@ const theme: HopeThemeConfig = {
},
},
},
};
}
export const globalStyles = globalCss({
"*": {
@@ -176,6 +176,6 @@ export const globalStyles = globalCss({
flexWrap: "wrap",
rowGap: "0 !important",
},
});
})
export { theme };
export { theme }

View File

@@ -1,6 +1,6 @@
import { Center, ElementType, Spinner, SpinnerProps } from "@hope-ui/solid";
import { JSXElement, mergeProps, Show } from "solid-js";
import { getMainColor } from "~/store";
import { Center, ElementType, Spinner, SpinnerProps } from "@hope-ui/solid"
import { JSXElement, mergeProps, Show } from "solid-js"
import { getMainColor } from "~/store"
export const FullScreenLoading = () => {
return (
<Center h="100vh">
@@ -12,14 +12,14 @@ export const FullScreenLoading = () => {
size="xl"
/>
</Center>
);
};
)
}
export const FullLoading = (props: {
py?: string;
size?: string;
thickness?: number;
ref?: any;
py?: string
size?: string
thickness?: number
ref?: any
}) => {
const merged = mergeProps(
{
@@ -28,7 +28,7 @@ export const FullLoading = (props: {
thickness: 4,
},
props
);
)
return (
<Center ref={props.ref} h="$full" w="$full" py={merged.py}>
<Spinner
@@ -39,19 +39,19 @@ export const FullLoading = (props: {
size={merged.size as any}
/>
</Center>
);
};
)
}
export const MaybeLoading = (props: {
children?: JSXElement;
loading: boolean;
children?: JSXElement
loading: boolean
}) => {
return (
<Show when={!props.loading} fallback={<FullLoading />}>
{props.children}
</Show>
);
};
)
}
export const CenterLoading = <C extends ElementType = "div">(
props: SpinnerProps<C>
@@ -60,5 +60,5 @@ export const CenterLoading = <C extends ElementType = "div">(
<Center w="$full" h="$full">
<Spinner color={getMainColor()} {...props} />
</Center>
);
};
)
}

View File

@@ -1,4 +1,4 @@
const Hello = () => {
return <h1>Hello, Solidjs</h1>
}
export default Hello;
export default Hello

View File

@@ -1,20 +1,20 @@
import { ElementType, Image, ImageProps } from "@hope-ui/solid";
import { createSignal, JSXElement, Show } from "solid-js";
import { ElementType, Image, ImageProps } from "@hope-ui/solid"
import { createSignal, JSXElement, Show } from "solid-js"
export const ImageWithError = <C extends ElementType = "img">(
props: ImageProps<C> & {
fallbackErr?: JSXElement;
fallbackErr?: JSXElement
}
) => {
const [err, setErr] = createSignal(false);
const [err, setErr] = createSignal(false)
return (
<Show when={!err()} fallback={props.fallbackErr}>
<Image
{...props}
onError={() => {
setErr(true);
setErr(true)
}}
/>
</Show>
);
};
)
}

View File

@@ -1,15 +1,15 @@
import { Link, LinkProps } from "@solidjs/router";
import { Anchor, AnchorProps, ElementType } from "@hope-ui/solid";
import { joinBase } from "~/utils";
import { useRouter } from "~/hooks";
import { Link, LinkProps } from "@solidjs/router"
import { Anchor, AnchorProps, ElementType } from "@hope-ui/solid"
import { joinBase } from "~/utils"
import { useRouter } from "~/hooks"
export const LinkWithBase = (props: LinkProps) => (
<Link {...props} href={joinBase(props.href)} />
);
)
export const AnchorWithBase = <C extends ElementType = "a">(
props: AnchorProps<C>
) => <Anchor {...props} href={joinBase(props.href)} />;
) => <Anchor {...props} href={joinBase(props.href)} />
export const LinkWithPush = (props: LinkProps) => {
const { pushHref } = useRouter();
return <LinkWithBase {...props} href={pushHref(props.href)} />;
};
const { pushHref } = useRouter()
return <LinkWithBase {...props} href={pushHref(props.href)} />
}

View File

@@ -1,15 +1,15 @@
// @ts-ignore
import { hljs } from "./highlight.js";
import SolidMarkdown from "solid-markdown";
import remarkGfm from "remark-gfm";
import rehypeRaw from "rehype-raw";
import "./markdown.css";
import { onMount } from "solid-js";
import { hljs } from "./highlight.js"
import SolidMarkdown from "solid-markdown"
import remarkGfm from "remark-gfm"
import rehypeRaw from "rehype-raw"
import "./markdown.css"
import { onMount } from "solid-js"
export const Markdown = (props: { children?: string }) => {
onMount(() => {
hljs.highlightAll();
});
hljs.highlightAll()
})
return (
<SolidMarkdown
class="markdown-body"
@@ -17,5 +17,5 @@ export const Markdown = (props: { children?: string }) => {
rehypePlugins={[rehypeRaw]}
children={props.children}
/>
);
};
)
}

View File

@@ -9,31 +9,31 @@ import {
Input,
Textarea,
FormHelperText,
} from "@hope-ui/solid";
import { createSignal, Show } from "solid-js";
import { useT } from "~/hooks";
import { notify } from "~/utils";
} from "@hope-ui/solid"
import { createSignal, Show } from "solid-js"
import { useT } from "~/hooks"
import { notify } from "~/utils"
export type ModalInputProps = {
opened: boolean;
onClose: () => void;
title: string;
onSubmit?: (text: string) => void;
type?: string;
defaultValue?: string;
loading?: boolean;
tips?: string;
};
opened: boolean
onClose: () => void
title: string
onSubmit?: (text: string) => void
type?: string
defaultValue?: string
loading?: boolean
tips?: string
}
export const ModalInput = (props: ModalInputProps) => {
const [value, setValue] = createSignal(props.defaultValue ?? "");
const t = useT();
const [value, setValue] = createSignal(props.defaultValue ?? "")
const t = useT()
const submit = () => {
if (!value()) {
notify.warning(t("global.empty_input"));
return;
notify.warning(t("global.empty_input"))
return
}
props.onSubmit?.(value())
setValue("")
}
props.onSubmit?.(value());
setValue("");
};
return (
<Modal
blockScrollOnMount={false}
@@ -54,11 +54,11 @@ export const ModalInput = (props: ModalInputProps) => {
type={props.type}
value={value()}
onInput={(e) => {
setValue(e.currentTarget.value);
setValue(e.currentTarget.value)
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
submit();
submit()
}
}}
/>
@@ -68,7 +68,7 @@ export const ModalInput = (props: ModalInputProps) => {
id="modal-input"
value={value()}
onInput={(e) => {
setValue(e.currentTarget.value);
setValue(e.currentTarget.value)
}}
/>
</Show>
@@ -86,5 +86,5 @@ export const ModalInput = (props: ModalInputProps) => {
</ModalFooter>
</ModalContent>
</Modal>
);
};
)
}

View File

@@ -1,62 +1,62 @@
import { Box } from "@hope-ui/solid";
import { createEffect, createSignal, onCleanup, onMount } from "solid-js";
import { MaybeLoading } from "./FullLoading";
import loader from "@monaco-editor/loader";
import { monaco_cdn } from "~/utils";
import { Box } from "@hope-ui/solid"
import { createEffect, createSignal, onCleanup, onMount } from "solid-js"
import { MaybeLoading } from "./FullLoading"
import loader from "@monaco-editor/loader"
import { monaco_cdn } from "~/utils"
loader.config({
paths: {
vs: monaco_cdn,
},
});
})
export interface MonacoEditorProps {
value: string;
onChange?: (value: string) => void;
theme: "vs" | "vs-dark";
path?: string;
language?: string;
value: string
onChange?: (value: string) => void
theme: "vs" | "vs-dark"
path?: string
language?: string
}
let monaco: any;
let monaco: any
export const MonacoEditorLoader = (props: MonacoEditorProps) => {
const [loading, setLoading] = createSignal(true);
const [loading, setLoading] = createSignal(true)
loader.init().then((m) => {
monaco = m;
setLoading(false);
});
monaco = m
setLoading(false)
})
return (
<MaybeLoading loading={loading()}>
<MonacoEditor {...props} />
</MaybeLoading>
);
};
)
}
export const MonacoEditor = (props: MonacoEditorProps) => {
let monacoEditorDiv: HTMLDivElement;
let monacoEditor: any /*monaco.editor.IStandaloneCodeEditor*/;
let model: any /*monaco.editor.ITextModel*/;
let monacoEditorDiv: HTMLDivElement
let monacoEditor: any /*monaco.editor.IStandaloneCodeEditor*/
let model: any /*monaco.editor.ITextModel*/
onMount(() => {
monacoEditor = monaco.editor.create(monacoEditorDiv!, {
value: props.value,
theme: props.theme,
});
})
model = monaco.editor.createModel(
props.value,
props.language,
props.path ? monaco.Uri.parse(props.path) : undefined
);
monacoEditor.setModel(model);
)
monacoEditor.setModel(model)
monacoEditor.onDidChangeModelContent(() => {
props.onChange?.(monacoEditor.getValue());
});
});
props.onChange?.(monacoEditor.getValue())
})
})
createEffect(() => {
monaco.editor.setTheme(props.theme);
});
monaco.editor.setTheme(props.theme)
})
onCleanup(() => {
model && model.dispose();
monacoEditor && monacoEditor.dispose();
});
return <Box w="$full" h="70vh" ref={monacoEditorDiv!} />;
};
model && model.dispose()
monacoEditor && monacoEditor.dispose()
})
return <Box w="$full" h="70vh" ref={monacoEditorDiv!} />
}

View File

@@ -1,7 +1,7 @@
import { Button, HStack, IconButton } from "@hope-ui/solid";
import { createMemo, For, mergeProps, Show } from "solid-js";
import { createStore } from "solid-js/store";
import { FaSolidAngleLeft, FaSolidAngleRight } from "solid-icons/fa";
import { Button, HStack, IconButton } from "@hope-ui/solid"
import { createMemo, For, mergeProps, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { FaSolidAngleLeft, FaSolidAngleRight } from "solid-icons/fa"
export interface PaginatorProps {
colorScheme?:
@@ -11,14 +11,14 @@ export interface PaginatorProps {
| "success"
| "info"
| "warning"
| "danger";
| "danger"
// size?: "xs" | "sm" | "lg" | "xl" | "md";
defaultCurrent?: number;
onChange?: (current: number) => void;
hideOnSinglePage?: boolean;
total: number;
defaultPageSize?: number;
maxShowPage?: number;
defaultCurrent?: number
onChange?: (current: number) => void
hideOnSinglePage?: boolean
total: number
defaultPageSize?: number
maxShowPage?: number
}
export const Paginator = (props: PaginatorProps) => {
const merged = mergeProps(
@@ -29,35 +29,35 @@ export const Paginator = (props: PaginatorProps) => {
hideOnSinglePage: true,
},
props
);
)
const [store, setStore] = createStore({
pageSize: merged.defaultPageSize,
current: merged.defaultCurrent,
});
})
const pages = createMemo(() => {
return Math.ceil(merged.total / store.pageSize);
});
return Math.ceil(merged.total / store.pageSize)
})
const leftPages = createMemo(() => {
const current = store.current;
const min = Math.max(2, current - Math.floor(merged.maxShowPage / 2));
return Array.from({ length: current - min }, (_, i) => min + i);
});
const current = store.current
const min = Math.max(2, current - Math.floor(merged.maxShowPage / 2))
return Array.from({ length: current - min }, (_, i) => min + i)
})
const rightPages = createMemo(() => {
const current = store.current;
const current = store.current
const max = Math.min(
pages() - 1,
current + Math.floor(merged.maxShowPage / 2)
);
return Array.from({ length: max - current }, (_, i) => current + 1 + i);
});
)
return Array.from({ length: max - current }, (_, i) => current + 1 + i)
})
const size = {
"@initial": "sm",
"@md": "md",
} as const;
} as const
const onPageChange = (page: number) => {
setStore("current", page);
merged.onChange?.(page);
};
setStore("current", page)
merged.onChange?.(page)
}
return (
<Show when={!merged.hideOnSinglePage || pages() > 1}>
<HStack spacing="$1">
@@ -66,7 +66,7 @@ export const Paginator = (props: PaginatorProps) => {
size={size}
colorScheme={merged.colorScheme}
onClick={() => {
onPageChange(1);
onPageChange(1)
}}
px="$3"
>
@@ -78,7 +78,7 @@ export const Paginator = (props: PaginatorProps) => {
aria-label="Previous"
colorScheme={merged.colorScheme}
onClick={() => {
onPageChange(store.current - 1);
onPageChange(store.current - 1)
}}
w="2rem !important"
/>
@@ -89,7 +89,7 @@ export const Paginator = (props: PaginatorProps) => {
size={size}
colorScheme={merged.colorScheme}
onClick={() => {
onPageChange(page);
onPageChange(page)
}}
px={page > 10 ? "$2_5" : "$3"}
>
@@ -111,7 +111,7 @@ export const Paginator = (props: PaginatorProps) => {
size={size}
colorScheme={merged.colorScheme}
onClick={() => {
onPageChange(page);
onPageChange(page)
}}
px={page > 10 ? "$2_5" : "$3"}
>
@@ -126,7 +126,7 @@ export const Paginator = (props: PaginatorProps) => {
aria-label="Next"
colorScheme={merged.colorScheme}
onClick={() => {
onPageChange(store.current + 1);
onPageChange(store.current + 1)
}}
w="2rem !important"
/>
@@ -134,7 +134,7 @@ export const Paginator = (props: PaginatorProps) => {
size={size}
colorScheme={merged.colorScheme}
onClick={() => {
onPageChange(pages());
onPageChange(pages())
}}
px={pages() > 10 ? "$2_5" : "$3"}
>
@@ -143,5 +143,5 @@ export const Paginator = (props: PaginatorProps) => {
</Show>
</HStack>
</Show>
);
};
)
}

View File

@@ -1,10 +1,10 @@
import { Icon, useColorMode, useColorModeValue } from "@hope-ui/solid";
import { Icon, useColorMode, useColorModeValue } from "@hope-ui/solid"
// import { IoMoonOutline as Moon } from "solid-icons/io";
import { FiSun as Sun } from "solid-icons/fi";
import { FiMoon as Moon } from "solid-icons/fi";
import { FiSun as Sun } from "solid-icons/fi"
import { FiMoon as Moon } from "solid-icons/fi"
const SwitchColorMode = () => {
const { toggleColorMode } = useColorMode();
const { toggleColorMode } = useColorMode()
const icon = useColorModeValue(
{
size: "$8",
@@ -16,7 +16,7 @@ const SwitchColorMode = () => {
component: Sun,
p: "$0_5",
}
);
)
return (
<Icon
cursor="pointer"
@@ -25,6 +25,6 @@ const SwitchColorMode = () => {
onClick={toggleColorMode}
p={icon().p}
/>
);
};
export { SwitchColorMode };
)
}
export { SwitchColorMode }

View File

@@ -1,15 +1,15 @@
import { Badge } from "@hope-ui/solid";
import { useT } from "~/hooks";
import { Badge } from "@hope-ui/solid"
import { useT } from "~/hooks"
export interface WetherProps {
yes?: boolean;
yes?: boolean
}
export const Wether = (props: WetherProps) => {
const t = useT();
const t = useT()
return (
<Badge colorScheme={props.yes ? "success" : "danger"}>
{t(`global.${props.yes ? "yes" : "no"}`)}
</Badge>
);
};
)
}

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,12 @@
export * from "./FullLoading";
export * from "./SwitchColorMode";
export * from "./SwitchLanguage";
export * from "./Hello";
export * from "./FolderTree";
export * from "./Wether";
export * from "./LinkWithBase";
export * from "./ImageWithError";
export * from "./Markdown";
export * from "./ModalInput";
export * from "./Base";
export * from "./Paginator";
export * from "./FullLoading"
export * from "./SwitchColorMode"
export * from "./SwitchLanguage"
export * from "./Hello"
export * from "./FolderTree"
export * from "./Wether"
export * from "./LinkWithBase"
export * from "./ImageWithError"
export * from "./Markdown"
export * from "./ModalInput"
export * from "./Base"
export * from "./Paginator"

View File

@@ -1,8 +1,8 @@
export * from "./useFetch";
export * from "./useRouter";
export * from "./useT";
export * from "./useTitle";
export * from "./usePath";
export * from "./useLink";
export * from "./useUtil";
export * from "./useDownload";
export * from "./useFetch"
export * from "./useRouter"
export * from "./useT"
export * from "./useTitle"
export * from "./usePath"
export * from "./useLink"
export * from "./useUtil"
export * from "./useDownload"

View File

@@ -1,25 +1,25 @@
import axios from "axios";
import { local, selectedObjs } from "~/store";
import { notify } from "~/utils";
import { useSelectedLink, useLink, useT } from ".";
import axios from "axios"
import { local, selectedObjs } from "~/store"
import { notify } from "~/utils"
import { useSelectedLink, useLink, useT } from "."
export const useDownload = () => {
const { rawLinks } = useSelectedLink();
const { rawLink } = useLink();
const t = useT();
const { rawLinks } = useSelectedLink()
const { rawLink } = useLink()
const t = useT()
return {
batchDownloadSelected: () => {
const urls = rawLinks(true);
const urls = rawLinks(true)
urls.forEach((url) => {
window.open(url, "_blank");
});
window.open(url, "_blank")
})
},
sendToAria2: async () => {
const selectedFiles = selectedObjs().filter((obj) => !obj.is_dir);
const { aria2_rpc_url, aria2_rpc_secret, aria2_dir } = local;
const selectedFiles = selectedObjs().filter((obj) => !obj.is_dir)
const { aria2_rpc_url, aria2_rpc_secret, aria2_dir } = local
if (!aria2_rpc_url) {
notify.warning(t("home.toolbar.aria2_not_set"));
return;
notify.warning(t("home.toolbar.aria2_not_set"))
return
}
try {
for (const file of selectedFiles) {
@@ -36,14 +36,14 @@ export const useDownload = () => {
"check-certificate": "false",
},
],
});
console.log(resp);
})
console.log(resp)
}
notify.success(t("home.toolbar.send_aria2_success"));
notify.success(t("home.toolbar.send_aria2_success"))
} catch (e) {
console.error(e);
notify.error(`failed to send to aria2: ${e}`);
console.error(e)
notify.error(`failed to send to aria2: ${e}`)
}
},
};
};
}
}

View File

@@ -1,15 +1,9 @@
import { objStore, selectedObjs, State, me } from "~/store";
import { Obj } from "~/types";
import {
api,
encodePath,
pathDir,
pathJoin,
standardizePath,
} from "~/utils";
import { useRouter, useUtil } from ".";
import { objStore, selectedObjs, State, me } from "~/store"
import { Obj } from "~/types"
import { api, encodePath, pathDir, pathJoin, standardizePath } from "~/utils"
import { useRouter, useUtil } from "."
type URLType = "preview" | "direct" | "proxy";
type URLType = "preview" | "direct" | "proxy"
// get download url by dir and obj
export const getLinkByDirAndObj = (
@@ -18,81 +12,81 @@ export const getLinkByDirAndObj = (
type: URLType = "direct",
encodeAll?: boolean
) => {
dir = standardizePath(pathJoin(me().base_path, dir), true);
let path = `${dir}/${obj.name}`;
path = encodePath(path, encodeAll);
let host = api;
let prefix = type === "direct" ? "/d" : "/p";
dir = standardizePath(pathJoin(me().base_path, dir), true)
let path = `${dir}/${obj.name}`
path = encodePath(path, encodeAll)
let host = api
let prefix = type === "direct" ? "/d" : "/p"
if (type === "preview") {
host = location.origin;
prefix = "";
host = location.origin
prefix = ""
}
let ans = `${host}${prefix}${path}`;
let ans = `${host}${prefix}${path}`
if (type !== "preview" && obj.sign) {
ans += `?sign=${obj.sign}`;
ans += `?sign=${obj.sign}`
}
return ans
}
return ans;
};
// get download link by current state and pathname
export const useLink = () => {
const { pathname } = useRouter();
const { pathname } = useRouter()
const getLinkByObj = (obj: Obj, type?: URLType, encodeAll?: boolean) => {
const dir =
objStore.state === State.Folder ? pathname() : pathDir(pathname());
return getLinkByDirAndObj(dir, obj, type, encodeAll);
};
objStore.state === State.Folder ? pathname() : pathDir(pathname())
return getLinkByDirAndObj(dir, obj, type, encodeAll)
}
const rawLink = (obj: Obj, encodeAll?: boolean) => {
return getLinkByObj(obj, "direct", encodeAll);
};
return getLinkByObj(obj, "direct", encodeAll)
}
return {
getLinkByObj: getLinkByObj,
rawLink: rawLink,
proxyLink: (obj: Obj, encodeAll?: boolean) => {
return getLinkByObj(obj, "proxy", encodeAll);
return getLinkByObj(obj, "proxy", encodeAll)
},
previewPage: (obj: Obj, encodeAll?: boolean) => {
return getLinkByObj(obj, "preview", encodeAll);
return getLinkByObj(obj, "preview", encodeAll)
},
currentObjLink: (encodeAll?: boolean) => {
return rawLink(objStore.obj, encodeAll);
return rawLink(objStore.obj, encodeAll)
},
};
};
}
}
export const useSelectedLink = () => {
const { previewPage, rawLink: rawUrl } = useLink();
const { previewPage, rawLink: rawUrl } = useLink()
const rawLinks = (encodeAll?: boolean) => {
return selectedObjs()
.filter((obj) => !obj.is_dir)
.map((obj) => rawUrl(obj, encodeAll));
};
.map((obj) => rawUrl(obj, encodeAll))
}
return {
rawLinks: rawLinks,
previewPagesText: () => {
return selectedObjs()
.map((obj) => previewPage(obj, true))
.join("\n");
.join("\n")
},
rawLinksText: (encodeAll?: boolean) => {
return rawLinks(encodeAll).join("\n");
return rawLinks(encodeAll).join("\n")
},
};
};
}
}
export const useCopyLink = () => {
const { copy } = useUtil();
const { previewPagesText, rawLinksText } = useSelectedLink();
const { currentObjLink } = useLink();
const { copy } = useUtil()
const { previewPagesText, rawLinksText } = useSelectedLink()
const { currentObjLink } = useLink()
return {
copySelectedPreviewPage: () => {
copy(previewPagesText());
copy(previewPagesText())
},
copySelectedRawLink: (encodeAll?: boolean) => {
copy(rawLinksText(encodeAll));
copy(rawLinksText(encodeAll))
},
copyCurrentRawLink: (encodeAll?: boolean) => {
copy(currentObjLink(encodeAll));
copy(currentObjLink(encodeAll))
},
};
};
}
}

View File

@@ -1,25 +1,25 @@
import { useI18n } from "@solid-primitives/i18n";
import { firstUpperCase } from "~/utils";
import { useI18n } from "@solid-primitives/i18n"
import { firstUpperCase } from "~/utils"
const useT = () => {
const [t] = useI18n();
const [t] = useI18n()
return (
key: string,
params?: Record<string, string> | undefined,
defaultValue?: string | undefined
) => {
const value = t(key, params, defaultValue);
const value = t(key, params, defaultValue)
if (!value) {
if (import.meta.env.DEV) return key;
let lastDotIndex = key.lastIndexOf(".");
if (import.meta.env.DEV) return key
let lastDotIndex = key.lastIndexOf(".")
if (lastDotIndex === key.length - 1) {
lastDotIndex = key.lastIndexOf(".", lastDotIndex - 1);
lastDotIndex = key.lastIndexOf(".", lastDotIndex - 1)
}
const last = key.slice(lastDotIndex + 1)
return firstUpperCase(last).split("_").join(" ")
}
return value
}
const last = key.slice(lastDotIndex + 1);
return firstUpperCase(last).split("_").join(" ");
}
return value;
};
};
export { useT };
export { useT }

View File

@@ -1,55 +1,55 @@
import { createEffect, onCleanup } from "solid-js";
import { getSetting } from "~/store";
import { pathBase } from "~/utils";
import { useRouter } from "./useRouter";
import { useT } from "./useT";
import { createEffect, onCleanup } from "solid-js"
import { getSetting } from "~/store"
import { pathBase } from "~/utils"
import { useRouter } from "./useRouter"
import { useT } from "./useT"
let id = 0;
const effects: Record<string, boolean> = {};
let id = 0
const effects: Record<string, boolean> = {}
const useTitle = (title: string | (() => string)) => {
const cid = (id++).toString();
const valids: string[] = [];
const cid = (id++).toString()
const valids: string[] = []
for (const key in effects) {
if (effects[key]) {
valids.push(key);
effects[key] = false;
valids.push(key)
effects[key] = false
}
}
effects[cid] = true;
const pre = document.title;
effects[cid] = true
const pre = document.title
if (typeof title === "function") {
createEffect(() => {
if (effects[cid]) {
document.title = title();
document.title = title()
}
});
})
} else {
document.title = title;
document.title = title
}
onCleanup(() => {
// document.title = pre;
delete effects[cid];
delete effects[cid]
for (const key in valids) {
effects[key] = true;
effects[key] = true
}
})
}
});
};
export const useObjTitle = () => {
const t = useT();
const { pathname } = useRouter();
const t = useT()
const { pathname } = useRouter()
useTitle(
() =>
`${
pathname() === "/" ? t("manage.sidemenu.home") : pathBase(pathname())
} | ${getSetting("site_title")}`
);
};
)
}
export const useManageTitle = (title: string) => {
const t = useT();
useTitle(() => `${t(title)} | ${t("manage.title")}`);
};
const t = useT()
useTitle(() => `${t(title)} | ${t("manage.title")}`)
}
export { useTitle };
export { useTitle }

View File

@@ -1,34 +1,34 @@
import copy from "copy-to-clipboard";
import { createResource } from "solid-js";
import { getHideFiles, objStore } from "~/store";
import { Obj } from "~/types";
import { fetchText, notify, pathJoin } from "~/utils";
import { useT, useLink, useRouter } from ".";
import copy from "copy-to-clipboard"
import { createResource } from "solid-js"
import { getHideFiles, objStore } from "~/store"
import { Obj } from "~/types"
import { fetchText, notify, pathJoin } from "~/utils"
import { useT, useLink, useRouter } from "."
export const useUtil = () => {
const t = useT();
const { pathname } = useRouter();
const t = useT()
const { pathname } = useRouter()
return {
copy: (text: string) => {
copy(text);
notify.success(t("global.copied"));
copy(text)
notify.success(t("global.copied"))
},
isHide: (obj: Obj) => {
const hideFiles = getHideFiles();
const hideFiles = getHideFiles()
for (const reg of hideFiles) {
if (reg.test(pathJoin(pathname(), obj.name))) {
return true;
return true
}
}
return false;
return false
},
};
};
}
}
export const useFetchText = () => {
const { proxyLink } = useLink();
const { proxyLink } = useLink()
const fetchContent = async () => {
return fetchText(proxyLink(objStore.obj, true));
};
return createResource("", fetchContent);
};
return fetchText(proxyLink(objStore.obj, true))
}
return createResource("", fetchContent)
}

6
src/index.d.ts vendored
View File

@@ -1,7 +1,7 @@
declare module "aplayer";
declare module "aplayer"
declare namespace aliyun {
class Config {
setToken(token: { token: string }): any;
setToken(token: { token: string }): any
}
function config(options: { mount: Element; url: string }): Config;
function config(options: { mount: Element; url: string }): Config
}

View File

@@ -1,7 +1,7 @@
const jsons = import.meta.glob("./*.json", { eager: true, import: "default" });
const langs: any = {};
const jsons = import.meta.glob("./*.json", { eager: true, import: "default" })
const langs: any = {}
for (const path in jsons) {
const name = path.split("/")[1].split(".")[0];
langs[name] = jsons[path];
const name = path.split("/")[1].split(".")[0]
langs[name] = jsons[path]
}
export default langs;
export default langs

View File

@@ -1,12 +1,12 @@
/* @refresh reload */
import { Router } from "@solidjs/router";
import { render } from "solid-js/web";
import { Router } from "@solidjs/router"
import { render } from "solid-js/web"
import { Index } from "./app";
import { Index } from "./app"
declare global {
interface Window {
[key: string]: any;
[key: string]: any
}
}
render(
@@ -16,4 +16,4 @@ render(
</Router>
),
document.getElementById("root") as HTMLElement
);
)

View File

@@ -1,8 +1,8 @@
import { VStack } from "@hope-ui/solid";
import { Nav } from "./Nav";
import { Obj } from "./Obj";
import { Readme } from "./Readme";
import { Container } from "./Container";
import { VStack } from "@hope-ui/solid"
import { Nav } from "./Nav"
import { Obj } from "./Obj"
import { Readme } from "./Readme"
import { Container } from "./Container"
export const Body = () => {
return (
@@ -21,5 +21,5 @@ export const Body = () => {
<Readme />
</VStack>
</Container>
);
};
)
}

View File

@@ -1,14 +1,14 @@
import { JSXElement, Match, Switch } from "solid-js";
import { getSetting } from "~/store";
import { Box, Container as HopeContainer } from "@hope-ui/solid";
import { JSXElement, Match, Switch } from "solid-js"
import { getSetting } from "~/store"
import { Box, Container as HopeContainer } from "@hope-ui/solid"
export const Container = (props: { children: JSXElement }) => {
const container = getSetting("home_container");
const container = getSetting("home_container")
return (
<Switch fallback={<Box w="min(99%, 980px)">{props.children}</Box>}>
<Match when={container === "hope_container"}>
<HopeContainer>{props.children}</HopeContainer>
</Match>
</Switch>
);
};
)
}

View File

@@ -1,12 +1,12 @@
import { Anchor, HStack, VStack } from "@hope-ui/solid";
import { Link } from "@solidjs/router";
import { AnchorWithBase } from "~/components";
import { useT } from "~/hooks";
import { me } from "~/store";
import { UserMethods } from "~/types";
import { Anchor, HStack, VStack } from "@hope-ui/solid"
import { Link } from "@solidjs/router"
import { AnchorWithBase } from "~/components"
import { useT } from "~/hooks"
import { me } from "~/store"
import { UserMethods } from "~/types"
export const Footer = () => {
const t = useT();
const t = useT()
return (
<VStack class="footer" w="$full" py="$4">
<HStack spacing="$1">
@@ -18,11 +18,9 @@ export const Footer = () => {
as={Link}
href={UserMethods.is_guest(me()) ? "/@login" : "/@manage"}
>
{t(
UserMethods.is_guest(me()) ? "login.login" : "home.footer.manage"
)}
{t(UserMethods.is_guest(me()) ? "login.login" : "home.footer.manage")}
</AnchorWithBase>
</HStack>
</VStack>
);
};
)
}

View File

@@ -1,17 +1,17 @@
import { Markdown } from "~/components";
import { useTitle } from "~/hooks";
import { getSetting } from "~/store";
import { notify } from "~/utils";
import { Body } from "./Body";
import { Footer } from "./Footer";
import { Header } from "./Header";
import { Toolbar } from "./toolbar/Toolbar";
import { Markdown } from "~/components"
import { useTitle } from "~/hooks"
import { getSetting } from "~/store"
import { notify } from "~/utils"
import { Body } from "./Body"
import { Footer } from "./Footer"
import { Header } from "./Header"
import { Toolbar } from "./toolbar/Toolbar"
const Index = () => {
useTitle(getSetting("site_title"));
const announcement = getSetting("announcement");
useTitle(getSetting("site_title"))
const announcement = getSetting("announcement")
if (announcement) {
notify.render(() => <Markdown children={announcement} />);
notify.render(() => <Markdown children={announcement} />)
}
return (
<>
@@ -20,7 +20,7 @@ const Index = () => {
<Body />
<Footer />
</>
);
};
)
}
export default Index;
export default Index

View File

@@ -3,33 +3,30 @@ import {
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbSeparator,
} from "@hope-ui/solid";
import { Link } from "@solidjs/router";
import { createMemo, For, Show } from "solid-js";
import { usePath, useRouter, useT } from "~/hooks";
import { getSetting } from "~/store";
import { encodePath, hoverColor, joinBase } from "~/utils";
} from "@hope-ui/solid"
import { Link } from "@solidjs/router"
import { createMemo, For, Show } from "solid-js"
import { usePath, useRouter, useT } from "~/hooks"
import { getSetting } from "~/store"
import { encodePath, hoverColor, joinBase } from "~/utils"
export const Nav = () => {
const { pathname } = useRouter();
const paths = createMemo(() => [
"",
...pathname().split("/").filter(Boolean),
]);
const t = useT();
const { setPathAs } = usePath();
const { pathname } = useRouter()
const paths = createMemo(() => ["", ...pathname().split("/").filter(Boolean)])
const t = useT()
const { setPathAs } = usePath()
return (
<Breadcrumb class="nav" w="$full">
<For each={paths()}>
{(name, i) => {
const isLast = createMemo(() => i() === paths().length - 1);
const isLast = createMemo(() => i() === paths().length - 1)
const path = paths()
.slice(0, i() + 1)
.join("/");
const href = encodePath(path);
let text = () => name;
.join("/")
const href = encodePath(path)
let text = () => name
if (text() === "") {
text = () => getSetting("home_icon") + t("manage.sidemenu.home");
text = () => getSetting("home_icon") + t("manage.sidemenu.home")
}
return (
<BreadcrumbItem class="nav-item">
@@ -55,9 +52,9 @@ export const Nav = () => {
<BreadcrumbSeparator class="nav-separator" />
</Show>
</BreadcrumbItem>
);
)
}}
</For>
</Breadcrumb>
);
};
)
}

View File

@@ -7,15 +7,15 @@ import {
Text,
useColorModeValue,
VStack,
} from "@hope-ui/solid";
import { LinkWithBase } from "~/components";
import { usePath, useRouter, useT } from "~/hooks";
import { password, setPassword } from "~/store";
} from "@hope-ui/solid"
import { LinkWithBase } from "~/components"
import { usePath, useRouter, useT } from "~/hooks"
import { password, setPassword } from "~/store"
const Password = () => {
const t = useT();
const { refresh } = usePath();
const { back } = useRouter();
const t = useT()
const { refresh } = usePath()
const { back } = useRouter()
return (
<VStack
w={{
@@ -33,7 +33,7 @@ const Password = () => {
background={useColorModeValue("$neutral3", "$neutral2")()}
onKeyDown={(e) => {
if (e.key === "Enter") {
refresh(true);
refresh(true)
}
}}
onInput={(e) => setPassword(e.currentTarget.value)}
@@ -62,6 +62,6 @@ const Password = () => {
</HStack>
</HStack>
</VStack>
);
};
export default Password;
)
}
export default Password

View File

@@ -1,17 +1,17 @@
import { HStack, VStack } from "@hope-ui/solid";
import { createMemo, createSignal, Show, Suspense } from "solid-js";
import { Dynamic } from "solid-js/web";
import { FullLoading, SelectWrapper } from "~/components";
import { objStore } from "~/store";
import { Download } from "../previews/download";
import { OpenWith } from "./open-with";
import { getPreviews } from "../previews";
import { HStack, VStack } from "@hope-ui/solid"
import { createMemo, createSignal, Show, Suspense } from "solid-js"
import { Dynamic } from "solid-js/web"
import { FullLoading, SelectWrapper } from "~/components"
import { objStore } from "~/store"
import { Download } from "../previews/download"
import { OpenWith } from "./open-with"
import { getPreviews } from "../previews"
const File = () => {
const previews = createMemo(() => {
return getPreviews({ ...objStore.obj, provider: objStore.provider });
});
const [cur, setCur] = createSignal(previews()[0]);
return getPreviews({ ...objStore.obj, provider: objStore.provider })
})
const [cur, setCur] = createSignal(previews()[0])
return (
<Show when={previews().length > 1} fallback={<Download openWith />}>
<VStack w="$full" spacing="$2">
@@ -20,7 +20,7 @@ const File = () => {
alwaysShowBorder
value={cur().name}
onChange={(name) => {
setCur(previews().find((p) => p.name === name)!);
setCur(previews().find((p) => p.name === name)!)
}}
options={previews().map((item) => ({ value: item.name }))}
/>
@@ -31,7 +31,7 @@ const File = () => {
</Suspense>
</VStack>
</Show>
);
};
)
}
export default File;
export default File

View File

@@ -5,18 +5,18 @@ import {
MenuContent,
MenuItem,
MenuTrigger,
} from "@hope-ui/solid";
import { createMemo, For, Show } from "solid-js";
import { useT } from "~/hooks";
import { getExternalPreviews, objStore } from "~/store";
import { FaSolidAngleDown } from "solid-icons/fa";
import { convertURL } from "~/utils";
} from "@hope-ui/solid"
import { createMemo, For, Show } from "solid-js"
import { useT } from "~/hooks"
import { getExternalPreviews, objStore } from "~/store"
import { FaSolidAngleDown } from "solid-icons/fa"
import { convertURL } from "~/utils"
export const OpenWith = () => {
const t = useT();
const t = useT()
const previews = createMemo(() => {
return getExternalPreviews(objStore.obj.name);
});
return getExternalPreviews(objStore.obj.name)
})
return (
<Show when={previews().length}>
<Menu>
@@ -46,5 +46,5 @@ export const OpenWith = () => {
</MenuContent>
</Menu>
</Show>
);
};
)
}

View File

@@ -1,55 +1,55 @@
import { lazy, Show, createEffect, createMemo, onCleanup } from "solid-js";
import { layout } from "~/store";
import { ContextMenu } from "./context-menu";
import { Pager } from "./Pager";
import { useLink } from "~/hooks";
import { objStore } from "~/store";
import { ObjType } from "~/types";
import { bus } from "~/utils";
import lightGallery from "lightgallery";
import lgThumbnail from "lightgallery/plugins/thumbnail";
import lgZoom from "lightgallery/plugins/zoom";
import lgRotate from "lightgallery/plugins/rotate";
import lgAutoplay from "lightgallery/plugins/autoplay";
import lgFullscreen from "lightgallery/plugins/fullscreen";
import "lightgallery/css/lightgallery-bundle.css";
import { LightGallery } from "lightgallery/lightgallery";
import { Search } from "./Search";
import { lazy, Show, createEffect, createMemo, onCleanup } from "solid-js"
import { layout } from "~/store"
import { ContextMenu } from "./context-menu"
import { Pager } from "./Pager"
import { useLink } from "~/hooks"
import { objStore } from "~/store"
import { ObjType } from "~/types"
import { bus } from "~/utils"
import lightGallery from "lightgallery"
import lgThumbnail from "lightgallery/plugins/thumbnail"
import lgZoom from "lightgallery/plugins/zoom"
import lgRotate from "lightgallery/plugins/rotate"
import lgAutoplay from "lightgallery/plugins/autoplay"
import lgFullscreen from "lightgallery/plugins/fullscreen"
import "lightgallery/css/lightgallery-bundle.css"
import { LightGallery } from "lightgallery/lightgallery"
import { Search } from "./Search"
const ListLayout = lazy(() => import("./List"));
const GridLayout = lazy(() => import("./Grid"));
const ListLayout = lazy(() => import("./List"))
const GridLayout = lazy(() => import("./Grid"))
const Folder = () => {
const { rawLink } = useLink();
const { rawLink } = useLink()
const images = createMemo(() =>
objStore.objs.filter((obj) => obj.type === ObjType.IMAGE)
);
let dynamicGallery: LightGallery | undefined;
)
let dynamicGallery: LightGallery | undefined
createEffect(() => {
dynamicGallery?.destroy();
dynamicGallery?.destroy()
if (images().length > 0) {
dynamicGallery = lightGallery(document.createElement("div"), {
dynamic: true,
thumbnail: true,
plugins: [lgZoom, lgThumbnail, lgRotate, lgAutoplay, lgFullscreen],
dynamicEl: images().map((obj) => {
const raw = rawLink(obj, true);
const raw = rawLink(obj, true)
return {
src: raw,
thumb: obj.thumb === "" ? raw : obj.thumb,
subHtml: `<h4>${obj.name}</h4>`,
};
}),
});
}
});
}),
})
}
})
bus.on("gallery", (name) => {
dynamicGallery?.openGallery(images().findIndex((obj) => obj.name === name));
});
dynamicGallery?.openGallery(images().findIndex((obj) => obj.name === name))
})
onCleanup(() => {
bus.off("gallery");
dynamicGallery?.destroy();
});
bus.off("gallery")
dynamicGallery?.destroy()
})
return (
<>
<Show when={layout() === "list"} fallback={<GridLayout />}>
@@ -59,7 +59,7 @@ const Folder = () => {
<Search />
<ContextMenu />
</>
);
};
)
}
export default Folder;
export default Folder

View File

@@ -1,8 +1,8 @@
import { Grid } from "@hope-ui/solid";
import { For } from "solid-js";
import { GridItem } from "./GridItem";
import "lightgallery/css/lightgallery-bundle.css";
import { objStore } from "~/store";
import { Grid } from "@hope-ui/solid"
import { For } from "solid-js"
import { GridItem } from "./GridItem"
import "lightgallery/css/lightgallery-bundle.css"
import { objStore } from "~/store"
const GridLayout = () => {
return (
@@ -13,11 +13,11 @@ const GridLayout = () => {
>
<For each={objStore.objs}>
{(obj, i) => {
return <GridItem obj={obj} index={i()} />;
return <GridItem obj={obj} index={i()} />
}}
</For>
</Grid>
);
};
)
}
export default GridLayout;
export default GridLayout

View File

@@ -1,5 +1,5 @@
import { Grid, Skeleton } from "@hope-ui/solid";
import { For } from "solid-js";
import { Grid, Skeleton } from "@hope-ui/solid"
import { For } from "solid-js"
const GridSkeleton = () => {
return (
@@ -12,7 +12,7 @@ const GridSkeleton = () => {
{() => <Skeleton w="$full" h="$28" rounded="$lg" />}
</For>
</Grid>
);
};
)
}
export default GridSkeleton;
export default GridSkeleton

View File

@@ -1,5 +1,5 @@
import { Skeleton, VStack } from "@hope-ui/solid";
import { For } from "solid-js";
import { Skeleton, VStack } from "@hope-ui/solid"
import { For } from "solid-js"
const ListSkeleton = () => {
return (
@@ -8,7 +8,7 @@ const ListSkeleton = () => {
{() => <Skeleton rounded="$lg" w="$full" h="$8" />}
</For>
</VStack>
);
};
)
}
export default ListSkeleton;
export default ListSkeleton

View File

@@ -1,15 +1,15 @@
import { Menu, Item } from "solid-contextmenu";
import { useCopyLink, useDownload, useT } from "~/hooks";
import "solid-contextmenu/dist/style.css";
import { HStack, Icon, Text, useColorMode } from "@hope-ui/solid";
import { operations } from "../toolbar/operations";
import { For } from "solid-js";
import { bus, notify } from "~/utils";
import { UserMethods, UserPermissions } from "~/types";
import { getSettingBool, me } from "~/store";
import { Menu, Item } from "solid-contextmenu"
import { useCopyLink, useDownload, useT } from "~/hooks"
import "solid-contextmenu/dist/style.css"
import { HStack, Icon, Text, useColorMode } from "@hope-ui/solid"
import { operations } from "../toolbar/operations"
import { For } from "solid-js"
import { bus, notify } from "~/utils"
import { UserMethods, UserPermissions } from "~/types"
import { getSettingBool, me } from "~/store"
const ItemContent = (props: { name: string }) => {
const t = useT();
const t = useT()
return (
<HStack spacing="$2">
<Icon
@@ -20,17 +20,17 @@ const ItemContent = (props: { name: string }) => {
/>
<Text>{t(`home.toolbar.${props.name}`)}</Text>
</HStack>
);
};
)
}
export const ContextMenu = () => {
const t = useT();
const { colorMode } = useColorMode();
const { copySelectedRawLink, copySelectedPreviewPage } = useCopyLink();
const { batchDownloadSelected } = useDownload();
const t = useT()
const { colorMode } = useColorMode()
const { copySelectedRawLink, copySelectedPreviewPage } = useCopyLink()
const { batchDownloadSelected } = useDownload()
const canPackageDownload = () => {
return UserMethods.is_admin(me()) || getSettingBool("package_download");
};
return UserMethods.is_admin(me()) || getSettingBool("package_download")
}
return (
<Menu
id={1}
@@ -41,11 +41,11 @@ export const ContextMenu = () => {
{(name) => (
<Item
hidden={() => {
const index = UserPermissions.findIndex((item) => item === name);
return !UserMethods.can(me(), index);
const index = UserPermissions.findIndex((item) => item === name)
return !UserMethods.can(me(), index)
}}
onClick={() => {
bus.emit("tool", name);
bus.emit("tool", name)
}}
>
<ItemContent name={name} />
@@ -55,9 +55,9 @@ export const ContextMenu = () => {
<Item
onClick={({ props }) => {
if (props.is_dir) {
copySelectedPreviewPage();
copySelectedPreviewPage()
} else {
copySelectedRawLink(true);
copySelectedRawLink(true)
}
}}
>
@@ -67,17 +67,17 @@ export const ContextMenu = () => {
onClick={({ props }) => {
if (props.is_dir) {
if (!canPackageDownload()) {
notify.warning(t("home.toolbar.package_download_disabled"));
return;
notify.warning(t("home.toolbar.package_download_disabled"))
return
}
bus.emit("tool", "package_download");
bus.emit("tool", "package_download")
} else {
batchDownloadSelected();
batchDownloadSelected()
}
}}
>
<ItemContent name="download" />
</Item>
</Menu>
);
};
)
}

View File

@@ -1,27 +1,27 @@
import "aplayer/dist/APlayer.min.css";
import "./audio.css";
import APlayer from "aplayer";
import { Box } from "@hope-ui/solid";
import { onCleanup, onMount } from "solid-js";
import { useLink } from "~/hooks";
import { getSetting, getSettingBool, objStore } from "~/store";
import { ObjType, StoreObj } from "~/types";
import { baseName } from "~/utils";
import "aplayer/dist/APlayer.min.css"
import "./audio.css"
import APlayer from "aplayer"
import { Box } from "@hope-ui/solid"
import { onCleanup, onMount } from "solid-js"
import { useLink } from "~/hooks"
import { getSetting, getSettingBool, objStore } from "~/store"
import { ObjType, StoreObj } from "~/types"
import { baseName } from "~/utils"
const Preview = () => {
const { proxyLink, rawLink } = useLink();
let audios = objStore.objs.filter((obj) => obj.type === ObjType.AUDIO);
const { proxyLink, rawLink } = useLink()
let audios = objStore.objs.filter((obj) => obj.type === ObjType.AUDIO)
if (audios.length === 0) {
audios = [objStore.obj];
audios = [objStore.obj]
}
let ap: any;
let ap: any
const objToAudio = (obj: StoreObj) => {
let lrc = undefined;
let lrc = undefined
const lrcObj = objStore.objs.find((o) => {
return baseName(o.name) === baseName(obj.name) && o.name.endsWith(".lrc");
});
return baseName(o.name) === baseName(obj.name) && o.name.endsWith(".lrc")
})
if (lrcObj) {
lrc = proxyLink(lrcObj, true);
lrc = proxyLink(lrcObj, true)
}
return {
name: obj.name,
@@ -31,8 +31,8 @@ const Preview = () => {
getSetting("audio_cover") ||
"https://jsd.nn.ci/gh/alist-org/logo@main/logo.svg",
lrc: lrc,
};
};
}
}
onMount(() => {
ap = new APlayer({
container: document.querySelector("#audio-player"),
@@ -46,16 +46,16 @@ const Preview = () => {
listFolded: false,
lrcType: 3,
audio: audios.map(objToAudio),
});
const curIndex = audios.findIndex((obj) => obj.name === objStore.obj.name);
})
const curIndex = audios.findIndex((obj) => obj.name === objStore.obj.name)
if (curIndex !== -1) {
ap.list.switch(curIndex);
ap.list.switch(curIndex)
}
});
})
onCleanup(() => {
ap?.destroy();
});
return <Box w="$full" id="audio-player" />;
};
ap?.destroy()
})
return <Box w="$full" id="audio-player" />
}
export default Preview;
export default Preview

View File

@@ -1,13 +1,13 @@
import { Button, HStack } from "@hope-ui/solid";
import { useCopyLink, useT } from "~/hooks";
import { objStore } from "~/store";
import { FileInfo } from "./info";
import { OpenWith } from "../file/open-with";
import { Show } from "solid-js";
import { Button, HStack } from "@hope-ui/solid"
import { useCopyLink, useT } from "~/hooks"
import { objStore } from "~/store"
import { FileInfo } from "./info"
import { OpenWith } from "../file/open-with"
import { Show } from "solid-js"
export const Download = (props: { openWith?: boolean }) => {
const t = useT();
const { copyCurrentRawLink } = useCopyLink();
const t = useT()
const { copyCurrentRawLink } = useCopyLink()
return (
<FileInfo>
<HStack spacing="$2">
@@ -22,7 +22,7 @@ export const Download = (props: { openWith?: boolean }) => {
<OpenWith />
</Show>
</FileInfo>
);
};
)
}
export default Download;
export default Download

View File

@@ -1,9 +1,9 @@
import { hope } from "@hope-ui/solid";
import { BoxWithFullScreen, MaybeLoading } from "~/components";
import { useFetchText } from "~/hooks";
import { hope } from "@hope-ui/solid"
import { BoxWithFullScreen, MaybeLoading } from "~/components"
import { useFetchText } from "~/hooks"
const HtmlPreview = () => {
const [content] = useFetchText();
const [content] = useFetchText()
return (
<MaybeLoading loading={content.loading}>
<BoxWithFullScreen w="$full" h="70vh">
@@ -16,7 +16,7 @@ const HtmlPreview = () => {
/>
</BoxWithFullScreen>
</MaybeLoading>
);
};
)
}
export default HtmlPreview;
export default HtmlPreview

View File

@@ -1,8 +1,8 @@
import { BoxWithFullScreen } from "~/components";
import { objStore } from "~/store";
import { hope } from "@hope-ui/solid";
import { convertURL } from "~/utils";
import { Component } from "solid-js";
import { BoxWithFullScreen } from "~/components"
import { objStore } from "~/store"
import { hope } from "@hope-ui/solid"
import { convertURL } from "~/utils"
import { Component } from "solid-js"
const IframePreview = (props: { scheme: string }) => {
return (
@@ -13,11 +13,11 @@ const IframePreview = (props: { scheme: string }) => {
src={convertURL(props.scheme, objStore.raw_url, objStore.obj.name)}
/>
</BoxWithFullScreen>
);
};
)
}
export const generateIframePreview = (scheme: string): Component => {
return () => {
return <IframePreview scheme={scheme} />;
};
};
return <IframePreview scheme={scheme} />
}
}

View File

@@ -1,9 +1,9 @@
import { Error, FullLoading, ImageWithError } from "~/components";
import { useT } from "~/hooks";
import { objStore } from "~/store";
import { Error, FullLoading, ImageWithError } from "~/components"
import { useT } from "~/hooks"
import { objStore } from "~/store"
const Preview = () => {
const t = useT();
const t = useT()
return (
<ImageWithError
maxH="75vh"
@@ -12,7 +12,7 @@ const Preview = () => {
fallback={<FullLoading />}
fallbackErr={<Error msg={t("home.preview.failed_load_img")} />}
/>
);
};
)
}
export default Preview;
export default Preview

View File

@@ -1,18 +1,18 @@
import { Component, lazy } from "solid-js";
import { getIframePreviews } from "~/store";
import { Obj, ObjType } from "~/types";
import { ext } from "~/utils";
import { generateIframePreview } from "./iframe";
import { Component, lazy } from "solid-js"
import { getIframePreviews } from "~/store"
import { Obj, ObjType } from "~/types"
import { ext } from "~/utils"
import { generateIframePreview } from "./iframe"
export interface Preview {
name: string;
type?: ObjType;
exts?: string[] | "*";
provider?: RegExp;
component: Component;
name: string
type?: ObjType
exts?: string[] | "*"
provider?: RegExp
component: Component
}
export type PreviewComponent = Pick<Preview, "name" | "component">;
export type PreviewComponent = Pick<Preview, "name" | "component">
const previews: Preview[] = [
{
@@ -61,37 +61,37 @@ const previews: Preview[] = [
provider: /Aliyundrive/,
component: lazy(() => import("./aliyun_office")),
},
];
]
export const getPreviews = (
file: Obj & { provider: string }
): PreviewComponent[] => {
const res: PreviewComponent[] = [];
const res: PreviewComponent[] = []
// internal previews
previews.forEach((preview) => {
if (preview.provider && !preview.provider.test(file.provider)) {
return;
return
}
if (
preview.type === file.type ||
preview.exts === "*" ||
preview.exts?.includes(ext(file.name).toLowerCase())
) {
res.push({ name: preview.name, component: preview.component });
res.push({ name: preview.name, component: preview.component })
}
});
})
// iframe previews
const iframePreviews = getIframePreviews(file.name);
const iframePreviews = getIframePreviews(file.name)
iframePreviews.forEach((preview) => {
res.push({
name: preview.key,
component: generateIframePreview(preview.value),
});
});
})
})
// download page
res.push({
name: "Download",
component: lazy(() => import("./download")),
});
return res;
};
})
return res
}

View File

@@ -1,8 +1,8 @@
import { Heading, Icon, Text, VStack } from "@hope-ui/solid";
import { JSXElement } from "solid-js";
import { getMainColor, objStore } from "~/store";
import { formatDate, getFileSize } from "~/utils";
import { getIconByObj } from "~/utils/icon";
import { Heading, Icon, Text, VStack } from "@hope-ui/solid"
import { JSXElement } from "solid-js"
import { getMainColor, objStore } from "~/store"
import { formatDate, getFileSize } from "~/utils"
import { getIconByObj } from "~/utils/icon"
export const FileInfo = (props: { children: JSXElement }) => {
return (
@@ -27,5 +27,5 @@ export const FileInfo = (props: { children: JSXElement }) => {
</VStack>
<VStack spacing="$2">{props.children}</VStack>
</VStack>
);
};
)
}

View File

@@ -1,13 +1,13 @@
import { Button } from "@hope-ui/solid";
import { createSignal } from "solid-js";
import { useT } from "~/hooks";
import { objStore } from "~/store";
import { api, baseName, safeBtoa } from "~/utils";
import { FileInfo } from "./info";
import { Button } from "@hope-ui/solid"
import { createSignal } from "solid-js"
import { useT } from "~/hooks"
import { objStore } from "~/store"
import { api, baseName, safeBtoa } from "~/utils"
import { FileInfo } from "./info"
const Ipa = () => {
const t = useT();
const [installing, setInstalling] = createSignal(false);
const t = useT()
const [installing, setInstalling] = createSignal(false)
return (
<FileInfo>
<Button
@@ -21,13 +21,13 @@ const Ipa = () => {
)}.plist`
}
onClick={() => {
setInstalling(true);
setInstalling(true)
}}
>
{t(`home.preview.${installing() ? "installing" : "install"}`)}
</Button>
</FileInfo>
);
};
)
}
export default Ipa;
export default Ipa

View File

@@ -1,12 +1,12 @@
import { Button } from "@hope-ui/solid";
import { createSignal } from "solid-js";
import { useT } from "~/hooks";
import { objStore } from "~/store";
import { FileInfo } from "./info";
import { Button } from "@hope-ui/solid"
import { createSignal } from "solid-js"
import { useT } from "~/hooks"
import { objStore } from "~/store"
import { FileInfo } from "./info"
const Plist = () => {
const t = useT();
const [installing, setInstalling] = createSignal(false);
const t = useT()
const [installing, setInstalling] = createSignal(false)
return (
<FileInfo>
<Button
@@ -15,13 +15,13 @@ const Plist = () => {
"itms-services://?action=download-manifest&url=" + objStore.raw_url
}
onClick={() => {
setInstalling(true);
setInstalling(true)
}}
>
{t(`home.preview.${installing() ? "installing" : "install"}`)}
</Button>
</FileInfo>
);
};
)
}
export default Plist;
export default Plist

View File

@@ -1,23 +1,23 @@
import { createDisclosure } from "@hope-ui/solid";
import { ModalInput } from "~/components";
import { useFetch, useRouter, useT } from "~/hooks";
import { addAria2, bus, handleRespWithNotifySuccess } from "~/utils";
import { onCleanup } from "solid-js";
import { createDisclosure } from "@hope-ui/solid"
import { ModalInput } from "~/components"
import { useFetch, useRouter, useT } from "~/hooks"
import { addAria2, bus, handleRespWithNotifySuccess } from "~/utils"
import { onCleanup } from "solid-js"
export const Aria2 = () => {
const t = useT();
const { isOpen, onOpen, onClose } = createDisclosure();
const [loading, ok] = useFetch(addAria2);
const { pathname } = useRouter();
const t = useT()
const { isOpen, onOpen, onClose } = createDisclosure()
const [loading, ok] = useFetch(addAria2)
const { pathname } = useRouter()
const handler = (name: string) => {
if (name === "offline_download") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<ModalInput
title="home.toolbar.offline_download"
@@ -27,11 +27,11 @@ export const Aria2 = () => {
loading={loading()}
tips={t("home.toolbar.offline_download-tips")}
onSubmit={async (urls) => {
const resp = await ok(pathname(), urls.split("\n"));
const resp = await ok(pathname(), urls.split("\n"))
handleRespWithNotifySuccess(resp, () => {
onClose();
});
onClose()
})
}}
/>
);
};
)
}

View File

@@ -1,17 +1,11 @@
import { Box, HStack, useColorModeValue } from "@hope-ui/solid";
import { createMemo, For, Show } from "solid-js";
import {
checkboxOpen,
haveSelected,
objStore,
selectAll,
State,
} from "~/store";
import { CopyLink } from "./CopyLink";
import { CenterIcon } from "./Icon";
import { bus } from "~/utils";
import { Download } from "./Download";
import { Motion, Presence } from "@motionone/solid";
import { Box, HStack, useColorModeValue } from "@hope-ui/solid"
import { createMemo, For, Show } from "solid-js"
import { checkboxOpen, haveSelected, objStore, selectAll, State } from "~/store"
import { CopyLink } from "./CopyLink"
import { CenterIcon } from "./Icon"
import { bus } from "~/utils"
import { Download } from "./Download"
import { Motion, Presence } from "@motionone/solid"
export const Center = () => {
const show = createMemo(
@@ -19,7 +13,7 @@ export const Center = () => {
[State.Folder, State.FetchingMore].includes(objStore.state) &&
checkboxOpen() &&
haveSelected()
);
)
return (
<Presence exitBeforeEnter>
<Show when={show()}>
@@ -53,10 +47,10 @@ export const Center = () => {
<CenterIcon
name={name}
onClick={() => {
bus.emit("tool", name);
bus.emit("tool", name)
}}
/>
);
)
}}
</For>
<CopyLink />
@@ -64,12 +58,12 @@ export const Center = () => {
<CenterIcon
name="cancel_select"
onClick={() => {
selectAll(false);
selectAll(false)
}}
/>
</HStack>
</Box>
</Show>
</Presence>
);
};
)
}

View File

@@ -1,11 +1,11 @@
import { Menu, MenuTrigger, MenuContent, MenuItem } from "@hope-ui/solid";
import { useT, useCopyLink } from "~/hooks";
import { CenterIcon } from "./Icon";
import { Menu, MenuTrigger, MenuContent, MenuItem } from "@hope-ui/solid"
import { useT, useCopyLink } from "~/hooks"
import { CenterIcon } from "./Icon"
export const CopyLink = () => {
const t = useT();
const { copySelectedPreviewPage, copySelectedRawLink } = useCopyLink();
const colorScheme = "neutral";
const t = useT()
const { copySelectedPreviewPage, copySelectedRawLink } = useCopyLink()
const colorScheme = "neutral"
return (
<Menu placement="top" offset={10}>
<MenuTrigger as={CenterIcon} name="copy_link" />
@@ -13,7 +13,7 @@ export const CopyLink = () => {
<MenuItem
colorScheme={colorScheme}
onSelect={() => {
copySelectedPreviewPage();
copySelectedPreviewPage()
}}
>
{t("home.toolbar.preview_page")}
@@ -21,7 +21,7 @@ export const CopyLink = () => {
<MenuItem
colorScheme={colorScheme}
onSelect={() => {
copySelectedRawLink();
copySelectedRawLink()
}}
>
{t("home.toolbar.down_link")}
@@ -29,12 +29,12 @@ export const CopyLink = () => {
<MenuItem
colorScheme={colorScheme}
onSelect={() => {
copySelectedRawLink(true);
copySelectedRawLink(true)
}}
>
{t("home.toolbar.encode_down_link")}
</MenuItem>
</MenuContent>
</Menu>
);
};
)
}

View File

@@ -1,24 +1,24 @@
import { createDisclosure } from "@hope-ui/solid";
import { onCleanup } from "solid-js";
import { ModalFolderChoose } from "~/components";
import { useFetch, usePath, useRouter } from "~/hooks";
import { selectedObjs } from "~/store";
import { bus, fsCopy, fsMove, handleRespWithNotifySuccess } from "~/utils";
import { createDisclosure } from "@hope-ui/solid"
import { onCleanup } from "solid-js"
import { ModalFolderChoose } from "~/components"
import { useFetch, usePath, useRouter } from "~/hooks"
import { selectedObjs } from "~/store"
import { bus, fsCopy, fsMove, handleRespWithNotifySuccess } from "~/utils"
export const Copy = () => {
const { isOpen, onOpen, onClose } = createDisclosure();
const [loading, ok] = useFetch(fsCopy);
const { pathname } = useRouter();
const { refresh } = usePath();
const { isOpen, onOpen, onClose } = createDisclosure()
const [loading, ok] = useFetch(fsCopy)
const { pathname } = useRouter()
const { refresh } = usePath()
const handler = (name: string) => {
if (name === "copy") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<ModalFolderChoose
opened={isOpen()}
@@ -29,30 +29,30 @@ export const Copy = () => {
pathname(),
dst,
selectedObjs().map((obj) => obj.name)
);
)
handleRespWithNotifySuccess(resp, () => {
refresh();
onClose();
});
refresh()
onClose()
})
}}
/>
);
};
)
}
export const Move = () => {
const { isOpen, onOpen, onClose } = createDisclosure();
const [loading, ok] = useFetch(fsMove);
const { pathname } = useRouter();
const { refresh } = usePath();
const { isOpen, onOpen, onClose } = createDisclosure()
const [loading, ok] = useFetch(fsMove)
const { pathname } = useRouter()
const { refresh } = usePath()
const handler = (name: string) => {
if (name === "move") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<ModalFolderChoose
opened={isOpen()}
@@ -63,16 +63,16 @@ export const Move = () => {
pathname(),
dst,
selectedObjs().map((obj) => obj.name)
);
)
handleRespWithNotifySuccess(resp, () => {
refresh();
onClose();
});
refresh()
onClose()
})
}}
/>
// <CenterIcon tip="move" viewBox="0 0 1024 1024" fill="currentColor">
// <path d="M840.704 256h-36.992c-82.624 0-82.496-128-140.864-128H311.232C245.44 128 192 181.44 192 247.296V384h64V247.296C256 216.832 280.832 192 311.232 192h339.456c3.968 6.144 9.024 15.36 12.672 22.208C684.8 253.76 720.704 320 803.712 320h36.992C869.12 320 896 351.104 896 384v392.768c0 30.4-24.832 55.232-55.296 55.232H311.232c-30.4 0-55.232-24.832-55.232-55.232V704h-64v72.768C192 842.624 245.44 896 311.232 896H840.64C906.56 896 960 842.624 960 776.768V384c0-65.856-53.44-128-119.296-128z"></path>
// <path d="M497.344 693.824L630.4 563.968c0.128-0.128 0.192-0.32 0.32-0.512 2.816-2.816 5.184-9.536 6.784-13.248 1.344-3.456 1.856-0.64 2.112-4.096 0-0.768 0.384-1.408 0.384-2.112 0-0.512-0.256-0.896-0.256-1.344-0.192-3.84-0.896-5.76-2.24-9.344-1.344-3.264-3.52-6.016-5.76-8.64-0.512-0.64-0.768-1.536-1.344-2.112L497.344 389.632c-12.8-12.864-33.6-6.976-46.4 5.888-12.864 12.8-12.864 33.6 0 46.464l76.864 70.976-429.632 0.064c-18.752 0-33.984 12.8-33.92 30.912-0.064 18.112 15.168 29.696 33.984 29.696h429.632l-76.864 79.552c-12.864 12.864-12.864 33.6 0 46.528 6.4 6.4 14.72 3.776 23.168 3.776s16.832-3.328 23.168-9.664z"></path>
// </CenterIcon>
);
};
)
}

View File

@@ -7,27 +7,27 @@ import {
ModalFooter,
Button,
createDisclosure,
} from "@hope-ui/solid";
import { onCleanup } from "solid-js";
import { useFetch, usePath, useRouter, useT } from "~/hooks";
import { selectedObjs } from "~/store";
import { bus, fsRemove, handleRespWithNotifySuccess } from "~/utils";
} from "@hope-ui/solid"
import { onCleanup } from "solid-js"
import { useFetch, usePath, useRouter, useT } from "~/hooks"
import { selectedObjs } from "~/store"
import { bus, fsRemove, handleRespWithNotifySuccess } from "~/utils"
export const Delete = () => {
const t = useT();
const { isOpen, onOpen, onClose } = createDisclosure();
const [loading, ok] = useFetch(fsRemove);
const { refresh } = usePath();
const { pathname } = useRouter();
const t = useT()
const { isOpen, onOpen, onClose } = createDisclosure()
const [loading, ok] = useFetch(fsRemove)
const { refresh } = usePath()
const { pathname } = useRouter()
const handler = (name: string) => {
if (name === "delete") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<Modal
blockScrollOnMount={false}
@@ -55,11 +55,11 @@ export const Delete = () => {
const resp = await ok(
pathname(),
selectedObjs().map((obj) => obj.name)
);
)
handleRespWithNotifySuccess(resp, () => {
refresh();
onClose();
});
refresh()
onClose()
})
}}
>
{t("global.confirm")}
@@ -67,5 +67,5 @@ export const Delete = () => {
</ModalFooter>
</ModalContent>
</Modal>
);
};
)
}

View File

@@ -11,19 +11,19 @@ import {
ModalHeader,
ModalOverlay,
createDisclosure,
} from "@hope-ui/solid";
import { createSignal, lazy, onCleanup, Show, Suspense } from "solid-js";
import { FullLoading } from "~/components";
import { useT, useDownload } from "~/hooks";
import { getSettingBool, me } from "~/store";
import { UserMethods } from "~/types";
import { bus } from "~/utils";
import { CenterIcon } from "./Icon";
} from "@hope-ui/solid"
import { createSignal, lazy, onCleanup, Show, Suspense } from "solid-js"
import { FullLoading } from "~/components"
import { useT, useDownload } from "~/hooks"
import { getSettingBool, me } from "~/store"
import { UserMethods } from "~/types"
import { bus } from "~/utils"
import { CenterIcon } from "./Icon"
export const Download = () => {
const t = useT();
const colorScheme = "neutral";
const { batchDownloadSelected, sendToAria2 } = useDownload();
const t = useT()
const colorScheme = "neutral"
const { batchDownloadSelected, sendToAria2 } = useDownload()
return (
<Menu placement="top" offset={10}>
<MenuTrigger as={CenterIcon} name="download" />
@@ -39,7 +39,7 @@ export const Download = () => {
<MenuItem
colorScheme={colorScheme}
onSelect={() => {
bus.emit("tool", "package_download");
bus.emit("tool", "package_download")
}}
>
{t("home.toolbar.package_download")}
@@ -50,24 +50,24 @@ export const Download = () => {
</MenuItem>
</MenuContent>
</Menu>
);
};
)
}
const PackageDownload = lazy(() => import("./PackageDownload"));
const PackageDownload = lazy(() => import("./PackageDownload"))
export const PackageDownloadModal = () => {
const t = useT();
const t = useT()
const handler = (name: string) => {
if (name === "package_download") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
const { isOpen, onOpen, onClose } = createDisclosure();
const [show, setShow] = createSignal("pre_tips");
bus.off("tool", handler)
})
const { isOpen, onOpen, onClose } = createDisclosure()
const [show, setShow] = createSignal("pre_tips")
return (
<Modal
blockScrollOnMount={false}
@@ -98,7 +98,7 @@ export const PackageDownloadModal = () => {
<Button
colorScheme="info"
onClick={() => {
setShow("package_download");
setShow("package_download")
}}
>
{t("global.confirm")}
@@ -108,5 +108,5 @@ export const PackageDownloadModal = () => {
</Suspense>
</ModalContent>
</Modal>
);
};
)
}

View File

@@ -1,19 +1,19 @@
import { ElementType, Icon, IconProps, Tooltip } from "@hope-ui/solid";
import { IconTypes } from "solid-icons";
import { useT } from "~/hooks";
import { getMainColor, me } from "~/store";
import { UserMethods, UserPermissions } from "~/types";
import { hoverColor } from "~/utils";
import { operations } from "./operations";
import { ElementType, Icon, IconProps, Tooltip } from "@hope-ui/solid"
import { IconTypes } from "solid-icons"
import { useT } from "~/hooks"
import { getMainColor, me } from "~/store"
import { UserMethods, UserPermissions } from "~/types"
import { hoverColor } from "~/utils"
import { operations } from "./operations"
export const CenterIcon = <C extends ElementType = "svg">(
props: IconProps<C> & {
name: string;
name: string
}
) => {
const index = UserPermissions.findIndex((p) => p === props.name);
if (index !== -1 && !UserMethods.can(me(), index)) return null;
const t = useT();
const index = UserPermissions.findIndex((p) => p === props.name)
if (index !== -1 && !UserMethods.can(me(), index)) return null
const t = useT()
return (
<Tooltip placement="top" withArrow label={t(`home.toolbar.${props.name}`)}>
<Icon
@@ -37,16 +37,16 @@ export const CenterIcon = <C extends ElementType = "svg">(
{...props}
/>
</Tooltip>
);
};
)
}
export const RightIcon = <C extends ElementType = "svg">(
props: IconProps<C> & {
tips?: string;
icon?: IconTypes;
tips?: string
icon?: IconTypes
}
) => {
const t = useT();
const t = useT()
return (
<Tooltip
disabled={!props.tips}
@@ -76,8 +76,8 @@ export const RightIcon = <C extends ElementType = "svg">(
{...props}
/>
</Tooltip>
);
};
)
}
// export const ToolIcon = <C extends ElementType = "button">(
// props: IconButtonProps<C>

View File

@@ -12,40 +12,40 @@ import {
HStack,
Input,
VStack,
} from "@hope-ui/solid";
import { For, onCleanup } from "solid-js";
import { SwitchLanguageWhite, SwitchColorMode } from "~/components";
import { useT } from "~/hooks";
import { initialLocalSettings, local, setLocal } from "~/store";
import { bus } from "~/utils";
} from "@hope-ui/solid"
import { For, onCleanup } from "solid-js"
import { SwitchLanguageWhite, SwitchColorMode } from "~/components"
import { useT } from "~/hooks"
import { initialLocalSettings, local, setLocal } from "~/store"
import { bus } from "~/utils"
const LocalSettingsInput = (props: { name: string }) => {
const t = useT();
const t = useT()
return (
<FormControl>
<FormLabel>{t(`home.local_settings.${props.name}`)}</FormLabel>
<Input
value={local[props.name]}
onInput={(e) => {
setLocal(props.name, e.currentTarget.value);
setLocal(props.name, e.currentTarget.value)
}}
/>
</FormControl>
);
};
)
}
export const LocalSettings = () => {
const { isOpen, onOpen, onClose } = createDisclosure();
const t = useT();
const { isOpen, onOpen, onClose } = createDisclosure()
const t = useT()
const handler = (name: string) => {
if (name === "local_settings") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<Drawer opened={isOpen()} placement="right" onClose={onClose}>
<DrawerOverlay />
@@ -69,5 +69,5 @@ export const LocalSettings = () => {
</DrawerBody>
</DrawerContent>
</Drawer>
);
};
)
}

View File

@@ -1,23 +1,23 @@
import { createDisclosure } from "@hope-ui/solid";
import { ModalInput } from "~/components";
import { useFetch, usePath, useRouter } from "~/hooks";
import { bus, fsMkdir, handleRespWithNotifySuccess, pathJoin } from "~/utils";
import { onCleanup } from "solid-js";
import { createDisclosure } from "@hope-ui/solid"
import { ModalInput } from "~/components"
import { useFetch, usePath, useRouter } from "~/hooks"
import { bus, fsMkdir, handleRespWithNotifySuccess, pathJoin } from "~/utils"
import { onCleanup } from "solid-js"
export const Mkdir = () => {
const { isOpen, onOpen, onClose } = createDisclosure();
const [loading, ok] = useFetch(fsMkdir);
const { pathname } = useRouter();
const { refresh } = usePath();
const { isOpen, onOpen, onClose } = createDisclosure()
const [loading, ok] = useFetch(fsMkdir)
const { pathname } = useRouter()
const { refresh } = usePath()
const handler = (name: string) => {
if (name === "mkdir") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<ModalInput
title="home.toolbar.input_dir_name"
@@ -25,12 +25,12 @@ export const Mkdir = () => {
onClose={onClose}
loading={loading()}
onSubmit={async (name) => {
const resp = await ok(pathJoin(pathname(), name));
const resp = await ok(pathJoin(pathname(), name))
handleRespWithNotifySuccess(resp, () => {
refresh();
onClose();
});
refresh()
onClose()
})
}}
/>
);
};
)
}

View File

@@ -6,29 +6,29 @@ import {
ModalOverlay,
createDisclosure,
ModalCloseButton,
} from "@hope-ui/solid";
import { JSXElement, onCleanup, Show, Suspense } from "solid-js";
import { FullLoading } from "~/components";
import { useT } from "~/hooks";
import { bus } from "~/utils";
} from "@hope-ui/solid"
import { JSXElement, onCleanup, Show, Suspense } from "solid-js"
import { FullLoading } from "~/components"
import { useT } from "~/hooks"
import { bus } from "~/utils"
export const ModalWrapper = (props: {
children: JSXElement;
name: string;
title: string;
blockScrollOnMount?: boolean;
children: JSXElement
name: string
title: string
blockScrollOnMount?: boolean
}) => {
const t = useT();
const t = useT()
const handler = (name: string) => {
if (name === props.name) {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
const { isOpen, onOpen, onClose } = createDisclosure();
bus.off("tool", handler)
})
const { isOpen, onOpen, onClose } = createDisclosure()
return (
<Modal
blockScrollOnMount={props.blockScrollOnMount}
@@ -55,5 +55,5 @@ export const ModalWrapper = (props: {
</ModalBody>
</ModalContent>
</Modal>
);
};
)
}

View File

@@ -1,29 +1,24 @@
import { createDisclosure } from "@hope-ui/solid";
import { onCleanup } from "solid-js";
import { ModalInput } from "~/components";
import { useFetch, usePath, useRouter } from "~/hooks";
import { password } from "~/store";
import {
bus,
fsNewFile,
handleRespWithNotifySuccess,
pathJoin,
} from "~/utils";
import { createDisclosure } from "@hope-ui/solid"
import { onCleanup } from "solid-js"
import { ModalInput } from "~/components"
import { useFetch, usePath, useRouter } from "~/hooks"
import { password } from "~/store"
import { bus, fsNewFile, handleRespWithNotifySuccess, pathJoin } from "~/utils"
export const NewFile = () => {
const { isOpen, onOpen, onClose } = createDisclosure();
const [loading, ok] = useFetch(fsNewFile);
const { refresh } = usePath();
const { pathname } = useRouter();
const { isOpen, onOpen, onClose } = createDisclosure()
const [loading, ok] = useFetch(fsNewFile)
const { refresh } = usePath()
const { pathname } = useRouter()
const handler = (name: string) => {
if (name === "new_file") {
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<ModalInput
title="home.toolbar.input_filename"
@@ -31,12 +26,12 @@ export const NewFile = () => {
onClose={onClose}
loading={loading()}
onSubmit={async (name) => {
const resp = await ok(pathJoin(pathname(), name), password());
const resp = await ok(pathJoin(pathname(), name), password())
handleRespWithNotifySuccess(resp, () => {
refresh();
onClose();
});
refresh()
onClose()
})
}}
/>
);
};
)
}

View File

@@ -1,35 +1,35 @@
import { createDisclosure } from "@hope-ui/solid";
import { onCleanup, Show } from "solid-js";
import { ModalInput } from "~/components";
import { useFetch, usePath, useRouter, useT } from "~/hooks";
import { oneChecked, selectedObjs } from "~/store";
import { createDisclosure } from "@hope-ui/solid"
import { onCleanup, Show } from "solid-js"
import { ModalInput } from "~/components"
import { useFetch, usePath, useRouter, useT } from "~/hooks"
import { oneChecked, selectedObjs } from "~/store"
import {
bus,
fsRename,
handleRespWithNotifySuccess,
notify,
pathJoin,
} from "~/utils";
} from "~/utils"
export const Rename = () => {
const { isOpen, onOpen, onClose } = createDisclosure();
const t = useT();
const [loading, ok] = useFetch(fsRename);
const { pathname } = useRouter();
const { refresh } = usePath();
const { isOpen, onOpen, onClose } = createDisclosure()
const t = useT()
const [loading, ok] = useFetch(fsRename)
const { pathname } = useRouter()
const { refresh } = usePath()
const handler = (name: string) => {
if (name === "rename") {
if (!oneChecked()) {
notify.warning(t("home.toolbar.only_one-tips"));
return;
notify.warning(t("home.toolbar.only_one-tips"))
return
}
onOpen();
onOpen()
}
};
bus.on("tool", handler);
}
bus.on("tool", handler)
onCleanup(() => {
bus.off("tool", handler);
});
bus.off("tool", handler)
})
return (
<Show when={isOpen()}>
<ModalInput
@@ -42,13 +42,13 @@ export const Rename = () => {
const resp = await ok(
pathJoin(pathname(), selectedObjs()[0].name),
name
);
)
handleRespWithNotifySuccess(resp, () => {
refresh();
onClose();
});
refresh()
onClose()
})
}}
/>
</Show>
);
};
)
}

View File

@@ -3,29 +3,29 @@ import {
createDisclosure,
useColorModeValue,
VStack,
} from "@hope-ui/solid";
import { createMemo, Show } from "solid-js";
import { RightIcon } from "./Icon";
import { CgMoreO } from "solid-icons/cg";
import { TbCheckbox } from "solid-icons/tb";
import { objStore, State, toggleCheckbox, userCan } from "~/store";
import { bus } from "~/utils";
import { operations } from "./operations";
import { IoMagnetOutline } from "solid-icons/io";
import { AiOutlineCloudUpload, AiOutlineSetting } from "solid-icons/ai";
import { RiSystemRefreshLine } from "solid-icons/ri";
import { usePath } from "~/hooks";
import { Motion } from "@motionone/solid";
} from "@hope-ui/solid"
import { createMemo, Show } from "solid-js"
import { RightIcon } from "./Icon"
import { CgMoreO } from "solid-icons/cg"
import { TbCheckbox } from "solid-icons/tb"
import { objStore, State, toggleCheckbox, userCan } from "~/store"
import { bus } from "~/utils"
import { operations } from "./operations"
import { IoMagnetOutline } from "solid-icons/io"
import { AiOutlineCloudUpload, AiOutlineSetting } from "solid-icons/ai"
import { RiSystemRefreshLine } from "solid-icons/ri"
import { usePath } from "~/hooks"
import { Motion } from "@motionone/solid"
export const Right = () => {
const { isOpen, onToggle } = createDisclosure({
defaultIsOpen: localStorage.getItem("more-open") === "true",
onClose: () => localStorage.setItem("more-open", "false"),
onOpen: () => localStorage.setItem("more-open", "true"),
});
const margin = createMemo(() => (isOpen() ? "$4" : "$5"));
const isFolder = createMemo(() => objStore.state === State.Folder);
const { refresh } = usePath();
})
const margin = createMemo(() => (isOpen() ? "$4" : "$5"))
const isFolder = createMemo(() => objStore.state === State.Folder)
const { refresh } = usePath()
return (
<Box
class="left-toolbar-box"
@@ -40,7 +40,7 @@ export const Right = () => {
class="toolbar-toggle"
as={CgMoreO}
onClick={() => {
onToggle();
onToggle()
}}
/>
}
@@ -67,14 +67,14 @@ export const Right = () => {
as={RiSystemRefreshLine}
tips="refresh"
onClick={() => {
refresh(undefined, true);
refresh(undefined, true)
}}
/>
<RightIcon
as={operations.new_file.icon}
tips="new_file"
onClick={() => {
bus.emit("tool", "new_file");
bus.emit("tool", "new_file")
}}
/>
<RightIcon
@@ -82,14 +82,14 @@ export const Right = () => {
p="$1_5"
tips="mkdir"
onClick={() => {
bus.emit("tool", "mkdir");
bus.emit("tool", "mkdir")
}}
/>
<RightIcon
as={AiOutlineCloudUpload}
tips="upload"
onClick={() => {
bus.emit("tool", "upload");
bus.emit("tool", "upload")
}}
/>
</Show>
@@ -99,7 +99,7 @@ export const Right = () => {
pl="0"
tips="offline_download"
onClick={() => {
bus.emit("tool", "offline_download");
bus.emit("tool", "offline_download")
}}
/>
</Show>
@@ -112,7 +112,7 @@ export const Right = () => {
as={AiOutlineSetting}
tips="local_settings"
onClick={() => {
bus.emit("tool", "local_settings");
bus.emit("tool", "local_settings")
}}
/>
</VStack>
@@ -120,5 +120,5 @@ export const Right = () => {
</VStack>
</Show>
</Box>
);
};
)
}

View File

@@ -1,17 +1,17 @@
import { Portal } from "solid-js/web";
import { Center } from "./Center";
import { Right } from "./Right";
import { Copy, Move } from "./CopyMove";
import { Delete } from "./Delete";
import { Rename } from "./Rename";
import { NewFile } from "./NewFile";
import { Mkdir } from "./Mkdir";
import { Aria2 } from "./Aria2";
import { PackageDownloadModal } from "./Download";
import { lazy } from "solid-js";
import { ModalWrapper } from "./ModalWrapper";
import { LocalSettings } from "./LocalSettings";
const Upload = lazy(() => import("../uploads/Upload"));
import { Portal } from "solid-js/web"
import { Center } from "./Center"
import { Right } from "./Right"
import { Copy, Move } from "./CopyMove"
import { Delete } from "./Delete"
import { Rename } from "./Rename"
import { NewFile } from "./NewFile"
import { Mkdir } from "./Mkdir"
import { Aria2 } from "./Aria2"
import { PackageDownloadModal } from "./Download"
import { lazy } from "solid-js"
import { ModalWrapper } from "./ModalWrapper"
import { LocalSettings } from "./LocalSettings"
const Upload = lazy(() => import("../uploads/Upload"))
export const Modal = () => {
return (
@@ -29,8 +29,8 @@ export const Modal = () => {
</ModalWrapper>
<LocalSettings />
</>
);
};
)
}
export const Toolbar = () => {
return (
@@ -39,5 +39,5 @@ export const Toolbar = () => {
<Center />
<Modal />
</Portal>
);
};
)
}

View File

@@ -1,18 +1,18 @@
import { IconTypes } from "solid-icons";
import { TiDeleteOutline } from "solid-icons/ti";
import { CgRename } from "solid-icons/cg";
import { TbFileArrowRight } from "solid-icons/tb";
import { TbCopy, TbLink } from "solid-icons/tb";
import { AiTwotoneDelete } from "solid-icons/ai";
import { CgFileAdd, CgFolderAdd } from "solid-icons/cg";
import { AiOutlineCloudDownload } from "solid-icons/ai";
import { IconTypes } from "solid-icons"
import { TiDeleteOutline } from "solid-icons/ti"
import { CgRename } from "solid-icons/cg"
import { TbFileArrowRight } from "solid-icons/tb"
import { TbCopy, TbLink } from "solid-icons/tb"
import { AiTwotoneDelete } from "solid-icons/ai"
import { CgFileAdd, CgFolderAdd } from "solid-icons/cg"
import { AiOutlineCloudDownload } from "solid-icons/ai"
interface Operations {
[key: string]: {
icon: IconTypes;
color?: string;
p?: boolean;
};
icon: IconTypes
color?: string
p?: boolean
}
}
export const operations: Operations = {
rename: { icon: CgRename, color: "$accent9" },
@@ -24,7 +24,7 @@ export const operations: Operations = {
new_file: { icon: CgFileAdd, p: true },
cancel_select: { icon: TiDeleteOutline },
download: { icon: AiOutlineCloudDownload, color: "$primary9" },
};
}
// interface Operation {
// label: string;
// icon: IconTypes;

View File

@@ -1,10 +1,10 @@
import { mergeProps } from "solid-js";
import { mergeProps } from "solid-js"
interface Props {
/** 过渡的开始颜色 */
startColor?: string;
startColor?: string
/** 过渡的结束颜色 */
endColor?: string;
endColor?: string
}
const CornerBottom = (props: Props) => {
@@ -14,7 +14,7 @@ const CornerBottom = (props: Props) => {
endColor: "#120fc4",
},
props
);
)
return (
<svg
version="1.1"
@@ -43,7 +43,7 @@ const CornerBottom = (props: Props) => {
/>
</g>
</svg>
);
};
)
}
export default CornerBottom;
export default CornerBottom

View File

@@ -1,10 +1,10 @@
import { mergeProps } from "solid-js";
import { mergeProps } from "solid-js"
interface Props {
/** 过渡的开始颜色 */
startColor?: string;
startColor?: string
/** 过渡的结束颜色 */
endColor?: string;
endColor?: string
}
const CornerTop = (props: Props) => {
@@ -14,7 +14,7 @@ const CornerTop = (props: Props) => {
endColor: "#120fc4",
},
props
);
)
return (
<svg height="1337" width="1337">
<defs>
@@ -43,7 +43,7 @@ const CornerTop = (props: Props) => {
/>
</g>
</svg>
);
};
)
}
export default CornerTop;
export default CornerTop

View File

@@ -1,9 +1,9 @@
import { Box, useColorModeValue } from "@hope-ui/solid";
import CornerBottom from "./CornerBottom";
import CornerTop from "./CornerTop";
import { Box, useColorModeValue } from "@hope-ui/solid"
import CornerBottom from "./CornerBottom"
import CornerTop from "./CornerTop"
const LoginBg = () => {
const bgColor = useColorModeValue("#a9c6ff", "#062b74");
const bgColor = useColorModeValue("#a9c6ff", "#062b74")
return (
<Box
bgColor={bgColor()}
@@ -42,7 +42,7 @@ const LoginBg = () => {
<CornerBottom />
</Box>
</Box>
);
};
)
}
export default LoginBg;
export default LoginBg

View File

@@ -1,18 +1,18 @@
import { createResource } from "solid-js";
import { Markdown, MaybeLoading } from "~/components";
import { createResource } from "solid-js"
import { Markdown, MaybeLoading } from "~/components"
const fetchReadme = async () =>
await (
await fetch("https://jsd.nn.ci/gh/alist-org/alist@main/README.md")
).text();
).text()
const About = () => {
const [readme] = createResource(fetchReadme);
const [readme] = createResource(fetchReadme)
return (
<MaybeLoading loading={readme.loading}>
<Markdown children={readme()} />
</MaybeLoading>
);
};
)
}
export default About;
export default About

View File

@@ -1,13 +1,13 @@
import { Center, Heading } from "@hope-ui/solid";
import { useManageTitle } from "~/hooks";
import { Center, Heading } from "@hope-ui/solid"
import { useManageTitle } from "~/hooks"
const Dashboard = () => {
useManageTitle("manage.sidemenu.dashboard");
useManageTitle("manage.sidemenu.dashboard")
return (
<Center h="$full">
<Heading>Dashboard</Heading>
</Center>
);
};
)
}
export default Dashboard;
export default Dashboard

View File

@@ -13,19 +13,19 @@ import {
HStack,
IconButton,
useColorModeValue,
} from "@hope-ui/solid";
import { TiThMenu } from "solid-icons/ti";
import { IoExit } from "solid-icons/io";
import { SwitchColorMode, SwitchLanguageWhite } from "~/components";
import { useRouter, useT } from "~/hooks";
import { SideMenu } from "./SideMenu";
import { side_menu_items } from "./sidemenu_items";
import { changeToken, notify } from "~/utils";
const { isOpen, onOpen, onClose } = createDisclosure();
} from "@hope-ui/solid"
import { TiThMenu } from "solid-icons/ti"
import { IoExit } from "solid-icons/io"
import { SwitchColorMode, SwitchLanguageWhite } from "~/components"
import { useRouter, useT } from "~/hooks"
import { SideMenu } from "./SideMenu"
import { side_menu_items } from "./sidemenu_items"
import { changeToken, notify } from "~/utils"
const { isOpen, onOpen, onClose } = createDisclosure()
const Header = () => {
const t = useT();
const { to } = useRouter();
const t = useT()
const { to } = useRouter()
return (
<Box
as="header"
@@ -54,7 +54,7 @@ const Header = () => {
color="$info9"
cursor="pointer"
onClick={() => {
to("/@manage");
to("/@manage")
}}
>
{t("manage.title")}
@@ -65,9 +65,9 @@ const Header = () => {
aria-label="logout"
icon={<IoExit />}
onClick={() => {
changeToken();
notify.success(t("manage.logout_success"));
to(`/@login?redirect=${encodeURIComponent(location.pathname)}`);
changeToken()
notify.success(t("manage.logout_success"))
to(`/@login?redirect=${encodeURIComponent(location.pathname)}`)
}}
size="sm"
/>
@@ -90,7 +90,7 @@ const Header = () => {
</DrawerContent>
</Drawer>
</Box>
);
};
)
}
export { Header, onClose };
export { Header, onClose }

View File

@@ -1,36 +1,33 @@
import { Box, Flex, Heading, HStack, Icon, VStack } from "@hope-ui/solid";
import { createMemo, createSignal, For, Match, Show, Switch } from "solid-js";
import { useRouter, useT } from "~/hooks";
import { BiSolidRightArrow } from "solid-icons/bi";
import { onClose } from "./Header";
import { UserMethods, UserRole } from "~/types";
import { me } from "~/store";
import { AnchorWithBase } from "~/components";
import { Link } from "@solidjs/router";
import { hoverColor } from "~/utils";
import { IconTypes } from "solid-icons";
import { Box, Flex, Heading, HStack, Icon, VStack } from "@hope-ui/solid"
import { createMemo, createSignal, For, Match, Show, Switch } from "solid-js"
import { useRouter, useT } from "~/hooks"
import { BiSolidRightArrow } from "solid-icons/bi"
import { onClose } from "./Header"
import { UserMethods, UserRole } from "~/types"
import { me } from "~/store"
import { AnchorWithBase } from "~/components"
import { Link } from "@solidjs/router"
import { hoverColor } from "~/utils"
import { IconTypes } from "solid-icons"
export interface SideMenuItemProps {
title: string;
to: string;
icon?: IconTypes;
children?: SideMenuItemProps[];
role?: number;
external?: true;
title: string
to: string
icon?: IconTypes
children?: SideMenuItemProps[]
role?: number
external?: true
}
const SideMenuItem = (props: SideMenuItemProps) => {
const ifShow = createMemo(() => {
if (!UserMethods.is_admin(me())) {
if (props.role === undefined) return false;
else if (
props.role === UserRole.GENERAL &&
!UserMethods.is_general(me())
)
return false;
if (props.role === undefined) return false
else if (props.role === UserRole.GENERAL && !UserMethods.is_general(me()))
return false
}
return true;
});
return true
})
return (
<Switch fallback={<SideMenuItemWithTo {...props} />}>
<Match when={!ifShow()}>{null}</Match>
@@ -38,13 +35,13 @@ const SideMenuItem = (props: SideMenuItemProps) => {
<SideMenuItemWithChildren {...props} />
</Match>
</Switch>
);
};
)
}
const SideMenuItemWithTo = (props: SideMenuItemProps) => {
const { pathname } = useRouter();
const t = useT();
const isActive = () => pathname() === props.to;
const { pathname } = useRouter()
const t = useT()
const isActive = () => pathname() === props.to
return (
<AnchorWithBase
display="flex"
@@ -52,7 +49,7 @@ const SideMenuItemWithTo = (props: SideMenuItemProps) => {
href={props.to}
onClick={() => {
// to(props.to!);
onClose();
onClose()
}}
w="$full"
alignItems="center"
@@ -72,19 +69,19 @@ const SideMenuItemWithTo = (props: SideMenuItemProps) => {
<Show when={props.icon}>{<Icon mr="$2" as={props.icon} />}</Show>
<Heading>{t(props.title)}</Heading>
</AnchorWithBase>
);
};
)
}
const SideMenuItemWithChildren = (props: SideMenuItemProps) => {
const { pathname } = useRouter();
const [open, setOpen] = createSignal(pathname().includes(props.to));
const t = useT();
const { pathname } = useRouter()
const [open, setOpen] = createSignal(pathname().includes(props.to))
const t = useT()
return (
<Box w="$full">
<Flex
justifyContent="space-between"
onClick={() => {
setOpen(!open());
setOpen(!open())
}}
w="$full"
alignItems="center"
@@ -112,17 +109,17 @@ const SideMenuItemWithChildren = (props: SideMenuItemProps) => {
</Box>
</Show>
</Box>
);
};
)
}
export const SideMenu = (props: { items: SideMenuItemProps[] }) => {
return (
<VStack p="$2" w="$full" color="$neutral11" spacing="$1">
<For each={props.items}>
{(item) => {
return <SideMenuItem {...item} />;
return <SideMenuItem {...item} />
}}
</For>
</VStack>
);
};
)
}

View File

@@ -7,16 +7,16 @@ import {
PopoverHeader,
PopoverBody,
HStack,
} from "@hope-ui/solid";
import { useT } from "~/hooks";
} from "@hope-ui/solid"
import { useT } from "~/hooks"
export interface DeletePopoverProps {
name: string;
loading: boolean;
onClick: () => void;
name: string
loading: boolean
onClick: () => void
}
export const DeletePopover = (props: DeletePopoverProps) => {
const t = useT();
const t = useT()
return (
<Popover>
{({ onClose }) => (
@@ -49,5 +49,5 @@ export const DeletePopover = (props: DeletePopoverProps) => {
</>
)}
</Popover>
);
};
)
}

View File

@@ -1,5 +1,5 @@
import { Grid } from "@hope-ui/solid";
import { JSXElement } from "solid-js";
import { Grid } from "@hope-ui/solid"
import { JSXElement } from "solid-js"
export const ResponsiveGrid = (props: { children: JSXElement }) => {
return (
@@ -13,5 +13,5 @@ export const ResponsiveGrid = (props: { children: JSXElement }) => {
>
{props.children}
</Grid>
);
};
)
}

View File

@@ -1,20 +1,16 @@
import { Box, Center, Flex, HStack, useColorModeValue } from "@hope-ui/solid";
import {
FullLoading,
SwitchColorMode,
SwitchLanguageWhite,
} from "~/components";
import { useT, useTitle } from "~/hooks";
import { Header } from "./Header";
import { SideMenu } from "./SideMenu";
import { side_menu_items } from "./sidemenu_items";
import { Route, Routes } from "@solidjs/router";
import { For, Suspense } from "solid-js";
import { routes } from "./routes";
import { Box, Center, Flex, HStack, useColorModeValue } from "@hope-ui/solid"
import { FullLoading, SwitchColorMode, SwitchLanguageWhite } from "~/components"
import { useT, useTitle } from "~/hooks"
import { Header } from "./Header"
import { SideMenu } from "./SideMenu"
import { side_menu_items } from "./sidemenu_items"
import { Route, Routes } from "@solidjs/router"
import { For, Suspense } from "solid-js"
import { routes } from "./routes"
const Manage = () => {
const t = useT();
useTitle(() => t("manage.title"));
const t = useT()
useTitle(() => t("manage.title"))
return (
<Box
css={{
@@ -52,14 +48,14 @@ const Manage = () => {
<Routes>
<For each={routes}>
{(route) => {
return <Route path={route.to!} component={route.component} />;
return <Route path={route.to!} component={route.component} />
}}
</For>
</Routes>
</Box>
</Flex>
</Box>
);
};
)
}
export default Manage;
export default Manage

View File

@@ -1,10 +1,10 @@
import { Message } from "./Messenger";
import { Heading, Image } from "@hope-ui/solid";
import { Message } from "./Messenger"
import { Heading, Image } from "@hope-ui/solid"
export const StringShow = (props: Message) => {
return <Heading>{props.content}</Heading>;
};
return <Heading>{props.content}</Heading>
}
export const ImageShow = (props: Message) => {
return <Image src={props.content} />;
};
return <Image src={props.content} />
}

View File

@@ -9,35 +9,35 @@ import {
Thead,
Tr,
VStack,
} from "@hope-ui/solid";
import { createSignal, For } from "solid-js";
} from "@hope-ui/solid"
import { createSignal, For } from "solid-js"
import {
useFetch,
useListFetch,
useManageTitle,
useRouter,
useT,
} from "~/hooks";
import { handleResp, notify, r } from "~/utils";
import { Meta, PageResp } from "~/types";
import { DeletePopover } from "../common/DeletePopover";
import { Wether } from "~/components";
} from "~/hooks"
import { handleResp, notify, r } from "~/utils"
import { Meta, PageResp } from "~/types"
import { DeletePopover } from "../common/DeletePopover"
import { Wether } from "~/components"
const Metas = () => {
const t = useT();
useManageTitle("manage.sidemenu.metas");
const { to } = useRouter();
const [getMetasLoading, getMetas] = useFetch(() => r.get("/admin/meta/list"));
const [metas, setMetas] = createSignal<Meta[]>([]);
const t = useT()
useManageTitle("manage.sidemenu.metas")
const { to } = useRouter()
const [getMetasLoading, getMetas] = useFetch(() => r.get("/admin/meta/list"))
const [metas, setMetas] = createSignal<Meta[]>([])
const refresh = async () => {
const resp: PageResp<Meta> = await getMetas();
handleResp(resp, (data) => setMetas(data.content));
};
refresh();
const resp: PageResp<Meta> = await getMetas()
handleResp(resp, (data) => setMetas(data.content))
}
refresh()
const [deleting, deleteMeta] = useListFetch((id: number) =>
r.post(`/admin/meta/delete?id=${id}`)
);
)
return (
<VStack spacing="$2" alignItems="start" w="$full">
<HStack spacing="$2">
@@ -50,7 +50,7 @@ const Metas = () => {
</Button>
<Button
onClick={() => {
to("/@manage/metas/add");
to("/@manage/metas/add")
}}
>
{t("global.add")}
@@ -80,7 +80,7 @@ const Metas = () => {
<HStack spacing="$2">
<Button
onClick={() => {
to(`/@manage/metas/edit/${meta.id}`);
to(`/@manage/metas/edit/${meta.id}`)
}}
>
{t("global.edit")}
@@ -89,11 +89,11 @@ const Metas = () => {
name={meta.path}
loading={deleting() === meta.id}
onClick={async () => {
const resp = await deleteMeta(meta.id);
const resp = await deleteMeta(meta.id)
handleResp(resp, () => {
notify.success(t("global.delete_success"));
refresh();
});
notify.success(t("global.delete_success"))
refresh()
})
}}
/>
</HStack>
@@ -105,7 +105,7 @@ const Metas = () => {
</Table>
</Box>
</VStack>
);
};
)
}
export default Metas;
export default Metas

View File

@@ -1,10 +1,10 @@
import { lazy } from "solid-js";
import { Center, Heading } from "@hope-ui/solid";
import { trimLeft } from "~/utils";
import { SideMenuItem, side_menu_items } from "./sidemenu_items";
import { useManageTitle } from "~/hooks";
import { lazy } from "solid-js"
import { Center, Heading } from "@hope-ui/solid"
import { trimLeft } from "~/utils"
import { SideMenuItem, side_menu_items } from "./sidemenu_items"
import { useManageTitle } from "~/hooks"
type Route = Pick<SideMenuItem, "to" | "component">;
type Route = Pick<SideMenuItem, "to" | "component">
const hide_routes: Route[] = [
{
@@ -39,32 +39,32 @@ const hide_routes: Route[] = [
to: "/messenger",
component: lazy(() => import("./messenger/Messenger")),
},
];
]
const Placeholder = (props: { title: string; to: string }) => {
useManageTitle(props.title);
useManageTitle(props.title)
return (
<Center h="$full">
<Heading>{props.title}</Heading>
</Center>
);
};
)
}
const get_routes = (items: SideMenuItem[], acc: Route[] = []) => {
items.forEach((item) => {
if (item.children) {
get_routes(item.children, acc);
get_routes(item.children, acc)
} else {
acc.push({
to: trimLeft(item.to!, "/@manage"),
component:
item.component ||
(() => <Placeholder title={item.title} to={item.to || "empty"} />),
});
})
}
})
return acc
}
});
return acc;
};
const routes = get_routes(side_menu_items).concat(hide_routes);
export { routes };
const routes = get_routes(side_menu_items).concat(hide_routes)
export { routes }

View File

@@ -16,36 +16,36 @@ import {
SelectValue,
Switch as HopeSwitch,
Textarea,
} from "@hope-ui/solid";
import { For, Match, Show, Switch } from "solid-js";
import { useT } from "~/hooks";
import { DriverItem, Type } from "~/types";
} from "@hope-ui/solid"
import { For, Match, Show, Switch } from "solid-js"
import { useT } from "~/hooks"
import { DriverItem, Type } from "~/types"
export type ItemProps = DriverItem & {
readonly?: boolean;
full_name_path?: string;
options_prefix?: string;
driver?: string;
readonly?: boolean
full_name_path?: string
options_prefix?: string
driver?: string
} & (
| {
type: Type.Bool;
onChange?: (value: boolean) => void;
value: boolean;
type: Type.Bool
onChange?: (value: boolean) => void
value: boolean
}
| {
type: Type.Number;
onChange?: (value: number) => void;
value: number;
type: Type.Number
onChange?: (value: number) => void
value: number
}
| {
type: Type.String | Type.Text | Type.Select;
onChange?: (value: string) => void;
value: string;
type: Type.String | Type.Text | Type.Select
onChange?: (value: string) => void
value: string
}
);
)
const Item = (props: ItemProps) => {
const t = useT();
const t = useT()
return (
<FormControl
w="$full"
@@ -159,7 +159,7 @@ const Item = (props: ItemProps) => {
</FormHelperText>
</Show>
</FormControl>
);
};
)
}
export { Item };
export { Item }

View File

@@ -1,11 +1,6 @@
import { Button, Grid, HStack, VStack } from "@hope-ui/solid"
import { createSignal, For } from "solid-js"
import {
useFetch,
useManageTitle,
useRouter,
useT,
} from "~/hooks"
import { useFetch, useManageTitle, useRouter, useT } from "~/hooks"
import { handleResp, r } from "~/utils"
import { PageResp, Storage } from "~/types"
import { StorageC } from "./Storage"

View File

@@ -1,15 +1,15 @@
import { VStack } from "@hope-ui/solid";
import { useManageTitle } from "~/hooks";
import { TypeTasks } from "./Tasks";
import { VStack } from "@hope-ui/solid"
import { useManageTitle } from "~/hooks"
import { TypeTasks } from "./Tasks"
const Aria2 = () => {
useManageTitle("manage.sidemenu.aria2");
useManageTitle("manage.sidemenu.aria2")
return (
<VStack w="$full" alignItems="start" spacing="$4">
<TypeTasks type="down" />
<TypeTasks type="transfer" />
</VStack>
);
};
)
}
export default Aria2;
export default Aria2

View File

@@ -1,9 +1,9 @@
import { useManageTitle } from "~/hooks";
import { TypeTasks } from "./Tasks";
import { useManageTitle } from "~/hooks"
import { TypeTasks } from "./Tasks"
const Copy = () => {
useManageTitle("manage.sidemenu.copy");
return <TypeTasks type="copy" />;
};
useManageTitle("manage.sidemenu.copy")
return <TypeTasks type="copy" />
}
export default Copy;
export default Copy

View File

@@ -11,13 +11,7 @@ import {
import { MaybeLoading, FolderChooseInput } from "~/components"
import { useFetch, useRouter, useT } from "~/hooks"
import { handleResp, notify, r } from "~/utils"
import {
PEmptyResp,
PResp,
User,
UserMethods,
UserPermissions,
} from "~/types"
import { PEmptyResp, PResp, User, UserMethods, UserPermissions } from "~/types"
import { createStore } from "solid-js/store"
import { For } from "solid-js"

View File

@@ -1,5 +1,5 @@
import { Box, VStack } from "@hope-ui/solid";
import Upload from "~/pages/home/uploads/Upload";
import { Box, VStack } from "@hope-ui/solid"
import Upload from "~/pages/home/uploads/Upload"
const Index = () => {
return (
@@ -8,7 +8,7 @@ const Index = () => {
<Upload />
</Box>
</VStack>
);
};
)
}
export default Index;
export default Index

View File

@@ -1,8 +1,8 @@
export const keyPressed: Record<string, boolean> = {};
export const keyPressed: Record<string, boolean> = {}
document.addEventListener("keydown", (e) => {
keyPressed[e.key] = true;
});
keyPressed[e.key] = true
})
document.addEventListener("keyup", (e) => {
// keyPressed[e.key] = false;
delete keyPressed[e.key];
});
delete keyPressed[e.key]
})

View File

@@ -1,22 +1,22 @@
import { createLocalStorage } from "@solid-primitives/storage";
import { createLocalStorage } from "@solid-primitives/storage"
const [local, setLocal, { remove, clear, toJSON }] = createLocalStorage();
const [local, setLocal, { remove, clear, toJSON }] = createLocalStorage()
export function isValidKey(
key: string | number | symbol,
object: object
): key is keyof typeof object {
return key in object;
return key in object
}
export const initialLocalSettings = {
aria2_rpc_url: "http://localhost:6800/jsonrpc",
aria2_rpc_secret: "",
// aria2_dir: "alist",
};
}
for (const key in initialLocalSettings) {
if (!local[key] && isValidKey(key, initialLocalSettings)) {
setLocal(key, initialLocalSettings[key]);
setLocal(key, initialLocalSettings[key])
}
}
export { local, setLocal, remove, clear, toJSON };
export { local, setLocal, remove, clear, toJSON }

View File

@@ -1,9 +1,9 @@
import { cookieStorage, createStorageSignal } from "@solid-primitives/storage";
import { createSignal } from "solid-js";
import { createStore, produce } from "solid-js/store";
import { Obj, StoreObj } from "~/types";
import { log } from "~/utils";
import { keyPressed } from "./key-event";
import { cookieStorage, createStorageSignal } from "@solid-primitives/storage"
import { createSignal } from "solid-js"
import { createStore, produce } from "solid-js/store"
import { Obj, StoreObj } from "~/types"
import { log } from "~/utils"
import { keyPressed } from "./key-event"
export enum State {
Initial, // Initial state
@@ -16,20 +16,20 @@ export enum State {
}
const [objStore, setObjStore] = createStore<{
obj: Obj;
raw_url: string;
related: Obj[];
obj: Obj
raw_url: string
related: Obj[]
objs: StoreObj[];
total: number;
write?: boolean;
objs: StoreObj[]
total: number
write?: boolean
readme: string;
provider: string;
readme: string
provider: string
// pageIndex: number;
// pageSize: number;
state: State;
err: string;
state: State
err: string
}>({
obj: {} as Obj,
raw_url: "",
@@ -44,30 +44,30 @@ const [objStore, setObjStore] = createStore<{
// pageSize: 50,
state: State.Initial,
err: "",
});
})
const [selectedNum, setSelectedNum] = createSignal(0);
const [selectedNum, setSelectedNum] = createSignal(0)
const setObjs = (objs: Obj[]) => {
setSelectedNum(0);
lastChecked = { index: -1, selected: false };
setObjStore("objs", objs);
setObjStore("obj", "is_dir", true);
};
setSelectedNum(0)
lastChecked = { index: -1, selected: false }
setObjStore("objs", objs)
setObjStore("obj", "is_dir", true)
}
export const ObjStore = {
setObj: (obj: Obj) => {
setObjStore("obj", obj);
setObjStore("obj", obj)
},
setRawUrl: (raw_url: string) => {
setObjStore("raw_url", raw_url);
setObjStore("raw_url", raw_url)
},
setProvider: (provider: string) => {
setObjStore("provider", provider);
setObjStore("provider", provider)
},
setObjs: setObjs,
setTotal: (total: number) => {
setObjStore("total", total);
setObjStore("total", total)
},
setReadme: (readme: string) => setObjStore("readme", readme),
setRelated: (related: Obj[]) => setObjStore("related", related),
@@ -84,35 +84,35 @@ export const ObjStore = {
// },
setState: (state: State) => setObjStore("state", state),
setErr: (err: string) => setObjStore("err", err),
};
}
export type OrderBy = "name" | "size" | "modified";
export type OrderBy = "name" | "size" | "modified"
export const sortObjs = (orderBy: OrderBy, reverse?: boolean) => {
log("sort:", orderBy, reverse);
log("sort:", orderBy, reverse)
setObjStore(
"objs",
produce((objs) =>
objs.sort((a, b) => {
if (a[orderBy] < b[orderBy]) return reverse ? 1 : -1;
if (a[orderBy] > b[orderBy]) return reverse ? -1 : 1;
return 0;
if (a[orderBy] < b[orderBy]) return reverse ? 1 : -1
if (a[orderBy] > b[orderBy]) return reverse ? -1 : 1
return 0
})
)
);
};
)
}
export const appendObjs = (objs: Obj[]) => {
setObjStore(
"objs",
produce((prev) => prev.push(...objs))
);
};
)
}
let lastChecked = {
index: -1,
selected: false,
};
}
export const selectIndex = (index: number, checked: boolean, one?: boolean) => {
if (
@@ -120,80 +120,80 @@ export const selectIndex = (index: number, checked: boolean, one?: boolean) => {
lastChecked.index !== -1 &&
lastChecked.selected === checked
) {
const start = Math.min(lastChecked.index, index);
const end = Math.max(lastChecked.index, index);
const start = Math.min(lastChecked.index, index)
const end = Math.max(lastChecked.index, index)
const curCheckedNum = objStore.objs
.slice(start, end + 1)
.filter((o) => o.selected).length;
.filter((o) => o.selected).length
setObjStore("objs", { from: start, to: end }, () => ({
selected: checked,
}));
}))
// update selected num
const newSelectedNum =
selectedNum() - curCheckedNum + (checked ? end - start + 1 : 0);
setSelectedNum(newSelectedNum);
selectedNum() - curCheckedNum + (checked ? end - start + 1 : 0)
setSelectedNum(newSelectedNum)
} else {
setObjStore(
"objs",
index,
produce((obj) => {
if (obj.selected !== checked) {
setSelectedNum(checked ? selectedNum() + 1 : selectedNum() - 1);
setSelectedNum(checked ? selectedNum() + 1 : selectedNum() - 1)
}
obj.selected = checked;
obj.selected = checked
})
);
)
}
lastChecked = { index, selected: checked }
one && setSelectedNum(checked ? 1 : 0)
}
lastChecked = { index, selected: checked };
one && setSelectedNum(checked ? 1 : 0);
};
export const selectAll = (checked: boolean) => {
setSelectedNum(checked ? objStore.objs.length : 0);
setObjStore("objs", {}, (obj) => ({ selected: checked }));
};
setSelectedNum(checked ? objStore.objs.length : 0)
setObjStore("objs", {}, (obj) => ({ selected: checked }))
}
export const selectedObjs = () => {
return objStore.objs.filter((obj) => obj.selected);
};
return objStore.objs.filter((obj) => obj.selected)
}
export const allChecked = () => {
return objStore.objs.length === selectedNum();
};
return objStore.objs.length === selectedNum()
}
export const oneChecked = () => {
return selectedNum() === 1;
};
return selectedNum() === 1
}
export const haveSelected = () => {
return selectedNum() > 0;
};
return selectedNum() > 0
}
export const isIndeterminate = () => {
return selectedNum() > 0 && selectedNum() < objStore.objs.length;
};
return selectedNum() > 0 && selectedNum() < objStore.objs.length
}
export type Layout = "list" | "grid";
const [layout, setLayout] = createStorageSignal<Layout>("layout", "list");
export type Layout = "list" | "grid"
const [layout, setLayout] = createStorageSignal<Layout>("layout", "list")
const [_checkboxOpen, setCheckboxOpen] = createStorageSignal<string>(
"checkbox-open",
"false"
);
export const checkboxOpen = () => _checkboxOpen() === "true";
)
export const checkboxOpen = () => _checkboxOpen() === "true"
export const toggleCheckbox = () => {
setCheckboxOpen(checkboxOpen() ? "false" : "true");
};
setCheckboxOpen(checkboxOpen() ? "false" : "true")
}
export { objStore, layout, setLayout };
export { objStore, layout, setLayout }
// browser password
const [_password, _setPassword] = createSignal<string>(
cookieStorage.getItem("browser-password") || ""
);
export { _password as password };
)
export { _password as password }
export const setPassword = (password: string) => {
_setPassword(password);
cookieStorage.setItem("browser-password", password);
};
_setPassword(password)
cookieStorage.setItem("browser-password", password)
}

View File

@@ -1,21 +1,21 @@
import { Type } from ".";
import { Type } from "."
export interface DriverItem {
name: string;
type: Type;
default: string;
options: string;
required?: boolean;
help?: string;
name: string
type: Type
default: string
options: string
required?: boolean
help?: string
}
export interface DriverConfig {
name: string;
local_sort: boolean;
only_local: boolean;
only_proxy: boolean;
no_cache: boolean;
no_upload: boolean;
need_ms: boolean;
default_root: string;
name: string
local_sort: boolean
only_local: boolean
only_proxy: boolean
no_cache: boolean
no_upload: boolean
need_ms: boolean
default_root: string
}

View File

@@ -1,9 +1,9 @@
export * from "./obj";
export * from "./resp";
export * from "./setting";
export * from "./storage";
export * from "./user";
export * from "./driver_item";
export * from "./item_type";
export * from "./meta";
export * from "./task";
export * from "./obj"
export * from "./resp"
export * from "./setting"
export * from "./storage"
export * from "./user"
export * from "./driver_item"
export * from "./item_type"
export * from "./meta"
export * from "./task"

View File

@@ -1,13 +1,12 @@
export interface Meta {
id: number;
path: string;
password: string;
p_sub: boolean;
write: boolean;
w_sub: boolean;
hide: string;
h_sub: boolean;
readme: string;
r_sub: boolean;
id: number
path: string
password: string
p_sub: boolean
write: boolean
w_sub: boolean
hide: string
h_sub: boolean
readme: string
r_sub: boolean
}

View File

@@ -9,16 +9,16 @@ export enum ObjType {
}
export interface Obj {
name: string;
size: number;
is_dir: boolean;
modified: string;
sign?: string;
thumb: string;
type: ObjType;
name: string
size: number
is_dir: boolean
modified: string
sign?: string
thumb: string
type: ObjType
path: string
}
export type StoreObj = Obj & {
selected?: boolean;
};
selected?: boolean
}

View File

@@ -1,4 +1,4 @@
import { Type } from ".";
import { Type } from "."
export enum Group {
SITE,
@@ -16,11 +16,11 @@ export enum Flag {
}
export interface SettingItem {
key: string;
value: string;
type: Type;
help: string;
options?: string;
group: Group;
flag: Flag;
key: string
value: string
type: Type
help: string
options?: string
group: Group
flag: Flag
}

Some files were not shown because too many files have changed in this diff Show More