forked from NG-SD-Plugins/PowerTools
Add minimal store UI functionality
This commit is contained in:
parent
2986c05170
commit
622f161560
13 changed files with 297 additions and 44 deletions
|
@ -28,6 +28,7 @@ pub enum ApiMessage {
|
|||
LoadSystemSettings,
|
||||
GetLimits(Callback<super::SettingsLimits>),
|
||||
GetProvider(String, Callback<crate::persist::DriverJson>),
|
||||
UploadCurrentVariant(String, String), // SteamID, Steam username
|
||||
}
|
||||
|
||||
pub enum BatteryMessage {
|
||||
|
@ -251,7 +252,7 @@ impl GeneralMessage {
|
|||
cb(Vec::with_capacity(0))
|
||||
},
|
||||
},
|
||||
Self::ApplyNow => {}
|
||||
Self::ApplyNow => {},
|
||||
}
|
||||
dirty
|
||||
}
|
||||
|
@ -304,7 +305,7 @@ impl ApiMessageHandler {
|
|||
if is_persistent {
|
||||
let settings_clone = settings.json();
|
||||
let save_json: SettingsJson = settings_clone.into();
|
||||
if let Err(e) = crate::persist::FileJson::update_variant_or_create(&save_path, save_json, settings.general.get_name().to_owned()) {
|
||||
if let Err(e) = crate::persist::FileJson::update_variant_or_create(&save_path, settings.general.get_app_id(), save_json, settings.general.get_name().to_owned()) {
|
||||
log::error!("Failed to create/update settings file {}: {}", save_path.display(), e);
|
||||
}
|
||||
//unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
|
||||
|
@ -383,7 +384,7 @@ impl ApiMessageHandler {
|
|||
}
|
||||
ApiMessage::LoadSettings(id, name, variant_id, variant_name) => {
|
||||
let path = format!("{}.ron", id);
|
||||
match settings.load_file(path.into(), name, variant_id, variant_name, false) {
|
||||
match settings.load_file(path.into(), id, name, variant_id, variant_name, false) {
|
||||
Ok(success) => log::info!("Loaded settings file? {}", success),
|
||||
Err(e) => log::warn!("Load file err: {}", e),
|
||||
}
|
||||
|
@ -391,7 +392,8 @@ impl ApiMessageHandler {
|
|||
}
|
||||
ApiMessage::LoadVariant(variant_id, variant_name) => {
|
||||
let path = settings.general.get_path();
|
||||
match settings.load_file(path.into(), settings.general.get_name().to_owned(), variant_id, variant_name, false) {
|
||||
let app_id = settings.general.get_app_id();
|
||||
match settings.load_file(path.into(), app_id, settings.general.get_name().to_owned(), variant_id, variant_name, false) {
|
||||
Ok(success) => log::info!("Loaded settings file? {}", success),
|
||||
Err(e) => log::warn!("Load file err: {}", e),
|
||||
}
|
||||
|
@ -400,6 +402,7 @@ impl ApiMessageHandler {
|
|||
ApiMessage::LoadMainSettings => {
|
||||
match settings.load_file(
|
||||
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||
0,
|
||||
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||
0,
|
||||
crate::consts::DEFAULT_SETTINGS_VARIANT_NAME.to_owned(),
|
||||
|
@ -431,7 +434,13 @@ impl ApiMessageHandler {
|
|||
_ => settings.general.provider(),
|
||||
});
|
||||
false
|
||||
}
|
||||
},
|
||||
ApiMessage::UploadCurrentVariant(steam_id, steam_username) => {
|
||||
//TODO
|
||||
let steam_app_id = settings.general.get_app_id();
|
||||
super::web::upload_settings(steam_app_id, steam_id, steam_username, settings.json());
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,34 +87,104 @@ fn web_config_to_settings_json(meta: community_settings_core::v1::Metadata) -> c
|
|||
}
|
||||
}
|
||||
|
||||
fn download_config(id: u128) -> std::io::Result<community_settings_core::v1::Metadata> {
|
||||
let req_url = format!("{}/api/setting/by_id/{}", BASE_URL, id);
|
||||
let response = ureq::get(&req_url).call()
|
||||
.map_err(|e| {
|
||||
log::warn!("GET to {} failed: {}", req_url, e);
|
||||
std::io::Error::new(std::io::ErrorKind::ConnectionAborted, e)
|
||||
})?;
|
||||
response.into_json()
|
||||
}
|
||||
|
||||
pub fn upload_settings(id: u64, user_id: String, username: String, settings: crate::persist::SettingsJson) {
|
||||
log::info!("Uploading settings {} by {} ({})", settings.name, username, user_id);
|
||||
let user_id: u64 = match user_id.parse() {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse `{}` as u64: {} (aborted upload_settings very early)", user_id, e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let meta = settings_to_web_config(id as _, user_id, username, settings);
|
||||
if let Err(e) = upload_config(meta) {
|
||||
log::error!("Failed to upload settings: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn settings_to_web_config(app_id: u32, user_id: u64, username: String, settings: crate::persist::SettingsJson) -> community_settings_core::v1::Metadata {
|
||||
community_settings_core::v1::Metadata {
|
||||
name: settings.name,
|
||||
steam_app_id: app_id,
|
||||
steam_user_id: user_id,
|
||||
steam_username: username,
|
||||
tags: vec!["wip".to_owned()],
|
||||
id: "".to_owned(),
|
||||
config: community_settings_core::v1::Config {
|
||||
cpus: settings.cpus.into_iter().map(|cpu| community_settings_core::v1::Cpu {
|
||||
online: cpu.online,
|
||||
clock_limits: cpu.clock_limits.map(|lim| community_settings_core::v1::MinMax {
|
||||
min: lim.min,
|
||||
max: lim.max,
|
||||
}),
|
||||
governor: cpu.governor,
|
||||
}).collect(),
|
||||
gpu: community_settings_core::v1::Gpu {
|
||||
fast_ppt: settings.gpu.fast_ppt,
|
||||
slow_ppt: settings.gpu.slow_ppt,
|
||||
tdp: settings.gpu.tdp,
|
||||
tdp_boost: settings.gpu.tdp_boost,
|
||||
clock_limits: settings.gpu.clock_limits.map(|lim| community_settings_core::v1::MinMax {
|
||||
min: lim.min,
|
||||
max: lim.max,
|
||||
}),
|
||||
slow_memory: settings.gpu.slow_memory,
|
||||
},
|
||||
battery: community_settings_core::v1::Battery {
|
||||
charge_rate: settings.battery.charge_rate,
|
||||
charge_mode: settings.battery.charge_mode,
|
||||
events: settings.battery.events.into_iter().map(|batt_ev| community_settings_core::v1::BatteryEvent {
|
||||
trigger: batt_ev.trigger,
|
||||
charge_rate: batt_ev.charge_rate,
|
||||
charge_mode: batt_ev.charge_mode,
|
||||
}).collect(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn upload_config(config: community_settings_core::v1::Metadata) -> std::io::Result<()> {
|
||||
let req_url = format!("{}/api/setting", BASE_URL);
|
||||
ureq::post(&req_url)
|
||||
.send_json(&config)
|
||||
.map_err(|e| {
|
||||
log::warn!("POST to {} failed: {}", req_url, e);
|
||||
std::io::Error::new(std::io::ErrorKind::ConnectionAborted, e)
|
||||
})
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
/// Download config web method
|
||||
pub fn download_new_config(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move |id: u128| {
|
||||
let req_url = format!("{}/api/setting/by_id/{}", BASE_URL, id);
|
||||
match ureq::get(&req_url).call() {
|
||||
Ok(response) => {
|
||||
let json_res: std::io::Result<community_settings_core::v1::Metadata> = response.into_json();
|
||||
match json_res {
|
||||
Ok(meta) => {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback =
|
||||
move |values: Vec<super::VariantInfo>| tx.send(values).expect("download_new_config callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::AddVariant(web_config_to_settings_json(meta), Box::new(callback))))
|
||||
.expect("download_new_config send failed");
|
||||
return rx.recv().expect("download_new_config callback recv failed");
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse response from `{}`: {}", req_url, e)
|
||||
}
|
||||
}
|
||||
match download_config(id) {
|
||||
Ok(meta) => {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback =
|
||||
move |values: Vec<super::VariantInfo>| tx.send(values).expect("download_new_config callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::AddVariant(web_config_to_settings_json(meta), Box::new(callback))))
|
||||
.expect("download_new_config send failed");
|
||||
return rx.recv().expect("download_new_config callback recv failed");
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Invalid response from download: {}", e);
|
||||
}
|
||||
Err(e) => log::warn!("Cannot get setting result from `{}`: {}", req_url, e),
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
|
@ -140,3 +210,36 @@ pub fn download_new_config(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Upload currently-loaded variant
|
||||
pub fn upload_current_variant(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move |(steam_id, steam_username): (String, String)| {
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::UploadCurrentVariant(steam_id, steam_username))
|
||||
.expect("upload_current_variant send failed");
|
||||
true
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIsh {
|
||||
trans_setter: |params| {
|
||||
if let Some(Primitive::String(steam_id)) = params.get(0) {
|
||||
if let Some(Primitive::String(steam_username)) = params.get(1) {
|
||||
Ok((steam_id.to_owned(), steam_username.to_owned()))
|
||||
} else {
|
||||
Err("upload_current_variant missing/invalid parameter 1".to_owned())
|
||||
}
|
||||
} else {
|
||||
Err("upload_current_variant missing/invalid parameter 0".to_owned())
|
||||
}
|
||||
},
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
vec![result.into()]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,15 +77,17 @@ fn main() -> Result<(), ()> {
|
|||
let mut loaded_settings =
|
||||
persist::FileJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||
.map(|mut file| file.variants.remove(&0)
|
||||
.map(|settings| settings::Settings::from_json(DEFAULT_SETTINGS_NAME.into(), settings, DEFAULT_SETTINGS_FILE.into()))
|
||||
.map(|settings| settings::Settings::from_json(DEFAULT_SETTINGS_NAME.into(), settings, DEFAULT_SETTINGS_FILE.into(), 0))
|
||||
.unwrap_or_else(|| settings::Settings::system_default(
|
||||
DEFAULT_SETTINGS_FILE.into(),
|
||||
0,
|
||||
DEFAULT_SETTINGS_NAME.into(),
|
||||
0,
|
||||
DEFAULT_SETTINGS_VARIANT_NAME.into())))
|
||||
.unwrap_or_else(|_| {
|
||||
settings::Settings::system_default(
|
||||
DEFAULT_SETTINGS_FILE.into(),
|
||||
0,
|
||||
DEFAULT_SETTINGS_NAME.into(),
|
||||
0,
|
||||
DEFAULT_SETTINGS_VARIANT_NAME.into(),
|
||||
|
@ -320,6 +322,10 @@ fn main() -> Result<(), ()> {
|
|||
.register_async(
|
||||
"WEB_download_new",
|
||||
api::web::download_new_config(api_sender.clone())
|
||||
)
|
||||
.register_async(
|
||||
"WEB_upload_new",
|
||||
api::web::upload_current_variant(api_sender.clone())
|
||||
);
|
||||
|
||||
utility::ioperm_power_ec();
|
||||
|
|
|
@ -9,6 +9,7 @@ use super::SettingsJson;
|
|||
pub struct FileJson {
|
||||
pub version: u64,
|
||||
pub name: String,
|
||||
pub app_id: u64,
|
||||
pub variants: HashMap<u64, SettingsJson>,
|
||||
}
|
||||
|
||||
|
@ -44,7 +45,7 @@ impl FileJson {
|
|||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn update_variant_or_create<P: AsRef<std::path::Path>>(path: P, mut setting: SettingsJson, given_name: String) -> Result<Self, SerdeError> {
|
||||
pub fn update_variant_or_create<P: AsRef<std::path::Path>>(path: P, app_id: u64, mut setting: SettingsJson, given_name: String) -> Result<Self, SerdeError> {
|
||||
if !setting.persistent {
|
||||
return Self::open(path)
|
||||
}
|
||||
|
@ -62,6 +63,7 @@ impl FileJson {
|
|||
setting_variants.insert(setting.variant, setting);
|
||||
Self {
|
||||
version: 0,
|
||||
app_id: app_id,
|
||||
name: given_name,
|
||||
variants: setting_variants,
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ pub fn auto_detect_provider() -> DriverJson {
|
|||
let provider = auto_detect0(
|
||||
None,
|
||||
crate::utility::settings_dir().join("autodetect.json"),
|
||||
0,
|
||||
"".to_owned(),
|
||||
0,
|
||||
crate::consts::DEFAULT_SETTINGS_VARIANT_NAME.to_owned(),
|
||||
|
@ -76,6 +77,7 @@ pub fn auto_detect_provider() -> DriverJson {
|
|||
pub fn auto_detect0(
|
||||
settings_opt: Option<&SettingsJson>,
|
||||
json_path: std::path::PathBuf,
|
||||
app_id: u64,
|
||||
name: String,
|
||||
variant_id: u64,
|
||||
variant_name: String,
|
||||
|
@ -83,6 +85,7 @@ pub fn auto_detect0(
|
|||
let mut general_driver = Box::new(General {
|
||||
persistent: false,
|
||||
path: json_path,
|
||||
app_id,
|
||||
name,
|
||||
variant_id,
|
||||
variant_name,
|
||||
|
|
|
@ -13,14 +13,15 @@ impl Driver {
|
|||
name: String,
|
||||
settings: &SettingsJson,
|
||||
json_path: std::path::PathBuf,
|
||||
app_id: u64,
|
||||
) -> Self {
|
||||
let name_bup = settings.name.clone();
|
||||
let id_bup = settings.variant;
|
||||
auto_detect0(Some(settings), json_path, name, id_bup, name_bup)
|
||||
auto_detect0(Some(settings), json_path, app_id, name, id_bup, name_bup)
|
||||
}
|
||||
|
||||
pub fn system_default(json_path: std::path::PathBuf, name: String, variant_id: u64, variant_name: String) -> Self {
|
||||
auto_detect0(None, json_path, name, variant_id, variant_name)
|
||||
pub fn system_default(json_path: std::path::PathBuf, app_id: u64, name: String, variant_id: u64, variant_name: String) -> Self {
|
||||
auto_detect0(None, json_path, app_id, name, variant_id, variant_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ impl std::fmt::Display for SettingVariant {
|
|||
pub struct General {
|
||||
pub persistent: bool,
|
||||
pub path: PathBuf,
|
||||
pub app_id: u64,
|
||||
pub name: String,
|
||||
pub variant_id: u64,
|
||||
pub variant_name: String,
|
||||
|
@ -73,6 +74,14 @@ impl TGeneral for General {
|
|||
self.path = path;
|
||||
}
|
||||
|
||||
fn app_id(&mut self) -> &'_ mut u64 {
|
||||
&mut self.app_id
|
||||
}
|
||||
|
||||
fn get_app_id(&self) -> u64 {
|
||||
self.app_id
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &'_ str {
|
||||
&self.name
|
||||
}
|
||||
|
@ -108,7 +117,7 @@ impl TGeneral for General {
|
|||
|
||||
fn add_variant(&self, variant: crate::persist::SettingsJson) -> Result<Vec<crate::api::VariantInfo>, SettingError> {
|
||||
let variant_name = variant.name.clone();
|
||||
crate::persist::FileJson::update_variant_or_create(self.get_path(), variant, variant_name)
|
||||
crate::persist::FileJson::update_variant_or_create(self.get_path(), self.get_app_id(), variant, variant_name)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("failed to add variant: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
|
@ -173,8 +182,8 @@ impl OnSet for Settings {
|
|||
|
||||
impl Settings {
|
||||
#[inline]
|
||||
pub fn from_json(name: String, other: SettingsJson, json_path: PathBuf) -> Self {
|
||||
let x = super::Driver::init(name, &other, json_path.clone());
|
||||
pub fn from_json(name: String, other: SettingsJson, json_path: PathBuf, app_id: u64) -> Self {
|
||||
let x = super::Driver::init(name, &other, json_path.clone(), app_id);
|
||||
log::info!(
|
||||
"Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}",
|
||||
x.general.provider(),
|
||||
|
@ -190,8 +199,8 @@ impl Settings {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn system_default(json_path: PathBuf, name: String, variant_id: u64, variant_name: String) -> Self {
|
||||
let driver = super::Driver::system_default(json_path, name, variant_id, variant_name);
|
||||
pub fn system_default(json_path: PathBuf, app_id: u64, name: String, variant_id: u64, variant_name: String) -> Self {
|
||||
let driver = super::Driver::system_default(json_path, app_id, name, variant_id, variant_name);
|
||||
Self {
|
||||
general: driver.general,
|
||||
cpus: driver.cpus,
|
||||
|
@ -201,7 +210,7 @@ impl Settings {
|
|||
}
|
||||
|
||||
pub fn load_system_default(&mut self, name: String, variant_id: u64, variant_name: String) {
|
||||
let driver = super::Driver::system_default(self.general.get_path().to_owned(), name, variant_id, variant_name);
|
||||
let driver = super::Driver::system_default(self.general.get_path().to_owned(), self.general.get_app_id(), name, variant_id, variant_name);
|
||||
self.cpus = driver.cpus;
|
||||
self.gpu = driver.gpu;
|
||||
self.battery = driver.battery;
|
||||
|
@ -222,6 +231,7 @@ impl Settings {
|
|||
pub fn load_file(
|
||||
&mut self,
|
||||
filename: PathBuf,
|
||||
app_id: u64,
|
||||
name: String,
|
||||
variant: u64,
|
||||
variant_name: String,
|
||||
|
@ -231,7 +241,7 @@ impl Settings {
|
|||
if json_path.exists() {
|
||||
if variant == u64::MAX {
|
||||
*self.general.persistent() = true;
|
||||
let file_json = FileJson::update_variant_or_create(&json_path, self.json(), variant_name.clone()).map_err(|e| SettingError {
|
||||
let file_json = FileJson::update_variant_or_create(&json_path, app_id, self.json(), variant_name.clone()).map_err(|e| SettingError {
|
||||
msg: format!("Failed to open settings {}: {}", json_path.display(), e),
|
||||
setting: SettingVariant::General,
|
||||
})?;
|
||||
|
@ -252,7 +262,7 @@ impl Settings {
|
|||
*self.general.persistent() = false;
|
||||
self.general.name(name);
|
||||
} else {
|
||||
let x = super::Driver::init(name, settings_json, json_path.clone());
|
||||
let x = super::Driver::init(name, settings_json, json_path.clone(), app_id);
|
||||
log::info!("Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}", x.general.provider(), x.cpus.provider(), x.gpu.provider(), x.battery.provider());
|
||||
self.general = x.general;
|
||||
self.cpus = x.cpus;
|
||||
|
@ -270,6 +280,7 @@ impl Settings {
|
|||
}
|
||||
*self.general.persistent() = false;
|
||||
}
|
||||
*self.general.app_id() = app_id;
|
||||
self.general.path(filename);
|
||||
self.general.variant_id(variant);
|
||||
Ok(*self.general.persistent())
|
||||
|
|
|
@ -105,6 +105,10 @@ pub trait TGeneral: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
|||
|
||||
fn path(&mut self, path: std::path::PathBuf);
|
||||
|
||||
fn app_id(&mut self) -> &'_ mut u64;
|
||||
|
||||
fn get_app_id(&self) -> u64;
|
||||
|
||||
fn get_name(&self) -> &'_ str;
|
||||
|
||||
fn name(&mut self, name: String);
|
||||
|
|
|
@ -383,6 +383,10 @@ export async function storeDownloadById(id: string): Promise<VariantInfo[]> {
|
|||
return (await call_backend("WEB_download_new", [id]));
|
||||
}
|
||||
|
||||
export async function storeUpload(steam_id: string, steam_username: string): Promise<VariantInfo[]> {
|
||||
return (await call_backend("WEB_upload_new", [steam_id, steam_username]));
|
||||
}
|
||||
|
||||
export async function getAllSettingVariants(): Promise<VariantInfo[]> {
|
||||
console.log("GENERAL_get_all_variants");
|
||||
return (await call_backend("GENERAL_get_all_variants", []));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Fragment } from "react";
|
||||
import {Component} from "react";
|
||||
import { Component } from "react";
|
||||
import {
|
||||
ToggleField,
|
||||
SliderField,
|
||||
|
|
|
@ -35,6 +35,13 @@ export const CURRENT_VARIANT_GEN = "GENERAL_current_variant";
|
|||
|
||||
export const MESSAGE_LIST = "MESSAGE_messages";
|
||||
|
||||
export const INTERNAL_STEAM_ID = "INTERNAL_steam_id";
|
||||
export const INTERNAL_STEAM_USERNAME = "INTERNAL_stream_username";
|
||||
|
||||
export const STORE_RESULTS = "INTERNAL_store_results";
|
||||
|
||||
export const PERIODICAL_BACKEND_PERIOD = 5000; // milliseconds
|
||||
export const AUTOMATIC_REAPPLY_WAIT = 2000; // milliseconds
|
||||
|
||||
export const STORE_RESULTS_URI = "/plugins/PowerTools/settings_store";
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
Field,
|
||||
Dropdown,
|
||||
SingleDropdownOption,
|
||||
Navigation,
|
||||
//NotchLabel
|
||||
//gamepadDialogClasses,
|
||||
//joinClassNames,
|
||||
|
@ -22,6 +23,7 @@ import {
|
|||
import { VFC, useState } from "react";
|
||||
import { GiDrill, GiTimeBomb, GiTimeTrap, GiDynamite } from "react-icons/gi";
|
||||
import { HiRefresh, HiTrash, HiPlus, HiUpload } from "react-icons/hi";
|
||||
import { TbWorldPlus } from "react-icons/tb";
|
||||
|
||||
//import * as python from "./python";
|
||||
import * as backend from "./backend";
|
||||
|
@ -63,6 +65,12 @@ import {
|
|||
|
||||
MESSAGE_LIST,
|
||||
|
||||
INTERNAL_STEAM_ID,
|
||||
INTERNAL_STEAM_USERNAME,
|
||||
|
||||
STORE_RESULTS,
|
||||
STORE_RESULTS_URI,
|
||||
|
||||
PERIODICAL_BACKEND_PERIOD,
|
||||
AUTOMATIC_REAPPLY_WAIT,
|
||||
} from "./consts";
|
||||
|
@ -73,10 +81,13 @@ import { Battery } from "./components/battery";
|
|||
import { Cpus } from "./components/cpus";
|
||||
import { DevMessages } from "./components/message";
|
||||
|
||||
import { StoreResultsPage } from "./store/page";
|
||||
|
||||
var periodicHook: NodeJS.Timeout | null = null;
|
||||
var lifetimeHook: any = null;
|
||||
var startHook: any = null;
|
||||
var endHook: any = null;
|
||||
var userHook: any = null;
|
||||
var usdplReady = false;
|
||||
|
||||
var tryNotifyProfileChange = function() {};
|
||||
|
@ -118,6 +129,10 @@ const reload = function() {
|
|||
console.debug("POWERTOOLS: got limits ", limits);
|
||||
});
|
||||
|
||||
if (!get_value(STORE_RESULTS)) {
|
||||
backend.resolve(backend.searchStoreByAppId(0), (results) => set_value(STORE_RESULTS, results));
|
||||
}
|
||||
|
||||
backend.resolve(backend.getBatteryCurrent(), (rate: number) => { set_value(CURRENT_BATT, rate) });
|
||||
backend.resolve_nullable(backend.getBatteryChargeRate(), (rate: number | null) => { set_value(CHARGE_RATE_BATT, rate) });
|
||||
backend.resolve_nullable(backend.getBatteryChargeMode(), (mode: string | null) => { set_value(CHARGE_MODE_BATT, mode) });
|
||||
|
@ -175,6 +190,7 @@ const clearHooks = function() {
|
|||
lifetimeHook?.unregister();
|
||||
startHook?.unregister();
|
||||
endHook?.unregister();
|
||||
userHook?.unregister();
|
||||
|
||||
backend.log(backend.LogLevel.Info, "Unregistered PowerTools callbacks, so long and thanks for all the fish.");
|
||||
};
|
||||
|
@ -209,7 +225,6 @@ const registerCallbacks = function(autoclear: boolean) {
|
|||
let appId = gameInfo.appid.toString();
|
||||
|
||||
backend.log(backend.LogLevel.Info, "RegisterForGameActionStart callback(" + actionType + ", " + id + ")");
|
||||
// don't use gameInfo.appid, haha
|
||||
backend.resolve(
|
||||
backend.loadGeneralSettings(appId, gameInfo.display_name, "0", undefined),
|
||||
(ok: boolean) => {
|
||||
|
@ -221,6 +236,12 @@ const registerCallbacks = function(autoclear: boolean) {
|
|||
});
|
||||
}
|
||||
);
|
||||
backend.resolve(
|
||||
backend.searchStoreByAppId(appId),
|
||||
(results: backend.StoreMetadata[]) => {
|
||||
set_value(STORE_RESULTS, results);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// this fires immediately, so let's ignore that callback
|
||||
|
@ -236,6 +257,20 @@ const registerCallbacks = function(autoclear: boolean) {
|
|||
setTimeout(() => backend.forceApplySettings(), AUTOMATIC_REAPPLY_WAIT);
|
||||
});
|
||||
|
||||
//@ts-ignore
|
||||
userHook = SteamClient.User.RegisterForCurrentUserChanges((data) => {
|
||||
const accountName = data.strAccountName;
|
||||
const steamId = data.strSteamID;
|
||||
SteamClient.User.GetLoginUsers().then((users: any) => {
|
||||
users.forEach((user: any) => {
|
||||
if (user && user.accountName == accountName) {
|
||||
set_value(INTERNAL_STEAM_ID, steamId);
|
||||
set_value(INTERNAL_STEAM_USERNAME, user.personaName ? user.personaName : accountName);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
backend.log(backend.LogLevel.Debug, "Registered PowerTools callbacks, hello!");
|
||||
};
|
||||
|
||||
|
@ -373,7 +408,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
|||
}}>
|
||||
<DialogButton
|
||||
style={{
|
||||
maxWidth: "45%",
|
||||
maxWidth: "30%",
|
||||
minWidth: "auto",
|
||||
}}
|
||||
//layout="below"
|
||||
|
@ -396,16 +431,35 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
|||
</DialogButton>
|
||||
<DialogButton
|
||||
style={{
|
||||
maxWidth: "45%",
|
||||
maxWidth: "30%",
|
||||
minWidth: "auto",
|
||||
}}
|
||||
//layout="below"
|
||||
onClick={(_: MouseEvent) => {
|
||||
backend.log(backend.LogLevel.Debug, "Clicked on unimplemented upload button");
|
||||
const steamId = get_value(INTERNAL_STEAM_ID);
|
||||
const steamName = get_value(INTERNAL_STEAM_USERNAME);
|
||||
if (steamId && steamName) {
|
||||
backend.storeUpload(steamId, steamName);
|
||||
} else {
|
||||
backend.log(backend.LogLevel.Warn, "Cannot upload with null steamID (is null: " + !steamId + ") and/or username (is null: " + !steamName + ")");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<HiUpload/>
|
||||
</DialogButton>
|
||||
<DialogButton
|
||||
style={{
|
||||
maxWidth: "30%",
|
||||
minWidth: "auto",
|
||||
}}
|
||||
//layout="below"
|
||||
onClick={(_: MouseEvent) => {
|
||||
Navigation.Navigate(STORE_RESULTS_URI);
|
||||
Navigation.CloseSideMenus();
|
||||
}}
|
||||
>
|
||||
<TbWorldPlus />
|
||||
</DialogButton>
|
||||
</PanelSectionRow>
|
||||
|
||||
<Debug idc={idc}/>
|
||||
|
@ -453,6 +507,7 @@ export default definePlugin((serverApi: ServerAPI) => {
|
|||
ico = <span><GiDynamite /><GiTimeTrap /><GiTimeBomb /></span>;
|
||||
}
|
||||
//registerCallbacks(false);
|
||||
serverApi.routerHook.addRoute(STORE_RESULTS_URI, StoreResultsPage);
|
||||
return {
|
||||
title: <div className={staticClasses.Title}>PowerTools</div>,
|
||||
content: <Content serverAPI={serverApi} />,
|
||||
|
|
48
src/store/page.tsx
Normal file
48
src/store/page.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { Component, Fragment } from "react";
|
||||
|
||||
import * as backend from "../backend";
|
||||
import { tr } from "usdpl-front";
|
||||
import { get_value} from "usdpl-front";
|
||||
|
||||
import {
|
||||
STORE_RESULTS,
|
||||
} from "../consts";
|
||||
|
||||
export class StoreResultsPage extends Component {
|
||||
constructor() {
|
||||
super({});
|
||||
this.state = {
|
||||
reloadThingy: "/shrug",
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const storeItems = get_value(STORE_RESULTS) as backend.StoreMetadata[] | undefined;
|
||||
console.log("POWERTOOLS: Rendering store results", storeItems);
|
||||
if (storeItems) {
|
||||
if (storeItems.length == 0) {
|
||||
backend.log(backend.LogLevel.Warn, "No store results; got array with length 0 from cache");
|
||||
return (<div>
|
||||
{ tr("No results") /* TODO translate */ }
|
||||
</div>);
|
||||
} else {
|
||||
// TODO
|
||||
return storeItems.map((meta: backend.StoreMetadata) => {
|
||||
<div>
|
||||
<div> { meta.name } </div>
|
||||
<div> { tr("Created by") /* TODO translate */} { meta.steam_username } </div>
|
||||
<div> { meta.tags.map((tag: string) => <span>{tag}</span>) } </div>
|
||||
Hey NG you should finish this page
|
||||
</div>
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
backend.log(backend.LogLevel.Warn, "Store failed to load; got null from cache");
|
||||
// store did not pre-load when the game started
|
||||
return (<Fragment>
|
||||
{ tr("Store failed to load") /* TODO translate */ }
|
||||
</Fragment>);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue