Fixed tweaks and mods, added localization, added antivirus walkthrough

This commit is contained in:
OctoWoW
2026-06-28 18:47:47 +00:00
parent c2f7b7d6e4
commit 1047a90704
51 changed files with 3426 additions and 938 deletions
+16 -9
View File
@@ -2,6 +2,7 @@ import { AlertTriangle, ExternalLink, RefreshCw } from 'lucide-react';
import { type NewsItem } from '~main/types';
import { api } from '~renderer/utils/api';
import { useT } from '~renderer/i18n';
import useScrollHint from '~renderer/utils/useScrollHint';
import IconSpinner from '../styled/IconSpinner';
@@ -18,15 +19,20 @@ const formatDate = (raw: string) => {
};
const NewsEntry = ({ item }: { item: NewsItem }) => {
const t = useT();
const openLink = api.general.openLink.useMutation();
return (
<article className="flex flex-col gap-1 border-b border-blueGray/30 pb-3 last:border-0">
<div className="flex items-baseline justify-between gap-3">
<h5 className="tw-color">{item.title}</h5>
<span className="s1 shrink-0 text-blueGray">{formatDate(item.date)}</span>
<span className="s1 shrink-0 text-blueGray">
{formatDate(item.date)}
</span>
</div>
{item.author && (
<span className="s1 italic text-blueGray">by {item.author}</span>
<span className="s1 italic text-blueGray">
{t('misc.newsByAuthor', { author: item.author })}
</span>
)}
<p className="whitespace-pre-wrap text-sm leading-relaxed">{item.body}</p>
{item.url && (
@@ -36,7 +42,7 @@ const NewsEntry = ({ item }: { item: NewsItem }) => {
className="-ml-2 self-start text-pink"
onClick={() => openLink.mutateAsync(item.url!)}
>
Read more
{t('misc.newsReadMore')}
</TextButton>
)}
</article>
@@ -44,6 +50,7 @@ const NewsEntry = ({ item }: { item: NewsItem }) => {
};
const NewsTab = () => {
const t = useT();
const query = api.news.list.useQuery(undefined, {
staleTime: 5 * 60 * 1000,
refetchOnWindowFocus: false,
@@ -54,14 +61,14 @@ const NewsTab = () => {
return (
<div className="tw-surface flex min-h-0 flex-grow flex-col gap-3">
<div className="flex items-center justify-between">
<h4 className="tw-color">News</h4>
<h4 className="tw-color">{t('misc.newsTitle')}</h4>
<TextButton
icon={RefreshCw}
size={18}
className="-mr-2 text-blueGray"
loading={query.isFetching}
onClick={() => query.refetch()}
title="Refresh"
title={t('misc.refresh')}
/>
</div>
<hr />
@@ -72,24 +79,24 @@ const NewsTab = () => {
{query.isLoading ? (
<div className="flex flex-grow flex-col items-center justify-center gap-2">
<IconSpinner className="text-blueGray" />
<p className="italic text-blueGray">Loading news...</p>
<p className="italic text-blueGray">{t('misc.newsLoading')}</p>
</div>
) : query.isError ? (
<div className="flex flex-grow flex-col items-center justify-center gap-3">
<AlertTriangle size={32} className="text-red" />
<p className="italic text-blueGray">Couldn't reach the news feed.</p>
<p className="italic text-blueGray">{t('misc.newsError')}</p>
<TextButton
icon={RefreshCw}
size={18}
className="text-pink"
onClick={() => query.refetch()}
>
Try again
{t('misc.tryAgain')}
</TextButton>
</div>
) : !query.data?.length ? (
<div className="flex flex-grow flex-col items-center justify-center">
<p className="italic text-blueGray">No news yet check back later.</p>
<p className="italic text-blueGray">{t('misc.newsEmpty')}</p>
</div>
) : (
query.data.map(item => <NewsEntry key={item.id} item={item} />)