From 49152aa6418e07e745dab4aa7f0ec8d6e4774192 Mon Sep 17 00:00:00 2001 From: marcobaobao Date: Wed, 7 Feb 2024 15:03:12 +0100 Subject: [PATCH] core functionalities --- ui/src/App.svelte | 46 ++++++++++++++++++++++-- ui/src/app.css | 6 +--- ui/src/lib/store.ts | 7 ++-- ui/src/lib/utils.ts | 84 +++++++++++++++++++++++++++++++++++++++++++ ui/tailwind.config.js | 2 +- 5 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 ui/src/lib/utils.ts diff --git a/ui/src/App.svelte b/ui/src/App.svelte index a8f8197..fed635a 100644 --- a/ui/src/App.svelte +++ b/ui/src/App.svelte @@ -1,13 +1,53 @@
- {$serverApiEndpoint} - {$httpPostRpcEndpoint} - {$websocketRpcEndpoint} +
+ {#each pipe( $downloads, O.getOrElseW(() => []), ) as download} +
+
{download.id}
+
{JSON.stringify(download.info)}
+
{JSON.stringify(download.progress)}
+
+ {/each} +
diff --git a/ui/src/app.css b/ui/src/app.css index 0251515..bd6213e 100644 --- a/ui/src/app.css +++ b/ui/src/app.css @@ -1,7 +1,3 @@ @tailwind base; @tailwind components; -@tailwind utilities; - -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; -} \ No newline at end of file +@tailwind utilities; \ No newline at end of file diff --git a/ui/src/lib/store.ts b/ui/src/lib/store.ts index 5e24744..f03735b 100644 --- a/ui/src/lib/store.ts +++ b/ui/src/lib/store.ts @@ -1,6 +1,7 @@ import { derived, readable, writable } from 'svelte/store' import { RPCClient } from './RPCClient' import type { RPCResponse, RPCResult } from './types' +import * as O from 'fp-ts/lib/Option' export const rpcHost = writable(localStorage.getItem('rpcHost') ?? 'localhost') export const rpcPort = writable(Number(localStorage.getItem('rpcPort')) || 3033) @@ -31,8 +32,4 @@ export const rpcClient = derived( ([$http, $ws, $token]) => new RPCClient($http, $ws, $token) ) -export const downloads = readable>({ - id: '', - error: null, - result: [], -}) \ No newline at end of file +export const downloads = writable>(O.none) \ No newline at end of file diff --git a/ui/src/lib/utils.ts b/ui/src/lib/utils.ts new file mode 100644 index 0000000..acfc6ac --- /dev/null +++ b/ui/src/lib/utils.ts @@ -0,0 +1,84 @@ +import { pipe } from 'fp-ts/lib/function' +import type { RPCResponse } from "./types" + +/** + * Validate an ip v4 via regex + * @param {string} ipAddr + * @returns ip validity test + */ +export function validateIP(ipAddr: string): boolean { + let ipRegex = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm + return ipRegex.test(ipAddr) +} + +export function validateDomain(url: string): boolean { + const urlRegex = /(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/ + const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/ + + const [name, slug] = url.split('/') + + return urlRegex.test(url) || name === 'localhost' && slugRegex.test(slug) +} + +export function isValidURL(url: string): boolean { + let urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/ + return urlRegex.test(url) +} + +export function ellipsis(str: string, lim: number): string { + if (str) { + return str.length > lim ? `${str.substring(0, lim)}...` : str + } + return '' +} + +export function toFormatArgs(codes: string[]): string { + if (codes.length > 1) { + return codes.reduce((v, a) => ` -f ${v}+${a}`) + } + if (codes.length === 1) { + return ` -f ${codes[0]}` + } + return '' +} + +export const formatGiB = (bytes: number) => + `${(bytes / 1_000_000_000).toFixed(0)}GiB` + +export const roundMiB = (bytes: number) => + `${(bytes / 1_000_000).toFixed(2)} MiB` + +export const formatSpeedMiB = (val: number) => + `${roundMiB(val)}/s` + +export const datetimeCompareFunc = (a: string, b: string) => + new Date(a).getTime() - new Date(b).getTime() + +export function isRPCResponse(object: any): object is RPCResponse { + return 'result' in object && 'id' in object +} + +export function mapProcessStatus(status: number) { + switch (status) { + case 0: + return 'Pending' + case 1: + return 'Downloading' + case 2: + return 'Completed' + case 3: + return 'Error' + default: + return 'Pending' + } +} + +export const prefersDarkMode = () => + window.matchMedia('(prefers-color-scheme: dark)').matches + +export const base64URLEncode = (s: string) => pipe( + s, + s => String.fromCodePoint(...new TextEncoder().encode(s)), + btoa, + encodeURIComponent +) \ No newline at end of file diff --git a/ui/tailwind.config.js b/ui/tailwind.config.js index d37737f..a4639ea 100644 --- a/ui/tailwind.config.js +++ b/ui/tailwind.config.js @@ -2,7 +2,7 @@ export default { content: [ "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", + "./src/**/*.{svelte,js,ts,jsx,tsx}", ], theme: { extend: {},