Add session-based history for queued items.
This commit is contained in:
parent
64cc7a6ed9
commit
596487a835
|
@ -1,6 +1,6 @@
|
||||||
import browser, {Menus} from 'webextension-polyfill';
|
import browser, {Menus} from 'webextension-polyfill';
|
||||||
|
|
||||||
import {error} from './utilities/log';
|
import {debug, error} from './utilities/log';
|
||||||
import {getManifest, updateBadge} from './utilities/browser';
|
import {getManifest, updateBadge} from './utilities/browser';
|
||||||
import {versionAsNumber} from './utilities/version';
|
import {versionAsNumber} from './utilities/version';
|
||||||
import Settings from './utilities/settings';
|
import Settings from './utilities/settings';
|
||||||
|
@ -9,6 +9,11 @@ import {Queue} from './types.d';
|
||||||
|
|
||||||
let timeoutID: number | null = null;
|
let timeoutID: number | null = null;
|
||||||
|
|
||||||
|
browser.runtime.onStartup.addListener(async () => {
|
||||||
|
debug('Removing history from local storage');
|
||||||
|
await browser.storage.local.remove('history');
|
||||||
|
});
|
||||||
|
|
||||||
browser.browserAction.onClicked.addListener(async () => {
|
browser.browserAction.onClicked.addListener(async () => {
|
||||||
const settings = await Settings.get();
|
const settings = await Settings.get();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Queue",
|
"name": "Queue",
|
||||||
"description": "A WebExtension for queueing links.",
|
"description": "A WebExtension for queueing links.",
|
||||||
"version": "0.1.8",
|
"version": "0.1.9",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"contextMenus",
|
"contextMenus",
|
||||||
"storage",
|
"storage",
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history,
|
||||||
.usage {
|
.usage {
|
||||||
border: 1px solid var(--df-2);
|
border: 1px solid var(--df-2);
|
||||||
|
|
||||||
|
@ -75,7 +76,17 @@
|
||||||
color: var(--db-1);
|
color: var(--db-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.history {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.q-list {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.usage {
|
||||||
ul {
|
ul {
|
||||||
list-style: square;
|
list-style: square;
|
||||||
margin: 4px 0 2rem 16px;
|
margin: 4px 0 2rem 16px;
|
||||||
|
|
|
@ -8,6 +8,10 @@ import Settings from './utilities/settings';
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', async () => {
|
window.addEventListener('DOMContentLoaded', async () => {
|
||||||
window.HollloQueue = {
|
window.HollloQueue = {
|
||||||
|
clearHistory: async () => {
|
||||||
|
debug('Clearing history');
|
||||||
|
await browser.storage.local.remove('history');
|
||||||
|
},
|
||||||
dumpBackup: async () => {
|
dumpBackup: async () => {
|
||||||
debug(JSON.stringify(await browser.storage.local.get(), null, 2));
|
debug(JSON.stringify(await browser.storage.local.get(), null, 2));
|
||||||
},
|
},
|
||||||
|
@ -28,10 +32,12 @@ window.addEventListener('DOMContentLoaded', async () => {
|
||||||
await settings.save();
|
await settings.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const history = await browser.storage.local.get({history: []});
|
||||||
|
|
||||||
render(
|
render(
|
||||||
html`
|
html`
|
||||||
<${PageHeader} />
|
<${PageHeader} />
|
||||||
<${PageMain} settings=${settings} />
|
<${PageMain} history=${history.history} settings=${settings} />
|
||||||
<${PageFooter}
|
<${PageFooter}
|
||||||
manifest=${manifest}
|
manifest=${manifest}
|
||||||
showVersionUpdated=${showVersionUpdated}
|
showVersionUpdated=${showVersionUpdated}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import browser from 'webextension-polyfill';
|
||||||
export {};
|
export {};
|
||||||
|
|
||||||
type HollloQueue = {
|
type HollloQueue = {
|
||||||
|
clearHistory: () => Promise<void>;
|
||||||
dumpBackup: () => Promise<void>;
|
dumpBackup: () => Promise<void>;
|
||||||
dumpSettings: () => Promise<void>;
|
dumpSettings: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {Link} from './link';
|
||||||
import {ConfirmButton} from './confirm-button';
|
import {ConfirmButton} from './confirm-button';
|
||||||
|
|
||||||
type MainProps = {
|
type MainProps = {
|
||||||
|
history: Queue.Item[];
|
||||||
settings: Settings;
|
settings: Settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,12 +38,29 @@ export class PageMain extends Component<MainProps, MainState> {
|
||||||
queueItems.push(html`<li>No items queued. 🤷</li>`);
|
queueItems.push(html`<li>No items queued. 🤷</li>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const historyItems: Queue.Component[] = this.props.history
|
||||||
|
.sort((a, b) => b.added.getTime() - a.added.getTime())
|
||||||
|
.map((item) => html`<${Item} item=${item} />`);
|
||||||
|
|
||||||
|
let history: Queue.Component | undefined;
|
||||||
|
if (historyItems.length > 0) {
|
||||||
|
history = html`<details class="history">
|
||||||
|
<summary>Queue history</summary>
|
||||||
|
|
||||||
|
<ul class="q-list">
|
||||||
|
${historyItems}
|
||||||
|
</ul>
|
||||||
|
</details>`;
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<main class="page-main">
|
<main class="page-main">
|
||||||
<ul class="q-list">
|
<ul class="q-list">
|
||||||
${queueItems}
|
${queueItems}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
${history}
|
||||||
|
|
||||||
<details class="usage">
|
<details class="usage">
|
||||||
<summary>How do I use Queue?</summary>
|
<summary>How do I use Queue?</summary>
|
||||||
|
|
||||||
|
@ -87,12 +105,24 @@ export class PageMain extends Component<MainProps, MainState> {
|
||||||
|
|
||||||
type ItemProps = {
|
type ItemProps = {
|
||||||
item: Queue.Item;
|
item: Queue.Item;
|
||||||
remove: (id: number) => Promise<void>;
|
remove?: (id: number) => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
function Item(props: ItemProps): Queue.Component {
|
function Item(props: ItemProps): Queue.Component {
|
||||||
const added = props.item.added.toLocaleString();
|
const added = props.item.added.toLocaleString();
|
||||||
const {id, text, url} = props.item;
|
const {id, text, url} = props.item;
|
||||||
|
let remove;
|
||||||
|
if (props.remove !== undefined) {
|
||||||
|
remove = html`<${ConfirmButton}
|
||||||
|
class="confirm-button"
|
||||||
|
clickHandler=${async () => props.remove!(id)}
|
||||||
|
confirmClass="confirm"
|
||||||
|
confirmText="✓"
|
||||||
|
text="✗"
|
||||||
|
timeout=${5 * 1000}
|
||||||
|
title="Remove"
|
||||||
|
/>`;
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<li class="q-item">
|
<li class="q-item">
|
||||||
|
@ -100,17 +130,7 @@ function Item(props: ItemProps): Queue.Component {
|
||||||
<${Link} text=${text ?? url} url=${url} />
|
<${Link} text=${text ?? url} url=${url} />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">${remove}</div>
|
||||||
<${ConfirmButton}
|
|
||||||
class="confirm-button"
|
|
||||||
clickHandler=${async () => props.remove(id)}
|
|
||||||
confirmClass="confirm"
|
|
||||||
confirmText="✓"
|
|
||||||
text="✗"
|
|
||||||
timeout=${5 * 1000}
|
|
||||||
title="Remove"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<time datetime=${added} title="Link queued on ${added}.">
|
<time datetime=${added} title="Link queued on ${added}.">
|
||||||
|
|
|
@ -89,7 +89,19 @@ export default class Settings implements ISettings {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.queue.splice(index, 1);
|
const removed = this.queue.splice(index, 1);
|
||||||
|
const history = (
|
||||||
|
(await browser.storage.local.get({history: []})) as {
|
||||||
|
history: Queue.Item[];
|
||||||
|
}
|
||||||
|
).history;
|
||||||
|
|
||||||
|
history.push(removed[0]);
|
||||||
|
for (const [index, item] of history.entries()) {
|
||||||
|
item.id = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
await browser.storage.local.set({history});
|
||||||
await browser.storage.sync.remove('qi' + id.toString());
|
await browser.storage.sync.remove('qi' + id.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue