From 6af7db4eed471a1eba71f774c7e986e357cf303e Mon Sep 17 00:00:00 2001 From: ewsgit Date: Sat, 18 Apr 2026 14:07:49 +0000 Subject: [PATCH] Begin Files Layout, add New LinearProgressIndicator & Rename IndeterminateSpinner to CircularProgressIndicator --- applications/uk.ewsgit.dashboard/web/Layout.tsx | 4 ++-- applications/uk.ewsgit.files/TODO | 14 -------------- applications/uk.ewsgit.files/backend/index.ts | 694 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- applications/uk.ewsgit.files/web/.backup/App.tsx | 20 ++++++++++++++++++++ applications/uk.ewsgit.files/web/App.tsx | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- applications/uk.ewsgit.files/web/.backup/Layout.module.scss | 0 applications/uk.ewsgit.files/web/.backup/Layout.tsx | 0 applications/uk.ewsgit.files/web/Redirect.tsx | 14 ++++++++++++++ applications/uk.ewsgit.files/web/appContext.ts | 6 ++++++ applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/Redirect.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItemRename.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ItemMenu.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.module.scss | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.tsx | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContext.ts | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/keyboard.ts | 0 applications/uk.ewsgit.files/web/.backup/components/ViewContainer/viewItem.ts | 0 applications/uk.ewsgit.files/web/layout/Layout.module.scss | 22 ++++++++++++++++++++++ applications/uk.ewsgit.files/web/layout/Layout.tsx | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.module.scss | 3 +++ applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.tsx | 8 ++++++++ applications/uk.ewsgit.files/web/layout/components/Quota/Quota.module.scss | 8 ++++++++ applications/uk.ewsgit.files/web/layout/components/Quota/Quota.tsx | 17 +++++++++++++++++ applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.module.scss | 3 +++ applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.tsx | 8 ++++++++ applications/uk.ewsgit.files/web/pages/welcome/Index.module.scss | 5 +++++ applications/uk.ewsgit.files/web/pages/welcome/Index.tsx | 43 +++++++++++++++++++++++++++++++++++++++++++ applications/uk.ewsgit.settings/backend/index.ts | 14 ++++++++++---- applications/uk.ewsgit.settings/web/Layout.tsx | 6 +++--- applications/uk.ewsgit.settings/web/pages/applications/Index.tsx | 4 ++-- applications/uk.ewsgit.settings/web/pages/authentication/Index.tsx | 4 ++-- applications/uk.ewsgit.settings/web/pages/authentication/components/Sessions/Sessions.tsx | 4 ++-- applications/uk.ewsgit.settings/web/pages/customization/quickShortcuts/components/addShortcutButton/AddShortcutButton.tsx | 4 ++-- applications/uk.ewsgit.settings/web/pages/customization/wallpaper/Index.tsx | 4 ++-- applications/uk.ewsgit.settings/web/pages/profile/components/ProfilePicture/components/CropImage/CropImage.tsx | 4 ++-- applications/uk.ewsgit.store/web/Layout.tsx | 4 ++-- applications/uk.ewsgit.store/web/pages/search/Index.tsx | 4 ++-- instance/src/systems/applications.ts | 4 ++-- instance/src/systems/image.ts | 2 +- instance/src/web/src/pages/app/AuthCheck.tsx | 4 ++-- instance/src/web/src/pages/app/Layout.tsx | 6 +++--- instance/src/web/src/pages/userSelect/Layout.tsx | 4 ++-- instance/src/web/src/pages/userSelect/signup/Signup.tsx | 4 ++-- uikit-solid/src/components/buttonGroup/UKButtonGroup.tsx | 31 +++++++++++++------------------ uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx | 27 +++++++++++++++++++++++++++ uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.module.scss | 0 uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx | 17 ----------------- uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.module.scss | 31 +++++++++++++++++++++++++++++++ uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.tsx | 34 ++++++++++++++++++++++++++++++++++ uikit-solid/src/components/sideBar/UKSideBar.tsx | 24 ++++++++++++++++-------- 64 file(s) changed, 792 insertion(s)(+), 446 deletion(s)(-) diff --git a/applications/uk.ewsgit.dashboard/web/Layout.tsx b/applications/uk.ewsgit.dashboard/web/Layout.tsx --- a/applications/uk.ewsgit.dashboard/web/Layout.tsx +++ b/applications/uk.ewsgit.dashboard/web/Layout.tsx @@ -1,4 +1,4 @@ -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import clsx from "clsx"; import { type Component, createResource, type ParentProps, Suspense } from "solid-js"; import PLACEHOLDER_WALLPAPER from "./assets/placeholder_wallpaper.png"; @@ -17,7 +17,7 @@ const [wallpaperOptions] = createResource(() => trpc.dashboard.getWallpaperOptions.query()); return (
- }> + }> { e.currentTarget.style.opacity = "1"; diff --git a/applications/uk.ewsgit.files/TODO b/applications/uk.ewsgit.files/TODO deleted file mode 100644 --- a/applications/uk.ewsgit.files/TODO +++ /dev/null @@ -1,14 +0,0 @@ -# TODO - -- Views - - Item View - - Details View - - Stage View -- View Item Context Menu -- ActionBar - - Back & Forwards -- SideBar - - Storage Shares - - Shared With Me -- StatusBar - - Current Status & Progress Indication diff --git a/applications/uk.ewsgit.files/backend/index.ts b/applications/uk.ewsgit.files/backend/index.ts --- a/applications/uk.ewsgit.files/backend/index.ts +++ b/applications/uk.ewsgit.files/backend/index.ts @@ -1,6 +1,6 @@ /// -import { promises as fs } from "node:fs"; +import { promises as fs, existsSync as fsExists } from "node:fs"; import * as path from "node:path"; import { createTRPCContext, procedure } from "@onlineworkspace/workspace-instance/src/systems/trpcRouter.js"; import { initTRPC } from "@trpc/server"; @@ -13,350 +13,358 @@ export const t = initTRPC.context>().create(); const router = t.router({ - getFileGrid: procedure.input(z.object({ path: z.string(), sortBy: z.enum(["name"]) })).query(async (opt) => { - const finalPath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.path); - - if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { - // send a missing permissions notification - return { - type: "error" as const, - message: "You cannot access this location!", - icon: "folder_limited", - }; - } - - const THUMBNAIL_SIZE = 128; - - const output: { - name: string; - path: string; - icon?: string; - type: "directory" | "file" | "alias"; - }[] = []; - - if (!(await fs.exists(finalPath))) { - return { - type: "error" as const, - message: "This directory does not exist!", - icon: "folder_limited", - }; - } - - for (const item of await fs.readdir(finalPath)) { - const itemPath = path.join(finalPath, item); - const isDirectory = (await fs.lstat(itemPath)).isDirectory(); - - let icon: string; - - if (!isDirectory) { - switch (instance.sys.filesystem.getFileType(itemPath)) { - case "image": { - icon = - opt.ctx.instance.sys.configuration.backendUrl + - (await instance.sys.image.serveImage(opt.ctx.userId, itemPath, { - resize: { - dimensions: (dimensions) => { - let newWidth = THUMBNAIL_SIZE; - let newHeight = THUMBNAIL_SIZE; - - if (dimensions.width > dimensions.height) { - newWidth = THUMBNAIL_SIZE; - newHeight = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); - } - - if (dimensions.height > dimensions.width) { - newHeight = THUMBNAIL_SIZE; - newWidth = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); - } - - return { - width: newWidth, - height: newHeight, - }; - }, - }, - })); - } - } - } - - let itemName = item; - const finalItemPath = path.relative(instance.sys.filesystem.FS_ROOT, itemPath); - - if (finalItemPath.split(itemName)[0] === "users/") { - itemName += ` (${await (await instance.sys.users.getUserById(Number(itemName)))?.getUsername()})`; - } - - output.push({ - name: itemName, - path: finalItemPath, - // @ts-ignore - icon: icon, - type: isDirectory ? "directory" : "file", - }); - } - - if (output.length < 1) { - return { - type: "info" as const, - message: "This directory is empty", - icon: "folder", - }; - } - - return { type: "success" as const, items: output }; - }), - getFileList: procedure.input(z.object({ path: z.string(), sortBy: z.enum(["name"]) })).query(async (opt) => { - const finalPath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.path); - - if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { - // send a missing permissions notification - return { - type: "error" as const, - message: "You cannot access this location!", - icon: "folder_limited", - }; - } - - const THUMBNAIL_SIZE = 32; - - const output: { - name: string; - path: string; - icon?: string; - type: "directory" | "file" | "alias"; - }[] = []; - - if (!(await fs.exists(finalPath))) { - return { - type: "error" as const, - message: "This directory does not exist!", - icon: "folder_limited", - }; - } - - for (const item of await fs.readdir(finalPath)) { - const itemPath = path.join(finalPath, item); - const isDirectory = (await fs.lstat(itemPath)).isDirectory(); - - let icon: string; - - if (!isDirectory) { - switch (instance.sys.filesystem.getFileType(itemPath)) { - case "image": { - icon = - opt.ctx.instance.sys.configuration.backendUrl + - (await instance.sys.image.serveImage(opt.ctx.userId, itemPath, { - resize: { - dimensions: (dimensions) => { - let newWidth = THUMBNAIL_SIZE; - let newHeight = THUMBNAIL_SIZE; - - if (dimensions.width > dimensions.height) { - newWidth = THUMBNAIL_SIZE; - newHeight = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); - } - - if (dimensions.height > dimensions.width) { - newHeight = THUMBNAIL_SIZE; - newWidth = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); - } - - return { - width: newWidth, - height: newHeight, - }; - }, - }, - })); - } - } - } - - let itemName = item; - const finalItemPath = path.relative(instance.sys.filesystem.FS_ROOT, itemPath); - - if (finalItemPath.split(itemName)[0] === "users/") { - itemName += ` (${await (await instance.sys.users.getUserById(Number(itemName)))?.getUsername()})`; - } - - output.push({ - name: itemName, - path: finalItemPath, - // @ts-ignore - icon: icon, - type: isDirectory ? "directory" : "file", - }); - } - - if (output.length < 1) { + // getFileGrid: procedure.input(z.object({ path: z.string(), sortBy: z.enum(["name"]) })).query(async (opt) => { + // const finalPath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.path); + // + // if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { + // // send a missing permissions notification + // return { + // type: "error" as const, + // message: "You cannot access this location!", + // icon: "folder_limited", + // }; + // } + // + // const THUMBNAIL_SIZE = 128; + // + // const output: { + // name: string; + // path: string; + // icon?: string; + // type: "directory" | "file" | "alias"; + // }[] = []; + // + // if (!fsExists(finalPath)) { + // return { + // type: "error" as const, + // message: "This directory does not exist!", + // icon: "folder_limited", + // }; + // } + // + // for (const item of await fs.readdir(finalPath)) { + // const itemPath = path.join(finalPath, item); + // const isDirectory = (await fs.lstat(itemPath)).isDirectory(); + // + // let icon: string; + // + // if (!isDirectory) { + // switch (instance.sys.filesystem.getFileType(itemPath)) { + // case "image": { + // icon = + // opt.ctx.instance.sys.configuration.backendUrl + + // (await instance.sys.image.serveImage(opt.ctx.userId, itemPath, { + // resize: { + // dimensions: (dimensions) => { + // let newWidth = THUMBNAIL_SIZE; + // let newHeight = THUMBNAIL_SIZE; + // + // if (dimensions.width > dimensions.height) { + // newWidth = THUMBNAIL_SIZE; + // newHeight = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); + // } + // + // if (dimensions.height > dimensions.width) { + // newHeight = THUMBNAIL_SIZE; + // newWidth = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); + // } + // + // return { + // width: newWidth, + // height: newHeight, + // }; + // }, + // }, + // })); + // } + // } + // } + // + // let itemName = item; + // const finalItemPath = path.relative(instance.sys.filesystem.FS_ROOT, itemPath); + // + // if (finalItemPath.split(itemName)[0] === "users/") { + // itemName += ` (${await (await instance.sys.users.getUserById(Number(itemName)))?.getUsername()})`; + // } + // + // output.push({ + // name: itemName, + // path: finalItemPath, + // // @ts-ignore + // icon: icon, + // type: isDirectory ? "directory" : "file", + // }); + // } + // + // if (output.length < 1) { + // return { + // type: "info" as const, + // message: "This directory is empty", + // icon: "folder", + // }; + // } + // + // return { type: "success" as const, items: output }; + // }), + // getFileList: procedure.input(z.object({ path: z.string(), sortBy: z.enum(["name"]) })).query(async (opt) => { + // const finalPath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.path); + // + // if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { + // // send a missing permissions notification + // return { + // type: "error" as const, + // message: "You cannot access this location!", + // icon: "folder_limited", + // }; + // } + // + // const THUMBNAIL_SIZE = 32; + // + // const output: { + // name: string; + // path: string; + // icon?: string; + // type: "directory" | "file" | "alias"; + // }[] = []; + // + // if (!fsExists(finalPath)) { + // return { + // type: "error" as const, + // message: "This directory does not exist!", + // icon: "folder_limited", + // }; + // } + // + // for (const item of await fs.readdir(finalPath)) { + // const itemPath = path.join(finalPath, item); + // const isDirectory = (await fs.lstat(itemPath)).isDirectory(); + // + // let icon: string; + // + // if (!isDirectory) { + // switch (instance.sys.filesystem.getFileType(itemPath)) { + // case "image": { + // icon = + // opt.ctx.instance.sys.configuration.backendUrl + + // (await instance.sys.image.serveImage(opt.ctx.userId, itemPath, { + // resize: { + // dimensions: (dimensions) => { + // let newWidth = THUMBNAIL_SIZE; + // let newHeight = THUMBNAIL_SIZE; + // + // if (dimensions.width > dimensions.height) { + // newWidth = THUMBNAIL_SIZE; + // newHeight = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); + // } + // + // if (dimensions.height > dimensions.width) { + // newHeight = THUMBNAIL_SIZE; + // newWidth = Math.round((dimensions.height / dimensions.width) * THUMBNAIL_SIZE); + // } + // + // return { + // width: newWidth, + // height: newHeight, + // }; + // }, + // }, + // })); + // } + // } + // } + // + // let itemName = item; + // const finalItemPath = path.relative(instance.sys.filesystem.FS_ROOT, itemPath); + // + // if (finalItemPath.split(itemName)[0] === "users/") { + // itemName += ` (${await (await instance.sys.users.getUserById(Number(itemName)))?.getUsername()})`; + // } + // + // output.push({ + // name: itemName, + // path: finalItemPath, + // // @ts-ignore + // icon: icon, + // type: isDirectory ? "directory" : "file", + // }); + // } + // + // if (output.length < 1) { + // return { + // type: "info" as const, + // message: "This directory is empty", + // icon: "folder", + // }; + // } + // + // return { type: "success" as const, items: output }; + // }), + // getRawFile: procedure.input(z.string()).query(async (opt) => { + // const finalPath = path.join(instance.sys.filesystem.FS_ROOT, opt.input); + // if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { + // return "You lack the required permissions to access this resource!"; + // } + // + // return opt.ctx.instance.sys.configuration.backendUrl + instance.sys.filesystem.serveFile(opt.ctx.userId, finalPath); + // }), + // batchMove: procedure.input(z.object({ path: z.string(), newPath: z.string() }).array()).mutation(async (opt) => { + // for (const item of opt.input) { + // if (item.path === item.newPath) continue; + // // TODO: send a failure notification + // if (path.join(item.newPath, "..") === "users") continue; + // if (path.join(item.path, "..") === "users") continue; + // + // const finalPath = path.join(instance.sys.filesystem.FS_ROOT, item.path); + // const finalNewPath = path.join(instance.sys.filesystem.FS_ROOT, item.newPath); + // + // try { + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalNewPath)).write) { + // await fs.rename(finalPath, finalNewPath); + // } else { + // // send a missing permissions notification + // return false; + // } + // } else { + // // send a missing permissions notification + // return false; + // } + // } catch (err) { + // log.error(err); + // } + // } + // }), + // batchCopy: procedure.input(z.object({ path: z.string(), newPath: z.string() }).array()).mutation(async (opt) => { + // for (const item of opt.input) { + // if (item.path === item.newPath) continue; + // // TODO: send a failure notification + // if (path.join(item.newPath, "..") === "users") continue; + // if (path.join(item.path, "..") === "users") continue; + // + // const finalPath = path.join(instance.sys.filesystem.FS_ROOT, item.path); + // const finalNewPath = path.join(instance.sys.filesystem.FS_ROOT, item.newPath); + // + // try { + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalNewPath)).write) { + // await fs.cp(finalPath, finalNewPath, { recursive: true }); + // } else { + // // send a missing permissions notification + // return false; + // } + // } else { + // // send a missing permissions notification + // return false; + // } + // } catch (err) { + // log.error(err); + // } + // } + // + // return true; + // }), + // batchDelete: procedure.input(z.string().array()).mutation(async (opt) => { + // for (const item of opt.input) { + // const itemPath = path.join(instance.sys.filesystem.FS_ROOT, item); + // + // try { + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, itemPath)).write) { + // await fs.rm(itemPath, { recursive: true }); + // } else { + // // send a missing permissions notification + // return false; + // } + // } catch (err) { + // log.error(err); + // } + // } + // + // return true; + // }), + // createFile: procedure.input(z.object({ filePath: z.string() })).mutation(async (opt) => { + // const filePath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.filePath); + // + // if (fsExists(filePath)) return false; + // + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, filePath)).write) { + // await fs.writeFile(filePath, ""); + // } else { + // // send a missing permissions notification + // return false; + // } + // + // return true; + // }), + // createDirectory: procedure.input(z.object({ directoryPath: z.string() })).mutation(async (opt) => { + // const filePath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.directoryPath); + // + // if (fsExists(filePath)) return false; + // + // if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, filePath)).write) { + // await fs.mkdir(filePath, { recursive: true }); + // } else { + // // send a missing permissions notification + // return false; + // } + // + // return true; + // }), + // getHome: procedure.query(async (opt) => { + // return `/users/${opt.ctx.userId}/fs`; + // }), + // getPlaces: procedure.query(async (opt) => { + // return [ + // { + // icon: "house", + // path: `/users/${opt.ctx.userId}/fs`, + // name: "Home", + // }, + // { + // icon: "data_usage", + // path: `/`, + // name: "Root", + // }, + // ]; + // }), + // uploadFile: procedure.input(octetInputParser).mutation(async (opt) => { + // const uuid = randomUUIDv7(); + // const uploadFilePath = path.join((await opt.ctx.user()).getPath(), `system/temp/${uuid}`); + // + // log.info(`Uploading file ${uuid}`); + // + // const fileResponse = new Response(opt.input); + // await fs.writeFile(uploadFilePath, await fileResponse.bytes()); + // + // return { id: uuid }; + // }), + // setUploadMetadata: procedure.input(z.object({ id: z.string(), path: z.string(), lastModified: z.number() })).mutation(async (opt) => { + // const uploadFilePath = path.join((await opt.ctx.user()).getPath(), `system/temp/${opt.input.id}`); + // const actualFilePath = path.join(instance.sys.filesystem.FS_ROOT, `${opt.input.path}`); + // const actualFilePathParentDir = path.join(actualFilePath, ".."); + // + // if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, actualFilePath)).write) { + // return false; + // } + // + // if (!fsExists(actualFilePathParentDir)) { + // await fs.mkdir(actualFilePathParentDir, { recursive: true }); + // } + // + // log.info(`Applying metadata to file (${opt.input.id}) '${actualFilePath}'`); + // + // await fs.rename(uploadFilePath, actualFilePath); + // await fs.utimes(actualFilePath, 0, opt.input.lastModified); + // + // return true; + // }), + userPreferences: { + get: procedure.query(async (opt) => { return { - type: "info" as const, - message: "This directory is empty", - icon: "folder", + showWelcome: false, + homePath: `/Users/${opt.ctx.userId}/fs/`, }; - } - - return { type: "success" as const, items: output }; - }), - getRawFile: procedure.input(z.string()).query(async (opt) => { - const finalPath = path.join(instance.sys.filesystem.FS_ROOT, opt.input); - if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { - return "You lack the required permissions to access this resource!"; - } - - return opt.ctx.instance.sys.configuration.backendUrl + instance.sys.filesystem.serveFile(opt.ctx.userId, finalPath); - }), - batchMove: procedure.input(z.object({ path: z.string(), newPath: z.string() }).array()).mutation(async (opt) => { - for (const item of opt.input) { - if (item.path === item.newPath) continue; - // TODO: send a failure notification - if (path.join(item.newPath, "..") === "users") continue; - if (path.join(item.path, "..") === "users") continue; - - const finalPath = path.join(instance.sys.filesystem.FS_ROOT, item.path); - const finalNewPath = path.join(instance.sys.filesystem.FS_ROOT, item.newPath); - - try { - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalNewPath)).write) { - await fs.rename(finalPath, finalNewPath); - } else { - // send a missing permissions notification - return false; - } - } else { - // send a missing permissions notification - return false; - } - } catch (err) { - log.error(err); - } - } - }), - batchCopy: procedure.input(z.object({ path: z.string(), newPath: z.string() }).array()).mutation(async (opt) => { - for (const item of opt.input) { - if (item.path === item.newPath) continue; - // TODO: send a failure notification - if (path.join(item.newPath, "..") === "users") continue; - if (path.join(item.path, "..") === "users") continue; - - const finalPath = path.join(instance.sys.filesystem.FS_ROOT, item.path); - const finalNewPath = path.join(instance.sys.filesystem.FS_ROOT, item.newPath); - - try { - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalPath)).read) { - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, finalNewPath)).write) { - await fs.cp(finalPath, finalNewPath, { recursive: true }); - } else { - // send a missing permissions notification - return false; - } - } else { - // send a missing permissions notification - return false; - } - } catch (err) { - log.error(err); - } - } - - return true; - }), - batchDelete: procedure.input(z.string().array()).mutation(async (opt) => { - for (const item of opt.input) { - const itemPath = path.join(instance.sys.filesystem.FS_ROOT, item); - - try { - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, itemPath)).write) { - await fs.rm(itemPath, { recursive: true }); - } else { - // send a missing permissions notification - return false; - } - } catch (err) { - log.error(err); - } - } - - return true; - }), - createFile: procedure.input(z.object({ filePath: z.string() })).mutation(async (opt) => { - const filePath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.filePath); - - if (await fs.exists(filePath)) return false; - - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, filePath)).write) { - await fs.writeFile(filePath, ""); - } else { - // send a missing permissions notification - return false; - } - - return true; - }), - createDirectory: procedure.input(z.object({ directoryPath: z.string() })).mutation(async (opt) => { - const filePath = path.join(instance.sys.filesystem.FS_ROOT, opt.input.directoryPath); - - if (await fs.exists(filePath)) return false; - - if ((await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, filePath)).write) { - await fs.mkdir(filePath, { recursive: true }); - } else { - // send a missing permissions notification - return false; - } - - return true; - }), - getHome: procedure.query(async (opt) => { - return `/users/${opt.ctx.userId}/fs`; - }), - getPlaces: procedure.query(async (opt) => { - return [ - { - icon: "house", - path: `/users/${opt.ctx.userId}/fs`, - name: "Home", - }, - { - icon: "data_usage", - path: `/`, - name: "Root", - }, - ]; - }), - uploadFile: procedure.input(octetInputParser).mutation(async (opt) => { - const uuid = randomUUIDv7(); - const uploadFilePath = path.join((await opt.ctx.user()).getPath(), `system/temp/${uuid}`); - - log.info(`Uploading file ${uuid}`); - - const fileResponse = new Response(opt.input); - await fs.writeFile(uploadFilePath, await fileResponse.bytes()); - - return { id: uuid }; - }), - setUploadMetadata: procedure.input(z.object({ id: z.string(), path: z.string(), lastModified: z.number() })).mutation(async (opt) => { - const uploadFilePath = path.join((await opt.ctx.user()).getPath(), `system/temp/${opt.input.id}`); - const actualFilePath = path.join(instance.sys.filesystem.FS_ROOT, `${opt.input.path}`); - const actualFilePathParentDir = path.join(actualFilePath, ".."); - - if (!(await instance.sys.filesystem.getUserPermissions(opt.ctx.userId, actualFilePath)).write) { - return false; - } - - if (!(await fs.exists(actualFilePathParentDir))) { - await fs.mkdir(actualFilePathParentDir, { recursive: true }); - } - - log.info(`Applying metadata to file (${opt.input.id}) '${actualFilePath}'`); - - await fs.rename(uploadFilePath, actualFilePath); - await fs.utimes(actualFilePath, 0, opt.input.lastModified); - - return true; - }), + }), + }, }); export type TRPCRouter = typeof router; diff --git a/applications/uk.ewsgit.files/web/.backup/App.tsx b/applications/uk.ewsgit.files/web/.backup/App.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/.backup/App.tsx @@ -0,0 +1,20 @@ +import { Route } from "@solidjs/router"; +import { type Component, lazy } from "solid-js"; + +const Redirect = lazy(() => import("./components/Redirect.tsx")); +const ViewContainer = lazy(() => import("./components/ViewContainer/ViewContainer.tsx")); +const Layout = lazy(() => import("./Layout.tsx")); + +const App: Component = () => { + return ( + <> + + + + + + + ); +}; + +export default App; diff --git a/applications/uk.ewsgit.files/web/App.tsx b/applications/uk.ewsgit.files/web/App.tsx --- a/applications/uk.ewsgit.files/web/App.tsx +++ b/applications/uk.ewsgit.files/web/App.tsx @@ -1,19 +1,66 @@ import { Route } from "@solidjs/router"; -import { type Component, lazy } from "solid-js"; +import { type Accessor, type Component, createSignal, lazy, onMount } from "solid-js"; +import { createStore, type Store } from "solid-js/store"; +import { AppContext } from "./appContext.ts"; +import trpc from "./lib/trpc.ts"; +import Redirect from "./Redirect.tsx"; + +const Layout = lazy(() => import("./layout/Layout.tsx")); +const WelcomePage = lazy(() => import("./pages/welcome/Index.tsx")); + +interface AppContextType { + isAdministrator: Accessor; + shootYourselfInTheFoot: Accessor; + userPreferences: Store<{ + showWelcome: boolean; + homePath: string; + pinnedDirectories: string[]; + }>; +} -const Redirect = lazy(() => import("./components/Redirect.tsx")); -const ViewContainer = lazy(() => import("./components/ViewContainer/ViewContainer.tsx")); -const Layout = lazy(() => import("./Layout.tsx")); +export type { AppContextType }; const App: Component = () => { + const [hasLoaded, setHasLoaded] = createSignal(false); + const [userPreferences, setUserPreferences] = createStore({ + showWelcome: true, + homePath: "/Users/1/fs/", + pinnedDirectories: ["/home"], + }); + + onMount(async () => { + const userServerPreferences = await trpc.userPreferences.get.query(); + + setUserPreferences("showWelcome", userServerPreferences.showWelcome); + setUserPreferences("homePath", userServerPreferences.homePath); + + setHasLoaded(true); + }); + return ( - <> - + false, + shootYourselfInTheFoot: () => false, + userPreferences: userPreferences, + }} + > + {!hasLoaded() && "Loading..."} />} + ( + + )} + /> + - - + "Dir View"} /> - + {/**/} + {/* */} + {/* */} + {/**/} + ); }; diff --git a/applications/uk.ewsgit.files/web/Layout.module.scss b/applications/uk.ewsgit.files/web/.backup/Layout.module.scss rename from applications/uk.ewsgit.files/web/Layout.module.scss rename to applications/uk.ewsgit.files/web/.backup/Layout.module.scss --- a/applications/uk.ewsgit.files/web/Layout.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/Layout.module.scss diff --git a/applications/uk.ewsgit.files/web/Layout.tsx b/applications/uk.ewsgit.files/web/.backup/Layout.tsx rename from applications/uk.ewsgit.files/web/Layout.tsx rename to applications/uk.ewsgit.files/web/.backup/Layout.tsx --- a/applications/uk.ewsgit.files/web/Layout.tsx +++ b/applications/uk.ewsgit.files/web/.backup/Layout.tsx diff --git a/applications/uk.ewsgit.files/web/Redirect.tsx b/applications/uk.ewsgit.files/web/Redirect.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/Redirect.tsx @@ -0,0 +1,14 @@ +import { useNavigate } from "@solidjs/router"; +import { type Component, onMount } from "solid-js"; + +const Redirect: Component<{ to: string }> = (props) => { + const navigate = useNavigate(); + + onMount(() => { + navigate(props.to); + }); + + return null; +}; + +export default Redirect; diff --git a/applications/uk.ewsgit.files/web/appContext.ts b/applications/uk.ewsgit.files/web/appContext.ts new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/appContext.ts @@ -0,0 +1,6 @@ +import { createContext } from "solid-js"; +import type { AppContextType } from "./App.tsx"; + +const AppContext = createContext(); + +export { AppContext }; diff --git a/applications/uk.ewsgit.files/web/components/PathBar/PathBar.module.scss b/applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.module.scss rename from applications/uk.ewsgit.files/web/components/PathBar/PathBar.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.module.scss --- a/applications/uk.ewsgit.files/web/components/PathBar/PathBar.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.module.scss diff --git a/applications/uk.ewsgit.files/web/components/PathBar/PathBar.tsx b/applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.tsx rename from applications/uk.ewsgit.files/web/components/PathBar/PathBar.tsx rename to applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.tsx --- a/applications/uk.ewsgit.files/web/components/PathBar/PathBar.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/PathBar/PathBar.tsx diff --git a/applications/uk.ewsgit.files/web/components/Redirect.tsx b/applications/uk.ewsgit.files/web/.backup/components/Redirect.tsx rename from applications/uk.ewsgit.files/web/components/Redirect.tsx rename to applications/uk.ewsgit.files/web/.backup/components/Redirect.tsx --- a/applications/uk.ewsgit.files/web/components/Redirect.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/Redirect.tsx diff --git a/applications/uk.ewsgit.files/web/components/SideBar/SideBar.module.scss b/applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.module.scss rename from applications/uk.ewsgit.files/web/components/SideBar/SideBar.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.module.scss --- a/applications/uk.ewsgit.files/web/components/SideBar/SideBar.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.module.scss diff --git a/applications/uk.ewsgit.files/web/components/SideBar/SideBar.tsx b/applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.tsx rename from applications/uk.ewsgit.files/web/components/SideBar/SideBar.tsx rename to applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.tsx --- a/applications/uk.ewsgit.files/web/components/SideBar/SideBar.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/SideBar/SideBar.tsx diff --git a/applications/uk.ewsgit.files/web/components/StatusBar/StatusBar.module.scss b/applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.module.scss rename from applications/uk.ewsgit.files/web/components/StatusBar/StatusBar.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.module.scss --- a/applications/uk.ewsgit.files/web/components/StatusBar/StatusBar.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.module.scss diff --git a/applications/uk.ewsgit.files/web/components/StatusBar/StatusBar.tsx b/applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.tsx rename from applications/uk.ewsgit.files/web/components/StatusBar/StatusBar.tsx rename to applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.tsx --- a/applications/uk.ewsgit.files/web/components/StatusBar/StatusBar.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/StatusBar/StatusBar.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/Grid.module.scss b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.module.scss rename from applications/uk.ewsgit.files/web/components/ViewContainer/Grid/Grid.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.module.scss --- a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/Grid.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.module.scss diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/Grid.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/Grid/Grid.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/Grid.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/Grid.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItem.module.scss b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.module.scss rename from applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItem.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.module.scss --- a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItem.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.module.scss diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItem.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItem.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItem.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItem.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItemRename.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItemRename.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItemRename.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItemRename.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/Grid/GridItemRename.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/Grid/GridItemRename.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/ItemMenu.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ItemMenu.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/ItemMenu.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ItemMenu.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/ItemMenu.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ItemMenu.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/List/List.module.scss b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.module.scss rename from applications/uk.ewsgit.files/web/components/ViewContainer/List/List.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.module.scss --- a/applications/uk.ewsgit.files/web/components/ViewContainer/List/List.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.module.scss diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/List/List.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/List/List.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/List/List.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/List.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/List/ListItem.module.scss b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.module.scss rename from applications/uk.ewsgit.files/web/components/ViewContainer/List/ListItem.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.module.scss --- a/applications/uk.ewsgit.files/web/components/ViewContainer/List/ListItem.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.module.scss diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/List/ListItem.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/List/ListItem.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/List/ListItem.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/List/ListItem.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/ViewContainer.module.scss b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.module.scss rename from applications/uk.ewsgit.files/web/components/ViewContainer/ViewContainer.module.scss rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.module.scss --- a/applications/uk.ewsgit.files/web/components/ViewContainer/ViewContainer.module.scss +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.module.scss diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/ViewContainer.tsx b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.tsx rename from applications/uk.ewsgit.files/web/components/ViewContainer/ViewContainer.tsx rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.tsx --- a/applications/uk.ewsgit.files/web/components/ViewContainer/ViewContainer.tsx +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContainer.tsx diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/ViewContext.ts b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContext.ts rename from applications/uk.ewsgit.files/web/components/ViewContainer/ViewContext.ts rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContext.ts --- a/applications/uk.ewsgit.files/web/components/ViewContainer/ViewContext.ts +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/ViewContext.ts diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/keyboard.ts b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/keyboard.ts rename from applications/uk.ewsgit.files/web/components/ViewContainer/keyboard.ts rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/keyboard.ts --- a/applications/uk.ewsgit.files/web/components/ViewContainer/keyboard.ts +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/keyboard.ts diff --git a/applications/uk.ewsgit.files/web/components/ViewContainer/viewItem.ts b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/viewItem.ts rename from applications/uk.ewsgit.files/web/components/ViewContainer/viewItem.ts rename to applications/uk.ewsgit.files/web/.backup/components/ViewContainer/viewItem.ts --- a/applications/uk.ewsgit.files/web/components/ViewContainer/viewItem.ts +++ b/applications/uk.ewsgit.files/web/.backup/components/ViewContainer/viewItem.ts diff --git a/applications/uk.ewsgit.files/web/layout/Layout.module.scss b/applications/uk.ewsgit.files/web/layout/Layout.module.scss new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/Layout.module.scss @@ -0,0 +1,22 @@ +.root { + display: grid; + grid-template-columns: auto 1fr auto; + grid-template-rows: auto 1fr auto; + width: 100%; + height: 100%; +} + +.sidebar { + grid-row-start: 1; + grid-row-end: 4; +} + +.actionbar { + grid-column-start: 2; + grid-column-end: 4; +} + +.statusbar { + grid-column-start: 2; + grid-column-end: 4; +} diff --git a/applications/uk.ewsgit.files/web/layout/Layout.tsx b/applications/uk.ewsgit.files/web/layout/Layout.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/Layout.tsx @@ -0,0 +1,64 @@ +import HOUSE_ICON from "@material-symbols/svg-700/outlined/house.svg"; +import PERSON_ICON from "@material-symbols/svg-700/outlined/person.svg"; +import UKSideBar from "@onlineworkspace/uikit-solid/src/components/sideBar/UKSideBar.tsx"; +import type { Component } from "solid-js"; +import ActionBar from "./components/ActionBar/ActionBar"; +import Quota from "./components/Quota/Quota.tsx"; +import StatusBar from "./components/StatusBar/StatusBar.tsx"; +import styles from "./Layout.module.scss"; + +const Layout: Component = () => { + return ( +
+ +
+ +
+
View
+
Preview
+
+ +
+
+ ); +}; + +export default Layout; diff --git a/applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.module.scss b/applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.module.scss new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.module.scss @@ -0,0 +1,3 @@ +.root { + background-color: rgb(var(--uk-sys-color-surface-container-low)); +} diff --git a/applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.tsx b/applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/components/ActionBar/ActionBar.tsx @@ -0,0 +1,8 @@ +import type { Component } from "solid-js"; +import styles from "./ActionBar.module.scss"; + +const ActionBar: Component = () => { + return
ActionBar Component
; +}; + +export default ActionBar; diff --git a/applications/uk.ewsgit.files/web/layout/components/Quota/Quota.module.scss b/applications/uk.ewsgit.files/web/layout/components/Quota/Quota.module.scss new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/components/Quota/Quota.module.scss @@ -0,0 +1,8 @@ +.root { + display: flex; + flex-direction: column; + gap: 0.5rem; + width: calc(100% - 2rem); + margin-left: auto; + margin-right: auto; +} diff --git a/applications/uk.ewsgit.files/web/layout/components/Quota/Quota.tsx b/applications/uk.ewsgit.files/web/layout/components/Quota/Quota.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/components/Quota/Quota.tsx @@ -0,0 +1,17 @@ +import UKLinearProgressIndicator from "@onlineworkspace/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.tsx"; +import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.tsx"; +import type { Component } from "solid-js"; +import styles from "./Quota.module.scss"; + +const Quota: Component = () => { + return ( +
+ + + 4 of 10GB Used + +
+ ); +}; + +export default Quota; diff --git a/applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.module.scss b/applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.module.scss new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.module.scss @@ -0,0 +1,3 @@ +.root { + background-color: rgb(var(--uk-sys-color-surface-container-low)); +} diff --git a/applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.tsx b/applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/layout/components/StatusBar/StatusBar.tsx @@ -0,0 +1,8 @@ +import type { Component } from "solid-js"; +import styles from "./StatusBar.module.scss"; + +const StatusBar: Component = () => { + return
Status Bar Component
; +}; + +export default StatusBar; diff --git a/applications/uk.ewsgit.files/web/pages/welcome/Index.module.scss b/applications/uk.ewsgit.files/web/pages/welcome/Index.module.scss new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/pages/welcome/Index.module.scss @@ -0,0 +1,5 @@ +.page { + display: flex; + flex-direction: column; + gap: 1rem; +} diff --git a/applications/uk.ewsgit.files/web/pages/welcome/Index.tsx b/applications/uk.ewsgit.files/web/pages/welcome/Index.tsx new file mode 100644 --- /dev/null +++ b/applications/uk.ewsgit.files/web/pages/welcome/Index.tsx @@ -0,0 +1,43 @@ +import UKButton from "@onlineworkspace/uikit-solid/src/components/button/UKButton.tsx"; +import UKButtonGroup from "@onlineworkspace/uikit-solid/src/components/buttonGroup/UKButtonGroup.tsx"; +import UKCard from "@onlineworkspace/uikit-solid/src/components/card/UKCard.tsx"; +import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.tsx"; +import { useNavigate } from "@solidjs/router"; +import type { Component } from "solid-js"; +import styles from "./Index.module.scss"; + +const WelcomePage: Component = () => { + const navigate = useNavigate(); + + return ( +
+ + + Welcome To Files + + + Let's get everything setup for you. + + + + { + navigate("/app/uk.ewsgit.files/dir"); + }} + color={"tonal"} + > + Skip + + { + navigate("/app/uk.ewsgit.files/dir"); + }} + > + Continue + + +
+ ); +}; + +export default WelcomePage; diff --git a/applications/uk.ewsgit.settings/backend/index.ts b/applications/uk.ewsgit.settings/backend/index.ts --- a/applications/uk.ewsgit.settings/backend/index.ts +++ b/applications/uk.ewsgit.settings/backend/index.ts @@ -655,13 +655,16 @@ }), setWallpaperToCustomWallpaper: procedure.input(z.object({ name: z.string() })).mutation(async (opt) => { const userWallpapersPath = path.join((await opt.ctx.user()).getPath(), "assets/wallpapers"); const resizedWallpapersPath = path.join(userWallpapersPath, "resized"); + const currentWallpaperPath = path.join(userWallpapersPath, "current.webp"); for (const resizedWallpaper of await fs.readdir(resizedWallpapersPath)) { await fs.rm(path.join(resizedWallpapersPath, resizedWallpaper)); } - await fs.rm(path.join(userWallpapersPath, "current.webp")); - await fs.copyFile(path.join(userWallpapersPath, opt.input.name.replace(".preview", "")), path.join(userWallpapersPath, "current.webp")); + if (fsExistsSync(currentWallpaperPath)) { + await fs.rm(currentWallpaperPath); + } + await fs.copyFile(path.join(userWallpapersPath, opt.input.name.replace(".preview", "")), currentWallpaperPath); return true; }), @@ -669,13 +672,16 @@ setWallpaperToDefaultWallpaper: procedure.input(z.object({ name: z.string() })).mutation(async (opt) => { const userWallpapersPath = path.join((await opt.ctx.user()).getPath(), "assets/wallpapers"); const officialWallpaperPath = path.join(instance.sys.filesystem.SRC_ROOT, "assets/wallpapers"); const resizedWallpapersPath = path.join(userWallpapersPath, "resized"); + const currentWallpaperPath = path.join(userWallpapersPath, "current.webp"); for (const resizedWallpaper of await fs.readdir(resizedWallpapersPath)) { await fs.rm(path.join(resizedWallpapersPath, resizedWallpaper)); } - await fs.rm(path.join(userWallpapersPath, "current.webp")); - await fs.copyFile(path.join(officialWallpaperPath, opt.input.name), path.join(userWallpapersPath, "current.webp")); + if (fsExistsSync(currentWallpaperPath)) { + await fs.rm(currentWallpaperPath); + } + await fs.copyFile(path.join(officialWallpaperPath, opt.input.name), currentWallpaperPath); return true; }), diff --git a/applications/uk.ewsgit.settings/web/Layout.tsx b/applications/uk.ewsgit.settings/web/Layout.tsx --- a/applications/uk.ewsgit.settings/web/Layout.tsx +++ b/applications/uk.ewsgit.settings/web/Layout.tsx @@ -5,7 +5,7 @@ import PERSON_ICON from "@material-symbols/svg-700/outlined/person.svg"; import SETTINGS_APPLICATIONS_ICON from "@material-symbols/svg-700/outlined/settings_applications.svg"; import STORAGE_ICON from "@material-symbols/svg-700/outlined/storage.svg"; import WALLPAPER_ICON from "@material-symbols/svg-700/outlined/wallpaper.svg"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKSideBar from "@onlineworkspace/uikit-solid/src/components/sideBar/UKSideBar.tsx"; import { useLocation, useNavigate, useSearchParams } from "@solidjs/router"; import { type Component, createEffect, createSignal, type ParentProps, Suspense } from "solid-js"; @@ -36,7 +36,7 @@ }} > {searchParams.sidebar_hidden === "true" ? (
- }>{props.children} + }>{props.children}
) : ( - }>{props.children} + }>{props.children} )} diff --git a/applications/uk.ewsgit.settings/web/pages/applications/Index.tsx b/applications/uk.ewsgit.settings/web/pages/applications/Index.tsx --- a/applications/uk.ewsgit.settings/web/pages/applications/Index.tsx +++ b/applications/uk.ewsgit.settings/web/pages/applications/Index.tsx @@ -1,5 +1,5 @@ import CHEVRON_LEFT_ICON from "@material-symbols/svg-700/outlined/chevron_left.svg"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKStack from "@onlineworkspace/uikit-solid/src/components/stack/UKStack.tsx"; import UKStackItem from "@onlineworkspace/uikit-solid/src/components/stack/UKStackItem.tsx"; import UKStackLabel from "@onlineworkspace/uikit-solid/src/components/stack/UKStackLabel.tsx"; @@ -28,7 +28,7 @@ }} />
Applications - }> + }> {(app) => { diff --git a/applications/uk.ewsgit.settings/web/pages/authentication/Index.tsx b/applications/uk.ewsgit.settings/web/pages/authentication/Index.tsx --- a/applications/uk.ewsgit.settings/web/pages/authentication/Index.tsx +++ b/applications/uk.ewsgit.settings/web/pages/authentication/Index.tsx @@ -1,5 +1,5 @@ import CHEVRON_LEFT_ICON from "@material-symbols/svg-700/outlined/chevron_left.svg"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKStack from "@onlineworkspace/uikit-solid/src/components/stack/UKStack.jsx"; import UKStackLabel from "@onlineworkspace/uikit-solid/src/components/stack/UKStackLabel.tsx"; import UKTopAppBar from "@onlineworkspace/uikit-solid/src/components/topAppBar/UKTopAppBar.jsx"; @@ -30,7 +30,7 @@ />
Login methods - }> + }> diff --git a/applications/uk.ewsgit.settings/web/pages/authentication/components/Sessions/Sessions.tsx b/applications/uk.ewsgit.settings/web/pages/authentication/components/Sessions/Sessions.tsx --- a/applications/uk.ewsgit.settings/web/pages/authentication/components/Sessions/Sessions.tsx +++ b/applications/uk.ewsgit.settings/web/pages/authentication/components/Sessions/Sessions.tsx @@ -1,6 +1,6 @@ import UKButton, { AffirmativeButtonState } from "@onlineworkspace/uikit-solid/src/components/button/UKButton.jsx"; import UKButtonGroup from "@onlineworkspace/uikit-solid/src/components/buttonGroup/UKButtonGroup.jsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKStack from "@onlineworkspace/uikit-solid/src/components/stack/UKStack.jsx"; import { type Component, createResource, For, Suspense } from "solid-js"; import trpc from "../../../../lib/trpc"; @@ -13,7 +13,7 @@ return ( <> - }> + }> {(s) => { return ; diff --git a/applications/uk.ewsgit.settings/web/pages/customization/quickShortcuts/components/addShortcutButton/AddShortcutButton.tsx b/applications/uk.ewsgit.settings/web/pages/customization/quickShortcuts/components/addShortcutButton/AddShortcutButton.tsx --- a/applications/uk.ewsgit.settings/web/pages/customization/quickShortcuts/components/addShortcutButton/AddShortcutButton.tsx +++ b/applications/uk.ewsgit.settings/web/pages/customization/quickShortcuts/components/addShortcutButton/AddShortcutButton.tsx @@ -1,10 +1,10 @@ import ADD_ICON from "@material-symbols/svg-700/outlined/add.svg"; import UKButton from "@onlineworkspace/uikit-solid/src/components/button/UKButton.tsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKCard from "@onlineworkspace/uikit-solid/src/components/card/UKCard.tsx"; import UKDialog from "@onlineworkspace/uikit-solid/src/components/dialog/UKDialog.tsx"; import UKDivider from "@onlineworkspace/uikit-solid/src/components/divider/UKDivider.jsx"; import UKIcon from "@onlineworkspace/uikit-solid/src/components/icon/UKIcon.tsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.tsx"; import { type Component, createSignal, For, Suspense } from "solid-js"; import styles from "./AddShortcutButton.module.scss"; @@ -43,7 +43,7 @@
- +
} > diff --git a/applications/uk.ewsgit.settings/web/pages/customization/wallpaper/Index.tsx b/applications/uk.ewsgit.settings/web/pages/customization/wallpaper/Index.tsx --- a/applications/uk.ewsgit.settings/web/pages/customization/wallpaper/Index.tsx +++ b/applications/uk.ewsgit.settings/web/pages/customization/wallpaper/Index.tsx @@ -5,10 +5,10 @@ import FOLDER_ICON from "@material-symbols/svg-700/outlined/folder.svg"; import UPLOAD_ICON from "@material-symbols/svg-700/outlined/upload.svg"; import UKButton from "@onlineworkspace/uikit-solid/src/components/button/UKButton.tsx"; import UKButtonGroup from "@onlineworkspace/uikit-solid/src/components/buttonGroup/UKButtonGroup.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx"; import { DividerDirection } from "@onlineworkspace/uikit-solid/src/components/divider/lib/direction.js"; import UKDivider from "@onlineworkspace/uikit-solid/src/components/divider/UKDivider.jsx"; import UKIconButton from "@onlineworkspace/uikit-solid/src/components/iconButton/UKIconButton.tsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx"; import UKStack from "@onlineworkspace/uikit-solid/src/components/stack/UKStack.jsx"; import UKStackItem from "@onlineworkspace/uikit-solid/src/components/stack/UKStackItem.jsx"; import UKStackLabel from "@onlineworkspace/uikit-solid/src/components/stack/UKStackLabel.jsx"; @@ -256,7 +256,7 @@ Previous Wallpapers
- }> + }> {(wallpaper) => { return ( diff --git a/applications/uk.ewsgit.settings/web/pages/profile/components/ProfilePicture/components/CropImage/CropImage.tsx b/applications/uk.ewsgit.settings/web/pages/profile/components/ProfilePicture/components/CropImage/CropImage.tsx --- a/applications/uk.ewsgit.settings/web/pages/profile/components/ProfilePicture/components/CropImage/CropImage.tsx +++ b/applications/uk.ewsgit.settings/web/pages/profile/components/ProfilePicture/components/CropImage/CropImage.tsx @@ -1,5 +1,5 @@ import UKButton, { AffirmativeButtonState } from "@onlineworkspace/uikit-solid/src/components/button/UKButton.tsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import { createFileUploader } from "@solid-primitives/upload"; import Cropper from "cropperjs"; import type { Component } from "solid-js"; @@ -42,7 +42,7 @@ return (
{files().length === 0 ? (
- +
) : ( <> diff --git a/applications/uk.ewsgit.store/web/Layout.tsx b/applications/uk.ewsgit.store/web/Layout.tsx --- a/applications/uk.ewsgit.store/web/Layout.tsx +++ b/applications/uk.ewsgit.store/web/Layout.tsx @@ -1,7 +1,7 @@ import APPS_ICON from "@material-symbols/svg-700/outlined/apps.svg"; import REWARDED_ADS_ICON from "@material-symbols/svg-700/outlined/rewarded_ads.svg"; import SEARCH_ICON from "@material-symbols/svg-700/outlined/search.svg"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx"; import UKSideBar from "@onlineworkspace/uikit-solid/src/components/sideBar/UKSideBar.tsx"; import { useLocation, useNavigate } from "@solidjs/router"; import { type Component, type ParentProps, Suspense } from "solid-js"; @@ -47,7 +47,7 @@ active: location.pathname === "/app/uk.ewsgit.store/manage-installed", }, ]} > - }>{props.children} + }>{props.children} ); }; diff --git a/applications/uk.ewsgit.store/web/pages/search/Index.tsx b/applications/uk.ewsgit.store/web/pages/search/Index.tsx --- a/applications/uk.ewsgit.store/web/pages/search/Index.tsx +++ b/applications/uk.ewsgit.store/web/pages/search/Index.tsx @@ -1,7 +1,7 @@ import INDETERMINATE_QUESTION_BOX_ICON from "@material-symbols/svg-700/outlined/indeterminate_question_box.svg"; import UKButton from "@onlineworkspace/uikit-solid/src/components/button/UKButton.jsx"; import UKIcon from "@onlineworkspace/uikit-solid/src/components/icon/UKIcon.jsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.jsx"; import UKTopAppBar from "@onlineworkspace/uikit-solid/src/components/topAppBar/UKTopAppBar.jsx"; import { type Component, createResource, createSignal, For, Suspense } from "solid-js"; @@ -31,7 +31,7 @@ }} value={searchQuery} placeholder={"Search Applications"} /> - }> + }> {(results() || [])?.length > 0 ? (
diff --git a/instance/src/systems/applications.ts b/instance/src/systems/applications.ts --- a/instance/src/systems/applications.ts +++ b/instance/src/systems/applications.ts @@ -38,7 +38,7 @@ for (const app of this.availableApplications) { if (this.enabledApplications.find((a) => a === app.manifest?.id)) { if (app.manifest?.modules.web) { applicationImportsInfill += `const App${ind}Router = lazy(() => import("${path.relative(path.join(this.instance.sys.filesystem.FS_ROOT), path.join(app.path, app.manifest.modules.web.path, "/App.tsx")).replaceAll("\\", "/")}"));`; - applicationsInfill += `}>`; + applicationsInfill += `}>`; ind++; } } @@ -48,7 +48,7 @@ if (this.availableApplications.length === 0) { applicationsInfill = `
How peculiar. You have no applications installed, please ask an administrator to install some via the command-line interface.
}/>`; } - const applicationsWebRouterTemplate = `import { Route } from "@solidjs/router";import { type Component, lazy, Suspense } from "solid-js";import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx";${applicationImportsInfill};const ApplicationsRouter: Component = () => {return (<>${applicationsInfill});};export default ApplicationsRouter`; + const applicationsWebRouterTemplate = `import { Route } from "@solidjs/router";import { type Component, lazy, Suspense } from "solid-js";import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx";${applicationImportsInfill};const ApplicationsRouter: Component = () => {return (<>${applicationsInfill});};export default ApplicationsRouter`; await fs.writeFile(path.join(this.instance.sys.filesystem.FS_ROOT, "Applications.tsx"), applicationsWebRouterTemplate); diff --git a/instance/src/systems/image.ts b/instance/src/systems/image.ts --- a/instance/src/systems/image.ts +++ b/instance/src/systems/image.ts @@ -1,5 +1,5 @@ +import * as nodePath from "node:path"; import { randomUUIDv7 } from "bun"; -import * as nodePath from "path"; import sharp from "sharp"; import type { Instance } from "../index.js"; import System from "../system.js"; diff --git a/instance/src/web/src/pages/app/AuthCheck.tsx b/instance/src/web/src/pages/app/AuthCheck.tsx --- a/instance/src/web/src/pages/app/AuthCheck.tsx +++ b/instance/src/web/src/pages/app/AuthCheck.tsx @@ -2,7 +2,7 @@ import UKButton from "@onlineworkspace/uikit-solid/src/components/button/UKButton.tsx"; import UKCard from "@onlineworkspace/uikit-solid/src/components/card/UKCard.tsx"; import { DividerDirection } from "@onlineworkspace/uikit-solid/src/components/divider/lib/direction.ts"; import UKDivider from "@onlineworkspace/uikit-solid/src/components/divider/UKDivider.tsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx"; import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.tsx"; import { useNavigate } from "@solidjs/router"; import { type Component, createResource, type ParentProps } from "solid-js"; @@ -16,7 +16,7 @@ return ( <> {checkResult() === undefined ? ( - + ) : !checkResult()?.authenticated ? ( diff --git a/instance/src/web/src/pages/app/Layout.tsx b/instance/src/web/src/pages/app/Layout.tsx --- a/instance/src/web/src/pages/app/Layout.tsx +++ b/instance/src/web/src/pages/app/Layout.tsx @@ -1,4 +1,4 @@ -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import { baselineTheme } from "@onlineworkspace/uikit-solid/src/core/design/themes/baseline.js"; import { applyTheme } from "@onlineworkspace/uikit-solid/src/core/design/tokens.js"; import { Ref } from "@solid-primitives/refs"; @@ -49,13 +49,13 @@ <> {window.localStorage.getItem("onlineworkspace_workspace_no_app_navigation_rail") !== "true" ? ( - }>{props.children} + }>{props.children} ) : (
- }>{props.children} + }>{props.children}
)} diff --git a/instance/src/web/src/pages/userSelect/Layout.tsx b/instance/src/web/src/pages/userSelect/Layout.tsx --- a/instance/src/web/src/pages/userSelect/Layout.tsx +++ b/instance/src/web/src/pages/userSelect/Layout.tsx @@ -1,5 +1,5 @@ import UKCard from "@onlineworkspace/uikit-solid/src/components/card/UKCard.jsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.jsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.jsx"; import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.jsx"; import type { RouteSectionProps } from "@solidjs/router"; import { type Component, Suspense } from "solid-js"; @@ -11,7 +11,7 @@ return (
- }>{props.children} + }>{props.children} Online Workspace Alpha diff --git a/instance/src/web/src/pages/userSelect/signup/Signup.tsx b/instance/src/web/src/pages/userSelect/signup/Signup.tsx --- a/instance/src/web/src/pages/userSelect/signup/Signup.tsx +++ b/instance/src/web/src/pages/userSelect/signup/Signup.tsx @@ -1,9 +1,9 @@ import UKAvatar from "@onlineworkspace/uikit-solid/src/components/avatar/UKAvatar.tsx"; import UKButton, { AffirmativeButtonState } from "@onlineworkspace/uikit-solid/src/components/button/UKButton.tsx"; +import UKCircularProgressIndicator from "@onlineworkspace/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx"; import UKCard from "@onlineworkspace/uikit-solid/src/components/card/UKCard.tsx"; import { DividerDirection } from "@onlineworkspace/uikit-solid/src/components/divider/lib/direction.ts"; import UKDivider from "@onlineworkspace/uikit-solid/src/components/divider/UKDivider.tsx"; -import UKIndeterminateSpinner from "@onlineworkspace/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx"; import UKSearchableDropdownMenu from "@onlineworkspace/uikit-solid/src/components/searchableDropdownMenu/UKSearchableDropdownMenu.tsx"; import UKText from "@onlineworkspace/uikit-solid/src/components/text/UKText.tsx"; import UKTextField from "@onlineworkspace/uikit-solid/src/components/textField/UKTextField.tsx"; @@ -53,7 +53,7 @@ const [twoFactorTestCode, setTwoFactorTestCode] = createSignal(""); const [isEmailCodeValid, setIsEmailCodeValid] = createSignal(false); return ( - }> + }> = (props) => { - return ( -
- {props.children} -
- ); + return ( +
+ {props.children} +
+ ); }; export default UKButtonGroup; diff --git a/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx b/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx new file mode 100644 --- /dev/null +++ b/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.tsx @@ -0,0 +1,27 @@ +import clsx from "clsx"; +import type { Component } from "solid-js"; +import styles from "./UKCircularProgressIndicator.module.scss"; + +const UKCircularProgressIndicator: Component<{ class?: string; centerSelf?: boolean }> = (props) => { + return ( +
+ + spinner + + + +
+ ); +}; + +export default UKCircularProgressIndicator; diff --git a/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.module.scss b/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.module.scss rename from uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.module.scss rename to uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.module.scss --- a/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.module.scss +++ b/uikit-solid/src/components/circularProgressIndicator/UKCircularProgressIndicator.module.scss diff --git a/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx b/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx deleted file mode 100644 --- a/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import clsx from "clsx"; -import type { Component } from "solid-js"; -import styles from "./UKIndeterminateSpinner.module.scss"; - -const UKIndeterminateSpinner: Component<{ class?: string; centerSelf?: boolean }> = (props) => { - return ( -
- - spinner - - - -
- ); -}; - -export default UKIndeterminateSpinner; diff --git a/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.module.scss b/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.module.scss new file mode 100644 --- /dev/null +++ b/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.module.scss @@ -0,0 +1,31 @@ +// track +.root { + --track-height: var(--thickness, 0.25rem); + + display: flex; + flex-direction: row; + width: 100%; + border-radius: 100rem; + height: var(--track-height); +} + +.activeIndicator { + border-radius: 100rem; + background-color: rgb(var(--uk-sys-color-primary)); +} + +.remainingIndicator { + border-radius: 100rem; + display: flex; + align-items: center; + background-color: rgb(var(--uk-sys-color-secondary-container)); +} + +.stopIndicator { + height: 0.25rem; + width: 0.25rem; + border-radius: 100rem; + background-color: rgb(var(--uk-sys-color-primary)); + margin-left: auto; + margin-right: calc(calc(var(--thickness) - 0.5rem) / 2); +} diff --git a/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.tsx b/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.tsx new file mode 100644 --- /dev/null +++ b/uikit-solid/src/components/linearProgressIndicator/UKLinearProgressIndicator.tsx @@ -0,0 +1,34 @@ +import { type Component, createEffect, createSignal } from "solid-js"; +import styles from "./UKLinearProgressIndicator.module.scss"; + +const UKLinearProgressIndicator: Component<{ start: number; stop: number; value: number; thickness?: number }> = (props) => { + const [percentageCompletion, setPercentageCompletion] = createSignal(45); + + createEffect(() => { + const range = props.stop - props.start; + + if (range === 0) { + setPercentageCompletion(0); + return; + } + + setPercentageCompletion(Math.min(Math.max(((props.value - props.start) / range) * 100, 0), 100)); + }); + + return ( +
+
+
5 ? "0.25rem" : "0px"})`, + "margin-left": percentageCompletion() <= 5 ? "0px" : "0.25rem", + }} + > +
+
+
+ ); +}; + +export default UKLinearProgressIndicator; diff --git a/uikit-solid/src/components/sideBar/UKSideBar.tsx b/uikit-solid/src/components/sideBar/UKSideBar.tsx --- a/uikit-solid/src/components/sideBar/UKSideBar.tsx +++ b/uikit-solid/src/components/sideBar/UKSideBar.tsx @@ -1,12 +1,12 @@ -import { createSignal, Index, Show, type Component, type ParentProps } from "solid-js"; -import styles from "./UKSideBar.module.scss"; -import UKIcon from "../icon/UKIcon.tsx"; +import MENU_ICON from "@material-symbols/svg-700/outlined/menu.svg"; +import MENU_OPEN_ICON from "@material-symbols/svg-700/outlined/menu_open.svg"; +import clsx from "clsx"; +import { type Component, createSignal, Index, type ParentProps, Show } from "solid-js"; import useIsMobile from "../../core/useIsMobile.ts"; import UKDivider from "../divider/UKDivider.tsx"; +import UKIcon from "../icon/UKIcon.tsx"; import UKIconButton from "../iconButton/UKIconButton.tsx"; -import clsx from "clsx"; -import MENU_ICON from "@material-symbols/svg-700/outlined/menu.svg" -import MENU_OPEN_ICON from "@material-symbols/svg-700/outlined/menu_open.svg"; +import styles from "./UKSideBar.module.scss"; interface ButtonItem { type: "button"; @@ -32,16 +32,22 @@ interface MarginItem { type: "margin"; } +interface ComponentItem { + type: "component"; + component: Component; +} + const UKSideBar: Component< ParentProps<{ - items: (ButtonItem | LabelItem | DividerItem | MarginItem | undefined)[]; + items: (ButtonItem | LabelItem | DividerItem | MarginItem | ComponentItem | undefined)[]; + containerClassName?: string; }> > = (props) => { const isMobile = useIsMobile(); const [isMobileToggled, setIsMobileToggled] = createSignal(false); return ( -
+
{isMobile() && ( ; case "divider": return ; + case "component": + return <>{(item() as ComponentItem).component}; default: return
AHH
; } -- tangled.sh