feat(frontend): analytics panel and online statuses speak russian and english with real plurals
This commit is contained in:
1 parent
543e6eaa50
commit
cff493f5dd
9 files changed
+286
-190
No files matched your search
@@ -5,6 +5,7 @@
|
||||
import Spinner from "#lib/components/ui/Spinner.svelte";
|
||||
import { formatLongDay, formatTime } from "#lib/format/datetime.js";
|
||||
import { formatSpan } from "#lib/format/presence.js";
|
||||
import { t } from "#lib/i18n/locale.svelte.js";
|
||||
|
||||
interface Props {
|
||||
days: number;
|
||||
@@ -16,18 +17,6 @@
|
||||
|
||||
const { days, first, pageSize, peerId, tz }: Props = $props();
|
||||
|
||||
const TEXT = {
|
||||
failed: "Не удалось загрузить сессии.",
|
||||
more: "Показать ещё",
|
||||
none: "За этот период в сети не был(а).",
|
||||
now: "в сети",
|
||||
retry: "Повторить",
|
||||
since: (time: string) => `с ${time}`,
|
||||
span: (from: string, to: string) => (from === to ? from : `${from}–${to}`),
|
||||
today: "Сегодня",
|
||||
yesterday: "Вчера",
|
||||
};
|
||||
|
||||
const MS_IN_DAY = 86_400_000;
|
||||
|
||||
let extra = $state<PresenceSession[]>([]);
|
||||
@@ -54,18 +43,22 @@
|
||||
function dayLabel(date: Date): string {
|
||||
const today = new Date();
|
||||
if (date.toDateString() === today.toDateString()) {
|
||||
return TEXT.today;
|
||||
return t("presence.today");
|
||||
}
|
||||
if (
|
||||
date.toDateString() ===
|
||||
new Date(today.getTime() - MS_IN_DAY).toDateString()
|
||||
) {
|
||||
return TEXT.yesterday;
|
||||
return t("presence.yesterday");
|
||||
}
|
||||
const text = formatLongDay(date);
|
||||
return text.charAt(0).toUpperCase() + text.slice(1);
|
||||
}
|
||||
|
||||
function span(from: string, to: string): string {
|
||||
return from === to ? from : `${from}–${to}`;
|
||||
}
|
||||
|
||||
async function loadMore() {
|
||||
if (loading) {
|
||||
return;
|
||||
@@ -92,7 +85,7 @@
|
||||
</script>
|
||||
|
||||
{#if sessions.length === 0}
|
||||
<p class="state">{TEXT.none}</p>
|
||||
<p class="state">{t("presence.noSessions")}</p>
|
||||
{:else}
|
||||
{#each groups as group (group.label)}
|
||||
<h4 class="day">{group.label}</h4>
|
||||
@@ -101,14 +94,13 @@
|
||||
<li>
|
||||
<span>
|
||||
{session.ongoing
|
||||
? TEXT.since(formatTime(session.started))
|
||||
: TEXT.span(
|
||||
formatTime(session.started),
|
||||
formatTime(session.ended)
|
||||
)}
|
||||
? t("presence.since", { time: formatTime(session.started) })
|
||||
: span(formatTime(session.started), formatTime(session.ended))}
|
||||
</span>
|
||||
<span class={["length", { online: session.ongoing }]}>
|
||||
{session.ongoing ? TEXT.now : formatSpan(session.seconds)}
|
||||
{session.ongoing
|
||||
? t("presence.online")
|
||||
: formatSpan(session.seconds)}
|
||||
</span>
|
||||
</li>
|
||||
{/each}
|
||||
@@ -118,11 +110,13 @@
|
||||
<div class="state"><Spinner /></div>
|
||||
{:else if failed}
|
||||
<div class="state">
|
||||
<p>{TEXT.failed}</p>
|
||||
<Button onclick={loadMore} smaller variant="text">{TEXT.retry}</Button>
|
||||
<p>{t("presence.sessionsFailed")}</p>
|
||||
<Button onclick={loadMore} smaller variant="text">{t("ui.retry")}</Button>
|
||||
</div>
|
||||
{:else if !exhausted}
|
||||
<button class="more" onclick={loadMore} type="button">{TEXT.more}</button>
|
||||
<button class="more" onclick={loadMore} type="button">
|
||||
{t("ui.showMore")}
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
||||
Reference in new issue
Block a user