gloomberb 0.10.0 → 0.10.2
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/package.json +8 -1
- package/src/api-client/auth.ts +1 -0
- package/src/api-client/index.test.ts +359 -108
- package/src/api-client/index.ts +24 -13
- package/src/api-client/socket.ts +70 -35
- package/src/api-client/types.ts +1 -1
- package/src/app/language-observer.test.tsx +82 -0
- package/src/app/language-observer.tsx +13 -0
- package/src/app/pane-runtime/index.tsx +2 -2
- package/src/app/pane-runtime/pane-settings-runtime.tsx +2 -2
- package/src/app/pane-runtime/pane-template-runtime.ts +2 -2
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +2 -2
- package/src/app/runtime/broker-import.ts +2 -2
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +2 -2
- package/src/app.tsx +16 -7
- package/src/brokers/account-cache.ts +6 -6
- package/src/brokers/broker-ticker-sync.ts +3 -3
- package/src/brokers/remote-broker-adapter.ts +2 -2
- package/src/brokers/sync-broker-instance.ts +5 -6
- package/src/cli/commands/api.ts +3 -6
- package/src/cli/commands/automation.ts +7 -15
- package/src/cli/commands/market.ts +26 -61
- package/src/cli/commands/overview.ts +34 -45
- package/src/cli/commands/search.ts +25 -27
- package/src/cli/commands/system.ts +27 -57
- package/src/cli/commands/ticker.ts +62 -63
- package/src/cli/context.test.ts +63 -0
- package/src/cli/context.ts +15 -1
- package/src/cli/index.ts +1 -1
- package/src/cli/pane-functions/data.ts +2 -19
- package/src/cli/pane-functions/index.ts +26 -25
- package/src/cli/pane-functions/report.ts +1 -1
- package/src/cli/pane-functions/screenshot.ts +3 -3
- package/src/cli/scoped-context.ts +41 -0
- package/src/components/chart/composite/composite-chart.test.tsx +615 -18
- package/src/components/chart/composite/composite-chart.tsx +179 -79
- package/src/components/chart/composite/format.test.ts +20 -7
- package/src/components/chart/composite/index.ts +0 -21
- package/src/components/chart/composite/interactions.test.ts +90 -3
- package/src/components/chart/composite/interactions.ts +189 -24
- package/src/components/chart/composite/price-series.ts +0 -2
- package/src/components/chart/composite/rasterizer.ts +10 -9
- package/src/components/chart/composite/renderers.test.ts +108 -2
- package/src/components/chart/composite/scene.test.ts +36 -0
- package/src/components/chart/composite/scene.ts +5 -2
- package/src/components/chart/composite/text-renderer.ts +37 -25
- package/src/components/chart/composite/time-axis.test.ts +243 -0
- package/src/components/chart/composite/time-axis.ts +608 -0
- package/src/components/chart/composite/types.ts +12 -1
- package/src/components/chart/core/data.ts +2 -159
- package/src/components/chart/core/date-window.ts +6 -225
- package/src/components/chart/core/palette.ts +1 -12
- package/src/components/chart/core/pointer.ts +0 -142
- package/src/components/chart/core/types.ts +1 -58
- package/src/components/chart/cursor-motion.ts +2 -4
- package/src/components/chart/indicators/types.ts +0 -9
- package/src/components/chart/market-session.ts +0 -11
- package/src/components/chart/native/kitty/protocol.ts +1 -1
- package/src/components/chart/native/raster/layout.ts +3 -10
- package/src/components/chart/static/chart/axis-overlays.test.tsx +64 -0
- package/src/components/chart/static/chart/axis-overlays.tsx +59 -14
- package/src/components/chart/static/chart/surface.tsx +1 -2
- package/src/components/command-bar/action-runtime.ts +2 -2
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/panel/body.tsx +2 -2
- package/src/components/command-bar/panel/index.tsx +11 -9
- package/src/components/command-bar/routes/ticker-search/actions.ts +2 -2
- package/src/components/command-bar/surface/index.tsx +2 -2
- package/src/components/command-bar/workflow/body.tsx +3 -3
- package/src/components/command-bar/workflow/collection-actions.ts +2 -2
- package/src/components/command-bar/workflow/coordinator.ts +2 -2
- package/src/components/command-bar/workflow/field-row.tsx +25 -11
- package/src/components/command-bar/workflow/tickers.ts +2 -2
- package/src/components/feed-data-table/stack-view.test.tsx +28 -36
- package/src/components/feed-data-table/stack-view.tsx +3 -1
- package/src/components/layout/detached-pane-shell.tsx +6 -6
- package/src/components/layout/header.tsx +13 -9
- package/src/components/layout/pane/content.test.tsx +42 -3
- package/src/components/layout/pane/content.tsx +3 -1
- package/src/components/layout/pane/footer/index.test.tsx +45 -2
- package/src/components/layout/pane/footer/registration.tsx +3 -1
- package/src/components/layout/shell/index.tsx +1 -2
- package/src/components/layout/shell/native/surfaces.ts +1 -1
- package/src/components/layout/shell/native/window-state.ts +1 -1
- package/src/components/layout/status-bar.tsx +12 -8
- package/src/components/layout/window-controls.tsx +8 -6
- package/src/components/onboarding/onboarding-wizard.tsx +3 -1
- package/src/components/pane-settings-dialog/desktop.tsx +0 -2
- package/src/components/pane-settings-dialog.tsx +0 -2
- package/src/components/pane-template-wizard.tsx +10 -9
- package/src/components/price-performance.tsx +2 -113
- package/src/components/price-sparkline/model.ts +15 -17
- package/src/components/price-sparkline/view.tsx +8 -7
- package/src/components/speedometer-gauge/desktop.tsx +2 -1
- package/src/components/speedometer-gauge/index.tsx +0 -2
- package/src/components/speedometer-gauge/terminal.tsx +24 -5
- package/src/components/ticker/badge/index.tsx +1 -18
- package/src/components/ui/data-table/opentui/index.tsx +3 -3
- package/src/components/ui/frame.tsx +1 -2
- package/src/components/ui/page-stack-view.test.tsx +126 -0
- package/src/components/ui/page-stack-view.tsx +24 -12
- package/src/components/ui/tabs.tsx +7 -3
- package/src/components/ui/ui.test.tsx +23 -2
- package/src/components/use-external-link-footer.ts +4 -2
- package/src/core/app-service-ports.ts +46 -0
- package/src/core/app-services.test.ts +66 -0
- package/src/core/app-services.ts +17 -15
- package/src/data/config/chart-settings.ts +3 -10
- package/src/data/config/store/index.test.ts +99 -2
- package/src/data/config/store/migrations.ts +278 -0
- package/src/data/config/store/normalize.ts +44 -186
- package/src/data/resource-store.ts +73 -12
- package/src/data/sqlite/cache.test.ts +104 -15
- package/src/i18n/index.test.ts +17 -0
- package/src/i18n/index.ts +23 -6
- package/src/i18n/ja.ts +13 -0
- package/src/i18n/ko.ts +13 -0
- package/src/i18n/react.ts +6 -0
- package/src/i18n/zh-cn.ts +13 -0
- package/src/i18n/zh-tw.ts +13 -0
- package/src/market-data/coordinator/auxiliary.ts +7 -3
- package/src/market-data/coordinator/chart.ts +1 -1
- package/src/market-data/coordinator/index.test.ts +26 -0
- package/src/market-data/coordinator/index.ts +11 -5
- package/src/market-data/coordinator/quotes.ts +4 -40
- package/src/market-data/coordinator/subscriptions.test.ts +89 -1
- package/src/market-data/hooks.tsx +47 -1
- package/src/market-data/market/status.ts +6 -6
- package/src/market-data/performance.ts +1 -1
- package/src/market-data/quote-subscription-target.test.ts +37 -0
- package/src/market-data/quote-subscription-target.ts +60 -0
- package/src/market-data/quotes/freshness.ts +1 -0
- package/src/market-data/quotes/resolution.ts +4 -0
- package/src/market-data/request-types.ts +3 -3
- package/src/news/aggregator.test.ts +97 -1
- package/src/news/aggregator.ts +100 -57
- package/src/news/hooks.test.tsx +64 -0
- package/src/news/hooks.ts +18 -25
- package/src/plugins/builtin/account-management/footer.ts +4 -2
- package/src/plugins/builtin/account-management/pane.tsx +9 -4
- package/src/plugins/builtin/ai/agent-history.ts +11 -7
- package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +0 -5
- package/src/plugins/builtin/ai/ask-ai.test.tsx +3 -4
- package/src/plugins/builtin/ai/index.test.ts +2 -2
- package/src/plugins/builtin/ai/index.tsx +10 -11
- package/src/plugins/builtin/ai/pane-settings.ts +1 -1
- package/src/plugins/builtin/ai/pi/runtime.ts +6 -5
- package/src/plugins/builtin/ai/providers.ts +1 -9
- package/src/plugins/builtin/ai/runner.ts +0 -6
- package/src/plugins/builtin/ai/screener/footer.ts +4 -1
- package/src/plugins/builtin/ai/screener/pane.test.tsx +9 -9
- package/src/plugins/builtin/ai/workspace/model.ts +2 -27
- package/src/plugins/builtin/ai/workspace/pane.tsx +2 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +3 -2
- package/src/plugins/builtin/broker-manager/index.tsx +4 -2
- package/src/plugins/builtin/chart-composer/editor/controller.ts +643 -0
- package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +134 -0
- package/src/plugins/builtin/chart-composer/editor/model.test.ts +85 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +292 -0
- package/src/plugins/builtin/chart-composer/editor/opentui-view.tsx +108 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +65 -947
- package/src/plugins/builtin/chart-composer/index.tsx +0 -6
- package/src/plugins/builtin/chart-composer/pane.tsx +69 -36
- package/src/plugins/builtin/chart-composer/presets.ts +1 -19
- package/src/plugins/builtin/chart-composer/settings.ts +1 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +1 -1
- package/src/plugins/builtin/chat/content/shortcuts.ts +0 -1
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/persistence.ts +2 -0
- package/src/plugins/builtin/chat/controller/session.test.ts +25 -0
- package/src/plugins/builtin/chat/controller/session.ts +2 -0
- package/src/plugins/builtin/chat/controller/state.ts +7 -0
- package/src/plugins/builtin/chat/controller.test.ts +73 -20
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -0
- package/src/plugins/builtin/cloud-tweets/footer.ts +9 -28
- package/src/plugins/builtin/cloud-tweets/pane.tsx +0 -5
- package/src/plugins/builtin/cloud-tweets/table.tsx +12 -17
- package/src/plugins/builtin/correlation/compute.ts +4 -10
- package/src/plugins/builtin/econ/index.tsx +17 -19
- package/src/plugins/builtin/holders/types.ts +0 -1
- package/src/plugins/builtin/insider/index.tsx +6 -31
- package/src/plugins/builtin/news/index.tsx +5 -7
- package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +6 -8
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -11
- package/src/plugins/builtin/news/wire/read-state.test.ts +7 -0
- package/src/plugins/builtin/news/wire/read-state.ts +18 -28
- package/src/plugins/builtin/news/wire/rss/parser.ts +1 -11
- package/src/plugins/builtin/options/footer.test.ts +115 -0
- package/src/plugins/builtin/options/footer.ts +110 -0
- package/src/plugins/builtin/options/live-quotes.test.ts +238 -0
- package/src/plugins/builtin/options/live-quotes.ts +147 -0
- package/src/plugins/builtin/options/view.test.tsx +71 -1
- package/src/plugins/builtin/options/view.tsx +39 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +103 -117
- package/src/plugins/builtin/portfolio-list/cli/render.ts +11 -5
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -135
- package/src/plugins/builtin/portfolio-list/header.tsx +9 -4
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +4 -2
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +24 -52
- package/src/plugins/builtin/sec/filing-content.test.ts +41 -0
- package/src/plugins/builtin/sec/filing-content.ts +94 -0
- package/src/plugins/builtin/sec/index.tsx +21 -104
- package/src/plugins/builtin/sectors/sector-model.ts +1 -7
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -0
- package/src/plugins/builtin/shared/pane-footer.ts +82 -0
- package/src/plugins/builtin/shared/read-state.ts +64 -3
- package/src/plugins/builtin/substack/read-state.ts +16 -41
- package/src/plugins/builtin/thirteenf/pane.tsx +24 -73
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +10 -10
- package/src/plugins/builtin/yield-curve/index.tsx +11 -9
- package/src/plugins/ibkr/dialogs.tsx +3 -3
- package/src/plugins/ibkr/gateway/fundamentals.ts +1 -1
- package/src/plugins/ibkr/gateway/history-requests.ts +2 -2
- package/src/plugins/ibkr/gateway/history.ts +2 -2
- package/src/plugins/ibkr/gateway/selection.ts +2 -2
- package/src/plugins/ibkr/gateway/service/index.ts +2 -2
- package/src/plugins/ibkr/gateway/service/native.ts +2 -2
- package/src/plugins/plugin-persistence.ts +3 -4
- package/src/plugins/prediction-markets/controller/keyboard.ts +1 -1
- package/src/plugins/prediction-markets/controller/live-updates.ts +6 -5
- package/src/plugins/prediction-markets/detail/book.tsx +2 -2
- package/src/plugins/prediction-markets/detail/outcomes.tsx +3 -1
- package/src/plugins/prediction-markets/detail/pane.tsx +3 -1
- package/src/plugins/prediction-markets/detail/trades.tsx +3 -3
- package/src/plugins/registry/context.ts +3 -4
- package/src/plugins/registry/index.ts +5 -6
- package/src/react/input.test.ts +126 -3
- package/src/react/input.ts +120 -1
- package/src/remote/app-host.tsx +2 -13
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +44 -60
- package/src/renderers/electrobun/bun/desktop/capability-bridge.ts +15 -13
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +26 -22
- package/src/renderers/electrobun/bun/desktop/http-fetch.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +11 -6
- package/src/renderers/electrobun/bun/desktop/media.ts +5 -3
- package/src/renderers/electrobun/bun/desktop/plugin-state.ts +21 -22
- package/src/renderers/electrobun/bun/desktop/window-controls.ts +3 -1
- package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +18 -18
- package/src/renderers/electrobun/bun/index.ts +123 -83
- package/src/renderers/electrobun/shared/protocol.ts +146 -7
- package/src/renderers/electrobun/view/app-services.ts +5 -8
- package/src/renderers/electrobun/view/backend-rpc.ts +18 -8
- package/src/renderers/electrobun/view/broker-remote-client.ts +2 -2
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +5 -22
- package/src/renderers/electrobun/view/config-host.ts +1 -1
- package/src/renderers/electrobun/view/context-menu.ts +1 -17
- package/src/renderers/electrobun/view/data-table/index.tsx +0 -1
- package/src/renderers/electrobun/view/data-table/row.tsx +0 -4
- package/src/renderers/electrobun/view/desktop/control-styles.ts +37 -34
- package/src/renderers/electrobun/view/desktop/controls.tsx +36 -33
- package/src/renderers/electrobun/view/desktop/list-view.tsx +15 -12
- package/src/renderers/electrobun/view/desktop/popover.tsx +2 -3
- package/src/renderers/electrobun/view/dialog-host.tsx +2 -3
- package/src/renderers/electrobun/view/fatal-screen.tsx +0 -1
- package/src/renderers/electrobun/view/host/box.tsx +0 -1
- package/src/renderers/electrobun/view/host/chart-surface.tsx +0 -1
- package/src/renderers/electrobun/view/host/input.tsx +0 -1
- package/src/renderers/electrobun/view/host/media-surface.tsx +0 -1
- package/src/renderers/electrobun/view/host/native.ts +0 -1
- package/src/renderers/electrobun/view/host/scroll-box.tsx +0 -1
- package/src/renderers/electrobun/view/host/tabs.tsx +0 -1
- package/src/renderers/electrobun/view/host/text.tsx +0 -1
- package/src/renderers/electrobun/view/http-fetch.ts +3 -11
- package/src/renderers/electrobun/view/input-host.tsx +10 -53
- package/src/renderers/electrobun/view/key-event.ts +0 -1
- package/src/renderers/electrobun/view/main.tsx +3 -3
- package/src/renderers/electrobun/view/native-renderer.ts +0 -1
- package/src/renderers/electrobun/view/native-stubs/backend-rpc.ts +13 -1
- package/src/renderers/electrobun/view/native-stubs/chart/surface-manager.ts +11 -0
- package/src/renderers/electrobun/view/native-stubs/native-stubs.test.ts +47 -0
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +6 -44
- package/src/renderers/electrobun/view/remote/persistence.ts +6 -2
- package/src/renderers/electrobun/view/remote/quote-subscription-registry.test.ts +86 -0
- package/src/renderers/electrobun/view/remote/quote-subscription-registry.ts +72 -0
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +2 -2
- package/src/renderers/electrobun/view/toast-host.tsx +0 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -2
- package/src/renderers/electrobun/view/update-host.ts +1 -1
- package/src/renderers/opentui/chart-surface.tsx +2 -1
- package/src/renderers/opentui/dialog-host.tsx +20 -4
- package/src/renderers/opentui/image/loader.ts +12 -2
- package/src/renderers/opentui/input-host.tsx +7 -49
- package/src/renderers/opentui/start.tsx +2 -0
- package/src/sources/gloomberb-cloud/history-quality.ts +44 -0
- package/src/sources/gloomberb-cloud/index.test.ts +173 -0
- package/src/sources/gloomberb-cloud/index.ts +42 -20
- package/src/sources/gloomberb-cloud/normalizers.ts +9 -3
- package/src/sources/provider-router/cache.ts +1 -1
- package/src/sources/provider-router/document-routes.ts +10 -5
- package/src/sources/provider-router/financials.test.ts +14 -0
- package/src/sources/provider-router/financials.ts +6 -1
- package/src/sources/provider-router/history.test.ts +163 -1
- package/src/sources/provider-router/history.ts +278 -347
- package/src/sources/provider-router/index.ts +2 -2
- package/src/sources/provider-router/routing.test.ts +39 -0
- package/src/sources/provider-router/routing.ts +24 -11
- package/src/sources/provider-router/supplemental.ts +37 -17
- package/src/sources/sec-edgar/content.ts +2 -12
- package/src/sources/sec-edgar.ts +2 -13
- package/src/sources/yahoo-finance/history.ts +2 -2
- package/src/sources/yahoo-finance/options.ts +5 -0
- package/src/sources/yahoo-finance.ts +2 -2
- package/src/state/app/bootstrap.ts +2 -2
- package/src/state/app/context/index.tsx +2 -2
- package/src/state/hooks/quote-streaming.ts +66 -1
- package/src/state/hooks/session-snapshot.ts +2 -2
- package/src/state/selectors.ts +0 -9
- package/src/sync/controller.test.ts +98 -0
- package/src/sync/controller.ts +29 -5
- package/src/sync/react.ts +2 -2
- package/src/sync/types.ts +2 -2
- package/src/theme/colors.test.ts +10 -0
- package/src/theme/colors.ts +75 -78
- package/src/theme/theme-context.test.tsx +67 -0
- package/src/theme/theme-context.tsx +9 -5
- package/src/tickers/open-target.ts +2 -2
- package/src/tickers/search/upsert.ts +2 -2
- package/src/time-series/alignment.ts +0 -7
- package/src/time-series/chart-data.ts +145 -0
- package/src/time-series/date-window.ts +44 -0
- package/src/time-series/history-window.ts +21 -0
- package/src/time-series/hooks.test.ts +59 -0
- package/src/time-series/hooks.ts +33 -12
- package/src/time-series/market-resolution.ts +2 -2
- package/src/time-series/market.ts +1 -1
- package/src/time-series/range.ts +9 -0
- package/src/{components/chart/core → time-series}/resolution.ts +3 -102
- package/src/time-series/resolve.test.ts +203 -1
- package/src/time-series/resolve.ts +96 -18
- package/src/time-series/spec-studies.test.ts +15 -0
- package/src/time-series/spec.ts +2 -2
- package/src/time-series/studies.ts +5 -2
- package/src/time-series/types.ts +3 -1
- package/src/time-series/use-chart-resolution.test.tsx +358 -0
- package/src/time-series/use-chart-resolution.ts +46 -4
- package/src/types/broker.ts +2 -2
- package/src/types/data-provider.ts +3 -3
- package/src/types/financials.ts +12 -0
- package/src/types/plugin.ts +2 -2
- package/src/ui/context-menu.tsx +3 -2
- package/src/ui/dialog.tsx +2 -2
- package/src/utils/html-entities.ts +3 -5
- package/src/utils/main-thread-monitor.ts +1 -1
- package/src/utils/price-history.ts +5 -5
- package/src/version.ts +3 -1
- package/src/components/chart/core/viewport.test.ts +0 -8
- package/src/components/chart/core/viewport.ts +0 -24
- package/src/time-series/index.ts +0 -14
- /package/src/{components/chart/core → time-series}/resolution.test.ts +0 -0
|
@@ -3,7 +3,7 @@ import { useRef, type RefObject } from "react";
|
|
|
3
3
|
import { Box, Input, Text, Textarea, editableTextContextMenuItems, useRendererHost, useUiCapabilities } from "../../../../ui";
|
|
4
4
|
import { TextAttributes, type InputRenderable } from "../../../../ui";
|
|
5
5
|
import { useShortcut } from "../../../../react/input";
|
|
6
|
-
import { blendHex,
|
|
6
|
+
import { blendHex, type ThemeColors } from "../../../../theme/colors";
|
|
7
7
|
import { contrastRatio } from "../../../../theme/color-utils";
|
|
8
8
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
9
9
|
import { isDetailBackNavigationKey } from "../../../../utils/back-navigation";
|
|
@@ -35,8 +35,8 @@ export function WebButton({
|
|
|
35
35
|
width,
|
|
36
36
|
height,
|
|
37
37
|
}: ButtonProps) {
|
|
38
|
-
useThemeColors();
|
|
39
|
-
const palette = buttonPalette({ variant, active, disabled });
|
|
38
|
+
const colors = useThemeColors();
|
|
39
|
+
const palette = buttonPalette({ variant, active, disabled }, colors);
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<Box
|
|
@@ -56,7 +56,7 @@ export function WebButton({
|
|
|
56
56
|
borderRadius: CONTROL_RADIUS,
|
|
57
57
|
paddingLeft: 8,
|
|
58
58
|
paddingRight: 8,
|
|
59
|
-
boxShadow: controlShadow(active),
|
|
59
|
+
boxShadow: controlShadow(active, colors),
|
|
60
60
|
cursor: disabled ? "default" : "pointer",
|
|
61
61
|
}}
|
|
62
62
|
>
|
|
@@ -81,7 +81,7 @@ export function WebButton({
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function checkboxAccentColor(): string {
|
|
84
|
+
function checkboxAccentColor(colors: ThemeColors): string {
|
|
85
85
|
const base = colors.borderFocused;
|
|
86
86
|
const nativeCheckmark = "#ffffff";
|
|
87
87
|
const candidates = [
|
|
@@ -112,15 +112,15 @@ export function WebCheckbox({
|
|
|
112
112
|
description,
|
|
113
113
|
width,
|
|
114
114
|
}: CheckboxProps) {
|
|
115
|
-
useThemeColors();
|
|
115
|
+
const colors = useThemeColors();
|
|
116
116
|
const textColor = disabled
|
|
117
117
|
? colors.textMuted
|
|
118
118
|
: active
|
|
119
119
|
? colors.textBright
|
|
120
120
|
: colors.text;
|
|
121
121
|
const visibleLabel = displayLabel ?? label;
|
|
122
|
-
const accentColor = checkboxAccentColor();
|
|
123
|
-
const borderColor = checked ? accentColor : controlBorderColor(active, false);
|
|
122
|
+
const accentColor = checkboxAccentColor(colors);
|
|
123
|
+
const borderColor = checked ? accentColor : controlBorderColor(active, false, colors);
|
|
124
124
|
return (
|
|
125
125
|
<Box
|
|
126
126
|
flexDirection="column"
|
|
@@ -164,7 +164,7 @@ export function WebCheckbox({
|
|
|
164
164
|
width: 14,
|
|
165
165
|
height: 14,
|
|
166
166
|
margin: 0,
|
|
167
|
-
backgroundColor: checked ? accentColor : panelFill(),
|
|
167
|
+
backgroundColor: checked ? accentColor : panelFill(colors),
|
|
168
168
|
backgroundImage: checked ? checkboxCheckImage() : undefined,
|
|
169
169
|
backgroundPosition: "center",
|
|
170
170
|
backgroundRepeat: "no-repeat",
|
|
@@ -217,12 +217,15 @@ export function WebTextField({
|
|
|
217
217
|
hint,
|
|
218
218
|
type = "text",
|
|
219
219
|
variant = "default",
|
|
220
|
-
backgroundColor
|
|
221
|
-
textColor
|
|
222
|
-
placeholderColor
|
|
220
|
+
backgroundColor,
|
|
221
|
+
textColor,
|
|
222
|
+
placeholderColor,
|
|
223
223
|
onMouseDown,
|
|
224
224
|
}: TextFieldProps) {
|
|
225
|
-
useThemeColors();
|
|
225
|
+
const colors = useThemeColors();
|
|
226
|
+
const resolvedBackgroundColor = backgroundColor ?? colors.bg;
|
|
227
|
+
const resolvedTextColor = textColor ?? colors.text;
|
|
228
|
+
const resolvedPlaceholderColor = placeholderColor ?? colors.textDim;
|
|
226
229
|
const localInputRef = useRef<InputRenderable>(null);
|
|
227
230
|
const resolvedInputRef = inputRef ?? localInputRef;
|
|
228
231
|
const renderer = useRendererHost();
|
|
@@ -234,7 +237,7 @@ export function WebTextField({
|
|
|
234
237
|
{label && (
|
|
235
238
|
<Box height={1}>
|
|
236
239
|
<Text
|
|
237
|
-
fg={focused ? colors.textBright :
|
|
240
|
+
fg={focused ? colors.textBright : resolvedPlaceholderColor}
|
|
238
241
|
style={{ fontWeight: 600 }}
|
|
239
242
|
>
|
|
240
243
|
{label}
|
|
@@ -245,7 +248,7 @@ export function WebTextField({
|
|
|
245
248
|
height={1}
|
|
246
249
|
width={width}
|
|
247
250
|
alignItems="center"
|
|
248
|
-
backgroundColor={plain ? "transparent" :
|
|
251
|
+
backgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
249
252
|
onMouseDown={() => {
|
|
250
253
|
onMouseDown?.();
|
|
251
254
|
resolvedInputRef.current?.focus?.();
|
|
@@ -259,9 +262,9 @@ export function WebTextField({
|
|
|
259
262
|
}}
|
|
260
263
|
data-gloom-role="desktop-text-field"
|
|
261
264
|
style={{
|
|
262
|
-
border: plain ? "none" : `1px solid ${controlBorderColor(focused, false)}`,
|
|
265
|
+
border: plain ? "none" : `1px solid ${controlBorderColor(focused, false, colors)}`,
|
|
263
266
|
borderRadius: plain ? 0 : CONTROL_RADIUS,
|
|
264
|
-
boxShadow: plain ? undefined : controlShadow(focused),
|
|
267
|
+
boxShadow: plain ? undefined : controlShadow(focused, colors),
|
|
265
268
|
overflow: "hidden",
|
|
266
269
|
}}
|
|
267
270
|
>
|
|
@@ -272,11 +275,11 @@ export function WebTextField({
|
|
|
272
275
|
type={type}
|
|
273
276
|
placeholder={placeholder}
|
|
274
277
|
focused={focused}
|
|
275
|
-
textColor={
|
|
276
|
-
focusedTextColor={
|
|
277
|
-
placeholderColor={
|
|
278
|
-
backgroundColor={plain ? "transparent" :
|
|
279
|
-
focusedBackgroundColor={plain ? "transparent" :
|
|
278
|
+
textColor={resolvedTextColor}
|
|
279
|
+
focusedTextColor={resolvedTextColor}
|
|
280
|
+
placeholderColor={resolvedPlaceholderColor}
|
|
281
|
+
backgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
282
|
+
focusedBackgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
280
283
|
cursorColor={colors.textBright}
|
|
281
284
|
style={{
|
|
282
285
|
paddingLeft: plain ? 0 : 10,
|
|
@@ -318,7 +321,7 @@ export function WebMessageComposer({
|
|
|
318
321
|
keyBindings,
|
|
319
322
|
wrapText = false,
|
|
320
323
|
}: MessageComposerProps) {
|
|
321
|
-
useThemeColors();
|
|
324
|
+
const colors = useThemeColors();
|
|
322
325
|
const borderColor = focused
|
|
323
326
|
? blendHex(colors.borderFocused, colors.textBright, 0.24)
|
|
324
327
|
: colors.border;
|
|
@@ -336,7 +339,7 @@ export function WebMessageComposer({
|
|
|
336
339
|
flexDirection="row"
|
|
337
340
|
width={width}
|
|
338
341
|
height={height}
|
|
339
|
-
backgroundColor={panelFill()}
|
|
342
|
+
backgroundColor={panelFill(colors)}
|
|
340
343
|
onMouseDown={requestFocus}
|
|
341
344
|
data-gloom-role="desktop-message-composer"
|
|
342
345
|
style={{
|
|
@@ -378,13 +381,13 @@ export function WebSegmentedControl({
|
|
|
378
381
|
value,
|
|
379
382
|
onChange,
|
|
380
383
|
}: SegmentedControlProps) {
|
|
381
|
-
useThemeColors();
|
|
384
|
+
const colors = useThemeColors();
|
|
382
385
|
return (
|
|
383
386
|
<Box
|
|
384
387
|
flexDirection="row"
|
|
385
|
-
backgroundColor={panelFill()}
|
|
388
|
+
backgroundColor={panelFill(colors)}
|
|
386
389
|
style={{
|
|
387
|
-
border: `1px solid ${panelBorder()}`,
|
|
390
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
388
391
|
borderRadius: CONTROL_RADIUS,
|
|
389
392
|
padding: 2,
|
|
390
393
|
}}
|
|
@@ -428,7 +431,7 @@ export function WebDialogFrame({
|
|
|
428
431
|
footer,
|
|
429
432
|
showTitleDivider = false,
|
|
430
433
|
}: DialogFrameProps) {
|
|
431
|
-
useThemeColors();
|
|
434
|
+
const colors = useThemeColors();
|
|
432
435
|
return (
|
|
433
436
|
<Box flexDirection="column" style={{ padding: 14 }}>
|
|
434
437
|
<Box
|
|
@@ -436,7 +439,7 @@ export function WebDialogFrame({
|
|
|
436
439
|
flexDirection="row"
|
|
437
440
|
alignItems="center"
|
|
438
441
|
style={{
|
|
439
|
-
borderBottom: showTitleDivider ? `1px solid ${panelBorder()}` : "none",
|
|
442
|
+
borderBottom: showTitleDivider ? `1px solid ${panelBorder(colors)}` : "none",
|
|
440
443
|
paddingBottom: showTitleDivider ? 8 : 0,
|
|
441
444
|
marginBottom: showTitleDivider ? 10 : 14,
|
|
442
445
|
}}
|
|
@@ -450,7 +453,7 @@ export function WebDialogFrame({
|
|
|
450
453
|
<Box
|
|
451
454
|
height={1}
|
|
452
455
|
style={{
|
|
453
|
-
borderTop: `1px solid ${panelBorder()}`,
|
|
456
|
+
borderTop: `1px solid ${panelBorder(colors)}`,
|
|
454
457
|
paddingTop: 8,
|
|
455
458
|
marginTop: 10,
|
|
456
459
|
}}
|
|
@@ -474,7 +477,7 @@ export function WebPageStackView({
|
|
|
474
477
|
backLabel = "Back",
|
|
475
478
|
backHint,
|
|
476
479
|
}: PageStackViewProps) {
|
|
477
|
-
useThemeColors();
|
|
480
|
+
const colors = useThemeColors();
|
|
478
481
|
useShortcut((event) => {
|
|
479
482
|
if (!focused || !detailOpen || !isDetailBackNavigationKey(event)) return;
|
|
480
483
|
event.stopPropagation?.();
|
|
@@ -506,7 +509,7 @@ export function WebPageStackView({
|
|
|
506
509
|
height={1}
|
|
507
510
|
flexDirection="row"
|
|
508
511
|
alignItems="center"
|
|
509
|
-
backgroundColor={panelFill()}
|
|
512
|
+
backgroundColor={panelFill(colors)}
|
|
510
513
|
onMouseDown={(event: { preventDefault?: () => void; stopPropagation?: () => void }) => {
|
|
511
514
|
event.preventDefault?.();
|
|
512
515
|
event.stopPropagation?.();
|
|
@@ -514,7 +517,7 @@ export function WebPageStackView({
|
|
|
514
517
|
}}
|
|
515
518
|
data-gloom-interactive="true"
|
|
516
519
|
style={{
|
|
517
|
-
border: `1px solid ${panelBorder()}`,
|
|
520
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
518
521
|
borderRadius: CONTROL_RADIUS,
|
|
519
522
|
paddingInline: 8,
|
|
520
523
|
cursor: "pointer",
|
|
@@ -3,7 +3,7 @@ import { useEffect, useRef, useState, type CSSProperties } from "react";
|
|
|
3
3
|
import { Box, ScrollBox, Text, type ScrollBoxRenderable } from "../../../../ui";
|
|
4
4
|
import { TextAttributes } from "../../../../ui";
|
|
5
5
|
import type { ListRowState, ListViewItem, ListViewProps } from "../../../../components/ui/list-view";
|
|
6
|
-
import { blendHex,
|
|
6
|
+
import { blendHex, hoverBg, type ThemeColors } from "../../../../theme/colors";
|
|
7
7
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
8
8
|
import {
|
|
9
9
|
CONTROL_RADIUS,
|
|
@@ -19,6 +19,7 @@ function DefaultDesktopRow({
|
|
|
19
19
|
item: ListViewItem;
|
|
20
20
|
selected: boolean;
|
|
21
21
|
}) {
|
|
22
|
+
const colors = useThemeColors();
|
|
22
23
|
return (
|
|
23
24
|
<Box
|
|
24
25
|
flexDirection="row"
|
|
@@ -50,7 +51,7 @@ function DefaultDesktopRow({
|
|
|
50
51
|
);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
function listRowStyle(selected: boolean): CSSProperties {
|
|
54
|
+
function listRowStyle(selected: boolean, colors: ThemeColors): CSSProperties {
|
|
54
55
|
return {
|
|
55
56
|
borderRadius: CONTROL_RADIUS,
|
|
56
57
|
border: `1px solid ${selected ? colors.borderFocused : "transparent"}`,
|
|
@@ -85,12 +86,12 @@ export function WebListView({
|
|
|
85
86
|
selectOnHover = false,
|
|
86
87
|
autoScrollToIndex = true,
|
|
87
88
|
}: ListViewProps) {
|
|
88
|
-
useThemeColors();
|
|
89
|
+
const colors = useThemeColors();
|
|
89
90
|
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
|
|
90
91
|
const scrollRef = useRef<ScrollBoxRenderable>(null);
|
|
91
92
|
const baseBg = bgColor ?? colors.bg;
|
|
92
|
-
const activeBg = selectedBgColor ?? selectedPanelFill();
|
|
93
|
-
const rowHoverBg = hoverBgColor ?? hoverBg();
|
|
93
|
+
const activeBg = selectedBgColor ?? selectedPanelFill(colors);
|
|
94
|
+
const rowHoverBg = hoverBgColor ?? hoverBg(colors);
|
|
94
95
|
const selectedItem = selectedIndex >= 0 ? items[selectedIndex] : undefined;
|
|
95
96
|
const activeScrollIndex = scrollIndex ?? selectedIndex;
|
|
96
97
|
const effectiveSurface = surface ?? (scrollable ? "framed" : "plain");
|
|
@@ -102,10 +103,10 @@ export function WebListView({
|
|
|
102
103
|
backgroundColor: "transparent",
|
|
103
104
|
}
|
|
104
105
|
: {
|
|
105
|
-
border: `1px solid ${panelBorder()}`,
|
|
106
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
106
107
|
borderRadius: CONTROL_RADIUS,
|
|
107
108
|
padding: 4,
|
|
108
|
-
backgroundColor: subtlePanelFill(),
|
|
109
|
+
backgroundColor: subtlePanelFill(colors),
|
|
109
110
|
};
|
|
110
111
|
|
|
111
112
|
useEffect(() => {
|
|
@@ -113,7 +114,7 @@ export function WebListView({
|
|
|
113
114
|
const scrollBox = scrollRef.current;
|
|
114
115
|
if (!scrollBox) return;
|
|
115
116
|
const safeIndex = Math.min(activeScrollIndex, items.length - 1);
|
|
116
|
-
const viewportHeight = Math.max(scrollBox.viewport
|
|
117
|
+
const viewportHeight = Math.max(scrollBox.viewport?.height ?? 0, 1);
|
|
117
118
|
const rowTop = safeIndex * rowHeight;
|
|
118
119
|
const rowBottom = rowTop + rowHeight;
|
|
119
120
|
if (rowTop < scrollBox.scrollTop) {
|
|
@@ -127,7 +128,9 @@ export function WebListView({
|
|
|
127
128
|
if (!scrollable) return;
|
|
128
129
|
const scrollBox = scrollRef.current;
|
|
129
130
|
if (!scrollBox) return;
|
|
130
|
-
scrollBox.verticalScrollBar
|
|
131
|
+
if (scrollBox.verticalScrollBar) {
|
|
132
|
+
scrollBox.verticalScrollBar.visible = items.length * rowHeight > (scrollBox.viewport?.height ?? 0);
|
|
133
|
+
}
|
|
131
134
|
}, [items.length, height, flexGrow, rowHeight, scrollable]);
|
|
132
135
|
|
|
133
136
|
const rows = items.length === 0
|
|
@@ -163,7 +166,7 @@ export function WebListView({
|
|
|
163
166
|
onActivate?.(item, index);
|
|
164
167
|
}}
|
|
165
168
|
data-gloom-role="desktop-list-row"
|
|
166
|
-
style={listRowStyle(selected)}
|
|
169
|
+
style={listRowStyle(selected, colors)}
|
|
167
170
|
>
|
|
168
171
|
{renderRow
|
|
169
172
|
? renderRow(item, state, index)
|
|
@@ -196,9 +199,9 @@ export function WebListView({
|
|
|
196
199
|
{showSelectedDescription && selectedItem?.description && (
|
|
197
200
|
<Box
|
|
198
201
|
flexDirection="row"
|
|
199
|
-
backgroundColor={subtlePanelFill()}
|
|
202
|
+
backgroundColor={subtlePanelFill(colors)}
|
|
200
203
|
style={{
|
|
201
|
-
border: `1px solid ${panelBorder()}`,
|
|
204
|
+
border: `1px solid ${panelBorder(colors)}`,
|
|
202
205
|
borderRadius: CONTROL_RADIUS,
|
|
203
206
|
paddingInline: 10,
|
|
204
207
|
}}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
|
|
4
3
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
5
4
|
import { createPortal } from "react-dom";
|
|
6
5
|
import type { HostPopoverProps } from "../../../../ui";
|
|
7
|
-
import { blendHex
|
|
6
|
+
import { blendHex } from "../../../../theme/colors";
|
|
8
7
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
9
8
|
|
|
10
9
|
const VIEWPORT_MARGIN = 10;
|
|
@@ -31,7 +30,7 @@ export function WebPopover({
|
|
|
31
30
|
maxWidth = "min(420px, calc(100vw - 20px))",
|
|
32
31
|
label,
|
|
33
32
|
}: HostPopoverProps) {
|
|
34
|
-
useThemeColors();
|
|
33
|
+
const colors = useThemeColors();
|
|
35
34
|
const anchorRef = useRef<HTMLDivElement | null>(null);
|
|
36
35
|
const popoverRef = useRef<HTMLDivElement | null>(null);
|
|
37
36
|
const [position, setPosition] = useState<PopoverPosition>({ left: 0, top: 0, visible: false });
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
|
4
3
|
import { DialogHostProvider, type DialogApi } from "../../../ui/dialog";
|
|
5
|
-
import { blendHex
|
|
4
|
+
import { blendHex } from "../../../theme/colors";
|
|
6
5
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
7
6
|
|
|
8
7
|
interface DialogState {
|
|
@@ -27,7 +26,7 @@ export function shouldFocusDialogContainer(
|
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
export function WebDialogHostProvider({ children }: { children: ReactNode }) {
|
|
30
|
-
useThemeColors();
|
|
29
|
+
const colors = useThemeColors();
|
|
31
30
|
const [dialogState, setDialogState] = useState<DialogState | null>(null);
|
|
32
31
|
const dialogStateRef = useRef<DialogState | null>(null);
|
|
33
32
|
const dialogElementRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
import { setCloudApiFetchTransport } from "../../../api-client";
|
|
3
2
|
import { setHttpFetchTransport } from "../../../utils/http-transport";
|
|
3
|
+
import type { DesktopHttpFetchResponse } from "../shared/protocol";
|
|
4
4
|
import { backendRequest } from "./backend-rpc";
|
|
5
5
|
|
|
6
|
-
interface ElectrobunHttpFetchResponse {
|
|
7
|
-
status: number;
|
|
8
|
-
statusText: string;
|
|
9
|
-
headers: Record<string, string>;
|
|
10
|
-
setCookie?: string[];
|
|
11
|
-
body: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
6
|
const CLOUD_MARKET_HTTP_TIMEOUT_MS = 10_000;
|
|
15
7
|
|
|
16
8
|
function normalizeHeaders(headers: HeadersInit | undefined): Record<string, string> {
|
|
@@ -81,8 +73,8 @@ async function requestBackendHttpFetch(
|
|
|
81
73
|
url: string,
|
|
82
74
|
init?: RequestInit,
|
|
83
75
|
timeoutMs?: number,
|
|
84
|
-
): Promise<
|
|
85
|
-
return backendRequest
|
|
76
|
+
): Promise<DesktopHttpFetchResponse> {
|
|
77
|
+
return backendRequest("http.fetch", {
|
|
86
78
|
url,
|
|
87
79
|
init: {
|
|
88
80
|
method: init?.method,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
|
-
import { useEffect,
|
|
2
|
+
import { useEffect, useMemo, useSyncExternalStore, type ReactNode } from "react";
|
|
4
3
|
import {
|
|
4
|
+
createShortcutRegistry,
|
|
5
5
|
InputHostProvider,
|
|
6
|
-
|
|
6
|
+
useRegisteredShortcut,
|
|
7
7
|
type InputHost,
|
|
8
8
|
type KeyEventLike,
|
|
9
|
-
type ShortcutOptions,
|
|
10
9
|
} from "../../../react/input";
|
|
11
10
|
import {
|
|
12
11
|
isMouseBackNavigationButton,
|
|
@@ -76,16 +75,6 @@ function toMouseBackKeyEventLike(event: MouseEvent): KeyEventLike {
|
|
|
76
75
|
};
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
interface ShortcutEntry {
|
|
80
|
-
handlerRef: { current: (event: KeyEventLike) => void };
|
|
81
|
-
enabledRef: { current: boolean };
|
|
82
|
-
allowEditableRef: { current: boolean };
|
|
83
|
-
phase: NonNullable<ShortcutOptions["phase"]>;
|
|
84
|
-
order: number;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
let nextShortcutOrder = 1;
|
|
88
|
-
|
|
89
78
|
function subscribeViewport(listener: () => void): () => void {
|
|
90
79
|
window.addEventListener("resize", listener);
|
|
91
80
|
return () => window.removeEventListener("resize", listener);
|
|
@@ -103,30 +92,17 @@ function getViewport() {
|
|
|
103
92
|
}
|
|
104
93
|
|
|
105
94
|
export function WebInputHostProvider({ children }: { children: ReactNode }) {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const dispatchShortcut = (shortcutEvent: KeyEventLike) => {
|
|
109
|
-
for (const phase of ["before", "normal", "after"] as const) {
|
|
110
|
-
if (phase === "after" && (shortcutEvent.defaultPrevented || shortcutEvent.propagationStopped)) break;
|
|
111
|
-
for (const entry of shortcutsRef.current) {
|
|
112
|
-
if (entry.phase !== phase || !entry.enabledRef.current) continue;
|
|
113
|
-
if (!shouldDeliverShortcut(shortcutEvent, entry.allowEditableRef.current)) continue;
|
|
114
|
-
entry.handlerRef.current(shortcutEvent);
|
|
115
|
-
if (shortcutEvent.propagationStopped) break;
|
|
116
|
-
}
|
|
117
|
-
if (shortcutEvent.propagationStopped) break;
|
|
118
|
-
}
|
|
119
|
-
};
|
|
95
|
+
const shortcutRegistry = useMemo(() => createShortcutRegistry(), []);
|
|
120
96
|
|
|
121
97
|
useEffect(() => {
|
|
122
98
|
const onKeyDown = (event: KeyboardEvent) => {
|
|
123
99
|
const shortcutEvent = toKeyEventLike(event);
|
|
124
|
-
|
|
100
|
+
shortcutRegistry.dispatch(shortcutEvent);
|
|
125
101
|
if (shouldConsumeWebAppKeyDown(event)) event.preventDefault();
|
|
126
102
|
};
|
|
127
103
|
window.addEventListener("keydown", onKeyDown);
|
|
128
104
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
129
|
-
}, []);
|
|
105
|
+
}, [shortcutRegistry]);
|
|
130
106
|
|
|
131
107
|
useEffect(() => {
|
|
132
108
|
const preventBrowserBack = (event: MouseEvent) => {
|
|
@@ -138,7 +114,7 @@ export function WebInputHostProvider({ children }: { children: ReactNode }) {
|
|
|
138
114
|
if (!isMouseBackNavigationButton(event.button)) return;
|
|
139
115
|
event.preventDefault();
|
|
140
116
|
event.stopPropagation();
|
|
141
|
-
|
|
117
|
+
shortcutRegistry.dispatch(toMouseBackKeyEventLike(event));
|
|
142
118
|
};
|
|
143
119
|
|
|
144
120
|
window.addEventListener("mousedown", preventBrowserBack, true);
|
|
@@ -149,35 +125,16 @@ export function WebInputHostProvider({ children }: { children: ReactNode }) {
|
|
|
149
125
|
window.removeEventListener("auxclick", preventBrowserBack, true);
|
|
150
126
|
window.removeEventListener("mouseup", onMouseUp, true);
|
|
151
127
|
};
|
|
152
|
-
}, []);
|
|
128
|
+
}, [shortcutRegistry]);
|
|
153
129
|
|
|
154
130
|
const host = useMemo<InputHost>(() => ({
|
|
155
131
|
useShortcut(handler, options) {
|
|
156
|
-
|
|
157
|
-
const enabledRef = useRef(options?.enabled !== false);
|
|
158
|
-
const allowEditableRef = useRef(options?.allowEditable === true);
|
|
159
|
-
handlerRef.current = handler;
|
|
160
|
-
enabledRef.current = options?.enabled !== false;
|
|
161
|
-
allowEditableRef.current = options?.allowEditable === true;
|
|
162
|
-
|
|
163
|
-
useLayoutEffect(() => {
|
|
164
|
-
const entry: ShortcutEntry = {
|
|
165
|
-
handlerRef,
|
|
166
|
-
enabledRef,
|
|
167
|
-
allowEditableRef,
|
|
168
|
-
phase: options?.phase ?? "normal",
|
|
169
|
-
order: nextShortcutOrder++,
|
|
170
|
-
};
|
|
171
|
-
shortcutsRef.current = [...shortcutsRef.current, entry].sort((a, b) => a.order - b.order);
|
|
172
|
-
return () => {
|
|
173
|
-
shortcutsRef.current = shortcutsRef.current.filter((current) => current !== entry);
|
|
174
|
-
};
|
|
175
|
-
}, [options?.phase, options?.scope]);
|
|
132
|
+
useRegisteredShortcut(shortcutRegistry, handler, options);
|
|
176
133
|
},
|
|
177
134
|
useViewport() {
|
|
178
135
|
return useSyncExternalStore(subscribeViewport, getViewport, getViewport);
|
|
179
136
|
},
|
|
180
|
-
}), []);
|
|
137
|
+
}), [shortcutRegistry]);
|
|
181
138
|
|
|
182
139
|
return (
|
|
183
140
|
<InputHostProvider host={host}>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
1
|
/** @jsxImportSource react */
|
|
3
2
|
import { createRoot } from "react-dom/client";
|
|
4
3
|
import { App } from "../../../app";
|
|
@@ -9,7 +8,6 @@ import { measurePerfAsync } from "../../../utils/perf-marks";
|
|
|
9
8
|
import {
|
|
10
9
|
backendRequest,
|
|
11
10
|
initElectrobunBackend,
|
|
12
|
-
requestMainWindowRemoteControl,
|
|
13
11
|
setElectrobunRemoteRequestHandler,
|
|
14
12
|
} from "./backend-rpc";
|
|
15
13
|
import { installElectrobunAiHost } from "./ai-host";
|
|
@@ -30,6 +28,7 @@ import { createApplicationMenuBridge } from "./application-menu-bridge";
|
|
|
30
28
|
import { createDesktopDeepLinkBridge } from "./desktop-deeplink-bridge";
|
|
31
29
|
import { createDesktopWindowBridge } from "./desktop/window/bridge";
|
|
32
30
|
import { prepareDetachedSnapshot } from "./desktop/window/snapshot";
|
|
31
|
+
import { createElectrobunAppServices } from "./app-services";
|
|
33
32
|
|
|
34
33
|
const rootElement = document.getElementById("root");
|
|
35
34
|
if (!rootElement) {
|
|
@@ -100,7 +99,7 @@ async function boot() {
|
|
|
100
99
|
const webUiHost = createWebUiHost(init.desktopPlatform);
|
|
101
100
|
const remoteControlAdapter = init.windowKind === "main"
|
|
102
101
|
? { registerHandler: setElectrobunRemoteRequestHandler }
|
|
103
|
-
:
|
|
102
|
+
: undefined;
|
|
104
103
|
measurePerfAsync("startup.electrobun.root-render", async () => {
|
|
105
104
|
root.render(
|
|
106
105
|
<ElectrobunErrorBoundary>
|
|
@@ -110,6 +109,7 @@ async function boot() {
|
|
|
110
109
|
<WebDialogHostProvider>
|
|
111
110
|
<App
|
|
112
111
|
config={config}
|
|
112
|
+
servicesFactory={createElectrobunAppServices}
|
|
113
113
|
desktopWindowBridge={desktopWindowBridge}
|
|
114
114
|
desktopApplicationMenuBridge={desktopApplicationMenuBridge}
|
|
115
115
|
desktopDeepLinkBridge={desktopDeepLinkBridge}
|
|
@@ -2,6 +2,10 @@ import type {
|
|
|
2
2
|
ApplicationMenuSelectMessage,
|
|
3
3
|
CapabilityEventMessage,
|
|
4
4
|
ContextMenuSelectMessage,
|
|
5
|
+
DesktopBackendRequestArgs,
|
|
6
|
+
DesktopBackendRequestMethod,
|
|
7
|
+
DesktopBackendRequestPayload,
|
|
8
|
+
DesktopBackendRequestResponse,
|
|
5
9
|
DesktopDockPreviewMessage,
|
|
6
10
|
DesktopRestartMessage,
|
|
7
11
|
DesktopStateMessage,
|
|
@@ -16,7 +20,15 @@ function unsubscribe(): () => void {
|
|
|
16
20
|
return () => {};
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
export
|
|
23
|
+
export function backendRequest<T = unknown>(
|
|
24
|
+
method: "capability.invoke",
|
|
25
|
+
payload: DesktopBackendRequestPayload<"capability.invoke">,
|
|
26
|
+
): Promise<T>;
|
|
27
|
+
export function backendRequest<K extends Exclude<DesktopBackendRequestMethod, "capability.invoke">>(
|
|
28
|
+
method: K,
|
|
29
|
+
...args: DesktopBackendRequestArgs<K>
|
|
30
|
+
): Promise<DesktopBackendRequestResponse<K>>;
|
|
31
|
+
export async function backendRequest(): Promise<unknown> {
|
|
20
32
|
throw new Error("Electrobun backend requests are unavailable in the CLI screenshot renderer.");
|
|
21
33
|
}
|
|
22
34
|
|
|
@@ -10,11 +10,22 @@ export interface NativeOccluder {
|
|
|
10
10
|
zIndex: number;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export interface NativeLocalOccluder {
|
|
14
|
+
id: string;
|
|
15
|
+
paneId: string;
|
|
16
|
+
rect: { x: number; y: number; width: number; height: number };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Must expose every public method of the terminal manager: the desktop view
|
|
20
|
+
// bundle swaps this module in, so a missing method is a runtime crash.
|
|
21
|
+
// native-stubs.test.ts guards the drift.
|
|
13
22
|
export class NativeSurfaceManager {
|
|
14
23
|
setWindowState(): void {}
|
|
15
24
|
upsertSurface(): void {}
|
|
16
25
|
updateSurfaceGeometry(): void {}
|
|
17
26
|
removeSurface(): void {}
|
|
27
|
+
upsertLocalOccluder(): void {}
|
|
28
|
+
removeLocalOccluder(): void {}
|
|
18
29
|
destroy(): void {}
|
|
19
30
|
}
|
|
20
31
|
|