diff --git a/app.vue b/app.vue index 70a8e63..13f24c7 100644 --- a/app.vue +++ b/app.vue @@ -1,7 +1,7 @@ - {{ customCss.value }} + {{ preferences.custom_css }} @@ -19,7 +19,6 @@ import ConfirmationModal from "./components/modals/confirm.vue"; import { Toaster } from "./components/ui/sonner"; import { TooltipProvider } from "./components/ui/tooltip"; import { overwriteGetLocale } from "./paraglide/runtime"; -import { type EnumSetting, SettingIds } from "./settings"; // Sin //import "~/styles/mcdonalds.css"; @@ -31,17 +30,16 @@ const origin = useRequestURL().searchParams.get("origin"); const appData = useAppData(); const instance = useInstance(); const description = useExtendedDescription(client); -const customCss = useSetting(SettingIds.CustomCSS); const route = useRoute(); // Theme switcher -const theme = useSetting(SettingIds.Theme) as Ref; const colorMode = useColorMode(); +const radius = useCssVar("--radius"); -watch(theme.value, () => { +watch(preferences.color_theme, (newVal) => { // Add theme-changing class to html to trigger transition document.documentElement.classList.add("theme-changing"); - colorMode.preference = theme.value.value; + colorMode.preference = newVal; setTimeout(() => { // Remove theme-changing class after transition @@ -49,6 +47,16 @@ watch(theme.value, () => { }, 1000); }); +watch( + preferences.border_radius, + (newVal) => { + radius.value = `${newVal}rem`; + }, + { + immediate: true, + }, +); + useSeoMeta({ titleTemplate: (titleChunk) => { return titleChunk ? `${titleChunk} · Versia` : "Versia"; diff --git a/biome.json b/biome.json index bce0c15..2ba3836 100644 --- a/biome.json +++ b/biome.json @@ -21,7 +21,8 @@ "noUnusedVariables": "off", "noUnusedImports": "off", "noUndeclaredDependencies": "off", - "useImportExtensions": "off" + "useImportExtensions": "off", + "useJsxKeyInIterable": "off" }, "complexity": { "noExcessiveCognitiveComplexity": "off" diff --git a/components/composer/composer.vue b/components/composer/composer.vue index 65bab80..c38cfe4 100644 --- a/components/composer/composer.vue +++ b/components/composer/composer.vue @@ -159,7 +159,6 @@ import { SelectTrigger, } from "~/components/ui/select"; import * as m from "~/paraglide/messages.js"; -import { SettingIds } from "~/settings"; import EditorContent from "../editor/content.vue"; import { Button } from "../ui/button"; import { DialogFooter } from "../ui/dialog"; @@ -169,13 +168,11 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; import Files from "./files.vue"; const { Control_Enter, Command_Enter } = useMagicKeys(); -const ctrlEnterSend = useSetting(SettingIds.CtrlEnterToSend); -const defaultVisibility = useSetting(SettingIds.DefaultVisibility); const { play } = useAudio(); const fileInput = ref(null); watch([Control_Enter, Command_Enter], () => { - if (sending.value || !ctrlEnterSend.value.value) { + if (sending.value || !preferences.ctrl_enter_send.value) { return; } @@ -220,9 +217,10 @@ const state = reactive({ sensitive: relation?.type === "edit" ? relation.note.sensitive : false, contentWarning: relation?.type === "edit" ? relation.note.spoiler_text : "", contentType: "text/html" as "text/html" | "text/plain", - visibility: (relation?.type === "edit" - ? relation.note.visibility - : (defaultVisibility.value.value ?? "public")) as Status["visibility"], + visibility: + relation?.type === "edit" + ? relation.note.visibility + : preferences.default_visibility.value, files: (relation?.type === "edit" ? relation.note.media_attachments.map((a) => ({ apiId: a.id, diff --git a/components/modals/confirm-inline.vue b/components/modals/confirm-inline.vue index cab014a..e168c94 100644 --- a/components/modals/confirm-inline.vue +++ b/components/modals/confirm-inline.vue @@ -19,9 +19,9 @@ defineProps<{ modalOptions: ConfirmModalOptions; }>(); -defineEmits<{ - confirm: (result: ConfirmModalResult) => void; - cancel: () => void; +const emit = defineEmits<{ + confirm: [result: ConfirmModalResult]; + cancel: []; }>(); const inputValue = ref(""); @@ -55,10 +55,10 @@ const inputValue = ref(""); - $emit('cancel')"> + emit('cancel')"> {{ modalOptions.cancelText }} - $emit('confirm', { + emit('confirm', { confirmed: true, value: inputValue, })"> @@ -67,4 +67,4 @@ const inputValue = ref(""); - \ No newline at end of file + diff --git a/components/notes/actions.vue b/components/notes/actions.vue index f047677..9cae48b 100644 --- a/components/notes/actions.vue +++ b/components/notes/actions.vue @@ -21,7 +21,6 @@ import { Ellipsis, Heart, Quote, Repeat, Reply } from "lucide-vue-next"; import { toast } from "vue-sonner"; import * as m from "~/paraglide/messages.js"; import { getLocale } from "~/paraglide/runtime"; -import { SettingIds } from "~/settings"; import { confirmModalService } from "../modals/composable"; import ActionButton from "./action-button.vue"; import Menu from "./menu.vue"; @@ -48,11 +47,8 @@ const emit = defineEmits<{ }>(); const { play } = useAudio(); -const confirmLikes = useSetting(SettingIds.ConfirmLike); -const confirmReblogs = useSetting(SettingIds.ConfirmReblog); - const like = async () => { - if (confirmLikes.value.value) { + if (preferences.confirm_actions.value.includes("like")) { const confirmation = await confirmModalService.confirm({ title: m.slimy_least_ray_aid(), message: m.stale_new_ray_jolt(), @@ -74,7 +70,7 @@ const like = async () => { }; const unlike = async () => { - if (confirmLikes.value.value) { + if (preferences.confirm_actions.value.includes("like")) { const confirmation = await confirmModalService.confirm({ title: m.odd_strong_halibut_prosper(), message: m.slow_blue_parrot_savor(), @@ -95,7 +91,7 @@ const unlike = async () => { }; const reblog = async () => { - if (confirmReblogs.value.value) { + if (preferences.confirm_actions.value.includes("reblog")) { const confirmation = await confirmModalService.confirm({ title: m.best_mellow_llama_surge(), message: m.salty_plain_mallard_gaze(), @@ -116,7 +112,7 @@ const reblog = async () => { }; const unreblog = async () => { - if (confirmReblogs.value.value) { + if (preferences.confirm_actions.value.includes("reblog")) { const confirmation = await confirmModalService.confirm({ title: m.main_fancy_octopus_loop(), message: m.odd_alive_swan_express(), diff --git a/components/notes/content.vue b/components/notes/content.vue index 5ddb12a..503d9b9 100644 --- a/components/notes/content.vue +++ b/components/notes/content.vue @@ -1,11 +1,11 @@ - + - + - + @@ -14,7 +14,6 @@ diff --git a/components/notes/header.vue b/components/notes/header.vue index a248d6a..b4e6bfb 100644 --- a/components/notes/header.vue +++ b/components/notes/header.vue @@ -1,7 +1,7 @@ { - if (!enableHoverCard.value) { + if (!preferences.popup_avatar_hover) { popupOpen = false; } }" :open-delay="2000"> @@ -51,7 +51,6 @@ import type { } from "@vueuse/core"; import { AtSign, Globe, Lock, LockOpen } from "lucide-vue-next"; import { getLocale } from "~/paraglide/runtime"; -import { SettingIds } from "~/settings"; import Avatar from "../profiles/avatar.vue"; import SmallCard from "../profiles/small-card.vue"; import { @@ -59,7 +58,6 @@ import { HoverCardContent, HoverCardTrigger, } from "../ui/hover-card"; -import CopyableText from "./copyable-text.vue"; const { createdAt, noteUrl, author, authorUrl } = defineProps<{ cornerAvatar?: string; @@ -94,7 +92,6 @@ const fullTime = new Intl.DateTimeFormat(getLocale(), { dateStyle: "medium", timeStyle: "short", }).format(createdAt); -const enableHoverCard = useSetting(SettingIds.PopupAvatarHover); const popupOpen = ref(false); const visibilities = { diff --git a/components/notes/menu.vue b/components/notes/menu.vue index 306ec95..8be2eee 100644 --- a/components/notes/menu.vue +++ b/components/notes/menu.vue @@ -21,7 +21,6 @@ import { import { toast } from "vue-sonner"; import { confirmModalService } from "~/components/modals/composable.ts"; import * as m from "~/paraglide/messages.js"; -import { SettingIds } from "~/settings"; const { authorId, noteId } = defineProps<{ apiNoteString: string; @@ -41,8 +40,6 @@ const { copy } = useClipboard(); const loggedIn = !!identity.value; const authorIsMe = loggedIn && authorId === identity.value?.account.id; -const confirmDeletes = useSetting(SettingIds.ConfirmDelete); - const copyText = (text: string) => { copy(text); toast.success(m.flat_nice_worm_dream()); @@ -57,7 +54,7 @@ const blockUser = async (userId: string) => { }; const _delete = async () => { - if (confirmDeletes.value.value) { + if (preferences.confirm_actions.value.includes("delete")) { const confirmation = await confirmModalService.confirm({ title: m.calm_icy_weasel_twirl(), message: m.gray_fun_toucan_slide(), diff --git a/components/preferences2/category.vue b/components/preferences2/category.vue index 264483e..371741a 100644 --- a/components/preferences2/category.vue +++ b/components/preferences2/category.vue @@ -5,13 +5,13 @@ - - - - - - - + + + + + + + diff --git a/components/preferences2/developer.vue b/components/preferences2/developer.vue new file mode 100644 index 0000000..5f49f72 --- /dev/null +++ b/components/preferences2/developer.vue @@ -0,0 +1,60 @@ + + + + + + {{ key }} + + {{ value }} + + + + + + + + + diff --git a/components/preferences2/dialog.vue b/components/preferences2/dialog.vue index 72bd28e..6b324d7 100644 --- a/components/preferences2/dialog.vue +++ b/components/preferences2/dialog.vue @@ -21,6 +21,7 @@ import TinyCard from "../profiles/tiny-card.vue"; import { Separator } from "../ui/separator"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs"; import Category from "./category.vue"; +import Developer from "./developer.vue"; import Emojis from "./emojis/index.vue"; import Page from "./page.vue"; import { preferences } from "./preferences"; @@ -110,6 +111,11 @@ const { account: author3 } = useAccountFromAcct( + + + + + diff --git a/components/preferences2/stats.vue b/components/preferences2/stats.vue index fe18dca..4d5b03d 100644 --- a/components/preferences2/stats.vue +++ b/components/preferences2/stats.vue @@ -25,7 +25,6 @@ const data: [string, string | VNode][] = [ ["Author", pkg.author.name], [ "Repository", - // biome-ignore lint/correctness/useJsxKeyInIterable: diff --git a/components/preferences2/types/code.vue b/components/preferences2/types/code.vue index b8e89bb..fc9da3e 100644 --- a/components/preferences2/types/code.vue +++ b/components/preferences2/types/code.vue @@ -1,6 +1,6 @@ - + @@ -25,10 +25,12 @@ import { CollapsibleTrigger, } from "~/components/ui/collapsible"; import { Textarea } from "~/components/ui/textarea"; +import type { preferences as prefs } from "../preferences"; import type { CodePreference } from "../types"; import Base from "./base.vue"; -const { pref } = defineProps<{ +const { pref, name } = defineProps<{ pref: CodePreference; + name: keyof typeof prefs; }>(); diff --git a/components/preferences2/types/multiselect.vue b/components/preferences2/types/multiselect.vue index 9dbde53..9c3e541 100644 --- a/components/preferences2/types/multiselect.vue +++ b/components/preferences2/types/multiselect.vue @@ -1,5 +1,5 @@ - + @@ -30,10 +30,12 @@ import { DropdownMenuContent, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu"; +import type { preferences as prefs } from "../preferences"; import type { MultiSelectPreference } from "../types"; import Base from "./base.vue"; -const { pref } = defineProps<{ +const { pref, name } = defineProps<{ pref: MultiSelectPreference; + name: keyof typeof prefs; }>(); diff --git a/components/preferences2/types/number.vue b/components/preferences2/types/number.vue index 9c66b8d..df60ce4 100644 --- a/components/preferences2/types/number.vue +++ b/components/preferences2/types/number.vue @@ -1,5 +1,5 @@ - + @@ -18,10 +18,12 @@ import { NumberFieldIncrement, NumberFieldInput, } from "~/components/ui/number-field"; +import type { preferences as prefs } from "../preferences"; import type { NumberPreference } from "../types"; import Base from "./base.vue"; -const { pref } = defineProps<{ +const { pref, name } = defineProps<{ pref: NumberPreference; + name: keyof typeof prefs; }>(); diff --git a/components/preferences2/types/select.vue b/components/preferences2/types/select.vue index 59b55cf..b6278b7 100644 --- a/components/preferences2/types/select.vue +++ b/components/preferences2/types/select.vue @@ -1,5 +1,5 @@ - + @@ -24,10 +24,12 @@ import { SelectTrigger, SelectValue, } from "~/components/ui/select"; +import type { preferences as prefs } from "../preferences"; import type { SelectPreference } from "../types"; import Base from "./base.vue"; -const { pref } = defineProps<{ +const { pref, name } = defineProps<{ pref: SelectPreference; + name: keyof typeof prefs; }>(); diff --git a/components/preferences2/types/text.vue b/components/preferences2/types/text.vue index 4660901..5c1608c 100644 --- a/components/preferences2/types/text.vue +++ b/components/preferences2/types/text.vue @@ -1,15 +1,17 @@ - + diff --git a/components/preferences2/types/url.vue b/components/preferences2/types/url.vue index c8491a3..655cab1 100644 --- a/components/preferences2/types/url.vue +++ b/components/preferences2/types/url.vue @@ -1,6 +1,6 @@ - + @@ -25,10 +25,12 @@ import { CollapsibleTrigger, } from "~/components/ui/collapsible"; import { Input, UrlInput } from "~/components/ui/input"; +import type { preferences as prefs } from "../preferences"; import type { TextPreference } from "../types"; import Base from "./base.vue"; -const { pref } = defineProps<{ +const { pref, name } = defineProps<{ pref: TextPreference; + name: keyof typeof prefs; }>(); diff --git a/components/profiles/avatar.vue b/components/profiles/avatar.vue index 3ece60e..5e52ab9 100644 --- a/components/profiles/avatar.vue +++ b/components/profiles/avatar.vue @@ -1,5 +1,5 @@ - + {{ getInitials(name) }} @@ -8,7 +8,6 @@ diff --git a/components/profiles/profile.vue b/components/profiles/profile.vue index 5505edc..ad80bcb 100644 --- a/components/profiles/profile.vue +++ b/components/profiles/profile.vue @@ -74,7 +74,6 @@ import { Button } from "~/components/ui/button"; import { Card, CardContent, CardFooter, CardTitle } from "~/components/ui/card"; import { Separator } from "~/components/ui/separator"; import * as m from "~/paraglide/messages.js"; -import { SettingIds } from "~/settings"; import { confirmModalService } from "../modals/composable"; import ProfileActions from "./profile-actions.vue"; import ProfileBadges from "./profile-badges.vue"; @@ -91,10 +90,8 @@ const { relationship, isLoading } = useRelationship(client, account.id); const isMe = identity.value?.account.id === account.id; const [username, instance] = account.acct.split("@"); -const confirmFollows = useSetting(SettingIds.ConfirmFollow); - const follow = async () => { - if (confirmFollows.value.value) { + if (preferences.confirm_actions.value.includes("follow")) { const confirmation = await confirmModalService.confirm({ title: m.many_fair_capybara_imagine(), message: m.mellow_yummy_jannes_cuddle({ @@ -118,7 +115,7 @@ const follow = async () => { }; const unfollow = async () => { - if (confirmFollows.value.value) { + if (preferences.confirm_actions.value.includes("follow")) { const confirmation = await confirmModalService.confirm({ title: m.funny_aloof_swan_loop(), message: m.white_best_dolphin_catch({ diff --git a/components/sidebars/sidebar.vue b/components/sidebars/sidebar.vue index 2eeeb00..84b8d83 100644 --- a/components/sidebars/sidebar.vue +++ b/components/sidebars/sidebar.vue @@ -1,13 +1,8 @@ diff --git a/pages/preferences/emojis.vue b/pages/preferences/emojis.vue deleted file mode 100644 index c8cb113..0000000 --- a/pages/preferences/emojis.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - {{ m.suave_smart_mantis_climb() }} - - - Upload - - - - - - - - - - {{ m.actual_steep_llama_rest() }} - - {{ m.lucky_suave_myna_adore() }} - - - - - - - diff --git a/pages/preferences/index.vue b/pages/preferences/index.vue deleted file mode 100644 index 53be26f..0000000 --- a/pages/preferences/index.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/plugins/EmojiRenderer.ts b/plugins/EmojiRenderer.ts index 7a77154..e4ea251 100644 --- a/plugins/EmojiRenderer.ts +++ b/plugins/EmojiRenderer.ts @@ -1,5 +1,4 @@ import type { Emoji } from "@versia/client/types"; -import { SettingIds } from "~/settings"; const emojisRegex = /\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?(\u200D(\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?))*/gu; @@ -8,11 +7,8 @@ const incorrectEmojisRegex = /^[#*0-9©®]$/; export default defineNuxtPlugin((nuxtApp) => { nuxtApp.vueApp.directive("render-emojis", { beforeMount(el, binding) { - const shouldRenderEmoji = useSetting(SettingIds.CustomEmojis); - const emojiFont = useSetting(SettingIds.EmojiTheme); - // Replace emoji shortcodes with images - if (shouldRenderEmoji.value.value) { + if (preferences.custom_emojis.value) { el.innerHTML = el.innerHTML.replace( /:([a-zA-Z0-9_-]+):/g, (match, emoji) => { @@ -35,13 +31,13 @@ export default defineNuxtPlugin((nuxtApp) => { ); } - if (emojiFont.value.value !== "native") { + if (preferences.emoji_theme.value !== "native") { el.innerHTML = el.innerHTML.replace(emojisRegex, (match) => { if (incorrectEmojisRegex.test(match)) { return match; } - return ``; + return ``; }); }