diff --git a/special-pages/pages/history/app/HistoryProvider.js b/special-pages/pages/history/app/HistoryProvider.js index cb08b77b55..ddaaa9d101 100644 --- a/special-pages/pages/history/app/HistoryProvider.js +++ b/special-pages/pages/history/app/HistoryProvider.js @@ -1,7 +1,7 @@ import { h, createContext } from 'preact'; import { useContext } from 'preact/hooks'; import { useSignalEffect } from '@preact/signals'; -import { paramsToQuery } from './history.service.js'; +import { paramsToQuery, toRange } from './history.service.js'; import { OVERSCAN_AMOUNT } from './constants.js'; import { usePlatformName } from './types.js'; import { eventToTarget } from '../../../shared/handlers.js'; @@ -75,12 +75,17 @@ export function HistoryServiceProvider({ service, initial, children }) { if (btn?.dataset.deleteRange) { event.stopImmediatePropagation(); event.preventDefault(); - return confirm(`todo: delete range for ${btn.dataset.deleteRange}`); + const range = toRange(btn.value); + if (range) { + // eslint-disable-next-line promise/prefer-await-to-then + service.deleteRange(range).catch(console.error); + } } if (btn?.dataset.deleteAll) { event.stopImmediatePropagation(); event.preventDefault(); - return confirm(`todo: delete all`); + // eslint-disable-next-line promise/prefer-await-to-then + service.deleteRange('all').catch(console.error); } } else if (anchor) { const url = anchor.dataset.url; diff --git a/special-pages/pages/history/app/components/App.jsx b/special-pages/pages/history/app/components/App.jsx index a429f4f061..04b082a12b 100644 --- a/special-pages/pages/history/app/components/App.jsx +++ b/special-pages/pages/history/app/components/App.jsx @@ -20,13 +20,14 @@ export function App() { const containerRef = useRef(/** @type {HTMLElement|null} */ (null)); const { initial, service } = useHistory(); + // NOTE: These states will get extracted out later, once I know all the use-cases + const ranges = useSignal(initial.ranges.ranges); + const term = useSignal('term' in initial.query.info.query ? initial.query.info.query.term : ''); const results = useSignal({ items: initial.query.results, heights: generateHeights(initial.query.results), }); - const term = useSignal('term' in initial.query.info.query ? initial.query.info.query.term : ''); - useSignalEffect(() => { const unsub = service.onResults((data) => { batch(() => { @@ -39,8 +40,14 @@ export function App() { }; }); }); + + // Subscribe to changes in the 'ranges' data and reflect the updates into the UI + const unsubRanges = service.onRanges((data) => { + ranges.value = data.ranges; + }); return () => { unsub(); + unsubRanges(); }; }); @@ -56,7 +63,7 @@ export function App() {
diff --git a/special-pages/pages/history/app/components/Header.js b/special-pages/pages/history/app/components/Header.js index bdfebd972a..0cac81bf13 100644 --- a/special-pages/pages/history/app/components/Header.js +++ b/special-pages/pages/history/app/components/Header.js @@ -3,17 +3,19 @@ import { h } from 'preact'; import { useComputed } from '@preact/signals'; import { SearchForm, useSearchContext } from './SearchForm.js'; import { Trash } from '../icons/Trash.js'; +import { useTypedTranslation } from '../types.js'; /** */ export function Header() { + const { t } = useTypedTranslation(); const search = useSearchContext(); const term = useComputed(() => search.value.term); return (
diff --git a/special-pages/pages/history/app/components/Results.js b/special-pages/pages/history/app/components/Results.js index c4bdbc517c..aabd2c8f74 100644 --- a/special-pages/pages/history/app/components/Results.js +++ b/special-pages/pages/history/app/components/Results.js @@ -1,14 +1,19 @@ import { h } from 'preact'; +import cn from 'classnames'; import { OVERSCAN_AMOUNT } from '../constants.js'; import { Item } from './Item.js'; import styles from './VirtualizedList.module.css'; import { VisibleItems } from './VirtualizedList.js'; +import { useTypedTranslation } from '../types.js'; /** * @param {object} props * @param {import("@preact/signals").Signal} props.results */ export function Results({ results }) { + if (results.value.items.length === 0) { + return ; + } const totalHeight = results.value.heights.reduce((acc, item) => acc + item, 0); return (
    @@ -36,3 +41,16 @@ export function Results({ results }) {
); } + +/** + * Empty state component displayed when no results are available + */ +function Empty() { + const { t } = useTypedTranslation(); + return ( +
+ +

{t('empty_title')}

+
+ ); +} diff --git a/special-pages/pages/history/app/components/Sidebar.js b/special-pages/pages/history/app/components/Sidebar.js index c58cde57dc..81158637a1 100644 --- a/special-pages/pages/history/app/components/Sidebar.js +++ b/special-pages/pages/history/app/components/Sidebar.js @@ -9,9 +9,10 @@ import { useTypedTranslationWith } from '../../../new-tab/app/types.js'; /** * @import json from "../strings.json" + * @typedef {import('../../types/history.js').Range} Range */ -/** @type {Record} */ +/** @type {Record} */ const iconMap = { all: 'icons/all.svg', today: 'icons/today.svg', @@ -23,11 +24,10 @@ const iconMap = { friday: 'icons/day.svg', saturday: 'icons/day.svg', sunday: 'icons/day.svg', - recentlyOpened: 'icons/closed.svg', older: 'icons/older.svg', }; -/** @type {Record string) => string>} */ +/** @type {Record string) => string>} */ const titleMap = { all: (t) => t('range_all'), today: (t) => t('range_today'), @@ -39,7 +39,6 @@ const titleMap = { friday: (t) => t('range_friday'), saturday: (t) => t('range_saturday'), sunday: (t) => t('range_sunday'), - recentlyOpened: (t) => t('range_recentlyOpened'), older: (t) => t('range_older'), }; @@ -47,25 +46,20 @@ const titleMap = { * Renders a sidebar navigation component with links based on the provided ranges. * * @param {Object} props - The properties object. - * @param {import('../../types/history.js').Range[]} props.ranges - An array of range values used to generate navigation links. + * @param {import("@preact/signals").Signal} props.ranges - An array of range values used to generate navigation links. */ export function Sidebar({ ranges }) { const { t } = useTypedTranslation(); const search = useSearchContext(); const current = useComputed(() => search.value.range); - const others = ranges.filter((x) => x === 'recentlyOpened'); - const main = ranges.filter((x) => x !== 'recentlyOpened'); return (

{t('page_title')}

- {others.map((range) => { - return ; - })}
); } @@ -74,16 +68,16 @@ export function Sidebar({ ranges }) { * Renders an item component with additional properties and functionality. * * @param {Object} props - * @param {import('../../types/history.js').Range} props.range The range value used for filtering and identification. + * @param {Range} props.range The range value used for filtering and identification. * @param {string} props.title The title or label of the item. - * @param {import("@preact/signals").Signal} props.current The current state object used to determine active item styling. + * @param {import("@preact/signals").Signal} props.current The current state object used to determine active item styling. */ function Item({ range, title, current }) { const { t } = useTypedTranslationWith(/** @type {json} */ ({})); - const label = (() => { + const [linkLabel, deleteLabel] = (() => { switch (range) { case 'all': - return t('show_history_all'); + return [t('show_history_all'), t('delete_history_all')]; case 'today': case 'yesterday': case 'monday': @@ -93,22 +87,28 @@ function Item({ range, title, current }) { case 'friday': case 'saturday': case 'sunday': - return t('show_history_for', { range }); + return [t('show_history_for', { range }), t('delete_history_for', { range })]; case 'older': - return t('show_history_older'); - case 'recentlyOpened': - return t('show_history_closed'); + return [t('show_history_older'), t('delete_history_older')]; } })(); return ( - - - - - {title} - - +
); } diff --git a/special-pages/pages/history/app/components/Sidebar.module.css b/special-pages/pages/history/app/components/Sidebar.module.css index 29046240c7..7b43f1b4f6 100644 --- a/special-pages/pages/history/app/components/Sidebar.module.css +++ b/special-pages/pages/history/app/components/Sidebar.module.css @@ -13,16 +13,8 @@ } .nav {} .item { - height: 40px; position: relative; - display: flex; - align-items: center; border-radius: 8px; - padding-left: 16px; - text-decoration: none; - font-weight: 510; - color: var(--history-text-normal); - gap: 6px; &:hover, &:focus-visible { background: var(--color-black-at-6); @@ -34,6 +26,17 @@ } } } +.link { + height: 40px; + display: flex; + align-items: center; + border-radius: 8px; + padding-left: 16px; + text-decoration: none; + font-weight: 510; + color: var(--history-text-normal); + gap: 6px; +} .delete { height: 40px; @@ -49,16 +52,18 @@ border-bottom-left-radius: 0; background: transparent; border: none; + cursor: pointer; opacity: 0; - visibility: hidden; color: inherit; - &:hover { + &:hover, &:focus-visible { background: var(--color-black-at-9); + opacity: 1; } &:active { background: var(--color-black-at-12); } + [data-theme="dark"] & { &:hover { background: var(--color-white-at-9); @@ -70,7 +75,10 @@ .item:hover & { opacity: 1; - visibility: visible; + } + + .link:focus-visible + & { + opacity: 1; } svg path { diff --git a/special-pages/pages/history/app/components/VirtualizedList.module.css b/special-pages/pages/history/app/components/VirtualizedList.module.css index c162ff7459..92110959b5 100644 --- a/special-pages/pages/history/app/components/VirtualizedList.module.css +++ b/special-pages/pages/history/app/components/VirtualizedList.module.css @@ -8,4 +8,27 @@ position: absolute; padding: 0; margin: 0; +} + +.emptyState { + width: 100%; + height: 100%; + text-align: center; + color: var(--history-text-normal) +} + +.emptyStateOffset { + padding-top: var(--sp-32); +} + +.emptyStateImage { + width: 128px; + height: 96px; + display: inline-block; +} + +.emptyTitle { + font-size: var(--title-3-em-font-size); + font-weight: var(--title-3-em-font-weight); + line-height: var(--title-3-em-line-height); } \ No newline at end of file diff --git a/special-pages/pages/history/app/history.md b/special-pages/pages/history/app/history.md index 1b2fdf08a6..12c5fe0965 100644 --- a/special-pages/pages/history/app/history.md +++ b/special-pages/pages/history/app/history.md @@ -97,6 +97,27 @@ Response, note: always return the same query I sent: } ``` +### `deleteRange` +- Sent to delete a range as displayed in the sidebar. +- Parameters: {@link "History Messages".DeleteRangeParams} +- If the user confirms, respond with `{ action: 'delete' }` +- otherwise `{ action: 'none' }` + - Response: {@link "History Messages".DeleteRangeResponse} + +**params** +```json +{ + "range": "today" +} +``` + +**response** +```json +{ + "action": "delete" +} +``` + ## Notifications ### `open` diff --git a/special-pages/pages/history/app/history.service.js b/special-pages/pages/history/app/history.service.js index 3667719691..1cd085969f 100644 --- a/special-pages/pages/history/app/history.service.js +++ b/special-pages/pages/history/app/history.service.js @@ -10,6 +10,7 @@ import { Service } from '../../new-tab/app/service.js'; */ export class HistoryService { + static CHUNK_SIZE = 150; /** * @param {import("../src/index.js").HistoryPage} history */ @@ -23,13 +24,15 @@ export class HistoryService { return { info: resp.info, results: resp.value }; }); }, - }).withUpdater((old, next) => { + }).withUpdater((old, next, trigger) => { + if (trigger === 'manual') { + // console.log('manual trigger, always accepting next:', next); + return next; + } if (eq(old.info.query, next.info.query)) { + // console.log('Query did match', [trigger], old.info.query); const results = old.results.concat(next.results); - console.log('next length', results.length); - return { info: next.info, results: old.results.concat(next.results) }; - } else { - console.log('saving new data', next); + return { info: next.info, results }; } return next; }); @@ -59,7 +62,6 @@ export class HistoryService { onResults(cb) { return this.query.onData(({ data, source }) => cb(data)); } - /** * @param {import('../types/history.js').HistoryQuery} query */ @@ -78,12 +80,11 @@ export class HistoryService { /** @type {import('../types/history.js').HistoryQuery} */ const query = { query: lastquery, - limit: 150, + limit: HistoryService.CHUNK_SIZE, offset: this.query.data.results.length, }; this.query.triggerFetch(query); - // console.log('next query', query); } /** @@ -93,6 +94,54 @@ export class HistoryService { openUrl(url, target) { this.history.messaging.notify('open', { url, target }); } + + /** + * @param {(data: RangeData) => void} cb + */ + onRanges(cb) { + return this.ranges.onData(({ data, source }) => cb(data)); + } + + /** + * @param {Range} range + */ + deleteRange(range) { + return ( + this.history.messaging + .request('deleteRange', { range }) + // eslint-disable-next-line promise/prefer-await-to-then + .then((resp) => { + if (resp.action === 'delete') { + if (range === 'all') { + this.ranges.update((_old) => { + return { + ranges: ['all'], + }; + }); + this.query.update((_old) => { + /** @type {QueryData} */ + const query = { + info: { + query: { term: '' }, + finished: true, + }, + results: [], + }; + return query; + }); + } else { + this.ranges.update((old) => { + return { + ...old, + ranges: old.ranges.filter((x) => x !== range), + }; + }); + } + } + return resp; + }) + ); + } } /** @@ -117,7 +166,7 @@ export function paramsToQuery(params) { return { query, - limit: 150, + limit: HistoryService.CHUNK_SIZE, offset: 0, }; } diff --git a/special-pages/pages/history/app/mocks/history.mocks.js b/special-pages/pages/history/app/mocks/history.mocks.js index 3d3888a36b..708caa14c0 100644 --- a/special-pages/pages/history/app/mocks/history.mocks.js +++ b/special-pages/pages/history/app/mocks/history.mocks.js @@ -1,3 +1,5 @@ +import { HistoryService } from '../history.service.js'; + /** * @type {Record} */ @@ -100,7 +102,7 @@ export function generateSampleData({ count, offset }) { * @param {number} chunkSize * @return {import("../../types/history").HistoryQueryResponse} */ -export function asResponse(items, offset, chunkSize = 150) { +export function asResponse(items, offset, chunkSize = HistoryService.CHUNK_SIZE) { // console.log(items.slice(offset, chunkSize)); const sliced = items.slice(offset, offset + chunkSize); const finished = sliced.length < chunkSize; diff --git a/special-pages/pages/history/app/mocks/mock-transport.js b/special-pages/pages/history/app/mocks/mock-transport.js index ce48d98ffc..f970190ee3 100644 --- a/special-pages/pages/history/app/mocks/mock-transport.js +++ b/special-pages/pages/history/app/mocks/mock-transport.js @@ -58,6 +58,13 @@ export function mockTransport() { const msg = /** @type {any} */ (_msg); switch (msg.method) { + case 'deleteRange': { + console.log('📤 [deleteRange]: ', JSON.stringify(msg.params)); + if (confirm(`Delete range ${msg.params.range}?`)) { + return Promise.resolve({ action: 'delete' }); + } + return Promise.resolve({ action: 'none' }); + } case 'initialSetup': { /** @type {import('../../types/history.ts').InitialSetupResponse} */ const initial = { @@ -72,12 +79,12 @@ export function mockTransport() { case 'getRanges': { /** @type {import('../../types/history.ts').GetRangesResponse} */ const response = { - ranges: ['all', 'today', 'yesterday', 'tuesday', 'monday', 'friday', 'older', 'recentlyOpened'], + ranges: ['all', 'today', 'yesterday', 'tuesday', 'monday', 'friday', 'older'], }; return Promise.resolve(response); } case 'query': { - console.log('📤 [outgoing]: ', JSON.stringify(msg.params)); + console.log('📤 [query]: ', JSON.stringify(msg.params)); if ('term' in msg.params.query) { const { term } = msg.params.query; if (term !== '') { diff --git a/special-pages/pages/history/app/strings.json b/special-pages/pages/history/app/strings.json index 9b14657173..3f773d6cee 100644 --- a/special-pages/pages/history/app/strings.json +++ b/special-pages/pages/history/app/strings.json @@ -1,4 +1,12 @@ { + "empty_title": { + "title": "Nothing to see here!", + "note": "Text shown where there are no remaining history items" + }, + "delete_all": { + "title": "Delete All", + "note": "Text for a button that deletes all items or entries." + }, "page_title": { "title": "History", "note": "" @@ -19,9 +27,17 @@ "title": "Show history for {range}", "note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Show history for Today'." }, - "show_history_closed": { - "title": "Show history for Recently Closed Tabs", - "note": "Button that shows history from tabs that were recently closed" + "delete_history_all": { + "title": "Delete all history", + "note": "Button text for an action that removes all history entries." + }, + "delete_history_older": { + "title": "Delete older history", + "note": "Button that deletes older history entries." + }, + "delete_history_for": { + "title": "Delete history for {range}", + "note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Delete history for Today'." }, "search_your_history": { "title": "Search your history", @@ -67,10 +83,6 @@ "title": "Sunday", "note": "" }, - "range_recentlyOpened": { - "title": "Recently Closed Tabs", - "note": "" - }, "range_older": { "title": "Older", "note": "" diff --git a/special-pages/pages/history/integration-tests/history.page.js b/special-pages/pages/history/integration-tests/history.page.js index 389d498957..408e51de68 100644 --- a/special-pages/pages/history/integration-tests/history.page.js +++ b/special-pages/pages/history/integration-tests/history.page.js @@ -210,4 +210,60 @@ export class HistoryTestPage { target: 'new-window', }); } + + /** + * @param {import('../types/history.ts').DeleteRangeResponse} resp + */ + async deletesHistoryForToday(resp = { action: 'delete' }) { + const { page } = this; + await page.getByLabel('Show history for today').hover(); + if (resp.action === 'delete') { + page.on('dialog', (dialog) => dialog.accept()); + } else { + page.on('dialog', (dialog) => dialog.dismiss()); + } + await page.getByLabel('Delete history for today').click(); + const calls = await this.mocks.waitForCallCount({ method: 'deleteRange', count: 1 }); + expect(calls[0].payload.params).toStrictEqual({ range: 'today' }); + } + + /** + * @param {import('../types/history.ts').DeleteRangeResponse} resp + */ + async deletesHistoryForYesterday(resp = { action: 'delete' }) { + const { page } = this; + await page.getByLabel('Show history for yesterday').hover(); + if (resp.action === 'delete') { + page.on('dialog', (dialog) => dialog.accept()); + } else { + page.on('dialog', (dialog) => dialog.dismiss()); + } + await page.getByLabel('Delete history for yesterday').click(); + } + + async sideBarItemWasRemoved(label) { + const { page } = this; + await expect(page.getByLabel(label)).not.toBeVisible({ timeout: 1000 }); + } + + async sidebarHasItem(label) { + const { page } = this; + await expect(page.getByLabel(label)).toBeVisible({ timeout: 1000 }); + } + + /** + * @param {import('../types/history.ts').DeleteRangeResponse} resp + */ + async deletesAllHistoryFromHeader(resp) { + const { page } = this; + if (resp.action === 'delete') { + page.on('dialog', (dialog) => dialog.accept()); + } else { + page.on('dialog', (dialog) => dialog.dismiss()); + } + await page.getByRole('button', { name: 'Delete All', exact: true }).click(); + const calls = await this.mocks.waitForCallCount({ method: 'deleteRange', count: 1 }); + expect(calls[0].payload.params).toStrictEqual({ range: 'all' }); + await expect(page.getByRole('heading', { level: 2, name: 'Nothing to see here!' })).toBeVisible(); + } } diff --git a/special-pages/pages/history/integration-tests/history.spec.js b/special-pages/pages/history/integration-tests/history.spec.js index 2b029e6450..e9f28466e5 100644 --- a/special-pages/pages/history/integration-tests/history.spec.js +++ b/special-pages/pages/history/integration-tests/history.spec.js @@ -91,4 +91,21 @@ test.describe('history', () => { await hp.openPage({}); await hp.opensLinks(); }); + test('deleting sidebar items', async ({ page }, workerInfo) => { + const hp = HistoryTestPage.create(page, workerInfo).withEntries(2000); + await hp.openPage({}); + await hp.deletesHistoryForToday({ action: 'delete' }); + await hp.sideBarItemWasRemoved('Show history for today'); + }); + test('deleting sidebar items, but dismissing modal', async ({ page }, workerInfo) => { + const hp = HistoryTestPage.create(page, workerInfo).withEntries(2000); + await hp.openPage({}); + await hp.deletesHistoryForYesterday({ action: 'none' }); + await hp.sidebarHasItem('Show history for today'); + }); + test('deleting from the header', async ({ page }, workerInfo) => { + const hp = HistoryTestPage.create(page, workerInfo).withEntries(2000); + await hp.openPage({}); + await hp.deletesAllHistoryFromHeader({ action: 'delete' }); + }); }); diff --git a/special-pages/pages/history/messages/deleteRange.request.json b/special-pages/pages/history/messages/deleteRange.request.json new file mode 100644 index 0000000000..cb688ce34a --- /dev/null +++ b/special-pages/pages/history/messages/deleteRange.request.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "required": ["range"], + "title": "Delete Range Params", + "properties": { + "range": { + "$ref": "./types/range.json" + } + } +} + diff --git a/special-pages/pages/history/messages/deleteRange.response.json b/special-pages/pages/history/messages/deleteRange.response.json new file mode 100644 index 0000000000..a6dc64cca6 --- /dev/null +++ b/special-pages/pages/history/messages/deleteRange.response.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": ["action"], + "properties": { + "action": { + "oneOf": [ + { + "const": "delete", + "title": "Delete Action", + "description": "Confirms the user deleted this" + }, + { + "const": "none", + "title": "None Action", + "description": "The user cancelled the action, or did not agree to it" + } + ] + } + } +} + diff --git a/special-pages/pages/history/messages/types/range.json b/special-pages/pages/history/messages/types/range.json index 7962412675..597e737b27 100644 --- a/special-pages/pages/history/messages/types/range.json +++ b/special-pages/pages/history/messages/types/range.json @@ -13,7 +13,6 @@ "friday", "saturday", "sunday", - "older", - "recentlyOpened" + "older" ] } diff --git a/special-pages/pages/history/public/icons/clock.svg b/special-pages/pages/history/public/icons/clock.svg new file mode 100644 index 0000000000..81a44daf49 --- /dev/null +++ b/special-pages/pages/history/public/icons/clock.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/special-pages/pages/history/public/locales/en/history.json b/special-pages/pages/history/public/locales/en/history.json index 9717ac88fa..315ebccc6a 100644 --- a/special-pages/pages/history/public/locales/en/history.json +++ b/special-pages/pages/history/public/locales/en/history.json @@ -9,6 +9,14 @@ } ] }, + "empty_title": { + "title": "Nothing to see here!", + "note": "Text shown where there are no remaining history items" + }, + "delete_all": { + "title": "Delete All", + "note": "Text for a button that deletes all items or entries." + }, "page_title": { "title": "History", "note": "" @@ -29,9 +37,17 @@ "title": "Show history for {range}", "note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Show history for Today'." }, - "show_history_closed": { - "title": "Show history for Recently Closed Tabs", - "note": "Button that shows history from tabs that were recently closed" + "delete_history_all": { + "title": "Delete all history", + "note": "Button text for an action that removes all history entries." + }, + "delete_history_older": { + "title": "Delete older history", + "note": "Button that deletes older history entries." + }, + "delete_history_for": { + "title": "Delete history for {range}", + "note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Delete history for Today'." }, "search_your_history": { "title": "Search your history", @@ -77,10 +93,6 @@ "title": "Sunday", "note": "" }, - "range_recentlyOpened": { - "title": "Recently Closed Tabs", - "note": "" - }, "range_older": { "title": "Older", "note": "" diff --git a/special-pages/pages/history/types/history.ts b/special-pages/pages/history/types/history.ts index cb5a68848b..d8ca069736 100644 --- a/special-pages/pages/history/types/history.ts +++ b/special-pages/pages/history/types/history.ts @@ -18,8 +18,15 @@ export type Range = | "friday" | "saturday" | "sunday" - | "older" - | "recentlyOpened"; + | "older"; +/** + * Confirms the user deleted this + */ +export type DeleteAction = "delete"; +/** + * The user cancelled the action, or did not agree to it + */ +export type NoneAction = "none"; export type QueryKind = SearchTerm | DomainFilter | RangeFilter; /** @@ -27,7 +34,7 @@ export type QueryKind = SearchTerm | DomainFilter | RangeFilter; */ export interface HistoryMessages { notifications: OpenNotification | ReportInitExceptionNotification | ReportPageExceptionNotification; - requests: GetRangesRequest | InitialSetupRequest | QueryRequest; + requests: DeleteRangeRequest | GetRangesRequest | InitialSetupRequest | QueryRequest; } /** * Generated from @see "../messages/open.notify.json" @@ -63,6 +70,20 @@ export interface ReportPageExceptionNotification { export interface ReportPageExceptionNotify { message: string; } +/** + * Generated from @see "../messages/deleteRange.request.json" + */ +export interface DeleteRangeRequest { + method: "deleteRange"; + params: DeleteRangeParams; + result: DeleteRangeResponse; +} +export interface DeleteRangeParams { + range: Range; +} +export interface DeleteRangeResponse { + action: DeleteAction | NoneAction; +} /** * Generated from @see "../messages/getRanges.request.json" */ diff --git a/special-pages/pages/new-tab/app/service.js b/special-pages/pages/new-tab/app/service.js index e757484c7c..b7d44d6847 100644 --- a/special-pages/pages/new-tab/app/service.js +++ b/special-pages/pages/new-tab/app/service.js @@ -38,7 +38,7 @@ export class Service { } /** - * @param {(old: Data, next: Data, trigger: string) => Data} fn + * @param {(old: Data, next: Data, trigger: InvocationSource) => Data} fn */ withUpdater(fn) { this.accept = fn;