csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.3 KiB
111 lines
3.3 KiB
import { avaloniaDb, fileBookmarksStore } from "./indexedDb";
|
|
|
|
export class StorageItem {
|
|
constructor(public handle: FileSystemHandle, private readonly bookmarkId?: string) { }
|
|
|
|
public get name(): string {
|
|
return this.handle.name;
|
|
}
|
|
|
|
public get kind(): string {
|
|
return this.handle.kind;
|
|
}
|
|
|
|
public static async openRead(item: StorageItem): Promise<Blob> {
|
|
if (!(item.handle instanceof FileSystemFileHandle)) {
|
|
throw new Error("StorageItem is not a file");
|
|
}
|
|
|
|
await item.verityPermissions("read");
|
|
|
|
const file = await item.handle.getFile();
|
|
return file;
|
|
}
|
|
|
|
public static async openWrite(item: StorageItem): Promise<FileSystemWritableFileStream> {
|
|
if (!(item.handle instanceof FileSystemFileHandle)) {
|
|
throw new Error("StorageItem is not a file");
|
|
}
|
|
|
|
await item.verityPermissions("readwrite");
|
|
|
|
return await item.handle.createWritable({ keepExistingData: true });
|
|
}
|
|
|
|
public static async getProperties(item: StorageItem): Promise<{ Size: number; LastModified: number; Type: string } | null> {
|
|
const file = item.handle instanceof FileSystemFileHandle &&
|
|
await item.handle.getFile();
|
|
|
|
if (!file) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
Size: file.size,
|
|
LastModified: file.lastModified,
|
|
Type: file.type
|
|
};
|
|
}
|
|
|
|
public static async getItems(item: StorageItem): Promise<StorageItems> {
|
|
if (item.handle.kind !== "directory") {
|
|
return new StorageItems([]);
|
|
}
|
|
|
|
const items: StorageItem[] = [];
|
|
for await (const [, value] of (item.handle as any).entries()) {
|
|
items.push(new StorageItem(value));
|
|
}
|
|
return new StorageItems(items);
|
|
}
|
|
|
|
private async verityPermissions(mode: FileSystemPermissionMode): Promise<void | never> {
|
|
if (await this.handle.queryPermission({ mode }) === "granted") {
|
|
return;
|
|
}
|
|
|
|
if (await this.handle.requestPermission({ mode }) === "denied") {
|
|
throw new Error("Permissions denied");
|
|
}
|
|
}
|
|
|
|
public static async saveBookmark(item: StorageItem): Promise<string> {
|
|
// If file was previously bookmarked, just return old one.
|
|
if (item.bookmarkId) {
|
|
return item.bookmarkId;
|
|
}
|
|
|
|
const connection = await avaloniaDb.connect();
|
|
try {
|
|
const key = await connection.put(fileBookmarksStore, item.handle, item.generateBookmarkId());
|
|
return key as string;
|
|
} finally {
|
|
connection.close();
|
|
}
|
|
}
|
|
|
|
public static async deleteBookmark(item: StorageItem): Promise<void> {
|
|
if (!item.bookmarkId) {
|
|
return;
|
|
}
|
|
|
|
const connection = await avaloniaDb.connect();
|
|
try {
|
|
await connection.delete(fileBookmarksStore, item.bookmarkId);
|
|
} finally {
|
|
connection.close();
|
|
}
|
|
}
|
|
|
|
private generateBookmarkId(): string {
|
|
return Date.now().toString(36) + Math.random().toString(36).substring(2);
|
|
}
|
|
}
|
|
|
|
export class StorageItems {
|
|
constructor(private readonly items: StorageItem[]) { }
|
|
|
|
public static itemsArray(instance: StorageItems): StorageItem[] {
|
|
return instance.items;
|
|
}
|
|
}
|
|
|