feat: more i18n text

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-09-13 22:20:34 +08:00
parent bf7da0431f
commit 6f8acced7b
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
7 changed files with 34 additions and 28 deletions

View File

@ -86,6 +86,7 @@
"search.placeholder": "Search...",
"search.result_count_local_mode": "(Local mode)",
"search.tooltip.local_search": "This search covers locally available data. Try a Refetch to include the latest data.",
"shortcuts.guide.title": "Shortcuts Guideline",
"sidebar.category_remove_dialog.cancel": "Cancel",
"sidebar.category_remove_dialog.continue": "Continue",
"sidebar.category_remove_dialog.description": "This operation will delete your category, but the feeds it contains will be retained and grouped by website.",
@ -114,6 +115,12 @@
"signin.sign_in_to": "Sign in to",
"sync_indicator.offline": "Offline",
"sync_indicator.synced": "Synced with server",
"user_button.account": "Account",
"user_button.download_desktop_app": "Download Desktop app",
"user_button.log_out": "Log out",
"user_button.power": "Power",
"user_button.preferences": "Preferences",
"user_button.profile": "Profile",
"user_profile.close": "Close",
"user_profile.edit": "Edit",
"user_profile.loading": "Loading",

View File

@ -1,4 +1,4 @@
export const currentSupportedLanguages = ["en", "ja", "zh-CN"]
export const currentSupportedLanguages = ["en", "ja", "zh-CN"].sort()
export const dayjsLocaleImportMap = {
en: ["en", () => import("dayjs/locale/en")],

View File

@ -64,6 +64,7 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
const signOut = useSignOut()
const settingModalPresent = useSettingModal()
const presentUserProfile = usePresentUserProfileModal("dialog")
const { t } = useTranslation()
if (status !== "authenticated") {
return <LoginButton {...props} />
}
@ -71,12 +72,14 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild className="!outline-none focus-visible:bg-theme-item-hover">
<ActionButton tooltip="Profile">
<ActionButton tooltip={t("words.user")}>
<UserAvatar className="h-5 p-0 [&_*]:border-0" hideName />
</ActionButton>
</DropdownMenuTrigger>
<DropdownMenuContent className="min-w-[180px]" side="bottom" align="end">
<DropdownMenuLabel className="text-xs text-theme-foreground/60">Account</DropdownMenuLabel>
<DropdownMenuLabel className="text-xs text-theme-foreground/60">
{t("user_button.account")}
</DropdownMenuLabel>
<DropdownMenuLabel>
<div className="-mt-1 flex items-center gap-2">
<UserAvatar className="h-7 shrink-0 p-0" hideName />
@ -93,26 +96,17 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
}}
icon={<i className="i-mgc-user-3-cute-re" />}
>
Profile
{t("user_button.profile")}
</DropdownMenuItem>
{/* <DropdownMenuSeparator />
<DropdownMenuLabel>
<AppTheme />
</DropdownMenuLabel> */}
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => {
// Here we need to delay one frame, so it's two raf,
// in order to have `point-event: none` recorded by RadixOverlay after modal is invoked in a certain scenario,
// and the page freezes after modal is turned off.
nextFrame(() => settingModalPresent("wallet"))
}}
icon={<i className="i-mgc-power-outline" />}
>
Power
{t("user_button.power")}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
@ -120,7 +114,7 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
}}
icon={<i className="i-mgc-settings-7-cute-re" />}
>
Preferences
{t("user_button.preferences")}
</DropdownMenuItem>
<DropdownMenuSeparator />
{!window.electron && (
@ -131,13 +125,13 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
}}
icon={<i className="i-mgc-download-2-cute-re" />}
>
Download Desktop app
{t("user_button.download_desktop_app")}
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem onClick={signOut} icon={<i className="i-mgc-exit-cute-re" />}>
Log out
{t("user_button.log_out")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

View File

@ -30,7 +30,7 @@ export const EntryEmptyList = forwardRef<HTMLDivElement, HTMLMotionProps<"div">>
{unreadOnly ? (
<>
<i className="i-mgc-celebrate-cute-re -mt-11 text-3xl" />
<span className="text-base">Zero Unread</span>
<span className="text-base">{t("entry_list.zero_unread")}</span>
</>
) : (
<div className="flex -translate-y-6 flex-col items-center justify-center gap-2">

View File

@ -21,6 +21,7 @@ import { useFeedById } from "@renderer/store/feed"
import { noop } from "foxact/noop"
import { AnimatePresence, m } from "framer-motion"
import { memo, useMemo, useState } from "react"
import { useTranslation } from "react-i18next"
import { useEntryContentScrollToTop, useEntryTitleMeta } from "./atoms"
import { EntryReadHistory } from "./components/EntryReadHistory"
@ -124,6 +125,8 @@ const ElectronAdditionActions = window.electron
}) => {
const entryReadabilityStatus = useEntryInReadabilityStatus(entry?.entries.id)
const { t } = useTranslation()
const feed = useFeedById(entry?.feedId)
const populatedEntry = useMemo(() => {
@ -147,7 +150,7 @@ const ElectronAdditionActions = window.electron
const items = [
{
key: "tts",
name: "Play TTS",
name: t("entry_content.header.play_tts"),
shortcut: shortcuts.entry.tts.key,
className: ttsLoading ? "i-mgc-loading-3-cute-re animate-spin" : "i-mgc-voice-cute-re",
@ -176,7 +179,7 @@ const ElectronAdditionActions = window.electron
},
},
{
name: "Readability",
name: t("entry_content.header.readability"),
className: cn(
isInReadability(entryReadabilityStatus)
? `i-mgc-sparkles-2-filled`

View File

@ -22,6 +22,7 @@ import { useFeedUnreadStore } from "@renderer/store/unread"
import { WEB_URL } from "@shared/constants"
import dayjs from "dayjs"
import { memo, useCallback } from "react"
import { useTranslation } from "react-i18next"
import { usePresentUserProfileModal } from "../profile/hooks"
import { UnreadNumber } from "./unread-number"
@ -33,6 +34,7 @@ interface FeedItemProps {
showUnreadCount?: boolean
}
const FeedItemImpl = ({ view, feedId, className, showUnreadCount = true }: FeedItemProps) => {
const { t } = useTranslation()
const subscription = useSubscriptionByFeedId(feedId)
const navigate = useNavigateEntry()
const handleNavigate: React.MouseEventHandler<HTMLDivElement> = useCallback(
@ -131,9 +133,9 @@ const FeedItemImpl = ({ view, feedId, className, showUnreadCount = true }: FeedI
<TooltipContent className="px-4 py-2">
<div className="flex items-center text-base font-semibold">
<i className="i-mgc-certificate-cute-fi mr-2 shrink-0 text-accent" />
Claimed feed
{t("feed_item.claimed_feed")}
</div>
<div>This feed is claimed by you.</div>
<div>{t("feed_item.claimed_by_you")}</div>
</TooltipContent>
</TooltipPortal>
</Tooltip>
@ -147,10 +149,10 @@ const FeedItemImpl = ({ view, feedId, className, showUnreadCount = true }: FeedI
<TooltipContent className="px-4 py-2">
<div className="flex items-center text-base font-semibold">
<i className="i-mgc-certificate-cute-fi mr-2 shrink-0 text-amber-500" />
Claimed feed
{t("feed_item.claimed_feed")}
</div>
<div className="mt-1 flex items-center gap-1.5">
<span>This feed is claimed by</span>
<span>{t("feed_item.claimed_by_owner")}</span>
{feed.owner ? (
<Avatar
className="inline-flex aspect-square size-5 rounded-full"
@ -163,7 +165,7 @@ const FeedItemImpl = ({ view, feedId, className, showUnreadCount = true }: FeedI
<AvatarFallback>{feed.owner.name?.slice(0, 2)}</AvatarFallback>
</Avatar>
) : (
<span>its owner.</span>
<span>{t("feed_item.claimed_by_unknown")}</span>
)}
</div>
</TooltipContent>
@ -179,7 +181,7 @@ const FeedItemImpl = ({ view, feedId, className, showUnreadCount = true }: FeedI
<TooltipContent>
<div className="flex items-center gap-1">
<i className="i-mgc-time-cute-re" />
Error since{" "}
{t("feed_item.error_since")}{" "}
{dayjs
.duration(dayjs(feed.errorAt).diff(dayjs(), "minute"), "minute")
.humanize(true)}
@ -200,7 +202,7 @@ const FeedItemImpl = ({ view, feedId, className, showUnreadCount = true }: FeedI
<OouiUserAnonymous className="ml-1 shrink-0 text-base" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>Not publicly visible on your profile page</TooltipContent>
<TooltipContent>{t("feed_item.not_publicly_visible")}</TooltipContent>
</TooltipPortal>
</Tooltip>
)}

View File

@ -43,7 +43,7 @@ const ShortcutModalContent = () => {
onPointerDownCapture={dragControls.start.bind(dragControls)}
className="center w-full border-b p-3 font-medium"
>
Shortcuts Guideline
{t("shortcuts.guide.title", { ns: "app" })}
</h2>
<MotionButtonBase onClick={dismiss} className="absolute right-3 top-2 p-2">
<i className="i-mgc-close-cute-re" />