feat: SettingsContext + Temporary fix for failing to fetch manifest
This commit is contained in:
parent
9cd0cebd06
commit
19ade5dc81
17 changed files with 175 additions and 138 deletions
|
|
@ -7,6 +7,7 @@ use crate::proxy::ClusterPayloadType;
|
|||
pub use crate::store::{Cluster, ClusterPath, JavaOptions, PackageData, State};
|
||||
use crate::utils::io::{self, canonicalize};
|
||||
use crate::{cluster, package};
|
||||
use anyhow::anyhow;
|
||||
use interpulse::api::modded::LoaderVersion;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
@ -226,6 +227,10 @@ pub(crate) async fn get_loader_version(
|
|||
_ => return Err(CreateClusterError::MissingManifest(loader.to_string()).into()),
|
||||
};
|
||||
|
||||
let loader_meta = loader_meta
|
||||
.to_owned()
|
||||
.ok_or(anyhow!("missing loader meta"))?;
|
||||
|
||||
let loaders = &loader_meta
|
||||
.game_versions
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use std::future::Future;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use tokio::process::Command;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
|
|
@ -311,8 +312,9 @@ pub async fn get_optimal_java_version(path: &ClusterPath) -> crate::Result<Optio
|
|||
let state = State::get().await?;
|
||||
if let Some(cluster) = get(path, None).await? {
|
||||
let metadata = state.metadata.read().await;
|
||||
let version = metadata
|
||||
.minecraft
|
||||
let minecraft_metadata = metadata.minecraft.to_owned().ok_or(anyhow!("misisng minecraft metadata"))?;
|
||||
|
||||
let version = minecraft_metadata
|
||||
.versions
|
||||
.iter()
|
||||
.find(|it| it.id == cluster.meta.mc_version)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Metadata management interface
|
||||
|
||||
use crate::State;
|
||||
use anyhow::anyhow;
|
||||
pub use interpulse::api::minecraft::VersionManifest;
|
||||
pub use interpulse::api::modded::Manifest;
|
||||
|
||||
|
|
@ -8,7 +9,7 @@ pub use interpulse::api::modded::Manifest;
|
|||
#[tracing::instrument]
|
||||
pub async fn get_minecraft_versions() -> crate::Result<VersionManifest> {
|
||||
let state = State::get().await?;
|
||||
let meta = state.metadata.read().await.minecraft.clone();
|
||||
let meta = state.metadata.read().await.minecraft.clone().ok_or(anyhow!("missing minecraft metadata"))?;
|
||||
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
@ -17,7 +18,7 @@ pub async fn get_minecraft_versions() -> crate::Result<VersionManifest> {
|
|||
#[tracing::instrument]
|
||||
pub async fn get_fabric_versions() -> crate::Result<Manifest> {
|
||||
let state = State::get().await?;
|
||||
let meta = state.metadata.read().await.fabric.clone();
|
||||
let meta = state.metadata.read().await.fabric.clone().ok_or(anyhow!("missing fabric metadata"))?;
|
||||
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
@ -26,7 +27,7 @@ pub async fn get_fabric_versions() -> crate::Result<Manifest> {
|
|||
#[tracing::instrument]
|
||||
pub async fn get_quilt_versions() -> crate::Result<Manifest> {
|
||||
let state = State::get().await?;
|
||||
let meta = state.metadata.read().await.quilt.clone();
|
||||
let meta = state.metadata.read().await.quilt.clone().ok_or(anyhow!("missing quilt metadata"))?;
|
||||
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
@ -35,7 +36,7 @@ pub async fn get_quilt_versions() -> crate::Result<Manifest> {
|
|||
#[tracing::instrument]
|
||||
pub async fn get_forge_versions() -> crate::Result<Manifest> {
|
||||
let state = State::get().await?;
|
||||
let meta = state.metadata.read().await.forge.clone();
|
||||
let meta = state.metadata.read().await.forge.clone().ok_or(anyhow!("missing forge metadata"))?;
|
||||
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
@ -44,7 +45,7 @@ pub async fn get_forge_versions() -> crate::Result<Manifest> {
|
|||
#[tracing::instrument]
|
||||
pub async fn get_neoforge_versions() -> crate::Result<Manifest> {
|
||||
let state = State::get().await?;
|
||||
let meta = state.metadata.read().await.neoforge.clone();
|
||||
let meta = state.metadata.read().await.neoforge.clone().ok_or(anyhow!("missing neoforce metadata"))?;
|
||||
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
@ -53,7 +54,7 @@ pub async fn get_neoforge_versions() -> crate::Result<Manifest> {
|
|||
#[tracing::instrument]
|
||||
pub async fn get_legacy_fabric_versions() -> crate::Result<Manifest> {
|
||||
let state = State::get().await?;
|
||||
let meta = state.metadata.read().await.legacy_fabric.clone();
|
||||
let meta = state.metadata.read().await.legacy_fabric.clone().ok_or(anyhow!("missing legacyfabric metadata"))?;
|
||||
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::store::{
|
|||
};
|
||||
use crate::utils::io::{self, IOError};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use chrono::Utc;
|
||||
use interpulse as ip;
|
||||
use interpulse::api::minecraft::{RuleAction, VersionInfo};
|
||||
|
|
@ -71,8 +72,9 @@ pub async fn install_minecraft(
|
|||
let instance_path = &io::canonicalize(cluster.get_full_path().await?)?;
|
||||
let metadata = state.metadata.read().await;
|
||||
|
||||
let version_idx = metadata
|
||||
.minecraft
|
||||
let version_manifest = metadata.minecraft.to_owned().ok_or(anyhow!("missing metadata"))?;
|
||||
|
||||
let version_idx = version_manifest
|
||||
.versions
|
||||
.iter()
|
||||
.position(|g| g.id == cluster.meta.mc_version)
|
||||
|
|
@ -81,11 +83,10 @@ pub async fn install_minecraft(
|
|||
cluster.meta.mc_version
|
||||
))?;
|
||||
|
||||
let version = &metadata.minecraft.versions[version_idx];
|
||||
let version = &version_manifest.versions[version_idx];
|
||||
let updated = version_idx
|
||||
<= metadata
|
||||
.minecraft
|
||||
.versions
|
||||
<= version_manifest
|
||||
.versions
|
||||
.iter()
|
||||
.position(|g| g.id == "22w16a")
|
||||
.unwrap_or(0); // LWJGL patching
|
||||
|
|
@ -273,8 +274,9 @@ pub async fn launch_minecraft(
|
|||
let instance_path = cluster.get_full_path().await?;
|
||||
let instance_path = &io::canonicalize(instance_path)?;
|
||||
|
||||
let version_index = metadata
|
||||
.minecraft
|
||||
let version_manifest = metadata.minecraft.to_owned().ok_or(anyhow!("missing minecraft metadata"))?;
|
||||
|
||||
let version_index = version_manifest
|
||||
.versions
|
||||
.iter()
|
||||
.position(|it| it.id == cluster.meta.mc_version)
|
||||
|
|
@ -282,10 +284,9 @@ pub async fn launch_minecraft(
|
|||
"invalid game version {}",
|
||||
cluster.meta.mc_version
|
||||
))?;
|
||||
let version = &metadata.minecraft.versions[version_index];
|
||||
let version = &version_manifest.versions[version_index];
|
||||
let updated = version_index
|
||||
<= metadata
|
||||
.minecraft
|
||||
<= version_manifest
|
||||
.versions
|
||||
.iter()
|
||||
.position(|x| x.id == "22w16a")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::utils::java;
|
|||
use crate::utils::java::JavaVersion;
|
||||
|
||||
/// A HashMap of all located and installed available Java versions
|
||||
#[cfg_attr(feature = "tauri", derive(specta::Type))]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct JavaVersions(HashMap<String, JavaVersion>);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,17 +24,17 @@ const METADATA_URL: &str = "localhost:5543";
|
|||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Metadata {
|
||||
/// The [`MinecraftManifest`] associated with core Minecraft versions.
|
||||
pub minecraft: MinecraftManifest,
|
||||
pub minecraft: Option<MinecraftManifest>,
|
||||
/// The [`ModdedManifest`] associated with core Fabric versions.
|
||||
pub fabric: ModdedManifest,
|
||||
pub fabric: Option<ModdedManifest>,
|
||||
/// The [`ModdedManifest`] associated with core Quilt versions.
|
||||
pub quilt: ModdedManifest,
|
||||
pub quilt: Option<ModdedManifest>,
|
||||
/// The [`ModdedManifest`] associated with core NeoForge versions.
|
||||
pub neoforge: ModdedManifest,
|
||||
pub neoforge: Option<ModdedManifest>,
|
||||
/// The [`ModdedManifest`] associated with core Forge versions.
|
||||
pub forge: ModdedManifest,
|
||||
pub forge: Option<ModdedManifest>,
|
||||
/// The [`ModdedManifest`] associated with core Legacy Fabric versions.
|
||||
pub legacy_fabric: ModdedManifest,
|
||||
pub legacy_fabric: Option<ModdedManifest>,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
|
|
@ -45,41 +45,49 @@ impl Metadata {
|
|||
|
||||
/// Fetch all available metadata types and get a new [`Metadata`] structure.
|
||||
pub async fn fetch() -> crate::Result<Self> {
|
||||
let (minecraft, fabric, quilt, neoforge, forge, legacy_fabric) = tokio::try_join! {
|
||||
async {
|
||||
let url = Self::get_manifest("minecraft");
|
||||
fetch_version_manifest(Some(&url)).await
|
||||
},
|
||||
async {
|
||||
let url = Self::get_manifest("fabric");
|
||||
fetch_modded_manifest(&url).await
|
||||
},
|
||||
async {
|
||||
let url = Self::get_manifest("quilt");
|
||||
fetch_modded_manifest(&url).await
|
||||
},
|
||||
async {
|
||||
let url = Self::get_manifest("neo");
|
||||
fetch_modded_manifest(&url).await
|
||||
},
|
||||
async {
|
||||
let url = Self::get_manifest("forge");
|
||||
fetch_modded_manifest(&url).await
|
||||
},
|
||||
async {
|
||||
let url = Self::get_manifest("legacy-fabric");
|
||||
fetch_modded_manifest(&url).await
|
||||
},
|
||||
}?;
|
||||
// let (minecraft, fabric, quilt, neoforge, forge, legacy_fabric) = tokio::try_join! {
|
||||
// async {
|
||||
// let url = Self::get_manifest("minecraft");
|
||||
// fetch_version_manifest(Some(&url)).await
|
||||
// },
|
||||
// async {
|
||||
// let url = Self::get_manifest("fabric");
|
||||
// fetch_modded_manifest(&url).await
|
||||
// },
|
||||
// async {
|
||||
// let url = Self::get_manifest("quilt");
|
||||
// fetch_modded_manifest(&url).await
|
||||
// },
|
||||
// async {
|
||||
// let url = Self::get_manifest("neo");
|
||||
// fetch_modded_manifest(&url).await
|
||||
// },
|
||||
// async {
|
||||
// let url = Self::get_manifest("forge");
|
||||
// fetch_modded_manifest(&url).await
|
||||
// },
|
||||
// async {
|
||||
// let url = Self::get_manifest("legacy-fabric");
|
||||
// fetch_modded_manifest(&url).await
|
||||
// },
|
||||
// }?;
|
||||
|
||||
Ok(Self {
|
||||
minecraft,
|
||||
fabric,
|
||||
quilt,
|
||||
neoforge,
|
||||
forge,
|
||||
legacy_fabric,
|
||||
})
|
||||
// Ok(Self {
|
||||
// minecraft,
|
||||
// fabric,
|
||||
// quilt,
|
||||
// neoforge,
|
||||
// forge,
|
||||
// legacy_fabric,
|
||||
// })
|
||||
Ok(Self {
|
||||
minecraft: None,
|
||||
fabric: None,
|
||||
quilt: None,
|
||||
neoforge: None,
|
||||
forge: None,
|
||||
legacy_fabric: None
|
||||
})
|
||||
}
|
||||
|
||||
/// Initialize the core Metadata manager.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
|
|||
const CURRENT_FORMAT_VERSION: u32 = 1;
|
||||
|
||||
/// A global settings state for the launcher.
|
||||
#[cfg_attr(feature = "tauri", derive(specta::Type))]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Settings {
|
||||
/// A OneLauncher [`Theme`] managed by the core GUI.
|
||||
|
|
@ -123,6 +124,7 @@ impl Settings {
|
|||
}
|
||||
|
||||
/// A OneLauncher theme managed by the GUI.
|
||||
#[cfg_attr(feature = "tauri", derive(specta::Type))]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Theme {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ fn main() {
|
|||
"get_clusters",
|
||||
"get_cluster",
|
||||
"get_manifest",
|
||||
"get_settings",
|
||||
"change_settings"
|
||||
]),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,4 +8,6 @@ permissions = [
|
|||
"allow-get-cluster",
|
||||
"allow-get-manifest",
|
||||
"allow-login-msa",
|
||||
"allow-get-settings",
|
||||
"allow-change-settings"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use std::{collections::HashMap, path::PathBuf, str::FromStr};
|
||||
|
||||
use chrono::DateTime;
|
||||
use onelauncher::{cluster, data::{ClusterMeta, Loader, PackageData}, store::{Cluster, ClusterPath}, State};
|
||||
use onelauncher::{cluster, data::{ClusterMeta, Loader, PackageData, Settings}, store::{Cluster, ClusterPath}, State};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[macro_export]
|
||||
|
|
@ -17,7 +18,9 @@ macro_rules! collect_commands {
|
|||
is_dev,
|
||||
create_cluster,
|
||||
get_cluster,
|
||||
get_clusters
|
||||
get_clusters,
|
||||
get_settings,
|
||||
change_settings
|
||||
])
|
||||
}
|
||||
};
|
||||
|
|
@ -117,3 +120,16 @@ pub async fn get_clusters() -> Result<HashMap<ClusterPath, Cluster>, String> {
|
|||
|
||||
// cluster::list(None).await.map_err(|op| op.into())
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn get_settings() -> Result<Settings, String> {
|
||||
Ok(State::get().await?.settings.read().await.clone())
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn change_settings(settings: Settings) -> Result<(), String> {
|
||||
State::get().await?.settings.write().await.clone_from(&settings);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,9 @@ pub async fn run_app<F: FnOnce(&mut tauri::App) + Send + 'static>(
|
|||
.build(tauri::tauri_build_context!())
|
||||
.expect("failed to build tauri application");
|
||||
|
||||
initialize_state(app.app_handle().clone()).await;
|
||||
if let Err(err) = initialize_state(app.app_handle().clone()).await {
|
||||
tracing::error!("{err}");
|
||||
};
|
||||
|
||||
app.run(|_app_handle, _event| {})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import Navbar from './components/Navbar';
|
|||
import ErrorBoundary from './components/ErrorBoundary';
|
||||
import AnimatedRoutes from './components/AnimatedRoutes';
|
||||
import NotificationOverlay from './components/overlay/notifications/NotificationOverlay';
|
||||
import { SettingsProvider } from './hooks/useSettings';
|
||||
import { bridge } from '~index';
|
||||
|
||||
function App(props: ParentProps) {
|
||||
|
|
@ -15,26 +16,28 @@ function App(props: ParentProps) {
|
|||
}
|
||||
|
||||
return (
|
||||
<main class="flex flex-col bg-primary w-full min-h-screen overflow-hidden h-screen max-h-screen text-fg-primary">
|
||||
<WindowFrame />
|
||||
<div class="flex flex-col px-8">
|
||||
<Navbar />
|
||||
</div>
|
||||
|
||||
<div class="relative h-full w-full overflow-hidden">
|
||||
<div class="absolute top-0 left-0 flex flex-col h-full w-full overflow-x-hidden">
|
||||
<ErrorBoundary>
|
||||
<OverlayScrollbarsComponent class="os-hide-horizontal-scrollbar absolute top-0 left-0 flex flex-col h-full w-full overflow-x-hidden overflow-y-auto px-8 pb-8">
|
||||
<AnimatedRoutes>
|
||||
{props.children}
|
||||
</AnimatedRoutes>
|
||||
</OverlayScrollbarsComponent>
|
||||
</ErrorBoundary>
|
||||
<SettingsProvider>
|
||||
<main class="flex flex-col bg-primary w-full min-h-screen overflow-hidden h-screen max-h-screen text-fg-primary">
|
||||
<WindowFrame />
|
||||
<div class="flex flex-col px-8">
|
||||
<Navbar />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NotificationOverlay />
|
||||
</main>
|
||||
<div class="relative h-full w-full overflow-hidden">
|
||||
<div class="absolute top-0 left-0 flex flex-col h-full w-full overflow-x-hidden">
|
||||
<ErrorBoundary>
|
||||
<OverlayScrollbarsComponent class="os-hide-horizontal-scrollbar absolute top-0 left-0 flex flex-col h-full w-full overflow-x-hidden overflow-y-auto px-8 pb-8">
|
||||
<AnimatedRoutes>
|
||||
{props.children}
|
||||
</AnimatedRoutes>
|
||||
</OverlayScrollbarsComponent>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NotificationOverlay />
|
||||
</main>
|
||||
</SettingsProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import type { JSX } from 'solid-js';
|
|||
import { createSignal, onMount } from 'solid-js';
|
||||
import Modal from './overlay/Modal';
|
||||
import Button from './base/Button';
|
||||
import appSettings from '~ui/state/appSettings';
|
||||
|
||||
interface TitlebarButtonProps {
|
||||
icon: (any: any) => JSX.Element;
|
||||
|
|
@ -32,10 +31,10 @@ function WindowFrame() {
|
|||
|
||||
onMount(() => {
|
||||
Window.getCurrent().onCloseRequested((event) => {
|
||||
if (appSettings.settings.closeDialog) {
|
||||
event.preventDefault();
|
||||
setModalVisible(true);
|
||||
}
|
||||
// if (appSettings.settings.closeDialog) {
|
||||
// event.preventDefault();
|
||||
// setModalVisible(true);
|
||||
// }
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
34
desktop/src/ui/hooks/useSettings.tsx
Normal file
34
desktop/src/ui/hooks/useSettings.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { type Context, type ParentProps, type Resource, Show, createContext, useContext } from 'solid-js';
|
||||
import useCommand from './useCommand';
|
||||
import type { Settings } from '~bindings';
|
||||
import { bridge } from '~index';
|
||||
|
||||
const SettingsContext = createContext<Settings>() as Context<Settings>;
|
||||
|
||||
export function getSettings(): Resource<Settings> | undefined {
|
||||
const [resource] = useCommand(bridge.commands.getSettings);
|
||||
return resource;
|
||||
}
|
||||
|
||||
export function SettingsProvider(props: ParentProps) {
|
||||
const settings = getSettings();
|
||||
|
||||
return (
|
||||
<Show when={settings !== undefined && settings() !== undefined}>
|
||||
<SettingsContext.Provider value={settings!()!}>
|
||||
{props.children}
|
||||
</SettingsContext.Provider>
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
|
||||
export function useSettingsContext() {
|
||||
const context = useContext(SettingsContext);
|
||||
|
||||
if (!context)
|
||||
throw new Error('useSettingsContext should be called inside its SettingsProvider');
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
export default useSettingsContext;
|
||||
|
|
@ -3,12 +3,9 @@ import SettingsRow from '../../../components/SettingsRow';
|
|||
import ScrollableContainer from '~ui/components/ScrollableContainer';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import Toggle from '~ui/components/base/Toggle';
|
||||
import appSettings from '~ui/state/appSettings';
|
||||
import Sidebar from '~ui/components/Sidebar';
|
||||
|
||||
function SettingsAppearance() {
|
||||
const { settings, setSettings } = appSettings;
|
||||
|
||||
return (
|
||||
<Sidebar.Page>
|
||||
<h1>Appearance</h1>
|
||||
|
|
@ -30,12 +27,7 @@ function SettingsAppearance() {
|
|||
description="Toggle all animations in the launcher."
|
||||
icon={<Speedometer04Icon />}
|
||||
>
|
||||
<Toggle
|
||||
defaultChecked={settings.reducedMotion}
|
||||
onChecked={(checked) => {
|
||||
setSettings('reducedMotion', checked);
|
||||
}}
|
||||
/>
|
||||
<Toggle />
|
||||
</SettingsRow>
|
||||
</ScrollableContainer>
|
||||
</Sidebar.Page>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
import { XIcon } from '@untitled-theme/icons-solid';
|
||||
import { createEffect } from 'solid-js';
|
||||
import SettingsRow from '../../../components/SettingsRow';
|
||||
import ScrollableContainer from '~ui/components/ScrollableContainer';
|
||||
import Toggle from '~ui/components/base/Toggle';
|
||||
import appSettings from '~ui/state/appSettings';
|
||||
import Sidebar from '~ui/components/Sidebar';
|
||||
import { bridge } from '~index';
|
||||
import useCommand from '~ui/hooks/useCommand';
|
||||
import useSettingsContext from '~ui/hooks/useSettings';
|
||||
|
||||
function SettingsGeneral() {
|
||||
const settings = useSettingsContext();
|
||||
|
||||
createEffect(() => {
|
||||
console.log(settings);
|
||||
});
|
||||
|
||||
return (
|
||||
<Sidebar.Page>
|
||||
<h1>General</h1>
|
||||
|
|
@ -15,12 +24,7 @@ function SettingsGeneral() {
|
|||
description="Show a confirmation dialog when closing the launcher."
|
||||
icon={<XIcon />}
|
||||
>
|
||||
<Toggle
|
||||
defaultChecked={appSettings.settings.closeDialog}
|
||||
onChecked={(checked) => {
|
||||
appSettings.setSettings('closeDialog', checked);
|
||||
}}
|
||||
/>
|
||||
<Toggle />
|
||||
</SettingsRow>
|
||||
</ScrollableContainer>
|
||||
</Sidebar.Page>
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
import { createEffect, createRoot, onMount } from 'solid-js';
|
||||
import { createStore } from 'solid-js/store';
|
||||
|
||||
export interface AppSettingsStore {
|
||||
reducedMotion: boolean;
|
||||
closeDialog: boolean;
|
||||
};
|
||||
|
||||
function globalStore() {
|
||||
// TODO: Much better management of this, currently temporary
|
||||
const [settings, setSettings] = createStore<AppSettingsStore>({
|
||||
reducedMotion: false,
|
||||
closeDialog: true,
|
||||
});
|
||||
|
||||
function set<K extends keyof AppSettingsStore>(key: K, value: AppSettingsStore[K]) {
|
||||
window.localStorage.setItem(key, value.toString());
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
setSettings('reducedMotion', window.localStorage.getItem('reducedMotion') === 'true');
|
||||
setSettings('closeDialog', window.localStorage.getItem('closeDialog') === 'true');
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
// Reduced Motion
|
||||
set('reducedMotion', settings.reducedMotion);
|
||||
document.body.classList.toggle('reduce-motion', settings.reducedMotion);
|
||||
|
||||
// Close Dialog
|
||||
set('closeDialog', settings.closeDialog);
|
||||
});
|
||||
|
||||
return { settings, setSettings };
|
||||
}
|
||||
|
||||
export default createRoot(globalStore);
|
||||
Loading…
Add table
Reference in a new issue