From 8eda5e6672556d9c51b8b039ce0fb37a7844a023 Mon Sep 17 00:00:00 2001 From: Astra Date: Thu, 15 May 2025 11:40:39 +0900 Subject: [PATCH 1/9] Config.ts -> config.ts.example --- README.md | 4 +++- config.ts => config.ts.example | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) rename config.ts => config.ts.example (52%) diff --git a/README.md b/README.md index d9eb2ea..45276cb 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ a frontend dashboard with stats for your ATProto PDS. ### installing -clone the repo, install dependencies using deno: +clone the repo, copy `config.ts.example` to `config.ts` and edit it to your liking. + +then, install dependencies using deno: ```sh deno install diff --git a/config.ts b/config.ts.example similarity index 52% rename from config.ts rename to config.ts.example index 8d09cf6..70caf9c 100644 --- a/config.ts +++ b/config.ts.example @@ -3,14 +3,14 @@ */ export class Config { /** - * The base URL of the PDS (Personal Data Server) - * @default "https://pds.witchcraft.systems" + * The base URL of the PDS (Personal Data Server). + * @default none */ - static readonly PDS_URL: string = "https://pds.witchcraft.systems"; + static readonly PDS_URL: string = ""; /** * The base URL of the frontend service for linking to replies/quotes/accounts etc. - * @default "https://deer.social" + * @default "https://deer.social" // or https://bsky.app if you're boring */ static readonly FRONTEND_URL: string = "https://deer.social"; @@ -24,13 +24,14 @@ export class Config { static readonly MAX_POSTS: number = 20; /** - * Footer text for the dashboard, you probably want to change this + * Footer text for the dashboard, you probably want to change this. Supports HTML. + * @default "Source (github mirror)" */ static readonly FOOTER_TEXT: string = - "Astrally projected from witchcraft.systems

Source (github mirror)"; + "Source (github mirror)"; /** - * Whether to show the posts that are in the future + * Whether to show the posts with timestamps that are in the future. * @default false */ static readonly SHOW_FUTURE_POSTS: boolean = false; From 4e1faff7e3b00083ee0b77d619a8b887cba1a2fd Mon Sep 17 00:00:00 2001 From: Astra Date: Thu, 15 May 2025 14:22:02 +0900 Subject: [PATCH 2/9] Update gitignore for configs --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 42a517f..991a625 100644 --- a/.gitignore +++ b/.gitignore @@ -149,4 +149,7 @@ dist .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz -.pnp.* \ No newline at end of file +.pnp.* + +# Config files +config.ts \ No newline at end of file From e49ce63db96b23bc130417a2b1cf4eb895f41a72 Mon Sep 17 00:00:00 2001 From: Ari Date: Thu, 15 May 2025 01:35:50 -0400 Subject: [PATCH 3/9] Build step for the theme file --- config.ts.example | 6 ++++ src/app.css | 89 ++--------------------------------------------- vite.config.ts | 6 +++- 3 files changed, 13 insertions(+), 88 deletions(-) diff --git a/config.ts.example b/config.ts.example index 70caf9c..3b78dde 100644 --- a/config.ts.example +++ b/config.ts.example @@ -8,6 +8,12 @@ export class Config { */ static readonly PDS_URL: string = ""; + /** + * Theme css file to be used + * @default "theme.css" + */ + static readonly THEME: string = "themes/theme.css"; + /** * The base URL of the frontend service for linking to replies/quotes/accounts etc. * @default "https://deer.social" // or https://bsky.app if you're boring diff --git a/src/app.css b/src/app.css index 50da734..88cb00c 100644 --- a/src/app.css +++ b/src/app.css @@ -1,88 +1,3 @@ -@font-face { - font-family: "ProggyClean"; - src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf); -} - -:root { - --link-color: #646cff; - --link-hover-color: #535bf2; - --background-color: #12082b; - --header-background-color: #1f1145; - --content-background-color: #0d0620; - --text-color: white; - --border-color: #8054f0; - --indicator-inactive-color: #4a4a4a; - --indicator-active-color: #8054f0; -} - -::-webkit-scrollbar { - width: 0px; - background: transparent; - padding: 0; - margin: 0; -} -::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 0; -} -::-webkit-scrollbar-track { - background: transparent; - border-radius: 0; -} -::-webkit-scrollbar-corner { - background: transparent; - border-radius: 0; -} -::-webkit-scrollbar-button { - background: transparent; - border-radius: 0; -} -* { - scrollbar-width: none; - scrollbar-color: transparent transparent; - -ms-overflow-style: none; /* IE and Edge */ - -webkit-overflow-scrolling: touch; - -webkit-scrollbar: none; /* Safari */ -} - -a { - font-weight: 500; - color: var(--link-color); - text-decoration: inherit; -} -a:hover { - color: var(--link-hover-color); - text-decoration: underline; -} - body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; - background-color: var(--background-color); - font-family: "ProggyClean", monospace; - font-size: 24px; - color: var(--text-color); - border-color: var(--border-color); - overflow-wrap: break-word; - word-wrap: normal; - word-break: break-word; - hyphens: none; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -#app { - max-width: 1400px; - width: 100%; - margin: 0; - padding: 0; - margin-left: auto; - margin-right: auto; - text-align: center; -} + background-color: red; +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 20d2272..96d3c8c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,11 @@ import { defineConfig } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; +import { themePlugin } from "./theming"; // https://vite.dev/config/ export default defineConfig({ - plugins: [svelte()], + plugins: [ + themePlugin(), + svelte(), + ], }); From 0a6279823efa8ca3c323b07f031791561454e838 Mon Sep 17 00:00:00 2001 From: Ari Date: Thu, 15 May 2025 01:36:19 -0400 Subject: [PATCH 4/9] Build step for the css themes continued --- src/themes/theme.css | 89 ++++++++++++++++++++++++++++++++++++++++++++ theming.ts | 30 +++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 src/themes/theme.css create mode 100644 theming.ts diff --git a/src/themes/theme.css b/src/themes/theme.css new file mode 100644 index 0000000..35739c0 --- /dev/null +++ b/src/themes/theme.css @@ -0,0 +1,89 @@ +@font-face { + font-family: "ProggyClean"; + src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf); +} + +:root { + --link-color: #646cff; + --link-hover-color: #535bf2; + --background-color: #12082b; + --header-background-color: #1f1145; + --content-background-color: #0d0620; + --text-color: white; + --border-color: #8054f0; + --indicator-inactive-color: #4a4a4a; + --indicator-active-color: #8054f0; +} + + +::-webkit-scrollbar { + width: 0px; + background: transparent; + padding: 0; + margin: 0; +} +::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 0; +} +::-webkit-scrollbar-track { + background: transparent; + border-radius: 0; +} +::-webkit-scrollbar-corner { + background: transparent; + border-radius: 0; +} +::-webkit-scrollbar-button { + background: transparent; + border-radius: 0; +} +* { + scrollbar-width: none; + scrollbar-color: transparent transparent; + -ms-overflow-style: none; /* IE and Edge */ + -webkit-overflow-scrolling: touch; + -webkit-scrollbar: none; /* Safari */ +} + +a { + font-weight: 500; + color: var(--link-color); + text-decoration: inherit; +} +a:hover { + color: var(--link-hover-color); + text-decoration: underline; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; + background-color: var(--background-color); + font-family: "ProggyClean", monospace; + font-size: 24px; + color: var(--text-color); + border-color: var(--border-color); + overflow-wrap: break-word; + word-wrap: normal; + word-break: break-word; + hyphens: none; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1400px; + width: 100%; + margin: 0; + padding: 0; + margin-left: auto; + margin-right: auto; + text-align: center; +} diff --git a/theming.ts b/theming.ts new file mode 100644 index 0000000..60117fd --- /dev/null +++ b/theming.ts @@ -0,0 +1,30 @@ +import { Plugin } from 'vite'; +import { Config } from './config'; +// Replaces app.css with the contents of the file specified in the +// config file. + +export const themePlugin = (): Plugin => { + const themeFile = Config.THEME; + console.log(`Using theme file: ${themeFile}`); + return { + name: 'theme-generator', + transform(code, id) { + if (id.endsWith('app.css')) { + // Read the theme file and replace the contents of app.css with it + // Needs full path to the file + const themeCode = Deno.readTextFileSync(Deno.cwd() + '/src/themes/' + themeFile); + // Replace the contents of app.css with the theme code + + // and add a comment at the top + const themeComment = `/* Generated from ${themeFile} */\n`; + const themeCodeWithComment = themeComment + themeCode; + // Return the theme code as the new contents of app.css + return { + code: themeCodeWithComment, + map: null, + }; + } + return null; + } + }; +}; \ No newline at end of file From cebae8c7ae5a1e54d5f9db6b90347c7f911f443c Mon Sep 17 00:00:00 2001 From: Ari Date: Thu, 15 May 2025 01:59:24 -0400 Subject: [PATCH 5/9] Moved all the styles into a single file --- src/App.svelte | 87 +--------- src/lib/AccountComponent.svelte | 25 --- src/lib/PostComponent.svelte | 162 ------------------ src/themes/theme.css | 282 +++++++++++++++++++++++++++++++- theming.ts | 3 +- 5 files changed, 284 insertions(+), 275 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index c6e7534..3ce393b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -64,90 +64,5 @@ diff --git a/src/lib/AccountComponent.svelte b/src/lib/AccountComponent.svelte index 880db3f..3f12cf7 100644 --- a/src/lib/AccountComponent.svelte +++ b/src/lib/AccountComponent.svelte @@ -20,30 +20,5 @@ diff --git a/src/lib/PostComponent.svelte b/src/lib/PostComponent.svelte index 43ad667..6cb6bcd 100644 --- a/src/lib/PostComponent.svelte +++ b/src/lib/PostComponent.svelte @@ -152,167 +152,5 @@ diff --git a/src/themes/theme.css b/src/themes/theme.css index 35739c0..08b0e1f 100644 --- a/src/themes/theme.css +++ b/src/themes/theme.css @@ -15,7 +15,6 @@ --indicator-active-color: #8054f0; } - ::-webkit-scrollbar { width: 0px; background: transparent; @@ -87,3 +86,284 @@ h1 { margin-right: auto; text-align: center; } + +/* Post Component */ + a:hover { + text-decoration: underline; + } + #postContainer { + display: flex; + flex-direction: column; + border: 1px solid var(--border-color); + background-color: var(--background-color); + margin-bottom: 15px; + overflow-wrap: break-word; + } + #postHeader { + display: flex; + flex-direction: row; + align-items: center; + justify-content: start; + background-color: var(--header-background-color); + padding: 0px 0px; + height: fit-content; + border-bottom: 1px solid var(--border-color); + font-weight: bold; + overflow-wrap: break-word; + height: 60px; + } + #displayName { + display: block; + color: var(--text-color); + font-size: 1.2em; + padding: 0; + margin: 0; + overflow-wrap:normal; + word-wrap: break-word; + word-break: break-word; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + width: 100%; + } + #handle { + display: block; + color: var(--border-color); + font-size: 0.8em; + padding: 0; + margin: 0; + } + + #postLink { + color: var(--border-color); + font-size: 0.8em; + padding: 0; + margin: 0; + } + #postContent { + display: flex; + text-align: start; + flex-direction: column; + padding: 10px; + background-color: var(--content-background-color); + color: var(--text-color); + overflow-wrap: break-word; + white-space: pre-line; + } + #replyingText { + font-size: 0.7em; + margin: 0; + padding: 0; + padding-bottom: 5px; + } + #quotingText { + font-size: 0.7em; + margin: 0; + padding: 0; + padding-bottom: 5px; + } + #postText { + margin: 0; + padding: 0; + overflow-wrap: break-word; + word-wrap: normal; + word-break: break-word; + hyphens: none; + } + #headerText { + margin-left: 10px; + font-size: 0.9em; + text-align: start; + word-break: break-word; + max-width: 80%; + max-height: 95%; + overflow: hidden; + align-self: flex-start; + margin-top: auto; + margin-bottom: auto; + } + #avatar { + height: 60px; + width: 60px; + margin: 0px; + margin-left: 0px; + overflow: hidden; + object-fit: cover; + border-right: var(--border-color) 1px solid; + } + #carouselContainer { + position: relative; + width: 100%; + margin-top: 10px; + display: flex; + flex-direction: column; + align-items: center; + } + #carouselControls { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + max-width: 500px; + margin-top: 5px; + } + #carouselIndicators { + display: flex; + gap: 5px; + } + .indicator { + width: 8px; + height: 8px; + background-color: var(--indicator-inactive-color); + } + .indicator.active { + background-color: var(--indicator-active-color); + } + #prevBtn, + #nextBtn { + background-color: rgba(31, 17, 69, 0.7); + color: var(--text-color); + border: 1px solid var(--border-color); + width: 30px; + height: 30px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + } + #prevBtn:disabled, + #nextBtn:disabled { + opacity: 0.5; + cursor: not-allowed; + } + #embedVideo { + width: 100%; + max-width: 500px; + margin-top: 10px; + align-self: center; + } + + #embedImages { + min-width: min(100%, 500px); + max-width: min(100%, 500px); + max-height: 500px; + object-fit: contain; + + margin: 0; + } + +/* Account Component */ + #accountContainer { + display: flex; + text-align: start; + align-items: center; + background-color: var(--background-color); + padding: 0px; + margin-bottom: 15px; + border: 1px solid var(--border-color); + } + #accountName { + margin-left: 10px; + font-size: 0.9em; + max-width: 80%; + + /* replace overflow with ellipsis */ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + #avatar { + width: 50px; + height: 50px; + margin: 0px; + object-fit: cover; + border-right: var(--border-color) 1px solid; + } + +/* App.Svelte */ + /* desktop style */ + + #Content { + display: flex; + /* split the screen in half, left for accounts, right for posts */ + width: 100%; + height: 100%; + flex-direction: row; + justify-content: space-between; + align-items: center; + background-color: var(--background-color); + color: var(--text-color); + } + #Feed { + overflow-y: scroll; + width: 65%; + height: 100vh; + padding: 20px; + padding-bottom: 0; + padding-top: 0; + margin-top: 0; + margin-bottom: 0; + } + #spacer { + padding: 0; + margin: 0; + height: 10vh; + width: 100%; + } + #Account { + width: 35%; + display: flex; + flex-direction: column; + border: 1px solid var(--border-color); + background-color: var(--content-background-color); + height: 80vh; + padding: 20px; + margin-left: 20px; + } + #accountsList { + display: flex; + flex-direction: column; + overflow-y: scroll; + height: 100%; + width: 100%; + padding: 0px; + margin: 0px; + } + + #Header { + text-align: center; + font-size: 2em; + margin-bottom: 20px; + } + + /* mobile style */ + @media screen and (max-width: 600px) { + #Content { + flex-direction: column; + width: auto; + padding-left: 0px; + padding-right: 0px; + margin-top: 5%; + } + #Account { + width: 85%; + padding-left: 5%; + padding-right: 5%; + margin-bottom: 20px; + margin-left: 5%; + margin-right: 5%; + height: auto; + } + #Feed { + width: 95%; + margin: 0px; + margin-left: 10%; + margin-right: 10%; + padding: 0px; + overflow-y: visible; + } + + #spacer { + height: 0; + } + } \ No newline at end of file diff --git a/theming.ts b/theming.ts index 60117fd..b0856bb 100644 --- a/theming.ts +++ b/theming.ts @@ -1,8 +1,9 @@ import { Plugin } from 'vite'; import { Config } from './config'; + + // Replaces app.css with the contents of the file specified in the // config file. - export const themePlugin = (): Plugin => { const themeFile = Config.THEME; console.log(`Using theme file: ${themeFile}`); From ec73af56183d17e25e85628867bedea6cda9bd49 Mon Sep 17 00:00:00 2001 From: Ari Date: Thu, 15 May 2025 02:24:42 -0400 Subject: [PATCH 6/9] Added a separate file for color variables --- src/app.css | 1 + src/themes/colors.css | 11 +++++++++++ src/themes/theme.css | 12 ------------ theming.ts | 3 ++- 4 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 src/themes/colors.css diff --git a/src/app.css b/src/app.css index 88cb00c..cb315e4 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,4 @@ +@import url('./themes/colors.css'); body { background-color: red; } \ No newline at end of file diff --git a/src/themes/colors.css b/src/themes/colors.css new file mode 100644 index 0000000..bc036e4 --- /dev/null +++ b/src/themes/colors.css @@ -0,0 +1,11 @@ +:root { + --link-color: #646cff; + --link-hover-color: #535bf2; + --background-color: #12082b; + --header-background-color: #1f1145; + --content-background-color: #0d0620; + --text-color: white; + --border-color: #8054f0; + --indicator-inactive-color: #4a4a4a; + --indicator-active-color: #8054f0; +} \ No newline at end of file diff --git a/src/themes/theme.css b/src/themes/theme.css index 08b0e1f..4ae67be 100644 --- a/src/themes/theme.css +++ b/src/themes/theme.css @@ -3,18 +3,6 @@ src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf); } -:root { - --link-color: #646cff; - --link-hover-color: #535bf2; - --background-color: #12082b; - --header-background-color: #1f1145; - --content-background-color: #0d0620; - --text-color: white; - --border-color: #8054f0; - --indicator-inactive-color: #4a4a4a; - --indicator-active-color: #8054f0; -} - ::-webkit-scrollbar { width: 0px; background: transparent; diff --git a/theming.ts b/theming.ts index b0856bb..174daa4 100644 --- a/theming.ts +++ b/theming.ts @@ -11,6 +11,7 @@ export const themePlugin = (): Plugin => { name: 'theme-generator', transform(code, id) { if (id.endsWith('app.css')) { + const colorsCode = Deno.readTextFileSync(Deno.cwd() + '/src/themes/colors.css'); // Read the theme file and replace the contents of app.css with it // Needs full path to the file const themeCode = Deno.readTextFileSync(Deno.cwd() + '/src/themes/' + themeFile); @@ -18,7 +19,7 @@ export const themePlugin = (): Plugin => { // and add a comment at the top const themeComment = `/* Generated from ${themeFile} */\n`; - const themeCodeWithComment = themeComment + themeCode; + const themeCodeWithComment = themeComment + colorsCode + themeCode; // Return the theme code as the new contents of app.css return { code: themeCodeWithComment, From fc8d61e1ef551fbd6171b4764f8bc61c9bf647a7 Mon Sep 17 00:00:00 2001 From: Astra Date: Thu, 15 May 2025 16:20:16 +0900 Subject: [PATCH 7/9] Theming 101 --- src/themes/colors.css | 11 -- src/themes/theme.css | 357 ----------------------------------- themes/colors.css | 22 +++ themes/default/theme.css | 0 themes/witchcraft/theme.css | 358 ++++++++++++++++++++++++++++++++++++ theming.ts | 10 +- 6 files changed, 385 insertions(+), 373 deletions(-) delete mode 100644 src/themes/colors.css delete mode 100644 src/themes/theme.css create mode 100644 themes/colors.css create mode 100644 themes/default/theme.css create mode 100644 themes/witchcraft/theme.css diff --git a/src/themes/colors.css b/src/themes/colors.css deleted file mode 100644 index bc036e4..0000000 --- a/src/themes/colors.css +++ /dev/null @@ -1,11 +0,0 @@ -:root { - --link-color: #646cff; - --link-hover-color: #535bf2; - --background-color: #12082b; - --header-background-color: #1f1145; - --content-background-color: #0d0620; - --text-color: white; - --border-color: #8054f0; - --indicator-inactive-color: #4a4a4a; - --indicator-active-color: #8054f0; -} \ No newline at end of file diff --git a/src/themes/theme.css b/src/themes/theme.css deleted file mode 100644 index 4ae67be..0000000 --- a/src/themes/theme.css +++ /dev/null @@ -1,357 +0,0 @@ -@font-face { - font-family: "ProggyClean"; - src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf); -} - -::-webkit-scrollbar { - width: 0px; - background: transparent; - padding: 0; - margin: 0; -} -::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 0; -} -::-webkit-scrollbar-track { - background: transparent; - border-radius: 0; -} -::-webkit-scrollbar-corner { - background: transparent; - border-radius: 0; -} -::-webkit-scrollbar-button { - background: transparent; - border-radius: 0; -} -* { - scrollbar-width: none; - scrollbar-color: transparent transparent; - -ms-overflow-style: none; /* IE and Edge */ - -webkit-overflow-scrolling: touch; - -webkit-scrollbar: none; /* Safari */ -} - -a { - font-weight: 500; - color: var(--link-color); - text-decoration: inherit; -} -a:hover { - color: var(--link-hover-color); - text-decoration: underline; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; - background-color: var(--background-color); - font-family: "ProggyClean", monospace; - font-size: 24px; - color: var(--text-color); - border-color: var(--border-color); - overflow-wrap: break-word; - word-wrap: normal; - word-break: break-word; - hyphens: none; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -#app { - max-width: 1400px; - width: 100%; - margin: 0; - padding: 0; - margin-left: auto; - margin-right: auto; - text-align: center; -} - -/* Post Component */ - a:hover { - text-decoration: underline; - } - #postContainer { - display: flex; - flex-direction: column; - border: 1px solid var(--border-color); - background-color: var(--background-color); - margin-bottom: 15px; - overflow-wrap: break-word; - } - #postHeader { - display: flex; - flex-direction: row; - align-items: center; - justify-content: start; - background-color: var(--header-background-color); - padding: 0px 0px; - height: fit-content; - border-bottom: 1px solid var(--border-color); - font-weight: bold; - overflow-wrap: break-word; - height: 60px; - } - #displayName { - display: block; - color: var(--text-color); - font-size: 1.2em; - padding: 0; - margin: 0; - overflow-wrap:normal; - word-wrap: break-word; - word-break: break-word; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - width: 100%; - } - #handle { - display: block; - color: var(--border-color); - font-size: 0.8em; - padding: 0; - margin: 0; - } - - #postLink { - color: var(--border-color); - font-size: 0.8em; - padding: 0; - margin: 0; - } - #postContent { - display: flex; - text-align: start; - flex-direction: column; - padding: 10px; - background-color: var(--content-background-color); - color: var(--text-color); - overflow-wrap: break-word; - white-space: pre-line; - } - #replyingText { - font-size: 0.7em; - margin: 0; - padding: 0; - padding-bottom: 5px; - } - #quotingText { - font-size: 0.7em; - margin: 0; - padding: 0; - padding-bottom: 5px; - } - #postText { - margin: 0; - padding: 0; - overflow-wrap: break-word; - word-wrap: normal; - word-break: break-word; - hyphens: none; - } - #headerText { - margin-left: 10px; - font-size: 0.9em; - text-align: start; - word-break: break-word; - max-width: 80%; - max-height: 95%; - overflow: hidden; - align-self: flex-start; - margin-top: auto; - margin-bottom: auto; - } - #avatar { - height: 60px; - width: 60px; - margin: 0px; - margin-left: 0px; - overflow: hidden; - object-fit: cover; - border-right: var(--border-color) 1px solid; - } - #carouselContainer { - position: relative; - width: 100%; - margin-top: 10px; - display: flex; - flex-direction: column; - align-items: center; - } - #carouselControls { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - max-width: 500px; - margin-top: 5px; - } - #carouselIndicators { - display: flex; - gap: 5px; - } - .indicator { - width: 8px; - height: 8px; - background-color: var(--indicator-inactive-color); - } - .indicator.active { - background-color: var(--indicator-active-color); - } - #prevBtn, - #nextBtn { - background-color: rgba(31, 17, 69, 0.7); - color: var(--text-color); - border: 1px solid var(--border-color); - width: 30px; - height: 30px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - } - #prevBtn:disabled, - #nextBtn:disabled { - opacity: 0.5; - cursor: not-allowed; - } - #embedVideo { - width: 100%; - max-width: 500px; - margin-top: 10px; - align-self: center; - } - - #embedImages { - min-width: min(100%, 500px); - max-width: min(100%, 500px); - max-height: 500px; - object-fit: contain; - - margin: 0; - } - -/* Account Component */ - #accountContainer { - display: flex; - text-align: start; - align-items: center; - background-color: var(--background-color); - padding: 0px; - margin-bottom: 15px; - border: 1px solid var(--border-color); - } - #accountName { - margin-left: 10px; - font-size: 0.9em; - max-width: 80%; - - /* replace overflow with ellipsis */ - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - #avatar { - width: 50px; - height: 50px; - margin: 0px; - object-fit: cover; - border-right: var(--border-color) 1px solid; - } - -/* App.Svelte */ - /* desktop style */ - - #Content { - display: flex; - /* split the screen in half, left for accounts, right for posts */ - width: 100%; - height: 100%; - flex-direction: row; - justify-content: space-between; - align-items: center; - background-color: var(--background-color); - color: var(--text-color); - } - #Feed { - overflow-y: scroll; - width: 65%; - height: 100vh; - padding: 20px; - padding-bottom: 0; - padding-top: 0; - margin-top: 0; - margin-bottom: 0; - } - #spacer { - padding: 0; - margin: 0; - height: 10vh; - width: 100%; - } - #Account { - width: 35%; - display: flex; - flex-direction: column; - border: 1px solid var(--border-color); - background-color: var(--content-background-color); - height: 80vh; - padding: 20px; - margin-left: 20px; - } - #accountsList { - display: flex; - flex-direction: column; - overflow-y: scroll; - height: 100%; - width: 100%; - padding: 0px; - margin: 0px; - } - - #Header { - text-align: center; - font-size: 2em; - margin-bottom: 20px; - } - - /* mobile style */ - @media screen and (max-width: 600px) { - #Content { - flex-direction: column; - width: auto; - padding-left: 0px; - padding-right: 0px; - margin-top: 5%; - } - #Account { - width: 85%; - padding-left: 5%; - padding-right: 5%; - margin-bottom: 20px; - margin-left: 5%; - margin-right: 5%; - height: auto; - } - #Feed { - width: 95%; - margin: 0px; - margin-left: 10%; - margin-right: 10%; - padding: 0px; - overflow-y: visible; - } - - #spacer { - height: 0; - } - } \ No newline at end of file diff --git a/themes/colors.css b/themes/colors.css new file mode 100644 index 0000000..b522a4f --- /dev/null +++ b/themes/colors.css @@ -0,0 +1,22 @@ +:root { + /* Primary hue of the theme */ + /* You can adjust it, or edit the values below directly */ + --primary-h: 260; + + /* Primary saturation and lightness of the theme, usually you shouldn't want to change those */ + --primary-s: 75%; + --primary-l: 60%; + + /* Derived colors using H, S, L manipulation */ + /* You can set those to be static values if you want, i.e.: */ + /* --link-color: #c579ff; */ + --link-color: hsl(calc(var(--primary-h) - 30), 75%, 60%); + --link-hover-color: hsl(calc(var(--primary-h) - 30), 75%, 50%); + --background-color: hsl(var(--primary-h), 75%, 10%); + --header-background-color: hsl(var(--primary-h), 75%, 18%); + --content-background-color: hsl(var(--primary-h), 75%, 8%); + --text-color: #fff; + --border-color: hsl(var(--primary-h), 75%, calc(var(--primary-l) * 1.05)); + --indicator-inactive-color: #4a4a4a; + --indicator-active-color: var(--border-color); +} diff --git a/themes/default/theme.css b/themes/default/theme.css new file mode 100644 index 0000000..e69de29 diff --git a/themes/witchcraft/theme.css b/themes/witchcraft/theme.css new file mode 100644 index 0000000..eee1f37 --- /dev/null +++ b/themes/witchcraft/theme.css @@ -0,0 +1,358 @@ +@font-face { + font-family: "ProggyClean"; + src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf); +} + +a { + font-weight: 500; + color: var(--link-color); + text-decoration: inherit; +} +a:hover { + color: var(--link-hover-color); + text-decoration: underline; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; + background-color: var(--background-color); + font-family: "ProggyClean", monospace; + font-size: 24px; + color: var(--text-color); + border-color: var(--border-color); + overflow-wrap: break-word; + word-wrap: normal; + word-break: break-word; + hyphens: none; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1400px; + width: 100%; + margin: 0; + padding: 0; + margin-left: auto; + margin-right: auto; + text-align: center; +} + +/* Post Component */ +a:hover { + text-decoration: underline; +} +#postContainer { + display: flex; + flex-direction: column; + border: 1px solid var(--border-color); + background-color: var(--background-color); + margin-bottom: 15px; + overflow-wrap: break-word; +} +#postHeader { + display: flex; + flex-direction: row; + align-items: center; + justify-content: start; + background-color: var(--header-background-color); + padding: 0px 0px; + height: fit-content; + border-bottom: 1px solid var(--border-color); + font-weight: bold; + overflow-wrap: break-word; + height: 60px; +} +#displayName { + display: block; + color: var(--text-color); + font-size: 1.2em; + padding: 0; + margin: 0; + overflow-wrap: normal; + word-wrap: break-word; + word-break: break-word; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + width: 100%; +} +#handle { + display: block; + color: var(--border-color); + font-size: 0.8em; + padding: 0; + margin: 0; +} + +#postLink { + color: var(--border-color); + font-size: 0.8em; + padding: 0; + margin: 0; +} +#postContent { + display: flex; + text-align: start; + flex-direction: column; + padding: 10px; + background-color: var(--content-background-color); + color: var(--text-color); + overflow-wrap: break-word; + white-space: pre-line; +} +#replyingText { + font-size: 0.7em; + margin: 0; + padding: 0; + padding-bottom: 5px; +} +#quotingText { + font-size: 0.7em; + margin: 0; + padding: 0; + padding-bottom: 5px; +} +#postText { + margin: 0; + padding: 0; + overflow-wrap: break-word; + word-wrap: normal; + word-break: break-word; + hyphens: none; +} +#headerText { + margin-left: 10px; + font-size: 0.9em; + text-align: start; + word-break: break-word; + max-width: 80%; + max-height: 95%; + overflow: hidden; + align-self: flex-start; + margin-top: auto; + margin-bottom: auto; +} +#avatar { + height: 60px; + width: 60px; + margin: 0px; + margin-left: 0px; + overflow: hidden; + object-fit: cover; + border-right: var(--border-color) 1px solid; +} +#carouselContainer { + position: relative; + width: 100%; + margin-top: 10px; + display: flex; + flex-direction: column; + align-items: center; +} +#carouselControls { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + max-width: 500px; + margin-top: 5px; +} +#carouselIndicators { + display: flex; + gap: 5px; +} +.indicator { + width: 8px; + height: 8px; + background-color: var(--indicator-inactive-color); +} +.indicator.active { + background-color: var(--indicator-active-color); +} +#prevBtn, +#nextBtn { + background-color: rgba(31, 17, 69, 0.7); + color: var(--text-color); + border: 1px solid var(--border-color); + width: 30px; + height: 30px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} +#prevBtn:disabled, +#nextBtn:disabled { + opacity: 0.5; + cursor: not-allowed; +} +#embedVideo { + width: 100%; + max-width: 500px; + margin-top: 10px; + align-self: center; +} + +#embedImages { + min-width: min(100%, 500px); + max-width: min(100%, 500px); + max-height: 500px; + object-fit: contain; + + margin: 0; +} + +/* Account Component */ +#accountContainer { + display: flex; + text-align: start; + align-items: center; + background-color: var(--background-color); + padding: 0px; + margin-bottom: 15px; + border: 1px solid var(--border-color); +} +#accountName { + margin-left: 10px; + font-size: 0.9em; + max-width: 80%; + + /* replace overflow with ellipsis */ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +#avatar { + width: 50px; + height: 50px; + margin: 0px; + object-fit: cover; + border-right: var(--border-color) 1px solid; +} + +/* App.Svelte */ +/* desktop style */ + +#Content { + display: flex; + /* split the screen in half, left for accounts, right for posts */ + width: 100%; + height: 100%; + flex-direction: row; + justify-content: space-between; + align-items: center; + background-color: var(--background-color); + color: var(--text-color); +} +#Feed { + overflow-y: scroll; + width: 65%; + height: 100vh; + padding: 20px; + padding-bottom: 0; + padding-top: 0; + margin-top: 0; + margin-bottom: 0; +} +#spacer { + padding: 0; + margin: 0; + height: 10vh; + width: 100%; +} +#Account { + width: 35%; + display: flex; + flex-direction: column; + border: 1px solid var(--border-color); + background-color: var(--content-background-color); + height: 80vh; + padding: 20px; + margin-left: 20px; +} +#accountsList { + display: flex; + flex-direction: column; + overflow-y: scroll; + height: 100%; + width: 100%; + padding: 0px; + margin: 0px; +} + +#Header { + text-align: center; + font-size: 2em; + margin-bottom: 20px; +} + +/* mobile style */ +@media screen and (max-width: 600px) { + #Content { + flex-direction: column; + width: auto; + padding-left: 0px; + padding-right: 0px; + margin-top: 5%; + } + #Account { + width: 85%; + padding-left: 5%; + padding-right: 5%; + margin-bottom: 20px; + margin-left: 5%; + margin-right: 5%; + height: auto; + } + #Feed { + width: 95%; + margin: 0px; + margin-left: 10%; + margin-right: 10%; + padding: 0px; + overflow-y: visible; + } + + #spacer { + height: 0; + } +} + +::-webkit-scrollbar { + width: 0px; + background: transparent; + padding: 0; + margin: 0; +} +::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 0; +} +::-webkit-scrollbar-track { + background: transparent; + border-radius: 0; +} +::-webkit-scrollbar-corner { + background: transparent; + border-radius: 0; +} +::-webkit-scrollbar-button { + background: transparent; + border-radius: 0; +} + +* { + scrollbar-width: none; + scrollbar-color: transparent transparent; + -ms-overflow-style: none; /* IE and Edge */ + -webkit-overflow-scrolling: touch; + -webkit-scrollbar: none; /* Safari */ +} \ No newline at end of file diff --git a/theming.ts b/theming.ts index 174daa4..9dd2e14 100644 --- a/theming.ts +++ b/theming.ts @@ -5,20 +5,20 @@ import { Config } from './config'; // Replaces app.css with the contents of the file specified in the // config file. export const themePlugin = (): Plugin => { - const themeFile = Config.THEME; - console.log(`Using theme file: ${themeFile}`); + const themeFolder = Config.THEME; + console.log(`Using theme folder: ${themeFolder}`); return { name: 'theme-generator', transform(code, id) { if (id.endsWith('app.css')) { - const colorsCode = Deno.readTextFileSync(Deno.cwd() + '/src/themes/colors.css'); + const colorsCode = Deno.readTextFileSync(Deno.cwd() + '/themes/colors.css'); // Read the theme file and replace the contents of app.css with it // Needs full path to the file - const themeCode = Deno.readTextFileSync(Deno.cwd() + '/src/themes/' + themeFile); + const themeCode = Deno.readTextFileSync(Deno.cwd() + '/themes/' + themeFolder + '/theme.css'); // Replace the contents of app.css with the theme code // and add a comment at the top - const themeComment = `/* Generated from ${themeFile} */\n`; + const themeComment = `/* Generated from ${themeFolder} */\n`; const themeCodeWithComment = themeComment + colorsCode + themeCode; // Return the theme code as the new contents of app.css return { From e75f41f7f10639e1a082809b019044c1321dc94d Mon Sep 17 00:00:00 2001 From: Ari Date: Thu, 15 May 2025 03:30:53 -0400 Subject: [PATCH 8/9] Run the plugin before svelte --- theming.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/theming.ts b/theming.ts index 174daa4..9cee430 100644 --- a/theming.ts +++ b/theming.ts @@ -9,6 +9,7 @@ export const themePlugin = (): Plugin => { console.log(`Using theme file: ${themeFile}`); return { name: 'theme-generator', + enforce: 'pre', // Ensure this plugin runs first transform(code, id) { if (id.endsWith('app.css')) { const colorsCode = Deno.readTextFileSync(Deno.cwd() + '/src/themes/colors.css'); From 04735a538deb098931a425d8d3a2c31dda05bc82 Mon Sep 17 00:00:00 2001 From: Astra Date: Thu, 15 May 2025 18:13:36 +0900 Subject: [PATCH 9/9] Remove colors.css and new default theme --- src/lib/PostComponent.svelte | 2 +- themes/colors.css | 22 -- themes/default/theme.css | 422 +++++++++++++++++++++++++++++++++++ themes/witchcraft/theme.css | 16 ++ theming.ts | 3 +- 5 files changed, 440 insertions(+), 25 deletions(-) delete mode 100644 themes/colors.css diff --git a/src/lib/PostComponent.svelte b/src/lib/PostComponent.svelte index 6cb6bcd..1cacc28 100644 --- a/src/lib/PostComponent.svelte +++ b/src/lib/PostComponent.svelte @@ -71,7 +71,7 @@ >

{post.authorHandle}@{post.authorHandle} { enforce: 'pre', // Ensure this plugin runs first transform(code, id) { if (id.endsWith('app.css')) { - const colorsCode = Deno.readTextFileSync(Deno.cwd() + '/themes/colors.css'); // Read the theme file and replace the contents of app.css with it // Needs full path to the file const themeCode = Deno.readTextFileSync(Deno.cwd() + '/themes/' + themeFolder + '/theme.css'); @@ -20,7 +19,7 @@ export const themePlugin = (): Plugin => { // and add a comment at the top const themeComment = `/* Generated from ${themeFolder} */\n`; - const themeCodeWithComment = themeComment + colorsCode + themeCode; + const themeCodeWithComment = themeComment + themeCode; // Return the theme code as the new contents of app.css return { code: themeCodeWithComment,