Compare commits

...

3 Commits

Author SHA1 Message Date
GitHub Action
28232b340b fix(i18n): Auto update translations for PR #11095 2025-11-01 12:53:45 +00:00
suyao
17764e6295 test 2025-11-01 20:51:10 +08:00
SuYao
28bc89ac7c perf: optimize QR code generation and connection info for phone LAN export (#11086)
* Increase QR code margin for better scanning reliability

- Change QRCodeSVG marginSize from 2 to 4 pixels
- Maintains same QR code size (160px) and error correction level (Q)
- Improves readability and scanning success rate on mobile devices

* Optimize QR code generation and connection info for phone LAN export

- Increase QR code size to 180px and reduce error correction to 'L' for better mobile scanning
- Replace hardcoded logo path with AppLogo config and increase logo size to 60px
- Simplify connection info by removing candidates array and using only essential IP/port data

* Optimize QR code data structure for LAN connection

- Compress IP addresses to numeric format to reduce QR code complexity
- Use compact array format instead of verbose JSON object structure
- Remove debug logging to streamline connection flow

* feat: 更新 WebSocket 状态和候选者响应类型,优化连接信息处理

* Increase QR code size and error correction for better scanning

- Increase QR code size from 180px to 300px for improved readability
- Change error correction level from L (low) to H (high) for better reliability
- Reduce logo size from 60px to 40px to accommodate larger QR data
- Increase margin size from 1 to 2 for better border clearance

* 调整二维码大小和图标尺寸以优化扫描体验

* fix(i18n): Auto update translations for PR #11086

* fix(i18n): Auto update translations for PR #11086

* fix(i18n): Auto update translations for PR #11086

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-01 12:13:11 +08:00
11 changed files with 102 additions and 56 deletions

View File

@@ -31,3 +31,16 @@ export type WebviewKeyEvent = {
shift: boolean
alt: boolean
}
export interface WebSocketStatusResponse {
isRunning: boolean
port?: number
ip?: string
clientConnected: boolean
}
export interface WebSocketCandidatesResponse {
host: string
interface: string
priority: number
}

View File

@@ -1,4 +1,5 @@
import { loggerService } from '@logger'
import { WebSocketCandidatesResponse, WebSocketStatusResponse } from '@shared/config/types'
import * as fs from 'fs'
import { networkInterfaces } from 'os'
import * as path from 'path'
@@ -202,12 +203,7 @@ class WebSocketService {
}
}
public getStatus = async (): Promise<{
isRunning: boolean
port?: number
ip?: string
clientConnected: boolean
}> => {
public getStatus = async (): Promise<WebSocketStatusResponse> => {
return {
isRunning: this.isStarted,
port: this.isStarted ? this.port : undefined,
@@ -216,13 +212,7 @@ class WebSocketService {
}
}
public getAllCandidates = async (): Promise<
Array<{
host: string
interface: string
priority: number
}>
> => {
public getAllCandidates = async (): Promise<WebSocketCandidatesResponse[]> => {
const interfaces = networkInterfaces()
// 按优先级排序的网络接口名称模式

View File

@@ -467,6 +467,8 @@ export default class ModernAiProvider {
}
}
// test comment
// 直接使用传统实现
return this.legacyProvider.generateImage(params)
}

View File

@@ -3,7 +3,9 @@ import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader } from '@herou
import { Progress } from '@heroui/progress'
import { Spinner } from '@heroui/spinner'
import { loggerService } from '@logger'
import { AppLogo } from '@renderer/config/env'
import { SettingHelpText, SettingRow } from '@renderer/pages/settings'
import { WebSocketCandidatesResponse } from '@shared/config/types'
import { QRCodeSVG } from 'qrcode.react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
@@ -38,12 +40,12 @@ const ScanQRCode: React.FC<{ qrCodeValue: string }> = ({ qrCodeValue }) => {
<QRCodeSVG
marginSize={2}
value={qrCodeValue}
level="Q"
size={160}
level="H"
size={200}
imageSettings={{
src: '/src/assets/images/logo.png',
width: 40,
height: 40,
src: AppLogo,
width: 60,
height: 60,
excavate: true
}}
/>
@@ -198,17 +200,28 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
const { port, ip } = await window.api.webSocket.status()
if (ip && port) {
const candidates = await window.api.webSocket.getAllCandidates()
const connectionInfo = {
type: 'cherry-studio-app',
candidates,
selectedHost: ip,
port,
timestamp: Date.now()
const candidatesData = await window.api.webSocket.getAllCandidates()
const optimizeConnectionInfo = () => {
const ipToNumber = (ip: string) => {
return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet), 0)
}
const compressedData = [
'CSA',
ipToNumber(ip),
candidatesData.map((candidate: WebSocketCandidatesResponse) => ipToNumber(candidate.host)),
port, // 端口号
Date.now() % 86400000
]
return compressedData
}
setQrCodeValue(JSON.stringify(connectionInfo))
const compressedData = optimizeConnectionInfo()
const qrCodeValue = JSON.stringify(compressedData)
setQrCodeValue(qrCodeValue)
setConnectionPhase('waiting_qr_scan')
logger.info(`QR code generated: ${ip}:${port} with ${candidates.length} IP candidates`)
} else {
setError(t('settings.data.export_to_phone.lan.error.no_ip'))
setConnectionPhase('error')

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Komplexe Aufgaben mit verschiedenen Tools bewältigen",
"error": {
"failed": "Agent hinzufügen fehlgeschlagen",
"invalid_agent": "Ungültiger Agent"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Tägliche Gespräche und schnelle Fragen & Antworten",
"title": "Assistent hinzufügen"
},
"option": {
"title": "Typ auswählen"
},
"topic": {
"title": "Neues Thema erstellen"
}
@@ -2923,15 +2928,14 @@
},
"description": "Ein KI-Assistent für Kreative",
"downloading": "Update wird heruntergeladen...",
"enterprise": {
"title": "Unternehmen"
},
"feedback": {
"button": "Feedback",
"title": "Feedback"
},
"label": "Über uns",
"license": {
"button": "Anzeigen",
"title": "Lizenz"
},
"releases": {
"button": "Anzeigen",
"title": "Changelog"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Χειριστείτε πολύπλοκα καθήκοντα με διάφορα εργαλεία",
"error": {
"failed": "Αποτυχία προσθήκης πράκτορα",
"invalid_agent": "Μη έγκυρος Agent"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Καθημερινές συζητήσεις και γρήγορες ερωταπαντήσεις",
"title": "Προσθήκη βοηθού"
},
"option": {
"title": "Επιλέξτε Τύπο"
},
"topic": {
"title": "Δημιουργία νέου θέματος"
}
@@ -2923,15 +2928,14 @@
},
"description": "Ένα AI ασιστάντα που έχει σχεδιαστεί για δημιουργούς",
"downloading": "Λήψη ενημερώσεων...",
"enterprise": {
"title": "Επιχείρηση"
},
"feedback": {
"button": "Σχόλια και Παρατηρήσεις",
"title": "Αποστολή σχολίων"
},
"label": "Περί μας",
"license": {
"button": "Προβολή",
"title": "Licenses"
},
"releases": {
"button": "Προβολή",
"title": "Ημερολόγιο Ενημερώσεων"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Manejar tareas complejas con varias herramientas",
"error": {
"failed": "Error al añadir agente",
"invalid_agent": "Agent inválido"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversaciones diarias y preguntas y respuestas rápidas",
"title": "Agregar asistente"
},
"option": {
"title": "Seleccionar Tipo"
},
"topic": {
"title": "Crear nuevo tema"
}
@@ -2923,15 +2928,14 @@
},
"description": "Una asistente de IA creada para los creadores",
"downloading": "Descargando actualización...",
"enterprise": {
"title": "Empresa"
},
"feedback": {
"button": "Enviar feedback",
"title": "Enviar comentarios"
},
"label": "Acerca de nosotros",
"license": {
"button": "Ver",
"title": "Licencia"
},
"releases": {
"button": "Ver",
"title": "Registro de cambios"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Gérez des tâches complexes avec divers outils",
"error": {
"failed": "Échec de l'ajout de l'agent",
"invalid_agent": "Agent invalide"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversations quotidiennes et Q&R rapides",
"title": "Ajouter un assistant"
},
"option": {
"title": "Sélectionner le type"
},
"topic": {
"title": "Nouveau sujet"
}
@@ -2923,15 +2928,14 @@
},
"description": "Un assistant IA conçu pour les créateurs",
"downloading": "Téléchargement de la mise à jour en cours...",
"enterprise": {
"title": "Entreprise"
},
"feedback": {
"button": "Faire un retour",
"title": "Retour d'information"
},
"label": "À propos de nous",
"license": {
"button": "Afficher",
"title": "Licence"
},
"releases": {
"button": "Afficher",
"title": "Journal des mises à jour"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "さまざまなツールを使って複雑なタスクを処理する",
"error": {
"failed": "エージェントの追加に失敗しました",
"invalid_agent": "無効なエージェント"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "日常会話と簡単な質問応答",
"title": "アシスタントを追加"
},
"option": {
"title": "種類を選択"
},
"topic": {
"title": "新しいトピック"
}
@@ -2923,15 +2928,14 @@
},
"description": "クリエイターのための強力なAIアシスタント",
"downloading": "ダウンロード中...",
"enterprise": {
"title": "エンタープライズ"
},
"feedback": {
"button": "フィードバック",
"title": "フィードバック"
},
"label": "について",
"license": {
"button": "ライセンス",
"title": "ライセンス"
},
"releases": {
"button": "リリース",
"title": "リリースノート"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Lide com tarefas complexas usando várias ferramentas",
"error": {
"failed": "Falha ao adicionar agente",
"invalid_agent": "Agent inválido"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversas diárias e perguntas e respostas rápidas",
"title": "Adicionar assistente"
},
"option": {
"title": "Selecionar Tipo"
},
"topic": {
"title": "Novo Tópico"
}
@@ -2923,15 +2928,14 @@
},
"description": "Um assistente de IA criado para criadores",
"downloading": "Baixando atualizações...",
"enterprise": {
"title": "Empresa"
},
"feedback": {
"button": "Feedback",
"title": "Enviar feedback"
},
"label": "Sobre Nós",
"license": {
"button": "Ver",
"title": "Licença"
},
"releases": {
"button": "Ver",
"title": "Registro de alterações"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Справляйтесь со сложными задачами с помощью различных инструментов",
"error": {
"failed": "Не удалось добавить агента",
"invalid_agent": "Недействительный агент"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Ежедневные разговоры и быстрые вопросы и ответы",
"title": "Добавить ассистента"
},
"option": {
"title": "Выберите тип"
},
"topic": {
"title": "Новый топик"
}
@@ -2923,15 +2928,14 @@
},
"description": "Мощный AI-ассистент для созидания",
"downloading": "Загрузка...",
"enterprise": {
"title": "Предприятие"
},
"feedback": {
"button": "Обратная связь",
"title": "Обратная связь"
},
"label": "О программе и обратная связь",
"license": {
"button": "Лицензия",
"title": "Лицензия"
},
"releases": {
"button": "Релизы",
"title": "Заметки о релизах"
@@ -3043,7 +3047,7 @@
"confirm": {
"button": "Выберите файл резервной копии"
},
"content": "Экспорт части данных, включая чат и настройки. Пожалуйста, обратите внимание, что процесс резервного копирования может занять некоторое время. Благодарим за ваше терпение.",
"content": "Экспорт части данных, включая историю чатов и настройки. Обратите внимание, процесс резервного копирования может занять некоторое время, благодарим за ваше терпение.",
"lan": {
"auto_close_tip": "Автоматическое закрытие через {{seconds}} секунд...",
"confirm_close_message": "Передача файла в процессе. Закрытие прервет передачу. Вы уверены, что хотите принудительно закрыть?",