@lobehub/lobehub 2.0.0-next.109 → 2.0.0-next.110
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/CHANGELOG.md +26 -0
- package/apps/desktop/src/common/routes.ts +0 -6
- package/apps/desktop/src/main/appBrowsers.ts +0 -13
- package/apps/desktop/src/main/controllers/BrowserWindowsCtr.ts +29 -48
- package/apps/desktop/src/main/controllers/__tests__/BrowserWindowsCtr.test.ts +21 -72
- package/apps/desktop/src/main/core/browser/Browser.ts +1 -0
- package/apps/desktop/src/main/core/browser/BrowserManager.ts +1 -56
- package/apps/desktop/src/main/menus/impls/macOS.ts +9 -3
- package/changelog/v1.json +9 -0
- package/locales/ar/setting.json +7 -1
- package/locales/bg-BG/setting.json +7 -1
- package/locales/de-DE/setting.json +7 -1
- package/locales/en-US/setting.json +7 -1
- package/locales/es-ES/setting.json +7 -1
- package/locales/fa-IR/setting.json +7 -1
- package/locales/fr-FR/setting.json +7 -1
- package/locales/it-IT/setting.json +7 -1
- package/locales/ja-JP/setting.json +7 -1
- package/locales/ko-KR/setting.json +7 -1
- package/locales/nl-NL/setting.json +7 -1
- package/locales/pl-PL/setting.json +7 -1
- package/locales/pt-BR/setting.json +7 -1
- package/locales/ru-RU/setting.json +7 -1
- package/locales/tr-TR/setting.json +7 -1
- package/locales/vi-VN/setting.json +7 -1
- package/locales/zh-CN/setting.json +6 -0
- package/locales/zh-TW/setting.json +7 -1
- package/package.json +1 -1
- package/packages/const/src/settings/common.ts +1 -0
- package/packages/model-bank/src/aiModels/ollamacloud.ts +0 -1
- package/packages/types/src/user/settings/general.ts +3 -0
- package/src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/index.tsx +32 -18
- package/src/app/[variants]/(main)/layouts/desktop/DesktopLayoutContainer.tsx +3 -6
- package/src/app/[variants]/(main)/layouts/desktop/SideBar/PinList/index.tsx +21 -14
- package/src/app/[variants]/(main)/settings/common/features/Common/Common.tsx +23 -1
- package/src/features/ChatItem/components/MessageContent.tsx +2 -1
- package/src/features/ChatList/Messages/Assistant/Actions/index.tsx +1 -0
- package/src/features/ChatList/Messages/Assistant/index.tsx +1 -1
- package/src/features/ChatList/Messages/Default.tsx +2 -0
- package/src/features/ChatList/Messages/index.tsx +80 -31
- package/src/features/ChatList/components/ContextMenu.tsx +391 -0
- package/src/features/ChatList/hooks/useChatItemContextMenu.tsx +135 -0
- package/src/locales/default/setting.ts +6 -0
- package/src/store/user/slices/settings/selectors/general.ts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.110](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.109...v2.0.0-next.110)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-11-24**</sup>
|
|
8
|
+
|
|
9
|
+
#### 💄 Styles
|
|
10
|
+
|
|
11
|
+
- **misc**: Add hyperlink to each topic & pinned agent, support ContextMenu on ChatItem.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Styles
|
|
19
|
+
|
|
20
|
+
- **misc**: Add hyperlink to each topic & pinned agent, closes [#10367](https://github.com/lobehub/lobe-chat/issues/10367) ([63e4b3d](https://github.com/lobehub/lobe-chat/commit/63e4b3d))
|
|
21
|
+
- **misc**: Support ContextMenu on ChatItem, closes [#9034](https://github.com/lobehub/lobe-chat/issues/9034) ([27c1154](https://github.com/lobehub/lobe-chat/commit/27c1154))
|
|
22
|
+
|
|
23
|
+
</details>
|
|
24
|
+
|
|
25
|
+
<div align="right">
|
|
26
|
+
|
|
27
|
+
[](#readme-top)
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
5
31
|
## [Version 2.0.0-next.109](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.108...v2.0.0-next.109)
|
|
6
32
|
|
|
7
33
|
<sup>Released on **2025-11-24**</sup>
|
|
@@ -33,12 +33,6 @@ export interface RouteInterceptConfig {
|
|
|
33
33
|
* 定义了所有需要特殊处理的路由
|
|
34
34
|
*/
|
|
35
35
|
export const interceptRoutes: RouteInterceptConfig[] = [
|
|
36
|
-
{
|
|
37
|
-
description: '设置页面',
|
|
38
|
-
enabled: true,
|
|
39
|
-
pathPrefix: '/settings',
|
|
40
|
-
targetWindow: 'settings',
|
|
41
|
-
},
|
|
42
36
|
{
|
|
43
37
|
description: '开发者工具',
|
|
44
38
|
enabled: true,
|
|
@@ -3,7 +3,6 @@ import type { BrowserWindowOpts } from './core/browser/Browser';
|
|
|
3
3
|
export const BrowsersIdentifiers = {
|
|
4
4
|
chat: 'chat',
|
|
5
5
|
devtools: 'devtools',
|
|
6
|
-
settings: 'settings',
|
|
7
6
|
};
|
|
8
7
|
|
|
9
8
|
export const appBrowsers = {
|
|
@@ -32,18 +31,6 @@ export const appBrowsers = {
|
|
|
32
31
|
vibrancy: 'under-window',
|
|
33
32
|
width: 1000,
|
|
34
33
|
},
|
|
35
|
-
settings: {
|
|
36
|
-
autoHideMenuBar: true,
|
|
37
|
-
height: 800,
|
|
38
|
-
identifier: 'settings',
|
|
39
|
-
keepAlive: true,
|
|
40
|
-
minWidth: 600,
|
|
41
|
-
parentIdentifier: 'chat',
|
|
42
|
-
path: '/settings',
|
|
43
|
-
titleBarStyle: 'hidden',
|
|
44
|
-
vibrancy: 'under-window',
|
|
45
|
-
width: 1000,
|
|
46
|
-
},
|
|
47
34
|
} satisfies Record<string, BrowserWindowOpts>;
|
|
48
35
|
|
|
49
36
|
// Window templates for multi-instance windows
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { InterceptRouteParams, OpenSettingsWindowOptions } from '@lobechat/electron-client-ipc';
|
|
2
|
-
import {
|
|
2
|
+
import { findMatchingRoute } from '~common/routes';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
AppBrowsersIdentifiers,
|
|
6
|
-
BrowsersIdentifiers,
|
|
7
6
|
WindowTemplateIdentifiers,
|
|
8
7
|
} from '@/appBrowsers';
|
|
9
8
|
import { IpcClientEventSender } from '@/types/ipcClientEvent';
|
|
@@ -24,14 +23,32 @@ export default class BrowserWindowsCtr extends ControllerModule {
|
|
|
24
23
|
? { tab: typeof options === 'string' ? options : undefined }
|
|
25
24
|
: options;
|
|
26
25
|
|
|
27
|
-
console.log('[BrowserWindowsCtr] Received request to open settings
|
|
26
|
+
console.log('[BrowserWindowsCtr] Received request to open settings', normalizedOptions);
|
|
28
27
|
|
|
29
28
|
try {
|
|
30
|
-
|
|
29
|
+
const query = new URLSearchParams();
|
|
30
|
+
if (normalizedOptions.searchParams) {
|
|
31
|
+
Object.entries(normalizedOptions.searchParams).forEach(([key, value]) => {
|
|
32
|
+
if (value !== undefined) query.set(key, value);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const tab = normalizedOptions.tab;
|
|
37
|
+
if (tab && tab !== 'common' && !query.has('active')) {
|
|
38
|
+
query.set('active', tab);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const queryString = query.toString();
|
|
42
|
+
const subPath = tab && !queryString ? `/${tab}` : '';
|
|
43
|
+
const fullPath = `/settings${subPath}${queryString ? `?${queryString}` : ''}`;
|
|
44
|
+
|
|
45
|
+
const mainWindow = this.app.browserManager.getMainWindow();
|
|
46
|
+
await mainWindow.loadUrl(fullPath);
|
|
47
|
+
mainWindow.show();
|
|
31
48
|
|
|
32
49
|
return { success: true };
|
|
33
50
|
} catch (error) {
|
|
34
|
-
console.error('[BrowserWindowsCtr] Failed to open settings
|
|
51
|
+
console.error('[BrowserWindowsCtr] Failed to open settings:', error);
|
|
35
52
|
return { error: error.message, success: false };
|
|
36
53
|
}
|
|
37
54
|
}
|
|
@@ -76,50 +93,14 @@ export default class BrowserWindowsCtr extends ControllerModule {
|
|
|
76
93
|
);
|
|
77
94
|
|
|
78
95
|
try {
|
|
79
|
-
|
|
80
|
-
const extractedSubPath = extractSubPath(path, matchedRoute.pathPrefix);
|
|
81
|
-
const sanitizedSubPath =
|
|
82
|
-
extractedSubPath && !extractedSubPath.startsWith('?') ? extractedSubPath : undefined;
|
|
83
|
-
let searchParams: Record<string, string> | undefined;
|
|
84
|
-
try {
|
|
85
|
-
const url = new URL(params.url);
|
|
86
|
-
const entries = Array.from(url.searchParams.entries());
|
|
87
|
-
if (entries.length > 0) {
|
|
88
|
-
searchParams = entries.reduce<Record<string, string>>((acc, [key, value]) => {
|
|
89
|
-
acc[key] = value;
|
|
90
|
-
return acc;
|
|
91
|
-
}, {});
|
|
92
|
-
}
|
|
93
|
-
} catch (error) {
|
|
94
|
-
console.warn(
|
|
95
|
-
'[BrowserWindowsCtr] Failed to parse URL for settings route interception:',
|
|
96
|
-
params.url,
|
|
97
|
-
error,
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
await this.app.browserManager.showSettingsWindowWithTab({
|
|
102
|
-
searchParams,
|
|
103
|
-
tab: sanitizedSubPath,
|
|
104
|
-
});
|
|
96
|
+
await this.openTargetWindow(matchedRoute.targetWindow as AppBrowsersIdentifiers);
|
|
105
97
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
};
|
|
113
|
-
} else {
|
|
114
|
-
await this.openTargetWindow(matchedRoute.targetWindow as AppBrowsersIdentifiers);
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
intercepted: true,
|
|
118
|
-
path,
|
|
119
|
-
source,
|
|
120
|
-
targetWindow: matchedRoute.targetWindow,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
98
|
+
return {
|
|
99
|
+
intercepted: true,
|
|
100
|
+
path,
|
|
101
|
+
source,
|
|
102
|
+
targetWindow: matchedRoute.targetWindow,
|
|
103
|
+
};
|
|
123
104
|
} catch (error) {
|
|
124
105
|
console.error('[BrowserWindowsCtr] Error while processing route interception:', error);
|
|
125
106
|
return {
|
|
@@ -9,36 +9,40 @@ import BrowserWindowsCtr from '../BrowserWindowsCtr';
|
|
|
9
9
|
|
|
10
10
|
// 模拟 App 及其依赖项
|
|
11
11
|
const mockToggleVisible = vi.fn();
|
|
12
|
-
const
|
|
12
|
+
const mockLoadUrl = vi.fn();
|
|
13
|
+
const mockShow = vi.fn();
|
|
14
|
+
const mockRedirectToPage = vi.fn();
|
|
13
15
|
const mockCloseWindow = vi.fn();
|
|
14
16
|
const mockMinimizeWindow = vi.fn();
|
|
15
17
|
const mockMaximizeWindow = vi.fn();
|
|
16
18
|
const mockRetrieveByIdentifier = vi.fn();
|
|
17
19
|
const mockGetMainWindow = vi.fn(() => ({
|
|
18
20
|
toggleVisible: mockToggleVisible,
|
|
21
|
+
loadUrl: mockLoadUrl,
|
|
22
|
+
show: mockShow,
|
|
19
23
|
}));
|
|
20
|
-
const
|
|
24
|
+
const mockShowOther = vi.fn();
|
|
21
25
|
|
|
22
26
|
// mock findMatchingRoute and extractSubPath
|
|
23
27
|
vi.mock('~common/routes', async () => ({
|
|
24
28
|
findMatchingRoute: vi.fn(),
|
|
25
29
|
extractSubPath: vi.fn(),
|
|
26
30
|
}));
|
|
27
|
-
const { findMatchingRoute
|
|
31
|
+
const { findMatchingRoute } = await import('~common/routes');
|
|
28
32
|
|
|
29
33
|
const mockApp = {
|
|
30
34
|
browserManager: {
|
|
31
35
|
getMainWindow: mockGetMainWindow,
|
|
32
|
-
|
|
36
|
+
redirectToPage: mockRedirectToPage,
|
|
33
37
|
closeWindow: mockCloseWindow,
|
|
34
38
|
minimizeWindow: mockMinimizeWindow,
|
|
35
39
|
maximizeWindow: mockMaximizeWindow,
|
|
36
40
|
retrieveByIdentifier: mockRetrieveByIdentifier.mockImplementation(
|
|
37
41
|
(identifier: AppBrowsersIdentifiers | string) => {
|
|
38
|
-
if (identifier ===
|
|
39
|
-
return { show:
|
|
42
|
+
if (identifier === 'some-other-window') {
|
|
43
|
+
return { show: mockShowOther };
|
|
40
44
|
}
|
|
41
|
-
return { show:
|
|
45
|
+
return { show: mockShowOther }; // Default mock for other identifiers
|
|
42
46
|
},
|
|
43
47
|
),
|
|
44
48
|
},
|
|
@@ -61,16 +65,18 @@ describe('BrowserWindowsCtr', () => {
|
|
|
61
65
|
});
|
|
62
66
|
|
|
63
67
|
describe('openSettingsWindow', () => {
|
|
64
|
-
it('should
|
|
68
|
+
it('should navigate to settings in main window with the specified tab', async () => {
|
|
65
69
|
const tab = 'appearance';
|
|
66
70
|
const result = await browserWindowsCtr.openSettingsWindow(tab);
|
|
67
|
-
expect(
|
|
71
|
+
expect(mockGetMainWindow).toHaveBeenCalled();
|
|
72
|
+
expect(mockLoadUrl).toHaveBeenCalledWith('/settings?active=appearance');
|
|
73
|
+
expect(mockShow).toHaveBeenCalled();
|
|
68
74
|
expect(result).toEqual({ success: true });
|
|
69
75
|
});
|
|
70
76
|
|
|
71
|
-
it('should return error if
|
|
72
|
-
const errorMessage = 'Failed to
|
|
73
|
-
|
|
77
|
+
it('should return error if navigation fails', async () => {
|
|
78
|
+
const errorMessage = 'Failed to navigate';
|
|
79
|
+
mockLoadUrl.mockRejectedValueOnce(new Error(errorMessage));
|
|
74
80
|
const result = await browserWindowsCtr.openSettingsWindow('display');
|
|
75
81
|
expect(result).toEqual({ error: errorMessage, success: false });
|
|
76
82
|
});
|
|
@@ -117,36 +123,7 @@ describe('BrowserWindowsCtr', () => {
|
|
|
117
123
|
expect(result).toEqual({ intercepted: false, path: params.path, source: params.source });
|
|
118
124
|
});
|
|
119
125
|
|
|
120
|
-
it('should
|
|
121
|
-
const params: InterceptRouteParams = {
|
|
122
|
-
...baseParams,
|
|
123
|
-
path: '/settings/provider',
|
|
124
|
-
url: 'app://host/settings/provider?active=provider&provider=ollama',
|
|
125
|
-
};
|
|
126
|
-
const matchedRoute = { targetWindow: BrowsersIdentifiers.settings, pathPrefix: '/settings' };
|
|
127
|
-
const subPath = 'provider';
|
|
128
|
-
(findMatchingRoute as Mock).mockReturnValue(matchedRoute);
|
|
129
|
-
(extractSubPath as Mock).mockReturnValue(subPath);
|
|
130
|
-
|
|
131
|
-
const result = await browserWindowsCtr.interceptRoute(params);
|
|
132
|
-
|
|
133
|
-
expect(findMatchingRoute).toHaveBeenCalledWith(params.path);
|
|
134
|
-
expect(extractSubPath).toHaveBeenCalledWith(params.path, matchedRoute.pathPrefix);
|
|
135
|
-
expect(mockShowSettingsWindowWithTab).toHaveBeenCalledWith({
|
|
136
|
-
searchParams: { active: 'provider', provider: 'ollama' },
|
|
137
|
-
tab: subPath,
|
|
138
|
-
});
|
|
139
|
-
expect(result).toEqual({
|
|
140
|
-
intercepted: true,
|
|
141
|
-
path: params.path,
|
|
142
|
-
source: params.source,
|
|
143
|
-
subPath,
|
|
144
|
-
targetWindow: matchedRoute.targetWindow,
|
|
145
|
-
});
|
|
146
|
-
expect(mockShow).not.toHaveBeenCalled();
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should open target window if matched route target is not settings', async () => {
|
|
126
|
+
it('should open target window if matched route is found', async () => {
|
|
150
127
|
const params: InterceptRouteParams = {
|
|
151
128
|
...baseParams,
|
|
152
129
|
path: '/other/page',
|
|
@@ -160,44 +137,16 @@ describe('BrowserWindowsCtr', () => {
|
|
|
160
137
|
|
|
161
138
|
expect(findMatchingRoute).toHaveBeenCalledWith(params.path);
|
|
162
139
|
expect(mockRetrieveByIdentifier).toHaveBeenCalledWith(targetWindowIdentifier);
|
|
163
|
-
expect(
|
|
140
|
+
expect(mockShowOther).toHaveBeenCalled();
|
|
164
141
|
expect(result).toEqual({
|
|
165
142
|
intercepted: true,
|
|
166
143
|
path: params.path,
|
|
167
144
|
source: params.source,
|
|
168
145
|
targetWindow: matchedRoute.targetWindow,
|
|
169
146
|
});
|
|
170
|
-
expect(mockShowSettingsWindowWithTab).not.toHaveBeenCalled();
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('should return error if processing route interception fails for settings', async () => {
|
|
174
|
-
const params: InterceptRouteParams = {
|
|
175
|
-
...baseParams,
|
|
176
|
-
path: '/settings',
|
|
177
|
-
url: 'app://host/settings?active=general',
|
|
178
|
-
};
|
|
179
|
-
const matchedRoute = { targetWindow: BrowsersIdentifiers.settings, pathPrefix: '/settings' };
|
|
180
|
-
const subPath = undefined;
|
|
181
|
-
const errorMessage = 'Processing error for settings';
|
|
182
|
-
(findMatchingRoute as Mock).mockReturnValue(matchedRoute);
|
|
183
|
-
(extractSubPath as Mock).mockReturnValue(subPath);
|
|
184
|
-
mockShowSettingsWindowWithTab.mockRejectedValueOnce(new Error(errorMessage));
|
|
185
|
-
|
|
186
|
-
const result = await browserWindowsCtr.interceptRoute(params);
|
|
187
|
-
|
|
188
|
-
expect(mockShowSettingsWindowWithTab).toHaveBeenCalledWith({
|
|
189
|
-
searchParams: { active: 'general' },
|
|
190
|
-
tab: subPath,
|
|
191
|
-
});
|
|
192
|
-
expect(result).toEqual({
|
|
193
|
-
error: errorMessage,
|
|
194
|
-
intercepted: false,
|
|
195
|
-
path: params.path,
|
|
196
|
-
source: params.source,
|
|
197
|
-
});
|
|
198
147
|
});
|
|
199
148
|
|
|
200
|
-
it('should return error if processing route interception fails
|
|
149
|
+
it('should return error if processing route interception fails', async () => {
|
|
201
150
|
const params: InterceptRouteParams = {
|
|
202
151
|
...baseParams,
|
|
203
152
|
path: '/another/custom',
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MainBroadcastEventKey,
|
|
3
|
-
MainBroadcastParams,
|
|
4
|
-
OpenSettingsWindowOptions,
|
|
5
|
-
} from '@lobechat/electron-client-ipc';
|
|
1
|
+
import { MainBroadcastEventKey, MainBroadcastParams } from '@lobechat/electron-client-ipc';
|
|
6
2
|
import { WebContents } from 'electron';
|
|
7
3
|
|
|
8
4
|
import { createLogger } from '@/utils/logger';
|
|
@@ -42,13 +38,6 @@ export class BrowserManager {
|
|
|
42
38
|
window.show();
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
showSettingsWindow() {
|
|
46
|
-
logger.debug('Showing settings window');
|
|
47
|
-
const window = this.retrieveByIdentifier('settings');
|
|
48
|
-
window.show();
|
|
49
|
-
return window;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
41
|
broadcastToAllWindows = <T extends MainBroadcastEventKey>(
|
|
53
42
|
event: T,
|
|
54
43
|
data: MainBroadcastParams<T>,
|
|
@@ -68,50 +57,6 @@ export class BrowserManager {
|
|
|
68
57
|
this.browsers.get(identifier)?.broadcast(event, data);
|
|
69
58
|
};
|
|
70
59
|
|
|
71
|
-
/**
|
|
72
|
-
* Display the settings window and navigate to a specific tab
|
|
73
|
-
* @param tab Settings window sub-path tab
|
|
74
|
-
*/
|
|
75
|
-
async showSettingsWindowWithTab(options?: OpenSettingsWindowOptions) {
|
|
76
|
-
const tab = options?.tab;
|
|
77
|
-
const searchParams = options?.searchParams;
|
|
78
|
-
|
|
79
|
-
const query = new URLSearchParams();
|
|
80
|
-
if (searchParams) {
|
|
81
|
-
Object.entries(searchParams).forEach(([key, value]) => {
|
|
82
|
-
if (value !== undefined) query.set(key, value);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (tab && tab !== 'common' && !query.has('active')) {
|
|
87
|
-
query.set('active', tab);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const queryString = query.toString();
|
|
91
|
-
const activeTab = query.get('active') ?? tab;
|
|
92
|
-
|
|
93
|
-
logger.debug(
|
|
94
|
-
`Showing settings window with navigation: active=${activeTab || 'default'}, query=${
|
|
95
|
-
queryString || 'none'
|
|
96
|
-
}`,
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
if (queryString) {
|
|
100
|
-
const browser = await this.redirectToPage('settings', undefined, queryString);
|
|
101
|
-
|
|
102
|
-
// make provider page more large
|
|
103
|
-
if (activeTab?.startsWith('provider')) {
|
|
104
|
-
logger.debug('Resizing window for provider settings');
|
|
105
|
-
browser.setWindowSize({ height: 1000, width: 1400 });
|
|
106
|
-
browser.moveToCenter();
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return browser;
|
|
110
|
-
} else {
|
|
111
|
-
return this.showSettingsWindow();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
60
|
/**
|
|
116
61
|
* Navigate window to specific sub-path
|
|
117
62
|
* @param identifier Window identifier
|
|
@@ -81,8 +81,10 @@ export class MacOSMenu extends BaseMenuPlatform implements IMenuPlatform {
|
|
|
81
81
|
{ type: 'separator' },
|
|
82
82
|
{
|
|
83
83
|
accelerator: 'Command+,',
|
|
84
|
-
click: () => {
|
|
85
|
-
this.app.browserManager.
|
|
84
|
+
click: async () => {
|
|
85
|
+
const mainWindow = this.app.browserManager.getMainWindow();
|
|
86
|
+
await mainWindow.loadUrl('/settings');
|
|
87
|
+
mainWindow.show();
|
|
86
88
|
},
|
|
87
89
|
label: t('macOS.preferences'),
|
|
88
90
|
},
|
|
@@ -337,7 +339,11 @@ export class MacOSMenu extends BaseMenuPlatform implements IMenuPlatform {
|
|
|
337
339
|
label: t('tray.show', { appName }),
|
|
338
340
|
},
|
|
339
341
|
{
|
|
340
|
-
click: () =>
|
|
342
|
+
click: async () => {
|
|
343
|
+
const mainWindow = this.app.browserManager.getMainWindow();
|
|
344
|
+
await mainWindow.loadUrl('/settings');
|
|
345
|
+
mainWindow.show();
|
|
346
|
+
},
|
|
341
347
|
label: t('file.preferences'),
|
|
342
348
|
},
|
|
343
349
|
{ type: 'separator' },
|
package/changelog/v1.json
CHANGED
package/locales/ar/setting.json
CHANGED
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "أنيق",
|
|
294
294
|
"title": "حركة الاستجابة"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "افتراضي",
|
|
298
|
+
"desc": "اختر طريقة عرض قائمة النقر بزر الماوس الأيمن لرسائل الدردشة",
|
|
299
|
+
"disabled": "عدم الاستخدام",
|
|
300
|
+
"title": "خطة قائمة النقر بزر الماوس الأيمن"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "تخصيص تدرجات الرمادي ذات الاتجاهات اللونية المختلفة",
|
|
298
304
|
"title": "لون محايد"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "أدوات الامتداد"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Елегантно",
|
|
294
294
|
"title": "Анимация на отговор"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "По подразбиране",
|
|
298
|
+
"desc": "Изберете начина на показване на контекстното меню за чат съобщения",
|
|
299
|
+
"disabled": "Не използвай",
|
|
300
|
+
"title": "Схема на контекстното меню"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Персонализиране на сивата скала с различни цветови нюанси",
|
|
298
304
|
"title": "Неутрални цветове"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Инструменти за разширение"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Elegant",
|
|
294
294
|
"title": "Reaktionsanimation"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "Standard",
|
|
298
|
+
"desc": "Wählen Sie das Anzeigeformat des Kontextmenüs für Chatnachrichten",
|
|
299
|
+
"disabled": "Nicht verwenden",
|
|
300
|
+
"title": "Kontextmenü-Option"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Anpassung der Graustufen mit unterschiedlichen Farbneigungen",
|
|
298
304
|
"title": "Neutrale Farben"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Erweiterungswerkzeuge"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Elegant",
|
|
294
294
|
"title": "Response Animation"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "Default",
|
|
298
|
+
"desc": "Select the display mode for the chat message right-click menu",
|
|
299
|
+
"disabled": "Disabled",
|
|
300
|
+
"title": "Right-Click Menu Mode"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Custom grayscale with different color tendencies",
|
|
298
304
|
"title": "Neutral Color"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Extension Tools"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Elegante",
|
|
294
294
|
"title": "Animación de respuesta"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "Predeterminado",
|
|
298
|
+
"desc": "Seleccione el esquema de visualización del menú contextual en los mensajes de chat",
|
|
299
|
+
"disabled": "No usar",
|
|
300
|
+
"title": "Esquema del menú contextual"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Personalización de escalas de grises con diferentes inclinaciones de color",
|
|
298
304
|
"title": "Color Neutro"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Herramientas de extensión"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "ظریف",
|
|
294
294
|
"title": "انیمیشن پاسخ"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "پیشفرض",
|
|
298
|
+
"desc": "انتخاب طرح نمایش منوی کلیک راست پیامهای چت",
|
|
299
|
+
"disabled": "استفاده نشود",
|
|
300
|
+
"title": "طرح منوی کلیک راست"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "سفارشیسازی مقیاس خاکستری با تمهای رنگی مختلف",
|
|
298
304
|
"title": "رنگهای خنثی"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "افزونههای گسترش"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Élégant",
|
|
294
294
|
"title": "Animation de réponse"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "Par défaut",
|
|
298
|
+
"desc": "Choisissez le mode d'affichage du menu contextuel des messages de chat",
|
|
299
|
+
"disabled": "Désactivé",
|
|
300
|
+
"title": "Mode du menu contextuel"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Personnalisation des nuances de gris selon les tendances de couleur",
|
|
298
304
|
"title": "Couleur neutre"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Outils supplémentaires"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Elegante",
|
|
294
294
|
"title": "Animazione di risposta"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "Predefinito",
|
|
298
|
+
"desc": "Seleziona il tipo di menu contestuale per i messaggi di chat",
|
|
299
|
+
"disabled": "Disabilitato",
|
|
300
|
+
"title": "Tipo di menu contestuale"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Personalizzazione dei grigi con diverse inclinazioni di colore",
|
|
298
304
|
"title": "Colore Neutro"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Strumenti aggiuntivi"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "エレガント",
|
|
294
294
|
"title": "応答アニメーション"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "デフォルト",
|
|
298
|
+
"desc": "チャットメッセージの右クリックメニューの表示方法を選択してください",
|
|
299
|
+
"disabled": "使用しない",
|
|
300
|
+
"title": "右クリックメニューの設定"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "異なる色彩傾向のグレースケールカスタマイズ",
|
|
298
304
|
"title": "ニュートラルカラー"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "拡張ツール"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "우아함",
|
|
294
294
|
"title": "반응 애니메이션"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "기본값",
|
|
298
|
+
"desc": "채팅 메시지 우클릭 메뉴 표시 방식을 선택하세요",
|
|
299
|
+
"disabled": "사용 안 함",
|
|
300
|
+
"title": "우클릭 메뉴 방식"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "다양한 색상 경향의 회색조 사용자 정의",
|
|
298
304
|
"title": "중립 색상"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "확장 도구"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|
|
@@ -293,6 +293,12 @@
|
|
|
293
293
|
"elegant": "Elegant",
|
|
294
294
|
"title": "Reactie-animatie"
|
|
295
295
|
},
|
|
296
|
+
"contextMenuMode": {
|
|
297
|
+
"default": "Standaard",
|
|
298
|
+
"desc": "Kies de weergaveoptie voor het contextmenu van chatberichten",
|
|
299
|
+
"disabled": "Niet gebruiken",
|
|
300
|
+
"title": "Contextmenu-optie"
|
|
301
|
+
},
|
|
296
302
|
"neutralColor": {
|
|
297
303
|
"desc": "Aangepaste grijstinten met verschillende kleurvoorkeuren",
|
|
298
304
|
"title": "Neutrale kleur"
|
|
@@ -777,4 +783,4 @@
|
|
|
777
783
|
},
|
|
778
784
|
"title": "Uitbreidingsgereedschap"
|
|
779
785
|
}
|
|
780
|
-
}
|
|
786
|
+
}
|