235 lines
6.7 KiB
TypeScript
235 lines
6.7 KiB
TypeScript
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<void>;
|
|
seek(position: number): Promise<void>;
|
|
truncate(size: number): Promise<void>;
|
|
close(): Promise<void>;
|
|
}
|
|
|
|
interface FileSystemFileHandle {
|
|
getFile(): Promise<File>;
|
|
createWritable(): Promise<FileSystemWritableFileStream>;
|
|
}
|
|
|
|
interface Window {
|
|
showSaveFilePicker(options?: {
|
|
types?: Array<{
|
|
description: string;
|
|
accept: Record<string, string[]>;
|
|
}>;
|
|
}): Promise<FileSystemFileHandle>;
|
|
|
|
showOpenFilePicker(options?: {
|
|
multiple?: boolean;
|
|
types?: Array<{
|
|
description: string;
|
|
accept: Record<string, string[]>;
|
|
}>;
|
|
}): Promise<FileSystemFileHandle[]>;
|
|
}
|
|
}
|
|
|
|
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<void> {
|
|
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<void> {
|
|
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);
|
|
}
|
|
}
|
|
} |