gloomberb 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/patches/@opentui%2Fcore@0.1.90.patch +48 -24
- package/src/app.tsx +158 -57
- package/src/capabilities/factories.ts +3 -0
- package/src/cli/registry.test.ts +0 -1
- package/src/components/chart/chart-controller.ts +0 -1
- package/src/components/chart/chart-data.ts +1 -31
- package/src/components/chart/chart-renderer.ts +94 -12
- package/src/components/chart/chart-resolution.test.ts +0 -36
- package/src/components/chart/chart-resolution.ts +0 -27
- package/src/components/chart/chart.test.ts +60 -45
- package/src/components/chart/comparison-chart-data.test.ts +1 -5
- package/src/components/chart/comparison-chart-data.ts +1 -4
- package/src/components/chart/comparison-chart-renderer.test.ts +26 -0
- package/src/components/chart/comparison-chart-renderer.ts +13 -6
- package/src/components/chart/comparison-stock-chart.tsx +63 -39
- package/src/components/chart/price-axis-labels.tsx +114 -0
- package/src/components/chart/static-chart-surface.tsx +30 -4
- package/src/components/chart/stock-chart.test.ts +0 -16
- package/src/components/chart/stock-chart.tsx +69 -41
- package/src/components/chart/time-axis-label.tsx +120 -0
- package/src/components/command-bar/__snapshots__/command-bar.test.tsx.snap +0 -28
- package/src/components/command-bar/command-bar.test.tsx +182 -36
- package/src/components/command-bar/command-bar.tsx +943 -1016
- package/src/components/command-bar/command-registry.ts +0 -10
- package/src/components/command-bar/confirm-body.tsx +51 -0
- package/src/components/command-bar/helpers.ts +2 -5
- package/src/components/command-bar/list-model.ts +76 -0
- package/src/components/command-bar/theme-picker.tsx +254 -0
- package/src/components/command-bar/view-model.test.ts +4 -4
- package/src/components/command-bar/view-model.ts +1 -20
- package/src/components/command-bar/workflow-ops.ts +4 -0
- package/src/components/command-bar/workflow-types.ts +1 -2
- package/src/components/data-table-stack-view.test.tsx +39 -4
- package/src/components/data-table-stack-view.tsx +11 -104
- package/src/components/data-table-view.tsx +43 -79
- package/src/components/feed-data-table-stack-view.tsx +10 -17
- package/src/components/feed-stack-controller.ts +39 -0
- package/src/components/index.ts +5 -1
- package/src/components/layout/detached-pane-shell.tsx +29 -10
- package/src/components/layout/floating-pane.tsx +35 -4
- package/src/components/layout/header.tsx +12 -7
- package/src/components/layout/pane-content.test.tsx +64 -0
- package/src/components/layout/pane-content.tsx +2 -0
- package/src/components/layout/pane-cycle-order.test.ts +30 -0
- package/src/components/layout/pane-cycle-order.ts +32 -0
- package/src/components/layout/pane-footer.tsx +11 -4
- package/src/components/layout/pane-header.tsx +5 -5
- package/src/components/layout/pane-sizing.ts +9 -2
- package/src/components/layout/pane-title.ts +4 -1
- package/src/components/layout/pane.tsx +11 -5
- package/src/components/layout/shell.test.tsx +264 -22
- package/src/components/layout/shell.tsx +46 -8
- package/src/components/layout/status-bar.tsx +2 -0
- package/src/components/onboarding/onboarding-wizard.tsx +1 -2
- package/src/components/pane-settings-dialog.tsx +12 -4
- package/src/components/pane-template-wizard.test.tsx +3 -4
- package/src/components/speedometer-gauge.test.tsx +45 -0
- package/src/components/speedometer-gauge.tsx +562 -0
- package/src/components/table-view-shared.tsx +218 -0
- package/src/components/ticker-list-table-view.tsx +57 -73
- package/src/components/ticker-list-table.test.tsx +82 -1
- package/src/components/ticker-list-table.tsx +22 -9
- package/src/components/ui/confirm-dialog.tsx +66 -0
- package/src/components/ui/data-table.tsx +30 -19
- package/src/components/ui/frame.tsx +2 -0
- package/src/components/ui/index.ts +0 -1
- package/src/components/ui/page-stack-view.tsx +39 -10
- package/src/components/ui/table-layout.test.ts +42 -0
- package/src/components/ui/table-layout.ts +49 -4
- package/src/components/ui/tabs.tsx +34 -1
- package/src/components/ui/ui.test.tsx +168 -21
- package/src/core/state/app-state.ts +10 -17
- package/src/market-data/coordinator.test.ts +76 -1
- package/src/market-data/coordinator.ts +218 -49
- package/src/news/aggregator.test.ts +49 -1
- package/src/news/aggregator.ts +48 -3
- package/src/news/hooks.ts +6 -2
- package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +46 -16
- package/src/plugins/builtin/ai/providers.ts +0 -17
- package/src/plugins/builtin/ai/screener-pane.test.tsx +3 -4
- package/src/plugins/builtin/ai/screener-pane.tsx +3 -5
- package/src/plugins/builtin/analytics/index.tsx +1 -18
- package/src/plugins/builtin/ask-ai.test.tsx +89 -2
- package/src/plugins/builtin/broker-manager/index.test.tsx +2 -2
- package/src/plugins/builtin/broker-manager/index.tsx +19 -36
- package/src/plugins/builtin/chat-controller.test.ts +188 -1
- package/src/plugins/builtin/chat-controller.ts +537 -220
- package/src/plugins/builtin/chat.test.tsx +431 -13
- package/src/plugins/builtin/chat.tsx +1134 -227
- package/src/plugins/builtin/cloud-tweets.tsx +1 -1
- package/src/plugins/builtin/comparison-chart.test.tsx +53 -2
- package/src/plugins/builtin/comparison-chart.tsx +11 -5
- package/src/plugins/builtin/correlation/index.tsx +1 -6
- package/src/plugins/builtin/debug.tsx +1 -3
- package/src/plugins/builtin/econ/index.tsx +1 -2
- package/src/plugins/builtin/fear-greed/fear-greed-data.test.ts +72 -0
- package/src/plugins/builtin/fear-greed/fear-greed-data.ts +366 -0
- package/src/plugins/builtin/fear-greed/index.tsx +587 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +2 -2
- package/src/plugins/builtin/help.test.tsx +2 -2
- package/src/plugins/builtin/help.tsx +2 -2
- package/src/plugins/builtin/holders/index.test.ts +13 -1
- package/src/plugins/builtin/holders/index.tsx +64 -29
- package/src/plugins/builtin/insider/index.tsx +22 -89
- package/src/plugins/builtin/market-movers/index.tsx +13 -19
- package/src/plugins/builtin/market-movers/screener.test.ts +39 -1
- package/src/plugins/builtin/market-movers/screener.ts +70 -17
- package/src/plugins/builtin/news-wire/breaking-pane.tsx +3 -2
- package/src/plugins/builtin/news-wire/index.tsx +41 -2
- package/src/plugins/builtin/news-wire/industry-pane.tsx +4 -18
- package/src/plugins/builtin/news-wire/news-detail-view.tsx +46 -4
- package/src/plugins/builtin/news-wire/news-preset-pane.tsx +3 -2
- package/src/plugins/builtin/news-wire/news-table.tsx +11 -11
- package/src/plugins/builtin/news.tsx +4 -16
- package/src/plugins/builtin/notes.tsx +19 -55
- package/src/plugins/builtin/options.test.tsx +58 -2
- package/src/plugins/builtin/options.tsx +110 -65
- package/src/plugins/builtin/plugin-groups.ts +2 -0
- package/src/plugins/builtin/portfolio-list/cli/commands.ts +1 -1
- package/src/plugins/builtin/portfolio-list/pane.tsx +16 -39
- package/src/plugins/builtin/research/index.test.ts +94 -0
- package/src/plugins/builtin/research/index.tsx +164 -33
- package/src/plugins/builtin/sec-filing-display.tsx +84 -0
- package/src/plugins/builtin/sec.tsx +13 -66
- package/src/plugins/builtin/sectors/index.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/chart-tab.tsx +0 -1
- package/src/plugins/builtin/ticker-detail/index.tsx +0 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +0 -1
- package/src/plugins/builtin/ticker-detail/pane.tsx +28 -22
- package/src/plugins/builtin/ticker-detail-chart-tab-switch.test.tsx +3 -4
- package/src/plugins/builtin/ticker-detail.test.tsx +38 -0
- package/src/plugins/builtin/world-indices/index.tsx +1 -1
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/ibkr/broker-adapter.ts +1 -3
- package/src/plugins/ibkr/gateway-service-native.ts +1 -5
- package/src/plugins/ibkr/gateway-service.ts +1 -1
- package/src/plugins/ibkr/index.test.tsx +0 -2
- package/src/plugins/ibkr/trade-tab.test.tsx +3 -4
- package/src/plugins/pane-manager.ts +0 -13
- package/src/plugins/plugin-runtime.test.tsx +40 -6
- package/src/plugins/plugin-runtime.tsx +20 -10
- package/src/plugins/prediction-markets/cli.ts +0 -1
- package/src/plugins/prediction-markets/controller-data.ts +0 -2
- package/src/plugins/prediction-markets/controller.ts +0 -15
- package/src/plugins/prediction-markets/detail/pane.tsx +1 -0
- package/src/plugins/prediction-markets/pane.test.tsx +3 -11
- package/src/plugins/prediction-markets/test-helpers.tsx +1 -1
- package/src/plugins/registry.ts +13 -42
- package/src/plugins/ticker-navigation.test.ts +66 -0
- package/src/plugins/ticker-navigation.ts +44 -0
- package/src/react/input.ts +2 -1
- package/src/renderers/electrobun/bun/index.ts +32 -11
- package/src/renderers/electrobun/bun/window-focus.ts +37 -0
- package/src/renderers/electrobun/shared/protocol.ts +7 -1
- package/src/renderers/electrobun/view/app-services.ts +88 -31
- package/src/renderers/electrobun/view/backend-rpc.ts +15 -0
- package/src/renderers/electrobun/view/data-table.tsx +138 -101
- package/src/renderers/electrobun/view/desktop-controls.tsx +42 -20
- package/src/renderers/electrobun/view/desktop-window-bridge.ts +12 -1
- package/src/renderers/electrobun/view/dialog-host.tsx +13 -1
- package/src/renderers/electrobun/view/input-host.tsx +74 -10
- package/src/renderers/electrobun/view/key-event.ts +1 -1
- package/src/renderers/electrobun/view/main.tsx +18 -1
- package/src/renderers/electrobun/view/styles.css +329 -0
- package/src/renderers/electrobun/view/toast-host.tsx +29 -3
- package/src/renderers/electrobun/view/ui-host.tsx +42 -0
- package/src/renderers/opentui/chart-surface.tsx +179 -0
- package/src/renderers/opentui/input-host.tsx +1 -1
- package/src/renderers/opentui/start.tsx +48 -30
- package/src/renderers/opentui/test-utils.tsx +17 -0
- package/src/renderers/opentui/ui-host.tsx +5 -2
- package/src/sources/gloomberb-cloud.test.ts +86 -1
- package/src/sources/gloomberb-cloud.ts +117 -21
- package/src/sources/provider-router.test.ts +122 -0
- package/src/sources/provider-router.ts +198 -15
- package/src/sources/yahoo-finance.test.ts +44 -0
- package/src/sources/yahoo-finance.ts +6 -0
- package/src/state/app-bootstrap.ts +20 -7
- package/src/state/app-context-selector.test.tsx +189 -4
- package/src/state/app-context.test.ts +65 -0
- package/src/state/app-context.tsx +48 -16
- package/src/state/use-inline-tickers.test.tsx +73 -0
- package/src/state/use-inline-tickers.ts +19 -10
- package/src/test-support/plugin-runtime.ts +3 -2
- package/src/theme/colors.test.ts +75 -0
- package/src/theme/colors.ts +76 -6
- package/src/theme/theme-context.tsx +26 -0
- package/src/theme/themes.test.ts +23 -1
- package/src/theme/themes.ts +115 -0
- package/src/types/broker.ts +1 -1
- package/src/types/capability-route-source.ts +1 -0
- package/src/types/data-provider.ts +15 -2
- package/src/types/desktop-window.ts +6 -0
- package/src/types/financials.ts +2 -0
- package/src/types/plugin.ts +1 -3
- package/src/ui/host.tsx +7 -0
- package/src/utils/api-client.test.ts +32 -0
- package/src/utils/api-client.ts +119 -18
- package/src/utils/back-navigation.ts +24 -1
- package/src/utils/double-escape-close.test.ts +33 -0
- package/src/utils/double-escape-close.ts +40 -0
- package/src/utils/throttled-fetch.test.ts +22 -0
- package/src/utils/throttled-fetch.ts +3 -1
- package/src/utils/ticker-search.ts +53 -9
- package/src/version.ts +1 -1
- package/src/plugins/builtin/news-wire/feed-pane.tsx +0 -21
- package/src/plugins/builtin/news-wire/top-pane.tsx +0 -21
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
diff --git a/index-e89anq5x.js b/index-e89anq5x.js
|
|
2
|
-
index
|
|
2
|
+
index e3b6cf9f90b13698966eec991fa7a1b2e1e22d96..709940f3998e5cb1caa88642fa68fa9ace80b7b1 100644
|
|
3
3
|
--- a/index-e89anq5x.js
|
|
4
4
|
+++ b/index-e89anq5x.js
|
|
5
5
|
@@ -6328,17 +6328,27 @@ class MouseParser {
|
|
@@ -66,16 +66,39 @@ index e3b6cf9..14a46d7 100644
|
|
|
66
66
|
consumed: index - offset + 1
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
-
@@ -6408,
|
|
69
|
+
@@ -6408,10 +6418,12 @@ class MouseParser {
|
|
70
70
|
consumed: 6
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
- decodeSgrEvent(rawButtonCode, wireX, wireY, pressRelease) {
|
|
74
|
+
- const button = rawButtonCode & 3;
|
|
74
75
|
+ decodeSgrEvent(rawButtonCode, wireX, wireY, pressRelease, context = void 0) {
|
|
75
|
-
|
|
76
|
+
+ const encodedButton = rawButtonCode & 3;
|
|
77
|
+
+ const isExtendedButton = (rawButtonCode & 128) !== 0;
|
|
78
|
+
+ const button = isExtendedButton ? 8 + encodedButton : encodedButton;
|
|
76
79
|
const isScroll = (rawButtonCode & 64) !== 0;
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
- const scrollDirection = !isScroll ? undefined : MouseParser.SCROLL_DIRECTIONS[button];
|
|
81
|
+
+ const scrollDirection = !isScroll ? undefined : MouseParser.SCROLL_DIRECTIONS[encodedButton];
|
|
82
|
+
const isMotion = (rawButtonCode & 32) !== 0;
|
|
83
|
+
const modifiers = {
|
|
84
|
+
shift: (rawButtonCode & 4) !== 0,
|
|
85
|
+
@@ -6422,7 +6434,7 @@ class MouseParser {
|
|
86
|
+
let scrollInfo;
|
|
87
|
+
if (isMotion) {
|
|
88
|
+
const isDragging = this.mouseButtonsPressed.size > 0;
|
|
89
|
+
- if (button === 3) {
|
|
90
|
+
+ if (!isExtendedButton && encodedButton === 3) {
|
|
91
|
+
type = "move";
|
|
92
|
+
} else if (isDragging) {
|
|
93
|
+
type = "drag";
|
|
94
|
+
@@ -6437,17 +6449,32 @@ class MouseParser {
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
type = pressRelease === "M" ? "down" : "up";
|
|
98
|
+
- if (type === "down" && button !== 3) {
|
|
99
|
+
+ if (type === "down" && (isExtendedButton || encodedButton !== 3)) {
|
|
100
|
+
this.mouseButtonsPressed.add(button);
|
|
101
|
+
} else if (type === "up") {
|
|
79
102
|
this.mouseButtonsPressed.clear();
|
|
80
103
|
}
|
|
81
104
|
}
|
|
@@ -90,9 +113,10 @@ index e3b6cf9..14a46d7 100644
|
|
|
90
113
|
+ const pixelY = pixelModeDetected ? Math.max(wireY - 1, 0) : void 0;
|
|
91
114
|
return {
|
|
92
115
|
type,
|
|
93
|
-
|
|
116
|
+
- button: button === 3 ? 0 : button,
|
|
94
117
|
- x: wireX - 1,
|
|
95
118
|
- y: wireY - 1,
|
|
119
|
+
+ button: !isExtendedButton && encodedButton === 3 ? 0 : button,
|
|
96
120
|
+ x: pixelModeDetected && pixelX !== void 0
|
|
97
121
|
+ ? this.projectPixelToCell(pixelX, context?.pixelWidth ?? 0, context?.terminalWidth ?? 0)
|
|
98
122
|
+ : wireX - 1,
|
|
@@ -104,7 +128,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
104
128
|
modifiers,
|
|
105
129
|
scroll: scrollInfo
|
|
106
130
|
};
|
|
107
|
-
@@ -6856,7 +
|
|
131
|
+
@@ -6856,7 +6883,13 @@ var DEFAULT_PROTOCOL_CONTEXT = {
|
|
108
132
|
kittyKeyboardEnabled: false,
|
|
109
133
|
privateCapabilityRepliesActive: false,
|
|
110
134
|
pixelResolutionQueryActive: false,
|
|
@@ -119,7 +143,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
119
143
|
};
|
|
120
144
|
var RXVT_DOLLAR_CSI_RE = /^\x1b\[\d+\$$/;
|
|
121
145
|
var SYSTEM_CLOCK = new SystemClock;
|
|
122
|
-
@@ -7149,7 +
|
|
146
|
+
@@ -7149,7 +7182,13 @@ class StdinParser {
|
|
123
147
|
kittyKeyboardEnabled: options.protocolContext?.kittyKeyboardEnabled ?? false,
|
|
124
148
|
privateCapabilityRepliesActive: options.protocolContext?.privateCapabilityRepliesActive ?? false,
|
|
125
149
|
pixelResolutionQueryActive: options.protocolContext?.pixelResolutionQueryActive ?? false,
|
|
@@ -134,7 +158,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
134
158
|
};
|
|
135
159
|
}
|
|
136
160
|
get bufferCapacity() {
|
|
137
|
-
@@ -7952,11 +
|
|
161
|
+
@@ -7952,11 +7991,14 @@ class StdinParser {
|
|
138
162
|
});
|
|
139
163
|
}
|
|
140
164
|
emitMouse(rawBytes, encoding) {
|
|
@@ -150,7 +174,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
150
174
|
this.events.push({
|
|
151
175
|
type: "mouse",
|
|
152
176
|
raw: decodeLatin1(rawBytes),
|
|
153
|
-
@@ -17295,6 +
|
|
177
|
+
@@ -17295,6 +17337,8 @@ class MouseEvent {
|
|
154
178
|
button;
|
|
155
179
|
x;
|
|
156
180
|
y;
|
|
@@ -159,7 +183,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
159
183
|
source;
|
|
160
184
|
modifiers;
|
|
161
185
|
scroll;
|
|
162
|
-
@@ -17314,6 +
|
|
186
|
+
@@ -17314,6 +17358,8 @@ class MouseEvent {
|
|
163
187
|
this.button = attributes.button;
|
|
164
188
|
this.x = attributes.x;
|
|
165
189
|
this.y = attributes.y;
|
|
@@ -168,7 +192,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
168
192
|
this.modifiers = attributes.modifiers;
|
|
169
193
|
this.scroll = attributes.scroll;
|
|
170
194
|
this.source = attributes.source;
|
|
171
|
-
@@ -17479,6 +
|
|
195
|
+
@@ -17479,6 +17525,8 @@ class CliRenderer extends EventEmitter8 {
|
|
172
196
|
resizeDebounceDelay = 100;
|
|
173
197
|
enableMouseMovement = false;
|
|
174
198
|
_useMouse = true;
|
|
@@ -177,7 +201,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
177
201
|
autoFocus = true;
|
|
178
202
|
_useAlternateScreen = env.OTUI_USE_ALTERNATE_SCREEN;
|
|
179
203
|
_suspendedMouseEnabled = false;
|
|
180
|
-
@@ -17507,7 +
|
|
204
|
+
@@ -17507,7 +17555,7 @@ class CliRenderer extends EventEmitter8 {
|
|
181
205
|
this.handleResize(width, height);
|
|
182
206
|
}).bind(this);
|
|
183
207
|
_capabilities = null;
|
|
@@ -186,7 +210,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
186
210
|
_hasPointer = false;
|
|
187
211
|
_lastPointerModifiers = { shift: false, alt: false, ctrl: false };
|
|
188
212
|
_currentMousePointerStyle = undefined;
|
|
189
|
-
@@ -17661,7 +
|
|
213
|
+
@@ -17661,7 +17709,13 @@ Captured output:
|
|
190
214
|
kittyKeyboardEnabled: useKittyForParsing,
|
|
191
215
|
privateCapabilityRepliesActive: false,
|
|
192
216
|
pixelResolutionQueryActive: false,
|
|
@@ -201,7 +225,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
201
225
|
},
|
|
202
226
|
clock: this.clock
|
|
203
227
|
});
|
|
204
|
-
@@ -17983,12 +
|
|
228
|
+
@@ -17983,12 +18037,14 @@ Captured output:
|
|
205
229
|
enableMouse() {
|
|
206
230
|
this._useMouse = true;
|
|
207
231
|
this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement);
|
|
@@ -216,7 +240,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
216
240
|
}
|
|
217
241
|
enableKittyKeyboard(flags = 3) {
|
|
218
242
|
this.lib.enableKittyKeyboard(this.rendererPtr, flags);
|
|
219
|
-
@@ -17998,6 +
|
|
243
|
+
@@ -17998,6 +18054,64 @@ Captured output:
|
|
220
244
|
this.lib.disableKittyKeyboard(this.rendererPtr);
|
|
221
245
|
this.updateStdinParserProtocolContext({ kittyKeyboardEnabled: false }, true);
|
|
222
246
|
}
|
|
@@ -281,7 +305,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
281
305
|
set useThread(useThread) {
|
|
282
306
|
this._useThread = useThread;
|
|
283
307
|
this.lib.setUseThread(this.rendererPtr, useThread);
|
|
284
|
-
@@ -18031,6 +
|
|
308
|
+
@@ -18031,6 +18145,7 @@ Captured output:
|
|
285
309
|
if (this._useMouse) {
|
|
286
310
|
this.enableMouse();
|
|
287
311
|
}
|
|
@@ -289,7 +313,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
289
313
|
this.queryPixelResolution();
|
|
290
314
|
}
|
|
291
315
|
stdinListener = ((chunk) => {
|
|
292
|
-
@@ -18070,6 +
|
|
316
|
+
@@ -18070,6 +18185,7 @@ Captured output:
|
|
293
317
|
if (isCapabilityResponse(sequence)) {
|
|
294
318
|
this.lib.processCapabilityResponse(this.rendererPtr, sequence);
|
|
295
319
|
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
@@ -297,7 +321,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
297
321
|
this.emit("capabilities" /* CAPABILITIES */, this._capabilities);
|
|
298
322
|
return true;
|
|
299
323
|
}
|
|
300
|
-
@@ -18079,6 +
|
|
324
|
+
@@ -18079,6 +18195,7 @@ Captured output:
|
|
301
325
|
if (sequence === "\x1B[I") {
|
|
302
326
|
if (this.shouldRestoreModesOnNextFocus) {
|
|
303
327
|
this.lib.restoreTerminalModes(this.rendererPtr);
|
|
@@ -305,7 +329,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
305
329
|
this.shouldRestoreModesOnNextFocus = false;
|
|
306
330
|
}
|
|
307
331
|
if (this._terminalFocusState !== true) {
|
|
308
|
-
@@ -18187,6 +
|
|
332
|
+
@@ -18187,6 +18304,7 @@ Captured output:
|
|
309
333
|
}
|
|
310
334
|
this.waitingForPixelResolution = false;
|
|
311
335
|
this.updateStdinParserProtocolContext({ pixelResolutionQueryActive: false }, true);
|
|
@@ -313,7 +337,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
313
337
|
return true;
|
|
314
338
|
}
|
|
315
339
|
return false;
|
|
316
|
-
@@ -18221,9 +
|
|
340
|
+
@@ -18221,9 +18339,15 @@ Captured output:
|
|
317
341
|
return false;
|
|
318
342
|
}
|
|
319
343
|
mouseEvent.y -= this.renderOffset;
|
|
@@ -329,7 +353,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
329
353
|
this._hasPointer = true;
|
|
330
354
|
this._lastPointerModifiers = mouseEvent.modifiers;
|
|
331
355
|
if (this._console.visible) {
|
|
332
|
-
@@ -18352,6 +
|
|
356
|
+
@@ -18352,6 +18476,8 @@ Captured output:
|
|
333
357
|
button: 0,
|
|
334
358
|
x: this._latestPointer.x,
|
|
335
359
|
y: this._latestPointer.y,
|
|
@@ -338,7 +362,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
338
362
|
modifiers: this._lastPointerModifiers
|
|
339
363
|
};
|
|
340
364
|
if (lastOver && !lastOver.isDestroyed) {
|
|
341
|
-
@@ -18435,6 +
|
|
365
|
+
@@ -18435,6 +18561,7 @@ Captured output:
|
|
342
366
|
const prevWidth = this._terminalWidth;
|
|
343
367
|
this._terminalWidth = width;
|
|
344
368
|
this._terminalHeight = height;
|
|
@@ -346,7 +370,7 @@ index e3b6cf9..14a46d7 100644
|
|
|
346
370
|
this.queryPixelResolution();
|
|
347
371
|
this.setCapturedRenderable(undefined);
|
|
348
372
|
this.stdinParser?.resetMouseState();
|
|
349
|
-
@@ -18712,6 +
|
|
373
|
+
@@ -18712,6 +18839,7 @@ Captured output:
|
|
350
374
|
}
|
|
351
375
|
this._isRunning = false;
|
|
352
376
|
this.waitingForPixelResolution = false;
|
package/src/app.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Box, ContextMenuProvider, useNativeRenderer, useRendererHost } from "./ui";
|
|
2
2
|
import { ToastViewport, useToastHost } from "./ui/toast";
|
|
3
|
-
import { useState, useEffect, useCallback, useRef, useMemo } from "react";
|
|
3
|
+
import { useState, useEffect, useCallback, useRef, useMemo, type ReactNode } from "react";
|
|
4
4
|
import { useShortcut } from "./react/input";
|
|
5
5
|
import {
|
|
6
6
|
AppProvider,
|
|
@@ -17,12 +17,13 @@ import { Header } from "./components/layout/header";
|
|
|
17
17
|
import { StatusBar } from "./components/layout/status-bar";
|
|
18
18
|
import { Shell } from "./components/layout/shell";
|
|
19
19
|
import { DetachedPaneShell } from "./components/layout/detached-pane-shell";
|
|
20
|
+
import { getVisiblePaneCycleOrder } from "./components/layout/pane-cycle-order";
|
|
20
21
|
import { CommandBar } from "./components/command-bar/command-bar";
|
|
21
22
|
import { OnboardingWizard } from "./components/onboarding/onboarding-wizard";
|
|
22
23
|
import { useDialog, useDialogState } from "./ui/dialog";
|
|
23
24
|
import { PluginRegistry } from "./plugins/registry";
|
|
24
25
|
import type { TickerRepository } from "./data/ticker-repository";
|
|
25
|
-
import {
|
|
26
|
+
import { ThemeProvider, useThemeColors } from "./theme/theme-context";
|
|
26
27
|
import {
|
|
27
28
|
createPaneInstance,
|
|
28
29
|
findPaneInstance,
|
|
@@ -44,7 +45,7 @@ import type { TickerRecord } from "./types/ticker";
|
|
|
44
45
|
import type { DataProvider } from "./types/data-provider";
|
|
45
46
|
import type { TickerFinancials } from "./types/financials";
|
|
46
47
|
import type { BrokerAccount } from "./types/trading";
|
|
47
|
-
import type { DesktopDockPreviewState, DesktopSharedStateSnapshot, DesktopWindowBridge } from "./types/desktop-window";
|
|
48
|
+
import type { DesktopDockPreviewState, DesktopSharedStateSnapshot, DesktopThemePreviewState, DesktopWindowBridge } from "./types/desktop-window";
|
|
48
49
|
import type { DesktopApplicationMenuBridge } from "./types/desktop-menu";
|
|
49
50
|
import { resolveTickerSearch, upsertTickerFromSearchResult } from "./utils/ticker-search";
|
|
50
51
|
|
|
@@ -94,6 +95,10 @@ import {
|
|
|
94
95
|
createPaneTemplateOrThrow,
|
|
95
96
|
} from "./components/command-bar/workflow-ops";
|
|
96
97
|
import { getPaneTemplateDisplayLabel } from "./components/command-bar/pane-template-display";
|
|
98
|
+
import {
|
|
99
|
+
resolveTickerNavigationDetailPane,
|
|
100
|
+
shouldFocusTickerNavigationTarget,
|
|
101
|
+
} from "./plugins/ticker-navigation";
|
|
97
102
|
import { debugLog } from "./utils/debug-log";
|
|
98
103
|
import type { MarketDataCoordinator } from "./market-data/coordinator";
|
|
99
104
|
import { instrumentFromTicker } from "./market-data/request-types";
|
|
@@ -135,6 +140,15 @@ interface AppInnerProps {
|
|
|
135
140
|
desktopApplicationMenuBridge?: DesktopApplicationMenuBridge;
|
|
136
141
|
}
|
|
137
142
|
|
|
143
|
+
function ThemedAppRoot({ children }: { children: ReactNode }) {
|
|
144
|
+
const themeColors = useThemeColors();
|
|
145
|
+
return (
|
|
146
|
+
<Box flexDirection="column" flexGrow={1} backgroundColor={themeColors.bg}>
|
|
147
|
+
{children}
|
|
148
|
+
</Box>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
function AppInner({
|
|
139
153
|
pluginRegistry,
|
|
140
154
|
tickerRepository,
|
|
@@ -510,6 +524,96 @@ function AppInner({
|
|
|
510
524
|
});
|
|
511
525
|
}, [performRefreshQuote]);
|
|
512
526
|
|
|
527
|
+
const refreshTickersBatch = useCallback((entries: Array<{ ticker: TickerRecord; priority: number }>) => {
|
|
528
|
+
const runnable = entries.filter(({ ticker }) => {
|
|
529
|
+
const symbol = ticker.metadata.ticker;
|
|
530
|
+
return !refreshInFlight.has(symbol) && !pendingRefreshesRef.current.financials.has(symbol);
|
|
531
|
+
});
|
|
532
|
+
if (runnable.length === 0) return;
|
|
533
|
+
for (const { ticker } of runnable) {
|
|
534
|
+
pendingRefreshesRef.current.financials.add(ticker.metadata.ticker);
|
|
535
|
+
}
|
|
536
|
+
const priority = Math.min(...runnable.map((entry) => entry.priority));
|
|
537
|
+
refreshQueueRef.current.queue.enqueue({
|
|
538
|
+
key: `financials-batch:${priority}:${runnable.map(({ ticker }) => ticker.metadata.ticker).join(",")}`,
|
|
539
|
+
priority,
|
|
540
|
+
run: async () => {
|
|
541
|
+
const instrumentEntries = runnable.flatMap(({ ticker }) => {
|
|
542
|
+
const instrument = instrumentFromTicker(ticker, ticker.metadata.ticker);
|
|
543
|
+
return instrument ? [{ ticker, instrument }] : [];
|
|
544
|
+
});
|
|
545
|
+
for (const { ticker } of runnable) {
|
|
546
|
+
const symbol = ticker.metadata.ticker;
|
|
547
|
+
refreshInFlight.add(symbol);
|
|
548
|
+
dispatch({ type: "SET_REFRESHING", symbol, refreshing: true });
|
|
549
|
+
}
|
|
550
|
+
try {
|
|
551
|
+
const entries = await marketData.loadSnapshotsBatch(instrumentEntries.map((entry) => entry.instrument));
|
|
552
|
+
entries.forEach((entry, index) => {
|
|
553
|
+
const ticker = instrumentEntries[index]?.ticker;
|
|
554
|
+
const data = entry.data ?? entry.lastGoodData;
|
|
555
|
+
if (ticker && data) {
|
|
556
|
+
pluginRegistry.events.emit("ticker:refreshed", { symbol: ticker.metadata.ticker, financials: data });
|
|
557
|
+
const currency = data.quote?.currency;
|
|
558
|
+
if (currency) void marketData.loadFxRate(currency).catch(() => {});
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
void marketData.loadFxRate(state.config.baseCurrency).catch(() => {});
|
|
562
|
+
} finally {
|
|
563
|
+
for (const { ticker } of runnable) {
|
|
564
|
+
const symbol = ticker.metadata.ticker;
|
|
565
|
+
refreshInFlight.delete(symbol);
|
|
566
|
+
pendingRefreshesRef.current.financials.delete(symbol);
|
|
567
|
+
dispatch({ type: "SET_REFRESHING", symbol, refreshing: false });
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
}, [dispatch, marketData, pluginRegistry.events, state.config.baseCurrency]);
|
|
573
|
+
|
|
574
|
+
const refreshQuotesBatch = useCallback((entries: Array<{ ticker: TickerRecord; priority: number }>) => {
|
|
575
|
+
const runnable = entries.filter(({ ticker }) => {
|
|
576
|
+
const symbol = ticker.metadata.ticker;
|
|
577
|
+
return !refreshInFlight.has(symbol)
|
|
578
|
+
&& !quoteRefreshInFlight.has(symbol)
|
|
579
|
+
&& !pendingRefreshesRef.current.financials.has(symbol)
|
|
580
|
+
&& !pendingRefreshesRef.current.quotes.has(symbol);
|
|
581
|
+
});
|
|
582
|
+
if (runnable.length === 0) return;
|
|
583
|
+
for (const { ticker } of runnable) {
|
|
584
|
+
pendingRefreshesRef.current.quotes.add(ticker.metadata.ticker);
|
|
585
|
+
}
|
|
586
|
+
const priority = Math.min(...runnable.map((entry) => entry.priority));
|
|
587
|
+
refreshQueueRef.current.queue.enqueue({
|
|
588
|
+
key: `quotes-batch:${priority}:${runnable.map(({ ticker }) => ticker.metadata.ticker).join(",")}`,
|
|
589
|
+
priority,
|
|
590
|
+
run: async () => {
|
|
591
|
+
const instrumentEntries = runnable.flatMap(({ ticker }) => {
|
|
592
|
+
const instrument = instrumentFromTicker(ticker, ticker.metadata.ticker);
|
|
593
|
+
return instrument ? [{ ticker, instrument }] : [];
|
|
594
|
+
});
|
|
595
|
+
for (const { ticker } of runnable) {
|
|
596
|
+
quoteRefreshInFlight.add(ticker.metadata.ticker);
|
|
597
|
+
}
|
|
598
|
+
try {
|
|
599
|
+
const entries = await marketData.loadQuotesBatch(instrumentEntries.map((entry) => entry.instrument));
|
|
600
|
+
entries.forEach((entry) => {
|
|
601
|
+
const quote = entry.data ?? entry.lastGoodData;
|
|
602
|
+
const currency = quote?.currency;
|
|
603
|
+
if (currency) void marketData.loadFxRate(currency).catch(() => {});
|
|
604
|
+
});
|
|
605
|
+
void marketData.loadFxRate(state.config.baseCurrency).catch(() => {});
|
|
606
|
+
} finally {
|
|
607
|
+
for (const { ticker } of runnable) {
|
|
608
|
+
const symbol = ticker.metadata.ticker;
|
|
609
|
+
quoteRefreshInFlight.delete(symbol);
|
|
610
|
+
pendingRefreshesRef.current.quotes.delete(symbol);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
});
|
|
615
|
+
}, [marketData, state.config.baseCurrency]);
|
|
616
|
+
|
|
513
617
|
const primeCachedFinancials = useCallback((entries: Array<{ ticker: TickerRecord; financials: TickerFinancials }>) => {
|
|
514
618
|
const primeEntries = entries.flatMap(({ ticker, financials }) => {
|
|
515
619
|
const instrument = instrumentFromTicker(ticker, ticker.metadata.ticker);
|
|
@@ -720,6 +824,8 @@ function AppInner({
|
|
|
720
824
|
primeCachedFinancials,
|
|
721
825
|
refreshTicker,
|
|
722
826
|
refreshQuote,
|
|
827
|
+
refreshTickersBatch,
|
|
828
|
+
refreshQuotesBatch,
|
|
723
829
|
autoImportBrokerPositions,
|
|
724
830
|
persistedBrokerAccounts,
|
|
725
831
|
}), {
|
|
@@ -731,7 +837,7 @@ function AppInner({
|
|
|
731
837
|
// Will show empty state
|
|
732
838
|
}
|
|
733
839
|
})();
|
|
734
|
-
}, [autoImportBrokerPositions, dataProvider, dispatch, primeCachedFinancials, tickerRepository, refreshQuote, refreshTicker, sessionSnapshot, state.config, state.initialized]);
|
|
840
|
+
}, [autoImportBrokerPositions, dataProvider, dispatch, primeCachedFinancials, tickerRepository, refreshQuote, refreshQuotesBatch, refreshTicker, refreshTickersBatch, sessionSnapshot, state.config, state.initialized]);
|
|
735
841
|
|
|
736
842
|
const focusedTickerSymbol = getFocusedTickerSymbol(state);
|
|
737
843
|
|
|
@@ -1272,8 +1378,9 @@ function AppInner({
|
|
|
1272
1378
|
activatePane(instance.instanceId, nextLayout);
|
|
1273
1379
|
};
|
|
1274
1380
|
|
|
1275
|
-
pluginRegistry.navigateTickerFn = (rawSymbol) => {
|
|
1381
|
+
pluginRegistry.navigateTickerFn = (rawSymbol, options) => {
|
|
1276
1382
|
if (isDetachedWindow) return;
|
|
1383
|
+
const sourcePaneId = options?.sourcePaneId ?? stateRef.current.focusedPaneId;
|
|
1277
1384
|
(async () => {
|
|
1278
1385
|
try {
|
|
1279
1386
|
// Resolve or create the ticker in the local database
|
|
@@ -1296,45 +1403,31 @@ function AppInner({
|
|
|
1296
1403
|
}
|
|
1297
1404
|
}
|
|
1298
1405
|
|
|
1299
|
-
// Active panel resolution — navigate the
|
|
1300
|
-
// 1. If the
|
|
1301
|
-
// 2. If a ticker-detail follows the
|
|
1406
|
+
// Active panel resolution — navigate the initiating or linked detail pane:
|
|
1407
|
+
// 1. If the source pane IS a ticker-detail, retarget it directly
|
|
1408
|
+
// 2. If a ticker-detail follows the source pane, retarget that
|
|
1302
1409
|
// 3. Any follow-mode ticker-detail in the layout
|
|
1303
1410
|
// 4. Any ticker-detail in the layout
|
|
1304
1411
|
// 5. Fall back to pinning a new pane
|
|
1305
1412
|
const currentState = stateRef.current;
|
|
1306
1413
|
const currentLayout = currentState.config.layout;
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
inst.paneId === "ticker-detail"
|
|
1319
|
-
&& inst.binding?.kind === "follow"
|
|
1320
|
-
&& inst.binding.sourceInstanceId === focused
|
|
1321
|
-
&& isPaneInLayout(currentLayout, inst.instanceId),
|
|
1322
|
-
)
|
|
1323
|
-
?? currentLayout.instances.find((inst) =>
|
|
1324
|
-
inst.paneId === "ticker-detail"
|
|
1325
|
-
&& inst.binding?.kind === "follow"
|
|
1326
|
-
&& isPaneInLayout(currentLayout, inst.instanceId),
|
|
1327
|
-
)
|
|
1328
|
-
?? currentLayout.instances.find((inst) =>
|
|
1329
|
-
inst.paneId === "ticker-detail"
|
|
1330
|
-
&& isPaneInLayout(currentLayout, inst.instanceId),
|
|
1331
|
-
);
|
|
1414
|
+
const detailPane = resolveTickerNavigationDetailPane(currentLayout, sourcePaneId);
|
|
1415
|
+
const focusIfStillOwned = (paneId: string, layout: LayoutConfig) => {
|
|
1416
|
+
if (!shouldFocusTickerNavigationTarget({
|
|
1417
|
+
sourcePaneId,
|
|
1418
|
+
currentFocusedPaneId: stateRef.current.focusedPaneId,
|
|
1419
|
+
targetPaneId: paneId,
|
|
1420
|
+
})) {
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
activatePane(paneId, layout);
|
|
1424
|
+
};
|
|
1332
1425
|
|
|
1333
1426
|
if (detailPane) {
|
|
1334
1427
|
if (detailPane.binding?.kind === "follow") {
|
|
1335
1428
|
const sourceId = detailPane.binding.sourceInstanceId;
|
|
1336
1429
|
dispatch({ type: "UPDATE_PANE_STATE", paneId: sourceId, patch: { cursorSymbol: symbol } });
|
|
1337
|
-
|
|
1430
|
+
focusIfStillOwned(detailPane.instanceId, currentLayout);
|
|
1338
1431
|
} else {
|
|
1339
1432
|
const nextLayout = {
|
|
1340
1433
|
...currentLayout,
|
|
@@ -1345,9 +1438,13 @@ function AppInner({
|
|
|
1345
1438
|
)),
|
|
1346
1439
|
};
|
|
1347
1440
|
persistLayout(nextLayout);
|
|
1348
|
-
|
|
1441
|
+
focusIfStillOwned(detailPane.instanceId, nextLayout);
|
|
1349
1442
|
}
|
|
1350
|
-
} else {
|
|
1443
|
+
} else if (shouldFocusTickerNavigationTarget({
|
|
1444
|
+
sourcePaneId,
|
|
1445
|
+
currentFocusedPaneId: stateRef.current.focusedPaneId,
|
|
1446
|
+
targetPaneId: null,
|
|
1447
|
+
})) {
|
|
1351
1448
|
pluginRegistry.pinTicker(symbol, { floating: false });
|
|
1352
1449
|
}
|
|
1353
1450
|
} catch (err) {
|
|
@@ -1441,18 +1538,20 @@ function AppInner({
|
|
|
1441
1538
|
if (state.commandBarOpen || state.inputCaptured) return;
|
|
1442
1539
|
|
|
1443
1540
|
if (event.name === "tab") {
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1541
|
+
const paneOrder = getVisiblePaneCycleOrder(
|
|
1542
|
+
state.config.layout,
|
|
1543
|
+
pluginRegistry,
|
|
1544
|
+
state.config.disabledPlugins,
|
|
1545
|
+
);
|
|
1546
|
+
if (paneOrder.length === 0) return;
|
|
1450
1547
|
|
|
1451
1548
|
if (event.shift) {
|
|
1452
1549
|
dispatch({ type: "FOCUS_PREV", paneOrder });
|
|
1453
1550
|
} else {
|
|
1454
1551
|
dispatch({ type: "FOCUS_NEXT", paneOrder });
|
|
1455
1552
|
}
|
|
1553
|
+
event.preventDefault();
|
|
1554
|
+
event.stopPropagation();
|
|
1456
1555
|
} else if (!isDetachedWindow && event.name === "q" && !(focusedPane?.paneId === "ticker-detail" && focusedDetailTab === "financials")) {
|
|
1457
1556
|
rendererHost.requestExit();
|
|
1458
1557
|
} else if (event.name === "r") {
|
|
@@ -1494,20 +1593,20 @@ function AppInner({
|
|
|
1494
1593
|
if (desktopWindowBridge?.kind === "detached" && desktopWindowBridge.paneId) {
|
|
1495
1594
|
return (
|
|
1496
1595
|
<ContextMenuProvider pluginRegistry={pluginRegistry}>
|
|
1497
|
-
<
|
|
1596
|
+
<ThemedAppRoot>
|
|
1498
1597
|
<DetachedPaneShell
|
|
1499
1598
|
pluginRegistry={pluginRegistry}
|
|
1500
1599
|
desktopWindowBridge={{ ...desktopWindowBridge, kind: "detached", paneId: desktopWindowBridge.paneId }}
|
|
1501
1600
|
/>
|
|
1502
1601
|
<ToastViewport position="bottom-right" />
|
|
1503
|
-
</
|
|
1602
|
+
</ThemedAppRoot>
|
|
1504
1603
|
</ContextMenuProvider>
|
|
1505
1604
|
);
|
|
1506
1605
|
}
|
|
1507
1606
|
|
|
1508
1607
|
return (
|
|
1509
1608
|
<ContextMenuProvider pluginRegistry={pluginRegistry}>
|
|
1510
|
-
<
|
|
1609
|
+
<ThemedAppRoot>
|
|
1511
1610
|
<Header />
|
|
1512
1611
|
<Shell
|
|
1513
1612
|
pluginRegistry={pluginRegistry}
|
|
@@ -1525,7 +1624,7 @@ function AppInner({
|
|
|
1525
1624
|
/>
|
|
1526
1625
|
)}
|
|
1527
1626
|
<ToastViewport position="bottom-right" />
|
|
1528
|
-
</
|
|
1627
|
+
</ThemedAppRoot>
|
|
1529
1628
|
</ContextMenuProvider>
|
|
1530
1629
|
);
|
|
1531
1630
|
}
|
|
@@ -1537,6 +1636,7 @@ interface AppProps {
|
|
|
1537
1636
|
desktopWindowBridge?: DesktopWindowBridge;
|
|
1538
1637
|
desktopApplicationMenuBridge?: DesktopApplicationMenuBridge;
|
|
1539
1638
|
desktopSnapshot?: DesktopSharedStateSnapshot | null;
|
|
1639
|
+
desktopThemePreview?: DesktopThemePreviewState | null;
|
|
1540
1640
|
}
|
|
1541
1641
|
|
|
1542
1642
|
export function App({
|
|
@@ -1546,6 +1646,7 @@ export function App({
|
|
|
1546
1646
|
desktopWindowBridge,
|
|
1547
1647
|
desktopApplicationMenuBridge,
|
|
1548
1648
|
desktopSnapshot = null,
|
|
1649
|
+
desktopThemePreview = null,
|
|
1549
1650
|
}: AppProps) {
|
|
1550
1651
|
const renderer = useNativeRenderer();
|
|
1551
1652
|
const effectiveInitialConfig = useMemo(() => {
|
|
@@ -1576,9 +1677,6 @@ export function App({
|
|
|
1576
1677
|
});
|
|
1577
1678
|
const [showOnboarding, setShowOnboarding] = useState(!effectiveInitialConfig.onboardingComplete);
|
|
1578
1679
|
|
|
1579
|
-
// Keep the shared palette aligned before this render builds any JSX that reads `colors`.
|
|
1580
|
-
syncTheme(config.theme);
|
|
1581
|
-
|
|
1582
1680
|
useEffect(() => bindAppActivity(renderer), [renderer]);
|
|
1583
1681
|
|
|
1584
1682
|
const services = useMemo(() => {
|
|
@@ -1634,14 +1732,16 @@ export function App({
|
|
|
1634
1732
|
|
|
1635
1733
|
if (showOnboarding) {
|
|
1636
1734
|
return (
|
|
1637
|
-
<
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1735
|
+
<ThemeProvider themeId={config.theme}>
|
|
1736
|
+
<OnboardingWizard
|
|
1737
|
+
config={config}
|
|
1738
|
+
pluginRegistry={services.pluginRegistry}
|
|
1739
|
+
onComplete={(updatedConfig) => {
|
|
1740
|
+
setConfig(updatedConfig);
|
|
1741
|
+
setShowOnboarding(false);
|
|
1742
|
+
}}
|
|
1743
|
+
/>
|
|
1744
|
+
</ThemeProvider>
|
|
1645
1745
|
);
|
|
1646
1746
|
}
|
|
1647
1747
|
|
|
@@ -1652,6 +1752,7 @@ export function App({
|
|
|
1652
1752
|
sessionSnapshot={sessionSnapshot}
|
|
1653
1753
|
desktopBridge={desktopWindowBridge}
|
|
1654
1754
|
desktopSnapshot={desktopSnapshot}
|
|
1755
|
+
initialThemePreview={desktopThemePreview}
|
|
1655
1756
|
>
|
|
1656
1757
|
<AppInner
|
|
1657
1758
|
pluginRegistry={services.pluginRegistry}
|
|
@@ -26,6 +26,8 @@ export function assetDataProvider(provider: AssetDataProvider): AssetDataCapabil
|
|
|
26
26
|
operations: {
|
|
27
27
|
canProvide: op((input: any) => provider.canProvide?.(input.ticker, input.exchange, input.context) ?? true, "query"),
|
|
28
28
|
getCachedFinancialsForTargets: op((input: any) => provider.getCachedFinancialsForTargets?.(input.targets ?? [], input.options) ?? new Map()),
|
|
29
|
+
getQuotesBatch: op((input: any) => provider.getQuotesBatch?.(input.targets ?? [], input.options) ?? Promise.resolve([])),
|
|
30
|
+
getTickerFinancialsBatch: op((input: any) => provider.getTickerFinancialsBatch?.(input.targets ?? [], input.options) ?? Promise.resolve([])),
|
|
29
31
|
getTickerFinancials: op((input: any) => provider.getTickerFinancials(input.ticker, input.exchange, input.context)),
|
|
30
32
|
getQuote: op((input: any) => provider.getQuote(input.ticker, input.exchange, input.context)),
|
|
31
33
|
getExchangeRate: op((input: any) => provider.getExchangeRate(input.fromCurrency)),
|
|
@@ -95,6 +97,7 @@ export function newsProvider(options: {
|
|
|
95
97
|
supports: op((input: any) => options.provider.supports?.(input.query) ?? true, "query"),
|
|
96
98
|
getCachedNews: op((input: any) => options.provider.getCachedNews?.(input.query) ?? [], "query"),
|
|
97
99
|
fetchNews: op((input: any) => options.provider.fetchNews(input.query), "query"),
|
|
100
|
+
fetchNewsStory: op((input: any) => options.provider.fetchNewsStory?.(input.storyId) ?? null, "query"),
|
|
98
101
|
},
|
|
99
102
|
};
|
|
100
103
|
}
|
package/src/cli/registry.test.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { join } from "path";
|
|
|
4
4
|
import { tmpdir } from "os";
|
|
5
5
|
import { createDefaultConfig } from "../types/config";
|
|
6
6
|
import type { GloomPlugin } from "../types/plugin";
|
|
7
|
-
import type { LoadedExternalPlugin } from "../plugins/loader";
|
|
8
7
|
import {
|
|
9
8
|
buildCliCommandRegistry,
|
|
10
9
|
createCliCommandContext,
|