parent
bf7da0431f
commit
6f8acced7b
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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")],
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue