Skip to content

Commit

Permalink
fix: fix file history error
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanyxh committed May 11, 2024
1 parent aec7168 commit 000d97c
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 87 deletions.
17 changes: 13 additions & 4 deletions src/filehandle/FileLinkedList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,22 @@ class FileLinkedList {
}
}

unlink(handle: DH) {
async unlink(handle: DH) {
const { next } = this.current;

if (next && next.value === handle) {
this.current.next = null;
if (!next) return false;

this.event.emit(UPDATE_KEY, this.current.value);
try {
const isSame = await next.value.isSameEntry(handle);

if (isSame) {
this.current.next = null;
this.event.emit(UPDATE_KEY, this.current.value);
}

return isSame;
} catch (err) {
return false;
}
}

Expand Down
176 changes: 109 additions & 67 deletions src/filehandle/WebdavFile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createElement } from 'react';

import { isEqual } from 'lodash-es';
import type { FileStat, WebDAVClient } from 'webdav';
import { AuthType, createClient } from 'webdav';

Expand All @@ -13,16 +14,23 @@ import { FileType } from './utils/fileManager';
function createWebdavFileSystemHandle(
file: FileStat,
webdav: WebDAVClient,
parentPath: string
parentPath: string,
webdavInfo: WebdavInfo
) {
if (file.type == 'directory') {
return new WebdavFileSystemDirectoryHandle(
webdav,
parentPath + '/',
file.basename
file.basename,
webdavInfo
);
} else {
return new WebdavFileSystemFileHandle(webdav, parentPath, file.basename);
return new WebdavFileSystemFileHandle(
webdav,
parentPath,
file.basename,
webdavInfo
);
}
}

Expand Down Expand Up @@ -77,37 +85,60 @@ class WebdavFileSystemWritableFileStream
}
}

class WebdavFileSystemFileHandle implements FileSystemFileHandle {
readonly kind = 'file';
class WebdavFileSystemHandle implements FileSystemHandle {
kind: FileSystemHandleKind;
name: string;

private webdav: WebDAVClient;
private _fullPath: string;

private fullPath: string;
private _webdav: WebDAVClient;

private _name: string;
private _webdavInfo: WebdavInfo;

private file: File | null = null;
constructor(
kind: FileSystemHandleKind,
name: string,
fullPath: string,
webdavClient: WebDAVClient,
webdavInfo: WebdavInfo
) {
this.kind = kind;
this.name = name;

constructor(webdav: WebDAVClient, fullPath: string, name: string) {
this.webdav = webdav;
this._fullPath = fullPath;
this._webdav = webdavClient;

this._name = name;
this._webdavInfo = webdavInfo;
}

this.fullPath = fullPath;
get fullPath() {
return this._fullPath;
}

get name() {
return this._name;
get webdav() {
return this._webdav;
}

createSyncAccessHandle(): Promise<FileSystemSyncAccessHandle> {
throw new Error('Method not implemented.');
get webdavInfo() {
return this._webdavInfo;
}

isSameEntry(other: FileSystemHandle): Promise<boolean>;
isSameEntry(arg: FileSystemHandle): boolean;
isSameEntry(): boolean | Promise<boolean> {
throw new Error('Method not implemented.');
isSameEntry(other: WebdavFileSystemHandle): Promise<boolean>;
isSameEntry(arg: WebdavFileSystemHandle): boolean;
isSameEntry(handle: WebdavFileSystemHandle): boolean | Promise<boolean> {
try {
if (
handle instanceof WebdavFileSystemHandle &&
isEqual(this.webdavInfo, handle.webdavInfo) &&
this._fullPath === handle._fullPath
) {
return Promise.resolve(true);
}
} catch (err) {
return Promise.resolve(false);
}

return Promise.resolve(false);
}

queryPermission(): Promise<PermissionStatus> {
Expand All @@ -121,6 +152,28 @@ class WebdavFileSystemFileHandle implements FileSystemFileHandle {
remove(): Promise<undefined> {
throw new Error('Method not implemented.');
}
}

class WebdavFileSystemFileHandle
extends WebdavFileSystemHandle
implements FileSystemFileHandle
{
readonly kind = 'file';

private file: File | null = null;

constructor(
webdav: WebDAVClient,
fullPath: string,
name: string,
webdavInfo: WebdavInfo
) {
super('file', name, fullPath, webdav, webdavInfo);
}

createSyncAccessHandle(): Promise<FileSystemSyncAccessHandle> {
throw new Error('Method not implemented.');
}

async getFile() {
if (this.file) {
Expand All @@ -131,7 +184,7 @@ class WebdavFileSystemFileHandle implements FileSystemFileHandle {
format: 'binary'
})) as ArrayBuffer;

this.file = new File([data], this._name);
this.file = new File([data], this.name);

return this.file;
}
Expand All @@ -146,29 +199,24 @@ class WebdavFileSystemFileHandle implements FileSystemFileHandle {
return new WebdavFileSystemWritableFileStream(
webdav,
fullPath,
(buffer) => (this.file = new File([buffer], this._name))
(buffer) => (this.file = new File([buffer], this.name))
);
}
}

class WebdavFileSystemDirectoryHandle implements FileSystemDirectoryHandle {
class WebdavFileSystemDirectoryHandle
extends WebdavFileSystemHandle
implements FileSystemDirectoryHandle
{
readonly kind = 'directory';

private webdav: WebDAVClient;

private fullPath: string;

private _name: string;

constructor(webdav: WebDAVClient, fullPath: string, name: string) {
this.webdav = webdav;

this._name = name;
this.fullPath = fullPath;
}

get name() {
return this._name;
constructor(
webdav: WebDAVClient,
fullPath: string,
name: string,
webdavInfo: WebdavInfo
) {
super('directory', name, fullPath, webdav, webdavInfo);
}

resolve(possibleDescendant: FileSystemHandle): Promise<string[] | null>;
Expand All @@ -187,30 +235,12 @@ class WebdavFileSystemDirectoryHandle implements FileSystemDirectoryHandle {
throw new Error('Method not implemented.');
}

isSameEntry(other: FileSystemHandle): Promise<boolean>;
isSameEntry(arg: FileSystemHandle): boolean;
isSameEntry(): boolean | Promise<boolean> {
throw new Error('Method not implemented.');
}

queryPermission(): Promise<PermissionStatus> {
throw new Error('Method not implemented.');
}

requestPermission(): Promise<PermissionStatus> {
throw new Error('Method not implemented.');
}

remove(): Promise<undefined> {
throw new Error('Method not implemented.');
}

entries(): AsyncIterableIterator<
[string, WebdavFileSystemDirectoryHandle | WebdavFileSystemFileHandle]
> {
let i = 0;

const { webdav, fullPath } = this;
const { webdav, fullPath, webdavInfo } = this;

const p = webdav.getDirectoryContents(fullPath, {
includeSelf: false
Expand All @@ -232,7 +262,12 @@ class WebdavFileSystemDirectoryHandle implements FileSystemDirectoryHandle {
return {
value: [
curr.basename,
createWebdavFileSystemHandle(curr, webdav, fullPath + curr.basename)
createWebdavFileSystemHandle(
curr,
webdav,
fullPath + curr.basename,
webdavInfo
)
],
done: false
};
Expand Down Expand Up @@ -267,7 +302,8 @@ class WebdavFileSystemDirectoryHandle implements FileSystemDirectoryHandle {
return new WebdavFileSystemDirectoryHandle(
this.webdav,
subFullPath + '/',
name
name,
this.webdavInfo
);
}

Expand All @@ -293,7 +329,12 @@ class WebdavFileSystemDirectoryHandle implements FileSystemDirectoryHandle {
}
}

return new WebdavFileSystemFileHandle(this.webdav, subFullPath, name);
return new WebdavFileSystemFileHandle(
this.webdav,
subFullPath,
name,
this.webdavInfo
);
}

async removeEntry(name: string): Promise<undefined> {
Expand Down Expand Up @@ -321,19 +362,20 @@ class WebdavFile {

remote = true;

constructor(webdav: WebdavInfo) {
this.name = webdav.name;
constructor(webdavInfo: WebdavInfo) {
this.name = webdavInfo.name;

this.webdav = createClient(webdav.url, {
this.webdav = createClient(webdavInfo.url, {
authType: AuthType.Auto,
username: webdav.username,
password: webdav.password
username: webdavInfo.username,
password: webdavInfo.password
});

this.handle = new WebdavFileSystemDirectoryHandle(
this.webdav,
'/',
this.name
this.name,
webdavInfo
);
}
}
Expand Down
22 changes: 14 additions & 8 deletions src/filehandle/components/FileContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ function MountWebdavModal(props: { open: boolean; close(): void }) {
name="username"
rules={[{ required: true, message: 'Please input your username!' }]}
>
<Input />
<Input autoComplete="username" />
</Form.Item>

<Form.Item<WebdavInfo>
label="密码"
name="password"
rules={[{ required: true, message: 'Please input your password!' }]}
>
<Input.Password />
<Input.Password autoComplete="current-password" />
</Form.Item>
</Form>
</Modal>
Expand Down Expand Up @@ -249,19 +249,25 @@ const FileContent: React.FC<IFileContentProps> = (props) => {
async onOk() {
try {
let _webdavs = webdavs.slice(0);

_selection.map((file) => {
if (file.remote) {
_webdavs = _webdavs.filter((webdav) => webdav.name !== file.name);
_webdavs = _webdavs.filter((webdav) => {
if (
webdav.name === file.name &&
file.handle.kind === 'directory'
) {
fileLinked.unlink(file.handle);
}

return webdav.name !== file.name;
});
}
});

setWebdavs(_webdavs);

await Promise.all(names.map((name) => remove(name)));

_selection.map(
(file) =>
file.handle.kind === 'directory' && fileLinked.unlink(file.handle)
);
} catch (err) {
error((err as Error).message);
}
Expand Down
12 changes: 10 additions & 2 deletions src/filehandle/hooks/useFileSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function useFileSystem(): FileSystem {

useMemo(() => update(), [webdavs]);

useMemo(
useEffect(
() => fileLinked.current?.listener((directory) => update(directory)),
[fileLinked.current, webdavs]
);
Expand Down Expand Up @@ -145,7 +145,15 @@ export function useFileSystem(): FileSystem {
try {
await removeFile(current, name);

setChildren(children.filter((c) => c.name !== name));
setChildren(
children.filter((c) => {
if (c.name === name && c.handle.kind === 'directory') {
fileLinked.current.unlink(c.handle);
}

return c.name !== name;
})
);
} catch (err) {
error((err as Error).message);
}
Expand Down
Loading

0 comments on commit 000d97c

Please sign in to comment.