gloomberb 0.10.4 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +30 -3
- package/README.zh-CN.md +1 -1
- package/package.json +5 -5
- package/src/api-client/auth.ts +34 -0
- package/src/api-client/data.ts +25 -0
- package/src/api-client/index.test.ts +81 -0
- package/src/api-client/index.ts +37 -0
- package/src/api-client/request.test.ts +30 -0
- package/src/api-client/request.ts +44 -20
- package/src/api-client/socket-health.test.ts +79 -0
- package/src/api-client/socket.ts +108 -5
- package/src/api-client/types.ts +139 -0
- package/src/app/global-shortcuts.test.tsx +144 -9
- package/src/app/global-shortcuts.ts +33 -11
- package/src/app/runtime/broker-import.ts +39 -5
- package/src/app/runtime/startup.ts +7 -1
- package/src/app/runtime/update.ts +26 -1
- package/src/app.tsx +36 -19
- package/src/brokers/broker-ticker-sync.ts +3 -8
- package/src/brokers/sync-broker-instance.test.ts +59 -0
- package/src/brokers/sync-broker-instance.ts +37 -13
- package/src/capabilities/chart-series.ts +318 -0
- package/src/capabilities/factories.ts +46 -0
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/registry.test.ts +135 -0
- package/src/capabilities/registry.ts +31 -4
- package/src/capabilities/types.ts +52 -0
- package/src/cli/commands/overview.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +2 -0
- package/src/cli/entry.ts +11 -1
- package/src/cli/native-smoke.ts +5 -0
- package/src/cli/pane-functions/catalog.ts +4 -0
- package/src/cli/pane-functions/data.ts +6 -1
- package/src/cli/pane-functions/discovery.ts +76 -10
- package/src/cli/pane-functions/report.test.ts +76 -0
- package/src/cli/pane-functions/report.ts +7 -1
- package/src/cli/pane-functions/resolver.ts +4 -1
- package/src/cli/pane-functions/screenshot.test.ts +56 -3
- package/src/cli/pane-functions/screenshot.ts +68 -5
- package/src/components/chart/composite/composite-chart.test.tsx +54 -0
- package/src/components/chart/composite/composite-chart.tsx +92 -15
- package/src/components/chart/composite/downsample.test.ts +136 -0
- package/src/components/chart/composite/downsample.ts +208 -0
- package/src/components/chart/composite/panel-series.test.ts +66 -0
- package/src/components/chart/composite/panel-series.ts +101 -0
- package/src/components/chart/multi-line/renderer.ts +1 -0
- package/src/components/chart/native/kitty/index.test.ts +25 -3
- package/src/components/chart/native/kitty/support.ts +37 -3
- package/src/components/chart/native/use-chart-text-fallback.ts +19 -0
- package/src/components/chart/static/chart/surface.tsx +43 -12
- package/src/components/chart/static/multi-line-chart-surface.tsx +41 -5
- package/src/components/command-bar/commands/direct/index.ts +18 -0
- package/src/components/command-bar/commands/registry.ts +14 -0
- package/src/components/command-bar/routes/root/article-results.test.ts +83 -0
- package/src/components/command-bar/routes/root/article-results.ts +55 -0
- package/src/components/command-bar/routes/root/command-items.ts +3 -0
- package/src/components/command-bar/routes/root/provider-search.ts +7 -3
- package/src/components/command-bar/routes/root/results.ts +38 -11
- package/src/components/command-bar/routes/root/runtime.ts +6 -2
- package/src/components/command-bar/routes/ticker-search/actions.ts +1 -1
- package/src/components/command-bar/routes/ticker-search/results.test.ts +34 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +4 -6
- package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
- package/src/components/command-bar/routing/list-state.ts +2 -1
- package/src/components/command-bar/surface/assist.test.tsx +13 -6
- package/src/components/command-bar/surface/index.test.tsx +65 -0
- package/src/components/command-bar/surface/index.tsx +35 -0
- package/src/components/command-bar/view-model.test.ts +43 -0
- package/src/components/command-bar/view-model.ts +41 -4
- package/src/components/command-bar/workflow/collection-actions.test.ts +94 -0
- package/src/components/command-bar/workflow/collection-actions.ts +14 -3
- package/src/components/command-bar/workflow/ops.test.ts +136 -0
- package/src/components/command-bar/workflow/ops.ts +71 -1
- package/src/components/index.ts +1 -1
- package/src/components/layout/header.test.tsx +35 -0
- package/src/components/layout/header.tsx +101 -9
- package/src/components/layout/pane/cycle-order.test.ts +0 -1
- package/src/components/layout/pane/footer/index.test.tsx +19 -19
- package/src/components/layout/pane/header.tsx +2 -13
- package/src/components/layout/shell/index.tsx +3 -0
- package/src/components/layout/status-bar.test.tsx +36 -1
- package/src/components/layout/status-bar.tsx +48 -2
- package/src/components/onboarding/account-step/chooser-panel.tsx +27 -50
- package/src/components/onboarding/account-step/form-panel.tsx +85 -29
- package/src/components/onboarding/account-step/index.tsx +10 -1
- package/src/components/onboarding/account-step/model.ts +3 -3
- package/src/components/onboarding/account-step/qr-panel.tsx +68 -0
- package/src/components/onboarding/account-step/signed-in-panel.tsx +4 -7
- package/src/components/onboarding/onboarding-frame.tsx +517 -0
- package/src/components/onboarding/onboarding-steps.tsx +0 -264
- package/src/components/onboarding/onboarding-wizard.test.tsx +626 -200
- package/src/components/onboarding/onboarding-wizard.tsx +848 -266
- package/src/components/onboarding/portfolio-step/broker-fields-panel.tsx +81 -51
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +14 -20
- package/src/components/onboarding/portfolio-step/broker-sync-panel.tsx +8 -11
- package/src/components/onboarding/portfolio-step/choose-panel.tsx +18 -22
- package/src/components/onboarding/portfolio-step/index.tsx +3 -0
- package/src/components/onboarding/portfolio-step/types.ts +3 -0
- package/src/components/onboarding/wizard-account.ts +38 -3
- package/src/components/onboarding/wizard-broker-sync.ts +45 -67
- package/src/components/onboarding/wizard-model.ts +18 -2
- package/src/components/ui/data-table/opentui/index.tsx +29 -9
- package/src/components/ui/data-table/types.ts +2 -0
- package/src/components/ui/external-link.tsx +4 -2
- package/src/components/ui/loading.tsx +1 -1
- package/src/components/ui/status.tsx +76 -4
- package/src/components/ui/table-layout.test.ts +24 -0
- package/src/components/ui/table-layout.ts +90 -23
- package/src/components/ui/tabs.tsx +86 -4
- package/src/core/app-services.ts +14 -3
- package/src/core/connection-health.test.ts +143 -0
- package/src/core/connection-health.ts +295 -0
- package/src/core/state/app/layout-reducer.ts +34 -0
- package/src/core/state/app/layout.ts +21 -0
- package/src/core/state/app/state.ts +10 -0
- package/src/core/state/app/types.ts +7 -1
- package/src/data/config/chart-settings.ts +11 -2
- package/src/data/config/store/index.test.ts +83 -9
- package/src/data/config/store/migrations.ts +16 -0
- package/src/data/config/store/normalize.ts +59 -1
- package/src/data/fred-series.ts +8 -2
- package/src/i18n/es.ts +126 -0
- package/src/i18n/ja.ts +126 -0
- package/src/i18n/ko.ts +126 -0
- package/src/i18n/zh-cn.ts +126 -0
- package/src/i18n/zh-tw.ts +126 -0
- package/src/market-data/coordinator/chart.ts +3 -2
- package/src/market-data/hooks.tsx +3 -2
- package/src/market-data/market/status.test.ts +12 -0
- package/src/market-data/market/status.ts +34 -17
- package/src/news/aggregator.test.ts +39 -0
- package/src/news/aggregator.ts +78 -22
- package/src/news/hooks.ts +4 -0
- package/src/notifications/app-notifier.test.ts +28 -6
- package/src/notifications/app-notifier.ts +24 -5
- package/src/plugins/broker-sync/broker-sync.test.ts +130 -0
- package/src/plugins/broker-sync/native-loader.ts +10 -0
- package/src/plugins/broker-sync/normalize.ts +271 -0
- package/src/plugins/broker-sync/public.ts +122 -0
- package/src/plugins/broker-sync/robinhood-native.ts +367 -0
- package/src/plugins/broker-sync/robinhood.ts +114 -0
- package/src/plugins/broker-sync/simplefin-native.ts +201 -0
- package/src/plugins/broker-sync/simplefin.ts +70 -0
- package/src/plugins/builtin/account-management/footer.ts +8 -19
- package/src/plugins/builtin/account-management/pane.tsx +13 -8
- package/src/plugins/builtin/ai/pi/host.ts +6 -5
- package/src/plugins/builtin/ai/providers.ts +1 -1
- package/src/plugins/builtin/ai/screener/footer.ts +0 -7
- package/src/plugins/builtin/ai/screener/pane.test.tsx +2 -1
- package/src/plugins/builtin/ai/screener/pane.tsx +3 -1
- package/src/plugins/builtin/ai/screener/results-view.tsx +8 -0
- package/src/plugins/builtin/ai/screener/runner.ts +7 -3
- package/src/plugins/builtin/ai/workspace/pane.tsx +13 -2
- package/src/plugins/builtin/alerts/alert-engine.ts +13 -0
- package/src/plugins/builtin/alerts/constants.ts +2 -1
- package/src/plugins/builtin/alerts/index.tsx +67 -36
- package/src/plugins/builtin/alerts/pane.tsx +17 -65
- package/src/plugins/builtin/analytics/index.tsx +24 -11
- package/src/plugins/builtin/analytics/pane-model.ts +48 -14
- package/src/plugins/builtin/analytics/portfolio-selection.ts +19 -0
- package/src/plugins/builtin/analytics/view.tsx +5 -3
- package/src/plugins/builtin/broker-manager/detail.tsx +7 -2
- package/src/plugins/builtin/broker-manager/footer.ts +4 -9
- package/src/plugins/builtin/broker-manager/index.tsx +1 -6
- package/src/plugins/builtin/buildout/detail/ui.tsx +15 -4
- package/src/plugins/builtin/buildout/pane/header.tsx +1 -0
- package/src/plugins/builtin/changelog/index.tsx +60 -45
- package/src/plugins/builtin/chart-composer/catalog-inventory.test.ts +97 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +366 -0
- package/src/plugins/builtin/chart-composer/chart-spec.ts +21 -1
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +307 -0
- package/src/plugins/builtin/chart-composer/editor/controller.ts +1 -1
- package/src/plugins/builtin/chart-composer/index.tsx +45 -5
- package/src/plugins/builtin/chart-composer/pane.tsx +7 -88
- package/src/plugins/builtin/chart-composer/presets.test.ts +48 -0
- package/src/plugins/builtin/chart-composer/presets.ts +69 -3
- package/src/plugins/builtin/chart-composer/quick-add.tsx +8 -5
- package/src/plugins/builtin/chart-composer/semantic.ts +18 -14
- package/src/plugins/builtin/chart-composer/series-catalog.test.ts +39 -0
- package/src/plugins/builtin/chart-composer/series-catalog.ts +104 -3
- package/src/plugins/builtin/chart-composer/shortcuts.test.ts +10 -10
- package/src/plugins/builtin/chart-composer/shortcuts.ts +4 -12
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +230 -23
- package/src/plugins/builtin/chat/chat.test.tsx +22 -0
- package/src/plugins/builtin/chat/content/composer.tsx +6 -4
- package/src/plugins/builtin/chat/content/index.tsx +7 -0
- package/src/plugins/builtin/chat/content/snapshot.ts +9 -2
- package/src/plugins/builtin/chat/content/transcript.tsx +10 -0
- package/src/plugins/builtin/chat/controller/channel-actions.ts +11 -1
- package/src/plugins/builtin/chat/controller/channels.ts +13 -3
- package/src/plugins/builtin/chat/controller/index.ts +61 -7
- package/src/plugins/builtin/chat/controller/lifecycle.ts +3 -0
- package/src/plugins/builtin/chat/controller/message-loading.ts +5 -1
- package/src/plugins/builtin/chat/controller/messages.ts +3 -1
- package/src/plugins/builtin/chat/controller/notifications.ts +32 -11
- package/src/plugins/builtin/chat/controller/state.ts +7 -0
- package/src/plugins/builtin/chat/controller/view.ts +1 -0
- package/src/plugins/builtin/chat/controller.test.ts +117 -28
- package/src/plugins/builtin/cloud/auth-commands.ts +18 -0
- package/src/plugins/builtin/cloud/device-signin-dialog.tsx +243 -0
- package/src/plugins/builtin/cloud/device-signin.test.ts +217 -0
- package/src/plugins/builtin/cloud/device-signin.ts +240 -0
- package/src/plugins/builtin/cloud/plugin.tsx +7 -1
- package/src/plugins/builtin/cloud-tweets/table.tsx +57 -10
- package/src/plugins/builtin/composite-plugins.ts +39 -5
- package/src/plugins/builtin/congress-trades/detail.tsx +2 -4
- package/src/plugins/builtin/congress-trades/footer.ts +7 -16
- package/src/plugins/builtin/congress-trades/pane.tsx +12 -20
- package/src/plugins/builtin/connections/index.ts +53 -0
- package/src/plugins/builtin/connections/pane.test.tsx +79 -0
- package/src/plugins/builtin/connections/pane.tsx +258 -0
- package/src/plugins/builtin/correlation/index.test.tsx +2 -1
- package/src/plugins/builtin/correlation/index.tsx +58 -19
- package/src/plugins/builtin/correlation/matrix/model.ts +18 -7
- package/src/plugins/builtin/correlation/relationship/pane.tsx +43 -19
- package/src/plugins/builtin/correlation/settings.ts +1 -1
- package/src/plugins/builtin/credit-conditions/client.test.ts +80 -0
- package/src/plugins/builtin/credit-conditions/client.ts +105 -0
- package/src/plugins/builtin/credit-conditions/index.test.tsx +111 -0
- package/src/plugins/builtin/credit-conditions/index.tsx +227 -0
- package/src/plugins/builtin/credit-conditions/model.test.ts +43 -0
- package/src/plugins/builtin/credit-conditions/model.ts +64 -0
- package/src/plugins/builtin/debug/index.tsx +11 -6
- package/src/plugins/builtin/dividend-yield/client.test.ts +58 -0
- package/src/plugins/builtin/dividend-yield/client.ts +252 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +61 -0
- package/src/plugins/builtin/dividend-yield/model.ts +83 -0
- package/src/plugins/builtin/dividend-yield/pane.tsx +305 -0
- package/src/plugins/builtin/dividend-yield/types.ts +22 -0
- package/src/plugins/builtin/earnings/data/cache.test.ts +10 -7
- package/src/plugins/builtin/earnings/data/cache.ts +23 -9
- package/src/plugins/builtin/earnings/index.tsx +57 -6
- package/src/plugins/builtin/econ/calendar-model.test.ts +37 -3
- package/src/plugins/builtin/econ/calendar-model.ts +32 -26
- package/src/plugins/builtin/econ/fred-cache.test.ts +8 -1
- package/src/plugins/builtin/econ/fred-series-map.ts +18 -0
- package/src/plugins/builtin/econ/index.test.tsx +105 -0
- package/src/plugins/builtin/econ/index.tsx +95 -52
- package/src/plugins/builtin/fear-greed/cache.test.ts +18 -3
- package/src/plugins/builtin/fear-greed/cache.ts +18 -6
- package/src/plugins/builtin/fear-greed/charts.tsx +9 -2
- package/src/plugins/builtin/fear-greed/format.ts +0 -9
- package/src/plugins/builtin/fear-greed/pane.tsx +21 -21
- package/src/plugins/builtin/futures/contracts.ts +100 -0
- package/src/plugins/builtin/futures/index.tsx +298 -0
- package/src/plugins/builtin/futures/model.test.ts +129 -0
- package/src/plugins/builtin/futures/model.ts +136 -0
- package/src/plugins/builtin/futures/pane.test.tsx +239 -0
- package/src/plugins/builtin/futures/table.test.ts +155 -0
- package/src/plugins/builtin/futures/table.tsx +241 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +160 -134
- package/src/plugins/builtin/fx-matrix/pairs.ts +12 -1
- package/src/plugins/builtin/fx-matrix/pane.test.tsx +109 -0
- package/src/plugins/builtin/help/components.tsx +1 -30
- package/src/plugins/builtin/help/index.tsx +5 -25
- package/src/plugins/builtin/holders/pane.tsx +17 -12
- package/src/plugins/builtin/holders/treemap.tsx +4 -2
- package/src/plugins/builtin/insider/index.tsx +20 -10
- package/src/plugins/builtin/ipo-calendar/cache.ts +101 -0
- package/src/plugins/builtin/ipo-calendar/client.test.ts +31 -0
- package/src/plugins/builtin/ipo-calendar/client.ts +296 -0
- package/src/plugins/builtin/ipo-calendar/index.tsx +65 -0
- package/src/plugins/builtin/ipo-calendar/model.ts +145 -0
- package/src/plugins/builtin/ipo-calendar/pane.tsx +328 -0
- package/src/plugins/builtin/ipo-calendar/types.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/index.test.tsx +3 -3
- package/src/plugins/builtin/kelly-sizer/model.ts +8 -1
- package/src/plugins/builtin/kelly-sizer/pane.tsx +33 -15
- package/src/plugins/builtin/kelly-sizer/view.tsx +12 -5
- package/src/plugins/builtin/market-halts/client.ts +114 -0
- package/src/plugins/builtin/market-halts/index.tsx +29 -0
- package/src/plugins/builtin/market-halts/model.test.ts +187 -0
- package/src/plugins/builtin/market-halts/model.ts +291 -0
- package/src/plugins/builtin/market-halts/pane.tsx +256 -0
- package/src/plugins/builtin/market-heatmap/data.test.ts +1 -0
- package/src/plugins/builtin/market-heatmap/data.ts +12 -3
- package/src/plugins/builtin/market-heatmap/index.tsx +131 -46
- package/src/plugins/builtin/market-movers/index.tsx +145 -63
- package/src/plugins/builtin/market-movers/model.ts +19 -3
- package/src/plugins/builtin/market-movers/screener.test.ts +108 -0
- package/src/plugins/builtin/market-movers/screener.ts +168 -10
- package/src/plugins/builtin/news/index.tsx +78 -99
- package/src/plugins/builtin/news/wire/article-search.test.ts +72 -0
- package/src/plugins/builtin/news/wire/article-search.ts +140 -0
- package/src/plugins/builtin/news/wire/breaking/pane.tsx +18 -8
- package/src/plugins/builtin/news/wire/categories.ts +35 -0
- package/src/plugins/builtin/news/wire/default-feeds.ts +47 -1
- package/src/plugins/builtin/news/wire/feed-config.test.ts +10 -5
- package/src/plugins/builtin/news/wire/index.tsx +41 -4
- package/src/plugins/builtin/news/wire/industry-pane.tsx +38 -19
- package/src/plugins/builtin/news/wire/news/detail-view.tsx +10 -5
- package/src/plugins/builtin/news/wire/news/footer.ts +1 -0
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +15 -6
- package/src/plugins/builtin/news/wire/news/query-presets.ts +16 -2
- package/src/plugins/builtin/news/wire/news/table.test.tsx +54 -0
- package/src/plugins/builtin/news/wire/news/table.tsx +111 -17
- package/src/plugins/builtin/notes/files.test.ts +18 -0
- package/src/plugins/builtin/notes/files.ts +10 -4
- package/src/plugins/builtin/notes/index.tsx +4 -1
- package/src/plugins/builtin/notes/quick-notes-pane.test.tsx +182 -0
- package/src/plugins/builtin/notes/quick-notes-pane.tsx +74 -31
- package/src/plugins/builtin/notes/ticker-notes-tab.test.tsx +380 -0
- package/src/plugins/builtin/notes/ticker-notes-tab.tsx +97 -40
- package/src/plugins/builtin/options/calc-seed.test.ts +118 -0
- package/src/plugins/builtin/options/calc-seed.ts +52 -0
- package/src/plugins/builtin/options/footer.ts +4 -1
- package/src/plugins/builtin/options/index.tsx +22 -1
- package/src/plugins/builtin/options/live-quotes.ts +8 -0
- package/src/plugins/builtin/options/table.ts +3 -1
- package/src/plugins/builtin/options/view.test.tsx +5 -1
- package/src/plugins/builtin/options/view.tsx +112 -17
- package/src/plugins/builtin/options-calculator/index.tsx +35 -0
- package/src/plugins/builtin/options-calculator/model.test.ts +172 -0
- package/src/plugins/builtin/options-calculator/model.ts +273 -0
- package/src/plugins/builtin/options-calculator/pane.test.tsx +138 -0
- package/src/plugins/builtin/options-calculator/pane.tsx +218 -0
- package/src/plugins/builtin/plugin-module.test.ts +16 -2
- package/src/plugins/builtin/plugin-module.ts +5 -1
- package/src/plugins/builtin/polls/client.ts +57 -0
- package/src/plugins/builtin/polls/hooks.ts +20 -0
- package/src/plugins/builtin/polls/index.tsx +35 -0
- package/src/plugins/builtin/polls/normalize.test.ts +230 -0
- package/src/plugins/builtin/polls/normalize.ts +319 -0
- package/src/plugins/builtin/polls/pane.tsx +722 -0
- package/src/plugins/builtin/polls/types.ts +77 -0
- package/src/plugins/builtin/portfolio-list/header.tsx +15 -4
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +7 -3
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +1 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +2 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +2 -1
- package/src/plugins/builtin/research/analyst-pane.tsx +40 -67
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +25 -19
- package/src/plugins/builtin/research/index.test.ts +6 -25
- package/src/plugins/builtin/research/index.tsx +11 -5
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +86 -26
- package/src/plugins/builtin/scanner/denied.tsx +31 -0
- package/src/plugins/builtin/scanner/feed.ts +94 -0
- package/src/plugins/builtin/scanner/flow-model.test.ts +85 -0
- package/src/plugins/builtin/scanner/flow-model.ts +133 -0
- package/src/plugins/builtin/scanner/flow-pane.tsx +197 -0
- package/src/plugins/builtin/scanner/hilo-bars.tsx +121 -0
- package/src/plugins/builtin/scanner/hilo-model.test.ts +44 -0
- package/src/plugins/builtin/scanner/hilo-model.ts +75 -0
- package/src/plugins/builtin/scanner/hilo-pane.tsx +165 -0
- package/src/plugins/builtin/scanner/index.ts +109 -0
- package/src/plugins/builtin/scanner/waiting.tsx +11 -0
- package/src/plugins/builtin/sec/index.tsx +11 -7
- package/src/plugins/builtin/sectors/index.tsx +105 -81
- package/src/plugins/builtin/sectors/move-bar.tsx +43 -0
- package/src/plugins/builtin/sectors/sector-data.ts +18 -0
- package/src/plugins/builtin/sectors/sector-model.ts +13 -15
- package/src/plugins/builtin/shared/auto-refresh.ts +51 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +29 -5
- package/src/plugins/builtin/shared/pane-footer.ts +16 -3
- package/src/plugins/builtin/shared/screener-live-quotes.test.ts +91 -0
- package/src/plugins/builtin/shared/screener-live-quotes.ts +134 -0
- package/src/plugins/builtin/shared/table-pane.ts +1 -5
- package/src/plugins/builtin/shared/use-quote-board.test.tsx +211 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +195 -0
- package/src/plugins/builtin/short-interest/client.ts +124 -0
- package/src/plugins/builtin/short-interest/index.tsx +62 -0
- package/src/plugins/builtin/short-interest/model.ts +113 -0
- package/src/plugins/builtin/short-interest/pane.tsx +252 -0
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/substack/article-detail.tsx +15 -1
- package/src/plugins/builtin/substack/pane-footer.ts +3 -22
- package/src/plugins/builtin/substack/pane.tsx +1 -2
- package/src/plugins/builtin/thirteenf/api.ts +4 -1
- package/src/plugins/builtin/thirteenf/model.ts +2 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +6 -2
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +10 -4
- package/src/plugins/builtin/ticker-detail/data-panes/provider-search.tsx +67 -11
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +15 -8
- package/src/plugins/builtin/ticker-detail/index.tsx +5 -21
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +72 -32
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +0 -10
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.test.tsx +70 -0
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +34 -26
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +96 -49
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +32 -0
- package/src/plugins/builtin/ticker-research-backend-plugin.ts +2 -9
- package/src/plugins/builtin/ticker-research-plugin.ts +6 -0
- package/src/plugins/builtin/treasury-auctions/cache.test.ts +173 -0
- package/src/plugins/builtin/treasury-auctions/cache.ts +104 -0
- package/src/plugins/builtin/treasury-auctions/client.test.ts +181 -0
- package/src/plugins/builtin/treasury-auctions/client.ts +151 -0
- package/src/plugins/builtin/treasury-auctions/index.tsx +90 -0
- package/src/plugins/builtin/treasury-auctions/model.test.ts +147 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +188 -0
- package/src/plugins/builtin/treasury-auctions/pane.test.tsx +170 -0
- package/src/plugins/builtin/treasury-auctions/pane.tsx +417 -0
- package/src/plugins/builtin/treasury-auctions/types.ts +59 -0
- package/src/plugins/builtin/tv/pane.tsx +67 -7
- package/src/plugins/builtin/tv/youtube-embed.test.ts +84 -0
- package/src/plugins/builtin/tv/youtube-embed.ts +173 -0
- package/src/plugins/builtin/tv/youtube-stream.ts +27 -2
- package/src/plugins/builtin/volatility/client.ts +87 -0
- package/src/plugins/builtin/volatility/index.test.tsx +107 -0
- package/src/plugins/builtin/volatility/index.tsx +193 -0
- package/src/plugins/builtin/volatility/model.test.ts +66 -0
- package/src/plugins/builtin/volatility/model.ts +113 -0
- package/src/plugins/builtin/world-indices/footer.ts +43 -23
- package/src/plugins/builtin/world-indices/index.tsx +44 -93
- package/src/plugins/builtin/world-indices/indices.ts +11 -2
- package/src/plugins/builtin/world-indices/model.ts +17 -24
- package/src/plugins/builtin/world-indices/pane.test.tsx +116 -0
- package/src/plugins/builtin/world-indices/table.tsx +82 -37
- package/src/plugins/builtin/yield-curve/index.tsx +16 -7
- package/src/plugins/builtin/yield-curve/treasury-data.test.ts +25 -0
- package/src/plugins/builtin/yield-curve/treasury-data.ts +16 -0
- package/src/plugins/catalog-backend.ts +8 -0
- package/src/plugins/catalog-ui.ts +8 -0
- package/src/plugins/event-bus.ts +1 -0
- package/src/plugins/ibkr/gateway/account-loaders.ts +1 -1
- package/src/plugins/ibkr/trade/tab/footer.ts +9 -23
- package/src/plugins/ibkr/trade/tab/index.tsx +1 -5
- package/src/plugins/ibkr/trading/pane-view.tsx +149 -87
- package/src/plugins/ibkr/trading/pane.tsx +2 -2
- package/src/plugins/ownership.ts +3 -0
- package/src/plugins/pane-manager/floating.ts +8 -2
- package/src/plugins/pane-manager.test.ts +13 -0
- package/src/plugins/prediction-markets/backend-plugin.ts +2 -0
- package/src/plugins/prediction-markets/capability.test.ts +281 -0
- package/src/plugins/prediction-markets/capability.ts +171 -0
- package/src/plugins/prediction-markets/chart.tsx +18 -26
- package/src/plugins/prediction-markets/columns.ts +3 -2
- package/src/plugins/prediction-markets/controller/catalog.ts +15 -12
- package/src/plugins/prediction-markets/controller/detail.ts +4 -0
- package/src/plugins/prediction-markets/controller/index.ts +0 -15
- package/src/plugins/prediction-markets/detail/book.tsx +3 -23
- package/src/plugins/prediction-markets/detail/overview.tsx +0 -18
- package/src/plugins/prediction-markets/detail/pane.tsx +36 -12
- package/src/plugins/prediction-markets/detail.test.tsx +1 -1
- package/src/plugins/prediction-markets/index.tsx +2 -0
- package/src/plugins/prediction-markets/metrics.ts +28 -18
- package/src/plugins/prediction-markets/navigation.ts +1 -0
- package/src/plugins/prediction-markets/pane.test.tsx +1 -1
- package/src/plugins/prediction-markets/pane.tsx +0 -1
- package/src/plugins/prediction-markets/services/fetch.ts +3 -2
- package/src/plugins/prediction-markets/services/kalshi/adapter.ts +82 -23
- package/src/plugins/prediction-markets/services/kalshi/normalize.ts +3 -1
- package/src/plugins/prediction-markets/services/kalshi/types.ts +14 -0
- package/src/plugins/prediction-markets/services/polymarket/adapter.ts +26 -14
- package/src/plugins/prediction-markets/services/polymarket/detail.ts +67 -18
- package/src/plugins/prediction-markets/test-helpers.tsx +0 -1
- package/src/plugins/prediction-markets/types.ts +3 -9
- package/src/plugins/registry/context.ts +6 -1
- package/src/plugins/registry/index.test.ts +2 -0
- package/src/plugins/registry/index.ts +53 -3
- package/src/plugins/runtime/context.tsx +4 -2
- package/src/plugins/runtime/index.tsx +9 -0
- package/src/remote/controller.test.ts +17 -4
- package/src/renderers/electrobun/bun/application-menu/index.ts +1 -1
- package/src/renderers/electrobun/bun/core-capabilities.ts +2 -2
- package/src/renderers/electrobun/bun/desktop/capability-bridge.test.ts +64 -0
- package/src/renderers/electrobun/bun/desktop/capability-bridge.ts +41 -7
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +5 -2
- package/src/renderers/electrobun/bun/desktop/http-fetch.test.ts +33 -0
- package/src/renderers/electrobun/bun/desktop/http-fetch.ts +53 -6
- package/src/renderers/electrobun/bun/desktop/initialization.test.ts +27 -0
- package/src/renderers/electrobun/bun/desktop/initialization.ts +6 -1
- package/src/renderers/electrobun/bun/index.ts +1 -0
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/app-services.ts +25 -2
- package/src/renderers/electrobun/view/build-assets.ts +5 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +186 -65
- package/src/renderers/electrobun/view/cli-pane-shot-health.test.ts +25 -0
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +31 -0
- package/src/renderers/electrobun/view/data-table/index.tsx +10 -11
- package/src/renderers/electrobun/view/data-table/row.tsx +2 -0
- package/src/renderers/electrobun/view/desktop/controls.test.tsx +68 -0
- package/src/renderers/electrobun/view/desktop/controls.tsx +25 -1
- package/src/renderers/electrobun/view/host/box.test.tsx +80 -0
- package/src/renderers/electrobun/view/host/media-surface.tsx +70 -3
- package/src/renderers/electrobun/view/host/tabs.tsx +97 -5
- package/src/renderers/electrobun/view/host/text.tsx +5 -2
- package/src/renderers/electrobun/view/input-host.test.tsx +140 -0
- package/src/renderers/electrobun/view/input-host.tsx +4 -2
- package/src/renderers/electrobun/view/native-stubs/backend-rpc.ts +19 -1
- package/src/renderers/electrobun/view/native-stubs/broker-sync-native-loader.ts +7 -0
- package/src/renderers/electrobun/view/native-stubs/chart/kitty-support.ts +10 -0
- package/src/renderers/electrobun/view/remote/capability-invoker.test.ts +46 -0
- package/src/renderers/electrobun/view/remote/capability-invoker.ts +34 -13
- package/src/renderers/electrobun/view/remote/connection-health-backend.ts +19 -0
- package/src/renderers/electrobun/view/remote/connection-health.test.ts +44 -0
- package/src/renderers/electrobun/view/remote/connection-health.ts +49 -0
- package/src/renderers/electrobun/view/styles.css +5 -0
- package/src/renderers/opentui/dialog-host.tsx +279 -80
- package/src/renderers/opentui/host.tsx +15 -1
- package/src/renderers/opentui/terminal-media.test.ts +102 -0
- package/src/renderers/opentui/terminal-media.ts +142 -0
- package/src/renderers/opentui/test-utils.tsx +9 -6
- package/src/renderers/opentui/toast-host.tsx +136 -7
- package/src/renderers/opentui/ui-host.tsx +19 -3
- package/src/sources/provider-router/connection-health.test.ts +28 -0
- package/src/sources/provider-router/connection-health.ts +47 -0
- package/src/sources/provider-router/history.test.ts +53 -4
- package/src/sources/provider-router/history.ts +119 -14
- package/src/sources/provider-router/index.ts +12 -1
- package/src/sources/yahoo-finance/history.ts +2 -9
- package/src/sources/yahoo-finance/http.ts +1 -1
- package/src/sources/yahoo-finance/symbols.ts +1 -1
- package/src/sources/yahoo-finance/types.ts +19 -0
- package/src/state/app/context/index.test.tsx +101 -0
- package/src/state/app/context/index.tsx +10 -0
- package/src/state/config-save-scheduler.ts +1 -6
- package/src/state/persist-scheduler.test.ts +31 -0
- package/src/state/persist-scheduler.ts +21 -8
- package/src/sync/auth-transition.test.ts +36 -0
- package/src/sync/auth-transition.ts +22 -0
- package/src/sync/core-contributors.test.ts +58 -1
- package/src/sync/core-contributors.ts +39 -2
- package/src/sync/react.ts +9 -0
- package/src/test-support/plugin-runtime.ts +3 -0
- package/src/theme/font-scale.test.ts +14 -0
- package/src/theme/font-scale.ts +69 -0
- package/src/tickers/search/index.test.ts +284 -2
- package/src/tickers/search/index.ts +55 -18
- package/src/tickers/search/ranking.ts +143 -18
- package/src/tickers/search/types.ts +1 -0
- package/src/time-series/alignment.ts +15 -11
- package/src/time-series/field-catalog.ts +10 -0
- package/src/time-series/fundamentals.ts +19 -11
- package/src/time-series/hooks.ts +8 -2
- package/src/time-series/parsed-history-cache.ts +35 -0
- package/src/time-series/resolution.ts +10 -0
- package/src/time-series/resolve.test.ts +332 -3
- package/src/time-series/resolve.ts +225 -25
- package/src/time-series/spec-studies.test.ts +23 -0
- package/src/time-series/spec.ts +21 -2
- package/src/time-series/transforms.test.ts +76 -1
- package/src/time-series/transforms.ts +39 -8
- package/src/time-series/types.ts +9 -2
- package/src/time-series/use-chart-resolution.test.tsx +105 -1
- package/src/time-series/use-chart-resolution.ts +67 -13
- package/src/types/config.ts +30 -27
- package/src/types/media.ts +2 -0
- package/src/types/plugin.ts +8 -1
- package/src/ui/host.tsx +4 -0
- package/src/ui/pointer-drag.ts +12 -0
- package/src/ui/qr.test.ts +79 -0
- package/src/ui/qr.ts +82 -0
- package/src/updater/github-releases.test.ts +3 -3
- package/src/updater/github-releases.ts +1 -1
- package/src/updater.test.ts +117 -16
- package/src/updater.ts +32 -5
- package/src/utils/exchanges.ts +1 -0
- package/src/utils/external-url.test.ts +32 -0
- package/src/utils/external-url.ts +23 -0
- package/src/utils/sort-values.ts +31 -0
- package/src/utils/zoned-date-time.ts +67 -0
- package/src/components/onboarding/wizard-keyboard.ts +0 -306
- package/src/plugins/builtin/chart-composer/date-window-dialog.tsx +0 -120
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { ResolvedSeries, TimeSeriesPoint } from "../../../time-series/types";
|
|
2
|
+
|
|
3
|
+
function sameTime(left: Date | undefined, right: Date | undefined): boolean {
|
|
4
|
+
if (left === right) return true;
|
|
5
|
+
if (!left || !right) return left == right;
|
|
6
|
+
return left.getTime() === right.getTime();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function samePoint(left: TimeSeriesPoint, right: TimeSeriesPoint): boolean {
|
|
10
|
+
return left === right
|
|
11
|
+
|| (
|
|
12
|
+
sameTime(left.date, right.date)
|
|
13
|
+
&& sameTime(left.observedAt, right.observedAt)
|
|
14
|
+
&& sameTime(left.availableAt, right.availableAt)
|
|
15
|
+
&& left.value === right.value
|
|
16
|
+
&& left.open === right.open
|
|
17
|
+
&& left.high === right.high
|
|
18
|
+
&& left.low === right.low
|
|
19
|
+
&& left.close === right.close
|
|
20
|
+
&& left.volume === right.volume
|
|
21
|
+
&& left.periodLabel === right.periodLabel
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function sameSeriesMeta(left: ResolvedSeries, right: ResolvedSeries): boolean {
|
|
26
|
+
return left.id === right.id
|
|
27
|
+
&& left.label === right.label
|
|
28
|
+
&& left.color === right.color
|
|
29
|
+
&& left.unit === right.unit
|
|
30
|
+
&& left.unitGroup === right.unitGroup
|
|
31
|
+
&& left.nativeFrequency === right.nativeFrequency
|
|
32
|
+
&& left.timestampMode === right.timestampMode
|
|
33
|
+
&& left.dataShape === right.dataShape
|
|
34
|
+
&& left.style === right.style
|
|
35
|
+
&& left.transform === right.transform
|
|
36
|
+
&& left.axis === right.axis
|
|
37
|
+
&& left.panelId === right.panelId
|
|
38
|
+
&& left.interpolation === right.interpolation
|
|
39
|
+
&& left.warning === right.warning
|
|
40
|
+
&& left.hidden === right.hidden
|
|
41
|
+
&& left.timeBasis?.kind === right.timeBasis?.kind
|
|
42
|
+
&& left.timeBasis?.timeZone === right.timeBasis?.timeZone
|
|
43
|
+
&& left.timeBasis?.cadenceMs === right.timeBasis?.cadenceMs;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function prefixPointsEqual(left: readonly TimeSeriesPoint[], right: readonly TimeSeriesPoint[]): boolean {
|
|
47
|
+
if (left.length !== right.length || left.length === 0) return false;
|
|
48
|
+
for (let index = 0; index < left.length - 1; index += 1) {
|
|
49
|
+
if (!samePoint(left[index]!, right[index]!)) return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Reuses a previous ResolvedSeries object when a parent allocated a new wrapper
|
|
56
|
+
* for the same data, including live ticks that only change the last bar's
|
|
57
|
+
* close/time. Bitmap dirty detection keys off object identity, so this keeps
|
|
58
|
+
* an otherwise-stable plot from full-rerastering on every quote.
|
|
59
|
+
*/
|
|
60
|
+
export function reuseResolvedSeriesIdentity(
|
|
61
|
+
previous: ResolvedSeries | undefined,
|
|
62
|
+
next: ResolvedSeries,
|
|
63
|
+
): ResolvedSeries {
|
|
64
|
+
if (!previous) return next;
|
|
65
|
+
if (previous === next) return next;
|
|
66
|
+
if (!sameSeriesMeta(previous, next)) return next;
|
|
67
|
+
if (previous.points === next.points && previous.latestChangePercent === next.latestChangePercent) {
|
|
68
|
+
return previous;
|
|
69
|
+
}
|
|
70
|
+
if (previous.points.length !== next.points.length) return next;
|
|
71
|
+
const lastPrev = previous.points[previous.points.length - 1]!;
|
|
72
|
+
const lastNext = next.points[next.points.length - 1]!;
|
|
73
|
+
if (!samePoint(lastPrev, lastNext)) {
|
|
74
|
+
if (!prefixPointsEqual(previous.points, next.points)) return next;
|
|
75
|
+
previous.points[previous.points.length - 1] = lastNext;
|
|
76
|
+
previous.latestChangePercent = next.latestChangePercent;
|
|
77
|
+
return previous;
|
|
78
|
+
}
|
|
79
|
+
if (previous.points.every((point, index) => samePoint(point, next.points[index]!))) {
|
|
80
|
+
if (previous.latestChangePercent === next.latestChangePercent) return previous;
|
|
81
|
+
previous.latestChangePercent = next.latestChangePercent;
|
|
82
|
+
return previous;
|
|
83
|
+
}
|
|
84
|
+
return next;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function reuseResolvedSeriesList(
|
|
88
|
+
previous: readonly ResolvedSeries[] | undefined,
|
|
89
|
+
next: readonly ResolvedSeries[],
|
|
90
|
+
): ResolvedSeries[] {
|
|
91
|
+
if (!previous) return next as ResolvedSeries[];
|
|
92
|
+
if (previous === next) return previous as ResolvedSeries[];
|
|
93
|
+
const reused = next.map((series, index) => reuseResolvedSeriesIdentity(previous[index], series));
|
|
94
|
+
if (
|
|
95
|
+
reused.length === previous.length
|
|
96
|
+
&& reused.every((series, index) => series === previous[index])
|
|
97
|
+
) {
|
|
98
|
+
return previous as ResolvedSeries[];
|
|
99
|
+
}
|
|
100
|
+
return reused;
|
|
101
|
+
}
|
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
} from "../chart-rasterizer";
|
|
12
12
|
import { KittyImageManager } from "./manager";
|
|
13
13
|
import { chunkBase64Payload, encodeKittyTransmitRgba } from "./protocol";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
ensureKittySupport,
|
|
16
|
+
getCachedKittySupport,
|
|
17
|
+
resolveKittySupport,
|
|
18
|
+
} from "./support";
|
|
15
19
|
import { resolveChartRendererState } from "../renderer-selection";
|
|
16
20
|
import { computeSurfaceVisibleFragments, NativeSurfaceManager } from "../surface/manager";
|
|
17
21
|
import { syncCachedNativeSurface } from "../surface/sync";
|
|
@@ -42,9 +46,27 @@ describe("resolveChartRendererState", () => {
|
|
|
42
46
|
});
|
|
43
47
|
});
|
|
44
48
|
|
|
49
|
+
describe("resolveKittySupport", () => {
|
|
50
|
+
const noMultiplexer = { TERM: "xterm-kitty" } as Record<string, string | undefined>;
|
|
51
|
+
|
|
52
|
+
test("never claims support behind a multiplexer, whatever it advertises", () => {
|
|
53
|
+
expect(resolveKittySupport({ kitty_graphics: true, multiplexer: "tmux" }, noMultiplexer)).toBe(false);
|
|
54
|
+
expect(resolveKittySupport({ kitty_graphics: true }, { TERM: "tmux-256color" })).toBe(false);
|
|
55
|
+
expect(resolveKittySupport({ kitty_graphics: true }, { TERM_PROGRAM: "tmux" })).toBe(false);
|
|
56
|
+
expect(resolveKittySupport({ kitty_graphics: true }, { TMUX: "/tmp/tmux-501/default,1,0" })).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("keeps confirmed support and leaves an unanswered query undecided", () => {
|
|
60
|
+
expect(resolveKittySupport({ kitty_graphics: true, multiplexer: "none" }, noMultiplexer)).toBe(true);
|
|
61
|
+
expect(resolveKittySupport({ kitty_graphics: false }, noMultiplexer)).toBe(false);
|
|
62
|
+
expect(resolveKittySupport({}, noMultiplexer)).toBe(null);
|
|
63
|
+
expect(resolveKittySupport(null, noMultiplexer)).toBe(null);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
45
67
|
describe("getCachedKittySupport", () => {
|
|
46
68
|
test("prefers later renderer capabilities over a failed query cache", async () => {
|
|
47
|
-
let capabilities: { kitty_graphics?: boolean } | null = null;
|
|
69
|
+
let capabilities: { kitty_graphics?: boolean; multiplexer?: string } | null = null;
|
|
48
70
|
const renderer = {
|
|
49
71
|
isDestroyed: false,
|
|
50
72
|
get capabilities() {
|
|
@@ -60,7 +82,7 @@ describe("getCachedKittySupport", () => {
|
|
|
60
82
|
expect(await ensureKittySupport(renderer)).toBe(false);
|
|
61
83
|
expect(getCachedKittySupport(renderer)).toBe(false);
|
|
62
84
|
|
|
63
|
-
capabilities = { kitty_graphics: true };
|
|
85
|
+
capabilities = { kitty_graphics: true, multiplexer: "none" };
|
|
64
86
|
expect(getCachedKittySupport(renderer)).toBe(true);
|
|
65
87
|
});
|
|
66
88
|
});
|
|
@@ -2,8 +2,9 @@ import { type NativeRendererHost as CliRenderer } from "../../../../ui";
|
|
|
2
2
|
import { writeRendererRaw } from "./adapter";
|
|
3
3
|
import { buildKittyGraphicsQuery } from "./protocol";
|
|
4
4
|
|
|
5
|
-
interface RendererCapabilities {
|
|
5
|
+
export interface RendererCapabilities {
|
|
6
6
|
kitty_graphics?: boolean;
|
|
7
|
+
multiplexer?: string;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
interface SupportCacheEntry {
|
|
@@ -14,11 +15,42 @@ interface SupportCacheEntry {
|
|
|
14
15
|
const supportCache = new WeakMap<CliRenderer, SupportCacheEntry>();
|
|
15
16
|
const QUERY_TIMEOUT_MS = 250;
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* A multiplexer swallows the graphics query and then passes image payloads
|
|
20
|
+
* through as literal text, which shreds the screen. Whatever it advertises,
|
|
21
|
+
* kitty graphics are not usable behind one.
|
|
22
|
+
*/
|
|
23
|
+
export function isMultiplexedTerminal(
|
|
24
|
+
capabilities: RendererCapabilities | null | undefined,
|
|
25
|
+
env: Record<string, string | undefined> = process.env,
|
|
26
|
+
): boolean {
|
|
27
|
+
const reported = capabilities?.multiplexer;
|
|
28
|
+
// The renderer's own detection wins when it has one; the environment is only
|
|
29
|
+
// consulted when nothing was reported.
|
|
30
|
+
if (typeof reported === "string") return reported !== "none";
|
|
31
|
+
if (env.TMUX) return true;
|
|
32
|
+
const termProgram = (env.TERM_PROGRAM ?? "").toLowerCase();
|
|
33
|
+
if (termProgram === "tmux" || termProgram === "screen") return true;
|
|
34
|
+
const term = (env.TERM ?? "").toLowerCase();
|
|
35
|
+
return term.startsWith("tmux") || term.startsWith("screen");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* What is known about kitty graphics before querying: `null` means undecided,
|
|
40
|
+
* so the query result (or its absence) decides.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveKittySupport(
|
|
43
|
+
capabilities: RendererCapabilities | null | undefined,
|
|
44
|
+
env: Record<string, string | undefined> = process.env,
|
|
45
|
+
): boolean | null {
|
|
46
|
+
if (isMultiplexedTerminal(capabilities, env)) return false;
|
|
19
47
|
return typeof capabilities?.kitty_graphics === "boolean" ? capabilities.kitty_graphics : null;
|
|
20
48
|
}
|
|
21
49
|
|
|
50
|
+
function readKnownSupport(renderer: CliRenderer): boolean | null {
|
|
51
|
+
return resolveKittySupport(renderer.capabilities as RendererCapabilities | null);
|
|
52
|
+
}
|
|
53
|
+
|
|
22
54
|
export function getCachedKittySupport(renderer: CliRenderer): boolean | null {
|
|
23
55
|
const known = readKnownSupport(renderer);
|
|
24
56
|
if (known !== null) return known;
|
|
@@ -54,6 +86,8 @@ export function ensureKittySupport(renderer: CliRenderer): Promise<boolean> {
|
|
|
54
86
|
if (supported !== null) finish(supported);
|
|
55
87
|
};
|
|
56
88
|
|
|
89
|
+
// No answer means unsupported: a terminal that speaks the protocol answers,
|
|
90
|
+
// and anything that swallows the query would also swallow the image.
|
|
57
91
|
const timer = setTimeout(() => finish(false), QUERY_TIMEOUT_MS);
|
|
58
92
|
renderer.on("capabilities", onCapabilities);
|
|
59
93
|
if (!writeRendererRaw(renderer, `${buildKittyGraphicsQuery()}\x1b[c`)) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useNativeRenderer } from "../../../ui";
|
|
2
|
+
import { useOptionalAppSelector } from "../../../state/app/context";
|
|
3
|
+
import type { ChartRendererPreference } from "../core/types";
|
|
4
|
+
import { useResolvedChartRendererState } from "./renderer-selection";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Cell-character plot text is only visible when kitty is not the active chart
|
|
8
|
+
* renderer. Skip rebuilding braille/ASCII fallback while the native bitmap is
|
|
9
|
+
* on screen.
|
|
10
|
+
*/
|
|
11
|
+
export function useShowChartTextFallback(): boolean {
|
|
12
|
+
const renderer = useNativeRenderer();
|
|
13
|
+
const preferredRenderer = useOptionalAppSelector<ChartRendererPreference>(
|
|
14
|
+
(state) => state.config.chartPreferences.renderer,
|
|
15
|
+
"braille",
|
|
16
|
+
);
|
|
17
|
+
const rendererState = useResolvedChartRendererState(preferredRenderer, renderer);
|
|
18
|
+
return rendererState.renderer !== "kitty";
|
|
19
|
+
}
|
|
@@ -8,8 +8,10 @@ import {
|
|
|
8
8
|
computeGridLines,
|
|
9
9
|
renderChart,
|
|
10
10
|
type RenderChartOptions,
|
|
11
|
+
type RenderChartResult,
|
|
11
12
|
} from "../../core/renderer";
|
|
12
13
|
import { renderNativeChartBase, type NativeChartBitmap } from "../../native/chart-rasterizer";
|
|
14
|
+
import { useShowChartTextFallback } from "../../native/use-chart-text-fallback";
|
|
13
15
|
import { useStaticChartBitmapSize } from "./bitmap";
|
|
14
16
|
import {
|
|
15
17
|
StaticXAxisLabels,
|
|
@@ -103,6 +105,7 @@ export function StaticChartSurface({
|
|
|
103
105
|
}: StaticChartSurfaceProps) {
|
|
104
106
|
const themeColors = useThemeColors();
|
|
105
107
|
const { cellWidthPx = 8, cellHeightPx = 18 } = useUiCapabilities();
|
|
108
|
+
const showTextFallback = useShowChartTextFallback();
|
|
106
109
|
const plotRef = useRef<BoxRenderable | null>(null);
|
|
107
110
|
const [cursor, setCursor] = useState<{ x: number; y: number } | null>(null);
|
|
108
111
|
const xAxisRows = showTimeAxis || (xAxisLabels?.length ?? 0) > 0 ? 1 : 0;
|
|
@@ -157,13 +160,13 @@ export function StaticChartSurface({
|
|
|
157
160
|
const axisGap = axisWidth > 0 ? 1 : 0;
|
|
158
161
|
const plotWidth = Math.max(1, totalWidth - axisWidth - axisGap);
|
|
159
162
|
const bitmapSize = useStaticChartBitmapSize(plotWidth, plotHeight);
|
|
160
|
-
const
|
|
163
|
+
const plotOptions = useMemo<RenderChartOptions>(() => ({
|
|
161
164
|
width: plotWidth,
|
|
162
165
|
height: plotHeight,
|
|
163
166
|
showVolume,
|
|
164
167
|
volumeHeight,
|
|
165
|
-
cursorX:
|
|
166
|
-
cursorY:
|
|
168
|
+
cursorX: null,
|
|
169
|
+
cursorY: null,
|
|
167
170
|
mode,
|
|
168
171
|
axisMode,
|
|
169
172
|
currency,
|
|
@@ -180,15 +183,45 @@ export function StaticChartSurface({
|
|
|
180
183
|
mode,
|
|
181
184
|
plotHeight,
|
|
182
185
|
plotWidth,
|
|
183
|
-
cursor,
|
|
184
186
|
showVolume,
|
|
185
187
|
timeAxisDates,
|
|
186
188
|
volumeHeight,
|
|
187
189
|
]);
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
190
|
+
const cursorOptions = useMemo<RenderChartOptions>(() => ({
|
|
191
|
+
...plotOptions,
|
|
192
|
+
cursorX: cursor?.x ?? null,
|
|
193
|
+
cursorY: cursor?.y ?? null,
|
|
194
|
+
}), [cursor, plotOptions]);
|
|
195
|
+
const plotScene = useMemo(
|
|
196
|
+
() => buildChartScene(points, plotOptions),
|
|
197
|
+
[plotOptions, points],
|
|
198
|
+
);
|
|
199
|
+
const cursorScene = useMemo(
|
|
200
|
+
() => {
|
|
201
|
+
if (showTextFallback || !cursor) return plotScene;
|
|
202
|
+
return buildChartScene(points, cursorOptions);
|
|
203
|
+
},
|
|
204
|
+
[cursor, cursorOptions, plotScene, points, showTextFallback],
|
|
191
205
|
);
|
|
206
|
+
const textResult = useMemo<RenderChartResult>(() => {
|
|
207
|
+
if (showTextFallback) return renderChart(points, cursorOptions);
|
|
208
|
+
return {
|
|
209
|
+
lines: [],
|
|
210
|
+
axisLabels: [],
|
|
211
|
+
timeLabels: cursorScene?.timeLabels ?? "",
|
|
212
|
+
activePoint: cursorScene?.activePoint ?? null,
|
|
213
|
+
priceAtCursor: cursorScene?.priceAtCursor ?? null,
|
|
214
|
+
crosshairPrice: cursorScene?.crosshairPrice ?? null,
|
|
215
|
+
dateAtCursor: cursorScene?.dateAtCursor ?? null,
|
|
216
|
+
changeAtCursor: cursorScene?.changeAtCursor ?? null,
|
|
217
|
+
changePctAtCursor: cursorScene?.changePctAtCursor ?? null,
|
|
218
|
+
cursorColumn: cursorScene?.cursorColumn ?? null,
|
|
219
|
+
cursorRow: cursorScene?.cursorRow ?? null,
|
|
220
|
+
axisFractionDigits: null,
|
|
221
|
+
priceRange: cursorScene ? cursorScene.max - cursorScene.min : null,
|
|
222
|
+
pixelBuffer: null,
|
|
223
|
+
};
|
|
224
|
+
}, [cursorOptions, cursorScene, points, showTextFallback]);
|
|
192
225
|
const effectiveAxisLabelsByRow = useMemo(() => {
|
|
193
226
|
return new Map(axisLabels.map((entry) => [entry.row, entry.label] as const));
|
|
194
227
|
}, [axisLabels]);
|
|
@@ -203,11 +236,9 @@ export function StaticChartSurface({
|
|
|
203
236
|
const effectiveAxisWidth = axisWidth;
|
|
204
237
|
const effectiveAxisGap = effectiveAxisWidth > 0 ? 1 : 0;
|
|
205
238
|
const bitmap = useMemo<NativeChartBitmap | null>(() => {
|
|
206
|
-
if (!bitmapSize) return null;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return renderNativeChartBase(scene, bitmapSize.pixelWidth, bitmapSize.pixelHeight);
|
|
210
|
-
}, [bitmapSize, points, renderOptions]);
|
|
239
|
+
if (!bitmapSize || !plotScene) return null;
|
|
240
|
+
return renderNativeChartBase(plotScene, bitmapSize.pixelWidth, bitmapSize.pixelHeight);
|
|
241
|
+
}, [bitmapSize, plotScene]);
|
|
211
242
|
const canvasCrosshair = useMemo<ChartSurfaceProps["crosshair"]>(() => {
|
|
212
243
|
if (!bitmap || !cursor) return null;
|
|
213
244
|
return {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useCallback, useMemo, useRef } from "react";
|
|
2
|
-
import { Box, ChartSurface, Text, type BoxRenderable } from "../../../ui";
|
|
2
|
+
import { Box, ChartSurface, Text, type BoxRenderable, type ChartSurfaceProps } from "../../../ui";
|
|
3
3
|
import { colors } from "../../../theme/colors";
|
|
4
4
|
import { computeGridLines, formatAxisCell } from "../core/renderer";
|
|
5
5
|
import type { NativeChartBitmap } from "../native/chart-rasterizer";
|
|
6
|
+
import { useShowChartTextFallback } from "../native/use-chart-text-fallback";
|
|
6
7
|
import { useStaticChartBitmapSize } from "./chart/bitmap";
|
|
7
8
|
import {
|
|
8
9
|
buildMultiLineChartScene,
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
renderMultiLineTimeAxis,
|
|
11
12
|
renderNativeMultiLineChart,
|
|
12
13
|
resolveMultiLineCursorDate,
|
|
14
|
+
valueToPixelY,
|
|
13
15
|
type MultiLineChartColors,
|
|
14
16
|
type MultiLineChartSeries,
|
|
15
17
|
} from "../multi-line/renderer";
|
|
@@ -101,15 +103,27 @@ export function StaticMultiLineChartSurface({
|
|
|
101
103
|
: 0;
|
|
102
104
|
const axisGap = axisWidth > 0 ? 1 : 0;
|
|
103
105
|
const plotWidth = Math.max(1, totalWidth - axisWidth - axisGap);
|
|
104
|
-
const
|
|
106
|
+
const plotOptions = useMemo(() => ({
|
|
105
107
|
width: plotWidth,
|
|
106
108
|
height: plotHeight,
|
|
107
109
|
colors: chartColors,
|
|
108
110
|
dates,
|
|
109
|
-
cursorDate,
|
|
111
|
+
cursorDate: null as Date | null,
|
|
110
112
|
yDomain,
|
|
111
|
-
}), [chartColors,
|
|
112
|
-
const
|
|
113
|
+
}), [chartColors, dates, plotHeight, plotWidth, yDomain]);
|
|
114
|
+
const scene = useMemo(
|
|
115
|
+
() => buildMultiLineChartScene(series, plotOptions),
|
|
116
|
+
[plotOptions, series],
|
|
117
|
+
);
|
|
118
|
+
const cursorScene = useMemo(
|
|
119
|
+
() => cursorDate == null ? scene : buildMultiLineChartScene(series, { ...plotOptions, cursorDate }),
|
|
120
|
+
[cursorDate, plotOptions, scene, series],
|
|
121
|
+
);
|
|
122
|
+
const showTextFallback = useShowChartTextFallback();
|
|
123
|
+
const textLines = useMemo(() => {
|
|
124
|
+
if (!showTextFallback) return [];
|
|
125
|
+
return cursorScene ? renderMultiLineChart(cursorScene) : [];
|
|
126
|
+
}, [cursorScene, showTextFallback]);
|
|
113
127
|
const timeLabels = useMemo(() => scene ? renderMultiLineTimeAxis(scene) : "", [scene]);
|
|
114
128
|
const effectiveAxisLabelsByRow = useMemo(() => {
|
|
115
129
|
return new Map(axisLabels.map((entry) => [entry.row, entry.label] as const));
|
|
@@ -119,6 +133,27 @@ export function StaticMultiLineChartSurface({
|
|
|
119
133
|
if (!scene || !bitmapSize) return null;
|
|
120
134
|
return renderNativeMultiLineChart(scene, bitmapSize.pixelWidth, bitmapSize.pixelHeight);
|
|
121
135
|
}, [bitmapSize, scene]);
|
|
136
|
+
const canvasCrosshair = useMemo<ChartSurfaceProps["crosshair"]>(() => {
|
|
137
|
+
if (!bitmap || !cursorScene || cursorScene.cursorX === null) return null;
|
|
138
|
+
const pixelX = (cursorScene.cursorX / Math.max(cursorScene.width - 1, 1)) * Math.max(bitmap.width - 1, 0);
|
|
139
|
+
const cursorIndex = cursorScene.cursorIndex;
|
|
140
|
+
const markers = cursorIndex === null
|
|
141
|
+
? []
|
|
142
|
+
: cursorScene.series.flatMap((item) => {
|
|
143
|
+
const point = item.points[cursorIndex];
|
|
144
|
+
if (!point) return [];
|
|
145
|
+
return [{
|
|
146
|
+
pixelY: valueToPixelY(point.value, cursorScene.min, cursorScene.max, bitmap.height),
|
|
147
|
+
color: item.color,
|
|
148
|
+
}];
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
pixelX,
|
|
152
|
+
pixelY: markers[0]?.pixelY ?? bitmap.height / 2,
|
|
153
|
+
color: chartColors.crosshairColor,
|
|
154
|
+
markers: markers.length > 0 ? markers : undefined,
|
|
155
|
+
};
|
|
156
|
+
}, [bitmap, chartColors.crosshairColor, cursorScene]);
|
|
122
157
|
|
|
123
158
|
const handleCursorEvent = useCallback((event: ChartMouseEventLike) => {
|
|
124
159
|
if (!scene || !onCursorDateChange) return;
|
|
@@ -152,6 +187,7 @@ export function StaticMultiLineChartSurface({
|
|
|
152
187
|
height={plotHeight}
|
|
153
188
|
flexDirection="column"
|
|
154
189
|
bitmaps={bitmap ? [bitmap] : null}
|
|
190
|
+
crosshair={canvasCrosshair}
|
|
155
191
|
onMouseMove={handleCursorEvent}
|
|
156
192
|
onMouseDown={handleCursorEvent}
|
|
157
193
|
>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
applyTheme,
|
|
12
12
|
clearTransientThemePreview,
|
|
13
13
|
} from "../../../../theme/colors";
|
|
14
|
+
import { clampFontSize, MIN_FONT_SIZE_PX } from "../../../../theme/font-scale";
|
|
14
15
|
import type { AppAction, AppState } from "../../../../state/app/context";
|
|
15
16
|
import { isManualPortfolio } from "../../../../plugins/builtin/portfolio-list/mutations";
|
|
16
17
|
import { CHART_RENDERER_PREFERENCES } from "../../../chart/core/types";
|
|
@@ -262,6 +263,23 @@ export function runDirectCommandAction(options: {
|
|
|
262
263
|
closeAll({ revertThemePreview: false });
|
|
263
264
|
return;
|
|
264
265
|
}
|
|
266
|
+
case "font-size-increase":
|
|
267
|
+
case "font-size-decrease": {
|
|
268
|
+
const delta = command.id === "font-size-increase" ? 1 : -1;
|
|
269
|
+
const current = clampFontSize(state.config.fontSize);
|
|
270
|
+
const next = clampFontSize(current + delta);
|
|
271
|
+
if (next === current) {
|
|
272
|
+
notify(`Font size already at ${next === MIN_FONT_SIZE_PX ? "minimum" : "maximum"} (${next}px)`, { type: "info" });
|
|
273
|
+
closeAll({ revertThemePreview: false });
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const nextConfig = { ...state.config, fontSize: next };
|
|
277
|
+
dispatch({ type: "SET_CONFIG", config: nextConfig });
|
|
278
|
+
persistConfig(nextConfig);
|
|
279
|
+
notify(`Font size: ${next}px`, { type: "success" });
|
|
280
|
+
closeAll({ revertThemePreview: false });
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
265
283
|
case "check-for-updates":
|
|
266
284
|
void onCheckForUpdates?.();
|
|
267
285
|
closeAll({ revertThemePreview: false });
|
|
@@ -173,6 +173,20 @@ export const commands: Command[] = [
|
|
|
173
173
|
description: "Turn quote update flashing on or off",
|
|
174
174
|
category: "Config",
|
|
175
175
|
},
|
|
176
|
+
{
|
|
177
|
+
id: "font-size-increase",
|
|
178
|
+
prefix: "FONT+",
|
|
179
|
+
label: "Increase Font Size",
|
|
180
|
+
description: "Increase the app-wide font size",
|
|
181
|
+
category: "Config",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "font-size-decrease",
|
|
185
|
+
prefix: "FONT-",
|
|
186
|
+
label: "Decrease Font Size",
|
|
187
|
+
description: "Decrease the app-wide font size",
|
|
188
|
+
category: "Config",
|
|
189
|
+
},
|
|
176
190
|
{
|
|
177
191
|
id: "check-for-updates",
|
|
178
192
|
prefix: "",
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { NewsArticle } from "../../../../news/types";
|
|
3
|
+
import { buildArticleSearchResultItems } from "./article-results";
|
|
4
|
+
import { isArticleLookupShortcut } from "./results";
|
|
5
|
+
|
|
6
|
+
function article(title: string, source: string): NewsArticle {
|
|
7
|
+
return {
|
|
8
|
+
id: title,
|
|
9
|
+
title,
|
|
10
|
+
source,
|
|
11
|
+
url: `https://example.com/${title}`,
|
|
12
|
+
publishedAt: new Date("2026-08-14T12:00:00Z"),
|
|
13
|
+
topic: "general",
|
|
14
|
+
topics: [],
|
|
15
|
+
sectors: [],
|
|
16
|
+
categories: [],
|
|
17
|
+
tickers: [],
|
|
18
|
+
scores: { importance: 50, urgency: 0, marketImpact: 0, novelty: 0, confidence: 0 },
|
|
19
|
+
isBreaking: false,
|
|
20
|
+
isDeveloping: false,
|
|
21
|
+
importance: 50,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe("buildArticleSearchResultItems", () => {
|
|
26
|
+
test("offers the matching article to open", () => {
|
|
27
|
+
const opened: string[] = [];
|
|
28
|
+
const items = buildArticleSearchResultItems({
|
|
29
|
+
articles: [
|
|
30
|
+
article("Iran Threatens to Close the Strait of Hormuz", "Reuters"),
|
|
31
|
+
article("Fed holds rates", "CNBC Top News"),
|
|
32
|
+
],
|
|
33
|
+
query: "article on the strait",
|
|
34
|
+
phase: "ready",
|
|
35
|
+
onOpen: (item) => {
|
|
36
|
+
opened.push(item.id);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(items).toHaveLength(1);
|
|
41
|
+
expect(items[0]?.label).toContain("Hormuz");
|
|
42
|
+
expect(items[0]?.detail).toBe("Reuters");
|
|
43
|
+
items[0]?.action();
|
|
44
|
+
expect(opened).toEqual(["Iran Threatens to Close the Strait of Hormuz"]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("shows a lookup row while subscribed feeds are still loading", () => {
|
|
48
|
+
const items = buildArticleSearchResultItems({
|
|
49
|
+
articles: [],
|
|
50
|
+
query: "article on the strait",
|
|
51
|
+
phase: "loading",
|
|
52
|
+
onOpen: () => {},
|
|
53
|
+
});
|
|
54
|
+
expect(items.map((item) => item.label)).toEqual(["Looking up articles…"]);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("returns local matches without waiting on a still-loading lookup", () => {
|
|
58
|
+
const items = buildArticleSearchResultItems({
|
|
59
|
+
articles: [article("Trump administration pauses talks", "AP")],
|
|
60
|
+
query: "ART trum",
|
|
61
|
+
phase: "loading",
|
|
62
|
+
onOpen: () => {},
|
|
63
|
+
});
|
|
64
|
+
expect(items.map((item) => item.label)).toEqual(["Trump administration pauses talks"]);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe("isArticleLookupShortcut", () => {
|
|
69
|
+
test("treats the ART plugin command as an article lookup", () => {
|
|
70
|
+
expect(isArticleLookupShortcut({ kind: "none" })).toBe(false);
|
|
71
|
+
expect(isArticleLookupShortcut({
|
|
72
|
+
kind: "partial",
|
|
73
|
+
source: "plugin-command",
|
|
74
|
+
prefix: "ART",
|
|
75
|
+
label: "Open Article",
|
|
76
|
+
description: "",
|
|
77
|
+
argKind: "text",
|
|
78
|
+
argText: "hormuz",
|
|
79
|
+
completionQuery: null,
|
|
80
|
+
command: { id: "open-news-article", label: "Open Article" } as never,
|
|
81
|
+
})).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { NewsArticle } from "../../../../news/types";
|
|
2
|
+
import {
|
|
3
|
+
looksLikeArticleQuery,
|
|
4
|
+
searchNewsArticles,
|
|
5
|
+
} from "../../../../plugins/builtin/news/wire/article-search";
|
|
6
|
+
import type { ResultItem } from "../../list/model";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Builds command-bar rows for an article-lookup (`ART`) query by matching the
|
|
10
|
+
* typed text against the loaded news feed.
|
|
11
|
+
*/
|
|
12
|
+
export function buildArticleSearchResultItems(options: {
|
|
13
|
+
articles: readonly NewsArticle[];
|
|
14
|
+
query: string;
|
|
15
|
+
phase?: "idle" | "loading" | "ready" | "refreshing" | "error";
|
|
16
|
+
onOpen: (article: NewsArticle) => void;
|
|
17
|
+
}): ResultItem[] {
|
|
18
|
+
const query = options.query.trim();
|
|
19
|
+
if (!query || !looksLikeArticleQuery(query)) return [];
|
|
20
|
+
|
|
21
|
+
const matches = searchNewsArticles(options.articles, query);
|
|
22
|
+
const items = matches.map((article) => ({
|
|
23
|
+
id: `article:${article.id}`,
|
|
24
|
+
label: article.title,
|
|
25
|
+
detail: article.source,
|
|
26
|
+
category: "Articles",
|
|
27
|
+
kind: "action" as const,
|
|
28
|
+
right: "ART",
|
|
29
|
+
searchText: [
|
|
30
|
+
article.title,
|
|
31
|
+
article.source,
|
|
32
|
+
article.summary ?? "",
|
|
33
|
+
...article.topics,
|
|
34
|
+
...article.categories,
|
|
35
|
+
"article",
|
|
36
|
+
"news",
|
|
37
|
+
"press",
|
|
38
|
+
].join(" "),
|
|
39
|
+
action: () => options.onOpen(article),
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
if (items.length > 0) return items;
|
|
43
|
+
if (options.phase === "loading" || options.phase === "idle" || options.phase === "refreshing") {
|
|
44
|
+
return [{
|
|
45
|
+
id: "article:loading",
|
|
46
|
+
label: "Looking up articles…",
|
|
47
|
+
detail: "",
|
|
48
|
+
category: "Articles",
|
|
49
|
+
kind: "info",
|
|
50
|
+
defaultSelectable: false,
|
|
51
|
+
action: () => {},
|
|
52
|
+
}];
|
|
53
|
+
}
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
@@ -142,6 +142,9 @@ export function createRootCommandItemBuilder({
|
|
|
142
142
|
return command.description;
|
|
143
143
|
case "toggle-value-flashing":
|
|
144
144
|
return state.config.valueFlashingEnabled ? "Currently on" : "Currently off";
|
|
145
|
+
case "font-size-increase":
|
|
146
|
+
case "font-size-decrease":
|
|
147
|
+
return `Currently ${state.config.fontSize ?? 12}px`;
|
|
145
148
|
default:
|
|
146
149
|
return command.description;
|
|
147
150
|
}
|
|
@@ -98,7 +98,7 @@ export function useRootProviderSearch(options: {
|
|
|
98
98
|
);
|
|
99
99
|
const localItems = localTickerSearchResultItems(searchQuery, { limit: 6 });
|
|
100
100
|
setRootProviderResults(cachedCandidates
|
|
101
|
-
? mergeTickerSearchResultItems(searchQuery,
|
|
101
|
+
? mergeTickerSearchResultItems(searchQuery, buildTickerSearchResultItems(cachedCandidates, searchQuery), localItems)
|
|
102
102
|
: null);
|
|
103
103
|
setRootProviderResultsQuery(cachedCandidates ? searchQuery : null);
|
|
104
104
|
|
|
@@ -125,8 +125,8 @@ export function useRootProviderSearch(options: {
|
|
|
125
125
|
);
|
|
126
126
|
setRootProviderResults(mergeTickerSearchResultItems(
|
|
127
127
|
searchQuery,
|
|
128
|
-
localTickerSearchResultItems(searchQuery, { limit: 6 }),
|
|
129
128
|
buildTickerSearchResultItems(combined, searchQuery),
|
|
129
|
+
localTickerSearchResultItems(searchQuery, { limit: 6 }),
|
|
130
130
|
));
|
|
131
131
|
setRootProviderResultsQuery(searchQuery);
|
|
132
132
|
} catch {
|
|
@@ -178,7 +178,11 @@ export function useRootProviderSearch(options: {
|
|
|
178
178
|
rootResultItems,
|
|
179
179
|
rootTickerSearchArg,
|
|
180
180
|
]);
|
|
181
|
-
const rootSectionOrder: CommandBarSectionOrder = rootPlainTickerSearchArg
|
|
181
|
+
const rootSectionOrder: CommandBarSectionOrder = rootPlainTickerSearchArg
|
|
182
|
+
? "app-first"
|
|
183
|
+
: rootTickerSearchArg
|
|
184
|
+
? "ranked"
|
|
185
|
+
: "default";
|
|
182
186
|
const orderedRootResults = useMemo(
|
|
183
187
|
() => orderListResults(rootResults, { sectionOrder: rootSectionOrder }),
|
|
184
188
|
[rootResults, rootSectionOrder],
|