Preserve literal plugin routing labels

Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
Loren Eteval
2026-08-12 12:20:15 +08:00
parent 2782e9247a
commit b8ad90ede3
7 changed files with 29 additions and 6 deletions
+8 -1
View File
@@ -1048,7 +1048,6 @@ TRANSLATION = {
},
"Routing": {
"source": [
"Furious.Plugins.Official.Xray.Plugin",
"Furious.TrayActions.Routing"
],
"RU": "Маршрутизация",
@@ -2147,5 +2146,13 @@ TRANSLATION = {
"RU": "Управление файлами ресурсов Xray-core...",
"ZH": "管理Xray-core资源文件...",
"isReviewed": "True"
},
"Edit Routing...": {
"source": [
"Furious.Plugins.Official.Xray.Plugin"
],
"RU": "Редактировать маршрут...",
"ZH": "编辑路由...",
"isReviewed": "True"
}
}
+1
View File
@@ -32,6 +32,7 @@ class PluginRouting:
id: str
displayName: str
separatorBefore: bool = False
translatable: bool = False
class FuriousPlugin:
+2 -1
View File
@@ -83,7 +83,8 @@ class Hysteria1Plugin(FuriousPlugin):
def routingOptions(self, config=None):
"""Return the routing modes supported by Hysteria 1."""
return tuple(
PluginRouting(routing.value, routing.value) for routing in AppBuiltinRouting
PluginRouting(routing.value, routing.value, translatable=True)
for routing in AppBuiltinRouting
)
def startCore(
+6 -2
View File
@@ -161,7 +161,7 @@ class XrayPlugin(FuriousPlugin):
def createManagementActions(self, parent=None, **kwargs):
"""Create Xray routing and asset-management actions."""
# These modules require a fully initialized Furious.Qt package.
from Furious.Qt import AppQAction, AppQSeperator
from Furious.Qt import AppQAction, AppQSeperator, bootstrapIcon
from Furious.Qt import gettext as _
from .UserRoutingWindow import UserRoutingWindow
@@ -172,7 +172,8 @@ class XrayPlugin(FuriousPlugin):
return (
AppQAction(
_('Routing'),
_('Edit Routing...'),
icon=bootstrapIcon('signpost.svg'),
callback=routingEditor.show,
),
AppQSeperator(),
@@ -188,14 +189,17 @@ class XrayPlugin(FuriousPlugin):
PluginRouting(
AppBuiltinRouting.BypassMainlandChina.value,
AppBuiltinRouting.BypassMainlandChina.value,
translatable=True,
),
PluginRouting(
AppBuiltinRouting.Global.value,
AppBuiltinRouting.Global.value,
translatable=True,
),
PluginRouting(
AppBuiltinRouting.Custom.value,
AppBuiltinRouting.Custom.value,
translatable=True,
),
]
enabledProfiles = tuple(
+3 -1
View File
@@ -67,7 +67,9 @@ class ExamplePlugin(FuriousPlugin):
supported by the given configuration. The tray Routing submenu follows the
active server's plugin and is hidden when that plugin returns no routing modes.
The host validates the current setting and falls back to the plugin's first
option before starting its core.
option before starting its core. Routing display names are treated as literal
text by default; set `translatable=True` only when the display name is an
application translation key. User-provided labels should remain literal.
Configuration classes should subclass `ConfigFactory` and implement its table
display, proxy endpoint, validity, serialization, and URI methods. Core process
+4
View File
@@ -228,6 +228,10 @@ class PluginRegistry:
raise TypeError(
'plugin routing option display name must be a string'
)
if not isinstance(option.translatable, bool):
raise TypeError(
'plugin routing option translatable flag must be a boolean'
)
optionId = option.id
if optionId in optionIds:
+5 -1
View File
@@ -92,7 +92,11 @@ class RoutingAction(AppQAction):
actions.append(
RoutingChildAction(
_(option.displayName),
(
_(option.displayName)
if option.translatable
else option.displayName
),
routingValue=option.id,
checkable=True,
checked=routing == option.id,