mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[hotfix] move instead of copy if no other version use the linked folder
This commit is contained in:
+3
-1
@@ -9,7 +9,7 @@ import { MapsDownloaderService } from "renderer/services/maps-downloader.service
|
||||
import { VariableSizeList } from "react-window"
|
||||
import { MapsRow } from "./maps-row.component"
|
||||
import { BehaviorSubject } from "rxjs"
|
||||
import { debounceTime, last, map, mergeMap, throttleTime } from "rxjs/operators"
|
||||
import { debounceTime, last, map, mergeMap } from "rxjs/operators"
|
||||
import { BeatSaverService } from "renderer/services/thrird-partys/beat-saver.service"
|
||||
import { OsDiagnosticService } from "renderer/services/os-diagnostic.service"
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook"
|
||||
@@ -64,6 +64,8 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
console.log(linked);
|
||||
|
||||
if(isVisible){
|
||||
loadMaps();
|
||||
mapsDownloader.addOnMapDownloadedListener((map, targerVersion) => {
|
||||
|
||||
+9
-8
@@ -17,7 +17,8 @@ import { BsmIcon } from "../svgs/bsm-icon.component"
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook"
|
||||
import { LinkButton } from "./link-button.component"
|
||||
import { debounceTime } from "rxjs/operators"
|
||||
import { FolderLinkerService } from "renderer/services/folder-linker.service"
|
||||
import { VersionFolderLinkerService, VersionLinkerActionListener } from "renderer/services/version-folder-linker.service"
|
||||
|
||||
|
||||
type Props = {
|
||||
version?: BSVersion
|
||||
@@ -28,7 +29,7 @@ export function MapsPlaylistsPanel({version}: Props) {
|
||||
const mapsService = MapsManagerService.getInstance();
|
||||
const mapsDownloader = MapsDownloaderService.getInstance();
|
||||
const osDiagnostic = OsDiagnosticService.getInstance();
|
||||
const linker = FolderLinkerService.getInstance();
|
||||
const linker = VersionFolderLinkerService.getInstance();
|
||||
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const [mapFilter, setMapFilter] = useState<MapFilter>({});
|
||||
@@ -46,18 +47,18 @@ export function MapsPlaylistsPanel({version}: Props) {
|
||||
|
||||
const sub = mapsService.$mapsLinkingPending(version).pipe(debounceTime(50)).subscribe(setLinkingPending);
|
||||
|
||||
const onMapsLinked = (folder: string) => {
|
||||
if(!folder.includes("CustomLevels")){ return; }
|
||||
const onMapsLinked: VersionLinkerActionListener = (action, linked) => {
|
||||
if(!action.relativeFolder.includes(MapsManagerService.RELATIVE_MAPS_FOLDER)){ return; }
|
||||
loadMapIsLinked();
|
||||
}
|
||||
|
||||
linker.onFolderLinked(onMapsLinked);
|
||||
linker.onFolderUnlinked(onMapsLinked);
|
||||
linker.onVersionFolderLinked(onMapsLinked);
|
||||
linker.onVersionFolderUnlinked(onMapsLinked);
|
||||
|
||||
return () => {
|
||||
sub.unsubscribe();
|
||||
linker.removeOnFolderLinked(onMapsLinked);
|
||||
linker.removeOnFolderUnlinked(onMapsLinked);
|
||||
linker.removeVersionFolderLinkedListener(onMapsLinked);
|
||||
linker.removeVersionFolderUnlinkedListener(onMapsLinked);
|
||||
}
|
||||
|
||||
}, [version]);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Tippy from "@tippyjs/react";
|
||||
import { Variants } from "framer-motion";
|
||||
import { version } from "os";
|
||||
import { useEffect, useState } from "react";
|
||||
import { LinkButton } from "renderer/components/maps-mangement-components/link-button.component";
|
||||
import { BsmBasicSpinner } from "renderer/components/shared/bsm-basic-spinner/bsm-basic-spinner.component";
|
||||
@@ -8,10 +9,11 @@ import { BsmIcon } from "renderer/components/svgs/bsm-icon.component";
|
||||
import { useObservable } from "renderer/hooks/use-observable.hook";
|
||||
import { useThemeColor } from "renderer/hooks/use-theme-color.hook";
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook";
|
||||
import { BSVersionManagerService } from "renderer/services/bs-version-manager.service";
|
||||
import { ConfigurationService } from "renderer/services/configuration.service";
|
||||
import { FolderLinkerService } from "renderer/services/folder-linker.service";
|
||||
import { IpcService } from "renderer/services/ipc.service";
|
||||
import { ModalComponent } from "renderer/services/modale.service";
|
||||
import { VersionFolderLinkerService, VersionLinkerActionType } from "renderer/services/version-folder-linker.service";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
|
||||
export const ShareFoldersModal: ModalComponent<void, BSVersion> = ({ data }) => {
|
||||
@@ -20,32 +22,18 @@ export const ShareFoldersModal: ModalComponent<void, BSVersion> = ({ data }) =>
|
||||
|
||||
const config = ConfigurationService.getInstance();
|
||||
const ipc = IpcService.getInstance();
|
||||
const linker = VersionFolderLinkerService.getInstance();
|
||||
const versionManager = BSVersionManagerService.getInstance();
|
||||
|
||||
const t = useTranslation();
|
||||
|
||||
const [folders, setFolders] = useState<string[]>([]);
|
||||
const versionPath = useObservable(ipc.sendV2<string>("get-version-full-path", {args: data}));
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const defaultFolders = config.get<string[]>(SHARED_FOLDERS_KEY);
|
||||
setFolders(prev => Array.from(new Set([...prev, ...config.get<string[]>(SHARED_FOLDERS_KEY)]).values()));
|
||||
|
||||
const promises = Promise.allSettled(defaultFolders.map(async (folder) => {
|
||||
return ipc.sendV2<string>("relative-version-path-to-full", {args: {version: data, relative: folder}}).toPromise();
|
||||
}));
|
||||
|
||||
promises.then((res) => {
|
||||
|
||||
const fullPathFolders = res.reduce((acc, curent) => {
|
||||
if(curent.status !== "fulfilled"){ return acc; }
|
||||
acc.push(curent.value);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
setFolders(prev => Array.from(new Set([...prev, ...fullPathFolders]).values()));
|
||||
});
|
||||
|
||||
ipc.sendV2<string[]>("get-linked-folders", {args: data}).toPromise().then(linkedFolders => {
|
||||
linker.getLinkedFolders(data, {relative: true}).toPromise().then(linkedFolders => {
|
||||
setFolders(prev => Array.from(new Set([...prev, ...linkedFolders]).values()));
|
||||
});
|
||||
|
||||
@@ -57,31 +45,22 @@ export const ShareFoldersModal: ModalComponent<void, BSVersion> = ({ data }) =>
|
||||
config.delete(SHARED_FOLDERS_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
const promises = Promise.allSettled(folders.map(async folder => {
|
||||
return ipc.sendV2<string>("full-version-path-to-relative", {args: {version: data, fullPath: folder}}).toPromise();
|
||||
}));
|
||||
|
||||
promises.then((res) => {
|
||||
const sharedFolders = res.reduce((acc, curent) => {
|
||||
if(curent.status !== "fulfilled"){ return acc; }
|
||||
acc.push(curent.value);
|
||||
return acc;
|
||||
}, [] as string[]);
|
||||
config.set(SHARED_FOLDERS_KEY, sharedFolders);
|
||||
});
|
||||
|
||||
config.set(SHARED_FOLDERS_KEY, folders);
|
||||
|
||||
}, [folders]);
|
||||
|
||||
const addFolder = async () => {
|
||||
const versionPath = await versionManager.getVersionPath(data).toPromise();
|
||||
const folder = await ipc.sendV2<{canceled: boolean, filePaths: string[]}, string>("choose-folder", {args: versionPath}).toPromise();
|
||||
|
||||
|
||||
if(!folder || folder.canceled || !folder.filePaths?.length){ return; }
|
||||
const linkedFolder = folder.filePaths[0];
|
||||
|
||||
if(folders.includes(linkedFolder)){ return; }
|
||||
const relativeFolder = await ipc.sendV2<string>("full-version-path-to-relative", {args: {version: data, fullPath: folder.filePaths[0]}}).toPromise();
|
||||
|
||||
setFolders(pre => [...pre, linkedFolder]);
|
||||
if(folders.includes(relativeFolder)){ return; }
|
||||
|
||||
setFolders(pre => [...pre, relativeFolder]);
|
||||
}
|
||||
|
||||
const removeFolder = (index: number) => {
|
||||
@@ -94,7 +73,7 @@ export const ShareFoldersModal: ModalComponent<void, BSVersion> = ({ data }) =>
|
||||
<p className="my-3">{t("modals.shared-folders.description")}</p>
|
||||
<ul className="flex flex-col gap-1 mb-2 h-[300px] max-h-[300px] overflow-scroll scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900 px-1">
|
||||
{folders.map((folder, index) => (
|
||||
<FolderItem key={index} path={folder} onDelete={() => {removeFolder(index)}}/>
|
||||
<FolderItem key={index} version={data} relativeFolder={folder} onDelete={() => {removeFolder(index)}}/>
|
||||
))}
|
||||
</ul>
|
||||
<div className="w-full h-12 rounded-md flex justify-center items-center cursor-pointer bg-light-main-color-1 dark:bg-main-color-1 hover:bg-light-main-color-3 hover:dark:bg-main-color-3" onClick={addFolder}>
|
||||
@@ -106,17 +85,18 @@ export const ShareFoldersModal: ModalComponent<void, BSVersion> = ({ data }) =>
|
||||
}
|
||||
|
||||
type FolderProps = {
|
||||
path: string;
|
||||
version: BSVersion;
|
||||
relativeFolder: string;
|
||||
onDelete?: () => void;
|
||||
}
|
||||
|
||||
const FolderItem = ({path, onDelete}: FolderProps) => {
|
||||
const FolderItem = ({version, relativeFolder, onDelete}: FolderProps) => {
|
||||
|
||||
const linker = FolderLinkerService.getInstance();
|
||||
const linker = VersionFolderLinkerService.getInstance();
|
||||
|
||||
const t = useTranslation();
|
||||
|
||||
const name = path.split("\\").at(-1);
|
||||
const name = relativeFolder.split("\\").at(-1);
|
||||
const color = useThemeColor("first-color");
|
||||
|
||||
const variants: Variants = {
|
||||
@@ -124,35 +104,43 @@ const FolderItem = ({path, onDelete}: FolderProps) => {
|
||||
tap: {rotate: 45}
|
||||
};
|
||||
|
||||
const pending = useObservable(linker.isPending(path));
|
||||
const processing = useObservable(linker.isProcessing(path));
|
||||
const pending = useObservable(linker.isPending(version, relativeFolder));
|
||||
const processing = useObservable(linker.isProcessing(version, relativeFolder));
|
||||
const linkDisabled = pending || processing;
|
||||
|
||||
const [linked, setLinked] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
loadFolderIsLinked();
|
||||
}, [path]);
|
||||
}, [version, relativeFolder]);
|
||||
|
||||
const loadFolderIsLinked = () => {
|
||||
linker.isFolderLinked(path).toPromise().then(setLinked);
|
||||
linker.isVersionFolderLinked(version, relativeFolder).toPromise().then(setLinked);
|
||||
}
|
||||
|
||||
const onClickLink = () => {
|
||||
if(linked){
|
||||
return linker.unlinkFolder(path).toPromise().then(loadFolderIsLinked);
|
||||
return linker.unlinkVersionFolder({
|
||||
version,
|
||||
relativeFolder,
|
||||
type: VersionLinkerActionType.Unlink,
|
||||
}).then(loadFolderIsLinked);
|
||||
}
|
||||
return linker.linkFolder(path).toPromise().then(loadFolderIsLinked);
|
||||
return linker.linkVersionFolder({
|
||||
version,
|
||||
relativeFolder,
|
||||
type: VersionLinkerActionType.Link,
|
||||
}).then(loadFolderIsLinked);
|
||||
}
|
||||
|
||||
const cancelLink = () => {
|
||||
linker.cancelFolder(path);
|
||||
const cancelLink = () => {
|
||||
linker.cancelAction(version, relativeFolder);
|
||||
loadFolderIsLinked();
|
||||
}
|
||||
|
||||
return (
|
||||
<li className="w-full h-12 rounded-md shrink-0 flex flex-row items-center justify-between px-2 font-bold bg-light-main-color-1 dark:bg-main-color-1">
|
||||
<span className="cursor-help" title={path}>{name}</span>
|
||||
<span className="cursor-help" title={relativeFolder}>{name}</span>
|
||||
<div className="flex flex-row gap-1.5">
|
||||
<Tippy placement="left" content={t(`modals.shared-folders.buttons.${linked ? "unlink-folder" : "link-folder"}`)} arrow={false}>
|
||||
<LinkButton variants={variants} linked={linked} disabled={linkDisabled} whileHover="hover" whileTap="tap" className="p-0.5 h-7 shrink-0 aspect-square blur-0 cursor-pointer hover:brightness-75" onClick={onClickLink}/>
|
||||
|
||||
Reference in New Issue
Block a user