From 2b19650e461924d80228da4c18db465cb506346a Mon Sep 17 00:00:00 2001 From: reya Date: Tue, 30 Jan 2024 08:13:12 +0700 Subject: [PATCH] feat: migrate onboarding to i18n --- apps/desktop/src/routes/auth/login.tsx | 9 +- apps/desktop/src/routes/error.tsx | 16 +- packages/ui/src/onboarding/finish.tsx | 14 +- packages/ui/src/onboarding/follow.tsx | 310 ------------------------ packages/ui/src/onboarding/home.tsx | 13 +- packages/ui/src/onboarding/interest.tsx | 12 +- packages/ui/src/onboarding/profile.tsx | 18 +- src-tauri/locales/en.json | 23 +- 8 files changed, 70 insertions(+), 345 deletions(-) delete mode 100644 packages/ui/src/onboarding/follow.tsx diff --git a/apps/desktop/src/routes/auth/login.tsx b/apps/desktop/src/routes/auth/login.tsx index 016c52492..9490644df 100644 --- a/apps/desktop/src/routes/auth/login.tsx +++ b/apps/desktop/src/routes/auth/login.tsx @@ -1,4 +1,4 @@ -import { useTranslation } from "react-i18next"; +import { Trans, useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; export function LoginScreen() { @@ -43,12 +43,15 @@ export function LoginScreen() { > {t("login.loginWithPrivkey")} -

+ Lume will put your Private Key in{" "} Secure Storage depended on your OS Platform. It will be secured by Password or Biometric ID -

+ diff --git a/apps/desktop/src/routes/error.tsx b/apps/desktop/src/routes/error.tsx index 6863b57d7..1e163742d 100644 --- a/apps/desktop/src/routes/error.tsx +++ b/apps/desktop/src/routes/error.tsx @@ -53,7 +53,7 @@ export function ErrorScreen() { return (
@@ -95,7 +95,7 @@ export function ErrorScreen() {
- 3. Report this issue to Lume's Devs + 3. Report this issue to Lume

- While waiting for Lume's Devs to release the bug fixes, - you always can use other Nostr clients with your account: + While waiting for Lume release the bug fixes, you always can + use other Nostr clients with your account:

@@ -134,15 +134,15 @@ export function ErrorScreen() { - primal.net + nostter diff --git a/packages/ui/src/onboarding/finish.tsx b/packages/ui/src/onboarding/finish.tsx index 228c58ba6..3c2022c90 100644 --- a/packages/ui/src/onboarding/finish.tsx +++ b/packages/ui/src/onboarding/finish.tsx @@ -5,12 +5,14 @@ import { useQueryClient } from "@tanstack/react-query"; import { motion } from "framer-motion"; import { useSetAtom } from "jotai"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; export function OnboardingFinishScreen() { const storage = useStorage(); const queryClient = useQueryClient(); const setOnboarding = useSetAtom(onboardingAtom); + const [t] = useTranslation(); const [loading, setLoading] = useState(false); const finish = async () => { @@ -33,9 +35,9 @@ export function OnboardingFinishScreen() { >
-

Profile setup complete!

+

{t("onboarding.finish.title")}

- You can exit the setup here and start using Lume. + {t("onboarding.finish.subtitle")}

diff --git a/packages/ui/src/onboarding/follow.tsx b/packages/ui/src/onboarding/follow.tsx deleted file mode 100644 index 3bc2df5aa..000000000 --- a/packages/ui/src/onboarding/follow.tsx +++ /dev/null @@ -1,310 +0,0 @@ -import { User, useArk } from "@lume/ark"; -import { - ArrowLeftIcon, - CancelIcon, - ChevronDownIcon, - LoaderIcon, - PlusIcon, -} from "@lume/icons"; -import { cn } from "@lume/utils"; -import * as Accordion from "@radix-ui/react-accordion"; -import { useQuery } from "@tanstack/react-query"; -import { motion } from "framer-motion"; -import { nip19 } from "nostr-tools"; -import { useState } from "react"; -import { useNavigate } from "react-router-dom"; -import { toast } from "sonner"; - -const POPULAR_USERS = [ - "npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6", - "npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237lmu63q0uf63m", - "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s", - "npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z", - "npub1az9xj85cmxv8e9j9y80lvqp97crsqdu2fpu3srwthd99qfu9qsgstam8y8", - "npub1a2cww4kn9wqte4ry70vyfwqyqvpswksna27rtxd8vty6c74era8sdcw83a", - "npub168ghgug469n4r2tuyw05dmqhqv5jcwm7nxytn67afmz8qkc4a4zqsu2dlc", - "npub133vj8ycevdle0cq8mtgddq0xtn34kxkwxvak983dx0u5vhqnycyqj6tcza", - "npub18ams6ewn5aj2n3wt2qawzglx9mr4nzksxhvrdc4gzrecw7n5tvjqctp424", - "npub1r0rs5q2gk0e3dk3nlc7gnu378ec6cnlenqp8a3cjhyzu6f8k5sgs4sq9ac", - "npub1prya33fnqerq0fljwjtp77ehtu7jlsjt5ydhwveuwmqdsdm6k8esk42xcv", - "npub19mduaf5569jx9xz555jcx3v06mvktvtpu0zgk47n4lcpjsz43zzqhj6vzk", -]; - -const LUME_USERS = [ - "npub1zfss807aer0j26mwp2la0ume0jqde3823rmu97ra6sgyyg956e0s6xw445", -]; - -export function OnboardingFollowScreen() { - const ark = useArk(); - const navigate = useNavigate(); - - const { isLoading, isError, data } = useQuery({ - queryKey: ["trending-users"], - queryFn: async ({ signal }: { signal: AbortSignal }) => { - const res = await fetch("https://api.nostr.band/v0/trending/profiles", { - signal, - }); - if (!res.ok) { - throw new Error("Failed to fetch trending users from nostr.band API."); - } - return res.json(); - }, - }); - - const [loading, setLoading] = useState(false); - const [follows, setFollows] = useState([]); - - // toggle follow state - const toggleFollow = (pubkey: string) => { - const arr = follows.includes(pubkey) - ? follows.filter((i) => i !== pubkey) - : [...follows, pubkey]; - setFollows(arr); - }; - - const submit = async () => { - try { - setLoading(true); - - if (!follows.length) return navigate("/finish"); - - const publish = await ark.newContactList({ - tags: follows.map((item) => { - if (item.startsWith("npub1")) - return ["p", nip19.decode(item).data as string]; - return ["p", item]; - }), - }); - - if (publish) { - setLoading(false); - return navigate("/finish"); - } - } catch (e) { - setLoading(false); - toast.error(String(e)); - } - }; - - return ( - -
- Dive into the nostrverse -
-
- -

- Nostr is fun when we are together. Try following some users that - interest you to build up your timeline. -

- - - - Recommended - - - -
- {POPULAR_USERS.map((pubkey) => ( -
- - - -
- -
- - -
-
-
-
-
- -
-
- ))} -
-
-
- - - Trending users - - - -
- {isLoading ? ( -
- -
- ) : isError ? ( -
- Error. Cannot get trending users -
- ) : ( - data?.profiles.map((item: { pubkey: string }) => ( -
- - - -
- -
- - -
-
-
-
-
- -
-
- )) - )} -
-
-
- - - Lume HQ - - - -
- {LUME_USERS.map((pubkey) => ( -
- - - -
- -
- - -
-
-
-
-
- -
-
- ))} -
-
-
-
-
-
- - -
-
-
- ); -} diff --git a/packages/ui/src/onboarding/home.tsx b/packages/ui/src/onboarding/home.tsx index fa863d75a..1de9984b5 100644 --- a/packages/ui/src/onboarding/home.tsx +++ b/packages/ui/src/onboarding/home.tsx @@ -2,10 +2,13 @@ import { ArrowRightIcon, PopperFilledIcon } from "@lume/icons"; import { onboardingAtom } from "@lume/utils"; import { motion } from "framer-motion"; import { useAtom } from "jotai"; +import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; export function OnboardingHomeScreen() { const navigate = useNavigate(); + + const [t] = useTranslation(); const [onboarding, setOnboarding] = useAtom(onboardingAtom); return ( @@ -17,11 +20,9 @@ export function OnboardingHomeScreen() { >
-

- Your account was successfully created! -

+

{t("onboarding.home.title")}

- For starters, let's set up your profile. + {t("onboarding.home.subtitle")}

@@ -32,7 +33,7 @@ export function OnboardingHomeScreen() { } className="inline-flex items-center justify-center gap-2 w-44 font-medium h-11 rounded-xl bg-blue-100 text-blue-500 hover:bg-blue-200 dark:bg-blue-900 dark:text-blue-500 dark:hover:bg-blue-800" > - Profile Settings + {t("onboarding.home.profileSettings")}
diff --git a/packages/ui/src/onboarding/interest.tsx b/packages/ui/src/onboarding/interest.tsx index 8b661a9ce..3d458ccd9 100644 --- a/packages/ui/src/onboarding/interest.tsx +++ b/packages/ui/src/onboarding/interest.tsx @@ -2,6 +2,7 @@ import { ArrowLeftIcon, LoaderIcon } from "@lume/icons"; import { useStorage } from "@lume/storage"; import { TOPICS, cn } from "@lume/utils"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; @@ -9,6 +10,7 @@ export function OnboardingInterestScreen() { const storage = useStorage(); const navigate = useNavigate(); + const [t] = useTranslation(); const [loading, setLoading] = useState(false); const [hashtags, setHashtags] = useState([]); @@ -49,9 +51,9 @@ export function OnboardingInterestScreen() {
-

Interests

+

{t("interests.title")}

- Pick things you'd like to see in your home feed. + {t("interests.subtitle")}

@@ -74,7 +76,7 @@ export function OnboardingInterestScreen() { onClick={() => toggleAll(topic.content)} className="text-sm font-medium text-blue-500" > - Follow All + {t("interests.followAll")}
@@ -105,7 +107,7 @@ export function OnboardingInterestScreen() { className="inline-flex h-9 flex-1 gap-2 shrink-0 items-center justify-center rounded-lg bg-neutral-100 font-medium dark:bg-neutral-900 dark:hover:bg-neutral-800 hover:bg-blue-200" > - Back + {t("global.back")}
diff --git a/packages/ui/src/onboarding/profile.tsx b/packages/ui/src/onboarding/profile.tsx index d61757e5e..b4a0a84b9 100644 --- a/packages/ui/src/onboarding/profile.tsx +++ b/packages/ui/src/onboarding/profile.tsx @@ -7,6 +7,7 @@ import { motion } from "framer-motion"; import { minidenticon } from "minidenticons"; import { useState } from "react"; import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; import { AvatarUploadButton } from "../avatarUploadButton"; @@ -20,6 +21,7 @@ export function OnboardingProfileScreen() { const queryClient = useQueryClient(); const navigate = useNavigate(); + const { t } = useTranslation(); const { register, handleSubmit } = useForm(); const svgURI = `data:image/svg+xml;utf8,${encodeURIComponent( @@ -71,9 +73,9 @@ export function OnboardingProfileScreen() {
-

About you

+

{t("onboarding.profile.title")}

- Tell Lume about yourself to start building your home feed. + {t("onboarding.profile.subtitle")}

@@ -89,7 +91,7 @@ export function OnboardingProfileScreen() { className="flex flex-col px-8 gap-4" >
- Avatar + {t("user.avatar")}
{picture.length ? (