Skip to content

Commit

Permalink
history: initial build (#1401)
Browse files Browse the repository at this point in the history
  • Loading branch information
shakyShane authored Jan 20, 2025
1 parent f8cde4a commit fee9760
Show file tree
Hide file tree
Showing 34 changed files with 1,042 additions and 1 deletion.
6 changes: 6 additions & 0 deletions special-pages/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ export const support = {
windows: ['copy', 'build-js'],
apple: ['copy', 'build-js'],
},
/** @type {Partial<Record<ImportMeta['injectName'], string[]>>} */
history: {
integration: ['copy', 'build-js'],
windows: ['copy', 'build-js'],
apple: ['copy', 'build-js'],
},
};

/** @type {{src: string, dest: string, dist: string, injectName: string}[]} */
Expand Down
32 changes: 32 additions & 0 deletions special-pages/pages/history/app/components/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Fragment, h } from 'preact';
import styles from './App.module.css';
import { useTypedTranslation } from '../types.js';
import { useEnv } from '../../../../shared/components/EnvironmentProvider.js';
import { Header } from './Header.js';
import { useSignal } from '@preact/signals';
import { Results } from './Results.js';

export function App() {
const { t } = useTypedTranslation();
const { isDarkMode } = useEnv();
const results = useSignal({
info: {
finished: true,
term: '',
},
value: [],
});
return (
<div class={styles.layout} data-theme={isDarkMode ? 'dark' : 'light'}>
<header class={styles.header}>
<Header setResults={(next) => (results.value = next)} />
</header>
<aside class={styles.aside}>
<h1 class={styles.pageTitle}>History</h1>
</aside>
<main class={styles.main}>
<Results results={results} />
</main>
</div>
);
}
47 changes: 47 additions & 0 deletions special-pages/pages/history/app/components/App.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@import url("../../../../shared/styles/variables.css");
@import url("../../styles/base.css");
@import url("../../styles/theme.css");

body {
font-size: var(--body-font-size);
font-weight: var(--body-font-weight);
line-height: var(--body-line-height);
}

.layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 64px auto;
grid-template-areas:
'aside header'
'aside main';
overflow: hidden;
height: 100vh;
}
.header {
grid-area: header;
padding-left: 48px;
padding-right: 76px;
padding-top: 16px;
padding-bottom: 16px;
}
.search {
justify-self: flex-end;
}
.aside {
grid-area: aside;
padding: 10px 16px;
border-right: 1px solid var(--history-surface-border-color);
}
.pageTitle {
font-size: var(--title-font-size);
font-weight: var(--title-font-weight);
line-height: var(--title-line-height);
padding: 10px 6px 10px 10px;
}
.main {
grid-area: main;
overflow: auto;
padding-left: 48px;
padding-right: 76px;
}
6 changes: 6 additions & 0 deletions special-pages/pages/history/app/components/Components.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { h } from 'preact';
import styles from './Components.module.css';

export function Components() {
return <main class={styles.main}>Component list here!</main>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.main {

}
54 changes: 54 additions & 0 deletions special-pages/pages/history/app/components/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import styles from './Header.module.css';
import { Fire } from '../icons/Fire.js';
import { h } from 'preact';
import { useMessaging, useTypedTranslation } from '../types.js';
import { Cross } from '../icons/Cross.js';
import { useEffect } from 'preact/hooks';

export function Header({ setResults }) {
const { t } = useTypedTranslation();
const historyPage = useMessaging();
useEffect(() => {
historyPage
.query({ term: '', limit: 150, offset: 0 })
// eslint-disable-next-line promise/prefer-await-to-then
.then(setResults)
// eslint-disable-next-line promise/prefer-await-to-then
.catch((e) => {
console.log('did catch...', e);
});
}, []);
return (
<div class={styles.root}>
<div class={styles.controls}>
<button class={styles.largeButton}>
<Fire />
<span>Clear History and Data...</span>
</button>
<button class={styles.largeButton}>
<Cross />
<span>Remove History...</span>
</button>
</div>
<div class={styles.search}>
<form
action=""
onSubmit={(e) => {
e.preventDefault();
const data = new FormData(/** @type {HTMLFormElement} */ (e.target));
historyPage
.query({ term: data.get('term')?.toString() || '', limit: 150, offset: 0 })
// eslint-disable-next-line promise/prefer-await-to-then
.then(setResults)
// eslint-disable-next-line promise/prefer-await-to-then
.catch((e) => {
console.log('did catch...', e);
});
}}
>
<input type="search" placeholder={t('search')} class={styles.searchInput} name="term" />
</form>
</div>
</div>
);
}
36 changes: 36 additions & 0 deletions special-pages/pages/history/app/components/Header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.root {
display: flex;
align-items: center;
gap: 8px;
}
.controls {
display: flex;
gap: 8px;
}
.largeButton {
background: transparent;
display: flex;
align-items: center;
gap: 4px;
height: 32px;
border: none;

svg {
flex-shrink: 0
}

&:hover {
background-color: var(--history-surface-color)
}
}
.search {
margin-left: auto;
}
.searchInput {
width: 238px;
height: 28px;
border-radius: 6px;
border: 1px solid var(--history-surface-border-color);
padding-left: 9px;
padding-right: 9px;
}
31 changes: 31 additions & 0 deletions special-pages/pages/history/app/components/Results.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { h } from 'preact';

/**
* @param {object} props
* @param {import("@preact/signals").Signal<import('../../types/history').HistoryQueryResponse>} props.results
*/
export function Results({ results }) {
return (
<div>
<p>Params:</p>
<pre>
<code>{JSON.stringify(results.value.info)}</code>
</pre>
<br />
<hr />
<br />
<p>Results:</p>
<ul>
{results.value.value.map((item) => {
return (
<li>
<pre>
<code>{JSON.stringify(item, null, 2)}</code>
</pre>
</li>
);
})}
</ul>
</div>
);
}
54 changes: 54 additions & 0 deletions special-pages/pages/history/app/history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: History Page
---

## Requests

- {@link "History Messages".InitialSetupRequest `initialSetup`}
- Returns {@link "History Messages".InitialSetupResponse}

## Requests

### {@link "History Messages".QueryRequest `query`}
- Sends {@link "History Messages".HistoryQuery}
- Receives {@link "History Messages".HistoryQueryResponse}
- Note: if an empty term is sent, you should reply with as many items as the limit allows.

The FE will send:
```json
{ "term": "", "limit": 150, "offset": 0 }
```

The response will be:

```json
{
"info": {
"finished": false,
"term": ""
},
"value": [
{
"dateRelativeDay": "Today - Wednesday 15 January 2025",
"dateShort": "15 Jan 2025",
"dateTimeOfDay": "11:10",
"domain": "youtube.com",
"fallbackFaviconText": "L",
"time": 1736939416961.617,
"title": "Electric Callboy - Hypa Hypa (OFFICIAL VIDEO) - YouTube",
"url": "https://www.youtube.com/watch?v=75Mw8r5gW8E"
},
{"...": "..."}
]
}
```

## Notifications

### {@link "History Messages".ReportInitExceptionNotification `reportInitException`}
- Sent when the application fails to initialize (for example, a JavaScript exception prevented it)
- Sends: `{ message: string }` - see {@link "History Messages".ReportInitExceptionNotify}

### {@link "History Messages".ReportPageExceptionNotification `reportPageException`}
- Sent when the application failed after initialization (for example, a JavaScript exception prevented it)
- Sends: `{ message: string }` - see {@link "History Messages".ReportPageExceptionNotify}
13 changes: 13 additions & 0 deletions special-pages/pages/history/app/icons/Cross.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { h } from 'preact';

export function Cross() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M13.2803 3.78033C13.5732 3.48744 13.5732 3.01256 13.2803 2.71967C12.9874 2.42678 12.5126 2.42678 12.2197 2.71967L8 6.93934L3.78033 2.71967C3.48744 2.42678 3.01256 2.42678 2.71967 2.71967C2.42678 3.01256 2.42678 3.48744 2.71967 3.78033L6.93934 8L2.71967 12.2197C2.42678 12.5126 2.42678 12.9874 2.71967 13.2803C3.01256 13.5732 3.48744 13.5732 3.78033 13.2803L8 9.06066L12.2197 13.2803C12.5126 13.5732 12.9874 13.5732 13.2803 13.2803C13.5732 12.9874 13.5732 12.5126 13.2803 12.2197L9.06066 8L13.2803 3.78033Z"
fill="currentColor"
fill-opacity="1"
/>
</svg>
);
}
1 change: 1 addition & 0 deletions special-pages/pages/history/app/icons/Cross.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions special-pages/pages/history/app/icons/Fire.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 75 additions & 0 deletions special-pages/pages/history/app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { h, render } from 'preact';
import { EnvironmentProvider, UpdateEnvironment } from '../../../shared/components/EnvironmentProvider.js';

import { App } from './components/App.jsx';
import { Components } from './components/Components.jsx';

import enStrings from '../public/locales/en/history.json';
import { TranslationProvider } from '../../../shared/components/TranslationsProvider.js';
import { callWithRetry } from '../../../shared/call-with-retry.js';

import '../../../shared/styles/global.css';
import { MessagingContext } from './types.js'; // global styles

/**
* @param {Element} root
* @param {import("../src/index.js").HistoryPage} messaging
* @param {import("../../../shared/environment").Environment} baseEnvironment
* @return {Promise<void>}
*/
export async function init(root, messaging, baseEnvironment) {
const result = await callWithRetry(() => messaging.initialSetup());
if ('error' in result) {
throw new Error(result.error);
}

const init = result.value;

console.log('initialSetup', init);

// update the 'env' in case it was changed by native sides
const environment = baseEnvironment
.withEnv(init.env)
.withLocale(init.locale)
.withLocale(baseEnvironment.urlParams.get('locale'))
.withTextLength(baseEnvironment.urlParams.get('textLength'))
.withDisplay(baseEnvironment.urlParams.get('display'));

const strings =
environment.locale === 'en'
? enStrings
: await fetch(`./locales/${environment.locale}/example.json`)
.then((resp) => {
if (!resp.ok) {
throw new Error('did not give a result');
}
return resp.json();
})
.catch((e) => {
console.error('Could not load locale', environment.locale, e);
return enStrings;
});

if (environment.display === 'app') {
render(
<EnvironmentProvider debugState={environment.debugState} injectName={environment.injectName} willThrow={environment.willThrow}>
<UpdateEnvironment search={window.location.search} />
<TranslationProvider translationObject={strings} fallback={enStrings} textLength={environment.textLength}>
<MessagingContext.Provider value={messaging}>
<App />
</MessagingContext.Provider>
</TranslationProvider>
</EnvironmentProvider>,
root,
);
} else if (environment.display === 'components') {
render(
<EnvironmentProvider debugState={false} injectName={environment.injectName}>
<TranslationProvider translationObject={strings} fallback={enStrings} textLength={environment.textLength}>
<Components />
</TranslationProvider>
</EnvironmentProvider>,
root,
);
}
}
Loading

0 comments on commit fee9760

Please sign in to comment.