i18n: localize all MessageBox dialogs
The previous batch only covered XAML strings. The runtime MessageBox dialogs (errors, confirmations, info popups) stayed hardcoded in French, breaking immersion for non-FR users. Added ~15 keys to Strings.cs for the MessageBox bodies and titles: - error / launch error / confirm / info / patience / language change / release notes (titles) - launch failed / self-update failed / install failed / uninstall failed / uninstall confirm with version+folder+size / no release notes / fetch failed / clear cache confirm / deactivate license (short and detailed) / language restart (bodies) Some are parametrized (MsgLaunchFailed(detail), MsgUninstallConfirm (version, folder, size)) so the localized strings interpolate the runtime values cleanly across all 5 languages. Replaced every MessageBox.Show in MainViewModel, SettingsViewModel and LicenseDetailsDialog.xaml.cs to use these keys. The "Échec : " prefix in the cache-clear error was dropped — the error message alone is sufficient with Strings.MsgBoxError as the dialog title. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ using PSLauncher.Core.Configuration;
|
|||||||
using PSLauncher.Core.Downloads;
|
using PSLauncher.Core.Downloads;
|
||||||
using PSLauncher.Core.Installations;
|
using PSLauncher.Core.Installations;
|
||||||
using PSLauncher.Core.Licensing;
|
using PSLauncher.Core.Licensing;
|
||||||
|
using PSLauncher.Core.Localization;
|
||||||
using PSLauncher.Core.Manifests;
|
using PSLauncher.Core.Manifests;
|
||||||
using PSLauncher.Core.Process;
|
using PSLauncher.Core.Process;
|
||||||
using PSLauncher.Core.Updates;
|
using PSLauncher.Core.Updates;
|
||||||
@@ -338,8 +339,8 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Self-update failed");
|
_logger.LogError(ex, "Self-update failed");
|
||||||
MessageBox.Show($"Mise à jour du launcher échouée :\n\n{ex.Message}",
|
MessageBox.Show(Strings.MsgSelfUpdateFailed(ex.Message),
|
||||||
"Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
|
Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
StatusMessage = $"Erreur self-update : {ex.Message}";
|
StatusMessage = $"Erreur self-update : {ex.Message}";
|
||||||
IsBusy = false;
|
IsBusy = false;
|
||||||
}
|
}
|
||||||
@@ -463,15 +464,15 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Launch failed");
|
_logger.LogError(ex, "Launch failed");
|
||||||
MessageBox.Show($"Impossible de lancer la version :\n\n{ex.Message}",
|
MessageBox.Show(Strings.MsgLaunchFailed(ex.Message),
|
||||||
"Erreur de lancement", MessageBoxButton.OK, MessageBoxImage.Error);
|
Strings.MsgBoxLaunchError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallVersionAsync(VersionRowViewModel row)
|
private async Task InstallVersionAsync(VersionRowViewModel row)
|
||||||
{
|
{
|
||||||
if (row.Remote is null) return;
|
if (row.Remote is null) return;
|
||||||
if (IsBusy) { MessageBox.Show("Une autre opération est déjà en cours.", "Patience", MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
if (IsBusy) { MessageBox.Show(Strings.MsgBusy, Strings.MsgBoxPatience, MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
||||||
|
|
||||||
IsBusy = true;
|
IsBusy = true;
|
||||||
_activeRow = row;
|
_activeRow = row;
|
||||||
@@ -555,8 +556,8 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
row.ProgressDetail = null;
|
row.ProgressDetail = null;
|
||||||
row.ProgressPercent = 0;
|
row.ProgressPercent = 0;
|
||||||
MessageBox.Show(
|
MessageBox.Show(
|
||||||
$"Le téléchargement ou l'installation a échoué :\n\n{ex.Message}",
|
Strings.MsgInstallFailed(ex.Message),
|
||||||
"Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
|
Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
StatusMessage = $"Erreur : {ex.Message}";
|
StatusMessage = $"Erreur : {ex.Message}";
|
||||||
_toastService.ShowError($"Échec v{row.Version}", ex.Message);
|
_toastService.ShowError($"Échec v{row.Version}", ex.Message);
|
||||||
}
|
}
|
||||||
@@ -575,13 +576,13 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
|
|
||||||
var sizeStr = FormatSize(row.SizeBytes);
|
var sizeStr = FormatSize(row.SizeBytes);
|
||||||
var confirm = MessageBox.Show(
|
var confirm = MessageBox.Show(
|
||||||
$"Supprimer la version v{row.Version} ?\n\nDossier : {row.FolderPath}\nLibérera {sizeStr}.\n\nCette action est irréversible.",
|
Strings.MsgUninstallConfirm(row.Version, row.FolderPath, sizeStr),
|
||||||
"Confirmer la suppression",
|
Strings.MsgBoxConfirm,
|
||||||
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||||
|
|
||||||
if (confirm != MessageBoxResult.Yes) return;
|
if (confirm != MessageBoxResult.Yes) return;
|
||||||
|
|
||||||
if (IsBusy) { MessageBox.Show("Une autre opération est déjà en cours.", "Patience", MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
if (IsBusy) { MessageBox.Show(Strings.MsgBusy, Strings.MsgBoxPatience, MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
||||||
|
|
||||||
IsBusy = true;
|
IsBusy = true;
|
||||||
row.State = VersionRowState.Uninstalling;
|
row.State = VersionRowState.Uninstalling;
|
||||||
@@ -596,7 +597,7 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
_logger.LogError(ex, "Uninstall failed for {Version}", row.Version);
|
_logger.LogError(ex, "Uninstall failed for {Version}", row.Version);
|
||||||
row.State = VersionRowState.InstalledIdle;
|
row.State = VersionRowState.InstalledIdle;
|
||||||
MessageBox.Show($"Suppression échouée : {ex.Message}", "Erreur",
|
MessageBox.Show(Strings.MsgUninstallFailed(ex.Message), Strings.MsgBoxError,
|
||||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
StatusMessage = $"Erreur : {ex.Message}";
|
StatusMessage = $"Erreur : {ex.Message}";
|
||||||
}
|
}
|
||||||
@@ -611,8 +612,8 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
var url = row.Remote?.ReleaseNotesUrl;
|
var url = row.Remote?.ReleaseNotesUrl;
|
||||||
if (string.IsNullOrEmpty(url))
|
if (string.IsNullOrEmpty(url))
|
||||||
{
|
{
|
||||||
MessageBox.Show("Aucune release note disponible pour cette version.",
|
MessageBox.Show(Strings.MsgNoReleaseNotes,
|
||||||
"Release notes", MessageBoxButton.OK, MessageBoxImage.Information);
|
Strings.MsgBoxReleaseNotes, MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string notes;
|
string notes;
|
||||||
@@ -620,8 +621,8 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogWarning(ex, "Failed to fetch release notes");
|
_logger.LogWarning(ex, "Failed to fetch release notes");
|
||||||
MessageBox.Show($"Impossible de récupérer les release notes :\n{ex.Message}",
|
MessageBox.Show(Strings.MsgReleaseNotesFetchFailed(ex.Message),
|
||||||
"Erreur", MessageBoxButton.OK, MessageBoxImage.Warning);
|
Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using PSLauncher.Core.Configuration;
|
using PSLauncher.Core.Configuration;
|
||||||
using PSLauncher.Core.Downloads;
|
using PSLauncher.Core.Downloads;
|
||||||
using PSLauncher.Core.Licensing;
|
using PSLauncher.Core.Licensing;
|
||||||
|
using PSLauncher.Core.Localization;
|
||||||
using PSLauncher.Models;
|
using PSLauncher.Models;
|
||||||
|
|
||||||
namespace PSLauncher.App.ViewModels;
|
namespace PSLauncher.App.ViewModels;
|
||||||
@@ -185,8 +186,8 @@ public sealed partial class SettingsViewModel : ObservableObject
|
|||||||
private void ClearCache()
|
private void ClearCache()
|
||||||
{
|
{
|
||||||
var confirm = MessageBox.Show(
|
var confirm = MessageBox.Show(
|
||||||
"Vider le cache de téléchargements ? Les téléchargements en cours/pause seront perdus.",
|
Strings.MsgClearCacheConfirm,
|
||||||
"Confirmer",
|
Strings.MsgBoxConfirm,
|
||||||
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||||
if (confirm != MessageBoxResult.Yes) return;
|
if (confirm != MessageBoxResult.Yes) return;
|
||||||
|
|
||||||
@@ -201,7 +202,7 @@ public sealed partial class SettingsViewModel : ObservableObject
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "ClearCache failed");
|
_logger.LogError(ex, "ClearCache failed");
|
||||||
MessageBox.Show("Échec : " + ex.Message, "Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(ex.Message, Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,8 +233,8 @@ public sealed partial class SettingsViewModel : ObservableObject
|
|||||||
// la nouvelle langue. Plutôt que de demander à l'utilisateur de fermer/rouvrir,
|
// la nouvelle langue. Plutôt que de demander à l'utilisateur de fermer/rouvrir,
|
||||||
// on spawne un cmd qui attend la fermeture puis relance.
|
// on spawne un cmd qui attend la fermeture puis relance.
|
||||||
var ok = MessageBox.Show(
|
var ok = MessageBox.Show(
|
||||||
"Le launcher va redémarrer pour appliquer la nouvelle langue.",
|
Strings.MsgLanguageRestart,
|
||||||
"Changement de langue",
|
Strings.MsgBoxLanguageChange,
|
||||||
MessageBoxButton.OKCancel, MessageBoxImage.Information, MessageBoxResult.OK);
|
MessageBoxButton.OKCancel, MessageBoxImage.Information, MessageBoxResult.OK);
|
||||||
if (ok == MessageBoxResult.OK)
|
if (ok == MessageBoxResult.OK)
|
||||||
{
|
{
|
||||||
@@ -263,8 +264,8 @@ public sealed partial class SettingsViewModel : ObservableObject
|
|||||||
private void DeactivateLicense()
|
private void DeactivateLicense()
|
||||||
{
|
{
|
||||||
var confirm = MessageBox.Show(
|
var confirm = MessageBox.Show(
|
||||||
"Désactiver la license sur cette machine ?\nTu pourras la réactiver avec ta clé.",
|
Strings.MsgDeactivateLicenseConfirm,
|
||||||
"Confirmer",
|
Strings.MsgBoxConfirm,
|
||||||
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
|
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
|
||||||
if (confirm != MessageBoxResult.Yes) return;
|
if (confirm != MessageBoxResult.Yes) return;
|
||||||
_licenseService.Clear();
|
_licenseService.Clear();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using PSLauncher.Core.Licensing;
|
using PSLauncher.Core.Licensing;
|
||||||
|
using PSLauncher.Core.Localization;
|
||||||
using PSLauncher.Models;
|
using PSLauncher.Models;
|
||||||
|
|
||||||
namespace PSLauncher.App.Views;
|
namespace PSLauncher.App.Views;
|
||||||
@@ -66,10 +67,8 @@ public partial class LicenseDetailsDialog : Window
|
|||||||
private void OnDeactivate(object sender, RoutedEventArgs e)
|
private void OnDeactivate(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var confirm = MessageBox.Show(
|
var confirm = MessageBox.Show(
|
||||||
"Désactiver la license sur cette machine ?\n\n" +
|
Strings.MsgDeactivateLicenseDetailedConfirm,
|
||||||
"Tu pourras la réactiver plus tard avec ta clé. " +
|
Strings.MsgBoxConfirm,
|
||||||
"Les versions déjà installées restent utilisables.",
|
|
||||||
"Confirmer la désactivation",
|
|
||||||
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
|
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
|
||||||
if (confirm != MessageBoxResult.Yes) return;
|
if (confirm != MessageBoxResult.Yes) return;
|
||||||
_licenseService.Clear();
|
_licenseService.Clear();
|
||||||
|
|||||||
@@ -152,4 +152,110 @@ public static class Strings
|
|||||||
// ==================== UPDATE ====================
|
// ==================== UPDATE ====================
|
||||||
public static string UpdateAvailableTitle => T("Mise à jour disponible", "Update available", "有可用更新", "มีการอัปเดต", "تحديث متاح");
|
public static string UpdateAvailableTitle => T("Mise à jour disponible", "Update available", "有可用更新", "มีการอัปเดต", "تحديث متاح");
|
||||||
public static string UpdateDownload => T("⬇ Télécharger", "⬇ Download", "⬇ 下载", "⬇ ดาวน์โหลด", "⬇ تنزيل");
|
public static string UpdateDownload => T("⬇ Télécharger", "⬇ Download", "⬇ 下载", "⬇ ดาวน์โหลด", "⬇ تنزيل");
|
||||||
|
|
||||||
|
// ==================== MESSAGEBOX TITLES ====================
|
||||||
|
public static string MsgBoxError => T("Erreur", "Error", "错误", "ข้อผิดพลาด", "خطأ");
|
||||||
|
public static string MsgBoxLaunchError => T("Erreur de lancement", "Launch error", "启动错误", "เปิดใช้งานล้มเหลว", "خطأ في التشغيل");
|
||||||
|
public static string MsgBoxConfirm => T("Confirmer", "Confirm", "确认", "ยืนยัน", "تأكيد");
|
||||||
|
public static string MsgBoxInfo => T("Information", "Information", "信息", "ข้อมูล", "معلومة");
|
||||||
|
public static string MsgBoxPatience => T("Patience", "Please wait", "请稍候", "โปรดรอ", "يرجى الانتظار");
|
||||||
|
public static string MsgBoxLanguageChange => T("Changement de langue", "Language change", "更改语言", "เปลี่ยนภาษา", "تغيير اللغة");
|
||||||
|
public static string MsgBoxReleaseNotes => T("Release notes", "Release notes", "版本说明", "บันทึกการเปลี่ยนแปลง", "ملاحظات الإصدار");
|
||||||
|
|
||||||
|
// ==================== MESSAGEBOX MESSAGES ====================
|
||||||
|
public static string MsgBusy => T(
|
||||||
|
"Une autre opération est déjà en cours.",
|
||||||
|
"Another operation is already in progress.",
|
||||||
|
"另一个操作正在进行中。",
|
||||||
|
"มีการดำเนินการอื่นอยู่แล้ว",
|
||||||
|
"هناك عملية أخرى قيد التنفيذ بالفعل."
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgLaunchFailed(string detail) => T(
|
||||||
|
$"Impossible de lancer la version :\n\n{detail}",
|
||||||
|
$"Could not launch the version:\n\n{detail}",
|
||||||
|
$"无法启动该版本:\n\n{detail}",
|
||||||
|
$"ไม่สามารถเปิดเวอร์ชันนี้ได้:\n\n{detail}",
|
||||||
|
$"تعذر تشغيل النسخة:\n\n{detail}"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgSelfUpdateFailed(string detail) => T(
|
||||||
|
$"Mise à jour du launcher échouée :\n\n{detail}",
|
||||||
|
$"Launcher update failed:\n\n{detail}",
|
||||||
|
$"启动器更新失败:\n\n{detail}",
|
||||||
|
$"การอัปเดต Launcher ล้มเหลว:\n\n{detail}",
|
||||||
|
$"فشل تحديث المُشغِّل:\n\n{detail}"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgInstallFailed(string detail) => T(
|
||||||
|
$"Le téléchargement ou l'installation a échoué :\n\n{detail}",
|
||||||
|
$"Download or installation failed:\n\n{detail}",
|
||||||
|
$"下载或安装失败:\n\n{detail}",
|
||||||
|
$"การดาวน์โหลดหรือติดตั้งล้มเหลว:\n\n{detail}",
|
||||||
|
$"فشل التنزيل أو التثبيت:\n\n{detail}"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgUninstallFailed(string detail) => T(
|
||||||
|
$"Suppression échouée : {detail}",
|
||||||
|
$"Uninstall failed: {detail}",
|
||||||
|
$"卸载失败:{detail}",
|
||||||
|
$"การถอนการติดตั้งล้มเหลว: {detail}",
|
||||||
|
$"فشل الإزالة: {detail}"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgUninstallConfirm(string version, string folder, string size) => T(
|
||||||
|
$"Supprimer la version v{version} ?\n\nDossier : {folder}\nLibérera {size}.\n\nCette action est irréversible.",
|
||||||
|
$"Uninstall version v{version}?\n\nFolder: {folder}\nWill free {size}.\n\nThis action is irreversible.",
|
||||||
|
$"卸载版本 v{version}?\n\n文件夹:{folder}\n将释放 {size}。\n\n此操作不可逆。",
|
||||||
|
$"ถอนการติดตั้งเวอร์ชัน v{version}?\n\nโฟลเดอร์: {folder}\nจะคืนพื้นที่ {size}\n\nการกระทำนี้ไม่สามารถย้อนกลับได้",
|
||||||
|
$"إلغاء تثبيت النسخة v{version}؟\n\nالمجلد: {folder}\nسيتم تحرير {size}.\n\nهذا الإجراء لا رجعة فيه."
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgNoReleaseNotes => T(
|
||||||
|
"Aucune release note disponible pour cette version.",
|
||||||
|
"No release notes available for this version.",
|
||||||
|
"此版本没有可用的版本说明。",
|
||||||
|
"ไม่มีบันทึกการเปลี่ยนแปลงสำหรับเวอร์ชันนี้",
|
||||||
|
"لا توجد ملاحظات إصدار متاحة لهذه النسخة."
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgReleaseNotesFetchFailed(string detail) => T(
|
||||||
|
$"Impossible de récupérer les release notes :\n{detail}",
|
||||||
|
$"Could not fetch release notes:\n{detail}",
|
||||||
|
$"无法获取版本说明:\n{detail}",
|
||||||
|
$"ไม่สามารถดึงบันทึกการเปลี่ยนแปลงได้:\n{detail}",
|
||||||
|
$"تعذر جلب ملاحظات الإصدار:\n{detail}"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgClearCacheConfirm => T(
|
||||||
|
"Vider le cache de téléchargements ? Les téléchargements en cours/pause seront perdus.",
|
||||||
|
"Clear the download cache? In-progress / paused downloads will be lost.",
|
||||||
|
"清空下载缓存?正在进行或暂停的下载将丢失。",
|
||||||
|
"ล้างแคชดาวน์โหลด? การดาวน์โหลดที่กำลังดำเนินการ/หยุดชั่วคราวจะสูญหาย",
|
||||||
|
"مسح ذاكرة التخزين المؤقت للتنزيلات؟ ستفقد التنزيلات قيد التقدم أو الموقوفة مؤقتًا."
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgDeactivateLicenseConfirm => T(
|
||||||
|
"Désactiver la license sur cette machine ?\nTu pourras la réactiver avec ta clé.",
|
||||||
|
"Deactivate the license on this machine?\nYou can reactivate it later with your key.",
|
||||||
|
"在此机器上停用许可证?\n您可以稍后用密钥重新激活。",
|
||||||
|
"ปิดใช้งานใบอนุญาตบนเครื่องนี้?\nคุณสามารถเปิดใช้งานใหม่ในภายหลังด้วยคีย์ของคุณ",
|
||||||
|
"إلغاء تنشيط الترخيص على هذا الجهاز؟\nيمكنك إعادة تنشيطه لاحقًا بمفتاحك."
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgDeactivateLicenseDetailedConfirm => T(
|
||||||
|
"Désactiver la license sur cette machine ?\n\nTu pourras la réactiver plus tard avec ta clé. Les versions déjà installées restent utilisables.",
|
||||||
|
"Deactivate the license on this machine?\n\nYou can reactivate it later with your key. Already-installed versions remain usable.",
|
||||||
|
"在此机器上停用许可证?\n\n您可以稍后用密钥重新激活。已安装的版本仍可使用。",
|
||||||
|
"ปิดใช้งานใบอนุญาตบนเครื่องนี้?\n\nคุณสามารถเปิดใช้งานใหม่ในภายหลังด้วยคีย์ของคุณ เวอร์ชันที่ติดตั้งแล้วยังคงใช้งานได้",
|
||||||
|
"إلغاء تنشيط الترخيص على هذا الجهاز؟\n\nيمكنك إعادة تنشيطه لاحقًا بمفتاحك. تظل النسخ المثبتة قابلة للاستخدام."
|
||||||
|
);
|
||||||
|
|
||||||
|
public static string MsgLanguageRestart => T(
|
||||||
|
"Le launcher va redémarrer pour appliquer la nouvelle langue.",
|
||||||
|
"The launcher will restart to apply the new language.",
|
||||||
|
"启动器将重启以应用新语言。",
|
||||||
|
"Launcher จะรีสตาร์ทเพื่อใช้ภาษาใหม่",
|
||||||
|
"سيتم إعادة تشغيل المُشغِّل لتطبيق اللغة الجديدة."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user