From f3444ccfadeb5e0375f9331968d81bf079a0fcd3 Mon Sep 17 00:00:00 2001 From: Ayush Sehrawat <69469790+AyushSehrawat@users.noreply.github.com> Date: Tue, 26 Dec 2023 00:50:25 +0530 Subject: [PATCH] feat: added content settings and other minor improvements (#88) * feat: added command menu * feat: added partial content settings * feat: improved progress bar with real progress * feat: added working of input chips & other minor improvements * feat: completed adding all settings and some other minor improvements --- frontend/package.json | 3 + frontend/pnpm-lock.yaml | 51 +++++ frontend/src/app.pcss | 2 + frontend/src/lib/components/header.svelte | 40 +--- .../ui/command/command-dialog.svelte | 23 ++ .../ui/command/command-empty.svelte | 15 ++ .../ui/command/command-group.svelte | 18 ++ .../ui/command/command-input.svelte | 23 ++ .../components/ui/command/command-item.svelte | 19 ++ .../components/ui/command/command-list.svelte | 15 ++ .../ui/command/command-separator.svelte | 13 ++ .../ui/command/command-shortcut.svelte | 19 ++ .../lib/components/ui/command/command.svelte | 22 ++ .../src/lib/components/ui/command/index.ts | 37 ++++ .../ui/dialog/dialog-content.svelte | 36 ++++ .../ui/dialog/dialog-description.svelte | 16 ++ .../components/ui/dialog/dialog-footer.svelte | 19 ++ .../components/ui/dialog/dialog-header.svelte | 16 ++ .../ui/dialog/dialog-overlay.svelte | 24 +++ .../components/ui/dialog/dialog-portal.svelte | 8 + .../components/ui/dialog/dialog-title.svelte | 16 ++ .../src/lib/components/ui/dialog/index.ts | 34 +++ frontend/src/lib/schemas/setting.ts | 14 +- frontend/src/nprogress.css | 83 +++++++ frontend/src/routes/+layout.svelte | 97 ++++++++- frontend/src/routes/settings/+layout.svelte | 4 +- .../src/routes/settings/about/+page.svelte | 26 ++- .../routes/settings/content/+page.server.ts | 68 +++++- .../src/routes/settings/content/+page.svelte | 202 +++++++++++++++++- .../routes/settings/general/+page.server.ts | 1 - .../src/routes/settings/general/+page.svelte | 5 +- .../src/routes/settings/plex/+page.server.ts | 2 - .../src/routes/settings/plex/+page.svelte | 2 +- 33 files changed, 913 insertions(+), 60 deletions(-) create mode 100644 frontend/src/lib/components/ui/command/command-dialog.svelte create mode 100644 frontend/src/lib/components/ui/command/command-empty.svelte create mode 100644 frontend/src/lib/components/ui/command/command-group.svelte create mode 100644 frontend/src/lib/components/ui/command/command-input.svelte create mode 100644 frontend/src/lib/components/ui/command/command-item.svelte create mode 100644 frontend/src/lib/components/ui/command/command-list.svelte create mode 100644 frontend/src/lib/components/ui/command/command-separator.svelte create mode 100644 frontend/src/lib/components/ui/command/command-shortcut.svelte create mode 100644 frontend/src/lib/components/ui/command/command.svelte create mode 100644 frontend/src/lib/components/ui/command/index.ts create mode 100644 frontend/src/lib/components/ui/dialog/dialog-content.svelte create mode 100644 frontend/src/lib/components/ui/dialog/dialog-description.svelte create mode 100644 frontend/src/lib/components/ui/dialog/dialog-footer.svelte create mode 100644 frontend/src/lib/components/ui/dialog/dialog-header.svelte create mode 100644 frontend/src/lib/components/ui/dialog/dialog-overlay.svelte create mode 100644 frontend/src/lib/components/ui/dialog/dialog-portal.svelte create mode 100644 frontend/src/lib/components/ui/dialog/dialog-title.svelte create mode 100644 frontend/src/lib/components/ui/dialog/index.ts create mode 100644 frontend/src/nprogress.css diff --git a/frontend/package.json b/frontend/package.json index c0657b15..6c12a79c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,6 +18,7 @@ "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/luxon": "^3.3.7", + "@types/nprogress": "^0.2.3", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.0.0", "autoprefixer": "^10.4.14", @@ -40,9 +41,11 @@ "dependencies": { "bits-ui": "^0.11.8", "clsx": "^2.0.0", + "cmdk-sv": "^0.0.12", "lucide-svelte": "^0.298.0", "luxon": "^3.4.4", "mode-watcher": "^0.1.2", + "nprogress": "^0.2.0", "svelte-sonner": "^0.3.6", "sveltekit-superforms": "^1.13.0", "tailwind-merge": "^2.1.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index d0b52271..11a6d4f7 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -11,6 +11,9 @@ dependencies: clsx: specifier: ^2.0.0 version: 2.0.0 + cmdk-sv: + specifier: ^0.0.12 + version: 0.0.12(svelte@4.2.8) lucide-svelte: specifier: ^0.298.0 version: 0.298.0(svelte@4.2.8) @@ -20,6 +23,9 @@ dependencies: mode-watcher: specifier: ^0.1.2 version: 0.1.2(svelte@4.2.8) + nprogress: + specifier: ^0.2.0 + version: 0.2.0 svelte-sonner: specifier: ^0.3.6 version: 0.3.6(svelte@4.2.8) @@ -52,6 +58,9 @@ devDependencies: '@types/luxon': specifier: ^3.3.7 version: 3.3.7 + '@types/nprogress': + specifier: ^0.2.3 + version: 0.2.3 '@typescript-eslint/eslint-plugin': specifier: ^6.14.0 version: 6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.56.0)(typescript@5.3.3) @@ -417,6 +426,20 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + /@melt-ui/svelte@0.61.2(svelte@4.2.8): + resolution: {integrity: sha512-BHkD9G31zQBToA4euDRBgTQRvWxT9scufOVCXgDO6HKTvyxFspbWT2bgiSFqAK4BbAGDn9Ao36Q8F9O71KN4OQ==} + peerDependencies: + svelte: '>=3 <5' + dependencies: + '@floating-ui/core': 1.5.2 + '@floating-ui/dom': 1.5.3 + '@internationalized/date': 3.5.0 + dequal: 2.0.3 + focus-trap: 7.5.4 + nanoid: 4.0.2 + svelte: 4.2.8 + dev: false + /@melt-ui/svelte@0.65.2(svelte@4.2.8): resolution: {integrity: sha512-BpsSl9Bjp1++8U3+LaDOFUoX/PFQ9N7QWFhlFdUEZduhrbVyU70v9A459SKrQ+esFSjvh1AvqJYkMAUJXJlAmQ==} peerDependencies: @@ -711,6 +734,10 @@ packages: resolution: {integrity: sha512-gKc9P2d4g5uYwmy4s/MO/yOVPmvHyvzka1YH6i5dM03UrFofHSmgc0D0ymbDRStFWHusk6cwwF6nhLm/ckBbbQ==} dev: true + /@types/nprogress@0.2.3: + resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} + dev: true + /@types/pug@2.0.10: resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} dev: true @@ -1010,6 +1037,16 @@ packages: svelte: 4.2.8 dev: false + /bits-ui@0.9.9(svelte@4.2.8): + resolution: {integrity: sha512-LkdkyTtpXdkjBzPZJVJgpcre4fut6DONoprMfadHFo82HNUhph+02CxDjYEcZcThb5z4YjSxMlCYvQPZm+YtfQ==} + peerDependencies: + svelte: ^4.0.0 + dependencies: + '@melt-ui/svelte': 0.61.2(svelte@4.2.8) + nanoid: 5.0.4 + svelte: 4.2.8 + dev: false + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1112,6 +1149,16 @@ packages: engines: {node: '>=6'} dev: false + /cmdk-sv@0.0.12(svelte@4.2.8): + resolution: {integrity: sha512-d+eILSOb2W+/3U/j7xGTgGRrZkFB/z4Xlvj0ADrWhf34y9YLzJon3JCGP2hMil5IrVm0P/+IFIeCF5l3//kcjA==} + peerDependencies: + svelte: ^4.0.0 + dependencies: + bits-ui: 0.9.9(svelte@4.2.8) + nanoid: 5.0.4 + svelte: 4.2.8 + dev: false + /code-red@1.0.4: resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} dependencies: @@ -1971,6 +2018,10 @@ packages: path-key: 4.0.0 dev: true + /nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + dev: false + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} diff --git a/frontend/src/app.pcss b/frontend/src/app.pcss index 6ff7062d..5e538664 100644 --- a/frontend/src/app.pcss +++ b/frontend/src/app.pcss @@ -1,3 +1,5 @@ +@import 'nprogress.css'; + @tailwind base; @tailwind components; @tailwind utilities; diff --git a/frontend/src/lib/components/header.svelte b/frontend/src/lib/components/header.svelte index 37a9a8dc..bc0875de 100644 --- a/frontend/src/lib/components/header.svelte +++ b/frontend/src/lib/components/header.svelte @@ -2,9 +2,8 @@ import type { NavItem } from '$lib/types'; import ThemeSwitcher from '$lib/components/theme-switcher.svelte'; import NavigationItem from '$lib/components/header-item.svelte'; - import { Mountain, MoreHorizontal, X, Loader2 } from 'lucide-svelte'; + import { Mountain, MoreHorizontal, X, Command } from 'lucide-svelte'; import { Button } from '$lib/components/ui/button'; - import { navigating } from '$app/stores'; const navItems: NavItem[] = [ { @@ -32,6 +31,13 @@

Iceberg

+
-{#if $navigating} -
-
-
-{/if} -
diff --git a/frontend/src/lib/components/ui/command/command-dialog.svelte b/frontend/src/lib/components/ui/command/command-dialog.svelte new file mode 100644 index 00000000..ecbf940f --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-dialog.svelte @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/frontend/src/lib/components/ui/command/command-empty.svelte b/frontend/src/lib/components/ui/command/command-empty.svelte new file mode 100644 index 00000000..f5e83e23 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-empty.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/frontend/src/lib/components/ui/command/command-group.svelte b/frontend/src/lib/components/ui/command/command-group.svelte new file mode 100644 index 00000000..198a3df3 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-group.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/frontend/src/lib/components/ui/command/command-input.svelte b/frontend/src/lib/components/ui/command/command-input.svelte new file mode 100644 index 00000000..057193a3 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-input.svelte @@ -0,0 +1,23 @@ + + +
+ + +
diff --git a/frontend/src/lib/components/ui/command/command-item.svelte b/frontend/src/lib/components/ui/command/command-item.svelte new file mode 100644 index 00000000..89a9e970 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-item.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/frontend/src/lib/components/ui/command/command-list.svelte b/frontend/src/lib/components/ui/command/command-list.svelte new file mode 100644 index 00000000..6b1c915c --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-list.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/frontend/src/lib/components/ui/command/command-separator.svelte b/frontend/src/lib/components/ui/command/command-separator.svelte new file mode 100644 index 00000000..249008b6 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-separator.svelte @@ -0,0 +1,13 @@ + + + diff --git a/frontend/src/lib/components/ui/command/command-shortcut.svelte b/frontend/src/lib/components/ui/command/command-shortcut.svelte new file mode 100644 index 00000000..ede60875 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command-shortcut.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/frontend/src/lib/components/ui/command/command.svelte b/frontend/src/lib/components/ui/command/command.svelte new file mode 100644 index 00000000..28067593 --- /dev/null +++ b/frontend/src/lib/components/ui/command/command.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/frontend/src/lib/components/ui/command/index.ts b/frontend/src/lib/components/ui/command/index.ts new file mode 100644 index 00000000..6fdefa6b --- /dev/null +++ b/frontend/src/lib/components/ui/command/index.ts @@ -0,0 +1,37 @@ +import { Command as CommandPrimitive } from "cmdk-sv"; + +import Root from "./command.svelte"; +import Dialog from "./command-dialog.svelte"; +import Empty from "./command-empty.svelte"; +import Group from "./command-group.svelte"; +import Item from "./command-item.svelte"; +import Input from "./command-input.svelte"; +import List from "./command-list.svelte"; +import Separator from "./command-separator.svelte"; +import Shortcut from "./command-shortcut.svelte"; + +const Loading = CommandPrimitive.Loading; + +export { + Root, + Dialog, + Empty, + Group, + Item, + Input, + List, + Separator, + Shortcut, + Loading, + // + Root as Command, + Dialog as CommandDialog, + Empty as CommandEmpty, + Group as CommandGroup, + Item as CommandItem, + Input as CommandInput, + List as CommandList, + Separator as CommandSeparator, + Shortcut as CommandShortcut, + Loading as CommandLoading +}; diff --git a/frontend/src/lib/components/ui/dialog/dialog-content.svelte b/frontend/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 00000000..8646900a --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,36 @@ + + + + + + + + + Close + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-description.svelte b/frontend/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 00000000..7250e093 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-footer.svelte b/frontend/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 00000000..36c0cca6 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,19 @@ + + +
+ +
diff --git a/frontend/src/lib/components/ui/dialog/dialog-header.svelte b/frontend/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 00000000..82fbe51f --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,16 @@ + + +
+ +
diff --git a/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte b/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 00000000..9524e520 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,24 @@ + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-portal.svelte b/frontend/src/lib/components/ui/dialog/dialog-portal.svelte new file mode 100644 index 00000000..eb5d0a57 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-portal.svelte @@ -0,0 +1,8 @@ + + + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-title.svelte b/frontend/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 00000000..fb863c9c --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/frontend/src/lib/components/ui/dialog/index.ts b/frontend/src/lib/components/ui/dialog/index.ts new file mode 100644 index 00000000..c05c48e8 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,34 @@ +import { Dialog as DialogPrimitive } from "bits-ui"; + +const Root = DialogPrimitive.Root; +const Trigger = DialogPrimitive.Trigger; + +import Title from "./dialog-title.svelte"; +import Portal from "./dialog-portal.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription +}; diff --git a/frontend/src/lib/schemas/setting.ts b/frontend/src/lib/schemas/setting.ts index 4f79174c..9020d6b3 100644 --- a/frontend/src/lib/schemas/setting.ts +++ b/frontend/src/lib/schemas/setting.ts @@ -10,6 +10,18 @@ export const generalSettingsSchema = z.object({ export const plexSettingsSchema = z.object({ user: z.string().min(1), token: z.string().min(1), - url: z.string().min(1), + url: z.string().url().min(1), watchlist: z.string().optional().default('') }); + +export const contentSettingsSchema = z.object({ + overseerr_url: z.string().url().optional().default(''), + overseerr_api_key: z.string().optional().default(''), + mdblist_api_key: z.string().optional().default(''), + mdblist_update_interval: z.number().int().min(1).default(80), + mdblist_lists: z.string().array().default(['']) +}); + +type GeneralSettings = z.infer; +type PlexSettings = z.infer; +type ContentSettings = z.infer; diff --git a/frontend/src/nprogress.css b/frontend/src/nprogress.css new file mode 100644 index 00000000..fa84bdb2 --- /dev/null +++ b/frontend/src/nprogress.css @@ -0,0 +1,83 @@ +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: red; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 3px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: + 0 0 10px red, + 0 0 5px red; + opacity: 1; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: red; + border-left-color: red; + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } +} +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 70d40124..afd64432 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -1,8 +1,37 @@ - @@ -12,3 +41,69 @@
+ + + + + No results found. + + { + open = false; + await goto('/settings'); + }} + > + + Settings + + { + open = false; + await goto('/status'); + }} + > + + Status + + + + + { + open = false; + await goto('/settings/general'); + }} + > + + General + + { + open = false; + await goto('/settings/plex'); + }} + > + + Plex + + { + open = false; + await goto('/settings/content'); + }} + > + + Content + + { + open = false; + await goto('/settings/about'); + }} + > + + About + + + + diff --git a/frontend/src/routes/settings/+layout.svelte b/frontend/src/routes/settings/+layout.svelte index 014a0cee..59f754a2 100644 --- a/frontend/src/routes/settings/+layout.svelte +++ b/frontend/src/routes/settings/+layout.svelte @@ -52,13 +52,13 @@