Add support for user-translated strings in the UI

This commit is contained in:
NGnius (Graham) 2023-01-10 20:54:33 -05:00
parent d33b657e8f
commit 8bc9c7b2d8
23 changed files with 726 additions and 151 deletions

83
backend/Cargo.lock generated
View file

@ -265,6 +265,70 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "encoding"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
dependencies = [
"encoding-index-japanese",
"encoding-index-korean",
"encoding-index-simpchinese",
"encoding-index-singlebyte",
"encoding-index-tradchinese",
]
[[package]]
name = "encoding-index-japanese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-korean"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-simpchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-singlebyte"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-tradchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding_index_tests"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.31" version = "0.8.31"
@ -371,6 +435,16 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "gettext-ng"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2c86be871deb255ef65fc8395048a2505912c595f1eddc4da03aeb6fda5cf34"
dependencies = [
"byteorder",
"encoding",
]
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.0" version = "0.3.0"
@ -1301,13 +1375,14 @@ dependencies = [
[[package]] [[package]]
name = "usdpl-back" name = "usdpl-back"
version = "0.7.2" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58928ed65332c30b9b9be5140fcdab97e45db679a5845d829aa26492765272e5" checksum = "32af4c47bfeca1d75de693be983edc2ecfee10e71f138933c959ea5f97ca1a64"
dependencies = [ dependencies = [
"async-recursion", "async-recursion",
"async-trait", "async-trait",
"bytes", "bytes",
"gettext-ng",
"hex", "hex",
"log", "log",
"obfstr", "obfstr",
@ -1318,9 +1393,9 @@ dependencies = [
[[package]] [[package]]
name = "usdpl-core" name = "usdpl-core"
version = "0.6.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862153581fac266458521f49e5906a71c1eee1665cb4c7d71e9586bd34b45394" checksum = "f3904ca38aca189c68a6bc876cf73de7cc60003476b4e118012ae7eb783c1700"
dependencies = [ dependencies = [
"aes-gcm-siv", "aes-gcm-siv",
"base64", "base64",

View file

@ -2,11 +2,17 @@
name = "powertools-rs" name = "powertools-rs"
version = "1.1.0" version = "1.1.0"
edition = "2021" edition = "2021"
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
description = "Backend (superuser) functionality for PowerTools"
license = "GPL-3.0-only"
repository = "https://github.com/NGnius/PowerTools"
keywords = ["utility", "power-management", "root", "decky"]
readme = "../README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
usdpl-back = { version = "0.7.2", features = ["blocking"]} usdpl-back = { version = "0.9.0", features = ["blocking"] }#, path = "../../usdpl-rs/usdpl-back"}
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"

View file

@ -52,6 +52,8 @@ fn main() -> Result<(), ()> {
println!("Logging to: {:?}", log_filepath); println!("Logging to: {:?}", log_filepath);
log::info!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION); log::info!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
println!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION); println!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
log::info!("Current dir `{}`", std::env::current_dir().unwrap().display());
println!("Current dir `{}`", std::env::current_dir().unwrap().display());
let _limits_handle = crate::settings::limits_worker_spawn(); let _limits_handle = crate::settings::limits_worker_spawn();
log::info!("Detected device automatically, starting with driver: {:?} (This can be overriden)", crate::settings::auto_detect_provider()); log::info!("Detected device automatically, starting with driver: {:?} (This can be overriden)", crate::settings::auto_detect_provider());

View file

@ -26,18 +26,10 @@ impl Battery {
fn read_f64<P: AsRef<std::path::Path>>(path: P) -> Result<f64, SettingError> { fn read_f64<P: AsRef<std::path::Path>>(path: P) -> Result<f64, SettingError> {
let path = path.as_ref(); let path = path.as_ref();
match usdpl_back::api::files::read_single::<_, f64, _>(path) { match usdpl_back::api::files::read_single::<_, f64, _>(path) {
Err((Some(e), None)) => Err(SettingError { Err(e) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", path.display(), e), msg: format!("Failed to read from `{}`: {}", path.display(), e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}), }),
Err((None, Some(e))) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", path.display(), e),
setting: crate::settings::SettingVariant::Battery,
}),
Err(_) => panic!(
"Invalid error while reading from `{}`",
path.display()
),
// this value is in uA, while it's set in mA // this value is in uA, while it's set in mA
// so convert this to mA for consistency // so convert this to mA for consistency
Ok(val) => Ok(val / 1000.0), Ok(val) => Ok(val / 1000.0),

View file

@ -273,15 +273,10 @@ impl Cpu {
// NOTE: this eats errors // NOTE: this eats errors
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) { let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
Ok(s) => s, Ok(s) => s,
Err((Some(e), None)) => { Err(e) => {
log::warn!("Error getting available CPU governors: {}", e); log::warn!("Error getting available CPU governors: {}", e);
return vec![]; return vec![];
}, },
Err((None, Some(e))) => {
log::warn!("Error getting available CPU governors: {}", e);
return vec![];
},
Err(_) => return vec![],
}; };
gov_str.split(' ').map(|s| s.to_owned()).collect() gov_str.split(' ').map(|s| s.to_owned()).collect()
} }

View file

@ -113,18 +113,10 @@ impl Battery {
pub fn read_current_now() -> Result<u64, SettingError> { pub fn read_current_now() -> Result<u64, SettingError> {
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CURRENT_NOW_PATH) { match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CURRENT_NOW_PATH) {
Err((Some(e), None)) => Err(SettingError { Err(e) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CURRENT_NOW_PATH, e), msg: format!("Failed to read from `{}`: {}", BATTERY_CURRENT_NOW_PATH, e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}), }),
Err((None, Some(e))) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CURRENT_NOW_PATH, e),
setting: crate::settings::SettingVariant::Battery,
}),
Err(_) => panic!(
"Invalid error while reading from `{}`",
BATTERY_CURRENT_NOW_PATH
),
// this value is in uA, while it's set in mA // this value is in uA, while it's set in mA
// so convert this to mA for consistency // so convert this to mA for consistency
Ok(val) => Ok(val / 1000), Ok(val) => Ok(val / 1000),
@ -133,18 +125,10 @@ impl Battery {
pub fn read_charge_now() -> Result<f64, SettingError> { pub fn read_charge_now() -> Result<f64, SettingError> {
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_NOW_PATH) { match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_NOW_PATH) {
Err((Some(e), None)) => Err(SettingError { Err(e) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_NOW_PATH, e), msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_NOW_PATH, e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}), }),
Err((None, Some(e))) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_NOW_PATH, e),
setting: crate::settings::SettingVariant::Battery,
}),
Err(_) => panic!(
"Invalid error while reading from `{}`",
BATTERY_CHARGE_NOW_PATH
),
// convert to Wh // convert to Wh
Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE), Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE),
} }
@ -152,18 +136,10 @@ impl Battery {
pub fn read_charge_full() -> Result<f64, SettingError> { pub fn read_charge_full() -> Result<f64, SettingError> {
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_FULL_PATH) { match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_FULL_PATH) {
Err((Some(e), None)) => Err(SettingError { Err(e) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_FULL_PATH, e), msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_FULL_PATH, e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}), }),
Err((None, Some(e))) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_FULL_PATH, e),
setting: crate::settings::SettingVariant::Battery,
}),
Err(_) => panic!(
"Invalid error while reading from `{}`",
BATTERY_CHARGE_NOW_PATH
),
// convert to Wh // convert to Wh
Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE), Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE),
} }
@ -171,18 +147,10 @@ impl Battery {
pub fn read_charge_design() -> Result<f64, SettingError> { pub fn read_charge_design() -> Result<f64, SettingError> {
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) { match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) {
Err((Some(e), None)) => Err(SettingError { Err(e) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e), msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}), }),
Err((None, Some(e))) => Err(SettingError {
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e),
setting: crate::settings::SettingVariant::Battery,
}),
Err(_) => panic!(
"Invalid error while reading from `{}`",
BATTERY_CHARGE_NOW_PATH
),
// convert to Wh // convert to Wh
Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE), Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE),
} }

View file

@ -355,15 +355,10 @@ impl Cpu {
// NOTE: this eats errors // NOTE: this eats errors
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) { let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
Ok(s) => s, Ok(s) => s,
Err((Some(e), None)) => { Err(e) => {
log::warn!("Error getting available CPU governors: {}", e); log::warn!("Error getting available CPU governors: {}", e);
return vec![]; return vec![];
}, }
Err((None, Some(e))) => {
log::warn!("Error getting available CPU governors: {}", e);
return vec![];
},
Err(_) => return vec![],
}; };
gov_str.split(' ').map(|s| s.to_owned()).collect() gov_str.split(' ').map(|s| s.to_owned()).collect()
} }

View file

@ -27,20 +27,20 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^21.1.0", "@rollup/plugin-commonjs": "^21.1.0",
"@rollup/plugin-json": "^4.1.0", "@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.2.1", "@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-replace": "^4.0.0", "@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.3.2", "@rollup/plugin-typescript": "^8.5.0",
"@types/react": "16.14.0", "@types/react": "16.14.0",
"@types/webpack": "^5.28.0", "@types/webpack": "^5.28.0",
"rollup": "^2.70.2", "rollup": "^2.79.1",
"rollup-plugin-import-assets": "^1.1.1", "rollup-plugin-import-assets": "^1.1.1",
"shx": "^0.3.4", "shx": "^0.3.4",
"tslib": "^2.4.0", "tslib": "^2.4.1",
"typescript": "^4.6.4" "typescript": "^4.9.4"
}, },
"dependencies": { "dependencies": {
"decky-frontend-lib": "3.*", "decky-frontend-lib": "~3.18.5",
"react-icons": "^4.4.0", "react-icons": "^4.7.1",
"usdpl-front": "file:./src/usdpl_front" "usdpl-front": "file:src/usdpl_front"
} }
} }

View file

@ -3,19 +3,19 @@ lockfileVersion: 5.4
specifiers: specifiers:
'@rollup/plugin-commonjs': ^21.1.0 '@rollup/plugin-commonjs': ^21.1.0
'@rollup/plugin-json': ^4.1.0 '@rollup/plugin-json': ^4.1.0
'@rollup/plugin-node-resolve': ^13.2.1 '@rollup/plugin-node-resolve': ^13.3.0
'@rollup/plugin-replace': ^4.0.0 '@rollup/plugin-replace': ^4.0.0
'@rollup/plugin-typescript': ^8.3.2 '@rollup/plugin-typescript': ^8.5.0
'@types/react': 16.14.0 '@types/react': 16.14.0
'@types/webpack': ^5.28.0 '@types/webpack': ^5.28.0
decky-frontend-lib: 3.* decky-frontend-lib: ~3.18.5
react-icons: ^4.4.0 react-icons: ^4.7.1
rollup: ^2.70.2 rollup: ^2.79.1
rollup-plugin-import-assets: ^1.1.1 rollup-plugin-import-assets: ^1.1.1
shx: ^0.3.4 shx: ^0.3.4
tslib: ^2.4.0 tslib: ^2.4.1
typescript: ^4.6.4 typescript: ^4.9.4
usdpl-front: file:./src/usdpl_front usdpl-front: file:src/usdpl_front
dependencies: dependencies:
decky-frontend-lib: 3.18.5 decky-frontend-lib: 3.18.5
@ -672,8 +672,8 @@ packages:
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
dev: true dev: true
/punycode/2.1.1: /punycode/2.2.0:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} resolution: {integrity: sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
@ -860,7 +860,7 @@ packages:
/uri-js/4.4.1: /uri-js/4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
dependencies: dependencies:
punycode: 2.1.1 punycode: 2.2.0
dev: true dev: true
/url-join/4.0.1: /url-join/4.0.1:
@ -927,5 +927,5 @@ packages:
file:src/usdpl_front: file:src/usdpl_front:
resolution: {directory: src/usdpl_front, type: directory} resolution: {directory: src/usdpl_front, type: directory}
name: usdpl-front name: usdpl-front
version: 0.7.0 version: 0.9.0
dev: false dev: false

View file

@ -1,4 +1,4 @@
import {init_usdpl, target_usdpl, init_embedded, call_backend} from "usdpl-front"; import {init_usdpl, target_usdpl, init_embedded, call_backend, init_tr} from "usdpl-front";
const USDPL_PORT: number = 44443; const USDPL_PORT: number = 44443;
@ -22,6 +22,14 @@ export async function initBackend() {
await init_embedded(); await init_embedded();
init_usdpl(USDPL_PORT); init_usdpl(USDPL_PORT);
console.log("USDPL started for framework: " + target_usdpl()); console.log("USDPL started for framework: " + target_usdpl());
const user_locale =
navigator.languages && navigator.languages.length
? navigator.languages[0]
: navigator.language;
console.log("POWERTOOLS: locale", user_locale);
let mo_path = "../plugins/PowerTools/translations/" + user_locale.toString() + ".mo";
await init_tr(mo_path);
//await init_tr("../plugins/PowerTools/translations/test.mo");
//setReady(true); //setReady(true);
} }

View file

@ -10,6 +10,7 @@ import {
staticClasses, staticClasses,
} from "decky-frontend-lib"; } from "decky-frontend-lib";
import * as backend from "../backend"; import * as backend from "../backend";
import { tr } from "usdpl-front";
import { import {
LIMITS_INFO, LIMITS_INFO,
CHARGE_DESIGN_BATT, CHARGE_DESIGN_BATT,
@ -38,25 +39,25 @@ export class Battery extends Component<{}> {
return (<Fragment> return (<Fragment>
{/* Battery */} {/* Battery */}
<div className={staticClasses.PanelSectionTitle}> <div className={staticClasses.PanelSectionTitle}>
Battery {tr("Battery")}
</div> </div>
{get_value(CHARGE_NOW_BATT) != null && get_value(CHARGE_FULL_BATT) != null && <PanelSectionRow> {get_value(CHARGE_NOW_BATT) != null && get_value(CHARGE_FULL_BATT) != null && <PanelSectionRow>
<Field <Field
label="Now (Charge)"> label={tr("Now (Charge)")}>
{get_value(CHARGE_NOW_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_NOW_BATT) / get_value(CHARGE_FULL_BATT)).toFixed(1)}%) {get_value(CHARGE_NOW_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_NOW_BATT) / get_value(CHARGE_FULL_BATT)).toFixed(1)}%)
</Field> </Field>
</PanelSectionRow>} </PanelSectionRow>}
{get_value(CHARGE_FULL_BATT) != null && get_value(CHARGE_DESIGN_BATT) != null && <PanelSectionRow> {get_value(CHARGE_FULL_BATT) != null && get_value(CHARGE_DESIGN_BATT) != null && <PanelSectionRow>
<Field <Field
label="Max (Design)"> label={tr("Max (Design)")}>
{get_value(CHARGE_FULL_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_FULL_BATT) / get_value(CHARGE_DESIGN_BATT)).toFixed(1)}%) {get_value(CHARGE_FULL_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_FULL_BATT) / get_value(CHARGE_DESIGN_BATT)).toFixed(1)}%)
</Field> </Field>
</PanelSectionRow>} </PanelSectionRow>}
{(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current != null && <PanelSectionRow> {(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current != null && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(CHARGE_RATE_BATT) != null} checked={get_value(CHARGE_RATE_BATT) != null}
label="Charge Current Limits" label={tr("Charge Current Limits")}
description="Control battery charge rate when awake" description={tr("Control battery charge rate when awake")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
set_value(CHARGE_RATE_BATT, 2500); set_value(CHARGE_RATE_BATT, 2500);
@ -70,7 +71,7 @@ export class Battery extends Component<{}> {
}} }}
/> />
{ get_value(CHARGE_RATE_BATT) != null && <SliderField { get_value(CHARGE_RATE_BATT) != null && <SliderField
label="Maximum (mA)" label={tr("Maximum (mA)")}
value={get_value(CHARGE_RATE_BATT)} value={get_value(CHARGE_RATE_BATT)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current!.min}
@ -93,8 +94,8 @@ export class Battery extends Component<{}> {
{chargeModeOptions.length != 0 && <PanelSectionRow> {chargeModeOptions.length != 0 && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(CHARGE_MODE_BATT) != null} checked={get_value(CHARGE_MODE_BATT) != null}
label="Charge Mode" label={tr("Charge Mode")}
description="Force battery charge mode" description={tr("Force battery charge mode")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
set_value(CHARGE_MODE_BATT, chargeModeOptions[0].data as string); set_value(CHARGE_MODE_BATT, chargeModeOptions[0].data as string);
@ -108,10 +109,10 @@ export class Battery extends Component<{}> {
}} }}
/> />
{get_value(CHARGE_MODE_BATT) != null && <Field {get_value(CHARGE_MODE_BATT) != null && <Field
label="Mode" label={tr("Mode")}
> >
<Dropdown <Dropdown
menuLabel="Charge Mode" menuLabel={tr("Charge Mode")}
rgOptions={chargeModeOptions} rgOptions={chargeModeOptions}
selectedOption={chargeModeOptions.find((val: SingleDropdownOption, _index, _arr) => { selectedOption={chargeModeOptions.find((val: SingleDropdownOption, _index, _arr) => {
return val.data == get_value(CHARGE_MODE_BATT); return val.data == get_value(CHARGE_MODE_BATT);
@ -129,7 +130,7 @@ export class Battery extends Component<{}> {
</PanelSectionRow>} </PanelSectionRow>}
<PanelSectionRow> <PanelSectionRow>
<Field <Field
label="Current"> label={tr("Current")}>
{get_value(CURRENT_BATT)} mA {get_value(CURRENT_BATT)} mA
</Field> </Field>
</PanelSectionRow> </PanelSectionRow>

View file

@ -10,6 +10,7 @@ import {
staticClasses, staticClasses,
} from "decky-frontend-lib"; } from "decky-frontend-lib";
import * as backend from "../backend"; import * as backend from "../backend";
import { tr } from "usdpl-front";
import { import {
LIMITS_INFO, LIMITS_INFO,
SMT_CPU, SMT_CPU,
@ -61,13 +62,13 @@ export class Cpus extends Component<{}, CpuState> {
return (<Fragment> return (<Fragment>
{/* CPU */} {/* CPU */}
<div className={staticClasses.PanelSectionTitle}> <div className={staticClasses.PanelSectionTitle}>
CPU {tr("CPU")}
</div> </div>
<PanelSectionRow> <PanelSectionRow>
<ToggleField <ToggleField
checked={advancedMode} checked={advancedMode}
label="Advanced" label={tr("Advanced")}
description="Enables per-thread configuration" description={tr("Enables per-thread configuration")}
onChange={(advanced: boolean) => { onChange={(advanced: boolean) => {
//advancedMode = advanced; //advancedMode = advanced;
this.setState((state) => { this.setState((state) => {
@ -84,8 +85,8 @@ export class Cpus extends Component<{}, CpuState> {
{!advancedMode && smtAllowed && <PanelSectionRow> {!advancedMode && smtAllowed && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(SMT_CPU)} checked={get_value(SMT_CPU)}
label="SMT" label={tr("SMT")}
description="Enables odd-numbered CPUs" description={tr("Enables odd-numbered CPUs")}
onChange={(smt: boolean) => { onChange={(smt: boolean) => {
backend.log(backend.LogLevel.Debug, "SMT is now " + smt.toString()); backend.log(backend.LogLevel.Debug, "SMT is now " + smt.toString());
//const cpus = get_value(ONLINE_CPUS); //const cpus = get_value(ONLINE_CPUS);
@ -102,7 +103,7 @@ export class Cpus extends Component<{}, CpuState> {
</PanelSectionRow>} </PanelSectionRow>}
{!advancedMode && <PanelSectionRow> {!advancedMode && <PanelSectionRow>
<SliderField <SliderField
label="Threads" label={tr("Threads")}
value={get_value(ONLINE_CPUS)} value={get_value(ONLINE_CPUS)}
step={1} step={1}
max={(get_value(SMT_CPU) || !smtAllowed) ? total_cpus : total_cpus/2} max={(get_value(SMT_CPU) || !smtAllowed) ? total_cpus : total_cpus/2}
@ -133,8 +134,8 @@ export class Cpus extends Component<{}, CpuState> {
{!advancedMode && <PanelSectionRow> {!advancedMode && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(CLOCK_MIN_CPU) != null || get_value(CLOCK_MAX_CPU) != null} checked={get_value(CLOCK_MIN_CPU) != null || get_value(CLOCK_MAX_CPU) != null}
label="Frequency Limits" label={tr("Frequency Limits")}
description="Set bounds on clock speed" description={tr("Set bounds on clock speed")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits != null) { if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits != null) {
@ -161,7 +162,7 @@ export class Cpus extends Component<{}, CpuState> {
</PanelSectionRow>} </PanelSectionRow>}
{!advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits != null && <PanelSectionRow> {!advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits != null && <PanelSectionRow>
{get_value(CLOCK_MIN_CPU) != null && <SliderField {get_value(CLOCK_MIN_CPU) != null && <SliderField
label="Minimum (MHz)" label={tr("Minimum (MHz)")}
value={get_value(CLOCK_MIN_CPU)} value={get_value(CLOCK_MIN_CPU)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits!.min}
@ -191,7 +192,7 @@ export class Cpus extends Component<{}, CpuState> {
</PanelSectionRow>} </PanelSectionRow>}
{!advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits != null && <PanelSectionRow> {!advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits != null && <PanelSectionRow>
{get_value(CLOCK_MAX_CPU) != null && <SliderField {get_value(CLOCK_MAX_CPU) != null && <SliderField
label="Maximum (MHz)" label={tr("Maximum (MHz)")}
value={get_value(CLOCK_MAX_CPU)} value={get_value(CLOCK_MAX_CPU)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits!.min}
@ -222,7 +223,7 @@ export class Cpus extends Component<{}, CpuState> {
{/* CPU advanced mode */} {/* CPU advanced mode */}
{advancedMode && <PanelSectionRow> {advancedMode && <PanelSectionRow>
<SliderField <SliderField
label="Selected CPU" label={tr("Selected CPU")}
value={advancedCpu} value={advancedCpu}
step={1} step={1}
max={total_cpus} max={total_cpus}
@ -242,8 +243,8 @@ export class Cpus extends Component<{}, CpuState> {
{advancedMode && <PanelSectionRow> {advancedMode && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(ONLINE_STATUS_CPUS)[advancedCpuIndex]} checked={get_value(ONLINE_STATUS_CPUS)[advancedCpuIndex]}
label="Online" label={tr("Online")}
description="Allow the CPU thread to do work" description={tr("Allow the CPU thread to do work")}
onChange={(status: boolean) => { onChange={(status: boolean) => {
backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString()); backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString());
if (!get_value(SMT_CPU)) { if (!get_value(SMT_CPU)) {
@ -262,8 +263,8 @@ export class Cpus extends Component<{}, CpuState> {
{advancedMode && <PanelSectionRow> {advancedMode && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min != null || get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max != null} checked={get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min != null || get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max != null}
label="Frequency Limits" label={tr("Frequency Limits")}
description="Set bounds on clock speed" description={tr("Set bounds on clock speed")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[];
@ -290,7 +291,7 @@ export class Cpus extends Component<{}, CpuState> {
</PanelSectionRow>} </PanelSectionRow>}
{advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits != null && <PanelSectionRow> {advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits != null && <PanelSectionRow>
{get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min != null && <SliderField {get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min != null && <SliderField
label="Minimum (MHz)" label={tr("Minimum (MHz)")}
value={get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min} value={get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.min}
@ -315,7 +316,7 @@ export class Cpus extends Component<{}, CpuState> {
</PanelSectionRow>} </PanelSectionRow>}
{advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits != null && <PanelSectionRow> {advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits != null && <PanelSectionRow>
{get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max != null && <SliderField {get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max != null && <SliderField
label="Maximum (MHz)" label={tr("Maximum (MHz)")}
value={get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max} value={get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.min}
@ -340,10 +341,10 @@ export class Cpus extends Component<{}, CpuState> {
</PanelSectionRow>} </PanelSectionRow>}
{advancedMode && governorOptions.length != 0 && <PanelSectionRow> {advancedMode && governorOptions.length != 0 && <PanelSectionRow>
<Field <Field
label="Governor" label={tr("Governor")}
> >
<Dropdown <Dropdown
menuLabel="Governor" menuLabel={tr("Governor")}
rgOptions={governorOptions} rgOptions={governorOptions}
selectedOption={governorOptions.find((val: SingleDropdownOption, _index, _arr) => { selectedOption={governorOptions.find((val: SingleDropdownOption, _index, _arr) => {
backend.log(backend.LogLevel.Debug, "POWERTOOLS: array item " + val.toString()); backend.log(backend.LogLevel.Debug, "POWERTOOLS: array item " + val.toString());

View file

@ -8,6 +8,7 @@ import {
Router, Router,
} from "decky-frontend-lib"; } from "decky-frontend-lib";
import * as backend from "../backend"; import * as backend from "../backend";
import { tr } from "usdpl-front";
import { import {
BACKEND_INFO, BACKEND_INFO,
DRIVER_INFO, DRIVER_INFO,
@ -25,11 +26,11 @@ export class Debug extends Component<{}> {
function buildDebug() { function buildDebug() {
return (<Fragment>{/* Version Info */} return (<Fragment>{/* Version Info */}
<div className={staticClasses.PanelSectionTitle}> <div className={staticClasses.PanelSectionTitle}>
{eggCount % 10 == 9 ? "Ha! Nerd" : "Debug"} {eggCount % 10 == 9 ? "Ha! Nerd" : tr("Debug")}
</div> </div>
<PanelSectionRow> <PanelSectionRow>
<Field <Field
label={eggCount % 10 == 9 ? "PowerTools" : "Native"} label={eggCount % 10 == 9 ? "PowerTools" : tr("Native")}
onClick={()=> { onClick={()=> {
if (eggCount % 10 == 9) { if (eggCount % 10 == 9) {
// you know you're bored and/or conceited when you spend time adding an easter egg // you know you're bored and/or conceited when you spend time adding an easter egg
@ -43,14 +44,14 @@ function buildDebug() {
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field <Field
label="Framework" label={tr("Framework")}
onClick={()=> eggCount++}> onClick={()=> eggCount++}>
{eggCount % 10 == 9 ? "<3 <3 <3" : target_usdpl()} {eggCount % 10 == 9 ? "<3 <3 <3" : target_usdpl()}
</Field> </Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field <Field
label="Driver" label={tr("Driver")}
onClick={()=> eggCount++}> onClick={()=> eggCount++}>
{eggCount % 10 == 9 ? "Tracy Chapman" : get_value(DRIVER_INFO)} {eggCount % 10 == 9 ? "Tracy Chapman" : get_value(DRIVER_INFO)}
</Field> </Field>

View file

@ -7,6 +7,7 @@ import {
staticClasses, staticClasses,
} from "decky-frontend-lib"; } from "decky-frontend-lib";
import * as backend from "../backend"; import * as backend from "../backend";
import { tr } from "usdpl-front";
import { import {
LIMITS_INFO, LIMITS_INFO,
SLOW_PPT_GPU, SLOW_PPT_GPU,
@ -30,13 +31,13 @@ export class Gpu extends Component<{}> {
return (<Fragment> return (<Fragment>
{/* GPU */} {/* GPU */}
<div className={staticClasses.PanelSectionTitle}> <div className={staticClasses.PanelSectionTitle}>
GPU {tr("GPU")}
</div> </div>
{ ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits != null ||(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits != null) && <PanelSectionRow> { ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits != null ||(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits != null) && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(SLOW_PPT_GPU) != null || get_value(FAST_PPT_GPU) != null} checked={get_value(SLOW_PPT_GPU) != null || get_value(FAST_PPT_GPU) != null}
label="PowerPlay Limits" label={tr("PowerPlay Limits")}
description="Override APU TDP settings" description={tr("Override APU TDP settings")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits != null) { if ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits != null) {
@ -59,7 +60,7 @@ export class Gpu extends Component<{}> {
</PanelSectionRow>} </PanelSectionRow>}
<PanelSectionRow> <PanelSectionRow>
{ get_value(SLOW_PPT_GPU) != null && <SliderField { get_value(SLOW_PPT_GPU) != null && <SliderField
label="SlowPPT (W)" label={tr("SlowPPT (W)")}
value={get_value(SLOW_PPT_GPU)} value={get_value(SLOW_PPT_GPU)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits!.min}
@ -83,7 +84,7 @@ export class Gpu extends Component<{}> {
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
{get_value(FAST_PPT_GPU) != null && <SliderField {get_value(FAST_PPT_GPU) != null && <SliderField
label="FastPPT (W)" label={tr("FastPPT (W)")}
value={get_value(FAST_PPT_GPU)} value={get_value(FAST_PPT_GPU)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits!.min}
@ -108,8 +109,8 @@ export class Gpu extends Component<{}> {
{((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits != null || (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits != null) && <PanelSectionRow> {((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits != null || (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits != null) && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(CLOCK_MIN_GPU) != null || get_value(CLOCK_MAX_GPU) != null} checked={get_value(CLOCK_MIN_GPU) != null || get_value(CLOCK_MAX_GPU) != null}
label="Frequency Limits" label={tr("Frequency Limits")}
description="Override bounds on gpu clock" description={tr("Set bounds on clock speed")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
let clock_min_limits = (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits; let clock_min_limits = (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits;
@ -133,7 +134,7 @@ export class Gpu extends Component<{}> {
</PanelSectionRow>} </PanelSectionRow>}
<PanelSectionRow> <PanelSectionRow>
{ get_value(CLOCK_MIN_GPU) != null && <SliderField { get_value(CLOCK_MIN_GPU) != null && <SliderField
label="Minimum (MHz)" label={tr("Minimum (MHz)")}
value={get_value(CLOCK_MIN_GPU)} value={get_value(CLOCK_MIN_GPU)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits!.min}
@ -156,7 +157,7 @@ export class Gpu extends Component<{}> {
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
{get_value(CLOCK_MAX_GPU) != null && <SliderField {get_value(CLOCK_MAX_GPU) != null && <SliderField
label="Maximum (MHz)" label={tr("Maximum (MHz)")}
value={get_value(CLOCK_MAX_GPU)} value={get_value(CLOCK_MAX_GPU)}
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits!.max} max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits!.max}
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits!.min} min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits!.min}
@ -180,8 +181,8 @@ export class Gpu extends Component<{}> {
{(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control_capable && <PanelSectionRow> {(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control_capable && <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(SLOW_MEMORY_GPU)} checked={get_value(SLOW_MEMORY_GPU)}
label="Downclock Memory" label={tr("Downclock Memory")}
description="Force RAM into low-power mode" description={tr("Force RAM into low-power mode")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
backend.resolve(backend.setGpuSlowMemory(value), (val: boolean) => { backend.resolve(backend.setGpuSlowMemory(value), (val: boolean) => {
set_value(SLOW_MEMORY_GPU, val); set_value(SLOW_MEMORY_GPU, val);

View file

@ -24,6 +24,7 @@ import { GiDrill } from "react-icons/gi";
//import * as python from "./python"; //import * as python from "./python";
import * as backend from "./backend"; import * as backend from "./backend";
import { tr } from "usdpl-front";
import { import {
BACKEND_INFO, BACKEND_INFO,
DRIVER_INFO, DRIVER_INFO,
@ -217,13 +218,13 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
{/* Persistence */} {/* Persistence */}
<div className={staticClasses.PanelSectionTitle}> <div className={staticClasses.PanelSectionTitle}>
Miscellaneous {tr("Miscellaneous")}
</div> </div>
<PanelSectionRow> <PanelSectionRow>
<ToggleField <ToggleField
checked={get_value(PERSISTENT_GEN)} checked={get_value(PERSISTENT_GEN)}
label="Persistent" label={tr("Persistent")}
description="Save profile and load it next time" description={tr("Save profile and load it next time")}
onChange={(persist: boolean) => { onChange={(persist: boolean) => {
backend.log(backend.LogLevel.Debug, "Persist is now " + persist.toString()); backend.log(backend.LogLevel.Debug, "Persist is now " + persist.toString());
backend.resolve( backend.resolve(
@ -235,7 +236,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field <Field
label="Profile"> label={tr("Profile")}>
{get_value(NAME_GEN)} {get_value(NAME_GEN)}
</Field> </Field>
</PanelSectionRow> </PanelSectionRow>
@ -278,7 +279,7 @@ export default definePlugin((serverApi: ServerAPI) => {
lifetimeHook!.unregister(); lifetimeHook!.unregister();
startHook!.unregister(); startHook!.unregister();
serverApi.routerHook.removeRoute("/decky-plugin-test"); serverApi.routerHook.removeRoute("/decky-plugin-test");
backend.log(backend.LogLevel.Debug, "Unregistered PowerTools callbacks, goodbye."); backend.log(backend.LogLevel.Debug, "Unregistered PowerTools callbacks, so long and thanks for all the fish.");
}, },
}; };
}); });

View file

@ -4,7 +4,7 @@
"NGnius (Graham) <ngniusness@gmail.com>" "NGnius (Graham) <ngniusness@gmail.com>"
], ],
"description": "Universal Steam Deck Plugin Library front-end designed for WASM", "description": "Universal Steam Deck Plugin Library front-end designed for WASM",
"version": "0.7.0", "version": "0.9.0",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -36,6 +36,25 @@ export function get_value(key: string): any;
* @returns {Promise<any>} * @returns {Promise<any>}
*/ */
export function call_backend(name: string, parameters: any[]): Promise<any>; export function call_backend(name: string, parameters: any[]): Promise<any>;
/**
* Initialize translation strings for the front-end
* @param {string} locale
* @returns {Promise<void>}
*/
export function init_tr(locale: string): Promise<void>;
/**
* Translate a phrase, equivalent to tr_n(msg_id, 0)
* @param {string} msg_id
* @returns {string}
*/
export function tr(msg_id: string): string;
/**
* Translate a phrase, retrieving the plural form for `n` items
* @param {string} msg_id
* @param {number} n
* @returns {string}
*/
export function tr_n(msg_id: string, n: number): string;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
@ -47,6 +66,9 @@ export interface InitOutput {
readonly set_value: (a: number, b: number, c: number) => number; readonly set_value: (a: number, b: number, c: number) => number;
readonly get_value: (a: number, b: number) => number; readonly get_value: (a: number, b: number) => number;
readonly call_backend: (a: number, b: number, c: number, d: number) => number; readonly call_backend: (a: number, b: number, c: number, d: number) => number;
readonly init_tr: (a: number, b: number) => number;
readonly tr: (a: number, b: number, c: number) => void;
readonly tr_n: (a: number, b: number, c: number, d: number) => void;
readonly __wbindgen_export_0: (a: number) => number; readonly __wbindgen_export_0: (a: number) => number;
readonly __wbindgen_export_1: (a: number, b: number, c: number) => number; readonly __wbindgen_export_1: (a: number, b: number, c: number) => number;
readonly __wbindgen_export_2: WebAssembly.Table; readonly __wbindgen_export_2: WebAssembly.Table;

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -7,6 +7,9 @@ export function version_usdpl(a: number): void;
export function set_value(a: number, b: number, c: number): number; export function set_value(a: number, b: number, c: number): number;
export function get_value(a: number, b: number): number; export function get_value(a: number, b: number): number;
export function call_backend(a: number, b: number, c: number, d: number): number; export function call_backend(a: number, b: number, c: number, d: number): number;
export function init_tr(a: number, b: number): number;
export function tr(a: number, b: number, c: number): void;
export function tr_n(a: number, b: number, c: number, d: number): void;
export function __wbindgen_export_0(a: number): number; export function __wbindgen_export_0(a: number): number;
export function __wbindgen_export_1(a: number, b: number, c: number): number; export function __wbindgen_export_1(a: number, b: number, c: number): number;
export const __wbindgen_export_2: WebAssembly.Table; export const __wbindgen_export_2: WebAssembly.Table;

229
translations/pt.pot Normal file
View file

@ -0,0 +1,229 @@
# TEMPLATE TITLE.
# Copyright (C) 2023 NGnius
# This file is distributed under the same license as the PowerTools package.
# NGnius (Graham) <ngniusness@gmail.com>, 2023.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: v1.1\n"
"Report-Msgid-Bugs-To: https://github.com/NGnius/PowerTools/issues\n"
"POT-Creation-Date: 2023-01-09 19:52-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
# -- index.tsx --
#: index.tsx:226
# (Section title)
msgid "Miscellaneous"
msgstr ""
#: index.tsx:226
# (Profile persistence toggle)
msgid "Persistent"
msgstr ""
#: index.tsx:227
# (Profile persistence toggle description)
msgid "Save profile and load it next time"
msgstr ""
#: index.tsx:239
# (Profile display)
msgid "Profile"
msgstr ""
# -- components/battery.tsx --
#: components/battery.tsx:42
# (Battery section title)
msgid "Battery"
msgstr ""
#: components/battery.tsx:46
# (Charge of battery at this moment, with percentage of expected full charge in brackets)
msgid "Now (Charge)"
msgstr ""
#: components/battery.tsx:52
# (Maximum capacity of battery, with percentage of design capacity in brackets)
msgid "Max (Design)"
msgstr ""
#: components/battery.tsx:59
# (Charge current limit override toggle)
msgid "Charge Current Limits"
msgstr ""
#: components/battery.tsx:60
# (Charge current limit override toggle description)
msgid "Control battery charge rate when awake"
msgstr ""
#: components/battery.tsx:74
# (Battery maximum input current with unit)
msgid "Maximum (mA)"
msgstr ""
#: components/battery.tsx:97,115
# (Battery charge mode override toggle)
msgid "Charge Mode"
msgstr ""
#: components/battery.tsx:98
# (Battery charge mode override toggle description)
msgid "Force battery charge mode"
msgstr ""
#: components/battery.tsx:112
# (Battery charge mode dropdown)
msgid "Mode"
msgstr ""
#: components/battery.tsx:133
# (Battery current display)
msgid "Current"
msgstr ""
# -- components/cpus.tsx --
#: components/cpus.tsx:64
# (CPU section title)
msgid "CPU"
msgstr ""
#: components/cpus.tsx:70
# (CPU advanced mode toggle)
msgid "Advanced"
msgstr ""
#: components/cpus.tsx:71
# (CPU advanced mode toggle description)
msgid "Enables per-thread configuration"
msgstr ""
#: components/cpus.tsx:88
# (CPU Simultaneous MultiThreading toggle)
msgid "SMT"
msgstr ""
#: components/cpus.tsx:89
# (CPU SMT toggle description)
msgid "Enables odd-numbered CPUs"
msgstr ""
#: components/cpus.tsx:106
# (CPU thread count slider)
msgid "Threads"
msgstr ""
#: components/cpus.tsx:137
#: components/gpu.tsx:112
# (Clock speed override toggle)
msgid "Frequency Limits"
msgstr ""
#: components/cpus.tsx:138
#: components/gpu.tsx:113
# (Clock speed override toggle description)
msgid "Set bounds on clock speed"
msgstr ""
#: components/cpus.tsx:165
#: components/gpu.tsx:137
# (Minimum clock speed with unit)
msgid "Minimum (MHz)"
msgstr ""
#: components/cpus.tsx:195
#: components/gpu.tsx:160
# (Maximum clock speed with unit)
msgid "Maximum (MHz)"
msgstr ""
# advanced mode
#: components/cpus.tsx:226
# (CPU selection slider)
msgid "Selected CPU"
msgstr ""
#: components/cpus.tsx:246
# (CPU Online toggle)
msgid "Online"
msgstr ""
#: components/cpus.tsx:247
# (CPU Online description)
msgid "Allow the CPU thread to do work"
msgstr ""
#: components/cpus.tsx:342
# (CPU scheduling governor dropdown -- governor names are not translated)
msgid "Governor"
msgstr ""
# -- components/debug.tsx --
#: components/debug.tsx:29
# (Debug section title)
msgid "Debug"
msgstr ""
#: components/debug.tsx:33
# (Version display for native back-end of PowerTools)
msgid "Native"
msgstr ""
#: components/debug.tsx:47
# (Mode display for framework of USDPL API)
msgid "Framework"
msgstr ""
#: components/debug.tsx:54
# (Display for software implementation in PowerTools which applies settings)
msgid "Driver"
msgstr ""
# -- components/gpu.tsx --
#: components/gpu.tsx:34
# (GPU section title)
msgid "GPU"
msgstr ""
#: components/gpu.tsx:39
# (PPT Limits override toggle)
msgid "PowerPlay Limits"
msgstr ""
#: components/gpu.tsx:40
# (PPT Limits override toggle description)
msgid "Override APU TDP settings"
msgstr ""
#: components/gpu.tsx:63
# (SlowPPT slider with unit)
msgid "SlowPPT (W)"
msgstr ""
#: components/gpu.tsx:87
# (FastPPT slider with unit)
msgid "FastPPT (W)"
msgstr ""
#: components/gpu.tsx:112
# (Reduce memory clock speed toggle)
msgid "Downclock Memory"
msgstr ""
#: components/gpu.tsx:112
# (Reduce memory clock speed toggle description)
msgid "Force RAM into low-power mode"
msgstr ""

BIN
translations/test.mo Normal file

Binary file not shown.

229
translations/test.po Normal file
View file

@ -0,0 +1,229 @@
# TEMPLATE TITLE.
# Copyright (C) 2023 NGnius
# This file is distributed under the same license as the PowerTools package.
# NGnius (Graham) <ngniusness@gmail.com>, 2023.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: v1.1\n"
"Report-Msgid-Bugs-To: https://github.com/NGnius/PowerTools/issues\n"
"POT-Creation-Date: 2023-01-10 20:06-0500\n"
"PO-Revision-Date: 2023-01-10 20:06-0500\n"
"Last-Translator: NGnius <ngniusness@gmail.com>\n"
"Language-Team: NGnius <ngniusness@gmail.com>\n"
"Language: conlang\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
# -- index.tsx --
#: index.tsx:226
# (Section title)
msgid "Miscellaneous"
msgstr "test123"
#: index.tsx:226
# (Profile persistence toggle)
msgid "Persistent"
msgstr "test123"
#: index.tsx:227
# (Profile persistence toggle description)
msgid "Save profile and load it next time"
msgstr "test123"
#: index.tsx:239
# (Profile display)
msgid "Profile"
msgstr "test123"
# -- components/battery.tsx --
#: components/battery.tsx:42
# (Battery section title)
msgid "Battery"
msgstr "test123"
#: components/battery.tsx:46
# (Charge of battery at this moment, with percentage of expected full charge in brackets)
msgid "Now (Charge)"
msgstr "test123"
#: components/battery.tsx:52
# (Maximum capacity of battery, with percentage of design capacity in brackets)
msgid "Max (Design)"
msgstr "test123"
#: components/battery.tsx:59
# (Charge current limit override toggle)
msgid "Charge Current Limits"
msgstr "test123"
#: components/battery.tsx:60
# (Charge current limit override toggle description)
msgid "Control battery charge rate when awake"
msgstr "test123"
#: components/battery.tsx:74
# (Battery maximum input current with unit)
msgid "Maximum (mA)"
msgstr "test123"
#: components/battery.tsx:97,115
# (Battery charge mode override toggle)
msgid "Charge Mode"
msgstr "test123"
#: components/battery.tsx:98
# (Battery charge mode override toggle description)
msgid "Force battery charge mode"
msgstr "test123"
#: components/battery.tsx:112
# (Battery charge mode dropdown)
msgid "Mode"
msgstr "test123"
#: components/battery.tsx:133
# (Battery current display)
msgid "Current"
msgstr "test123"
# -- components/cpus.tsx --
#: components/cpus.tsx:64
# (CPU section title)
msgid "CPU"
msgstr "test123"
#: components/cpus.tsx:70
# (CPU advanced mode toggle)
msgid "Advanced"
msgstr "test123"
#: components/cpus.tsx:71
# (CPU advanced mode toggle description)
msgid "Enables per-thread configuration"
msgstr "test123"
#: components/cpus.tsx:88
# (CPU Simultaneous MultiThreading toggle)
msgid "SMT"
msgstr "test123"
#: components/cpus.tsx:89
# (CPU SMT toggle description)
msgid "Enables odd-numbered CPUs"
msgstr "test123"
#: components/cpus.tsx:106
# (CPU thread count slider)
msgid "Threads"
msgstr "test123"
#: components/cpus.tsx:137
#: components/gpu.tsx:112
# (Clock speed override toggle)
msgid "Frequency Limits"
msgstr "test123"
#: components/cpus.tsx:138
#: components/gpu.tsx:113
# (Clock speed override toggle description)
msgid "Set bounds on clock speed"
msgstr "test123"
#: components/cpus.tsx:165
#: components/gpu.tsx:137
# (Minimum clock speed with unit)
msgid "Minimum (MHz)"
msgstr "test123"
#: components/cpus.tsx:195
#: components/gpu.tsx:160
# (Maximum clock speed with unit)
msgid "Maximum (MHz)"
msgstr "test123"
# advanced mode
#: components/cpus.tsx:226
# (CPU selection slider)
msgid "Selected CPU"
msgstr "test123"
#: components/cpus.tsx:246
# (CPU Online toggle)
msgid "Online"
msgstr "test123"
#: components/cpus.tsx:247
# (CPU Online description)
msgid "Allow the CPU thread to do work"
msgstr "test123"
#: components/cpus.tsx:342
# (CPU scheduling governor dropdown -- governor names are not translated)
msgid "Governor"
msgstr "test123"
# -- components/debug.tsx --
#: components/debug.tsx:29
# (Debug section title)
msgid "Debug"
msgstr "test123"
#: components/debug.tsx:33
# (Version display for native back-end of PowerTools)
msgid "Native"
msgstr "test123"
#: components/debug.tsx:47
# (Mode display for framework of USDPL API)
msgid "Framework"
msgstr "test123"
#: components/debug.tsx:54
# (Display for software implementation in PowerTools which applies settings)
msgid "Driver"
msgstr "test123"
# -- components/gpu.tsx --
#: components/gpu.tsx:34
# (GPU section title)
msgid "GPU"
msgstr "test123"
#: components/gpu.tsx:39
# (PPT Limits override toggle)
msgid "PowerPlay Limits"
msgstr "test123"
#: components/gpu.tsx:40
# (PPT Limits override toggle description)
msgid "Override APU TDP settings"
msgstr "test123"
#: components/gpu.tsx:63
# (SlowPPT slider with unit)
msgid "SlowPPT (W)"
msgstr "test123"
#: components/gpu.tsx:87
# (FastPPT slider with unit)
msgid "FastPPT (W)"
msgstr "test123"
#: components/gpu.tsx:112
# (Reduce memory clock speed toggle)
msgid "Downclock Memory"
msgstr "test123"
#: components/gpu.tsx:112
# (Reduce memory clock speed toggle description)
msgid "Force RAM into low-power mode"
msgstr "test123"