feat: macOS architecture, cloud ASR/LLM providers, and 6-step iOS onboarding
- Add macOS menu-bar dictation app with local ASR models (SenseVoice/Qwen3),
global Option hotkey, and bottom overlay
- Add cloud ASR/LLM providers (Anthropic, Volcengine, Bailian, and more) with
provider logos, model listing, and connection checks
- Add shared 7-day usage stats UI (UsageStatsCluster / SevenDayUsageChart)
- Add iOS onboarding step 6 for polish LLM setup; hide custom-language-model
diagnostic toggle behind DEBUG
- Unify iOS onboarding tagline with the macOS brand line ("开口即文字。")
- Rewrite README (Chinese-first, product-oriented) and refresh GitHub Pages
This commit is contained in:
@@ -27,6 +27,7 @@ public struct SyncedAppSettingsV2: Codable, Equatable, Sendable {
|
||||
public var handednessPreference: SyncedField<HandednessPreference>
|
||||
public var cursorDragNavigationEnabled: SyncedField<Bool>
|
||||
public var polishIntensity: SyncedField<PolishIntensity>
|
||||
public var llmThinkingEnabled: SyncedField<Bool>
|
||||
public var flowSkipAppSwitch: SyncedField<Bool>
|
||||
public var flowInactivityDuration: SyncedField<FlowInactivityDuration>
|
||||
|
||||
@@ -47,6 +48,7 @@ public struct SyncedAppSettingsV2: Codable, Equatable, Sendable {
|
||||
handednessPreference: SyncedField<HandednessPreference>,
|
||||
cursorDragNavigationEnabled: SyncedField<Bool>,
|
||||
polishIntensity: SyncedField<PolishIntensity>,
|
||||
llmThinkingEnabled: SyncedField<Bool>,
|
||||
flowSkipAppSwitch: SyncedField<Bool>,
|
||||
flowInactivityDuration: SyncedField<FlowInactivityDuration>
|
||||
) {
|
||||
@@ -66,6 +68,7 @@ public struct SyncedAppSettingsV2: Codable, Equatable, Sendable {
|
||||
self.handednessPreference = handednessPreference
|
||||
self.cursorDragNavigationEnabled = cursorDragNavigationEnabled
|
||||
self.polishIntensity = polishIntensity
|
||||
self.llmThinkingEnabled = llmThinkingEnabled
|
||||
self.flowSkipAppSwitch = flowSkipAppSwitch
|
||||
self.flowInactivityDuration = flowInactivityDuration
|
||||
}
|
||||
@@ -87,6 +90,7 @@ public struct SyncedAppSettingsV2: Codable, Equatable, Sendable {
|
||||
case handednessPreference
|
||||
case cursorDragNavigationEnabled
|
||||
case polishIntensity
|
||||
case llmThinkingEnabled
|
||||
case flowSkipAppSwitch
|
||||
case flowInactivityDuration
|
||||
}
|
||||
@@ -115,6 +119,10 @@ public struct SyncedAppSettingsV2: Codable, Equatable, Sendable {
|
||||
forKey: .cursorDragNavigationEnabled
|
||||
)
|
||||
polishIntensity = try container.decode(SyncedField<PolishIntensity>.self, forKey: .polishIntensity)
|
||||
llmThinkingEnabled = try container.decodeIfPresent(
|
||||
SyncedField<Bool>.self,
|
||||
forKey: .llmThinkingEnabled
|
||||
) ?? SyncedField(value: false, updatedAt: polishIntensity.updatedAt, deviceID: polishIntensity.deviceID)
|
||||
flowSkipAppSwitch = try container.decode(SyncedField<Bool>.self, forKey: .flowSkipAppSwitch)
|
||||
flowInactivityDuration = try container.decode(
|
||||
SyncedField<FlowInactivityDuration>.self,
|
||||
@@ -161,6 +169,7 @@ public struct SyncedAppSettingsV2: Codable, Equatable, Sendable {
|
||||
handednessPreference.updatedAt,
|
||||
cursorDragNavigationEnabled.updatedAt,
|
||||
polishIntensity.updatedAt,
|
||||
llmThinkingEnabled.updatedAt,
|
||||
flowSkipAppSwitch.updatedAt,
|
||||
flowInactivityDuration.updatedAt,
|
||||
].max() ?? .distantPast
|
||||
@@ -197,6 +206,7 @@ public extension SyncedAppSettingsV2 {
|
||||
handednessPreference: field(configuration.handednessPreference),
|
||||
cursorDragNavigationEnabled: field(configuration.cursorDragNavigationEnabled),
|
||||
polishIntensity: field(configuration.polishIntensity),
|
||||
llmThinkingEnabled: field(configuration.llmThinkingEnabled),
|
||||
flowSkipAppSwitch: field(configuration.flowSkipAppSwitch),
|
||||
flowInactivityDuration: field(configuration.flowInactivityDuration)
|
||||
)
|
||||
@@ -225,6 +235,7 @@ public extension SyncedAppSettingsV2 {
|
||||
handednessPreference: field(legacy.handednessPreference),
|
||||
cursorDragNavigationEnabled: field(legacy.cursorDragNavigationEnabled),
|
||||
polishIntensity: field(legacy.polishIntensity),
|
||||
llmThinkingEnabled: field(false),
|
||||
flowSkipAppSwitch: field(legacy.flowSkipAppSwitch),
|
||||
flowInactivityDuration: field(legacy.flowInactivityDuration)
|
||||
)
|
||||
@@ -256,6 +267,7 @@ public extension SyncedAppSettingsV2 {
|
||||
remote: remote.cursorDragNavigationEnabled
|
||||
),
|
||||
polishIntensity: .merge(local: local.polishIntensity, remote: remote.polishIntensity),
|
||||
llmThinkingEnabled: .merge(local: local.llmThinkingEnabled, remote: remote.llmThinkingEnabled),
|
||||
flowSkipAppSwitch: .merge(local: local.flowSkipAppSwitch, remote: remote.flowSkipAppSwitch),
|
||||
flowInactivityDuration: .merge(
|
||||
local: local.flowInactivityDuration,
|
||||
@@ -280,6 +292,7 @@ public extension SyncedAppSettingsV2 {
|
||||
configuration.handednessPreference = handednessPreference.value
|
||||
configuration.cursorDragNavigationEnabled = cursorDragNavigationEnabled.value
|
||||
configuration.polishIntensity = polishIntensity.value
|
||||
configuration.llmThinkingEnabled = llmThinkingEnabled.value
|
||||
configuration.flowSkipAppSwitch = flowSkipAppSwitch.value
|
||||
configuration.flowInactivityDuration = flowInactivityDuration.value
|
||||
}
|
||||
@@ -306,6 +319,7 @@ public extension SyncedAppSettingsV2 {
|
||||
patch(©.handednessPreference, value: configuration.handednessPreference)
|
||||
patch(©.cursorDragNavigationEnabled, value: configuration.cursorDragNavigationEnabled)
|
||||
patch(©.polishIntensity, value: configuration.polishIntensity)
|
||||
patch(©.llmThinkingEnabled, value: configuration.llmThinkingEnabled)
|
||||
patch(©.flowSkipAppSwitch, value: configuration.flowSkipAppSwitch)
|
||||
patch(©.flowInactivityDuration, value: configuration.flowInactivityDuration)
|
||||
return copy
|
||||
@@ -335,6 +349,7 @@ public extension SyncedAppSettingsV2 {
|
||||
touch(©.handednessPreference, value: configuration.handednessPreference)
|
||||
touch(©.cursorDragNavigationEnabled, value: configuration.cursorDragNavigationEnabled)
|
||||
touch(©.polishIntensity, value: configuration.polishIntensity)
|
||||
touch(©.llmThinkingEnabled, value: configuration.llmThinkingEnabled)
|
||||
touch(©.flowSkipAppSwitch, value: configuration.flowSkipAppSwitch)
|
||||
touch(©.flowInactivityDuration, value: configuration.flowInactivityDuration)
|
||||
return copy
|
||||
|
||||
Reference in New Issue
Block a user