You've already forked AstralRinth
forked from didirus/AstralRinth
* Make theseus capable of logging messages from the `log` crate * Move update checking entirely into JS and open a modal if an update is available * Fix formatjs on Windows and run formatjs * Add in the buttons and body * Fix lint * Show update size in modal * Fix update not being rechecked if the update modal was directly dismissed * Slight UI tweaks * Fix lint * Implement skipping the update * Implement the Update Now button * Implement updating at next exit * Turn download progress into an error bar on failure * Restore 5 minute update check instead of 30 seconds * Fix PendingUpdateData being seen as a unit struct * Fix lint * Make CI also lint updater code * feat: create AppearingProgressBar component * feat: polish update available modal * feat: add error handling * Open changelog with tauri-plugin-opener * Run intl:extract * Update completion toasts (#3978) * Use single LAUNCHER_USER_AGENT constant for all user agents * Fix build on Mac * Request the update size with HEAD instead of GET * UI tweaks * lint * Fix lint * fix: hide modal header & add "Hide update reminder" button w/ tooltip * Run intl:extract * fix: lint issues * fix: merge issues * notifications.js no longer exists * Add metered network checking * Add a timeout to macOS is_network_metered * Fix tauri.conf.json * vibe debugging * Set a dispatch queue * Have a popup that asks you if you'd like to disable automatic file downloads if you're on a metered network * Move UpdateModal to modal package * Fix lint * Add a toggle for automatic downloads * Fix type Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com> Signed-off-by: Josiah Glosson <soujournme@gmail.com> * Redo updating UI and experience * lint * fix unlistener issue * remove unneeded translation keys * Fix expose issue * temp disable cranelift, tweak some messages * change version back * Clean up App.vue * move toast to top right * update reload icon * Fixed the bug!!!!!!!!!!!! * improve messages * intl:extract * Add liquid glass icon file * not you! * use dependency injection * lint on apple icon * Fix imports, move download size to button * change update check back to 5 mins * lint + move to providers * intl:extract --------- Signed-off-by: Cal H. <hendersoncal117@gmail.com> Signed-off-by: Josiah Glosson <soujournme@gmail.com> Co-authored-by: Calum <calum@modrinth.com> Co-authored-by: Prospector <prospectordev@gmail.com> Co-authored-by: Cal H. <hendersoncal117@gmail.com> Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com> Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
303 lines
9.5 KiB
Rust
303 lines
9.5 KiB
Rust
//! Theseus settings file
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
|
|
// Types
|
|
/// Global Theseus settings
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Settings {
|
|
pub max_concurrent_downloads: usize,
|
|
pub max_concurrent_writes: usize,
|
|
|
|
pub theme: Theme,
|
|
pub default_page: DefaultPage,
|
|
pub collapsed_navigation: bool,
|
|
pub hide_nametag_skins_page: bool,
|
|
pub advanced_rendering: bool,
|
|
pub native_decorations: bool,
|
|
pub toggle_sidebar: bool,
|
|
|
|
pub telemetry: bool,
|
|
pub discord_rpc: bool,
|
|
pub personalized_ads: bool,
|
|
|
|
pub onboarded: bool,
|
|
|
|
pub extra_launch_args: Vec<String>,
|
|
pub custom_env_vars: Vec<(String, String)>,
|
|
pub memory: MemorySettings,
|
|
pub force_fullscreen: bool,
|
|
pub game_resolution: WindowSize,
|
|
pub hide_on_process_start: bool,
|
|
pub hooks: Hooks,
|
|
|
|
pub custom_dir: Option<String>,
|
|
pub prev_custom_dir: Option<String>,
|
|
pub migrated: bool,
|
|
|
|
pub developer_mode: bool,
|
|
pub feature_flags: HashMap<FeatureFlag, bool>,
|
|
|
|
pub skipped_update: Option<String>,
|
|
pub pending_update_toast_for_version: Option<String>,
|
|
pub auto_download_updates: Option<bool>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, Hash, PartialEq)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum FeatureFlag {
|
|
PagePath,
|
|
ProjectBackground,
|
|
WorldsTab,
|
|
WorldsInHome,
|
|
}
|
|
|
|
impl Settings {
|
|
pub async fn get(
|
|
exec: impl sqlx::Executor<'_, Database = sqlx::Sqlite>,
|
|
) -> crate::Result<Self> {
|
|
let res = sqlx::query!(
|
|
"
|
|
SELECT
|
|
max_concurrent_writes, max_concurrent_downloads,
|
|
theme, default_page, collapsed_navigation, hide_nametag_skins_page, advanced_rendering, native_decorations,
|
|
discord_rpc, developer_mode, telemetry, personalized_ads,
|
|
onboarded,
|
|
json(extra_launch_args) extra_launch_args, json(custom_env_vars) custom_env_vars,
|
|
mc_memory_max, mc_force_fullscreen, mc_game_resolution_x, mc_game_resolution_y, hide_on_process_start,
|
|
hook_pre_launch, hook_wrapper, hook_post_exit,
|
|
custom_dir, prev_custom_dir, migrated, json(feature_flags) feature_flags, toggle_sidebar,
|
|
skipped_update, pending_update_toast_for_version, auto_download_updates
|
|
FROM settings
|
|
"
|
|
)
|
|
.fetch_one(exec)
|
|
.await?;
|
|
|
|
Ok(Self {
|
|
max_concurrent_downloads: res.max_concurrent_downloads as usize,
|
|
max_concurrent_writes: res.max_concurrent_writes as usize,
|
|
theme: Theme::from_string(&res.theme),
|
|
default_page: DefaultPage::from_string(&res.default_page),
|
|
collapsed_navigation: res.collapsed_navigation == 1,
|
|
hide_nametag_skins_page: res.hide_nametag_skins_page == 1,
|
|
advanced_rendering: res.advanced_rendering == 1,
|
|
native_decorations: res.native_decorations == 1,
|
|
toggle_sidebar: res.toggle_sidebar == 1,
|
|
telemetry: res.telemetry == 1,
|
|
discord_rpc: res.discord_rpc == 1,
|
|
developer_mode: res.developer_mode == 1,
|
|
personalized_ads: res.personalized_ads == 1,
|
|
onboarded: res.onboarded == 1,
|
|
extra_launch_args: res
|
|
.extra_launch_args
|
|
.as_ref()
|
|
.and_then(|x| serde_json::from_str(x).ok())
|
|
.unwrap_or_default(),
|
|
custom_env_vars: res
|
|
.custom_env_vars
|
|
.as_ref()
|
|
.and_then(|x| serde_json::from_str(x).ok())
|
|
.unwrap_or_default(),
|
|
memory: MemorySettings {
|
|
maximum: res.mc_memory_max as u32,
|
|
},
|
|
force_fullscreen: res.mc_force_fullscreen == 1,
|
|
game_resolution: WindowSize(
|
|
res.mc_game_resolution_x as u16,
|
|
res.mc_game_resolution_y as u16,
|
|
),
|
|
hide_on_process_start: res.hide_on_process_start == 1,
|
|
hooks: Hooks {
|
|
pre_launch: res.hook_pre_launch,
|
|
wrapper: res.hook_wrapper,
|
|
post_exit: res.hook_post_exit,
|
|
},
|
|
custom_dir: res.custom_dir,
|
|
prev_custom_dir: res.prev_custom_dir,
|
|
migrated: res.migrated == 1,
|
|
feature_flags: res
|
|
.feature_flags
|
|
.as_ref()
|
|
.and_then(|x| serde_json::from_str(x).ok())
|
|
.unwrap_or_default(),
|
|
skipped_update: res.skipped_update,
|
|
pending_update_toast_for_version: res
|
|
.pending_update_toast_for_version,
|
|
auto_download_updates: res.auto_download_updates.map(|x| x == 1),
|
|
})
|
|
}
|
|
|
|
pub async fn update(
|
|
&self,
|
|
exec: impl sqlx::Executor<'_, Database = sqlx::Sqlite>,
|
|
) -> crate::Result<()> {
|
|
let max_concurrent_writes = self.max_concurrent_writes as i32;
|
|
let max_concurrent_downloads = self.max_concurrent_downloads as i32;
|
|
let theme = self.theme.as_str();
|
|
let default_page = self.default_page.as_str();
|
|
let extra_launch_args = serde_json::to_string(&self.extra_launch_args)?;
|
|
let custom_env_vars = serde_json::to_string(&self.custom_env_vars)?;
|
|
let feature_flags = serde_json::to_string(&self.feature_flags)?;
|
|
|
|
sqlx::query!(
|
|
"
|
|
UPDATE settings
|
|
SET
|
|
max_concurrent_writes = $1,
|
|
max_concurrent_downloads = $2,
|
|
|
|
theme = $3,
|
|
default_page = $4,
|
|
collapsed_navigation = $5,
|
|
advanced_rendering = $6,
|
|
native_decorations = $7,
|
|
|
|
discord_rpc = $8,
|
|
developer_mode = $9,
|
|
telemetry = $10,
|
|
personalized_ads = $11,
|
|
|
|
onboarded = $12,
|
|
|
|
extra_launch_args = jsonb($13),
|
|
custom_env_vars = jsonb($14),
|
|
mc_memory_max = $15,
|
|
mc_force_fullscreen = $16,
|
|
mc_game_resolution_x = $17,
|
|
mc_game_resolution_y = $18,
|
|
hide_on_process_start = $19,
|
|
|
|
hook_pre_launch = $20,
|
|
hook_wrapper = $21,
|
|
hook_post_exit = $22,
|
|
|
|
custom_dir = $23,
|
|
prev_custom_dir = $24,
|
|
migrated = $25,
|
|
|
|
toggle_sidebar = $26,
|
|
feature_flags = $27,
|
|
hide_nametag_skins_page = $28,
|
|
|
|
skipped_update = $29,
|
|
pending_update_toast_for_version = $30,
|
|
auto_download_updates = $31
|
|
",
|
|
max_concurrent_writes,
|
|
max_concurrent_downloads,
|
|
theme,
|
|
default_page,
|
|
self.collapsed_navigation,
|
|
self.advanced_rendering,
|
|
self.native_decorations,
|
|
self.discord_rpc,
|
|
self.developer_mode,
|
|
self.telemetry,
|
|
self.personalized_ads,
|
|
self.onboarded,
|
|
extra_launch_args,
|
|
custom_env_vars,
|
|
self.memory.maximum,
|
|
self.force_fullscreen,
|
|
self.game_resolution.0,
|
|
self.game_resolution.1,
|
|
self.hide_on_process_start,
|
|
self.hooks.pre_launch,
|
|
self.hooks.wrapper,
|
|
self.hooks.post_exit,
|
|
self.custom_dir,
|
|
self.prev_custom_dir,
|
|
self.migrated,
|
|
self.toggle_sidebar,
|
|
feature_flags,
|
|
self.hide_nametag_skins_page,
|
|
self.skipped_update,
|
|
self.pending_update_toast_for_version,
|
|
self.auto_download_updates,
|
|
)
|
|
.execute(exec)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Theseus theme
|
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum Theme {
|
|
Dark,
|
|
Light,
|
|
Oled,
|
|
System,
|
|
}
|
|
|
|
impl Theme {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Theme::Dark => "dark",
|
|
Theme::Light => "light",
|
|
Theme::Oled => "oled",
|
|
Theme::System => "system",
|
|
}
|
|
}
|
|
|
|
pub fn from_string(string: &str) -> Theme {
|
|
match string {
|
|
"dark" => Theme::Dark,
|
|
"light" => Theme::Light,
|
|
"oled" => Theme::Oled,
|
|
"system" => Theme::System,
|
|
_ => Theme::Dark,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Minecraft memory settings
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
|
pub struct MemorySettings {
|
|
pub maximum: u32,
|
|
}
|
|
|
|
/// Game window size
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
|
pub struct WindowSize(pub u16, pub u16);
|
|
|
|
/// Game initialization hooks
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[serde_with::serde_as]
|
|
pub struct Hooks {
|
|
#[serde_as(as = "serde_with::NoneAsEmptyString")]
|
|
pub pre_launch: Option<String>,
|
|
#[serde_as(as = "serde_with::NoneAsEmptyString")]
|
|
pub wrapper: Option<String>,
|
|
#[serde_as(as = "serde_with::NoneAsEmptyString")]
|
|
pub post_exit: Option<String>,
|
|
}
|
|
|
|
/// Opening window to start with
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
|
pub enum DefaultPage {
|
|
Home,
|
|
Library,
|
|
}
|
|
|
|
impl DefaultPage {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
DefaultPage::Home => "home",
|
|
DefaultPage::Library => "library",
|
|
}
|
|
}
|
|
|
|
pub fn from_string(string: &str) -> Self {
|
|
match string {
|
|
"home" => Self::Home,
|
|
"library" => Self::Library,
|
|
_ => Self::Home,
|
|
}
|
|
}
|
|
}
|