mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-05-19 05:45:01 -04:00
Merge branch 'main' of https://github.com/Rocky43007/spacedrive
This commit is contained in:
BIN
Cargo.lock
generated
BIN
Cargo.lock
generated
Binary file not shown.
@@ -1,3 +1,5 @@
|
||||
- Make sure to run `pnpm i` if you make any change to the `package` mobile uses like `assets`.
|
||||
- If iOS build fails with `node not found` error, run `echo "export NODE_BINARY=$(command -v node)" >> .xcode.env.local` on `mobile/ios/` directory.
|
||||
- If XCode can't find node, run `ln -s "$(which node)" /usr/local/bin/node`
|
||||
- To view the logs from the Spacedrive Core API, run `xcrun simctl launch --console booted com.spacedrive.app` with the app built in debug mode.
|
||||
- If Rive Assets have been updated, run `pnpm mobile prebuild` to import the latest version of the `.riv` files into the project.
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
"deploymentTarget": "14.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
["./withRiveAssets.js"]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -56,21 +56,21 @@ afterEvaluate {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion safeExtGet("compileSdkVersion", 33)
|
||||
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
||||
jvmTarget = JavaVersion.VERSION_17.majorVersion
|
||||
}
|
||||
|
||||
namespace "com.spacedrive.core"
|
||||
defaultConfig {
|
||||
minSdkVersion safeExtGet("minSdkVersion", 28)
|
||||
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
||||
targetSdkVersion safeExtGet("targetSdkVersion", 34)
|
||||
versionCode 1
|
||||
versionName "0.2.0"
|
||||
}
|
||||
|
||||
@@ -21,44 +21,45 @@
|
||||
"@hookform/resolvers": "^3.1.0",
|
||||
"@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2",
|
||||
"@oscartbeaumont-sd/rspc-react": "=0.0.0-main-dc31e5b2",
|
||||
"@react-native-async-storage/async-storage": "~1.18.2",
|
||||
"@react-native-masked-view/masked-view": "^0.2.9",
|
||||
"@react-native-async-storage/async-storage": "~1.21.0",
|
||||
"@react-native-masked-view/masked-view": "^0.3.0",
|
||||
"@react-navigation/bottom-tabs": "^6.5.8",
|
||||
"@react-navigation/drawer": "^6.6.3",
|
||||
"@react-navigation/native": "^6.1.7",
|
||||
"@react-navigation/stack": "^6.3.17",
|
||||
"@sd/assets": "workspace:*",
|
||||
"@sd/client": "workspace:*",
|
||||
"@shopify/flash-list": "1.4.3",
|
||||
"@shopify/flash-list": "1.6.3",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"babel-preset-solid": "^1.8.9",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"event-target-polyfill": "^0.0.3",
|
||||
"expo": "~49.0.8",
|
||||
"expo-blur": "^12.4.1",
|
||||
"expo-build-properties": "~0.8.3",
|
||||
"expo-linking": "~5.0.2",
|
||||
"expo-media-library": "~15.4.1",
|
||||
"expo-splash-screen": "~0.20.5",
|
||||
"expo-status-bar": "~1.6.0",
|
||||
"expo": "~50.0.5",
|
||||
"expo-blur": "^12.9.1",
|
||||
"expo-build-properties": "~0.11.1",
|
||||
"expo-linking": "~6.2.2",
|
||||
"expo-media-library": "~15.9.1",
|
||||
"expo-splash-screen": "~0.26.4",
|
||||
"expo-status-bar": "~1.11.1",
|
||||
"intl": "^1.2.5",
|
||||
"lottie-react-native": "5.1.6",
|
||||
"lottie-react-native": "6.5.1",
|
||||
"metro-react-native-babel-transformer": "^0.77.0",
|
||||
"moti": "^0.26.0",
|
||||
"phosphor-react-native": "^2.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-hook-form": "^7.47.0",
|
||||
"react-native": "0.72.6",
|
||||
"react-native": "0.73.2",
|
||||
"react-native-circular-progress": "^1.3.9",
|
||||
"react-native-document-picker": "^9.0.1",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-gesture-handler": "~2.12.1",
|
||||
"react-native-gesture-handler": "~2.14.1",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-popup-menu": "^0.16.1",
|
||||
"react-native-reanimated": "~3.3.0",
|
||||
"react-native-safe-area-context": "4.6.3",
|
||||
"react-native-screens": "~3.22.1",
|
||||
"react-native-svg": "13.9.0",
|
||||
"react-native-reanimated": "~3.6.2",
|
||||
"react-native-safe-area-context": "4.8.2",
|
||||
"react-native-screens": "~3.29.0",
|
||||
"react-native-svg": "14.1.0",
|
||||
"react-native-wheel-color-picker": "^1.2.0",
|
||||
"rive-react-native": "^6.2.3",
|
||||
"solid-js": "^1.8.8",
|
||||
@@ -72,10 +73,10 @@
|
||||
"@babel/core": "^7.23.2",
|
||||
"@rnx-kit/metro-config": "^1.3.12",
|
||||
"@sd/config": "workspace:*",
|
||||
"@types/react": "^18.2.34",
|
||||
"@types/react": "^18.2.52",
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
"eslint-plugin-react-native": "^4.1.0",
|
||||
"react-native-svg-transformer": "^1.1.0",
|
||||
"typescript": "^5.2.2"
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
|
||||
import { SettingsStackScreenProps } from '~/navigation/tabs/SettingsStack';
|
||||
|
||||
import FolderIcon from '../icons/FolderIcon';
|
||||
import { Icon } from '../icons/Icon';
|
||||
import Fade from '../layout/Fade';
|
||||
import ImportModal from '../modal/ImportModal';
|
||||
import { LocationModal } from '../modal/location/LocationModal';
|
||||
@@ -39,7 +40,7 @@ const BrowseLocationItem: React.FC<BrowseLocationItemProps> = ({
|
||||
return (
|
||||
<Pressable onPress={onPress}>
|
||||
<View
|
||||
style={tw`h-auto w-[100px] flex-col justify-center gap-3 rounded-md border border-sidebar-line/50 bg-sidebar-box p-2`}
|
||||
style={tw`h-auto w-[110px] flex-col justify-center gap-3 rounded-md border border-sidebar-line/50 bg-sidebar-box p-2`}
|
||||
>
|
||||
<View style={tw`w-full flex-col justify-between gap-1`}>
|
||||
<View style={tw`flex-row items-center justify-between`}>
|
||||
@@ -61,7 +62,7 @@ const BrowseLocationItem: React.FC<BrowseLocationItemProps> = ({
|
||||
</Pressable>
|
||||
</View>
|
||||
<Text
|
||||
style={tw`w-full max-w-[75px] text-xs font-bold text-white`}
|
||||
style={tw`w-full max-w-[100px] text-xs font-bold text-white`}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{location.name}
|
||||
@@ -98,14 +99,19 @@ const BrowseLocations = () => {
|
||||
return (
|
||||
<View style={tw`gap-5`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between px-7`}>
|
||||
<Text style={tw`text-xl font-bold text-white`}>Locations</Text>
|
||||
<Text style={tw`text-lg font-bold text-white`}>Locations</Text>
|
||||
<View style={tw`flex-row gap-3`}>
|
||||
<Pressable
|
||||
disabled={result.data?.nodes.length === 0}
|
||||
onPress={() => {
|
||||
navigation.navigate('Locations');
|
||||
}}
|
||||
>
|
||||
<View style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent`}>
|
||||
<View
|
||||
style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent ${
|
||||
result.data?.nodes.length === 0 ? 'opacity-40' : 'opacity-100'
|
||||
}`}
|
||||
>
|
||||
<Eye weight="bold" size={18} style={tw`text-white`} />
|
||||
</View>
|
||||
</Pressable>
|
||||
@@ -121,6 +127,16 @@ const BrowseLocations = () => {
|
||||
<Fade color="mobile-screen" width={30} height="100%">
|
||||
<FlatList
|
||||
data={locations}
|
||||
ListEmptyComponent={() => (
|
||||
<View
|
||||
style={tw`relative h-auto w-[85.5vw] flex-col items-center justify-center overflow-hidden rounded-md border border-dashed border-sidebar-line p-4`}
|
||||
>
|
||||
<Icon name="Folder" size={38} />
|
||||
<Text style={tw`mt-2 text-center font-medium text-ink-dull`}>
|
||||
You have no locations
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
contentContainerStyle={tw`px-7`}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
ItemSeparatorComponent={() => <View style={tw`w-2`} />}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ModalRef } from '~/components/layout/Modal';
|
||||
import { tw, twStyle } from '~/lib/tailwind';
|
||||
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
|
||||
|
||||
import { Icon } from '../icons/Icon';
|
||||
import Fade from '../layout/Fade';
|
||||
import CreateTagModal from '../modal/tag/CreateTagModal';
|
||||
import { TagModal } from '../modal/tag/TagModal';
|
||||
@@ -63,10 +64,14 @@ const BrowseTags = () => {
|
||||
return (
|
||||
<View style={tw`gap-5`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between px-7`}>
|
||||
<Text style={tw`text-xl font-bold text-white`}>Tags</Text>
|
||||
<Text style={tw`text-lg font-bold text-white`}>Tags</Text>
|
||||
<View style={tw`flex-row gap-3`}>
|
||||
<Pressable>
|
||||
<View style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent`}>
|
||||
<View
|
||||
style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent ${
|
||||
tags.data?.nodes.length === 0 ? 'opacity-40' : 'opacity-100'
|
||||
}`}
|
||||
>
|
||||
<Eye weight="bold" size={18} style={tw`text-white`} />
|
||||
</View>
|
||||
</Pressable>
|
||||
@@ -82,10 +87,22 @@ const BrowseTags = () => {
|
||||
<Fade color="mobile-screen" width={30} height="100%">
|
||||
<FlatList
|
||||
data={tagData}
|
||||
ListEmptyComponent={() => (
|
||||
<View
|
||||
style={tw`relative h-auto w-[85.5vw] flex-col items-center justify-center overflow-hidden rounded-md border border-dashed border-sidebar-line p-4`}
|
||||
>
|
||||
<Icon name="Tags" size={38} />
|
||||
<Text style={tw`mt-2 text-center font-medium text-ink-dull`}>
|
||||
You have no tags
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
renderItem={({ item }) => (
|
||||
<BrowseTagItem
|
||||
tag={item}
|
||||
onPress={() => navigation.navigate('Tag', { id: item.id })}
|
||||
onPress={() =>
|
||||
navigation.navigate('Tag', { id: item.id, color: item.color! })
|
||||
}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
|
||||
@@ -29,7 +29,7 @@ const CATEGORIES_LIST = [
|
||||
const Categories = () => {
|
||||
return (
|
||||
<View style={tw`relative gap-5`}>
|
||||
<Text style={tw`px-7 text-xl font-bold text-white`}>Library</Text>
|
||||
<Text style={tw`text-lg font-bold text-white px-7`}>Library</Text>
|
||||
<Fade width={30} height="100%" color="mobile-screen">
|
||||
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
|
||||
<View style={tw`flex-row gap-2 px-7`}>
|
||||
|
||||
@@ -11,7 +11,7 @@ const Jobs = () => {
|
||||
return (
|
||||
<View style={tw`gap-5`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between px-7`}>
|
||||
<Text style={tw`text-xl font-bold text-white`}>Jobs</Text>
|
||||
<Text style={tw`text-lg font-bold text-white`}>Jobs</Text>
|
||||
</View>
|
||||
<Fade color="mobile-screen" height="100%" width={30}>
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
||||
@@ -45,7 +45,7 @@ const Job = ({ progress, message, error }: JobProps) => {
|
||||
: tw.color('accent');
|
||||
return (
|
||||
<View
|
||||
style={tw`h-auto w-[310px] flex-col rounded-md border border-sidebar-line/50 bg-sidebar-box`}
|
||||
style={tw`h-[170px] w-[310px] flex-col rounded-md border border-sidebar-line/50 bg-sidebar-box`}
|
||||
>
|
||||
<View
|
||||
style={tw`w-full flex-row items-center justify-between rounded-t-md border-b border-sidebar-line/80 bg-mobile-header/50 px-5 py-2`}
|
||||
@@ -56,7 +56,7 @@ const Job = ({ progress, message, error }: JobProps) => {
|
||||
</View>
|
||||
<DotsThreeOutlineVertical weight="fill" size={20} color={tw.color('ink-faint')} />
|
||||
</View>
|
||||
<View style={tw`mx-auto flex-1 flex-row items-center justify-between gap-5 px-5 py-2`}>
|
||||
<View style={tw`mx-auto flex-1 flex-row items-center justify-between gap-5 px-5 py-3`}>
|
||||
<AnimatedCircularProgress
|
||||
size={80}
|
||||
width={7}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { FlashList } from '@shopify/flash-list';
|
||||
import { Rows, SquaresFour } from 'phosphor-react-native';
|
||||
import { AnimatePresence, MotiView } from 'moti';
|
||||
import { MonitorPlay, Rows, SlidersHorizontal, SquaresFour } from 'phosphor-react-native';
|
||||
import { useState } from 'react';
|
||||
import { Pressable, View } from 'react-native';
|
||||
import { isPath, type ExplorerItem } from '@sd/client';
|
||||
import SortByMenu from '~/components/menu/SortByMenu';
|
||||
import Layout from '~/constants/Layout';
|
||||
import { tw } from '~/lib/tailwind';
|
||||
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
|
||||
import { getExplorerStore } from '~/stores/explorerStore';
|
||||
import { ExplorerLayoutMode, getExplorerStore, useExplorerStore } from '~/stores/explorerStore';
|
||||
import { useActionsModalStore } from '~/stores/modalStore';
|
||||
|
||||
import FileItem from './FileItem';
|
||||
@@ -20,10 +20,10 @@ type ExplorerProps = {
|
||||
|
||||
const Explorer = ({ items }: ExplorerProps) => {
|
||||
const navigation = useNavigation<BrowseStackScreenProps<'Location'>['navigation']>();
|
||||
const explorerStore = useExplorerStore();
|
||||
const [layoutMode, setLayoutMode] = useState<ExplorerLayoutMode>(getExplorerStore().layoutMode);
|
||||
|
||||
const [layoutMode, setLayoutMode] = useState<'grid' | 'list'>(getExplorerStore().layoutMode);
|
||||
|
||||
function changeLayoutMode(kind: 'grid' | 'list') {
|
||||
function changeLayoutMode(kind: ExplorerLayoutMode) {
|
||||
// We need to keep layoutMode as a state to make sure flash-list re-renders.
|
||||
setLayoutMode(kind);
|
||||
getExplorerStore().layoutMode = kind;
|
||||
@@ -44,13 +44,30 @@ const Explorer = ({ items }: ExplorerProps) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={tw`flex-1`}>
|
||||
<View style={tw`flex-1 bg-mobile-screen`}>
|
||||
{/* Header */}
|
||||
<View style={tw`flex flex-row items-center justify-between p-3`}>
|
||||
<View style={tw`flex flex-row items-center justify-between`}>
|
||||
{/* Sort By */}
|
||||
<SortByMenu />
|
||||
{/* <SortByMenu /> */}
|
||||
<AnimatePresence>
|
||||
{explorerStore.toggleMenu && (
|
||||
<MotiView
|
||||
from={{ translateY: -70 }}
|
||||
animate={{ translateY: 0 }}
|
||||
transition={{ type: 'timing', duration: 300 }}
|
||||
exit={{ translateY: -70 }}
|
||||
>
|
||||
<ExplorerMenu
|
||||
changeLayoutMode={(kind: ExplorerLayoutMode) => {
|
||||
changeLayoutMode(kind);
|
||||
}}
|
||||
layoutMode={layoutMode}
|
||||
/>
|
||||
</MotiView>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
{/* Layout (Grid/List) */}
|
||||
{layoutMode === 'grid' ? (
|
||||
{/* {layoutMode === 'grid' ? (
|
||||
<Pressable onPress={() => changeLayoutMode('list')}>
|
||||
<SquaresFour color={tw.color('ink')} size={23} />
|
||||
</Pressable>
|
||||
@@ -58,7 +75,7 @@ const Explorer = ({ items }: ExplorerProps) => {
|
||||
<Pressable onPress={() => changeLayoutMode('grid')}>
|
||||
<Rows color={tw.color('ink')} size={23} />
|
||||
</Pressable>
|
||||
)}
|
||||
)} */}
|
||||
</View>
|
||||
{/* Items */}
|
||||
{items && (
|
||||
@@ -94,4 +111,39 @@ const Explorer = ({ items }: ExplorerProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
interface ExplorerMenuProps {
|
||||
layoutMode: ExplorerLayoutMode;
|
||||
changeLayoutMode: (kind: ExplorerLayoutMode) => void;
|
||||
}
|
||||
|
||||
const ExplorerMenu = ({ layoutMode, changeLayoutMode }: ExplorerMenuProps) => {
|
||||
return (
|
||||
<View
|
||||
style={tw`w-screen flex-row justify-between border-b border-app-line/50 bg-mobile-header px-7 py-4`}
|
||||
>
|
||||
<View style={tw`flex-row gap-3`}>
|
||||
<Pressable onPress={() => changeLayoutMode('grid')}>
|
||||
<SquaresFour
|
||||
color={tw.color(layoutMode === 'grid' ? 'text-accent' : 'text-ink-dull')}
|
||||
size={23}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => changeLayoutMode('list')}>
|
||||
<Rows
|
||||
color={tw.color(layoutMode === 'list' ? 'text-accent' : 'text-ink-dull')}
|
||||
size={23}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => changeLayoutMode('media')}>
|
||||
<MonitorPlay
|
||||
color={tw.color(layoutMode === 'media' ? 'text-accent' : 'text-ink-dull')}
|
||||
size={23}
|
||||
/>
|
||||
</Pressable>
|
||||
</View>
|
||||
<SlidersHorizontal style={tw`text-ink-dull`} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default Explorer;
|
||||
|
||||
@@ -1,24 +1,48 @@
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { ArrowLeft, MagnifyingGlass } from 'phosphor-react-native';
|
||||
import { StackHeaderProps } from '@react-navigation/stack';
|
||||
import { ArrowLeft, DotsThreeOutline, MagnifyingGlass } from 'phosphor-react-native';
|
||||
import { lazy } from 'react';
|
||||
import { Pressable, Text, View } from 'react-native';
|
||||
import { tw } from '~/lib/tailwind';
|
||||
import { Platform, Pressable, Text, View } from 'react-native';
|
||||
import { tw, twStyle } from '~/lib/tailwind';
|
||||
import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore';
|
||||
|
||||
import { Icon } from '../icons/Icon';
|
||||
|
||||
//Not all pages use these components - so we lazy load for performance
|
||||
const BrowseLibraryManager = lazy(() => import('../browse/DrawerLibraryManager'));
|
||||
const Search = lazy(() => import('../inputs/Search'));
|
||||
|
||||
interface Props {
|
||||
type HeaderProps = {
|
||||
title?: string; //title of the page
|
||||
showLibrary?: boolean; //show the library manager
|
||||
searchType?: 'explorer' | 'location'; //Temporary
|
||||
navBack?: boolean; //navigate back to the previous screen
|
||||
}
|
||||
headerKind?: 'default' | 'location' | 'tag'; //kind of header
|
||||
route?: never;
|
||||
routeTitle?: never;
|
||||
};
|
||||
|
||||
//you can pass in a routeTitle only if route is passed in
|
||||
type Props =
|
||||
| HeaderProps
|
||||
| ({
|
||||
route: StackHeaderProps;
|
||||
routeTitle?: boolean;
|
||||
} & Omit<HeaderProps, 'route' | 'routeTitle'>);
|
||||
|
||||
// Default header with search bar and button to open drawer
|
||||
export default function Header({ title, showLibrary, searchType, navBack }: Props) {
|
||||
export default function Header({
|
||||
title,
|
||||
showLibrary,
|
||||
searchType,
|
||||
navBack,
|
||||
route,
|
||||
routeTitle,
|
||||
headerKind = 'default'
|
||||
}: Props) {
|
||||
const navigation = useNavigation();
|
||||
|
||||
const explorerStore = useExplorerStore();
|
||||
const routeParams = route?.route.params as any;
|
||||
const SearchType = () => {
|
||||
switch (searchType) {
|
||||
case 'explorer':
|
||||
@@ -29,9 +53,30 @@ export default function Header({ title, showLibrary, searchType, navBack }: Prop
|
||||
return null;
|
||||
}
|
||||
};
|
||||
const HeaderIconKind = () => {
|
||||
switch (headerKind) {
|
||||
case 'location':
|
||||
return <Icon size={32} name="Folder" />;
|
||||
case 'tag':
|
||||
return (
|
||||
<View
|
||||
style={twStyle('h-6 w-6 rounded-full', {
|
||||
backgroundColor: routeParams.color
|
||||
})}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={tw`relative h-auto w-full border-b border-app-line/50 bg-mobile-header pt-10`}>
|
||||
<View
|
||||
style={twStyle(
|
||||
'relative h-auto w-full border-b border-app-line/50 bg-mobile-header',
|
||||
Platform.OS === 'android' ? 'pt-5' : 'pt-10'
|
||||
)}
|
||||
>
|
||||
<View style={tw`mx-auto mt-5 h-auto w-full justify-center px-7 pb-5`}>
|
||||
<View style={tw`w-full flex-row items-center justify-between`}>
|
||||
<View style={tw`flex-row items-center gap-5`}>
|
||||
@@ -44,16 +89,41 @@ export default function Header({ title, showLibrary, searchType, navBack }: Prop
|
||||
<ArrowLeft size={23} color={tw.color('ink')} />
|
||||
</Pressable>
|
||||
)}
|
||||
<Text style={tw`text-[24px] font-bold text-white`}>{title}</Text>
|
||||
<View style={tw`flex-row items-center gap-2`}>
|
||||
<HeaderIconKind />
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={tw`max-w-[190px] text-lg font-bold text-white`}
|
||||
>
|
||||
{title || (routeTitle && route?.options.title)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={tw`flex-row items-center gap-3`}>
|
||||
<Pressable onPress={() => navigation.navigate('Search')}>
|
||||
<MagnifyingGlass
|
||||
size={20}
|
||||
weight="bold"
|
||||
color={tw.color('text-zinc-300')}
|
||||
/>
|
||||
</Pressable>
|
||||
{(headerKind === 'location' || headerKind === 'tag') && (
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
getExplorerStore().toggleMenu = !explorerStore.toggleMenu;
|
||||
}}
|
||||
>
|
||||
<DotsThreeOutline
|
||||
size={24}
|
||||
color={tw.color(
|
||||
explorerStore.toggleMenu ? 'text-accent' : 'text-zinc-300'
|
||||
)}
|
||||
/>
|
||||
</Pressable>
|
||||
)}
|
||||
</View>
|
||||
<Pressable onPress={() => navigation.navigate('Search')}>
|
||||
<MagnifyingGlass
|
||||
size={20}
|
||||
weight="bold"
|
||||
color={tw.color('text-zinc-300')}
|
||||
/>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
{showLibrary && <BrowseLibraryManager style="mt-4" />}
|
||||
{searchType && <SearchType />}
|
||||
</View>
|
||||
|
||||
@@ -34,8 +34,10 @@ export function SettingsItem(props: SettingsItemProps) {
|
||||
)}
|
||||
<View
|
||||
style={twStyle(
|
||||
`flex-1 flex-row items-center justify-between py-4`,
|
||||
borderRounded !== 'rounded-b-md' && 'border-b border-app-input'
|
||||
`flex-1 flex-row items-center justify-between border-b py-4`,
|
||||
borderRounded !== 'rounded-b-md'
|
||||
? 'border-app-input'
|
||||
: 'border-transparent'
|
||||
)}
|
||||
>
|
||||
<Text style={tw`text-sm font-medium text-ink`}>{props.title}</Text>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/n
|
||||
import { StackScreenProps } from '@react-navigation/stack';
|
||||
import { BlurView } from 'expo-blur';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Platform, StyleSheet } from 'react-native';
|
||||
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
|
||||
import Rive, { RiveRef } from 'rive-react-native';
|
||||
import { Style } from 'twrnc/dist/esm/types';
|
||||
@@ -106,7 +106,12 @@ export default function TabNavigator() {
|
||||
position: 'absolute',
|
||||
backgroundColor: tw.color('mobile-navtab'),
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: tw.color('app-line/50')
|
||||
borderTopColor: tw.color('app-line/50'),
|
||||
height: Platform.OS === 'android' ? 60 : 80,
|
||||
paddingVertical: 5
|
||||
},
|
||||
tabBarItemStyle: {
|
||||
marginBottom: Platform.OS === 'android' ? 10 : 0
|
||||
},
|
||||
tabBarBackground: () => (
|
||||
<BlurView tint="dark" intensity={50} style={StyleSheet.absoluteFill} />
|
||||
@@ -121,14 +126,21 @@ export default function TabNavigator() {
|
||||
key={screen.name + index}
|
||||
name={screen.name}
|
||||
component={screen.component}
|
||||
options={{
|
||||
options={({ navigation }) => ({
|
||||
tabBarLabel: screen.label,
|
||||
tabBarLabelStyle: screen.labelStyle,
|
||||
tabBarIcon: () => (
|
||||
<TouchableWithoutFeedback>{screen.icon}</TouchableWithoutFeedback>
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() => {
|
||||
navigation.navigate(screen.name);
|
||||
setActiveIndex(index);
|
||||
}}
|
||||
>
|
||||
{screen.icon}
|
||||
</TouchableWithoutFeedback>
|
||||
),
|
||||
tabBarTestID: screen.testID
|
||||
}}
|
||||
})}
|
||||
listeners={() => ({
|
||||
tabPress: () => {
|
||||
setActiveIndex(index);
|
||||
@@ -158,8 +170,10 @@ const TabBarButton = ({
|
||||
const ref = useRef<RiveRef>(null);
|
||||
useEffect(() => {
|
||||
if (active && ref.current) {
|
||||
ref.current?.play();
|
||||
} else ref.current?.stop();
|
||||
ref.current?.play('animate');
|
||||
} else {
|
||||
ref.current?.stop();
|
||||
}
|
||||
}, [active]);
|
||||
return (
|
||||
<Rive
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { CompositeScreenProps } from '@react-navigation/native';
|
||||
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
|
||||
import { ArrowLeft } from 'phosphor-react-native';
|
||||
import Header from '~/components/header/Header';
|
||||
import { tw } from '~/lib/tailwind';
|
||||
import BrowseScreen from '~/screens/browse';
|
||||
@@ -32,8 +31,8 @@ export default function BrowseStack() {
|
||||
name="Location"
|
||||
component={LocationScreen}
|
||||
options={{
|
||||
headerBackImage: () => (
|
||||
<ArrowLeft size={23} color={tw.color('ink')} style={tw`ml-2`} />
|
||||
header: (route) => (
|
||||
<Header route={route} headerKind="location" routeTitle navBack />
|
||||
)
|
||||
}}
|
||||
/>
|
||||
@@ -48,9 +47,7 @@ export default function BrowseStack() {
|
||||
name="Tag"
|
||||
component={TagScreen}
|
||||
options={{
|
||||
headerBackImage: () => (
|
||||
<ArrowLeft size={23} color={tw.color('ink')} style={tw`ml-2`} />
|
||||
)
|
||||
header: (route) => <Header routeTitle route={route} headerKind="tag" navBack />
|
||||
}}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
@@ -61,7 +58,7 @@ export type BrowseStackParamList = {
|
||||
Browse: undefined;
|
||||
Location: { id: number; path?: string };
|
||||
Locations: undefined;
|
||||
Tag: { id: number };
|
||||
Tag: { id: number; color: string };
|
||||
};
|
||||
|
||||
export type BrowseStackScreenProps<Screen extends keyof BrowseStackParamList> =
|
||||
|
||||
@@ -105,7 +105,7 @@ const LocationItem: React.FC<LocationItemProps> = ({
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
style={tw`w-auto max-w-[160px] truncate text-sm font-bold text-white`}
|
||||
style={tw`w-auto max-w-[160px] text-sm font-bold text-white`}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{location.name}
|
||||
@@ -114,7 +114,7 @@ const LocationItem: React.FC<LocationItemProps> = ({
|
||||
<View style={tw`flex-row items-center gap-3`}>
|
||||
<View style={tw`rounded-md bg-app-input p-1.5`}>
|
||||
<Text
|
||||
style={tw`truncate text-left text-xs font-bold text-ink-dull`}
|
||||
style={tw`text-left text-xs font-bold text-ink-dull`}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{`${byteSize(location.size_in_bytes)}`}
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function BrowseScreen() {
|
||||
const height = useBottomTabBarHeight();
|
||||
return (
|
||||
<ScrollView style={twStyle('flex-1 bg-mobile-screen', { marginBottom: height })}>
|
||||
<View style={twStyle('justify-between gap-3 py-5')}>
|
||||
<View style={twStyle('justify-between gap-6 py-5')}>
|
||||
{/*Categories*/}
|
||||
<Categories />
|
||||
{/* Locations */}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
TagSimple
|
||||
} from 'phosphor-react-native';
|
||||
import React from 'react';
|
||||
import { SectionList, Text, TouchableWithoutFeedback, View } from 'react-native';
|
||||
import { Platform, SectionList, Text, TouchableWithoutFeedback, View } from 'react-native';
|
||||
import { DebugState, useDebugState, useDebugStateEnabler } from '@sd/client';
|
||||
import { SettingsItem } from '~/components/settings/SettingsItem';
|
||||
import { tw, twStyle } from '~/lib/tailwind';
|
||||
@@ -143,7 +143,7 @@ export default function SettingsScreen({ navigation }: SettingsStackScreenProps<
|
||||
<View style={tw`flex-1 bg-mobile-screen px-7`}>
|
||||
<SectionList
|
||||
sections={sections(debugState)}
|
||||
contentContainerStyle={tw`py-5`}
|
||||
contentContainerStyle={tw`h-auto pb-5 pt-3`}
|
||||
renderItem={({ item }) => (
|
||||
<SettingsItem
|
||||
title={item.title}
|
||||
@@ -164,9 +164,10 @@ export default function SettingsScreen({ navigation }: SettingsStackScreenProps<
|
||||
|
||||
function FooterComponent() {
|
||||
const onClick = useDebugStateEnabler();
|
||||
|
||||
return (
|
||||
<View style={tw`mb-4 mt-6 items-center`}>
|
||||
<View
|
||||
style={twStyle(Platform.OS === 'android' ? 'mb-14 mt-4' : 'mb-20 mt-5', 'items-center')}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={onClick}>
|
||||
<Text style={tw`text-base font-bold text-ink`}>Spacedrive</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { resetStore } from '@sd/client';
|
||||
import { proxy, useSnapshot } from 'valtio';
|
||||
import { proxySet } from 'valtio/utils';
|
||||
import { resetStore } from '@sd/client';
|
||||
|
||||
// TODO: Add "media"
|
||||
export type ExplorerLayoutMode = 'list' | 'grid';
|
||||
export type ExplorerLayoutMode = 'list' | 'grid' | "media"
|
||||
|
||||
export type ExplorerKind = 'Location' | 'Tag' | 'Space';
|
||||
|
||||
@@ -11,6 +11,7 @@ const state = {
|
||||
locationId: null as number | null,
|
||||
path: '',
|
||||
layoutMode: 'grid' as ExplorerLayoutMode,
|
||||
toggleMenu: false as boolean,
|
||||
// Using gridNumColumns instead of fixed size. We dynamically calculate the item size.
|
||||
gridNumColumns: 3,
|
||||
listItemSize: 65,
|
||||
|
||||
102
apps/mobile/withRiveAssets.js
Normal file
102
apps/mobile/withRiveAssets.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* If you add an asset you need to run `npx expo prebuild`
|
||||
* If you rename or delete an asset you need to run `npx expo prebuild --clean` to delete them in your android and ios folder as well.
|
||||
*/
|
||||
|
||||
const {
|
||||
withDangerousMod,
|
||||
withXcodeProject,
|
||||
IOSConfig,
|
||||
} = require("@expo/config-plugins");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// Specify the source directory of your assets
|
||||
const ASSET_SOURCE_DIR = "assets/rive";
|
||||
|
||||
const IOS_GROUP_NAME = "Rivassets";
|
||||
|
||||
const withRiveAssets = (config) => {
|
||||
config = addAndroidResources(config);
|
||||
config = addIOSResources(config);
|
||||
return config;
|
||||
};
|
||||
|
||||
// Code inspired by https://github.com/rive-app/rive-react-native/issues/185#issuecomment-1593396573
|
||||
function addAndroidResources(config) {
|
||||
return withDangerousMod(config, [
|
||||
"android",
|
||||
async (config) => {
|
||||
// Get the path to the Android project directory
|
||||
const projectRoot = config.modRequest.projectRoot;
|
||||
|
||||
// Get the path to the Android resources directory
|
||||
const resDir = path.join(
|
||||
projectRoot,
|
||||
"android",
|
||||
"app",
|
||||
"src",
|
||||
"main",
|
||||
"res"
|
||||
);
|
||||
|
||||
// Create the 'raw' directory if it doesn't exist
|
||||
const rawDir = path.join(resDir, "raw");
|
||||
fs.mkdirSync(rawDir, { recursive: true });
|
||||
|
||||
// Get the path to the assets directory
|
||||
const assetSourcePath = path.join(projectRoot, ASSET_SOURCE_DIR);
|
||||
|
||||
// Retrieve all files in the assets directory
|
||||
const assetFiles = fs.readdirSync(assetSourcePath);
|
||||
|
||||
// Move each asset file to the resources 'raw' directory
|
||||
for (const assetFile of assetFiles) {
|
||||
const srcAssetPath = path.join(assetSourcePath, assetFile);
|
||||
const destAssetPath = path.join(rawDir, assetFile);
|
||||
fs.copyFileSync(srcAssetPath, destAssetPath);
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
// Code inspired by https://github.com/expo/expo/blob/61f8cf8d4b3cf5f8bf61f346476ebdb4aff40545/packages/expo-font/plugin/src/withFontsIos.ts
|
||||
function addIOSResources(config) {
|
||||
return withXcodeProject(config, async (config) => {
|
||||
const project = config.modResults;
|
||||
const platformProjectRoot = config.modRequest.platformProjectRoot;
|
||||
|
||||
// Create Assets group in project
|
||||
IOSConfig.XcodeUtils.ensureGroupRecursively(project, IOS_GROUP_NAME);
|
||||
|
||||
// Get riv filepaths
|
||||
const projectRoot = config.modRequest.projectRoot;
|
||||
const assetSourcePath = path.join(projectRoot, ASSET_SOURCE_DIR);
|
||||
const assetFiles = fs.readdirSync(assetSourcePath);
|
||||
const assetFilesPaths = assetFiles.map(
|
||||
(assetFile) => `${assetSourcePath}/${assetFile}`
|
||||
);
|
||||
|
||||
// Add assets to group
|
||||
addIOSResourceFile(project, platformProjectRoot, assetFilesPaths);
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
function addIOSResourceFile(project, platformRoot, assetFilesPaths) {
|
||||
for (const riveFile of assetFilesPaths) {
|
||||
const riveFilePath = path.relative(platformRoot, riveFile);
|
||||
IOSConfig.XcodeUtils.addResourceFileToGroup({
|
||||
filepath: riveFilePath,
|
||||
groupName: IOS_GROUP_NAME,
|
||||
project,
|
||||
isBuildFile: true,
|
||||
verbose: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = withRiveAssets;
|
||||
@@ -24,14 +24,7 @@ pub async fn declare_actors(library: &Arc<Library>, node: &Arc<Node>) {
|
||||
let library = library.clone();
|
||||
let node = node.clone();
|
||||
|
||||
move || {
|
||||
send::run_actor(
|
||||
library.db.clone(),
|
||||
library.id,
|
||||
library.sync.clone(),
|
||||
node.clone(),
|
||||
)
|
||||
}
|
||||
move || send::run_actor(library.id, library.sync.clone(), node.clone())
|
||||
},
|
||||
autorun,
|
||||
)
|
||||
|
||||
@@ -2,8 +2,6 @@ use super::CompressedCRDTOperations;
|
||||
|
||||
use sd_cloud_api::RequestConfigProvider;
|
||||
use sd_core_sync::{GetOpsArgs, SyncMessage, NTP64};
|
||||
use sd_prisma::prisma::{instance, PrismaClient};
|
||||
use sd_utils::from_bytes_to_uuid;
|
||||
use uuid::Uuid;
|
||||
|
||||
use std::{sync::Arc, time::Duration};
|
||||
@@ -13,24 +11,22 @@ use tokio::time::sleep;
|
||||
use super::err_break;
|
||||
|
||||
pub async fn run_actor(
|
||||
db: Arc<PrismaClient>,
|
||||
library_id: Uuid,
|
||||
sync: Arc<sd_core_sync::Manager>,
|
||||
cloud_api_config_provider: Arc<impl RequestConfigProvider>,
|
||||
) {
|
||||
loop {
|
||||
loop {
|
||||
let instances = err_break!(
|
||||
db.instance()
|
||||
.find_many(vec![])
|
||||
.select(instance::select!({ pub_id }))
|
||||
.exec()
|
||||
.await
|
||||
)
|
||||
.into_iter()
|
||||
.map(|i| from_bytes_to_uuid(&i.pub_id))
|
||||
.collect::<Vec<_>>();
|
||||
// all available instances will have a default timestamp from create_instance
|
||||
let instances = sync
|
||||
.timestamps
|
||||
.read()
|
||||
.await
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// obtains a lock on the timestamp collections for the instances we have
|
||||
let req_adds = err_break!(
|
||||
sd_cloud_api::library::message_collections::request_add(
|
||||
cloud_api_config_provider.get_request_config().await,
|
||||
@@ -44,6 +40,7 @@ pub async fn run_actor(
|
||||
|
||||
use sd_cloud_api::library::message_collections::do_add;
|
||||
|
||||
// gets new operations for each instance to send to cloud
|
||||
for req_add in req_adds {
|
||||
let ops = err_break!(
|
||||
sync.get_ops(GetOpsArgs {
|
||||
@@ -83,6 +80,7 @@ pub async fn run_actor(
|
||||
break;
|
||||
}
|
||||
|
||||
// uses lock we acquired earlier to send the operations to the cloud
|
||||
err_break!(
|
||||
do_add(
|
||||
cloud_api_config_provider.get_request_config().await,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ArrowClockwise, Info } from '@phosphor-icons/react';
|
||||
import { memo, useEffect, useMemo } from 'react';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useSearchParams as useRawSearchParams } from 'react-router-dom';
|
||||
import { stringify } from 'uuid';
|
||||
import {
|
||||
@@ -143,7 +143,7 @@ const LocationExplorer = ({ location }: { location: Location; path?: string }) =
|
||||
<Folder size={22} className="mt-[-1px]" />
|
||||
<span className="truncate text-sm font-medium">{title}</span>
|
||||
{!locationOnline && (
|
||||
<Tooltip label={t('location_offline_tooltip')}>
|
||||
<Tooltip label={t('location_disconnected_tooltip')}>
|
||||
<Info className="text-ink-faint" />
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -28,6 +28,7 @@ const LANGUAGE_OPTIONS = [
|
||||
{ value: 'es', label: 'Español' },
|
||||
{ value: 'fr', label: 'Français' },
|
||||
{ value: 'tr', label: 'Türkçe' },
|
||||
{ value: 'nl', label: 'Nederlands'},
|
||||
{ value: 'zh-CN', label: '中文(简体)' },
|
||||
{ value: 'zh-TW', label: '中文(繁體)' }
|
||||
];
|
||||
@@ -201,8 +202,8 @@ export const Component = () => {
|
||||
<Select
|
||||
value={i18n.language}
|
||||
onChange={(e) => {
|
||||
// add "i18nextLng" key to localStorage and set it to the selected language
|
||||
i18n.changeLanguage(e);
|
||||
// add "i18nextLng" key to localStorage and set it to the selected language
|
||||
localStorage.setItem('i18nextLng', e);
|
||||
}}
|
||||
containerClassName="h-[30px] whitespace-nowrap"
|
||||
|
||||
@@ -56,23 +56,33 @@ export default ({ location }: Props) => {
|
||||
<div className="flex grow" />
|
||||
<div className="flex h-[45px] w-full max-w-fit space-x-2 p-2">
|
||||
{/* This is a fake button, do not add disabled prop pls */}
|
||||
<Button
|
||||
onClick={(e: { stopPropagation: () => void }) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
variant="gray"
|
||||
className="pointer-events-none flex !px-2 !py-1.5"
|
||||
<Tooltip
|
||||
position="top"
|
||||
tooltipClassName="max-w-[140px]"
|
||||
label={
|
||||
online
|
||||
? t('location_connected_tooltip')
|
||||
: t('location_disconnected_tooltip')
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'h-2 w-2 rounded-full',
|
||||
online ? 'bg-green-500' : 'bg-red-500'
|
||||
)}
|
||||
/>
|
||||
<span className="ml-1.5 text-xs text-ink-dull">
|
||||
{online ? t('online') : t('offline')}
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={(e: { stopPropagation: () => void }) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
variant="gray"
|
||||
className="pointer-events-none flex !px-2 !py-1.5"
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'h-2 w-2 rounded-full',
|
||||
online ? 'bg-green-500' : 'bg-red-500'
|
||||
)}
|
||||
/>
|
||||
<span className="ml-1.5 text-xs text-ink-dull">
|
||||
{online ? t('connected') : t('disconnected')}
|
||||
</span>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Button
|
||||
onClick={(e: { stopPropagation: () => void }) => {
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -13,8 +13,14 @@ i18n
|
||||
// for all options read: https://www.i18next.com/overview/configuration-options
|
||||
.init({
|
||||
resources,
|
||||
load: 'languageOnly',
|
||||
detection: {
|
||||
// We need to convert due to ES syntactical rules (e.g. ch-TW -> ch_TW) and vite's virtual module stuff -_-
|
||||
// NOTE: This whole issue sounds very error-prone...
|
||||
convertDetectedLanguage: (lng) => lng.replace('-', '_')
|
||||
},
|
||||
// debug: true,
|
||||
fallbackLng: 'en',
|
||||
nonExplicitSupportedLngs: true,
|
||||
ns: ['common'],
|
||||
fallbackNS: 'common',
|
||||
defaultNS: 'common'
|
||||
|
||||
@@ -142,7 +142,6 @@
|
||||
"failed_to_resume_job": "Aufgabe konnte nicht fortgesetzt werden.",
|
||||
"failed_to_update_location_settings": "Standorteinstellungen konnten nicht aktualisiert werden",
|
||||
"favorite": "Favorit",
|
||||
"favorites": "Favoriten",
|
||||
"file_indexing_rules": "Dateiindizierungsregeln",
|
||||
"filters": "Filter",
|
||||
"forward": "Vorwärts",
|
||||
@@ -194,9 +193,6 @@
|
||||
"keybinds_description": "Client-Tastenkombinationen anzeigen und verwalten",
|
||||
"keys": "Schlüssel",
|
||||
"kilometers": "Kilometer",
|
||||
"labels": "Labels",
|
||||
"language": "Sprache",
|
||||
"language_description": "Ändern Sie die Sprache der Spacedrive-Benutzeroberfläche",
|
||||
"learn_more_about_telemetry": "Mehr über Telemetrie erfahren",
|
||||
"libraries": "Bibliotheken",
|
||||
"libraries_description": "Die Datenbank enthält alle Bibliotheksdaten und Dateimetadaten.",
|
||||
@@ -213,7 +209,8 @@
|
||||
"local_node": "Lokaler Knoten",
|
||||
"location_display_name_info": "Der Name dieses Standorts, so wird er in der Seitenleiste angezeigt. Wird den eigentlichen Ordner auf der Festplatte nicht umbenennen.",
|
||||
"location_is_already_linked": "Standort ist bereits verknüpft",
|
||||
"location_offline_tooltip": "Standort ist offline, Sie können immer noch durchsuchen und organisieren.",
|
||||
"location_connected_tooltip": "Der Standort wird auf Änderungen überwacht",
|
||||
"location_disconnected_tooltip": "Die Position wird nicht auf Änderungen überwacht",
|
||||
"location_path_info": "Der Pfad zu diesem Standort, hier werden die Dateien auf der Festplatte gespeichert.",
|
||||
"location_type": "Standorttyp",
|
||||
"location_type_managed": "Spacedrive wird Dateien für Sie sortieren. Wenn der Standort nicht leer ist, wird ein \"spacedrive\" Ordner erstellt.",
|
||||
@@ -287,7 +284,6 @@
|
||||
"quick_preview": "Schnellvorschau",
|
||||
"quick_view": "Schnellansicht",
|
||||
"recent_jobs": "Aktuelle Aufgaben",
|
||||
"recents": "Zuletzt verwendet",
|
||||
"regen_labels": "Labels erneuern",
|
||||
"regen_thumbnails": "Vorschaubilder erneuern",
|
||||
"regenerate_thumbs": "Vorschaubilder neu generieren",
|
||||
@@ -364,5 +360,10 @@
|
||||
"your_account": "Ihr Konto",
|
||||
"your_account_description": "Spacedrive-Konto und -Informationen.",
|
||||
"your_local_network": "Ihr lokales Netzwerk",
|
||||
"your_privacy": "Ihre Privatsphäre"
|
||||
"your_privacy": "Ihre Privatsphäre",
|
||||
"recents": "Zuletzt verwendet",
|
||||
"favorites": "Favoriten",
|
||||
"labels": "Labels",
|
||||
"language": "Sprache",
|
||||
"language_description": "Ändern Sie die Sprache der Spacedrive-Benutzeroberfläche"
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
"deselect": "Deselect",
|
||||
"details": "Details",
|
||||
"devices": "Devices",
|
||||
"disconnected": "Disconnected",
|
||||
"devices_coming_soon_tooltip": "Coming soon! This alpha release doesn't include library sync, it will be ready very soon.",
|
||||
"direction": "Direction",
|
||||
"disabled": "Disabled",
|
||||
@@ -209,7 +210,8 @@
|
||||
"local_node": "Local Node",
|
||||
"location_display_name_info": "The name of this Location, this is what will be displayed in the sidebar. Will not rename the actual folder on disk.",
|
||||
"location_is_already_linked": "Location is already linked",
|
||||
"location_offline_tooltip": "Location is offline, you can still browse and organize.",
|
||||
"location_connected_tooltip": "Location is being watched for changes",
|
||||
"location_disconnected_tooltip": "Location is not being watched for changes",
|
||||
"location_path_info": "The path to this Location, this is where the files will be stored on disk.",
|
||||
"location_type": "Location Type",
|
||||
"location_type_managed": "Spacedrive will sort files for you. If Location isn't empty a \"spacedrive\" folder will be created.",
|
||||
|
||||
@@ -142,7 +142,6 @@
|
||||
"failed_to_resume_job": "Error al reanudar el trabajo.",
|
||||
"failed_to_update_location_settings": "Error al actualizar configuraciones de ubicación",
|
||||
"favorite": "Favorito",
|
||||
"favorites": "Favoritos",
|
||||
"file_indexing_rules": "Reglas de indexación de archivos",
|
||||
"filters": "Filtros",
|
||||
"forward": "Adelante",
|
||||
@@ -194,9 +193,6 @@
|
||||
"keybinds_description": "Ver y administrar atajos de teclado del cliente",
|
||||
"keys": "Claves",
|
||||
"kilometers": "Kilómetros",
|
||||
"labels": "Etiquetas",
|
||||
"language": "Idioma",
|
||||
"language_description": "Cambiar el idioma de la interfaz de Spacedrive",
|
||||
"learn_more_about_telemetry": "Aprende más sobre la telemetría",
|
||||
"libraries": "Bibliotecas",
|
||||
"libraries_description": "La base de datos contiene todos los datos de la biblioteca y metadatos de archivos.",
|
||||
@@ -213,7 +209,8 @@
|
||||
"local_node": "Nodo Local",
|
||||
"location_display_name_info": "El nombre de esta Ubicación, esto es lo que se mostrará en la barra lateral. No renombrará la carpeta real en el disco.",
|
||||
"location_is_already_linked": "Ubicación ya está vinculada",
|
||||
"location_offline_tooltip": "La ubicación está fuera de línea, aún puedes navegar y organizar.",
|
||||
"location_connected_tooltip": "La ubicación está siendo vigilada en busca de cambios",
|
||||
"location_disconnected_tooltip": "La ubicación no está siendo vigilada en busca de cambios",
|
||||
"location_path_info": "La ruta a esta Ubicación, aquí es donde los archivos serán almacenados en el disco.",
|
||||
"location_type": "Tipo de Ubicación",
|
||||
"location_type_managed": "Spacedrive ordenará los archivos por ti. Si la Ubicación no está vacía se creará una carpeta \"spacedrive\".",
|
||||
@@ -287,7 +284,6 @@
|
||||
"quick_preview": "Vista rápida",
|
||||
"quick_view": "Vista rápida",
|
||||
"recent_jobs": "Trabajos recientes",
|
||||
"recents": "Recientes",
|
||||
"regen_labels": "Regenerar Etiquetas",
|
||||
"regen_thumbnails": "Regenerar Miniaturas",
|
||||
"regenerate_thumbs": "Regenerar Miniaturas",
|
||||
@@ -364,5 +360,10 @@
|
||||
"your_account": "Tu cuenta",
|
||||
"your_account_description": "Cuenta de Spacedrive e información.",
|
||||
"your_local_network": "Tu Red Local",
|
||||
"your_privacy": "Tu Privacidad"
|
||||
"your_privacy": "Tu Privacidad",
|
||||
"recents": "Recientes",
|
||||
"favorites": "Favoritos",
|
||||
"labels": "Etiquetas",
|
||||
"language": "Idioma",
|
||||
"language_description": "Cambiar el idioma de la interfaz de Spacedrive"
|
||||
}
|
||||
|
||||
@@ -141,7 +141,6 @@
|
||||
"failed_to_resume_job": "Échec de la reprise du travail.",
|
||||
"failed_to_update_location_settings": "Échec de la mise à jour des paramètres de l'emplacement",
|
||||
"favorite": "Favori",
|
||||
"favorites": "Favoris",
|
||||
"file_indexing_rules": "Règles d'indexation des fichiers",
|
||||
"filters": "Filtres",
|
||||
"forward": "Avancer",
|
||||
@@ -193,9 +192,6 @@
|
||||
"keybinds_description": "Afficher et gérer les raccourcis clavier du client",
|
||||
"keys": "Clés",
|
||||
"kilometers": "Kilomètres",
|
||||
"labels": "Étiquettes",
|
||||
"language": "Langue",
|
||||
"language_description": "Changer la langue de l'interface Spacedrive",
|
||||
"learn_more_about_telemetry": "En savoir plus sur la télémesure",
|
||||
"libraries": "Bibliothèques",
|
||||
"libraries_description": "La base de données contient toutes les données de la bibliothèque et les métadonnées des fichiers.",
|
||||
@@ -212,7 +208,8 @@
|
||||
"local_node": "Nœud local",
|
||||
"location_display_name_info": "Le nom de cet emplacement, c'est ce qui sera affiché dans la barre latérale. Ne renommera pas le dossier réel sur le disque.",
|
||||
"location_is_already_linked": "L'emplacement est déjà lié",
|
||||
"location_offline_tooltip": "L'emplacement est hors ligne, vous pouvez toujours parcourir et organiser.",
|
||||
"location_connected_tooltip": "L'emplacement est surveillé pour les changements",
|
||||
"location_disconnected_tooltip": "L'emplacement n'est pas surveillé pour les changements",
|
||||
"location_path_info": "Le chemin vers cet emplacement, c'est là que les fichiers seront stockés sur le disque.",
|
||||
"location_type": "Type d'emplacement",
|
||||
"location_type_managed": "Spacedrive triera les fichiers pour vous. Si l'emplacement n'est pas vide, un dossier \"spacedrive\" sera créé.",
|
||||
@@ -286,7 +283,6 @@
|
||||
"quick_preview": "Aperçu rapide",
|
||||
"quick_view": "Vue rapide",
|
||||
"recent_jobs": "Travaux récents",
|
||||
"recents": "Récents",
|
||||
"regen_labels": "Régénérer les étiquettes",
|
||||
"regen_thumbnails": "Régénérer les vignettes",
|
||||
"regenerate_thumbs": "Régénérer les miniatures",
|
||||
@@ -363,5 +359,10 @@
|
||||
"your_account": "Votre compte",
|
||||
"your_account_description": "Compte et informations Spacedrive.",
|
||||
"your_local_network": "Votre réseau local",
|
||||
"your_privacy": "Votre confidentialité"
|
||||
"your_privacy": "Votre confidentialité",
|
||||
"recents": "Récents",
|
||||
"favorites": "Favoris",
|
||||
"labels": "Étiquettes",
|
||||
"language": "Langue",
|
||||
"language_description": "Changer la langue de l'interface Spacedrive"
|
||||
}
|
||||
|
||||
369
interface/locales/nl/common.json
Normal file
369
interface/locales/nl/common.json
Normal file
@@ -0,0 +1,369 @@
|
||||
{
|
||||
"about": "Over",
|
||||
"about_vision_text": "Veel van ons hebben meerdere cloud accounts, schijven waarvan geen back-ups worden gemaakt en gegevens die het risico lopen verloren te gaan. We zijn afhankelijk van clouddiensten als Google Photos en iCloud, maar zitten vast met een beperkte capaciteit en vrijwel geen interoperabiliteit tussen diensten en besturingssystemen. Fotoalbums mogen niet vastzitten in het ecosysteem van een apparaat, of worden gebruikt voor advertentiegegevens. Ze moeten OS-agnostisch, permanent en persoonlijk eigendom zijn. De gegevens die we creëren zijn onze erfenis, die ons nog lang zal overleven. Open source-technologie is de enige manier om ervoor te zorgen dat we de absolute controle behouden over de gegevens die ons leven bepalen, op onbeperkte schaal.",
|
||||
"about_vision_title": "Visie",
|
||||
"accept": "Accepteren",
|
||||
"accessed": "Geopend",
|
||||
"account": "Account",
|
||||
"actions": "Acties",
|
||||
"add": "Toevoegen",
|
||||
"add_device": "Apparaat Toevoegen",
|
||||
"add_library": "Bibliotheek Toevoegen",
|
||||
"add_location_description": "Verbeter je Spacedrive ervaring door al je favoriete locaties toe te voegen aan je persoonlijke bibliotheek, voor een naadloze en efficiënte bestandsbeheer.",
|
||||
"add_location_tooltip": "Voeg pad toe als een geïndexeerde locatie",
|
||||
"add_locations": "Locaties Toevoegen",
|
||||
"add_tag": "Tag Toevoegen",
|
||||
"advanced_settings": "Geavanceerde Instellingen",
|
||||
"all_jobs_have_been_cleared": "Alle taken zijn opgeruimd.",
|
||||
"alpha_release_description": "We zijn blij dat je de Alpha-versie van Spacedrive nu kunt uitproberen, met spannende nieuwe functies. Zoals met elke eerste release kan deze versie enkele bugs bevatten. Je kan ons helpen bij het melden van eventuele problemen die u tegenkomt op ons Discord kanaal. Je waardevolle feedback draagt in grote mate bij aan het verbeteren van de gebruikerservaring.",
|
||||
"alpha_release_title": "Alpha Release",
|
||||
"appearance": "Uiterlijk",
|
||||
"appearance_description": "Verander het uiterlijk van de client.",
|
||||
"archive": "Archiveer",
|
||||
"archive_coming_soon": "Archiveren van locaties komt binnenkort...",
|
||||
"archive_info": "Exporteer gegevens van de bibliotheek als een archief, handig om de mapstructuur van de locatie te behouden.",
|
||||
"are_you_sure": "Weet je het zeker?",
|
||||
"assign_tag": "Tag toewijzen",
|
||||
"audio_preview_not_supported": "Audio voorvertoning wordt niet ondersteund.",
|
||||
"back": "Terug",
|
||||
"backups": "Backups",
|
||||
"backups_description": "Beheer je Spacedrive database backups.",
|
||||
"blur_effects": "Blur Effecten",
|
||||
"blur_effects_description": "Op sommige onderdelen wordt een blur effect toegepast.",
|
||||
"cancel": "Annuleren",
|
||||
"celcius": "Celsius",
|
||||
"change": "Wijzigen",
|
||||
"changelog": "Wijzigingslogboek",
|
||||
"changelog_page_description": "Zie welke coole nieuwe functies we aan het maken zijn",
|
||||
"changelog_page_title": "Wijzigingslogboek",
|
||||
"checksum": "Controlegetal",
|
||||
"clear_finished_jobs": "Ruim voltooide taken op",
|
||||
"client": "Client",
|
||||
"close": "Sluit",
|
||||
"clouds": "Clouds",
|
||||
"color": "Kleur",
|
||||
"coming_soon": "Komt binnenkort",
|
||||
"compress": "Comprimeer",
|
||||
"configure_location": "Locatie Configureren",
|
||||
"connected": "Verbonden",
|
||||
"contacts": "Contacten",
|
||||
"contacts_description": "Beheer je contacten in Spacedrive.",
|
||||
"content_id": "Inhouds-ID",
|
||||
"continue": "Verdergaan",
|
||||
"convert_to": "Omzetten naar",
|
||||
"coordinates": "Coördinaten",
|
||||
"copied": "Gekopieerd",
|
||||
"copy": "Kopieer",
|
||||
"copy_as_path": "Kopieer als pad",
|
||||
"copy_path_to_clipboard": "Kopieer pad naar klembord",
|
||||
"create": "Creëer",
|
||||
"create_library": "Creëer Bibliotheek",
|
||||
"create_library_description": "Bibliotheken zijn een veilige lokale database. Je bestanden blijven waar ze zijn, de Bibliotheek catalogiseert ze een slaat alle Spacedrive gerelateerde gegevens op.",
|
||||
"create_new_library": "Creëer nieuwe bibliotheek",
|
||||
"create_new_library_description": "Bibliotheken zijn een veilige lokale database. Je bestanden blijven waar ze zijn, de Bibliotheek catalogiseert ze een slaat alle Spacedrive gerelateerde gegevens op.",
|
||||
"create_new_tag": "Creëer Nieuwe Tag",
|
||||
"create_new_tag_description": "Kies een naam en kleur.",
|
||||
"create_tag": "Creëer Tag",
|
||||
"created": "Gecreëerd",
|
||||
"creating_library": "Bibliotheek creëren...",
|
||||
"creating_your_library": "Je bibliotheek creëren",
|
||||
"current": "Huidig",
|
||||
"current_directory": "Huidige Map",
|
||||
"current_directory_with_descendants": "Huidige Map Met Afstammelingen",
|
||||
"custom": "Aangepast",
|
||||
"cut": "Knip",
|
||||
"data_folder": "Gegevens Map",
|
||||
"debug_mode": "Debug modus",
|
||||
"debug_mode_description": "Schakel extra debugging functies in de app in.",
|
||||
"default": "Standaard",
|
||||
"delete": "Verwijder",
|
||||
"delete_dialog_title": "Verwijder {{prefix}} {{type}}",
|
||||
"delete_info": "Hiermee wordt de daadwerkelijke map op de schijf niet verwijderd. Voorvertoning media wordt verwijderd.",
|
||||
"delete_library": "Verwijder Bibliotheek",
|
||||
"delete_library_description": "Dit is permanent, je bestanden worden niet verwijderd, alleen de Spacedrive bibliotheek.",
|
||||
"delete_location": "Verwijder Locatie",
|
||||
"delete_location_description": "Als je een locatie verwijdert, worden ook alle bijbehorende bestanden uit de Spacedrive database verwijderd, de bestanden zelf worden niet verwijderd.",
|
||||
"delete_rule": "Verwijder regel",
|
||||
"delete_tag": "Verwijder Tag",
|
||||
"delete_tag_description": "Weet je zeker dat je deze tag wilt verwijderen? Dit kan niet ongedaan worden gemaakt en ge-tagde bestanden worden ontkoppeld.",
|
||||
"delete_warning": "Waarschuwing: hiermee wordt je {{type}} permanent verwijderd, we hebben nog geen prullenbak...",
|
||||
"description": "Omschrijving",
|
||||
"deselect": "Deselecteer",
|
||||
"details": "Details",
|
||||
"devices": "Apparaten",
|
||||
"devices_coming_soon_tooltip": "Binnenkort beschikbaar! Deze alpha release bevat geen bibliotheeksynchronisatie, dit zal binnenkort beschikbaar zijn.",
|
||||
"direction": "Richting",
|
||||
"disabled": "Uitgeschakeld",
|
||||
"display_formats": "Weergave Eenheden",
|
||||
"display_name": "Weergave Naam",
|
||||
"distance": "Afstand",
|
||||
"done": "Klaar",
|
||||
"dont_show_again": "Niet meer laten zien",
|
||||
"double_click_action": "Dubbele klikactie",
|
||||
"download": "Download",
|
||||
"duplicate": "Dupliceer",
|
||||
"edit": "Bewerk",
|
||||
"edit_library": "Bewerk Bibliotheek",
|
||||
"edit_location": "Bewerk Locatie",
|
||||
"enable_networking": "Netwerk Inschakelen",
|
||||
"encrypt": "Versleutel",
|
||||
"encrypt_library": "Versleutel Bibliotheek",
|
||||
"encrypt_library_coming_soon": "Bibliotheek versleuteling komt binnenkort",
|
||||
"encrypt_library_description": "Schakel versleuteling in voor deze bibliotheek. dit versleuteld alleen de Spacedrive database, niet de bestanden zelf.",
|
||||
"ephemeral_notice_browse": "Blader door je bestand en mappen rechtstreeks vanaf je apparaat.",
|
||||
"ephemeral_notice_consider_indexing": "Overweeg om je lokale locaties te indexeren voor een snellere en efficiënte verkenning.",
|
||||
"erase": "Wis",
|
||||
"erase_a_file": "Wis een bestand",
|
||||
"erase_a_file_description": "Configureer je wis instellingen.",
|
||||
"error": "Fout",
|
||||
"error_loading_original_file": "Fout bij het laden van het originele bestand",
|
||||
"expand": "Uitbreiden",
|
||||
"explorer": "Verkenner",
|
||||
"export": "Exporteer",
|
||||
"export_library": "Exporteer Bibliotheek",
|
||||
"export_library_coming_soon": "Bibliotheek Exporteren komt binnenkort",
|
||||
"export_library_description": "Exporteer deze bibliotheek naar een bestand.",
|
||||
"extensions": "Extensies",
|
||||
"extensions_description": "Installeer extensies om de functionaliteit van deze client uit te breiden.",
|
||||
"fahrenheit": "Fahrenheit",
|
||||
"failed_to_cancel_job": "Kan taak niet annuleren.",
|
||||
"failed_to_clear_all_jobs": "Kan niet alle taken wissen.",
|
||||
"failed_to_copy_file_path": "Kan bestandspad niet kopiëren",
|
||||
"failed_to_duplicate_file": "Kan bestand niet dupliceren",
|
||||
"failed_to_generate_checksum": "Kan controlegetal niet genereren",
|
||||
"failed_to_generate_labels": "Kan labels niet genereren",
|
||||
"failed_to_generate_thumbnails": "Kan voorvertoningen niet genereren",
|
||||
"failed_to_load_tags": "Kan tags niet laden",
|
||||
"failed_to_pause_job": "Kan taak niet pauzeren.",
|
||||
"failed_to_reindex_location": "Kan locatie niet herindexeren",
|
||||
"failed_to_remove_file_from_recents": "Kan bestand niet verwijderen uit recente bestanden",
|
||||
"failed_to_remove_job": "Kan taak niet verwijderen.",
|
||||
"failed_to_rescan_location": "Kan locatie niet opnieuw scannen",
|
||||
"failed_to_resume_job": "Kan taak niet hervatten.",
|
||||
"failed_to_update_location_settings": "Kan locatie instellingen niet updaten",
|
||||
"favorite": "Favoriet",
|
||||
"file_indexing_rules": "Bestand indexeringsregels",
|
||||
"filters": "Filters",
|
||||
"forward": "Vooruit",
|
||||
"full_disk_access": "Volledige schijftoegang",
|
||||
"full_disk_access_description": "Om de beste ervaring te bieden, hebben we toegang tot je schijf nodig om uw bestanden te indexeren. Je bestanden zijn alleen voor je beschikbaar.",
|
||||
"full_reindex": "Volledig Herindexeren",
|
||||
"full_reindex_info": "Voer een volledige nieuwe scan uit van deze locatie.",
|
||||
"general": "Algemeen",
|
||||
"general_settings": "Algemene Instellingen",
|
||||
"general_settings_description": "Algemene instellingen gerelateerd aan deze client.",
|
||||
"generatePreviewMedia_label": "Genereer voorvertoning media voor deze Locatie",
|
||||
"generate_checksums": "Genereer Controlegetal",
|
||||
"go_back": "Ga Terug",
|
||||
"got_it": "Begrepen",
|
||||
"grid_gap": "Tussenruimte",
|
||||
"grid_view": "Rasterweergave",
|
||||
"grid_view_notice_description": "Krijg een visueel overzicht van je bestanden met Rasterweergave. In deze weergave worden je bestanden en mappen weergegeven als miniaturen, zodat je snel het bestand kan identificeren dat je zoekt.",
|
||||
"hidden_label": "Voorkomt dat de locatie en de inhoud ervan verschijnen in overzichtscategorieën, zoekacties en tags, tenzij \"Verborgen items weergeven\" is ingeschakeld.",
|
||||
"hide_in_library_search": "Verberg in zoeken in Bibliotheek",
|
||||
"hide_in_library_search_description": "Verberg bestanden met deze tag voor de zoekresultaten wanneer u de hele bibliotheek doorzoekt.",
|
||||
"hide_in_sidebar": "Verbergen in zijbalk",
|
||||
"hide_in_sidebar_description": "Voorkom dat deze tag wordt weergegeven in de zijbalk van de app.",
|
||||
"hide_location_from_view": "Verberg locatie en inhoud uit het zicht",
|
||||
"home": "Thuismap",
|
||||
"image_labeler_ai_model": "AI model voor beeldlabelherkenning",
|
||||
"image_labeler_ai_model_description": "Het model dat wordt gebruikt om objecten in afbeeldingen te herkennen. Grotere modellen zijn nauwkeuriger, maar langzamer.",
|
||||
"import": "Importeer",
|
||||
"indexed": "Geïndexeerd",
|
||||
"indexer_rule_reject_allow_label": "Standaard functioneert een indexeringsregel als een Afwijzingslijst, wat resulteert in de uitsluiting van alle bestanden die aan de criteria voldoen. Als u deze optie inschakelt, wordt deze omgezet in een lijst met toegestane bestanden, waardoor de locatie alleen bestanden kan indexeren die aan de opgegeven regels voldoen.",
|
||||
"indexer_rules": "Indexeringsregels",
|
||||
"indexer_rules_info": "Met Indexeringsregels kan je paden opgeven die je wilt negeren met behulp van globs.",
|
||||
"install": "Installeer",
|
||||
"install_update": "Installeer Update",
|
||||
"installed": "Geïnstalleerd",
|
||||
"item_size": "Item grootte",
|
||||
"item_with_count_one": "{{count}} item",
|
||||
"item_with_count_other": "{{count}} items",
|
||||
"job_has_been_canceled": "Taak is geannuleerd.",
|
||||
"job_has_been_paused": "Taak is gepauzeerd.",
|
||||
"job_has_been_removed": "Taak is verwijderd.",
|
||||
"job_has_been_resumed": "Taak is hervat.",
|
||||
"join": "Meedoen",
|
||||
"join_discord": "Meedoen op Discord",
|
||||
"join_library": "Neem deel aan een Bibliotheek",
|
||||
"join_library_description": "Bibliotheken zijn een veilige lokale database op het apparaat. Je bestanden blijven waar ze zijn, de bibliotheek catalogiseert ze en slaat alle Spacedrive gerelateerde gegevens op.",
|
||||
"key_manager": "Sleutel Beheerder",
|
||||
"key_manager_description": "Creëer encryptiesleutels, koppel en ontkoppel je sleutels om te zien dat bestanden direct worden versleuteld.",
|
||||
"keybinds": "Toetscombinaties",
|
||||
"keybinds_description": "Bekijk en beheer client toetscombinaties",
|
||||
"keys": "Sleutels",
|
||||
"kilometers": "Kilometers",
|
||||
"learn_more_about_telemetry": "Meer informatie over telemetrie",
|
||||
"libraries": "Bibliotheken",
|
||||
"libraries_description": "De database bevat all bibliotheek gegevens en metagegevens van bestanden.",
|
||||
"library": "Bibliotheek",
|
||||
"library_name": "Bibliotheek naam",
|
||||
"library_overview": "Bibliotheek Overzicht",
|
||||
"library_settings": "Bibliotheek Instellingen",
|
||||
"library_settings_description": "Algemene Instellingen met betrekking to de momenteel actieve bibliotheek.",
|
||||
"list_view": "Lijstweergave",
|
||||
"list_view_notice_description": "Navigeer eenvoudig door je bestanden en mappen met Lijstweergave. In deze weergave worden je bestanden weergegeven in een eenvoudige, georganiseerde lijstindeling, zodat je snel de bestanden kunt vinden en openen die je nodig hebt.",
|
||||
"loading": "Laden",
|
||||
"local": "Lokaal",
|
||||
"local_locations": "Lokale Locaties",
|
||||
"local_node": "Lokale Node",
|
||||
"location_display_name_info": "De naam van deze Locatie, deze wordt weergegeven in de zijbalk. Zal de daadwerkelijke map op schijf niet hernoemen.",
|
||||
"location_is_already_linked": "Locatie is al gekoppeld",
|
||||
"location_connected_tooltip": "De locatie wordt in de gaten gehouden voor wijzigingen",
|
||||
"location_disconnected_tooltip": "De locatie wordt niet in de gaten gehouden voor wijzigingen",
|
||||
"location_path_info": "Het pad naar deze locatie, dit is waar bestanden op de schijf worden opgeslagen.",
|
||||
"location_type": "Locatie Type",
|
||||
"location_type_managed": "Spacedrive sorteert bestanden voor je. Als de Locatie niet leeg is, wordt er een map \"Spacedrive\" gecreëerd.",
|
||||
"location_type_normal": "De inhoud wordt ongewijzigd geïndexeerd, nieuwe bestanden worden niet automatisch gesorteerd.",
|
||||
"location_type_replica": "Deze locatie is een replica van een andere locatie, de inhoud ervan wordt automatisch gesynchroniseerd.",
|
||||
"locations": "Locaties",
|
||||
"locations_description": "Beheer je opslaglocaties.",
|
||||
"lock": "Vergrendel",
|
||||
"log_in_with_browser": "Inloggen met browser",
|
||||
"log_out": "Uitloggen",
|
||||
"manage_library": "Beheer Bibliotheek",
|
||||
"managed": "Beheerd",
|
||||
"media": "Media",
|
||||
"media_view_context": "Media Weergave Context",
|
||||
"media_view_notice_description": "Ontdek eenvoudig foto's en video's, Mediaweergave toont resultaten vanaf de huidige locatie, inclusief submappen.",
|
||||
"meet_contributors_behind_spacedrive": "Maak kennis met de bijdragers achter Spacedrive=",
|
||||
"meet_title": "Maak kennis met {{title}}",
|
||||
"miles": "Mijlen",
|
||||
"mode": "Modus",
|
||||
"modified": "Gewijzigd",
|
||||
"more": "Meer",
|
||||
"more_actions": "Meer acties...",
|
||||
"more_info": "Meer info",
|
||||
"move_files": "Verplaats Bestanden",
|
||||
"name": "Naam",
|
||||
"navigate_back": "Navigeer terug",
|
||||
"navigate_forward": "Navigeer vooruit",
|
||||
"network": "Netwerk",
|
||||
"network_page_description": "Andere Spacedrive nodes op je LAN verschijnen hier, samen met je standaard OS netwerkkoppelingen.",
|
||||
"networking": "Netwerk",
|
||||
"networking_port": "Netwerk Poort",
|
||||
"networking_port_description": "De poort waarop het Peer-to-peer netwerk van Spacedrive kan communiceren. Je moet dit uitgeschakeld laten, tenzij je een beperkende firewall hebt. Deze poort niet openstellen aan het internet!",
|
||||
"new_folder": "Nieuwe map",
|
||||
"new_library": "Nieuwe bibliotheek",
|
||||
"new_location": "Nieuwe locatie",
|
||||
"new_location_web_description": "Omdat je de browserversie van Spacedrive gebruikt, moet je (voorlopig) een absolute URL opgeven van een lokale map op de externe node.",
|
||||
"new_tab": "Nieuw Tabblad",
|
||||
"new_tag": "Nieuwe tag",
|
||||
"no_files_found_here": "Er zijn hier geen bestanden gevonden",
|
||||
"no_jobs": "Geen taken.",
|
||||
"no_tag_selected": "Geen Tag Geselecteerd",
|
||||
"no_tags": "Geen tags",
|
||||
"node_name": "Node Naam",
|
||||
"nodes": "Nodes",
|
||||
"nodes_description": "Beheer de nodes die met deze bibliotheek zijn verbonden. Een node is een instantie van de Spacedrive backend, die op een apparaat of server draait. Elke node houdt een kopie van de database bij en synchroniseert deze in realtime via peer-to-peer verbindingen.",
|
||||
"none": "Geen",
|
||||
"normal": "Normaal",
|
||||
"not_you": "Ben je dit niet?",
|
||||
"number_of_passes": "# runs",
|
||||
"object_id": "Object-ID",
|
||||
"offline": "Offline",
|
||||
"online": "Online",
|
||||
"open": "Open",
|
||||
"open_file": "Open Bestand",
|
||||
"open_new_location_once_added": "Open nieuwe locatie zodra deze is toegevoegd",
|
||||
"open_settings": "Open Instellingen",
|
||||
"open_with": "Open met",
|
||||
"or": "OF",
|
||||
"overview": "Overzicht",
|
||||
"pair": "Koppel",
|
||||
"pairing_with_node": "Koppelen met {{node}}",
|
||||
"paste": "Plak",
|
||||
"path": "Pad",
|
||||
"path_copied_to_clipboard_description": "Pad van locatie {{location}} gekopieerd naar klembord.",
|
||||
"path_copied_to_clipboard_title": "Pad gekopieerd naar klembord",
|
||||
"pause": "Pauzeer",
|
||||
"peers": "Peers",
|
||||
"people": "Personen",
|
||||
"privacy": "Privacy",
|
||||
"privacy_description": "Spacedrive is gebouwd met het oog op privacy, daarom zijn we open source en \"local first\". Daarom maken we heel duidelijk welke gegevens met ons worden gedeeld.",
|
||||
"quick_preview": "Snelle Voorvertoning",
|
||||
"quick_view": "Geef snel weer",
|
||||
"recent_jobs": "Recente Taken",
|
||||
"regen_labels": "Regenereer Labels",
|
||||
"regen_thumbnails": "Regenereer Miniaturen",
|
||||
"regenerate_thumbs": "Regenereer Miniaturen",
|
||||
"reindex": "Herindexeren",
|
||||
"reject": "Afwijzen",
|
||||
"reload": "Herlaad",
|
||||
"remove": "Verwijder",
|
||||
"remove_from_recents": "Verwijder van Recent",
|
||||
"rename": "Naam wijzigen",
|
||||
"replica": "Replica",
|
||||
"rescan_directory": "Bibliotheek Opnieuw Scannen",
|
||||
"rescan_location": "Locatie Opnieuw Scannen",
|
||||
"reset": "Reset",
|
||||
"resources": "Bronnen",
|
||||
"restore": "Herstel",
|
||||
"resume": "Hervat",
|
||||
"retry": "Probeer Opnieuw",
|
||||
"revel_in_browser": "Toon in {{browser}}",
|
||||
"running": "Actief",
|
||||
"save": "Opslaan",
|
||||
"save_changes": "Wijzigingen Opslaan",
|
||||
"saved_searches": "Opgeslagen Zoekopdrachten",
|
||||
"search_extensions": "Zoek extensies",
|
||||
"secure_delete": "Veilig verwijderen",
|
||||
"security": "Veiligheid",
|
||||
"security_description": "Houd je client veilig.",
|
||||
"send": "Verstuur",
|
||||
"settings": "Instellingen",
|
||||
"setup": "Instellen",
|
||||
"share": "Delen",
|
||||
"share_anonymous_usage": "Deel anonieme gebruiksgegevens",
|
||||
"share_anonymous_usage_description": "Deel volledig anonieme telemetrie gegevens om de ontwikkelaars te helpen de app te verbeteren",
|
||||
"share_bare_minimum": "Deel het absolute minimale",
|
||||
"share_bare_minimum_description": "Deel alleen dat ik een actieve gebruiker ben van Spacedrive en een paar technische details",
|
||||
"sharing": "Delen",
|
||||
"sharing_description": "Beheer wie toegang heeft tot je bibliotheken.",
|
||||
"show_details": "Toon details",
|
||||
"show_hidden_files": "Toon Verborgen Bestanden",
|
||||
"show_object_size": "Toon Object grootte",
|
||||
"show_path_bar": "Padbalk Tonen",
|
||||
"show_slider": "Toon schuifregelaar",
|
||||
"size": "Grootte",
|
||||
"skip_login": "Inloggen overslaan",
|
||||
"sort_by": "Sorteer op",
|
||||
"spacedrop_a_file": "Spacedrop een Bestand",
|
||||
"square_thumbnails": "Vierkante Miniaturen",
|
||||
"star_on_github": "Ster op GitHub",
|
||||
"stop": "Stop",
|
||||
"success": "Succes",
|
||||
"support": "Ondersteuning",
|
||||
"sync": "Synchronisatie",
|
||||
"syncPreviewMedia_label": "Synchroniseer voorvertoningsmedia van deze locatie met je apparaten",
|
||||
"sync_description": "Beheer hoe Spacedrive synchroniseert.",
|
||||
"sync_with_library": "Synchroniseer met Bibliotheek",
|
||||
"sync_with_library_description": "Indien ingeschakeld, worden je toetscombinaties gesynchroniseerd met de bibliotheek, anders zijn ze alleen van toepassing op deze client.",
|
||||
"tags": "Tags",
|
||||
"tags_description": "Beheer je tags.",
|
||||
"telemetry_description": "Schakel in om de ontwikkelaars te voorzien van gedetailleerde gebruik en telemetrie gegevens om de app te verbeteren. Schakel uit om alleen basisgegevens te verzenden: je status, app-versie, core versie en platform (bijvoorbeeld, mobiel, browser, of desktop).",
|
||||
"telemetry_title": "Deel Aanvullende Telemetrie en Gebruiksgegevens",
|
||||
"temperature": "Temperatuur",
|
||||
"thumbnailer_cpu_usage": "CPU-gebruik van thumbnailer",
|
||||
"thumbnailer_cpu_usage_description": "Beperk hoeveel CPU de thumbnailer kan gebruiken voor achtergrondverwerking.",
|
||||
"toggle_all": "Selecteer Alles",
|
||||
"type": "Type",
|
||||
"ui_animations": "UI Animaties",
|
||||
"ui_animations_description": "Dialogen en andere UI elementen zullen animeren bij het openen en sluiten.",
|
||||
"unnamed_location": "Naamloze Locatie",
|
||||
"usage": "Gebruik",
|
||||
"usage_description": "Je bibliotheek gebruik en hardware informatie",
|
||||
"value": "Waarde",
|
||||
"video_preview_not_supported": "Video voorvertoning wordt niet ondersteund.",
|
||||
"want_to_do_this_later": "Wil je dit later doen?",
|
||||
"website": "Website",
|
||||
"your_account": "Je account",
|
||||
"your_account_description": "Spacedrive account en informatie.",
|
||||
"your_local_network": "Je Lokale Netwerk",
|
||||
"your_privacy": "Jouw Privacy",
|
||||
"recents": "Recent",
|
||||
"favorites": "Favorieten",
|
||||
"labels": "Labels",
|
||||
"language": "Taal",
|
||||
"language_description": "Wijzig de taal van de Spacedrive interface"
|
||||
}
|
||||
@@ -142,7 +142,6 @@
|
||||
"failed_to_resume_job": "İş devam ettirilemedi.",
|
||||
"failed_to_update_location_settings": "Konum ayarları güncellenemedi",
|
||||
"favorite": "Favori",
|
||||
"favorites": "Favoriler",
|
||||
"file_indexing_rules": "Dosya İndeksleme Kuralları",
|
||||
"filters": "Filtreler",
|
||||
"forward": "İleri",
|
||||
@@ -194,9 +193,6 @@
|
||||
"keybinds_description": "İstemci tuş bağlamalarını görüntüleyin ve yönetin",
|
||||
"keys": "Anahtarlar",
|
||||
"kilometers": "Kilometreler",
|
||||
"labels": "Etiketler",
|
||||
"language": "Dil",
|
||||
"language_description": "Spacedrive arayüzünün dilini değiştirin",
|
||||
"learn_more_about_telemetry": "Telemetri hakkında daha fazla bilgi edinin",
|
||||
"libraries": "Kütüphaneler",
|
||||
"libraries_description": "Veritabanı tüm kütüphane verilerini ve dosya metaverilerini içerir.",
|
||||
@@ -213,7 +209,8 @@
|
||||
"local_node": "Yerel Düğüm",
|
||||
"location_display_name_info": "Bu Konumun adı, kenar çubuğunda gösterilecek olan budur. Diskteki gerçek klasörü yeniden adlandırmaz.",
|
||||
"location_is_already_linked": "Konum zaten bağlantılı",
|
||||
"location_offline_tooltip": "Konum çevrimdışı, yine de göz atabilir ve düzenleyebilirsiniz.",
|
||||
"location_connected_tooltip": "Konum değişiklikler için izleniyor",
|
||||
"location_disconnected_tooltip": "Konum değişiklikler için izlenmiyor",
|
||||
"location_path_info": "Bu Konumun yolu, dosyaların disk üzerinde saklandığı yerdir.",
|
||||
"location_type": "Konum Türü",
|
||||
"location_type_managed": "Spacedrive sizin için dosyaları sıralar. Eğer Konum boş değilse, bir \"spacedrive\" klasörü oluşturulacak.",
|
||||
@@ -287,7 +284,6 @@
|
||||
"quick_preview": "Hızlı Önizleme",
|
||||
"quick_view": "Hızlı bakış",
|
||||
"recent_jobs": "Son İşler",
|
||||
"recents": "Son Kullanılanlar",
|
||||
"regen_labels": "Etiketleri Yeniden Oluştur",
|
||||
"regen_thumbnails": "Küçük Resimleri Yeniden Oluştur",
|
||||
"regenerate_thumbs": "Küçük Resimleri Yeniden Oluştur",
|
||||
@@ -364,5 +360,10 @@
|
||||
"your_account": "Hesabınız",
|
||||
"your_account_description": "Spacedrive hesabınız ve bilgileri.",
|
||||
"your_local_network": "Yerel Ağınız",
|
||||
"your_privacy": "Gizliliğiniz"
|
||||
"your_privacy": "Gizliliğiniz",
|
||||
"recents": "Son Kullanılanlar",
|
||||
"favorites": "Favoriler",
|
||||
"labels": "Etiketler",
|
||||
"language": "Dil",
|
||||
"language_description": "Spacedrive arayüzünün dilini değiştirin"
|
||||
}
|
||||
|
||||
@@ -142,7 +142,6 @@
|
||||
"failed_to_resume_job": "恢复任务失败。",
|
||||
"failed_to_update_location_settings": "更新位置设置失败",
|
||||
"favorite": "收藏",
|
||||
"favorites": "收藏夹",
|
||||
"file_indexing_rules": "文件索引规则",
|
||||
"filters": "过滤器",
|
||||
"forward": "前进",
|
||||
@@ -194,9 +193,6 @@
|
||||
"keybinds_description": "查看和管理客户端键绑定",
|
||||
"keys": "密钥",
|
||||
"kilometers": "千米",
|
||||
"labels": "标签",
|
||||
"language": "语言",
|
||||
"language_description": "更改Spacedrive界面的语言",
|
||||
"learn_more_about_telemetry": "了解更多有关遥测的信息",
|
||||
"libraries": "库",
|
||||
"libraries_description": "数据库包含所有库数据和文件元数据。",
|
||||
@@ -213,7 +209,8 @@
|
||||
"local_node": "本地节点",
|
||||
"location_display_name_info": "此位置的名称,这是将显示在侧边栏的名称。不会重命名磁盘上的实际文件夹。",
|
||||
"location_is_already_linked": "位置已经链接",
|
||||
"location_offline_tooltip": "位置离线,您仍然可以浏览和组织。",
|
||||
"location_connected_tooltip": "位置正在监视变化",
|
||||
"location_disconnected_tooltip": "位置未被监视以检查更改",
|
||||
"location_path_info": "此位置的路径,这是文件在磁盘上的存储位置。",
|
||||
"location_type": "位置类型",
|
||||
"location_type_managed": "Spacedrive将为您排序文件。如果位置不为空,将创建一个“spacedrive”文件夹。",
|
||||
@@ -287,7 +284,6 @@
|
||||
"quick_preview": "快速预览",
|
||||
"quick_view": "快速查看",
|
||||
"recent_jobs": "最近的作业",
|
||||
"recents": "最近使用",
|
||||
"regen_labels": "重新生成标签",
|
||||
"regen_thumbnails": "重新生成缩略图",
|
||||
"regenerate_thumbs": "重新生成缩略图",
|
||||
@@ -364,5 +360,10 @@
|
||||
"your_account": "您的账户",
|
||||
"your_account_description": "Spacedrive账号和信息。",
|
||||
"your_local_network": "您的本地网络",
|
||||
"your_privacy": "您的隐私"
|
||||
"your_privacy": "您的隐私",
|
||||
"recents": "最近使用",
|
||||
"favorites": "收藏夹",
|
||||
"labels": "标签",
|
||||
"language": "语言",
|
||||
"language_description": "更改Spacedrive界面的语言"
|
||||
}
|
||||
|
||||
@@ -141,7 +141,6 @@
|
||||
"failed_to_resume_job": "恢復工作失敗。",
|
||||
"failed_to_update_location_settings": "更新位置設置失敗",
|
||||
"favorite": "最愛",
|
||||
"favorites": "收藏夾",
|
||||
"file_indexing_rules": "文件索引規則",
|
||||
"filters": "篩選器",
|
||||
"forward": "前進",
|
||||
@@ -193,9 +192,6 @@
|
||||
"keybinds_description": "查看和管理客戶端鍵綁定",
|
||||
"keys": "鍵",
|
||||
"kilometers": "公里",
|
||||
"labels": "標籤",
|
||||
"language": "語言",
|
||||
"language_description": "更改Spacedrive界面的語言",
|
||||
"learn_more_about_telemetry": "了解更多關於遙測的信息",
|
||||
"libraries": "圖書館",
|
||||
"libraries_description": "數據庫包含所有圖書館數據和文件元數據。",
|
||||
@@ -212,7 +208,8 @@
|
||||
"local_node": "本地節點",
|
||||
"location_display_name_info": "這個位置的名稱,這是在側邊欄中顯示的內容。不會重命名磁碟上的實際文件夾。",
|
||||
"location_is_already_linked": "位置已經被連接",
|
||||
"location_offline_tooltip": "位置離線,您可以繼續瀏覽和組織。",
|
||||
"location_connected_tooltip": "正在監視位置是否有變化",
|
||||
"location_disconnected_tooltip": "正在監視位置是否有變化",
|
||||
"location_path_info": "這是位置的路徑,這是在磁碟上存儲文件的位置。",
|
||||
"location_type": "位置類型",
|
||||
"location_type_managed": "Spacedrive將為你分類文件。如果位置不是空的,將創建一個“spacedrive”文件夾。",
|
||||
@@ -286,7 +283,6 @@
|
||||
"quick_preview": "快速預覽",
|
||||
"quick_view": "快速查看",
|
||||
"recent_jobs": "最近的工作",
|
||||
"recents": "最近的文件",
|
||||
"regen_labels": "重新生成標籤",
|
||||
"regen_thumbnails": "重新生成縮略圖",
|
||||
"regenerate_thumbs": "重新生成縮略圖",
|
||||
@@ -363,5 +359,10 @@
|
||||
"your_account": "您的帳戶",
|
||||
"your_account_description": "Spacedrive帳戶和資訊。",
|
||||
"your_local_network": "您的本地網路",
|
||||
"your_privacy": "您的隱私"
|
||||
"your_privacy": "您的隱私",
|
||||
"recents": "最近的文件",
|
||||
"favorites": "收藏夾",
|
||||
"labels": "標籤",
|
||||
"language": "語言",
|
||||
"language_description": "更改Spacedrive界面的語言"
|
||||
}
|
||||
|
||||
BIN
pnpm-lock.yaml
generated
BIN
pnpm-lock.yaml
generated
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://inlang.com/schema/project-settings",
|
||||
"sourceLanguageTag": "en",
|
||||
"languageTags": ["en", "de", "tr", "es", "fr", "zh-CN", "zh-TW"],
|
||||
"languageTags": ["en", "de", "tr", "es", "fr", "nl", "zh-CN", "zh-TW"],
|
||||
"modules": [
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/plugin-i18next@latest/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@1/dist/index.js",
|
||||
|
||||
Reference in New Issue
Block a user