gloomberb 0.17.6 → 0.18.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/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/package.json +6 -1
- package/patches/electrobun@1.18.1.patch +74 -0
- package/src/account/auth-model.ts +3 -2
- package/src/account/device-signin-dialog.tsx +38 -13
- package/src/account/device-signin.ts +2 -1
- package/src/account/upgrade-dialog.tsx +6 -2
- package/src/api-client/askg.ts +5 -3
- package/src/api-client/bank-figures.ts +73 -0
- package/src/api-client/credit-boards.ts +21 -1
- package/src/api-client/crypto-markets.ts +88 -1
- package/src/api-client/data.ts +104 -4
- package/src/api-client/debt-maturities.ts +18 -0
- package/src/api-client/equity-screener.ts +3 -0
- package/src/api-client/errors.ts +13 -0
- package/src/api-client/fund-facts.ts +72 -0
- package/src/api-client/futures-curve.ts +26 -3
- package/src/api-client/geo.ts +11 -1
- package/src/api-client/index.ts +25 -2
- package/src/api-client/insider-signals.ts +95 -11
- package/src/api-client/normalizers.ts +1 -0
- package/src/api-client/paths.ts +20 -1
- package/src/api-client/request.ts +11 -3
- package/src/api-client/research-activity.ts +15 -8
- package/src/api-client/socket.ts +6 -3
- package/src/api-client/supply-chain-graph.ts +2 -2
- package/src/api-client/supply-chain.ts +8 -0
- package/src/api-client/tape.ts +12 -0
- package/src/api-client/types.ts +66 -2
- package/src/api-client/upgrade-experiment.ts +4 -3
- package/src/api-client/wall-experiments.ts +5 -3
- package/src/api-client/wall-summary.ts +3 -1
- package/src/api-client/web-experiments.ts +5 -2
- package/src/api-client/yield-curves.ts +17 -0
- package/src/app/command-bar-intro.ts +38 -0
- package/src/app/keybindings/actions.ts +1 -1
- package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
- package/src/app/pane-runtime/plugin-bindings.ts +4 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
- package/src/app/pane-runtime/ticker-open-target.ts +31 -0
- package/src/app/runtime/desktop-deeplink.ts +3 -4
- package/src/app/runtime/plugin-bindings.ts +3 -2
- package/src/app/runtime/startup.ts +3 -4
- package/src/app/runtime/ticker-refresh.ts +13 -12
- package/src/app/runtime/update.ts +3 -2
- package/src/architecture/core-builtin-allowlist.json +0 -3
- package/src/architecture/silent-catch-allowlist.json +3 -0
- package/src/architecture/ui-literals-allowlist.json +186 -0
- package/src/architecture/ui-tokens-allowlist.json +40 -0
- package/src/ask-gloom/pane-context.ts +3 -1
- package/src/brokers/signed-in/catalog.ts +2 -1
- package/src/brokers/signed-in/client.ts +7 -2
- package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
- package/src/brokers/signed-in/sign-in.ts +22 -20
- package/src/brokers/sync-broker-instance.ts +2 -1
- package/src/capabilities/chart-series.ts +2 -0
- package/src/capabilities/registry.ts +1 -3
- package/src/cli/bank-section.ts +147 -0
- package/src/cli/base-converter.ts +5 -2
- package/src/cli/board-coins.ts +70 -0
- package/src/cli/commands/fred-series.ts +90 -0
- package/src/cli/commands/market.ts +340 -69
- package/src/cli/commands/news-search.ts +35 -2
- package/src/cli/commands/options-chain.ts +7 -5
- package/src/cli/commands/options-leaps.ts +3 -3
- package/src/cli/commands/overview.ts +78 -29
- package/src/cli/commands/plugins.ts +1 -0
- package/src/cli/commands/search.ts +87 -24
- package/src/cli/commands/system.ts +5 -2
- package/src/cli/commands/ticker.ts +337 -60
- package/src/cli/context.ts +2 -1
- package/src/cli/desktop-pane-shot.ts +11 -3
- package/src/cli/earnings-calendar.ts +2 -1
- package/src/cli/errors.ts +10 -0
- package/src/cli/export-source.ts +18 -3
- package/src/cli/glossary.ts +196 -14
- package/src/cli/history-rows.ts +60 -9
- package/src/cli/index-roots.ts +26 -0
- package/src/cli/index.ts +34 -9
- package/src/cli/known-gaps.ts +156 -22
- package/src/cli/listing-arg.ts +156 -12
- package/src/cli/listing-suggestion.ts +4 -2
- package/src/cli/name-entries.ts +76 -0
- package/src/cli/not-a-ticker.ts +15 -6
- package/src/cli/pane-functions/access-gate.ts +22 -0
- package/src/cli/pane-functions/capabilities.ts +62 -4
- package/src/cli/pane-functions/catalog.ts +94 -39
- package/src/cli/pane-functions/data.ts +6 -5
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +3 -3
- package/src/cli/pane-functions/freshness.ts +49 -8
- package/src/cli/pane-functions/function-help.ts +13 -10
- package/src/cli/pane-functions/headless.ts +177 -42
- package/src/cli/pane-functions/index.ts +64 -8
- package/src/cli/pane-functions/options.ts +17 -3
- package/src/cli/pane-functions/report-notices.ts +17 -3
- package/src/cli/pane-functions/resolver.ts +48 -13
- package/src/cli/pane-functions/screenshot.ts +124 -23
- package/src/cli/pane-functions/shot-options.ts +68 -0
- package/src/cli/perpetual-contract.ts +3 -1
- package/src/cli/report-tables.ts +10 -2
- package/src/cli/staged-tickers.ts +5 -0
- package/src/cli/statement-filings.ts +261 -0
- package/src/cli/symbol-args.ts +47 -8
- package/src/cli/symbol-list.ts +9 -2
- package/src/cli/symbol-rows.ts +269 -29
- package/src/cli/ticker-resolution.ts +148 -34
- package/src/cli/treasury-yields.ts +86 -0
- package/src/cli/types.ts +3 -0
- package/src/cli/uncovered-instrument.ts +20 -0
- package/src/components/chart/composite/axis-overlays.tsx +16 -9
- package/src/components/chart/composite/composite-chart.tsx +85 -6
- package/src/components/chart/composite/downsample.ts +19 -3
- package/src/components/chart/composite/format.ts +3 -0
- package/src/components/chart/composite/legend.tsx +155 -76
- package/src/components/chart/composite/panel-bitmap.ts +8 -2
- package/src/components/chart/composite/panel-surface.tsx +3 -3
- package/src/components/chart/composite/toolbar.tsx +12 -7
- package/src/components/chart/composite/types.ts +6 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
- package/src/components/chart/curve/curve-surface.tsx +1 -1
- package/src/components/chart/static/series.ts +39 -0
- package/src/components/chart/static/trail-chart-surface.tsx +2 -1
- package/src/components/command-bar/commands/collection-list.ts +45 -15
- package/src/components/command-bar/commands/collection.ts +10 -3
- package/src/components/command-bar/commands/registry.ts +2 -2
- package/src/components/command-bar/list/badge.ts +4 -3
- package/src/components/command-bar/list/model.ts +5 -0
- package/src/components/command-bar/list/view.tsx +1 -1
- package/src/components/command-bar/panel/index.tsx +19 -8
- package/src/components/command-bar/panel/native-surface.ts +6 -4
- package/src/components/command-bar/panel/prompt-example.ts +22 -0
- package/src/components/command-bar/routes/root/provider-search.ts +3 -9
- package/src/components/command-bar/routes/root/results.ts +13 -0
- package/src/components/command-bar/routes/root/start-here.ts +90 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
- package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
- package/src/components/command-bar/theme-picker.tsx +3 -1
- package/src/components/command-bar/workflow/builtin.ts +5 -1
- package/src/components/command-bar/workflow/collection-actions.ts +21 -12
- package/src/components/command-bar/workflow/ops.ts +21 -1
- package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
- package/src/components/command-bar/workflow/tickers.ts +6 -4
- package/src/components/feedback-dialog.tsx +1 -1
- package/src/components/form-modal/broker-step.tsx +7 -63
- package/src/components/form-modal/content.tsx +7 -2
- package/src/components/form-modal/field-row.tsx +6 -8
- package/src/components/form-modal/host.tsx +3 -3
- package/src/components/form-modal/model.ts +3 -0
- package/src/components/form-modal/routes.ts +17 -2
- package/src/components/index.ts +6 -6
- package/src/components/input-search-bar.tsx +43 -6
- package/src/components/layout/detached-pane-shell.tsx +0 -1
- package/src/components/layout/floating-pane.tsx +0 -1
- package/src/components/layout/header.tsx +8 -7
- package/src/components/layout/pane/footer/index.tsx +7 -4
- package/src/components/layout/pane/footer/model.ts +28 -2
- package/src/components/layout/pane/header.tsx +9 -19
- package/src/components/layout/pane/index.tsx +0 -1
- package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
- package/src/components/layout/pane/pane-tabs.tsx +4 -3
- package/src/components/layout/pane/sizing.ts +9 -0
- package/src/components/layout/pane/ticker-fate-gate.tsx +8 -2
- package/src/components/layout/shell/pane/capture.ts +44 -20
- package/src/components/layout/status-bar.tsx +3 -6
- package/src/components/markdown-text.tsx +17 -2
- package/src/components/market-board/index.tsx +19 -8
- package/src/components/metric-treemap/heat-surface.tsx +2 -7
- package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
- package/src/components/onboarding/onboarding-frame.tsx +24 -21
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
- package/src/components/onboarding/wizard-positions.ts +40 -11
- package/src/components/pane-settings-dialog/desktop.tsx +12 -50
- package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
- package/src/components/price-performance.tsx +18 -2
- package/src/components/reader/article-reader.tsx +11 -10
- package/src/components/reader/detail-reader.tsx +9 -5
- package/src/components/reader/reader-text.tsx +51 -24
- package/src/components/sign-in-code-panel.tsx +129 -75
- package/src/components/ticker/badge/index.tsx +2 -1
- package/src/components/ui/action-row.tsx +5 -2
- package/src/components/ui/audio-player.tsx +70 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/data-table/index.tsx +4 -2
- package/src/components/ui/data-table/types.ts +11 -0
- package/src/components/ui/detail-scroll-body.tsx +1 -1
- package/src/components/ui/dialog-actions.tsx +1 -21
- package/src/components/ui/display.tsx +13 -5
- package/src/components/ui/external-link.tsx +4 -2
- package/src/components/ui/fields.tsx +12 -0
- package/src/components/ui/figure.tsx +5 -3
- package/src/components/ui/frame.tsx +40 -6
- package/src/components/ui/icon.tsx +4 -0
- package/src/components/ui/index.ts +4 -1
- package/src/components/ui/list-view.tsx +8 -0
- package/src/components/ui/prose.tsx +97 -25
- package/src/components/ui/query-bar-keys.tsx +3 -1
- package/src/components/ui/query-bar.tsx +6 -0
- package/src/components/ui/quote.ts +42 -0
- package/src/components/ui/range-track.tsx +15 -2
- package/src/components/ui/reveal-in-scroll-box.ts +21 -3
- package/src/components/ui/select-button.tsx +38 -3
- package/src/components/ui/status.tsx +73 -4
- package/src/components/ui/table-layout.ts +20 -0
- package/src/components/use-pinned-moment.ts +19 -0
- package/src/core/app-runtime.ts +2 -2
- package/src/core/state/app/instrument.ts +18 -1
- package/src/core/state/app/layout.ts +6 -0
- package/src/core/state/app/state.ts +14 -2
- package/src/data/cached-query.ts +1 -1
- package/src/data/config/chart-settings.ts +3 -1
- package/src/data/config/home.ts +4 -1
- package/src/data/config/store/node.ts +9 -4
- package/src/data/config/store/normalize.ts +9 -0
- package/src/data/json-storage.ts +6 -3
- package/src/data/json-ticker-repository.ts +3 -1
- package/src/data/plugin-cache.ts +5 -1
- package/src/data/sqlite/json.ts +3 -1
- package/src/data/ticker-repository.ts +5 -2
- package/src/feedback/diagnostics.ts +2 -6
- package/src/i18n/es.ts +86 -6
- package/src/i18n/index.ts +3 -9
- package/src/i18n/ja.ts +86 -6
- package/src/i18n/ko.ts +86 -6
- package/src/i18n/zh-cn.ts +86 -6
- package/src/i18n/zh-tw.ts +86 -6
- package/src/layout-marketplace/gallery-desktop.tsx +8 -4
- package/src/market-data/bars-per-year.ts +43 -0
- package/src/market-data/bond-funds.ts +85 -0
- package/src/market-data/coordinator/auxiliary.ts +5 -2
- package/src/market-data/coordinator/index.ts +6 -5
- package/src/market-data/futures-contract.ts +102 -5
- package/src/market-data/hooks.tsx +20 -11
- package/src/market-data/market/bar-period.ts +36 -0
- package/src/market-data/market/format.ts +5 -13
- package/src/market-data/market/freshness.ts +1 -3
- package/src/market-data/market/index-level.ts +51 -0
- package/src/market-data/model-dividend-yield.ts +57 -16
- package/src/market-data/quotes/live-valuation.ts +48 -2
- package/src/market-data/realized-volatility.ts +16 -7
- package/src/market-data/tax-equivalent.ts +344 -0
- package/src/news/aggregator.ts +4 -2
- package/src/notifications/notification-log.ts +5 -3
- package/src/plugins/auto-update-node.ts +1 -0
- package/src/plugins/builtin/account-management/footer.ts +1 -1
- 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/pane.tsx +71 -19
- package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
- package/src/plugins/builtin/alerts/cli.ts +7 -18
- package/src/plugins/builtin/alerts/constants.ts +8 -0
- package/src/plugins/builtin/alerts/event-rows.ts +16 -0
- package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
- package/src/plugins/builtin/alerts/headless.ts +182 -0
- package/src/plugins/builtin/alerts/index.tsx +3 -0
- package/src/plugins/builtin/alerts/pane.tsx +1 -7
- package/src/plugins/builtin/alerts/storage.ts +17 -1
- package/src/plugins/builtin/analytics/index.tsx +6 -1
- package/src/plugins/builtin/analytics/metrics.ts +47 -9
- package/src/plugins/builtin/analytics/risk-headless.ts +14 -2
- package/src/plugins/builtin/analytics/risk-math.ts +83 -0
- package/src/plugins/builtin/analytics/risk-model.ts +97 -4
- package/src/plugins/builtin/analytics/risk-pane.tsx +11 -6
- package/src/plugins/builtin/analytics/sector-model.ts +14 -3
- package/src/plugins/builtin/awards/headless.ts +6 -5
- package/src/plugins/builtin/awards/index.tsx +1 -1
- package/src/plugins/builtin/backtest/client.ts +38 -8
- package/src/plugins/builtin/backtest/engine.ts +25 -13
- package/src/plugins/builtin/backtest/export.ts +27 -0
- package/src/plugins/builtin/backtest/format.ts +19 -3
- package/src/plugins/builtin/backtest/headless.ts +42 -28
- package/src/plugins/builtin/backtest/index.tsx +3 -0
- package/src/plugins/builtin/backtest/pane.tsx +39 -10
- package/src/plugins/builtin/backtest/report.ts +160 -0
- package/src/plugins/builtin/backtest/rules.ts +2 -0
- package/src/plugins/builtin/backtest/window.ts +112 -0
- package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
- package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
- package/src/plugins/builtin/catalysts/headless.ts +24 -13
- package/src/plugins/builtin/catalysts/index.tsx +4 -2
- package/src/plugins/builtin/catalysts/model.ts +18 -1
- package/src/plugins/builtin/catalysts/pane.tsx +2 -2
- package/src/plugins/builtin/cds/client.ts +28 -5
- package/src/plugins/builtin/cds/headless.ts +183 -31
- package/src/plugins/builtin/cds/index.tsx +1 -1
- package/src/plugins/builtin/cds/model.ts +229 -53
- package/src/plugins/builtin/cds/pane.tsx +82 -26
- package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
- package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
- package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
- package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
- package/src/plugins/builtin/chart-composer/headless.ts +99 -21
- package/src/plugins/builtin/chart-composer/index.tsx +70 -13
- package/src/plugins/builtin/chart-composer/pane.tsx +65 -15
- package/src/plugins/builtin/chart-composer/presets.ts +79 -11
- package/src/plugins/builtin/chart-composer/series-catalog.ts +50 -14
- package/src/plugins/builtin/chart-composer/series-expression.ts +9 -7
- package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
- package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
- package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
- package/src/plugins/builtin/chat/content/composer.tsx +22 -1
- package/src/plugins/builtin/chat/content/index.tsx +35 -5
- package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
- package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
- package/src/plugins/builtin/chat/content/snapshot.ts +29 -6
- package/src/plugins/builtin/chat/ghost-user.ts +11 -3
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +13 -5
- package/src/plugins/builtin/chat/message/header.tsx +26 -4
- package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
- package/src/plugins/builtin/chat/message/render-state.ts +28 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
- package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
- package/src/plugins/builtin/chat/share/flow.tsx +9 -73
- package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
- package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
- package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
- package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
- package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
- package/src/plugins/builtin/cloud/plugin.tsx +2 -0
- package/src/plugins/builtin/cloud/team/module.tsx +5 -1
- package/src/plugins/builtin/cloud/team/pane.tsx +11 -4
- package/src/plugins/builtin/cloud/team/views.ts +11 -4
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
- package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
- package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
- package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
- package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
- package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
- package/src/plugins/builtin/commodities-energy/index.tsx +8 -5
- package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
- package/src/plugins/builtin/company-attention/headless.ts +15 -7
- package/src/plugins/builtin/company-attention/index.tsx +1 -1
- package/src/plugins/builtin/company-attention/model.ts +49 -4
- package/src/plugins/builtin/company-attention/pane.tsx +11 -9
- package/src/plugins/builtin/company-kpis/headless.ts +4 -3
- package/src/plugins/builtin/company-kpis/index.tsx +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
- package/src/plugins/builtin/congress-trades/headless.ts +23 -2
- package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
- package/src/plugins/builtin/cot/headless.ts +5 -2
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
- package/src/plugins/builtin/credit-boards/client.ts +9 -2
- package/src/plugins/builtin/credit-boards/headless.ts +93 -27
- package/src/plugins/builtin/credit-boards/index.tsx +15 -4
- package/src/plugins/builtin/credit-boards/model.ts +105 -6
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
- package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
- package/src/plugins/builtin/credit-documents/index.tsx +3 -0
- package/src/plugins/builtin/credit-documents/model.ts +3 -10
- package/src/plugins/builtin/crypto-board/client.ts +152 -2
- package/src/plugins/builtin/crypto-board/headless.ts +138 -19
- package/src/plugins/builtin/crypto-board/index.tsx +5 -3
- package/src/plugins/builtin/crypto-board/model.ts +210 -12
- package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
- package/src/plugins/builtin/crypto-board/series.ts +52 -1
- package/src/plugins/builtin/crypto-board/supply.ts +123 -0
- package/src/plugins/builtin/debt-maturities/client.ts +54 -1
- package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/model.ts +58 -13
- package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
- package/src/plugins/builtin/dividend-yield/client.ts +42 -36
- package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
- package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
- package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
- package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
- package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
- package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
- package/src/plugins/builtin/dividend-yield/types.ts +6 -1
- package/src/plugins/builtin/dividend-yield/view.ts +1 -1
- package/src/plugins/builtin/docs/blocks.tsx +54 -8
- package/src/plugins/builtin/docs/pane.tsx +8 -13
- package/src/plugins/builtin/earnings/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/data.ts +51 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
- package/src/plugins/builtin/earnings-calls/model.ts +97 -0
- package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
- package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
- package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
- package/src/plugins/builtin/econ/calendar-model.ts +22 -0
- package/src/plugins/builtin/econ/calendar-source.ts +35 -0
- package/src/plugins/builtin/econ/index.tsx +40 -8
- package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +8 -1
- package/src/plugins/builtin/econ-statistics/headless.ts +26 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +4 -2
- package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
- package/src/plugins/builtin/econ-statistics/view.ts +19 -0
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +46 -4
- package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
- package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
- package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
- package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
- package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
- package/src/plugins/builtin/executives/index.tsx +1 -0
- package/src/plugins/builtin/exposure/editor.tsx +3 -3
- package/src/plugins/builtin/fear-greed/index.tsx +9 -0
- package/src/plugins/builtin/filing-events/index.tsx +1 -0
- package/src/plugins/builtin/futures/index.tsx +2 -2
- package/src/plugins/builtin/futures/model.ts +34 -21
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
- package/src/plugins/builtin/futures-curve/headless.ts +4 -2
- package/src/plugins/builtin/futures-curve/model.ts +5 -7
- package/src/plugins/builtin/help/index.tsx +55 -8
- package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
- package/src/plugins/builtin/holders/headless.ts +12 -0
- package/src/plugins/builtin/insider/headless.ts +311 -41
- package/src/plugins/builtin/insider/index.tsx +280 -106
- package/src/plugins/builtin/insider/insiders.tsx +224 -0
- package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
- package/src/plugins/builtin/insider/signals-client.ts +135 -11
- package/src/plugins/builtin/insider/signals-model.ts +628 -56
- package/src/plugins/builtin/insider/signals.tsx +283 -83
- package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
- package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
- package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
- package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
- package/src/plugins/builtin/iv-history/headless.ts +2 -0
- package/src/plugins/builtin/jobs/headless.ts +1 -0
- package/src/plugins/builtin/jobs/index.tsx +1 -0
- package/src/plugins/builtin/jodi/headless.ts +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
- package/src/plugins/builtin/market-valuation/pane.tsx +1 -1
- package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
- package/src/plugins/builtin/mna/distress/headless.ts +2 -1
- package/src/plugins/builtin/mna/headless.ts +14 -2
- package/src/plugins/builtin/mna/index.tsx +1 -0
- package/src/plugins/builtin/news/headless.ts +4 -0
- package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
- package/src/plugins/builtin/news/wire/news/table.tsx +57 -11
- package/src/plugins/builtin/notes/cli.ts +8 -4
- package/src/plugins/builtin/notes/files.ts +66 -20
- package/src/plugins/builtin/notes/migration.ts +18 -6
- package/src/plugins/builtin/notes/owner.tsx +3 -2
- package/src/plugins/builtin/notes/quick-notes-pane.tsx +3 -2
- package/src/plugins/builtin/options-scenario/client.ts +7 -4
- package/src/plugins/builtin/options-scenario/headless.ts +5 -3
- package/src/plugins/builtin/pe-band/index.tsx +1 -1
- package/src/plugins/builtin/pe-band/model.ts +1 -15
- package/src/plugins/builtin/perps/headless.ts +30 -13
- package/src/plugins/builtin/perps/model.ts +45 -3
- package/src/plugins/builtin/perps/pane.tsx +7 -7
- package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +128 -14
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +108 -46
- package/src/plugins/builtin/portfolio-list/cli/render.ts +368 -45
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +8 -2
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +24 -34
- package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +151 -29
- package/src/plugins/builtin/portfolio-list/income.ts +296 -0
- package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
- package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +27 -10
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +3 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +10 -3
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +26 -4
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +31 -3
- package/src/plugins/builtin/portfolio-list/table.tsx +25 -5
- package/src/plugins/builtin/power/prices-headless.ts +2 -1
- package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
- package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
- package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
- package/src/plugins/builtin/realized-vol/headless.ts +6 -4
- package/src/plugins/builtin/realized-vol/model.ts +5 -1
- package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
- package/src/plugins/builtin/realized-vol/settings.ts +1 -1
- package/src/plugins/builtin/research/analyst-headless.ts +4 -0
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -0
- package/src/plugins/builtin/research/event-model.ts +22 -2
- package/src/plugins/builtin/research/headless-schema.ts +1 -0
- package/src/plugins/builtin/research/headless.ts +3 -0
- package/src/plugins/builtin/research/index.tsx +3 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
- package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +9 -6
- package/src/plugins/builtin/reverse-dcf/index.tsx +2 -2
- package/src/plugins/builtin/reverse-dcf/model.ts +51 -4
- package/src/plugins/builtin/reverse-dcf/pane.tsx +23 -10
- package/src/plugins/builtin/risk-factors/headless.ts +7 -0
- package/src/plugins/builtin/risk-factors/index.tsx +1 -0
- package/src/plugins/builtin/scanner/feed.ts +5 -3
- package/src/plugins/builtin/scanner/headless.ts +9 -57
- package/src/plugins/builtin/scanner/index.ts +1 -2
- package/src/plugins/builtin/sec/forms.ts +2 -6
- package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
- package/src/plugins/builtin/sec/fund-facts.ts +328 -0
- package/src/plugins/builtin/sec/headless.ts +140 -44
- package/src/plugins/builtin/sec/index.tsx +95 -30
- package/src/plugins/builtin/sec/model.ts +2 -44
- package/src/plugins/builtin/shared/headless-options.ts +10 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
- package/src/plugins/builtin/shared/move-rank.ts +108 -0
- package/src/plugins/builtin/shared/report-freshness.ts +25 -9
- package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
- package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +1 -0
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
- package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
- package/src/plugins/builtin/short-interest/headless.ts +3 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
- package/src/plugins/builtin/social-mentions/client.ts +8 -1
- package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
- package/src/plugins/builtin/supply-chain/client.ts +12 -3
- package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
- package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
- package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
- package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
- package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
- package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
- package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
- package/src/plugins/builtin/supply-chain/headless.ts +69 -27
- package/src/plugins/builtin/supply-chain/index.tsx +1 -1
- package/src/plugins/builtin/supply-chain/model.ts +76 -15
- package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
- package/src/plugins/builtin/themes/model.ts +2 -5
- package/src/plugins/builtin/thirteenf/api.ts +50 -2
- package/src/plugins/builtin/thirteenf/data.ts +250 -11
- package/src/plugins/builtin/thirteenf/headless.ts +311 -28
- package/src/plugins/builtin/thirteenf/index.tsx +4 -1
- package/src/plugins/builtin/thirteenf/model.ts +244 -19
- package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
- package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
- package/src/plugins/builtin/thirteenf/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
- package/src/plugins/builtin/thirteenf/types.ts +49 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -8
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +17 -1
- package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/headless.ts +23 -10
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
- package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +36 -3
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
- package/src/plugins/builtin/time-sales/client.ts +7 -4
- package/src/plugins/builtin/time-sales/headless.ts +71 -22
- package/src/plugins/builtin/time-sales/model.ts +12 -0
- package/src/plugins/builtin/time-sales/pane.tsx +31 -7
- package/src/plugins/builtin/time-sales/window.ts +128 -0
- package/src/plugins/builtin/trace-bonds/client.ts +351 -33
- package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
- package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
- package/src/plugins/builtin/trace-bonds/model.ts +27 -25
- package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
- package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
- package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
- package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
- package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
- package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
- package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
- package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
- package/src/plugins/builtin/vol-surface/headless.ts +3 -2
- package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
- package/src/plugins/builtin/vol-surface/stored.ts +4 -7
- package/src/plugins/builtin/volatility/chart-model.ts +16 -15
- package/src/plugins/builtin/volatility/charts.tsx +5 -5
- package/src/plugins/builtin/volatility/client.ts +73 -2
- package/src/plugins/builtin/volatility/evidence.ts +13 -14
- package/src/plugins/builtin/volatility/headless.ts +13 -7
- package/src/plugins/builtin/volatility/index.tsx +1 -1
- package/src/plugins/builtin/volatility/model.ts +104 -38
- package/src/plugins/builtin/volatility/pane.tsx +42 -24
- package/src/plugins/builtin/volatility/series.ts +22 -13
- package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
- package/src/plugins/builtin/world-venue-map/headless.ts +8 -5
- package/src/plugins/builtin/world-venue-map/index.ts +16 -2
- package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
- package/src/plugins/builtin/yield-curve/curves.ts +29 -5
- package/src/plugins/builtin/yield-curve/headless.ts +41 -8
- package/src/plugins/builtin/yield-curve/history.ts +5 -5
- package/src/plugins/builtin/yield-curve/index.tsx +30 -13
- package/src/plugins/compat.ts +3 -1
- package/src/plugins/dependencies.ts +8 -2
- package/src/plugins/host-link.ts +12 -5
- package/src/plugins/installer.ts +16 -7
- package/src/plugins/loader.ts +9 -2
- package/src/plugins/marketplace/activation.ts +10 -4
- package/src/plugins/registry/host-actions.ts +3 -0
- package/src/plugins/registry/index.ts +3 -1
- package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +74 -12
- package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +140 -53
- package/src/portfolio/futures-positions.ts +213 -0
- package/src/portfolio/futures-terms.ts +75 -0
- package/src/portfolio/manual-lots.ts +78 -0
- package/src/portfolio/mutations.ts +54 -10
- package/src/portfolio/position-metrics.ts +44 -10
- package/src/portfolio/valuation-basis.ts +31 -4
- package/src/public/__snapshots__/public-api.test.ts.snap +4 -0
- package/src/public/time-series.ts +2 -1
- package/src/remote/confirm-change.tsx +2 -1
- package/src/remote/server.ts +1 -1
- package/src/remote/watchlist.ts +9 -1
- package/src/renderers/dom/data-table/row.tsx +1 -1
- package/src/renderers/dom/desktop/audio-player.tsx +312 -0
- package/src/renderers/dom/desktop/control-styles.ts +17 -82
- package/src/renderers/dom/desktop/controls.tsx +39 -63
- package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
- package/src/renderers/dom/desktop/icons.tsx +8 -0
- package/src/renderers/dom/desktop/list-view.tsx +6 -6
- package/src/renderers/dom/desktop/popover.tsx +0 -3
- package/src/renderers/dom/desktop/query-bar.tsx +6 -4
- package/src/renderers/dom/desktop/select-field.tsx +9 -8
- package/src/renderers/dom/desktop/stack-header.ts +3 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -2
- package/src/renderers/dom/host/chart-surface.tsx +3 -3
- package/src/renderers/dom/host/size-observer.ts +33 -4
- package/src/renderers/dom/host/surface-3d.tsx +3 -2
- package/src/renderers/dom/host/surface-fit.ts +4 -1
- package/src/renderers/dom/host/tabs.tsx +22 -132
- package/src/renderers/dom/styles.css +358 -160
- package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
- package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
- package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
- package/src/series/capability.ts +1 -0
- package/src/series/files.ts +9 -3
- package/src/series/registry.ts +40 -14
- package/src/series/resolve.ts +121 -18
- package/src/series/standalone.ts +3 -2
- package/src/series/types.ts +55 -1
- package/src/series/validate.ts +39 -0
- package/src/shares/api.ts +26 -7
- package/src/shares/bug-report-dialog.tsx +2 -2
- package/src/shares/bug-report-flow.tsx +4 -7
- package/src/shares/capture-flow.ts +5 -4
- package/src/shares/capture-preview.tsx +2 -2
- package/src/shares/chat.ts +7 -27
- package/src/shares/flow.tsx +86 -40
- package/src/shares/location.ts +1 -3
- package/src/shares/pane-image.ts +11 -9
- package/src/shares/pane.ts +5 -2
- package/src/shares/payload.ts +1 -1
- package/src/shares/personal-pane.ts +3 -3
- package/src/shares/portable-layout.ts +9 -2
- package/src/shares/ready.ts +42 -0
- package/src/shares/test-harness.ts +62 -0
- package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
- package/src/sources/gloomberb-cloud/index.ts +64 -12
- package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
- package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
- package/src/sources/history-omitted.ts +34 -0
- package/src/sources/history-result.ts +3 -0
- package/src/sources/history-retention.ts +1 -1
- package/src/sources/provider-errors.ts +43 -1
- package/src/sources/provider-router/batches.ts +3 -2
- package/src/sources/provider-router/cache.ts +2 -1
- package/src/sources/provider-router/cached-routes.ts +9 -3
- package/src/sources/provider-router/history.ts +9 -8
- package/src/sources/provider-router/index.ts +18 -3
- package/src/sources/provider-router/primary.ts +5 -4
- package/src/sources/provider-router/quote-route.ts +3 -1
- package/src/sources/provider-router/routing.ts +2 -1
- package/src/sources/provider-router/search.ts +47 -13
- package/src/sources/provider-router/streaming.ts +7 -4
- package/src/sources/sec-edgar.ts +1 -3
- package/src/state/app/context/index.tsx +9 -13
- package/src/state/app/tab-cursor.ts +149 -12
- package/src/state/hooks/quote-streaming.ts +3 -2
- package/src/state/hooks/session-snapshot.ts +3 -2
- package/src/state/persist-scheduler.ts +12 -4
- package/src/sync/controller.ts +22 -1
- package/src/sync/core-contributors.ts +58 -15
- package/src/team/collections-sync.ts +14 -4
- package/src/team/collections.ts +40 -11
- package/src/team/store.ts +5 -4
- package/src/telemetry/attention-counts.ts +8 -2
- package/src/telemetry/crash-reports-dom.ts +3 -0
- package/src/telemetry/crash-reports-node.ts +7 -4
- package/src/telemetry/crash-reports.ts +11 -11
- package/src/telemetry/usage-counts.ts +16 -12
- package/src/theme/colors.ts +2 -0
- package/src/theme/font-scale.ts +2 -0
- package/src/theme/ui-tokens.ts +71 -0
- package/src/tickers/batched-lookups.ts +186 -0
- package/src/tickers/company-name-listing.ts +97 -0
- package/src/tickers/company-name.ts +13 -0
- package/src/tickers/instrument-coverage.ts +112 -0
- package/src/tickers/listing-fate.ts +49 -9
- package/src/tickers/listing-venues.ts +24 -5
- package/src/tickers/open-target.ts +13 -5
- package/src/tickers/search/index.ts +112 -35
- package/src/tickers/search/ranking.ts +49 -1
- package/src/tickers/terminal-codes.ts +79 -0
- package/src/tickers/ticker-changes.ts +74 -3
- package/src/tickers/us-listing.ts +2 -1
- package/src/time-series/chart-data.ts +79 -8
- package/src/time-series/fundamentals.ts +55 -7
- package/src/time-series/ice-credit.ts +17 -2
- package/src/time-series/live-bars.ts +21 -8
- package/src/time-series/live-quotes.ts +2 -3
- package/src/time-series/price-comparison.ts +6 -1
- package/src/time-series/resolve.ts +65 -10
- package/src/time-series/spec.ts +2 -1
- package/src/time-series/studies.ts +3 -3
- package/src/time-series/types.ts +22 -0
- package/src/time-series/use-chart-resolution.ts +2 -1
- package/src/types/config.ts +7 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/headless.ts +142 -1
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +32 -9
- package/src/types/price-history.ts +5 -0
- package/src/types/ticker-changes.ts +19 -0
- package/src/types/ticker.ts +10 -2
- package/src/ui/context-menu.tsx +2 -0
- package/src/ui/host.tsx +40 -4
- package/src/ui/measured-cells.ts +13 -7
- package/src/ui/qr.ts +7 -5
- package/src/updater/index.ts +5 -5
- package/src/utils/calendar-date.ts +86 -27
- package/src/utils/currency-units.ts +17 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/dividend-cash.ts +48 -0
- package/src/utils/dom-screenshot-rasters.ts +3 -1
- package/src/utils/dom-screenshot.ts +14 -10
- package/src/utils/exchange-rate-snapshot.ts +9 -4
- package/src/utils/external-url.ts +1 -0
- package/src/utils/fiscal-period.ts +47 -0
- package/src/utils/format.ts +5 -2
- package/src/utils/forward-dividend.ts +160 -11
- package/src/utils/futures-generic.ts +34 -8
- package/src/utils/http-proxy-response.ts +2 -1
- package/src/utils/local-utc-offset.ts +2 -0
- package/src/utils/log-failure.ts +31 -0
- package/src/utils/option-expiry.ts +12 -12
- package/src/utils/price-history-integrity.ts +56 -0
- package/src/utils/price-history.ts +13 -1
- package/src/utils/sec-filings.ts +245 -0
- package/src/utils/selection-clipboard.ts +5 -2
- package/src/utils/throttled-fetch.ts +1 -0
- package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
- package/src/utils/url.ts +1 -0
- package/src/utils/utc-time.ts +11 -0
- package/src/plugins/builtin/chat/share/targets.ts +0 -27
- package/src/renderers/dom/host/top-surface.ts +0 -119
- package/src/shares/dialog.tsx +0 -221
- package/src/shares/live.ts +0 -19
|
@@ -49,6 +49,7 @@ export function resolveChatContentHeightMetrics({
|
|
|
49
49
|
replyTo,
|
|
50
50
|
stackHeader = false,
|
|
51
51
|
draftAttachmentCount = 0,
|
|
52
|
+
draftLinkCount = 0,
|
|
52
53
|
promptRows = 0,
|
|
53
54
|
}: {
|
|
54
55
|
canSend: boolean;
|
|
@@ -61,6 +62,7 @@ export function resolveChatContentHeightMetrics({
|
|
|
61
62
|
/** The narrow stack's Back row is drawn above the transcript. */
|
|
62
63
|
stackHeader?: boolean;
|
|
63
64
|
draftAttachmentCount?: number;
|
|
65
|
+
draftLinkCount?: number;
|
|
64
66
|
/** Terminal rows the handle prompt above the composer takes. */
|
|
65
67
|
promptRows?: number;
|
|
66
68
|
}) {
|
|
@@ -77,6 +79,7 @@ export function resolveChatContentHeightMetrics({
|
|
|
77
79
|
nativePaneChrome,
|
|
78
80
|
replyTo,
|
|
79
81
|
draftAttachmentCount,
|
|
82
|
+
draftLinkCount,
|
|
80
83
|
promptRows,
|
|
81
84
|
});
|
|
82
85
|
// In the terminal the Back row replaces the top rule.
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { useState, type MutableRefObject } from "react";
|
|
2
2
|
import { useShortcut } from "../../../../react/input";
|
|
3
3
|
import type { ScrollBoxRenderable } from "../../../../ui";
|
|
4
4
|
import type { ChatMessage } from "../../../../api-client";
|
|
5
5
|
import { countEscapeTowardClose } from "../../../../utils/double-escape-close";
|
|
6
6
|
import { isPlainKey } from "../../../../utils/keyboard";
|
|
7
|
+
import { createOneShot } from "../../../../utils/one-shot";
|
|
7
8
|
import { scrollToBottom } from "../layout";
|
|
8
9
|
import type { ChatSidebarRow } from "../sidebar-rows";
|
|
10
|
+
import type { ComposerShareLink } from "../pane-links/composer";
|
|
9
11
|
|
|
10
12
|
export function useChatContentShortcuts({
|
|
11
13
|
beginEditLatestMessage,
|
|
@@ -42,6 +44,8 @@ export function useChatContentShortcuts({
|
|
|
42
44
|
returnToComposer,
|
|
43
45
|
retryMessage,
|
|
44
46
|
removeLastDraftAttachment,
|
|
47
|
+
draftLinksRef,
|
|
48
|
+
removeLastDraftLink,
|
|
45
49
|
scrollRef,
|
|
46
50
|
selectedIdx,
|
|
47
51
|
setFollowMessages,
|
|
@@ -88,6 +92,10 @@ export function useChatContentShortcuts({
|
|
|
88
92
|
retryMessage: (index: number) => void;
|
|
89
93
|
/** Drops the last image waiting in the composer; false when there is none. */
|
|
90
94
|
removeLastDraftAttachment: () => boolean;
|
|
95
|
+
/** The share links waiting as chips above the field: with any, the composer is not empty. */
|
|
96
|
+
draftLinksRef: MutableRefObject<ComposerShareLink[]>;
|
|
97
|
+
/** Drops the last of them; false when there is none. */
|
|
98
|
+
removeLastDraftLink: () => boolean;
|
|
91
99
|
scrollRef: MutableRefObject<ScrollBoxRenderable | null>;
|
|
92
100
|
selectedIdx: number;
|
|
93
101
|
setFollowMessages: (followMessages: boolean) => void;
|
|
@@ -99,6 +107,10 @@ export function useChatContentShortcuts({
|
|
|
99
107
|
sidebarCursorRow: ChatSidebarRow | null;
|
|
100
108
|
sidebarFocusedRef: MutableRefObject<boolean>;
|
|
101
109
|
}) {
|
|
110
|
+
// A terminal says a key is held only where its keyboard protocol can;
|
|
111
|
+
// elsewhere a held Backspace is a stream of presses, told apart by the gaps.
|
|
112
|
+
const [backspaceShot] = useState(createOneShot);
|
|
113
|
+
|
|
102
114
|
useShortcut((event) => {
|
|
103
115
|
if (!focused || commandBarOpen || !inputFocused || !mentionMenuOpen) return;
|
|
104
116
|
if (
|
|
@@ -200,23 +212,29 @@ export function useChatContentShortcuts({
|
|
|
200
212
|
} else {
|
|
201
213
|
// Leaving an empty composer is the first half of a double-Esc close;
|
|
202
214
|
// leaving a draft is not, so a quick Esc Esc never closes over it.
|
|
203
|
-
if (inputValueRef.current.trim().length === 0) countEscapeTowardClose(event);
|
|
215
|
+
if (inputValueRef.current.trim().length === 0 && draftLinksRef.current.length === 0) countEscapeTowardClose(event);
|
|
204
216
|
blurInput();
|
|
205
217
|
}
|
|
206
218
|
return;
|
|
207
219
|
}
|
|
208
220
|
|
|
209
|
-
//
|
|
210
|
-
// empty composer takes the
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
221
|
+
// A pasted link is one chip, and the terminal's image rows have no
|
|
222
|
+
// focus of their own: Backspace in an empty composer takes the nearest
|
|
223
|
+
// one back out, the links right above the field first. One for each
|
|
224
|
+
// new press: a Backspace held to clear the text, or held on after one
|
|
225
|
+
// went, takes out nothing more. Every press counts toward the gap.
|
|
226
|
+
if (isPlainKey(event, "backspace")) {
|
|
227
|
+
const freshPress = nativePaneChrome ? event.repeat !== true : !backspaceShot.refuses({ repeat: event.repeat });
|
|
228
|
+
if (freshPress && !nativePaneChrome) backspaceShot.end();
|
|
229
|
+
if (
|
|
230
|
+
freshPress
|
|
231
|
+
&& inputValueRef.current.length === 0
|
|
232
|
+
&& (removeLastDraftLink() || (!nativePaneChrome && removeLastDraftAttachment()))
|
|
233
|
+
) {
|
|
234
|
+
event.preventDefault?.();
|
|
235
|
+
event.stopPropagation?.();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
220
238
|
}
|
|
221
239
|
|
|
222
240
|
const verticalDirection = event.name === "up" || event.name === "down" ? event.name : null;
|
|
@@ -225,6 +243,7 @@ export function useChatContentShortcuts({
|
|
|
225
243
|
&& canSend
|
|
226
244
|
&& isPlainKey(event, "up")
|
|
227
245
|
&& inputValueRef.current.trim().length === 0
|
|
246
|
+
&& draftLinksRef.current.length === 0
|
|
228
247
|
&& beginEditLatestMessage({ deferFocus: true })
|
|
229
248
|
) {
|
|
230
249
|
event.preventDefault?.();
|
|
@@ -3,6 +3,7 @@ import type { TextareaRenderable } from "../../../../ui";
|
|
|
3
3
|
import type { ChatMessage } from "../../../../api-client";
|
|
4
4
|
import type { ChatContentController } from "./types";
|
|
5
5
|
import type { ChatPrependAnchor } from "./scroll";
|
|
6
|
+
import { composerViewOfDraft, type ComposerShareLink } from "../pane-links/composer";
|
|
6
7
|
|
|
7
8
|
type ChatSnapshot = ReturnType<ChatContentController["getSnapshot"]>;
|
|
8
9
|
|
|
@@ -19,6 +20,10 @@ interface ChatSnapshotStateArgs {
|
|
|
19
20
|
inputRef: MutableRef<TextareaRenderable | null>;
|
|
20
21
|
inputValueRef: MutableRef<string>;
|
|
21
22
|
onComposerStateChange?: (draft: string, cursorOffset: number) => void;
|
|
23
|
+
/** The share links at the end of the saved draft, drawn as chips above the field. */
|
|
24
|
+
draftLinksRef: MutableRef<ComposerShareLink[]>;
|
|
25
|
+
/** Sets the chips; also updates `draftLinksRef`. */
|
|
26
|
+
onDraftLinksChange: (links: ComposerShareLink[]) => void;
|
|
22
27
|
prependAnchorRef: MutableRef<ChatPrependAnchor | null>;
|
|
23
28
|
setFollowMessages: Dispatch<SetStateAction<boolean>>;
|
|
24
29
|
setSelectedIdx: Dispatch<SetStateAction<number>>;
|
|
@@ -26,30 +31,42 @@ interface ChatSnapshotStateArgs {
|
|
|
26
31
|
useDefaultControllerChannel: boolean;
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
function sameLinks(a: readonly ComposerShareLink[], b: readonly ComposerShareLink[]): boolean {
|
|
35
|
+
return a.length === b.length && a.every((link, index) => link.url === b[index]!.url);
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
function syncDraftFromSnapshot({
|
|
30
39
|
applyingExternalDraftRef,
|
|
40
|
+
draftLinksRef,
|
|
31
41
|
inputRef,
|
|
32
42
|
inputValueRef,
|
|
33
43
|
onComposerStateChange,
|
|
44
|
+
onDraftLinksChange,
|
|
34
45
|
snapshot,
|
|
35
46
|
updateComposerRows,
|
|
36
47
|
}: {
|
|
37
48
|
applyingExternalDraftRef: MutableRef<boolean>;
|
|
49
|
+
draftLinksRef: MutableRef<ComposerShareLink[]>;
|
|
38
50
|
inputRef: MutableRef<TextareaRenderable | null>;
|
|
39
51
|
inputValueRef: MutableRef<string>;
|
|
40
52
|
onComposerStateChange?: (draft: string, cursorOffset: number) => void;
|
|
53
|
+
onDraftLinksChange: (links: ComposerShareLink[]) => void;
|
|
41
54
|
snapshot: ChatSnapshot;
|
|
42
55
|
updateComposerRows: (draft: string) => void;
|
|
43
56
|
}) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
// Every snapshot carries the draft, this composer's own included: only one
|
|
58
|
+
// that changed elsewhere is read afresh, never what is being typed.
|
|
59
|
+
const { text, links } = composerViewOfDraft(snapshot.draft, { text: inputValueRef.current, links: draftLinksRef.current });
|
|
60
|
+
if (!sameLinks(draftLinksRef.current, links)) onDraftLinksChange(links);
|
|
61
|
+
if (inputValueRef.current !== text) {
|
|
62
|
+
inputValueRef.current = text;
|
|
63
|
+
updateComposerRows(text);
|
|
64
|
+
onComposerStateChange?.(text, text.length);
|
|
48
65
|
}
|
|
49
66
|
const textarea = inputRef.current;
|
|
50
|
-
if (textarea && textarea.editBuffer.getText() !==
|
|
67
|
+
if (textarea && textarea.editBuffer.getText() !== text) {
|
|
51
68
|
applyingExternalDraftRef.current = true;
|
|
52
|
-
textarea.setText(
|
|
69
|
+
textarea.setText(text);
|
|
53
70
|
applyingExternalDraftRef.current = false;
|
|
54
71
|
}
|
|
55
72
|
}
|
|
@@ -69,6 +86,8 @@ export function useChatSnapshotState({
|
|
|
69
86
|
inputRef,
|
|
70
87
|
inputValueRef,
|
|
71
88
|
onComposerStateChange,
|
|
89
|
+
draftLinksRef,
|
|
90
|
+
onDraftLinksChange,
|
|
72
91
|
prependAnchorRef,
|
|
73
92
|
setFollowMessages,
|
|
74
93
|
setSelectedIdx,
|
|
@@ -128,9 +147,11 @@ export function useChatSnapshotState({
|
|
|
128
147
|
setDraftAttachments(snapshot.draftAttachments);
|
|
129
148
|
syncDraftFromSnapshot({
|
|
130
149
|
applyingExternalDraftRef,
|
|
150
|
+
draftLinksRef,
|
|
131
151
|
inputRef,
|
|
132
152
|
inputValueRef,
|
|
133
153
|
onComposerStateChange,
|
|
154
|
+
onDraftLinksChange,
|
|
134
155
|
snapshot,
|
|
135
156
|
updateComposerRows,
|
|
136
157
|
});
|
|
@@ -149,9 +170,11 @@ export function useChatSnapshotState({
|
|
|
149
170
|
applyingExternalDraftRef,
|
|
150
171
|
channelId,
|
|
151
172
|
controller,
|
|
173
|
+
draftLinksRef,
|
|
152
174
|
inputRef,
|
|
153
175
|
inputValueRef,
|
|
154
176
|
onComposerStateChange,
|
|
177
|
+
onDraftLinksChange,
|
|
155
178
|
prependAnchorRef,
|
|
156
179
|
setFollowMessages,
|
|
157
180
|
setSelectedIdx,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChatUserSummary } from "../../../api-client";
|
|
1
|
+
import type { ChatMessage, ChatUserSummary } from "../../../api-client";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A person on the Gloom Discord with no linked Gloom account. Their messages
|
|
@@ -18,14 +18,22 @@ export function isManagedBot(user: Pick<ChatUserSummary, "accountType"> | null |
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* A reply quotes its author by name only, so whether that author is a managed
|
|
21
|
-
* assistant comes from the users the pane has seen.
|
|
21
|
+
* assistant comes from the users the pane has seen. A quoted announcement is
|
|
22
|
+
* Gloom speaking, not a bot, when the pane has it to tell.
|
|
22
23
|
*/
|
|
23
24
|
export function isQuotedAuthorManagedBot(
|
|
24
25
|
quoted: { user: { username?: string | null } },
|
|
25
26
|
userByUsername: ReadonlyMap<string, ChatUserSummary>,
|
|
27
|
+
/** The quoted message, when the pane holds it. */
|
|
28
|
+
findQuoted?: () => Pick<ChatMessage, "announcement"> | null | undefined,
|
|
26
29
|
): boolean {
|
|
27
30
|
const username = quoted.user.username?.toLowerCase();
|
|
28
|
-
return !!username && isManagedBot(userByUsername.get(username));
|
|
31
|
+
return !!username && isManagedBot(userByUsername.get(username)) && !findQuoted?.()?.announcement;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** A message among those the pane holds, by id. */
|
|
35
|
+
export function heldMessage(messages: readonly ChatMessage[], id: string | null | undefined): ChatMessage | null {
|
|
36
|
+
return id ? messages.find((message) => message.id === id) ?? null : null;
|
|
29
37
|
}
|
|
30
38
|
|
|
31
39
|
/** The name a message is signed with: the username, or for a ghost that has none the Discord name it carries. */
|
|
@@ -27,6 +27,8 @@ export function isGroupedWithPrevious(messages: ChatMessage[], index: number) {
|
|
|
27
27
|
const prev = messages[index - 1]!;
|
|
28
28
|
const curr = messages[index]!;
|
|
29
29
|
if (prev.user.id !== curr.user.id) return false;
|
|
30
|
+
// An announcement is a card of its own, with its own header.
|
|
31
|
+
if (prev.announcement || curr.announcement) return false;
|
|
30
32
|
// The Discord tag sits on a header, so a linked person's Discord and app messages do not share one.
|
|
31
33
|
if ((prev.origin === "discord") !== (curr.origin === "discord")) return false;
|
|
32
34
|
return new Date(curr.createdAt).getTime() - new Date(prev.createdAt).getTime() < MESSAGE_GROUP_THRESHOLD_MS;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { memo } from "react";
|
|
2
2
|
import { Box, Text } from "../../../../ui";
|
|
3
|
+
import { accentRuleOverlayStyle } from "../../../../components/ui/quote";
|
|
3
4
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
4
5
|
import { t } from "../../../../i18n";
|
|
5
6
|
import { useAppLanguage } from "../../../../i18n/react";
|
|
6
7
|
import { normalizeInlinePreview } from "../layout";
|
|
7
8
|
import { DesktopChatMessageImages } from "../attachments/desktop";
|
|
8
9
|
import { chatReplyQuoteText } from "../attachments/model";
|
|
9
|
-
import { chatAuthorName, isQuotedAuthorManagedBot } from "../ghost-user";
|
|
10
|
+
import { chatAuthorName, heldMessage, isQuotedAuthorManagedBot } from "../ghost-user";
|
|
10
11
|
import { ChatBotIcon } from "./person-icons";
|
|
11
12
|
import { ChatMessageActions, ChatMessageHeader, chatHeaderFitsEveryIcon } from "./header";
|
|
12
13
|
import { MESSAGE_ACTION_WIDTH } from "../layout";
|
|
@@ -16,7 +17,7 @@ import { DesktopChatMessageText } from "./inline-tokens";
|
|
|
16
17
|
import { DesktopChatPaneChip } from "./pane-chip";
|
|
17
18
|
import { chatMessagePaneLinks } from "../pane-links/model";
|
|
18
19
|
import { useSlowPendingSend } from "./pending-send";
|
|
19
|
-
import { chatHighlightBg, getChatMessageRenderState } from "./render-state";
|
|
20
|
+
import { chatAnnouncementBg, chatHighlightBg, getChatMessageRenderState } from "./render-state";
|
|
20
21
|
import type { ChatMessageBaseProps } from "./types";
|
|
21
22
|
|
|
22
23
|
const DESKTOP_MESSAGE_RIGHT_PADDING = 2;
|
|
@@ -99,7 +100,7 @@ export const DesktopChatMessage = memo(function DesktopChatMessage({
|
|
|
99
100
|
) : null;
|
|
100
101
|
const actionProps = { state, index, beginReplyTo, beginEditMessage, retryMessage, reactAction, reactionPickerOpen };
|
|
101
102
|
const { links: paneLinks, content } = chatMessagePaneLinks(msg);
|
|
102
|
-
// A share
|
|
103
|
+
// A share link sent with one picture, such as a pasted screenshot: the
|
|
103
104
|
// picture is the chip's thumbnail rather than a second copy below it.
|
|
104
105
|
const chipPreview = paneLinks.length === 1 && paneLinks[0]!.kind === "share"
|
|
105
106
|
&& msg.attachments?.length === 1 && !msg.attachmentReview
|
|
@@ -131,7 +132,12 @@ export const DesktopChatMessage = memo(function DesktopChatMessage({
|
|
|
131
132
|
data-selected={state.isSelected ? "true" : "false"}
|
|
132
133
|
data-hovered={state.isHovered ? "true" : "false"}
|
|
133
134
|
data-highlighted={state.isHighlighted ? "true" : "false"}
|
|
134
|
-
|
|
135
|
+
data-announcement={state.isAnnouncement ? "true" : undefined}
|
|
136
|
+
style={{
|
|
137
|
+
"--chat-highlight-bg": chatHighlightBg(themeColors),
|
|
138
|
+
minWidth: 0,
|
|
139
|
+
...(state.isAnnouncement ? { position: "relative", "--chat-highlight-rest": chatAnnouncementBg("desktop") } : {}),
|
|
140
|
+
}}
|
|
135
141
|
>
|
|
136
142
|
{msg.replyTo && (
|
|
137
143
|
<Box
|
|
@@ -148,7 +154,7 @@ export const DesktopChatMessage = memo(function DesktopChatMessage({
|
|
|
148
154
|
>
|
|
149
155
|
{/* One line: the quoted text ends in an ellipsis, the whole message is a click away. */}
|
|
150
156
|
<Text fg={state.replyMetaColor} style={{ flexShrink: 0, whiteSpace: "pre" }}>{`${t("reply")} `}</Text>
|
|
151
|
-
{isQuotedAuthorManagedBot(msg.replyTo, userByUsername) ? (
|
|
157
|
+
{isQuotedAuthorManagedBot(msg.replyTo, userByUsername, () => heldMessage(messages, msg.replyToId)) ? (
|
|
152
158
|
// The bot's icon stands where the colon would.
|
|
153
159
|
<>
|
|
154
160
|
<Text fg={state.replyAuthorColor} style={{ flexShrink: 0, whiteSpace: "pre" }}>{msg.replyTo.user.username}</Text>
|
|
@@ -262,6 +268,8 @@ export const DesktopChatMessage = memo(function DesktopChatMessage({
|
|
|
262
268
|
/>
|
|
263
269
|
</Box>
|
|
264
270
|
)}
|
|
271
|
+
{/* Last, so it draws over the rows' backgrounds. */}
|
|
272
|
+
{state.isAnnouncement && <Box data-gloom-role="chat-announcement-rule" style={accentRuleOverlayStyle()} />}
|
|
265
273
|
</Box>
|
|
266
274
|
);
|
|
267
275
|
});
|
|
@@ -3,7 +3,7 @@ import { Box, Text, useUiCapabilities, type BoxRenderable } from "../../../../ui
|
|
|
3
3
|
import { t } from "../../../../i18n";
|
|
4
4
|
import { displayWidth } from "../../../../utils/format";
|
|
5
5
|
import { chatAuthorName, isDiscordGhost } from "../ghost-user";
|
|
6
|
-
import { Button } from "../../../../components/ui";
|
|
6
|
+
import { Badge, Button } from "../../../../components/ui";
|
|
7
7
|
import { MESSAGE_ACTION_WIDTH } from "../layout";
|
|
8
8
|
import { CHAT_PERSON_ICON_WIDTH, chatPersonIcons, fitChatPersonIcons } from "../people";
|
|
9
9
|
import { ChatPersonIcons } from "./person-icons";
|
|
@@ -90,7 +90,7 @@ const WIDEST_HEADER_ACTIONS = 1 + MESSAGE_ACTION_WIDTH * 3;
|
|
|
90
90
|
* no longer depend on the width, so a row need not draw again as it changes.
|
|
91
91
|
*/
|
|
92
92
|
export function chatHeaderFitsEveryIcon(msg: ChatMessageBaseProps["msg"], rowWidth: number): boolean {
|
|
93
|
-
const icons =
|
|
93
|
+
const icons = chatHeaderIcons(msg).length;
|
|
94
94
|
if (icons === 0) return true;
|
|
95
95
|
const spare = rowWidth - 1 - displayWidth(chatAuthorName(msg.user))
|
|
96
96
|
- (msg.origin === "discord" ? 8 : 0)
|
|
@@ -99,6 +99,19 @@ export function chatHeaderFitsEveryIcon(msg: ChatMessageBaseProps["msg"], rowWid
|
|
|
99
99
|
return spare >= icons * CHAT_PERSON_ICON_WIDTH;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/** The mark an announcement carries beside its author, in place of the author's icons. */
|
|
103
|
+
const ANNOUNCEMENT_LABEL = "Announcement";
|
|
104
|
+
|
|
105
|
+
/** Cells the mark takes in the terminal: a cell of space, then the chip with a cell inside each edge. */
|
|
106
|
+
function announcementMarkWidth(): number {
|
|
107
|
+
return 1 + displayWidth(t(ANNOUNCEMENT_LABEL)) + 2;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** An announcement is signed by its mark alone: Gloom's account is not a bot speaking. */
|
|
111
|
+
function chatHeaderIcons(msg: ChatMessageBaseProps["msg"]) {
|
|
112
|
+
return msg.announcement ? [] : chatPersonIcons(msg.user);
|
|
113
|
+
}
|
|
114
|
+
|
|
102
115
|
/**
|
|
103
116
|
* Author, send status and inline actions for the first message of a group.
|
|
104
117
|
*
|
|
@@ -106,7 +119,9 @@ export function chatHeaderFitsEveryIcon(msg: ChatMessageBaseProps["msg"], rowWid
|
|
|
106
119
|
* the row is pointed at or selected, after the status, in the space the row
|
|
107
120
|
* already has: nothing before them moves, and a row that is not pointed at
|
|
108
121
|
* keeps no room for them. A row too narrow for its icons, its status and its
|
|
109
|
-
* actions drops Pro first, then the role, and never cuts the name.
|
|
122
|
+
* actions drops Pro first, then the role, and never cuts the name. An
|
|
123
|
+
* announcement carries its mark beside the name instead, dropped only by a
|
|
124
|
+
* terminal row too narrow for it (the band and its rule still say what it is).
|
|
110
125
|
*/
|
|
111
126
|
export function ChatMessageHeader({
|
|
112
127
|
msg,
|
|
@@ -141,7 +156,8 @@ export function ChatMessageHeader({
|
|
|
141
156
|
- (msg.origin === "discord" ? 8 : 0)
|
|
142
157
|
- 1 - displayWidth(state.headerStatus)
|
|
143
158
|
- state.actionsWidth;
|
|
144
|
-
const icons =
|
|
159
|
+
const icons = chatHeaderIcons(msg);
|
|
160
|
+
const showAnnouncementMark = msg.announcement === true && spare >= announcementMarkWidth();
|
|
145
161
|
const besideName = fitChatPersonIcons(icons.filter((icon) => icon.id === "bot"), spare);
|
|
146
162
|
const onPoint = fitChatPersonIcons(icons.filter((icon) => icon.id !== "bot"), spare - besideName.length * CHAT_PERSON_ICON_WIDTH);
|
|
147
163
|
// An open reaction picker keeps the row's actions, so it keeps what stands before them too.
|
|
@@ -177,6 +193,12 @@ export function ChatMessageHeader({
|
|
|
177
193
|
</Text>
|
|
178
194
|
</Box>
|
|
179
195
|
<ChatPersonIcons icons={besideName} selectedColor={iconColor} terminalTarget={profileTarget} />
|
|
196
|
+
{showAnnouncementMark && (
|
|
197
|
+
<>
|
|
198
|
+
<Text fg={state.headerStatusColor}> </Text>
|
|
199
|
+
<Badge label={ANNOUNCEMENT_LABEL} tone="accent" />
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
180
202
|
{msg.origin === "discord" && <Text fg={state.originTagColor}> Discord</Text>}
|
|
181
203
|
<Text fg={state.headerStatusColor}> {state.headerStatus}</Text>
|
|
182
204
|
{showOnPoint && <ChatPersonIcons icons={onPoint} selectedColor={iconColor} terminalTarget={profileTarget} />}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { createElement, useState } from "react";
|
|
2
2
|
import type { ChatAttachment } from "../../../../api-client";
|
|
3
|
+
import { IconButton } from "../../../../components/ui";
|
|
4
|
+
import { tf } from "../../../../i18n";
|
|
3
5
|
import { Box, Text, TextAttributes } from "../../../../ui";
|
|
4
6
|
import { blendHex, colors } from "../../../../theme/colors";
|
|
5
7
|
import { useThemeColors } from "../../../../theme/theme-context";
|
|
6
8
|
import { formatInlinePreview } from "../layout";
|
|
7
9
|
import { wirePaneTarget, type ChatMessagePaneLink } from "../pane-links/model";
|
|
8
10
|
import { chatPaneLinkPane, useSharePreview } from "../pane-links/previews";
|
|
11
|
+
import type { ComposerShareLink } from "../pane-links/composer";
|
|
12
|
+
import { DESKTOP_DRAFT_STRIP_STYLE } from "../attachments/desktop";
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* A chip for something a message opens in the terminal: a shared pane (its
|
|
@@ -62,6 +66,7 @@ export function DesktopChatPaneChip({
|
|
|
62
66
|
dimmed,
|
|
63
67
|
onOpen,
|
|
64
68
|
onPreviewError,
|
|
69
|
+
onRemove,
|
|
65
70
|
}: {
|
|
66
71
|
link: ChatMessagePaneLink;
|
|
67
72
|
/** The picture the sender posted with the link: the chip's thumbnail. */
|
|
@@ -70,6 +75,8 @@ export function DesktopChatPaneChip({
|
|
|
70
75
|
onOpen: (link: ChatMessagePaneLink) => void;
|
|
71
76
|
/** The picture did not load, perhaps because its signed link expired. */
|
|
72
77
|
onPreviewError?: (attachment: ChatAttachment) => void;
|
|
78
|
+
/** In the composer: the x at the chip's end that takes the link back out. */
|
|
79
|
+
onRemove?: () => void;
|
|
73
80
|
}) {
|
|
74
81
|
const themeColors = useThemeColors();
|
|
75
82
|
const content = useChatPaneChipContent(link);
|
|
@@ -138,34 +145,36 @@ export function DesktopChatPaneChip({
|
|
|
138
145
|
},
|
|
139
146
|
}, text);
|
|
140
147
|
const label = [content.title, content.detail].filter(Boolean).join(", ");
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
const text = compact
|
|
149
|
+
? createElement("span", {
|
|
150
|
+
key: "text",
|
|
151
|
+
style: { display: "flex", flexDirection: "row", gap: 6, minWidth: 0, alignItems: "baseline" },
|
|
152
|
+
}, line(content.title, "title"), content.detail ? line(content.detail, "detail") : null)
|
|
153
|
+
: createElement("span", {
|
|
154
|
+
key: "text",
|
|
155
|
+
style: { display: "flex", flexDirection: "column", justifyContent: "center", minWidth: 0, flex: "1 1 auto", gap: 1 },
|
|
156
|
+
}, line(content.title, "title"), line(content.detail, "detail"));
|
|
157
|
+
const frame = {
|
|
158
|
+
boxSizing: "border-box",
|
|
159
|
+
display: "flex",
|
|
160
|
+
flexDirection: "row",
|
|
161
|
+
alignItems: "center",
|
|
162
|
+
gap: compact ? 6 : 8,
|
|
163
|
+
height,
|
|
164
|
+
width: compact ? "auto" : `min(100%, ${CHIP_MAX_WIDTH}px)`,
|
|
165
|
+
maxWidth: "100%",
|
|
166
|
+
flex: "none",
|
|
167
|
+
margin: "2px 0",
|
|
168
|
+
padding: compact ? "0 10px 0 5px" : "4px 10px 4px 4px",
|
|
169
|
+
border: `1px solid ${border}`,
|
|
170
|
+
borderRadius: 6,
|
|
171
|
+
background: surface,
|
|
172
|
+
opacity: dimmed ? 0.6 : 1,
|
|
173
|
+
overflow: "hidden",
|
|
174
|
+
};
|
|
175
|
+
const pressable = {
|
|
145
176
|
"aria-label": label || undefined,
|
|
146
177
|
title: link.kind === "share" ? link.url : undefined,
|
|
147
|
-
style: {
|
|
148
|
-
boxSizing: "border-box",
|
|
149
|
-
display: "flex",
|
|
150
|
-
flexDirection: "row",
|
|
151
|
-
alignItems: "center",
|
|
152
|
-
gap: compact ? 6 : 8,
|
|
153
|
-
height,
|
|
154
|
-
width: compact ? "auto" : `min(100%, ${CHIP_MAX_WIDTH}px)`,
|
|
155
|
-
maxWidth: "100%",
|
|
156
|
-
flex: "none",
|
|
157
|
-
margin: "2px 0",
|
|
158
|
-
padding: compact ? "0 10px 0 5px" : "4px 10px 4px 4px",
|
|
159
|
-
border: `1px solid ${border}`,
|
|
160
|
-
borderRadius: 6,
|
|
161
|
-
background: surface,
|
|
162
|
-
opacity: dimmed ? 0.6 : 1,
|
|
163
|
-
cursor: "pointer",
|
|
164
|
-
font: "inherit",
|
|
165
|
-
color: "inherit",
|
|
166
|
-
textAlign: "left",
|
|
167
|
-
overflow: "hidden",
|
|
168
|
-
},
|
|
169
178
|
onMouseEnter: () => setHovered(true),
|
|
170
179
|
onMouseLeave: () => setHovered(false),
|
|
171
180
|
// A press on the chip is not a press on the row behind it.
|
|
@@ -174,15 +183,102 @@ export function DesktopChatPaneChip({
|
|
|
174
183
|
event.stopPropagation();
|
|
175
184
|
onOpen(link);
|
|
176
185
|
},
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
+
};
|
|
187
|
+
const buttonReset = { cursor: "pointer", font: "inherit", color: "inherit", textAlign: "left" };
|
|
188
|
+
const dataAttributes = {
|
|
189
|
+
"data-gloom-role": "chat-pane-chip",
|
|
190
|
+
"data-gloom-pane-link": link.kind === "share" ? `share:${link.id}` : link.link.kind,
|
|
191
|
+
};
|
|
192
|
+
if (!onRemove) {
|
|
193
|
+
return createElement("button", { type: "button", ...dataAttributes, ...pressable, style: { ...frame, ...buttonReset } }, lead, text);
|
|
194
|
+
}
|
|
195
|
+
// The same chip with its x inside the frame, where a waiting image keeps its own.
|
|
196
|
+
return createElement("div", { ...dataAttributes, style: { ...frame, paddingRight: 4 } },
|
|
197
|
+
createElement("button", {
|
|
198
|
+
key: "open",
|
|
199
|
+
type: "button",
|
|
200
|
+
...pressable,
|
|
201
|
+
style: {
|
|
202
|
+
...buttonReset,
|
|
203
|
+
display: "flex",
|
|
204
|
+
flexDirection: "row",
|
|
205
|
+
alignItems: "center",
|
|
206
|
+
gap: frame.gap,
|
|
207
|
+
flex: "1 1 auto",
|
|
208
|
+
minWidth: 0,
|
|
209
|
+
height: "100%",
|
|
210
|
+
padding: 0,
|
|
211
|
+
border: "none",
|
|
212
|
+
background: "transparent",
|
|
213
|
+
},
|
|
214
|
+
}, lead, text),
|
|
215
|
+
<IconButton key="remove" icon="close" label={tf("Remove {name}", { name: content.title })} onPress={onRemove} />);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* The share links waiting in the composer, above the field: the chips the
|
|
220
|
+
* message will show, each with its x. A draft from an older app can hold the
|
|
221
|
+
* same link twice, so a chip is known by its place: its x takes out that one.
|
|
222
|
+
*/
|
|
223
|
+
export function DesktopComposerPaneChips({
|
|
224
|
+
links,
|
|
225
|
+
onOpen,
|
|
226
|
+
onRemove,
|
|
227
|
+
}: {
|
|
228
|
+
links: readonly ComposerShareLink[];
|
|
229
|
+
onOpen: (link: ChatMessagePaneLink) => void;
|
|
230
|
+
/** Takes out the chip at this place in `links`. */
|
|
231
|
+
onRemove: (index: number) => void;
|
|
232
|
+
}) {
|
|
233
|
+
if (links.length === 0) return null;
|
|
234
|
+
return (
|
|
235
|
+
<Box flexDirection="column" data-gloom-role="chat-draft-links" style={DESKTOP_DRAFT_STRIP_STYLE}>
|
|
236
|
+
{links.map((link, index) => (
|
|
237
|
+
<DesktopChatPaneChip key={`${index}:${link.id}`} link={link} dimmed={false} onOpen={onOpen} onRemove={() => onRemove(index)} />
|
|
238
|
+
))}
|
|
239
|
+
</Box>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** The terminal's composer rows for waiting share links: the chip a message draws, then its x at the row's end. */
|
|
244
|
+
export function TerminalComposerPaneChips({
|
|
245
|
+
links,
|
|
246
|
+
width,
|
|
247
|
+
onOpen,
|
|
248
|
+
onRemove,
|
|
249
|
+
}: {
|
|
250
|
+
links: readonly ComposerShareLink[];
|
|
251
|
+
width: number;
|
|
252
|
+
onOpen: (link: ChatMessagePaneLink) => void;
|
|
253
|
+
/** Takes out the chip at this place in `links`, as on the desktop. */
|
|
254
|
+
onRemove: (index: number) => void;
|
|
255
|
+
}) {
|
|
256
|
+
// Lined up with the field's text after its prompt, as a message's chips line up with its text.
|
|
257
|
+
const inset = 3;
|
|
258
|
+
const removeWidth = 3;
|
|
259
|
+
return (
|
|
260
|
+
<>
|
|
261
|
+
{links.map((link, index) => (
|
|
262
|
+
<Box key={`${index}:${link.id}`} width={width} height={1} flexDirection="row">
|
|
263
|
+
<Box width={inset} />
|
|
264
|
+
<TerminalChatPaneChip
|
|
265
|
+
link={link}
|
|
266
|
+
width={Math.max(1, width - inset - removeWidth - 1)}
|
|
267
|
+
selected={false}
|
|
268
|
+
selectedTextColor={colors.textBright}
|
|
269
|
+
onOpen={onOpen}
|
|
270
|
+
/>
|
|
271
|
+
<Box flexGrow={1} />
|
|
272
|
+
<TerminalComposerChipRemove link={link} onRemove={() => onRemove(index)} />
|
|
273
|
+
</Box>
|
|
274
|
+
))}
|
|
275
|
+
</>
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function TerminalComposerChipRemove({ link, onRemove }: { link: ComposerShareLink; onRemove: () => void }) {
|
|
280
|
+
const content = useChatPaneChipContent(link);
|
|
281
|
+
return <IconButton icon="close" label={tf("Remove {name}", { name: content.title })} onPress={onRemove} />;
|
|
186
282
|
}
|
|
187
283
|
|
|
188
284
|
/** One row in the terminal: the pane's letter, the title and the pane, cut to the line. */
|