diff --git a/src/OpenClaw.Tray.WinUI/Controls/SchemaConfigEditor.xaml.cs b/src/OpenClaw.Tray.WinUI/Controls/SchemaConfigEditor.xaml.cs index 1099b8f6..e72583e5 100644 --- a/src/OpenClaw.Tray.WinUI/Controls/SchemaConfigEditor.xaml.cs +++ b/src/OpenClaw.Tray.WinUI/Controls/SchemaConfigEditor.xaml.cs @@ -3,6 +3,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; +using OpenClawTray.Helpers; using OpenClawTray.Services; using System; using System.Collections.Generic; @@ -413,7 +414,7 @@ private UIElement RenderArrayField(string path, string label, string? descriptio Children = { new FontIcon { Glyph = "\uE710", FontSize = 12 }, - new TextBlock { Text = "Add item" } + new TextBlock { Text = LocalizationHelper.GetString("SchemaConfigEditor_AddItem") } } }, Margin = new Thickness(0, 4, 0, 0) diff --git a/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml b/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml index 30062e5c..c5e82ef2 100644 --- a/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml +++ b/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml @@ -21,7 +21,7 @@ Background="#20FF4444"> - @@ -52,7 +52,7 @@ - + diff --git a/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml.cs b/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml.cs index fb0d596a..8858c022 100644 --- a/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml.cs +++ b/src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml.cs @@ -4,6 +4,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using OpenClaw.Shared; +using OpenClawTray.Helpers; using OpenClawTray.Services; using OpenClawTray.Windows; @@ -44,7 +45,7 @@ public void PopulateAgentFilter(HubWindow hub) { AgentFilterCombo.SelectionChanged -= OnAgentFilterComboChanged; AgentFilterCombo.Items.Clear(); - AgentFilterCombo.Items.Add(new ComboBoxItem { Content = "All Agents", Tag = "" }); + AgentFilterCombo.Items.Add(new ComboBoxItem { Content = LocalizationHelper.GetString("AgentEventsPage_AllAgents"), Tag = "" }); foreach (var id in hub.GetAgentIds()) AgentFilterCombo.Items.Add(new ComboBoxItem { Content = id, Tag = id }); AgentFilterCombo.SelectedIndex = 0; @@ -178,7 +179,7 @@ private void ApplyFilter() EventsList.Visibility = list.Count > 0 ? Visibility.Visible : Visibility.Collapsed; EmptyState.Visibility = list.Count > 0 ? Visibility.Collapsed : Visibility.Visible; CountText.Text = $"({_allEvents.Count})"; - StatusText.Text = $"{list.Count} of {_allEvents.Count} events"; + StatusText.Text = string.Format(LocalizationHelper.GetString("AgentEventsPage_EventsStatus"), list.Count, _allEvents.Count); } private void OnClear(object sender, RoutedEventArgs e) diff --git a/src/OpenClaw.Tray.WinUI/Pages/ChannelsPage.xaml.cs b/src/OpenClaw.Tray.WinUI/Pages/ChannelsPage.xaml.cs index fc8e1854..74f6f857 100644 --- a/src/OpenClaw.Tray.WinUI/Pages/ChannelsPage.xaml.cs +++ b/src/OpenClaw.Tray.WinUI/Pages/ChannelsPage.xaml.cs @@ -779,7 +779,7 @@ private FrameworkElement BuildBody(ChannelRecord record) var unavailableGuide = BuildSetupGuide(record); if (unavailableGuide != null) stack.Children.Add(unavailableGuide); else stack.Children.Add(BuildInfoText( - "This channel requires a macOS host. It can't be configured from a Windows machine.")); + LocalizationHelper.GetString("ChannelsPage_UnavailableOnWindows"))); return stack; } @@ -819,7 +819,7 @@ private FrameworkElement BuildBody(ChannelRecord record) // channels it reads "Configuration" because that's where the // channel becomes configured in the first place. var inlineForm = BuildInlineConfigForm(record); - var configSectionTitle = record.IsConfigured ? "Replace credentials" : "Configuration"; + var configSectionTitle = record.IsConfigured ? LocalizationHelper.GetString("ChannelsPage_ReplaceCredentials") : LocalizationHelper.GetString("ChannelsPage_Configuration"); stack.Children.Add(BuildSection(configSectionTitle, inlineForm)); // "Install plugin on your gateway" panel. Hidden entirely when the @@ -865,23 +865,23 @@ private FrameworkElement BuildBody(ChannelRecord record) string caption; if (isQr && hasLogout) { - caption = "Unlink this device from the channel. Scan a fresh QR to reconnect — your account stays paired on your phone."; + caption = LocalizationHelper.GetString("ChannelsPage_CaptionQrLogout"); } else if (hasStop && hasLogout) { - caption = "Pause the channel temporarily — credentials are kept so you can start it again. Or disconnect entirely to clear them."; + caption = LocalizationHelper.GetString("ChannelsPage_CaptionStopLogout"); } else if (hasStart && hasLogout) { - caption = "Start the channel — it'll begin handling messages with the stored credentials. Or disconnect entirely to clear them."; + caption = LocalizationHelper.GetString("ChannelsPage_CaptionStartLogout"); } else if (hasStop) { - caption = "Pause the channel — credentials are kept so you can start it again."; + caption = LocalizationHelper.GetString("ChannelsPage_CaptionStopOnly"); } else if (hasStart) { - caption = "Start the channel — it'll begin handling messages with the stored credentials."; + caption = LocalizationHelper.GetString("ChannelsPage_CaptionStartOnly"); } else { @@ -902,12 +902,12 @@ private FrameworkElement BuildBody(ChannelRecord record) var buttonRow = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8 }; if (hasStart) - buttonRow.Children.Add(BuildHeaderActionButton(FluentIconCatalog.ChannelStart, "Start", record.Id, channelId => StartChannelAsync(channelId!))); + buttonRow.Children.Add(BuildHeaderActionButton(FluentIconCatalog.ChannelStart, LocalizationHelper.GetString("ChannelsPage_Start"), record.Id, channelId => StartChannelAsync(channelId!))); if (hasStop) { var stopBtn = new Button { - Content = "Stop", + Content = LocalizationHelper.GetString("ChannelsPage_Stop"), MinHeight = 32, Padding = new Thickness(12, 5, 12, 5), }; @@ -926,13 +926,13 @@ private FrameworkElement BuildBody(ChannelRecord record) // Non-QR channels: Logout = clear credentials (destructive — label says so). if (hasLogout && isQr) { - buttonRow.Children.Add(BuildHeaderActionButton(FluentIconCatalog.ChannelLogout, "Logout", record.Id, channelId => LogoutAsync(channelId!, isQr: true))); + buttonRow.Children.Add(BuildHeaderActionButton(FluentIconCatalog.ChannelLogout, LocalizationHelper.GetString("ChannelsPage_Logout"), record.Id, channelId => LogoutAsync(channelId!, isQr: true))); } else if (hasLogout && !isQr) { var disconnectBtn = new Button { - Content = "Disconnect and forget credentials", + Content = LocalizationHelper.GetString("ChannelsPage_DisconnectForget"), MinHeight = 32, Padding = new Thickness(12, 5, 12, 5), }; @@ -950,7 +950,7 @@ private FrameworkElement BuildBody(ChannelRecord record) } stack.Children.Add(buttonRow); - return BuildSection("Controls", stack); + return BuildSection(LocalizationHelper.GetString("ChannelsPage_Controls"), stack); } private static FrameworkElement BuildSection(string title, FrameworkElement content) @@ -1061,14 +1061,14 @@ private static FrameworkElement BuildSection(string title, FrameworkElement cont private static (string? Text, string? Url) ResolveExternalHelpLink(string channelId) => channelId.ToLowerInvariant() switch { - "whatsapp" => ("WhatsApp Linked devices help →", "https://faq.whatsapp.com/378279004439436/"), - "signal" => ("Signal Linked devices help →", "https://support.signal.org/hc/en-us/articles/360007320551"), - "telegram" => ("How to create a Telegram bot →", "https://core.telegram.org/bots/features#botfather"), - "discord" => ("How to create a Discord webhook →", "https://support.discord.com/hc/en-us/articles/228383668"), - "googlechat" => ("How to add a Google Chat webhook →", "https://developers.google.com/chat/how-tos/webhooks"), - "slack" => ("Slack app dashboard →", "https://api.slack.com/apps"), - "nostr" => ("About Nostr →", "https://nostr.com/"), - "imessage" => ("About macOS Messages →", "https://support.apple.com/guide/messages/welcome/mac"), + "whatsapp" => (LocalizationHelper.GetString("ChannelsPage_HelpWhatsApp"), "https://faq.whatsapp.com/378279004439436/"), + "signal" => (LocalizationHelper.GetString("ChannelsPage_HelpSignal"), "https://support.signal.org/hc/en-us/articles/360007320551"), + "telegram" => (LocalizationHelper.GetString("ChannelsPage_HelpTelegram"), "https://core.telegram.org/bots/features#botfather"), + "discord" => (LocalizationHelper.GetString("ChannelsPage_HelpDiscord"), "https://support.discord.com/hc/en-us/articles/228383668"), + "googlechat" => (LocalizationHelper.GetString("ChannelsPage_HelpGoogleChat"), "https://developers.google.com/chat/how-tos/webhooks"), + "slack" => (LocalizationHelper.GetString("ChannelsPage_HelpSlack"), "https://api.slack.com/apps"), + "nostr" => (LocalizationHelper.GetString("ChannelsPage_HelpNostr"), "https://nostr.com/"), + "imessage" => (LocalizationHelper.GetString("ChannelsPage_HelpIMessage"), "https://support.apple.com/guide/messages/welcome/mac"), _ => (null, null), }; @@ -1080,67 +1080,64 @@ private static (string? Text, string? Url) ResolveExternalHelpLink(string channe private static (string? Headline, string[]? Steps) ResolveSetupGuide(string channelId) => channelId.ToLowerInvariant() switch { - "whatsapp" => ("Link your WhatsApp phone", new[] + "whatsapp" => (LocalizationHelper.GetString("ChannelsPage_GuideWhatsAppHeadline"), new[] { - "Click \"Show QR\" in the Linking section below.", - "On your phone: WhatsApp → Settings → Linked devices → Link a device.", - "Scan the QR code that appears here.", + LocalizationHelper.GetString("ChannelsPage_GuideWhatsAppStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideWhatsAppStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideWhatsAppStep3"), }), - "signal" => ("Link your Signal phone", new[] + "signal" => (LocalizationHelper.GetString("ChannelsPage_GuideSignalHeadline"), new[] { - "Click \"Show QR\" in the Linking section below.", - "On your phone: Signal → Settings → Linked devices → Link new device.", - "Scan the QR code that appears here.", + LocalizationHelper.GetString("ChannelsPage_GuideSignalStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideSignalStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideSignalStep3"), }), - "telegram" => ("Connect Telegram via a bot", new[] + "telegram" => (LocalizationHelper.GetString("ChannelsPage_GuideTelegramHeadline"), new[] { - "Open Telegram and send a message to @BotFather.", - "Send /newbot and follow the prompts. Copy the bot token at the end.", - "Paste the token into the Configuration form below.", - "Click \"Save and start\". The channel will start automatically.", + LocalizationHelper.GetString("ChannelsPage_GuideTelegramStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideTelegramStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideTelegramStep3"), + LocalizationHelper.GetString("ChannelsPage_GuideTelegramStep4"), }), - "discord" => ("Connect Discord via a webhook", new[] + "discord" => (LocalizationHelper.GetString("ChannelsPage_GuideDiscordHeadline"), new[] { - "Open your Discord server settings → Integrations → Webhooks.", - "Click \"New Webhook\", give it a name, and copy the webhook URL.", - "Paste the URL into the Configuration form below.", - "Click \"Save and start\".", + LocalizationHelper.GetString("ChannelsPage_GuideDiscordStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideDiscordStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideDiscordStep3"), + LocalizationHelper.GetString("ChannelsPage_GuideDiscordStep4"), }), - "googlechat" => ("Connect Google Chat via a webhook", new[] + "googlechat" => (LocalizationHelper.GetString("ChannelsPage_GuideGoogleChatHeadline"), new[] { - "In Google Chat, open the space → Manage webhooks → Add webhook.", - "Copy the webhook URL.", - "Paste the URL into the Configuration form below.", - "Click \"Save and start\".", + LocalizationHelper.GetString("ChannelsPage_GuideGoogleChatStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideGoogleChatStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideGoogleChatStep3"), + LocalizationHelper.GetString("ChannelsPage_GuideGoogleChatStep4"), }), - "slack" => ("Connect Slack via an app", new[] + "slack" => (LocalizationHelper.GetString("ChannelsPage_GuideSlackHeadline"), new[] { - "Create a Slack app at api.slack.com/apps and install it to your workspace.", - "Copy the bot token (xoxb-…) and the signing secret.", - "Paste both into the Configuration form below.", - "Click \"Save and start\".", + LocalizationHelper.GetString("ChannelsPage_GuideSlackStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideSlackStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideSlackStep3"), + LocalizationHelper.GetString("ChannelsPage_GuideSlackStep4"), }), - "nostr" => ("Connect Nostr via relays", new[] + "nostr" => (LocalizationHelper.GetString("ChannelsPage_GuideNostrHeadline"), new[] { - "Generate or paste a private key (nsec).", - "Pick one or more relay URLs (e.g. wss://relay.damus.io).", - "Paste both into the Configuration form below.", - "Click \"Save and start\".", + LocalizationHelper.GetString("ChannelsPage_GuideNostrStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideNostrStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideNostrStep3"), + LocalizationHelper.GetString("ChannelsPage_GuideNostrStep4"), }), - "imessage" => ("iMessage is macOS-only", new[] + "imessage" => (LocalizationHelper.GetString("ChannelsPage_GuideIMessageHeadline"), new[] { - "iMessage reads the local Messages.app database, which only exists on macOS.", - "To use iMessage with OpenClaw, run the gateway on a Mac instead of this Windows host.", - "All other channels in this list work fine from a Windows-hosted gateway.", + LocalizationHelper.GetString("ChannelsPage_GuideIMessageStep1"), + LocalizationHelper.GetString("ChannelsPage_GuideIMessageStep2"), + LocalizationHelper.GetString("ChannelsPage_GuideIMessageStep3"), }), - // Generic fallback for plugin channels we don't have explicit - // guidance for. Better than leaving the section blank — at least - // the user knows it's a plugin and where to find its settings. - _ => ("Connect this channel", new[] + _ => (LocalizationHelper.GetString("ChannelsPage_GuideGenericHeadline"), new[] { - $"\"{channelId}\" is a plugin channel. Refer to its documentation for the fields it needs.", - $"Use \"Open Config page\" in the Configuration section below to add settings under channels.{channelId}.", - "Save the config; OpenClaw will start the channel automatically.", + string.Format(LocalizationHelper.GetString("ChannelsPage_GuideGenericStep1"), channelId), + string.Format(LocalizationHelper.GetString("ChannelsPage_GuideGenericStep2"), channelId), + LocalizationHelper.GetString("ChannelsPage_GuideGenericStep3"), }), }; @@ -1170,65 +1167,65 @@ private sealed record ConfigField( { new ConfigField( "channels.telegram.botToken", - "Bot token", + LocalizationHelper.GetString("ChannelsPage_FieldBotToken"), "123456:ABCdef...", Sensitive: true, Required: true, - HelpText: "Get from @BotFather (/newbot)."), + HelpText: LocalizationHelper.GetString("ChannelsPage_HelpBotToken")), }, "discord" => new[] { new ConfigField( "channels.discord.webhookUrl", - "Webhook URL", + LocalizationHelper.GetString("ChannelsPage_FieldWebhookUrl"), "https://discord.com/api/webhooks/...", Sensitive: true, Required: true, - HelpText: "Server Settings → Integrations → Webhooks → New Webhook."), + HelpText: LocalizationHelper.GetString("ChannelsPage_HelpWebhookDiscord")), }, "googlechat" => new[] { new ConfigField( "channels.googlechat.webhookUrl", - "Webhook URL", + LocalizationHelper.GetString("ChannelsPage_FieldWebhookUrl"), "https://chat.googleapis.com/v1/spaces/...", Sensitive: true, Required: true, - HelpText: "Open a space → Manage webhooks → Add webhook."), + HelpText: LocalizationHelper.GetString("ChannelsPage_HelpWebhookGoogleChat")), }, "slack" => new[] { new ConfigField( "channels.slack.botToken", - "Bot token", + LocalizationHelper.GetString("ChannelsPage_FieldBotToken"), "xoxb-...", Sensitive: true, Required: true, - HelpText: "OAuth tokens from your Slack app."), + HelpText: LocalizationHelper.GetString("ChannelsPage_HelpSlackBotToken")), new ConfigField( "channels.slack.signingSecret", - "Signing secret", + LocalizationHelper.GetString("ChannelsPage_FieldSigningSecret"), "", Sensitive: true, Required: true, - HelpText: "Basic Information → App Credentials."), + HelpText: LocalizationHelper.GetString("ChannelsPage_HelpSlackSigningSecret")), }, "nostr" => new[] { new ConfigField( "channels.nostr.nsec", - "Private key (nsec)", + LocalizationHelper.GetString("ChannelsPage_FieldPrivateKey"), "nsec1...", Sensitive: true, Required: true), new ConfigField( "channels.nostr.relays", - "Relay URLs", + LocalizationHelper.GetString("ChannelsPage_FieldRelayUrls"), "wss://relay.damus.io", Sensitive: false, Required: true, Multiline: true, - HelpText: "One per line."), + HelpText: LocalizationHelper.GetString("ChannelsPage_HelpRelayUrls")), }, _ => null, }; @@ -1339,12 +1336,12 @@ private FrameworkElement BuildInlineConfigForm(ChannelRecord record) var actionRow = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8, Margin = new Thickness(0, 4, 0, 0) }; var saveBtn = new Button { - Content = record.IsConfigured ? "Save changes" : "Save and start", + Content = record.IsConfigured ? LocalizationHelper.GetString("ChannelsPage_SaveChanges") : LocalizationHelper.GetString("ChannelsPage_SaveAndStart"), Style = (Style)Application.Current.Resources["AccentButtonStyle"], }; var openConfigBtn = new Button { - Content = "Open Config page", + Content = LocalizationHelper.GetString("ChannelsPage_OpenConfigPage"), }; openConfigBtn.Click += (_, _) => ((IAppCommands)CurrentApp).Navigate("config"); actionRow.Children.Add(saveBtn); @@ -1361,8 +1358,8 @@ async Task SaveAsync() var client = CurrentApp.GatewayClient; if (client == null) { - _pendingSaveBanner = (record.Id, "Not connected", - "Connect to a gateway before saving channel config.", + _pendingSaveBanner = (record.Id, LocalizationHelper.GetString("ChannelsPage_BannerNotConnectedTitle"), + LocalizationHelper.GetString("ChannelsPage_BannerNotConnectedMessage"), InfoBarSeverity.Error); ApplyPendingSaveBanner(); return; @@ -1381,8 +1378,8 @@ async Task SaveAsync() }; if (field.Required && string.IsNullOrWhiteSpace(raw)) { - _pendingSaveBanner = (record.Id, "Missing field", - $"{field.Label} is required.", + _pendingSaveBanner = (record.Id, LocalizationHelper.GetString("ChannelsPage_BannerMissingFieldTitle"), + string.Format(LocalizationHelper.GetString("ChannelsPage_BannerMissingFieldMessage"), field.Label), InfoBarSeverity.Error); ApplyPendingSaveBanner(); return; @@ -1397,8 +1394,8 @@ async Task SaveAsync() saveBtn.IsEnabled = false; try { - _pendingSaveBanner = (record.Id, $"Saving {record.Id}…", - $"Writing {values.Count} field(s) and enabling the channel.", + _pendingSaveBanner = (record.Id, string.Format(LocalizationHelper.GetString("ChannelsPage_BannerSavingTitle"), record.Id), + string.Format(LocalizationHelper.GetString("ChannelsPage_BannerSavingMessage"), values.Count), InfoBarSeverity.Informational); ApplyPendingSaveBanner(); @@ -1409,8 +1406,8 @@ async Task SaveAsync() // the gateway's actual response. if (!await EnsureConfigLoadedAsync()) { - _pendingSaveBanner = (record.Id, $"Couldn't load gateway config", - "The gateway didn't return its current config — can't safely save without it. Try Refresh and save again.", + _pendingSaveBanner = (record.Id, LocalizationHelper.GetString("ChannelsPage_BannerCantLoadConfigTitle"), + LocalizationHelper.GetString("ChannelsPage_BannerCantLoadConfigMessage"), InfoBarSeverity.Error); ApplyPendingSaveBanner(); return; @@ -1426,8 +1423,8 @@ async Task SaveAsync() // true when the snapshot is populated — but defend // against a race where the snapshot was reset between // the load returning and this read. - _pendingSaveBanner = (record.Id, $"Couldn't load gateway config", - "The gateway's config was cleared mid-save. Try Refresh and save again.", + _pendingSaveBanner = (record.Id, LocalizationHelper.GetString("ChannelsPage_BannerCantLoadConfigTitle"), + LocalizationHelper.GetString("ChannelsPage_BannerConfigClearedMessage"), InfoBarSeverity.Error); ApplyPendingSaveBanner(); return; @@ -1442,7 +1439,7 @@ async Task SaveAsync() if (buildResult.BlockedReason != null) { - _pendingSaveBanner = (record.Id, $"Save blocked for {record.Id}", + _pendingSaveBanner = (record.Id, string.Format(LocalizationHelper.GetString("ChannelsPage_BannerSaveBlockedTitle"), record.Id), buildResult.BlockedReason, InfoBarSeverity.Warning); ApplyPendingSaveBanner(); @@ -1453,30 +1450,29 @@ async Task SaveAsync() if (!patchResult.Ok) { - var detail = patchResult.Error ?? "The gateway didn't respond."; - var title = $"Save failed for {record.Id}"; + var detail = patchResult.Error ?? LocalizationHelper.GetString("ChannelsPage_BannerGatewayNoResponse"); + var title = string.Format(LocalizationHelper.GetString("ChannelsPage_BannerSaveFailedTitle"), record.Id); if (patchResult.LooksLikeStaleBaseHash) { // Config changed elsewhere. Refresh the cache so the // next retry uses a fresh baseHash. _ = client.RequestConfigAsync(); _pendingSaveBanner = (record.Id, title, - $"Your gateway config changed elsewhere (e.g., from the Config page). " + - $"We refreshed the cache — try Save again. Details: {detail}", + string.Format(LocalizationHelper.GetString("ChannelsPage_BannerStaleConfigMessage"), detail), InfoBarSeverity.Warning); } else { _pendingSaveBanner = (record.Id, title, - $"{detail} If this looks like a wire-format mismatch, open the Config page for direct JSON editing.", + string.Format(LocalizationHelper.GetString("ChannelsPage_BannerSaveFailedMessage"), detail), InfoBarSeverity.Error); } ApplyPendingSaveBanner(); return; } - _pendingSaveBanner = (record.Id, $"{record.Id} config saved", - "Waiting for the gateway to confirm the channel is running…", + _pendingSaveBanner = (record.Id, string.Format(LocalizationHelper.GetString("ChannelsPage_BannerConfigSavedTitle"), record.Id), + LocalizationHelper.GetString("ChannelsPage_BannerConfigSavedMessage"), InfoBarSeverity.Success); ApplyPendingSaveBanner(); // Invalidate the snapshot so a rapid second save MUST wait @@ -1933,15 +1929,15 @@ private FrameworkElement BuildConfigPlaceholder(ChannelRecord record) stack.Children.Add(new TextBlock { Text = record.IsConfigured - ? $"Edit this channel's settings in the gateway Config page." - : $"After following the steps above, save the config to start the channel.", + ? LocalizationHelper.GetString("ChannelsPage_ConfigPlaceholderConfigured") + : LocalizationHelper.GetString("ChannelsPage_ConfigPlaceholderUnconfigured"), Style = (Style)Application.Current.Resources["BodyTextBlockStyle"], Foreground = (Brush)Application.Current.Resources["TextFillColorSecondaryBrush"], TextWrapping = TextWrapping.Wrap, }); var btn = new Button { - Content = "Open Config page", + Content = LocalizationHelper.GetString("ChannelsPage_OpenConfigPage"), HorizontalAlignment = HorizontalAlignment.Left, }; btn.Click += (_, _) => diff --git a/src/OpenClaw.Tray.WinUI/Pages/ChatPage.xaml.cs b/src/OpenClaw.Tray.WinUI/Pages/ChatPage.xaml.cs index 37aaa0f5..b767839c 100644 --- a/src/OpenClaw.Tray.WinUI/Pages/ChatPage.xaml.cs +++ b/src/OpenClaw.Tray.WinUI/Pages/ChatPage.xaml.cs @@ -339,7 +339,7 @@ private void ShowMissingChatCredentialError() WebView.Visibility = Visibility.Collapsed; PlaceholderPanel.Visibility = Visibility.Collapsed; ErrorPanel.Visibility = Visibility.Visible; - ErrorText.Text = "Open Connection settings to finish pairing with a gateway."; + ErrorText.Text = LocalizationHelper.GetString("ChatPage_OpenConnectionSettings"); } private void StopWebViewNavigation() @@ -380,7 +380,7 @@ private async Task InitializeWebViewAsync(SettingsManager settings) { PlaceholderPanel.Visibility = Visibility.Collapsed; ErrorPanel.Visibility = Visibility.Visible; - ErrorText.Text = "Open Connection settings to finish pairing with a gateway."; + ErrorText.Text = LocalizationHelper.GetString("ChatPage_OpenConnectionSettings"); return; } @@ -388,7 +388,7 @@ private async Task InitializeWebViewAsync(SettingsManager settings) { PlaceholderPanel.Visibility = Visibility.Collapsed; ErrorPanel.Visibility = Visibility.Visible; - ErrorText.Text = "Gateway pairing is not complete. Open Connection settings to finish pairing."; + ErrorText.Text = LocalizationHelper.GetString("ChatPage_GatewayPairingIncomplete"); return; } @@ -406,7 +406,7 @@ private async Task InitializeWebViewAsync(SettingsManager settings) ErrorPanel.Visibility = Visibility.Collapsed; WebView.Visibility = Visibility.Collapsed; WaitingPanel.Visibility = Visibility.Visible; - WaitingStatusText.Text = "The gateway is connected; the chat surface is still coming online."; + WaitingStatusText.Text = LocalizationHelper.GetString("ChatPage_ChatSurfaceComingOnline"); RetryChatButton.Visibility = Visibility.Collapsed; LoadingRing.IsActive = true; LoadingRing.Visibility = Visibility.Visible; @@ -440,7 +440,7 @@ private async Task InitializeWebViewAsync(SettingsManager settings) { WebView.Visibility = Visibility.Collapsed; ErrorPanel.Visibility = Visibility.Visible; - ErrorText.Text = $"Cannot connect to gateway at {credential.GatewayUrl}\n\nMake sure the gateway is running."; + ErrorText.Text = string.Format(LocalizationHelper.GetString("ChatPage_CannotConnectToGateway"), credential.GatewayUrl); } }; WebView.CoreWebView2.NavigationCompleted += _navCompletedHandler; @@ -464,7 +464,7 @@ private async Task InitializeWebViewAsync(SettingsManager settings) PlaceholderPanel.Visibility = Visibility.Collapsed; WebView.Visibility = Visibility.Collapsed; ErrorPanel.Visibility = Visibility.Visible; - ErrorText.Text = $"WebView2 failed to initialize:\n{ex.Message}"; + ErrorText.Text = string.Format(LocalizationHelper.GetString("ChatPage_WebView2InitFailed"), ex.Message); } } @@ -481,7 +481,7 @@ private async Task NavigateWhenChatReadyAsync( var ready = await ChatNavigationReadiness.WaitForOperatorHandshakeAsync(connectionManager, TimeSpan.FromSeconds(30), cancellationToken); if (!ready) { - ShowChatReadinessFailure("Timed out waiting for the gateway operator handshake. Retry once the gateway is ready."); + ShowChatReadinessFailure(LocalizationHelper.GetString("ChatPage_TimedOutHandshake")); Logger.Warn("[ChatPage] Timed out waiting for operator handshake before chat navigation"); return; } @@ -490,12 +490,12 @@ private async Task NavigateWhenChatReadyAsync( ready = await ProbeChatSurfaceAsync(_chatUrl!, TimeSpan.FromSeconds(30), cancellationToken); if (!ready) { - ShowChatReadinessFailure($"Timed out waiting for chat at {gatewayUrl}. Retry once the gateway is ready."); + ShowChatReadinessFailure(string.Format(LocalizationHelper.GetString("ChatPage_TimedOutChat"), gatewayUrl)); Logger.Warn("[ChatPage] Timed out waiting for chat HTTP surface before navigation"); return; } - WaitingStatusText.Text = "Chat is ready; starting your first hatching conversation…"; + WaitingStatusText.Text = LocalizationHelper.GetString("ChatPage_ChatReady"); var bootstrapped = await OnboardingChatBootstrapper.BootstrapAsync( connectionManager?.OperatorClient, ((App)Application.Current).Settings, @@ -520,7 +520,7 @@ private async Task NavigateWhenChatReadyAsync( } catch (Exception ex) { - ShowChatReadinessFailure($"Chat failed to start:\n{ex.Message}"); + ShowChatReadinessFailure(string.Format(LocalizationHelper.GetString("ChatPage_ChatFailedToStart"), ex.Message)); Logger.Warn($"[ChatPage] Chat readiness wait failed: {ex.Message}"); } } @@ -608,7 +608,7 @@ private static bool TryBuildChatUrl(string gatewayUrl, string token, out string if (!GatewayUrlHelper.TryNormalizeWebSocketUrl(gatewayUrl, out var normalizedUrl) || !Uri.TryCreate(normalizedUrl, UriKind.Absolute, out var gatewayUri)) { - errorMessage = $"Invalid gateway URL: {gatewayUrl}"; + errorMessage = string.Format(LocalizationHelper.GetString("ChatPage_InvalidGatewayUrl"), gatewayUrl); return false; } @@ -793,7 +793,7 @@ private async Task PickAndAttachFileAsync() } var hwnd = WinRT.Interop.WindowNative.GetWindowHandle((Window)_hub!); - var path = await Win32FilePickerHelper.PickSingleFileAsync(hwnd, "Attach file"); + var path = await Win32FilePickerHelper.PickSingleFileAsync(hwnd, LocalizationHelper.GetString("ChatPage_AttachFile")); if (path is null) { @@ -822,9 +822,9 @@ private async Task ShowAttachmentErrorAsync(string message) { var dialog = new ContentDialog { - Title = "Cannot attach file", + Title = LocalizationHelper.GetString("ChatPage_CannotAttachFile"), Content = message, - CloseButtonText = "OK", + CloseButtonText = LocalizationHelper.GetString("ChatPage_OK"), DefaultButton = ContentDialogButton.Close, XamlRoot = this.XamlRoot }; diff --git a/src/OpenClaw.Tray.WinUI/Pages/ConnectionPage.xaml b/src/OpenClaw.Tray.WinUI/Pages/ConnectionPage.xaml index 8addc3de..b8579a1f 100644 --- a/src/OpenClaw.Tray.WinUI/Pages/ConnectionPage.xaml +++ b/src/OpenClaw.Tray.WinUI/Pages/ConnectionPage.xaml @@ -165,7 +165,8 @@ Visibility="Collapsed" Click="OnStripPrimaryClicked" AutomationProperties.AutomationId="StripPrimaryAction"/> - - - - - - @@ -64,13 +64,13 @@ - - @@ -216,7 +216,7 @@ Width="140"> - + diff --git a/src/OpenClaw.Tray.WinUI/Strings/en-us/Resources.resw b/src/OpenClaw.Tray.WinUI/Strings/en-us/Resources.resw index 8f22d472..7740514b 100644 --- a/src/OpenClaw.Tray.WinUI/Strings/en-us/Resources.resw +++ b/src/OpenClaw.Tray.WinUI/Strings/en-us/Resources.resw @@ -3954,13 +3954,13 @@ On your gateway host (Mac/Linux), run: SCHEDULE - + Every - + At - + Cron @@ -4625,4 +4625,906 @@ On your gateway host (Mac/Linux), run: Advanced - + + + Live + + + Clear + + + Conversations this gateway is currently handling, grouped by channel. + + + Sessions appear here when a channel is connected and traffic is flowing. + + + Open chat + + + Enabled + + + Disabled + + + Preview + + + Preview Voice + + + Disconnected + + + Commands the agent runs directly on the gateway aren't. If the gateway is on this PC they may still be able to reach your Windows files, clipboard, and network — check your gateway's configuration. + + All Agents + + + {0} of {1} events + + + Create Job + + + Edit Job + + + New Job + + + Running... + + + Save Changes + + + Add item + + + Attach file + + + Cancel + + + Cannot attach file + + + Cannot connect to gateway at {0} + +Make sure the gateway is running. + + + Chat failed to start: +{0} + + + Chat is ready; starting your first hatching conversation… + + + The gateway is connected; the chat surface is still coming online. + + + Gateway pairing is not complete. Open Connection settings to finish pairing. + + + Invalid gateway URL: {0} + + + OK + + + Open Connection settings to finish pairing with a gateway. + + + Open Voice Settings + + + Timed out waiting for chat at {0}. Retry once the gateway is ready. + + + Timed out waiting for the gateway operator handshake. Retry once the gateway is ready. + + + The speech-to-text model needs to be installed before you can use voice input. Would you like to open Voice settings to install it? + + + Voice Model Required + + + WebView2 failed to initialize: +{0} + + + Applying… + + + Awaiting approval + + + 🔐 Awaiting approval — approve then click Connect + + + 🔐 Awaiting approval from gateway + + + Connect + + + ✓ Connected + + + ✓ Connected to {0} + + + Connecting… + + + Connect (once approved) + + + disabled + + + Disconnected + + + Enter a gateway URL + + + No gateways + + + Reconnecting… + + + rejected + + + Starting SSH tunnel… + + + on {0} + + + 1 client + + + {0} clients + + + {0}/{1} channel + + + {0}/{1} channels + + + ${0} today + + + $0.00 today + + + Shared token + + + Tap to copy shared token + + + via SSH tunnel + + + Local + + + Tailscale + + + LAN + + + Remote + + + Active · {0} sessions + + + Active · 1 session + + + Active · no current sessions + + + Disconnected + + + Connecting… + + + Reconnecting… + + + Node active · {0} capabilities + + + Node active · 1 capability + + + Node active · no capabilities enabled + + + Awaiting pairing approval + + + Pairing rejected + + + Rate-limited + + + Node error + + + Node mode disabled + + + No capabilities enabled. Pick what to share in Permissions. + + + Awaiting approval on the gateway host. + + + Pairing was rejected. Re-pair from Add Gateway. + + + Rate-limited by the gateway. Will retry after cooldown. + + + Node reported an error. + + + Providing no capabilities + + + Providing 1 capability: {0} + + + Providing {0} capabilities: {1} + + + Connected + + + Connecting… + + + Awaiting approval + + + Disconnecting… + + + Connect + + + Open dashboard + + + Disconnect + + + Edit + + + Remove + + + via SSH + + + Saved gateways (1) + + + Saved gateways ({0}) + + + just now + + + {0}m ago + + + {0}h ago + + + {0}d ago + + + {0}mo ago + + + {0}y ago + + + Re-pair this gateway: + + + Awaiting approval: + + + Help us fix the SSH tunnel: + + + Help us fix this connection: + + + Get a fresh setup code from the gateway host. + + + Or paste a new direct token below. + + + Approve this client on the gateway host using the command below. + + + Once approved, click Connect to resume. + + + Confirm SSH is reachable on the host. + + + Restart the tunnel below if it stopped. + + + Check the gateway logs on the host. + + + If the gateway is partially up, open its dashboard. + + + Edit gateway settings to change URL or token. + + + Check that the gateway is running on the host. + + + Check that you're on the same network or VPN. + + + If using SSH tunnel: confirm it's up. + + + SSH tunnel is down. + + + Testing connection… + + + Gateway reachable + + + Gateway responded with {0} + + + Cannot reach gateway + + + Enter a gateway URL + + + Connecting… + + + Starting SSH tunnel… + + + Pairing approval required for {0}. + + + Connected to {0}. + + + SSH remote port must be 1–65535 + + + SSH local port must be 1–65535 + + + Tunnel restart triggered. + + + Tunnel restart failed: {0} + + + Re-paired. Reconnecting… + + + Could not apply code. + + + Please paste a setup code. + + + Applying… + + + Applied — gateway: {0} + + + Invalid setup code + + + Invalid URL + + + Connection failed + + + Unknown error + + + Gateway: {0} + + + (not specified) + + + (no token) + + + Token: {0} + + + Press Start scan to look for gateways on your network. + + + Scanning your network… + + + No gateways found on your network. + + + Discovered on your network ({0}) + + + Scan failed: {0} + + + Stop + + + Scan + + + Add + + + Pick a discovered gateway above to connect. + + + Remove gateway? + + + This will forget {0} and its credentials on this machine. + + + Cancel + + + Connect failed + + + Gateway connection failed. + + + 1 approval waiting on you + + + {0} approvals waiting on you + + + Device · {0} + + + Node · {0} + + + ⚠️ Repair request + + + Approve + + + Deny + + + Approve pairing request + + + Deny pairing request + + + {0} + +Paste a new setup code from the Add Gateway flow. + + + {0} + +Your device needs approval on the gateway host. + + + {0} + +This gateway requires password authentication. + + + {0} + +The gateway may require a different auth protocol version. + + + {0} + +Check your connection settings and try again. + + + bootstrap + + + shared token + + + device token + + + unknown + + + Timed out waiting for the gateway connection to complete. + + + This channel requires a macOS host. It can’t be configured from a Windows machine. + + + Replace credentials + + + Configuration + + + Unlink this device from the channel. Scan a fresh QR to reconnect — your account stays paired on your phone. + + + Pause the channel temporarily — credentials are kept so you can start it again. Or disconnect entirely to clear them. + + + Start the channel — it’ll begin handling messages with the stored credentials. Or disconnect entirely to clear them. + + + Pause the channel — credentials are kept so you can start it again. + + + Start the channel — it’ll begin handling messages with the stored credentials. + + + Start + + + Stop + + + Logout + + + Disconnect and forget credentials + + + Controls + + + WhatsApp Linked devices help → + + + Signal Linked devices help → + + + How to create a Telegram bot → + + + How to create a Discord webhook → + + + How to add a Google Chat webhook → + + + Slack app dashboard → + + + About Nostr → + + + About macOS Messages → + + + Link your WhatsApp phone + + + Click "Show QR" in the Linking section below. + + + On your phone: WhatsApp → Settings → Linked devices → Link a device. + + + Scan the QR code that appears here. + + + Link your Signal phone + + + Click "Show QR" in the Linking section below. + + + On your phone: Signal → Settings → Linked devices → Link new device. + + + Scan the QR code that appears here. + + + Connect Telegram via a bot + + + Open Telegram and send a message to @BotFather. + + + Send /newbot and follow the prompts. Copy the bot token at the end. + + + Paste the token into the Configuration form below. + + + Click "Save and start". The channel will start automatically. + + + Connect Discord via a webhook + + + Open your Discord server settings → Integrations → Webhooks. + + + Click "New Webhook", give it a name, and copy the webhook URL. + + + Paste the URL into the Configuration form below. + + + Click "Save and start". + + + Connect Google Chat via a webhook + + + In Google Chat, open the space → Manage webhooks → Add webhook. + + + Copy the webhook URL. + + + Paste the URL into the Configuration form below. + + + Click "Save and start". + + + Connect Slack via an app + + + Create a Slack app at api.slack.com/apps and install it to your workspace. + + + Copy the bot token (xoxb-…) and the signing secret. + + + Paste both into the Configuration form below. + + + Click "Save and start". + + + Connect Nostr via relays + + + Generate or paste a private key (nsec). + + + Pick one or more relay URLs (e.g. wss://relay.damus.io). + + + Paste both into the Configuration form below. + + + Click "Save and start". + + + iMessage is macOS-only + + + iMessage reads the local Messages.app database, which only exists on macOS. + + + To use iMessage with OpenClaw, run the gateway on a Mac instead of this Windows host. + + + All other channels in this list work fine from a Windows-hosted gateway. + + + Connect this channel + + + "{0}" is a plugin channel. Refer to its documentation for the fields it needs. + + + Use "Open Config page" in the Configuration section below to add settings under channels.{0}. + + + Save the config; OpenClaw will start the channel automatically. + + + Bot token + + + Webhook URL + + + Signing secret + + + Private key (nsec) + + + Relay URLs + + + Get from @BotFather (/newbot). + + + Server Settings → Integrations → Webhooks → New Webhook. + + + Open a space → Manage webhooks → Add webhook. + + + OAuth tokens from your Slack app. + + + Basic Information → App Credentials. + + + One per line. + + + Save changes + + + Save and start + + + Open Config page + + + Edit this channel's settings in the gateway Config page. + + + After following the steps above, save the config to start the channel. + + + Not connected + + + Connect to a gateway before saving channel config. + + + Missing field + + + {0} is required. + + + Saving {0}… + + + Writing {0} field(s) and enabling the channel. + + + Couldn’t load gateway config + + + The gateway didn’t return its current config — can’t safely save without it. Try Refresh and save again. + + + The gateway’s config was cleared mid-save. Try Refresh and save again. + + + Save blocked for {0} + + + The gateway didn’t respond. + + + Save failed for {0} + + + Your gateway config changed elsewhere (e.g., from the Config page). We refreshed the cache — try Save again. Details: {0} + + + {0} If this looks like a wire-format mismatch, open the Config page for direct JSON editing. + + + {0} config saved + + + Waiting for the gateway to confirm the channel is running… + + + WSL gateway + + + Open a shell or manage the local gateway service in WSL. + + + Terminal + + + Start + + + Stop + + + Restart + + + Open terminal + + + Open terminal + + + Open dashboard (in browser) + + + Open dashboard + + + Disconnect / reconnect + + + Disconnect or reconnect + + + Open terminal + + + Open terminal + + + Run openclaw gateway start in WSL + + + Start WSL gateway + + + Run openclaw gateway stop in WSL + + + Stop WSL gateway + + + Run openclaw gateway restart in WSL + + + Restart WSL gateway + + diff --git a/src/OpenClaw.Tray.WinUI/Strings/fr-fr/Resources.resw b/src/OpenClaw.Tray.WinUI/Strings/fr-fr/Resources.resw index 10d0ab86..94d9d813 100644 --- a/src/OpenClaw.Tray.WinUI/Strings/fr-fr/Resources.resw +++ b/src/OpenClaw.Tray.WinUI/Strings/fr-fr/Resources.resw @@ -2284,7 +2284,7 @@ Sur votre hôte passerelle (Mac/Linux), exécutez : Utilisations - Cron + Planification Cet ordinateur @@ -3906,13 +3906,13 @@ Sur votre hôte passerelle (Mac/Linux), exécutez : PLANIFICATION - + Toutes les - + À - + Cron @@ -4577,4 +4577,906 @@ Sur votre hôte passerelle (Mac/Linux), exécutez : Avancé - + + + En direct + + + Effacer + + + Conversations actuellement gérées par cette passerelle, regroupées par canal. + + + Les sessions apparaissent ici lorsqu'un canal est connecté et que le trafic circule. + + + Ouvrir le chat + + + Activées + + + Désactivées + + + Aperçu + + + Aperçu de la voix + + + Déconnecté + + + Les commandes que l'agent exécute directement sur la passerelle ne le sont pas. Si la passerelle se trouve sur ce PC, elles peuvent toujours accéder à vos fichiers Windows, au presse-papiers et au réseau — vérifiez la configuration de votre passerelle. + + Tous les agents + + + {0} sur {1} événements + + + Créer la tâche + + + Modifier la tâche + + + Nouvelle tâche + + + Exécution... + + + Enregistrer les modifications + + + Ajouter un élément + + + Joindre un fichier + + + Annuler + + + Impossible de joindre le fichier + + + Impossible de se connecter à la passerelle à {0} + +Assurez-vous que la passerelle est en cours d'exécution. + + + Échec du démarrage du chat : +{0} + + + Le chat est prêt ; démarrage de votre première conversation… + + + La passerelle est connectée ; l'interface de chat est en cours de chargement. + + + Le jumelage avec la passerelle n'est pas terminé. Ouvrez les paramètres de connexion pour terminer le jumelage. + + + URL de passerelle non valide : {0} + + + OK + + + Ouvrez les paramètres de connexion pour terminer le jumelage avec une passerelle. + + + Ouvrir les paramètres vocaux + + + Délai d'attente dépassé pour le chat à {0}. Réessayez lorsque la passerelle est prête. + + + Délai d'attente dépassé pour la négociation avec l'opérateur de la passerelle. Réessayez lorsque la passerelle est prête. + + + Le modèle de reconnaissance vocale doit être installé avant de pouvoir utiliser la saisie vocale. Souhaitez-vous ouvrir les paramètres vocaux pour l'installer ? + + + Modèle vocal requis + + + Échec de l'initialisation de WebView2 : +{0} + + + Application en cours… + + + En attente d'approbation + + + 🔐 En attente d'approbation — approuvez puis cliquez sur Connecter + + + 🔐 En attente d'approbation de la passerelle + + + Connecter + + + ✓ Connecté + + + ✓ Connecté à {0} + + + Connexion en cours… + + + Connecter (une fois approuvé) + + + désactivé + + + Déconnecté + + + Entrez une URL de passerelle + + + Aucune passerelle + + + Reconnexion en cours… + + + rejeté + + + Démarrage du tunnel SSH… + + + sur {0} + + + 1 client connecté + + + {0} clients connectés + + + {0}/{1} canal + + + {0}/{1} canaux + + + {0} $ aujourd’hui + + + 0,00 $ aujourd’hui + + + Jeton partagé + + + Appuyez pour copier le jeton partagé + + + via tunnel SSH + + + Locale + + + Tailscale + + + Réseau local + + + Distant + + + Actif · {0} sessions + + + Actif · 1 session + + + Actif · aucune session en cours + + + Déconnecté + + + Connexion en cours… + + + Reconnexion en cours… + + + Nœud actif · {0} capacités + + + Nœud actif · 1 capacité + + + Nœud actif · aucune capacité activée + + + En attente d’approbation de l’appairage + + + Appairage refusé + + + Limité en débit + + + Erreur du nœud + + + Mode nœud désactivé + + + Aucune capacité activée. Choisissez ce que vous souhaitez partager dans les Autorisations. + + + En attente d’approbation sur l’hôte de la passerelle. + + + L’appairage a été refusé. Réappairez depuis Ajouter une passerelle. + + + Limité en débit par la passerelle. Nouvel essai après refroidissement. + + + Le nœud a signalé une erreur. + + + Aucune capacité fournie + + + 1 capacité fournie : {0} + + + {0} capacités fournies : {1} + + + Connecté + + + Connexion en cours… + + + En attente d’approbation + + + Déconnexion en cours… + + + Connecter + + + Ouvrir le tableau de bord + + + Déconnecter + + + Modifier + + + Supprimer + + + via SSH + + + Passerelles enregistrées (1) + + + Passerelles enregistrées ({0}) + + + à l’instant + + + il y a {0} min + + + il y a {0} h + + + il y a {0} j + + + il y a {0} mois + + + il y a {0} an(s) + + + Réappairer cette passerelle : + + + En attente d’approbation : + + + Aidez-nous à réparer le tunnel SSH : + + + Aidez-nous à réparer cette connexion : + + + Obtenez un nouveau code de configuration auprès de l’hôte de la passerelle. + + + Ou collez un nouveau jeton direct ci-dessous. + + + Approuvez ce client sur l’hôte de la passerelle à l’aide de la commande ci-dessous. + + + Une fois approuvé, cliquez sur Connecter pour reprendre. + + + Confirmez que SSH est accessible sur l’hôte. + + + Redémarrez le tunnel ci-dessous s’il s’est arrêté. + + + Vérifiez les journaux de la passerelle sur l’hôte. + + + Si la passerelle est partiellement en marche, ouvrez son tableau de bord. + + + Modifiez les paramètres de la passerelle pour changer l’URL ou le jeton. + + + Vérifiez que la passerelle est en cours d’exécution sur l’hôte. + + + Vérifiez que vous êtes sur le même réseau ou VPN. + + + Si vous utilisez un tunnel SSH : confirmez qu’il est actif. + + + Le tunnel SSH est interrompu. + + + Test de connexion… + + + Passerelle accessible + + + La passerelle a répondu avec {0} + + + Impossible d’atteindre la passerelle + + + Saisissez l’URL de la passerelle + + + Connexion en cours… + + + Démarrage du tunnel SSH… + + + Approbation d’appairage requise pour {0}. + + + Connecté à {0}. + + + Le port distant SSH doit être compris entre 1 et 65535 + + + Le port local SSH doit être compris entre 1 et 65535 + + + Redémarrage du tunnel déclenché. + + + Échec du redémarrage du tunnel : {0} + + + Réappairé. Reconnexion en cours… + + + Impossible d’appliquer le code. + + + Veuillez coller un code de configuration. + + + Application en cours… + + + Appliqué — passerelle : {0} + + + Code de configuration invalide + + + URL invalide + + + Échec de la connexion + + + Erreur inconnue + + + Passerelle : {0} + + + (non spécifié) + + + (pas de jeton) + + + Jeton : {0} + + + Appuyez sur Lancer l’analyse pour rechercher des passerelles sur votre réseau. + + + Analyse de votre réseau… + + + Aucune passerelle trouvée sur votre réseau. + + + Découverts sur votre réseau ({0}) + + + Échec de l’analyse : {0} + + + Arrêter + + + Analyser + + + Ajouter + + + Choisissez une passerelle découverte ci-dessus pour vous connecter. + + + Supprimer la passerelle ? + + + Cela supprimera {0} et ses identifiants sur cette machine. + + + Annuler + + + Échec de la connexion + + + Échec de la connexion à la passerelle. + + + 1 approbation en attente + + + {0} approbations en attente + + + Appareil · {0} + + + Nœud · {0} + + + ⚠️ Demande de réparation + + + Approuver + + + Refuser + + + Approuver la demande d’appairage + + + Refuser la demande d’appairage + + + {0} + +Collez un nouveau code de configuration depuis le flux Ajouter une passerelle. + + + {0} + +Votre appareil nécessite une approbation sur l’hôte de la passerelle. + + + {0} + +Cette passerelle nécessite une authentification par mot de passe. + + + {0} + +La passerelle pourrait nécessiter une version différente du protocole d’authentification. + + + {0} + +Vérifiez vos paramètres de connexion et réessayez. + + + amorçage + + + jeton partagé + + + jeton d’appareil + + + inconnu + + + Le délai d’attente de la connexion à la passerelle a expiré. + + + Ce canal nécessite un hôte macOS. Il ne peut pas être configuré depuis une machine Windows. + + + Remplacer les identifiants + + + Paramètres + + + Dissocier cet appareil du canal. Scannez un nouveau QR pour vous reconnecter — votre compte reste associé sur votre téléphone. + + + Mettre le canal en pause temporairement — les identifiants sont conservés pour pouvoir le redémarrer. Ou déconnectez-vous entièrement pour les effacer. + + + Démarrer le canal — il commencera à traiter les messages avec les identifiants enregistrés. Ou déconnectez-vous entièrement pour les effacer. + + + Mettre le canal en pause — les identifiants sont conservés pour pouvoir le redémarrer. + + + Démarrer le canal — il commencera à traiter les messages avec les identifiants enregistrés. + + + Démarrer + + + Arrêter + + + Déconnexion + + + Déconnecter et oublier les identifiants + + + Commandes + + + Aide sur les appareils liés WhatsApp → + + + Aide sur les appareils liés Signal → + + + Comment créer un bot Telegram → + + + Comment créer un webhook Discord → + + + Comment ajouter un webhook Google Chat → + + + Tableau de bord des applications Slack → + + + À propos de Nostr → + + + À propos de Messages sur macOS → + + + Associer votre téléphone WhatsApp + + + Cliquez sur "Show QR" dans la section Liaison ci-dessous. + + + Sur votre téléphone : WhatsApp → Paramètres → Appareils liés → Lier un appareil. + + + Scannez le code QR qui s’affiche ici. + + + Associer votre téléphone Signal + + + Cliquez sur "Show QR" dans la section Liaison ci-dessous. + + + Sur votre téléphone : Signal → Paramètres → Appareils liés → Lier un nouvel appareil. + + + Scannez le code QR qui s’affiche ici. + + + Connecter Telegram via un bot + + + Ouvrez Telegram et envoyez un message à @BotFather. + + + Envoyez /newbot et suivez les instructions. Copiez le jeton du bot à la fin. + + + Collez le jeton dans le formulaire de configuration ci-dessous. + + + Cliquez sur "Save and start". Le canal démarrera automatiquement. + + + Connecter Discord via un webhook + + + Ouvrez les paramètres de votre serveur Discord → Intégrations → Webhooks. + + + Cliquez sur "New Webhook", donnez-lui un nom et copiez l’URL du webhook. + + + Collez l’URL dans le formulaire de configuration ci-dessous. + + + Cliquez sur "Save and start". + + + Connecter Google Chat via un webhook + + + Dans Google Chat, ouvrez l’espace → Gérer les webhooks → Ajouter un webhook. + + + Copiez l’URL du webhook. + + + Collez l’URL dans le formulaire de configuration ci-dessous. + + + Cliquez sur "Save and start". + + + Connecter Slack via une application + + + Créez une application Slack sur api.slack.com/apps et installez-la dans votre espace de travail. + + + Copiez le jeton du bot (xoxb-…) et le secret de signature. + + + Collez les deux dans le formulaire de configuration ci-dessous. + + + Cliquez sur "Save and start". + + + Connecter Nostr via des relais + + + Générez ou collez une clé privée (nsec). + + + Choisissez une ou plusieurs URL de relais (p. ex. wss://relay.damus.io). + + + Collez les deux dans le formulaire de configuration ci-dessous. + + + Cliquez sur "Save and start". + + + iMessage est réservé à macOS + + + iMessage lit la base de données locale de Messages.app, qui n’existe que sur macOS. + + + Pour utiliser iMessage avec OpenClaw, exécutez la passerelle sur un Mac au lieu de cet hôte Windows. + + + Tous les autres canaux de cette liste fonctionnent correctement depuis une passerelle hébergée sous Windows. + + + Connecter ce canal + + + "{0}" est un canal de plugin. Consultez sa documentation pour connaître les champs requis. + + + Utilisez "Open Config page" dans la section Configuration ci-dessous pour ajouter des paramètres sous channels.{0}. + + + Enregistrez la configuration ; OpenClaw démarrera le canal automatiquement. + + + Jeton du bot + + + URL du webhook + + + Secret de signature + + + Clé privée (nsec) + + + URL des relais + + + Obtenez-le auprès de @BotFather (/newbot). + + + Paramètres du serveur → Intégrations → Webhooks → New Webhook. + + + Ouvrez un espace → Gérer les webhooks → Ajouter un webhook. + + + Jetons OAuth de votre application Slack. + + + Informations de base → Identifiants de l'application. + + + Une par ligne. + + + Enregistrer les modifications + + + Enregistrer et démarrer + + + Ouvrir la page de configuration + + + Modifiez les paramètres de ce canal dans la page de configuration de la passerelle. + + + Après avoir suivi les étapes ci-dessus, enregistrez la configuration pour démarrer le canal. + + + Non connecté + + + Connectez-vous à une passerelle avant d’enregistrer la configuration du canal. + + + Champ manquant + + + {0} est requis. + + + Enregistrement de {0}… + + + Écriture de {0} champ(s) et activation du canal. + + + Impossible de charger la configuration de la passerelle + + + La passerelle n’a pas renvoyé sa configuration actuelle — impossible d’enregistrer en toute sécurité sans elle. Essayez d’actualiser et d’enregistrer à nouveau. + + + La configuration de la passerelle a été effacée en cours d’enregistrement. Essayez d’actualiser et d’enregistrer à nouveau. + + + Enregistrement bloqué pour {0} + + + La passerelle n’a pas répondu. + + + Échec de l’enregistrement pour {0} + + + La configuration de votre passerelle a été modifiée ailleurs (p. ex., depuis la page de configuration). Nous avons actualisé le cache — réessayez d’enregistrer. Détails : {0} + + + {0} Si cela ressemble à une incompatibilité de format filaire, ouvrez la page de configuration pour modifier directement le JSON. + + + Configuration de {0} enregistrée + + + En attente de la confirmation par la passerelle que le canal est en cours d’exécution… + + + Passerelle WSL + + + Ouvrez un shell ou gérez le service de passerelle locale dans WSL. + + + Invite de commandes + + + Démarrer + + + Arrêter + + + Redémarrer + + + Ouvrir le terminal + + + Ouvrir le terminal + + + Ouvrir le tableau de bord (dans le navigateur) + + + Ouvrir le tableau de bord + + + Déconnecter / reconnecter + + + Déconnecter ou reconnecter + + + Ouvrir le terminal + + + Ouvrir le terminal + + + Exécuter openclaw gateway start dans WSL + + + Démarrer la passerelle WSL + + + Exécuter openclaw gateway stop dans WSL + + + Arrêter la passerelle WSL + + + Exécuter openclaw gateway restart dans WSL + + + Redémarrer la passerelle WSL + + diff --git a/src/OpenClaw.Tray.WinUI/Strings/nl-nl/Resources.resw b/src/OpenClaw.Tray.WinUI/Strings/nl-nl/Resources.resw index 251ef4f0..c6631660 100644 --- a/src/OpenClaw.Tray.WinUI/Strings/nl-nl/Resources.resw +++ b/src/OpenClaw.Tray.WinUI/Strings/nl-nl/Resources.resw @@ -2285,7 +2285,7 @@ Voer op uw gateway-host (Mac/Linux) uit: Gebruik - Cron + Planning Deze computer @@ -3907,13 +3907,13 @@ Voer op uw gateway-host (Mac/Linux) uit: PLANNING - + Elke - + Om - + Cron @@ -4578,4 +4578,906 @@ Voer op uw gateway-host (Mac/Linux) uit: Geavanceerd - + + + Actueel + + + Wissen + + + Gesprekken die deze gateway momenteel afhandelt, gegroepeerd per kanaal. + + + Sessies verschijnen hier wanneer een kanaal is verbonden en er verkeer loopt. + + + Chat openen + + + Ingeschakeld + + + Uitgeschakeld + + + Voorbeeld + + + Stemvoorbeeld + + + Niet verbonden + + + Opdrachten die de agent rechtstreeks op de gateway uitvoert, vallen hier niet onder. Als de gateway op deze pc staat, hebben ze mogelijk nog steeds toegang tot uw Windows-bestanden, klembord en netwerk — controleer de configuratie van uw gateway. + + Alle agenten + + + {0} van {1} gebeurtenissen + + + Taak aanmaken + + + Taak bewerken + + + Nieuwe taak + + + Uitvoeren... + + + Wijzigingen opslaan + + + Item toevoegen + + + Bestand bijvoegen + + + Annuleren + + + Kan bestand niet bijvoegen + + + Kan geen verbinding maken met de gateway op {0} + +Controleer of de gateway actief is. + + + Chat kon niet worden gestart: +{0} + + + Chat is gereed; uw eerste gesprek wordt gestart… + + + De gateway is verbonden; de chatinterface wordt nog geladen. + + + Het koppelen met de gateway is niet voltooid. Open de verbindingsinstellingen om het koppelen te voltooien. + + + Ongeldige gateway-URL: {0} + + + OK + + + Open de verbindingsinstellingen om het koppelen met een gateway te voltooien. + + + Spraakinstellingen openen + + + Time-out bij het wachten op chat op {0}. Probeer het opnieuw wanneer de gateway gereed is. + + + Time-out bij het wachten op de gateway-operatorhandshake. Probeer het opnieuw wanneer de gateway gereed is. + + + Het spraak-naar-tekstmodel moet worden geïnstalleerd voordat u spraakinvoer kunt gebruiken. Wilt u de spraakinstellingen openen om het te installeren? + + + Spraakmodel vereist + + + WebView2 kon niet worden geïnitialiseerd: +{0} + + + Toepassen… + + + Wacht op goedkeuring + + + 🔐 Wacht op goedkeuring — keur goed en klik op Verbinden + + + 🔐 Wacht op goedkeuring van de gateway + + + Verbinden + + + ✓ Verbonden + + + ✓ Verbonden met {0} + + + Verbinden… + + + Verbinden (na goedkeuring) + + + uitgeschakeld + + + Verbinding verbroken + + + Voer een gateway-URL in + + + Geen gateways + + + Opnieuw verbinden… + + + afgewezen + + + SSH-tunnel starten… + + + op {0} + + + 1 verbonden client + + + {0} verbonden clients + + + {0}/{1} kanaal + + + {0}/{1} kanalen + + + ${0} vandaag + + + $0,00 vandaag + + + Gedeeld token + + + Tik om gedeeld token te kopiëren + + + via SSH-tunnel + + + Lokaal + + + Tailscale + + + Lokaal netwerk + + + Extern + + + Actief · {0} sessies + + + Actief · 1 sessie + + + Actief · geen actieve sessies + + + Niet verbonden + + + Verbinden… + + + Opnieuw verbinden… + + + Node actief · {0} mogelijkheden + + + Node actief · 1 mogelijkheid + + + Node actief · geen mogelijkheden ingeschakeld + + + Wacht op goedkeuring van koppeling + + + Koppeling geweigerd + + + Snelheidsbeperkt + + + Nodefout + + + Nodemodus uitgeschakeld + + + Geen mogelijkheden ingeschakeld. Kies wat u wilt delen bij Machtigingen. + + + Wacht op goedkeuring van de gatewayhost. + + + Koppeling is geweigerd. Koppel opnieuw via Gateway toevoegen. + + + Snelheidsbeperkt door de gateway. Wordt opnieuw geprobeerd na afkoeling. + + + De node heeft een fout gemeld. + + + Geen mogelijkheden aangeboden + + + 1 mogelijkheid aangeboden: {0} + + + {0} mogelijkheden aangeboden: {1} + + + Verbonden + + + Verbinden… + + + Wacht op goedkeuring + + + Verbinding verbreken… + + + Verbinden + + + Dashboard openen + + + Verbinding verbreken + + + Bewerken + + + Verwijderen + + + via SSH + + + Opgeslagen gateways (1) + + + Opgeslagen gateways ({0}) + + + zojuist + + + {0} min. geleden + + + {0} uur geleden + + + {0} dagen geleden + + + {0} mnd. geleden + + + {0} jaar geleden + + + Deze gateway opnieuw koppelen: + + + Wacht op goedkeuring: + + + Help ons de SSH-tunnel te herstellen: + + + Help ons deze verbinding te herstellen: + + + Vraag een nieuwe installatiecode aan bij de gatewayhost. + + + Of plak hieronder een nieuw direct token. + + + Keur deze client goed op de gatewayhost met het onderstaande commando. + + + Zodra goedgekeurd, klik op Verbinden om door te gaan. + + + Bevestig dat SSH bereikbaar is op de host. + + + Herstart de tunnel hieronder als deze is gestopt. + + + Controleer de gatewaylogs op de host. + + + Als de gateway gedeeltelijk actief is, open het dashboard. + + + Bewerk de gatewayinstellingen om de URL of het token te wijzigen. + + + Controleer of de gateway draait op de host. + + + Controleer of u zich op hetzelfde netwerk of VPN bevindt. + + + Als u een SSH-tunnel gebruikt: bevestig dat deze actief is. + + + SSH-tunnel is uitgevallen. + + + Verbinding testen… + + + Gateway bereikbaar + + + Gateway antwoordde met {0} + + + Kan de gateway niet bereiken + + + Voer een gateway-URL in + + + Verbinden… + + + SSH-tunnel starten… + + + Koppelinggoedkeuring vereist voor {0}. + + + Verbonden met {0}. + + + SSH-externe poort moet 1–65535 zijn + + + SSH-lokale poort moet 1–65535 zijn + + + Herstart van tunnel geactiveerd. + + + Herstart van tunnel mislukt: {0} + + + Opnieuw gekoppeld. Opnieuw verbinden… + + + Kan de code niet toepassen. + + + Plak een installatiecode. + + + Toepassen… + + + Toegepast — gateway: {0} + + + Ongeldige installatiecode + + + Ongeldige URL + + + Verbinding mislukt + + + Onbekende fout + + + Gateway-adres: {0} + + + (niet opgegeven) + + + (geen token) + + + Toegangstoken: {0} + + + Druk op Scan starten om gateways op uw netwerk te zoeken. + + + Uw netwerk scannen… + + + Geen gateways gevonden op uw netwerk. + + + Gevonden op uw netwerk ({0}) + + + Scan mislukt: {0} + + + Stoppen + + + Scannen + + + Toevoegen + + + Kies een gevonden gateway hierboven om te verbinden. + + + Gateway verwijderen? + + + Hiermee worden {0} en de bijbehorende referenties op deze machine vergeten. + + + Annuleren + + + Verbinding mislukt + + + Gatewayverbinding mislukt. + + + 1 goedkeuring wacht op u + + + {0} goedkeuringen wachten op u + + + Apparaat · {0} + + + Knooppunt · {0} + + + ⚠️ Reparatieverzoek + + + Goedkeuren + + + Weigeren + + + Koppelingverzoek goedkeuren + + + Koppelingverzoek weigeren + + + {0} + +Plak een nieuwe installatiecode vanuit het Gateway toevoegen-proces. + + + {0} + +Uw apparaat moet worden goedgekeurd op de gatewayhost. + + + {0} + +Deze gateway vereist wachtwoordverificatie. + + + {0} + +De gateway vereist mogelijk een andere versie van het verificatieprotocol. + + + {0} + +Controleer uw verbindingsinstellingen en probeer het opnieuw. + + + bootstrap-modus + + + gedeeld token + + + apparaattoken + + + onbekend + + + Time-out bij het wachten op de gatewayverbinding. + + + Dit kanaal vereist een macOS-host. Het kan niet worden geconfigureerd vanaf een Windows-machine. + + + Inloggegevens vervangen + + + Configuratie + + + Ontkoppel dit apparaat van het kanaal. Scan een nieuwe QR om opnieuw te verbinden — uw account blijft gekoppeld op uw telefoon. + + + Pauzeer het kanaal tijdelijk — inloggegevens worden bewaard zodat u het opnieuw kunt starten. Of verbreek de verbinding volledig om ze te wissen. + + + Start het kanaal — het begint berichten te verwerken met de opgeslagen inloggegevens. Of verbreek de verbinding volledig om ze te wissen. + + + Pauzeer het kanaal — inloggegevens worden bewaard zodat u het opnieuw kunt starten. + + + Start het kanaal — het begint berichten te verwerken met de opgeslagen inloggegevens. + + + Starten + + + Stoppen + + + Afmelden + + + Verbinding verbreken en inloggegevens vergeten + + + Besturing + + + WhatsApp gekoppelde apparaten hulp → + + + Signal gekoppelde apparaten hulp → + + + Een Telegram-bot aanmaken → + + + Een Discord-webhook aanmaken → + + + Een Google Chat-webhook toevoegen → + + + Slack-app-dashboard → + + + Over Nostr → + + + Over Berichten op macOS → + + + Koppel uw WhatsApp-telefoon + + + Klik op "Show QR" in het gedeelte Koppelen hieronder. + + + Op uw telefoon: WhatsApp → Instellingen → Gekoppelde apparaten → Apparaat koppelen. + + + Scan de QR-code die hier verschijnt. + + + Koppel uw Signal-telefoon + + + Klik op "Show QR" in het gedeelte Koppelen hieronder. + + + Op uw telefoon: Signal → Instellingen → Gekoppelde apparaten → Nieuw apparaat koppelen. + + + Scan de QR-code die hier verschijnt. + + + Telegram verbinden via een bot + + + Open Telegram en stuur een bericht naar @BotFather. + + + Stuur /newbot en volg de aanwijzingen. Kopieer het bot-token aan het einde. + + + Plak het token in het configuratieformulier hieronder. + + + Klik op "Save and start". Het kanaal start automatisch. + + + Discord verbinden via een webhook + + + Open uw Discord-serverinstellingen → Integraties → Webhooks. + + + Klik op "New Webhook", geef het een naam en kopieer de webhook-URL. + + + Plak de URL in het configuratieformulier hieronder. + + + Klik op "Save and start". + + + Google Chat verbinden via een webhook + + + Open in Google Chat de ruimte → Webhooks beheren → Webhook toevoegen. + + + Kopieer de webhook-URL. + + + Plak de URL in het configuratieformulier hieronder. + + + Klik op "Save and start". + + + Slack verbinden via een app + + + Maak een Slack-app aan op api.slack.com/apps en installeer deze in uw werkruimte. + + + Kopieer het bot-token (xoxb-…) en het ondertekeningsgeheim. + + + Plak beide in het configuratieformulier hieronder. + + + Klik op "Save and start". + + + Nostr verbinden via relays + + + Genereer of plak een privésleutel (nsec). + + + Kies een of meer relay-URL's (bijv. wss://relay.damus.io). + + + Plak beide in het configuratieformulier hieronder. + + + Klik op "Save and start". + + + iMessage is alleen beschikbaar op macOS + + + iMessage leest de lokale Messages.app-database, die alleen op macOS bestaat. + + + Om iMessage met OpenClaw te gebruiken, voert u de gateway uit op een Mac in plaats van deze Windows-host. + + + Alle andere kanalen in deze lijst werken prima vanaf een Windows-gehoste gateway. + + + Dit kanaal verbinden + + + "{0}" is een pluginkanaal. Raadpleeg de documentatie voor de vereiste velden. + + + Gebruik "Open Config page" in het gedeelte Configuratie hieronder om instellingen toe te voegen onder channels.{0}. + + + Sla de configuratie op; OpenClaw start het kanaal automatisch. + + + Bot-token + + + Webhook-URL + + + Ondertekeningsgeheim + + + Privésleutel (nsec) + + + Relay-URL's + + + Verkrijg het via @BotFather (/newbot). + + + Serverinstellingen → Integraties → Webhooks → New Webhook. + + + Open een ruimte → Webhooks beheren → Webhook toevoegen. + + + OAuth-tokens van uw Slack-app. + + + Basisinformatie → App-referenties. + + + Eén per regel. + + + Wijzigingen opslaan + + + Opslaan en starten + + + Configuratiepagina openen + + + Bewerk de instellingen van dit kanaal op de configuratiepagina van de gateway. + + + Sla na het volgen van de bovenstaande stappen de configuratie op om het kanaal te starten. + + + Niet verbonden + + + Maak verbinding met een gateway voordat u de kanaalconfiguratie opslaat. + + + Ontbrekend veld + + + {0} is vereist. + + + {0} opslaan… + + + {0} veld(en) schrijven en het kanaal inschakelen. + + + Kan gatewayconfiguratie niet laden + + + De gateway heeft de huidige configuratie niet geretourneerd — kan niet veilig opslaan zonder deze. Probeer te vernieuwen en opnieuw op te slaan. + + + De configuratie van de gateway is tijdens het opslaan gewist. Probeer te vernieuwen en opnieuw op te slaan. + + + Opslaan geblokkeerd voor {0} + + + De gateway heeft niet gereageerd. + + + Opslaan mislukt voor {0} + + + Uw gatewayconfiguratie is elders gewijzigd (bijv. vanaf de configuratiepagina). We hebben de cache vernieuwd — probeer opnieuw op te slaan. Details: {0} + + + {0} Als dit lijkt op een mismatch in het draadformaat, open dan de configuratiepagina voor directe JSON-bewerking. + + + Configuratie van {0} opgeslagen + + + Wachten tot de gateway bevestigt dat het kanaal actief is… + + + WSL-gateway + + + Open een shell of beheer de lokale gatewayservice in WSL. + + + Terminalvenster + + + Starten + + + Stoppen + + + Opnieuw starten + + + Terminal openen + + + Terminal openen + + + Dashboard openen (in browser) + + + Dashboard openen + + + Verbinding verbreken / opnieuw verbinden + + + Verbinding verbreken of opnieuw verbinden + + + Terminal openen + + + Terminal openen + + + openclaw gateway start uitvoeren in WSL + + + WSL-gateway starten + + + openclaw gateway stop uitvoeren in WSL + + + WSL-gateway stoppen + + + openclaw gateway restart uitvoeren in WSL + + + WSL-gateway opnieuw starten + + diff --git a/src/OpenClaw.Tray.WinUI/Strings/zh-cn/Resources.resw b/src/OpenClaw.Tray.WinUI/Strings/zh-cn/Resources.resw index 88945594..106bb16a 100644 --- a/src/OpenClaw.Tray.WinUI/Strings/zh-cn/Resources.resw +++ b/src/OpenClaw.Tray.WinUI/Strings/zh-cn/Resources.resw @@ -2284,7 +2284,7 @@ 用量 - Cron + 计划任务 此计算机 @@ -3906,13 +3906,13 @@ 计划 - + - + - + Cron @@ -4577,4 +4577,907 @@ 高级 - + + + 实时 + + + 清除 + + + 此网关当前正在处理的对话,按频道分组。 + + + 当频道已连接且有流量时,会话将显示在此处。 + + + 打开聊天 + + + 已启用 + + + 已禁用 + + + 预览 + + + 语音预览 + + + 已断开连接 + + + 代理直接在网关上运行的命令不受此限制。如果网关在此电脑上,它们仍可能访问您的 Windows 文件、剪贴板和网络——请检查网关的配置。 + + + 所有代理 + + + {0} / {1} 个事件 + + + 创建任务 + + + 编辑任务 + + + 新任务 + + + 正在运行... + + + 保存更改 + + + 添加项目 + + + 附加文件 + + + 取消 + + + 无法附加文件 + + + 无法连接到 {0} 的网关 + +请确保网关正在运行。 + + + 聊天启动失败: +{0} + + + 聊天已准备就绪;正在启动您的首次对话… + + + 网关已连接;聊天界面仍在加载中。 + + + 网关配对未完成。请打开连接设置以完成配对。 + + + 无效的网关 URL:{0} + + + 确定 + + + 打开连接设置以完成与网关的配对。 + + + 打开语音设置 + + + 等待 {0} 的聊天超时。请在网关准备就绪后重试。 + + + 等待网关操作员握手超时。请在网关准备就绪后重试。 + + + 需要先安装语音转文字模型才能使用语音输入。是否要打开语音设置进行安装? + + + 需要语音模型 + + + WebView2 初始化失败: +{0} + + + 正在应用… + + + 等待批准 + + + 🔐 等待批准 - 批准后请点击连接 + + + 🔐 等待网关批准 + + + 连接 + + + ✓ 已连接 + + + ✓ 已连接到 {0} + + + 正在连接… + + + 连接(批准后) + + + 已禁用 + + + 已断开连接 + + + 输入网关 URL + + + 没有网关 + + + 正在重新连接… + + + 已拒绝 + + + 正在启动 SSH 隧道… + + + 在 {0} 上 + + + 1 个客户端 + + + {0} 个客户端 + + + {0}/{1} 个频道 + + + {0}/{1} 个频道 + + + 今日 ${0} + + + 今日 $0.00 + + + 共享令牌 + + + 点击以复制共享令牌 + + + 通过 SSH 隧道 + + + 本地 + + + Tailscale + + + 局域网 + + + 远程 + + + 活动 · {0} 个会话 + + + 活动 · 1 个会话 + + + 活动 · 无当前会话 + + + 已断开连接 + + + 正在连接… + + + 正在重新连接… + + + 节点活动 · {0} 项能力 + + + 节点活动 · 1 项能力 + + + 节点活动 · 无已启用的能力 + + + 等待配对审批 + + + 配对被拒绝 + + + 已限流 + + + 节点错误 + + + 节点模式已禁用 + + + 未启用任何能力。请在权限中选择要共享的内容。 + + + 等待网关主机上的审批。 + + + 配对被拒绝。请从添加网关重新配对。 + + + 被网关限流。将在冷却后重试。 + + + 节点报告了一个错误。 + + + 未提供任何能力 + + + 提供 1 项能力:{0} + + + 提供 {0} 项能力:{1} + + + 已连接 + + + 正在连接… + + + 等待审批 + + + 正在断开连接… + + + 连接 + + + 打开仪表板 + + + 断开连接 + + + 编辑 + + + 移除 + + + 通过 SSH + + + 已保存的网关 (1) + + + 已保存的网关 ({0}) + + + 刚刚 + + + {0}分钟前 + + + {0}小时前 + + + {0}天前 + + + {0}个月前 + + + {0}年前 + + + 重新配对此网关: + + + 等待审批: + + + 帮助我们修复 SSH 隧道: + + + 帮助我们修复此连接: + + + 从网关主机获取新的设置代码。 + + + 或在下方粘贴新的直接令牌。 + + + 使用以下命令在网关主机上批准此客户端。 + + + 批准后,点击连接以继续。 + + + 确认主机上的 SSH 可访问。 + + + 如果隧道已停止,请在下方重新启动。 + + + 检查主机上的网关日志。 + + + 如果网关部分运行,请打开其仪表板。 + + + 编辑网关设置以更改 URL 或令牌。 + + + 检查网关是否在主机上运行。 + + + 检查您是否在同一网络或 VPN 上。 + + + 如果使用 SSH 隧道:确认其已启动。 + + + SSH 隧道已断开。 + + + 正在测试连接… + + + 网关可访问 + + + 网关响应代码为 {0} + + + 无法访问网关 + + + 输入网关 URL + + + 正在连接… + + + 正在启动 SSH 隧道… + + + 需要对 {0} 进行配对审批。 + + + 已连接到 {0}。 + + + SSH 远程端口必须在 1–65535 之间 + + + SSH 本地端口必须在 1–65535 之间 + + + 隧道重启已触发。 + + + 隧道重启失败:{0} + + + 已重新配对。正在重新连接… + + + 无法应用代码。 + + + 请粘贴设置代码。 + + + 正在应用… + + + 已应用 — 网关:{0} + + + 设置代码无效 + + + URL 无效 + + + 连接失败 + + + 未知错误 + + + 网关:{0} + + + (未指定) + + + (无令牌) + + + 令牌:{0} + + + 按“开始扫描”以在您的网络上查找网关。 + + + 正在扫描您的网络… + + + 未在您的网络上找到网关。 + + + 在您的网络上发现 ({0}) + + + 扫描失败:{0} + + + 停止 + + + 扫描 + + + 添加 + + + 选择上方发现的网关进行连接。 + + + 移除网关? + + + 这将移除此计算机上的 {0} 及其凭据。 + + + 取消 + + + 连接失败 + + + 网关连接失败。 + + + 1 项审批等待您处理 + + + {0} 项审批等待您处理 + + + 设备 · {0} + + + 节点 · {0} + + + ⚠️ 修复请求 + + + 批准 + + + 拒绝 + + + 批准配对请求 + + + 拒绝配对请求 + + + {0} + +从添加网关流程中粘贴新的设置代码。 + + + {0} + +您的设备需要在网关主机上获得批准。 + + + {0} + +此网关需要密码身份验证。 + + + {0} + +网关可能需要不同版本的认证协议。 + + + {0} + +请检查您的连接设置并重试。 + + + 引导 + + + 共享令牌 + + + 设备令牌 + + + 未知 + + + 等待网关连接完成超时。 + + + 此频道需要 macOS 主机,无法从 Windows 计算机进行配置。 + + + 替换凭据 + + + 配置 + + + 将此设备与频道取消关联。扫描新的 QR 码以重新连接——您的帐户仍会在手机上保持配对。 + + + 暂时暂停频道——凭据会被保留,以便您可以重新启动。或完全断开连接以清除凭据。 + + + 启动频道——它将使用已存储的凭据开始处理消息。或完全断开连接以清除凭据。 + + + 暂停频道——凭据会被保留,以便您可以重新启动。 + + + 启动频道——它将使用已存储的凭据开始处理消息。 + + + 启动 + + + 停止 + + + 注销 + + + 断开连接并清除凭据 + + + 控制 + + + WhatsApp 已关联设备帮助 → + + + Signal 已关联设备帮助 → + + + 如何创建 Telegram 机器人 → + + + 如何创建 Discord webhook → + + + 如何添加 Google Chat webhook → + + + Slack 应用控制台 → + + + 关于 Nostr → + + + 关于 macOS“信息”→ + + + 关联您的 WhatsApp 手机 + + + 点击下方“关联”部分中的 "Show QR"。 + + + 在手机上:WhatsApp → 设置 → 已关联设备 → 关联设备。 + + + 扫描此处显示的 QR 码。 + + + 关联您的 Signal 手机 + + + 点击下方“关联”部分中的 "Show QR"。 + + + 在手机上:Signal → 设置 → 已关联设备 → 关联新设备。 + + + 扫描此处显示的 QR 码。 + + + 通过机器人连接 Telegram + + + 打开 Telegram 并向 @BotFather 发送消息。 + + + 发送 /newbot 并按照提示操作。最后复制机器人令牌。 + + + 将令牌粘贴到下方的配置表单中。 + + + 点击 "Save and start"。频道将自动启动。 + + + 通过 webhook 连接 Discord + + + 打开您的 Discord 服务器设置 → 集成 → Webhooks。 + + + 点击 "New Webhook",为其命名,然后复制 webhook URL。 + + + 将 URL 粘贴到下方的配置表单中。 + + + 点击 "Save and start"。 + + + 通过 webhook 连接 Google Chat + + + 在 Google Chat 中,打开聊天室 → 管理 webhook → 添加 webhook。 + + + 复制 webhook URL。 + + + 将 URL 粘贴到下方的配置表单中。 + + + 点击 "Save and start"。 + + + 通过应用连接 Slack + + + 在 api.slack.com/apps 上创建 Slack 应用并将其安装到您的工作区。 + + + 复制机器人令牌 (xoxb-…) 和签名密钥。 + + + 将两者粘贴到下方的配置表单中。 + + + 点击 "Save and start"。 + + + 通过中继连接 Nostr + + + 生成或粘贴私钥 (nsec)。 + + + 选择一个或多个中继 URL(例如 wss://relay.damus.io)。 + + + 将两者粘贴到下方的配置表单中。 + + + 点击 "Save and start"。 + + + iMessage 仅适用于 macOS + + + iMessage 读取本地 Messages.app 数据库,该数据库仅存在于 macOS 上。 + + + 若要将 iMessage 与 OpenClaw 配合使用,请在 Mac 上运行网关,而非此 Windows 主机。 + + + 此列表中的所有其他频道都可以在 Windows 托管的网关上正常使用。 + + + 连接此频道 + + + "{0}" 是一个插件频道。请参阅其文档以了解所需字段。 + + + 使用下方“配置”部分中的 "Open Config page" 在 channels.{0} 下添加设置。 + + + 保存配置;OpenClaw 将自动启动频道。 + + + 机器人令牌 + + + Webhook 网址 + + + 签名密钥 + + + 私钥 (nsec) + + + 中继 URL + + + 从 @BotFather (/newbot) 获取。 + + + 服务器设置 → 集成 → Webhooks → New Webhook。 + + + 打开聊天室 → 管理 webhook → 添加 webhook。 + + + 来自您 Slack 应用的 OAuth 令牌。 + + + Basic Information → App Credentials。 + + + 每行一个。 + + + 保存更改 + + + 保存并启动 + + + 打开配置页面 + + + 在网关配置页面中编辑此频道的设置。 + + + 按照上述步骤操作后,保存配置以启动频道。 + + + 未连接 + + + 请先连接到网关,然后再保存频道配置。 + + + 缺少字段 + + + {0} 为必填项。 + + + 正在保存 {0}… + + + 正在写入 {0} 个字段并启用频道。 + + + 无法加载网关配置 + + + 网关未返回其当前配置——没有它无法安全保存。请尝试刷新并重新保存。 + + + 网关配置在保存过程中被清除。请尝试刷新并重新保存。 + + + {0} 的保存被阻止 + + + 网关未响应。 + + + {0} 的保存失败 + + + 您的网关配置已在其他位置更改(例如,从配置页面)。我们已刷新缓存——请再次尝试保存。详细信息:{0} + + + {0} 如果这看起来像是线路格式不匹配,请打开配置页面进行直接 JSON 编辑。 + + + {0} 配置已保存 + + + 正在等待网关确认频道已运行… + + + WSL 网关 + + + 打开 shell,或在 WSL 中管理本地网关服务。 + + + 终端 + + + 启动 + + + 停止 + + + 重启 + + + 打开终端 + + + 打开终端 + + + 在浏览器中打开仪表板 + + + 打开仪表板 + + + 断开/重新连接 + + + 断开连接或重新连接 + + + 打开终端 + + + 打开终端 + + + 在 WSL 中运行 openclaw gateway start + + + 启动 WSL 网关 + + + 在 WSL 中运行 openclaw gateway stop + + + 停止 WSL 网关 + + + 在 WSL 中运行 openclaw gateway restart + + + 重启 WSL 网关 + + diff --git a/src/OpenClaw.Tray.WinUI/Strings/zh-tw/Resources.resw b/src/OpenClaw.Tray.WinUI/Strings/zh-tw/Resources.resw index 4e8bbefd..e22f5630 100644 --- a/src/OpenClaw.Tray.WinUI/Strings/zh-tw/Resources.resw +++ b/src/OpenClaw.Tray.WinUI/Strings/zh-tw/Resources.resw @@ -2284,7 +2284,7 @@ 用量 - Cron + 排程工作 這部電腦 @@ -3906,13 +3906,13 @@ 排程 - + - + - + Cron @@ -4577,4 +4577,907 @@ 進階 - + + + 即時 + + + 清除 + + + 此閘道目前正在處理的對話,依頻道分組。 + + + 當頻道已連線且有流量時,工作階段將顯示在此處。 + + + 開啟聊天 + + + 已啟用 + + + 已停用 + + + 預覽 + + + 語音預覽 + + + 已中斷連線 + + + 代理直接在閘道上執行的命令不受此限制。如果閘道在此電腦上,它們仍可能存取您的 Windows 檔案、剪貼簿和網路——請檢查閘道的設定。 + + + 所有代理 + + + {0} / {1} 個事件 + + + 建立任務 + + + 編輯任務 + + + 新任務 + + + 正在執行... + + + 儲存變更 + + + 新增項目 + + + 附加檔案 + + + 取消 + + + 無法附加檔案 + + + 無法連線到 {0} 的閘道 + +請確認閘道正在運行。 + + + 聊天啟動失敗: +{0} + + + 聊天已準備就緒;正在啟動您的首次對話… + + + 閘道已連線;聊天介面仍在載入中。 + + + 閘道配對未完成。請開啟連線設定以完成配對。 + + + 無效的閘道 URL:{0} + + + 確定 + + + 開啟連線設定以完成與閘道的配對。 + + + 開啟語音設定 + + + 等待 {0} 的聊天逾時。請在閘道準備就緒後重試。 + + + 等待閘道操作員交握逾時。請在閘道準備就緒後重試。 + + + 需要先安裝語音轉文字模型才能使用語音輸入。是否要開啟語音設定進行安裝? + + + 需要語音模型 + + + WebView2 初始化失敗: +{0} + + + 正在套用… + + + 等待核准 + + + 🔐 等待核准 — 核准後請點擊連線 + + + 🔐 等待閘道核准 + + + 連線 + + + ✓ 已連線 + + + ✓ 已連線到 {0} + + + 正在連線… + + + 連線(核准後) + + + 已停用 + + + 已中斷連線 + + + 輸入閘道 URL + + + 沒有閘道 + + + 正在重新連線… + + + 已拒絕 + + + 正在啟動 SSH 通道… + + + 在 {0} 上 + + + 1 個用戶端 + + + {0} 個用戶端 + + + {0}/{1} 個頻道 + + + {0}/{1} 個頻道 + + + 今日 ${0} + + + 今日 $0.00 + + + 共用權杖 + + + 點擊以複製共用權杖 + + + 透過 SSH 通道 + + + 本機 + + + Tailscale + + + 區域網路 + + + 遠端 + + + 使用中 · {0} 個工作階段 + + + 使用中 · 1 個工作階段 + + + 使用中 · 目前無工作階段 + + + 已中斷連線 + + + 連線中… + + + 重新連線中… + + + 節點使用中 · {0} 項功能 + + + 節點使用中 · 1 項功能 + + + 節點使用中 · 未啟用任何功能 + + + 等待配對核准 + + + 配對遭拒 + + + 已限流 + + + 節點錯誤 + + + 節點模式已停用 + + + 未啟用任何功能。請在權限中選擇要共用的內容。 + + + 等待閘道主機上的核准。 + + + 配對遭拒。請從新增閘道重新配對。 + + + 被閘道限流。將在冷卻後重試。 + + + 節點回報了一個錯誤。 + + + 未提供任何功能 + + + 提供 1 項功能:{0} + + + 提供 {0} 項功能:{1} + + + 已連線 + + + 連線中… + + + 等待核准 + + + 正在中斷連線… + + + 連線 + + + 開啟儀表板 + + + 中斷連線 + + + 編輯 + + + 移除 + + + 透過 SSH + + + 已儲存的閘道 (1) + + + 已儲存的閘道 ({0}) + + + 剛才 + + + {0}分鐘前 + + + {0}小時前 + + + {0}天前 + + + {0}個月前 + + + {0}年前 + + + 重新配對此閘道: + + + 等待核准: + + + 協助我們修復 SSH 通道: + + + 協助我們修復此連線: + + + 從閘道主機取得新的設定碼。 + + + 或在下方貼上新的直接權杖。 + + + 使用以下命令在閘道主機上核准此用戶端。 + + + 核准後,按一下連線以繼續。 + + + 確認主機上的 SSH 可存取。 + + + 如果通道已停止,請在下方重新啟動。 + + + 檢查主機上的閘道記錄。 + + + 如果閘道部分運作中,請開啟其儀表板。 + + + 編輯閘道設定以變更 URL 或權杖。 + + + 檢查閘道是否在主機上執行。 + + + 檢查您是否在相同的網路或 VPN 上。 + + + 如果使用 SSH 通道:確認其已啟動。 + + + SSH 通道已中斷。 + + + 正在測試連線… + + + 閘道可存取 + + + 閘道回應代碼為 {0} + + + 無法存取閘道 + + + 輸入閘道 URL + + + 連線中… + + + 正在啟動 SSH 通道… + + + 需要對 {0} 進行配對核准。 + + + 已連線到 {0}。 + + + SSH 遠端連接埠必須在 1–65535 之間 + + + SSH 本機連接埠必須在 1–65535 之間 + + + 通道重新啟動已觸發。 + + + 通道重新啟動失敗:{0} + + + 已重新配對。重新連線中… + + + 無法套用代碼。 + + + 請貼上設定碼。 + + + 正在套用… + + + 已套用 — 閘道:{0} + + + 設定碼無效 + + + URL 無效 + + + 連線失敗 + + + 未知錯誤 + + + 閘道:{0} + + + (未指定) + + + (無權杖) + + + 權杖:{0} + + + 按下開始掃描以在您的網路上尋找閘道。 + + + 正在掃描您的網路… + + + 未在您的網路上找到閘道。 + + + 在您的網路上發現 ({0}) + + + 掃描失敗:{0} + + + 停止 + + + 掃描 + + + 新增 + + + 選擇上方發現的閘道進行連線。 + + + 移除閘道? + + + 這將移除此電腦上的 {0} 及其認證。 + + + 取消 + + + 連線失敗 + + + 閘道連線失敗。 + + + 1 項核准等待您處理 + + + {0} 項核准等待您處理 + + + 裝置 · {0} + + + 節點 · {0} + + + ⚠️ 修復請求 + + + 核准 + + + 拒絕 + + + 核准配對請求 + + + 拒絕配對請求 + + + {0} + +從新增閘道流程中貼上新的設定碼。 + + + {0} + +您的裝置需要在閘道主機上獲得核准。 + + + {0} + +此閘道需要密碼驗證。 + + + {0} + +閘道可能需要不同版本的認證協定。 + + + {0} + +請檢查您的連線設定並重試。 + + + 引導 + + + 共用權杖 + + + 裝置權杖 + + + 未知 + + + 等待閘道連線完成逾時。 + + + 此頻道需要 macOS 主機,無法從 Windows 電腦進行設定。 + + + 替換憑證 + + + 設定 + + + 將此裝置與頻道取消連結。掌描新的 QR 碼以重新連線——您的帳戶仍會在手機上保持配對。 + + + 暫時暫停頻道——憑證會被保留,以便您可以重新啟動。或完全中斷連線以清除憑證。 + + + 啟動頻道——它將使用已儲存的憑證開始處理訊息。或完全中斷連線以清除憑證。 + + + 暫停頻道——憑證會被保留,以便您可以重新啟動。 + + + 啟動頻道——它將使用已儲存的憑證開始處理訊息。 + + + 啟動 + + + 停止 + + + 登出 + + + 中斷連線並清除憑證 + + + 控制 + + + WhatsApp 已連結裝置說明 → + + + Signal 已連結裝置說明 → + + + 如何建立 Telegram 機器人 → + + + 如何建立 Discord webhook → + + + 如何新增 Google Chat webhook → + + + Slack 應用程式控制台 → + + + 關於 Nostr → + + + 關於 macOS「訊息」→ + + + 連結您的 WhatsApp 手機 + + + 點擊下方「連結」區段中的 "Show QR"。 + + + 在手機上:WhatsApp → 設定 → 已連結裝置 → 連結裝置。 + + + 掌描此處顯示的 QR 碼。 + + + 連結您的 Signal 手機 + + + 點擊下方「連結」區段中的 "Show QR"。 + + + 在手機上:Signal → 設定 → 已連結裝置 → 連結新裝置。 + + + 掌描此處顯示的 QR 碼。 + + + 透過機器人連接 Telegram + + + 開啟 Telegram 並向 @BotFather 傳送訊息。 + + + 傳送 /newbot 並按照提示操作。最後複製機器人權杖。 + + + 將權杖貼到下方的設定表單中。 + + + 點擊 "Save and start"。頻道將自動啟動。 + + + 透過 webhook 連接 Discord + + + 開啟您的 Discord 伺服器設定 → 整合 → Webhooks。 + + + 點擊 "New Webhook",為其命名,然後複製 webhook URL。 + + + 將 URL 貼到下方的設定表單中。 + + + 點擊 "Save and start"。 + + + 透過 webhook 連接 Google Chat + + + 在 Google Chat 中,開啟聊天室 → 管理 webhook → 新增 webhook。 + + + 複製 webhook URL。 + + + 將 URL 貼到下方的設定表單中。 + + + 點擊 "Save and start"。 + + + 透過應用程式連接 Slack + + + 在 api.slack.com/apps 上建立 Slack 應用程式並將其安裝到您的工作區。 + + + 複製機器人權杖 (xoxb-…) 和簽署密鑰。 + + + 將兩者貼到下方的設定表單中。 + + + 點擊 "Save and start"。 + + + 透過中繼連接 Nostr + + + 產生或貼上私鑰 (nsec)。 + + + 選擇一個或多個中繼 URL(例如 wss://relay.damus.io)。 + + + 將兩者貼到下方的設定表單中。 + + + 點擊 "Save and start"。 + + + iMessage 僅適用於 macOS + + + iMessage 讀取本機 Messages.app 資料庫,該資料庫僅存在於 macOS 上。 + + + 若要將 iMessage 與 OpenClaw 搭配使用,請在 Mac 上執行閘道,而非此 Windows 主機。 + + + 此列表中的所有其他頻道都可以在 Windows 託管的閘道上正常使用。 + + + 連接此頻道 + + + "{0}" 是一個外掛頻道。請參閱其文件以了解所需欄位。 + + + 使用下方「設定」區段中的 "Open Config page" 在 channels.{0} 下新增設定。 + + + 儲存設定;OpenClaw 將自動啟動頻道。 + + + 機器人權杖 + + + Webhook 網址 + + + 簽署密鑰 + + + 私鑰 (nsec) + + + 中繼 URL + + + 從 @BotFather (/newbot) 取得。 + + + 伺服器設定 → 整合 → Webhooks → New Webhook。 + + + 開啟聊天室 → 管理 webhook → 新增 webhook。 + + + 來自您 Slack 應用程式的 OAuth 權杖。 + + + Basic Information → App Credentials。 + + + 每行一個。 + + + 儲存變更 + + + 儲存並啟動 + + + 開啟設定頁面 + + + 在閘道設定頁面中編輯此頻道的設定。 + + + 按照上述步驟操作後,儲存設定以啟動頻道。 + + + 未連線 + + + 請先連線到閘道,然後再儲存頻道設定。 + + + 缺少欄位 + + + {0} 為必填項。 + + + 正在儲存 {0}… + + + 正在寫入 {0} 個欄位並啟用頻道。 + + + 無法載入閘道設定 + + + 閘道未傳回其目前設定——沒有它無法安全儲存。請嘗試重新整理並再次儲存。 + + + 閘道設定在儲存過程中被清除。請嘗試重新整理並再次儲存。 + + + {0} 的儲存被封鎖 + + + 閘道未回應。 + + + {0} 的儲存失敗 + + + 您的閘道設定已在其他位置變更(例如,從設定頁面)。我們已重新整理快取——請再次嘗試儲存。詳細資訊:{0} + + + {0} 如果這看起來像是線路格式不符,請開啟設定頁面進行直接 JSON 編輯。 + + + {0} 設定已儲存 + + + 正在等待閘道確認頻道已執行… + + + WSL 閘道 + + + 開啟 shell,或在 WSL 中管理本機閘道服務。 + + + 終端機 + + + 啟動 + + + 停止 + + + 重新啟動 + + + 開啟終端機 + + + 開啟終端機 + + + 在瀏覽器中開啟儀表板 + + + 開啟儀表板 + + + 中斷連線/重新連線 + + + 中斷連線或重新連線 + + + 開啟終端機 + + + 開啟終端機 + + + 在 WSL 中執行 openclaw gateway start + + + 啟動 WSL 閘道 + + + 在 WSL 中執行 openclaw gateway stop + + + 停止 WSL 閘道 + + + 在 WSL 中執行 openclaw gateway restart + + + 重新啟動 WSL 閘道 + + diff --git a/src/OpenClaw.Tray.WinUI/Windows/ConnectionStatusWindow.xaml.cs b/src/OpenClaw.Tray.WinUI/Windows/ConnectionStatusWindow.xaml.cs index 04c4354e..be7d37e5 100644 --- a/src/OpenClaw.Tray.WinUI/Windows/ConnectionStatusWindow.xaml.cs +++ b/src/OpenClaw.Tray.WinUI/Windows/ConnectionStatusWindow.xaml.cs @@ -86,18 +86,18 @@ private void OnManagerStateChanged(object? sender, GatewayConnectionSnapshot sna // Update connect button and status based on state if (snapshot.OverallState == OverallConnectionState.PairingRequired) { - ConnectButton.Content = "Connect (once approved)"; - SetupCodeResult.Text = "🔐 Awaiting approval from gateway"; - DirectConnectResult.Text = "🔐 Awaiting approval — approve then click Connect"; + ConnectButton.Content = LocalizationHelper.GetString("ConnectionStatus_ConnectOnceApproved"); + SetupCodeResult.Text = LocalizationHelper.GetString("ConnectionStatus_AwaitingApprovalFromGateway"); + DirectConnectResult.Text = LocalizationHelper.GetString("ConnectionStatus_AwaitingApprovalApproveThenConnect"); } else if (snapshot.OverallState is OverallConnectionState.Connected or OverallConnectionState.Ready) { - ConnectButton.Content = "Connect"; - DirectConnectResult.Text = "✓ Connected"; + ConnectButton.Content = LocalizationHelper.GetString("ConnectionStatus_Connect"); + DirectConnectResult.Text = LocalizationHelper.GetString("ConnectionStatus_Connected"); } else { - ConnectButton.Content = "Connect"; + ConnectButton.Content = LocalizationHelper.GetString("ConnectionStatus_Connect"); } }); } @@ -137,7 +137,7 @@ private void RefreshStateMachine(GatewayConnectionSnapshot snapshot) { RoleConnectionState.Connected => $"✓ {elapsedStr} device={snapshot.OperatorDeviceId ?? "—"}", RoleConnectionState.Error => $"✗ {elapsedStr} — {snapshot.OperatorError ?? "unknown"}", - RoleConnectionState.PairingRequired => $"⏳ Awaiting approval", + RoleConnectionState.PairingRequired => $"⏳ {LocalizationHelper.GetString("ConnectionStatus_AwaitingApproval")}", _ => elapsedStr }; @@ -152,9 +152,9 @@ private void RefreshStateMachine(GatewayConnectionSnapshot snapshot) snapshot.NodeState is RoleConnectionState.PairingRequired or RoleConnectionState.PairingRejected, AmberBrush); NodeDetailText.Text = snapshot.NodeState switch { - RoleConnectionState.Disabled => "disabled", + RoleConnectionState.Disabled => LocalizationHelper.GetString("ConnectionStatus_Disabled"), RoleConnectionState.Error => snapshot.NodeError ?? "error", - RoleConnectionState.PairingRejected => "rejected", + RoleConnectionState.PairingRejected => LocalizationHelper.GetString("ConnectionStatus_Rejected"), _ => "" }; } @@ -175,7 +175,7 @@ private void RefreshGateways() { GatewayListPanel.Children.Add(new TextBlock { - Text = "No gateways", FontSize = 11, Foreground = DimTextBrush + Text = LocalizationHelper.GetString("ConnectionStatus_NoGateways"), FontSize = 11, Foreground = DimTextBrush }); return; } @@ -301,13 +301,13 @@ private async Task OnConnectAsync() if (!string.IsNullOrEmpty(code)) { ConnectButton.IsEnabled = false; - SetupCodeResult.Text = "Applying…"; + SetupCodeResult.Text = LocalizationHelper.GetString("ConnectionStatus_Applying"); try { var result = await _manager.ApplySetupCodeAsync(code); SetupCodeResult.Text = result.Outcome switch { - SetupCodeOutcome.Success => $"✓ Connected to {GatewayUrlHelper.SanitizeForDisplay(result.GatewayUrl ?? "")}", + SetupCodeOutcome.Success => string.Format(LocalizationHelper.GetString("ConnectionStatus_ConnectedTo"), GatewayUrlHelper.SanitizeForDisplay(result.GatewayUrl ?? "")), _ => $"✗ {result.ErrorMessage ?? result.Outcome.ToString()}" }; } @@ -319,7 +319,7 @@ private async Task OnConnectAsync() else { // Reconnect to active gateway - SetupCodeResult.Text = "Reconnecting…"; + SetupCodeResult.Text = LocalizationHelper.GetString("ConnectionStatus_Reconnecting"); await _manager.ReconnectAsync(); SetupCodeResult.Text = ""; } @@ -335,7 +335,7 @@ private async Task OnDisconnectClickAsync() { if (_manager == null) return; await _manager.DisconnectAsync(); - SetupCodeResult.Text = "Disconnected"; + SetupCodeResult.Text = LocalizationHelper.GetString("ConnectionStatus_Disconnected"); } private void OnDiagSshToggled(object sender, RoutedEventArgs e) @@ -357,7 +357,7 @@ private async Task OnDirectConnectAsync() var token = DirectTokenBox.Text?.Trim(); if (string.IsNullOrWhiteSpace(url)) { - DirectConnectResult.Text = "Enter a gateway URL"; + DirectConnectResult.Text = LocalizationHelper.GetString("ConnectionStatus_EnterGatewayUrl"); return; } @@ -377,7 +377,7 @@ private async Task OnDirectConnectAsync() sshConfig = new SshTunnelConfig(sshUser, sshHost, remotePort, localPort); } - DirectConnectResult.Text = useSsh ? "Starting SSH tunnel…" : "Connecting…"; + DirectConnectResult.Text = useSsh ? LocalizationHelper.GetString("ConnectionStatus_StartingSshTunnel") : LocalizationHelper.GetString("ConnectionStatus_Connecting"); try { await _manager.DisconnectAsync(); @@ -414,11 +414,11 @@ private async Task OnDirectConnectAsync() settings.SshTunnelLocalPort = sshConfig.LocalPort; settings.Save(); app.EnsureSshTunnelStarted(); - DirectConnectResult.Text = "Connecting…"; + DirectConnectResult.Text = LocalizationHelper.GetString("ConnectionStatus_Connecting"); } await _manager.ConnectAsync(recordId); - DirectConnectResult.Text = $"✓ Connected to {GatewayUrlHelper.SanitizeForDisplay(url)}"; + DirectConnectResult.Text = string.Format(LocalizationHelper.GetString("ConnectionStatus_ConnectedTo"), GatewayUrlHelper.SanitizeForDisplay(url)); } catch (Exception ex) { diff --git a/src/OpenClaw.Tray.WinUI/Windows/HubWindow.xaml b/src/OpenClaw.Tray.WinUI/Windows/HubWindow.xaml index bc75f9e4..2a757d2a 100644 --- a/src/OpenClaw.Tray.WinUI/Windows/HubWindow.xaml +++ b/src/OpenClaw.Tray.WinUI/Windows/HubWindow.xaml @@ -77,7 +77,7 @@ Tapped="OnTitleBarStatusTapped"> - diff --git a/tests/OpenClaw.Tray.Tests/LocalizationValidationTests.cs b/tests/OpenClaw.Tray.Tests/LocalizationValidationTests.cs index f52eae38..b3892f24 100644 --- a/tests/OpenClaw.Tray.Tests/LocalizationValidationTests.cs +++ b/tests/OpenClaw.Tray.Tests/LocalizationValidationTests.cs @@ -47,6 +47,8 @@ public class LocalizationValidationTests // VoiceOverlayWindow window-title key — matches the convention // for ChatWindow / HubWindow / CanvasWindow / TrayMenuWindow. "VoiceOverlayWindow_winexWindowEx_2.Title", + // Brand name — identical across all locales. + "ConnectionPage_TopologyTailscale", "PermissionsPage_TtsElevenLabsModel.PlaceholderText", "PermissionsPage_TtsProviderElevenLabs.Content", // Sample IDs / brand identifiers — same across locales. @@ -430,6 +432,8 @@ public void MojibakeDetector_AllowsLegitimateUnicode() { "Update_OK", "Onboarding_IncompleteSetup_Close", + "ChatPage_OK", + "ConnectionPage_ViaSSH", }; // Locales whose translations are allowed to remain identical to en-us