queue/source/settings/settings.ts

135 lines
3.4 KiB
TypeScript
Raw Normal View History

2022-03-05 13:10:45 +00:00
import browser from 'webextension-polyfill';
2022-10-03 16:44:28 +00:00
import {migrate} from '@holllo/migration-helper';
2022-03-05 13:10:45 +00:00
import {History} from '../utilities/history.js';
import {
dataMigrations,
deserializeQueue,
serializeQueue,
} from './migrations.js';
export class Settings {
public static async fromSyncStorage(): Promise<Settings> {
const settings = new Settings();
const sync = await browser.storage.sync.get(null);
const migrated = (await migrate(
sync,
sync.version ?? settings.version,
dataMigrations,
)) as Record<string, any>;
settings.queue = deserializeQueue(migrated);
settings.version = migrated.version as string;
await settings.save();
return settings;
}
public manifest: browser.Manifest.ManifestBase;
public queue: Queue.Item[];
public version: string;
constructor() {
this.manifest = browser.runtime.getManifest();
this.queue = [];
this.version = '0.0.0';
}
public async insertQueueItem(text: string, url: string): Promise<void> {
const id = this.newQueueItemId();
const item: Queue.Item = {
added: new Date(),
id,
2022-10-25 10:04:11 +00:00
sortIndex: id,
2022-03-05 13:10:45 +00:00
text,
url,
};
this.queue.push(item);
await browser.storage.sync.set({
[`qi${id}`]: {
added: item.added.toISOString(),
id,
2022-10-25 10:04:11 +00:00
sortIndex: id,
text,
url,
},
});
2022-03-05 13:10:45 +00:00
}
public async moveQueueItem(
id: number,
direction: Queue.MoveDirection,
): Promise<void> {
const targetItem = this.queue.find((item) => item.id === id);
if (targetItem === undefined) {
throw new Error(`Failed to move item with ID: ${id}`);
}
const currentIndex = targetItem.sortIndex;
const targetIndex = this.nextQueueItemSortIndex(currentIndex, direction);
const existingItem = this.queue.find(
2022-10-25 10:55:07 +00:00
(item) => item.sortIndex === targetIndex,
);
if (existingItem !== undefined && targetIndex !== undefined) {
existingItem.sortIndex = currentIndex;
2022-10-25 10:55:07 +00:00
targetItem.sortIndex = targetIndex;
await this.save();
}
}
2022-03-05 13:10:45 +00:00
public newQueueItemId(): number {
const item = this.queue.sort((a, b) => b.id - a.id)[0];
return item === undefined ? 1 : item.id + 1;
}
public nextQueueItem(): Queue.Item | undefined {
return this.queue.sort((a, b) => a.sortIndex - b.sortIndex)[0];
2022-03-05 13:10:45 +00:00
}
public nextQueueItemSortIndex(
currentIndex: number,
direction: Queue.MoveDirection,
): number | undefined {
this.queue.sort((a, b) => {
return direction === 'up'
? b.sortIndex - a.sortIndex
: a.sortIndex - b.sortIndex;
});
let foundCurrent = false;
for (const item of this.queue) {
if (foundCurrent) {
return item.sortIndex;
}
if (item.sortIndex === currentIndex) {
foundCurrent = true;
}
}
}
2022-03-05 13:10:45 +00:00
public async removeQueueItem(id: number): Promise<void> {
const itemIndex = this.queue.findIndex((item) => item.id === id);
if (itemIndex === -1) {
console.error(`Tried to remove an item with unknown ID: ${id}`);
return;
}
const removedItems = this.queue.splice(itemIndex, 1);
await browser.storage.sync.remove(removedItems.map(({id}) => `qi${id}`));
const history = await History.fromLocalStorage();
await history.insertItems(removedItems);
}
public async save(): Promise<void> {
await browser.storage.sync.set({
...serializeQueue(this.queue),
version: this.version,
});
}
}