Files
wordIn/src/scripts/wordsets.ts
T

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);
}
}
}