mirror of
https://github.com/versia-pub/frontend.git
synced 2026-03-13 11:39:16 +01:00
feat: ✨ Wire up new preferences and remove old settings
Some checks failed
Mirror to Codeberg / Mirror (push) Failing after 0s
Some checks failed
Mirror to Codeberg / Mirror (push) Failing after 0s
This commit is contained in:
parent
412e49dfe2
commit
3ce71dd4df
32 changed files with 213 additions and 340 deletions
|
|
@ -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<HTMLInputElement | null>(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,
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ defineProps<{
|
|||
modalOptions: ConfirmModalOptions;
|
||||
}>();
|
||||
|
||||
defineEmits<{
|
||||
confirm: (result: ConfirmModalResult) => void;
|
||||
cancel: () => void;
|
||||
const emit = defineEmits<{
|
||||
confirm: [result: ConfirmModalResult];
|
||||
cancel: [];
|
||||
}>();
|
||||
|
||||
const inputValue = ref<string>("");
|
||||
|
|
@ -55,10 +55,10 @@ const inputValue = ref<string>("");
|
|||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" @click="() => $emit('cancel')">
|
||||
<Button variant="outline" @click="() => emit('cancel')">
|
||||
{{ modalOptions.cancelText }}
|
||||
</Button>
|
||||
<Button @click="() => $emit('confirm', {
|
||||
<Button @click="() => emit('confirm', {
|
||||
confirmed: true,
|
||||
value: inputValue,
|
||||
})">
|
||||
|
|
@ -67,4 +67,4 @@ const inputValue = ref<string>("");
|
|||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<ContentWarning v-if="(sensitive || contentWarning) && showCw.value" :content-warning="contentWarning" v-model="blurred" />
|
||||
<ContentWarning v-if="(sensitive || contentWarning) && preferences.show_content_warning" :content-warning="contentWarning" v-model="blurred" />
|
||||
|
||||
<OverflowGuard :character-count="characterCount" :class="(blurred && showCw.value) && 'blur-md'">
|
||||
<OverflowGuard :character-count="characterCount" :class="(blurred && preferences.show_content_warning) && 'blur-md'">
|
||||
<Prose v-html="content" v-render-emojis="emojis"></Prose>
|
||||
</OverflowGuard>
|
||||
|
||||
<Attachments v-if="attachments.length > 0" :attachments="attachments" :class="(blurred && showCw.value) && 'blur-xl'" />
|
||||
<Attachments v-if="attachments.length > 0" :attachments="attachments" :class="(blurred && preferences.show_content_warning) && 'blur-xl'" />
|
||||
|
||||
<div v-if="quote" class="mt-4 rounded border overflow-hidden">
|
||||
<Note :note="quote" :hide-actions="true" :small-layout="true" />
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import type { Attachment, Emoji, Status } from "@versia/client/types";
|
||||
import { type BooleanSetting, SettingIds } from "~/settings";
|
||||
import Attachments from "./attachments.vue";
|
||||
import ContentWarning from "./content-warning.vue";
|
||||
import Note from "./note.vue";
|
||||
|
|
@ -32,7 +31,6 @@ const { content, plainContent, sensitive, contentWarning } = defineProps<{
|
|||
}>();
|
||||
|
||||
const blurred = ref(sensitive || !!contentWarning);
|
||||
const showCw = useSetting(SettingIds.ShowContentWarning) as Ref<BooleanSetting>;
|
||||
|
||||
const characterCount = plainContent?.length;
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="rounded flex flex-row items-center gap-3">
|
||||
<HoverCard v-model:open="popupOpen" @update:open="() => {
|
||||
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 = {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
</CardTitle>
|
||||
<Card class="p-0 gap-0">
|
||||
<div v-for="preference of preferences" :key="preference">
|
||||
<TextPreferenceVue v-if="(prefs[preference] instanceof TextPreference)" :pref="(prefs[preference] as TextPreference)" />
|
||||
<BooleanPreferenceVue v-else-if="(prefs[preference] instanceof BooleanPreference)" :pref="(prefs[preference] as BooleanPreference)" />
|
||||
<SelectPreferenceVue v-else-if="(prefs[preference] instanceof SelectPreference)" :pref="(prefs[preference] as SelectPreference<string>)" />
|
||||
<NumberPreferenceVue v-else-if="(prefs[preference] instanceof NumberPreference)" :pref="(prefs[preference] as NumberPreference)" />
|
||||
<MultiSelectPreferenceVue v-else-if="(prefs[preference] instanceof MultiSelectPreference)" :pref="(prefs[preference] as MultiSelectPreference<string>)" />
|
||||
<CodePreferenceVue v-else-if="(prefs[preference] instanceof CodePreference)" :pref="(prefs[preference] as CodePreference)" />
|
||||
<UrlPreferenceVue v-else-if="(prefs[preference] instanceof UrlPreference)" :pref="(prefs[preference] as UrlPreference)" />
|
||||
<TextPreferenceVue v-if="(prefs[preference] instanceof TextPreference)" :pref="(prefs[preference] as TextPreference)" :name="preference" />
|
||||
<BooleanPreferenceVue v-else-if="(prefs[preference] instanceof BooleanPreference)" :pref="(prefs[preference] as BooleanPreference)" :name="preference" />
|
||||
<SelectPreferenceVue v-else-if="(prefs[preference] instanceof SelectPreference)" :pref="(prefs[preference] as SelectPreference<string>)" :name="preference" />
|
||||
<NumberPreferenceVue v-else-if="(prefs[preference] instanceof NumberPreference)" :pref="(prefs[preference] as NumberPreference)" :name="preference" />
|
||||
<MultiSelectPreferenceVue v-else-if="(prefs[preference] instanceof MultiSelectPreference)" :pref="(prefs[preference] as MultiSelectPreference<string>)" :name="preference" />
|
||||
<CodePreferenceVue v-else-if="(prefs[preference] instanceof CodePreference)" :pref="(prefs[preference] as CodePreference)" :name="preference" />
|
||||
<UrlPreferenceVue v-else-if="(prefs[preference] instanceof UrlPreference)" :pref="(prefs[preference] as UrlPreference)" :name="preference" />
|
||||
</div>
|
||||
</Card>
|
||||
</section>
|
||||
|
|
|
|||
60
components/preferences2/developer.vue
Normal file
60
components/preferences2/developer.vue
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<Card class="grid gap-3 text-sm p-4">
|
||||
<dl class="grid gap-3">
|
||||
<div v-for="[key, value] of data" :key="key" class="flex flex-row items-baseline justify-between gap-4 truncate">
|
||||
<dt class="text-muted-foreground">
|
||||
{{ key }}
|
||||
</dt>
|
||||
<dd class="font-mono" v-if="typeof value === 'string'">{{ value }}</dd>
|
||||
<dd class="font-mono" v-else>
|
||||
<component :is="value" />
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type { VNode } from "vue";
|
||||
import { toast } from "vue-sonner";
|
||||
import { Button } from "../ui/button";
|
||||
import { Card } from "../ui/card";
|
||||
|
||||
const copy = (data: string) => {
|
||||
navigator.clipboard.writeText(data);
|
||||
toast.success("Copied to clipboard");
|
||||
};
|
||||
|
||||
const appData = useAppData();
|
||||
|
||||
const data: [string, string | VNode][] = [
|
||||
["User ID", identity.value?.account.id ?? ""],
|
||||
["Instance domain", identity.value?.instance.domain ?? ""],
|
||||
["Instance version", identity.value?.instance.versia_version ?? ""],
|
||||
["Client ID", appData.value?.client_id ?? ""],
|
||||
[
|
||||
"Client secret",
|
||||
<Button
|
||||
variant="outline"
|
||||
class="font-sans"
|
||||
size="sm"
|
||||
// @ts-expect-error missing onClick types
|
||||
onClick={() => copy(appData.value?.client_secret ?? "")}
|
||||
>
|
||||
Click to copy
|
||||
</Button>,
|
||||
],
|
||||
[
|
||||
"Access token",
|
||||
<Button
|
||||
variant="outline"
|
||||
class="font-sans"
|
||||
size="sm"
|
||||
// @ts-expect-error missing onClick types
|
||||
onClick={() => copy(identity.value?.tokens.access_token ?? "")}
|
||||
>
|
||||
Click to copy
|
||||
</Button>,
|
||||
],
|
||||
];
|
||||
</script>
|
||||
|
|
@ -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(
|
|||
<Emojis />
|
||||
</Page>
|
||||
</TabsContent>
|
||||
<TabsContent value="Developer" as-child>
|
||||
<Page title="Developer">
|
||||
<Developer />
|
||||
</Page>
|
||||
</TabsContent>
|
||||
<TabsContent value="About" as-child>
|
||||
<Page title="About">
|
||||
<section class="space-y-4">
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ const data: [string, string | VNode][] = [
|
|||
["Author", pkg.author.name],
|
||||
[
|
||||
"Repository",
|
||||
// biome-ignore lint/correctness/useJsxKeyInIterable: <explanation>
|
||||
<a
|
||||
href={pkg.repository.url.replace("git+", "")}
|
||||
target="_blank"
|
||||
|
|
|
|||
|
|
@ -13,17 +13,23 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { preferences as prefs } from "../preferences";
|
||||
import type { Preference } from "../types";
|
||||
|
||||
const { pref } = defineProps<{
|
||||
const { pref, name } = defineProps<{
|
||||
pref: Preference<any>;
|
||||
name: keyof typeof prefs;
|
||||
}>();
|
||||
|
||||
const value = ref<any>(pref.options.defaultValue);
|
||||
const value = ref<any>(preferences[name].value);
|
||||
const setValue = (newValue: MaybeRef<any>) => {
|
||||
value.value = toValue(newValue);
|
||||
};
|
||||
|
||||
watch(value, (newVal) => {
|
||||
preferences[name].value = newVal;
|
||||
});
|
||||
|
||||
defineSlots<{
|
||||
default(props: {
|
||||
value: any;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
<template>
|
||||
<Base :pref="pref" v-slot="{ setValue, value }">
|
||||
<Base :pref="pref" :name="name" v-slot="{ setValue, value }">
|
||||
<Switch @update:model-value="setValue" :model-value="value" />
|
||||
</Base>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Switch } from "~/components/ui/switch";
|
||||
import type { preferences as prefs } from "../preferences";
|
||||
import type { BooleanPreference } from "../types";
|
||||
import Base from "./base.vue";
|
||||
|
||||
const { pref } = defineProps<{
|
||||
const { pref, name } = defineProps<{
|
||||
pref: BooleanPreference;
|
||||
name: keyof typeof prefs;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Collapsible as-child>
|
||||
<Base :pref="pref">
|
||||
<Base :name="name" :pref="pref">
|
||||
<template #default>
|
||||
<CollapsibleTrigger as-child>
|
||||
<Button variant="outline">
|
||||
|
|
@ -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;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Base :pref="pref" v-slot="{ setValue, value }">
|
||||
<Base :pref="pref" :name="name" v-slot="{ setValue, value }">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<Button variant="outline">
|
||||
|
|
@ -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<string>;
|
||||
name: keyof typeof prefs;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Base :pref="pref" v-slot="{ setValue, value }">
|
||||
<Base :pref="pref" :name="name" v-slot="{ setValue, value }">
|
||||
<NumberField :model-value="value" @update:model-value="setValue" :min="pref.options.min" :max="pref.options.max" :step="pref.options.integer ? 1 : pref.options.step">
|
||||
<NumberFieldContent>
|
||||
<NumberFieldDecrement />
|
||||
|
|
@ -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;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Base :pref="pref" v-slot="{ setValue, value }">
|
||||
<Base :pref="pref" :name="name" v-slot="{ setValue, value }">
|
||||
<Select :model-value="value" @update:model-value="setValue">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select an option" />
|
||||
|
|
@ -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<string>;
|
||||
name: keyof typeof prefs;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
<template>
|
||||
<Base :pref="pref" v-slot="{ setValue, value }">
|
||||
<Base :pref="pref" :name="name" v-slot="{ setValue, value }">
|
||||
<Input placeholder="Content here..." :model-value="value" @update:model-value="setValue" />
|
||||
</Base>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Input } 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;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Collapsible as-child>
|
||||
<Base :pref="pref">
|
||||
<Base :pref="pref" :name="name">
|
||||
<template #default>
|
||||
<CollapsibleTrigger as-child>
|
||||
<Button variant="outline">
|
||||
|
|
@ -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;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Avatar :class="[shape.value === 'square' && 'rounded-md', 'bg-secondary']">
|
||||
<Avatar :class="['rounded-md bg-secondary']">
|
||||
<AvatarFallback v-if="name">
|
||||
{{ getInitials(name) }}
|
||||
</AvatarFallback>
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { SettingIds } from "~/settings";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
|
||||
|
||||
const { name } = defineProps<{
|
||||
|
|
@ -29,6 +28,4 @@ const getInitials = (name: string): string => {
|
|||
|
||||
return `${firstLetter}${secondLetter}`.toUpperCase();
|
||||
};
|
||||
|
||||
const shape = useSetting(SettingIds.AvatarShape);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import Timelines from "~/components/navigation/timelines.vue";
|
||||
import { SidebarInset } from "~/components/ui/sidebar";
|
||||
import { SettingIds } from "~/settings";
|
||||
import LeftSidebar from "./left-sidebar.vue";
|
||||
import RightSidebar from "./right-sidebar.vue";
|
||||
|
||||
const showRightSidebar = useSetting(SettingIds.NotificationsSidebar);
|
||||
|
||||
const route = useRoute();
|
||||
const isMd = useMediaQuery("(max-width: 768px)");
|
||||
const showTimelines = computed(
|
||||
|
|
@ -28,5 +23,5 @@ const showTimelines = computed(
|
|||
</header>
|
||||
<slot />
|
||||
</main>
|
||||
<RightSidebar v-if="identity" v-show="showRightSidebar.value" />
|
||||
<RightSidebar v-if="identity" v-show="preferences.display_notifications_sidebar" />
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
<!-- If there are no posts at all -->
|
||||
<NoPosts v-else-if="hasReachedEnd && items.length === 0" />
|
||||
|
||||
<div v-else-if="!infiniteScroll.value" class="py-10 px-4">
|
||||
<div v-else-if="!preferences.infinite_scroll" class="py-10 px-4">
|
||||
<Button
|
||||
variant="secondary"
|
||||
@click="loadNext"
|
||||
|
|
@ -43,7 +43,6 @@
|
|||
import type { Notification, Status } from "@versia/client/types";
|
||||
import { useIntersectionObserver } from "@vueuse/core";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { SettingIds } from "~/settings";
|
||||
import NoPosts from "../errors/NoPosts.vue";
|
||||
import ReachedEnd from "../errors/ReachedEnd.vue";
|
||||
import Spinner from "../graphics/spinner.vue";
|
||||
|
|
@ -66,14 +65,13 @@ const emit = defineEmits<(e: "update") => void>();
|
|||
|
||||
const loadMoreTrigger = ref<HTMLElement | null>(null);
|
||||
|
||||
// @ts-expect-error Too complex?
|
||||
useIntersectionObserver(loadMoreTrigger, ([observer]) => {
|
||||
if (observer?.isIntersecting && !props.isLoading && !props.hasReachedEnd) {
|
||||
props.loadNext();
|
||||
}
|
||||
});
|
||||
|
||||
const infiniteScroll = useSetting(SettingIds.InfiniteScroll);
|
||||
|
||||
watch(
|
||||
() => props.items,
|
||||
() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue