gloomberb 0.9.4 → 0.9.6
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 +49 -8
- package/package.json +4 -3
- package/patches/@opentui%2Fcore@0.3.2.patch +231 -29
- package/patches/react-reconciler@0.33.0.patch +10 -0
- package/src/app/global-shortcuts.test.tsx +20 -1
- package/src/app/global-shortcuts.ts +2 -0
- package/src/app/pane-runtime/index.tsx +11 -4
- package/src/app/pane-runtime/pane-settings-runtime.tsx +1 -1
- package/src/app.tsx +41 -17
- package/src/cli/commands/remote.ts +206 -0
- package/src/cli/entry.ts +8 -1
- package/src/cli/index.ts +2 -0
- package/src/cli/native-smoke.ts +5 -0
- package/src/components/chart/core/keyboard.ts +10 -1
- package/src/components/chart/native/bitmap-support.test.ts +27 -0
- package/src/components/chart/native/bitmap-support.ts +55 -0
- package/src/components/chart/native/kitty/index.test.ts +47 -0
- package/src/components/chart/native/surface/visibility.ts +8 -1
- package/src/components/chart/static/bar-chart-surface.test.tsx +4 -0
- package/src/components/chart/static/chart/bitmap.ts +16 -9
- package/src/components/chart/static/chart/surface.test.tsx +59 -4
- package/src/components/chart/static/chart/surface.tsx +4 -0
- package/src/components/chart/stock-chart/index.test.ts +7 -0
- package/src/components/command-bar/list/view.tsx +48 -1
- package/src/components/command-bar/multi-select-picker.tsx +7 -0
- package/src/components/command-bar/routing/navigation-state.ts +10 -1
- package/src/components/command-bar/surface/index.test.tsx +14 -0
- package/src/components/command-bar/theme-picker.tsx +91 -79
- package/src/components/command-bar/workflow/field-row.tsx +30 -5
- package/src/components/data-table/view.tsx +0 -12
- package/src/components/index.ts +7 -0
- package/src/components/layout/floating-pane.tsx +3 -3
- package/src/components/layout/pane/footer/index.tsx +23 -0
- package/src/components/layout/pane/header.tsx +5 -0
- package/src/components/layout/pane/index.tsx +3 -3
- package/src/components/layout/shell/action-menu-overlay.tsx +1 -1
- package/src/components/layout/shell/cursor-occlusion.ts +9 -1
- package/src/components/layout/shell/index.test.tsx +2 -0
- package/src/components/layout/shell/index.tsx +16 -4
- package/src/components/layout/shell/pane/actions.ts +21 -7
- package/src/components/layout/shell/pane/layers.tsx +2 -2
- package/src/components/layout/status-bar.tsx +5 -5
- package/src/components/metric-treemap/index.tsx +317 -0
- package/src/components/metric-treemap/layout.test.ts +77 -0
- package/src/components/metric-treemap/layout.ts +476 -0
- package/src/components/pane-settings-dialog/desktop.tsx +1 -1
- package/src/components/price-performance.tsx +1 -1
- package/src/components/price-sparkline/view.tsx +15 -14
- package/src/components/speedometer-gauge/terminal.tsx +18 -15
- package/src/components/table-view-shared.tsx +0 -10
- package/src/components/ticker/list-table-view.tsx +1 -7
- package/src/components/ticker/list-table.test.tsx +0 -4
- package/src/components/toggle-list.tsx +10 -0
- package/src/components/ui/button.tsx +12 -0
- package/src/components/ui/data-table/index.tsx +51 -0
- package/src/components/ui/data-table/opentui/index.tsx +4 -10
- package/src/components/ui/data-table/types.ts +6 -4
- package/src/components/ui/fields.tsx +18 -0
- package/src/components/ui/list-view.tsx +84 -4
- package/src/components/ui/message-composer.tsx +22 -0
- package/src/components/ui/tabs.tsx +46 -2
- package/src/components/ui/ui.test.tsx +0 -9
- package/src/core/state/app/layout-reducer.ts +7 -1
- package/src/core/state/app/layout.ts +6 -0
- package/src/core/state/app/state.ts +23 -1
- package/src/core/state/app/types.ts +4 -2
- package/src/plugins/builtin/account-management/form-components.tsx +2 -2
- package/src/plugins/builtin/alerts/pane.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +1 -1
- package/src/plugins/builtin/chat/channels.ts +5 -18
- package/src/plugins/builtin/chat/chat.test.tsx +1 -7
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -1
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +1 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +2 -2
- package/src/plugins/builtin/chat/sidebar.tsx +1 -1
- package/src/plugins/builtin/chat/status-widget.tsx +2 -8
- package/src/plugins/builtin/cloud/auth-actions.tsx +2 -2
- package/src/plugins/builtin/cloud/plugin.tsx +4 -13
- package/src/plugins/builtin/correlation/matrix/symbol-cell.tsx +1 -1
- package/src/plugins/builtin/debug/index.tsx +3 -4
- package/src/plugins/builtin/help/components.tsx +1 -1
- package/src/plugins/builtin/holders/treemap.tsx +28 -297
- package/src/plugins/builtin/holders/types.ts +0 -34
- package/src/plugins/builtin/market-heatmap/data.test.ts +121 -0
- package/src/plugins/builtin/market-heatmap/data.ts +296 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +320 -0
- package/src/plugins/builtin/options/table.ts +5 -5
- package/src/plugins/builtin/plugin-groups.ts +2 -0
- package/src/plugins/builtin/portfolio-list/grid.tsx +197 -0
- package/src/plugins/builtin/portfolio-list/pane/index.test.tsx +41 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +78 -22
- package/src/plugins/ibkr/gateway/service/index.test.ts +22 -0
- package/src/plugins/ibkr/gateway/service/index.ts +6 -9
- package/src/plugins/ibkr/gateway/service/native-loader.ts +12 -0
- package/src/plugins/ibkr/trade/ticket-panel.tsx +1 -1
- package/src/remote/app-host.tsx +77 -0
- package/src/remote/client.ts +34 -0
- package/src/remote/command-bar.ts +98 -0
- package/src/remote/controller-utils.ts +111 -0
- package/src/remote/controller.test.ts +365 -0
- package/src/remote/controller.ts +434 -0
- package/src/remote/endpoint.ts +41 -0
- package/src/remote/json-patch.test.ts +31 -0
- package/src/remote/json-patch.ts +89 -0
- package/src/remote/layout-helpers.ts +62 -0
- package/src/remote/resources.ts +186 -0
- package/src/remote/revision.ts +18 -0
- package/src/remote/schema.ts +143 -0
- package/src/remote/semantic-helpers.ts +161 -0
- package/src/remote/semantic-tree.tsx +112 -0
- package/src/remote/server.test.ts +50 -0
- package/src/remote/server.ts +121 -0
- package/src/remote/types.ts +119 -0
- package/src/renderers/electrobun/bun/index.ts +55 -1
- package/src/renderers/electrobun/shared/protocol.ts +11 -1
- package/src/renderers/electrobun/view/backend-rpc.ts +28 -1
- package/src/renderers/electrobun/view/build-assets.ts +1 -0
- package/src/renderers/electrobun/view/data-table/index.tsx +0 -8
- package/src/renderers/electrobun/view/data-table/row.tsx +2 -12
- package/src/renderers/electrobun/view/host/box.tsx +11 -1
- package/src/renderers/electrobun/view/host/mouse.test.ts +37 -0
- package/src/renderers/electrobun/view/host/mouse.ts +2 -0
- package/src/renderers/electrobun/view/host/style.ts +1 -0
- package/src/renderers/electrobun/view/main.tsx +5 -1
- package/src/renderers/electrobun/view/native-stubs/ibkr-native-loader.ts +3 -0
- package/src/renderers/electrobun/view/styles.css +7 -0
- package/src/renderers/opentui/chart-surface.test.tsx +101 -0
- package/src/renderers/opentui/chart-surface.tsx +15 -20
- package/src/renderers/opentui/native-smoke.ts +1 -0
- package/src/renderers/opentui/start.tsx +32 -0
- package/src/sources/yahoo-finance/http.ts +31 -4
- package/src/state/app/context/index.test.tsx +47 -0
- package/src/state/app/context/index.tsx +48 -18
- package/src/ui/host.tsx +1 -0
- package/src/ui/index.tsx +183 -7
- package/src/version.ts +1 -1
- package/src/plugins/builtin/holders/treemap-layout.ts +0 -231
|
@@ -351,6 +351,9 @@ export function focusPaneState(state: AppState, paneId: string): AppState {
|
|
|
351
351
|
...state,
|
|
352
352
|
config: syncConfigActiveLayoutState(config, state.paneState, paneId, state.activePanel),
|
|
353
353
|
focusedPaneId: paneId,
|
|
354
|
+
previousFocusedPaneId: state.focusedPaneId && state.focusedPaneId !== paneId
|
|
355
|
+
? state.focusedPaneId
|
|
356
|
+
: state.previousFocusedPaneId,
|
|
354
357
|
recentTickers,
|
|
355
358
|
};
|
|
356
359
|
}
|
|
@@ -386,6 +389,9 @@ export function withFocusedPane(
|
|
|
386
389
|
paneState: nextPaneState,
|
|
387
390
|
brokerAccounts: reconcileBrokerAccounts(syncedConfig, state.brokerAccounts),
|
|
388
391
|
focusedPaneId,
|
|
392
|
+
previousFocusedPaneId: state.focusedPaneId && state.focusedPaneId !== focusedPaneId
|
|
393
|
+
? state.focusedPaneId
|
|
394
|
+
: state.previousFocusedPaneId,
|
|
389
395
|
activePanel,
|
|
390
396
|
};
|
|
391
397
|
}
|
|
@@ -108,7 +108,9 @@ export function appReducer(state: AppState, action: AppAction): AppState {
|
|
|
108
108
|
return { ...state, recentTickers: nextRecentTickers(state.recentTickers, action.symbol) };
|
|
109
109
|
|
|
110
110
|
case "SET_ACTIVE_PANEL": {
|
|
111
|
-
const firstPane =
|
|
111
|
+
const firstPane = action.preserveFocus
|
|
112
|
+
? state.focusedPaneId
|
|
113
|
+
: getPanelFocusTarget(state.config.layout, action.panel);
|
|
112
114
|
return withFocusedPane(state, state.config, {
|
|
113
115
|
activePanel: action.panel,
|
|
114
116
|
focusedPaneId: firstPane ?? state.focusedPaneId,
|
|
@@ -260,6 +262,25 @@ export function appReducer(state: AppState, action: AppAction): AppState {
|
|
|
260
262
|
};
|
|
261
263
|
}
|
|
262
264
|
|
|
265
|
+
case "REPLACE_PANE_STATE": {
|
|
266
|
+
const current = state.paneState[action.paneId] ?? {};
|
|
267
|
+
const nextState = action.state;
|
|
268
|
+
if (Object.is(current, nextState)) return state;
|
|
269
|
+
const paneState = {
|
|
270
|
+
...state.paneState,
|
|
271
|
+
[action.paneId]: nextState,
|
|
272
|
+
};
|
|
273
|
+
const recentTickers = current.cursorSymbol !== nextState.cursorSymbol
|
|
274
|
+
? nextRecentTickers(state.recentTickers, typeof nextState.cursorSymbol === "string" ? nextState.cursorSymbol : null)
|
|
275
|
+
: state.recentTickers;
|
|
276
|
+
return {
|
|
277
|
+
...state,
|
|
278
|
+
config: syncConfigActiveLayoutState(state.config, paneState, state.focusedPaneId, state.activePanel),
|
|
279
|
+
paneState,
|
|
280
|
+
recentTickers,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
263
284
|
case "UPDATE_PLUGIN_PANE_STATE": {
|
|
264
285
|
const current = state.paneState[action.paneId] ?? {};
|
|
265
286
|
const currentPluginState = current.pluginState ?? {};
|
|
@@ -319,6 +340,7 @@ export function createInitialState(config: AppConfig, sessionSnapshot: AppSessio
|
|
|
319
340
|
brokerAccounts: {},
|
|
320
341
|
activePanel,
|
|
321
342
|
focusedPaneId,
|
|
343
|
+
previousFocusedPaneId: null,
|
|
322
344
|
paneState,
|
|
323
345
|
recentTickers: config.recentTickers,
|
|
324
346
|
commandBarOpen: false,
|
|
@@ -48,6 +48,7 @@ export interface AppState {
|
|
|
48
48
|
brokerAccounts: Record<string, BrokerAccount[]>;
|
|
49
49
|
activePanel: "left" | "right";
|
|
50
50
|
focusedPaneId: string | null;
|
|
51
|
+
previousFocusedPaneId: string | null;
|
|
51
52
|
paneState: Record<string, PaneRuntimeState>;
|
|
52
53
|
recentTickers: string[];
|
|
53
54
|
commandBarOpen: boolean;
|
|
@@ -76,7 +77,7 @@ export type AppAction =
|
|
|
76
77
|
| { type: "MERGE_QUOTE"; symbol: string; quote: Quote }
|
|
77
78
|
| { type: "HYDRATE_FINANCIALS"; financials: Map<string, TickerFinancials> }
|
|
78
79
|
| { type: "TRACK_TICKER"; symbol: string | null }
|
|
79
|
-
| { type: "SET_ACTIVE_PANEL"; panel: "left" | "right" }
|
|
80
|
+
| { type: "SET_ACTIVE_PANEL"; panel: "left" | "right"; preserveFocus?: boolean }
|
|
80
81
|
| { type: "TOGGLE_COMMAND_BAR" }
|
|
81
82
|
| {
|
|
82
83
|
type: "SET_COMMAND_BAR";
|
|
@@ -104,7 +105,7 @@ export type AppAction =
|
|
|
104
105
|
| { type: "PUSH_LAYOUT_HISTORY" }
|
|
105
106
|
| { type: "UNDO_LAYOUT" }
|
|
106
107
|
| { type: "REDO_LAYOUT" }
|
|
107
|
-
| { type: "UPDATE_LAYOUT"; layout: LayoutConfig }
|
|
108
|
+
| { type: "UPDATE_LAYOUT"; layout: LayoutConfig; focusedPaneId?: string | null }
|
|
108
109
|
| { type: "SWITCH_LAYOUT"; index: number }
|
|
109
110
|
| { type: "NEW_LAYOUT"; name: string }
|
|
110
111
|
| { type: "DELETE_LAYOUT"; index: number }
|
|
@@ -121,4 +122,5 @@ export type AppAction =
|
|
|
121
122
|
key: string;
|
|
122
123
|
value: unknown;
|
|
123
124
|
}
|
|
125
|
+
| { type: "REPLACE_PANE_STATE"; paneId: string; state: PaneRuntimeState }
|
|
124
126
|
| { type: "UPDATE_PANE_STATE"; paneId: string; patch: Partial<PaneRuntimeState> };
|
|
@@ -85,7 +85,7 @@ export function PickerRow({
|
|
|
85
85
|
return (
|
|
86
86
|
<Box
|
|
87
87
|
flexDirection="column"
|
|
88
|
-
|
|
88
|
+
onMouseOver={onFocus}
|
|
89
89
|
onMouseDown={(event?: { stopPropagation?: () => void; preventDefault?: () => void }) => {
|
|
90
90
|
event?.stopPropagation?.();
|
|
91
91
|
event?.preventDefault?.();
|
|
@@ -135,7 +135,7 @@ export function CheckboxRow({
|
|
|
135
135
|
<Box
|
|
136
136
|
flexDirection="column"
|
|
137
137
|
backgroundColor={hovered ? hoverBg() : undefined}
|
|
138
|
-
|
|
138
|
+
onMouseOver={() => {
|
|
139
139
|
setHovered(true);
|
|
140
140
|
onFocus();
|
|
141
141
|
}}
|
|
@@ -214,7 +214,7 @@ export function AlertsPane({ focused, width, height, close }: PaneProps) {
|
|
|
214
214
|
alert: AlertRule,
|
|
215
215
|
column: AlertColumn,
|
|
216
216
|
_index: number,
|
|
217
|
-
rowState: { selected: boolean
|
|
217
|
+
rowState: { selected: boolean },
|
|
218
218
|
): DataTableCell => {
|
|
219
219
|
const selectedColor = rowState.selected ? colors.selectedText : undefined;
|
|
220
220
|
const actionMouseDown = (handler: () => void) => (
|
|
@@ -26,7 +26,7 @@ interface BuildoutCellContext {
|
|
|
26
26
|
export function renderBuildoutCell(
|
|
27
27
|
row: BuildoutRow,
|
|
28
28
|
column: BuildoutColumn,
|
|
29
|
-
rowState: { selected: boolean
|
|
29
|
+
rowState: { selected: boolean },
|
|
30
30
|
context: BuildoutCellContext,
|
|
31
31
|
): DataTableCell {
|
|
32
32
|
const selectedColor = rowState.selected ? colors.selectedText : undefined;
|
|
@@ -314,7 +314,7 @@ export function BuildoutPane({ focused, width, height }: PaneProps) {
|
|
|
314
314
|
row: BuildoutRow,
|
|
315
315
|
column: BuildoutColumn,
|
|
316
316
|
_index: number,
|
|
317
|
-
rowState: { selected: boolean
|
|
317
|
+
rowState: { selected: boolean },
|
|
318
318
|
) => renderBuildoutCell(row, column, rowState, {
|
|
319
319
|
favoriteBusyKey,
|
|
320
320
|
toggleFavorite,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandResultDef, GloomPluginContext } from "../../../types/plugin";
|
|
2
2
|
import type { ChatChannel, ChatChannelState } from "../../../api-client";
|
|
3
|
-
import type { AppConfig
|
|
3
|
+
import type { AppConfig } from "../../../types/config";
|
|
4
4
|
import { chatController } from "./controller";
|
|
5
5
|
import { formatChannelLabel } from "./channel-labels";
|
|
6
6
|
|
|
@@ -25,14 +25,6 @@ export function getLastVisitedChatChannelId(config: { pluginConfig: Record<strin
|
|
|
25
25
|
return normalizeChannelId(config.pluginConfig["gloomberb-cloud"]?.[LAST_VISITED_CHAT_CHANNEL_KEY] as string | undefined);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function findChatPaneInstanceForChannel(config: AppConfig, channelId: string): PaneInstanceConfig | undefined {
|
|
29
|
-
const normalizedChannelId = normalizeChannelId(channelId);
|
|
30
|
-
return config.layout.instances.find((instance) => (
|
|
31
|
-
instance.paneId === "chat"
|
|
32
|
-
&& normalizeChannelId(typeof instance.settings?.channelId === "string" ? instance.settings.channelId : null) === normalizedChannelId
|
|
33
|
-
));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
28
|
export function getPreferredChatOpenChannelId(
|
|
37
29
|
config: AppConfig,
|
|
38
30
|
snapshot?: { channels: ChatChannel[]; channelStates: ChatChannelState[] },
|
|
@@ -80,17 +72,12 @@ export function hasOnlyDmUsernameArgs(value: string): boolean {
|
|
|
80
72
|
return parts.length > 0 && parts.every((part) => CHAT_USERNAME_ARG.test(part));
|
|
81
73
|
}
|
|
82
74
|
|
|
83
|
-
function openChatChannelFromCommand(ctx: Pick<GloomPluginContext, "createPaneFromTemplate"
|
|
84
|
-
const existingInstance = findChatPaneInstanceForChannel(ctx.getConfig(), channelId);
|
|
85
|
-
if (existingInstance) {
|
|
86
|
-
ctx.focusPane(existingInstance.instanceId);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
75
|
+
function openChatChannelFromCommand(ctx: Pick<GloomPluginContext, "createPaneFromTemplate">, channelId: string): void {
|
|
89
76
|
ctx.createPaneFromTemplate("new-chat-pane", { arg: channelId });
|
|
90
77
|
}
|
|
91
78
|
|
|
92
|
-
|
|
93
|
-
ctx: Pick<GloomPluginContext, "createPaneFromTemplate" | "
|
|
79
|
+
function openDefaultChatPane(
|
|
80
|
+
ctx: Pick<GloomPluginContext, "createPaneFromTemplate" | "getConfig">,
|
|
94
81
|
): void {
|
|
95
82
|
const config = ctx.getConfig();
|
|
96
83
|
openChatChannelFromCommand(ctx, getPreferredChatOpenChannelId(config, chatController.getSnapshot()));
|
|
@@ -98,7 +85,7 @@ export function openDefaultChatFromCommand(
|
|
|
98
85
|
|
|
99
86
|
export async function openDmTargetFromCommand(ctx: GloomPluginContext, usernames: string[]): Promise<void> {
|
|
100
87
|
if (usernames.length === 0) {
|
|
101
|
-
|
|
88
|
+
openDefaultChatPane(ctx);
|
|
102
89
|
return;
|
|
103
90
|
}
|
|
104
91
|
const channel = usernames.length === 1
|
|
@@ -1178,7 +1178,6 @@ describe("ChatContent", () => {
|
|
|
1178
1178
|
user: { id: "u1", username: "vince", emailVerified: true },
|
|
1179
1179
|
});
|
|
1180
1180
|
const openedTemplates: Array<{ templateId: string; options?: { arg?: string } }> = [];
|
|
1181
|
-
const focusedPanes: string[] = [];
|
|
1182
1181
|
const state = createInitialState(createDefaultConfig("/tmp/gloomberb-chat"));
|
|
1183
1182
|
state.config.disabledPlugins = [];
|
|
1184
1183
|
|
|
@@ -1186,9 +1185,6 @@ describe("ChatContent", () => {
|
|
|
1186
1185
|
createPaneFromTemplate(templateId: string, options?: { arg?: string }) {
|
|
1187
1186
|
openedTemplates.push({ templateId, options });
|
|
1188
1187
|
},
|
|
1189
|
-
focusPane(paneId: string) {
|
|
1190
|
-
focusedPanes.push(paneId);
|
|
1191
|
-
},
|
|
1192
1188
|
});
|
|
1193
1189
|
|
|
1194
1190
|
await act(async () => {
|
|
@@ -1230,9 +1226,7 @@ describe("ChatContent", () => {
|
|
|
1230
1226
|
await setup().renderOnce();
|
|
1231
1227
|
});
|
|
1232
1228
|
|
|
1233
|
-
expect(openedTemplates).toEqual([]);
|
|
1234
|
-
expect(focusedPanes).toHaveLength(1);
|
|
1235
|
-
expect(focusedPanes[0]?.startsWith("chat:")).toBe(true);
|
|
1229
|
+
expect(openedTemplates).toEqual([{ templateId: "new-chat-pane", options: { arg: "everyone" } }]);
|
|
1236
1230
|
});
|
|
1237
1231
|
|
|
1238
1232
|
test("opens an unread direct-message channel from the status widget", async () => {
|
|
@@ -97,7 +97,7 @@ export const DesktopChatMessage = memo(function DesktopChatMessage({
|
|
|
97
97
|
<Text
|
|
98
98
|
fg={state.authorColor}
|
|
99
99
|
attributes={state.authorAttributes}
|
|
100
|
-
|
|
100
|
+
onMouseOver={() => onUserHover(msg.user)}
|
|
101
101
|
onMouseOut={onUserHoverEnd}
|
|
102
102
|
style={{ cursor: "default" }}
|
|
103
103
|
>
|
|
@@ -44,7 +44,7 @@ export function TerminalChatMessage({
|
|
|
44
44
|
const messageRowProps = {
|
|
45
45
|
width: contentWidth,
|
|
46
46
|
backgroundColor: state.bgColor,
|
|
47
|
-
|
|
47
|
+
onMouseOver: setHovered,
|
|
48
48
|
onMouseOut: clearHovered,
|
|
49
49
|
};
|
|
50
50
|
|
|
@@ -80,7 +80,7 @@ export function TerminalChatMessage({
|
|
|
80
80
|
<Text
|
|
81
81
|
fg={state.authorColor}
|
|
82
82
|
attributes={state.authorAttributes}
|
|
83
|
-
|
|
83
|
+
onMouseOver={() => onUserHover(msg.user)}
|
|
84
84
|
onMouseOut={onUserHoverEnd}
|
|
85
85
|
>
|
|
86
86
|
{msg.user.username ?? "anon"}
|
|
@@ -239,7 +239,7 @@ export function ChannelSidebar({
|
|
|
239
239
|
flexDirection="row"
|
|
240
240
|
backgroundColor={bg}
|
|
241
241
|
onMouseDown={selectChannel}
|
|
242
|
-
|
|
242
|
+
onMouseOver={() => setHoveredChannelId((current) => (current === channel.id ? current : channel.id))}
|
|
243
243
|
onMouseOut={() => setHoveredChannelId((current) => (current === channel.id ? null : current))}
|
|
244
244
|
style={{ cursor: "pointer" }}
|
|
245
245
|
>
|
|
@@ -5,7 +5,6 @@ import { Box, Span, Text, TextAttributes, useUiCapabilities } from "../../../ui"
|
|
|
5
5
|
import { usePluginAppActions } from "../../runtime";
|
|
6
6
|
import { InlineAuthActions } from "../cloud/auth-actions";
|
|
7
7
|
import {
|
|
8
|
-
findChatPaneInstanceForChannel,
|
|
9
8
|
getPreferredChatOpenChannelId,
|
|
10
9
|
} from "./channels";
|
|
11
10
|
import { chatController, type ChatController } from "./controller";
|
|
@@ -53,7 +52,7 @@ function CloudStatusIcon() {
|
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
export function ChatStatusWidget({ controller = chatController }: ChatStatusWidgetProps) {
|
|
56
|
-
const { createPaneFromTemplate
|
|
55
|
+
const { createPaneFromTemplate } = usePluginAppActions();
|
|
57
56
|
const config = useAppSelector((state) => state.config);
|
|
58
57
|
const cloudPluginDisabled = config.disabledPlugins.includes("gloomberb-cloud");
|
|
59
58
|
const initialSnapshot = controller.getSnapshot();
|
|
@@ -67,11 +66,6 @@ export function ChatStatusWidget({ controller = chatController }: ChatStatusWidg
|
|
|
67
66
|
event?.preventDefault?.();
|
|
68
67
|
event?.stopPropagation?.();
|
|
69
68
|
const channelId = getPreferredChatOpenChannelId(config, snapshot);
|
|
70
|
-
const existingInstance = findChatPaneInstanceForChannel(config, channelId);
|
|
71
|
-
if (existingInstance) {
|
|
72
|
-
focusPane(existingInstance.instanceId);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
69
|
createPaneFromTemplate("new-chat-pane", { arg: channelId });
|
|
76
70
|
};
|
|
77
71
|
|
|
@@ -98,7 +92,7 @@ export function ChatStatusWidget({ controller = chatController }: ChatStatusWidg
|
|
|
98
92
|
<Box
|
|
99
93
|
flexDirection="row"
|
|
100
94
|
backgroundColor={hovered ? hoverBg() : undefined}
|
|
101
|
-
|
|
95
|
+
onMouseOver={() => setHovered((current) => (current ? current : true))}
|
|
102
96
|
onMouseOut={() => setHovered((current) => (current ? false : current))}
|
|
103
97
|
onMouseDown={openChat}
|
|
104
98
|
>
|
|
@@ -22,7 +22,7 @@ export function InlineAuthActions({ showSignup = true }: { showSignup?: boolean
|
|
|
22
22
|
<Box flexDirection="row">
|
|
23
23
|
<Box
|
|
24
24
|
backgroundColor={hoveredAction === "login" ? hoverBg() : undefined}
|
|
25
|
-
|
|
25
|
+
onMouseOver={() => setHoveredAction((current) => (current === "login" ? current : "login"))}
|
|
26
26
|
onMouseOut={() => setHoveredAction((current) => (current === "login" ? null : current))}
|
|
27
27
|
onMouseDown={(event: any) => openAuthCommand(openCommandBar, "Log In", event)}
|
|
28
28
|
>
|
|
@@ -33,7 +33,7 @@ export function InlineAuthActions({ showSignup = true }: { showSignup?: boolean
|
|
|
33
33
|
<Text fg={colors.textDim}>/</Text>
|
|
34
34
|
<Box
|
|
35
35
|
backgroundColor={hoveredAction === "signup" ? hoverBg() : undefined}
|
|
36
|
-
|
|
36
|
+
onMouseOver={() => setHoveredAction((current) => (current === "signup" ? current : "signup"))}
|
|
37
37
|
onMouseOut={() => setHoveredAction((current) => (current === "signup" ? null : current))}
|
|
38
38
|
onMouseDown={(event: any) => openAuthCommand(openCommandBar, "Sign Up", event)}
|
|
39
39
|
>
|
|
@@ -14,10 +14,9 @@ import { registerTwitterFeedFeature } from "../cloud-tweets";
|
|
|
14
14
|
import {
|
|
15
15
|
buildDmCommandResults,
|
|
16
16
|
formatChatPaneTitle,
|
|
17
|
-
|
|
17
|
+
getPreferredChatOpenChannelId,
|
|
18
18
|
hasOnlyDmUsernameArgs,
|
|
19
19
|
normalizeShortcutChannelId,
|
|
20
|
-
openDefaultChatFromCommand,
|
|
21
20
|
openDmTargetFromCommand,
|
|
22
21
|
parseDmUsernames,
|
|
23
22
|
} from "../chat/channels";
|
|
@@ -50,7 +49,9 @@ export function createGloomberbCloudPlugin({
|
|
|
50
49
|
createInstance: async (context, options) => {
|
|
51
50
|
const channelId = options?.arg
|
|
52
51
|
? await chatController.resolveRequiredChannelId(normalizeShortcutChannelId(options.arg))
|
|
53
|
-
: await chatController.resolvePreferredChannelId(
|
|
52
|
+
: await chatController.resolvePreferredChannelId(
|
|
53
|
+
getPreferredChatOpenChannelId(context.config, chatController.getSnapshot()),
|
|
54
|
+
);
|
|
54
55
|
const channel = chatController.getChannels().find((entry) => entry.id === channelId);
|
|
55
56
|
return {
|
|
56
57
|
placement: "floating",
|
|
@@ -144,16 +145,6 @@ export function createGloomberbCloudPlugin({
|
|
|
144
145
|
|
|
145
146
|
registerTwitterFeedFeature(ctx);
|
|
146
147
|
|
|
147
|
-
ctx.registerCommand({
|
|
148
|
-
id: "open-chat",
|
|
149
|
-
label: "Chat",
|
|
150
|
-
description: "Open chat",
|
|
151
|
-
keywords: ["chat", "message", "messages"],
|
|
152
|
-
category: "navigation",
|
|
153
|
-
shortcut: "CHAT",
|
|
154
|
-
execute: () => openDefaultChatFromCommand(ctx),
|
|
155
|
-
});
|
|
156
|
-
|
|
157
148
|
ctx.registerCommand({
|
|
158
149
|
id: "direct-message",
|
|
159
150
|
label: "DM",
|
|
@@ -41,7 +41,7 @@ export function SymbolLabelCell({
|
|
|
41
41
|
overflow="hidden"
|
|
42
42
|
backgroundColor={hovered ? hoverBg() : undefined}
|
|
43
43
|
style={{ cursor: "pointer" }}
|
|
44
|
-
|
|
44
|
+
onMouseOver={() => onHover(symbol)}
|
|
45
45
|
onMouseOut={() => onLeave(symbol)}
|
|
46
46
|
onMouseDown={(event: any) => handleSymbolMouseDown(event, openSymbol)}
|
|
47
47
|
>
|
|
@@ -64,7 +64,6 @@ function DebugPane({ focused, width, height }: PaneProps) {
|
|
|
64
64
|
const [filterSource, setFilterSource] = useState<string | null>(null);
|
|
65
65
|
const [autoScroll, setAutoScroll] = useState(true);
|
|
66
66
|
const [selectedIdx, setSelectedIdx] = useState(-1);
|
|
67
|
-
const [hoveredIdx, setHoveredIdx] = useState<number | null>(null);
|
|
68
67
|
const [showDetail, setShowDetail] = useState(false);
|
|
69
68
|
const sourcesRef = useRef<string[]>(debugLog.getSources());
|
|
70
69
|
|
|
@@ -261,8 +260,8 @@ function DebugPane({ focused, width, height }: PaneProps) {
|
|
|
261
260
|
{visibleEntries.map((entry, i) => {
|
|
262
261
|
const globalIdx = viewStart + i;
|
|
263
262
|
const isSelected = globalIdx === selectedIdx;
|
|
264
|
-
const
|
|
265
|
-
const
|
|
263
|
+
const bgColor = isSelected ? colors.selected : undefined;
|
|
264
|
+
const rowHoverBg = isSelected ? undefined : hoverBg();
|
|
266
265
|
const ts = formatTimestamp(entry.timestamp);
|
|
267
266
|
const lvl = LEVEL_LABELS[entry.level];
|
|
268
267
|
const sourceTag = entry.source;
|
|
@@ -278,7 +277,7 @@ function DebugPane({ focused, width, height }: PaneProps) {
|
|
|
278
277
|
width={contentWidth}
|
|
279
278
|
flexDirection="row"
|
|
280
279
|
backgroundColor={bgColor}
|
|
281
|
-
|
|
280
|
+
hoverBackgroundColor={rowHoverBg}
|
|
282
281
|
onMouseDown={() => { setSelectedIdx(globalIdx); setAutoScroll(false); }}
|
|
283
282
|
>
|
|
284
283
|
<Text fg={colors.textMuted}> {ts} </Text>
|
|
@@ -63,7 +63,7 @@ export function ActionButton({
|
|
|
63
63
|
return (
|
|
64
64
|
<Box
|
|
65
65
|
backgroundColor={hovered ? hoverBg() : colors.panel}
|
|
66
|
-
|
|
66
|
+
onMouseOver={() => onHover(id)}
|
|
67
67
|
onMouseOut={() => onHover(null)}
|
|
68
68
|
onMouseDown={(event: any) => {
|
|
69
69
|
event.stopPropagation?.();
|