Skip to content

Commit

Permalink
[ENG-1578] Missing localization & language detect and settings (#2037)
Browse files Browse the repository at this point in the history
* i18n privacy screen

* more missing translations

* language detector

* Language Settings

* sort german

* bump version to 0.2.3
  • Loading branch information
utkubakir committed Feb 2, 2024
1 parent 4032677 commit e2175aa
Show file tree
Hide file tree
Showing 24 changed files with 314 additions and 128 deletions.
2 changes: 1 addition & 1 deletion apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sd-desktop"
version = "0.2.2"
version = "0.2.3"
description = "The universal file manager."
authors = ["Spacedrive Technology Inc <support@spacedrive.com>"]
default-run = "sd-desktop"
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sd-core"
version = "0.2.2"
version = "0.2.3"
description = "Virtual distributed filesystem engine that powers Spacedrive."
authors = ["Spacedrive Technology Inc."]
rust-version = "1.73.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Link } from 'react-router-dom';
import { useBridgeQuery, useFeatureFlag } from '@sd/client';
import { useBridgeQuery } from '@sd/client';
import { Button, Tooltip } from '@sd/ui';
import { Icon, SubtleButton } from '~/components';
import { Icon } from '~/components';
import { useLocale } from '~/hooks';

import SidebarLink from '../../SidebarLayout/Link';
Expand All @@ -13,7 +12,7 @@ export default function DevicesSection() {
const { t } = useLocale();

return (
<Section name="Devices">
<Section name={t('devices')}>
{node && (
<SidebarLink className="group relative w-full" to={`node/${node.id}`} key={node.id}>
<Icon name="Laptop" className="mr-1 h-5 w-5" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Clock, Heart, Planet, Tag } from '@phosphor-icons/react';
import { useLibraryQuery } from '@sd/client';
import { useLocale } from '~/hooks';

import Icon from '../../SidebarLayout/Icon';
import SidebarLink from '../../SidebarLayout/Link';
Expand All @@ -9,25 +10,27 @@ export const COUNT_STYLE = `absolute right-1 min-w-[20px] top-1 flex h-[19px] px
export default function LibrarySection() {
const labelCount = useLibraryQuery(['labels.count']);

const { t } = useLocale();

return (
<div className="space-y-0.5">
<SidebarLink to="overview">
<Icon component={Planet} />
Overview
{t('overview')}
</SidebarLink>
<SidebarLink to="recents">
<Icon component={Clock} />
Recents
{t('recents')}
{/* <div className={COUNT_STYLE}>34</div> */}
</SidebarLink>
<SidebarLink to="favorites">
<Icon component={Heart} />
Favorites
{t('favorites')}
{/* <div className={COUNT_STYLE}>2</div> */}
</SidebarLink>
<SidebarLink to="labels">
<Icon component={Tag} />
Labels
{t('labels')}
<div className={COUNT_STYLE}>{labelCount.data || 0}</div>
</SidebarLink>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PropsWithChildren, useMemo } from 'react';
import { useBridgeQuery, useCache, useLibraryQuery, useNodes } from '@sd/client';
import { Button, toast, tw } from '@sd/ui';
import { Icon, IconName } from '~/components';
import { useLocale } from '~/hooks';
import { useHomeDir } from '~/hooks/useHomeDir';

import { useExplorerDroppable } from '../../../../Explorer/useExplorerDroppable';
Expand Down Expand Up @@ -39,6 +40,8 @@ export default function LocalSection() {
useNodes(result.data?.nodes);
const volumes = useCache(result.data?.items);

const { t } = useLocale();

// this will return an array of location ids that are also volumes
// { "/Mount/Point": 1, "/Mount/Point2": 2"}
const locationIdsForVolumes = useMemo(() => {
Expand Down Expand Up @@ -74,11 +77,11 @@ export default function LocalSection() {
);

return (
<Section name="Local">
<Section name={t('local')}>
<SeeMore>
<SidebarLink className="group relative w-full" to="network">
<SidebarIcon name="Globe" />
<Name>Network</Name>
<Name>{t('network')}</Name>
</SidebarLink>

{homeDir.data && (
Expand All @@ -87,7 +90,7 @@ export default function LocalSection() {
path={homeDir.data ?? ''}
>
<SidebarIcon name="Home" />
<Name>Home</Name>
<Name>{t('home')}</Name>
</EphemeralLocation>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useExplorerDroppable } from '~/app/$libraryId/Explorer/useExplorerDropp
import { useExplorerSearchParams } from '~/app/$libraryId/Explorer/util';
import { AddLocationButton } from '~/app/$libraryId/settings/library/locations/AddLocationButton';
import { Icon, SubtleButton } from '~/components';
import { useLocale } from '~/hooks';

import SidebarLink from '../../SidebarLayout/Link';
import Section from '../../SidebarLayout/Section';
Expand All @@ -24,9 +25,11 @@ export default function Locations() {
const locations = useCache(locationsQuery.data?.items);
const onlineLocations = useOnlineLocations();

const { t } = useLocale();

return (
<Section
name="Locations"
name={t('locations')}
actionArea={
<Link to="settings/library/locations">
<SubtleButton />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useLibraryMutation, useLibraryQuery, type SavedSearch } from '@sd/clien
import { Button } from '@sd/ui';
import { useExplorerDroppable } from '~/app/$libraryId/Explorer/useExplorerDroppable';
import { Folder } from '~/components';
import { useLocale } from '~/hooks';

import SidebarLink from '../../SidebarLayout/Link';
import Section from '../../SidebarLayout/Section';
Expand All @@ -23,6 +24,8 @@ export default function SavedSearches() {

const navigate = useNavigate();

const { t } = useLocale();

const deleteSavedSearch = useLibraryMutation(['search.saved.delete'], {
onSuccess() {
if (currentIndex !== undefined && savedSearches.data) {
Expand All @@ -40,7 +43,7 @@ export default function SavedSearches() {

return (
<Section
name="Saved Searches"
name={t('saved_searches')}
// actionArea={
// <Link to="settings/library/saved-searches">
// <SubtleButton />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import clsx from 'clsx';
import { t } from 'i18next';
import { NavLink, useMatch } from 'react-router-dom';
import { useCache, useLibraryQuery, useNodes, type Tag } from '@sd/client';
import { useExplorerDroppable } from '~/app/$libraryId/Explorer/useExplorerDroppable';
import { SubtleButton } from '~/components';
import { useLocale } from '~/hooks';

import SidebarLink from '../../SidebarLayout/Link';
import Section from '../../SidebarLayout/Section';
Expand All @@ -14,11 +16,13 @@ export default function TagsSection() {
useNodes(result.data?.nodes);
const tags = useCache(result.data?.items);

const { t } = useLocale();

if (!tags?.length) return null;

return (
<Section
name="Tags"
name={t('tags')}
actionArea={
<NavLink to="settings/library/tags">
<SubtleButton />
Expand Down
14 changes: 10 additions & 4 deletions interface/app/$libraryId/overview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Link } from 'react-router-dom';
import { useBridgeQuery, useCache, useLibraryQuery, useNodes } from '@sd/client';
import { useLocale } from '~/hooks';
import { useRouteTitle } from '~/hooks/useRouteTitle';
import { hardwareModelToIcon } from '~/util/hardware';

Expand All @@ -15,6 +16,9 @@ import StatisticItem from './StatCard';

export const Component = () => {
useRouteTitle('Overview');

const { t } = useLocale();

const locationsQuery = useLibraryQuery(['locations.list'], { keepPreviousData: true });
useNodes(locationsQuery.data?.nodes);
const locations = useCache(locationsQuery.data?.items) ?? [];
Expand All @@ -31,7 +35,9 @@ export const Component = () => {
<TopBarPortal
left={
<div className="flex items-center gap-2">
<span className="text-sm font-medium truncate">Library Overview</span>
<span className="truncate text-sm font-medium">
{t('library_overview')}
</span>
</div>
}
center={<SearchBar redirectToSearch />}
Expand Down Expand Up @@ -65,7 +71,7 @@ export const Component = () => {
// />
// }
/>
<div className="flex flex-col gap-3 pt-3 mt-4">
<div className="mt-4 flex flex-col gap-3 pt-3">
<OverviewSection>
<LibraryStatistics />
</OverviewSection>
Expand Down Expand Up @@ -132,11 +138,11 @@ export const Component = () => {
{/**/}
</OverviewSection>

<OverviewSection count={locations.length} title="Locations">
<OverviewSection count={locations.length} title={t('locations')}>
{locations?.map((item) => (
<Link key={item.id} to={`../location/${item.id}`}>
<StatisticItem
name={item.name || 'Unnamed Location'}
name={item.name || t('unnamed_location')}
icon="Folder"
totalSpace={item.size_in_bytes || [0]}
color="#0362FF"
Expand Down
40 changes: 37 additions & 3 deletions interface/app/$libraryId/settings/client/general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useZodForm
} from '@sd/client';
import { Button, Card, Input, Select, SelectOption, Slider, Switch, tw, z } from '@sd/ui';
import i18n from '~/app/I18n';
import { Icon } from '~/components';
import { useDebouncedFormWatch, useLocale } from '~/hooks';
import { usePlatform } from '~/util/Platform';
Expand All @@ -21,6 +22,16 @@ const NodeSettingLabel = tw.div`mb-1 text-xs font-medium`;
// https://doc.rust-lang.org/std/u16/index.html
const u16 = z.number().min(0).max(65_535);

const LANGUAGE_OPTIONS = [
{ value: 'en', label: 'English' },
{ value: 'de', label: 'Deutsch' },
{ value: 'es', label: 'Español' },
{ value: 'fr', label: 'Français' },
{ value: 'tr', label: 'Türkçe' },
{ value: 'zh-CN', label: '中文(简体)' },
{ value: 'zh-TW', label: '中文(繁體)' }
];

export const Component = () => {
const node = useBridgeQuery(['nodeState']);
const platform = usePlatform();
Expand Down Expand Up @@ -96,6 +107,7 @@ export const Component = () => {
title={t('general_settings')}
description={t('general_settings_description')}
/>
{/* Node Card */}
<Card className="px-5">
<div className="my-2 flex w-full flex-col">
<div className="flex flex-row items-center justify-between">
Expand Down Expand Up @@ -161,7 +173,7 @@ export const Component = () => {
}
}}
>
Open
{t('open')}
</Button>
{/* <Button size="sm" variant="outline">
Change
Expand All @@ -183,14 +195,35 @@ export const Component = () => {
</div> */}
</div>
</Card>

{/* Language Settings */}
<Setting mini title={t('language')} description={t('language_description')}>
<div className="flex h-[30px] gap-2">
<Select
value={i18n.language}
onChange={(e) => {
// add "i18nextLng" key to localStorage and set it to the selected language
i18n.changeLanguage(e);
localStorage.setItem('i18nextLng', e);
}}
containerClassName="h-[30px] whitespace-nowrap"
>
{LANGUAGE_OPTIONS.map((lang, key) => (
<SelectOption key={key} value={lang.value}>
{lang.label}
</SelectOption>
))}
</Select>
</div>
</Setting>
{/* Debug Mode */}
<Setting mini title={t('debug_mode')} description={t('debug_mode_description')}>
<Switch
size="md"
checked={debugState.enabled}
onClick={() => (debugState.enabled = !debugState.enabled)}
/>
</Setting>
{/* Background Processing */}
<Setting
mini
registerName="background_processing_percentage"
Expand Down Expand Up @@ -223,13 +256,14 @@ export const Component = () => {
/>
</div>
</Setting>
{/* Image Labeler */}
<Setting
mini
title={t('image_labeler_ai_model')}
description={t('image_labeler_ai_model_description')}
registerName="image_labeler_version"
>
<div className="flex h-[30px] gap-2">
<div className="flex h-[30px]">
<Controller
name="image_labeler_version"
disabled={node.data?.image_labeler_version == null}
Expand Down
8 changes: 5 additions & 3 deletions interface/app/$libraryId/settings/node/libraries/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { t } from 'i18next';
import { useBridgeQuery, useCache, useLibraryContext, useNodes } from '@sd/client';
import { Button, dialogManager } from '@sd/ui';
import { useLocale } from '~/hooks';

import { Heading } from '../../Layout';
import CreateDialog from './CreateDialog';
Expand All @@ -13,11 +13,13 @@ export const Component = () => {

const { library } = useLibraryContext();

const { t } = useLocale();

return (
<>
<Heading
title={t('libraries')}
description={t("libraries_description")}
description={t('libraries_description')}
rightArea={
<div className="flex-row space-x-2">
<Button
Expand All @@ -27,7 +29,7 @@ export const Component = () => {
dialogManager.create((dp) => <CreateDialog {...dp} />);
}}
>
{t("add_library")}
{t('add_library')}
</Button>
</div>
}
Expand Down
8 changes: 4 additions & 4 deletions interface/app/I18n.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import i18n from 'i18next';
// import LanguageDetector from 'i18next-browser-languagedetector';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import * as resources from 'virtual:i18next-loader';

i18n
// // detect user language
// // learn more: https://github.com/i18next/i18next-browser-languageDetector
// .use(LanguageDetector)
// detect user language
// learn more: https://github.com/i18next/i18next-browser-languageDetector
.use(LanguageDetector)
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
Expand Down
Loading

0 comments on commit e2175aa

Please sign in to comment.