diff --git a/.config/devenv.yml b/.config/devenv.yml new file mode 100644 index 0000000000..6c60f338ae --- /dev/null +++ b/.config/devenv.yml @@ -0,0 +1,38 @@ +url: http://localhost:3000 +port: 3000 + +db: + host: 127.0.0.1 + port: 5432 + + db: calckey + + user: calckey + pass: calckey + +redis: + host: localhost + port: 6379 + family: 4 +#sonic: +# host: localhost +# port: 1491 +# auth: SecretPassword +# collection: notes +# bucket: default + +#elasticsearch: +# host: localhost +# port: 9200 +# ssl: false +# user: +# pass: + +id: 'aid' + +reservedUsernames: + - root + - admin + - administrator + - me + - system diff --git a/.gitignore b/.gitignore index 1fadce4317..63ee4f35fc 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ coverage # config /.config/* !/.config/example.yml +!/.config/devenv.yml !/.config/docker_example.env !/.config/helm_values_example.yml diff --git a/CALCKEY.md b/CALCKEY.md index 923cbe6805..55d37a56e5 100644 --- a/CALCKEY.md +++ b/CALCKEY.md @@ -19,7 +19,6 @@ - MFM button - Personal notes for all accounts - Fully revamp non-logged-in screen - - Classic mode make instance icon bring up new context menu - Lookup/details for post/file/instance - [Rat mode?](https://stop.voring.me/notes/933fx97bmd) @@ -118,6 +117,13 @@ - Sonic search - Popular color schemes, including Nord, Gruvbox, and Catppuccin - Non-nyaify cat mode +- Post imports from other Calckey/Misskey/Mastodon/Pleroma/Akkoma instances +- Improve Classic mode +- Proper Helm/Kubernetes config +- Multiple boost visibilities +- Improve system emails +- Mod mail +- Focus trapping and button labels ## Implemented (remote) diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000000..41d1b34699 --- /dev/null +++ b/docs/development.md @@ -0,0 +1,22 @@ +# 🌎 Calckey Developer Docs + +## Nix Dev Environment +The Calckey repo comes with a Nix-based shell environment to help make development as easy as possible! + +Please note, however, that this environment will not work on Windows outside of a WSL2 environment. + +### Prerequisites + +- Installed the [Nix Package Manager](https://nixos.org/download.html) +- Installed [direnv](https://direnv.net/docs/installation.html) and added its hook to your shell. + +Once the repo is cloned to your computer, follow these next few steps inside the Calckey folder: + +- Run `direnv allow`. This will build the environment and install all needed tools. +- Run `install-deps`, then `prepare-config`, to install the node dependencies and prepare the needed config files. +- In a second terminal, run `devenv up`. This will spawn a **Redis** server, a **Postgres** server, and the **Calckey** server in dev mode. +- Once you see the Calckey banner printed in your second terminal, run `migrate` in the first. +- Once migrations finish, open http://localhost:3000 in your web browser. +- You should now see the admin user creation screen! + +Note: When you want to restart a dev server, all you need to do is run `devenv up`, no other steps are necessary. diff --git a/flake.nix b/flake.nix index fd9098f0dd..73d8fe02f1 100644 --- a/flake.nix +++ b/flake.nix @@ -32,6 +32,8 @@ # Add additional packages to our environment packages = [ pkgs.nodePackages.pnpm + + pkgs.python3 ]; # No need to warn on a new version, we'll update as needed. devenv.warnOnNewVersion = false; @@ -43,6 +45,18 @@ # Enable stable Rust for the backend languages.rust.enable = true; languages.rust.version = "stable"; + processes = { + dev-server.exec = "pnpm run dev"; + }; + scripts = { + build.exec = "pnpm run build"; + clean.exec = "pnpm run clean"; + clear-state.exec = "rm -rf .devenv/state/redis .devenv/state/postgres"; + format.exec = "pnpm run format"; + install-deps.exec = "pnpm install"; + migrate.exec = "pnpm run migrate"; + prepare-config.exec = "cp .config/devenv.yml .config/default.yml"; + }; services = { postgres = { enable = true; diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 800d2677b1..129cf89bd8 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -517,8 +517,8 @@ dayOverDayChanges: "VerĂ€nderung zu Gestern" appearance: "Aussehen" clientSettings: "Client-Einstellungen" accountSettings: "Nutzerkonto-Einstellungen" -promotion: "Werbung" -promote: "Werbung schalten" +promotion: "geworben" +promote: "Werben" numberOfDays: "Anzahl der Tage" hideThisNote: "Diesen Beitrag verstecken" showFeaturedNotesInTimeline: "Beliebte BeitrĂ€ge in der Timeline anzeigen" @@ -852,7 +852,7 @@ gallery: "Bilder-Galerie" recentPosts: "Neue BeitrĂ€ge" popularPosts: "Beliebte BeitrĂ€ge" shareWithNote: "Mit Beitrag teilen" -ads: "Werbung" +ads: "Werbeanzeigen" expiration: "Frist" memo: "Merkzettel" priority: "PrioritĂ€t" @@ -1034,7 +1034,7 @@ _accountDelete: inProgress: "Löschung in Bearbeitung" _ad: back: "ZurĂŒck" - reduceFrequencyOfThisAd: "Diese Werbung weniger anzeigen" + reduceFrequencyOfThisAd: "Diese Werbeanzeige weniger anzeigen" _forgotPassword: enterEmail: "Gib die Email-Adresse ein, mit der du dich registriert hast. An diese\ \ wird ein Link gesendet, mit dem du dein Passwort zurĂŒcksetzen kannst." @@ -1174,6 +1174,10 @@ _mfm: \ befindet." foreground: Vordergrundfarbe background: Hintergrundfarbe + positionDescription: Verschieben Sie Inhalte um einen bestimmten Betrag + position: Position + scale: Maßstab + scaleDescription: Skaliere den Inhalt um einen bestimmten Betrag. _instanceTicker: none: "Nie anzeigen" remote: "FĂŒr Nutzer eines anderen Servers anzeigen" @@ -1989,3 +1993,51 @@ userSaysSomethingReasonReply: '{name} hat auf einen Beitrag geantwortet der {rea beinhaltet' userSaysSomethingReasonRenote: '{name} hat einen Beitrag geteilt der {reason} beinhaltet' userSaysSomethingReasonQuote: '{name} hat einen Beitrag zitiert der {reason} beinhaltet' +seperateRenoteQuote: Getrennte Boost- und Zitat-SchaltflĂ€chen +showAds: Anzeigen anzeigen +splash: BegrĂŒĂŸungsbildschirm +customSplashIconsDescription: URLs fĂŒr benutzerdefinierte Splash-Screen-Symbole, die + durch ZeilenumbrĂŒche getrennt sind und nach dem Zufallsprinzip jedes Mal angezeigt + werden, wenn ein Benutzer die Seite lĂ€dt/neu lĂ€dt. Bitte stelle sicher, dass die + Bilder unter einer statischen URL stehen, vorzugsweise alle in der GrĂ¶ĂŸe 192x192. +sendPushNotificationReadMessageCaption: Eine Benachrichtigung mit dem Text "{emptyPushNotificationMessage}" + wird fĂŒr kurze Zeit angezeigt. Dies kann ggf. den Akkuverbrauch Ihres GerĂ€ts erhöhen. +customSplashIcons: Benutzerdefinierte BegrĂŒĂŸungsbildschirmsymbole (URLs) +adminCustomCssWarn: Diese Einstellung sollte nur verwendet werden, wenn Sie wissen, + was sie tut. Die Eingabe falscher Werte kann dazu fĂŒhren, dass ALLE Clients nicht + mehr normal funktionieren. Bitte stellen Sie sicher, dass Ihr CSS ordnungsgemĂ€ĂŸ + funktioniert, indem Sie es in Ihren Benutzereinstellungen testen. +customMOTD: Benutzerdefinierte Meldung des Tages (BegrĂŒĂŸungsbildschirmmeldungen) +allowedInstancesDescription: Hosts von Instanzen, die fĂŒr den Verbund auf die Whitelist + gesetzt werden sollen, jeweils durch eine neue Zeile getrennt (gilt nur im privaten + Modus). +migration: Migration +updateAvailable: Es könnte eine Aktualisierung verfĂŒgbar sein! +showAdminUpdates: Anzeigen, dass eine neue Calckey-Version verfĂŒgbar ist (nur Administrator) +customMOTDDescription: Benutzerdefinierte Meldungen fĂŒr die Meldung des Tages (BegrĂŒĂŸungsbildschirm), + die durch ZeilenumbrĂŒche getrennt sind und nach dem Zufallsprinzip jedes Mal angezeigt + werden, wenn ein Benutzer die Seite (neu) lĂ€dt. +recommendedInstancesDescription: Empfohlene Instanzen, die durch ZeilenumbrĂŒche getrennt + sind, werden in der empfohlenen Zeitachse angezeigt. FĂŒgen Sie NICHT "https://" + hinzu, sondern NUR die Domain. +sendModMail: Moderationshinweis senden +moveFromDescription: 'Dadurch wird ein Alias Ihres alten Nutzerkontos festgelegt, + sodass Sie von ihrem bisherigen Konto zu diesem Nutzerkonto wechseln können. Tun + Sie dies, BEVOR Sie von Ihrem bisherigen Nutzerkonto hierhin wechseln. Bitte geben + Sie den Namen des Nutzerkontos wie folgt ein: person@server.xyz' +preventAiLearning: KI gestĂŒtztes bot-scraping unterdrĂŒcken +preventAiLearningDescription: Fordern Sie KI-Sprachmodelle von Drittanbietern auf, + die von Ihnen hochgeladenen Inhalte, wie z. B. BeitrĂ€ge und Bilder, nicht zu untersuchen. +license: Genehmigung +indexPosts: Gelistete BeitrĂ€ge +migrationConfirm: "Sind Sie absolut sicher, dass Sie Ihr Nutzerkonto zu diesem {account}\ + \ umziehen möchten? Sobald Sie dies bestĂ€tigt haben, kann dies nicht mehr rĂŒckgĂ€ngig\ + \ gemacht werden und Ihr Nutzerkonto kann nicht mehr von ihnen genutzt werden.\n\ + Stellen Sie außerdem sicher, dass Sie dieses Nutzerkonto als das Konto festgelegt\ + \ haben, von dem Sie umziehen." +noteId: Beitrags-ID +customKaTeXMacro: Individuelle KaTeX Makros +enableCustomKaTeXMacro: Individuelle KaTeX-Makros aktivieren +replayTutorial: Wiederhole die Benutzeranleitung +apps: Apps +caption: Automatische Untertitelung diff --git a/locales/en-US.yml b/locales/en-US.yml index 4c73c5b8f1..5558e538de 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1085,7 +1085,7 @@ apps: "Apps" sendModMail: "Send Moderation Notice" preventAiLearning: "Prevent AI bot scraping" preventAiLearningDescription: "Request third-party AI language models not to study content you upload, such as posts and images." - +pwa: "Install PWA" _sensitiveMediaDetection: description: "Reduces the effort of server moderation through automatically recognizing\ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 4fc2f42d79..445d839b3e 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -975,6 +975,7 @@ customKaTeXMacroDescription: "æ•°ćŒć…„ćŠ›ă‚’æ„œă«ă™ă‚‹ăŸă‚ăźăƒžă‚Żăƒ­ă‚’ enableCustomKaTeXMacro: "ă‚«ă‚čタムKaTeXăƒžă‚Żăƒ­ă‚’æœ‰ćŠčにする" preventAiLearning: "AIă«ă‚ˆă‚‹ć­Šçż’ă‚’é˜Čæ­ą" preventAiLearningDescription: "æŠ•çšżă—ăŸăƒŽăƒŒăƒˆă€æ·»ä»˜ă—ăŸç”»ćƒăȘă©ăźă‚łăƒłăƒ†ăƒłăƒ„ă‚’ć­Šçż’ăźćŻŸè±Ąă«ă—ăȘいようAIă«èŠæ±‚ă—ăŸă™ă€‚ă“ă‚ŒăŻnoaiăƒ•ăƒ©ă‚°ă‚’HTMLハă‚čポンă‚čă«ć«ă‚ă‚‹ă“ăšă«ă‚ˆăŁăŠćźŸçŸă•ă‚ŒăŸă™ă€‚" +pwa: "PWAă‚’ă‚€ăƒłă‚čăƒˆăƒŒăƒ«" _sensitiveMediaDetection: description: "æ©Ÿæą°ć­Šçż’ă‚’äœżăŁăŠè‡Șć‹•ă§ă‚»ăƒłă‚·ăƒ†ă‚Łăƒ–ăȘăƒĄăƒ‡ă‚Łă‚ąă‚’æ€œć‡șă—ă€ăƒąăƒ‡ăƒŹăƒŒă‚·ăƒ§ăƒłă«ćœčç«‹ăŠă‚‰ă‚ŒăŸă™ă€‚ă‚”ăƒŒăƒăƒŒăźèČ è·ăŒć°‘ă—ćą—ăˆăŸă™ă€‚" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 492f6af0ce..5c7f9fbbb1 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -1921,7 +1921,7 @@ sendErrorReportsDescription: "Gdy ta opcja jest wƂączona, szczegóƂowe inform \ Calckey.\nZawrze to informacje takie jak wersja twojego systemu operacyjnego,\ \ przeglądarki, Twoja aktywnoƛć na Calckey itd." privateModeInfo: Jeƛli wƂączone, tylko dopuszczone instancje będą mogƂy federować - z Twoją instancją. Wszystkie posty będą ukryte przed publiką. + z Twoją instancją. Wszystkie posty będą jedynie widoczne na Twojej instancji. oneHour: Godzina oneDay: DzieƄ oneWeek: TydzieƄ @@ -2012,3 +2012,4 @@ silencedInstancesDescription: WymieƄ nazwy domenowe instancji, ktĂłre chcesz wy są obserwowane. To nie będzie miaƂo wpƂywu na zablokowane instancje. cannotUploadBecauseExceedsFileSizeLimit: Ten plik nie mĂłgƂ być przesƂany, poniewaĆŒ jego wielkoƛć przekracza dozwolony limit. +sendModMail: Wyƛlij Powiadomienie Moderacyjne diff --git a/package.json b/package.json index 8aaa427a13..686b9ea932 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "calckey", - "version": "14.0.0-dev8", + "version": "14.0.0-dev9", "codename": "aqua", "repository": { "type": "git", "url": "https://codeberg.org/calckey/calckey.git" }, - "packageManager": "pnpm@8.4.0", + "packageManager": "pnpm@8.5.0", "private": true, "scripts": { "rebuild": "pnpm run clean && pnpm -r run build && pnpm run gulp", diff --git a/packages/backend/migration/1683682889948-prevent-ai-larning.js b/packages/backend/migration/1683682889948-PreventAiLearning.js similarity index 76% rename from packages/backend/migration/1683682889948-prevent-ai-larning.js rename to packages/backend/migration/1683682889948-PreventAiLearning.js index 8a88fb3bcc..809ce4213a 100644 --- a/packages/backend/migration/1683682889948-prevent-ai-larning.js +++ b/packages/backend/migration/1683682889948-PreventAiLearning.js @@ -1,5 +1,5 @@ -export class PreventAiLarning1683682889948 { - name = 'PreventAiLarning1683682889948' +export class PreventAiLearning1683682889948 { + name = 'PreventAiLearning1683682889948' async up(queryRunner) { await queryRunner.query(`ALTER TABLE "user_profile" ADD "preventAiLearning" boolean NOT NULL DEFAULT true`); diff --git a/packages/backend/src/server/web/style.css b/packages/backend/src/server/web/style.css index ee42b9deba..5072e0ad4e 100644 --- a/packages/backend/src/server/web/style.css +++ b/packages/backend/src/server/web/style.css @@ -1,4 +1,4 @@ -html, body { +html { background-color: var(--bg); color: var(--fg); } diff --git a/packages/client/package.json b/packages/client/package.json index 69346651d8..1735855037 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -9,6 +9,7 @@ }, "devDependencies": { "@discordapp/twemoji": "14.0.2", + "@khmyznikov/pwa-install": "^0.2.0", "@phosphor-icons/web": "^2.0.3", "@rollup/plugin-alias": "3.1.9", "@rollup/plugin-json": "4.1.0", diff --git a/packages/client/src/components/MkFolder.vue b/packages/client/src/components/MkFolder.vue index 337873fc1c..63d47f2bf4 100644 --- a/packages/client/src/components/MkFolder.vue +++ b/packages/client/src/components/MkFolder.vue @@ -144,6 +144,10 @@ export default defineComponent({ padding: var(--x-padding); -webkit-backdrop-filter: var(--blur, blur(8px)); backdrop-filter: var(--blur, blur(20px)); + margin-inline: -12px; + padding-inline: 12px; + mask: linear-gradient(to right, transparent, black 12px calc(100% - 12px), transparent); + -webkit-mask: linear-gradient(to right, transparent, black 12px calc(100% - 12px), transparent); > .title { margin: 0; diff --git a/packages/client/src/components/MkNotes.vue b/packages/client/src/components/MkNotes.vue index 124ffea6a1..bf3631c182 100644 --- a/packages/client/src/components/MkNotes.vue +++ b/packages/client/src/components/MkNotes.vue @@ -58,13 +58,12 @@ defineExpose({ .giivymft { &.noGap { > .notes { - background: var(--panel); + background: var(--panel) !important; border-radius: var(--radius); } } &:not(.noGap) { > .notes { - background: var(--bg); .qtqtichx { background: var(--panel); border-radius: var(--radius); diff --git a/packages/client/src/components/MkTutorialDialog.vue b/packages/client/src/components/MkTutorialDialog.vue index eafc882950..8fecc44294 100644 --- a/packages/client/src/components/MkTutorialDialog.vue +++ b/packages/client/src/components/MkTutorialDialog.vue @@ -180,6 +180,13 @@ primary show-only-to-register /> + + {{ i18n.ts.pwa }} @@ -201,6 +208,7 @@ import { defaultStore } from "@/store"; import { i18n } from "@/i18n"; import { $i } from "@/account"; import { instance } from "@/instance"; +import "@khmyznikov/pwa-install"; const isLocalTimelineAvailable = !instance.disableLocalTimeline || @@ -243,6 +251,11 @@ const tutorial = computed({ }, }); +function installPwa(ev: MouseEvent) { + const pwaInstall = document.getElementsByTagName("pwa-install")[0]; + pwaInstall.showDialog(); +} + function close(res) { tutorial.value = -1; dialog.close(); diff --git a/packages/client/src/pages/antenna-timeline.vue b/packages/client/src/pages/antenna-timeline.vue index c33eed75f2..442d6882a8 100644 --- a/packages/client/src/pages/antenna-timeline.vue +++ b/packages/client/src/pages/antenna-timeline.vue @@ -158,7 +158,7 @@ definePageMetadata( } > .tl { - background: var(--bg); + background: none; border-radius: var(--radius); overflow: clip; } diff --git a/packages/client/src/pages/note.vue b/packages/client/src/pages/note.vue index 29c18c12ea..dbc2f2aa92 100644 --- a/packages/client/src/pages/note.vue +++ b/packages/client/src/pages/note.vue @@ -218,7 +218,9 @@ definePageMetadata( } .fcuexfpr { - background: var(--bg); + #calckey_app > :not(.wallpaper) & { + background: var(--bg); + } > .note { > .main { diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue index e3f8a0083a..6ab0fdda46 100644 --- a/packages/client/src/pages/timeline.vue +++ b/packages/client/src/pages/timeline.vue @@ -391,7 +391,7 @@ onMounted(() => { } > .tl { - background: var(--bg); + background: none; border-radius: var(--radius); overflow: clip; } diff --git a/packages/client/src/pages/user-list-timeline.vue b/packages/client/src/pages/user-list-timeline.vue index 2fd82500e4..352e5d6838 100644 --- a/packages/client/src/pages/user-list-timeline.vue +++ b/packages/client/src/pages/user-list-timeline.vue @@ -125,7 +125,7 @@ definePageMetadata( } > .tl { - background: var(--bg); + background: none; border-radius: var(--radius); overflow: clip; } diff --git a/packages/client/src/scripts/helpMenu.ts b/packages/client/src/scripts/helpMenu.ts index 81e0a08ec6..58730c61ee 100644 --- a/packages/client/src/scripts/helpMenu.ts +++ b/packages/client/src/scripts/helpMenu.ts @@ -4,6 +4,7 @@ import { host } from "@/config"; import * as os from "@/os"; import XTutorial from "../components/MkTutorialDialog.vue"; import { i18n } from "@/i18n"; +import "@khmyznikov/pwa-install"; export function openHelpMenu_(ev: MouseEvent) { os.popupMenu( @@ -24,6 +25,14 @@ export function openHelpMenu_(ev: MouseEvent) { icon: "ph-lightbulb ph-bold ph-lg", to: "/about-calckey", }, + { + type: "button", + text: i18n.ts.pwa, + icon: "ph-plus-square ph-bold ph-lg", + action: () => { + document.getElementsByTagName("pwa-install")[0].showDialog(); + } + }, { type: "button", text: i18n.ts.apps, diff --git a/packages/client/src/style.scss b/packages/client/src/style.scss index 52c7b62f4a..37cb76f020 100644 --- a/packages/client/src/style.scss +++ b/packages/client/src/style.scss @@ -40,7 +40,6 @@ html { touch-action: manipulation; - background-color: var(--bg); background-attachment: fixed; background-size: cover; background-position: center; diff --git a/packages/client/src/ui/_common_/navbar-for-mobile.vue b/packages/client/src/ui/_common_/navbar-for-mobile.vue index 39abb7c261..9ea373025b 100644 --- a/packages/client/src/ui/_common_/navbar-for-mobile.vue +++ b/packages/client/src/ui/_common_/navbar-for-mobile.vue @@ -105,6 +105,7 @@ {{ i18n.ts.note }} +