@peers-app/peers-ui 0.27.3 → 0.27.4
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/screens/network-viewer/network-viewer-ipc.d.ts +3 -1
- package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
- package/dist/screens/network-viewer/sync-recovery.js +103 -1
- package/dist/screens/variables/variable-details.js +2 -1
- package/dist/tabs-layout/network-status-indicator.js +26 -12
- package/dist/tabs-layout/use-network-status.d.ts +6 -1
- package/dist/tabs-layout/use-network-status.js +27 -4
- package/package.json +9 -3
- package/.claude/settings.local.json +0 -34
- package/.github/README.md +0 -52
- package/.github/workflows/delete-all-artifacts.yml +0 -49
- package/.github/workflows/publish.yml +0 -51
- package/babel.config.js +0 -7
- package/biome.json +0 -198
- package/dist/app-updates/app-updates-consumer.test.d.ts +0 -1
- package/dist/app-updates/app-updates-consumer.test.js +0 -56
- package/dist/app-updates/app-updates-settings.test.d.ts +0 -1
- package/dist/app-updates/app-updates-settings.test.js +0 -93
- package/dist/app-updates/remote-app-update-panel.test.d.ts +0 -1
- package/dist/app-updates/remote-app-update-panel.test.js +0 -165
- package/dist/components/access-level-field.test.d.ts +0 -1
- package/dist/components/access-level-field.test.js +0 -28
- package/dist/components/message-logs/tool-access-approval-card.test.d.ts +0 -1
- package/dist/components/message-logs/tool-access-approval-card.test.js +0 -102
- package/dist/components/responsive-section-nav.test.d.ts +0 -1
- package/dist/components/responsive-section-nav.test.js +0 -45
- package/dist/globals-hash.test.d.ts +0 -1
- package/dist/globals-hash.test.js +0 -16
- package/dist/hooks/use-observable-state.test.d.ts +0 -1
- package/dist/hooks/use-observable-state.test.js +0 -64
- package/dist/hooks/use-observable.test.d.ts +0 -1
- package/dist/hooks/use-observable.test.js +0 -191
- package/dist/hooks/use-rows.test.d.ts +0 -1
- package/dist/hooks/use-rows.test.js +0 -175
- package/dist/hooks/use-tool.test.d.ts +0 -1
- package/dist/hooks/use-tool.test.js +0 -190
- package/dist/host-shell/host-shell-consumer.test.d.ts +0 -1
- package/dist/host-shell/host-shell-consumer.test.js +0 -28
- package/dist/root-layout/root-layout-host.test.d.ts +0 -1
- package/dist/root-layout/root-layout-host.test.js +0 -86
- package/dist/screens/account/account-screen.test.d.ts +0 -1
- package/dist/screens/account/account-screen.test.js +0 -51
- package/dist/screens/assistants/assistant-config.test.d.ts +0 -1
- package/dist/screens/assistants/assistant-config.test.js +0 -57
- package/dist/screens/contacts/contact-list.test.d.ts +0 -1
- package/dist/screens/contacts/contact-list.test.js +0 -48
- package/dist/screens/device-pairing/device-pairing.test.d.ts +0 -1
- package/dist/screens/device-pairing/device-pairing.test.js +0 -119
- package/dist/screens/devices/devices-list.test.d.ts +0 -1
- package/dist/screens/devices/devices-list.test.js +0 -53
- package/dist/screens/groups/group-list.test.d.ts +0 -1
- package/dist/screens/groups/group-list.test.js +0 -38
- package/dist/screens/identity/identity-routes.test.d.ts +0 -1
- package/dist/screens/identity/identity-routes.test.js +0 -51
- package/dist/screens/identity/identity-screen.test.d.ts +0 -1
- package/dist/screens/identity/identity-screen.test.js +0 -103
- package/dist/screens/invites/accept-invite.test.d.ts +0 -1
- package/dist/screens/invites/accept-invite.test.js +0 -103
- package/dist/screens/invites/activity-view.test.d.ts +0 -1
- package/dist/screens/invites/activity-view.test.js +0 -108
- package/dist/screens/invites/invite-classify.test.d.ts +0 -1
- package/dist/screens/invites/invite-classify.test.js +0 -115
- package/dist/screens/network-viewer/network-viewer-ipc.test.d.ts +0 -1
- package/dist/screens/network-viewer/network-viewer-ipc.test.js +0 -61
- package/dist/screens/network-viewer/network-viewer.section.test.d.ts +0 -1
- package/dist/screens/network-viewer/network-viewer.section.test.js +0 -63
- package/dist/screens/network-viewer/sync-recovery.test.d.ts +0 -1
- package/dist/screens/network-viewer/sync-recovery.test.js +0 -104
- package/dist/screens/packages/package-helpers.test.d.ts +0 -1
- package/dist/screens/packages/package-helpers.test.js +0 -53
- package/dist/screens/packages/package-runtime-status.test.d.ts +0 -1
- package/dist/screens/packages/package-runtime-status.test.js +0 -50
- package/dist/screens/packages/packages-ipc.test.d.ts +0 -1
- package/dist/screens/packages/packages-ipc.test.js +0 -43
- package/dist/screens/settings/settings-page.test.d.ts +0 -1
- package/dist/screens/settings/settings-page.test.js +0 -19
- package/dist/screens/tools/tool-access-ipc.test.d.ts +0 -1
- package/dist/screens/tools/tool-access-ipc.test.js +0 -40
- package/dist/screens/tools/tool-catalog-ipc.test.d.ts +0 -1
- package/dist/screens/tools/tool-catalog-ipc.test.js +0 -52
- package/dist/tabs-layout/network-status-indicator.test.d.ts +0 -1
- package/dist/tabs-layout/network-status-indicator.test.js +0 -665
- package/dist/tabs-layout/tabs-state.test.d.ts +0 -1
- package/dist/tabs-layout/tabs-state.test.js +0 -110
- package/dist/tabs-layout/use-network-status.test.d.ts +0 -1
- package/dist/tabs-layout/use-network-status.test.js +0 -45
- package/dist/ui-router/ui-loader.test.d.ts +0 -1
- package/dist/ui-router/ui-loader.test.js +0 -91
- package/jest.config.js +0 -25
- package/release-guard.js +0 -10
- package/src/app-updates/app-update-controls.tsx +0 -73
- package/src/app-updates/app-updates-consumer.test.ts +0 -83
- package/src/app-updates/app-updates-consumer.ts +0 -121
- package/src/app-updates/app-updates-settings.test.tsx +0 -109
- package/src/app-updates/app-updates-settings.tsx +0 -136
- package/src/app-updates/remote-app-update-panel.test.tsx +0 -205
- package/src/app-updates/remote-app-update-panel.tsx +0 -210
- package/src/app-updates/use-app-update-status.ts +0 -16
- package/src/command-palette/command-palette-ui.tsx +0 -564
- package/src/command-palette/command-palette.ts +0 -242
- package/src/components/access-level-field.test.tsx +0 -32
- package/src/components/access-level-field.tsx +0 -68
- package/src/components/checkbox.tsx +0 -25
- package/src/components/group-switcher.tsx +0 -526
- package/src/components/input-date.tsx +0 -29
- package/src/components/input-number.tsx +0 -83
- package/src/components/input.tsx +0 -25
- package/src/components/inverse-lazy-list.tsx +0 -107
- package/src/components/io-schema-values.tsx +0 -103
- package/src/components/io-schema.tsx +0 -259
- package/src/components/lazy-list.tsx +0 -115
- package/src/components/list-screen.tsx +0 -126
- package/src/components/loading-indicator.tsx +0 -7
- package/src/components/markdown-editor/autolink-plugin.tsx +0 -29
- package/src/components/markdown-editor/editor-inline.tsx +0 -9
- package/src/components/markdown-editor/editor.tsx +0 -158
- package/src/components/markdown-editor/markdown-plugin.tsx +0 -202
- package/src/components/markdown-editor/mention-node.ts +0 -204
- package/src/components/markdown-editor/mentions-plugin.tsx +0 -354
- package/src/components/markdown-editor/move-line-plugin.tsx +0 -186
- package/src/components/markdown-editor/select-line-boundary-plugin.tsx +0 -95
- package/src/components/markdown-editor/theme.ts +0 -46
- package/src/components/markdown-editor/toolbar.tsx +0 -269
- package/src/components/markdown-with-mentions.tsx +0 -198
- package/src/components/message-logs/message-logs.tsx +0 -523
- package/src/components/message-logs/tool-access-approval-card.test.tsx +0 -127
- package/src/components/message-logs/tool-access-approval-card.tsx +0 -178
- package/src/components/messages/avatar.tsx +0 -171
- package/src/components/messages/channel-message-list.tsx +0 -189
- package/src/components/messages/channel-view.tsx +0 -92
- package/src/components/messages/message-compose.tsx +0 -192
- package/src/components/messages/message-display.tsx +0 -231
- package/src/components/messages/thread-message-list.tsx +0 -135
- package/src/components/qr-scanner.tsx +0 -180
- package/src/components/responsive-section-nav.test.tsx +0 -88
- package/src/components/responsive-section-nav.tsx +0 -92
- package/src/components/router.tsx +0 -175
- package/src/components/save-button.tsx +0 -134
- package/src/components/sortable-list.tsx +0 -130
- package/src/components/tabs.tsx +0 -76
- package/src/components/tooltip.tsx +0 -43
- package/src/components/trust-level-badge.tsx +0 -44
- package/src/components/trust-level-dropdown.tsx +0 -136
- package/src/components/typeahead.tsx +0 -357
- package/src/globals-hash.test.ts +0 -19
- package/src/globals.tsx +0 -226
- package/src/hooks/index.ts +0 -8
- package/src/hooks/use-host-contract.ts +0 -75
- package/src/hooks/use-observable-state.test.tsx +0 -101
- package/src/hooks/use-observable-state.ts +0 -29
- package/src/hooks/use-observable.test.tsx +0 -258
- package/src/hooks/use-observable.ts +0 -67
- package/src/hooks/use-on-screen.ts +0 -24
- package/src/hooks/use-promise.ts +0 -34
- package/src/hooks/use-rows.test.tsx +0 -196
- package/src/hooks/use-rows.ts +0 -120
- package/src/hooks/use-subscription.ts +0 -24
- package/src/hooks/use-tool.test.tsx +0 -225
- package/src/hooks/use-tool.ts +0 -116
- package/src/host-shell/host-shell-consumer.test.ts +0 -32
- package/src/host-shell/host-shell-consumer.ts +0 -53
- package/src/index.tsx +0 -42
- package/src/mention-configs.ts +0 -185
- package/src/operator-console/operator-console-state.ts +0 -119
- package/src/operator-console/operator-console.tsx +0 -233
- package/src/peers-services-registration.ts +0 -6
- package/src/root-layout/global-overlays.ts +0 -50
- package/src/root-layout/layout-picker.tsx +0 -47
- package/src/root-layout/layouts/full-screen-layout.tsx +0 -144
- package/src/root-layout/layouts/tabs-with-console-layout.tsx +0 -260
- package/src/root-layout/root-layout-host.test.tsx +0 -108
- package/src/root-layout/root-layout-host.tsx +0 -147
- package/src/root-layout/root-layout-registry.ts +0 -51
- package/src/root-layout/root-layout-state.ts +0 -55
- package/src/root-layout/root-layout.ts +0 -32
- package/src/screens/account/account-screen.test.tsx +0 -65
- package/src/screens/account/account-screen.tsx +0 -942
- package/src/screens/assistants/assistant-config.test.tsx +0 -54
- package/src/screens/assistants/assistant-config.tsx +0 -121
- package/src/screens/assistants/assistant-details.tsx +0 -89
- package/src/screens/assistants/assistant-info.tsx +0 -66
- package/src/screens/assistants/assistant-list.tsx +0 -145
- package/src/screens/assistants/assistant-tools.tsx +0 -82
- package/src/screens/console-logs/console-logs-list.tsx +0 -374
- package/src/screens/console-logs/log-display.tsx +0 -137
- package/src/screens/console-logs/log-filters.tsx +0 -64
- package/src/screens/console-logs/mobile-log-card.tsx +0 -161
- package/src/screens/console-logs/resizable-table-header.tsx +0 -110
- package/src/screens/contacts/contact-details.tsx +0 -123
- package/src/screens/contacts/contact-list.test.tsx +0 -59
- package/src/screens/contacts/contact-list.tsx +0 -286
- package/src/screens/contacts/index.ts +0 -2
- package/src/screens/data-explorer/data-explorer.tsx +0 -633
- package/src/screens/data-explorer/index.ts +0 -6
- package/src/screens/data-explorer/query-executor.tsx +0 -520
- package/src/screens/device-pairing/device-pairing.test.tsx +0 -143
- package/src/screens/device-pairing/device-pairing.tsx +0 -461
- package/src/screens/device-pairing/identity-ipc.ts +0 -25
- package/src/screens/device-pairing/index.ts +0 -2
- package/src/screens/device-pairing/use-device-pairing-state.ts +0 -15
- package/src/screens/devices/devices-list.test.tsx +0 -68
- package/src/screens/devices/devices-list.tsx +0 -365
- package/src/screens/devices/index.ts +0 -1
- package/src/screens/groups/group-details.tsx +0 -160
- package/src/screens/groups/group-invite-panel.tsx +0 -311
- package/src/screens/groups/group-list.test.tsx +0 -44
- package/src/screens/groups/group-list.tsx +0 -317
- package/src/screens/groups/group-members.tsx +0 -343
- package/src/screens/groups/index.ts +0 -3
- package/src/screens/identity/identity-routes.test.ts +0 -70
- package/src/screens/identity/identity-routes.ts +0 -301
- package/src/screens/identity/identity-screen.test.tsx +0 -138
- package/src/screens/identity/identity-screen.tsx +0 -282
- package/src/screens/identity/index.ts +0 -2
- package/src/screens/identity/invite-contact-panel.tsx +0 -45
- package/src/screens/identity/profile-invite.tsx +0 -93
- package/src/screens/invites/accept-invite.test.tsx +0 -115
- package/src/screens/invites/accept-invite.tsx +0 -318
- package/src/screens/invites/activity-view.test.tsx +0 -127
- package/src/screens/invites/activity-view.tsx +0 -162
- package/src/screens/invites/index.ts +0 -6
- package/src/screens/invites/invite-capture.ts +0 -104
- package/src/screens/invites/invite-classify.test.ts +0 -129
- package/src/screens/invites/invite-share.tsx +0 -104
- package/src/screens/invites/invites-ipc.ts +0 -25
- package/src/screens/invites/pending-invites-list.tsx +0 -256
- package/src/screens/network-viewer/connection-troubleshooter.tsx +0 -395
- package/src/screens/network-viewer/cpu-usage-graph.tsx +0 -294
- package/src/screens/network-viewer/device-details-modal.tsx +0 -339
- package/src/screens/network-viewer/group-details-modal.tsx +0 -421
- package/src/screens/network-viewer/index.ts +0 -8
- package/src/screens/network-viewer/network-viewer-ipc.test.ts +0 -72
- package/src/screens/network-viewer/network-viewer-ipc.ts +0 -39
- package/src/screens/network-viewer/network-viewer-section.ts +0 -12
- package/src/screens/network-viewer/network-viewer.section.test.tsx +0 -68
- package/src/screens/network-viewer/network-viewer.tsx +0 -708
- package/src/screens/network-viewer/remote-logs-panel.tsx +0 -190
- package/src/screens/network-viewer/sync-recovery.test.tsx +0 -114
- package/src/screens/network-viewer/sync-recovery.tsx +0 -461
- package/src/screens/network-viewer/usage-graph.tsx +0 -455
- package/src/screens/packages/local-folder-grants-panel.tsx +0 -290
- package/src/screens/packages/local-folders-ipc.ts +0 -28
- package/src/screens/packages/package-details.tsx +0 -166
- package/src/screens/packages/package-helpers.test.ts +0 -57
- package/src/screens/packages/package-helpers.ts +0 -137
- package/src/screens/packages/package-info.tsx +0 -354
- package/src/screens/packages/package-list.tsx +0 -519
- package/src/screens/packages/package-network-panel.tsx +0 -82
- package/src/screens/packages/package-new-local.tsx +0 -100
- package/src/screens/packages/package-runtime-status.test.tsx +0 -58
- package/src/screens/packages/package-runtime-status.tsx +0 -68
- package/src/screens/packages/package-versions.tsx +0 -298
- package/src/screens/packages/packages-ipc.test.ts +0 -47
- package/src/screens/packages/packages-ipc.ts +0 -125
- package/src/screens/peer-types/peer-type-details.tsx +0 -172
- package/src/screens/peer-types/peer-type-list.tsx +0 -64
- package/src/screens/search/global-search.tsx +0 -406
- package/src/screens/settings/color-mode-dropdown.tsx +0 -82
- package/src/screens/settings/settings-page.test.tsx +0 -24
- package/src/screens/settings/settings-page.tsx +0 -426
- package/src/screens/setup-user.tsx +0 -355
- package/src/screens/tools/tool-access-ipc.test.ts +0 -55
- package/src/screens/tools/tool-access-ipc.ts +0 -27
- package/src/screens/tools/tool-catalog-ipc.test.ts +0 -52
- package/src/screens/tools/tool-catalog-ipc.ts +0 -51
- package/src/screens/tools/tool-details.tsx +0 -52
- package/src/screens/tools/tool-info.tsx +0 -45
- package/src/screens/tools/tool-list.tsx +0 -106
- package/src/screens/tools/tool-schema.tsx +0 -44
- package/src/screens/tools/tool-test-details.tsx +0 -89
- package/src/screens/tools/tool-test-list.tsx +0 -73
- package/src/screens/variables/variable-details.tsx +0 -289
- package/src/screens/variables/variable-list.tsx +0 -110
- package/src/screens/welcome-modal.tsx +0 -294
- package/src/screens/workflows/workflow-details.tsx +0 -115
- package/src/screens/workflows/workflow-info.tsx +0 -22
- package/src/screens/workflows/workflow-instructions.tsx +0 -134
- package/src/screens/workflows/workflow-list.tsx +0 -117
- package/src/setupTests.ts +0 -38
- package/src/system-apps/assistants.app.ts +0 -7
- package/src/system-apps/console-logs.app.ts +0 -7
- package/src/system-apps/data-explorer.app.ts +0 -8
- package/src/system-apps/identity.app.ts +0 -9
- package/src/system-apps/index.ts +0 -77
- package/src/system-apps/mobile-settings.app.ts +0 -7
- package/src/system-apps/network-viewer.app.ts +0 -8
- package/src/system-apps/packages.app.ts +0 -7
- package/src/system-apps/search.app.ts +0 -8
- package/src/system-apps/settings.app.ts +0 -7
- package/src/system-apps/threads.app.ts +0 -7
- package/src/system-apps/tools.app.ts +0 -7
- package/src/system-apps/types.app.ts +0 -7
- package/src/system-apps/variables.app.ts +0 -7
- package/src/system-apps/workflows.app.ts +0 -7
- package/src/tabs-layout/network-status-indicator.test.tsx +0 -799
- package/src/tabs-layout/network-status-indicator.tsx +0 -756
- package/src/tabs-layout/tabs-layout.tsx +0 -857
- package/src/tabs-layout/tabs-state.test.ts +0 -152
- package/src/tabs-layout/tabs-state.ts +0 -587
- package/src/tabs-layout/use-network-status.test.tsx +0 -58
- package/src/tabs-layout/use-network-status.ts +0 -68
- package/src/ui-defaults/index.ts +0 -2
- package/src/ui-defaults/list-screen.tsx +0 -94
- package/src/ui-defaults/markdown-field.tsx +0 -87
- package/src/ui-router/routes-loader.ts +0 -193
- package/src/ui-router/ui-loader.test.tsx +0 -108
- package/src/ui-router/ui-loader.tsx +0 -606
- package/src/utils.ts +0 -95
- package/tsconfig.json +0 -18
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { camelCaseToSpaces, deviceVar } from "@peers-app/peers-sdk";
|
|
2
|
-
import { useObservable } from "../../hooks";
|
|
3
|
-
|
|
4
|
-
export type ColorModePreference = "light" | "dark" | "auto";
|
|
5
|
-
export type ColorMode = "light" | "dark";
|
|
6
|
-
|
|
7
|
-
export const colorMode = deviceVar<ColorMode>("colorMode", {
|
|
8
|
-
defaultValue: "dark",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export const colorModePreference = deviceVar<ColorModePreference>("colorModePreference", {
|
|
12
|
-
defaultValue: "dark",
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
function applyColorMode(modePreference?: ColorModePreference): ColorMode {
|
|
16
|
-
if (!modePreference) {
|
|
17
|
-
modePreference = colorModePreference() || "dark";
|
|
18
|
-
} else {
|
|
19
|
-
colorModePreference(modePreference);
|
|
20
|
-
}
|
|
21
|
-
let mode = colorMode();
|
|
22
|
-
if (modePreference === "auto") {
|
|
23
|
-
const isDarkMode = window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
24
|
-
mode = isDarkMode ? "dark" : "light";
|
|
25
|
-
} else {
|
|
26
|
-
mode = modePreference;
|
|
27
|
-
}
|
|
28
|
-
document.documentElement.setAttribute("data-bs-theme", mode);
|
|
29
|
-
if (mode === "light") {
|
|
30
|
-
document.documentElement.style.backgroundColor = "";
|
|
31
|
-
document.body.style.backgroundColor = "initial";
|
|
32
|
-
} else {
|
|
33
|
-
document.documentElement.style.backgroundColor = "rgb(33, 37, 41)";
|
|
34
|
-
document.body.style.backgroundColor = "rgb(33, 37, 41)";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const themeMeta = document.querySelector('meta[name="theme-color"]');
|
|
38
|
-
if (themeMeta) {
|
|
39
|
-
themeMeta.setAttribute("content", mode === "light" ? "#ffffff" : "#212529");
|
|
40
|
-
}
|
|
41
|
-
colorMode(mode);
|
|
42
|
-
colorMode.notifySubscribers();
|
|
43
|
-
|
|
44
|
-
return mode;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
colorModePreference.subscribe((newValue) => applyColorMode(newValue));
|
|
48
|
-
|
|
49
|
-
export const ColorModeDropdown = () => {
|
|
50
|
-
const [modePreference] = useObservable(colorModePreference);
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<div className="dropdown">
|
|
54
|
-
<button
|
|
55
|
-
className="btn btn-secondary dropdown-toggle"
|
|
56
|
-
type="button"
|
|
57
|
-
id="colorModeDropdown"
|
|
58
|
-
data-bs-toggle="dropdown"
|
|
59
|
-
aria-expanded="false"
|
|
60
|
-
>
|
|
61
|
-
Color Mode: {camelCaseToSpaces(modePreference)}
|
|
62
|
-
</button>
|
|
63
|
-
<ul className="dropdown-menu" aria-labelledby="colorModeDropdown">
|
|
64
|
-
<li>
|
|
65
|
-
<button className="dropdown-item" onClick={() => colorModePreference("auto")}>
|
|
66
|
-
Auto {modePreference === "auto" && "✓"}
|
|
67
|
-
</button>
|
|
68
|
-
</li>
|
|
69
|
-
<li>
|
|
70
|
-
<button className="dropdown-item" onClick={() => colorModePreference("light")}>
|
|
71
|
-
Light {modePreference === "light" && "✓"}
|
|
72
|
-
</button>
|
|
73
|
-
</li>
|
|
74
|
-
<li>
|
|
75
|
-
<button className="dropdown-item" onClick={() => colorModePreference("dark")}>
|
|
76
|
-
Dark {modePreference === "dark" && "✓"}
|
|
77
|
-
</button>
|
|
78
|
-
</li>
|
|
79
|
-
</ul>
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { renderToStaticMarkup } from "react-dom/server";
|
|
2
|
-
import { SettingsPage } from "./settings-page";
|
|
3
|
-
|
|
4
|
-
jest.mock("../../components/tooltip", () => ({ Tooltip: () => null }));
|
|
5
|
-
jest.mock("../../hooks", () => ({ usePromise: () => undefined, useObservable: () => [false] }));
|
|
6
|
-
jest.mock("../../components/tabs", () => ({
|
|
7
|
-
Tabs: ({ tabs }: any) => (
|
|
8
|
-
<>
|
|
9
|
-
{tabs.map((tab: any) => (
|
|
10
|
-
<div key={tab.name}>{tab.content}</div>
|
|
11
|
-
))}
|
|
12
|
-
</>
|
|
13
|
-
),
|
|
14
|
-
}));
|
|
15
|
-
jest.mock("../../root-layout/layout-picker", () => ({ LayoutPicker: () => <div>Layout</div> }));
|
|
16
|
-
jest.mock("./color-mode-dropdown", () => ({ ColorModeDropdown: () => <div>Theme</div> }));
|
|
17
|
-
jest.mock("../../globals", () => ({ me: {}, isDesktop: () => false }));
|
|
18
|
-
|
|
19
|
-
test("Settings renders advanced controls without the retired Tasks importer", () => {
|
|
20
|
-
const html = renderToStaticMarkup(<SettingsPage />);
|
|
21
|
-
expect(html).toContain("Advanced Settings");
|
|
22
|
-
expect(html).not.toContain("Import Old Peers");
|
|
23
|
-
expect(html).not.toContain("Dry Run");
|
|
24
|
-
});
|
|
@@ -1,426 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
autoUpdatePeersCore,
|
|
3
|
-
DISPLAY_NAME_MAX_LENGTH,
|
|
4
|
-
getUserContext,
|
|
5
|
-
packagesRootDir,
|
|
6
|
-
reloadPackagesOnPageRefresh,
|
|
7
|
-
rpcServerCalls,
|
|
8
|
-
Users,
|
|
9
|
-
} from "@peers-app/peers-sdk";
|
|
10
|
-
import type React from "react";
|
|
11
|
-
import { useEffect, useState } from "react";
|
|
12
|
-
import { AppUpdatesSettings } from "../../app-updates/app-updates-settings";
|
|
13
|
-
import { Input } from "../../components/input";
|
|
14
|
-
import { Tabs } from "../../components/tabs";
|
|
15
|
-
import { Tooltip } from "../../components/tooltip";
|
|
16
|
-
import * as globals from "../../globals";
|
|
17
|
-
import { useObservable, usePromise } from "../../hooks";
|
|
18
|
-
import { LayoutPicker } from "../../root-layout/layout-picker";
|
|
19
|
-
import { identityTools } from "../device-pairing/identity-ipc";
|
|
20
|
-
import { IDENTITY_ACCOUNT_PATH, IDENTITY_PAIR_PATH } from "../identity/identity-routes";
|
|
21
|
-
import { getNetworkControlConsumer } from "../network-viewer/network-viewer-ipc";
|
|
22
|
-
import { ColorModeDropdown } from "./color-mode-dropdown";
|
|
23
|
-
|
|
24
|
-
type PeersHostWindow = Window & {
|
|
25
|
-
electronAPI?: unknown;
|
|
26
|
-
ReactNativeWebView?: unknown;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const isBrowserPwaHost =
|
|
30
|
-
typeof window !== "undefined" &&
|
|
31
|
-
!(window as PeersHostWindow).electronAPI &&
|
|
32
|
-
!(window as PeersHostWindow).ReactNativeWebView;
|
|
33
|
-
|
|
34
|
-
type PeersGlobal = typeof globalThis & {
|
|
35
|
-
__PEERS_APP_VERSION__?: string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
function getAppVersion() {
|
|
39
|
-
return (globalThis as PeersGlobal).__PEERS_APP_VERSION__ || "unknown";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Application settings organized by user, system, and developer concerns. */
|
|
43
|
-
export const SettingsPage: React.FC = () => {
|
|
44
|
-
return (
|
|
45
|
-
<div className="d-flex flex-column h-100 overflow-hidden" style={{ minHeight: 0 }}>
|
|
46
|
-
<div className="container-fluid flex-grow-1 overflow-auto" style={{ minHeight: 0 }}>
|
|
47
|
-
<Tabs
|
|
48
|
-
tabs={[
|
|
49
|
-
{
|
|
50
|
-
name: "User",
|
|
51
|
-
content: <UserSettingsTab />,
|
|
52
|
-
active: true,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "Appearance",
|
|
56
|
-
content: <AppearanceSettingsTab />,
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: "Updates",
|
|
60
|
-
content: <AppUpdatesSettings />,
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: "Advanced",
|
|
64
|
-
content: <AdvancedSettingsTab />,
|
|
65
|
-
},
|
|
66
|
-
]}
|
|
67
|
-
/>
|
|
68
|
-
</div>
|
|
69
|
-
<footer className="flex-shrink-0 border-top px-3 py-2 small text-muted">
|
|
70
|
-
Peers {getAppVersion()}
|
|
71
|
-
</footer>
|
|
72
|
-
</div>
|
|
73
|
-
);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const UserSettingsTab: React.FC = () => {
|
|
77
|
-
return (
|
|
78
|
-
<>
|
|
79
|
-
<ProfileSection />
|
|
80
|
-
<IdentityAccountSection />
|
|
81
|
-
<AddDeviceSection />
|
|
82
|
-
<LogoutSection />
|
|
83
|
-
</>
|
|
84
|
-
);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const AppearanceSettingsTab: React.FC = () => {
|
|
88
|
-
return (
|
|
89
|
-
<>
|
|
90
|
-
<h5 className="mb-3">Appearance</h5>
|
|
91
|
-
<div className="mb-3">
|
|
92
|
-
<ColorModeDropdown />
|
|
93
|
-
</div>
|
|
94
|
-
<div className="mb-3">
|
|
95
|
-
<LayoutPicker />
|
|
96
|
-
</div>
|
|
97
|
-
</>
|
|
98
|
-
);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const AdvancedSettingsTab: React.FC = () => {
|
|
102
|
-
return (
|
|
103
|
-
<>
|
|
104
|
-
<h5 className="mb-3">Advanced Settings</h5>
|
|
105
|
-
<PackagesRootDirectory />
|
|
106
|
-
<ReloadPackagesOnPageRefresh />
|
|
107
|
-
<AutoUpdatePeersCore />
|
|
108
|
-
<ResetDeviceSyncInfos />
|
|
109
|
-
<DeleteLocalDatabase />
|
|
110
|
-
<CleanupOldDataDir />
|
|
111
|
-
<ResetChangeTracking />
|
|
112
|
-
</>
|
|
113
|
-
);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const ProfileSection: React.FC = () => {
|
|
117
|
-
const me = usePromise(async () => {
|
|
118
|
-
const userContext = await getUserContext();
|
|
119
|
-
return Users(userContext.userDataContext).initDoc(globals.me);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const handleSave = async () => {
|
|
123
|
-
try {
|
|
124
|
-
// Save user profile (only when it actually changed). Pass me.toJS() — the
|
|
125
|
-
// raw doc's fields are non-enumerable getters that get dropped when the
|
|
126
|
-
// signAndSave call is serialized to JSON over the socket to the server.
|
|
127
|
-
if (me?.q()) {
|
|
128
|
-
const userContext = await getUserContext();
|
|
129
|
-
const updatedUser = me.toJS();
|
|
130
|
-
updatedUser.name = updatedUser.name.slice(0, DISPLAY_NAME_MAX_LENGTH);
|
|
131
|
-
await Users(userContext.userDataContext).signAndSave(updatedUser);
|
|
132
|
-
me.qs.name(updatedUser.name);
|
|
133
|
-
me.q(0); // Reset change counter
|
|
134
|
-
}
|
|
135
|
-
} catch (err) {
|
|
136
|
-
console.error("Error saving profile:", err);
|
|
137
|
-
alert(`Failed to save: ${(err as Error).message}`);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
// Subscribe to changes
|
|
142
|
-
useObservable(me?.q);
|
|
143
|
-
|
|
144
|
-
if (!me) {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const hasChanges = !!me.q();
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<>
|
|
152
|
-
<div className="d-flex align-items-center mb-3">
|
|
153
|
-
<h5 className="mb-0 me-auto">Profile</h5>
|
|
154
|
-
<button className="btn btn-primary btn-sm" onClick={handleSave} disabled={!hasChanges}>
|
|
155
|
-
Save
|
|
156
|
-
</button>
|
|
157
|
-
</div>
|
|
158
|
-
|
|
159
|
-
<div className="mb-3">
|
|
160
|
-
<label className="form-label small" htmlFor="settings-display-name">
|
|
161
|
-
Display name
|
|
162
|
-
</label>
|
|
163
|
-
<Input
|
|
164
|
-
id="settings-display-name"
|
|
165
|
-
value={me.qs.name}
|
|
166
|
-
className="form-control"
|
|
167
|
-
maxLength={DISPLAY_NAME_MAX_LENGTH}
|
|
168
|
-
placeholder="Enter your name"
|
|
169
|
-
/>
|
|
170
|
-
</div>
|
|
171
|
-
</>
|
|
172
|
-
);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const IdentityAccountSection: React.FC = () => {
|
|
176
|
-
return (
|
|
177
|
-
<section className="mt-4 pt-3 border-top">
|
|
178
|
-
<h6>Identity account</h6>
|
|
179
|
-
<p className="small text-muted">
|
|
180
|
-
View account identifiers, security keys, this device’s ID, and Peers Services registration.
|
|
181
|
-
</p>
|
|
182
|
-
<a href={`#${IDENTITY_ACCOUNT_PATH}`} className="btn btn-outline-primary">
|
|
183
|
-
View Identity account
|
|
184
|
-
</a>
|
|
185
|
-
</section>
|
|
186
|
-
);
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
const AddDeviceSection: React.FC = () => {
|
|
190
|
-
return (
|
|
191
|
-
<section className="mt-4 pt-3 border-top">
|
|
192
|
-
<h6>Add another device</h6>
|
|
193
|
-
<p className="small text-muted">
|
|
194
|
-
On the new device choose “Sign in from another device”, then type the code it shows on
|
|
195
|
-
Identity → Devices and approve. Account access is transferred only after you approve.
|
|
196
|
-
</p>
|
|
197
|
-
<a href={`#${IDENTITY_PAIR_PATH}`} className="btn btn-outline-primary">
|
|
198
|
-
Add another device
|
|
199
|
-
</a>
|
|
200
|
-
</section>
|
|
201
|
-
);
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
const PackagesRootDirectory: React.FC = () => {
|
|
205
|
-
return (
|
|
206
|
-
<div className="mt-3">
|
|
207
|
-
<small>
|
|
208
|
-
Packages Directory:
|
|
209
|
-
<Tooltip markdownContent={`Changing this will not effect existing packages.`} />
|
|
210
|
-
</small>
|
|
211
|
-
<Input value={packagesRootDir} className="form-control" />
|
|
212
|
-
</div>
|
|
213
|
-
);
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
const ReloadPackagesOnPageRefresh: React.FC = () => {
|
|
217
|
-
useObservable(reloadPackagesOnPageRefresh);
|
|
218
|
-
return (
|
|
219
|
-
<div>
|
|
220
|
-
<label htmlFor="isPrimary" className="form-label small mt-2 me-2">
|
|
221
|
-
Reload Packages on Page Load:
|
|
222
|
-
</label>
|
|
223
|
-
<input
|
|
224
|
-
type="checkbox"
|
|
225
|
-
checked={reloadPackagesOnPageRefresh()}
|
|
226
|
-
onChange={(e) => {
|
|
227
|
-
const checked = (e.target as HTMLInputElement).checked;
|
|
228
|
-
reloadPackagesOnPageRefresh(checked);
|
|
229
|
-
}}
|
|
230
|
-
/>
|
|
231
|
-
<Tooltip
|
|
232
|
-
markdownContent={`Checking this will reload all packages very time the page is loaded. Particularly useful while developing packages.`}
|
|
233
|
-
/>
|
|
234
|
-
</div>
|
|
235
|
-
);
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
const AutoUpdatePeersCore: React.FC = () => {
|
|
239
|
-
useObservable(autoUpdatePeersCore);
|
|
240
|
-
return (
|
|
241
|
-
<div>
|
|
242
|
-
<label htmlFor="autoUpdatePeersCore" className="form-label small mt-2 me-2">
|
|
243
|
-
Auto-update peers-core on startup:
|
|
244
|
-
</label>
|
|
245
|
-
<input
|
|
246
|
-
type="checkbox"
|
|
247
|
-
checked={autoUpdatePeersCore()}
|
|
248
|
-
onChange={(e) => {
|
|
249
|
-
const checked = (e.target as HTMLInputElement).checked;
|
|
250
|
-
autoUpdatePeersCore(checked);
|
|
251
|
-
}}
|
|
252
|
-
/>
|
|
253
|
-
<Tooltip
|
|
254
|
-
markdownContent={`When enabled, the peers-core system package is automatically updated from the bundled version on every app startup. Disable this if you want to manage peers-core manually.`}
|
|
255
|
-
/>
|
|
256
|
-
</div>
|
|
257
|
-
);
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const ResetDeviceSyncInfos: React.FC = () => {
|
|
261
|
-
return (
|
|
262
|
-
<div className="mt-3">
|
|
263
|
-
<button
|
|
264
|
-
className="btn btn-secondary btn-sm ms-2"
|
|
265
|
-
onClick={async () => {
|
|
266
|
-
try {
|
|
267
|
-
const result = await (await getNetworkControlConsumer()).tools.resetDeviceSyncInfo();
|
|
268
|
-
if (!result.success) {
|
|
269
|
-
alert(result.message);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
alert("All device sync info has been reset. Syncing in progress...");
|
|
273
|
-
} catch (err) {
|
|
274
|
-
console.error("Error while resetting all device sync info", err);
|
|
275
|
-
alert(`Failed to reset device sync info: ${(err as Error).message || String(err)}`);
|
|
276
|
-
}
|
|
277
|
-
}}
|
|
278
|
-
>
|
|
279
|
-
Reset All Device Sync Info
|
|
280
|
-
</button>
|
|
281
|
-
</div>
|
|
282
|
-
);
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
const DeleteLocalDatabase: React.FC = () => {
|
|
286
|
-
return (
|
|
287
|
-
<div className="mt-3">
|
|
288
|
-
<button
|
|
289
|
-
className="btn btn-danger btn-sm ms-2"
|
|
290
|
-
onClick={async () => {
|
|
291
|
-
const confirmed = confirm(
|
|
292
|
-
"Are you sure you want to delete the local database for the current group? " +
|
|
293
|
-
"This removes local data for the current personal or group context only. " +
|
|
294
|
-
"The context will be rebuilt by re-syncing from another of your online devices. " +
|
|
295
|
-
"Account credentials and other contexts are not deleted.",
|
|
296
|
-
);
|
|
297
|
-
if (!confirmed) return;
|
|
298
|
-
try {
|
|
299
|
-
await rpcServerCalls.deleteLocalDatabase();
|
|
300
|
-
if (isBrowserPwaHost) {
|
|
301
|
-
window.location.reload();
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
alert("Local database has been deleted. Please restart the app.");
|
|
305
|
-
} catch (err) {
|
|
306
|
-
console.error("Error while deleting local database", err);
|
|
307
|
-
alert(`Failed to delete local database: ${(err as Error).message}`);
|
|
308
|
-
}
|
|
309
|
-
}}
|
|
310
|
-
>
|
|
311
|
-
Delete Local Database
|
|
312
|
-
</button>
|
|
313
|
-
</div>
|
|
314
|
-
);
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
const CleanupOldDataDir: React.FC = () => {
|
|
318
|
-
const [info, setInfo] = useState<{ path: string; sizeMB: number } | null | undefined>(undefined);
|
|
319
|
-
const [busy, setBusy] = useState(false);
|
|
320
|
-
|
|
321
|
-
useEffect(() => {
|
|
322
|
-
rpcServerCalls
|
|
323
|
-
.getOldDataDirInfo()
|
|
324
|
-
.then(setInfo)
|
|
325
|
-
.catch(() => setInfo(null));
|
|
326
|
-
}, []);
|
|
327
|
-
|
|
328
|
-
if (info === undefined || info === null) return null;
|
|
329
|
-
|
|
330
|
-
return (
|
|
331
|
-
<div className="mt-4 pt-3 border-top">
|
|
332
|
-
<h6 className="mb-2">Clean up old data directory</h6>
|
|
333
|
-
<small className="text-muted d-block mb-2">
|
|
334
|
-
Your data has been migrated to <code>~/peers/data</code>. The old copy below can be deleted
|
|
335
|
-
once you've confirmed everything works.
|
|
336
|
-
</small>
|
|
337
|
-
<small className="text-muted d-block mb-2">
|
|
338
|
-
<strong>Old location:</strong> <code>{info.path}</code> ({info.sizeMB} MB)
|
|
339
|
-
</small>
|
|
340
|
-
<button
|
|
341
|
-
className="btn btn-danger btn-sm"
|
|
342
|
-
disabled={busy}
|
|
343
|
-
onClick={async () => {
|
|
344
|
-
const confirmed = confirm(
|
|
345
|
-
`Delete the old data directory? This will free ~${info.sizeMB} MB.\n\n${info.path}\n\nThis cannot be undone.`,
|
|
346
|
-
);
|
|
347
|
-
if (!confirmed) return;
|
|
348
|
-
setBusy(true);
|
|
349
|
-
try {
|
|
350
|
-
await rpcServerCalls.cleanupOldDataDir();
|
|
351
|
-
setInfo(null);
|
|
352
|
-
alert("Old data directory deleted.");
|
|
353
|
-
} catch (err) {
|
|
354
|
-
alert(`Failed to delete: ${(err as Error).message}`);
|
|
355
|
-
} finally {
|
|
356
|
-
setBusy(false);
|
|
357
|
-
}
|
|
358
|
-
}}
|
|
359
|
-
>
|
|
360
|
-
{busy ? "Deleting..." : "Delete Old Data Directory"}
|
|
361
|
-
</button>
|
|
362
|
-
</div>
|
|
363
|
-
);
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
const ResetChangeTracking: React.FC = () => {
|
|
367
|
-
const [busy, setBusy] = useState(false);
|
|
368
|
-
return (
|
|
369
|
-
<div className="mt-4 pt-3 border-top">
|
|
370
|
-
<h6 className="mb-2">Change tracking</h6>
|
|
371
|
-
<small className="text-muted d-block mb-2">
|
|
372
|
-
Clears change history for every personal and group context on this device and rebuilds it
|
|
373
|
-
from current rows. Device sync cursors are cleared; a full resync with peers may follow. Use
|
|
374
|
-
when debugging sync issues.
|
|
375
|
-
</small>
|
|
376
|
-
<button
|
|
377
|
-
className="btn btn-warning btn-sm"
|
|
378
|
-
disabled={busy}
|
|
379
|
-
onClick={async () => {
|
|
380
|
-
const confirmed = window.confirm(
|
|
381
|
-
"Reset Change Tracking will clear all change history and rebuild it from scratch. This may take a while. Continue?",
|
|
382
|
-
);
|
|
383
|
-
if (!confirmed) return;
|
|
384
|
-
setBusy(true);
|
|
385
|
-
try {
|
|
386
|
-
const result = await (await getNetworkControlConsumer()).tools.resetChangeTracking();
|
|
387
|
-
if (!result.success) {
|
|
388
|
-
alert(result.message);
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
await rpcServerCalls.flushDatabases();
|
|
392
|
-
alert("Change tracking reset successfully.");
|
|
393
|
-
} catch (err) {
|
|
394
|
-
console.error("Error while resetting change tracking", err);
|
|
395
|
-
alert(`Failed to reset change tracking: ${(err as Error).message || String(err)}`);
|
|
396
|
-
} finally {
|
|
397
|
-
setBusy(false);
|
|
398
|
-
}
|
|
399
|
-
}}
|
|
400
|
-
>
|
|
401
|
-
{busy ? "Resetting…" : "Reset Change Tracking"}
|
|
402
|
-
</button>
|
|
403
|
-
</div>
|
|
404
|
-
);
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
const LogoutSection: React.FC = () => {
|
|
408
|
-
if (!isBrowserPwaHost) return null;
|
|
409
|
-
return (
|
|
410
|
-
<div className="mt-4 pt-3 border-top">
|
|
411
|
-
<button
|
|
412
|
-
className="btn btn-outline-danger btn-sm"
|
|
413
|
-
onClick={async () => {
|
|
414
|
-
const confirmed = confirm(
|
|
415
|
-
"Are you sure you want to logout? This will clear your credentials from this browser. " +
|
|
416
|
-
"Make sure you have your User ID and Secret Key saved securely, or you will lose access to your account.",
|
|
417
|
-
);
|
|
418
|
-
if (!confirmed) return;
|
|
419
|
-
await (await identityTools()).signOut();
|
|
420
|
-
}}
|
|
421
|
-
>
|
|
422
|
-
Logout
|
|
423
|
-
</button>
|
|
424
|
-
</div>
|
|
425
|
-
);
|
|
426
|
-
};
|