import { WordItem, WordSetInfo } from '@/types'; import { v1 as uuidv1 } from 'uuid'; // Add type declarations for the File System Access API declare global { interface FileSystemWritableFileStream { write(data: any): Promise; seek(position: number): Promise; truncate(size: number): Promise; close(): Promise; } interface FileSystemFileHandle { getFile(): Promise; createWritable(): Promise; } interface Window { showSaveFilePicker(options?: { types?: Array<{ description: string; accept: Record; }>; }): Promise; showOpenFilePicker(options?: { multiple?: boolean; types?: Array<{ description: string; accept: Record; }>; }): Promise; } } export class Wordset { private sets: {[className: string]: WordSetInfo[]}; constructor() { this.sets = {}; let wordsets = localStorage.getItem("wordsets"); if (wordsets) { this.sets = JSON.parse(wordsets); } } save(): void { localStorage.setItem("wordsets", JSON.stringify(this.sets)); } get _inner(): {[className: string]: WordSetInfo[]} { return this.sets; } get _firstClass(): string | null { return Object.keys(this.sets)[0] || null; } get _allclass(): string[] { return Object.keys(this.sets); } get _allsets(): WordSetInfo[][] { return Object.values(this.sets); } getClass(class_name: string): WordSetInfo[] | null { if (this.sets[class_name]) { return this.sets[class_name]; } else return null; } getSetStatus(class_name: string, id: string): WordSetInfo | null { let set_class = this.getClass(class_name); if(set_class) { for(let i of set_class) { if(i.id === id) { return i; } } } return null; } getId(class_name: string, id: string): number | undefined { let set_class = this.sets[class_name]; for(let index in set_class) { if(set_class[index].id === id) { return Number(index); } } return undefined; } getSet(id: string): WordItem[] { let sets = localStorage.getItem(id); if (sets) { return JSON.parse(sets); } else return []; } delSet(class_name: string, index: number): boolean { let set_class = this.sets[class_name]; if (set_class) { if (set_class[index]) { localStorage.removeItem(set_class[index].id); this.sets[class_name].splice(index, 1); if (!this.sets[class_name].length) { delete this.sets[class_name]; } localStorage.setItem("wordsets", JSON.stringify(this.sets)); return true; } } return false; } addSet(class_name: string, name: string): string { if (!this.sets[class_name]) { this.sets[class_name] = []; } let id = uuidv1(); let time = (new Date()).getTime() this.sets[class_name].push({ name: name, id: id, created: time, }); localStorage.setItem(id, JSON.stringify([])); this.save(); return id; } saveSet(id: string, data: WordItem[]): void { localStorage.setItem(id, JSON.stringify(data)); } renameSet(class_name: string, id: string, new_name: string): void { let set_class = this.getClass(class_name); if(set_class) { for(let i of set_class) { if(i.id === id) { i.name = new_name; this.save(); return; } } } } addSetTo(origin_id: string, dest_id: string): number { let origin_set = this.getSet(origin_id); let dest_set = this.getSet(dest_id); let set: {[word: string]: WordItem} = {}; origin_set.forEach(element => { set[element.word] = element; }); dest_set.forEach(element => { set[element.word] = element; }); let mergedSet = Object.values(set); this.saveSet(dest_id, mergedSet); return origin_set.length + dest_set.length - mergedSet.length; } fromArray(arr: WordItem[], class_name: string, name: string): void { let id = this.addSet(class_name, name); this.saveSet(id, arr); } async import_set(callback?: (count: number) => void): Promise { let [fileHandle] = await window.showOpenFilePicker({ types: [ { description: "JSON file", accept: { 'text/json': ['.json'], }, }, ], }); let file = await fileHandle.getFile(); let data = JSON.parse(await file.text()); let cnt = 0; for (let i of Object.keys(data.wordsets)) { for (let j of data.wordsets[i]) { if (!localStorage.getItem(j.id)) { if (!this.sets[i]) this.sets[i] = []; this.sets[i].push(j); localStorage.setItem(j.id, data.words[j.id]); cnt++; } } } this.save(); if(typeof callback === "function") { callback(cnt); } } async export_set(callback?: (count: number) => void): Promise { let fileHandle = await window.showSaveFilePicker({ types: [ { description: "JSON file", accept: { 'text/json': ['.json'], }, }, ], }); let writestream = await fileHandle.createWritable(); let data = { wordsets: this.sets, words: {} as {[id: string]: string} }; let cnt = 0; for (let i of Object.values(this.sets)) { for (let j of i) { let temp = localStorage.getItem(j.id); if (temp) { data.words[j.id] = temp; cnt++; } } } await writestream.write(JSON.stringify(data)); await writestream.close(); if(typeof callback === "function") { callback(cnt); } } }