feat(i18n): wrap all user-facing strings in TailscaleWidget.qml with I18n.tr (strategy A)

- header, details, exit node prefix/none, invalid hostname, copied (with .arg), all formatError toasts
- Glyph literals ("×", "↗", "—") left as-is (decorative, not linguistic)
- "tailscalectl" toast titles kept as technical IDs
- All call sites now go through I18n for future translation
- Tests unaffected (still green)

Written by AI agent working for @jtmorris. Model: grok-build-0.1.
This commit is contained in:
Vybe (Coding Agent) 2026-05-24 20:57:49 +00:00
parent 7942bc3471
commit cb280d1e4e

View file

@ -35,7 +35,7 @@ PluginComponent {
if (code !== 0) {
var action = root.isConnected ? "disconnect" : "connect";
var detail = toggleProcess.stderr.text.trim();
ToastService.showError("tailscalectl", TailscaleLib.formatError(action, detail));
ToastService.showError("tailscalectl", I18n.tr(TailscaleLib.formatError(action, detail)));
}
root.refreshStatus();
}
@ -48,7 +48,7 @@ PluginComponent {
onExited: (code, status) => {
if (code === 0) {
ToastService.showInfo(TailscaleLib.getStrings().copied(root._copyText))
ToastService.showInfo(I18n.tr(TailscaleLib.getStrings().copied).arg(root._copyText))
} else {
root._copyIndex += 1
root._runNextCopy()
@ -66,7 +66,7 @@ PluginComponent {
onExited: (code, status) => {
if (code !== 0) {
var detail = exitNodeProcess.stderr.text.trim();
ToastService.showError("tailscalectl", TailscaleLib.formatError("set", detail));
ToastService.showError("tailscalectl", I18n.tr(TailscaleLib.formatError("set", detail)));
}
root.refreshStatus();
}
@ -91,7 +91,7 @@ PluginComponent {
root.tailscaleIP = ""
root.currentExitNode = ""
root.peers = []
ToastService.showError("tailscalectl", TailscaleLib.formatError("status"))
ToastService.showError("tailscalectl", I18n.tr(TailscaleLib.formatError("status")))
}
const cmd = TailscaleLib.commandForPendingAction(statusCheck._pendingAction, root.isConnected);
@ -115,7 +115,7 @@ PluginComponent {
function setExitNode(hostname) {
const cmd = TailscaleLib.makeExitNodeCommand(hostname)
if (!cmd) {
ToastService.showError("tailscalectl", TailscaleLib.getStrings().invalidExitNodeHostname)
ToastService.showError("tailscalectl", I18n.tr(TailscaleLib.getStrings().invalidExitNodeHostname))
return
}
exitNodeProcess.command = cmd
@ -131,7 +131,7 @@ PluginComponent {
function _runNextCopy() {
const cmds = TailscaleLib.getClipboardCommands(root._copyText)
if (root._copyIndex >= cmds.length) {
ToastService.showError("tailscalectl", TailscaleLib.formatError("clipboard"))
ToastService.showError("tailscalectl", I18n.tr(TailscaleLib.formatError("clipboard")))
return
}
copyProcess.command = cmds[root._copyIndex]
@ -140,8 +140,8 @@ PluginComponent {
popoutContent: Component {
PopoutComponent {
headerText: "Tailscale"
detailsText: root.isConnected ? TailscaleLib.getStrings().connected : TailscaleLib.getStrings().disconnected
headerText: I18n.tr(TailscaleLib.getStrings().header)
detailsText: root.isConnected ? I18n.tr(TailscaleLib.getStrings().connected) : I18n.tr(TailscaleLib.getStrings().disconnected)
showCloseButton: true
Item {
@ -188,7 +188,7 @@ PluginComponent {
Item { width: 1; height: 1; Layout.fillWidth: true }
StyledText {
text: TailscaleLib.getStrings().exitNodePrefix + (root.currentExitNode || TailscaleLib.getStrings().none)
text: I18n.tr(TailscaleLib.getStrings().exitNodePrefix) + (root.currentExitNode || I18n.tr(TailscaleLib.getStrings().none))
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter