2022-10-03 16:44:28 +00:00
|
|
|
import {ConfirmButton, PrivacyLink} from '@holllo/preact-components';
|
2021-09-01 10:46:29 +00:00
|
|
|
import {Component, html} from 'htm/preact';
|
|
|
|
|
2022-09-27 10:49:00 +00:00
|
|
|
import type {Settings} from '../../settings/settings.js';
|
2022-03-14 22:58:05 +00:00
|
|
|
import {updateBadge} from '../../utilities/badge.js';
|
2022-09-27 10:49:00 +00:00
|
|
|
import type {History} from '../../utilities/history.js';
|
2020-11-11 17:17:37 +00:00
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
type Props = {
|
|
|
|
history: History;
|
2020-11-11 17:17:37 +00:00
|
|
|
settings: Settings;
|
|
|
|
};
|
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
type State = {
|
2021-09-01 10:46:29 +00:00
|
|
|
queue: Queue.Item[];
|
|
|
|
};
|
2020-11-11 17:17:37 +00:00
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
export class PageMain extends Component<Props, State> {
|
|
|
|
constructor(props: Props) {
|
2021-09-01 10:46:29 +00:00
|
|
|
super(props);
|
2022-03-05 13:10:45 +00:00
|
|
|
|
2021-09-01 10:46:29 +00:00
|
|
|
this.state = {
|
|
|
|
queue: props.settings.queue,
|
|
|
|
};
|
2020-11-11 17:17:37 +00:00
|
|
|
}
|
|
|
|
|
2022-10-25 11:08:53 +00:00
|
|
|
moveItem = async (id: number, direction: Queue.MoveDirection) => {
|
|
|
|
const {settings} = this.props;
|
|
|
|
await settings.moveQueueItem(id, direction);
|
|
|
|
this.setState({queue: this.props.settings.queue});
|
|
|
|
};
|
|
|
|
|
2021-09-01 10:46:29 +00:00
|
|
|
removeItem = async (id: number) => {
|
2022-03-05 13:10:45 +00:00
|
|
|
const {settings} = this.props;
|
|
|
|
await settings.removeQueueItem(id);
|
2022-03-14 22:58:05 +00:00
|
|
|
await updateBadge(settings);
|
2022-03-05 13:10:45 +00:00
|
|
|
this.setState({queue: this.props.settings.queue});
|
2021-09-01 10:46:29 +00:00
|
|
|
};
|
2020-11-11 17:17:37 +00:00
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
render() {
|
2022-03-20 18:59:00 +00:00
|
|
|
const isFirefox = import.meta.env.VITE_BROWSER === 'firefox';
|
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
const queueItems = this.state.queue
|
2022-10-25 11:08:53 +00:00
|
|
|
.sort((a, b) => a.sortIndex - b.sortIndex)
|
2022-03-05 13:10:45 +00:00
|
|
|
.map(
|
2022-10-25 11:08:53 +00:00
|
|
|
(item) =>
|
|
|
|
html`
|
|
|
|
<${queueItem}
|
|
|
|
item=${item}
|
|
|
|
move=${this.moveItem}
|
|
|
|
remove=${this.removeItem}
|
|
|
|
/>
|
|
|
|
`,
|
2022-03-05 13:10:45 +00:00
|
|
|
);
|
2020-11-11 17:17:37 +00:00
|
|
|
|
2021-09-01 10:46:29 +00:00
|
|
|
if (queueItems.length === 0) {
|
|
|
|
queueItems.push(html`<li>No items queued. 🤷</li>`);
|
|
|
|
}
|
2020-11-11 17:17:37 +00:00
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
const historyItems = this.props.history.queue
|
2021-09-02 13:59:18 +00:00
|
|
|
.sort((a, b) => b.added.getTime() - a.added.getTime())
|
2022-03-05 13:10:45 +00:00
|
|
|
.map((item) => html`<${queueItem} item=${item} />`);
|
2021-09-02 13:59:18 +00:00
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
let history: HtmComponent | undefined;
|
2021-09-02 13:59:18 +00:00
|
|
|
if (historyItems.length > 0) {
|
2022-03-05 13:10:45 +00:00
|
|
|
history = html`
|
|
|
|
<details class="history">
|
|
|
|
<summary>Queue history</summary>
|
2021-09-02 13:59:18 +00:00
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
<ul class="q-list">
|
|
|
|
${historyItems}
|
|
|
|
</ul>
|
|
|
|
</details>
|
|
|
|
`;
|
2021-09-02 13:59:18 +00:00
|
|
|
}
|
|
|
|
|
2021-09-01 10:46:29 +00:00
|
|
|
return html`
|
|
|
|
<main class="page-main">
|
|
|
|
<ul class="q-list">
|
|
|
|
${queueItems}
|
2020-11-11 17:17:37 +00:00
|
|
|
</ul>
|
|
|
|
|
2021-09-02 13:59:18 +00:00
|
|
|
${history}
|
|
|
|
|
2021-09-01 10:46:29 +00:00
|
|
|
<details class="usage">
|
|
|
|
<summary>How do I use Queue?</summary>
|
|
|
|
|
|
|
|
<p>Adding links to your queue:</p>
|
|
|
|
<ul>
|
2022-03-20 18:59:00 +00:00
|
|
|
<li>
|
|
|
|
Right-click any link ${isFirefox ? 'or tab' : ''} and click "Add
|
|
|
|
to Queue".
|
|
|
|
</li>
|
2021-09-01 10:46:29 +00:00
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>Opening the next link from your queue:</p>
|
|
|
|
<ul>
|
2022-03-14 22:58:05 +00:00
|
|
|
<li>Click on the extension icon to open it in the current tab.</li>
|
2021-09-01 10:46:29 +00:00
|
|
|
<li>
|
|
|
|
Right-click the extension icon and click "Open next link in new
|
|
|
|
tab".
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>Opening the extension page:</p>
|
|
|
|
<ul>
|
2022-03-20 18:59:00 +00:00
|
|
|
${isFirefox
|
|
|
|
? html`<li>Double-click the extension icon.</li>`
|
|
|
|
: undefined}
|
2021-09-01 10:46:29 +00:00
|
|
|
<li>
|
|
|
|
Right-click the extension icon and click "Open the extension
|
|
|
|
page".
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>Deleting queue items:</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
Click the red button with the ✗ and then confirm it by clicking
|
|
|
|
again.
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</details>
|
|
|
|
</main>
|
|
|
|
`;
|
|
|
|
}
|
2020-11-11 17:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type ItemProps = {
|
2021-09-01 10:46:29 +00:00
|
|
|
item: Queue.Item;
|
2022-10-25 11:08:53 +00:00
|
|
|
move?: (id: number, direction: Queue.MoveDirection) => Promise<void>;
|
2021-09-02 13:59:18 +00:00
|
|
|
remove?: (id: number) => Promise<void>;
|
2020-11-11 17:17:37 +00:00
|
|
|
};
|
|
|
|
|
2022-03-05 13:10:45 +00:00
|
|
|
function queueItem(props: ItemProps): HtmComponent {
|
2021-09-01 10:46:29 +00:00
|
|
|
const added = props.item.added.toLocaleString();
|
|
|
|
const {id, text, url} = props.item;
|
2022-10-25 11:08:53 +00:00
|
|
|
|
|
|
|
const move = [];
|
|
|
|
if (props.move !== undefined) {
|
|
|
|
const moveButtons: Array<[string, Queue.MoveDirection]> = [
|
|
|
|
['↑', 'up'],
|
|
|
|
['↓', 'down'],
|
|
|
|
];
|
|
|
|
move.push(
|
|
|
|
...moveButtons.map(
|
|
|
|
([text, direction]) =>
|
|
|
|
html`
|
|
|
|
<button
|
|
|
|
title="Move item ${direction}"
|
|
|
|
onClick=${async () => props.move!(id, direction)}
|
|
|
|
>
|
|
|
|
${text}
|
|
|
|
</button>
|
|
|
|
`,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-09-02 13:59:18 +00:00
|
|
|
let remove;
|
|
|
|
if (props.remove !== undefined) {
|
2022-03-05 13:10:45 +00:00
|
|
|
remove = html`
|
|
|
|
<${ConfirmButton}
|
2022-03-17 13:06:27 +00:00
|
|
|
class="confirm-button"
|
|
|
|
click=${async () => props.remove!(id)}
|
2022-03-05 13:10:45 +00:00
|
|
|
confirmClass="confirm"
|
|
|
|
confirmText="✓"
|
2022-03-17 13:06:27 +00:00
|
|
|
extraAttributes=${{title: 'Remove'}}
|
2022-03-05 13:10:45 +00:00
|
|
|
text="✗"
|
|
|
|
timeout=${5 * 1000}
|
|
|
|
/>
|
|
|
|
`;
|
2021-09-02 13:59:18 +00:00
|
|
|
}
|
2020-11-11 17:17:37 +00:00
|
|
|
|
|
|
|
return html`
|
|
|
|
<li class="q-item">
|
|
|
|
<p class="title">
|
2022-09-27 10:49:00 +00:00
|
|
|
<${PrivacyLink} attributes=${{href: url}}>${text ?? url}<//>
|
2020-11-11 17:17:37 +00:00
|
|
|
</p>
|
|
|
|
|
2022-10-25 11:08:53 +00:00
|
|
|
<div class="buttons">${move}${remove}</div>
|
2020-11-11 17:17:37 +00:00
|
|
|
|
|
|
|
<p>
|
2021-09-01 10:46:29 +00:00
|
|
|
<time datetime=${added} title="Link queued on ${added}.">
|
|
|
|
${added}
|
2020-11-11 17:17:37 +00:00
|
|
|
</time>
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
`;
|
|
|
|
}
|