mirror of
https://github.com/versia-pub/frontend.git
synced 2025-12-06 16:38:20 +01:00
refactor: 🌐 Internationalize every string
This commit is contained in:
parent
8c3ddc2a28
commit
2ceee4827f
4
app.vue
4
app.vue
|
|
@ -19,10 +19,14 @@ import "~/styles/index.css";
|
|||
import { convert } from "html-to-text";
|
||||
import ConfirmationModal from "./components/modals/confirm.vue";
|
||||
import { Toaster } from "./components/ui/sonner";
|
||||
import { setLanguageTag } from "./paraglide/runtime";
|
||||
import { type EnumSetting, SettingIds } from "./settings";
|
||||
// Sin
|
||||
//import "~/styles/mcdonalds.css";
|
||||
|
||||
const lang = useLanguage();
|
||||
setLanguageTag(lang.value);
|
||||
|
||||
const code = useRequestURL().searchParams.get("code");
|
||||
const appData = useAppData();
|
||||
const instance = useInstance();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Mention someone</p>
|
||||
<p>{{ m.game_tough_seal_adore() }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
</Toggle>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Enable Markdown</p>
|
||||
<p>{{ m.plane_born_koala_hope() }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Select v-model:model-value="state.visibility">
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Insert emoji</p>
|
||||
<p>{{ m.blue_ornate_coyote_tickle() }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Attach a file</p>
|
||||
<p>{{ m.top_patchy_earthworm_vent() }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
|
|
@ -82,12 +82,12 @@
|
|||
</Toggle>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Mark as sensitive</p>
|
||||
<p>{{ m.frail_broad_mallard_dart() }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Button type="submit" size="lg" class="ml-auto" :disabled="sending" @click="submit">
|
||||
<Loader v-if="sending" class="!size-5 animate-spin" />
|
||||
{{ relation?.type === "edit" ? "Save" : "Send" }}
|
||||
{{ relation?.type === "edit" ? m.gaudy_strong_puma_slide() : m.free_teal_bulldog_learn() }}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</template>
|
||||
|
|
@ -110,6 +110,7 @@ import { SelectTrigger } from "radix-vue";
|
|||
import { toast } from "vue-sonner";
|
||||
import Note from "~/components/notes/note.vue";
|
||||
import { Select, SelectContent, SelectItem } from "~/components/ui/select";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { SettingIds } from "~/settings";
|
||||
import { Button } from "../ui/button";
|
||||
import { Input } from "../ui/input";
|
||||
|
|
@ -145,11 +146,11 @@ const getMentions = () => {
|
|||
const peopleToMention = relation.note.mentions
|
||||
.concat(relation.note.account)
|
||||
// Deduplicate mentions
|
||||
.filter((m, i, a) => a.indexOf(m) === i)
|
||||
.filter((men, i, a) => a.indexOf(men) === i)
|
||||
// Remove self
|
||||
.filter((m) => m.id !== identity.value?.account.id);
|
||||
.filter((men) => men.id !== identity.value?.account.id);
|
||||
|
||||
const mentions = peopleToMention.map((m) => `@${m.acct}`).join(" ");
|
||||
const mentions = peopleToMention.map((me) => `@${me.acct}`).join(" ");
|
||||
|
||||
return `${mentions} `;
|
||||
};
|
||||
|
|
@ -165,10 +166,10 @@ const state = reactive({
|
|||
? relation.note.visibility
|
||||
: "public") as Status["visibility"],
|
||||
files: (relation?.type === "edit"
|
||||
? relation.note.media_attachments.map((m) => ({
|
||||
apiId: m.id,
|
||||
file: new File([], m.url),
|
||||
alt: m.description,
|
||||
? relation.note.media_attachments.map((a) => ({
|
||||
apiId: a.id,
|
||||
file: new File([], a.url),
|
||||
alt: a.description,
|
||||
uploading: false,
|
||||
updating: false,
|
||||
}))
|
||||
|
|
@ -276,23 +277,23 @@ const uploadFiles = (files: File[]) => {
|
|||
const visibilities = {
|
||||
public: {
|
||||
icon: Globe,
|
||||
name: "Public",
|
||||
text: "Can be seen by anyone.",
|
||||
name: m.lost_trick_dog_grace(),
|
||||
text: m.last_mean_peacock_zip(),
|
||||
},
|
||||
unlisted: {
|
||||
icon: LockOpen,
|
||||
name: "Unlisted",
|
||||
text: "Can be seen by anyone with the link.",
|
||||
name: m.funny_slow_jannes_walk(),
|
||||
text: m.grand_strong_gibbon_race(),
|
||||
},
|
||||
private: {
|
||||
icon: Lock,
|
||||
name: "Private",
|
||||
text: "Can only be seen by your followers.",
|
||||
name: m.grassy_empty_raven_startle(),
|
||||
text: m.white_teal_ostrich_yell(),
|
||||
},
|
||||
direct: {
|
||||
icon: AtSign,
|
||||
name: "Direct",
|
||||
text: "Can only be seen by mentioned users.",
|
||||
name: m.pretty_bold_baboon_wave(),
|
||||
text: m.lucky_mean_robin_link(),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
||||
import type { Status, StatusSource } from "@versia/client/types";
|
||||
import { toast } from "vue-sonner";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import Composer from "./composer.vue";
|
||||
|
||||
useListen("composer:open", () => {
|
||||
|
|
@ -11,7 +12,7 @@ useListen("composer:open", () => {
|
|||
});
|
||||
|
||||
useListen("composer:edit", async (note) => {
|
||||
const id = toast.loading("Loading note data...", {
|
||||
const id = toast.loading(m.wise_late_fireant_walk(), {
|
||||
duration: 0,
|
||||
});
|
||||
const { data: source } = await client.value.getStatusSource(note.id);
|
||||
|
|
@ -56,13 +57,16 @@ const relation = ref(
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="open" @update:open="o => {if (!o) { relation = null}}">
|
||||
<DialogContent :hide-close="true" class="sm:max-w-xl max-w-full w-full grid-rows-[minmax(0,1fr)_auto] max-h-[90dvh] p-5 pt-6 top-0 sm:top-1/2 translate-y-0 sm:-translate-y-1/2">
|
||||
<Dialog v-model:open="open" @update:open="o => { if (!o) { relation = null } }">
|
||||
<DialogContent :hide-close="true"
|
||||
class="sm:max-w-xl max-w-full w-full grid-rows-[minmax(0,1fr)_auto] max-h-[90dvh] p-5 pt-6 top-0 sm:top-1/2 translate-y-0 sm:-translate-y-1/2">
|
||||
<DialogTitle class="sr-only">
|
||||
{{ relation?.type === "reply" ? "Reply" : relation?.type === "quote" ? "Quote" : "Compose" }}
|
||||
{{ relation?.type === "reply" ? m.loved_busy_mantis_slide() : relation?.type === "quote" ? "Quote" :
|
||||
m.chunky_dull_marlin_trip() }}
|
||||
</DialogTitle>
|
||||
<DialogDescription class="sr-only">
|
||||
{{ relation?.type === "reply" ? "Reply to this status" : relation?.type === "quote" ? "Quote this status" : "Compose a new status" }}
|
||||
{{ relation?.type === "reply" ? m.tired_grassy_vulture_forgive() : relation?.type === "quote" ?
|
||||
m.livid_livid_nils_snip() : m.brief_cool_capybara_fear() }}
|
||||
</DialogDescription>
|
||||
<Composer :relation="relation ?? undefined" />
|
||||
</DialogContent>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import type { ConfirmModalOptions, ConfirmModalResult } from "./composable.ts";
|
||||
|
||||
defineProps<{
|
||||
|
|
@ -41,14 +42,14 @@ const inputValue = ref<string>("");
|
|||
|
||||
<div v-if="modalOptions.inputType === 'text'" class="grid gap-4 py-4">
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label for="confirmInput" class="text-right">Value</Label>
|
||||
<Label for="confirmInput" class="text-right">{{ m.mean_mean_badger_inspire() }}</Label>
|
||||
<Input id="confirmInput" v-model="inputValue" class="col-span-3" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="modalOptions.inputType === 'textarea'" class="grid gap-4 py-4">
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label for="confirmTextarea" class="text-right">Value</Label>
|
||||
<Label for="confirmTextarea" class="text-right">{{ m.mean_mean_badger_inspire() }}</Label>
|
||||
<Textarea id="confirmTextarea" v-model="inputValue" class="col-span-3" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import {
|
||||
type ConfirmModalOptions,
|
||||
type ConfirmModalResult,
|
||||
|
|
@ -20,11 +21,11 @@ import {
|
|||
|
||||
const isOpen = ref(false);
|
||||
const modalOptions = ref<ConfirmModalOptions>({
|
||||
title: "Confirm",
|
||||
title: m.antsy_whole_alligator_blink(),
|
||||
message: "",
|
||||
inputType: "none",
|
||||
confirmText: "Confirm",
|
||||
cancelText: "Cancel",
|
||||
confirmText: m.antsy_whole_alligator_blink(),
|
||||
cancelText: m.soft_bold_ant_attend(),
|
||||
});
|
||||
const inputValue = ref("");
|
||||
const resolvePromise = ref<((result: ConfirmModalResult) => void) | null>(null);
|
||||
|
|
@ -32,11 +33,11 @@ const resolvePromise = ref<((result: ConfirmModalResult) => void) | null>(null);
|
|||
function open(options: ConfirmModalOptions): Promise<ConfirmModalResult> {
|
||||
isOpen.value = true;
|
||||
modalOptions.value = {
|
||||
title: options.title || "Confirm",
|
||||
title: options.title || m.antsy_whole_alligator_blink(),
|
||||
message: options.message,
|
||||
inputType: options.inputType || "none",
|
||||
confirmText: options.confirmText || "Confirm",
|
||||
cancelText: options.cancelText || "Cancel",
|
||||
confirmText: options.confirmText || m.antsy_whole_alligator_blink(),
|
||||
cancelText: options.cancelText || m.soft_bold_ant_attend(),
|
||||
};
|
||||
inputValue.value = options.defaultValue || "";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
<template>
|
||||
<div class="flex flex-row w-full items-stretch justify-around text-sm *:max-w-28 *:w-full *:text-muted-foreground">
|
||||
<Button variant="ghost" @click="emit('reply')" title="Reply" :disabled="!identity">
|
||||
<Button variant="ghost" @click="emit('reply')" :title="m.drab_tense_turtle_comfort()" :disabled="!identity">
|
||||
<Reply class="size-5 text-primary" />
|
||||
{{ numberFormat(replyCount) }}
|
||||
</Button>
|
||||
<Button variant="ghost" @click="liked ? unlike() : like()" :title="liked ? 'Unlike' : 'Like'" :disabled="!identity">
|
||||
<Button variant="ghost" @click="liked ? unlike() : like()" :title="liked ? m.vexed_fluffy_clownfish_dance() : m.royal_close_samuel_scold()" :disabled="!identity">
|
||||
<Heart class="size-5 text-primary" />
|
||||
{{ numberFormat(likeCount) }}
|
||||
</Button>
|
||||
<Button variant="ghost" @click="reblogged ? unreblog() : reblog()" :title="reblogged ? 'Unreblog' : 'Reblog'" :disabled="!identity">
|
||||
<Button variant="ghost" @click="reblogged ? unreblog() : reblog()" :title="reblogged ? m.lime_neat_ox_stab() : m.aware_helpful_marlin_drop()" :disabled="!identity">
|
||||
<Repeat class="size-5 text-primary" />
|
||||
{{ numberFormat(reblogCount) }}
|
||||
</Button>
|
||||
<Button variant="ghost" @click="emit('quote')" title="Quote" :disabled="!identity">
|
||||
<Button variant="ghost" @click="emit('quote')" :title="m.true_shy_jackal_drip()" :disabled="!identity">
|
||||
<Quote class="size-5 text-primary" />
|
||||
</Button>
|
||||
<Menu :api-note-string="apiNoteString" :url="url" :remote-url="remoteUrl" :is-remote="isRemote" :author-id="authorId" @edit="emit('edit')" :note-id="noteId" @delete="emit('delete')">
|
||||
<Button variant="ghost" title="Actions">
|
||||
<Button variant="ghost" :title="m.busy_merry_cowfish_absorb()">
|
||||
<Ellipsis class="size-5 text-primary" />
|
||||
</Button>
|
||||
</Menu>
|
||||
|
|
@ -27,6 +27,8 @@
|
|||
import { Ellipsis, Heart, Quote, Repeat, Reply } from "lucide-vue-next";
|
||||
import { toast } from "vue-sonner";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { languageTag } from "~/paraglide/runtime";
|
||||
import { SettingIds } from "~/settings";
|
||||
import { confirmModalService } from "../modals/composable";
|
||||
import Menu from "./menu.vue";
|
||||
|
|
@ -58,9 +60,9 @@ const confirmReblogs = useSetting(SettingIds.ConfirmReblog);
|
|||
const like = async () => {
|
||||
if (confirmLikes.value.value) {
|
||||
const confirmation = await confirmModalService.confirm({
|
||||
title: "Like status",
|
||||
message: "Are you sure you want to like this status?",
|
||||
confirmText: "Like",
|
||||
title: m.slimy_least_ray_aid(),
|
||||
message: m.stale_new_ray_jolt(),
|
||||
confirmText: m.royal_close_samuel_scold(),
|
||||
inputType: "none",
|
||||
});
|
||||
|
||||
|
|
@ -69,19 +71,19 @@ const like = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
const id = toast.loading("Liking status...");
|
||||
const id = toast.loading(m.slimy_candid_tiger_read());
|
||||
const { data } = await client.value.favouriteStatus(noteId);
|
||||
toast.dismiss(id);
|
||||
toast.success("Status liked");
|
||||
toast.success(m.mealy_slow_buzzard_commend());
|
||||
useEvent("note:edit", data);
|
||||
};
|
||||
|
||||
const unlike = async () => {
|
||||
if (confirmLikes.value.value) {
|
||||
const confirmation = await confirmModalService.confirm({
|
||||
title: "Unlike status",
|
||||
message: "Are you sure you want to unlike this status?",
|
||||
confirmText: "Unlike",
|
||||
title: m.odd_strong_halibut_prosper(),
|
||||
message: m.slow_blue_parrot_savor(),
|
||||
confirmText: m.vexed_fluffy_clownfish_dance(),
|
||||
inputType: "none",
|
||||
});
|
||||
|
||||
|
|
@ -90,19 +92,19 @@ const unlike = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
const id = toast.loading("Unliking status...");
|
||||
const id = toast.loading(m.busy_active_leopard_strive());
|
||||
const { data } = await client.value.unfavouriteStatus(noteId);
|
||||
toast.dismiss(id);
|
||||
toast.success("Status unliked");
|
||||
toast.success(m.fresh_direct_bear_affirm());
|
||||
useEvent("note:edit", data);
|
||||
};
|
||||
|
||||
const reblog = async () => {
|
||||
if (confirmReblogs.value.value) {
|
||||
const confirmation = await confirmModalService.confirm({
|
||||
title: "Reblog status",
|
||||
message: "Are you sure you want to reblog this status?",
|
||||
confirmText: "Reblog",
|
||||
title: m.best_mellow_llama_surge(),
|
||||
message: m.salty_plain_mallard_gaze(),
|
||||
confirmText: m.aware_helpful_marlin_drop(),
|
||||
inputType: "none",
|
||||
});
|
||||
|
||||
|
|
@ -111,19 +113,19 @@ const reblog = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
const id = toast.loading("Reblogging status...");
|
||||
const id = toast.loading(m.late_sunny_cobra_scold());
|
||||
const { data } = await client.value.reblogStatus(noteId);
|
||||
toast.dismiss(id);
|
||||
toast.success("Status reblogged");
|
||||
toast.success(m.weird_moving_hawk_lift());
|
||||
useEvent("note:edit", data.reblog || data);
|
||||
};
|
||||
|
||||
const unreblog = async () => {
|
||||
if (confirmReblogs.value.value) {
|
||||
const confirmation = await confirmModalService.confirm({
|
||||
title: "Unreblog status",
|
||||
message: "Are you sure you want to unreblog this status?",
|
||||
confirmText: "Unreblog",
|
||||
title: m.main_fancy_octopus_loop(),
|
||||
message: m.odd_alive_swan_express(),
|
||||
confirmText: m.lime_neat_ox_stab(),
|
||||
inputType: "none",
|
||||
});
|
||||
|
||||
|
|
@ -132,16 +134,16 @@ const unreblog = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
const id = toast.loading("Unreblogging status...");
|
||||
const id = toast.loading(m.white_sharp_gorilla_embrace());
|
||||
const { data } = await client.value.unreblogStatus(noteId);
|
||||
toast.dismiss(id);
|
||||
toast.success("Status unreblogged");
|
||||
toast.success(m.royal_polite_moose_catch());
|
||||
useEvent("note:edit", data);
|
||||
};
|
||||
|
||||
const numberFormat = (number = 0) =>
|
||||
number !== 0
|
||||
? new Intl.NumberFormat(undefined, {
|
||||
? new Intl.NumberFormat(languageTag(), {
|
||||
notation: "compact",
|
||||
compactDisplay: "short",
|
||||
maximumFractionDigits: 1,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<template>
|
||||
<Alert variant="warning" v-if="(sensitive || contentWarning) && showCw.value"
|
||||
class="mb-4 py-2 px-4 grid grid-cols-[auto,1fr,auto] gap-2 items-center [&>svg~*]:pl-0 [&>svg+div]:translate-y-0 [&>svg]:static">
|
||||
<AlertTitle class="sr-only">Sensitive content</AlertTitle>
|
||||
<AlertTitle class="sr-only">{{ m.livid_tangy_lionfish_clasp() }}</AlertTitle>
|
||||
<div>
|
||||
<TriangleAlert class="size-4" />
|
||||
</div>
|
||||
<AlertDescription>
|
||||
{{ contentWarning || "This content is sensitive" }}
|
||||
{{ contentWarning || m.sour_seemly_bird_hike() }}
|
||||
</AlertDescription>
|
||||
<Button @click="blurred = !blurred" variant="outline" size="sm">{{ blurred ? "Show" : "Hide" }}</Button>
|
||||
<Button @click="blurred = !blurred" variant="outline" size="sm">{{ blurred ? m.bald_direct_turtle_win() : m.known_flaky_cockroach_dash() }}</Button>
|
||||
</Alert>
|
||||
|
||||
<div ref="container" :class="cn('overflow-y-hidden relative duration-200', (blurred && showCw.value) && 'blur-md')" :style="{
|
||||
|
|
@ -23,9 +23,10 @@
|
|||
<Button v-if="isOverflowing" @click="collapsed = !collapsed"
|
||||
class="absolute bottom-2 right-1/2 translate-x-1/2">{{
|
||||
collapsed
|
||||
? `Show more${plainContent ? ` • ${formattedCharacterCount} characters` : ""
|
||||
}`
|
||||
: "Show less"
|
||||
? `${m.lazy_honest_mammoth_bump()}${plainContent ? ` • ${m.dark_spare_goldfish_charm({
|
||||
count: formattedCharacterCount ?? '0',
|
||||
})}` : "" }`
|
||||
: m.that_misty_mule_arrive()
|
||||
}}</Button>
|
||||
</div>
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ import { cn } from "@/lib/utils";
|
|||
import type { Attachment, Emoji, Status } from "@versia/client/types";
|
||||
import { TriangleAlert } from "lucide-vue-next";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { languageTag } from "~/paraglide/runtime";
|
||||
import { type BooleanSetting, SettingIds } from "~/settings";
|
||||
import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<span @click="copyText"
|
||||
class="select-none cursor-pointer space-x-1">
|
||||
<Clipboard class="size-4 -translate-y-0.5 inline" />
|
||||
Click to copy
|
||||
{{ m.clean_yummy_owl_reside() }}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
|
@ -18,6 +18,7 @@ import { cn } from "@/lib/utils";
|
|||
import { Check, Clipboard } from "lucide-vue-next";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { toast } from "vue-sonner";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const { text } = defineProps<{
|
||||
text: string;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import {
|
|||
} from "lucide-vue-next";
|
||||
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<{
|
||||
|
|
@ -45,23 +46,23 @@ const confirmDeletes = useSetting(SettingIds.ConfirmDelete);
|
|||
|
||||
const copyText = (text: string) => {
|
||||
copy(text);
|
||||
toast.success("Copied to clipboard");
|
||||
toast.success(m.flat_nice_worm_dream());
|
||||
};
|
||||
|
||||
const blockUser = async (userId: string) => {
|
||||
const id = toast.loading("Blocking user...");
|
||||
const id = toast.loading(m.top_cute_bison_nudge());
|
||||
await client.value.blockAccount(userId);
|
||||
toast.dismiss(id);
|
||||
|
||||
toast.success("User blocked");
|
||||
toast.success(m.main_weary_racoon_peek());
|
||||
};
|
||||
|
||||
const _delete = async () => {
|
||||
if (confirmDeletes.value.value) {
|
||||
const confirmation = await confirmModalService.confirm({
|
||||
title: "Delete status",
|
||||
message: "Are you sure you want to delete this status?",
|
||||
confirmText: "Delete",
|
||||
title: m.calm_icy_weasel_twirl(),
|
||||
message: m.gray_fun_toucan_slide(),
|
||||
confirmText: m.royal_best_tern_transform(),
|
||||
inputType: "none",
|
||||
});
|
||||
|
||||
|
|
@ -70,11 +71,11 @@ const _delete = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
const id = toast.loading("Deleting status...");
|
||||
const id = toast.loading(m.new_funny_fox_boil());
|
||||
await client.value.deleteStatus(noteId);
|
||||
toast.dismiss(id);
|
||||
|
||||
toast.success("Status deleted");
|
||||
toast.success(m.green_tasty_bumblebee_beam());
|
||||
emit("delete");
|
||||
};
|
||||
</script>
|
||||
|
|
@ -85,57 +86,57 @@ const _delete = async () => {
|
|||
<slot />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent class="min-w-56">
|
||||
<DropdownMenuLabel>Note Actions</DropdownMenuLabel>
|
||||
<DropdownMenuLabel>{{ m.many_misty_parakeet_fall() }}</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem v-if="authorIsMe" as="button" @click="emit('edit')">
|
||||
<Pencil class="mr-2 size-4" />
|
||||
<span>Edit</span>
|
||||
{{ m.front_lime_grizzly_persist() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="button" @click="copyText(apiNoteString)">
|
||||
<Code class="mr-2 size-4" />
|
||||
<span>Copy API data</span>
|
||||
{{ m.yummy_moving_scallop_sail() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="button" @click="copyText(noteId)">
|
||||
<Hash class="mr-2 size-4" />
|
||||
<span>Copy ID</span>
|
||||
{{ m.sunny_zany_jellyfish_pop() }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem as="button" @click="copyText(url)">
|
||||
<Link class="mr-2 size-4" />
|
||||
<span>Copy link</span>
|
||||
{{ m.ago_new_pelican_drip() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="button" v-if="isRemote" @click="copyText(remoteUrl)">
|
||||
<Link class="mr-2 size-4" />
|
||||
<span>Copy link (origin)</span>
|
||||
{{ m.solid_witty_zebra_walk() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="a" v-if="isRemote" target="_blank" rel="noopener noreferrer" :href="remoteUrl">
|
||||
<ExternalLink class="mr-2 size-4" />
|
||||
<span>Open on remote</span>
|
||||
{{ m.active_trite_lark_inspire() }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator v-if="authorIsMe" />
|
||||
<DropdownMenuGroup v-if="authorIsMe">
|
||||
<DropdownMenuItem as="button" :disabled="true">
|
||||
<Delete class="mr-2 size-4" />
|
||||
<span>Delete and redraft</span>
|
||||
{{ m.real_green_clownfish_pet() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="button" @click="_delete">
|
||||
<Trash class="mr-2 size-4" />
|
||||
<span>Delete</span>
|
||||
{{ m.tense_quick_cod_favor() }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator v-if="loggedIn && !authorIsMe" />
|
||||
<DropdownMenuGroup v-if="loggedIn && !authorIsMe">
|
||||
<DropdownMenuItem as="button" :disabled="true">
|
||||
<Flag class="mr-2 size-4" />
|
||||
<span>Report</span>
|
||||
{{ m.great_few_jaguar_rise() }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as="button" @click="blockUser(authorId)">
|
||||
<Ban class="mr-2 size-4" />
|
||||
<span>Block user</span>
|
||||
{{ m.misty_soft_sparrow_vent() }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import {
|
|||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "~/components/ui/tooltip";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import Note from "../notes/note.vue";
|
||||
import Avatar from "../profiles/avatar.vue";
|
||||
import FollowRequest from "./follow-request.vue";
|
||||
|
|
@ -85,17 +86,17 @@ const icon = computed(() => {
|
|||
const text = computed(() => {
|
||||
switch (notification.type) {
|
||||
case "mention":
|
||||
return "Mentioned you";
|
||||
return m.fuzzy_orange_tuna_succeed();
|
||||
case "reblog":
|
||||
return "Reblogged your note";
|
||||
return m.grand_proof_quail_read();
|
||||
case "follow":
|
||||
return "Followed you";
|
||||
return m.top_steep_scallop_care();
|
||||
case "favourite":
|
||||
return "Liked your note";
|
||||
return m.swift_just_beetle_devour();
|
||||
case "follow_request":
|
||||
return "Requested to follow you";
|
||||
return m.seemly_short_thrush_bloom();
|
||||
case "follow_accept":
|
||||
return "Accepted your follow request";
|
||||
return m.weird_seemly_termite_scold();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
{{ emoji.shortcode }}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
{{ emoji.global ? m.lime_day_squid_pout() : m.witty_heroic_trout_cry() }}
|
||||
{{ emoji.global ? m.real_tame_moose_greet() : m.witty_heroic_trout_cry() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter class="p-0" v-if="canEdit">
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<Card class="grid grid-cols-[1fr,auto] items-center p-6 gap-2">
|
||||
<CardHeader class="space-y-0.5 p-0">
|
||||
<CardTitle class="text-base">
|
||||
{{ setting.title }}
|
||||
{{ setting.title() }}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
{{ setting.description }}
|
||||
{{ setting.description() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter class="p-0">
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="option of setting.options" :value="option.value">
|
||||
{{ option.label }}
|
||||
{{ option.label() }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<Card class="grid grid-cols-[1fr,auto] items-center p-6 gap-2">
|
||||
<CardHeader class="space-y-0.5 p-0">
|
||||
<CardTitle class="text-base">
|
||||
{{ setting.title }}
|
||||
{{ setting.title() }}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
{{ setting.description }}
|
||||
{{ setting.description() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter class="p-0">
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ import {
|
|||
SidebarRail,
|
||||
} from "~/components/ui/sidebar";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { setLanguageTag } from "~/paraglide/runtime";
|
||||
import { type EnumSetting, SettingIds } from "~/settings";
|
||||
import Avatar from "../profiles/avatar.vue";
|
||||
import { Button } from "../ui/button";
|
||||
|
|
@ -128,8 +127,6 @@ import AccountSwitcher from "./account-switcher.vue";
|
|||
|
||||
const sidebarStyle = useSetting(SettingIds.SidebarStyle) as Ref<EnumSetting>;
|
||||
|
||||
setLanguageTag("fr");
|
||||
|
||||
const data = {
|
||||
navMain: [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
<!-- If there are some posts, but the user scrolled to the end -->
|
||||
<Card v-if="hasReachedEnd && items.length > 0" class="shadow-none bg-transparent border-none p-4">
|
||||
<CardHeader class="text-center gap-y-4">
|
||||
<CardTitle class="text-">No more data.</CardTitle>
|
||||
<CardTitle>{{ m.steep_suave_fish_snap() }}</CardTitle>
|
||||
<CardDescription>
|
||||
You've scrolled so far, there's nothing left to show.
|
||||
{{ m.muddy_bland_shark_accept() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
|
@ -28,16 +28,16 @@
|
|||
<!-- If there are no posts at all -->
|
||||
<Card v-else-if="hasReachedEnd && items.length === 0" class="shadow-none bg-transparent border-none p-4">
|
||||
<CardHeader class="text-center gap-y-4">
|
||||
<CardTitle class="text-">There's nothing to show here.</CardTitle>
|
||||
<CardTitle>{{ m.fine_arable_lemming_fold() }}</CardTitle>
|
||||
<CardDescription>
|
||||
Either you're all caught up or there's nothing to show.
|
||||
{{ m.petty_honest_fish_stir() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
||||
<div v-else-if="!infiniteScroll.value" class="py-10 px-4">
|
||||
<Button variant="secondary" @click="loadNext" :disabled="isLoading" class="w-full">
|
||||
Load More
|
||||
{{ m.gaudy_bland_gorilla_talk() }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
|
@ -55,6 +55,7 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { SettingIds } from "~/settings";
|
||||
import { Button } from "../ui/button";
|
||||
import TimelineItem from "./timeline-item.vue";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import type { Client } from "@versia/client";
|
||||
import type { RolePermission } from "@versia/client/types";
|
||||
import { toast } from "vue-sonner";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
export const useCacheRefresh = (client: MaybeRef<Client | null>) => {
|
||||
// Refresh custom emojis and instance data and me on every reload
|
||||
|
|
@ -21,11 +23,8 @@ export const useCacheRefresh = (client: MaybeRef<Client | null>) => {
|
|||
if (code === 401) {
|
||||
// Reset tokenData
|
||||
identity.value = null;
|
||||
useEvent("notification:new", {
|
||||
type: "error",
|
||||
title: "Your session has expired",
|
||||
description:
|
||||
"You have been logged out. Please log in again.",
|
||||
toast.error(m.fancy_this_wasp_renew(), {
|
||||
description: m.real_weird_deer_stop(),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
7
composables/Language.ts
Normal file
7
composables/Language.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { SettingIds } from "~/settings";
|
||||
|
||||
export const useLanguage = () => {
|
||||
const lang = useSetting(SettingIds.Language);
|
||||
|
||||
return computed(() => lang.value.value as "en" | "fr");
|
||||
};
|
||||
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from "~/settings";
|
||||
|
||||
const useSettings = () => {
|
||||
return useLocalStorage<Settings>("versia:settings", settingsJson, {
|
||||
return useLocalStorage<Settings>("versia:settings", settingsJson(), {
|
||||
serializer: {
|
||||
read(raw) {
|
||||
const json = StorageSerializers.object.read(raw);
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
<slot v-if="!route.meta.requiresAuth || identity" />
|
||||
<Card v-else class="shadow-none bg-transparent border-none p-4 max-w-md mx-auto">
|
||||
<CardHeader class="text-center gap-y-4">
|
||||
<CardTitle class="text-">Not signed in</CardTitle>
|
||||
<CardTitle>{{ m.sunny_quick_lionfish_flip() }}</CardTitle>
|
||||
<CardDescription>
|
||||
This page requires you to be authenticated. Please sign in to continue.
|
||||
{{ m.brave_known_pelican_drip() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter>
|
||||
<Button variant="secondary" class="w-full" @click="signInAction">
|
||||
Sign in
|
||||
{{ m.fuzzy_sea_moth_absorb() }}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
|
@ -31,6 +31,7 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const appData = useAppData();
|
||||
const signInAction = () => signIn(appData);
|
||||
|
|
|
|||
222
messages/en.json
222
messages/en.json
|
|
@ -56,10 +56,8 @@
|
|||
"awake_quick_cuckoo_smile": "User followed",
|
||||
"funny_aloof_swan_loop": "Unfollow user",
|
||||
"cute_polite_oryx_blend": "Unfollow",
|
||||
"dirty_inclusive_meerkat_nudge": "Cancel",
|
||||
"big_safe_guppy_mix": "Unfollowing user...",
|
||||
"misty_level_stingray_expand": "User unfollowed",
|
||||
"lime_day_squid_pout": "Global",
|
||||
"witty_heroic_trout_cry": "Uploaded by you",
|
||||
"cuddly_such_swallow_hush": "Rename",
|
||||
"tense_quick_cod_favor": "Delete",
|
||||
|
|
@ -100,7 +98,7 @@
|
|||
"sunny_novel_otter_glow": "Must be at least 3 characters long",
|
||||
"fluffy_soft_wolf_cook": "Email (or username)",
|
||||
"livid_bright_wallaby_quiz": "Password",
|
||||
"fuzzy_sea_moth_absorb": "Sign In",
|
||||
"fuzzy_sea_moth_absorb": "Sign in",
|
||||
"tidy_tidy_cow_cut": "Or continue with",
|
||||
"slow_these_kestrel_sail": "Accept",
|
||||
"weary_steep_yak_embrace": "Reject",
|
||||
|
|
@ -108,5 +106,221 @@
|
|||
"busy_awful_mouse_jump": "Follow request accepted.",
|
||||
"front_sunny_penguin_flip": "Rejecting follow request...",
|
||||
"green_flat_mayfly_trust": "Follow request rejected.",
|
||||
"large_vivid_horse_catch": "reblogged"
|
||||
"large_vivid_horse_catch": "reblogged",
|
||||
"sour_major_baboon_wish": "Copied to clipboard",
|
||||
"top_cute_bison_nudge": "Blocking user...",
|
||||
"main_weary_racoon_peek": "User blocked",
|
||||
"calm_icy_weasel_twirl": "Delete note",
|
||||
"gray_fun_toucan_slide": "Are you sure you want to delete this note?",
|
||||
"royal_best_tern_transform": "Delete",
|
||||
"new_funny_fox_boil": "Deleting note...",
|
||||
"green_tasty_bumblebee_beam": "Note deleted",
|
||||
"many_misty_parakeet_fall": "Note Actions",
|
||||
"front_lime_grizzly_persist": "Edit",
|
||||
"wise_crazy_eel_honor": "Copy API data",
|
||||
"dizzy_alive_wombat_bump": "Copy ID",
|
||||
"slimy_livid_rabbit_belong": "Copy link",
|
||||
"inner_pink_mare_renew": "Copy link (origin)",
|
||||
"calm_fuzzy_thrush_soar": "Open on remote",
|
||||
"real_green_clownfish_pet": " Delete and redraft",
|
||||
"zippy_key_antelope_drop": "Delete",
|
||||
"chunky_dry_gull_sing": "Report",
|
||||
"bald_vexed_firefox_startle": "Block user",
|
||||
"clean_yummy_owl_reside": "Click to copy",
|
||||
"livid_tangy_lionfish_clasp": "Sensitive content",
|
||||
"sour_seemly_bird_hike": "This content is sensitive",
|
||||
"bald_direct_turtle_win": "Show",
|
||||
"known_flaky_cockroach_dash": "Hide",
|
||||
"dirty_sound_skunk_dust": "Show more${plainContent ? ` • ${formattedCharacterCount} characters",
|
||||
"mad_direct_opossum_gleam": "`Show more${plainContent ? ` • ${formattedCharacterCount} characters` : \"\"\n }`",
|
||||
"that_misty_mule_arrive": "Show less",
|
||||
"lazy_honest_mammoth_bump": "Show more",
|
||||
"dark_spare_goldfish_charm": "{count} characters",
|
||||
"drab_tense_turtle_comfort": "Reply",
|
||||
"vexed_fluffy_clownfish_dance": "Unlike",
|
||||
"royal_close_samuel_scold": "Like",
|
||||
"lime_neat_ox_stab": "Unreblog",
|
||||
"aware_helpful_marlin_drop": "Reblog",
|
||||
"true_shy_jackal_drip": "Quote",
|
||||
"busy_merry_cowfish_absorb": "Actions",
|
||||
"slimy_least_ray_aid": "Like note",
|
||||
"stale_new_ray_jolt": "Are you sure you want to like this note?",
|
||||
"slimy_candid_tiger_read": "Liking note...",
|
||||
"mealy_slow_buzzard_commend": "Note liked",
|
||||
"odd_strong_halibut_prosper": "Unlike note",
|
||||
"slow_blue_parrot_savor": "Are you sure you want to unlike this note?",
|
||||
"busy_active_leopard_strive": "Unliking note...",
|
||||
"fresh_direct_bear_affirm": "Note unliked",
|
||||
"best_mellow_llama_surge": "Reblog note",
|
||||
"salty_plain_mallard_gaze": "Are you sure you want to reblog this note?",
|
||||
"late_sunny_cobra_scold": "Reblogging note...",
|
||||
"weird_moving_hawk_lift": "Note reblogged",
|
||||
"main_fancy_octopus_loop": "Unreblog note",
|
||||
"odd_alive_swan_express": "Are you sure you want to unreblog this note?",
|
||||
"white_sharp_gorilla_embrace": "Unreblogging note...",
|
||||
"royal_polite_moose_catch": "Note unreblogged",
|
||||
"mean_mean_badger_inspire": "Value",
|
||||
"antsy_whole_alligator_blink": "Confirm",
|
||||
"game_tough_seal_adore": "Mention someone",
|
||||
"plane_born_koala_hope": "Enable Markdown",
|
||||
"blue_ornate_coyote_tickle": "Insert emoji",
|
||||
"top_patchy_earthworm_vent": "Attach a file",
|
||||
"frail_broad_mallard_dart": "Mark as sensitive",
|
||||
"gaudy_strong_puma_slide": "Save",
|
||||
"free_teal_bulldog_learn": "Send",
|
||||
"last_mean_peacock_zip": "Can be seen by anyone.",
|
||||
"funny_slow_jannes_walk": "Unlisted",
|
||||
"grassy_empty_raven_startle": "Private",
|
||||
"pretty_bold_baboon_wave": "Direct",
|
||||
"grand_strong_gibbon_race": "Can be seen by anyone with the link.",
|
||||
"white_teal_ostrich_yell": "Can only be seen by your followers.",
|
||||
"lucky_mean_robin_link": "Can only be seen by mentioned users.",
|
||||
"wise_late_fireant_walk": "Loading note data...",
|
||||
"loved_busy_mantis_slide": "Reply",
|
||||
"tired_grassy_vulture_forgive": "Reply to this note",
|
||||
"solid_slow_angelfish_pave": "Compose",
|
||||
"livid_livid_nils_snip": "Quote this note",
|
||||
"brief_cool_capybara_fear": "Compose a new note",
|
||||
"chunky_dull_marlin_trip": "Compose",
|
||||
"steep_suave_fish_snap": "No more data.",
|
||||
"muddy_bland_shark_accept": "You've scrolled so far, there's nothing left to show.",
|
||||
"petty_honest_fish_stir": "Either you're all caught up or there's nothing to show.",
|
||||
"fine_arable_lemming_fold": "There's nothing to show here.",
|
||||
"gaudy_bland_gorilla_talk": "Load More",
|
||||
"fancy_this_wasp_renew": "Your session has expired",
|
||||
"real_weird_deer_stop": "You have been logged out. Please log in again.",
|
||||
"sunny_quick_lionfish_flip": "Not signed in",
|
||||
"brave_known_pelican_drip": "This page requires you to be authenticated. Please sign in to continue.",
|
||||
"chunky_awake_mallard_grow": "Note",
|
||||
"steep_sour_warthog_aim": "Loading",
|
||||
"tough_nice_ox_drum": "Profile",
|
||||
"noble_cute_ocelot_aim": "Register",
|
||||
"novel_fine_stork_snap": "Log in to your account.",
|
||||
"smug_main_whale_snip": "Enter your credentials for <code>{host}</code>.",
|
||||
"aware_awful_crow_spur": "Here's your code",
|
||||
"mushy_soft_lizard_propel": "You have signed in successfully.",
|
||||
"short_arable_leopard_zap": "Paste the following code into your app:",
|
||||
"spare_aqua_warthog_mend": "Authorization Code",
|
||||
"fresh_broad_cockroach_radiate": "Authorize “{application}”?",
|
||||
"gross_antsy_kangaroo_succeed": "You are signing in to <b>{application}</b> with your account.",
|
||||
"hour_close_giraffe_mop": "This allows <b>{application}</b> to perform the above actions.",
|
||||
"last_spare_polecat_reside": "Authorize",
|
||||
"lower_factual_frog_evoke": "Authorization",
|
||||
"awake_ago_capybara_kick": "$VERB your account information",
|
||||
"teary_zesty_racoon_transform": "$VERB your block list",
|
||||
"whole_flaky_nuthatch_rush": "$VERB your bookmarks",
|
||||
"still_spicy_lionfish_quell": "$VERB your favourites",
|
||||
"away_mean_dolphin_empower": "$VERB your filters",
|
||||
"sleek_empty_penguin_radiate": "$VERB your follows",
|
||||
"every_silly_racoon_lift": "$VERB your lists",
|
||||
"top_careful_scallop_clip": "$VERB your mutes",
|
||||
"this_short_bulldog_walk": "$VERB your notifications",
|
||||
"fresh_odd_rook_forgive": "Perform searches",
|
||||
"witty_whole_capybara_pull": "$VERB your notes",
|
||||
"agent_warm_javelina_blink": "Edit your conversations",
|
||||
"dirty_red_jellyfish_ascend": "Upload media",
|
||||
"crisp_vivid_seahorse_tend": "Report users",
|
||||
"teary_such_jay_fade": "Read and write",
|
||||
"smug_safe_warthog_dare": "Read",
|
||||
"loose_large_blackbird_peek": "Write",
|
||||
"late_mean_capybara_fade": "Success",
|
||||
"brave_acidic_lobster_fetch": "Your password has been reset. You can now log in with your new password.",
|
||||
"every_tangy_koala_persist": "Back to front page",
|
||||
"good_plane_gazelle_glow": "Your password has been reset by an administrator. Please change it here.",
|
||||
"east_loud_lobster_explore": "Info",
|
||||
"solid_slow_platypus_talk": "Enter your new password below. Make sure to put it in a password manager.",
|
||||
"tired_green_sloth_evoke": "Reset your password",
|
||||
"true_male_gadfly_stab": "New password",
|
||||
"awful_cozy_jannes_rise": "Confirm password",
|
||||
"noisy_round_skate_yell": "Reset",
|
||||
"smart_bold_macaw_aid": "Must be at least {count} characters long",
|
||||
"dry_smug_goldfish_promise": "Must be at most {count} characters long",
|
||||
"candid_fancy_leopard_prosper": "Passwords do not match",
|
||||
"arable_arable_herring_lead": "Reset Password",
|
||||
"broad_whole_herring_reside": "Preferences",
|
||||
"tasty_late_termite_sew": "Account",
|
||||
"actual_mean_cow_dare": "Account Preferences",
|
||||
"suave_smart_mantis_climb": "Emojis",
|
||||
"lucky_suave_myna_adore": "Ask your administrator to add some emojis.",
|
||||
"actual_steep_llama_rest": "No emojis found.",
|
||||
"mild_many_dolphin_mend": "Emoji Preferences",
|
||||
"lucky_ago_rat_pinch": "Uncategorized",
|
||||
"empty_awful_lark_dart": "Account not found.",
|
||||
"clean_even_mayfly_tap": "Check for typos or try again later.",
|
||||
"vexed_each_falcon_enjoy": "Error",
|
||||
"wide_topical_vole_walk": "Create an account",
|
||||
"keen_clean_nils_slurp": "Username",
|
||||
"top_inclusive_wallaby_hack": "Email address",
|
||||
"mad_this_bumblebee_burn": "Password",
|
||||
"happy_house_dragonfly_clap": "Passwords are never stored in plain text.",
|
||||
"early_last_ocelot_praise": "Register",
|
||||
"safe_candid_horse_jump": "Registrations are disabled on this instance.",
|
||||
"wide_away_cat_taste": "Sorry :c",
|
||||
"sea_maroon_peacock_yell": "Must be lowercase letters, numbers, underscores or hyphens",
|
||||
"civil_loose_coyote_jump": "You must agree to the Terms of Service",
|
||||
"plane_quick_chipmunk_rush": "I agree to the",
|
||||
"glad_last_crow_dine": "Terms of Service",
|
||||
"left_maroon_myna_drip": "You've successfully registered. You can now log in with your new account.",
|
||||
"steep_aqua_fox_harbor": "Timelines",
|
||||
"silly_sour_fireant_fear": "Failed to create app",
|
||||
"level_due_ox_greet": "Signing in...",
|
||||
"candid_frail_lion_value": "Failed to generate auth URL",
|
||||
"wide_least_samuel_conquer": "Style of the left sidebar.",
|
||||
"fluffy_north_crow_blink": "Inset",
|
||||
"day_polite_newt_loop": "Sidebar",
|
||||
"jolly_mad_jackdaw_assure": "Floating",
|
||||
"agent_misty_firefox_arise": "Shape of all user avatars.",
|
||||
"polite_awful_ladybug_greet": "Round",
|
||||
"sad_each_cowfish_lock": "Square",
|
||||
"fit_cool_bulldog_dine": "Avatar Shape",
|
||||
"deft_seemly_donkey_slide": "Sidebar Style",
|
||||
"quaint_clear_boar_attend": "Render MFM",
|
||||
"aloof_helpful_larva_spur": "Render Misskey-Flavoured Markdown.",
|
||||
"smart_awake_dachshund_view": "Custom CSS",
|
||||
"loved_topical_rat_coax": "Custom CSS for the UI.",
|
||||
"wise_neat_ox_buzz": "Dark",
|
||||
"each_strong_snail_aid": "Light",
|
||||
"helpful_raw_seal_nurture": "System",
|
||||
"male_stout_florian_feast": "UI theme.",
|
||||
"hour_elegant_mink_grip": "Theme",
|
||||
"loud_raw_sheep_imagine": "Render Custom Emojis",
|
||||
"inclusive_pink_tuna_enjoy": "Render custom emojis. Requires a page reload to apply.",
|
||||
"fair_swift_elephant_hunt": "Blur Sensitive Content",
|
||||
"gray_minor_bee_endure": "Blur notes marked sensitive/spoiler.",
|
||||
"stock_large_marten_comfort": "Background URL",
|
||||
"mean_weird_donkey_stab": "Change the background image of the site.",
|
||||
"tired_jumpy_rook_slurp": "Notifications Sidebar",
|
||||
"wide_new_robin_empower": "Display a sidebar with notifications on desktop.",
|
||||
"less_early_lionfish_honor": "Fluent Emojis (flat version)",
|
||||
"many_tasty_midge_zoom": "Fluent Emojis",
|
||||
"shy_clear_spider_cook": "Noto Emoji",
|
||||
"new_brave_maggot_relish": "Twitter Emojis",
|
||||
"slimy_sound_termite_hug": "Operating System",
|
||||
"warm_round_dove_skip": "Theme used for rendering emojis. Requires a page reload to apply.",
|
||||
"weak_bad_martin_glow": "Emoji Theme",
|
||||
"equal_blue_zebra_launch": "Ctrl+Enter to Send",
|
||||
"heavy_pink_meerkat_affirm": "Send a note by pressing ⌘+Enter or Ctrl+Enter.",
|
||||
"north_nimble_turkey_transform": "Popup Profile Hover",
|
||||
"bold_moving_fly_savor": "Show profile popup when hovering over a user's avatar.",
|
||||
"plane_dark_salmon_pout": "Automatically load more notes when reaching the bottom of the page.",
|
||||
"helpful_early_worm_laugh": "Confirm before deleting a note.",
|
||||
"trite_salty_eel_race": "Confirm Delete",
|
||||
"sleek_this_earthworm_hug": "Infinite Scroll",
|
||||
"jolly_empty_bullock_mend": "Confirm Follow",
|
||||
"cool_tasty_mule_soar": "Confirm before following/unfollowing a user.",
|
||||
"calm_male_wombat_relish": "Confirm before following/unfollowing a user.",
|
||||
"wacky_inner_osprey_intend": "Confirm before reblogging a note.",
|
||||
"honest_great_rooster_taste": "Confirm Reblog",
|
||||
"patchy_basic_alligator_inspire": "Confirm Like",
|
||||
"antsy_weak_raven_treat": "Confirm before liking a note.",
|
||||
"fuzzy_orange_tuna_succeed": "Mentioned you",
|
||||
"grand_proof_quail_read": "Reblogged your note",
|
||||
"top_steep_scallop_care": "Followed you",
|
||||
"swift_just_beetle_devour": "Liked your note",
|
||||
"seemly_short_thrush_bloom": "Requested to follow you",
|
||||
"weird_seemly_termite_scold": "Accepted your follow request",
|
||||
"pretty_born_jackal_dial": "Language",
|
||||
"tired_happy_lobster_pet": "Change the language of the interface. Requires a reload to apply.",
|
||||
"keen_aware_goldfish_thrive": "English",
|
||||
"vivid_mellow_sawfish_approve": "French"
|
||||
}
|
||||
|
|
|
|||
200
messages/fr.json
200
messages/fr.json
|
|
@ -55,10 +55,8 @@
|
|||
"awake_quick_cuckoo_smile": "Utilisateur suivi",
|
||||
"funny_aloof_swan_loop": "Se désabonner",
|
||||
"cute_polite_oryx_blend": "Se désabonner",
|
||||
"dirty_inclusive_meerkat_nudge": "Annuler",
|
||||
"big_safe_guppy_mix": "Désabonnement...",
|
||||
"misty_level_stingray_expand": "Utilisateur désabonné",
|
||||
"lime_day_squid_pout": "Global",
|
||||
"witty_heroic_trout_cry": "Ajouté par vous",
|
||||
"cuddly_such_swallow_hush": "Renommer",
|
||||
"tense_quick_cod_favor": "Supprimer",
|
||||
|
|
@ -105,5 +103,201 @@
|
|||
"busy_awful_mouse_jump": "Demande de suivi acceptée.",
|
||||
"front_sunny_penguin_flip": "Rejet de la demande de suivi...",
|
||||
"green_flat_mayfly_trust": "Demande de suivi rejetée.",
|
||||
"large_vivid_horse_catch": "a reblogué•e"
|
||||
"large_vivid_horse_catch": "a reblogué•e",
|
||||
"top_cute_bison_nudge": "Blocage de l'utilisateur...",
|
||||
"main_weary_racoon_peek": "Utilisateur bloqué",
|
||||
"calm_icy_weasel_twirl": "Supprimer la note",
|
||||
"gray_fun_toucan_slide": "Etes-vous sûr de vouloir supprimer cette note ?",
|
||||
"royal_best_tern_transform": "Supprimer",
|
||||
"new_funny_fox_boil": "Suppression de la note...",
|
||||
"green_tasty_bumblebee_beam": "Note supprimée",
|
||||
"many_misty_parakeet_fall": "Actions sur la note",
|
||||
"front_lime_grizzly_persist": "Modifier",
|
||||
"real_green_clownfish_pet": " Supprimer et reformuler",
|
||||
"clean_yummy_owl_reside": "Cliquez pour copier",
|
||||
"livid_tangy_lionfish_clasp": "Contenu sensible",
|
||||
"sour_seemly_bird_hike": "Ce contenu est sensible",
|
||||
"bald_direct_turtle_win": "Montrer",
|
||||
"known_flaky_cockroach_dash": "Cacher",
|
||||
"that_misty_mule_arrive": "Afficher moins",
|
||||
"lazy_honest_mammoth_bump": "Afficher plus",
|
||||
"dark_spare_goldfish_charm": "{count} caractères",
|
||||
"drab_tense_turtle_comfort": "Répondre",
|
||||
"vexed_fluffy_clownfish_dance": "Dé-aimer",
|
||||
"royal_close_samuel_scold": "Aimer",
|
||||
"lime_neat_ox_stab": "Dé-rebloguer",
|
||||
"aware_helpful_marlin_drop": "Rebloguer",
|
||||
"true_shy_jackal_drip": "Citer",
|
||||
"busy_merry_cowfish_absorb": "Actions",
|
||||
"slimy_least_ray_aid": "Aimer note",
|
||||
"stale_new_ray_jolt": "Etes-vous sûr de vouloir aimer cette note ?",
|
||||
"slimy_candid_tiger_read": "En cours...",
|
||||
"mealy_slow_buzzard_commend": "Note aimé",
|
||||
"odd_strong_halibut_prosper": "Dé-aimer note",
|
||||
"slow_blue_parrot_savor": "Etes-vous sûr de vouloir dé-aimer cette note ?",
|
||||
"busy_active_leopard_strive": "En cours...",
|
||||
"fresh_direct_bear_affirm": "Note dé-aimée",
|
||||
"best_mellow_llama_surge": "Rebloguer note",
|
||||
"salty_plain_mallard_gaze": "Etes-vous sûr de vouloir rebloguer cette note ?",
|
||||
"late_sunny_cobra_scold": "Rebloguage de la note...",
|
||||
"weird_moving_hawk_lift": "Note rebloguée",
|
||||
"main_fancy_octopus_loop": "Dé-rebloguer la note",
|
||||
"odd_alive_swan_express": "Etes-vous sûr de vouloir dé-rebloguer cette note ?",
|
||||
"white_sharp_gorilla_embrace": "Dé-rebloguage de la note...",
|
||||
"royal_polite_moose_catch": "Note dé-rebloguée",
|
||||
"mean_mean_badger_inspire": "Valeur",
|
||||
"antsy_whole_alligator_blink": "Confirmer",
|
||||
"game_tough_seal_adore": "Mentionner quelqu'un",
|
||||
"plane_born_koala_hope": "Activer le Markdown",
|
||||
"blue_ornate_coyote_tickle": "Insérer un emoji",
|
||||
"top_patchy_earthworm_vent": "Joindre un fichier",
|
||||
"frail_broad_mallard_dart": "Marquer comme sensible",
|
||||
"gaudy_strong_puma_slide": "Sauvegarder",
|
||||
"free_teal_bulldog_learn": "Envoyer",
|
||||
"last_mean_peacock_zip": "Peut être vu par tout le monde.",
|
||||
"funny_slow_jannes_walk": "Non répertorié",
|
||||
"grassy_empty_raven_startle": "Privé",
|
||||
"pretty_bold_baboon_wave": "Direct",
|
||||
"grand_strong_gibbon_race": "Peut être vu par toute personne avec le lien.",
|
||||
"white_teal_ostrich_yell": "Ne peut être vu que par vos abonnés.",
|
||||
"lucky_mean_robin_link": "Ne peut être vu que par les utilisateurs mentionnés.",
|
||||
"wise_late_fireant_walk": "Chargement des données de la note...",
|
||||
"loved_busy_mantis_slide": "Répondre",
|
||||
"tired_grassy_vulture_forgive": "Répondre à cette note",
|
||||
"livid_livid_nils_snip": "Citer cette note",
|
||||
"brief_cool_capybara_fear": "Composer une nouvelle note",
|
||||
"chunky_dull_marlin_trip": "Composer",
|
||||
"steep_suave_fish_snap": "Plus de données.",
|
||||
"muddy_bland_shark_accept": "Vous avez tellement défilé•e, qu'il il n'y a plus rien à afficher.",
|
||||
"petty_honest_fish_stir": "Soit vous avez tout rattrapé, soit il n'y a rien à montrer.",
|
||||
"fine_arable_lemming_fold": "Il n'y a rien ici.",
|
||||
"gaudy_bland_gorilla_talk": "Charger plus",
|
||||
"fancy_this_wasp_renew": "Votre session a expirée",
|
||||
"real_weird_deer_stop": "Vous avez été déconnecté•e. Veuillez vous reconnecter.",
|
||||
"sunny_quick_lionfish_flip": "Non connecté•e",
|
||||
"brave_known_pelican_drip": "Cette page nécessite une authentification. Veuillez vous connecter pour continuer.",
|
||||
"chunky_awake_mallard_grow": "Note",
|
||||
"steep_sour_warthog_aim": "Chargement",
|
||||
"tough_nice_ox_drum": "Profil",
|
||||
"noble_cute_ocelot_aim": "Créer un compte",
|
||||
"novel_fine_stork_snap": "Connectez-vous à votre compte.",
|
||||
"smug_main_whale_snip": "Saisissez vos informations d'identification pour <code>{host}</code> .",
|
||||
"aware_awful_crow_spur": "Voici votre code",
|
||||
"mushy_soft_lizard_propel": "Vous vous êtes connecté avec succès.",
|
||||
"short_arable_leopard_zap": "Collez le code suivant dans votre application :",
|
||||
"spare_aqua_warthog_mend": "Code d'autorisation",
|
||||
"fresh_broad_cockroach_radiate": "Autoriser « {application} » ?",
|
||||
"gross_antsy_kangaroo_succeed": "Vous vous connectez à <b>{application}</b> avec votre compte.",
|
||||
"hour_close_giraffe_mop": "Cela permet à <b>{application}</b> d'effectuer les actions listées.",
|
||||
"last_spare_polecat_reside": "Autoriser",
|
||||
"lower_factual_frog_evoke": "Autorisation",
|
||||
"awake_ago_capybara_kick": "$VERB vos informations de compte",
|
||||
"teary_zesty_racoon_transform": "$VERB votre liste de blocage",
|
||||
"whole_flaky_nuthatch_rush": "$VERB vos signets",
|
||||
"still_spicy_lionfish_quell": "$VERB vos favoris",
|
||||
"away_mean_dolphin_empower": "$VERB vos filtres",
|
||||
"sleek_empty_penguin_radiate": "$VERB vos suivis",
|
||||
"every_silly_racoon_lift": "$VERB vos listes",
|
||||
"top_careful_scallop_clip": "$VERB votre liste de mutage",
|
||||
"this_short_bulldog_walk": "$VERB vos notifications",
|
||||
"fresh_odd_rook_forgive": "Effectuer des recherches",
|
||||
"witty_whole_capybara_pull": "$VERB vos notes",
|
||||
"agent_warm_javelina_blink": "Modifier vos conversations",
|
||||
"dirty_red_jellyfish_ascend": "Ajouter des médias",
|
||||
"crisp_vivid_seahorse_tend": "Signaler des utilisateurs",
|
||||
"teary_such_jay_fade": "Lire et modifier",
|
||||
"smug_safe_warthog_dare": "Lire",
|
||||
"loose_large_blackbird_peek": "Modifier",
|
||||
"late_mean_capybara_fade": "Succès",
|
||||
"brave_acidic_lobster_fetch": "Votre mot de passe a été réinitialisé. Vous pouvez désormais vous connecter avec votre nouveau mot de passe.",
|
||||
"every_tangy_koala_persist": "Retour à la page d'accueil",
|
||||
"good_plane_gazelle_glow": "Votre mot de passe a été réinitialisé par un administrateur. Veuillez le modifier ici.",
|
||||
"east_loud_lobster_explore": "Info",
|
||||
"solid_slow_platypus_talk": "Saisissez votre nouveau mot de passe ci-dessous. Assurez-vous de l'enregistrer dans un gestionnaire de mots de passe.",
|
||||
"tired_green_sloth_evoke": "Réinitialisez votre mot de passe",
|
||||
"true_male_gadfly_stab": "Nouveau mot de passe",
|
||||
"awful_cozy_jannes_rise": "Confirmez le mot de passe",
|
||||
"noisy_round_skate_yell": "Réinitialiser",
|
||||
"smart_bold_macaw_aid": "Doit comporter au moins {count} caractères",
|
||||
"dry_smug_goldfish_promise": "Doit comporter au maximum {count} caractères",
|
||||
"candid_fancy_leopard_prosper": "Les mots de passe ne correspondent pas",
|
||||
"arable_arable_herring_lead": "Réinitialiser le mot de passe",
|
||||
"broad_whole_herring_reside": "Préférences",
|
||||
"tasty_late_termite_sew": "Compte",
|
||||
"actual_mean_cow_dare": "Préférences du compte",
|
||||
"suave_smart_mantis_climb": "Émojis",
|
||||
"lucky_suave_myna_adore": "Demandez à votre administrateur d’ajouter des émojis.",
|
||||
"actual_steep_llama_rest": "Aucun emoji trouvé.",
|
||||
"mild_many_dolphin_mend": "Préférences d'emoji",
|
||||
"lucky_ago_rat_pinch": "Non classé",
|
||||
"empty_awful_lark_dart": "Compte non trouvé.",
|
||||
"clean_even_mayfly_tap": "Changez d'utilisateur ou réessayez plus tard.",
|
||||
"early_last_ocelot_praise": "Créer un compte",
|
||||
"dirty_inclusive_meerkat_nudge": "Annuler",
|
||||
"sea_maroon_peacock_yell": "Ne peut contenir que des lettres minuscules, des chiffres, des tirets ou des traits de soulignement",
|
||||
"civil_loose_coyote_jump": "Vous devez accepter les conditions d'utilisation",
|
||||
"plane_quick_chipmunk_rush": "J'accepte les",
|
||||
"glad_last_crow_dine": "Conditions d'Utilisation",
|
||||
"left_maroon_myna_drip": "Vous vous êtes inscrit. Vous pouvez désormais vous connecter avec votre nouveau compte.",
|
||||
"steep_aqua_fox_harbor": "Fils",
|
||||
"silly_sour_fireant_fear": "Échec de la création de l'application",
|
||||
"level_due_ox_greet": "Connexion...",
|
||||
"candid_frail_lion_value": "Échec de la génération de l'URL d'authentification",
|
||||
"wide_least_samuel_conquer": "Style de la barre latérale gauche.",
|
||||
"fluffy_north_crow_blink": "Encart",
|
||||
"day_polite_newt_loop": "Barre latérale",
|
||||
"jolly_mad_jackdaw_assure": "Flottant",
|
||||
"agent_misty_firefox_arise": "Forme de tous les avatars utilisateurs.",
|
||||
"polite_awful_ladybug_greet": "Rond",
|
||||
"sad_each_cowfish_lock": "Carré",
|
||||
"fit_cool_bulldog_dine": "Forme d'avatar",
|
||||
"deft_seemly_donkey_slide": "Style de la barre latérale",
|
||||
"quaint_clear_boar_attend": "Rendu MFM",
|
||||
"aloof_helpful_larva_spur": "Afficher le Misskey-Flavoured Markdown",
|
||||
"smart_awake_dachshund_view": "CSS personnalisé",
|
||||
"loved_topical_rat_coax": "CSS personnalisé, appliqué à l'interface utilisateur.",
|
||||
"wise_neat_ox_buzz": "Sombre",
|
||||
"each_strong_snail_aid": "Clair",
|
||||
"helpful_raw_seal_nurture": "Système",
|
||||
"male_stout_florian_feast": "Thème de l'interface.",
|
||||
"hour_elegant_mink_grip": "Thème",
|
||||
"loud_raw_sheep_imagine": "Afficher les émojis personnalisés",
|
||||
"inclusive_pink_tuna_enjoy": "Afficher les émojis personnalisés. Nécessite un rechargement de la page.",
|
||||
"fair_swift_elephant_hunt": "Flouter les contenus sensibles",
|
||||
"gray_minor_bee_endure": "Floute les notes marquées comme sensibles/spoiler.",
|
||||
"stock_large_marten_comfort": "URL d'arrière-plan",
|
||||
"mean_weird_donkey_stab": "Change l'image d'arrière-plan du site.",
|
||||
"tired_jumpy_rook_slurp": "Barre de notifications",
|
||||
"wide_new_robin_empower": "Affiche une barre latérale avec des notifications.",
|
||||
"less_early_lionfish_honor": "Emojis Fluents (version plate)",
|
||||
"many_tasty_midge_zoom": "Émojis Fluent",
|
||||
"shy_clear_spider_cook": "Émojis Noto",
|
||||
"new_brave_maggot_relish": "Émojis Twitter",
|
||||
"slimy_sound_termite_hug": "Système",
|
||||
"warm_round_dove_skip": "Thème utilisé pour le rendu des émojis. Nécessite un rechargement de la page.",
|
||||
"weak_bad_martin_glow": "Thème Emoji",
|
||||
"equal_blue_zebra_launch": "Ctrl+Entrée pour envoyer",
|
||||
"heavy_pink_meerkat_affirm": "Envoyez une note en appuyant sur ⌘+Entrée ou Ctrl+Entrée.",
|
||||
"north_nimble_turkey_transform": "Popup sur les profils",
|
||||
"bold_moving_fly_savor": "Afficher un popup d'iinformations lorsque vous survolez l'avatar d'un utilisateur.",
|
||||
"plane_dark_salmon_pout": "Charger automatiquement plus de notes lorsque vous atteignez le bas de la page.",
|
||||
"helpful_early_worm_laugh": "Confirmer avant de supprimer une note.",
|
||||
"trite_salty_eel_race": "Confirmer les suppressions",
|
||||
"sleek_this_earthworm_hug": "Défilement infini",
|
||||
"jolly_empty_bullock_mend": "Confirmer suivre",
|
||||
"calm_male_wombat_relish": "Confirmez avant de suivre/ne plus suivre un utilisateur.",
|
||||
"wacky_inner_osprey_intend": "Confirmer avant de rebloguer une note.",
|
||||
"honest_great_rooster_taste": "Confirmer les reblogs",
|
||||
"patchy_basic_alligator_inspire": "Confirmer J'aime",
|
||||
"antsy_weak_raven_treat": "Confirmer avant d'aimer une note.",
|
||||
"fuzzy_orange_tuna_succeed": "Vous a mentionné•e",
|
||||
"grand_proof_quail_read": "A reblogué•e votre note",
|
||||
"top_steep_scallop_care": "Vous a suivi•e",
|
||||
"swift_just_beetle_devour": "A aimé•e votre note",
|
||||
"seemly_short_thrush_bloom": "Fait une demande de suivi",
|
||||
"weird_seemly_termite_scold": "A accepté•e votre demande de suivi",
|
||||
"pretty_born_jackal_dial": "Langue",
|
||||
"tired_happy_lobster_pet": "Changer la langue de l'interface. Nécessite un rechargement.",
|
||||
"keen_aware_goldfish_thrive": "Anglais",
|
||||
"vivid_mellow_sawfish_approve": "Français"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useTitle } from "@vueuse/core";
|
||||
import { Loader } from "lucide-vue-next";
|
||||
import Note from "~/components/notes/note.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Note",
|
||||
text: m.chunky_awake_mallard_grow(),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
@ -57,7 +57,9 @@ watch(
|
|||
|
||||
useSeoMeta({
|
||||
title: computed(() =>
|
||||
note.value ? note.value.account.display_name : "Loading",
|
||||
note.value
|
||||
? note.value.account.display_name
|
||||
: m.steep_sour_warthog_aim(),
|
||||
),
|
||||
description: computed(() => (note.value ? note.value.content : undefined)),
|
||||
ogImage: computed(() =>
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
</TimelineScroller>
|
||||
<Card v-else class="shadow-none bg-transparent border-none p-4">
|
||||
<CardHeader class="text-center gap-y-4">
|
||||
<CardTitle class="text-">Account not found.</CardTitle>
|
||||
<CardTitle>{{ m.empty_awful_lark_dart() }}</CardTitle>
|
||||
<CardDescription>
|
||||
Check for typos or try again later.
|
||||
{{ m.clean_even_mayfly_tap() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
|
@ -23,6 +23,7 @@ import { Loader } from "lucide-vue-next";
|
|||
import AccountProfile from "~/components/profiles/profile.vue";
|
||||
import AccountTimeline from "~/components/timelines/account.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
const route = useRoute();
|
||||
const username = (route.params.username as string).startsWith("@")
|
||||
|
|
@ -33,7 +34,7 @@ definePageMeta({
|
|||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Profile",
|
||||
text: m.tough_nice_ox_drum(),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
@ -43,10 +44,10 @@ const accountId = computed(() => account.value?.id ?? undefined);
|
|||
|
||||
useSeoMeta({
|
||||
title: computed(() =>
|
||||
account.value ? account.value.display_name : "Loading",
|
||||
account.value ? account.value.display_name : m.steep_sour_warthog_aim(),
|
||||
),
|
||||
ogTitle: computed(() =>
|
||||
account.value ? account.value.display_name : "Loading",
|
||||
account.value ? account.value.display_name : m.steep_sour_warthog_aim(),
|
||||
),
|
||||
ogImage: computed(() => (account.value ? account.value.avatar : undefined)),
|
||||
ogType: "profile",
|
||||
|
|
|
|||
|
|
@ -9,19 +9,20 @@
|
|||
<script setup lang="ts">
|
||||
import Global from "~/components/timelines/global.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Global",
|
||||
title: m.real_tame_moose_greet(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Timelines",
|
||||
text: m.steep_aqua_fox_harbor(),
|
||||
},
|
||||
{
|
||||
text: "Global",
|
||||
text: m.real_tame_moose_greet(),
|
||||
href: "/global",
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<script setup lang="ts">
|
||||
import Home from "~/components/timelines/home.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Home",
|
||||
|
|
@ -18,10 +19,10 @@ definePageMeta({
|
|||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Timelines",
|
||||
text: m.steep_aqua_fox_harbor(),
|
||||
},
|
||||
{
|
||||
text: "Home",
|
||||
text: m.bland_chunky_sparrow_propel(),
|
||||
href: "/home",
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -12,24 +12,27 @@
|
|||
import Home from "~/components/timelines/home.vue";
|
||||
import Public from "~/components/timelines/public.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: identity.value ? "Home" : "Public",
|
||||
title: identity.value
|
||||
? m.bland_chunky_sparrow_propel()
|
||||
: m.lost_trick_dog_grace(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Timelines",
|
||||
text: m.steep_aqua_fox_harbor(),
|
||||
},
|
||||
identity.value
|
||||
? {
|
||||
text: "Home",
|
||||
text: m.bland_chunky_sparrow_propel(),
|
||||
href: "/home",
|
||||
}
|
||||
: {
|
||||
text: "Public",
|
||||
text: m.lost_trick_dog_grace(),
|
||||
href: "/public",
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -10,19 +10,20 @@
|
|||
<script lang="ts" setup>
|
||||
import Local from "~/components/timelines/local.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Local",
|
||||
title: m.crazy_game_parrot_pave(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Timelines",
|
||||
text: m.steep_aqua_fox_harbor(),
|
||||
},
|
||||
{
|
||||
text: "Local",
|
||||
text: m.crazy_game_parrot_pave(),
|
||||
href: "/local",
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -22,16 +22,17 @@
|
|||
<script lang="ts" setup>
|
||||
import Notifications from "~/components/timelines/notifications.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Notifications",
|
||||
title: m.that_patchy_mare_snip(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Notifications",
|
||||
text: m.that_patchy_mare_snip(),
|
||||
href: "/notifications",
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ import { AlertCircle, Loader } from "lucide-vue-next";
|
|||
import UserAuthForm from "~/components/oauth/login.vue";
|
||||
import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { NuxtLink } from "#components";
|
||||
|
||||
useHead({
|
||||
title: "Sign In",
|
||||
title: m.fuzzy_sea_moth_absorb(),
|
||||
});
|
||||
|
||||
const host = new URL(useBaseUrl().value).host;
|
||||
|
|
@ -18,7 +19,7 @@ const { error, error_description } = useUrlSearchParams();
|
|||
<template>
|
||||
<div class="container relative flex h-svh flex-col items-center justify-center md:flex-row lg:max-w-none lg:px-0">
|
||||
<Button :as="NuxtLink" href="/register" variant="link" class="absolute right-4 top-4 md:right-8 md:top-8">
|
||||
Register
|
||||
{{ m.noble_cute_ocelot_aim() }}
|
||||
</Button>
|
||||
<div class="relative hidden h-full flex-col bg-muted p-10 text-white dark:border-r lg:flex grow bg-center bg-no-repeat bg-cover"
|
||||
:style="{
|
||||
|
|
@ -55,10 +56,11 @@ const { error, error_description } = useUrlSearchParams();
|
|||
</Alert>
|
||||
<div class="flex flex-col space-y-2 text-center">
|
||||
<h1 class="text-2xl font-semibold tracking-tight">
|
||||
Log in to your account.
|
||||
{{ m.novel_fine_stork_snap() }}
|
||||
</h1>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
Enter your credentials for <code>{{ host }}</code>.
|
||||
<p class="text-sm text-muted-foreground" v-html="m.smug_main_whale_snip({
|
||||
host,
|
||||
})">
|
||||
</p>
|
||||
</div>
|
||||
<UserAuthForm v-if="instance" :instance="instance" />
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
}">
|
||||
<Card class="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Here's your code</CardTitle>
|
||||
<CardDescription>You have signed in successfully.<br />Paste the following code into your app:
|
||||
<CardTitle>{{ m.aware_awful_crow_spur() }}</CardTitle>
|
||||
<CardDescription>{{ m.mushy_soft_lizard_propel() }}<br />{{ m.short_arable_leopard_zap() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent class="grid">
|
||||
|
|
@ -23,9 +23,10 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Authorization Code",
|
||||
title: m.spare_aqua_warthog_mend(),
|
||||
});
|
||||
|
||||
const { code } = useUrlSearchParams();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
<Card class="w-full max-w-md" as="form" method="POST" :action="url.pathname.replace('/oauth/consent', '/oauth/authorize')">
|
||||
<input type="hidden" v-for="([key, value]) in url.searchParams" :key="key" :name="key" :value="value" />
|
||||
<CardHeader>
|
||||
<CardTitle as="h1" class="text-2xl break-words">Authorize “{{ application }}”?</CardTitle>
|
||||
<CardTitle as="h1" class="text-2xl break-words">{{ m.fresh_broad_cockroach_radiate({
|
||||
application: application ?? "",
|
||||
}) }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Card>
|
||||
|
|
@ -23,16 +25,17 @@
|
|||
</li>
|
||||
</ul>
|
||||
<div class="flex-col flex gap-y-1 text-sm">
|
||||
<p>You are signing in to <b>{{ application }}</b> with your
|
||||
account.</p>
|
||||
<p>This allows <b>{{ application }}</b> to perform the above
|
||||
account
|
||||
actions.</p>
|
||||
<p v-html="m.gross_antsy_kangaroo_succeed({
|
||||
application: application ?? '',
|
||||
})"></p>
|
||||
<p v-html="m.hour_close_giraffe_mop({
|
||||
application: application ?? '',
|
||||
})"></p>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter class="grid gap-2">
|
||||
<Button variant="default" type="submit">Authorize</Button>
|
||||
<Button :as="NuxtLink" href="/" variant="secondary">Cancel</Button>
|
||||
<Button variant="default" type="submit">{{ m.last_spare_polecat_reside() }}</Button>
|
||||
<Button :as="NuxtLink" href="/" variant="secondary">{{ m.soft_bold_ant_attend() }}</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
|
|
@ -42,10 +45,11 @@
|
|||
import { Check } from "lucide-vue-next";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { NuxtLink } from "#components";
|
||||
|
||||
useHead({
|
||||
title: "Authorization",
|
||||
title: m.lower_factual_frog_evoke(),
|
||||
});
|
||||
|
||||
const url = useRequestURL();
|
||||
|
|
@ -62,20 +66,20 @@ const scope = params.scope ? decodeURIComponent(params.scope as string) : "";
|
|||
const validUrlParameters = application && redirectUri && clientId && scope;
|
||||
|
||||
const oauthScopeText: Record<string, string> = {
|
||||
"rw:accounts": "$VERB your account information",
|
||||
"rw:blocks": "$VERB your block list",
|
||||
"rw:bookmarks": "$VERB your bookmarks",
|
||||
"rw:favourites": "$VERB your favourites",
|
||||
"rw:filters": "$VERB your filters",
|
||||
"rw:follows": "$VERB your follows",
|
||||
"rw:lists": "$VERB your lists",
|
||||
"rw:mutes": "$VERB your mutes",
|
||||
"rw:notifications": "$VERB your notifications",
|
||||
"r:search": "Perform searches",
|
||||
"rw:statuses": "$VERB your statuses",
|
||||
"w:conversations": "Edit your conversations",
|
||||
"w:media": "Upload media",
|
||||
"w:reports": "Report users",
|
||||
"rw:accounts": m.awake_ago_capybara_kick(),
|
||||
"rw:blocks": m.teary_zesty_racoon_transform(),
|
||||
"rw:bookmarks": m.whole_flaky_nuthatch_rush(),
|
||||
"rw:favourites": m.still_spicy_lionfish_quell(),
|
||||
"rw:filters": m.away_mean_dolphin_empower(),
|
||||
"rw:follows": m.sleek_empty_penguin_radiate(),
|
||||
"rw:lists": m.every_silly_racoon_lift(),
|
||||
"rw:mutes": m.top_careful_scallop_clip(),
|
||||
"rw:notifications": m.this_short_bulldog_walk(),
|
||||
"r:search": m.fresh_odd_rook_forgive(),
|
||||
"rw:statuses": m.witty_whole_capybara_pull(),
|
||||
"w:conversations": m.agent_warm_javelina_blink(),
|
||||
"w:media": m.dirty_red_jellyfish_ascend(),
|
||||
"w:reports": m.crisp_vivid_seahorse_tend(),
|
||||
};
|
||||
|
||||
const scopes = scope.split(" ");
|
||||
|
|
@ -103,7 +107,7 @@ const getScopeText = (fullScopes: string[]) => {
|
|||
) {
|
||||
if (oauthScopeText[possibleScope]?.includes("$VERB")) {
|
||||
scopeTexts.push([
|
||||
"Read and write",
|
||||
m.teary_such_jay_fade(),
|
||||
oauthScopeText[possibleScope]?.replace("$VERB", "") ?? "",
|
||||
]);
|
||||
} else {
|
||||
|
|
@ -119,7 +123,7 @@ const getScopeText = (fullScopes: string[]) => {
|
|||
) {
|
||||
if (oauthScopeText[possibleScope]?.includes("$VERB")) {
|
||||
scopeTexts.push([
|
||||
"Read",
|
||||
m.smug_safe_warthog_dare(),
|
||||
oauthScopeText[possibleScope]?.replace("$VERB", "") ?? "",
|
||||
]);
|
||||
} else {
|
||||
|
|
@ -134,7 +138,7 @@ const getScopeText = (fullScopes: string[]) => {
|
|||
) {
|
||||
if (oauthScopeText[possibleScope]?.includes("$VERB")) {
|
||||
scopeTexts.push([
|
||||
"Write",
|
||||
m.loose_large_blackbird_peek(),
|
||||
oauthScopeText[possibleScope]?.replace("$VERB", "") ?? "",
|
||||
]);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
}">
|
||||
<Card v-if="params.success" class="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Success</CardTitle>
|
||||
<CardTitle>{{ m.late_mean_capybara_fade() }}</CardTitle>
|
||||
<CardDescription>
|
||||
Your password has been reset. You can now log in with your new password.
|
||||
{{ m.brave_acidic_lobster_fetch() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter class="grid">
|
||||
<Button :as="NuxtLink" href="/" variant="default">
|
||||
Back to front page
|
||||
{{ m.every_tangy_koala_persist() }}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
|
@ -20,9 +20,9 @@
|
|||
<CardHeader>
|
||||
<Alert v-if="params.login_reset" variant="default" class="mb-4">
|
||||
<AlertCircle class="size-4" />
|
||||
<AlertTitle>Info</AlertTitle>
|
||||
<AlertTitle>{{ m.east_loud_lobster_explore() }}</AlertTitle>
|
||||
<AlertDescription>
|
||||
Your password has been reset by an administrator. Please change it here.
|
||||
{{ m.good_plane_gazelle_glow() }}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
<Alert v-if="params.error" variant="destructive" class="mb-4">
|
||||
|
|
@ -32,9 +32,9 @@
|
|||
{{ params.error_description }}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
<CardTitle as="h1">Reset your password</CardTitle>
|
||||
<CardTitle as="h1">{{ m.tired_green_sloth_evoke() }}</CardTitle>
|
||||
<CardDescription>
|
||||
Enter your new password below. Make sure to put it in a password manager.
|
||||
{{ m.solid_slow_platypus_talk() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent class="grid gap-6">
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
<FormField v-slot="{ componentField }" name="password">
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
New password
|
||||
{{ m.true_male_gadfly_stab() }}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="hunter2" type="password" auto-capitalize="none" auto-correct="off"
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
<FormField v-slot="{ componentField }" name="password-confirm">
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Confirm password
|
||||
{{ m.awful_cozy_jannes_rise() }}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="hunter2" type="password" auto-capitalize="none" auto-correct="off"
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
</FormField>
|
||||
</CardContent>
|
||||
<CardFooter class="grid gap-2">
|
||||
<Button variant="default" type="submit">Reset</Button>
|
||||
<Button variant="default" type="submit">{{ m.noisy_round_skate_yell() }}</Button>
|
||||
</CardFooter>
|
||||
</form>
|
||||
</Card>
|
||||
|
|
@ -100,10 +100,11 @@ import {
|
|||
FormMessage,
|
||||
} from "~/components/ui/form";
|
||||
import { Input } from "~/components/ui/input";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { NuxtLink } from "#components";
|
||||
|
||||
useHead({
|
||||
title: "Reset Password",
|
||||
title: m.arable_arable_herring_lead(),
|
||||
});
|
||||
|
||||
identity.value = null;
|
||||
|
|
@ -115,18 +116,26 @@ const formSchema = toTypedSchema(
|
|||
password: z
|
||||
.string()
|
||||
.min(3, {
|
||||
message: "Must be at least 3 characters long",
|
||||
message: m.smart_bold_macaw_aid({
|
||||
count: 3,
|
||||
}),
|
||||
})
|
||||
.max(100, {
|
||||
message: "Must be at most 100 characters long",
|
||||
message: m.dry_smug_goldfish_promise({
|
||||
count: 100,
|
||||
}),
|
||||
}),
|
||||
"password-confirm": z
|
||||
.string()
|
||||
.min(3, {
|
||||
message: "Must be at least 3 characters long",
|
||||
message: m.smart_bold_macaw_aid({
|
||||
count: 3,
|
||||
}),
|
||||
})
|
||||
.max(100, {
|
||||
message: "Must be at most 100 characters long",
|
||||
message: m.dry_smug_goldfish_promise({
|
||||
count: 100,
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
|
|
@ -134,7 +143,7 @@ const formSchema = toTypedSchema(
|
|||
ctx.addIssue({
|
||||
path: [...ctx.path, "password-confirm"],
|
||||
code: "custom",
|
||||
message: "Passwords do not match",
|
||||
message: m.candid_fancy_leopard_prosper(),
|
||||
});
|
||||
}
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<script lang="ts" setup>
|
||||
import SelectPreference from "~/components/preferences/select.vue";
|
||||
import SwitchPreference from "~/components/preferences/switch.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import {
|
||||
type BooleanSetting,
|
||||
type EnumSetting,
|
||||
|
|
@ -25,14 +26,14 @@ import {
|
|||
} from "~/settings.ts";
|
||||
|
||||
useHead({
|
||||
title: "Preferences",
|
||||
title: m.broad_whole_herring_reside(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Preferences",
|
||||
text: m.broad_whole_herring_reside(),
|
||||
},
|
||||
],
|
||||
requiresAuth: true,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="md:px-8 px-4 py-2 max-w-7xl mx-auto w-full space-y-6">
|
||||
<div :class="cn('grid gap-2', profileEditor?.dirty && 'grid-cols-[1fr,auto]')">
|
||||
<h1 class="scroll-m-20 text-3xl font-extrabold tracking-tight lg:text-4xl capitalize">
|
||||
Account
|
||||
{{ m.tasty_late_termite_sew() }}
|
||||
</h1>
|
||||
<Button class="ml-auto" v-if="profileEditor?.dirty" @click="profileEditor.submitForm">Save</Button>
|
||||
</div>
|
||||
|
|
@ -17,16 +17,17 @@ import { cn } from "@/lib/utils";
|
|||
// biome-ignore lint/style/useImportType: <explanation>
|
||||
import ProfileEditor from "~/components/preferences/profile/editor.vue";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Account Preferences",
|
||||
title: m.actual_mean_cow_dare(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Preferences",
|
||||
text: m.broad_whole_herring_reside(),
|
||||
},
|
||||
],
|
||||
requiresAuth: true,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="md:px-8 px-4 py-2 max-w-7xl mx-auto w-full space-y-6">
|
||||
<h1 class="scroll-m-20 text-3xl font-extrabold tracking-tight lg:text-4xl capitalize">
|
||||
Emojis
|
||||
{{ m.suave_smart_mantis_climb() }}
|
||||
</h1>
|
||||
<div v-if="emojis.length > 0" class="max-w-sm w-full relative">
|
||||
<Input v-model="search" placeholder="Search" class="pl-8" />
|
||||
|
|
@ -11,9 +11,9 @@
|
|||
:name="name" />
|
||||
<Card v-else class="shadow-none bg-transparent border-none p-4">
|
||||
<CardHeader class="text-center gap-y-4">
|
||||
<CardTitle class="text-">No emojis found.</CardTitle>
|
||||
<CardTitle>{{ m.actual_steep_llama_rest() }}</CardTitle>
|
||||
<CardDescription>
|
||||
Ask your administrator to add some emojis.
|
||||
{{ m.lucky_suave_myna_adore() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
|
@ -24,17 +24,24 @@
|
|||
import type { Emoji } from "@versia/client/types";
|
||||
import { Search } from "lucide-vue-next";
|
||||
import Category from "~/components/preferences/emojis/category.vue";
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import { Input } from "~/components/ui/input";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Emoji Preferences",
|
||||
title: m.mild_many_dolphin_mend(),
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Preferences",
|
||||
text: m.broad_whole_herring_reside(),
|
||||
},
|
||||
],
|
||||
requiresAuth: true,
|
||||
|
|
@ -56,11 +63,11 @@ const categories = computed(() => {
|
|||
const categories = new Map<string, Emoji[]>();
|
||||
for (const emoji of emojis.value) {
|
||||
if (!emoji.category) {
|
||||
if (!categories.has("Uncategorized")) {
|
||||
categories.set("Uncategorized", []);
|
||||
if (!categories.has(m.lucky_ago_rat_pinch())) {
|
||||
categories.set(m.lucky_ago_rat_pinch(), []);
|
||||
}
|
||||
|
||||
categories.get("Uncategorized")?.push(emoji);
|
||||
categories.get(m.lucky_ago_rat_pinch())?.push(emoji);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
definePageMeta({
|
||||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Preferences",
|
||||
text: m.broad_whole_herring_reside(),
|
||||
},
|
||||
],
|
||||
requiresAuth: true,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<script setup lang="ts">
|
||||
import Public from "~/components/timelines/public.vue";
|
||||
import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
useHead({
|
||||
title: "Public",
|
||||
|
|
@ -18,10 +19,10 @@ definePageMeta({
|
|||
layout: "app",
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: "Timelines",
|
||||
text: m.steep_aqua_fox_harbor(),
|
||||
},
|
||||
{
|
||||
text: "Public",
|
||||
text: m.lost_trick_dog_grace(),
|
||||
href: "/public",
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -6,18 +6,18 @@
|
|||
<CardHeader>
|
||||
<Alert v-if="errors.error" variant="destructive" class="mb-4">
|
||||
<AlertCircle class="size-4" />
|
||||
<AlertTitle>Error</AlertTitle>
|
||||
<AlertTitle>{{ m.vexed_each_falcon_enjoy() }}</AlertTitle>
|
||||
<AlertDescription>
|
||||
{{ errors.error }}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
<CardTitle as="h1" class="text-2xl break-words">Create an account</CardTitle>
|
||||
<CardTitle as="h1" class="text-2xl break-words">{{ m.wide_topical_vole_walk() }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent v-if="instance && tos" class="grid gap-6">
|
||||
<FormField v-slot="{ componentField }" name="username">
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Username
|
||||
{{ m.keen_clean_nils_slurp() }}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="petergriffin" type="text" auto-capitalize="none"
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
<FormField v-slot="{ componentField }" name="email">
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Email address
|
||||
{{ m.top_inclusive_wallaby_hack() }}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="peter.griffin@fox.com" type="email" auto-capitalize="none"
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
<FormField v-slot="{ componentField }" name="password">
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Password
|
||||
{{ m.livid_bright_wallaby_quiz() }}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="hunter2" type="password" auto-capitalize="none" auto-complete="password"
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
<FormField v-slot="{ componentField }" name="password-confirm">
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Confirm password
|
||||
{{ m.awful_cozy_jannes_rise() }}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="hunter2" type="password" auto-capitalize="none" auto-complete="password"
|
||||
|
|
@ -72,8 +72,8 @@
|
|||
</FormControl>
|
||||
<FormLabel>
|
||||
<Dialog>
|
||||
I agree to the <DialogTrigger :as-child="true"><Button variant="link"
|
||||
class="px-0 underline">Terms of Service</Button>.</DialogTrigger>
|
||||
{{ m.plane_quick_chipmunk_rush() }} <DialogTrigger :as-child="true"><Button variant="link"
|
||||
class="px-0 underline">{{ m.glad_last_crow_dine() }}</Button>.</DialogTrigger>
|
||||
<DialogContent class="!max-h-[90vh] overflow-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{{ instance.title }}
|
||||
|
|
@ -88,11 +88,11 @@
|
|||
</FormItem>
|
||||
</FormField>
|
||||
<div class="flex-col flex gap-y-1 text-sm text-muted-foreground">
|
||||
<p>Passwords are never stored in plain text.</p>
|
||||
<p>{{ m.happy_house_dragonfly_clap() }}</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter v-if="instance && tos" class="grid gap-2">
|
||||
<Button variant="default" type="submit">Register</Button>
|
||||
<Button variant="default" type="submit">{{ m.early_last_ocelot_praise() }}</Button>
|
||||
</CardFooter>
|
||||
<div v-else class="p-4 flex items-center justify-center h-48">
|
||||
<Loader class="size-8 animate-spin" />
|
||||
|
|
@ -100,14 +100,14 @@
|
|||
</Card>
|
||||
<Card v-else class="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Sorry :c</CardTitle>
|
||||
<CardTitle>{{ m.wide_away_cat_taste() }}</CardTitle>
|
||||
<CardDescription>
|
||||
Registrations are disabled on this instance.
|
||||
{{ m.safe_candid_horse_jump() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter class="grid">
|
||||
<Button :as="NuxtLink" href="/" variant="default">
|
||||
Back to front page
|
||||
{{ m.every_tangy_koala_persist() }}}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
|
@ -117,7 +117,7 @@
|
|||
<script setup lang="ts">
|
||||
import { toTypedSchema } from "@vee-validate/zod";
|
||||
import { Client, type ResponseError } from "@versia/client";
|
||||
import { AlertCircle, Check, Loader } from "lucide-vue-next";
|
||||
import { AlertCircle, Loader } from "lucide-vue-next";
|
||||
import { useForm } from "vee-validate";
|
||||
import { z } from "zod";
|
||||
import { Button } from "~/components/ui/button";
|
||||
|
|
@ -126,10 +126,11 @@ import { Checkbox } from "~/components/ui/checkbox";
|
|||
import { Dialog, DialogContent, DialogHeader } from "~/components/ui/dialog";
|
||||
import { FormItem } from "~/components/ui/form";
|
||||
import { Input } from "~/components/ui/input";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { NuxtLink } from "#components";
|
||||
|
||||
useHead({
|
||||
title: "Register",
|
||||
title: m.early_last_ocelot_praise(),
|
||||
});
|
||||
|
||||
const schema = toTypedSchema(
|
||||
|
|
@ -141,13 +142,10 @@ const schema = toTypedSchema(
|
|||
username: z
|
||||
.string()
|
||||
.min(3)
|
||||
.regex(
|
||||
/^[a-z0-9_]+$/,
|
||||
"Must be lowercase letters, numbers, or underscores",
|
||||
),
|
||||
.regex(/^[a-z0-9_-]+$/, m.sea_maroon_peacock_yell()),
|
||||
reason: z.string().optional(),
|
||||
tos: z.boolean().refine((value) => value, {
|
||||
message: "You must agree to the Terms of Service",
|
||||
message: m.civil_loose_coyote_jump(),
|
||||
}),
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
|
|
@ -155,7 +153,7 @@ const schema = toTypedSchema(
|
|||
ctx.addIssue({
|
||||
path: [...ctx.path, "password-confirm"],
|
||||
code: "custom",
|
||||
message: "Passwords do not match",
|
||||
message: m.candid_fancy_leopard_prosper(),
|
||||
});
|
||||
}
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
}">
|
||||
<Card class="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Success</CardTitle>
|
||||
<CardTitle>{{ m.late_mean_capybara_fade() }}</CardTitle>
|
||||
<CardDescription>
|
||||
You've successfully registered. You can now log in with your new account.
|
||||
{{ m.left_maroon_myna_drip() }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter class="grid">
|
||||
<Button :as="NuxtLink" href="/" variant="default">
|
||||
Back to front page
|
||||
{{ m.every_tangy_koala_persist() }}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardFooter, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
import { NuxtLink } from "#components";
|
||||
|
||||
useHead({
|
||||
|
|
|
|||
417
settings.ts
417
settings.ts
|
|
@ -1,3 +1,6 @@
|
|||
import * as m from "~/paraglide/messages.js";
|
||||
import { setLanguageTag } from "./paraglide/runtime";
|
||||
|
||||
export enum SettingType {
|
||||
String = "string",
|
||||
Boolean = "boolean",
|
||||
|
|
@ -8,8 +11,8 @@ export enum SettingType {
|
|||
}
|
||||
|
||||
export type Setting = {
|
||||
title: string;
|
||||
description: string;
|
||||
title: () => string;
|
||||
description: () => string;
|
||||
notImplemented?: boolean;
|
||||
type: SettingType;
|
||||
value: unknown;
|
||||
|
|
@ -31,7 +34,7 @@ export type EnumSetting = Setting & {
|
|||
value: string;
|
||||
options: {
|
||||
value: string;
|
||||
label: string;
|
||||
label: () => string;
|
||||
icon?: string;
|
||||
}[];
|
||||
};
|
||||
|
|
@ -66,6 +69,7 @@ export enum SettingPages {
|
|||
}
|
||||
|
||||
export enum SettingIds {
|
||||
Language = "language",
|
||||
Mfm = "mfm",
|
||||
CustomCSS = "custom-css",
|
||||
Theme = "theme",
|
||||
|
|
@ -85,195 +89,226 @@ export enum SettingIds {
|
|||
SidebarStyle = "sidebar-style",
|
||||
}
|
||||
|
||||
export const settings: Record<SettingIds, Setting> = {
|
||||
[SettingIds.Mfm]: {
|
||||
title: "Render MFM",
|
||||
description: "Render Misskey-Flavoured Markdown.",
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
notImplemented: true,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.SidebarStyle]: {
|
||||
title: "Sidebar Style",
|
||||
description: "Style of the left sidebar.",
|
||||
type: SettingType.Enum,
|
||||
value: "inset",
|
||||
options: [
|
||||
{
|
||||
value: "inset",
|
||||
label: "Inset",
|
||||
},
|
||||
{
|
||||
value: "sidebar",
|
||||
label: "Sidebar",
|
||||
},
|
||||
{
|
||||
value: "floating",
|
||||
label: "Floating",
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.AvatarShape]: {
|
||||
title: "Avatar Shape",
|
||||
description: "Shape of all user avatars.",
|
||||
type: SettingType.Enum,
|
||||
value: "square",
|
||||
options: [
|
||||
{
|
||||
value: "circle",
|
||||
label: "Round",
|
||||
},
|
||||
{
|
||||
value: "square",
|
||||
label: "Square",
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.CustomCSS]: {
|
||||
title: "Custom CSS",
|
||||
description: "Custom CSS for the UI.",
|
||||
type: SettingType.Code,
|
||||
value: "",
|
||||
language: "css",
|
||||
page: SettingPages.Appearance,
|
||||
} as CodeSetting,
|
||||
[SettingIds.Theme]: {
|
||||
title: "Theme",
|
||||
description: "UI theme.",
|
||||
type: SettingType.Enum,
|
||||
value: "dark",
|
||||
options: [
|
||||
{
|
||||
value: "dark",
|
||||
label: "Dark",
|
||||
},
|
||||
{
|
||||
value: "light",
|
||||
label: "Light",
|
||||
},
|
||||
{
|
||||
value: "system",
|
||||
label: "System",
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.CustomEmojis]: {
|
||||
title: "Render Custom Emojis",
|
||||
description: "Render custom emojis. Requires a page reload to apply.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ShowContentWarning]: {
|
||||
title: "Blur Sensitive Content",
|
||||
description: "Blur notes marked sensitive/spoiler.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.PopupAvatarHover]: {
|
||||
title: "Popup Profile Hover",
|
||||
description: "Show profile popup when hovering over a user's avatar.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.InfiniteScroll]: {
|
||||
title: "Infinite Scroll",
|
||||
description:
|
||||
"Automatically load more notes when reaching the bottom of the page.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmDelete]: {
|
||||
title: "Confirm Delete",
|
||||
description: "Confirm before deleting a note.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmFollow]: {
|
||||
title: "Confirm Follow",
|
||||
description: "Confirm before following/unfollowing a user.",
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmReblog]: {
|
||||
title: "Confirm Reblog",
|
||||
description: "Confirm before reblogging a note.",
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmLike]: {
|
||||
title: "Confirm Like",
|
||||
description: "Confirm before liking a note.",
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.CtrlEnterToSend]: {
|
||||
title: "Ctrl+Enter to Send",
|
||||
description: "Send a note by pressing ⌘+Enter or Ctrl+Enter.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.EmojiTheme]: {
|
||||
title: "Emoji Theme",
|
||||
description:
|
||||
"Theme used for rendering emojis. Requires a page reload to apply.",
|
||||
type: SettingType.Enum,
|
||||
value: "native",
|
||||
options: [
|
||||
{
|
||||
value: "native",
|
||||
label: "Operating System",
|
||||
},
|
||||
{
|
||||
value: "twemoji",
|
||||
label: "Twitter Emojis",
|
||||
},
|
||||
{
|
||||
value: "noto",
|
||||
label: "Noto Emoji",
|
||||
},
|
||||
{
|
||||
value: "fluent",
|
||||
label: "Fluent Emojis",
|
||||
},
|
||||
{
|
||||
value: "fluent-flat",
|
||||
label: "Fluent Emojis (flat version)",
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.BackgroundURL]: {
|
||||
title: "Background URL",
|
||||
description: "Change the background image of the site.",
|
||||
type: SettingType.String,
|
||||
value: "",
|
||||
page: SettingPages.Appearance,
|
||||
} as StringSetting,
|
||||
[SettingIds.NotificationsSidebar]: {
|
||||
title: "Notifications Sidebar",
|
||||
description: "Display a sidebar with notifications on desktop.",
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Appearance,
|
||||
} as BooleanSetting,
|
||||
export const settings = (): Record<SettingIds, Setting> => {
|
||||
return {
|
||||
[SettingIds.Mfm]: {
|
||||
title: m.quaint_clear_boar_attend,
|
||||
description: m.aloof_helpful_larva_spur,
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
notImplemented: true,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.Language]: {
|
||||
title: m.pretty_born_jackal_dial,
|
||||
description: m.tired_happy_lobster_pet,
|
||||
type: SettingType.Enum,
|
||||
value: "en",
|
||||
options: [
|
||||
{
|
||||
value: "en",
|
||||
label: () =>
|
||||
m.keen_aware_goldfish_thrive(
|
||||
{},
|
||||
{
|
||||
languageTag: "en",
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
value: "fr",
|
||||
label: () =>
|
||||
m.vivid_mellow_sawfish_approve(
|
||||
{},
|
||||
{
|
||||
languageTag: "fr",
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
page: SettingPages.Behaviour,
|
||||
} as EnumSetting,
|
||||
[SettingIds.SidebarStyle]: {
|
||||
title: m.deft_seemly_donkey_slide,
|
||||
description: m.wide_least_samuel_conquer,
|
||||
type: SettingType.Enum,
|
||||
value: "inset",
|
||||
options: [
|
||||
{
|
||||
value: "inset",
|
||||
label: m.fluffy_north_crow_blink,
|
||||
},
|
||||
{
|
||||
value: "sidebar",
|
||||
label: m.day_polite_newt_loop,
|
||||
},
|
||||
{
|
||||
value: "floating",
|
||||
label: m.jolly_mad_jackdaw_assure,
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.AvatarShape]: {
|
||||
title: m.fit_cool_bulldog_dine,
|
||||
description: m.agent_misty_firefox_arise,
|
||||
type: SettingType.Enum,
|
||||
value: "square",
|
||||
options: [
|
||||
{
|
||||
value: "circle",
|
||||
label: m.polite_awful_ladybug_greet,
|
||||
},
|
||||
{
|
||||
value: "square",
|
||||
label: m.sad_each_cowfish_lock,
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.CustomCSS]: {
|
||||
title: m.smart_awake_dachshund_view,
|
||||
description: m.loved_topical_rat_coax,
|
||||
type: SettingType.Code,
|
||||
value: "",
|
||||
language: "css",
|
||||
page: SettingPages.Appearance,
|
||||
} as CodeSetting,
|
||||
[SettingIds.Theme]: {
|
||||
title: m.hour_elegant_mink_grip,
|
||||
description: m.male_stout_florian_feast,
|
||||
type: SettingType.Enum,
|
||||
value: "dark",
|
||||
options: [
|
||||
{
|
||||
value: "dark",
|
||||
label: m.wise_neat_ox_buzz,
|
||||
},
|
||||
{
|
||||
value: "light",
|
||||
label: m.each_strong_snail_aid,
|
||||
},
|
||||
{
|
||||
value: "system",
|
||||
label: m.helpful_raw_seal_nurture,
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.CustomEmojis]: {
|
||||
title: m.loud_raw_sheep_imagine,
|
||||
description: m.inclusive_pink_tuna_enjoy,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ShowContentWarning]: {
|
||||
title: m.fair_swift_elephant_hunt,
|
||||
description: m.gray_minor_bee_endure,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.PopupAvatarHover]: {
|
||||
title: m.north_nimble_turkey_transform,
|
||||
description: m.bold_moving_fly_savor,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.InfiniteScroll]: {
|
||||
title: m.sleek_this_earthworm_hug,
|
||||
description: m.plane_dark_salmon_pout,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmDelete]: {
|
||||
title: m.trite_salty_eel_race,
|
||||
description: m.helpful_early_worm_laugh,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmFollow]: {
|
||||
title: m.jolly_empty_bullock_mend,
|
||||
description: m.calm_male_wombat_relish,
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmReblog]: {
|
||||
title: m.honest_great_rooster_taste,
|
||||
description: m.wacky_inner_osprey_intend,
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.ConfirmLike]: {
|
||||
title: m.patchy_basic_alligator_inspire,
|
||||
description: m.antsy_weak_raven_treat,
|
||||
type: SettingType.Boolean,
|
||||
value: false,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.CtrlEnterToSend]: {
|
||||
title: m.equal_blue_zebra_launch,
|
||||
description: m.heavy_pink_meerkat_affirm,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Behaviour,
|
||||
} as BooleanSetting,
|
||||
[SettingIds.EmojiTheme]: {
|
||||
title: m.weak_bad_martin_glow,
|
||||
description: m.warm_round_dove_skip,
|
||||
type: SettingType.Enum,
|
||||
value: "native",
|
||||
options: [
|
||||
{
|
||||
value: "native",
|
||||
label: m.slimy_sound_termite_hug,
|
||||
},
|
||||
{
|
||||
value: "twemoji",
|
||||
label: m.new_brave_maggot_relish,
|
||||
},
|
||||
{
|
||||
value: "noto",
|
||||
label: m.shy_clear_spider_cook,
|
||||
},
|
||||
{
|
||||
value: "fluent",
|
||||
label: m.many_tasty_midge_zoom,
|
||||
},
|
||||
{
|
||||
value: "fluent-flat",
|
||||
label: m.less_early_lionfish_honor,
|
||||
},
|
||||
],
|
||||
page: SettingPages.Appearance,
|
||||
} as EnumSetting,
|
||||
[SettingIds.BackgroundURL]: {
|
||||
title: m.stock_large_marten_comfort,
|
||||
description: m.mean_weird_donkey_stab,
|
||||
type: SettingType.String,
|
||||
value: "",
|
||||
page: SettingPages.Appearance,
|
||||
} as StringSetting,
|
||||
[SettingIds.NotificationsSidebar]: {
|
||||
title: m.tired_jumpy_rook_slurp,
|
||||
description: m.wide_new_robin_empower,
|
||||
type: SettingType.Boolean,
|
||||
value: true,
|
||||
page: SettingPages.Appearance,
|
||||
} as BooleanSetting,
|
||||
};
|
||||
};
|
||||
|
||||
export const getSettingsForPage = (page: SettingPages): Partial<Settings> => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(settings).filter(([, setting]) => setting.page === page),
|
||||
Object.entries(settings()).filter(
|
||||
([, setting]) => setting.page === page,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -284,14 +319,14 @@ export const getSettingsForPage = (page: SettingPages): Partial<Settings> => {
|
|||
export const mergeSettings = (
|
||||
settingsToMerge: Record<SettingIds, Setting["value"]>,
|
||||
): Settings => {
|
||||
const finalSettings = structuredClone(settings);
|
||||
const finalSettings = settings();
|
||||
|
||||
for (const [key, value] of Object.entries(settingsToMerge)) {
|
||||
if (key in settings) {
|
||||
if (key in settings()) {
|
||||
finalSettings[key as SettingIds].value = value;
|
||||
}
|
||||
}
|
||||
|
||||
return finalSettings;
|
||||
};
|
||||
export type Settings = typeof settings;
|
||||
export type Settings = ReturnType<typeof settings>;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import type { ApplicationData } from "@versia/client/types";
|
||||
import { nanoid } from "nanoid";
|
||||
import { toast } from "vue-sonner";
|
||||
import * as m from "~/paraglide/messages.js";
|
||||
|
||||
export const signIn = async (appData: Ref<ApplicationData | null>) => {
|
||||
const id = toast.loading("Signing in...");
|
||||
const id = toast.loading(m.level_due_ox_greet());
|
||||
|
||||
const output = await client.value.createApp("Versia", {
|
||||
scopes: ["read", "write", "follow", "push"],
|
||||
|
|
@ -13,7 +14,7 @@ export const signIn = async (appData: Ref<ApplicationData | null>) => {
|
|||
|
||||
if (!output?.data) {
|
||||
toast.dismiss(id);
|
||||
toast.error("Failed to create app");
|
||||
toast.error(m.silly_sour_fireant_fear());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ export const signIn = async (appData: Ref<ApplicationData | null>) => {
|
|||
|
||||
if (!url) {
|
||||
toast.dismiss(id);
|
||||
toast.error("Failed to generate auth URL");
|
||||
toast.error(m.candid_frail_lion_value());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue