@@ -89,7 +91,7 @@ export function OnboardingProfileScreen() {
className="flex flex-col px-8 gap-4"
>
-
Avatar
+
{t("user.avatar")}
{picture.length ? (
- Name *
+ {t("user.name")} *
diff --git a/packages/ui/src/routes/suggest.tsx b/packages/ui/src/routes/suggest.tsx
index 1630953c..d16ef695 100644
--- a/packages/ui/src/routes/suggest.tsx
+++ b/packages/ui/src/routes/suggest.tsx
@@ -1,6 +1,7 @@
import { User } from "@lume/ark";
import { ArrowLeftIcon, ArrowRightIcon, LoaderIcon } from "@lume/icons";
import { useQuery, useQueryClient } from "@tanstack/react-query";
+import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { toast } from "sonner";
import { WindowVirtualizer } from "virtua";
@@ -28,6 +29,7 @@ export function SuggestRoute({ queryKey }: { queryKey: string[] }) {
const queryClient = useQueryClient();
const navigate = useNavigate();
+ const { t } = useTranslation();
const { isLoading, isError, data } = useQuery({
queryKey: ["trending-users"],
queryFn: async ({ signal }: { signal: AbortSignal }) => {
@@ -71,7 +73,7 @@ export function SuggestRoute({ queryKey }: { queryKey: string[] }) {
-
Suggested Follows
+ {t("suggestion.title")}
{isLoading ? (
@@ -80,7 +82,7 @@ export function SuggestRoute({ queryKey }: { queryKey: string[] }) {
) : isError ? (
- Error. Cannot get trending users
+ {t("suggestion.error")}
) : (
data?.profiles.map((item: { pubkey: string }) => (
@@ -115,7 +117,7 @@ export function SuggestRoute({ queryKey }: { queryKey: string[] }) {
onClick={submit}
className="inline-flex items-center justify-center gap-2 px-6 font-medium shadow-xl dark:shadow-none shadow-neutral-500/50 text-white transform bg-blue-500 rounded-full active:translate-y-1 w-44 h-11 hover:bg-blue-600 focus:outline-none disabled:cursor-not-allowed"
>
- Save & Go back
+ {t("suggestion.button")}
diff --git a/packages/ui/src/routes/user.tsx b/packages/ui/src/routes/user.tsx
index 2ff5b49c..2cdeb60a 100644
--- a/packages/ui/src/routes/user.tsx
+++ b/packages/ui/src/routes/user.tsx
@@ -9,6 +9,7 @@ import { FETCH_LIMIT } from "@lume/utils";
import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk";
import { useInfiniteQuery } from "@tanstack/react-query";
import { useMemo } from "react";
+import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { WindowVirtualizer } from "virtua";
@@ -17,6 +18,7 @@ export function UserRoute() {
const navigate = useNavigate();
const { id } = useParams();
+ const { t } = useTranslation();
const { data, hasNextPage, isLoading, isFetchingNextPage, fetchNextPage } =
useInfiniteQuery({
queryKey: ["user-posts", id],
@@ -107,7 +109,7 @@ export function UserRoute() {
- Latest posts
+ {t("user.latestPosts")}
{isLoading ? (
@@ -130,7 +132,7 @@ export function UserRoute() {
) : (
<>
- Load more
+ {t("global.loadMore")}
>
)}
diff --git a/packages/ui/src/search/dialog.tsx b/packages/ui/src/search/dialog.tsx
index c39e2341..af739f2f 100644
--- a/packages/ui/src/search/dialog.tsx
+++ b/packages/ui/src/search/dialog.tsx
@@ -4,17 +4,20 @@ import { COL_TYPES, searchAtom } from "@lume/utils";
import { type NDKEvent, NDKKind } from "@nostr-dev-kit/ndk";
import { useAtom } from "jotai";
import { useEffect, useState } from "react";
+import { useTranslation } from "react-i18next";
import { useDebounce } from "use-debounce";
import { Command } from "../cmdk";
export function SearchDialog() {
+ const ark = useArk();
+
const [open, setOpen] = useAtom(searchAtom);
const [loading, setLoading] = useState(false);
const [events, setEvents] = useState
([]);
const [search, setSearch] = useState("");
const [value] = useDebounce(search, 1200);
- const ark = useArk();
+ const { t } = useTranslation();
const { vlistRef, columns, addColumn } = useColumnContext();
const searchEvents = async () => {
@@ -90,7 +93,7 @@ export function SearchDialog() {
@@ -101,7 +104,7 @@ export function SearchDialog() {
) : !events.length ? (
- No results found.
+ {t("global.noResult")}
) : (
<>
@@ -161,7 +164,7 @@ export function SearchDialog() {
- Try searching for people, notes, or keywords
+ {t("search.empty")}
) : null}
diff --git a/packages/utils/src/constants.ts b/packages/utils/src/constants.ts
index 5fc22a55..9b2d98e7 100644
--- a/packages/utils/src/constants.ts
+++ b/packages/utils/src/constants.ts
@@ -1,5 +1,10 @@
export const FETCH_LIMIT = 20;
+export const LANGUAGES = [
+ { label: "English", code: "en" },
+ { label: "Japanese", code: "ja" },
+];
+
export const NOSTR_MENTIONS = [
"@npub1",
"nostr:npub1",
@@ -26,7 +31,7 @@ export const NOSTR_EVENTS = [
"Nostr:nevent1",
];
-export const BITCOINS = ['lnbc', 'bc1p', 'bc1q'];
+export const BITCOINS = ["lnbc", "bc1p", "bc1q"];
export const IMAGES = ["jpg", "jpeg", "gif", "png", "webp", "avif", "tiff"];
@@ -374,4 +379,5 @@ export const QUOTES = [
"Are you a fan of following topics, instead of people? Use https://zapddit.com",
];
+// @ts-ignore, it works
export const VITE_FLATPAK_RESOURCE = import.meta.env.VITE_FLATPAK_RESOURCE;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 478fa0a4..721cea0b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -150,6 +150,12 @@ importers:
framer-motion:
specifier: ^10.18.0
version: 10.18.0(react-dom@18.2.0)(react@18.2.0)
+ i18next:
+ specifier: ^23.8.0
+ version: 23.8.0
+ i18next-resources-to-backend:
+ specifier: ^1.2.0
+ version: 1.2.0
jotai:
specifier: ^2.6.3
version: 2.6.3(@types/react@18.2.48)(react@18.2.0)
@@ -177,6 +183,9 @@ importers:
react-hook-form:
specifier: ^7.49.3
version: 7.49.3(react@18.2.0)
+ react-i18next:
+ specifier: ^14.0.1
+ version: 14.0.1(i18next@23.8.0)(react-dom@18.2.0)(react@18.2.0)
react-router-dom:
specifier: ^6.21.3
version: 6.21.3(react-dom@18.2.0)(react@18.2.0)
@@ -359,6 +368,9 @@ importers:
react-currency-input-field:
specifier: ^3.6.14
version: 3.6.14(react@18.2.0)
+ react-i18next:
+ specifier: ^14.0.1
+ version: 14.0.1(i18next@23.8.0)(react-dom@18.2.0)(react@18.2.0)
react-router-dom:
specifier: ^6.21.3
version: 6.21.3(react-dom@18.2.0)(react@18.2.0)
@@ -993,6 +1005,9 @@ importers:
react-hotkeys-hook:
specifier: ^4.4.4
version: 4.4.4(react-dom@18.2.0)(react@18.2.0)
+ react-i18next:
+ specifier: ^14.0.1
+ version: 14.0.1(i18next@23.8.0)(react-dom@18.2.0)(react@18.2.0)
react-router-dom:
specifier: ^6.21.3
version: 6.21.3(react-dom@18.2.0)(react@18.2.0)
@@ -5180,6 +5195,12 @@ packages:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
dev: false
+ /html-parse-stringify@3.0.1:
+ resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
+ dependencies:
+ void-elements: 3.1.0
+ dev: false
+
/html-void-elements@3.0.0:
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
dev: false
@@ -5203,6 +5224,18 @@ packages:
engines: {node: '>=16.17.0'}
dev: false
+ /i18next-resources-to-backend@1.2.0:
+ resolution: {integrity: sha512-8f1l03s+QxDmCfpSXCh9V+AFcxAwIp0UaroWuyOx+hmmv8484GcELHs+lnu54FrNij8cDBEXvEwhzZoXsKcVpg==}
+ dependencies:
+ '@babel/runtime': 7.23.9
+ dev: false
+
+ /i18next@23.8.0:
+ resolution: {integrity: sha512-1H+39doU9dQZrRprpnZ2aZetbX9I1N3bM/YGHN/ZkMJ//wJqrxDEqgI5mmSsh/rglsFBiNxI6UtFZfUO2A6XbA==}
+ dependencies:
+ '@babel/runtime': 7.23.9
+ dev: false
+
/iconv-lite@0.4.23:
resolution: {integrity: sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==}
engines: {node: '>=0.10.0'}
@@ -6970,6 +7003,26 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /react-i18next@14.0.1(i18next@23.8.0)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-TMV8hFismBmpMdIehoFHin/okfvgjFhp723RYgIqB4XyhDobVMyukyM3Z8wtTRmajyFMZrBl/OaaXF2P6WjUAw==}
+ peerDependencies:
+ i18next: '>= 23.2.3'
+ react: '>= 16.8.0'
+ react-dom: '*'
+ react-native: '*'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.23.9
+ html-parse-stringify: 3.0.1
+ i18next: 23.8.0
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/react-remove-scroll-bar@2.3.4(@types/react@18.2.48)(react@18.2.0):
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
engines: {node: '>=10'}
@@ -8594,6 +8647,11 @@ packages:
vite: 5.0.12(@types/node@20.11.8)
dev: false
+ /void-elements@3.1.0:
+ resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/volar-service-css@0.0.17(@volar/language-service@1.11.1):
resolution: {integrity: sha512-bEDJykygMzn2+a9ud6KwZZLli9eqarxApAXZuf2CqJJh6Trw1elmbBCo9SlPfqMrIhpFnwV0Sa+Xoc9x5WPeGw==}
peerDependencies:
diff --git a/src-tauri/locales/cn.json b/src-tauri/locales/cn.json
new file mode 100644
index 00000000..8400f6f8
--- /dev/null
+++ b/src-tauri/locales/cn.json
@@ -0,0 +1,295 @@
+{
+ "global": {
+ "relay": "Relay",
+ "back": "Back",
+ "continue": "Continue",
+ "loading": "Loading",
+ "error": "Error",
+ "moveLeft": "Move Left",
+ "moveRight": "Move Right",
+ "newColumn": "New Column",
+ "inspect": "Inspect",
+ "loadMore": "Load more",
+ "delete": "Delete",
+ "refresh": "Refresh",
+ "cancel": "Cancel",
+ "save": "Save",
+ "post": "Post",
+ "update": "Update",
+ "noResult": "No results found.",
+ "emptyFeedTitle": "This feed is empty",
+ "emptyFeedSubtitle": "You can follow more users to build up your timeline",
+ "apiKey": "API Key",
+ "skip": "Skip",
+ "close": "Close"
+ },
+ "nip89": {
+ "unsupported": "Lume isn't support this event",
+ "openWith": "Open with"
+ },
+ "note": {
+ "showThread": "Show thread",
+ "showMore": "Show more",
+ "error": "Failed to fetch event.",
+ "posted": "posted",
+ "replied": "replied",
+ "reposted": "reposted",
+ "menu": {
+ "viewThread": "View thread",
+ "copyLink": "Copy shareable link",
+ "copyNoteId": "Copy note ID",
+ "copyAuthorId": "Copy author ID",
+ "viewAuthor": "View author",
+ "pinAuthor": "Pin author",
+ "copyRaw": "Copy raw event",
+ "mute": "Mute"
+ },
+ "buttons": {
+ "pin": "Pin",
+ "pinTooltip": "Pin Note",
+ "repost": "Repost",
+ "quote": "Quote",
+ "viewProfile": "View profile"
+ },
+ "zap": {
+ "zap": "Zap",
+ "tooltip": "Send zap",
+ "modalTitle": "Send zap to",
+ "messagePlaceholder": "Enter message (optional)",
+ "buttonFinish": "Zapped",
+ "buttonLoading": "Processing...",
+ "invoiceButton": "Scan to zap",
+ "invoiceFooter": "You must use Bitcoin wallet which support Lightning\nsuch as: Blue Wallet, Bitkit, Phoenix,..."
+ },
+ "reply": {
+ "single": "reply",
+ "plural": "replies",
+ "empty": "Be the first to Reply!"
+ }
+ },
+ "user": {
+ "avatar": "Avatar",
+ "displayName": "Display Name",
+ "name": "Name",
+ "bio": "Bio",
+ "lna": "Lightning address",
+ "website": "Website",
+ "verified": "Verified",
+ "unverified": "Unverified",
+ "follow": "Follow",
+ "unfollow": "Unfollow",
+ "latestPosts": "Latest posts",
+ "avatarButton": "Change avatar",
+ "coverButton": "Change cover",
+ "editProfile": "Edit profile",
+ "settings": "Settings",
+ "logout": "Log out",
+ "logoutConfirmTitle": "Are you sure!",
+ "logoutConfirmSubtitle": "You can always log back in at any time. If you just want to switch accounts, you can do that by adding an existing account."
+ },
+ "editor": {
+ "title": "New Post",
+ "placeholder": "What are you up to?",
+ "successMessage": "Your note has been published successfully.",
+ "replyPlaceholder": "Post your reply"
+ },
+ "search": {
+ "placeholder": "Type something to search...",
+ "empty": "Try searching for people, notes, or keywords"
+ },
+ "welcome": {
+ "title": "Lume is a magnificent client for Nostr to meet, explore\nand freely share your thoughts with everyone.",
+ "signup": "Join Nostr",
+ "login": "Login",
+ "footer": "Before joining Nostr, you can take time to learn more about Nostr"
+ },
+ "login": {
+ "title": "Welcome back, anon!",
+ "footer": "Lume will put your Private Key in Secure Storage depended on your OS Platform. It will be secured by Password or Biometric ID",
+ "loginWithAddress": "Login with Nostr Address",
+ "loginWithBunker": "Login with nsecBunker",
+ "or": "Or continue with",
+ "loginWithPrivkey": "Login with Private Key"
+ },
+ "loginWithAddress": {
+ "title": "Enter your Nostr Address"
+ },
+ "loginWithBunker": {
+ "title": "Enter your nsecbunker token"
+ },
+ "loginWithPrivkey": {
+ "title": "Enter your Private Key",
+ "subtitle": "Lume will put your private key to <1>{{service}}1>.\nIt will be secured by your OS."
+ },
+ "signup": {
+ "title": "Let's Get Started",
+ "subtitle": "Choose one of methods below to create your account",
+ "selfManageMethod": "Self-Managed",
+ "selfManageMethodDescription": "You create your keys and keep them safe.",
+ "providerMethod": "Managed by Provider",
+ "providerMethodDescription": "A 3rd party provider will handle your sign in keys for you."
+ },
+ "signupWithSelfManage": {
+ "title": "This is your new Account Key",
+ "subtitle": "Keep your key in safe place. If you lose this key, you will lose access to your account.",
+ "confirm1": "I understand the risk of lost private key.",
+ "confirm2": "I will make sure keep it safe and not sharing with anyone.",
+ "confirm3": "I understand I cannot recover private key.",
+ "button": "Save key & Continue"
+ },
+ "signupWithProvider": {
+ "title": "Let's set up your account on Nostr",
+ "username": "Username *",
+ "chooseProvider": "Choose a Provider",
+ "usernameFooter": "Use to login to Lume and other Nostr apps. You can choose provider you trust to manage your account",
+ "email": "Backup Email (optional)",
+ "emailFooter": "Use for recover your account if you lose your password"
+ },
+ "onboardingSettings": {
+ "title": "You're almost ready to use Lume.",
+ "subtitle": "Let's start personalizing your experience.",
+ "notification": {
+ "title": "Push notification",
+ "subtitle": "Enabling push notifications will allow you to receive notifications from Lume."
+ },
+ "lowPower": {
+ "title": "Low Power Mode",
+ "subtitle": "Limited relay connection and hide all media, sustainable for low network environment."
+ },
+ "translation": {
+ "title": "Translation (nostr.wine)",
+ "subtitle": "Translate text to your preferred language, powered by Nostr Wine."
+ },
+ "footer": "There are many more settings you can configure from the 'Settings' Screen. Be sure to visit it later."
+ },
+ "relays": {
+ "global": "Global",
+ "follows": "Follows",
+ "sidebar": {
+ "title": "Connected relays",
+ "empty": "Empty."
+ },
+ "relayView": {
+ "empty": "Could not load relay information 😬",
+ "owner": "Owner",
+ "contact": "Contact",
+ "software": "Software",
+ "nips": "Supported NIPs",
+ "limit": "Limitation",
+ "payment": "Open payment website",
+ "paymentNote": "You need to make a payment to connect this relay"
+ }
+ },
+ "suggestion": {
+ "title": "Suggested Follows",
+ "error": "Error. Cannot get trending users",
+ "button": "Save & Go back"
+ },
+ "interests": {
+ "title": "Interests",
+ "subtitle": "Pick things you'd like to see in your home feed.",
+ "edit": "Edit Interest",
+ "followAll": "Follow All",
+ "unfollowAll": "Unfollow All"
+ },
+ "settings": {
+ "general": {
+ "title": "General",
+ "update": {
+ "title": "Update",
+ "subtitle": "Automatically download new update"
+ },
+ "lowPower": {
+ "title": "Low Power",
+ "subtitle": "Sustainable for low network environment"
+ },
+ "startup": {
+ "title": "Startup",
+ "subtitle": "Launch Lume at Login"
+ },
+ "media": {
+ "title": "Media",
+ "subtitle": "Automatically load media"
+ },
+ "hashtag": {
+ "title": "Hashtag",
+ "subtitle": "Show all hashtags in content"
+ },
+ "notification": {
+ "title": "Notification",
+ "subtitle": "Automatically send notification"
+ },
+ "translation": {
+ "title": "Translation",
+ "subtitle": "Translate text to your language"
+ },
+ "appearance": {
+ "title": "Appearance",
+ "light": "Light",
+ "dark": "Dark",
+ "system": "System"
+ }
+ },
+ "user": {
+ "title": "User"
+ },
+ "zap": {
+ "title": "Zap",
+ "nwc": "Connection String"
+ },
+ "backup": {
+ "title": "Backup",
+ "privkey": {
+ "title": "Private key",
+ "button": "Remove private key"
+ }
+ },
+ "advanced": {
+ "title": "Advanced",
+ "cache": {
+ "title": "Cache",
+ "subtitle": "Use for boost up nostr connection",
+ "button": "Clear"
+ },
+ "instant": {
+ "title": "Instant Zap",
+ "subtitle": "Zap with default amount, no confirmation"
+ },
+ "defaultAmount": "Default amount"
+ },
+ "about": {
+ "title": "About",
+ "version": "Version",
+ "checkUpdate": "Check for update",
+ "installUpdate": "Install"
+ }
+ },
+ "onboarding": {
+ "home": {
+ "title": "Your account was successfully created!",
+ "subtitle": "For starters, let's set up your profile.",
+ "profileSettings": "Profile Settings"
+ },
+ "profile": {
+ "title": "About you",
+ "subtitle": "Tell Lume about yourself to start building your home feed."
+ },
+ "finish": {
+ "title": "Profile setup complete!",
+ "subtitle": "You can exit the setup here and start using Lume.",
+ "report": "Report a issue"
+ }
+ },
+ "activity": {
+ "title": "Activity",
+ "empty": "Yo! Nothing new yet.",
+ "mention": "mention you",
+ "repost": "reposted",
+ "zap": "zapped",
+ "newReply": "New reply",
+ "boost": "Boost",
+ "boostSubtitle": "@ Someone has reposted to your note",
+ "conversation": "Conversation",
+ "conversationSubtitle": "@ Someone has replied to your note"
+ }
+}
diff --git a/src-tauri/locales/en.json b/src-tauri/locales/en.json
new file mode 100644
index 00000000..8400f6f8
--- /dev/null
+++ b/src-tauri/locales/en.json
@@ -0,0 +1,295 @@
+{
+ "global": {
+ "relay": "Relay",
+ "back": "Back",
+ "continue": "Continue",
+ "loading": "Loading",
+ "error": "Error",
+ "moveLeft": "Move Left",
+ "moveRight": "Move Right",
+ "newColumn": "New Column",
+ "inspect": "Inspect",
+ "loadMore": "Load more",
+ "delete": "Delete",
+ "refresh": "Refresh",
+ "cancel": "Cancel",
+ "save": "Save",
+ "post": "Post",
+ "update": "Update",
+ "noResult": "No results found.",
+ "emptyFeedTitle": "This feed is empty",
+ "emptyFeedSubtitle": "You can follow more users to build up your timeline",
+ "apiKey": "API Key",
+ "skip": "Skip",
+ "close": "Close"
+ },
+ "nip89": {
+ "unsupported": "Lume isn't support this event",
+ "openWith": "Open with"
+ },
+ "note": {
+ "showThread": "Show thread",
+ "showMore": "Show more",
+ "error": "Failed to fetch event.",
+ "posted": "posted",
+ "replied": "replied",
+ "reposted": "reposted",
+ "menu": {
+ "viewThread": "View thread",
+ "copyLink": "Copy shareable link",
+ "copyNoteId": "Copy note ID",
+ "copyAuthorId": "Copy author ID",
+ "viewAuthor": "View author",
+ "pinAuthor": "Pin author",
+ "copyRaw": "Copy raw event",
+ "mute": "Mute"
+ },
+ "buttons": {
+ "pin": "Pin",
+ "pinTooltip": "Pin Note",
+ "repost": "Repost",
+ "quote": "Quote",
+ "viewProfile": "View profile"
+ },
+ "zap": {
+ "zap": "Zap",
+ "tooltip": "Send zap",
+ "modalTitle": "Send zap to",
+ "messagePlaceholder": "Enter message (optional)",
+ "buttonFinish": "Zapped",
+ "buttonLoading": "Processing...",
+ "invoiceButton": "Scan to zap",
+ "invoiceFooter": "You must use Bitcoin wallet which support Lightning\nsuch as: Blue Wallet, Bitkit, Phoenix,..."
+ },
+ "reply": {
+ "single": "reply",
+ "plural": "replies",
+ "empty": "Be the first to Reply!"
+ }
+ },
+ "user": {
+ "avatar": "Avatar",
+ "displayName": "Display Name",
+ "name": "Name",
+ "bio": "Bio",
+ "lna": "Lightning address",
+ "website": "Website",
+ "verified": "Verified",
+ "unverified": "Unverified",
+ "follow": "Follow",
+ "unfollow": "Unfollow",
+ "latestPosts": "Latest posts",
+ "avatarButton": "Change avatar",
+ "coverButton": "Change cover",
+ "editProfile": "Edit profile",
+ "settings": "Settings",
+ "logout": "Log out",
+ "logoutConfirmTitle": "Are you sure!",
+ "logoutConfirmSubtitle": "You can always log back in at any time. If you just want to switch accounts, you can do that by adding an existing account."
+ },
+ "editor": {
+ "title": "New Post",
+ "placeholder": "What are you up to?",
+ "successMessage": "Your note has been published successfully.",
+ "replyPlaceholder": "Post your reply"
+ },
+ "search": {
+ "placeholder": "Type something to search...",
+ "empty": "Try searching for people, notes, or keywords"
+ },
+ "welcome": {
+ "title": "Lume is a magnificent client for Nostr to meet, explore\nand freely share your thoughts with everyone.",
+ "signup": "Join Nostr",
+ "login": "Login",
+ "footer": "Before joining Nostr, you can take time to learn more about Nostr"
+ },
+ "login": {
+ "title": "Welcome back, anon!",
+ "footer": "Lume will put your Private Key in Secure Storage depended on your OS Platform. It will be secured by Password or Biometric ID",
+ "loginWithAddress": "Login with Nostr Address",
+ "loginWithBunker": "Login with nsecBunker",
+ "or": "Or continue with",
+ "loginWithPrivkey": "Login with Private Key"
+ },
+ "loginWithAddress": {
+ "title": "Enter your Nostr Address"
+ },
+ "loginWithBunker": {
+ "title": "Enter your nsecbunker token"
+ },
+ "loginWithPrivkey": {
+ "title": "Enter your Private Key",
+ "subtitle": "Lume will put your private key to <1>{{service}}1>.\nIt will be secured by your OS."
+ },
+ "signup": {
+ "title": "Let's Get Started",
+ "subtitle": "Choose one of methods below to create your account",
+ "selfManageMethod": "Self-Managed",
+ "selfManageMethodDescription": "You create your keys and keep them safe.",
+ "providerMethod": "Managed by Provider",
+ "providerMethodDescription": "A 3rd party provider will handle your sign in keys for you."
+ },
+ "signupWithSelfManage": {
+ "title": "This is your new Account Key",
+ "subtitle": "Keep your key in safe place. If you lose this key, you will lose access to your account.",
+ "confirm1": "I understand the risk of lost private key.",
+ "confirm2": "I will make sure keep it safe and not sharing with anyone.",
+ "confirm3": "I understand I cannot recover private key.",
+ "button": "Save key & Continue"
+ },
+ "signupWithProvider": {
+ "title": "Let's set up your account on Nostr",
+ "username": "Username *",
+ "chooseProvider": "Choose a Provider",
+ "usernameFooter": "Use to login to Lume and other Nostr apps. You can choose provider you trust to manage your account",
+ "email": "Backup Email (optional)",
+ "emailFooter": "Use for recover your account if you lose your password"
+ },
+ "onboardingSettings": {
+ "title": "You're almost ready to use Lume.",
+ "subtitle": "Let's start personalizing your experience.",
+ "notification": {
+ "title": "Push notification",
+ "subtitle": "Enabling push notifications will allow you to receive notifications from Lume."
+ },
+ "lowPower": {
+ "title": "Low Power Mode",
+ "subtitle": "Limited relay connection and hide all media, sustainable for low network environment."
+ },
+ "translation": {
+ "title": "Translation (nostr.wine)",
+ "subtitle": "Translate text to your preferred language, powered by Nostr Wine."
+ },
+ "footer": "There are many more settings you can configure from the 'Settings' Screen. Be sure to visit it later."
+ },
+ "relays": {
+ "global": "Global",
+ "follows": "Follows",
+ "sidebar": {
+ "title": "Connected relays",
+ "empty": "Empty."
+ },
+ "relayView": {
+ "empty": "Could not load relay information 😬",
+ "owner": "Owner",
+ "contact": "Contact",
+ "software": "Software",
+ "nips": "Supported NIPs",
+ "limit": "Limitation",
+ "payment": "Open payment website",
+ "paymentNote": "You need to make a payment to connect this relay"
+ }
+ },
+ "suggestion": {
+ "title": "Suggested Follows",
+ "error": "Error. Cannot get trending users",
+ "button": "Save & Go back"
+ },
+ "interests": {
+ "title": "Interests",
+ "subtitle": "Pick things you'd like to see in your home feed.",
+ "edit": "Edit Interest",
+ "followAll": "Follow All",
+ "unfollowAll": "Unfollow All"
+ },
+ "settings": {
+ "general": {
+ "title": "General",
+ "update": {
+ "title": "Update",
+ "subtitle": "Automatically download new update"
+ },
+ "lowPower": {
+ "title": "Low Power",
+ "subtitle": "Sustainable for low network environment"
+ },
+ "startup": {
+ "title": "Startup",
+ "subtitle": "Launch Lume at Login"
+ },
+ "media": {
+ "title": "Media",
+ "subtitle": "Automatically load media"
+ },
+ "hashtag": {
+ "title": "Hashtag",
+ "subtitle": "Show all hashtags in content"
+ },
+ "notification": {
+ "title": "Notification",
+ "subtitle": "Automatically send notification"
+ },
+ "translation": {
+ "title": "Translation",
+ "subtitle": "Translate text to your language"
+ },
+ "appearance": {
+ "title": "Appearance",
+ "light": "Light",
+ "dark": "Dark",
+ "system": "System"
+ }
+ },
+ "user": {
+ "title": "User"
+ },
+ "zap": {
+ "title": "Zap",
+ "nwc": "Connection String"
+ },
+ "backup": {
+ "title": "Backup",
+ "privkey": {
+ "title": "Private key",
+ "button": "Remove private key"
+ }
+ },
+ "advanced": {
+ "title": "Advanced",
+ "cache": {
+ "title": "Cache",
+ "subtitle": "Use for boost up nostr connection",
+ "button": "Clear"
+ },
+ "instant": {
+ "title": "Instant Zap",
+ "subtitle": "Zap with default amount, no confirmation"
+ },
+ "defaultAmount": "Default amount"
+ },
+ "about": {
+ "title": "About",
+ "version": "Version",
+ "checkUpdate": "Check for update",
+ "installUpdate": "Install"
+ }
+ },
+ "onboarding": {
+ "home": {
+ "title": "Your account was successfully created!",
+ "subtitle": "For starters, let's set up your profile.",
+ "profileSettings": "Profile Settings"
+ },
+ "profile": {
+ "title": "About you",
+ "subtitle": "Tell Lume about yourself to start building your home feed."
+ },
+ "finish": {
+ "title": "Profile setup complete!",
+ "subtitle": "You can exit the setup here and start using Lume.",
+ "report": "Report a issue"
+ }
+ },
+ "activity": {
+ "title": "Activity",
+ "empty": "Yo! Nothing new yet.",
+ "mention": "mention you",
+ "repost": "reposted",
+ "zap": "zapped",
+ "newReply": "New reply",
+ "boost": "Boost",
+ "boostSubtitle": "@ Someone has reposted to your note",
+ "conversation": "Conversation",
+ "conversationSubtitle": "@ Someone has replied to your note"
+ }
+}
diff --git a/src-tauri/locales/ja.json b/src-tauri/locales/ja.json
new file mode 100644
index 00000000..8400f6f8
--- /dev/null
+++ b/src-tauri/locales/ja.json
@@ -0,0 +1,295 @@
+{
+ "global": {
+ "relay": "Relay",
+ "back": "Back",
+ "continue": "Continue",
+ "loading": "Loading",
+ "error": "Error",
+ "moveLeft": "Move Left",
+ "moveRight": "Move Right",
+ "newColumn": "New Column",
+ "inspect": "Inspect",
+ "loadMore": "Load more",
+ "delete": "Delete",
+ "refresh": "Refresh",
+ "cancel": "Cancel",
+ "save": "Save",
+ "post": "Post",
+ "update": "Update",
+ "noResult": "No results found.",
+ "emptyFeedTitle": "This feed is empty",
+ "emptyFeedSubtitle": "You can follow more users to build up your timeline",
+ "apiKey": "API Key",
+ "skip": "Skip",
+ "close": "Close"
+ },
+ "nip89": {
+ "unsupported": "Lume isn't support this event",
+ "openWith": "Open with"
+ },
+ "note": {
+ "showThread": "Show thread",
+ "showMore": "Show more",
+ "error": "Failed to fetch event.",
+ "posted": "posted",
+ "replied": "replied",
+ "reposted": "reposted",
+ "menu": {
+ "viewThread": "View thread",
+ "copyLink": "Copy shareable link",
+ "copyNoteId": "Copy note ID",
+ "copyAuthorId": "Copy author ID",
+ "viewAuthor": "View author",
+ "pinAuthor": "Pin author",
+ "copyRaw": "Copy raw event",
+ "mute": "Mute"
+ },
+ "buttons": {
+ "pin": "Pin",
+ "pinTooltip": "Pin Note",
+ "repost": "Repost",
+ "quote": "Quote",
+ "viewProfile": "View profile"
+ },
+ "zap": {
+ "zap": "Zap",
+ "tooltip": "Send zap",
+ "modalTitle": "Send zap to",
+ "messagePlaceholder": "Enter message (optional)",
+ "buttonFinish": "Zapped",
+ "buttonLoading": "Processing...",
+ "invoiceButton": "Scan to zap",
+ "invoiceFooter": "You must use Bitcoin wallet which support Lightning\nsuch as: Blue Wallet, Bitkit, Phoenix,..."
+ },
+ "reply": {
+ "single": "reply",
+ "plural": "replies",
+ "empty": "Be the first to Reply!"
+ }
+ },
+ "user": {
+ "avatar": "Avatar",
+ "displayName": "Display Name",
+ "name": "Name",
+ "bio": "Bio",
+ "lna": "Lightning address",
+ "website": "Website",
+ "verified": "Verified",
+ "unverified": "Unverified",
+ "follow": "Follow",
+ "unfollow": "Unfollow",
+ "latestPosts": "Latest posts",
+ "avatarButton": "Change avatar",
+ "coverButton": "Change cover",
+ "editProfile": "Edit profile",
+ "settings": "Settings",
+ "logout": "Log out",
+ "logoutConfirmTitle": "Are you sure!",
+ "logoutConfirmSubtitle": "You can always log back in at any time. If you just want to switch accounts, you can do that by adding an existing account."
+ },
+ "editor": {
+ "title": "New Post",
+ "placeholder": "What are you up to?",
+ "successMessage": "Your note has been published successfully.",
+ "replyPlaceholder": "Post your reply"
+ },
+ "search": {
+ "placeholder": "Type something to search...",
+ "empty": "Try searching for people, notes, or keywords"
+ },
+ "welcome": {
+ "title": "Lume is a magnificent client for Nostr to meet, explore\nand freely share your thoughts with everyone.",
+ "signup": "Join Nostr",
+ "login": "Login",
+ "footer": "Before joining Nostr, you can take time to learn more about Nostr"
+ },
+ "login": {
+ "title": "Welcome back, anon!",
+ "footer": "Lume will put your Private Key in Secure Storage depended on your OS Platform. It will be secured by Password or Biometric ID",
+ "loginWithAddress": "Login with Nostr Address",
+ "loginWithBunker": "Login with nsecBunker",
+ "or": "Or continue with",
+ "loginWithPrivkey": "Login with Private Key"
+ },
+ "loginWithAddress": {
+ "title": "Enter your Nostr Address"
+ },
+ "loginWithBunker": {
+ "title": "Enter your nsecbunker token"
+ },
+ "loginWithPrivkey": {
+ "title": "Enter your Private Key",
+ "subtitle": "Lume will put your private key to <1>{{service}}1>.\nIt will be secured by your OS."
+ },
+ "signup": {
+ "title": "Let's Get Started",
+ "subtitle": "Choose one of methods below to create your account",
+ "selfManageMethod": "Self-Managed",
+ "selfManageMethodDescription": "You create your keys and keep them safe.",
+ "providerMethod": "Managed by Provider",
+ "providerMethodDescription": "A 3rd party provider will handle your sign in keys for you."
+ },
+ "signupWithSelfManage": {
+ "title": "This is your new Account Key",
+ "subtitle": "Keep your key in safe place. If you lose this key, you will lose access to your account.",
+ "confirm1": "I understand the risk of lost private key.",
+ "confirm2": "I will make sure keep it safe and not sharing with anyone.",
+ "confirm3": "I understand I cannot recover private key.",
+ "button": "Save key & Continue"
+ },
+ "signupWithProvider": {
+ "title": "Let's set up your account on Nostr",
+ "username": "Username *",
+ "chooseProvider": "Choose a Provider",
+ "usernameFooter": "Use to login to Lume and other Nostr apps. You can choose provider you trust to manage your account",
+ "email": "Backup Email (optional)",
+ "emailFooter": "Use for recover your account if you lose your password"
+ },
+ "onboardingSettings": {
+ "title": "You're almost ready to use Lume.",
+ "subtitle": "Let's start personalizing your experience.",
+ "notification": {
+ "title": "Push notification",
+ "subtitle": "Enabling push notifications will allow you to receive notifications from Lume."
+ },
+ "lowPower": {
+ "title": "Low Power Mode",
+ "subtitle": "Limited relay connection and hide all media, sustainable for low network environment."
+ },
+ "translation": {
+ "title": "Translation (nostr.wine)",
+ "subtitle": "Translate text to your preferred language, powered by Nostr Wine."
+ },
+ "footer": "There are many more settings you can configure from the 'Settings' Screen. Be sure to visit it later."
+ },
+ "relays": {
+ "global": "Global",
+ "follows": "Follows",
+ "sidebar": {
+ "title": "Connected relays",
+ "empty": "Empty."
+ },
+ "relayView": {
+ "empty": "Could not load relay information 😬",
+ "owner": "Owner",
+ "contact": "Contact",
+ "software": "Software",
+ "nips": "Supported NIPs",
+ "limit": "Limitation",
+ "payment": "Open payment website",
+ "paymentNote": "You need to make a payment to connect this relay"
+ }
+ },
+ "suggestion": {
+ "title": "Suggested Follows",
+ "error": "Error. Cannot get trending users",
+ "button": "Save & Go back"
+ },
+ "interests": {
+ "title": "Interests",
+ "subtitle": "Pick things you'd like to see in your home feed.",
+ "edit": "Edit Interest",
+ "followAll": "Follow All",
+ "unfollowAll": "Unfollow All"
+ },
+ "settings": {
+ "general": {
+ "title": "General",
+ "update": {
+ "title": "Update",
+ "subtitle": "Automatically download new update"
+ },
+ "lowPower": {
+ "title": "Low Power",
+ "subtitle": "Sustainable for low network environment"
+ },
+ "startup": {
+ "title": "Startup",
+ "subtitle": "Launch Lume at Login"
+ },
+ "media": {
+ "title": "Media",
+ "subtitle": "Automatically load media"
+ },
+ "hashtag": {
+ "title": "Hashtag",
+ "subtitle": "Show all hashtags in content"
+ },
+ "notification": {
+ "title": "Notification",
+ "subtitle": "Automatically send notification"
+ },
+ "translation": {
+ "title": "Translation",
+ "subtitle": "Translate text to your language"
+ },
+ "appearance": {
+ "title": "Appearance",
+ "light": "Light",
+ "dark": "Dark",
+ "system": "System"
+ }
+ },
+ "user": {
+ "title": "User"
+ },
+ "zap": {
+ "title": "Zap",
+ "nwc": "Connection String"
+ },
+ "backup": {
+ "title": "Backup",
+ "privkey": {
+ "title": "Private key",
+ "button": "Remove private key"
+ }
+ },
+ "advanced": {
+ "title": "Advanced",
+ "cache": {
+ "title": "Cache",
+ "subtitle": "Use for boost up nostr connection",
+ "button": "Clear"
+ },
+ "instant": {
+ "title": "Instant Zap",
+ "subtitle": "Zap with default amount, no confirmation"
+ },
+ "defaultAmount": "Default amount"
+ },
+ "about": {
+ "title": "About",
+ "version": "Version",
+ "checkUpdate": "Check for update",
+ "installUpdate": "Install"
+ }
+ },
+ "onboarding": {
+ "home": {
+ "title": "Your account was successfully created!",
+ "subtitle": "For starters, let's set up your profile.",
+ "profileSettings": "Profile Settings"
+ },
+ "profile": {
+ "title": "About you",
+ "subtitle": "Tell Lume about yourself to start building your home feed."
+ },
+ "finish": {
+ "title": "Profile setup complete!",
+ "subtitle": "You can exit the setup here and start using Lume.",
+ "report": "Report a issue"
+ }
+ },
+ "activity": {
+ "title": "Activity",
+ "empty": "Yo! Nothing new yet.",
+ "mention": "mention you",
+ "repost": "reposted",
+ "zap": "zapped",
+ "newReply": "New reply",
+ "boost": "Boost",
+ "boostSubtitle": "@ Someone has reposted to your note",
+ "conversation": "Conversation",
+ "conversationSubtitle": "@ Someone has replied to your note"
+ }
+}
diff --git a/src-tauri/locales/ru.json b/src-tauri/locales/ru.json
new file mode 100644
index 00000000..8400f6f8
--- /dev/null
+++ b/src-tauri/locales/ru.json
@@ -0,0 +1,295 @@
+{
+ "global": {
+ "relay": "Relay",
+ "back": "Back",
+ "continue": "Continue",
+ "loading": "Loading",
+ "error": "Error",
+ "moveLeft": "Move Left",
+ "moveRight": "Move Right",
+ "newColumn": "New Column",
+ "inspect": "Inspect",
+ "loadMore": "Load more",
+ "delete": "Delete",
+ "refresh": "Refresh",
+ "cancel": "Cancel",
+ "save": "Save",
+ "post": "Post",
+ "update": "Update",
+ "noResult": "No results found.",
+ "emptyFeedTitle": "This feed is empty",
+ "emptyFeedSubtitle": "You can follow more users to build up your timeline",
+ "apiKey": "API Key",
+ "skip": "Skip",
+ "close": "Close"
+ },
+ "nip89": {
+ "unsupported": "Lume isn't support this event",
+ "openWith": "Open with"
+ },
+ "note": {
+ "showThread": "Show thread",
+ "showMore": "Show more",
+ "error": "Failed to fetch event.",
+ "posted": "posted",
+ "replied": "replied",
+ "reposted": "reposted",
+ "menu": {
+ "viewThread": "View thread",
+ "copyLink": "Copy shareable link",
+ "copyNoteId": "Copy note ID",
+ "copyAuthorId": "Copy author ID",
+ "viewAuthor": "View author",
+ "pinAuthor": "Pin author",
+ "copyRaw": "Copy raw event",
+ "mute": "Mute"
+ },
+ "buttons": {
+ "pin": "Pin",
+ "pinTooltip": "Pin Note",
+ "repost": "Repost",
+ "quote": "Quote",
+ "viewProfile": "View profile"
+ },
+ "zap": {
+ "zap": "Zap",
+ "tooltip": "Send zap",
+ "modalTitle": "Send zap to",
+ "messagePlaceholder": "Enter message (optional)",
+ "buttonFinish": "Zapped",
+ "buttonLoading": "Processing...",
+ "invoiceButton": "Scan to zap",
+ "invoiceFooter": "You must use Bitcoin wallet which support Lightning\nsuch as: Blue Wallet, Bitkit, Phoenix,..."
+ },
+ "reply": {
+ "single": "reply",
+ "plural": "replies",
+ "empty": "Be the first to Reply!"
+ }
+ },
+ "user": {
+ "avatar": "Avatar",
+ "displayName": "Display Name",
+ "name": "Name",
+ "bio": "Bio",
+ "lna": "Lightning address",
+ "website": "Website",
+ "verified": "Verified",
+ "unverified": "Unverified",
+ "follow": "Follow",
+ "unfollow": "Unfollow",
+ "latestPosts": "Latest posts",
+ "avatarButton": "Change avatar",
+ "coverButton": "Change cover",
+ "editProfile": "Edit profile",
+ "settings": "Settings",
+ "logout": "Log out",
+ "logoutConfirmTitle": "Are you sure!",
+ "logoutConfirmSubtitle": "You can always log back in at any time. If you just want to switch accounts, you can do that by adding an existing account."
+ },
+ "editor": {
+ "title": "New Post",
+ "placeholder": "What are you up to?",
+ "successMessage": "Your note has been published successfully.",
+ "replyPlaceholder": "Post your reply"
+ },
+ "search": {
+ "placeholder": "Type something to search...",
+ "empty": "Try searching for people, notes, or keywords"
+ },
+ "welcome": {
+ "title": "Lume is a magnificent client for Nostr to meet, explore\nand freely share your thoughts with everyone.",
+ "signup": "Join Nostr",
+ "login": "Login",
+ "footer": "Before joining Nostr, you can take time to learn more about Nostr"
+ },
+ "login": {
+ "title": "Welcome back, anon!",
+ "footer": "Lume will put your Private Key in Secure Storage depended on your OS Platform. It will be secured by Password or Biometric ID",
+ "loginWithAddress": "Login with Nostr Address",
+ "loginWithBunker": "Login with nsecBunker",
+ "or": "Or continue with",
+ "loginWithPrivkey": "Login with Private Key"
+ },
+ "loginWithAddress": {
+ "title": "Enter your Nostr Address"
+ },
+ "loginWithBunker": {
+ "title": "Enter your nsecbunker token"
+ },
+ "loginWithPrivkey": {
+ "title": "Enter your Private Key",
+ "subtitle": "Lume will put your private key to <1>{{service}}1>.\nIt will be secured by your OS."
+ },
+ "signup": {
+ "title": "Let's Get Started",
+ "subtitle": "Choose one of methods below to create your account",
+ "selfManageMethod": "Self-Managed",
+ "selfManageMethodDescription": "You create your keys and keep them safe.",
+ "providerMethod": "Managed by Provider",
+ "providerMethodDescription": "A 3rd party provider will handle your sign in keys for you."
+ },
+ "signupWithSelfManage": {
+ "title": "This is your new Account Key",
+ "subtitle": "Keep your key in safe place. If you lose this key, you will lose access to your account.",
+ "confirm1": "I understand the risk of lost private key.",
+ "confirm2": "I will make sure keep it safe and not sharing with anyone.",
+ "confirm3": "I understand I cannot recover private key.",
+ "button": "Save key & Continue"
+ },
+ "signupWithProvider": {
+ "title": "Let's set up your account on Nostr",
+ "username": "Username *",
+ "chooseProvider": "Choose a Provider",
+ "usernameFooter": "Use to login to Lume and other Nostr apps. You can choose provider you trust to manage your account",
+ "email": "Backup Email (optional)",
+ "emailFooter": "Use for recover your account if you lose your password"
+ },
+ "onboardingSettings": {
+ "title": "You're almost ready to use Lume.",
+ "subtitle": "Let's start personalizing your experience.",
+ "notification": {
+ "title": "Push notification",
+ "subtitle": "Enabling push notifications will allow you to receive notifications from Lume."
+ },
+ "lowPower": {
+ "title": "Low Power Mode",
+ "subtitle": "Limited relay connection and hide all media, sustainable for low network environment."
+ },
+ "translation": {
+ "title": "Translation (nostr.wine)",
+ "subtitle": "Translate text to your preferred language, powered by Nostr Wine."
+ },
+ "footer": "There are many more settings you can configure from the 'Settings' Screen. Be sure to visit it later."
+ },
+ "relays": {
+ "global": "Global",
+ "follows": "Follows",
+ "sidebar": {
+ "title": "Connected relays",
+ "empty": "Empty."
+ },
+ "relayView": {
+ "empty": "Could not load relay information 😬",
+ "owner": "Owner",
+ "contact": "Contact",
+ "software": "Software",
+ "nips": "Supported NIPs",
+ "limit": "Limitation",
+ "payment": "Open payment website",
+ "paymentNote": "You need to make a payment to connect this relay"
+ }
+ },
+ "suggestion": {
+ "title": "Suggested Follows",
+ "error": "Error. Cannot get trending users",
+ "button": "Save & Go back"
+ },
+ "interests": {
+ "title": "Interests",
+ "subtitle": "Pick things you'd like to see in your home feed.",
+ "edit": "Edit Interest",
+ "followAll": "Follow All",
+ "unfollowAll": "Unfollow All"
+ },
+ "settings": {
+ "general": {
+ "title": "General",
+ "update": {
+ "title": "Update",
+ "subtitle": "Automatically download new update"
+ },
+ "lowPower": {
+ "title": "Low Power",
+ "subtitle": "Sustainable for low network environment"
+ },
+ "startup": {
+ "title": "Startup",
+ "subtitle": "Launch Lume at Login"
+ },
+ "media": {
+ "title": "Media",
+ "subtitle": "Automatically load media"
+ },
+ "hashtag": {
+ "title": "Hashtag",
+ "subtitle": "Show all hashtags in content"
+ },
+ "notification": {
+ "title": "Notification",
+ "subtitle": "Automatically send notification"
+ },
+ "translation": {
+ "title": "Translation",
+ "subtitle": "Translate text to your language"
+ },
+ "appearance": {
+ "title": "Appearance",
+ "light": "Light",
+ "dark": "Dark",
+ "system": "System"
+ }
+ },
+ "user": {
+ "title": "User"
+ },
+ "zap": {
+ "title": "Zap",
+ "nwc": "Connection String"
+ },
+ "backup": {
+ "title": "Backup",
+ "privkey": {
+ "title": "Private key",
+ "button": "Remove private key"
+ }
+ },
+ "advanced": {
+ "title": "Advanced",
+ "cache": {
+ "title": "Cache",
+ "subtitle": "Use for boost up nostr connection",
+ "button": "Clear"
+ },
+ "instant": {
+ "title": "Instant Zap",
+ "subtitle": "Zap with default amount, no confirmation"
+ },
+ "defaultAmount": "Default amount"
+ },
+ "about": {
+ "title": "About",
+ "version": "Version",
+ "checkUpdate": "Check for update",
+ "installUpdate": "Install"
+ }
+ },
+ "onboarding": {
+ "home": {
+ "title": "Your account was successfully created!",
+ "subtitle": "For starters, let's set up your profile.",
+ "profileSettings": "Profile Settings"
+ },
+ "profile": {
+ "title": "About you",
+ "subtitle": "Tell Lume about yourself to start building your home feed."
+ },
+ "finish": {
+ "title": "Profile setup complete!",
+ "subtitle": "You can exit the setup here and start using Lume.",
+ "report": "Report a issue"
+ }
+ },
+ "activity": {
+ "title": "Activity",
+ "empty": "Yo! Nothing new yet.",
+ "mention": "mention you",
+ "repost": "reposted",
+ "zap": "zapped",
+ "newReply": "New reply",
+ "boost": "Boost",
+ "boostSubtitle": "@ Someone has reposted to your note",
+ "conversation": "Conversation",
+ "conversationSubtitle": "@ Someone has replied to your note"
+ }
+}
diff --git a/src-tauri/locales/vi.json b/src-tauri/locales/vi.json
new file mode 100644
index 00000000..8400f6f8
--- /dev/null
+++ b/src-tauri/locales/vi.json
@@ -0,0 +1,295 @@
+{
+ "global": {
+ "relay": "Relay",
+ "back": "Back",
+ "continue": "Continue",
+ "loading": "Loading",
+ "error": "Error",
+ "moveLeft": "Move Left",
+ "moveRight": "Move Right",
+ "newColumn": "New Column",
+ "inspect": "Inspect",
+ "loadMore": "Load more",
+ "delete": "Delete",
+ "refresh": "Refresh",
+ "cancel": "Cancel",
+ "save": "Save",
+ "post": "Post",
+ "update": "Update",
+ "noResult": "No results found.",
+ "emptyFeedTitle": "This feed is empty",
+ "emptyFeedSubtitle": "You can follow more users to build up your timeline",
+ "apiKey": "API Key",
+ "skip": "Skip",
+ "close": "Close"
+ },
+ "nip89": {
+ "unsupported": "Lume isn't support this event",
+ "openWith": "Open with"
+ },
+ "note": {
+ "showThread": "Show thread",
+ "showMore": "Show more",
+ "error": "Failed to fetch event.",
+ "posted": "posted",
+ "replied": "replied",
+ "reposted": "reposted",
+ "menu": {
+ "viewThread": "View thread",
+ "copyLink": "Copy shareable link",
+ "copyNoteId": "Copy note ID",
+ "copyAuthorId": "Copy author ID",
+ "viewAuthor": "View author",
+ "pinAuthor": "Pin author",
+ "copyRaw": "Copy raw event",
+ "mute": "Mute"
+ },
+ "buttons": {
+ "pin": "Pin",
+ "pinTooltip": "Pin Note",
+ "repost": "Repost",
+ "quote": "Quote",
+ "viewProfile": "View profile"
+ },
+ "zap": {
+ "zap": "Zap",
+ "tooltip": "Send zap",
+ "modalTitle": "Send zap to",
+ "messagePlaceholder": "Enter message (optional)",
+ "buttonFinish": "Zapped",
+ "buttonLoading": "Processing...",
+ "invoiceButton": "Scan to zap",
+ "invoiceFooter": "You must use Bitcoin wallet which support Lightning\nsuch as: Blue Wallet, Bitkit, Phoenix,..."
+ },
+ "reply": {
+ "single": "reply",
+ "plural": "replies",
+ "empty": "Be the first to Reply!"
+ }
+ },
+ "user": {
+ "avatar": "Avatar",
+ "displayName": "Display Name",
+ "name": "Name",
+ "bio": "Bio",
+ "lna": "Lightning address",
+ "website": "Website",
+ "verified": "Verified",
+ "unverified": "Unverified",
+ "follow": "Follow",
+ "unfollow": "Unfollow",
+ "latestPosts": "Latest posts",
+ "avatarButton": "Change avatar",
+ "coverButton": "Change cover",
+ "editProfile": "Edit profile",
+ "settings": "Settings",
+ "logout": "Log out",
+ "logoutConfirmTitle": "Are you sure!",
+ "logoutConfirmSubtitle": "You can always log back in at any time. If you just want to switch accounts, you can do that by adding an existing account."
+ },
+ "editor": {
+ "title": "New Post",
+ "placeholder": "What are you up to?",
+ "successMessage": "Your note has been published successfully.",
+ "replyPlaceholder": "Post your reply"
+ },
+ "search": {
+ "placeholder": "Type something to search...",
+ "empty": "Try searching for people, notes, or keywords"
+ },
+ "welcome": {
+ "title": "Lume is a magnificent client for Nostr to meet, explore\nand freely share your thoughts with everyone.",
+ "signup": "Join Nostr",
+ "login": "Login",
+ "footer": "Before joining Nostr, you can take time to learn more about Nostr"
+ },
+ "login": {
+ "title": "Welcome back, anon!",
+ "footer": "Lume will put your Private Key in Secure Storage depended on your OS Platform. It will be secured by Password or Biometric ID",
+ "loginWithAddress": "Login with Nostr Address",
+ "loginWithBunker": "Login with nsecBunker",
+ "or": "Or continue with",
+ "loginWithPrivkey": "Login with Private Key"
+ },
+ "loginWithAddress": {
+ "title": "Enter your Nostr Address"
+ },
+ "loginWithBunker": {
+ "title": "Enter your nsecbunker token"
+ },
+ "loginWithPrivkey": {
+ "title": "Enter your Private Key",
+ "subtitle": "Lume will put your private key to <1>{{service}}1>.\nIt will be secured by your OS."
+ },
+ "signup": {
+ "title": "Let's Get Started",
+ "subtitle": "Choose one of methods below to create your account",
+ "selfManageMethod": "Self-Managed",
+ "selfManageMethodDescription": "You create your keys and keep them safe.",
+ "providerMethod": "Managed by Provider",
+ "providerMethodDescription": "A 3rd party provider will handle your sign in keys for you."
+ },
+ "signupWithSelfManage": {
+ "title": "This is your new Account Key",
+ "subtitle": "Keep your key in safe place. If you lose this key, you will lose access to your account.",
+ "confirm1": "I understand the risk of lost private key.",
+ "confirm2": "I will make sure keep it safe and not sharing with anyone.",
+ "confirm3": "I understand I cannot recover private key.",
+ "button": "Save key & Continue"
+ },
+ "signupWithProvider": {
+ "title": "Let's set up your account on Nostr",
+ "username": "Username *",
+ "chooseProvider": "Choose a Provider",
+ "usernameFooter": "Use to login to Lume and other Nostr apps. You can choose provider you trust to manage your account",
+ "email": "Backup Email (optional)",
+ "emailFooter": "Use for recover your account if you lose your password"
+ },
+ "onboardingSettings": {
+ "title": "You're almost ready to use Lume.",
+ "subtitle": "Let's start personalizing your experience.",
+ "notification": {
+ "title": "Push notification",
+ "subtitle": "Enabling push notifications will allow you to receive notifications from Lume."
+ },
+ "lowPower": {
+ "title": "Low Power Mode",
+ "subtitle": "Limited relay connection and hide all media, sustainable for low network environment."
+ },
+ "translation": {
+ "title": "Translation (nostr.wine)",
+ "subtitle": "Translate text to your preferred language, powered by Nostr Wine."
+ },
+ "footer": "There are many more settings you can configure from the 'Settings' Screen. Be sure to visit it later."
+ },
+ "relays": {
+ "global": "Global",
+ "follows": "Follows",
+ "sidebar": {
+ "title": "Connected relays",
+ "empty": "Empty."
+ },
+ "relayView": {
+ "empty": "Could not load relay information 😬",
+ "owner": "Owner",
+ "contact": "Contact",
+ "software": "Software",
+ "nips": "Supported NIPs",
+ "limit": "Limitation",
+ "payment": "Open payment website",
+ "paymentNote": "You need to make a payment to connect this relay"
+ }
+ },
+ "suggestion": {
+ "title": "Suggested Follows",
+ "error": "Error. Cannot get trending users",
+ "button": "Save & Go back"
+ },
+ "interests": {
+ "title": "Interests",
+ "subtitle": "Pick things you'd like to see in your home feed.",
+ "edit": "Edit Interest",
+ "followAll": "Follow All",
+ "unfollowAll": "Unfollow All"
+ },
+ "settings": {
+ "general": {
+ "title": "General",
+ "update": {
+ "title": "Update",
+ "subtitle": "Automatically download new update"
+ },
+ "lowPower": {
+ "title": "Low Power",
+ "subtitle": "Sustainable for low network environment"
+ },
+ "startup": {
+ "title": "Startup",
+ "subtitle": "Launch Lume at Login"
+ },
+ "media": {
+ "title": "Media",
+ "subtitle": "Automatically load media"
+ },
+ "hashtag": {
+ "title": "Hashtag",
+ "subtitle": "Show all hashtags in content"
+ },
+ "notification": {
+ "title": "Notification",
+ "subtitle": "Automatically send notification"
+ },
+ "translation": {
+ "title": "Translation",
+ "subtitle": "Translate text to your language"
+ },
+ "appearance": {
+ "title": "Appearance",
+ "light": "Light",
+ "dark": "Dark",
+ "system": "System"
+ }
+ },
+ "user": {
+ "title": "User"
+ },
+ "zap": {
+ "title": "Zap",
+ "nwc": "Connection String"
+ },
+ "backup": {
+ "title": "Backup",
+ "privkey": {
+ "title": "Private key",
+ "button": "Remove private key"
+ }
+ },
+ "advanced": {
+ "title": "Advanced",
+ "cache": {
+ "title": "Cache",
+ "subtitle": "Use for boost up nostr connection",
+ "button": "Clear"
+ },
+ "instant": {
+ "title": "Instant Zap",
+ "subtitle": "Zap with default amount, no confirmation"
+ },
+ "defaultAmount": "Default amount"
+ },
+ "about": {
+ "title": "About",
+ "version": "Version",
+ "checkUpdate": "Check for update",
+ "installUpdate": "Install"
+ }
+ },
+ "onboarding": {
+ "home": {
+ "title": "Your account was successfully created!",
+ "subtitle": "For starters, let's set up your profile.",
+ "profileSettings": "Profile Settings"
+ },
+ "profile": {
+ "title": "About you",
+ "subtitle": "Tell Lume about yourself to start building your home feed."
+ },
+ "finish": {
+ "title": "Profile setup complete!",
+ "subtitle": "You can exit the setup here and start using Lume.",
+ "report": "Report a issue"
+ }
+ },
+ "activity": {
+ "title": "Activity",
+ "empty": "Yo! Nothing new yet.",
+ "mention": "mention you",
+ "repost": "reposted",
+ "zap": "zapped",
+ "newReply": "New reply",
+ "boost": "Boost",
+ "boostSubtitle": "@ Someone has reposted to your note",
+ "conversation": "Conversation",
+ "conversationSubtitle": "@ Someone has replied to your note"
+ }
+}
diff --git a/src-tauri/resources/.keep b/src-tauri/resources/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/src-tauri/resources/config.toml b/src-tauri/resources/config.toml
deleted file mode 100644
index 8cf06f1d..00000000
--- a/src-tauri/resources/config.toml
+++ /dev/null
@@ -1,108 +0,0 @@
-[info]
-relay_url = "
"
-name = "depot"
-description = "Nostr Relay inside Lume. Powered by nostr-rs-relay"
-pubkey = ""
-favicon = "favicon.ico"
-relay_icon = "https://example.test/img.png"
-#contact = "mailto:contact@example.com"
-
-[diagnostics]
-#tracing = false
-
-[database]
-engine = "sqlite"
-data_directory = "."
-max_conn = 8
-min_conn = 0
-
-[logging]
-#folder_path = "./log"
-#file_prefix = "nostr-relay"
-
-[network]
-address = "0.0.0.0"
-port = 6090
-#remote_ip_header = "x-forwarded-for"
-#remote_ip_header = "cf-connecting-ip"
-#ping_interval = 300
-
-[options]
-reject_future_seconds = 1800
-
-[limits]
-messages_per_sec = 10
-subscriptions_per_min = 10
-limit_scrapers = false
-
-[authorization]
-pubkey_whitelist = []
-nip42_auth = true
-nip42_dms = true
-
-[verified_users]
-mode = "passive"
-#domain_blacklist = ["wellorder.net"]
-#domain_whitelist = ["example.com"]
-verify_expiration = "1 week"
-#verify_update_frequency = "24 hours"
-max_consecutive_failures = 3
-
-[grpc]
-# gRPC interfaces for externalized decisions and other extensions to
-# functionality.
-#
-# Events can be authorized through an external service, by providing
-# the URL below. In the event the server is not accessible, events
-# will be permitted. The protobuf3 schema used is available in
-# `proto/nauthz.proto`.
-# event_admission_server = "http://[::1]:50051"
-
-# If the event admission server denies writes
-# in any case (excluding spam filtering).
-# This is reflected in the relay information document.
-# restricts_write = true
-
-[pay_to_relay]
-# Enable pay to relay
-#enabled = false
-
-# The cost to be admitted to relay
-#admission_cost = 4200
-
-# The cost in sats per post
-#cost_per_event = 0
-
-# Url of lnbits api
-#node_url = ""
-
-# LNBits api secret
-#api_secret = ""
-
-# Nostr direct message on signup
-#direct_message=false
-
-# Terms of service
-#terms_message = """
-#This service (and supporting services) are provided "as is", without warranty of any kind, express or implied.
-#
-#By using this service, you agree:
-#* Not to engage in spam or abuse the relay service
-#* Not to disseminate illegal content
-#* That requests to delete content cannot be guaranteed
-#* To use the service in compliance with all applicable laws
-#* To grant necessary rights to your content for unlimited time
-#* To be of legal age and have capacity to use this service
-#* That the service may be terminated at any time without notice
-#* That the content you publish may be removed at any time without notice
-#* To have your IP address collected to detect abuse or misuse
-#* To cooperate with the relay to combat abuse or misuse
-#* You may be exposed to content that you might find triggering or distasteful
-#* The relay operator is not liable for content produced by users of the relay
-#"""
-
-# Whether or not new sign ups should be allowed
-#sign_ups = false
-
-# optional if `direct_message=false`
-#secret_key = ""
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index bc04f7e0..3b5c8f66 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -26,7 +26,8 @@
"$VIDEO/*",
"$RESOURCE",
"$RESOURCE/*",
- "$RESOURCE/**"
+ "$RESOURCE/**",
+ "$RESOURCE/locales/*"
]
},
"http": {
@@ -34,7 +35,7 @@
},
"shell": {
"open": true,
- "scope": [{ "name": "bin/depot", "sidecar": true, "args": true }]
+ "scope": []
},
"updater": {
"endpoints": [
@@ -51,7 +52,7 @@
"depends": []
},
"externalBin": [],
- "resources": ["resources/*"],
+ "resources": ["resources/*", "./locales/*"],
"icon": [
"icons/32x32.png",
"icons/128x128.png",