mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 17:47:27 +00:00
♻️ refactor(desktop): consolidate global shortcuts (LOBE-7181) (#13880)
* ♻️ refactor(desktop): consolidate global shortcuts and remove default showApp hotkey - Add desktopGlobalShortcuts.ts as single source for Electron + renderer defaults - Wire ShortcutManager and store to DEFAULT_ELECTRON_DESKTOP_SHORTCUTS - Use DesktopHotkeyId for @shortcut; drop local shortcuts barrel - Stop re-exporting DESKTOP_HOTKEYS_REGISTRATION from hotkeys Fixes LOBE-7181 Made-with: Cursor * ✨ feat(desktop): introduce new stubs for business constants and types - Added `@lobechat/business-const` and `@lobechat/types` packages to support workspace dependency resolution. - Updated `package.json` and `pnpm-workspace.yaml` to include new stubs. - Refactored imports in `index.ts` to utilize the new constants structure. - Enhanced `desktopGlobalShortcuts.ts` with improved type definitions for hotkeys. This change streamlines the management of constants and types across the desktop application. Signed-off-by: Innei <tukon479@gmail.com> * ♻️ refactor(hotkeys): consolidate desktop global shortcut definitions (LOBE-7181) Made-with: Cursor * ✨ feat(session, user): replace direct type imports with constants - Updated session.ts to use constants for session types instead of direct imports from @lobechat/types. - Updated user.ts to use a constant for the default topic display mode, enhancing consistency and maintainability. This change improves code clarity and reduces dependencies on external type definitions. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
parent
35558cbea1
commit
d2197f4c30
43 changed files with 260 additions and 236 deletions
|
|
@ -1,8 +1,11 @@
|
|||
packages:
|
||||
- '../../packages/const'
|
||||
- '../../packages/electron-server-ipc'
|
||||
- '../../packages/electron-client-ipc'
|
||||
- '../../packages/file-loaders'
|
||||
- '../../packages/desktop-bridge'
|
||||
- '../../packages/device-gateway-client'
|
||||
- '../../packages/local-file-shell'
|
||||
- './stubs/business-const'
|
||||
- './stubs/types'
|
||||
- '.'
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* Application settings storage related constants
|
||||
*/
|
||||
import { DEFAULT_ELECTRON_DESKTOP_SHORTCUTS } from '@lobechat/const/desktopGlobalShortcuts';
|
||||
import type { NetworkProxySettings } from '@lobechat/electron-client-ipc';
|
||||
|
||||
import { appStorageDir } from '@/const/dir';
|
||||
import { UPDATE_CHANNEL } from '@/modules/updater/configs';
|
||||
import { DEFAULT_SHORTCUTS_CONFIG } from '@/shortcuts';
|
||||
import type { ElectronMainStore } from '@/types/store';
|
||||
|
||||
/**
|
||||
|
|
@ -35,7 +35,7 @@ export const STORE_DEFAULTS: ElectronMainStore = {
|
|||
gatewayUrl: 'https://device-gateway.lobehub.com',
|
||||
locale: 'auto',
|
||||
networkProxy: defaultProxySettings,
|
||||
shortcuts: DEFAULT_SHORTCUTS_CONFIG,
|
||||
shortcuts: DEFAULT_ELECTRON_DESKTOP_SHORTCUTS,
|
||||
storagePath: appStorageDir,
|
||||
themeMode: 'system',
|
||||
updateChannel: UPDATE_CHANNEL,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { DesktopHotkeyId } from '@lobechat/const/desktopGlobalShortcuts';
|
||||
|
||||
import type { App } from '@/core/App';
|
||||
import { IoCContainer } from '@/core/infrastructure/IoCContainer';
|
||||
import type { ShortcutActionType } from '@/shortcuts';
|
||||
import { IpcService } from '@/utils/ipc';
|
||||
|
||||
const shortcutDecorator = (name: string) => (target: any, methodName: string, descriptor?: any) => {
|
||||
|
|
@ -15,7 +16,7 @@ const shortcutDecorator = (name: string) => (target: any, methodName: string, de
|
|||
/**
|
||||
* shortcut inject decorator
|
||||
*/
|
||||
export const shortcut = (method: ShortcutActionType) => shortcutDecorator(method);
|
||||
export const shortcut = (method: DesktopHotkeyId) => shortcutDecorator(method);
|
||||
|
||||
const protocolDecorator =
|
||||
(urlType: string, action: string) => (target: any, methodName: string, descriptor?: any) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { DEFAULT_ELECTRON_DESKTOP_SHORTCUTS } from '@lobechat/const/desktopGlobalShortcuts';
|
||||
import { globalShortcut } from 'electron';
|
||||
|
||||
import { DEFAULT_SHORTCUTS_CONFIG } from '@/shortcuts';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
import type { App } from '../App';
|
||||
|
|
@ -77,8 +77,8 @@ export class ShortcutManager {
|
|||
try {
|
||||
logger.debug(`Updating shortcut ${id} to ${accelerator}`);
|
||||
|
||||
// 1. Check if ID is valid
|
||||
if (!DEFAULT_SHORTCUTS_CONFIG[id]) {
|
||||
// 1. Check if ID is valid (value may be empty string when disabled by default)
|
||||
if (!(id in DEFAULT_ELECTRON_DESKTOP_SHORTCUTS)) {
|
||||
logger.error(`Invalid shortcut ID: ${id}`);
|
||||
return { errorType: 'INVALID_ID', success: false };
|
||||
}
|
||||
|
|
@ -231,15 +231,15 @@ export class ShortcutManager {
|
|||
// If no configuration, use default configuration
|
||||
if (!config || Object.keys(config).length === 0) {
|
||||
logger.debug('No shortcuts config found, using defaults');
|
||||
this.shortcutsConfig = { ...DEFAULT_SHORTCUTS_CONFIG };
|
||||
this.shortcutsConfig = { ...DEFAULT_ELECTRON_DESKTOP_SHORTCUTS };
|
||||
this.saveShortcutsConfig();
|
||||
} else {
|
||||
// Filter out invalid shortcuts that are not in DEFAULT_SHORTCUTS_CONFIG
|
||||
// Filter out invalid shortcuts that are not in DEFAULT_ELECTRON_DESKTOP_SHORTCUTS
|
||||
const filteredConfig: Record<string, string> = {};
|
||||
let hasInvalidKeys = false;
|
||||
|
||||
Object.entries(config).forEach(([id, accelerator]) => {
|
||||
if (DEFAULT_SHORTCUTS_CONFIG[id]) {
|
||||
if (id in DEFAULT_ELECTRON_DESKTOP_SHORTCUTS) {
|
||||
filteredConfig[id] = accelerator;
|
||||
} else {
|
||||
hasInvalidKeys = true;
|
||||
|
|
@ -248,7 +248,7 @@ export class ShortcutManager {
|
|||
});
|
||||
|
||||
// Ensure all default shortcuts are present
|
||||
Object.entries(DEFAULT_SHORTCUTS_CONFIG).forEach(([id, defaultAccelerator]) => {
|
||||
Object.entries(DEFAULT_ELECTRON_DESKTOP_SHORTCUTS).forEach(([id, defaultAccelerator]) => {
|
||||
if (!(id in filteredConfig)) {
|
||||
filteredConfig[id] = defaultAccelerator;
|
||||
logger.debug(`Adding missing default shortcut: ${id} = ${defaultAccelerator}`);
|
||||
|
|
@ -267,7 +267,7 @@ export class ShortcutManager {
|
|||
logger.debug('Loaded shortcuts config:', this.shortcutsConfig);
|
||||
} catch (error) {
|
||||
logger.error('Error loading shortcuts config:', error);
|
||||
this.shortcutsConfig = { ...DEFAULT_SHORTCUTS_CONFIG };
|
||||
this.shortcutsConfig = { ...DEFAULT_ELECTRON_DESKTOP_SHORTCUTS };
|
||||
this.saveShortcutsConfig();
|
||||
}
|
||||
}
|
||||
|
|
@ -295,9 +295,9 @@ export class ShortcutManager {
|
|||
Object.entries(this.shortcutsConfig).forEach(([id, accelerator]) => {
|
||||
logger.debug(`Registering shortcut '${id}' with ${accelerator}`);
|
||||
|
||||
// Only register shortcuts that exist in DEFAULT_SHORTCUTS_CONFIG
|
||||
if (!DEFAULT_SHORTCUTS_CONFIG[id]) {
|
||||
logger.debug(`Skipping shortcut '${id}' - not found in DEFAULT_SHORTCUTS_CONFIG`);
|
||||
// Only register shortcuts that exist in DEFAULT_ELECTRON_DESKTOP_SHORTCUTS
|
||||
if (!(id in DEFAULT_ELECTRON_DESKTOP_SHORTCUTS)) {
|
||||
logger.debug(`Skipping shortcut '${id}' - not found in DEFAULT_ELECTRON_DESKTOP_SHORTCUTS`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { DEFAULT_ELECTRON_DESKTOP_SHORTCUTS } from '@lobechat/const/desktopGlobalShortcuts';
|
||||
import { globalShortcut } from 'electron';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { DEFAULT_SHORTCUTS_CONFIG } from '@/shortcuts';
|
||||
|
||||
import type { App } from '../../App';
|
||||
import { ShortcutManager } from '../ShortcutManager';
|
||||
|
||||
|
|
@ -26,10 +25,10 @@ vi.mock('@/utils/logger', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
// Mock DEFAULT_SHORTCUTS_CONFIG
|
||||
vi.mock('@/shortcuts', () => ({
|
||||
DEFAULT_SHORTCUTS_CONFIG: {
|
||||
showApp: 'Control+E',
|
||||
// Mock desktop global shortcut defaults
|
||||
vi.mock('@lobechat/const/desktopGlobalShortcuts', () => ({
|
||||
DEFAULT_ELECTRON_DESKTOP_SHORTCUTS: {
|
||||
showApp: '',
|
||||
openSettings: 'CommandOrControl+,',
|
||||
},
|
||||
}));
|
||||
|
|
@ -115,7 +114,7 @@ describe('ShortcutManager', () => {
|
|||
|
||||
expect(mockStoreManager.get).toHaveBeenCalledWith('shortcuts');
|
||||
expect(globalShortcut.unregisterAll).toHaveBeenCalled();
|
||||
expect(globalShortcut.register).toHaveBeenCalledWith('Control+E', expect.any(Function));
|
||||
expect(globalShortcut.register).not.toHaveBeenCalledWith('Control+E', expect.any(Function));
|
||||
expect(globalShortcut.register).toHaveBeenCalledWith(
|
||||
'CommandOrControl+,',
|
||||
expect.any(Function),
|
||||
|
|
@ -145,7 +144,7 @@ describe('ShortcutManager', () => {
|
|||
shortcutManager.initialize();
|
||||
|
||||
const config = shortcutManager.getShortcutsConfig();
|
||||
expect(config).toEqual(DEFAULT_SHORTCUTS_CONFIG);
|
||||
expect(config).toEqual(DEFAULT_ELECTRON_DESKTOP_SHORTCUTS);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -346,8 +345,11 @@ describe('ShortcutManager', () => {
|
|||
|
||||
shortcutManager['loadShortcutsConfig']();
|
||||
|
||||
expect(shortcutManager['shortcutsConfig']).toEqual(DEFAULT_SHORTCUTS_CONFIG);
|
||||
expect(mockStoreManager.set).toHaveBeenCalledWith('shortcuts', DEFAULT_SHORTCUTS_CONFIG);
|
||||
expect(shortcutManager['shortcutsConfig']).toEqual(DEFAULT_ELECTRON_DESKTOP_SHORTCUTS);
|
||||
expect(mockStoreManager.set).toHaveBeenCalledWith(
|
||||
'shortcuts',
|
||||
DEFAULT_ELECTRON_DESKTOP_SHORTCUTS,
|
||||
);
|
||||
});
|
||||
|
||||
it('should use defaults when config is empty', () => {
|
||||
|
|
@ -355,7 +357,7 @@ describe('ShortcutManager', () => {
|
|||
|
||||
shortcutManager['loadShortcutsConfig']();
|
||||
|
||||
expect(shortcutManager['shortcutsConfig']).toEqual(DEFAULT_SHORTCUTS_CONFIG);
|
||||
expect(shortcutManager['shortcutsConfig']).toEqual(DEFAULT_ELECTRON_DESKTOP_SHORTCUTS);
|
||||
});
|
||||
|
||||
it('should filter invalid keys from stored config', () => {
|
||||
|
|
@ -413,8 +415,11 @@ describe('ShortcutManager', () => {
|
|||
|
||||
shortcutManager['loadShortcutsConfig']();
|
||||
|
||||
expect(shortcutManager['shortcutsConfig']).toEqual(DEFAULT_SHORTCUTS_CONFIG);
|
||||
expect(mockStoreManager.set).toHaveBeenCalledWith('shortcuts', DEFAULT_SHORTCUTS_CONFIG);
|
||||
expect(shortcutManager['shortcutsConfig']).toEqual(DEFAULT_ELECTRON_DESKTOP_SHORTCUTS);
|
||||
expect(mockStoreManager.set).toHaveBeenCalledWith(
|
||||
'shortcuts',
|
||||
DEFAULT_ELECTRON_DESKTOP_SHORTCUTS,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -458,7 +463,7 @@ describe('ShortcutManager', () => {
|
|||
expect(globalShortcut.register).toHaveBeenCalledWith('Ctrl+P', expect.any(Function));
|
||||
});
|
||||
|
||||
it('should skip shortcuts not in DEFAULT_SHORTCUTS_CONFIG', () => {
|
||||
it('should skip shortcuts not defined in default electron desktop shortcuts', () => {
|
||||
shortcutManager['shortcutsConfig'] = {
|
||||
showApp: 'Alt+E',
|
||||
invalidKey: 'Ctrl+I',
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
/**
|
||||
* Shortcut action type enum
|
||||
*/
|
||||
export const ShortcutActionEnum = {
|
||||
openSettings: 'openSettings',
|
||||
/**
|
||||
* Show/hide main window
|
||||
*/
|
||||
showApp: 'showApp',
|
||||
} as const;
|
||||
|
||||
export type ShortcutActionType = (typeof ShortcutActionEnum)[keyof typeof ShortcutActionEnum];
|
||||
|
||||
/**
|
||||
* Default shortcut configuration
|
||||
*/
|
||||
export const DEFAULT_SHORTCUTS_CONFIG: Record<ShortcutActionType, string> = {
|
||||
[ShortcutActionEnum.showApp]: 'Control+E',
|
||||
[ShortcutActionEnum.openSettings]: 'CommandOrControl+,',
|
||||
};
|
||||
|
|
@ -1 +0,0 @@
|
|||
export * from './config';
|
||||
9
apps/desktop/stubs/business-const/package.json
Normal file
9
apps/desktop/stubs/business-const/package.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@lobechat/business-const",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"main": "./src/index.ts"
|
||||
}
|
||||
6
apps/desktop/stubs/business-const/src/index.ts
Normal file
6
apps/desktop/stubs/business-const/src/index.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export const BRANDING_LOGO_URL = '';
|
||||
export const BRANDING_NAME = 'LobeHub';
|
||||
export const DEFAULT_EMBEDDING_PROVIDER = 'openai';
|
||||
export const DEFAULT_MINI_PROVIDER = 'openai';
|
||||
export const DEFAULT_PROVIDER = 'openai';
|
||||
export const ORG_NAME = 'LobeHub';
|
||||
9
apps/desktop/stubs/types/package.json
Normal file
9
apps/desktop/stubs/types/package.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@lobechat/types",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"main": "./src/index.ts"
|
||||
}
|
||||
8
apps/desktop/stubs/types/src/index.ts
Normal file
8
apps/desktop/stubs/types/src/index.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Desktop isolated workspace stub.
|
||||
*
|
||||
* `@lobechat/types` is only consumed via `import type` in desktop code; those
|
||||
* specifiers are erased at build time, so this package needs no runtime
|
||||
* exports.
|
||||
*/
|
||||
export {};
|
||||
|
|
@ -4,7 +4,9 @@
|
|||
"private": true,
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./currency": "./src/currency.ts"
|
||||
"./currency": "./src/currency.ts",
|
||||
"./desktopGlobalShortcuts": "./src/desktopGlobalShortcuts.ts",
|
||||
"./hotkeys": "./src/hotkeys.ts"
|
||||
},
|
||||
"main": "./src/index.ts",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import type { DesktopHotkeyConfig } from '@lobechat/types';
|
||||
|
||||
import { DESKTOP_HOTKEYS_REGISTRATION } from './hotkeys';
|
||||
import { DESKTOP_HOTKEYS_REGISTRATION, type DesktopHotkeyConfig } from './desktopGlobalShortcuts';
|
||||
|
||||
export const DESKTOP_USER_ID = 'DEFAULT_DESKTOP_USER';
|
||||
|
||||
|
|
|
|||
59
packages/const/src/desktopGlobalShortcuts.ts
Normal file
59
packages/const/src/desktopGlobalShortcuts.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
const combineKeys = (keys: string[]) => keys.join('+');
|
||||
|
||||
export const DesktopHotkeyEnum = {
|
||||
OpenSettings: 'openSettings',
|
||||
ShowApp: 'showApp',
|
||||
} as const;
|
||||
|
||||
export type DesktopHotkeyId = (typeof DesktopHotkeyEnum)[keyof typeof DesktopHotkeyEnum];
|
||||
|
||||
export interface DesktopHotkeyItem {
|
||||
id: DesktopHotkeyId;
|
||||
keys: string;
|
||||
nonEditable?: boolean;
|
||||
}
|
||||
|
||||
export type DesktopHotkeyConfig = Record<DesktopHotkeyId, string>;
|
||||
|
||||
interface DesktopGlobalShortcutDefault {
|
||||
/** Electron `globalShortcut` accelerator; empty string means unregistered. */
|
||||
electronAccelerator: string;
|
||||
id: DesktopHotkeyId;
|
||||
nonEditable?: boolean;
|
||||
/** React-hotkey style string for renderer (HotkeyInput, merge defaults). */
|
||||
uiKeys: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single source of truth for desktop (Electron) global shortcut defaults.
|
||||
* Main process reads `electronAccelerator`; renderer uses `uiKeys` and metadata.
|
||||
*/
|
||||
export const DESKTOP_GLOBAL_SHORTCUT_DEFAULTS = [
|
||||
{
|
||||
electronAccelerator: '',
|
||||
id: DesktopHotkeyEnum.ShowApp,
|
||||
uiKeys: '',
|
||||
},
|
||||
{
|
||||
electronAccelerator: 'CommandOrControl+,',
|
||||
id: DesktopHotkeyEnum.OpenSettings,
|
||||
nonEditable: true,
|
||||
uiKeys: combineKeys(['mod', 'comma']),
|
||||
},
|
||||
] as const satisfies readonly DesktopGlobalShortcutDefault[];
|
||||
|
||||
export const DESKTOP_HOTKEYS_REGISTRATION: DesktopHotkeyItem[] =
|
||||
DESKTOP_GLOBAL_SHORTCUT_DEFAULTS.map((item): DesktopHotkeyItem => {
|
||||
const base: DesktopHotkeyItem = {
|
||||
id: item.id,
|
||||
keys: item.uiKeys,
|
||||
};
|
||||
|
||||
return 'nonEditable' in item && item.nonEditable ? { ...base, nonEditable: true } : base;
|
||||
});
|
||||
|
||||
export const DEFAULT_ELECTRON_DESKTOP_SHORTCUTS: DesktopHotkeyConfig =
|
||||
DESKTOP_GLOBAL_SHORTCUT_DEFAULTS.reduce<DesktopHotkeyConfig>((acc, item) => {
|
||||
acc[item.id] = item.electronAccelerator;
|
||||
return acc;
|
||||
}, {} as DesktopHotkeyConfig);
|
||||
|
|
@ -1,14 +1,87 @@
|
|||
import type { DesktopHotkeyItem, HotkeyItem } from '@lobechat/types';
|
||||
import {
|
||||
DesktopHotkeyEnum,
|
||||
HotkeyEnum,
|
||||
HotkeyGroupEnum,
|
||||
HotkeyScopeEnum,
|
||||
KeyEnum,
|
||||
} from '@lobechat/types';
|
||||
|
||||
const combineKeys = (keys: string[]) => keys.join('+');
|
||||
|
||||
export const KeyEnum = {
|
||||
Alt: 'alt',
|
||||
Backquote: 'backquote',
|
||||
Backslash: 'backslash',
|
||||
Backspace: 'backspace',
|
||||
BracketLeft: 'bracketleft',
|
||||
BracketRight: 'bracketright',
|
||||
Comma: 'comma',
|
||||
Ctrl: 'ctrl',
|
||||
Down: 'down',
|
||||
Enter: 'enter',
|
||||
Equal: 'equal',
|
||||
Esc: 'esc',
|
||||
Left: 'left',
|
||||
LeftClick: 'left-click',
|
||||
LeftDoubleClick: 'left-double-click',
|
||||
Meta: 'meta',
|
||||
MiddleClick: 'middle-click',
|
||||
Minus: 'minus',
|
||||
Mod: 'mod',
|
||||
Number: '1-9',
|
||||
Period: 'period',
|
||||
Plus: 'equal',
|
||||
QuestionMark: 'slash',
|
||||
Quote: 'quote',
|
||||
Right: 'right',
|
||||
RightClick: 'right-click',
|
||||
RightDoubleClick: 'right-double-click',
|
||||
Semicolon: 'semicolon',
|
||||
Shift: 'shift',
|
||||
Slash: 'slash',
|
||||
Space: 'space',
|
||||
Tab: 'tab',
|
||||
Up: 'up',
|
||||
Zero: '0',
|
||||
} as const;
|
||||
|
||||
export const HotkeyEnum = {
|
||||
AddUserMessage: 'addUserMessage',
|
||||
ClearCurrentMessages: 'clearCurrentMessages',
|
||||
CommandPalette: 'commandPalette',
|
||||
DeleteAndRegenerateMessage: 'deleteAndRegenerateMessage',
|
||||
DeleteLastMessage: 'deleteLastMessage',
|
||||
EditMessage: 'editMessage',
|
||||
NavigateToChat: 'navigateToChat',
|
||||
OpenChatSettings: 'openChatSettings',
|
||||
OpenHotkeyHelper: 'openHotkeyHelper',
|
||||
RegenerateMessage: 'regenerateMessage',
|
||||
SaveDocument: 'saveDocument',
|
||||
SaveTopic: 'saveTopic',
|
||||
Search: 'search',
|
||||
ShowApp: 'showApp',
|
||||
SwitchAgent: 'switchAgent',
|
||||
ToggleLeftPanel: 'toggleLeftPanel',
|
||||
ToggleRightPanel: 'toggleRightPanel',
|
||||
ToggleZenMode: 'toggleZenMode',
|
||||
} as const;
|
||||
|
||||
export const HotkeyGroupEnum = {
|
||||
Conversation: 'conversation',
|
||||
Essential: 'essential',
|
||||
} as const;
|
||||
|
||||
export const HotkeyScopeEnum = {
|
||||
Chat: 'chat',
|
||||
Files: 'files',
|
||||
Global: 'global',
|
||||
Image: 'image',
|
||||
} as const;
|
||||
|
||||
export type HotkeyId = (typeof HotkeyEnum)[keyof typeof HotkeyEnum];
|
||||
export type HotkeyGroupId = (typeof HotkeyGroupEnum)[keyof typeof HotkeyGroupEnum];
|
||||
export type HotkeyScopeId = (typeof HotkeyScopeEnum)[keyof typeof HotkeyScopeEnum];
|
||||
|
||||
export interface HotkeyItem {
|
||||
group: HotkeyGroupId;
|
||||
id: HotkeyId;
|
||||
keys: string;
|
||||
nonEditable?: boolean;
|
||||
scopes?: HotkeyScopeId[];
|
||||
}
|
||||
|
||||
export type HotkeyRegistration = HotkeyItem[];
|
||||
|
||||
// mod is the command key on Mac, alt is the ctrl key on Windows
|
||||
|
|
@ -120,18 +193,3 @@ export const HOTKEYS_REGISTRATION: HotkeyRegistration = [
|
|||
scopes: [HotkeyScopeEnum.Files],
|
||||
},
|
||||
];
|
||||
|
||||
type DesktopHotkeyRegistration = DesktopHotkeyItem[];
|
||||
|
||||
// Desktop hotkey configuration
|
||||
export const DESKTOP_HOTKEYS_REGISTRATION: DesktopHotkeyRegistration = [
|
||||
{
|
||||
id: DesktopHotkeyEnum.ShowApp,
|
||||
keys: combineKeys([KeyEnum.Ctrl, 'e']),
|
||||
},
|
||||
{
|
||||
id: DesktopHotkeyEnum.OpenSettings,
|
||||
keys: combineKeys([KeyEnum.Mod, KeyEnum.Comma]),
|
||||
nonEditable: true,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export * from './bot';
|
||||
export * from './currency';
|
||||
export * from './desktop';
|
||||
export * from './desktopGlobalShortcuts';
|
||||
export * from './discover';
|
||||
export * from './editor';
|
||||
export * from './file';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import type { LobeAgentSession, LobeGroupSession } from '@lobechat/types';
|
||||
import { LobeSessionType } from '@lobechat/types';
|
||||
|
||||
import { DEFAULT_AGENT_META, DEFAULT_INBOX_AVATAR } from './meta';
|
||||
import { DEFAULT_AGENT_CONFIG } from './settings';
|
||||
|
|
@ -9,13 +8,16 @@ export const INBOX_SESSION_ID = 'inbox';
|
|||
|
||||
export const WELCOME_GUIDE_CHAT_ID = 'welcome';
|
||||
|
||||
const DEFAULT_AGENT_SESSION_TYPE = 'agent' as LobeAgentSession['type'];
|
||||
const DEFAULT_GROUP_SESSION_TYPE = 'group' as LobeGroupSession['type'];
|
||||
|
||||
export const DEFAULT_AGENT_LOBE_SESSION: LobeAgentSession = {
|
||||
config: DEFAULT_AGENT_CONFIG,
|
||||
createdAt: new Date(),
|
||||
id: '',
|
||||
meta: DEFAULT_AGENT_META,
|
||||
model: DEFAULT_AGENT_CONFIG.model,
|
||||
type: LobeSessionType.Agent,
|
||||
type: DEFAULT_AGENT_SESSION_TYPE,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
|
|
@ -24,7 +26,7 @@ export const DEFAULT_GROUP_LOBE_SESSION: LobeGroupSession = {
|
|||
id: '',
|
||||
members: [],
|
||||
meta: DEFAULT_AGENT_META,
|
||||
type: LobeSessionType.Group,
|
||||
type: DEFAULT_GROUP_SESSION_TYPE,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { UserHotkeyConfig } from '@lobechat/types';
|
||||
import { type HotkeyId, HOTKEYS_REGISTRATION } from '../hotkeys';
|
||||
|
||||
import { HOTKEYS_REGISTRATION } from '../hotkeys';
|
||||
type UserHotkeyConfig = Record<HotkeyId, string>;
|
||||
|
||||
export const DEFAULT_HOTKEY_CONFIG: UserHotkeyConfig = HOTKEYS_REGISTRATION.reduce(
|
||||
(acc: UserHotkeyConfig, item) => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import type { UserPreference } from '@lobechat/types';
|
||||
import { TopicDisplayMode } from '@lobechat/types';
|
||||
|
||||
/**
|
||||
* Current onboarding flow version.
|
||||
|
|
@ -8,6 +7,10 @@ import { TopicDisplayMode } from '@lobechat/types';
|
|||
*/
|
||||
export const CURRENT_ONBOARDING_VERSION = 1;
|
||||
|
||||
const DEFAULT_TOPIC_DISPLAY_MODE = 'byUpdatedTime' as NonNullable<
|
||||
UserPreference['topicDisplayMode']
|
||||
>;
|
||||
|
||||
export const DEFAULT_PREFERENCE: UserPreference = {
|
||||
guide: {
|
||||
moveSettingsToAvatar: true,
|
||||
|
|
@ -17,6 +20,6 @@ export const DEFAULT_PREFERENCE: UserPreference = {
|
|||
enableAgentWorkingPanel: false,
|
||||
enableInputMarkdown: true,
|
||||
},
|
||||
topicDisplayMode: TopicDisplayMode.ByUpdatedTime,
|
||||
topicDisplayMode: DEFAULT_TOPIC_DISPLAY_MODE,
|
||||
useCmdEnterToSend: false,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"dependencies": {
|
||||
"@lobechat/const": "workspace:*",
|
||||
"@lobechat/python-interpreter": "workspace:*",
|
||||
"@lobechat/web-crawler": "workspace:*",
|
||||
"@lobehub/market-sdk": "0.32.2",
|
||||
|
|
|
|||
|
|
@ -1,131 +1,11 @@
|
|||
export const KeyEnum = {
|
||||
Alt: 'alt',
|
||||
Backquote: 'backquote',
|
||||
// `
|
||||
Backslash: 'backslash',
|
||||
// \
|
||||
Backspace: 'backspace',
|
||||
BracketLeft: 'bracketleft',
|
||||
// [
|
||||
BracketRight: 'bracketright',
|
||||
// ]
|
||||
Comma: 'comma',
|
||||
// ,
|
||||
Ctrl: 'ctrl',
|
||||
Down: 'down',
|
||||
Enter: 'enter',
|
||||
Equal: 'equal',
|
||||
// =
|
||||
Esc: 'esc',
|
||||
Left: 'left',
|
||||
LeftClick: 'left-click',
|
||||
LeftDoubleClick: 'left-double-click',
|
||||
Meta: 'meta',
|
||||
// Command on Mac, Win on Win
|
||||
MiddleClick: 'middle-click',
|
||||
Minus: 'minus',
|
||||
// -
|
||||
Mod: 'mod',
|
||||
import type { HotkeyId } from '@lobechat/const/hotkeys';
|
||||
|
||||
Number: '1-9',
|
||||
|
||||
// Command on Mac, Ctrl on Win
|
||||
Period: 'period',
|
||||
|
||||
// .
|
||||
Plus: 'equal',
|
||||
|
||||
// +
|
||||
QuestionMark: 'slash',
|
||||
|
||||
// ?
|
||||
Quote: 'quote',
|
||||
// '
|
||||
Right: 'right',
|
||||
RightClick: 'right-click',
|
||||
RightDoubleClick: 'right-double-click',
|
||||
|
||||
Semicolon: 'semicolon',
|
||||
// ;
|
||||
Shift: 'shift',
|
||||
|
||||
Slash: 'slash',
|
||||
// /
|
||||
Space: 'space',
|
||||
Tab: 'tab',
|
||||
Up: 'up',
|
||||
Zero: '0',
|
||||
} as const;
|
||||
|
||||
export const HotkeyEnum = {
|
||||
AddUserMessage: 'addUserMessage',
|
||||
ClearCurrentMessages: 'clearCurrentMessages',
|
||||
CommandPalette: 'commandPalette',
|
||||
DeleteAndRegenerateMessage: 'deleteAndRegenerateMessage',
|
||||
DeleteLastMessage: 'deleteLastMessage',
|
||||
EditMessage: 'editMessage',
|
||||
NavigateToChat: 'navigateToChat',
|
||||
OpenChatSettings: 'openChatSettings',
|
||||
OpenHotkeyHelper: 'openHotkeyHelper',
|
||||
RegenerateMessage: 'regenerateMessage',
|
||||
SaveDocument: 'saveDocument',
|
||||
SaveTopic: 'saveTopic',
|
||||
Search: 'search',
|
||||
ShowApp: 'showApp',
|
||||
SwitchAgent: 'switchAgent',
|
||||
ToggleLeftPanel: 'toggleLeftPanel',
|
||||
ToggleRightPanel: 'toggleRightPanel',
|
||||
ToggleZenMode: 'toggleZenMode',
|
||||
} as const;
|
||||
|
||||
export const HotkeyGroupEnum = {
|
||||
Conversation: 'conversation',
|
||||
Essential: 'essential',
|
||||
} as const;
|
||||
|
||||
export const HotkeyScopeEnum = {
|
||||
Chat: 'chat',
|
||||
Files: 'files',
|
||||
// Default globally registered hotkey scope
|
||||
// https://react-hotkeys-hook.vercel.app/docs/documentation/hotkeys-provider
|
||||
Global: 'global',
|
||||
|
||||
Image: 'image',
|
||||
} as const;
|
||||
|
||||
export type HotkeyId = (typeof HotkeyEnum)[keyof typeof HotkeyEnum];
|
||||
export type HotkeyGroupId = (typeof HotkeyGroupEnum)[keyof typeof HotkeyGroupEnum];
|
||||
export type HotkeyScopeId = (typeof HotkeyScopeEnum)[keyof typeof HotkeyScopeEnum];
|
||||
|
||||
export interface HotkeyItem {
|
||||
// Hotkey grouping for display purposes
|
||||
group: HotkeyGroupId;
|
||||
id: HotkeyId;
|
||||
keys: string;
|
||||
// Whether the hotkey is non-editable
|
||||
nonEditable?: boolean;
|
||||
// Hotkey scope
|
||||
scopes?: HotkeyScopeId[];
|
||||
}
|
||||
|
||||
// ================== Desktop ================== //
|
||||
|
||||
export const DesktopHotkeyEnum = {
|
||||
OpenSettings: 'openSettings',
|
||||
ShowApp: 'showApp',
|
||||
};
|
||||
|
||||
export type DesktopHotkeyId = (typeof DesktopHotkeyEnum)[keyof typeof DesktopHotkeyEnum];
|
||||
|
||||
export interface DesktopHotkeyItem {
|
||||
id: DesktopHotkeyId;
|
||||
|
||||
keys: string;
|
||||
// Whether the hotkey is non-editable
|
||||
nonEditable?: boolean;
|
||||
}
|
||||
|
||||
export type DesktopHotkeyConfig = Record<DesktopHotkeyId, string>;
|
||||
export type {
|
||||
DesktopHotkeyConfig,
|
||||
DesktopHotkeyId,
|
||||
DesktopHotkeyItem,
|
||||
} from '@lobechat/const/desktopGlobalShortcuts';
|
||||
export type { HotkeyGroupId, HotkeyId, HotkeyItem, HotkeyScopeId } from '@lobechat/const/hotkeys';
|
||||
|
||||
export type HotkeyI18nTranslations = Record<
|
||||
HotkeyId,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { Popconfirm } from 'antd';
|
||||
import { Eraser } from 'lucide-react';
|
||||
import { memo, useCallback, useState } from 'react';
|
||||
|
|
@ -8,7 +9,6 @@ import { useChatStore } from '@/store/chat';
|
|||
import { useFileStore } from '@/store/file';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
import Action from '../components/Action';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { ActionIcon, Flexbox, Hotkey } from '@lobehub/ui';
|
||||
import { Popconfirm } from 'antd';
|
||||
import { LucideGalleryVerticalEnd, LucideMessageSquarePlus } from 'lucide-react';
|
||||
|
|
@ -9,7 +10,6 @@ import { useActionSWR } from '@/libs/swr';
|
|||
import { useChatStore } from '@/store/chat';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
const SaveTopic = memo(() => {
|
||||
const { t } = useTranslation('chat');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { KeyEnum } from '@lobechat/types';
|
||||
import { combineKeys,Flexbox, Hotkey } from '@lobehub/ui';
|
||||
import { KeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { combineKeys, Flexbox, Hotkey } from '@lobehub/ui';
|
||||
import { memo } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { isDesktop } from '@lobechat/const';
|
||||
import { HotkeyEnum, KeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { chainInputCompletion } from '@lobechat/prompts';
|
||||
import { HotkeyEnum, KeyEnum } from '@lobechat/types';
|
||||
import { isCommandPressed, merge } from '@lobechat/utils';
|
||||
import { INSERT_MENTION_COMMAND, ReactAutoCompletePlugin, ReactMathPlugin } from '@lobehub/editor';
|
||||
import { Editor, FloatMenu, useEditorState } from '@lobehub/editor/react';
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { combineKeys,Flexbox, Hotkey, Text } from '@lobehub/ui';
|
||||
import { KeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { combineKeys, Flexbox, Hotkey, Text } from '@lobehub/ui';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { preferenceSelectors } from '@/store/user/selectors';
|
||||
import { KeyEnum } from '@/types/hotkey';
|
||||
|
||||
const ShortcutHint = memo(() => {
|
||||
const { t } = useTranslation('chat');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyGroupEnum } from '@lobechat/const/hotkeys';
|
||||
import { Grid, Icon, Modal, Segmented } from '@lobehub/ui';
|
||||
import { MessageSquare, Settings2 } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
|
|
@ -7,7 +8,6 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import { type HotkeyGroupId } from '@/types/hotkey';
|
||||
import { HotkeyGroupEnum } from '@/types/hotkey';
|
||||
|
||||
import HotkeyContent from './HotkeyContent';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { type ActionIconProps } from '@lobehub/ui';
|
||||
import { ActionIcon } from '@lobehub/ui';
|
||||
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
|
||||
|
|
@ -12,7 +13,6 @@ import { useGlobalStore } from '@/store/global';
|
|||
import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
export const TOGGLE_BUTTON_ID = 'toggle_left_panel_button';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { type ActionIconProps } from '@lobehub/ui';
|
||||
import { ActionIcon } from '@lobehub/ui';
|
||||
import { PanelRightClose, PanelRightOpen } from 'lucide-react';
|
||||
|
|
@ -12,7 +13,6 @@ import { useGlobalStore } from '@/store/global';
|
|||
import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
export const TOGGLE_BUTTON_ID = 'toggle_right_panel_button';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { Flexbox, Hotkey } from '@lobehub/ui';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
|
@ -7,7 +8,6 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
closeButton: css`
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { HotkeyEnum, HotkeyScopeEnum } from '@lobechat/const/hotkeys';
|
||||
import { useEffect } from 'react';
|
||||
import { useHotkeysContext } from 'react-hotkeys-hook';
|
||||
|
||||
|
|
@ -6,7 +7,6 @@ import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
|
|||
import { useActionSWR } from '@/libs/swr';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import { HotkeyEnum, HotkeyScopeEnum } from '@/types/hotkey';
|
||||
|
||||
import { useHotkeyById } from './useHotkeyById';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { HotkeyEnum, HotkeyScopeEnum } from '@lobechat/types';
|
||||
import { HotkeyEnum, HotkeyScopeEnum } from '@lobechat/const/hotkeys';
|
||||
import { useEffect } from 'react';
|
||||
import { useHotkeysContext } from 'react-hotkeys-hook';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { INBOX_SESSION_ID } from '@lobechat/const';
|
||||
import { HotkeyEnum } from '@lobechat/types';
|
||||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { useNavigateToAgent } from '@/hooks/useNavigateToAgent';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { HotkeyEnum, HotkeyScopeEnum } from '@lobechat/const/hotkeys';
|
||||
import { useEffect } from 'react';
|
||||
import { useHotkeysContext } from 'react-hotkeys-hook';
|
||||
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
import { HotkeyEnum, HotkeyScopeEnum } from '@/types/hotkey';
|
||||
|
||||
import { useHotkeyById } from './useHotkeyById';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { HotkeyEnum, HotkeyScopeEnum } from '@lobechat/const/hotkeys';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { uniq } from 'es-toolkit/compat';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { HOTKEYS_REGISTRATION } from '@/const/hotkeys';
|
||||
import { HotkeyEnum, HotkeyScopeEnum } from '@/types/hotkey';
|
||||
|
||||
import { useHotkeyById } from './useHotkeyById';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyScopeEnum } from '@lobechat/const/hotkeys';
|
||||
import { TITLE_BAR_HEIGHT } from '@lobechat/desktop-bridge';
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { cx } from 'antd-style';
|
||||
|
|
@ -24,7 +25,6 @@ import CmdkLazy from '@/layout/GlobalProvider/CmdkLazy';
|
|||
import dynamic from '@/libs/next/dynamic';
|
||||
import { DndContextWrapper } from '@/routes/(main)/resource/features/DndContextWrapper';
|
||||
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
|
||||
import { HotkeyScopeEnum } from '@/types/hotkey';
|
||||
|
||||
import DesktopHome from '../home';
|
||||
import DesktopHomeLayout from '../home/_layout';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum, KeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Flexbox, Hotkey, Icon } from '@lobehub/ui';
|
||||
import { BotMessageSquare, LucideCheck, MessageSquarePlus } from 'lucide-react';
|
||||
|
|
@ -10,7 +11,6 @@ import { useConversationStore, useConversationStoreApi } from '@/features/Conver
|
|||
import { useAddUserMessageHotkey } from '@/hooks/useHotkeys';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { preferenceSelectors, settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum, KeyEnum } from '@/types/hotkey';
|
||||
|
||||
/**
|
||||
* useSendMenuItems hook for ConversationStore
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum, KeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Flexbox, Hotkey, Icon } from '@lobehub/ui';
|
||||
import { BotMessageSquare, LucideCheck, MessageSquarePlus } from 'lucide-react';
|
||||
|
|
@ -9,7 +10,6 @@ import { Trans, useTranslation } from 'react-i18next';
|
|||
import { useConversationStore, useConversationStoreApi } from '@/features/Conversation';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { preferenceSelectors, settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum, KeyEnum } from '@/types/hotkey';
|
||||
|
||||
/**
|
||||
* useSendMenuItems hook for ConversationStore
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyGroupEnum } from '@lobechat/const/hotkeys';
|
||||
import { type FormGroupItemType } from '@lobehub/ui';
|
||||
import { Form, HotkeyInput, Icon, Skeleton } from '@lobehub/ui';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
|
|
@ -13,7 +14,6 @@ import hotkeyMeta from '@/locales/default/hotkey';
|
|||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { type HotkeyItem } from '@/types/hotkey';
|
||||
import { HotkeyGroupEnum } from '@/types/hotkey';
|
||||
|
||||
const HotkeySetting = memo(() => {
|
||||
const { t } = useTranslation(['setting', 'hotkey']);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Loader2Icon } from 'lucide-react';
|
|||
import { memo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { DESKTOP_HOTKEYS_REGISTRATION } from '@/const/hotkeys';
|
||||
import { DESKTOP_HOTKEYS_REGISTRATION } from '@/const/desktopGlobalShortcuts';
|
||||
import { FORM_STYLE } from '@/const/layoutTokens';
|
||||
import hotkeyMeta from '@/locales/default/hotkey';
|
||||
import { useElectronStore } from '@/store/electron';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyGroupEnum } from '@lobechat/const/hotkeys';
|
||||
import { type FormGroupItemType } from '@lobehub/ui';
|
||||
import { Form, HotkeyInput, Icon, Skeleton } from '@lobehub/ui';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
|
|
@ -13,7 +14,6 @@ import hotkeyMeta from '@/locales/default/hotkey';
|
|||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { type HotkeyItem } from '@/types/hotkey';
|
||||
import { HotkeyGroupEnum } from '@/types/hotkey';
|
||||
|
||||
const HotkeySetting = memo(() => {
|
||||
const { t } = useTranslation(['setting', 'hotkey']);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { SearchBar } from '@lobehub/ui';
|
||||
import { type ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
|
|
@ -8,7 +9,6 @@ import { useTranslation } from 'react-i18next';
|
|||
import { useSessionStore } from '@/store/session';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
const SessionSearchBar = memo<{ mobile?: boolean }>(({ mobile }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { HotkeyEnum } from '@lobechat/const/hotkeys';
|
||||
import { ActionIcon } from '@lobehub/ui';
|
||||
import { AlignJustify } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
|
|
@ -11,7 +12,6 @@ import dynamic from '@/libs/next/dynamic';
|
|||
import { useSessionStore } from '@/store/session';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { settingsSelectors } from '@/store/user/selectors';
|
||||
import { HotkeyEnum } from '@/types/hotkey';
|
||||
|
||||
const AgentSettingsEditor = dynamic(() => import('@/routes/(main)/agent/profile'), {
|
||||
ssr: false,
|
||||
|
|
|
|||
Loading…
Reference in a new issue