use sep() for platform aware separator & cleanup

Signed-off-by: FTCHD <144691102+FTCHD@users.noreply.github.com>
This commit is contained in:
FTCHD
2025-08-31 01:45:31 +02:00
parent 6d67f88582
commit 90f9885baa
10 changed files with 28 additions and 62 deletions
+3 -1
View File
@@ -1,3 +1,5 @@
import { sep } from '@tauri-apps/api/path'
export function formatBytes(bytes: number) {
if (bytes < 1024) {
return `${bytes} B`
@@ -36,7 +38,7 @@ export function buildReadablePath(path: string, type: 'short' | 'long' = 'long')
return ''
}
const lastSegment = path.split('\\').slice(-1).join('').split('/').slice(-1).join('')
const lastSegment = path.split(sep()).slice(-1).join('')
if (type === 'short') {
return lastSegment
+2 -1
View File
@@ -1,4 +1,5 @@
import * as Sentry from '@sentry/browser'
import { sep } from '@tauri-apps/api/path'
import { readDir } from '@tauri-apps/plugin-fs'
export async function isDirectoryEmpty(path: string): Promise<boolean> {
@@ -13,5 +14,5 @@ export async function isDirectoryEmpty(path: string): Promise<boolean> {
}
export function isRemotePath(path: string): boolean {
return path.includes(':/') && !path.startsWith('/')
return path.includes(':/') && !path.startsWith(sep())
}
+2 -12
View File
@@ -1,7 +1,6 @@
import { appLocalDataDir } from '@tauri-apps/api/path'
import { appLocalDataDir, sep } from '@tauri-apps/api/path'
import { exists } from '@tauri-apps/plugin-fs'
import { fetch } from '@tauri-apps/plugin-http'
import { platform } from '@tauri-apps/plugin-os'
import { Command } from '@tauri-apps/plugin-shell'
export async function getDefaultPaths() {
@@ -84,16 +83,7 @@ export async function getConfigPath({ id, validate = true }: { id: string; valid
const appLocalDataDirPath = await appLocalDataDir()
console.log('[getConfigPath] appLocalDataDirPath', appLocalDataDirPath)
const slashSymbol = platform() === 'windows' ? '\\' : '/'
let configPath =
appLocalDataDirPath +
slashSymbol +
'configs' +
slashSymbol +
id +
slashSymbol +
'rclone.conf'
let configPath = appLocalDataDirPath + sep() + 'configs' + sep() + id + sep() + 'rclone.conf'
console.log('[getConfigPath] configPath', configPath)
+4 -6
View File
@@ -1,6 +1,6 @@
import * as Sentry from '@sentry/browser'
import { invoke } from '@tauri-apps/api/core'
import { BaseDirectory, appLocalDataDir } from '@tauri-apps/api/path'
import { BaseDirectory, appLocalDataDir, sep } from '@tauri-apps/api/path'
import { tempDir } from '@tauri-apps/api/path'
import { ask, message } from '@tauri-apps/plugin-dialog'
import { copyFile, exists, mkdir, readTextFile, remove } from '@tauri-apps/plugin-fs'
@@ -104,8 +104,7 @@ export async function initRclone(args: string[]) {
)
if (activeConfigFile.sync) {
const slashSymbol = platform() === 'windows' ? '\\' : '/'
if (!(await exists(configFolderPath + slashSymbol + 'rclone.conf'))) {
if (!(await exists(configFolderPath + sep() + 'rclone.conf'))) {
await message('The config file could not be found. Switching to the default config.', {
title: 'Invalid synced config',
kind: 'error',
@@ -176,7 +175,7 @@ export async function provisionRclone() {
console.log('currentOs', currentOs)
let tempDirPath = await tempDir()
if (tempDirPath.endsWith('/') || tempDirPath.endsWith('\\')) {
if (tempDirPath.endsWith(sep())) {
tempDirPath = tempDirPath.slice(0, -1)
}
console.log('[provisionRclone] tempDirPath', tempDirPath)
@@ -265,8 +264,7 @@ export async function provisionRclone() {
const binaryName = currentPlatform === 'windows' ? 'rclone.exe' : 'rclone'
// "/" here looks to be working on windows
const rcloneBinaryPath = unarchivedPath + '/' + binaryName
const rcloneBinaryPath = unarchivedPath + sep() + binaryName
console.log('[provisionRclone] rcloneBinaryPath', rcloneBinaryPath)
try {
+1 -1
View File
@@ -28,7 +28,7 @@ fn unzip_file(zip_path: &str, output_folder: &str) -> Result<(), String> {
let mut file = archive.by_index(i).map_err(|e| e.to_string())?;
let outpath = Path::new(output_folder).join(file.name());
if file.name().ends_with('/') {
if file.name().ends_with('/') || file.name().ends_with('\\') {
fs::create_dir_all(&outpath).map_err(|e| e.to_string())?;
} else {
if let Some(p) = outpath.parent() {
+3 -8
View File
@@ -8,9 +8,9 @@ import {
Textarea,
} from '@heroui/react'
import { Button } from '@heroui/react'
import { sep } from '@tauri-apps/api/path'
import { message, open } from '@tauri-apps/plugin-dialog'
import { mkdir, readTextFile, writeTextFile } from '@tauri-apps/plugin-fs'
import { platform } from '@tauri-apps/plugin-os'
import { UploadIcon } from 'lucide-react'
import { useCallback, useMemo, useState } from 'react'
import { getConfigPath } from '../../lib/rclone/common'
@@ -59,9 +59,7 @@ export default function ConfigCreateDrawer({
const configPath = await getConfigPath({ id: generatedId, validate: false })
const slashSymbol = platform() === 'windows' ? '\\' : '/'
await mkdir(configPath.replace(slashSymbol + 'rclone.conf', ''), {
await mkdir(configPath.replace(sep() + 'rclone.conf', ''), {
recursive: true,
})
await writeTextFile(configPath, content)
@@ -202,15 +200,12 @@ export default function ConfigCreateDrawer({
}, '')
}
const slashSymbol =
platform() === 'windows' ? '\\' : '/'
setConfigContent(content)
setConfig({
...config,
label:
config.label ||
selectedFile.split(slashSymbol).pop() ||
selectedFile.split(sep()).pop() ||
'New Config',
isEncrypted:
content.includes('RCLONE_ENCRYPT_V0:'),
+4 -14
View File
@@ -8,9 +8,9 @@ import {
Switch,
} from '@heroui/react'
import { Button } from '@heroui/react'
import { sep } from '@tauri-apps/api/path'
import { message, open } from '@tauri-apps/plugin-dialog'
import { exists, readTextFile } from '@tauri-apps/plugin-fs'
import { platform } from '@tauri-apps/plugin-os'
import { UploadIcon } from 'lucide-react'
import { useCallback, useState } from 'react'
import { usePersistedStore } from '../../lib/store'
@@ -221,10 +221,7 @@ export default function ConfigSyncDrawer({
return
}
if (
selectedFolder.endsWith('/') ||
selectedFolder.endsWith('\\')
) {
if (selectedFolder.endsWith(sep())) {
selectedFolder = selectedFolder.slice(
0,
-1
@@ -237,13 +234,8 @@ export default function ConfigSyncDrawer({
)
}
const slashSymbol =
platform() === 'windows' ? '\\' : '/'
const configPath =
selectedFolder +
slashSymbol +
'rclone.conf'
selectedFolder + sep() + 'rclone.conf'
let content: string | null = null
@@ -265,9 +257,7 @@ export default function ConfigSyncDrawer({
...config,
label:
config.label ||
configPath
.split(slashSymbol)
.pop() ||
configPath.split(sep()).pop() ||
'New Config',
sync: selectedFolder,
})
+5 -12
View File
@@ -2,9 +2,9 @@ import { Autocomplete, Tooltip } from '@heroui/react'
import { AutocompleteItem, Button } from '@heroui/react'
import { cn } from '@heroui/react'
import * as Sentry from '@sentry/browser'
import { sep } from '@tauri-apps/api/path'
import { open } from '@tauri-apps/plugin-dialog'
import { readDir } from '@tauri-apps/plugin-fs'
import { platform } from '@tauri-apps/plugin-os'
import { ArrowDownUp, FolderOpen, XIcon } from 'lucide-react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useDebounce } from 'use-debounce'
@@ -256,8 +256,6 @@ export function PathField({
// console.log('fetching suggestions for', path, field)
const slashSymbol = platform() === 'windows' ? '\\' : '/'
try {
// If path is empty, show list of remotes
if (!searchPath) {
@@ -282,17 +280,14 @@ export function PathField({
console.error('Failed to fetch local suggestions:', err)
try {
// we also retry in case the last part of the path is wrong
cleanedPath = searchPath
.split(slashSymbol)
.slice(0, -1)
.join(slashSymbol)
cleanedPath = searchPath.split(sep()).slice(0, -1).join(sep())
localEntries = await readDir(cleanedPath)
} catch (err) {
console.error('Failed to fetch local suggestions (again):', err)
}
}
const extraSlash = cleanedPath.endsWith(slashSymbol) ? '' : slashSymbol
const extraSlash = cleanedPath.endsWith(sep()) ? '' : sep()
const localSuggestions = localEntries
.filter((entry) => !entry.isSymlink)
@@ -484,8 +479,6 @@ export function MultiPathField({
// console.log('fetching suggestions for', path, field)
const slashSymbol = platform() === 'windows' ? '\\' : '/'
try {
// If path is empty, show list of remotes
if (!path) {
@@ -510,14 +503,14 @@ export function MultiPathField({
console.error('Failed to fetch local suggestions:', err)
try {
// we also retry in case the last part of the path is wrong
cleanedPath = path.split(slashSymbol).slice(0, -1).join(slashSymbol)
cleanedPath = path.split(sep()).slice(0, -1).join(sep())
localEntries = await readDir(cleanedPath)
} catch (err) {
console.error('Failed to fetch local suggestions (again):', err)
}
}
const extraSlash = cleanedPath.endsWith(slashSymbol) ? '' : slashSymbol
const extraSlash = cleanedPath.endsWith(sep()) ? '' : sep()
const localSuggestions = localEntries
.filter((entry) => !entry.isSymlink)
+2 -2
View File
@@ -36,14 +36,13 @@ export default function Jobs() {
await fetchJobs()
}, 2000)
// prevents jobs being refreshed after closing the window
const unlisten = listen('tauri://close-requested', () => {
clearInterval(interval)
})
return () => {
clearInterval(interval)
unlisten.then((unlisten) => unlisten())
unlisten.then((u) => u())
}
}, [fetchJobs])
@@ -69,6 +68,7 @@ export default function Jobs() {
<Card
key={job.id}
radius="none"
shadow="sm"
style={{
flexShrink: 0,
}}
+2 -5
View File
@@ -1,4 +1,5 @@
import { Accordion, AccordionItem, Avatar, Button } from '@heroui/react'
import { sep } from '@tauri-apps/api/path'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { message } from '@tauri-apps/plugin-dialog'
import { exists, mkdir, remove } from '@tauri-apps/plugin-fs'
@@ -110,11 +111,7 @@ export default function Mount() {
const _mountOptions = { ...mountOptions }
if (!('VolumeName' in _mountOptions) && ['windows', 'macos'].includes(platform())) {
if (platform() === 'windows') {
_mountOptions.VolumeName = source!.split('\\').pop()!
} else {
_mountOptions.VolumeName = source!.split('/').pop()!
}
_mountOptions.VolumeName = source!.split(sep()).pop()!
}
let directoryExists: boolean | undefined