mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-17 05:54:19 +01:00
feat: update translation
This commit is contained in:
@@ -6,9 +6,9 @@
|
|||||||
<title>Rabbit</title>
|
<title>Rabbit</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>お探しのページは見つかりませんでした</h1>
|
<h1>Page not found</h1>
|
||||||
<p>
|
<p>
|
||||||
<a href="/rabbit/">トップに戻る</a>
|
<a href="/">Jump into rabbit hole</a>
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ const queryClient = new QueryClient({});
|
|||||||
|
|
||||||
const i18next = i18nextInstance();
|
const i18next = i18nextInstance();
|
||||||
|
|
||||||
|
const permalinkFilters = {
|
||||||
|
id: /^npub1[ac-hj-np-z02-9]+$/,
|
||||||
|
};
|
||||||
|
|
||||||
const indexedDBPersister = createAsyncStoragePersister({
|
const indexedDBPersister = createAsyncStoragePersister({
|
||||||
storage: {
|
storage: {
|
||||||
getItem(key: string) {
|
getItem(key: string) {
|
||||||
@@ -64,7 +68,7 @@ const App: Component = () => {
|
|||||||
<HashRouter>
|
<HashRouter>
|
||||||
<Route path="/hello" component={() => <Navigate href="/" />} />
|
<Route path="/hello" component={() => <Navigate href="/" />} />
|
||||||
<Route path="/" component={() => <EntryPoint />} />
|
<Route path="/" component={() => <EntryPoint />} />
|
||||||
<Route path="/:id" component={() => <Permalink />} />
|
<Route path="/:id" component={() => <Permalink />} matchFilters={permalinkFilters} />
|
||||||
<Route path="/*" component={() => <NotFound />} />
|
<Route path="/*" component={() => <NotFound />} />
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
</DomainTransferInfo>
|
</DomainTransferInfo>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import Repost from '@/components/event/Repost';
|
|||||||
// eslint-disable-next-line import/no-cycle
|
// eslint-disable-next-line import/no-cycle
|
||||||
import TextNote from '@/components/event/TextNote';
|
import TextNote from '@/components/event/TextNote';
|
||||||
import EventLink from '@/components/EventLink';
|
import EventLink from '@/components/EventLink';
|
||||||
|
import { useTranslation } from '@/i18n/useTranslation';
|
||||||
|
|
||||||
export type EventDisplayProps = {
|
export type EventDisplayProps = {
|
||||||
event: NostrEvent;
|
event: NostrEvent;
|
||||||
@@ -18,8 +19,8 @@ export type EventDisplayProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const EventDisplay: Component<EventDisplayProps> = (props) => {
|
const EventDisplay: Component<EventDisplayProps> = (props) => {
|
||||||
// noteの場合は kind:1 であることを保証するために利用できる
|
const i18n = useTranslation();
|
||||||
// タイムラインで表示されるべきでないイベントが表示されてしまうのを防ぐ
|
|
||||||
const isAllowedKind = () =>
|
const isAllowedKind = () =>
|
||||||
props.ensureKinds == null ||
|
props.ensureKinds == null ||
|
||||||
props.ensureKinds.length === 0 ||
|
props.ensureKinds.length === 0 ||
|
||||||
@@ -28,17 +29,17 @@ const EventDisplay: Component<EventDisplayProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<Switch
|
<Switch
|
||||||
fallback={
|
fallback={
|
||||||
<span>
|
<div>
|
||||||
<span>未対応のイベント種別({props.event.kind})</span>
|
<span>{i18n()('post.unsupportedKind', { kind: props.event.kind })}</span>
|
||||||
<EventLink eventId={props.event.id} kind={props.event.kind} />
|
<EventLink eventId={props.event.id} kind={props.event.kind} />
|
||||||
</span>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Match when={!isAllowedKind()} keyed>
|
<Match when={!isAllowedKind()} keyed>
|
||||||
<span>
|
<div>
|
||||||
予期しないイベント種別({props.event.kind})
|
<span>{i18n()('post.unexpectedKind', { kind: props.event.kind })}</span>
|
||||||
<EventLink eventId={props.event.id} kind={props.event.kind} />
|
<EventLink eventId={props.event.id} kind={props.event.kind} />
|
||||||
</span>
|
</div>
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={props.event.kind === Kind.ShortTextNote}>
|
<Match when={props.event.kind === Kind.ShortTextNote}>
|
||||||
<TextNote event={props.event} embedding={props.actions} actions={props.actions} />
|
<TextNote event={props.event} embedding={props.actions} actions={props.actions} />
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const ContentWarningDisplay: Component<ContentWarningDisplayProps> = (props) =>
|
|||||||
class="mt-2 flex w-full flex-col items-center rounded border border-border p-2 text-center text-xs text-fg-secondary"
|
class="mt-2 flex w-full flex-col items-center rounded border border-border p-2 text-center text-xs text-fg-secondary"
|
||||||
onClick={() => setShowContentWarning(true)}
|
onClick={() => setShowContentWarning(true)}
|
||||||
>
|
>
|
||||||
<span class="inline-block h-4 w-4">
|
<span class="inline-block size-4">
|
||||||
<ExclamationTriangle />
|
<ExclamationTriangle />
|
||||||
</span>
|
</span>
|
||||||
<span>{i18n()('post.contentWarning.show')}</span>
|
<span>{i18n()('post.contentWarning.show')}</span>
|
||||||
@@ -40,7 +40,7 @@ const ContentWarningDisplay: Component<ContentWarningDisplayProps> = (props) =>
|
|||||||
class="text-xs text-fg-secondary hover:text-fg-secondary/70"
|
class="text-xs text-fg-secondary hover:text-fg-secondary/70"
|
||||||
onClick={() => setShowContentWarning(false)}
|
onClick={() => setShowContentWarning(false)}
|
||||||
>
|
>
|
||||||
隠す
|
{i18n()('post.contentWarning.hide')}
|
||||||
</button>
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Component, createResource, For, Show } from 'solid-js';
|
|||||||
|
|
||||||
import BasicModal from '@/components/modal/BasicModal';
|
import BasicModal from '@/components/modal/BasicModal';
|
||||||
import SafeLink from '@/components/utils/SafeLink';
|
import SafeLink from '@/components/utils/SafeLink';
|
||||||
|
import { useTranslation } from '@/i18n/useTranslation';
|
||||||
import resolveAsset from '@/utils/resolveAsset';
|
import resolveAsset from '@/utils/resolveAsset';
|
||||||
|
|
||||||
type AboutProps = {
|
type AboutProps = {
|
||||||
@@ -34,6 +35,8 @@ const fetchPackageInfo = async (): Promise<PackageInfo> => {
|
|||||||
const commit = import.meta.env.VITE_COMMIT as string | null;
|
const commit = import.meta.env.VITE_COMMIT as string | null;
|
||||||
|
|
||||||
const About: Component<AboutProps> = (props) => {
|
const About: Component<AboutProps> = (props) => {
|
||||||
|
const i18n = useTranslation();
|
||||||
|
|
||||||
const [packageInfo] = createResource(fetchPackageInfo);
|
const [packageInfo] = createResource(fetchPackageInfo);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -45,38 +48,30 @@ const About: Component<AboutProps> = (props) => {
|
|||||||
<h1 class="my-4">
|
<h1 class="my-4">
|
||||||
Rabbit{' '}
|
Rabbit{' '}
|
||||||
<span id="app-version">
|
<span id="app-version">
|
||||||
v{packageInfo()?.self?.version}
|
<Show when={commit} fallback="(dev)">
|
||||||
<Show when={commit}> ({commit})</Show>
|
{' '}
|
||||||
|
({commit})
|
||||||
|
</Show>
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="my-4 text-xl font-bold">バグ報告について</h2>
|
<div class="my-4 flex justify-center gap-3">
|
||||||
|
<SafeLink
|
||||||
<p class="my-4">
|
class="rounded border-2 border-primary px-4 py-2 font-bold text-primary hover:border-primary-hover hover:text-primary-hover"
|
||||||
おかしな動作を見つけたら
|
|
||||||
<a
|
|
||||||
class="text-link underline"
|
|
||||||
href="https://github.com/syusui-s/rabbit/issues/new/choose"
|
href="https://github.com/syusui-s/rabbit/issues/new/choose"
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
>
|
||||||
GitHubのIssues
|
{i18n()('about.bugReport')}
|
||||||
</a>
|
|
||||||
までご報告ください。
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 class="my-4 text-xl font-bold">ソースコード</h2>
|
|
||||||
|
|
||||||
<p class="my-4">
|
|
||||||
ソースコードは
|
|
||||||
<SafeLink class="text-link underline" href="https://github.com/syusui-s/rabbit">
|
|
||||||
GitHub
|
|
||||||
</SafeLink>
|
</SafeLink>
|
||||||
で入手できます。
|
<SafeLink
|
||||||
</p>
|
class="rounded border-2 border-primary px-4 py-2 font-bold text-primary hover:border-primary-hover hover:text-primary-hover"
|
||||||
|
href="https://github.com/syusui-s/rabbit"
|
||||||
|
>
|
||||||
|
{i18n()('about.sourceCode')}
|
||||||
|
</SafeLink>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2 class="my-4 text-xl font-bold">利用規約</h2>
|
<h2 class="my-4 text-xl font-bold">{i18n()('about.termOfService')}</h2>
|
||||||
|
|
||||||
<p class="my-4">
|
<p class="my-4">
|
||||||
Copyright (C) 2023 Shusui Moyatani and{' '}
|
Copyright (C) 2023 Shusui Moyatani and{' '}
|
||||||
@@ -88,43 +83,29 @@ const About: Component<AboutProps> = (props) => {
|
|||||||
</SafeLink>
|
</SafeLink>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="my-4">
|
<pre class=" max-h-96 overflow-auto rounded bg-bg-tertiary p-2 text-sm">
|
||||||
このプログラムは自由ソフトウェアです。フリーソフトウェア財団から発行された
|
{i18n()('about.agplText')}
|
||||||
GNUアフェロー一般公衆ライセンス(バージョン3か、(任意で)より新しいバージョンのいずれか)の条件の下で
|
</pre>
|
||||||
再頒布や改変、あるいはその両方を行うことができます。
|
|
||||||
|
<p>
|
||||||
|
<SafeLink class="text-link underline" href="https://gpl.mhatta.org/agpl.ja.html">
|
||||||
|
{i18n()('about.agplTranslationJa')}
|
||||||
|
</SafeLink>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="my-4">
|
<pre class="scrollbar max-h-96 overflow-auto rounded bg-bg-tertiary p-4 text-xs">
|
||||||
このプログラムは役立つことを願って頒布されていますが、
|
|
||||||
<strong class="font-bold">いかなる保証もありません</strong>。<em>商品性</em>や
|
|
||||||
<em>特定目的適合性</em> に対する保証は暗示されたものも含めて存在しません。
|
|
||||||
詳しくはGNUアフェロー一般公衆ライセンスをご覧ください。
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="my-4">
|
|
||||||
あなたは、このプログラムに付随してGNUアフェロー一般公衆ライセンスのコピーを受け取っていることでしょう。
|
|
||||||
そうでなければ、
|
|
||||||
<SafeLink href="https://www.gnu.org/licenses/" />
|
|
||||||
をご参照ください。
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<a class="text-link underline" href="https://gpl.mhatta.org/agpl.ja.html">
|
|
||||||
参考訳
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<pre class="scorllbar max-h-96 overflow-auto rounded bg-bg-secondary p-4 text-xs">
|
|
||||||
{packageInfo()?.self.licenseText}
|
{packageInfo()?.self.licenseText}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2 class="my-4 text-xl font-bold">使用ライブラリ</h2>
|
<h2 class="my-4 text-xl font-bold">{i18n()('about.usingLibraries')}</h2>
|
||||||
|
|
||||||
<For each={packageInfo()?.packages ?? []} fallback="取得中">
|
<For each={packageInfo()?.packages ?? []}>
|
||||||
{(p) => (
|
{(p) => (
|
||||||
<>
|
<>
|
||||||
<h3 class="mb-2 mt-4 font-mono">
|
<h3 class="mb-2 mt-4 font-mono">
|
||||||
{p.name}@{p.version} ({p.licenseSpdx})
|
{p.name}@{p.version} ({p.licenseSpdx})
|
||||||
</h3>
|
</h3>
|
||||||
<pre class="scrollbar max-h-96 overflow-auto rounded bg-bg-secondary p-4 text-xs">
|
<pre class="scrollbar max-h-96 overflow-auto rounded bg-bg-tertiary p-4 text-xs">
|
||||||
{p.licenseText}
|
{p.licenseText}
|
||||||
</pre>
|
</pre>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ export default {
|
|||||||
loading: 'Loading',
|
loading: 'Loading',
|
||||||
updating: 'Updating',
|
updating: 'Updating',
|
||||||
},
|
},
|
||||||
|
notFound: {
|
||||||
|
title: 'Not found',
|
||||||
|
back: 'Back',
|
||||||
|
},
|
||||||
posting: {
|
posting: {
|
||||||
placeholder: "What's happening?",
|
placeholder: "What's happening?",
|
||||||
placeholderReply: 'Post a reply',
|
placeholderReply: 'Post a reply',
|
||||||
@@ -115,8 +119,11 @@ export default {
|
|||||||
contentWarning: {
|
contentWarning: {
|
||||||
show: 'Click to display',
|
show: 'Click to display',
|
||||||
reason: 'Reason',
|
reason: 'Reason',
|
||||||
|
hide: 'Hide',
|
||||||
},
|
},
|
||||||
failedToFetchEvent: 'Failed to fetch event',
|
failedToFetchEvent: 'Failed to fetch event',
|
||||||
|
unexpectedKind: 'Unexpected event(kind:{{kind}})',
|
||||||
|
unsupportedKind: 'Unsupported event(kind:{{kind}})',
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
reposted: ' reposted',
|
reposted: ' reposted',
|
||||||
@@ -208,6 +215,26 @@ export default {
|
|||||||
reloadAfterInstall: 'Please reload after the installation is complete.',
|
reloadAfterInstall: 'Please reload after the installation is complete.',
|
||||||
reload: 'Reload',
|
reload: 'Reload',
|
||||||
},
|
},
|
||||||
|
about: {
|
||||||
|
bugReport: 'Report bug',
|
||||||
|
sourceCode: 'Source code',
|
||||||
|
termOfService: 'License',
|
||||||
|
agplText: stripMargin`
|
||||||
|
This program is free software:
|
||||||
|
|
||||||
|
you can redistribute it and/or modify it under the terms of
|
||||||
|
the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
`,
|
||||||
|
agplTranslationJa: 'Japanese translation',
|
||||||
|
usingLibraries: 'Using libraries',
|
||||||
|
},
|
||||||
domainTransfer: {
|
domainTransfer: {
|
||||||
announcementHead: 'Rabbit has moved to the new domain',
|
announcementHead: 'Rabbit has moved to the new domain',
|
||||||
announcementDescription: 'Please update your bookmark and links',
|
announcementDescription: 'Please update your bookmark and links',
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ export default {
|
|||||||
loading: '読み込み中',
|
loading: '読み込み中',
|
||||||
updating: '更新中',
|
updating: '更新中',
|
||||||
},
|
},
|
||||||
|
notFound: {
|
||||||
|
title: 'ページが見つかりませんでした',
|
||||||
|
back: '戻る',
|
||||||
|
},
|
||||||
posting: {
|
posting: {
|
||||||
placeholder: 'いまどうしてる?',
|
placeholder: 'いまどうしてる?',
|
||||||
placeholderReply: '返信を投稿',
|
placeholderReply: '返信を投稿',
|
||||||
@@ -111,8 +115,11 @@ export default {
|
|||||||
contentWarning: {
|
contentWarning: {
|
||||||
show: '表示するにはクリック',
|
show: '表示するにはクリック',
|
||||||
reason: '理由',
|
reason: '理由',
|
||||||
|
hide: '隠す',
|
||||||
},
|
},
|
||||||
failedToFetchEvent: '取得に失敗しました',
|
failedToFetchEvent: '取得に失敗しました',
|
||||||
|
unexpectedKind: '予期しないイベントです(kind:{{kind}})',
|
||||||
|
unsupportedKind: '未対応のイベントです(kind:{{kind}})',
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
reposted: 'がリポスト',
|
reposted: 'がリポスト',
|
||||||
@@ -205,6 +212,26 @@ export default {
|
|||||||
reloadAfterInstall: 'インストールが完了したら再読み込みしてください。',
|
reloadAfterInstall: 'インストールが完了したら再読み込みしてください。',
|
||||||
reload: '再読み込み',
|
reload: '再読み込み',
|
||||||
},
|
},
|
||||||
|
about: {
|
||||||
|
bugReport: 'バグ報告',
|
||||||
|
sourceCode: 'ソースコード',
|
||||||
|
termOfService: '利用規約',
|
||||||
|
agplText: stripMargin`
|
||||||
|
このプログラムは自由ソフトウェアです。
|
||||||
|
|
||||||
|
フリーソフトウェア財団から発行された GNUアフェロー一般公衆ライセンス
|
||||||
|
(バージョン3か、(任意で)より新しいバージョンのいずれか)の条件の下で
|
||||||
|
再頒布や改変、あるいはその両方を行うことができます。
|
||||||
|
|
||||||
|
このプログラムは役立つことを願って頒布されていますが、
|
||||||
|
**いかなる保証もありません**。
|
||||||
|
|
||||||
|
_商品性_や_特定目的適合性_ に対する保証は暗示されたものも含めて存在しません。
|
||||||
|
詳しくはGNUアフェロー一般公衆ライセンスをご覧ください。
|
||||||
|
`,
|
||||||
|
agplTranslationJa: '日本語訳',
|
||||||
|
usingLibraries: '使用ライブラリ',
|
||||||
|
},
|
||||||
domainTransfer: {
|
domainTransfer: {
|
||||||
announcementHead: 'Rabbitは新しいドメインに移りました',
|
announcementHead: 'Rabbitは新しいドメインに移りました',
|
||||||
announcementDescription: 'ブックマークやリンクの更新をお願いします',
|
announcementDescription: 'ブックマークやリンクの更新をお願いします',
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import type { Component } from 'solid-js';
|
import type { Component } from 'solid-js';
|
||||||
|
|
||||||
const NotFound: Component = () => (
|
import { useTranslation } from '@/i18n/useTranslation';
|
||||||
<div class="container mx-auto max-w-[640px] py-10">
|
|
||||||
<h1 class="text-4xl font-bold text-fg">お探しのページは見つかりませんでした</h1>
|
const NotFound: Component = () => {
|
||||||
<p class="pt-4">
|
const i18n = useTranslation();
|
||||||
<a class="text-link underline" href="/">
|
|
||||||
← トップに戻る
|
return (
|
||||||
</a>
|
<div class="container mx-auto max-w-[640px] py-10">
|
||||||
</p>
|
<h1 class="text-4xl font-bold text-fg">{i18n()('notFound.title')}</h1>
|
||||||
</div>
|
<p class="pt-4">
|
||||||
);
|
<a class="text-link underline" href="/">
|
||||||
|
{i18n()('notFound.back')}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default NotFound;
|
export default NotFound;
|
||||||
|
|||||||
@@ -6,21 +6,13 @@ import { decode } from 'nostr-tools/nip19';
|
|||||||
import GlobalModal from '@/components/modal/GlobalModal';
|
import GlobalModal from '@/components/modal/GlobalModal';
|
||||||
import SideBar from '@/components/SideBar';
|
import SideBar from '@/components/SideBar';
|
||||||
import useModalState from '@/hooks/useModalState';
|
import useModalState from '@/hooks/useModalState';
|
||||||
import usePersistStatus from '@/hooks/usePersistStatus';
|
|
||||||
|
|
||||||
const Permalink = () => {
|
const Permalink = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const { modalState, showProfile } = useModalState();
|
const { modalState, showProfile } = useModalState();
|
||||||
const { persistStatus } = usePersistStatus();
|
|
||||||
|
|
||||||
const navigateTop = () => {
|
const navigateTop = () => navigate('/');
|
||||||
if (persistStatus().loggedIn) {
|
|
||||||
navigate('/');
|
|
||||||
} else {
|
|
||||||
navigate('/hello');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (params.id != null) {
|
if (params.id != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user