@reticlehq/browser 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/actions-dom.d.ts +6 -5
- package/dist/actions/actions-dom.js +5 -4
- package/dist/actions/actions-press.d.ts +3 -3
- package/dist/actions/actions-press.js +0 -3
- package/dist/actions/actions.d.ts +0 -1
- package/dist/actions/actions.js +17 -13
- package/dist/actions/check-state.d.ts +5 -0
- package/dist/actions/check-state.js +24 -0
- package/dist/actions/danger-context.d.ts +3 -2
- package/dist/actions/danger-context.js +2 -1
- package/dist/actions/value-input.d.ts +2 -1
- package/dist/actions/value-input.js +15 -6
- package/dist/connect-options.d.ts +1 -0
- package/dist/dom/a11y.js +43 -3
- package/dist/dom/addressing/source.d.ts +2 -1
- package/dist/dom/dom-ignore.d.ts +1 -0
- package/dist/dom/dom-ignore.js +13 -0
- package/dist/dom/query.js +6 -4
- package/dist/dom/realm.d.ts +6 -0
- package/dist/dom/realm.js +5 -0
- package/dist/dom/snapshot.d.ts +1 -1
- package/dist/dom/snapshot.js +8 -2
- package/dist/observers/console.js +38 -13
- package/dist/observers/dom.js +3 -1
- package/dist/observers/download.js +3 -2
- package/dist/observers/error-repeats.d.ts +18 -0
- package/dist/observers/error-repeats.js +41 -0
- package/dist/observers/field.d.ts +2 -0
- package/dist/observers/field.js +86 -0
- package/dist/observers/frames.js +3 -4
- package/dist/observers/install-all.js +2 -0
- package/dist/observers/net-detail/network-body.d.ts +2 -0
- package/dist/observers/net-detail/network-body.js +24 -7
- package/dist/observers/network.js +14 -1
- package/dist/observers/route.js +4 -4
- package/dist/observers/state.js +21 -8
- package/dist/presenter/carousel/carousel.d.ts +13 -0
- package/dist/presenter/carousel/carousel.js +126 -0
- package/dist/presenter/carousel/offer-card.d.ts +21 -0
- package/dist/presenter/carousel/offer-card.js +55 -0
- package/dist/presenter/carousel/panel-slides.d.ts +7 -0
- package/dist/presenter/carousel/panel-slides.js +10 -0
- package/dist/presenter/carousel/talk-card.d.ts +8 -0
- package/dist/presenter/carousel/talk-card.js +20 -0
- package/dist/presenter/chrome/presenter-log.d.ts +2 -1
- package/dist/presenter/chrome/presenter-log.js +14 -3
- package/dist/presenter/chrome/presenter-report-copy.d.ts +0 -1
- package/dist/presenter/chrome/presenter-report-copy.js +1 -1
- package/dist/presenter/hud-telemetry.d.ts +3 -0
- package/dist/presenter/hud-telemetry.js +87 -0
- package/dist/presenter/presenter-account.js +1 -1
- package/dist/presenter/presenter-config.d.ts +5 -1
- package/dist/presenter/presenter-config.js +4 -1
- package/dist/presenter/presenter-controls.d.ts +1 -0
- package/dist/presenter/presenter-controls.js +12 -1
- package/dist/presenter/presenter-report.js +6 -6
- package/dist/presenter/presenter-settings-styles.js +2 -1
- package/dist/presenter/presenter-settings.d.ts +2 -4
- package/dist/presenter/presenter-settings.js +13 -4
- package/dist/presenter/presenter-shell-styles.js +4 -0
- package/dist/presenter/presenter-shell.d.ts +4 -1
- package/dist/presenter/presenter-shell.js +49 -11
- package/dist/presenter/presenter-styles.js +5 -1
- package/dist/presenter/presenter-workspace.d.ts +0 -7
- package/dist/presenter/presenter-workspace.js +7 -7
- package/dist/presenter/presenter.js +43 -10
- package/dist/presenter/tour/tour.d.ts +3 -0
- package/dist/presenter/tour/tour.js +5 -0
- package/dist/recorder/recorder.js +25 -22
- package/dist/registry/store-adapters.js +32 -2
- package/dist/registry/stores/adapters.js +8 -2
- package/dist/reticle-inject.d.ts +2 -0
- package/dist/reticle-inject.js +1337 -0
- package/dist/reticle.js +6 -0
- package/dist/review/annotator.d.ts +3 -1
- package/dist/review/annotator.js +37 -40
- package/dist/review/marks-for-agent.d.ts +9 -0
- package/dist/review/marks-for-agent.js +12 -0
- package/dist/util/captured-method.d.ts +0 -1
- package/dist/util/captured-method.js +1 -1
- package/package.json +15 -11
- package/dist/presenter/presenter-offer.d.ts +0 -25
- package/dist/presenter/presenter-offer.js +0 -87
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DISCOVERY_CALL_URL } from '@reticlehq/core';
|
|
2
|
+
export const TALK_BOOK_ATTR = 'data-reticle-talk-book';
|
|
3
|
+
export const TALK_TEXT = {
|
|
4
|
+
HEADLINE: 'Talk to Founders',
|
|
5
|
+
BODY: 'Tell us where Reticle got in your way.',
|
|
6
|
+
BOOK: 'Book a call',
|
|
7
|
+
};
|
|
8
|
+
const escape = (text) => text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
9
|
+
export function talkCardHtml() {
|
|
10
|
+
return `<div class="reticle-talk">
|
|
11
|
+
<span class="reticle-talk-title">${escape(TALK_TEXT.HEADLINE)}</span>
|
|
12
|
+
<p class="reticle-talk-body">${escape(TALK_TEXT.BODY)}</p>
|
|
13
|
+
<a ${TALK_BOOK_ATTR} class="reticle-talk-book" href="${escape(DISCOVERY_CALL_URL)}" target="_blank" rel="noopener noreferrer">${escape(TALK_TEXT.BOOK)}</a>
|
|
14
|
+
</div>`;
|
|
15
|
+
}
|
|
16
|
+
export const TALK_CSS = `
|
|
17
|
+
.reticle-talk-title{display:block;font-weight:600;font-size:12px;padding-right:18px;}
|
|
18
|
+
.reticle-talk-body{margin:6px 0 8px;font-size:11px;line-height:1.45;opacity:.8;}
|
|
19
|
+
.reticle-talk-book{display:inline-block;font-size:11px;font-weight:600;padding:4px 10px;border-radius:6px;background:var(--reticle-accent,#4f7cff);color:#fff;text-decoration:none;}
|
|
20
|
+
`;
|
|
@@ -6,11 +6,12 @@ export declare const CHIP_LABEL: Record<PresenterMode, string>;
|
|
|
6
6
|
export declare const DATA_RETICLE_LOG = "data-reticle-log";
|
|
7
7
|
export declare const LOG_TIME_ATTR = "data-reticle-log-time";
|
|
8
8
|
export declare const LOG_CSS: string;
|
|
9
|
-
export declare function scrollLogToLatest(container: HTMLElement): void;
|
|
10
9
|
export declare function settleLogAtLatest(container: HTMLElement): void;
|
|
11
10
|
export interface LogHandle {
|
|
12
11
|
result(r: LogResult): void;
|
|
13
12
|
}
|
|
13
|
+
export declare function trimLogRows(container: HTMLElement, max: number): void;
|
|
14
|
+
export declare function clearLogRows(container: HTMLElement): void;
|
|
14
15
|
export declare function clampLogMax(n: number | undefined): number;
|
|
15
16
|
export declare function humanDuration(ms: number): string;
|
|
16
17
|
export declare function formatElapsed(ms: number): string;
|
|
@@ -70,7 +70,7 @@ export const LOG_CSS = `
|
|
|
70
70
|
border-radius:16px 16px 4px 16px;box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
|
|
71
71
|
[data-reticle-log-row][data-kind="human"] .reticle-log-text{color:var(--reticle-fg);font-size:12px;line-height:1.45;}
|
|
72
72
|
`;
|
|
73
|
-
|
|
73
|
+
function scrollLogToLatest(container) {
|
|
74
74
|
container.scrollTop = container.scrollHeight;
|
|
75
75
|
}
|
|
76
76
|
export function settleLogAtLatest(container) {
|
|
@@ -81,6 +81,18 @@ export function settleLogAtLatest(container) {
|
|
|
81
81
|
});
|
|
82
82
|
nativeSetTimeout(() => scrollLogToLatest(container), LOG_SETTLE_MS);
|
|
83
83
|
}
|
|
84
|
+
function logRows(container) {
|
|
85
|
+
return [...container.children].filter((el) => el.hasAttribute(DATA_RETICLE_LOG_ROW));
|
|
86
|
+
}
|
|
87
|
+
export function trimLogRows(container, max) {
|
|
88
|
+
const rows = logRows(container);
|
|
89
|
+
for (const row of rows.slice(0, Math.max(0, rows.length - max)))
|
|
90
|
+
row.remove();
|
|
91
|
+
}
|
|
92
|
+
export function clearLogRows(container) {
|
|
93
|
+
for (const row of logRows(container))
|
|
94
|
+
row.remove();
|
|
95
|
+
}
|
|
84
96
|
export function clampLogMax(n) {
|
|
85
97
|
if (n === undefined || !Number.isFinite(n) || n <= 0)
|
|
86
98
|
return DEFAULT_LOG_MAX;
|
|
@@ -135,8 +147,7 @@ export function appendLogRow(container, kind, text, ts, logMax) {
|
|
|
135
147
|
rowNodes.push(resEl);
|
|
136
148
|
row.append(...rowNodes);
|
|
137
149
|
container.appendChild(row);
|
|
138
|
-
|
|
139
|
-
container.firstElementChild?.remove();
|
|
150
|
+
trimLogRows(container, logMax);
|
|
140
151
|
requestAnimationFrame(() => {
|
|
141
152
|
scrollLogToLatest(container);
|
|
142
153
|
});
|
|
@@ -5,7 +5,6 @@ export declare const REPORT_LINKS: {
|
|
|
5
5
|
readonly GITHUB: "https://github.com/reticlehq/reticle";
|
|
6
6
|
readonly DISCORD: "https://discord.gg/BwAbzv9ZRz";
|
|
7
7
|
};
|
|
8
|
-
export declare const SHARE_VIA_HANDLE = "";
|
|
9
8
|
export declare const REPORT_TEXT: {
|
|
10
9
|
readonly TITLE: "Impact";
|
|
11
10
|
readonly PROJECT: "This project";
|
|
@@ -5,7 +5,7 @@ export const REPORT_LINKS = {
|
|
|
5
5
|
GITHUB: 'https://github.com/reticlehq/reticle',
|
|
6
6
|
DISCORD: 'https://discord.gg/BwAbzv9ZRz',
|
|
7
7
|
};
|
|
8
|
-
|
|
8
|
+
const SHARE_VIA_HANDLE = '';
|
|
9
9
|
export const REPORT_TEXT = {
|
|
10
10
|
TITLE: 'Impact',
|
|
11
11
|
PROJECT: 'This project',
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { HUD_KEYED_ATTRS, isHudControl } from '@reticlehq/core/hud';
|
|
2
|
+
import { HudPanel, HudToggle, HudView } from '@reticlehq/core';
|
|
3
|
+
import { isReticleUi } from '../dom/dom-ignore.js';
|
|
4
|
+
import { nativeSetTimeout } from '../timers/native/native-timers.js';
|
|
5
|
+
import { CHAT_ATTR, MIN_ATTR, REPORT_ATTR, SETTINGS_ATTR } from './presenter-config.js';
|
|
6
|
+
const PREFIX = 'data-reticle-';
|
|
7
|
+
const TOGGLE_ROLES = new Set(['switch', 'checkbox']);
|
|
8
|
+
export function controlIdOf(el) {
|
|
9
|
+
for (const attr of Array.from(el.attributes)) {
|
|
10
|
+
if (!attr.name.startsWith(PREFIX))
|
|
11
|
+
continue;
|
|
12
|
+
const name = attr.name.slice(PREFIX.length);
|
|
13
|
+
const id = HUD_KEYED_ATTRS.includes(name)
|
|
14
|
+
? `${name}.${attr.value}`
|
|
15
|
+
: name;
|
|
16
|
+
if (isHudControl(id))
|
|
17
|
+
return id;
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
function controlOf(path) {
|
|
22
|
+
for (const node of path) {
|
|
23
|
+
if (!(node instanceof Element))
|
|
24
|
+
continue;
|
|
25
|
+
if (controlIdOf(node) !== undefined)
|
|
26
|
+
return node;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
function viewOf(root) {
|
|
31
|
+
if ('1' === root.getAttribute(MIN_ATTR))
|
|
32
|
+
return { view: HudView.BUBBLE, panel: HudPanel.NONE };
|
|
33
|
+
if ('1' === root.getAttribute(SETTINGS_ATTR)) {
|
|
34
|
+
return { view: HudView.EXPANDED, panel: HudPanel.SETTINGS };
|
|
35
|
+
}
|
|
36
|
+
if ('1' === root.getAttribute(REPORT_ATTR)) {
|
|
37
|
+
return { view: HudView.EXPANDED, panel: HudPanel.REPORT };
|
|
38
|
+
}
|
|
39
|
+
if ('1' === root.getAttribute(CHAT_ATTR))
|
|
40
|
+
return { view: HudView.EXPANDED, panel: HudPanel.CHAT };
|
|
41
|
+
return { view: HudView.COLLAPSED, panel: HudPanel.NONE };
|
|
42
|
+
}
|
|
43
|
+
export function installHudTelemetry(doc, root, report) {
|
|
44
|
+
const send = (use) => {
|
|
45
|
+
try {
|
|
46
|
+
report(use);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const onPress = (event) => {
|
|
52
|
+
const el = controlOf(event.composedPath());
|
|
53
|
+
if (el === undefined || !isReticleUi(el))
|
|
54
|
+
return;
|
|
55
|
+
const control = controlIdOf(el);
|
|
56
|
+
if (control === undefined)
|
|
57
|
+
return;
|
|
58
|
+
if (!TOGGLE_ROLES.has(el.getAttribute('role') ?? '')) {
|
|
59
|
+
send({ control });
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
nativeSetTimeout(() => {
|
|
63
|
+
const on = 'true' === el.getAttribute('aria-checked');
|
|
64
|
+
send({ control, toggle: on ? HudToggle.ON : HudToggle.OFF });
|
|
65
|
+
}, 0);
|
|
66
|
+
};
|
|
67
|
+
let last = '';
|
|
68
|
+
const onChange = () => {
|
|
69
|
+
const now = viewOf(root);
|
|
70
|
+
const key = `${now.view}/${now.panel}`;
|
|
71
|
+
if (key === last)
|
|
72
|
+
return;
|
|
73
|
+
last = key;
|
|
74
|
+
send(now);
|
|
75
|
+
};
|
|
76
|
+
doc.addEventListener('click', onPress, true);
|
|
77
|
+
const observer = new MutationObserver(onChange);
|
|
78
|
+
observer.observe(root, {
|
|
79
|
+
attributes: true,
|
|
80
|
+
attributeFilter: [MIN_ATTR, CHAT_ATTR, SETTINGS_ATTR, REPORT_ATTR],
|
|
81
|
+
});
|
|
82
|
+
onChange();
|
|
83
|
+
return () => {
|
|
84
|
+
doc.removeEventListener('click', onPress, true);
|
|
85
|
+
observer.disconnect();
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -77,7 +77,7 @@ function accountMenuHtml(account, details) {
|
|
|
77
77
|
detailRow(ACCOUNT_TEXT.DEFECTS_LABEL, details.defects !== undefined ? String(details.defects) : undefined);
|
|
78
78
|
const linked = details.dashboardUrl !== undefined && isSafeDashboardUrl(details.dashboardUrl);
|
|
79
79
|
const dashboard = linked
|
|
80
|
-
? `<a class="reticle-account-action" href="${esc(details.dashboardUrl ?? '')}" target="_blank" rel="noreferrer noopener" title="${ACCOUNT_TEXT.DASHBOARD_TITLE}">${hiIconHtml(PresenterIcon.VIEW, PRESENTER_ICON_SIZE.HELP)}<span>${ACCOUNT_TEXT.DASHBOARD_ACTION}</span></a>`
|
|
80
|
+
? `<a class="reticle-account-action" data-reticle-account-dashboard href="${esc(details.dashboardUrl ?? '')}" target="_blank" rel="noreferrer noopener" title="${ACCOUNT_TEXT.DASHBOARD_TITLE}">${hiIconHtml(PresenterIcon.VIEW, PRESENTER_ICON_SIZE.HELP)}<span>${ACCOUNT_TEXT.DASHBOARD_ACTION}</span></a>`
|
|
81
81
|
:
|
|
82
82
|
`<button type="button" class="reticle-account-action reticle-account-action--hint" ${ACCOUNT_SIGNIN_ATTR} data-reticle-copy="${ACCOUNT_TEXT.LINK_COMMAND}" title="${ACCOUNT_TEXT.LINK_HINT}"><span>${ACCOUNT_TEXT.LINK_HINT}</span></button>`;
|
|
83
83
|
const signOut = `<button type="button" class="reticle-account-action" ${ACCOUNT_SIGNOUT_ATTR} data-reticle-copy="${ACCOUNT_TEXT.SIGNOUT_COMMAND}" title="${ACCOUNT_TEXT.SIGNOUT_TITLE}"><span>${ACCOUNT_TEXT.SIGNOUT_ACTION}</span></button>`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HumanControlKind } from '@reticlehq/core';
|
|
1
|
+
import type { HudUseData, HumanControlKind } from '@reticlehq/core';
|
|
2
2
|
export declare const BorderMode: {
|
|
3
3
|
readonly SESSION: "session";
|
|
4
4
|
readonly BUSY: "busy";
|
|
@@ -21,6 +21,7 @@ export interface PresenterOptions {
|
|
|
21
21
|
border?: BorderMode;
|
|
22
22
|
logMax?: number;
|
|
23
23
|
onControl?: ControlHandler;
|
|
24
|
+
onHudUse?: (use: HudUseData) => void;
|
|
24
25
|
endedFadeMs?: number;
|
|
25
26
|
}
|
|
26
27
|
export declare const DEFAULT_PACE = 450;
|
|
@@ -65,6 +66,8 @@ export declare const Placement: {
|
|
|
65
66
|
};
|
|
66
67
|
export declare const MARKERS_BTN_ATTR = "data-reticle-markers-btn";
|
|
67
68
|
export declare const CLEAR_MARKS_ATTR = "data-reticle-clear-marks";
|
|
69
|
+
export declare const COPY_MARKS_ATTR = "data-reticle-copy-marks";
|
|
70
|
+
export declare const MARKS_ROW_ATTR = "data-reticle-marks-row";
|
|
68
71
|
export declare const MARK_COUNT_ATTR = "data-reticle-mark-count";
|
|
69
72
|
export declare const ANNOTATE_BTN_ATTR = "data-reticle-annotate-btn";
|
|
70
73
|
export declare const CHAT_MIN_ATTR = "data-reticle-chat-min";
|
|
@@ -79,6 +82,7 @@ export declare const SETTINGS_PANEL_ATTR = "data-reticle-settings-panel";
|
|
|
79
82
|
export declare const SETTINGS_CLOSE_ATTR = "data-reticle-settings-close";
|
|
80
83
|
export declare const SETTING_KEY_ATTR = "data-reticle-setting";
|
|
81
84
|
export declare const SETTINGS_STORAGE_KEY = "reticle-presenter-settings";
|
|
85
|
+
export declare const MINIMISED_STORAGE_KEY = "reticle-presenter-minimised";
|
|
82
86
|
export declare const AMBIENT_GLOW_ATTR = "data-reticle-ambient-glow";
|
|
83
87
|
export declare const LIVENESS_ATTR = "data-reticle-live";
|
|
84
88
|
export declare const BLOCK_ATTR = "data-reticle-block";
|
|
@@ -45,6 +45,8 @@ export const DOCK_ALIGN_ATTR = 'data-reticle-dock-align';
|
|
|
45
45
|
export const Placement = { ABOVE: 'above', BELOW: 'below' };
|
|
46
46
|
export const MARKERS_BTN_ATTR = 'data-reticle-markers-btn';
|
|
47
47
|
export const CLEAR_MARKS_ATTR = 'data-reticle-clear-marks';
|
|
48
|
+
export const COPY_MARKS_ATTR = 'data-reticle-copy-marks';
|
|
49
|
+
export const MARKS_ROW_ATTR = 'data-reticle-marks-row';
|
|
48
50
|
export const MARK_COUNT_ATTR = 'data-reticle-mark-count';
|
|
49
51
|
export const ANNOTATE_BTN_ATTR = 'data-reticle-annotate-btn';
|
|
50
52
|
export const CHAT_MIN_ATTR = 'data-reticle-chat-min';
|
|
@@ -59,6 +61,7 @@ export const SETTINGS_PANEL_ATTR = 'data-reticle-settings-panel';
|
|
|
59
61
|
export const SETTINGS_CLOSE_ATTR = 'data-reticle-settings-close';
|
|
60
62
|
export const SETTING_KEY_ATTR = 'data-reticle-setting';
|
|
61
63
|
export const SETTINGS_STORAGE_KEY = 'reticle-presenter-settings';
|
|
64
|
+
export const MINIMISED_STORAGE_KEY = 'reticle-presenter-minimised';
|
|
62
65
|
export const AMBIENT_GLOW_ATTR = 'data-reticle-ambient-glow';
|
|
63
66
|
export const LIVENESS_ATTR = 'data-reticle-live';
|
|
64
67
|
export const BLOCK_ATTR = 'data-reticle-block';
|
|
@@ -71,6 +74,6 @@ export const HUD_POS_X_VAR = '--reticle-hud-x';
|
|
|
71
74
|
export const HUD_POS_Y_VAR = '--reticle-hud-y';
|
|
72
75
|
export const HUD_DRAG_THRESHOLD_PX = 4;
|
|
73
76
|
export const HUD_DOCK_MARGIN_PX = 8;
|
|
74
|
-
export const HUD_DRAG_IGNORE_SEL = '[data-reticle-pause], [data-reticle-annotate-btn], [data-reticle-markers-btn], [data-reticle-clear-marks], [data-reticle-end], [data-reticle-min-btn], [data-reticle-settings-btn], [data-reticle-settings-panel], [data-reticle-report-btn], [data-reticle-report-panel], [data-reticle-chat-panel], [data-reticle-chat-toggle], [data-reticle-workspace-btn], [data-reticle-workspace-menu], [data-reticle-copy], [data-reticle-export], input, textarea, select, a, .reticle-head-ctl, [data-reticle-tally], .reticle-maxhint';
|
|
77
|
+
export const HUD_DRAG_IGNORE_SEL = '[data-reticle-pause], [data-reticle-annotate-btn], [data-reticle-markers-btn], [data-reticle-clear-marks], [data-reticle-copy-marks], [data-reticle-end], [data-reticle-min-btn], [data-reticle-settings-btn], [data-reticle-settings-panel], [data-reticle-report-btn], [data-reticle-report-panel], [data-reticle-chat-panel], [data-reticle-chat-toggle], [data-reticle-workspace-btn], [data-reticle-workspace-menu], [data-reticle-copy], [data-reticle-export], input, textarea, select, a, .reticle-head-ctl, [data-reticle-tally], .reticle-maxhint';
|
|
75
78
|
export const THROTTLED_ATTR = 'data-reticle-throttled';
|
|
76
79
|
export const Z_HUD_TOOLTIP = 100;
|
|
@@ -4,6 +4,7 @@ export declare const ENDED_FADE_MS = 4000;
|
|
|
4
4
|
export declare const CONTROLS_CSS: string;
|
|
5
5
|
export declare const CONTROLS_TOOLBAR_HTML: string;
|
|
6
6
|
export declare const CONTROLS_BANNER_HTML = "<div data-reticle-banner class=\"reticle-banner\">Session ended</div>";
|
|
7
|
+
export declare const CONTROLS_MARKS_HTML: string;
|
|
7
8
|
export declare const CONTROLS_FLOWS_HTML = "<div data-reticle-flows class=\"reticle-flows\"><span class=\"reticle-flows-cap\">Replay a flow</span></div>";
|
|
8
9
|
export declare const CONTROLS_FOOT_HTML: string;
|
|
9
10
|
interface ControlPanelHost {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HumanControlKind, PresenterTone, SessionState } from '@reticlehq/core';
|
|
2
2
|
import { nativeSetTimeout, nativeClearTimeout } from '../timers/native/native-timers.js';
|
|
3
|
-
import { CHAT_TOGGLE_ATTR, CLEAR_MARKS_ATTR, MARKERS_BTN_ATTR } from './presenter-config.js';
|
|
3
|
+
import { CHAT_TOGGLE_ATTR, CLEAR_MARKS_ATTR, COPY_MARKS_ATTR, MARKERS_BTN_ATTR, MARKS_ROW_ATTR, } from './presenter-config.js';
|
|
4
4
|
import { PresenterIcon, PRESENTER_ICON_SIZE, hiIcon, hiIconHtml, hiToggleIconHtml, } from './icons/presenter-icons.js';
|
|
5
5
|
import { getPresenterSettings } from './presenter-settings.js';
|
|
6
6
|
import { mountWorkspaceSelector, workspaceRowHtml } from './presenter-workspace.js';
|
|
@@ -101,6 +101,15 @@ export const CONTROLS_CSS = `
|
|
|
101
101
|
[data-reticle-chat-panel] .reticle-flow:active{transform:scale(.95);}
|
|
102
102
|
[data-reticle-overlay][data-reticle-state="paused"] [data-reticle-hud] .reticle-tb-btn--primary{
|
|
103
103
|
box-shadow:inset 0 0 0 1px rgba(255,255,255,.16),0 0 12px rgba(255,255,255,.04);}
|
|
104
|
+
[data-reticle-chat-panel] .reticle-marks-row{display:flex;align-items:center;justify-content:space-between;gap:8px;
|
|
105
|
+
padding:7px 12px;border-top:1px solid var(--reticle-line2);pointer-events:auto;}
|
|
106
|
+
[data-reticle-chat-panel] .reticle-marks-row[hidden]{display:none;}
|
|
107
|
+
[data-reticle-chat-panel] .reticle-marks-text{color:var(--reticle-muted);font-size:11px;}
|
|
108
|
+
[data-reticle-chat-panel] .reticle-marks-copy{display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 10px;
|
|
109
|
+
border-radius:7px;border:1px solid var(--reticle-line);background:rgba(255,255,255,.04);color:var(--reticle-fg);
|
|
110
|
+
font-family:var(--reticle-font);font-size:11px;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s;}
|
|
111
|
+
[data-reticle-chat-panel] .reticle-marks-copy:hover{background:var(--reticle-accent-soft);border-color:var(--reticle-accent);}
|
|
112
|
+
[data-reticle-chat-panel] .reticle-marks-copy[data-copied="1"]{color:#22c55e;border-color:#22c55e;}
|
|
104
113
|
[data-reticle-hud] .reticle-export-msg{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
|
|
105
114
|
overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;}
|
|
106
115
|
`;
|
|
@@ -116,6 +125,7 @@ function paintPauseBtn(btn, paused) {
|
|
|
116
125
|
const CHAT_LABEL = 'Agent chat';
|
|
117
126
|
const MARKERS_LABEL = 'Hide markers';
|
|
118
127
|
const CLEAR_MARKS_LABEL = 'Clear all';
|
|
128
|
+
const COPY_MARKS_LABEL = 'Copy for your agent';
|
|
119
129
|
const TB = PRESENTER_ICON_SIZE.TOOLBAR;
|
|
120
130
|
function tbWrap(btn, tip, kbd) {
|
|
121
131
|
const shortcut = kbd === undefined ? '' : `<span class="reticle-tb-kbd">${kbd}</span>`;
|
|
@@ -138,6 +148,7 @@ export const CONTROLS_TOOLBAR_HTML = [
|
|
|
138
148
|
'<span data-reticle-export-msg class="reticle-export-msg" aria-live="polite"></span>',
|
|
139
149
|
].join('');
|
|
140
150
|
export const CONTROLS_BANNER_HTML = `<div data-reticle-banner class="reticle-banner">${ENDED_BANNER_TEXT}</div>`;
|
|
151
|
+
export const CONTROLS_MARKS_HTML = `<div ${MARKS_ROW_ATTR} class="reticle-marks-row" hidden><span data-reticle-marks-text class="reticle-marks-text"></span><button type="button" ${COPY_MARKS_ATTR} class="reticle-marks-copy" title="${COPY_MARKS_LABEL}">${hiIconHtml(PresenterIcon.COPY, PRESENTER_ICON_SIZE.HELP)}<span>${COPY_MARKS_LABEL}</span></button></div>`;
|
|
141
152
|
export const CONTROLS_FLOWS_HTML = `<div data-reticle-flows class="reticle-flows"><span class="reticle-flows-cap">${FLOWS_LABEL}</span></div>`;
|
|
142
153
|
export const CONTROLS_FOOT_HTML = `<div data-reticle-foot><div class="reticle-foot-stack">${workspaceRowHtml()}</div></div>`;
|
|
143
154
|
function queryControlRefs(root) {
|
|
@@ -28,10 +28,10 @@ export function reportPanelHtml() {
|
|
|
28
28
|
<button type="button" ${REFER_ATTR} class="reticle-report-share reticle-report-refer">${REPORT_TEXT.REFER}</button>
|
|
29
29
|
</div>
|
|
30
30
|
<div class="reticle-report-links">
|
|
31
|
-
<a href="${REPORT_LINKS.DOCS}" target="_blank" rel="noreferrer noopener">Docs</a>
|
|
32
|
-
<a href="${REPORT_LINKS.GITHUB}" target="_blank" rel="noreferrer noopener">GitHub</a>
|
|
33
|
-
<a href="${REPORT_LINKS.SITE}" target="_blank" rel="noreferrer noopener">reticle.sh</a>
|
|
34
|
-
<a href="${REPORT_LINKS.DISCORD}" target="_blank" rel="noreferrer noopener">Discord</a>
|
|
31
|
+
<a data-reticle-link="docs" href="${REPORT_LINKS.DOCS}" target="_blank" rel="noreferrer noopener">Docs</a>
|
|
32
|
+
<a data-reticle-link="github" href="${REPORT_LINKS.GITHUB}" target="_blank" rel="noreferrer noopener">GitHub</a>
|
|
33
|
+
<a data-reticle-link="site" href="${REPORT_LINKS.SITE}" target="_blank" rel="noreferrer noopener">reticle.sh</a>
|
|
34
|
+
<a data-reticle-link="discord" href="${REPORT_LINKS.DISCORD}" target="_blank" rel="noreferrer noopener">Discord</a>
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
37
|
</div>`;
|
|
@@ -63,7 +63,7 @@ function defects(scope, dashboardUrl) {
|
|
|
63
63
|
return '';
|
|
64
64
|
const linked = dashboardUrl !== undefined && isSafeDashboardUrl(dashboardUrl);
|
|
65
65
|
const rowLink = linked
|
|
66
|
-
? `<a class="reticle-report-defect-link" href="${esc(dashboardUrl)}" target="_blank" rel="noreferrer noopener" title="${REPORT_TEXT.DEFECT_LINK_TITLE}" aria-label="${REPORT_TEXT.DEFECT_LINK_TITLE}">${hiIconHtml(PresenterIcon.VIEW, PRESENTER_ICON_SIZE.SEND)}</a>`
|
|
66
|
+
? `<a class="reticle-report-defect-link" data-reticle-link="defect" href="${esc(dashboardUrl)}" target="_blank" rel="noreferrer noopener" title="${REPORT_TEXT.DEFECT_LINK_TITLE}" aria-label="${REPORT_TEXT.DEFECT_LINK_TITLE}">${hiIconHtml(PresenterIcon.VIEW, PRESENTER_ICON_SIZE.SEND)}</a>`
|
|
67
67
|
: '';
|
|
68
68
|
const rows = list
|
|
69
69
|
.map((d) => {
|
|
@@ -78,7 +78,7 @@ function defects(scope, dashboardUrl) {
|
|
|
78
78
|
.join('');
|
|
79
79
|
const more = !linked
|
|
80
80
|
? ''
|
|
81
|
-
: `<a class="reticle-report-defects-more" href="${esc(dashboardUrl)}" target="_blank" rel="noreferrer noopener">${REPORT_TEXT.DEFECTS_MORE}${scope.counts.failed > list.length ? ` (${String(scope.counts.failed)})` : ''}</a>`;
|
|
81
|
+
: `<a class="reticle-report-defects-more" data-reticle-link="dashboard" href="${esc(dashboardUrl)}" target="_blank" rel="noreferrer noopener">${REPORT_TEXT.DEFECTS_MORE}${scope.counts.failed > list.length ? ` (${String(scope.counts.failed)})` : ''}</a>`;
|
|
82
82
|
const sync = syncButtonHtml(dashboardUrl);
|
|
83
83
|
return `<div class="reticle-report-defects-wrap"><div class="reticle-report-defects-head"><span class="reticle-report-section">${REPORT_TEXT.DEFECTS}</span>${sync}</div><ul class="reticle-report-defects">${rows}</ul>${more}</div>`;
|
|
84
84
|
}
|
|
@@ -120,7 +120,8 @@ export const SETTINGS_CSS = `
|
|
|
120
120
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-link{
|
|
121
121
|
width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;
|
|
122
122
|
border:none;background:transparent;color:rgba(255,255,255,.82);font:inherit;font-size:13px;
|
|
123
|
-
padding:11px 14px;cursor:pointer;text-align:left;transition:background .12s,color .12s;
|
|
123
|
+
padding:11px 14px;cursor:pointer;text-align:left;transition:background .12s,color .12s;
|
|
124
|
+
text-decoration:none;box-sizing:border-box;}
|
|
124
125
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-link-caret{display:inline-flex;align-items:center;flex:none;opacity:.55;}
|
|
125
126
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-link:hover{background:rgba(255,255,255,.04);color:#fff;}
|
|
126
127
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-link:focus-visible{outline:2px solid rgba(59,130,246,.55);outline-offset:-2px;}
|
|
@@ -9,14 +9,14 @@ export declare const OutputDetail: {
|
|
|
9
9
|
readonly VERBOSE: "verbose";
|
|
10
10
|
};
|
|
11
11
|
export type OutputDetail = (typeof OutputDetail)[keyof typeof OutputDetail];
|
|
12
|
-
|
|
12
|
+
declare const StatusThemeId: {
|
|
13
13
|
readonly SIGNAL: "signal";
|
|
14
14
|
readonly TRAFFIC: "traffic";
|
|
15
15
|
readonly MONO: "mono";
|
|
16
16
|
readonly NEON: "neon";
|
|
17
17
|
readonly EMBER: "ember";
|
|
18
18
|
};
|
|
19
|
-
|
|
19
|
+
type StatusThemeId = (typeof StatusThemeId)[keyof typeof StatusThemeId];
|
|
20
20
|
interface StatusTheme {
|
|
21
21
|
id: StatusThemeId;
|
|
22
22
|
label: string;
|
|
@@ -24,7 +24,6 @@ interface StatusTheme {
|
|
|
24
24
|
idle: string;
|
|
25
25
|
ended: string;
|
|
26
26
|
}
|
|
27
|
-
export declare const STATUS_THEMES: readonly StatusTheme[];
|
|
28
27
|
export declare function statusTheme(id: StatusThemeId): StatusTheme;
|
|
29
28
|
export interface PresenterSettings {
|
|
30
29
|
outputDetail: OutputDetail;
|
|
@@ -51,7 +50,6 @@ export interface SettingsHost {
|
|
|
51
50
|
onSettingsChange?: (settings: PresenterSettings) => void;
|
|
52
51
|
onBeforeOpen?: () => void;
|
|
53
52
|
}
|
|
54
|
-
export declare function applyPresenterSettings(root: HTMLElement, settings: PresenterSettings): void;
|
|
55
53
|
export declare function syncPageBlocker(root: HTMLElement, settings: PresenterSettings, annotateLive: boolean): void;
|
|
56
54
|
export declare function blockerHtml(): string;
|
|
57
55
|
export declare class PresenterSettingsPanel {
|
|
@@ -4,6 +4,7 @@ import { HUD_SURFACE_CLASS } from './chrome/presenter-hud-chrome.js';
|
|
|
4
4
|
import { resetHudDockPosition } from './presenter-drag.js';
|
|
5
5
|
import { findDock, scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
6
6
|
import { SETTINGS_CSS } from './presenter-settings-styles.js';
|
|
7
|
+
import { DISCOVERY_CALL_URL, FOUNDER_EMAIL, FOUNDER_MAILTO } from '@reticlehq/core';
|
|
7
8
|
import { accountControlHtml } from './presenter-account.js';
|
|
8
9
|
export { SETTINGS_CSS };
|
|
9
10
|
export const OutputDetail = {
|
|
@@ -11,14 +12,14 @@ export const OutputDetail = {
|
|
|
11
12
|
STANDARD: 'standard',
|
|
12
13
|
VERBOSE: 'verbose',
|
|
13
14
|
};
|
|
14
|
-
|
|
15
|
+
const StatusThemeId = {
|
|
15
16
|
SIGNAL: 'signal',
|
|
16
17
|
TRAFFIC: 'traffic',
|
|
17
18
|
MONO: 'mono',
|
|
18
19
|
NEON: 'neon',
|
|
19
20
|
EMBER: 'ember',
|
|
20
21
|
};
|
|
21
|
-
|
|
22
|
+
const STATUS_THEMES = [
|
|
22
23
|
{
|
|
23
24
|
id: StatusThemeId.SIGNAL,
|
|
24
25
|
label: 'Signal',
|
|
@@ -132,7 +133,7 @@ function settingsHelpIcon() {
|
|
|
132
133
|
}
|
|
133
134
|
function settingsLabel(text, helpTitle) {
|
|
134
135
|
const help = settingsHelpIcon();
|
|
135
|
-
return `<span class="reticle-settings-label">${text}<button type="button" class="reticle-settings-help" title="${helpTitle}" aria-label="${helpTitle}">${help}</button></span>`;
|
|
136
|
+
return `<span class="reticle-settings-label">${text}<button type="button" class="reticle-settings-help" data-reticle-settings-help title="${helpTitle}" aria-label="${helpTitle}">${help}</button></span>`;
|
|
136
137
|
}
|
|
137
138
|
function settingsToggleRow(key, label, helpTitle, extra = '') {
|
|
138
139
|
return `<div class="reticle-settings-row" ${extra}>
|
|
@@ -181,6 +182,12 @@ export function paintSettingsAccount(root, account, dashboardUrl, details = {})
|
|
|
181
182
|
row.hidden = 0 === html.length;
|
|
182
183
|
slot.innerHTML = html;
|
|
183
184
|
}
|
|
185
|
+
const FEEDBACK_TEXT = {
|
|
186
|
+
EMAIL: 'Email the founder',
|
|
187
|
+
EMAIL_TITLE: `Write to ${FOUNDER_EMAIL}: a problem, a wish, anything`,
|
|
188
|
+
CALL: 'Book a call',
|
|
189
|
+
CALL_TITLE: 'Pick a time to talk it through',
|
|
190
|
+
};
|
|
184
191
|
export function settingsPanelHtml() {
|
|
185
192
|
const close = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.MIN);
|
|
186
193
|
const caret = hiIconHtml(PresenterIcon.CARET_RIGHT, PRESENTER_ICON_SIZE.HELP);
|
|
@@ -228,11 +235,13 @@ export function settingsPanelHtml() {
|
|
|
228
235
|
<div class="reticle-settings-foot">
|
|
229
236
|
<button type="button" class="reticle-settings-reset" data-reticle-settings-reset>Reset HUD position</button>
|
|
230
237
|
<button type="button" class="reticle-settings-link" data-reticle-settings-mcp>Manage MCP & Webhooks<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></button>
|
|
238
|
+
<a class="reticle-settings-link" data-reticle-feedback-email href="${FOUNDER_MAILTO}" target="_blank" rel="noopener noreferrer" title="${FEEDBACK_TEXT.EMAIL_TITLE}">${FEEDBACK_TEXT.EMAIL}<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></a>
|
|
239
|
+
<a class="reticle-settings-link" data-reticle-feedback-call href="${DISCOVERY_CALL_URL}" target="_blank" rel="noopener noreferrer" title="${FEEDBACK_TEXT.CALL_TITLE}">${FEEDBACK_TEXT.CALL}<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></a>
|
|
231
240
|
</div>
|
|
232
241
|
</div>
|
|
233
242
|
</div>`;
|
|
234
243
|
}
|
|
235
|
-
|
|
244
|
+
function applyPresenterSettings(root, settings) {
|
|
236
245
|
const theme = statusTheme(settings.statusThemeId);
|
|
237
246
|
root.style.setProperty('--reticle-mark-accent', theme.active);
|
|
238
247
|
root.style.setProperty('--reticle-accent', theme.active);
|
|
@@ -246,6 +246,10 @@ export const SHELL_CSS = `
|
|
|
246
246
|
transition:opacity .2s var(--reticle-shell-ease),transform .18s var(--reticle-shell-ease);}
|
|
247
247
|
[${OVERLAY}][${MIN_ATTR}="0"] [${HUD}] .reticle-toolbar{
|
|
248
248
|
display:flex;opacity:1;transform:scale(1);pointer-events:auto;}
|
|
249
|
+
/* The HUD block is transformed, which makes it a stacking context at level 0 inside the dock, so a
|
|
250
|
+
tooltip's z-index only ranked it within the block and it drew behind the chat and settings panels,
|
|
251
|
+
its siblings. Lift the block while a tooltip can show. */
|
|
252
|
+
[${HUD}]:hover,[${HUD}]:focus-within{z-index:${String(Z_HUD_TOOLTIP)};}
|
|
249
253
|
[${HUD}] .reticle-toolbar-drag{cursor:grab;touch-action:none;user-select:none;}
|
|
250
254
|
[${HUD}] .reticle-toolbar-drag.reticle-drag-handle--dragging{cursor:grabbing;}
|
|
251
255
|
[${HUD}] .reticle-toolbar-actions{
|
|
@@ -2,7 +2,7 @@ import type { HarnessConfig } from '@reticlehq/core';
|
|
|
2
2
|
import { PresenterReport } from './presenter-report.js';
|
|
3
3
|
import type { AccountState } from '@reticlehq/core';
|
|
4
4
|
import { type AccountDetails } from './presenter-account.js';
|
|
5
|
-
import { type OfferState } from './
|
|
5
|
+
import { type OfferState } from './carousel/offer-card.js';
|
|
6
6
|
import { type SettingsHost } from './presenter-settings.js';
|
|
7
7
|
interface HudShellCallbacks {
|
|
8
8
|
onChatOpen?: () => void;
|
|
@@ -35,4 +35,7 @@ export declare class HudShell {
|
|
|
35
35
|
showChat(): void;
|
|
36
36
|
pulseFab(active: boolean): void;
|
|
37
37
|
}
|
|
38
|
+
export declare function wasMinimised(): boolean;
|
|
39
|
+
export declare function rememberMinimised(minimised: boolean): void;
|
|
40
|
+
export declare function shouldAutoOpenChat(autoOpenChat: boolean): boolean;
|
|
38
41
|
export {};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { appModalOpen } from '../dom/dom-ignore.js';
|
|
1
2
|
import { PresenterReport, reportPanelHtml } from './presenter-report.js';
|
|
2
3
|
import { paintToolbarAccount, TOOLBAR_ACCOUNT_ATTR } from './presenter-workspace.js';
|
|
3
4
|
import { mountAccountControl } from './presenter-account.js';
|
|
4
5
|
import { paintSettingsAccount } from './presenter-settings.js';
|
|
5
|
-
import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR, REPORT_BTN_ATTR, ANNOTATE_BTN_ATTR, CHAT_ATTR, CHAT_TOGGLE_ATTR, CHAT_PANEL_ATTR, DOCK_ATTR, FAB_ATTR, MIN_ATTR, SETTINGS_ATTR, SETTINGS_BTN_ATTR, } from './presenter-config.js';
|
|
6
|
-
import {
|
|
6
|
+
import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR, REPORT_BTN_ATTR, ANNOTATE_BTN_ATTR, CHAT_ATTR, CHAT_TOGGLE_ATTR, CHAT_PANEL_ATTR, DOCK_ATTR, FAB_ATTR, MIN_ATTR, SETTINGS_ATTR, SETTINGS_BTN_ATTR, MINIMISED_STORAGE_KEY, } from './presenter-config.js';
|
|
7
|
+
import { offerDismissed } from './carousel/offer-card.js';
|
|
8
|
+
import { paintCarousel } from './carousel/carousel.js';
|
|
9
|
+
import { panelSlides } from './carousel/panel-slides.js';
|
|
7
10
|
import { BRAND_NAME, FAB_TOGGLE_HTML, MARK_SVG } from './chrome/presenter-brand.js';
|
|
8
|
-
import { settleLogAtLatest } from './chrome/presenter-log.js';
|
|
11
|
+
import { DATA_RETICLE_LOG, settleLogAtLatest } from './chrome/presenter-log.js';
|
|
9
12
|
import { installHudDragHandles, installHudPositionGuards } from './presenter-drag.js';
|
|
10
13
|
import { scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
11
14
|
import { hiIconHtml, hiToggleIconHtml, PRESENTER_ICON_SIZE, PresenterIcon, } from './icons/presenter-icons.js';
|
|
@@ -59,9 +62,22 @@ export class HudShell {
|
|
|
59
62
|
#pushedOffer;
|
|
60
63
|
paintOffer(offer) {
|
|
61
64
|
this.#pushedOffer = offer;
|
|
62
|
-
|
|
65
|
+
this.#paintCarousel();
|
|
66
|
+
}
|
|
67
|
+
#paintCarousel() {
|
|
68
|
+
const log = this.#root?.querySelector(`[${DATA_RETICLE_LOG}]`);
|
|
69
|
+
if (!(log instanceof HTMLElement))
|
|
63
70
|
return;
|
|
64
|
-
|
|
71
|
+
const declined = offerDismissed(this.#storage());
|
|
72
|
+
paintCarousel(log, panelSlides(this.#pushedOffer, declined), this.#sessionStorage());
|
|
73
|
+
}
|
|
74
|
+
#sessionStorage() {
|
|
75
|
+
try {
|
|
76
|
+
return globalThis.sessionStorage;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
65
81
|
}
|
|
66
82
|
#storage() {
|
|
67
83
|
try {
|
|
@@ -97,7 +113,6 @@ export class HudShell {
|
|
|
97
113
|
${actStripHtml}
|
|
98
114
|
<span class="reticle-tally" data-reticle-tally hidden></span>
|
|
99
115
|
${bannerHtml}
|
|
100
|
-
<div ${OFFER_SLOT_ATTR}></div>
|
|
101
116
|
<div class="${HUD_LOG_WELL_CLASS}"><div ${logAttr}></div></div>
|
|
102
117
|
${flowsHtml}
|
|
103
118
|
${footHtml}
|
|
@@ -248,8 +263,7 @@ export class HudShell {
|
|
|
248
263
|
const pushed = this.#pushedAccount;
|
|
249
264
|
this.paintAccount(pushed.account, pushed.dashboardUrl, pushed.details);
|
|
250
265
|
}
|
|
251
|
-
|
|
252
|
-
this.paintOffer(this.#pushedOffer);
|
|
266
|
+
this.#paintCarousel();
|
|
253
267
|
}
|
|
254
268
|
teardown() {
|
|
255
269
|
this.#accountTeardown?.();
|
|
@@ -283,6 +297,7 @@ export class HudShell {
|
|
|
283
297
|
return;
|
|
284
298
|
this.#lockTransition();
|
|
285
299
|
this.#root.setAttribute(MIN_ATTR, '0');
|
|
300
|
+
rememberMinimised(false);
|
|
286
301
|
if (this.#fab !== undefined)
|
|
287
302
|
this.#fab.setAttribute('aria-expanded', 'true');
|
|
288
303
|
this.#callbacks.onExpand?.();
|
|
@@ -297,6 +312,7 @@ export class HudShell {
|
|
|
297
312
|
this.closeChat();
|
|
298
313
|
this.#settings.close();
|
|
299
314
|
this.#root.setAttribute(MIN_ATTR, '1');
|
|
315
|
+
rememberMinimised(true);
|
|
300
316
|
if (this.#fab !== undefined)
|
|
301
317
|
this.#fab.setAttribute('aria-expanded', 'false');
|
|
302
318
|
this.#callbacks.onCollapse?.();
|
|
@@ -367,6 +383,10 @@ export class HudShell {
|
|
|
367
383
|
#onKeyDown = (e) => {
|
|
368
384
|
if ('Escape' !== e.key || this.#root === undefined)
|
|
369
385
|
return;
|
|
386
|
+
if (e.defaultPrevented)
|
|
387
|
+
return;
|
|
388
|
+
if (appModalOpen(document))
|
|
389
|
+
return;
|
|
370
390
|
const target = e.target;
|
|
371
391
|
if (target instanceof HTMLElement &&
|
|
372
392
|
('INPUT' === target.tagName ||
|
|
@@ -375,18 +395,36 @@ export class HudShell {
|
|
|
375
395
|
return;
|
|
376
396
|
}
|
|
377
397
|
if (this.isChatOpen()) {
|
|
378
|
-
e.preventDefault();
|
|
379
398
|
this.closeChat();
|
|
380
399
|
return;
|
|
381
400
|
}
|
|
382
401
|
if (this.#settings.isOpen()) {
|
|
383
|
-
e.preventDefault();
|
|
384
402
|
this.#settings.close();
|
|
385
403
|
return;
|
|
386
404
|
}
|
|
387
405
|
if (!this.isCollapsed()) {
|
|
388
|
-
e.preventDefault();
|
|
389
406
|
this.collapse();
|
|
390
407
|
}
|
|
391
408
|
};
|
|
392
409
|
}
|
|
410
|
+
export function wasMinimised() {
|
|
411
|
+
try {
|
|
412
|
+
return '1' === globalThis.sessionStorage.getItem(MINIMISED_STORAGE_KEY);
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
export function rememberMinimised(minimised) {
|
|
419
|
+
try {
|
|
420
|
+
if (minimised)
|
|
421
|
+
globalThis.sessionStorage.setItem(MINIMISED_STORAGE_KEY, '1');
|
|
422
|
+
else
|
|
423
|
+
globalThis.sessionStorage.removeItem(MINIMISED_STORAGE_KEY);
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
export function shouldAutoOpenChat(autoOpenChat) {
|
|
429
|
+
return autoOpenChat && !wasMinimised();
|
|
430
|
+
}
|
|
@@ -6,7 +6,9 @@ import { SETTINGS_CSS } from './presenter-settings-styles.js';
|
|
|
6
6
|
import { ACCOUNT_CSS } from './presenter-account-styles.js';
|
|
7
7
|
import { HUD_CHROME_CSS, HUD_LOG_WELL_CSS } from './chrome/presenter-hud-chrome.js';
|
|
8
8
|
import { REPORT_CSS } from './presenter-report-styles.js';
|
|
9
|
-
import { OFFER_CSS } from './
|
|
9
|
+
import { OFFER_CSS } from './carousel/offer-card.js';
|
|
10
|
+
import { TALK_CSS } from './carousel/talk-card.js';
|
|
11
|
+
import { CAROUSEL_CSS } from './carousel/carousel.js';
|
|
10
12
|
export { Z_OVERLAY };
|
|
11
13
|
export const PRESENTER_CSS = `
|
|
12
14
|
[data-reticle-overlay]{position:fixed;inset:0;pointer-events:none;z-index:${String(Z_OVERLAY)};}
|
|
@@ -65,5 +67,7 @@ ${SETTINGS_CSS}
|
|
|
65
67
|
${REPORT_CSS}
|
|
66
68
|
${ACCOUNT_CSS}
|
|
67
69
|
${OFFER_CSS}
|
|
70
|
+
${TALK_CSS}
|
|
71
|
+
${CAROUSEL_CSS}
|
|
68
72
|
${LOG_CSS}
|
|
69
73
|
${CONTROLS_CSS}`;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import type { AccountState } from '@reticlehq/core';
|
|
2
2
|
import { type AccountDetails } from './presenter-account.js';
|
|
3
3
|
export declare const TOOLBAR_ACCOUNT_ATTR = "data-reticle-toolbar-account";
|
|
4
|
-
export declare function readWorkspaceRoot(): string | undefined;
|
|
5
4
|
export declare function workspaceFolderLabel(root: string): string;
|
|
6
|
-
export declare function readProjectIdFromUrl(): string | undefined;
|
|
7
|
-
export declare function workspaceSummary(): {
|
|
8
|
-
folder: string;
|
|
9
|
-
root?: string;
|
|
10
|
-
projectId?: string;
|
|
11
|
-
};
|
|
12
5
|
export declare function workspaceRowHtml(): string;
|
|
13
6
|
export declare function paintWorkspace(root: HTMLElement): void;
|
|
14
7
|
export declare function mountWorkspaceSelector(root: HTMLElement): () => void;
|