feat(channels): implement channel connection flows with multi-platform support

- Add comprehensive Channels page with connection statistics and status display
- Implement AddChannelDialog with type-specific connection flows:
  - QR code-based connection for WhatsApp/WeChat
  - Token-based connection for Telegram/Discord/Slack
- Enhance channels store with addChannel, deleteChannel, and requestQrCode actions
- Update electron-store usage to dynamic imports for ESM compatibility
- Add channel connection instructions and documentation links
This commit is contained in:
Haze
2026-02-05 23:29:18 +08:00
Unverified
parent ebb6f515a7
commit 98a2d9bc83
5 changed files with 619 additions and 100 deletions

View File

@@ -3,7 +3,6 @@
* Handles window state persistence and multi-window management
*/
import { BrowserWindow, screen } from 'electron';
import Store from 'electron-store';
interface WindowState {
x?: number;
@@ -13,21 +12,31 @@ interface WindowState {
isMaximized: boolean;
}
const store = new Store<{ windowState: WindowState }>({
name: 'window-state',
defaults: {
windowState: {
width: 1280,
height: 800,
isMaximized: false,
},
},
});
// Lazy-load electron-store (ESM module)
let windowStateStore: any = null;
async function getStore() {
if (!windowStateStore) {
const Store = (await import('electron-store')).default;
windowStateStore = new Store<{ windowState: WindowState }>({
name: 'window-state',
defaults: {
windowState: {
width: 1280,
height: 800,
isMaximized: false,
},
},
});
}
return windowStateStore;
}
/**
* Get saved window state with bounds validation
*/
export function getWindowState(): WindowState {
export async function getWindowState(): Promise<WindowState> {
const store = await getStore();
const state = store.get('windowState');
// Validate that the window is visible on a screen
@@ -56,7 +65,8 @@ export function getWindowState(): WindowState {
/**
* Save window state
*/
export function saveWindowState(win: BrowserWindow): void {
export async function saveWindowState(win: BrowserWindow): Promise<void> {
const store = await getStore();
const isMaximized = win.isMaximized();
if (!isMaximized) {

View File

@@ -2,7 +2,9 @@
* Persistent Storage
* Electron-store wrapper for application settings
*/
import Store from 'electron-store';
// Lazy-load electron-store (ESM module)
let settingsStoreInstance: any = null;
/**
* Application settings schema
@@ -65,58 +67,70 @@ const defaults: AppSettings = {
};
/**
* Create settings store
* Get the settings store instance (lazy initialization)
*/
export const settingsStore = new Store<AppSettings>({
name: 'settings',
defaults,
});
async function getSettingsStore() {
if (!settingsStoreInstance) {
const Store = (await import('electron-store')).default;
settingsStoreInstance = new Store<AppSettings>({
name: 'settings',
defaults,
});
}
return settingsStoreInstance;
}
/**
* Get a setting value
*/
export function getSetting<K extends keyof AppSettings>(key: K): AppSettings[K] {
return settingsStore.get(key);
export async function getSetting<K extends keyof AppSettings>(key: K): Promise<AppSettings[K]> {
const store = await getSettingsStore();
return store.get(key);
}
/**
* Set a setting value
*/
export function setSetting<K extends keyof AppSettings>(
export async function setSetting<K extends keyof AppSettings>(
key: K,
value: AppSettings[K]
): void {
settingsStore.set(key, value);
): Promise<void> {
const store = await getSettingsStore();
store.set(key, value);
}
/**
* Get all settings
*/
export function getAllSettings(): AppSettings {
return settingsStore.store;
export async function getAllSettings(): Promise<AppSettings> {
const store = await getSettingsStore();
return store.store;
}
/**
* Reset settings to defaults
*/
export function resetSettings(): void {
settingsStore.clear();
export async function resetSettings(): Promise<void> {
const store = await getSettingsStore();
store.clear();
}
/**
* Export settings to JSON
*/
export function exportSettings(): string {
return JSON.stringify(settingsStore.store, null, 2);
export async function exportSettings(): Promise<string> {
const store = await getSettingsStore();
return JSON.stringify(store.store, null, 2);
}
/**
* Import settings from JSON
*/
export function importSettings(json: string): void {
export async function importSettings(json: string): Promise<void> {
try {
const settings = JSON.parse(json);
settingsStore.set(settings);
const store = await getSettingsStore();
store.set(settings);
} catch (error) {
throw new Error('Invalid settings JSON');
}