gloomberb 0.16.2 → 0.16.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/package.json +4 -1
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +34 -16
- package/src/api-client/index.ts +12 -0
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +88 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +31 -0
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +57 -1
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/app/global-shortcuts.ts +11 -1
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +18 -1
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +70 -0
- package/src/brokers/account-cache.ts +45 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +23 -9
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/command-options.ts +74 -0
- package/src/cli/commands/command-utils.ts +29 -0
- package/src/cli/commands/crypto-hints.ts +12 -4
- package/src/cli/commands/market.ts +524 -148
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +422 -0
- package/src/cli/commands/overview.ts +223 -42
- package/src/cli/commands/search.ts +29 -8
- package/src/cli/commands/system.ts +99 -19
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +200 -73
- package/src/cli/desktop-pane-shot.ts +100 -16
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +7 -4
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/help.ts +40 -7
- package/src/cli/history-rows.ts +187 -15
- package/src/cli/index-roots.ts +51 -0
- package/src/cli/index.ts +21 -13
- package/src/cli/listing-arg.ts +211 -3
- package/src/cli/not-a-ticker.ts +37 -0
- package/src/cli/options.ts +55 -7
- package/src/cli/pane-functions/capabilities.ts +13 -2
- package/src/cli/pane-functions/catalog.ts +13 -2
- package/src/cli/pane-functions/data.ts +36 -5
- package/src/cli/pane-functions/dom.ts +89 -28
- package/src/cli/pane-functions/freshness.ts +205 -26
- package/src/cli/pane-functions/function-help.ts +71 -24
- package/src/cli/pane-functions/headless.ts +168 -35
- package/src/cli/pane-functions/index.ts +12 -2
- package/src/cli/pane-functions/market-session.ts +133 -0
- package/src/cli/pane-functions/options.ts +15 -4
- package/src/cli/pane-functions/report-notices.ts +63 -0
- package/src/cli/pane-functions/report.ts +12 -1
- package/src/cli/pane-functions/resolver.ts +32 -8
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +109 -23
- package/src/cli/registry.ts +8 -4
- package/src/cli/report-tables.ts +460 -0
- package/src/cli/result.ts +63 -16
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/components/chart/composite/composite-chart.tsx +43 -4
- package/src/components/chart/composite/legend.tsx +39 -6
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/routes/root/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- package/src/components/command-bar/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/data-table/export.ts +6 -51
- package/src/components/data-table/view.tsx +31 -10
- package/src/components/layout/floating-pane.tsx +6 -2
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +46 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/header.tsx +2 -1
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +67 -35
- package/src/components/layout/shell/cursor-occlusion.ts +6 -5
- package/src/components/layout/shell/drag/index.ts +16 -7
- package/src/components/layout/shell/drag/live.ts +193 -0
- package/src/components/layout/shell/drag/overlays.tsx +179 -35
- package/src/components/layout/shell/drag/runtime.ts +62 -50
- package/src/components/layout/shell/drag/slide.ts +10 -0
- package/src/components/layout/shell/index.tsx +84 -57
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +28 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +13 -13
- package/src/components/layout/shell/native/surfaces.ts +30 -14
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +461 -180
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/terminal-pointer-runtime.ts +18 -18
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/shell/window-mode/overlays.tsx +12 -4
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +9 -5
- package/src/components/metric-treemap/heat-surface.tsx +27 -8
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- package/src/components/onboarding/onboarding-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-wizard.tsx +49 -40
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +6 -2
- package/src/components/ui/button.tsx +10 -0
- package/src/components/ui/data-table/index.tsx +38 -0
- package/src/components/ui/data-table/types.ts +8 -1
- package/src/components/ui/data-table/visible-range.ts +2 -0
- package/src/components/ui/icon.tsx +11 -2
- package/src/components/ui/index.ts +1 -1
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +37 -3
- package/src/data/json-persistence.ts +17 -3
- package/src/data/json-storage.ts +2 -0
- package/src/data/memory-resource-store.ts +46 -0
- package/src/i18n/es.ts +14 -1
- package/src/i18n/ja.ts +14 -1
- package/src/i18n/ko.ts +14 -1
- package/src/i18n/zh-cn.ts +14 -1
- package/src/i18n/zh-tw.ts +14 -1
- package/src/layout/desks.ts +1 -2
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/quotes.ts +2 -2
- package/src/market-data/market/freshness.ts +156 -11
- package/src/market-data/market/status.ts +40 -0
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/quotes/contributions.ts +19 -2
- package/src/market-data/quotes/freshness.ts +5 -0
- package/src/market-data/quotes/metadata.ts +16 -0
- package/src/market-data/quotes/screener-live-quotes.ts +56 -5
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +1 -0
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +31 -4
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- package/src/plugins/builtin/analytics/pane-model.ts +10 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +3 -1
- package/src/plugins/builtin/analytics/risk-model.ts +37 -8
- package/src/plugins/builtin/analytics/risk-pane.tsx +8 -4
- package/src/plugins/builtin/attention/pane.tsx +1 -1
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/catalysts/detail.tsx +1 -1
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- package/src/plugins/builtin/chat/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +48 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +112 -4
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/manifest.ts +1 -0
- package/src/plugins/builtin/cloud/askg/model.ts +129 -70
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +40 -2
- package/src/plugins/builtin/cloud/askg/tool-display.ts +437 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +360 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/starter-symbols.ts +8 -0
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +666 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +234 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +153 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +168 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/upgrade-dialog.tsx +26 -2
- package/src/plugins/builtin/cloud/upgrade-personalization.ts +57 -0
- package/src/plugins/builtin/cloud/upgrade-tickers.ts +124 -0
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-attention/pane.tsx +1 -1
- package/src/plugins/builtin/company-kpis/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +107 -64
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +21 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/debt-maturities/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/earnings-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/index.tsx +68 -22
- package/src/plugins/builtin/econ-statistics/headless.ts +12 -2
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- package/src/plugins/builtin/fx-matrix/freshness.ts +65 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- package/src/plugins/builtin/gpu/headless.ts +9 -3
- package/src/plugins/builtin/gpu/model.ts +14 -5
- package/src/plugins/builtin/help/index.tsx +1 -0
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +3 -6
- package/src/plugins/builtin/holders/format.ts +31 -1
- package/src/plugins/builtin/holders/headless.ts +32 -6
- package/src/plugins/builtin/holders/pane.tsx +25 -13
- package/src/plugins/builtin/holders/report-header.ts +46 -5
- package/src/plugins/builtin/insider/index.tsx +4 -4
- package/src/plugins/builtin/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +12 -2
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +22 -10
- package/src/plugins/builtin/iv-history/index.tsx +3 -3
- package/src/plugins/builtin/iv-history/model.ts +61 -13
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +42 -18
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +121 -45
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +25 -0
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +24 -0
- package/src/plugins/builtin/macro-day/headless.ts +11 -8
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +11 -6
- package/src/plugins/builtin/macro-day/pane.tsx +12 -8
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +94 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +8 -1
- package/src/plugins/builtin/market-movers/model.ts +71 -17
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- package/src/plugins/builtin/members/pane.tsx +10 -0
- package/src/plugins/builtin/news/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +161 -12
- package/src/plugins/builtin/options-positioning/headless.ts +4 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +73 -17
- package/src/plugins/builtin/options-scenario/headless.ts +71 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +284 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/equity-row.tsx +8 -5
- package/src/plugins/builtin/perps/model.ts +16 -5
- package/src/plugins/builtin/perps/pane.tsx +1 -1
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +344 -32
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +87 -4
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +16 -1
- package/src/plugins/builtin/portfolio-list/allocation.ts +3 -0
- package/src/plugins/builtin/portfolio-list/cached-account.ts +18 -9
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +71 -36
- package/src/plugins/builtin/portfolio-list/cli/render.ts +89 -18
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +2 -16
- package/src/plugins/builtin/portfolio-list/headless.ts +40 -7
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +7 -4
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +22 -4
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +11 -1
- package/src/plugins/builtin/realized-vol/headless.ts +3 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -2
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- package/src/plugins/builtin/research/relative-valuation-model.ts +7 -3
- package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- package/src/plugins/builtin/seasonality/pane.tsx +1 -1
- package/src/plugins/builtin/sec/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/shared/command-tab.ts +51 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +260 -0
- package/src/plugins/builtin/shared/report-freshness.ts +50 -2
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/index.tsx +19 -4
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-volume/index.tsx +1 -10
- package/src/plugins/builtin/short-volume/pane.tsx +1 -1
- package/src/plugins/builtin/social-mentions/pane.tsx +1 -1
- package/src/plugins/builtin/supply-chain/model.ts +1 -1
- package/src/plugins/builtin/themes/pane.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +4 -0
- package/src/plugins/builtin/ticker-detail/financials/model.ts +25 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +63 -25
- package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -4
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +3 -2
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +40 -4
- package/src/plugins/builtin/treasury-auctions/index.tsx +11 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +197 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +124 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +2 -0
- package/src/plugins/builtin/world-venue-map/basemap.ts +18 -0
- package/src/plugins/builtin/world-venue-map/country-labels.ts +78 -0
- package/src/plugins/builtin/world-venue-map/geo-series.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/index.ts +6 -6
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +27 -14
- package/src/plugins/builtin/world-venue-map/layers.ts +68 -10
- package/src/plugins/builtin/world-venue-map/map.tsx +198 -62
- package/src/plugins/builtin/world-venue-map/model.ts +16 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +3 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/labels.chunk.ts +244 -0
- package/src/plugins/builtin/world-venue-map/pane.tsx +16 -10
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +127 -63
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +84 -24
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/react/input.ts +48 -1
- package/src/remote/app-host.tsx +5 -0
- package/src/remote/controller.ts +3 -53
- package/src/remote/matching.ts +69 -0
- package/src/remote/schema.ts +1 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +2 -0
- package/src/renderers/browser/app-services.ts +3 -1
- package/src/renderers/dom/data-table/dom.ts +31 -0
- package/src/renderers/dom/data-table/index.tsx +5 -0
- package/src/renderers/dom/desktop/icons.tsx +14 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/host/box.tsx +113 -17
- package/src/renderers/dom/host/drag-shield.ts +35 -0
- package/src/renderers/dom/host/live-frame.ts +62 -0
- package/src/renderers/dom/host/mouse.ts +8 -1
- package/src/renderers/dom/host/scroll-box.tsx +6 -5
- package/src/renderers/dom/host/tabs.tsx +3 -2
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +26 -5
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +7 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +15 -1
- package/src/renderers/electrobun/shared/protocol.ts +12 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +4 -1
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +101 -5
- package/src/renderers/electrobun/view/host/native.ts +0 -10
- package/src/renderers/electrobun/view/host/window-move.ts +28 -0
- package/src/renderers/electrobun/view/main.tsx +4 -1
- package/src/renderers/electrobun/view/remote/persistence.ts +15 -2
- package/src/renderers/electrobun/view/ui-host.tsx +2 -5
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- package/src/renderers/opentui/ui-host.tsx +7 -1
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +19 -10
- package/src/sources/gloomberb-cloud/normalizers.ts +20 -21
- package/src/sources/listing-symbols.ts +11 -5
- package/src/sources/provider-errors.ts +88 -3
- package/src/sources/provider-router/batches.ts +3 -3
- package/src/sources/provider-router/cached-routes.ts +8 -4
- package/src/sources/provider-router/financial-routes.ts +13 -7
- package/src/sources/provider-router/financials.ts +106 -16
- package/src/sources/provider-router/history.ts +27 -11
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +24 -6
- package/src/sources/sec-edgar.ts +68 -8
- package/src/state/pane-scroll-registry.tsx +67 -35
- package/src/sync/core-contributors.ts +4 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/margin-account.ts +108 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/search/index.ts +22 -2
- package/src/tickers/search/ranking.ts +45 -1
- package/src/tickers/search/types.ts +3 -1
- package/src/time-series/resolution.ts +15 -0
- package/src/time-series/resolve.ts +1 -14
- package/src/types/config.ts +61 -1
- package/src/types/financials.ts +32 -3
- package/src/types/headless.ts +11 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +49 -3
- package/src/ui/host.tsx +16 -0
- package/src/ui/index.tsx +10 -3
- package/src/ui/scroll-box-axis.ts +26 -0
- package/src/utils/cli-output.ts +14 -1
- package/src/utils/currency-units.ts +8 -3
- package/src/utils/depositary-receipt.ts +54 -10
- package/src/utils/display-number.ts +63 -0
- package/src/utils/exchanges.ts +13 -0
- package/src/utils/format.ts +2 -1
- package/src/utils/fundamentals.ts +17 -1
- package/src/utils/fx-market-hours.ts +34 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history-integrity.ts +19 -6
- package/src/utils/price-history.ts +39 -6
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +159 -30
- package/src/utils/sec.ts +38 -34
- package/src/utils/throttled-fetch.ts +51 -22
|
@@ -8,6 +8,7 @@ import { scopedBrokerContractIdentityKey } from "../../../utils/instrument-ident
|
|
|
8
8
|
import { tickerSelectionFromSearchResult } from "../../../tickers/selection";
|
|
9
9
|
import { tickerInstrumentLabel } from "../../../tickers/instrument-label";
|
|
10
10
|
import type { PluginRegistry } from "../../../plugins/registry";
|
|
11
|
+
import { PluginOffError } from "../../../plugins/plugin-off";
|
|
11
12
|
import { formatTickerListInput } from "../../../tickers/list";
|
|
12
13
|
import { PANE_LOCK_SETTING_KEY, setPaneLocked, updatePaneInstance, setPaneSettings } from "../../../pane-settings";
|
|
13
14
|
import { TICKER_RESEARCH_PANE_ID } from "../../../types/config";
|
|
@@ -291,9 +292,10 @@ export async function createPaneTemplateOrThrow(
|
|
|
291
292
|
|
|
292
293
|
const state = deps.getState();
|
|
293
294
|
const pluginId = deps.pluginRegistry.getPaneTemplatePluginId(templateId);
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
// The template's plugin, or the plugin of the pane it opens (CHOKE opens a
|
|
296
|
+
// chart): a pane of a switched-off plugin would be added hidden.
|
|
297
|
+
const disabledOwner = deps.pluginRegistry.getDisabledPaneTemplateOwner(templateId, state.config.disabledPlugins);
|
|
298
|
+
if (disabledOwner) throw new PluginOffError(disabledOwner, getPaneTemplateDisplayLabel(template));
|
|
297
299
|
|
|
298
300
|
const { context, resolvedOptions } = await resolvePaneTemplateOptions(template, options, deps);
|
|
299
301
|
|
|
@@ -1,56 +1,11 @@
|
|
|
1
1
|
import type { DataTableCell, DataTableColumn, DataTableProps } from "../ui";
|
|
2
2
|
import { serializeCsv } from "../../utils/csv";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* decimals, a compact scale (12.3k, 1.20B) and a unit (%, x, bp, USD).
|
|
10
|
-
*/
|
|
11
|
-
const DISPLAY_NUMBER = /^([+-]?)([A-Z]{0,3}[$\u20ac\u00a3\u00a5\u20b9\u20a9\u20bd\u20ba\u20aa\u20ab\u0e3f])?(?=\.?\d)(\d{1,3}(?:,\d{3})+|\d*)(?:\.(\d+))?([kKMBT])?(%|x| ?bps?| [A-Z]{3})?$/;
|
|
12
|
-
|
|
13
|
-
const SCALE_DIGITS: Record<string, number> = { k: 3, K: 3, M: 6, B: 9, T: 12 };
|
|
14
|
-
|
|
15
|
-
interface DisplayNumber {
|
|
16
|
-
/** Plain decimal text: no sign for positives, no commas, no scale letter. */
|
|
17
|
-
number: string;
|
|
18
|
-
/** What the column header has to name once the cells are bare numbers. */
|
|
19
|
-
unit: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const BLANK = "blank";
|
|
23
|
-
|
|
24
|
-
/** Moves the decimal point right without going through a float, so 1.23B is exactly 1230000000. */
|
|
25
|
-
function scaleDecimal(integer: string, fraction: string, digits: number): string {
|
|
26
|
-
const whole = `${integer}${fraction.padEnd(digits, "0").slice(0, digits)}`.replace(/^0+(?=\d)/, "") || "0";
|
|
27
|
-
const rest = fraction.slice(digits);
|
|
28
|
-
return rest ? `${whole}.${rest}` : whole;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function parseDisplayNumber(text: string): DisplayNumber | typeof BLANK | null {
|
|
32
|
-
// A direction arrow beside a signed move repeats the sign.
|
|
33
|
-
const trimmed = text.trim().replace(/\u2212/g, "-").replace(/\s*[\u2191\u2193]$/, "");
|
|
34
|
-
if (!trimmed || PLACEHOLDER.test(trimmed)) return BLANK;
|
|
35
|
-
const match = DISPLAY_NUMBER.exec(trimmed);
|
|
36
|
-
if (!match) return null;
|
|
37
|
-
const [, sign, currency = "", grouped, fraction = "", scale, unitText = ""] = match;
|
|
38
|
-
const integer = grouped!.replace(/,/g, "") || "0";
|
|
39
|
-
const digits = scale ? SCALE_DIGITS[scale]! : 0;
|
|
40
|
-
const magnitude = digits ? scaleDecimal(integer, fraction, digits) : fraction ? `${integer}.${fraction}` : integer;
|
|
41
|
-
const unit = unitText.trim().replace(/^bps$/, "bp");
|
|
42
|
-
return { number: `${sign === "-" ? "-" : ""}${magnitude}`, unit: [currency, unit].filter(Boolean).join(" ") };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Adds the unit the cells dropped, unless the header already names it. */
|
|
46
|
-
function labelWithUnit(label: string, unit: string): string {
|
|
47
|
-
if (!unit) return label;
|
|
48
|
-
// A word unit has to stand alone: "Max" does not name x.
|
|
49
|
-
const named = unit === "bp" ? /\bbps?\b/i.test(label)
|
|
50
|
-
: /^[A-Za-z]+$/.test(unit) ? new RegExp(`\\b${unit}\\b`, "i").test(label)
|
|
51
|
-
: label.includes(unit);
|
|
52
|
-
return named ? label : `${label} (${unit})`;
|
|
53
|
-
}
|
|
3
|
+
import {
|
|
4
|
+
BLANK_DISPLAY as BLANK,
|
|
5
|
+
DISPLAY_PLACEHOLDER as PLACEHOLDER,
|
|
6
|
+
labelWithUnit,
|
|
7
|
+
parseDisplayNumber,
|
|
8
|
+
} from "../../utils/display-number";
|
|
54
9
|
|
|
55
10
|
function rawExportValue(value: NonNullable<DataTableCell["value"]> | null): unknown {
|
|
56
11
|
if (value == null) return "";
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
type RefObject,
|
|
10
10
|
} from "react";
|
|
11
11
|
import type { ScrollBoxRenderable } from "../../ui";
|
|
12
|
-
import { useShortcut } from "../../react/input";
|
|
12
|
+
import { useBeforeShortcut, useShortcut } from "../../react/input";
|
|
13
13
|
import { isPlainKey, isPlainKeyboardEvent } from "../../utils/keyboard";
|
|
14
14
|
import { DataTable, type DataTableColumn, type DataTableProps } from "../ui";
|
|
15
15
|
import { useDataTableSortMenu } from "./sort-menu";
|
|
@@ -42,6 +42,11 @@ function stopTableKey(event: DataTableKeyEvent) {
|
|
|
42
42
|
|
|
43
43
|
const DATA_TABLE_SELECTION_COMMIT_DELAY_MS = 150;
|
|
44
44
|
|
|
45
|
+
/** The keys that step the cursor: a burst of them is what the commit delay collapses. */
|
|
46
|
+
function isCursorStepKey(event: DataTableKeyEvent): boolean {
|
|
47
|
+
return isPlainKey(event, "j", "k", "down", "up", "home", "end", "pageup", "pagedown");
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
/** Shift+Left/Right or Ctrl+Left/Right, with no other modifier. */
|
|
46
51
|
function horizontalScrollDirection(event: DataTableKeyEvent): -1 | 0 | 1 {
|
|
47
52
|
if (event.name !== "left" && event.name !== "right") return 0;
|
|
@@ -108,7 +113,8 @@ export interface DataTableViewProps<
|
|
|
108
113
|
/**
|
|
109
114
|
* Fires immediately as the lightweight visual cursor moves. Expensive detail
|
|
110
115
|
* work and persisted selection belong in selection.onChange, which is
|
|
111
|
-
* coalesced across keyboard repeats
|
|
116
|
+
* coalesced across keyboard repeats and lands before any other key reaches
|
|
117
|
+
* a handler.
|
|
112
118
|
*/
|
|
113
119
|
onCursorChange?: (
|
|
114
120
|
item: T,
|
|
@@ -445,6 +451,24 @@ export function DataTableView<
|
|
|
445
451
|
commitTarget(target, reason);
|
|
446
452
|
}, [clearPendingCommit, commitTarget, getCommitTarget]);
|
|
447
453
|
|
|
454
|
+
const flushPendingCommit = useCallback(() => {
|
|
455
|
+
if (!pendingCommitRef.current) return;
|
|
456
|
+
const target = pendingCommitTargetRef.current;
|
|
457
|
+
clearPendingCommit();
|
|
458
|
+
lastKeyboardCommitAtRef.current = performance.now();
|
|
459
|
+
commitTarget(target, "keyboard");
|
|
460
|
+
}, [clearPendingCommit, commitTarget]);
|
|
461
|
+
const flushPendingCommitRef = useRef(flushPendingCommit);
|
|
462
|
+
flushPendingCommitRef.current = flushPendingCommit;
|
|
463
|
+
|
|
464
|
+
// The delay only coalesces a burst of steps. Any other key acts on the row
|
|
465
|
+
// under the cursor, so a step still waiting commits before the key reaches
|
|
466
|
+
// a handler, which reads the selection the pane holds.
|
|
467
|
+
useBeforeShortcut((event) => {
|
|
468
|
+
if (event.defaultPrevented || event.propagationStopped || isCursorStepKey(event)) return;
|
|
469
|
+
flushPendingCommitRef.current();
|
|
470
|
+
});
|
|
471
|
+
|
|
448
472
|
const scheduleCommitIndex = useCallback((index: number) => {
|
|
449
473
|
if (selection.kind === "none") return;
|
|
450
474
|
const target = getCommitTarget(index);
|
|
@@ -464,14 +488,9 @@ export function DataTableView<
|
|
|
464
488
|
pendingCommitTargetRef.current = target;
|
|
465
489
|
pendingCommitTimerRef.current = setTimeout(() => {
|
|
466
490
|
pendingCommitTimerRef.current = null;
|
|
467
|
-
|
|
468
|
-
const pendingTarget = pendingCommitTargetRef.current;
|
|
469
|
-
pendingCommitTargetRef.current = null;
|
|
470
|
-
clearSelectionScrollTarget();
|
|
471
|
-
lastKeyboardCommitAtRef.current = performance.now();
|
|
472
|
-
commitTarget(pendingTarget, "keyboard");
|
|
491
|
+
flushPendingCommitRef.current();
|
|
473
492
|
}, DATA_TABLE_SELECTION_COMMIT_DELAY_MS);
|
|
474
|
-
}, [
|
|
493
|
+
}, [commitIndexImmediately, getCommitTarget, selection.kind]);
|
|
475
494
|
|
|
476
495
|
const updateCursorIndex = useCallback((
|
|
477
496
|
index: number,
|
|
@@ -672,7 +691,9 @@ export function DataTableView<
|
|
|
672
691
|
event.preventDefault();
|
|
673
692
|
return;
|
|
674
693
|
}
|
|
675
|
-
|
|
694
|
+
// Without a cursor there is nothing for these keys to move, so they stay
|
|
695
|
+
// free for the pane scroll keys to scroll the rows.
|
|
696
|
+
if (tableProps.items.length === 0 || selection.kind === "none") return;
|
|
676
697
|
|
|
677
698
|
if (isPlainKey(event, "j", "down")) {
|
|
678
699
|
stopTableKey(event);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Box, Text, useUiCapabilities } from "../../ui";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
1
|
+
import { Box, Text, useUiCapabilities, type BoxRenderable } from "../../ui";
|
|
2
|
+
import type { ReactNode, RefObject } from "react";
|
|
3
3
|
import { colors, floatingPaneBg } from "../../theme/colors";
|
|
4
4
|
import { PaneBodyFrame, getPaneWindowAttributes } from "./pane/frame";
|
|
5
5
|
import { PaneHeader, type PaneHeaderQuickSetting } from "./pane/header";
|
|
@@ -37,6 +37,8 @@ interface FloatingPaneWrapperProps {
|
|
|
37
37
|
onResizeMouseDrag?: (event: any) => void;
|
|
38
38
|
onResizeMouseDragEnd?: (event: any) => void;
|
|
39
39
|
footer?: CombinedPaneFooter | null;
|
|
40
|
+
/** The pane's frame, which a desktop resize sizes outside React; its header, body and footer stretch with it. */
|
|
41
|
+
frameRef?: RefObject<BoxRenderable | null>;
|
|
40
42
|
children: ReactNode;
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -88,6 +90,7 @@ export function FloatingPaneWrapper({
|
|
|
88
90
|
onResizeMouseDrag,
|
|
89
91
|
onResizeMouseDragEnd,
|
|
90
92
|
footer,
|
|
93
|
+
frameRef,
|
|
91
94
|
children,
|
|
92
95
|
}: FloatingPaneWrapperProps) {
|
|
93
96
|
const { nativePaneChrome } = useUiCapabilities();
|
|
@@ -100,6 +103,7 @@ export function FloatingPaneWrapper({
|
|
|
100
103
|
|
|
101
104
|
return (
|
|
102
105
|
<Box
|
|
106
|
+
ref={frameRef}
|
|
103
107
|
position="absolute"
|
|
104
108
|
top={y}
|
|
105
109
|
left={x}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
import { priceColor } from "../../theme/colors";
|
|
2
|
+
import { priceColor, type ThemeColors } from "../../theme/colors";
|
|
3
3
|
import { useThemeColors } from "../../theme/theme-context";
|
|
4
4
|
import { useAppVisible } from "../../state/app/activity";
|
|
5
5
|
import { useAppSelector } from "../../state/app/context";
|
|
@@ -10,7 +10,8 @@ import { useQuoteStreaming } from "../../state/hooks/quote-streaming";
|
|
|
10
10
|
import type { QuoteSubscriptionTarget } from "../../types/data-provider";
|
|
11
11
|
import { formatPercentRaw } from "../../utils/format";
|
|
12
12
|
import { formatMarketPrice, liveQuoteFormatOptions } from "../../market-data/market/format";
|
|
13
|
-
import {
|
|
13
|
+
import { getSessionMoveDisplay, marketStateColor, marketStateCountdown, marketStateLabel } from "../../market-data/market/status";
|
|
14
|
+
import type { Quote } from "../../types/financials";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* SPY rides the shared feed. The snapshot poll only runs while the feed has
|
|
@@ -76,6 +77,25 @@ export function resolveMarketSummaryFit(options: {
|
|
|
76
77
|
return { showBaseCurrency, showCountdown, showState, showSpy };
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
/**
|
|
81
|
+
* SPY in the header's one slot, beside the market state: the live quote while
|
|
82
|
+
* the regular session trades, and once it is over its close and the move to
|
|
83
|
+
* it, as `ticker SPY` headlines them. While a pre-market or after-hours
|
|
84
|
+
* session is open (PRE-MKT, AFTER-HRS) the slot is that session's print and
|
|
85
|
+
* its move from the close, so the figure is the session the label names.
|
|
86
|
+
*/
|
|
87
|
+
export function spySummary(quote: Quote | null | undefined, colors: ThemeColors): Pick<MarketSummary, "spyColor" | "spyText"> {
|
|
88
|
+
const display = getSessionMoveDisplay(quote);
|
|
89
|
+
// Fixed decimals and a percent slot as wide as "+0.53%", so a streamed tick
|
|
90
|
+
// never slides the market-state label or re-fits the cluster.
|
|
91
|
+
return {
|
|
92
|
+
spyColor: display?.change != null ? priceColor(display.change, colors) : colors.textDim,
|
|
93
|
+
spyText: display
|
|
94
|
+
? `SPY ${formatMarketPrice(display.price, liveQuoteFormatOptions(quote, quote?.currency, "ETF"))} ${formatPercentRaw(display.changePercent).padStart(6)}`
|
|
95
|
+
: "SPY —",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
79
99
|
export function useMarketSummary(): MarketSummary {
|
|
80
100
|
const colors = useThemeColors();
|
|
81
101
|
const appActive = useAppVisible();
|
|
@@ -112,13 +132,7 @@ export function useMarketSummary(): MarketSummary {
|
|
|
112
132
|
return () => { clearInterval(id); };
|
|
113
133
|
}, [appActive]);
|
|
114
134
|
|
|
115
|
-
const
|
|
116
|
-
const spyColor = activeSpyQuote?.change != null ? priceColor(activeSpyQuote.change, colors) : colors.textDim;
|
|
117
|
-
// Fixed decimals and a percent slot as wide as "+0.53%", so a streamed tick
|
|
118
|
-
// never slides the market-state label or re-fits the cluster.
|
|
119
|
-
const spyText = activeSpyQuote
|
|
120
|
-
? `SPY ${formatMarketPrice(activeSpyQuote.price, liveQuoteFormatOptions(spyQuote, spyQuote?.currency, "ETF"))} ${formatPercentRaw(activeSpyQuote.changePercent).padStart(6)}`
|
|
121
|
-
: "SPY —";
|
|
135
|
+
const { spyColor, spyText } = spySummary(spyQuote, colors);
|
|
122
136
|
|
|
123
137
|
const mktCountdown = mktState ? marketStateCountdown(mktState, now) : null;
|
|
124
138
|
const marketLabelShort = mktState ? t(marketStateLabel(mktState)) : "";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { memo, Profiler, useCallback, type ReactNode } from "react";
|
|
1
|
+
import { memo, Profiler, useCallback, useMemo, type ReactNode } from "react";
|
|
2
2
|
import { useAppLanguage } from "../../../i18n/react";
|
|
3
3
|
import { isPerfTraceEnabled, recordPerfSample } from "../../../utils/perf-marks";
|
|
4
4
|
import { PaneInViewProvider } from "../../../state/app/activity";
|
|
5
5
|
import { PaneInstanceProvider } from "../../../state/app/context";
|
|
6
|
+
import { RemoteUiPaneScope } from "../../../remote/semantic-tree";
|
|
6
7
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
7
8
|
import { PaneKeyboardScrollController } from "../../../state/pane-scroll-registry";
|
|
8
9
|
import type { PaneDef } from "../../../types/plugin";
|
|
@@ -41,6 +42,13 @@ interface PaneContentProps {
|
|
|
41
42
|
onClose?: (paneId: string) => void;
|
|
42
43
|
/** Takes the pane out of its layout; the failure card offers it. Keep it stable: the content is memoized. */
|
|
43
44
|
closePane?: (paneId: string) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Desktop: lays the content out at `width` by `height` instead of filling
|
|
47
|
+
* the pane, while a resize sizes the pane's frame ahead of it. The content,
|
|
48
|
+
* and whatever measures it, then lays out again only when it renders at a
|
|
49
|
+
* new size.
|
|
50
|
+
*/
|
|
51
|
+
pinned?: boolean;
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
export const PaneContent = memo(function PaneContent({
|
|
@@ -54,44 +62,53 @@ export const PaneContent = memo(function PaneContent({
|
|
|
54
62
|
inView = true,
|
|
55
63
|
onClose,
|
|
56
64
|
closePane,
|
|
65
|
+
pinned = false,
|
|
57
66
|
}: PaneContentProps) {
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
// The pane reads text and colors while it renders, so either redraws it.
|
|
68
|
+
const language = useAppLanguage();
|
|
69
|
+
const theme = useThemeColors();
|
|
60
70
|
const close = useCallback(() => {
|
|
61
71
|
onClose?.(paneId);
|
|
62
72
|
}, [onClose, paneId]);
|
|
63
73
|
const closeFailedPane = useCallback(() => {
|
|
64
74
|
closePane?.(paneId);
|
|
65
75
|
}, [closePane, paneId]);
|
|
76
|
+
// Built again only when what the pane is given changes: pinning or
|
|
77
|
+
// unpinning the content box does not render the pane.
|
|
78
|
+
const body = useMemo(() => (
|
|
79
|
+
<PaneErrorBoundary paneType={paneType} title={title} onClose={closePane ? closeFailedPane : undefined}>
|
|
80
|
+
<PaneRenderTrace paneId={paneId} paneType={paneType}>
|
|
81
|
+
<Component
|
|
82
|
+
paneId={paneId}
|
|
83
|
+
paneType={paneType}
|
|
84
|
+
focused={focused}
|
|
85
|
+
width={width}
|
|
86
|
+
height={height}
|
|
87
|
+
close={onClose ? close : undefined}
|
|
88
|
+
/>
|
|
89
|
+
</PaneRenderTrace>
|
|
90
|
+
</PaneErrorBoundary>
|
|
91
|
+
), [Component, close, closeFailedPane, closePane, focused, height, language, onClose, paneId, paneType, theme, title, width]);
|
|
66
92
|
|
|
67
93
|
return (
|
|
68
94
|
<PaneInstanceProvider paneId={paneId}>
|
|
69
|
-
<
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
focused={focused}
|
|
87
|
-
width={width}
|
|
88
|
-
height={height}
|
|
89
|
-
close={onClose ? close : undefined}
|
|
90
|
-
/>
|
|
91
|
-
</PaneRenderTrace>
|
|
92
|
-
</PaneErrorBoundary>
|
|
93
|
-
</Box>
|
|
94
|
-
</PaneInViewProvider>
|
|
95
|
+
<RemoteUiPaneScope paneId={paneId}>
|
|
96
|
+
<PaneInViewProvider value={inView}>
|
|
97
|
+
<PaneKeyboardScrollController paneId={paneId} focused={focused} />
|
|
98
|
+
<Box
|
|
99
|
+
flexDirection="column"
|
|
100
|
+
{...(pinned
|
|
101
|
+
? { width, height, flexGrow: 0, flexShrink: 0 }
|
|
102
|
+
: { flexGrow: 1, flexShrink: 1, flexBasis: 0 })}
|
|
103
|
+
minWidth={0}
|
|
104
|
+
minHeight={0}
|
|
105
|
+
overflow="hidden"
|
|
106
|
+
data-gloom-role="pane-content"
|
|
107
|
+
>
|
|
108
|
+
{body}
|
|
109
|
+
</Box>
|
|
110
|
+
</PaneInViewProvider>
|
|
111
|
+
</RemoteUiPaneScope>
|
|
95
112
|
</PaneInstanceProvider>
|
|
96
113
|
);
|
|
97
114
|
});
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
import { getDockedPaneIds } from "../../../layout/pane-manager";
|
|
2
2
|
import type { PluginRegistry } from "../../../plugins/registry";
|
|
3
3
|
import { findPaneInstance, type LayoutConfig } from "../../../types/config";
|
|
4
|
-
|
|
5
|
-
function disabledPaneTypes(pluginRegistry: PluginRegistry, disabledPlugins: readonly string[]): Set<string> {
|
|
6
|
-
const paneTypes = new Set<string>();
|
|
7
|
-
for (const pluginId of disabledPlugins) {
|
|
8
|
-
for (const paneId of pluginRegistry.getPluginPaneIds(pluginId)) {
|
|
9
|
-
paneTypes.add(paneId);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
return paneTypes;
|
|
13
|
-
}
|
|
4
|
+
import { collectDisabledPaneIds } from "../shell/visible-layout";
|
|
14
5
|
|
|
15
6
|
export function getVisiblePaneCycleOrder(
|
|
16
7
|
layout: LayoutConfig,
|
|
17
8
|
pluginRegistry: PluginRegistry,
|
|
18
9
|
disabledPlugins: readonly string[],
|
|
19
10
|
): string[] {
|
|
20
|
-
const disabledTypes =
|
|
11
|
+
const disabledTypes = collectDisabledPaneIds(pluginRegistry, disabledPlugins);
|
|
21
12
|
const isVisiblePane = (instanceId: string) => {
|
|
22
13
|
const instance = findPaneInstance(layout, instanceId);
|
|
23
14
|
return !!instance
|
|
@@ -174,10 +174,11 @@ export function PaneHeader({
|
|
|
174
174
|
|
|
175
175
|
if (nativePaneChrome) {
|
|
176
176
|
const ruleColor = visuallyFocused ? colors.borderFocused : colors.border;
|
|
177
|
+
// No width of its own: it stretches across its pane, so it follows a
|
|
178
|
+
// frame a resize sizes outside React.
|
|
177
179
|
return (
|
|
178
180
|
<Box
|
|
179
181
|
height={titleBar?.rows ?? nativePaneHeaderRows()}
|
|
180
|
-
width={width}
|
|
181
182
|
backgroundColor={backgroundColor}
|
|
182
183
|
flexDirection="row"
|
|
183
184
|
data-gloom-role="pane-header"
|
|
@@ -13,7 +13,7 @@ import { canFollowTickerSource, isTickerLinkPeer } from "../../../layout/ticker-
|
|
|
13
13
|
const LINK_GLYPH = "\u29c9";
|
|
14
14
|
|
|
15
15
|
/** The title without the link suffix. */
|
|
16
|
-
function getBasePaneDisplayTitle(
|
|
16
|
+
export function getBasePaneDisplayTitle(
|
|
17
17
|
state: Pick<AppState, "config" | "paneState">,
|
|
18
18
|
instance: PaneInstanceConfig,
|
|
19
19
|
paneDef: PaneDef,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useAppSelector } from "../../state/app/context";
|
|
2
|
+
import { useUiCapabilities } from "../../ui";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Which app chrome is on screen. Presentation mode (`presentationMode` in the
|
|
6
|
+
* config) leaves the window to the panes: no header (the command prompt and
|
|
7
|
+
* the market summary) and no status bar (layout tabs, version, account and
|
|
8
|
+
* feedback). The header comes back while the command bar is open, as its
|
|
9
|
+
* prompt is where the command bar types, and stays in the desktop app, where
|
|
10
|
+
* it is the window's own title bar with its window controls.
|
|
11
|
+
*/
|
|
12
|
+
export function useAppChromeShown(): { header: boolean; statusBar: boolean } {
|
|
13
|
+
const { titleBarOverlay = false, nativeWindowChrome = true } = useUiCapabilities();
|
|
14
|
+
const windowTitleBar = titleBarOverlay && nativeWindowChrome;
|
|
15
|
+
const presentation = useAppSelector((state) => state.config.presentationMode === true);
|
|
16
|
+
const commandBarOpen = useAppSelector((state) => state.commandBarOpen);
|
|
17
|
+
const statusBarVisible = useAppSelector((state) => state.statusBarVisible);
|
|
18
|
+
return {
|
|
19
|
+
header: !presentation || commandBarOpen || windowTitleBar,
|
|
20
|
+
statusBar: statusBarVisible && !presentation,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
1
|
+
import { useCallback, useRef } from "react";
|
|
2
2
|
import {
|
|
3
3
|
floatAtRect,
|
|
4
4
|
getRememberedFloatingRect,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type DockGeometryOptions,
|
|
8
8
|
type DockLeafLayout,
|
|
9
9
|
type DropTarget,
|
|
10
|
+
type FloatingRect,
|
|
10
11
|
type LayoutBounds,
|
|
11
12
|
type ResolvedPane,
|
|
12
13
|
} from "../../../layout/pane-manager";
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
resolveHoverOverlay,
|
|
24
25
|
resolvePaneDragFloatingRect,
|
|
25
26
|
resolveSnapGuide,
|
|
27
|
+
type DragPreview,
|
|
26
28
|
} from "./drag";
|
|
27
29
|
import type { ShellDragRuntimeState, ShellMouseEvent } from "./drag/runtime";
|
|
28
30
|
import type { WindowEditState } from "../window-edit/mode";
|
|
@@ -65,37 +67,74 @@ export function useShellActiveDrag({
|
|
|
65
67
|
windowMode,
|
|
66
68
|
}: UseShellActiveDragOptions) {
|
|
67
69
|
const {
|
|
68
|
-
|
|
69
|
-
dockPreviewRef,
|
|
70
|
+
cancelActiveDrag,
|
|
70
71
|
dragRef,
|
|
71
|
-
|
|
72
|
+
live,
|
|
73
|
+
setHoverTarget,
|
|
72
74
|
updateDividerPreview,
|
|
73
75
|
updateDockPreview,
|
|
74
76
|
updateDragFloatingRect,
|
|
75
77
|
} = dragRuntime;
|
|
78
|
+
// What one drag keeps between moves: a docked pane's floating size, and the
|
|
79
|
+
// last drop it simulated, so a move over the same target computes nothing.
|
|
80
|
+
const memoRef = useRef<{
|
|
81
|
+
drag: unknown;
|
|
82
|
+
baseRect: FloatingRect | null;
|
|
83
|
+
dropKey: string | null;
|
|
84
|
+
drop: DragPreview | null;
|
|
85
|
+
}>({ drag: null, baseRect: null, dropKey: null, drop: null });
|
|
76
86
|
|
|
77
87
|
return useCallback((event: ShellMouseEvent) => {
|
|
78
88
|
const shellY = event.y - appHeaderHeight;
|
|
79
89
|
const preciseX = event.preciseX ?? event.x;
|
|
80
90
|
const preciseShellY = (event.preciseY ?? event.y) - appHeaderHeight;
|
|
91
|
+
// Drawn a moment ahead where the host predicts the pointer; hit tests and
|
|
92
|
+
// the release use where it is.
|
|
93
|
+
const drawX = event.predictedX ?? preciseX;
|
|
94
|
+
const drawShellY = event.predictedY != null ? event.predictedY - appHeaderHeight : preciseShellY;
|
|
81
95
|
const hitX = precisePointer ? preciseX : event.x;
|
|
82
96
|
const hitShellY = precisePointer ? preciseShellY : shellY;
|
|
83
97
|
const dragThreshold = precisePointer ? PRECISE_PANE_DRAG_THRESHOLD : PANE_DRAG_THRESHOLD;
|
|
84
98
|
const drag = dragRef.current;
|
|
85
99
|
if (!drag) return;
|
|
86
100
|
const baseLayout = windowMode?.previewLayout ?? visibleLayout;
|
|
101
|
+
const memo = memoRef.current;
|
|
102
|
+
if (memo.drag !== drag) {
|
|
103
|
+
memo.drag = drag;
|
|
104
|
+
memo.baseRect = null;
|
|
105
|
+
memo.dropKey = null;
|
|
106
|
+
memo.drop = null;
|
|
107
|
+
}
|
|
108
|
+
const dividerRatioAt = (x: number, y: number) => {
|
|
109
|
+
if (drag.type !== "divider") return 0;
|
|
110
|
+
const total = drag.axis === "horizontal" ? drag.bounds.width : drag.bounds.height;
|
|
111
|
+
const delta = drag.axis === "horizontal" ? x - drag.startX : y - drag.startY;
|
|
112
|
+
return Math.max(0.1, Math.min(0.9, drag.startRatio + (delta / Math.max(1, total))));
|
|
113
|
+
};
|
|
114
|
+
const dragBaseRect = () => {
|
|
115
|
+
if (drag.type !== "pane-drag") return null;
|
|
116
|
+
if (drag.mode === "floating") return drag.origRect;
|
|
117
|
+
memo.baseRect ??= getRememberedFloatingRect(baseLayout, drag.paneId, width, contentHeight, paneMap.get(drag.paneId)?.def);
|
|
118
|
+
return memo.baseRect;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (event.type === "drag-cancel") {
|
|
122
|
+
// The window lost focus or the system took the pointer: put everything back.
|
|
123
|
+
cancelActiveDrag();
|
|
124
|
+
event.stopPropagation();
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
87
128
|
|
|
88
129
|
if (event.type === "drag") {
|
|
89
130
|
if (drag.type === "divider") {
|
|
90
|
-
const
|
|
91
|
-
const delta = drag.axis === "horizontal" ? preciseX - drag.startX : preciseShellY - drag.startY;
|
|
92
|
-
const nextRatio = Math.max(0.1, Math.min(0.9, drag.startRatio + (delta / Math.max(1, total))));
|
|
131
|
+
const nextRatio = dividerRatioAt(drawX, drawShellY);
|
|
93
132
|
const nextRect = resolveDividerPreviewRect(drag.axis, drag.bounds, nextRatio, nativePaneChrome === true);
|
|
94
133
|
updateDividerPreview({ pathKey: drag.path.join("."), rect: nextRect, ratio: nextRatio });
|
|
95
134
|
} else if (drag.type === "pane-drag") {
|
|
96
135
|
if (!isMeaningfulPaneDrag(drag.startX, drag.startY, preciseX, preciseShellY, dragThreshold)) {
|
|
97
136
|
updateDockPreview(null);
|
|
98
|
-
|
|
137
|
+
setHoverTarget(null);
|
|
99
138
|
if (drag.mode === "floating") {
|
|
100
139
|
updateDragFloatingRect({ paneId: drag.paneId, rect: drag.origRect });
|
|
101
140
|
}
|
|
@@ -104,25 +143,22 @@ export function useShellActiveDrag({
|
|
|
104
143
|
return;
|
|
105
144
|
}
|
|
106
145
|
|
|
107
|
-
const
|
|
108
|
-
const baseRect = drag.mode === "docked"
|
|
109
|
-
? getRememberedFloatingRect(baseLayout, drag.paneId, width, contentHeight, pane?.def)
|
|
110
|
-
: drag.origRect;
|
|
111
|
-
const nextRect = resolvePaneDragFloatingRect(drag, baseRect, preciseX, preciseShellY, width, contentHeight);
|
|
146
|
+
const nextRect = resolvePaneDragFloatingRect(drag, dragBaseRect()!, drawX, drawShellY, width, contentHeight);
|
|
112
147
|
updateDragFloatingRect({ paneId: drag.paneId, rect: nextRect });
|
|
113
|
-
setDragCursor({ x: hitX, y: hitShellY });
|
|
114
148
|
|
|
115
149
|
const hoveredOverlay = resolveHoverOverlay(hitX, hitShellY, dockLeafLayouts, drag.paneId);
|
|
150
|
+
setHoverTarget(hoveredOverlay?.targetId ?? null);
|
|
116
151
|
if (hoveredOverlay) {
|
|
117
152
|
const hoveredCell = hoveredOverlay.cells.find((cell) => pointInRect(cell.rect, hitX, hitShellY));
|
|
118
153
|
if (hoveredCell) {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
154
|
+
const dropKey = `${hoveredOverlay.targetId}:${hoveredCell.position}`;
|
|
155
|
+
if (memo.dropKey !== dropKey) {
|
|
156
|
+
const target: DropTarget = { kind: "leaf", targetId: hoveredOverlay.targetId, position: hoveredCell.position };
|
|
157
|
+
const simulation = simulateDrop(baseLayout, drag.paneId, target, bounds, dockGeometryOptions);
|
|
158
|
+
memo.dropKey = dropKey;
|
|
159
|
+
memo.drop = simulation.previewRect ? { kind: "dock", target, rect: simulation.previewRect } : null;
|
|
125
160
|
}
|
|
161
|
+
updateDockPreview(memo.drop);
|
|
126
162
|
} else {
|
|
127
163
|
updateDockPreview(null);
|
|
128
164
|
}
|
|
@@ -143,9 +179,8 @@ export function useShellActiveDrag({
|
|
|
143
179
|
|
|
144
180
|
if (event.type === "up" || event.type === "drag-end") {
|
|
145
181
|
if (drag.type === "divider") {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const nextLayout = resizeSplitAtPath(baseLayout, drag.path, preview.ratio);
|
|
182
|
+
if (live.get().divider) {
|
|
183
|
+
const nextLayout = resizeSplitAtPath(baseLayout, drag.path, dividerRatioAt(preciseX, preciseShellY));
|
|
149
184
|
if (windowMode) {
|
|
150
185
|
updateWindowModePreviewLayout(nextLayout);
|
|
151
186
|
} else {
|
|
@@ -157,15 +192,11 @@ export function useShellActiveDrag({
|
|
|
157
192
|
const movedEnough = isMeaningfulPaneDrag(drag.startX, drag.startY, preciseX, preciseShellY, dragThreshold);
|
|
158
193
|
if (!movedEnough) {
|
|
159
194
|
updateDockPreview(null);
|
|
160
|
-
|
|
195
|
+
setHoverTarget(null);
|
|
161
196
|
updateDragFloatingRect(null);
|
|
162
197
|
} else {
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
? getRememberedFloatingRect(baseLayout, drag.paneId, width, contentHeight, pane?.def)
|
|
166
|
-
: drag.origRect;
|
|
167
|
-
const releaseRect = resolvePaneDragFloatingRect(drag, baseRect, preciseX, preciseShellY, width, contentHeight);
|
|
168
|
-
const nextLayout = finalizePaneDragRelease(baseLayout, drag.paneId, releaseRect, dockPreviewRef.current);
|
|
198
|
+
const releaseRect = resolvePaneDragFloatingRect(drag, dragBaseRect()!, preciseX, preciseShellY, width, contentHeight);
|
|
199
|
+
const nextLayout = finalizePaneDragRelease(baseLayout, drag.paneId, releaseRect, live.get().dockPreview);
|
|
169
200
|
if (windowMode) {
|
|
170
201
|
updateWindowModePreviewLayout(nextLayout, drag.paneId);
|
|
171
202
|
} else {
|
|
@@ -173,7 +204,7 @@ export function useShellActiveDrag({
|
|
|
173
204
|
}
|
|
174
205
|
focusPane(drag.paneId);
|
|
175
206
|
updateDockPreview(null);
|
|
176
|
-
|
|
207
|
+
setHoverTarget(null);
|
|
177
208
|
updateDragFloatingRect(null);
|
|
178
209
|
}
|
|
179
210
|
} else if (drag.type === "float-resize") {
|
|
@@ -185,27 +216,28 @@ export function useShellActiveDrag({
|
|
|
185
216
|
persistLayout(nextLayout);
|
|
186
217
|
}
|
|
187
218
|
updateDragFloatingRect(null);
|
|
188
|
-
|
|
219
|
+
setHoverTarget(null);
|
|
189
220
|
}
|
|
190
221
|
dragRef.current = null;
|
|
222
|
+
live.set({ paneDrag: null, paneResize: null });
|
|
191
223
|
event.stopPropagation();
|
|
192
224
|
event.preventDefault();
|
|
193
225
|
}
|
|
194
226
|
}, [
|
|
195
227
|
appHeaderHeight,
|
|
196
228
|
bounds,
|
|
229
|
+
cancelActiveDrag,
|
|
197
230
|
contentHeight,
|
|
198
231
|
dockGeometryOptions,
|
|
199
|
-
dividerPreviewRef,
|
|
200
232
|
dockLeafLayouts,
|
|
201
|
-
dockPreviewRef,
|
|
202
233
|
dragRef,
|
|
203
234
|
focusPane,
|
|
235
|
+
live,
|
|
204
236
|
nativePaneChrome,
|
|
205
237
|
paneMap,
|
|
206
238
|
persistLayout,
|
|
207
239
|
precisePointer,
|
|
208
|
-
|
|
240
|
+
setHoverTarget,
|
|
209
241
|
snapGuides,
|
|
210
242
|
updateDividerPreview,
|
|
211
243
|
updateDockPreview,
|