abstract: abstract array manipulation functions for reuse

This commit is contained in:
Xu Quan 2025-06-24 16:58:18 +08:00
parent 7aeb9e801c
commit a9b608aaaa
11 changed files with 90 additions and 53 deletions

View file

@ -19,7 +19,7 @@ const useChangeFile = () => {
const {
focusedFolder,
focusedTag,
updateFilePinState,
updatePinnedFilePath,
updateFileManualOrder,
fileSortRule,
initOrder,
@ -30,7 +30,7 @@ const useChangeFile = () => {
useShallow((store: ExplorerStore) => ({
focusedFolder: store.focusedFolder,
focusedTag: store.focusedTag,
updateFilePinState: store.updateFilePinState,
updatePinnedFilePath: store.updatePinnedFilePath,
updateFileManualOrder: store.updateFileManualOrder,
fileSortRule: store.fileSortRule,
initOrder: store.initFilesManualSortOrder,
@ -90,7 +90,7 @@ const useChangeFile = () => {
updateFileList();
if (oldPath) {
const parentPath = file.parent?.path;
await updateFilePinState(oldPath, file.path);
await updatePinnedFilePath(oldPath, file.path);
if (parentPath && fileSortRule === FILE_MANUAL_SORT_RULE) {
await updateFileManualOrder(
parentPath,

View file

@ -4,7 +4,7 @@ import { useShallow } from "zustand/react/shallow";
import { VaultChangeEvent, VaultChangeEventName } from "src/assets/constants";
import { ExplorerStore } from "src/store";
import { isFolder } from "src/utils";
import { isFolder, removeItemFromArray } from "src/utils";
import { useExplorer } from "../useExplorer";
import { FOLDER_MANUAL_SORT_RULE } from "src/store/folder/sort";

View file

@ -8,6 +8,7 @@ import { ExplorerStore } from "..";
import { ManualSortOrder } from "../common";
import { FILE_MANUAL_SORT_RULE } from "./sort";
import { moveItemInArray } from "src/utils";
export interface ManualSortFileSlice {
filesManualSortOrder: ManualSortOrder;
@ -111,9 +112,11 @@ export const createManualSortFileSlice =
if (currentIndex === atIndex) {
return filesManualSortOrder;
}
const newOrder = [...initialOrder];
newOrder.splice(currentIndex, 1);
newOrder.splice(atIndex, 0, file.path);
const newOrder = moveItemInArray(
initialOrder,
currentIndex,
atIndex
);
const updatedOrder = {
...filesManualSortOrder,
[parentPath]: newOrder,

View file

@ -3,6 +3,7 @@ import { StateCreator } from "zustand";
import { FFS_PINNED_FILE_PATHS_KEY } from "src/assets/constants";
import FolderFileSplitterPlugin from "src/main";
import { removeItemFromArray, replaceItemInArray } from "src/utils";
import { ExplorerStore } from "..";
@ -11,11 +12,11 @@ export interface PinnedFileSlice {
isFilePinned: (file: TFile) => boolean;
pinFile: (file: TFile) => Promise<void>;
unpinFile: (file: TFile) => Promise<void>;
restorePinnedFiles: () => Promise<void>;
updateFilePinState: (oldPath: string, newPath: string) => Promise<void>;
_updatePinnedFilePath: (oldPath: string, newPath: string) => Promise<void>;
_updatePinnedFilePaths: (paths: string[]) => Promise<void>;
unpinFile: (file: TFile) => Promise<void>;
updatePinnedFilePath: (oldPath: string, newPath: string) => Promise<void>;
restorePinnedFiles: () => Promise<void>;
}
export const createPinnedFileSlice =
@ -45,11 +46,19 @@ export const createPinnedFileSlice =
},
unpinFile: async (file: TFile) => {
const { pinnedFilePaths, _updatePinnedFilePaths } = get();
const filePaths = pinnedFilePaths.filter(
(path) => path !== file.path
);
const filePaths = removeItemFromArray(pinnedFilePaths, file.path);
await _updatePinnedFilePaths(filePaths);
},
updatePinnedFilePath: async (oldPath: string, newPath: string) => {
const { pinnedFilePaths, _updatePinnedFilePaths } = get();
if (!pinnedFilePaths.includes(oldPath)) return;
const updatedPaths = replaceItemInArray(
pinnedFilePaths,
oldPath,
newPath
);
await _updatePinnedFilePaths(updatedPaths);
},
restorePinnedFiles: async () => {
const { getDataFromPlugin: getData } = get();
const pinnedFilePaths = await getData<string>(
@ -66,18 +75,4 @@ export const createPinnedFileSlice =
}
}
},
updateFilePinState: async (oldPath: string, newPath: string) => {
const { pinnedFilePaths, _updatePinnedFilePath } = get();
if (!pinnedFilePaths.includes(oldPath)) return;
await _updatePinnedFilePath(oldPath, newPath);
},
_updatePinnedFilePath: async (oldPath: string, newPath: string) => {
const { pinnedFilePaths, _updatePinnedFilePaths } = get();
if (!pinnedFilePaths.includes(oldPath)) return;
const pinnedIndex = pinnedFilePaths.indexOf(oldPath);
const paths = [...pinnedFilePaths];
paths.splice(pinnedIndex, 1, newPath);
await _updatePinnedFilePaths(paths);
},
});

View file

@ -6,6 +6,7 @@ import FolderFileSplitterPlugin from "src/main";
import { ExplorerStore } from "..";
import { ManualSortOrder } from "../common";
import { moveItemInArray } from "src/utils";
export interface ManualSortFolderSlice {
foldersManualSortOrder: ManualSortOrder;
@ -122,9 +123,11 @@ export const createManualSortFolderSlice =
if (currentIndex === atIndex) {
return foldersManualSortOrder;
}
const newOrder = [...initialOrder];
newOrder.splice(currentIndex, 1);
newOrder.splice(atIndex, 0, folder.path);
const newOrder = moveItemInArray(
initialOrder,
currentIndex,
atIndex
);
const updatedOrder = {
...foldersManualSortOrder,
[parentPath]: newOrder,

View file

@ -3,6 +3,7 @@ import { StateCreator } from "zustand";
import { FFS_PINNED_FOLDER_PATHS_KEY } from "src/assets/constants";
import FolderFileSplitterPlugin from "src/main";
import { removeItemFromArray, replaceItemInArray } from "src/utils";
import { ExplorerStore } from "..";
@ -14,10 +15,6 @@ export interface PinnedFolderSlice {
unpinFolder: (folder: TFolder) => Promise<void>;
isFolderPinned: (folder: TFolder) => boolean;
restorePinnedFolders: () => Promise<void>;
_updatePinnedFolderPath: (
oldPath: string,
newPath: string
) => Promise<void>;
updateFolderPinState: (oldPath: string, newPath: string) => Promise<void>;
}
@ -50,8 +47,9 @@ export const createPinnedFolderSlice =
unpinFolder: async (folder: TFolder) => {
const { pinnedFolderPaths, _updatePinnedFolderPaths } = get();
if (!pinnedFolderPaths.includes(folder.path)) return;
const folderPaths = pinnedFolderPaths.filter(
(path) => path !== folder.path
const folderPaths = removeItemFromArray(
pinnedFolderPaths,
folder.path
);
await _updatePinnedFolderPaths(folderPaths);
},
@ -71,18 +69,17 @@ export const createPinnedFolderSlice =
}
}
},
_updatePinnedFolderPath: async (oldPath: string, newPath: string) => {
const { pinnedFolderPaths, _updatePinnedFolderPaths } = get();
if (!pinnedFolderPaths.includes(oldPath)) return;
const pinnedIndex = pinnedFolderPaths.indexOf(oldPath);
const paths = [...pinnedFolderPaths];
paths.splice(pinnedIndex, 1, newPath);
await _updatePinnedFolderPaths(paths);
},
updateFolderPinState: async (oldPath: string, newPath: string) => {
const { pinnedFolderPaths, _updatePinnedFolderPath } = get();
const {
pinnedFolderPaths,
_updatePinnedFolderPaths,
} = get();
if (!pinnedFolderPaths.includes(oldPath)) return;
await _updatePinnedFolderPath(oldPath, newPath);
const updatedPaths = replaceItemInArray(
pinnedFolderPaths,
oldPath,
newPath
);
await _updatePinnedFolderPaths(updatedPaths);
},
});

View file

@ -3,7 +3,7 @@ import { StateCreator } from "zustand";
import { FFS_EXPANDED_FOLDER_PATHS_KEY } from "src/assets/constants";
import FolderFileSplitterPlugin from "src/main";
import { uniq } from "src/utils";
import { removeItemFromArray, uniq } from "src/utils";
import { ExplorerStore } from "..";
@ -49,7 +49,7 @@ export const createToggleFolderSlice =
} = get();
if (!canFolderToggle(folder)) return;
await changeExpandedFolderPaths(
expandedFolderPaths.filter((path) => path !== folder.path)
removeItemFromArray(expandedFolderPaths, folder.path)
);
},
changeExpandedFolderPaths: async (folderPaths: string[]) => {

View file

@ -2,6 +2,7 @@ import { StateCreator } from "zustand";
import { FFS_PINNED_TAG_PATHS_KEY } from "src/assets/constants";
import FolderFileSplitterPlugin from "src/main";
import { removeItemFromArray } from "src/utils";
import { ExplorerStore } from "..";
@ -45,7 +46,7 @@ export const createPinnedTagSlice =
const { pinnedTagPaths, _updatePinnedTagPaths } = get();
if (!pinnedTagPaths.includes(tagPath)) return;
await _updatePinnedTagPaths(
pinnedTagPaths.filter((path) => path !== tagPath)
removeItemFromArray(pinnedTagPaths, tagPath)
);
},
restorePinnedTags: async () => {

View file

@ -6,6 +6,7 @@ import FolderFileSplitterPlugin from "src/main";
import { ExplorerStore } from "..";
import { TagNode, TagTree } from ".";
import { removeItemFromArray } from "src/utils";
export interface TagStructureSlice {

View file

@ -2,7 +2,7 @@ import { StateCreator } from "zustand";
import { FFS_EXPANDED_TAG_PATHS_KEY } from "src/assets/constants";
import FolderFileSplitterPlugin from "src/main";
import { uniq } from "src/utils";
import { removeItemFromArray, uniq } from "src/utils";
import { ExplorerStore } from "..";
@ -46,7 +46,7 @@ export const createToggleTagSlice =
get();
if (!hasTagChildren(tag)) return;
await changeExpandedTagPaths(
expandedTagPaths.filter((path) => path !== tag.fullPath)
removeItemFromArray(expandedTagPaths, tag.fullPath)
);
},

View file

@ -26,3 +26,40 @@ export const toValidNumber = (value: string | null): number | null => {
const num = Number(value);
return value !== null && !isNaN(num) ? num : null;
};
export const replaceItemInArray = <T>(
array: T[],
oldItem: T,
newItem: T
): T[] => {
const index = array.indexOf(oldItem);
if (index === -1) return array;
const newArray = [...array];
newArray.splice(index, 1, newItem);
return newArray;
};
export const moveItemInArray = <T>(
array: T[],
fromIndex: number,
toIndex: number
): T[] => {
if (
fromIndex < 0 ||
toIndex < 0 ||
fromIndex >= array.length ||
toIndex >= array.length ||
fromIndex === toIndex
) {
return array;
}
const newArray = [...array];
const [item] = newArray.splice(fromIndex, 1);
newArray.splice(toIndex, 0, item);
return newArray;
};
export const removeItemFromArray = <T>(array: T[], item: T): T[] => {
return array.filter((i) => i !== item);
};