@lvce-editor/chat-view 3.10.0 → 4.0.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/dist/chatViewWorkerMain.js +837 -107
- package/package.json +1 -1
|
@@ -1122,6 +1122,10 @@ const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
|
|
|
1122
1122
|
const sendMessagePortToChatNetworkWorker = async port => {
|
|
1123
1123
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatNetworkWorker', port, 'HandleMessagePort.handleMessagePort');
|
|
1124
1124
|
};
|
|
1125
|
+
const confirm = async (message, options) => {
|
|
1126
|
+
const result = await invoke('ConfirmPrompt.prompt', message, options);
|
|
1127
|
+
return result;
|
|
1128
|
+
};
|
|
1125
1129
|
const activateByEvent$1 = (event, assetDir, platform) => {
|
|
1126
1130
|
return invoke('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
|
|
1127
1131
|
};
|
|
@@ -1336,6 +1340,12 @@ const backToChats = () => {
|
|
|
1336
1340
|
const settings = () => {
|
|
1337
1341
|
return i18nString('Settings');
|
|
1338
1342
|
};
|
|
1343
|
+
const chatFocusMode = () => {
|
|
1344
|
+
return i18nString('Switch to chat focus mode');
|
|
1345
|
+
};
|
|
1346
|
+
const normalChatMode = () => {
|
|
1347
|
+
return i18nString('Switch to normal chat mode');
|
|
1348
|
+
};
|
|
1339
1349
|
const closeChat = () => {
|
|
1340
1350
|
return i18nString('Close Chat');
|
|
1341
1351
|
};
|
|
@@ -1476,6 +1486,7 @@ const getDefaultModels = () => {
|
|
|
1476
1486
|
};
|
|
1477
1487
|
|
|
1478
1488
|
const createDefaultState = () => {
|
|
1489
|
+
const defaultProjectId = 'project-1';
|
|
1479
1490
|
const defaultSessionId = 'session-1';
|
|
1480
1491
|
const defaultModelId = 'test';
|
|
1481
1492
|
const chatMessageFontSize = 13;
|
|
@@ -1504,6 +1515,7 @@ const createDefaultState = () => {
|
|
|
1504
1515
|
height: 0,
|
|
1505
1516
|
initial: true,
|
|
1506
1517
|
inputSource: 'script',
|
|
1518
|
+
lastNormalViewMode: 'list',
|
|
1507
1519
|
lastSubmittedSessionId: '',
|
|
1508
1520
|
listItemHeight: 40,
|
|
1509
1521
|
maxComposerRows: 5,
|
|
@@ -1523,12 +1535,21 @@ const createDefaultState = () => {
|
|
|
1523
1535
|
openRouterApiKeyState: 'idle',
|
|
1524
1536
|
passIncludeObfuscation: false,
|
|
1525
1537
|
platform: 0,
|
|
1538
|
+
projectExpandedIds: [defaultProjectId],
|
|
1539
|
+
projectListScrollTop: 0,
|
|
1540
|
+
projects: [{
|
|
1541
|
+
id: defaultProjectId,
|
|
1542
|
+
name: '_blank',
|
|
1543
|
+
uri: ''
|
|
1544
|
+
}],
|
|
1526
1545
|
renamingSessionId: '',
|
|
1527
1546
|
selectedModelId: defaultModelId,
|
|
1547
|
+
selectedProjectId: defaultProjectId,
|
|
1528
1548
|
selectedSessionId: defaultSessionId,
|
|
1529
1549
|
sessions: [{
|
|
1530
1550
|
id: defaultSessionId,
|
|
1531
1551
|
messages: [],
|
|
1552
|
+
projectId: defaultProjectId,
|
|
1532
1553
|
title: defaultSessionTitle()
|
|
1533
1554
|
}],
|
|
1534
1555
|
streamingEnabled: true,
|
|
@@ -2148,29 +2169,49 @@ const createDefaultStorage = () => {
|
|
|
2148
2169
|
let chatSessionStorage = createDefaultStorage();
|
|
2149
2170
|
const listChatSessions = async () => {
|
|
2150
2171
|
const sessions = await chatSessionStorage.listSessions();
|
|
2151
|
-
return sessions.map(session =>
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2172
|
+
return sessions.map(session => {
|
|
2173
|
+
const summary = {
|
|
2174
|
+
id: session.id,
|
|
2175
|
+
messages: [],
|
|
2176
|
+
title: session.title
|
|
2177
|
+
};
|
|
2178
|
+
if (!session.projectId) {
|
|
2179
|
+
return summary;
|
|
2180
|
+
}
|
|
2181
|
+
return {
|
|
2182
|
+
...summary,
|
|
2183
|
+
projectId: session.projectId
|
|
2184
|
+
};
|
|
2185
|
+
});
|
|
2156
2186
|
};
|
|
2157
2187
|
const getChatSession = async id => {
|
|
2158
2188
|
const session = await chatSessionStorage.getSession(id);
|
|
2159
2189
|
if (!session) {
|
|
2160
2190
|
return undefined;
|
|
2161
2191
|
}
|
|
2162
|
-
|
|
2192
|
+
const result = {
|
|
2163
2193
|
id: session.id,
|
|
2164
2194
|
messages: [...session.messages],
|
|
2165
2195
|
title: session.title
|
|
2166
2196
|
};
|
|
2197
|
+
if (!session.projectId) {
|
|
2198
|
+
return result;
|
|
2199
|
+
}
|
|
2200
|
+
return {
|
|
2201
|
+
...result,
|
|
2202
|
+
projectId: session.projectId
|
|
2203
|
+
};
|
|
2167
2204
|
};
|
|
2168
2205
|
const saveChatSession = async session => {
|
|
2169
|
-
|
|
2206
|
+
const value = {
|
|
2170
2207
|
id: session.id,
|
|
2171
2208
|
messages: [...session.messages],
|
|
2172
2209
|
title: session.title
|
|
2173
|
-
}
|
|
2210
|
+
};
|
|
2211
|
+
await chatSessionStorage.setSession(session.projectId ? {
|
|
2212
|
+
...value,
|
|
2213
|
+
projectId: session.projectId
|
|
2214
|
+
} : value);
|
|
2174
2215
|
};
|
|
2175
2216
|
const deleteChatSession = async id => {
|
|
2176
2217
|
await chatSessionStorage.deleteSession(id);
|
|
@@ -2194,6 +2235,17 @@ const getNextSelectedSessionId = (sessions, deletedId) => {
|
|
|
2194
2235
|
return sessions[nextIndex].id;
|
|
2195
2236
|
};
|
|
2196
2237
|
|
|
2238
|
+
const getVisibleSessions = (sessions, selectedProjectId) => {
|
|
2239
|
+
if (!selectedProjectId) {
|
|
2240
|
+
return sessions;
|
|
2241
|
+
}
|
|
2242
|
+
const hasAssignedProjects = sessions.some(session => !!session.projectId);
|
|
2243
|
+
if (!hasAssignedProjects) {
|
|
2244
|
+
return sessions;
|
|
2245
|
+
}
|
|
2246
|
+
return sessions.filter(session => session.projectId === selectedProjectId);
|
|
2247
|
+
};
|
|
2248
|
+
|
|
2197
2249
|
const deleteSession = async (state, id) => {
|
|
2198
2250
|
const {
|
|
2199
2251
|
renamingSessionId,
|
|
@@ -2232,10 +2284,8 @@ const deleteSession = async (state, id) => {
|
|
|
2232
2284
|
};
|
|
2233
2285
|
};
|
|
2234
2286
|
const deleteSessionAtIndex = async (state, index) => {
|
|
2235
|
-
const
|
|
2236
|
-
|
|
2237
|
-
} = state;
|
|
2238
|
-
const session = sessions[index];
|
|
2287
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
2288
|
+
const session = visibleSessions[index];
|
|
2239
2289
|
if (!session) {
|
|
2240
2290
|
return state;
|
|
2241
2291
|
}
|
|
@@ -2301,12 +2351,23 @@ const diffFocus = (oldState, newState) => {
|
|
|
2301
2351
|
return oldState.focus === newState.focus && oldState.focused === newState.focused;
|
|
2302
2352
|
};
|
|
2303
2353
|
|
|
2354
|
+
const isEqualProjectExpandedIds = (a, b) => {
|
|
2355
|
+
if (a.length !== b.length) {
|
|
2356
|
+
return false;
|
|
2357
|
+
}
|
|
2358
|
+
for (let i = 0; i < a.length; i++) {
|
|
2359
|
+
if (a[i] !== b[i]) {
|
|
2360
|
+
return false;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
return true;
|
|
2364
|
+
};
|
|
2304
2365
|
const isEqual = (oldState, newState) => {
|
|
2305
|
-
return oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedSessionId === newState.selectedSessionId && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.viewMode === newState.viewMode;
|
|
2366
|
+
return oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.viewMode === newState.viewMode;
|
|
2306
2367
|
};
|
|
2307
2368
|
|
|
2308
2369
|
const diffScrollTop = (oldState, newState) => {
|
|
2309
|
-
return oldState.chatListScrollTop === newState.chatListScrollTop && oldState.messagesScrollTop === newState.messagesScrollTop;
|
|
2370
|
+
return oldState.chatListScrollTop === newState.chatListScrollTop && oldState.messagesScrollTop === newState.messagesScrollTop && oldState.projectListScrollTop === newState.projectListScrollTop;
|
|
2310
2371
|
};
|
|
2311
2372
|
|
|
2312
2373
|
const RenderItems = 4;
|
|
@@ -2745,7 +2806,8 @@ const handleChatListContextMenu = async (state, eventX, eventY) => {
|
|
|
2745
2806
|
if (index === -1) {
|
|
2746
2807
|
return state;
|
|
2747
2808
|
}
|
|
2748
|
-
const
|
|
2809
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
2810
|
+
const item = visibleSessions[index];
|
|
2749
2811
|
if (!item) {
|
|
2750
2812
|
return state;
|
|
2751
2813
|
}
|
|
@@ -2757,22 +2819,106 @@ const generateSessionId = () => {
|
|
|
2757
2819
|
return crypto.randomUUID();
|
|
2758
2820
|
};
|
|
2759
2821
|
|
|
2760
|
-
const createSession = async state => {
|
|
2822
|
+
const createSession = async (state, projectIdOverride = '') => {
|
|
2761
2823
|
const id = generateSessionId();
|
|
2824
|
+
const fallbackProjectId = state.projects.find(project => project.name === '_blank')?.id || state.projects[0]?.id || 'project-1';
|
|
2825
|
+
const projectId = projectIdOverride || state.selectedProjectId || fallbackProjectId;
|
|
2762
2826
|
const session = {
|
|
2763
2827
|
id,
|
|
2764
2828
|
messages: [],
|
|
2829
|
+
projectId,
|
|
2765
2830
|
title: `Chat ${state.sessions.length + 1}`
|
|
2766
2831
|
};
|
|
2767
2832
|
await saveChatSession(session);
|
|
2768
2833
|
return {
|
|
2769
2834
|
...state,
|
|
2835
|
+
projectExpandedIds: state.projectExpandedIds.includes(projectId) ? state.projectExpandedIds : [...state.projectExpandedIds, projectId],
|
|
2770
2836
|
renamingSessionId: '',
|
|
2837
|
+
selectedProjectId: projectId,
|
|
2771
2838
|
selectedSessionId: id,
|
|
2772
2839
|
sessions: [...state.sessions, session]
|
|
2773
2840
|
};
|
|
2774
2841
|
};
|
|
2775
2842
|
|
|
2843
|
+
const selectProject = async (state, projectId) => {
|
|
2844
|
+
if (!projectId || state.selectedProjectId === projectId) {
|
|
2845
|
+
return state;
|
|
2846
|
+
}
|
|
2847
|
+
const visibleSessions = getVisibleSessions(state.sessions, projectId);
|
|
2848
|
+
if (visibleSessions.length === 0) {
|
|
2849
|
+
return {
|
|
2850
|
+
...state,
|
|
2851
|
+
selectedProjectId: projectId,
|
|
2852
|
+
selectedSessionId: '',
|
|
2853
|
+
viewMode: state.viewMode === 'chat-focus' ? 'chat-focus' : 'list'
|
|
2854
|
+
};
|
|
2855
|
+
}
|
|
2856
|
+
const currentSessionVisible = visibleSessions.some(session => session.id === state.selectedSessionId);
|
|
2857
|
+
const nextSelectedSessionId = currentSessionVisible ? state.selectedSessionId : visibleSessions[0].id;
|
|
2858
|
+
const loadedSession = await getChatSession(nextSelectedSessionId);
|
|
2859
|
+
const sessions = state.sessions.map(session => {
|
|
2860
|
+
if (session.id !== nextSelectedSessionId || !loadedSession) {
|
|
2861
|
+
return session;
|
|
2862
|
+
}
|
|
2863
|
+
return loadedSession;
|
|
2864
|
+
});
|
|
2865
|
+
return {
|
|
2866
|
+
...state,
|
|
2867
|
+
selectedProjectId: projectId,
|
|
2868
|
+
selectedSessionId: nextSelectedSessionId,
|
|
2869
|
+
sessions,
|
|
2870
|
+
viewMode: state.viewMode === 'chat-focus' ? 'chat-focus' : 'detail'
|
|
2871
|
+
};
|
|
2872
|
+
};
|
|
2873
|
+
|
|
2874
|
+
const getProjectName = (uri, fallbackIndex) => {
|
|
2875
|
+
if (!uri) {
|
|
2876
|
+
return `Project ${fallbackIndex}`;
|
|
2877
|
+
}
|
|
2878
|
+
const withoutScheme = uri.replace(/^file:\/\//, '');
|
|
2879
|
+
const normalized = withoutScheme.replace(/\/+$/, '');
|
|
2880
|
+
const lastSegment = normalized.split('/').pop();
|
|
2881
|
+
if (!lastSegment) {
|
|
2882
|
+
return `Project ${fallbackIndex}`;
|
|
2883
|
+
}
|
|
2884
|
+
return decodeURIComponent(lastSegment);
|
|
2885
|
+
};
|
|
2886
|
+
const getNextProjectId = projects => {
|
|
2887
|
+
return `project-${projects.length + 1}`;
|
|
2888
|
+
};
|
|
2889
|
+
const pickProjectUri = async () => {
|
|
2890
|
+
try {
|
|
2891
|
+
const workspaceUri = await getWorkspacePath();
|
|
2892
|
+
return workspaceUri;
|
|
2893
|
+
} catch {
|
|
2894
|
+
return '';
|
|
2895
|
+
}
|
|
2896
|
+
};
|
|
2897
|
+
const handleClickCreateProject = async state => {
|
|
2898
|
+
await confirm('project added');
|
|
2899
|
+
const uri = await pickProjectUri();
|
|
2900
|
+
if (!uri) {
|
|
2901
|
+
return state;
|
|
2902
|
+
}
|
|
2903
|
+
const existingProject = state.projects.find(project => project.uri === uri);
|
|
2904
|
+
if (existingProject) {
|
|
2905
|
+
return selectProject(state, existingProject.id);
|
|
2906
|
+
}
|
|
2907
|
+
const id = getNextProjectId(state.projects);
|
|
2908
|
+
const project = {
|
|
2909
|
+
id,
|
|
2910
|
+
name: getProjectName(uri, state.projects.length + 1),
|
|
2911
|
+
uri
|
|
2912
|
+
};
|
|
2913
|
+
return {
|
|
2914
|
+
...state,
|
|
2915
|
+
projects: [...state.projects, project],
|
|
2916
|
+
selectedProjectId: project.id,
|
|
2917
|
+
selectedSessionId: '',
|
|
2918
|
+
viewMode: 'list'
|
|
2919
|
+
};
|
|
2920
|
+
};
|
|
2921
|
+
|
|
2776
2922
|
const handleClickOpenApiApiKeySettings = async state => {
|
|
2777
2923
|
await invoke('Main.openUri', 'app://settings.json');
|
|
2778
2924
|
return state;
|
|
@@ -5822,13 +5968,35 @@ const ComposerDropTarget = 'composer-drop-target';
|
|
|
5822
5968
|
const Send = 'send';
|
|
5823
5969
|
const Back = 'back';
|
|
5824
5970
|
const Model = 'model';
|
|
5971
|
+
const ToggleChatFocus = 'toggle-chat-focus';
|
|
5972
|
+
const CreateProject = 'create-project';
|
|
5825
5973
|
const CreateSession = 'create-session';
|
|
5974
|
+
const CreateSessionInProjectPrefix = 'create-session-in-project:';
|
|
5826
5975
|
const SessionDebug = 'session-debug';
|
|
5827
5976
|
const Settings = 'settings';
|
|
5828
5977
|
const CloseChat = 'close-chat';
|
|
5829
5978
|
const SessionDelete = 'SessionDelete';
|
|
5979
|
+
const ProjectPrefix = 'project:';
|
|
5830
5980
|
const SessionPrefix = 'session:';
|
|
5831
5981
|
const RenamePrefix = 'session-rename:';
|
|
5982
|
+
const getProjectInputName = projectId => {
|
|
5983
|
+
return `${ProjectPrefix}${projectId}`;
|
|
5984
|
+
};
|
|
5985
|
+
const getCreateSessionInProjectInputName = projectId => {
|
|
5986
|
+
return `${CreateSessionInProjectPrefix}${projectId}`;
|
|
5987
|
+
};
|
|
5988
|
+
const isCreateSessionInProjectInputName = name => {
|
|
5989
|
+
return name.startsWith(CreateSessionInProjectPrefix);
|
|
5990
|
+
};
|
|
5991
|
+
const getProjectIdFromCreateSessionInProjectInputName = name => {
|
|
5992
|
+
return name.slice(CreateSessionInProjectPrefix.length);
|
|
5993
|
+
};
|
|
5994
|
+
const isProjectInputName = name => {
|
|
5995
|
+
return name.startsWith(ProjectPrefix);
|
|
5996
|
+
};
|
|
5997
|
+
const getProjectIdFromInputName = name => {
|
|
5998
|
+
return name.slice(ProjectPrefix.length);
|
|
5999
|
+
};
|
|
5832
6000
|
const getSessionInputName = sessionId => {
|
|
5833
6001
|
return `${SessionPrefix}${sessionId}`;
|
|
5834
6002
|
};
|
|
@@ -5873,10 +6041,11 @@ const selectSession = async (state, id) => {
|
|
|
5873
6041
|
});
|
|
5874
6042
|
return {
|
|
5875
6043
|
...state,
|
|
6044
|
+
lastNormalViewMode: state.viewMode === 'chat-focus' ? state.lastNormalViewMode : 'detail',
|
|
5876
6045
|
renamingSessionId: '',
|
|
5877
6046
|
selectedSessionId: id,
|
|
5878
6047
|
sessions,
|
|
5879
|
-
viewMode: 'detail'
|
|
6048
|
+
viewMode: state.viewMode === 'chat-focus' ? 'chat-focus' : 'detail'
|
|
5880
6049
|
};
|
|
5881
6050
|
};
|
|
5882
6051
|
|
|
@@ -5897,14 +6066,61 @@ const startRename = (state, id) => {
|
|
|
5897
6066
|
};
|
|
5898
6067
|
};
|
|
5899
6068
|
|
|
6069
|
+
const toggleChatFocusMode = async state => {
|
|
6070
|
+
if (state.viewMode === 'chat-focus') {
|
|
6071
|
+
return {
|
|
6072
|
+
...state,
|
|
6073
|
+
viewMode: state.lastNormalViewMode
|
|
6074
|
+
};
|
|
6075
|
+
}
|
|
6076
|
+
if (state.viewMode === 'list' || state.viewMode === 'detail') {
|
|
6077
|
+
return {
|
|
6078
|
+
...state,
|
|
6079
|
+
lastNormalViewMode: state.viewMode,
|
|
6080
|
+
viewMode: 'chat-focus'
|
|
6081
|
+
};
|
|
6082
|
+
}
|
|
6083
|
+
return state;
|
|
6084
|
+
};
|
|
6085
|
+
|
|
6086
|
+
const toggleProjectExpanded = async (state, projectId) => {
|
|
6087
|
+
const isExpanded = state.projectExpandedIds.includes(projectId);
|
|
6088
|
+
const projectExpandedIds = isExpanded ? state.projectExpandedIds.filter(id => id !== projectId) : [...state.projectExpandedIds, projectId];
|
|
6089
|
+
const visibleSessions = getVisibleSessions(state.sessions, projectId);
|
|
6090
|
+
if (visibleSessions.length === 0) {
|
|
6091
|
+
return {
|
|
6092
|
+
...state,
|
|
6093
|
+
projectExpandedIds,
|
|
6094
|
+
selectedProjectId: projectId,
|
|
6095
|
+
selectedSessionId: '',
|
|
6096
|
+
viewMode: 'chat-focus'
|
|
6097
|
+
};
|
|
6098
|
+
}
|
|
6099
|
+
const selectedSessionVisible = visibleSessions.some(session => session.id === state.selectedSessionId);
|
|
6100
|
+
const selectedSessionId = selectedSessionVisible ? state.selectedSessionId : visibleSessions[0].id;
|
|
6101
|
+
const loadedSession = await getChatSession(selectedSessionId);
|
|
6102
|
+
const sessions = state.sessions.map(session => {
|
|
6103
|
+
if (session.id !== selectedSessionId || !loadedSession) {
|
|
6104
|
+
return session;
|
|
6105
|
+
}
|
|
6106
|
+
return loadedSession;
|
|
6107
|
+
});
|
|
6108
|
+
return {
|
|
6109
|
+
...state,
|
|
6110
|
+
projectExpandedIds,
|
|
6111
|
+
selectedProjectId: projectId,
|
|
6112
|
+
selectedSessionId,
|
|
6113
|
+
sessions,
|
|
6114
|
+
viewMode: 'chat-focus'
|
|
6115
|
+
};
|
|
6116
|
+
};
|
|
6117
|
+
|
|
5900
6118
|
const selectListIndex = async (state, index) => {
|
|
5901
|
-
const
|
|
5902
|
-
|
|
5903
|
-
} = state;
|
|
5904
|
-
if (index < 0 || index >= sessions.length) {
|
|
6119
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
6120
|
+
if (index < 0 || index >= visibleSessions.length) {
|
|
5905
6121
|
return state;
|
|
5906
6122
|
}
|
|
5907
|
-
const session =
|
|
6123
|
+
const session = visibleSessions[index];
|
|
5908
6124
|
return selectSession(state, session.id);
|
|
5909
6125
|
};
|
|
5910
6126
|
|
|
@@ -5920,6 +6136,23 @@ const handleClick = async (state, name, id = '') => {
|
|
|
5920
6136
|
if (name === CreateSession) {
|
|
5921
6137
|
return createSession(state);
|
|
5922
6138
|
}
|
|
6139
|
+
if (name === CreateProject) {
|
|
6140
|
+
return handleClickCreateProject(state);
|
|
6141
|
+
}
|
|
6142
|
+
if (isCreateSessionInProjectInputName(name)) {
|
|
6143
|
+
const projectId = getProjectIdFromCreateSessionInProjectInputName(name);
|
|
6144
|
+
return createSession(state, projectId);
|
|
6145
|
+
}
|
|
6146
|
+
if (name === ToggleChatFocus) {
|
|
6147
|
+
return toggleChatFocusMode(state);
|
|
6148
|
+
}
|
|
6149
|
+
if (isProjectInputName(name)) {
|
|
6150
|
+
const projectId = getProjectIdFromInputName(name);
|
|
6151
|
+
if (state.viewMode === 'chat-focus') {
|
|
6152
|
+
return toggleProjectExpanded(state, projectId);
|
|
6153
|
+
}
|
|
6154
|
+
return selectProject(state, projectId);
|
|
6155
|
+
}
|
|
5923
6156
|
if (isSessionInputName(name)) {
|
|
5924
6157
|
const sessionId = getSessionIdFromInputName(name);
|
|
5925
6158
|
return selectSession(state, sessionId);
|
|
@@ -5958,6 +6191,7 @@ const handleClick = async (state, name, id = '') => {
|
|
|
5958
6191
|
const handleClickBack = async state => {
|
|
5959
6192
|
return {
|
|
5960
6193
|
...state,
|
|
6194
|
+
lastNormalViewMode: 'list',
|
|
5961
6195
|
renamingSessionId: '',
|
|
5962
6196
|
viewMode: 'list'
|
|
5963
6197
|
};
|
|
@@ -6239,6 +6473,15 @@ const handleMessagesScroll = async (state, messagesScrollTop) => {
|
|
|
6239
6473
|
messagesScrollTop
|
|
6240
6474
|
};
|
|
6241
6475
|
};
|
|
6476
|
+
const handleProjectListScroll = async (state, projectListScrollTop) => {
|
|
6477
|
+
if (state.projectListScrollTop === projectListScrollTop) {
|
|
6478
|
+
return state;
|
|
6479
|
+
}
|
|
6480
|
+
return {
|
|
6481
|
+
...state,
|
|
6482
|
+
projectListScrollTop
|
|
6483
|
+
};
|
|
6484
|
+
};
|
|
6242
6485
|
|
|
6243
6486
|
const id = 7201;
|
|
6244
6487
|
const sendMessagePortToExtensionHostWorker = async port => {
|
|
@@ -6338,7 +6581,7 @@ const getSavedViewMode = savedState => {
|
|
|
6338
6581
|
const {
|
|
6339
6582
|
viewMode
|
|
6340
6583
|
} = savedState;
|
|
6341
|
-
if (viewMode !== 'list' && viewMode !== 'detail') {
|
|
6584
|
+
if (viewMode !== 'list' && viewMode !== 'detail' && viewMode !== 'chat-focus') {
|
|
6342
6585
|
return undefined;
|
|
6343
6586
|
}
|
|
6344
6587
|
return viewMode;
|
|
@@ -6455,11 +6698,97 @@ const loadSelectedSessionMessages = async (sessions, selectedSessionId) => {
|
|
|
6455
6698
|
};
|
|
6456
6699
|
|
|
6457
6700
|
const toSummarySession = session => {
|
|
6458
|
-
|
|
6701
|
+
const summary = {
|
|
6459
6702
|
id: session.id,
|
|
6460
6703
|
messages: [],
|
|
6461
6704
|
title: session.title
|
|
6462
6705
|
};
|
|
6706
|
+
if (!session.projectId) {
|
|
6707
|
+
return summary;
|
|
6708
|
+
}
|
|
6709
|
+
return {
|
|
6710
|
+
...summary,
|
|
6711
|
+
projectId: session.projectId
|
|
6712
|
+
};
|
|
6713
|
+
};
|
|
6714
|
+
const getSavedSelectedProjectId = savedState => {
|
|
6715
|
+
if (!isObject(savedState)) {
|
|
6716
|
+
return undefined;
|
|
6717
|
+
}
|
|
6718
|
+
const {
|
|
6719
|
+
selectedProjectId
|
|
6720
|
+
} = savedState;
|
|
6721
|
+
if (typeof selectedProjectId !== 'string') {
|
|
6722
|
+
return undefined;
|
|
6723
|
+
}
|
|
6724
|
+
return selectedProjectId;
|
|
6725
|
+
};
|
|
6726
|
+
const getSavedProjects = savedState => {
|
|
6727
|
+
if (!isObject(savedState)) {
|
|
6728
|
+
return undefined;
|
|
6729
|
+
}
|
|
6730
|
+
const {
|
|
6731
|
+
projects
|
|
6732
|
+
} = savedState;
|
|
6733
|
+
if (!Array.isArray(projects)) {
|
|
6734
|
+
return undefined;
|
|
6735
|
+
}
|
|
6736
|
+
const validProjects = projects.filter(project => {
|
|
6737
|
+
if (!isObject(project)) {
|
|
6738
|
+
return false;
|
|
6739
|
+
}
|
|
6740
|
+
return typeof project.id === 'string' && typeof project.name === 'string' && typeof project.uri === 'string';
|
|
6741
|
+
});
|
|
6742
|
+
if (validProjects.length === 0) {
|
|
6743
|
+
return undefined;
|
|
6744
|
+
}
|
|
6745
|
+
return validProjects;
|
|
6746
|
+
};
|
|
6747
|
+
const ensureBlankProject = (projects, fallbackBlankProject) => {
|
|
6748
|
+
if (projects.some(project => project.name === '_blank')) {
|
|
6749
|
+
return projects;
|
|
6750
|
+
}
|
|
6751
|
+
return [fallbackBlankProject, ...projects];
|
|
6752
|
+
};
|
|
6753
|
+
const getSavedProjectListScrollTop = savedState => {
|
|
6754
|
+
if (!isObject(savedState)) {
|
|
6755
|
+
return undefined;
|
|
6756
|
+
}
|
|
6757
|
+
const {
|
|
6758
|
+
projectListScrollTop
|
|
6759
|
+
} = savedState;
|
|
6760
|
+
if (typeof projectListScrollTop !== 'number') {
|
|
6761
|
+
return undefined;
|
|
6762
|
+
}
|
|
6763
|
+
return projectListScrollTop;
|
|
6764
|
+
};
|
|
6765
|
+
const getSavedProjectExpandedIds = savedState => {
|
|
6766
|
+
if (!isObject(savedState)) {
|
|
6767
|
+
return undefined;
|
|
6768
|
+
}
|
|
6769
|
+
const {
|
|
6770
|
+
projectExpandedIds
|
|
6771
|
+
} = savedState;
|
|
6772
|
+
if (!Array.isArray(projectExpandedIds)) {
|
|
6773
|
+
return undefined;
|
|
6774
|
+
}
|
|
6775
|
+
const ids = projectExpandedIds.filter(id => typeof id === 'string');
|
|
6776
|
+
if (ids.length === 0) {
|
|
6777
|
+
return undefined;
|
|
6778
|
+
}
|
|
6779
|
+
return ids;
|
|
6780
|
+
};
|
|
6781
|
+
const getSavedLastNormalViewMode = savedState => {
|
|
6782
|
+
if (!isObject(savedState)) {
|
|
6783
|
+
return undefined;
|
|
6784
|
+
}
|
|
6785
|
+
const {
|
|
6786
|
+
lastNormalViewMode
|
|
6787
|
+
} = savedState;
|
|
6788
|
+
if (lastNormalViewMode !== 'list' && lastNormalViewMode !== 'detail') {
|
|
6789
|
+
return undefined;
|
|
6790
|
+
}
|
|
6791
|
+
return lastNormalViewMode;
|
|
6463
6792
|
};
|
|
6464
6793
|
const loadContent = async (state, savedState) => {
|
|
6465
6794
|
const savedSelectedModelId = getSavedSelectedModelId(savedState);
|
|
@@ -6490,14 +6819,30 @@ const loadContent = async (state, savedState) => {
|
|
|
6490
6819
|
sessions = state.sessions.map(toSummarySession);
|
|
6491
6820
|
}
|
|
6492
6821
|
const preferredSessionId = getSavedSelectedSessionId(savedState) || state.selectedSessionId;
|
|
6822
|
+
const savedProjects = getSavedProjects(savedState);
|
|
6823
|
+
const baseProjects = savedProjects && savedProjects.length > 0 ? savedProjects : state.projects;
|
|
6824
|
+
const blankProject = state.projects.find(project => project.name === '_blank') || {
|
|
6825
|
+
id: 'project-blank',
|
|
6826
|
+
name: '_blank',
|
|
6827
|
+
uri: ''
|
|
6828
|
+
};
|
|
6829
|
+
const projects = ensureBlankProject(baseProjects, blankProject);
|
|
6830
|
+
const preferredProjectId = getSavedSelectedProjectId(savedState) || state.selectedProjectId;
|
|
6831
|
+
const selectedProjectId = projects.some(project => project.id === preferredProjectId) ? preferredProjectId : projects[0]?.id || '';
|
|
6493
6832
|
const preferredModelId = savedSelectedModelId || state.selectedModelId;
|
|
6494
6833
|
const chatListScrollTop = getSavedChatListScrollTop(savedState) ?? state.chatListScrollTop;
|
|
6495
6834
|
const messagesScrollTop = getSavedMessagesScrollTop(savedState) ?? state.messagesScrollTop;
|
|
6835
|
+
const projectListScrollTop = getSavedProjectListScrollTop(savedState) ?? state.projectListScrollTop;
|
|
6836
|
+
const savedProjectExpandedIds = getSavedProjectExpandedIds(savedState);
|
|
6837
|
+
const projectExpandedIds = (savedProjectExpandedIds || state.projectExpandedIds).filter(id => projects.some(project => project.id === id));
|
|
6496
6838
|
const selectedModelId = state.models.some(model => model.id === preferredModelId) ? preferredModelId : state.models[0]?.id || '';
|
|
6497
|
-
const
|
|
6839
|
+
const visibleSessions = getVisibleSessions(sessions, selectedProjectId);
|
|
6840
|
+
const selectedSessionId = visibleSessions.some(session => session.id === preferredSessionId) ? preferredSessionId : visibleSessions[0]?.id || '';
|
|
6498
6841
|
sessions = await loadSelectedSessionMessages(sessions, selectedSessionId);
|
|
6499
6842
|
const preferredViewMode = savedViewMode || state.viewMode;
|
|
6500
|
-
const
|
|
6843
|
+
const savedLastNormalViewMode = getSavedLastNormalViewMode(savedState);
|
|
6844
|
+
const lastNormalViewMode = savedLastNormalViewMode || (preferredViewMode === 'detail' ? 'detail' : state.lastNormalViewMode);
|
|
6845
|
+
const viewMode = sessions.length === 0 || !selectedSessionId ? 'list' : preferredViewMode;
|
|
6501
6846
|
return {
|
|
6502
6847
|
...state,
|
|
6503
6848
|
aiSessionTitleGenerationEnabled,
|
|
@@ -6506,13 +6851,18 @@ const loadContent = async (state, savedState) => {
|
|
|
6506
6851
|
composerDropEnabled,
|
|
6507
6852
|
emitStreamingFunctionCallEvents,
|
|
6508
6853
|
initial: false,
|
|
6854
|
+
lastNormalViewMode,
|
|
6509
6855
|
messagesScrollTop,
|
|
6510
6856
|
openApiApiKey,
|
|
6511
6857
|
openApiApiKeyInput: openApiApiKey,
|
|
6512
6858
|
openRouterApiKey,
|
|
6513
6859
|
openRouterApiKeyInput: openRouterApiKey,
|
|
6514
6860
|
passIncludeObfuscation,
|
|
6861
|
+
projectExpandedIds,
|
|
6862
|
+
projectListScrollTop,
|
|
6863
|
+
projects,
|
|
6515
6864
|
selectedModelId,
|
|
6865
|
+
selectedProjectId,
|
|
6516
6866
|
selectedSessionId,
|
|
6517
6867
|
sessions,
|
|
6518
6868
|
streamingEnabled,
|
|
@@ -6599,6 +6949,219 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
6599
6949
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
6600
6950
|
--ChatMessageFontFamily: ${chatMessageFontFamily};
|
|
6601
6951
|
}
|
|
6952
|
+
|
|
6953
|
+
.Viewlet.Chat.ChatFocus {
|
|
6954
|
+
background: linear-gradient(180deg, var(--ColorViewBackground, #1d2229) 0%, #1f252d 100%);
|
|
6955
|
+
display: grid;
|
|
6956
|
+
grid-template-columns: 320px 1fr;
|
|
6957
|
+
grid-template-rows: auto 1fr auto;
|
|
6958
|
+
}
|
|
6959
|
+
|
|
6960
|
+
.Chat.ChatFocus .ChatHeader {
|
|
6961
|
+
grid-column: 1 / 3;
|
|
6962
|
+
}
|
|
6963
|
+
|
|
6964
|
+
.Chat.ChatFocus .ProjectSidebar {
|
|
6965
|
+
background: color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 88%, #1f2b38 12%);
|
|
6966
|
+
border-right: 1px solid var(--ColorBorder, #3a3d41);
|
|
6967
|
+
box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.2);
|
|
6968
|
+
display: flex;
|
|
6969
|
+
flex-direction: column;
|
|
6970
|
+
grid-column: 1;
|
|
6971
|
+
grid-row: 2 / 4;
|
|
6972
|
+
min-height: 0;
|
|
6973
|
+
}
|
|
6974
|
+
|
|
6975
|
+
.Chat.ChatFocus .ProjectList {
|
|
6976
|
+
min-height: 0;
|
|
6977
|
+
overflow: auto;
|
|
6978
|
+
padding: 10px 8px 12px;
|
|
6979
|
+
scrollbar-color: color-mix(in srgb, var(--ColorScrollBarSliderBackground, #4b5563) 78%, transparent)
|
|
6980
|
+
color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 92%, transparent);
|
|
6981
|
+
scrollbar-width: thin;
|
|
6982
|
+
}
|
|
6983
|
+
|
|
6984
|
+
.Chat.ChatFocus .ProjectList::-webkit-scrollbar {
|
|
6985
|
+
height: 10px;
|
|
6986
|
+
width: 10px;
|
|
6987
|
+
}
|
|
6988
|
+
|
|
6989
|
+
.Chat.ChatFocus .ProjectList::-webkit-scrollbar-track {
|
|
6990
|
+
background: color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 94%, transparent);
|
|
6991
|
+
border-radius: 999px;
|
|
6992
|
+
}
|
|
6993
|
+
|
|
6994
|
+
.Chat.ChatFocus .ProjectList::-webkit-scrollbar-thumb {
|
|
6995
|
+
background: color-mix(in srgb, var(--ColorScrollBarSliderBackground, #4b5563) 70%, transparent);
|
|
6996
|
+
border: 2px solid color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 94%, transparent);
|
|
6997
|
+
border-radius: 999px;
|
|
6998
|
+
}
|
|
6999
|
+
|
|
7000
|
+
.Chat.ChatFocus .ProjectList::-webkit-scrollbar-thumb:hover {
|
|
7001
|
+
background: color-mix(in srgb, var(--ColorScrollBarSliderHoverBackground, #667284) 80%, transparent);
|
|
7002
|
+
}
|
|
7003
|
+
|
|
7004
|
+
.ProjectListGroup {
|
|
7005
|
+
border: 1px solid transparent;
|
|
7006
|
+
border-radius: 8px;
|
|
7007
|
+
margin-bottom: 6px;
|
|
7008
|
+
overflow: hidden;
|
|
7009
|
+
}
|
|
7010
|
+
|
|
7011
|
+
.ProjectListItem {
|
|
7012
|
+
align-items: center;
|
|
7013
|
+
display: flex;
|
|
7014
|
+
gap: 6px;
|
|
7015
|
+
min-height: calc(var(--ChatListItemHeight) - 2px);
|
|
7016
|
+
}
|
|
7017
|
+
|
|
7018
|
+
.ProjectListItemLabel {
|
|
7019
|
+
align-items: center;
|
|
7020
|
+
border-radius: 6px;
|
|
7021
|
+
color: var(--ColorForeground, #d5dbe3);
|
|
7022
|
+
cursor: pointer;
|
|
7023
|
+
display: flex;
|
|
7024
|
+
flex: 1;
|
|
7025
|
+
font-weight: 500;
|
|
7026
|
+
gap: 2px;
|
|
7027
|
+
overflow: hidden;
|
|
7028
|
+
padding: 0 10px;
|
|
7029
|
+
text-overflow: ellipsis;
|
|
7030
|
+
transition: background-color 80ms ease, color 80ms ease;
|
|
7031
|
+
white-space: nowrap;
|
|
7032
|
+
}
|
|
7033
|
+
|
|
7034
|
+
.ProjectListChevron {
|
|
7035
|
+
color: color-mix(in srgb, var(--ColorForeground, #c8d0da) 70%, transparent);
|
|
7036
|
+
display: inline-block;
|
|
7037
|
+
flex: 0 0 12px;
|
|
7038
|
+
font-size: 11px;
|
|
7039
|
+
margin-right: 4px;
|
|
7040
|
+
text-align: center;
|
|
7041
|
+
width: 12px;
|
|
7042
|
+
}
|
|
7043
|
+
|
|
7044
|
+
.ProjectListItemSelected {
|
|
7045
|
+
background: color-mix(in srgb, var(--ColorListInactiveSelectionBackground, #39424d) 84%, #2f3741 16%);
|
|
7046
|
+
}
|
|
7047
|
+
|
|
7048
|
+
.ProjectListItem:not(.ProjectListItemSelected) .ProjectListItemLabel:hover,
|
|
7049
|
+
.ProjectListItem:not(.ProjectListItemSelected) .ProjectListItemLabel:focus-visible {
|
|
7050
|
+
background: color-mix(in srgb, var(--ColorListHoverBackground, #38414b) 50%, transparent);
|
|
7051
|
+
}
|
|
7052
|
+
|
|
7053
|
+
.ProjectListItemSelected .ProjectListItemLabel {
|
|
7054
|
+
color: var(--ColorListInactiveSelectionForeground, #e5ebf2);
|
|
7055
|
+
}
|
|
7056
|
+
|
|
7057
|
+
.ProjectListItemActions {
|
|
7058
|
+
display: flex;
|
|
7059
|
+
padding-right: 6px;
|
|
7060
|
+
}
|
|
7061
|
+
|
|
7062
|
+
.ProjectListItemAddChatButton {
|
|
7063
|
+
align-items: center;
|
|
7064
|
+
background: color-mix(in srgb, var(--ColorButtonSecondaryBackground, #3a434f) 76%, transparent);
|
|
7065
|
+
border: 0;
|
|
7066
|
+
border-radius: 5px;
|
|
7067
|
+
color: var(--ColorForeground, #d0d8e2);
|
|
7068
|
+
cursor: pointer;
|
|
7069
|
+
display: inline-flex;
|
|
7070
|
+
font-size: 13px;
|
|
7071
|
+
font-weight: 500;
|
|
7072
|
+
height: 18px;
|
|
7073
|
+
justify-content: center;
|
|
7074
|
+
opacity: 0;
|
|
7075
|
+
padding: 0;
|
|
7076
|
+
transition: opacity 90ms ease, background-color 90ms ease;
|
|
7077
|
+
visibility: hidden;
|
|
7078
|
+
width: 18px;
|
|
7079
|
+
}
|
|
7080
|
+
|
|
7081
|
+
.ProjectListItem:hover .ProjectListItemAddChatButton,
|
|
7082
|
+
.ProjectListItem:focus-within .ProjectListItemAddChatButton {
|
|
7083
|
+
opacity: 1;
|
|
7084
|
+
visibility: visible;
|
|
7085
|
+
}
|
|
7086
|
+
|
|
7087
|
+
.ProjectListItemAddChatButton:hover,
|
|
7088
|
+
.ProjectListItemAddChatButton:focus-visible {
|
|
7089
|
+
background: color-mix(in srgb, var(--ColorButtonSecondaryHoverBackground, #4a5460) 82%, transparent);
|
|
7090
|
+
}
|
|
7091
|
+
|
|
7092
|
+
.ProjectSessionItem {
|
|
7093
|
+
align-items: center;
|
|
7094
|
+
display: flex;
|
|
7095
|
+
min-height: calc(var(--ChatListItemHeight) - 5px);
|
|
7096
|
+
}
|
|
7097
|
+
|
|
7098
|
+
.ProjectSessionItemLabel {
|
|
7099
|
+
border-radius: 6px;
|
|
7100
|
+
color: color-mix(in srgb, var(--ColorForeground, #cfd7df) 92%, transparent);
|
|
7101
|
+
cursor: pointer;
|
|
7102
|
+
display: block;
|
|
7103
|
+
flex: 1;
|
|
7104
|
+
font-size: 12.5px;
|
|
7105
|
+
overflow: hidden;
|
|
7106
|
+
padding: 0 10px 0 28px;
|
|
7107
|
+
text-overflow: ellipsis;
|
|
7108
|
+
transition: background-color 80ms ease, color 80ms ease;
|
|
7109
|
+
white-space: nowrap;
|
|
7110
|
+
}
|
|
7111
|
+
|
|
7112
|
+
.ProjectSessionItemSelected {
|
|
7113
|
+
background: color-mix(in srgb, var(--ColorListInactiveSelectionBackground, #353f4a) 86%, #2c3540 14%);
|
|
7114
|
+
}
|
|
7115
|
+
|
|
7116
|
+
.ProjectSessionItem:not(.ProjectSessionItemSelected) .ProjectSessionItemLabel:hover,
|
|
7117
|
+
.ProjectSessionItem:not(.ProjectSessionItemSelected) .ProjectSessionItemLabel:focus-visible {
|
|
7118
|
+
background: color-mix(in srgb, var(--ColorListHoverBackground, #38414c) 46%, transparent);
|
|
7119
|
+
}
|
|
7120
|
+
|
|
7121
|
+
.ProjectSessionItemSelected .ProjectSessionItemLabel {
|
|
7122
|
+
color: var(--ColorListInactiveSelectionForeground, #f2f6fc);
|
|
7123
|
+
}
|
|
7124
|
+
|
|
7125
|
+
.Chat.ChatFocus .ProjectAddButton {
|
|
7126
|
+
background: color-mix(in srgb, var(--ColorButtonSecondaryBackground, #21252c) 72%, transparent);
|
|
7127
|
+
border: 0;
|
|
7128
|
+
border-top: 1px solid color-mix(in srgb, var(--ColorBorder, #3a3d41) 70%, transparent);
|
|
7129
|
+
color: var(--ColorForeground, #d2d9e2);
|
|
7130
|
+
cursor: pointer;
|
|
7131
|
+
font-size: 12.5px;
|
|
7132
|
+
letter-spacing: 0.01em;
|
|
7133
|
+
margin-top: auto;
|
|
7134
|
+
min-height: var(--ChatListItemHeight);
|
|
7135
|
+
padding: 0 12px;
|
|
7136
|
+
text-align: left;
|
|
7137
|
+
transition: background-color 80ms ease;
|
|
7138
|
+
}
|
|
7139
|
+
|
|
7140
|
+
.Chat.ChatFocus .ProjectAddButton:hover,
|
|
7141
|
+
.Chat.ChatFocus .ProjectAddButton:focus-visible {
|
|
7142
|
+
background: color-mix(in srgb, var(--ColorButtonSecondaryHoverBackground, #2a3039) 78%, transparent);
|
|
7143
|
+
}
|
|
7144
|
+
|
|
7145
|
+
.ChatList,
|
|
7146
|
+
.ChatListEmpty,
|
|
7147
|
+
.ChatMessages {
|
|
7148
|
+
min-height: 0;
|
|
7149
|
+
}
|
|
7150
|
+
|
|
7151
|
+
.Chat.ChatFocus .ChatList,
|
|
7152
|
+
.Chat.ChatFocus .ChatListEmpty {
|
|
7153
|
+
display: none;
|
|
7154
|
+
}
|
|
7155
|
+
|
|
7156
|
+
.Chat.ChatFocus .ChatMessages {
|
|
7157
|
+
grid-column: 2;
|
|
7158
|
+
grid-row: 2;
|
|
7159
|
+
}
|
|
7160
|
+
|
|
7161
|
+
.Chat.ChatFocus .ChatSendArea {
|
|
7162
|
+
grid-column: 2;
|
|
7163
|
+
grid-row: 3;
|
|
7164
|
+
}
|
|
6602
7165
|
`;
|
|
6603
7166
|
if (!renderHtmlCss.trim()) {
|
|
6604
7167
|
return baseCss;
|
|
@@ -6676,6 +7239,19 @@ const ChatList = 'ChatList';
|
|
|
6676
7239
|
const ChatListEmpty = 'ChatListEmpty';
|
|
6677
7240
|
const ChatListItem = 'ChatListItem';
|
|
6678
7241
|
const ChatListItemLabel = 'ChatListItemLabel';
|
|
7242
|
+
const ProjectAddButton = 'ProjectAddButton';
|
|
7243
|
+
const ProjectList = 'ProjectList';
|
|
7244
|
+
const ProjectListChevron = 'ProjectListChevron';
|
|
7245
|
+
const ProjectListGroup = 'ProjectListGroup';
|
|
7246
|
+
const ProjectListItem = 'ProjectListItem';
|
|
7247
|
+
const ProjectListItemActions = 'ProjectListItemActions';
|
|
7248
|
+
const ProjectListItemAddChatButton = 'ProjectListItemAddChatButton';
|
|
7249
|
+
const ProjectListItemLabel = 'ProjectListItemLabel';
|
|
7250
|
+
const ProjectListItemSelected = 'ProjectListItemSelected';
|
|
7251
|
+
const ProjectSessionItem = 'ProjectSessionItem';
|
|
7252
|
+
const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
|
|
7253
|
+
const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
|
|
7254
|
+
const ProjectSidebar = 'ProjectSidebar';
|
|
6679
7255
|
const Markdown = 'Markdown';
|
|
6680
7256
|
const MarkdownTable = 'MarkdownTable';
|
|
6681
7257
|
const Message = 'Message';
|
|
@@ -6726,6 +7302,7 @@ const HandleDragLeave = 28;
|
|
|
6726
7302
|
const HandleDrop = 29;
|
|
6727
7303
|
const HandleDragEnterChatView = 30;
|
|
6728
7304
|
const HandleDragOverChatView = 31;
|
|
7305
|
+
const HandleProjectListScroll = 32;
|
|
6729
7306
|
|
|
6730
7307
|
const getModelLabel = model => {
|
|
6731
7308
|
if (model.provider === 'openRouter') {
|
|
@@ -6842,82 +7419,6 @@ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOvervie
|
|
|
6842
7419
|
}, ...getChatSelectVirtualDom(models, selectedModelId), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled)];
|
|
6843
7420
|
};
|
|
6844
7421
|
|
|
6845
|
-
const getBackButtonVirtualDom = () => {
|
|
6846
|
-
return [{
|
|
6847
|
-
childCount: 1,
|
|
6848
|
-
className: IconButton,
|
|
6849
|
-
name: Back,
|
|
6850
|
-
onClick: HandleClickBack,
|
|
6851
|
-
role: Button$2,
|
|
6852
|
-
title: backToChats(),
|
|
6853
|
-
type: Button$1
|
|
6854
|
-
}, {
|
|
6855
|
-
childCount: 0,
|
|
6856
|
-
className: 'MaskIcon MaskIconArrowLeft',
|
|
6857
|
-
type: Div
|
|
6858
|
-
}];
|
|
6859
|
-
};
|
|
6860
|
-
|
|
6861
|
-
const getHeaderActionVirtualDom = item => {
|
|
6862
|
-
return [{
|
|
6863
|
-
childCount: 1,
|
|
6864
|
-
className: IconButton,
|
|
6865
|
-
name: item.name,
|
|
6866
|
-
onClick: item.onClick,
|
|
6867
|
-
title: item.title,
|
|
6868
|
-
type: Button$1
|
|
6869
|
-
}, {
|
|
6870
|
-
childCount: 0,
|
|
6871
|
-
className: item.icon,
|
|
6872
|
-
type: Div
|
|
6873
|
-
}];
|
|
6874
|
-
};
|
|
6875
|
-
|
|
6876
|
-
const getChatHeaderActionsDom = () => {
|
|
6877
|
-
const items = [{
|
|
6878
|
-
icon: 'MaskIcon MaskIconDebugPause',
|
|
6879
|
-
name: SessionDebug,
|
|
6880
|
-
onClick: HandleClickSessionDebug,
|
|
6881
|
-
title: debug()
|
|
6882
|
-
}, {
|
|
6883
|
-
icon: 'MaskIcon MaskIconAdd',
|
|
6884
|
-
name: CreateSession,
|
|
6885
|
-
onClick: HandleClickNew,
|
|
6886
|
-
title: newChat()
|
|
6887
|
-
}, {
|
|
6888
|
-
icon: 'MaskIcon MaskIconSettingsGear',
|
|
6889
|
-
name: Settings,
|
|
6890
|
-
onClick: HandleClickSettings,
|
|
6891
|
-
title: settings()
|
|
6892
|
-
}, {
|
|
6893
|
-
icon: 'MaskIcon MaskIconClose',
|
|
6894
|
-
name: CloseChat,
|
|
6895
|
-
onClick: HandleClickClose,
|
|
6896
|
-
title: closeChat()
|
|
6897
|
-
}];
|
|
6898
|
-
return [{
|
|
6899
|
-
childCount: items.length,
|
|
6900
|
-
className: ChatActions,
|
|
6901
|
-
type: Div
|
|
6902
|
-
}, ...items.flatMap(getHeaderActionVirtualDom)];
|
|
6903
|
-
};
|
|
6904
|
-
|
|
6905
|
-
const getChatHeaderDomDetailMode = selectedSessionTitle => {
|
|
6906
|
-
return [{
|
|
6907
|
-
childCount: 2,
|
|
6908
|
-
className: ChatHeader,
|
|
6909
|
-
type: Div
|
|
6910
|
-
}, {
|
|
6911
|
-
childCount: 2,
|
|
6912
|
-
className: ChatName,
|
|
6913
|
-
type: Div
|
|
6914
|
-
}, ...getBackButtonVirtualDom(), {
|
|
6915
|
-
childCount: 1,
|
|
6916
|
-
className: Label,
|
|
6917
|
-
type: Span
|
|
6918
|
-
}, text(selectedSessionTitle), ...getChatHeaderActionsDom()];
|
|
6919
|
-
};
|
|
6920
|
-
|
|
6921
7422
|
const getInlineNodeDom = inlineNode => {
|
|
6922
7423
|
if (inlineNode.type === 'text') {
|
|
6923
7424
|
return [text(inlineNode.text)];
|
|
@@ -7457,8 +7958,12 @@ const getElementType = tagName => {
|
|
|
7457
7958
|
return inlineTags.has(tagName) ? Span : Div;
|
|
7458
7959
|
}
|
|
7459
7960
|
};
|
|
7961
|
+
const isHttpUrl$1 = url => {
|
|
7962
|
+
const normalized = url.trim().toLowerCase();
|
|
7963
|
+
return normalized.startsWith('http://') || normalized.startsWith('https://');
|
|
7964
|
+
};
|
|
7460
7965
|
const normalizeUrl = url => {
|
|
7461
|
-
return url
|
|
7966
|
+
return isHttpUrl$1(url) ? url : '#';
|
|
7462
7967
|
};
|
|
7463
7968
|
const getElementAttributes = node => {
|
|
7464
7969
|
const attributes = {};
|
|
@@ -7603,6 +8108,13 @@ const markdownInlineRegex = /\[([^\]]+)\]\(([^)]+)\)|\*\*([^*]+)\*\*|\*([^*]+)\*
|
|
|
7603
8108
|
const markdownTableSeparatorCellRegex = /^:?-{3,}:?$/;
|
|
7604
8109
|
const fencedCodeBlockRegex = /^```/;
|
|
7605
8110
|
const markdownHeadingRegex = /^\s*(#{1,6})\s+(.*)$/;
|
|
8111
|
+
const isHttpUrl = url => {
|
|
8112
|
+
const normalized = url.trim().toLowerCase();
|
|
8113
|
+
return normalized.startsWith('http://') || normalized.startsWith('https://');
|
|
8114
|
+
};
|
|
8115
|
+
const sanitizeUrl = url => {
|
|
8116
|
+
return isHttpUrl(url) ? url : '#';
|
|
8117
|
+
};
|
|
7606
8118
|
const normalizeEscapedNewlines = value => {
|
|
7607
8119
|
if (value.includes('\\n')) {
|
|
7608
8120
|
return value.replaceAll(/\\r\\n|\\n/g, '\n');
|
|
@@ -7672,7 +8184,7 @@ const parseInlineNodes = value => {
|
|
|
7672
8184
|
}
|
|
7673
8185
|
if (linkText && href) {
|
|
7674
8186
|
nodes.push({
|
|
7675
|
-
href,
|
|
8187
|
+
href: sanitizeUrl(href),
|
|
7676
8188
|
text: linkText,
|
|
7677
8189
|
type: 'link'
|
|
7678
8190
|
});
|
|
@@ -7880,6 +8392,204 @@ const getMessagesDom = (messages, openRouterApiKeyInput, openApiApiKeyInput = ''
|
|
|
7880
8392
|
}, ...messages.flatMap(message => getChatMessageDom(message, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState))];
|
|
7881
8393
|
};
|
|
7882
8394
|
|
|
8395
|
+
const getProjectSessionDom = (session, selectedSessionId) => {
|
|
8396
|
+
const className = mergeClassNames(ProjectSessionItem, session.id === selectedSessionId ? ProjectSessionItemSelected : Empty);
|
|
8397
|
+
return [{
|
|
8398
|
+
childCount: 1,
|
|
8399
|
+
className,
|
|
8400
|
+
type: Div
|
|
8401
|
+
}, {
|
|
8402
|
+
childCount: 1,
|
|
8403
|
+
className: ProjectSessionItemLabel,
|
|
8404
|
+
name: getSessionInputName(session.id),
|
|
8405
|
+
onClick: HandleClick,
|
|
8406
|
+
tabIndex: 0,
|
|
8407
|
+
type: Div
|
|
8408
|
+
}, text(session.title)];
|
|
8409
|
+
};
|
|
8410
|
+
const getProjectGroupDom = (project, sessions, projectExpandedIds, selectedProjectId, selectedSessionId) => {
|
|
8411
|
+
const expanded = projectExpandedIds.includes(project.id);
|
|
8412
|
+
const projectClassName = mergeClassNames(ProjectListItem, project.id === selectedProjectId ? ProjectListItemSelected : Empty);
|
|
8413
|
+
return [{
|
|
8414
|
+
childCount: 1 + (expanded ? sessions.length : 0),
|
|
8415
|
+
className: ProjectListGroup,
|
|
8416
|
+
type: Div
|
|
8417
|
+
}, {
|
|
8418
|
+
childCount: 2,
|
|
8419
|
+
className: projectClassName,
|
|
8420
|
+
type: Div
|
|
8421
|
+
}, {
|
|
8422
|
+
childCount: 2,
|
|
8423
|
+
className: ProjectListItemLabel,
|
|
8424
|
+
name: getProjectInputName(project.id),
|
|
8425
|
+
onClick: HandleClick,
|
|
8426
|
+
tabIndex: 0,
|
|
8427
|
+
type: Div
|
|
8428
|
+
}, {
|
|
8429
|
+
childCount: 1,
|
|
8430
|
+
className: ProjectListChevron,
|
|
8431
|
+
type: Span
|
|
8432
|
+
}, text(expanded ? '▾' : '▸'), text(project.name), {
|
|
8433
|
+
childCount: 1,
|
|
8434
|
+
className: ProjectListItemActions,
|
|
8435
|
+
type: Div
|
|
8436
|
+
}, {
|
|
8437
|
+
childCount: 1,
|
|
8438
|
+
className: ProjectListItemAddChatButton,
|
|
8439
|
+
name: getCreateSessionInProjectInputName(project.id),
|
|
8440
|
+
onClick: HandleClick,
|
|
8441
|
+
tabIndex: 0,
|
|
8442
|
+
title: 'New chat in this project',
|
|
8443
|
+
type: Button$1
|
|
8444
|
+
}, text('+'), ...(expanded ? sessions.flatMap(session => getProjectSessionDom(session, selectedSessionId)) : [])];
|
|
8445
|
+
};
|
|
8446
|
+
const getProjectListDom = (projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop) => {
|
|
8447
|
+
const blankProjectId = projects.find(project => project.name === '_blank')?.id || projects[0]?.id || '';
|
|
8448
|
+
const projectGroups = projects.map(project => {
|
|
8449
|
+
const projectSessions = sessions.filter(session => {
|
|
8450
|
+
const sessionProjectId = session.projectId || blankProjectId;
|
|
8451
|
+
return sessionProjectId === project.id;
|
|
8452
|
+
});
|
|
8453
|
+
return getProjectGroupDom(project, projectSessions, projectExpandedIds, selectedProjectId, selectedSessionId);
|
|
8454
|
+
});
|
|
8455
|
+
return [{
|
|
8456
|
+
childCount: 2,
|
|
8457
|
+
className: ProjectSidebar,
|
|
8458
|
+
type: Div
|
|
8459
|
+
}, {
|
|
8460
|
+
childCount: projects.length,
|
|
8461
|
+
className: ProjectList,
|
|
8462
|
+
onScroll: HandleProjectListScroll,
|
|
8463
|
+
scrollTop: projectListScrollTop,
|
|
8464
|
+
type: Div
|
|
8465
|
+
}, ...projectGroups.flat(), {
|
|
8466
|
+
childCount: 1,
|
|
8467
|
+
className: ProjectAddButton,
|
|
8468
|
+
name: CreateProject,
|
|
8469
|
+
onClick: HandleClick,
|
|
8470
|
+
tabIndex: 0,
|
|
8471
|
+
type: Button$1
|
|
8472
|
+
}, text('+ Add Project')];
|
|
8473
|
+
};
|
|
8474
|
+
|
|
8475
|
+
const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, messagesScrollTop = 0, composerDropActive = false, composerDropEnabled = true, projects = [], projectExpandedIds = [], selectedProjectId = '', projectListScrollTop = 0) => {
|
|
8476
|
+
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
8477
|
+
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
8478
|
+
const messages = selectedSession ? selectedSession.messages : [];
|
|
8479
|
+
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
8480
|
+
return [{
|
|
8481
|
+
childCount: 5,
|
|
8482
|
+
className: mergeClassNames(Viewlet, Chat, 'ChatFocus'),
|
|
8483
|
+
onDragEnter: HandleDragEnterChatView,
|
|
8484
|
+
onDragOver: HandleDragOverChatView,
|
|
8485
|
+
type: Div
|
|
8486
|
+
}, {
|
|
8487
|
+
childCount: 1,
|
|
8488
|
+
className: ChatHeader,
|
|
8489
|
+
type: Div
|
|
8490
|
+
}, {
|
|
8491
|
+
childCount: 1,
|
|
8492
|
+
className: Label,
|
|
8493
|
+
type: Span
|
|
8494
|
+
}, {
|
|
8495
|
+
text: selectedSessionTitle,
|
|
8496
|
+
type: Text
|
|
8497
|
+
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight), {
|
|
8498
|
+
childCount: 1,
|
|
8499
|
+
className: mergeClassNames(ChatViewDropOverlay, isDropOverlayVisible ? ChatViewDropOverlayActive : Empty),
|
|
8500
|
+
name: ComposerDropTarget,
|
|
8501
|
+
onDragLeave: HandleDragLeave,
|
|
8502
|
+
onDragOver: HandleDragOver,
|
|
8503
|
+
onDrop: HandleDrop,
|
|
8504
|
+
type: Div
|
|
8505
|
+
}, {
|
|
8506
|
+
text: attachImageAsContext(),
|
|
8507
|
+
type: Text
|
|
8508
|
+
}];
|
|
8509
|
+
};
|
|
8510
|
+
|
|
8511
|
+
const getBackButtonVirtualDom = () => {
|
|
8512
|
+
return [{
|
|
8513
|
+
childCount: 1,
|
|
8514
|
+
className: IconButton,
|
|
8515
|
+
name: Back,
|
|
8516
|
+
onClick: HandleClickBack,
|
|
8517
|
+
role: Button$2,
|
|
8518
|
+
title: backToChats(),
|
|
8519
|
+
type: Button$1
|
|
8520
|
+
}, {
|
|
8521
|
+
childCount: 0,
|
|
8522
|
+
className: 'MaskIcon MaskIconArrowLeft',
|
|
8523
|
+
type: Div
|
|
8524
|
+
}];
|
|
8525
|
+
};
|
|
8526
|
+
|
|
8527
|
+
const getHeaderActionVirtualDom = item => {
|
|
8528
|
+
return [{
|
|
8529
|
+
childCount: 1,
|
|
8530
|
+
className: IconButton,
|
|
8531
|
+
name: item.name,
|
|
8532
|
+
onClick: item.onClick,
|
|
8533
|
+
title: item.title,
|
|
8534
|
+
type: Button$1
|
|
8535
|
+
}, {
|
|
8536
|
+
childCount: 0,
|
|
8537
|
+
className: item.icon,
|
|
8538
|
+
type: Div
|
|
8539
|
+
}];
|
|
8540
|
+
};
|
|
8541
|
+
|
|
8542
|
+
const getChatHeaderActionsDom = viewMode => {
|
|
8543
|
+
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
8544
|
+
const items = [{
|
|
8545
|
+
icon: 'MaskIcon MaskIconLayoutPanelLeft',
|
|
8546
|
+
name: ToggleChatFocus,
|
|
8547
|
+
onClick: HandleClick,
|
|
8548
|
+
title: toggleTitle
|
|
8549
|
+
}, {
|
|
8550
|
+
icon: 'MaskIcon MaskIconDebugPause',
|
|
8551
|
+
name: SessionDebug,
|
|
8552
|
+
onClick: HandleClickSessionDebug,
|
|
8553
|
+
title: debug()
|
|
8554
|
+
}, {
|
|
8555
|
+
icon: 'MaskIcon MaskIconAdd',
|
|
8556
|
+
name: CreateSession,
|
|
8557
|
+
onClick: HandleClickNew,
|
|
8558
|
+
title: newChat()
|
|
8559
|
+
}, {
|
|
8560
|
+
icon: 'MaskIcon MaskIconSettingsGear',
|
|
8561
|
+
name: Settings,
|
|
8562
|
+
onClick: HandleClickSettings,
|
|
8563
|
+
title: settings()
|
|
8564
|
+
}, {
|
|
8565
|
+
icon: 'MaskIcon MaskIconClose',
|
|
8566
|
+
name: CloseChat,
|
|
8567
|
+
onClick: HandleClickClose,
|
|
8568
|
+
title: closeChat()
|
|
8569
|
+
}];
|
|
8570
|
+
return [{
|
|
8571
|
+
childCount: items.length,
|
|
8572
|
+
className: ChatActions,
|
|
8573
|
+
type: Div
|
|
8574
|
+
}, ...items.flatMap(getHeaderActionVirtualDom)];
|
|
8575
|
+
};
|
|
8576
|
+
|
|
8577
|
+
const getChatHeaderDomDetailMode = selectedSessionTitle => {
|
|
8578
|
+
return [{
|
|
8579
|
+
childCount: 2,
|
|
8580
|
+
className: ChatHeader,
|
|
8581
|
+
type: Div
|
|
8582
|
+
}, {
|
|
8583
|
+
childCount: 2,
|
|
8584
|
+
className: ChatName,
|
|
8585
|
+
type: Div
|
|
8586
|
+
}, ...getBackButtonVirtualDom(), {
|
|
8587
|
+
childCount: 1,
|
|
8588
|
+
className: Label,
|
|
8589
|
+
type: Span
|
|
8590
|
+
}, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail')];
|
|
8591
|
+
};
|
|
8592
|
+
|
|
7883
8593
|
const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, messagesScrollTop = 0, composerDropActive = false, composerDropEnabled = true) => {
|
|
7884
8594
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
7885
8595
|
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
@@ -7914,7 +8624,7 @@ const getChatHeaderListModeDom = () => {
|
|
|
7914
8624
|
childCount: 1,
|
|
7915
8625
|
className: Label,
|
|
7916
8626
|
type: Span
|
|
7917
|
-
}, text(chats()), ...getChatHeaderActionsDom()];
|
|
8627
|
+
}, text(chats()), ...getChatHeaderActionsDom('list')];
|
|
7918
8628
|
};
|
|
7919
8629
|
|
|
7920
8630
|
const getEmptyChatSessionsDom = () => {
|
|
@@ -8001,8 +8711,10 @@ const getChatModeUnsupportedVirtualDom = () => {
|
|
|
8001
8711
|
}, text(unknownViewMode())];
|
|
8002
8712
|
};
|
|
8003
8713
|
|
|
8004
|
-
const getChatVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive = false, composerDropEnabled = true) => {
|
|
8714
|
+
const getChatVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive = false, composerDropEnabled = true, projects = [], projectExpandedIds = [], selectedProjectId = '', projectListScrollTop = 0) => {
|
|
8005
8715
|
switch (viewMode) {
|
|
8716
|
+
case 'chat-focus':
|
|
8717
|
+
return getChatModeChatFocusVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop, composerDropActive, composerDropEnabled, projects, projectExpandedIds, selectedProjectId, projectListScrollTop);
|
|
8006
8718
|
case 'detail':
|
|
8007
8719
|
return getChatModeDetailVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop, composerDropActive, composerDropEnabled);
|
|
8008
8720
|
case 'list':
|
|
@@ -8028,7 +8740,11 @@ const renderItems = (oldState, newState) => {
|
|
|
8028
8740
|
openApiApiKeyInput,
|
|
8029
8741
|
openRouterApiKeyInput,
|
|
8030
8742
|
openRouterApiKeyState,
|
|
8743
|
+
projectExpandedIds,
|
|
8744
|
+
projectListScrollTop,
|
|
8745
|
+
projects,
|
|
8031
8746
|
selectedModelId,
|
|
8747
|
+
selectedProjectId,
|
|
8032
8748
|
selectedSessionId,
|
|
8033
8749
|
sessions,
|
|
8034
8750
|
tokensMax,
|
|
@@ -8040,7 +8756,7 @@ const renderItems = (oldState, newState) => {
|
|
|
8040
8756
|
if (initial) {
|
|
8041
8757
|
return [SetDom2, uid, []];
|
|
8042
8758
|
}
|
|
8043
|
-
const dom = getChatVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive, composerDropEnabled);
|
|
8759
|
+
const dom = getChatVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive, composerDropEnabled, projects, projectExpandedIds, selectedProjectId, projectListScrollTop);
|
|
8044
8760
|
return [SetDom2, uid, dom];
|
|
8045
8761
|
};
|
|
8046
8762
|
|
|
@@ -8177,6 +8893,9 @@ const renderEventListeners = () => {
|
|
|
8177
8893
|
}, {
|
|
8178
8894
|
name: HandleMessagesScroll,
|
|
8179
8895
|
params: ['handleMessagesScroll', 'event.target.scrollTop']
|
|
8896
|
+
}, {
|
|
8897
|
+
name: HandleProjectListScroll,
|
|
8898
|
+
params: ['handleProjectListScroll', 'event.target.scrollTop']
|
|
8180
8899
|
}, {
|
|
8181
8900
|
name: HandleMessagesContextMenu,
|
|
8182
8901
|
params: ['handleMessagesContextMenu'],
|
|
@@ -8224,20 +8943,30 @@ const saveState = state => {
|
|
|
8224
8943
|
const {
|
|
8225
8944
|
chatListScrollTop,
|
|
8226
8945
|
composerValue,
|
|
8946
|
+
lastNormalViewMode,
|
|
8227
8947
|
messagesScrollTop,
|
|
8228
8948
|
nextMessageId,
|
|
8949
|
+
projectExpandedIds,
|
|
8950
|
+
projectListScrollTop,
|
|
8951
|
+
projects,
|
|
8229
8952
|
renamingSessionId,
|
|
8230
8953
|
selectedModelId,
|
|
8954
|
+
selectedProjectId,
|
|
8231
8955
|
selectedSessionId,
|
|
8232
8956
|
viewMode
|
|
8233
8957
|
} = state;
|
|
8234
8958
|
return {
|
|
8235
8959
|
chatListScrollTop,
|
|
8236
8960
|
composerValue,
|
|
8961
|
+
lastNormalViewMode,
|
|
8237
8962
|
messagesScrollTop,
|
|
8238
8963
|
nextMessageId,
|
|
8964
|
+
projectExpandedIds,
|
|
8965
|
+
projectListScrollTop,
|
|
8966
|
+
projects,
|
|
8239
8967
|
renamingSessionId,
|
|
8240
8968
|
selectedModelId,
|
|
8969
|
+
selectedProjectId,
|
|
8241
8970
|
selectedSessionId,
|
|
8242
8971
|
viewMode
|
|
8243
8972
|
};
|
|
@@ -8336,6 +9065,7 @@ const commandMap = {
|
|
|
8336
9065
|
'Chat.handleMessagesContextMenu': wrapCommand(handleMessagesContextMenu),
|
|
8337
9066
|
'Chat.handleMessagesScroll': wrapCommand(handleMessagesScroll),
|
|
8338
9067
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
9068
|
+
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|
|
8339
9069
|
'Chat.handleSubmit': wrapCommand(handleSubmit),
|
|
8340
9070
|
'Chat.initialize': initialize,
|
|
8341
9071
|
'Chat.loadContent': wrapCommand(loadContent),
|