refactor/cleanup (#426)
This commit is contained in:
parent
cbdb43b796
commit
d5a5bd7f05
69 changed files with 551 additions and 360 deletions
122
Cargo.lock
generated
122
Cargo.lock
generated
|
|
@ -971,6 +971,26 @@ dependencies = [
|
|||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format_proc_macros"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
|
|
@ -1275,7 +1295,7 @@ dependencies = [
|
|||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2041,6 +2061,19 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.18.5"
|
||||
|
|
@ -2561,6 +2594,12 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_debug"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fe266d2e243c931d8190177f20bf7f24eed45e96f39e87dc49a27b32d12d407"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
|
|
@ -2742,6 +2781,18 @@ version = "0.2.171"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.18.3+1.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
|
|
@ -2800,6 +2851,18 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
|
|
@ -3176,6 +3239,15 @@ dependencies = [
|
|||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "number_prefix"
|
||||
version = "0.4.0"
|
||||
|
|
@ -3527,6 +3599,7 @@ dependencies = [
|
|||
"serde_with",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"shadow-rs",
|
||||
"specta",
|
||||
"sysinfo",
|
||||
"tauri",
|
||||
|
|
@ -5262,6 +5335,19 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shadow-rs"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72d18183cef626bce22836103349c7050d73db799be0171386b80947d157ae32"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"git2",
|
||||
"is_debug",
|
||||
"time",
|
||||
"tzdb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
|
|
@ -6504,7 +6590,9 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
|||
dependencies = [
|
||||
"deranged",
|
||||
"itoa 1.0.11",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
|
|
@ -6830,6 +6918,32 @@ version = "1.17.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "tz-rs"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14eff19b8dc1ace5bf7e4d920b2628ae3837f422ff42210cb1567cbf68b5accf"
|
||||
|
||||
[[package]]
|
||||
name = "tzdb"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0be2ea5956f295449f47c0b825c5e109022ff1a6a53bb4f77682a87c2341fbf5"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"tz-rs",
|
||||
"tzdb_data",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdb_data"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c4c81d75033770e40fbd3643ce7472a1a9fd301f90b7139038228daf8af03ec"
|
||||
dependencies = [
|
||||
"tz-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uds_windows"
|
||||
version = "1.1.0"
|
||||
|
|
@ -6930,6 +7044,12 @@ version = "0.1.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ sysinfo = { version = "=0.34.2", features = [ "serde" ] }
|
|||
thiserror = { version = "2" }
|
||||
whoami = { version = "=1.6.0" }
|
||||
opener = { version = "=0.8.2" }
|
||||
shadow-rs = { version = "1.4.0", default-features = false }
|
||||
|
||||
# macro
|
||||
paste = { version = "1" }
|
||||
|
|
|
|||
|
|
@ -1,20 +1,3 @@
|
|||
use std::process::Command;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn main() {
|
||||
let output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.unwrap();
|
||||
let git_hash = String::from_utf8(output.stdout).unwrap();
|
||||
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
||||
|
||||
let start = SystemTime::now();
|
||||
let timestamp = start
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time went backwards")
|
||||
.as_secs();
|
||||
println!("cargo:rustc-env=BUILD_TIMESTAMP={}", timestamp);
|
||||
|
||||
tauri_build::build();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,13 @@
|
|||
"fs:allow-data-read-recursive",
|
||||
"fs:allow-data-write-recursive",
|
||||
|
||||
"os:default"
|
||||
"os:allow-arch",
|
||||
"os:deny-exe-extension",
|
||||
"os:allow-family",
|
||||
"os:deny-hostname",
|
||||
"os:allow-locale",
|
||||
"os:allow-os-type",
|
||||
"os:allow-platform",
|
||||
"os:allow-version"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// === API ===
|
||||
pub const CURSEFORGE_API_KEY: &'static str =
|
||||
"$2a$10$6utA1UNSmFPrE/Lh7b7ndeeGmiOkjKNY8kpFB0fsmE/d42ZAfFgCe";
|
||||
pub const DISCORD_CLIENT_ID: &'static str = "1274084193193955408";
|
||||
pub const DISCORD_CLIENT_ID: &'static str = "1426999264633946334";
|
||||
|
||||
// === Meta ===
|
||||
// Cannot contain trailing slash
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ async fn initialize_core() -> LauncherResult<()> {
|
|||
launcher_name: "OneClient".to_string(),
|
||||
launcher_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
launcher_website: "https://polyfrost.org/".to_string(),
|
||||
discord_client_id: None, //Some(constants::DISCORD_CLIENT_ID.to_string()), // disabled for now
|
||||
discord_client_id: Some(constants::DISCORD_CLIENT_ID.to_string()),
|
||||
fetch_attempts: 3,
|
||||
logger_filter: Some(format!(
|
||||
"{}={level},onelauncher_core={level}",
|
||||
|
|
|
|||
|
|
@ -301,22 +301,10 @@ export type VersionType =
|
|||
*/
|
||||
"old_beta"
|
||||
|
||||
const ARGS_MAP = { 'debug':'{"getFamily":[],"getPlatform":[],"getCommitHash":[],"getArch":[],"openDevTools":[],"getVersion":[],"isInDev":[],"getType":[],"getLocale":[],"getBuildTimestamp":[]}', 'oneclient':'{"getVersions":[],"getClustersGroupedByMajor":[],"getBundlesFor":["cluster_id"]}', 'core':'{"getPackageBody":["provider","body"],"createSettingsProfile":["name"],"getProfileOrDefault":["name"],"setDefaultUser":["uuid"],"getUsersFromAuthor":["provider","author"],"removeCluster":["id"],"writeSettings":["setting"],"getUser":["uuid"],"readSettings":[],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"updateClusterProfile":["name","profile"],"convertUsernameUUID":["username_uuid"],"open":["input"],"getRunningProcesses":[],"installModpack":["modpack","cluster_id"],"searchPackages":["provider","query"],"changeSkin":["access_token","skin_url","skin_variant"],"launchCluster":["id","uuid"],"changeCape":["access_token","cape_uuid"],"getGlobalProfile":[],"getClusters":[],"getWorlds":["id"],"getMultiplePackages":["provider","slugs"],"removeUser":["uuid"],"removeCape":["access_token"],"getUsers":[],"getPackage":["provider","slug"],"downloadExternalPackage":["package","cluster_id","force","skip_compatibility"],"getRunningProcessesByClusterId":["cluster_id"],"fetchMinecraftProfile":["uuid"],"getClusterById":["id"],"getGameVersions":[],"getDefaultUser":["fallback"],"getLogs":["id"],"getLogByName":["id","name"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getLoadersForVersion":["mc_version"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"fetchLoggedInProfile":["access_token"],"openMsaLogin":[],"getScreenshots":["id"],"isClusterRunning":["cluster_id"],"killProcess":["pid"],"createCluster":["options"],"updateClusterById":["id","request"]}', 'events':'{"process":["event"],"message":["event"],"ingress":["event"]}', 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}' }
|
||||
const ARGS_MAP = { 'debug':'{"getType":[],"getGitCommitHash":[],"getBuildTimestamp":[],"getPlatform":[],"getOsVersion":[],"getArch":[],"getPackageVersion":[],"openDevTools":[],"getFamily":[],"isInDev":[],"getLocale":[]}', 'oneclient':'{"getClustersGroupedByMajor":[],"getVersions":[],"getBundlesFor":["cluster_id"]}', 'events':'{"message":["event"],"process":["event"],"ingress":["event"]}', 'core':'{"getScreenshots":["id"],"getPackageBody":["provider","body"],"convertUsernameUUID":["username_uuid"],"writeSettings":["setting"],"createCluster":["options"],"createSettingsProfile":["name"],"getMultiplePackages":["provider","slugs"],"updateClusterProfile":["name","profile"],"downloadExternalPackage":["package","cluster_id","force","skip_compatibility"],"openMsaLogin":[],"getClusters":[],"installModpack":["modpack","cluster_id"],"fetchMinecraftProfile":["uuid"],"killProcess":["pid"],"getUsers":[],"searchPackages":["provider","query"],"readSettings":[],"getLoadersForVersion":["mc_version"],"getRunningProcessesByClusterId":["cluster_id"],"getProfileOrDefault":["name"],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"getUser":["uuid"],"getRunningProcesses":[],"fetchLoggedInProfile":["access_token"],"getLogs":["id"],"isClusterRunning":["cluster_id"],"getWorlds":["id"],"removeCape":["access_token"],"updateClusterById":["id","request"],"getGameVersions":[],"launchCluster":["id","uuid"],"removeCluster":["id"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"getLinkedPackages":["cluster_id"],"getClusterById":["id"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"removeUser":["uuid"],"changeSkin":["access_token","skin_url","skin_variant"],"getUsersFromAuthor":["provider","author"],"getGlobalProfile":[],"changeCape":["access_token","cape_uuid"],"getLogByName":["id","name"],"getDefaultUser":["fallback"],"setDiscordRPCMessage":["message"],"getPackage":["provider","slug"],"open":["input"],"setDefaultUser":["uuid"]}', 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}' }
|
||||
export type Router = { 'events': { ingress: (event: IngressPayload) => Promise<void>,
|
||||
message: (event: MessagePayload) => Promise<void>,
|
||||
process: (event: ProcessPayload) => Promise<void> },
|
||||
'folders': { fromCluster: (folderName: string) => Promise<string>,
|
||||
openCluster: (folderName: string) => Promise<null> },
|
||||
'debug': { openDevTools: () => Promise<void>,
|
||||
isInDev: () => Promise<boolean>,
|
||||
getPlatform: () => Promise<string>,
|
||||
getArch: () => Promise<string>,
|
||||
getFamily: () => Promise<string>,
|
||||
getLocale: () => Promise<string | null>,
|
||||
getType: () => Promise<string>,
|
||||
getVersion: () => Promise<string>,
|
||||
getCommitHash: () => Promise<string>,
|
||||
getBuildTimestamp: () => Promise<string> },
|
||||
'oneclient': { getClustersGroupedByMajor: () => Promise<Partial<{ [key in number]: ClusterModel[] }>>,
|
||||
getBundlesFor: (clusterId: number) => Promise<ModpackArchive[]>,
|
||||
getVersions: () => Promise<OnlineClusterManifest> },
|
||||
|
|
@ -356,6 +344,7 @@ getPackageVersions: (provider: Provider, slug: string, mcVersion: string | null,
|
|||
downloadPackage: (provider: Provider, packageId: string, versionId: string, clusterId: number, skipCompatibility: boolean | null) => Promise<PackageModel>,
|
||||
downloadExternalPackage: (package: ExternalPackage, clusterId: number, force: boolean | null, skipCompatibility: boolean | null) => Promise<PackageModel | null>,
|
||||
getUsersFromAuthor: (provider: Provider, author: PackageAuthor) => Promise<ManagedUser[]>,
|
||||
getLinkedPackages: (clusterId: number) => Promise<PackageModel[]>,
|
||||
installModpack: (modpack: ModpackArchive, clusterId: number) => Promise<null>,
|
||||
fetchMinecraftProfile: (uuid: string) => Promise<MojangPlayerProfile>,
|
||||
fetchLoggedInProfile: (accessToken: string) => Promise<MojangFullPlayerProfile>,
|
||||
|
|
@ -364,7 +353,21 @@ changeSkin: (accessToken: string, skinUrl: string, skinVariant: SkinVariant) =>
|
|||
changeCape: (accessToken: string, capeUuid: string) => Promise<MojangFullPlayerProfile>,
|
||||
removeCape: (accessToken: string) => Promise<MojangFullPlayerProfile>,
|
||||
convertUsernameUUID: (usernameUuid: string) => Promise<MowojangProfile>,
|
||||
open: (input: string) => Promise<null> } };
|
||||
setDiscordRPCMessage: (message: string) => Promise<null>,
|
||||
open: (input: string) => Promise<null> },
|
||||
'debug': { openDevTools: () => Promise<void>,
|
||||
isInDev: () => Promise<boolean>,
|
||||
getArch: () => Promise<string>,
|
||||
getFamily: () => Promise<string>,
|
||||
getLocale: () => Promise<string | null>,
|
||||
getType: () => Promise<string>,
|
||||
getPlatform: () => Promise<string>,
|
||||
getOsVersion: () => Promise<string>,
|
||||
getGitCommitHash: () => Promise<string>,
|
||||
getBuildTimestamp: () => Promise<string>,
|
||||
getPackageVersion: () => Promise<string> },
|
||||
'folders': { fromCluster: (folderName: string) => Promise<string>,
|
||||
openCluster: (folderName: string) => Promise<null> } };
|
||||
|
||||
|
||||
export type { InferCommandOutput }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { ClusterModel, ModpackFile } from '@/bindings.gen';
|
||||
import { ModCard, useModCardContext } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { ModCard, useModCardContext } from '.';
|
||||
|
||||
interface BundleProps {
|
||||
files: Array<ModpackFile>;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import type { ClusterModel, ModpackFile, ModpackFileKind } from '@/bindings.gen';
|
||||
import MissingLogo from '@/assets/misc/missingLogo.svg';
|
||||
import { DownloadModButton, ModTag } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { DownloadModButton, ModTag } from '.';
|
||||
|
||||
export interface ModInfo {
|
||||
name: string;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { ClusterModel, ModpackArchive } from '@/bindings.gen';
|
||||
import { Bundle, useModCardContext } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { Button, Tab, TabContent, TabList, TabPanel, Tabs } from '@onelauncher/common/components';
|
||||
import { Bundle, useModCardContext } from '.';
|
||||
|
||||
function getBundleName(name: string): string {
|
||||
return (name.match(/\[(.*?)\]/)?.[1]) ?? 'Loading...';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ClusterModel } from '@/bindings.gen';
|
||||
import type { ModInfo } from '.';
|
||||
import type { ModInfo } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import type { MinecraftCredentials } from '@/bindings.gen';
|
||||
import { Overlay, RemoveAccountModal } from '@/components';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { Trash01Icon } from '@untitled-theme/icons-react';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
import { Overlay, RemoveAccountModal } from './overlay';
|
||||
|
||||
export function DeleteAccountButton({ profile, onPress }: { profile: MinecraftCredentials; onPress: () => void }) {
|
||||
return (
|
||||
<DialogTrigger>
|
||||
<Overlay.Trigger>
|
||||
<Button className="group w-8 h-8" color="ghost" size="icon">
|
||||
<Trash01Icon className="group-hover:stroke-danger" />
|
||||
</Button>
|
||||
|
|
@ -14,6 +13,6 @@ export function DeleteAccountButton({ profile, onPress }: { profile: MinecraftCr
|
|||
<Overlay>
|
||||
<RemoveAccountModal onPress={onPress} profile={profile} />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
</Overlay.Trigger>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { ExternalPackage, ManagedVersionDependency, ModpackFile, Provider } from '@/bindings.gen';
|
||||
import { getModMetaDataName, Overlay } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandMut } from '@onelauncher/common';
|
||||
|
|
@ -6,8 +7,6 @@ import { Button } from '@onelauncher/common/components';
|
|||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { useEffect, useImperativeHandle, useState } from 'react';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
import { getModMetaDataName } from './Bundle';
|
||||
import { Overlay } from './overlay';
|
||||
|
||||
export interface DownloadModsRef {
|
||||
openDownloadDialog: (nextPath?: string) => void;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type React from 'react';
|
||||
import type { HTMLProps } from 'react';
|
||||
import { Overlay } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
import { LinkExternal01Icon } from '@untitled-theme/icons-react';
|
||||
import { useState } from 'react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { Overlay } from './overlay';
|
||||
|
||||
export interface ExternalLinkProps extends HTMLProps<HTMLAnchorElement> {
|
||||
href?: string | undefined;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import type { ClusterModel } from '@/bindings.gen';
|
||||
import type { ButtonProps } from '@onelauncher/common/components';
|
||||
import { KillMinecraft, NoAccountPopup, Overlay } from '@/components';
|
||||
import { useIsRunning } from '@/hooks/useClusters';
|
||||
import { useLaunchCluster } from '@/hooks/useLaunchCluster';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { useState } from 'react';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
import { tv } from 'tailwind-variants';
|
||||
import { NoAccountPopup, Overlay } from './overlay';
|
||||
|
||||
export type LaunchButtonProps = Omit<ButtonProps, 'children' | 'onClick'> & {
|
||||
clusterId: number | undefined | null;
|
||||
cluster: ClusterModel;
|
||||
};
|
||||
|
||||
const launchButtonVariants = tv({
|
||||
|
|
@ -21,32 +22,73 @@ const launchButtonVariants = tv({
|
|||
},
|
||||
});
|
||||
|
||||
function PromptForOnboarding({ launch, setSkipPackagesCheck, cluster }: { launch: () => void; setSkipPackagesCheck: React.Dispatch<React.SetStateAction<boolean>>; cluster: ClusterModel }) {
|
||||
const navigate = useNavigate();
|
||||
const onClickYes = () => {
|
||||
localStorage.setItem('selectedClusters', JSON.stringify([{ mc_version: cluster.mc_version, mc_loader: cluster.mc_loader }]));
|
||||
navigate({ to: `/onboarding/preferences/versionCategory` });
|
||||
};
|
||||
|
||||
const onClickLaunch = () => {
|
||||
setSkipPackagesCheck(true);
|
||||
launch();
|
||||
};
|
||||
|
||||
return (
|
||||
<Overlay.Dialog>
|
||||
<Overlay.Title>Not Setup</Overlay.Title>
|
||||
<div className="flex flex-col items-center">
|
||||
<p className="max-w-sm text-fg-secondary">It seems like you haven't setup this version</p>
|
||||
<p className="max-w-sm text-fg-secondary">Do you want to setup this version?</p>
|
||||
</div>
|
||||
<Overlay.Buttons
|
||||
buttons={[
|
||||
{ color: 'primary', key: 'Yes', children: 'Yes', size: 'normal', onClick: onClickYes },
|
||||
{
|
||||
color: 'secondary',
|
||||
key: 'anyways',
|
||||
children: 'Launch Anyways',
|
||||
size: 'normal',
|
||||
onClick: onClickLaunch,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Overlay.Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function LaunchButton({
|
||||
clusterId,
|
||||
cluster,
|
||||
isDisabled,
|
||||
className,
|
||||
...rest
|
||||
}: LaunchButtonProps) {
|
||||
const { data: currentAccount } = useCommandSuspense(['getDefaultUser'], () => bindings.core.getDefaultUser(true));
|
||||
const launchCluster = useLaunchCluster(clusterId);
|
||||
const isRunning = useIsRunning(clusterId);
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const { data: installedPackages } = useCommandSuspense(['getLinkedPackages', cluster.id], () => bindings.core.getLinkedPackages(cluster.id));
|
||||
const launchCluster = useLaunchCluster(cluster.id);
|
||||
const isRunning = useIsRunning(cluster.id);
|
||||
|
||||
const [reason, setReason] = useState<'account' | 'packages' | 'kill' | null>(null);
|
||||
const [skipPackagesCheck, setSkipPackagesCheck] = useState(false);
|
||||
|
||||
const launch = () => {
|
||||
if (currentAccount === null) {
|
||||
setOpen(true);
|
||||
}
|
||||
else {
|
||||
launchCluster();
|
||||
setOpen(false);
|
||||
}
|
||||
if (isRunning)
|
||||
return setReason('kill');
|
||||
if (!currentAccount)
|
||||
return setReason('account');
|
||||
if (installedPackages.length === 0 && !skipPackagesCheck)
|
||||
return setReason('packages');
|
||||
|
||||
launchCluster();
|
||||
setSkipPackagesCheck(false);
|
||||
setReason(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<DialogTrigger isOpen={open} onOpenChange={setOpen}>
|
||||
<Overlay.Trigger isOpen={reason !== null} onOpenChange={open => !open && setReason(null)}>
|
||||
<Button
|
||||
className={launchButtonVariants({ isRunning, className })}
|
||||
isDisabled={isDisabled || isRunning}
|
||||
isDisabled={isDisabled}
|
||||
onPress={launch}
|
||||
{...rest}
|
||||
>
|
||||
|
|
@ -54,8 +96,10 @@ export function LaunchButton({
|
|||
</Button>
|
||||
|
||||
<Overlay>
|
||||
<NoAccountPopup />
|
||||
{reason === 'kill' && <KillMinecraft setOpen={() => setReason(null)} />}
|
||||
{reason === 'packages' && <PromptForOnboarding cluster={cluster} launch={launch} setSkipPackagesCheck={setSkipPackagesCheck} />}
|
||||
{reason === 'account' && <NoAccountPopup />}
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
</Overlay.Trigger>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import type { SpinnerProps } from '@/components';
|
||||
import type { HTMLAttributes, ReactNode } from 'react';
|
||||
import type { SpinnerProps } from './Spinner';
|
||||
import { Spinner } from '@/components';
|
||||
import { motion } from 'motion/react';
|
||||
import { Suspense } from 'react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { Spinner } from './Spinner';
|
||||
|
||||
interface LoaderProps extends HTMLAttributes<HTMLDivElement> {
|
||||
children?: ReactNode;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ExternalLink } from '@/components';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { ExternalLink } from './ExternalLink';
|
||||
import styles from './Markdown.module.css';
|
||||
|
||||
export function Markdown({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { ButtonProps } from '@onelauncher/common/components';
|
||||
import type { LinkProps, RegisteredRouter } from '@tanstack/react-router';
|
||||
import LauncherLogo from '@/assets/logos/oneclient.svg?react';
|
||||
import { AccountAvatar, AccountPopup, Overlay, SuperSecretDevOptions } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommand } from '@onelauncher/common';
|
||||
import { Button, Popup } from '@onelauncher/common/components';
|
||||
|
|
@ -8,9 +9,6 @@ import { Link, useNavigate } from '@tanstack/react-router';
|
|||
import { Window } from '@tauri-apps/api/window';
|
||||
import { MinusIcon, Settings02Icon, SquareIcon, XCloseIcon } from '@untitled-theme/icons-react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { AccountAvatar } from './AccountAvatar';
|
||||
import { Overlay, SuperSecretDevOptions } from './overlay';
|
||||
import { AccountPopup } from './overlay/AccountPopup';
|
||||
|
||||
export function Navbar() {
|
||||
const { data: currentAccount } = useCommand(['getDefaultUser'], () => bindings.core.getDefaultUser(true));
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ type BooleanSetting = [
|
|||
(value: boolean) => void,
|
||||
];
|
||||
|
||||
export default function SettingsSwitch({ setting }: { setting: BooleanSetting }) {
|
||||
export function SettingsSwitch({ setting }: { setting: BooleanSetting }) {
|
||||
return (
|
||||
<Switch
|
||||
isSelected={setting[0]}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export interface SettingsRowProps {
|
|||
children?: JSX.Element;
|
||||
}
|
||||
|
||||
function SettingsRow({ disabled, description, icon, title, children }: SettingsRowProps) {
|
||||
export function SettingsRow({ disabled, description, icon, title, children }: SettingsRowProps) {
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ SheetPage.Content = ({
|
|||
</motion.div>
|
||||
);
|
||||
|
||||
function GoBackButton() {
|
||||
export function GoBackButton() {
|
||||
const router = useRouter();
|
||||
const canGoBack = useCanGoBack();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export function Stepper({ steps, currentStepIndex }: VerticalStepperProps) {
|
|||
<div className="max-w-md mx-auto">
|
||||
{steps.map((step, index) => (
|
||||
<div
|
||||
className={twMerge('transition-all duration-300 relative flex items-center cursor-pointer py-2 pl-4 border-l-3 border-gray-600 font-medium text-gray-400 text-base data-active:border-brand data-active:text-white data-active:text-lg data-complete:border-brand', index === 0 ? 'pt-0' : '', index === steps.length - 1 ? 'pb-0' : '')}
|
||||
className={twMerge('after:transition-all after:duration-300 after:text-brand transition-all duration-300 relative flex items-center cursor-pointer py-2 pl-4 font-medium text-gray-400 text-base partial-leftline-0% data-active:text-white data-active:text-lg data-active:partial-leftline-100% data-complete:partial-leftline-100%')}
|
||||
data-active={index === currentStepIndex || null}
|
||||
data-complete={index < currentStepIndex || null}
|
||||
key={index}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
export * from './AccountAvatar';
|
||||
export * from './BrowserPackageItem';
|
||||
export * from './Bundle';
|
||||
export * from './DeleteAccountButton';
|
||||
export * from './DownloadMods';
|
||||
export * from './ExternalLink';
|
||||
export * from './GameBackground';
|
||||
export * from './LaunchButton';
|
||||
export * from './Loader';
|
||||
export * from './LogViewer';
|
||||
export * from './ManageSkinButton';
|
||||
export * from './Markdown';
|
||||
export * from './Navbar';
|
||||
export * from './overlay';
|
||||
export * from './SettingsRow';
|
||||
export * from './SettingSwitch';
|
||||
export * from './SheetPage';
|
||||
export * from './SkinViewer';
|
||||
export * from './Spinner';
|
||||
export * from './Stepper';
|
||||
export * from './Tabs';
|
||||
|
|
|
|||
|
|
@ -1,17 +1,11 @@
|
|||
import type { MinecraftCredentials } from '@/bindings.gen';
|
||||
import { AccountAvatar, AddAccountModal, DeleteAccountButton, ManageSkinButton, Overlay, Popup } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommand } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { PlusIcon, Settings01Icon } from '@untitled-theme/icons-react';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { AccountAvatar } from '../AccountAvatar';
|
||||
import { DeleteAccountButton } from '../DeleteAccountButton';
|
||||
import { ManageSkinButton } from '../ManageSkinButton';
|
||||
import { AddAccountModal } from './AddAccountModal';
|
||||
import { Overlay } from './Overlay';
|
||||
import { Popup } from './Popup';
|
||||
|
||||
export function AccountPopup() {
|
||||
const users = useCommand(['getUsers'], bindings.core.getUsers);
|
||||
|
|
@ -40,47 +34,40 @@ export function AccountPopup() {
|
|||
|
||||
<div className="min-w-3xs">
|
||||
{defaultUser.data && (
|
||||
<div>
|
||||
<AccountEntry
|
||||
loggedIn
|
||||
onClick={() => { }}
|
||||
onDelete={() => deleteUser(defaultUser.data as MinecraftCredentials)}
|
||||
user={defaultUser.data}
|
||||
/>
|
||||
</div>
|
||||
<AccountEntry
|
||||
loggedIn
|
||||
onClick={() => { }}
|
||||
onDelete={() => deleteUser(defaultUser.data as MinecraftCredentials)}
|
||||
user={defaultUser.data}
|
||||
/>
|
||||
)}
|
||||
|
||||
{users.data?.filter(user => user.id !== defaultUser.data?.id).map(user => (
|
||||
<div key={user.id}>
|
||||
<AccountEntry
|
||||
onClick={() => setDefaultUser(user)}
|
||||
onDelete={() => deleteUser(user)}
|
||||
user={user}
|
||||
/>
|
||||
</div>
|
||||
<AccountEntry
|
||||
key={user.id}
|
||||
onClick={() => setDefaultUser(user)}
|
||||
onDelete={() => deleteUser(user)}
|
||||
user={user}
|
||||
/>
|
||||
))}
|
||||
|
||||
<div className="flex flex-row justify-between">
|
||||
<div className="self-center">
|
||||
<Overlay.Trigger>
|
||||
<Button color="ghost">
|
||||
<PlusIcon />
|
||||
<p>Add Account</p>
|
||||
</Button>
|
||||
|
||||
<DialogTrigger>
|
||||
<Button color="ghost">
|
||||
<PlusIcon />
|
||||
Add Account
|
||||
</Button>
|
||||
<Overlay>
|
||||
<AddAccountModal />
|
||||
</Overlay>
|
||||
</Overlay.Trigger>
|
||||
|
||||
<Overlay>
|
||||
<AddAccountModal />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
</div>
|
||||
<div className="flex flex-row">
|
||||
<Link to="/app/accounts">
|
||||
<Button color="ghost" size="iconLarge">
|
||||
<Settings01Icon className="stroke-fg-primary" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<Link to="/app/accounts">
|
||||
<Button color="ghost" size="iconLarge">
|
||||
<Settings01Icon className="stroke-fg-primary" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</Popup>
|
||||
|
|
@ -89,23 +76,9 @@ export function AccountPopup() {
|
|||
|
||||
export default AccountPopup;
|
||||
|
||||
function AccountEntry({
|
||||
onClick,
|
||||
onDelete,
|
||||
user,
|
||||
loggedIn = false,
|
||||
}: {
|
||||
onClick: () => void;
|
||||
onDelete: () => void;
|
||||
user: MinecraftCredentials;
|
||||
loggedIn?: boolean;
|
||||
}) {
|
||||
function AccountEntry({ onClick, onDelete, user, loggedIn = false }: { onClick: () => void; onDelete: () => void; user: MinecraftCredentials; loggedIn?: boolean }) {
|
||||
return (
|
||||
<Button
|
||||
className={twMerge('w-full flex flex-row justify-between p-2 rounded-lg', !loggedIn && 'hover:bg-component-bg-hover active:bg-component-bg-pressed hover:text-fg-primary-hover')}
|
||||
color="ghost"
|
||||
onClick={onClick}
|
||||
>
|
||||
<Button className={twMerge('w-full flex flex-row justify-between p-2 rounded-lg', !loggedIn && 'hover:bg-component-bg-hover active:bg-component-bg-pressed hover:text-fg-primary-hover')} color="ghost" onClick={onClick}>
|
||||
<div className="flex flex-1 flex-row justify-start gap-x-3">
|
||||
<div className="flex flex-1 flex-row justify-start gap-x-3">
|
||||
<AccountAvatar className="h-8 w-8 rounded-md" uuid={user.id} />
|
||||
|
|
|
|||
|
|
@ -1,12 +1,20 @@
|
|||
import type { MinecraftCredentials } from '@/bindings.gen';
|
||||
import { AccountAvatar } from '@/components/AccountAvatar';
|
||||
import { AccountAvatar, Overlay } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandMut } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export function AddAccountModal() {
|
||||
return (
|
||||
<Overlay.Dialog>
|
||||
<Overlay.Title>Add Account</Overlay.Title>
|
||||
<p className="text-fg-secondary">Add a new account to OneClient</p>
|
||||
<AddAccountModalButton />
|
||||
</Overlay.Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function AddAccountModalButton() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { data: profile, isPending, mutate: login } = useCommandMut(bindings.core.openMsaLogin, {
|
||||
|
|
@ -25,47 +33,18 @@ export function AddAccountModal() {
|
|||
};
|
||||
|
||||
return (
|
||||
<Overlay.Dialog>
|
||||
<Overlay.Title>Add Account</Overlay.Title>
|
||||
|
||||
<p className="max-w-sm text-fg-secondary">
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Fugiat aut unde, rem esse natus iusto impedit doloribus laborum laboriosam amet? Totam, commodi sed ducimus dicta praesentium sunt? A, soluta iusto.
|
||||
</p>
|
||||
|
||||
{profile
|
||||
? (
|
||||
<>
|
||||
<AccountRow profile={profile} />
|
||||
<Button
|
||||
className="w-full"
|
||||
color="primary"
|
||||
size="large"
|
||||
slot="close"
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
: (
|
||||
<Button
|
||||
className="w-full"
|
||||
color="primary"
|
||||
isPending={isPending}
|
||||
onClick={onClick}
|
||||
size="large"
|
||||
>
|
||||
Add Account
|
||||
</Button>
|
||||
)}
|
||||
</Overlay.Dialog>
|
||||
profile
|
||||
? (
|
||||
<>
|
||||
<AccountRow profile={profile} />
|
||||
<Overlay.Buttons buttons={[{ color: 'primary', children: 'Close', slot: 'close' }]} />
|
||||
</>
|
||||
)
|
||||
: <Overlay.Buttons buttons={[{ color: 'primary', children: 'Add Account', isPending, onClick }]} />
|
||||
);
|
||||
}
|
||||
|
||||
function AccountRow({
|
||||
profile,
|
||||
}: {
|
||||
profile: MinecraftCredentials;
|
||||
}) {
|
||||
function AccountRow({ profile }: { profile: MinecraftCredentials }) {
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-start gap-2">
|
||||
<AccountAvatar className="aspect-square h-12 rounded-sm " uuid={profile.id} />
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import { ModList, Overlay, useModCardContext } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { useState } from 'react';
|
||||
import { ModList, useModCardContext } from '../Bundle';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export function BundleModListModal({ clusterId, name }: { clusterId: number; name: string }) {
|
||||
const { data: cluster } = useCommandSuspense(['getClusterById'], () => bindings.core.getClusterById(clusterId));
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { Overlay } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export type DebugInfoArray = Array<{ title: string; value: string }>;
|
||||
export interface DebugInfoData {
|
||||
|
|
@ -12,9 +12,10 @@ export interface DebugInfoData {
|
|||
family: string;
|
||||
locale: string;
|
||||
type: string;
|
||||
version: string;
|
||||
osVersion: string;
|
||||
commitHash: string;
|
||||
buildTimestamp: string;
|
||||
buildVersion: string;
|
||||
}
|
||||
|
||||
export function useDebugInfo(): DebugInfoArray {
|
||||
|
|
@ -25,9 +26,10 @@ export function useDebugInfo(): DebugInfoArray {
|
|||
family: 'UNKNOWN',
|
||||
locale: 'UNKNOWN',
|
||||
type: 'UNKNOWN',
|
||||
version: 'UNKNOWN',
|
||||
osVersion: 'UNKNOWN',
|
||||
commitHash: 'UNKNOWN',
|
||||
buildTimestamp: 'UNKNOWN',
|
||||
buildVersion: 'UNKNOWN',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -39,9 +41,10 @@ export function useDebugInfo(): DebugInfoArray {
|
|||
family,
|
||||
locale,
|
||||
type,
|
||||
version,
|
||||
osVersion,
|
||||
commitHash,
|
||||
buildTimestamp,
|
||||
buildVersion,
|
||||
] = await Promise.all([
|
||||
bindings.debug.isInDev(),
|
||||
bindings.debug.getPlatform(),
|
||||
|
|
@ -49,9 +52,10 @@ export function useDebugInfo(): DebugInfoArray {
|
|||
bindings.debug.getFamily(),
|
||||
bindings.debug.getLocale(),
|
||||
bindings.debug.getType(),
|
||||
bindings.debug.getVersion(),
|
||||
bindings.debug.getCommitHash(),
|
||||
bindings.debug.getOsVersion(),
|
||||
bindings.debug.getGitCommitHash(),
|
||||
bindings.debug.getBuildTimestamp(),
|
||||
bindings.debug.getPackageVersion(),
|
||||
]);
|
||||
|
||||
setDevInfo({
|
||||
|
|
@ -61,9 +65,10 @@ export function useDebugInfo(): DebugInfoArray {
|
|||
family,
|
||||
locale: locale ?? 'UNKNOWN',
|
||||
type,
|
||||
version,
|
||||
osVersion,
|
||||
commitHash,
|
||||
buildTimestamp,
|
||||
buildTimestamp: new Date(buildTimestamp).getTime().toString(),
|
||||
buildVersion,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -77,9 +82,10 @@ export function useDebugInfo(): DebugInfoArray {
|
|||
{ title: 'Family', value: devInfo.family },
|
||||
{ title: 'Locale', value: devInfo.locale },
|
||||
{ title: 'Type', value: devInfo.type },
|
||||
{ title: 'Version', value: devInfo.version },
|
||||
{ title: 'Os Version', value: devInfo.osVersion },
|
||||
{ title: 'Commit Hash', value: devInfo.commitHash },
|
||||
{ title: 'Build Timestamp', value: devInfo.buildTimestamp },
|
||||
{ title: 'Version', value: devInfo.buildVersion },
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +93,7 @@ export function copyDebugInfo(debugInfo: DebugInfoArray) {
|
|||
const timestamp = Math.floor(new Date().getTime() / 1000);
|
||||
const lines = [`**Data exported at:** <t:${timestamp}> (\`${timestamp}\`)`, ...debugInfo.map((lineData) => {
|
||||
if (lineData.title === 'Build Timestamp')
|
||||
return `**${lineData.title}:** <t:${lineData.value}> (\`${lineData.value}\`)`;
|
||||
return `**${lineData.title}:** <t:${Math.floor(Number(lineData.value) / 1000)}> (\`${Math.floor(Number(lineData.value) / 1000)}\`)`;
|
||||
return `**${lineData.title}:** \`${lineData.value}\``;
|
||||
})];
|
||||
writeText(lines.join('\n'));
|
||||
|
|
@ -111,7 +117,7 @@ export function RawDebugInfo({ debugInfo }: { debugInfo: DebugInfoArray }) {
|
|||
{debugInfo.map((lineData) => {
|
||||
let line = '';
|
||||
if (lineData.title === 'Build Timestamp')
|
||||
line = `${lineData.title}: ${new Date(Number(lineData.value) * 1000)}`;
|
||||
line = `${lineData.title}: ${new Date(Number(lineData.value))}`;
|
||||
else line = `${lineData.title}: ${lineData.value}`;
|
||||
|
||||
return <p key={lineData.title}>{line}</p>;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Overlay } from '@/components';
|
||||
import { Button, TextField } from '@onelauncher/common/components';
|
||||
import { useState } from 'react';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export function ImportSkinModal({ importFromURL, importFromUsername }: { importFromURL: (url: string) => void; importFromUsername: (username: string) => void }) {
|
||||
const [input, setInput] = useState<string>('');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
import { Overlay } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
|
||||
export function KillMinecraft({ setOpen }: { setOpen: React.Dispatch<React.SetStateAction<boolean>> }) {
|
||||
const { data: foundAllProcess } = useCommandSuspense(['getRunningProcesses'], () => bindings.core.getRunningProcesses());
|
||||
const kill = () => {
|
||||
foundAllProcess.forEach(process => bindings.core.killProcess(process.pid));
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Overlay.Dialog>
|
||||
<Overlay.Title>Minecraft is running</Overlay.Title>
|
||||
<p className="max-w-sm text-fg-secondary">Do you want to kill minecraft?</p>
|
||||
<Overlay.Buttons buttons={[{ color: 'danger', key: 'Yes', children: 'Yes', size: 'normal', onClick: kill }, { color: 'secondary', key: 'No', children: 'No', size: 'normal', slot: 'close' }]} />
|
||||
</Overlay.Dialog>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,23 +1,11 @@
|
|||
import { Button } from '@onelauncher/common/components';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
import { AddAccountModal } from './AddAccountModal';
|
||||
import { Overlay } from './Overlay';
|
||||
import { AddAccountModalButton, Overlay } from '@/components';
|
||||
|
||||
export function NoAccountPopup() {
|
||||
return (
|
||||
<Overlay.Dialog>
|
||||
<Overlay.Title>No Account</Overlay.Title>
|
||||
<p className="max-w-sm text-fg-secondary">Please add an account before you start minecraft</p>
|
||||
|
||||
<DialogTrigger>
|
||||
<Button className="w-full" size="large">
|
||||
Add Account
|
||||
</Button>
|
||||
|
||||
<Overlay>
|
||||
<AddAccountModal />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
<AddAccountModalButton />
|
||||
</Overlay.Dialog>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
import type { OverlayProps } from './Overlay';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export interface PolyBundleModalProps extends OverlayProps {
|
||||
|
||||
}
|
||||
|
||||
export function PolyBundleModal() {
|
||||
return (
|
||||
<Overlay.Dialog>
|
||||
<Overlay.Title>test</Overlay.Title>
|
||||
</Overlay.Dialog>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import type { MinecraftCredentials } from '@/bindings.gen';
|
||||
import { AccountAvatar } from '@/components/AccountAvatar';
|
||||
import { AccountAvatar, Overlay } from '@/components';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export function RemoveAccountModal({
|
||||
profile,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Overlay } from '@/components';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export function RemoveSkinCapeModal({ onPress }: { onPress: () => void }) {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Overlay, RawDebugInfo, SettingsRow, SettingsSwitch, useDebugInfo } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
|
|
@ -5,10 +6,6 @@ import { Link } from '@tanstack/react-router';
|
|||
import { dataDir, join } from '@tauri-apps/api/path';
|
||||
import { BatteryEmptyIcon, Code02Icon, FolderIcon, LinkExternal01Icon, Truck01Icon } from '@untitled-theme/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import SettingsRow from '../SettingsRow';
|
||||
import SettingsSwitch from '../SettingSwitch';
|
||||
import { RawDebugInfo, useDebugInfo } from './DebugInfo';
|
||||
import { Overlay } from './Overlay';
|
||||
|
||||
export function SuperSecretDevOptions() {
|
||||
const { createSetting } = useSettings();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import type { IngressType } from '@/bindings.gen';
|
|||
import type { ToastData, ToastId } from '@/utils/toast';
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import type { ToastContentProps, ToastOptions } from 'react-toastify';
|
||||
import { Spinner } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { toast, toastUpdate } from '@/utils/toast';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
|
|
@ -9,7 +10,6 @@ import { AlertCircleIcon, AlertTriangleIcon, CheckCircleIcon, InfoCircleIcon, XC
|
|||
import { useEffect, useRef } from 'react';
|
||||
import { cssTransition, ToastContainer } from 'react-toastify';
|
||||
import { tv } from 'tailwind-variants';
|
||||
import { Spinner } from '../Spinner';
|
||||
import styles from './Toasts.module.css';
|
||||
|
||||
const toastVariants = tv({
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ export * from './AddAccountModal';
|
|||
export * from './BundleModListModal';
|
||||
export * from './DebugInfo';
|
||||
export * from './ImportSkinModal';
|
||||
export * from './KillMinecraft';
|
||||
export * from './NoAccountPopup';
|
||||
export * from './Overlay';
|
||||
export * from './Popup';
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export function useActiveCluster() {
|
|||
|
||||
const { data: clusters } = useLastPlayedClusters();
|
||||
|
||||
return clusters.find(c => c.id === clusterId) ?? clusters.at(0);
|
||||
return clusters.find(c => c.id === clusterId) ?? clusters[0];
|
||||
}
|
||||
|
||||
export function useIsRunning(clusterId: number | undefined | null) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import type { QueryClient } from '@tanstack/react-query';
|
||||
import type { NavigateOptions, ToOptions } from '@tanstack/react-router';
|
||||
import { Toasts } from '@/components/overlay';
|
||||
import { Toasts } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommand } from '@onelauncher/common';
|
||||
import { TanStackDevtools } from '@tanstack/react-devtools';
|
||||
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
|
||||
import { createRootRouteWithContext, Outlet, useRouter } from '@tanstack/react-router';
|
||||
import { createRootRouteWithContext, Outlet, useLocation, useRouter } from '@tanstack/react-router';
|
||||
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
|
||||
import { useEffect } from 'react';
|
||||
import { RouterProvider } from 'react-aria-components';
|
||||
|
||||
interface AppRouterContext {
|
||||
|
|
@ -23,9 +26,58 @@ export const Route = createRootRouteWithContext<AppRouterContext>()({
|
|||
component: RootRoute,
|
||||
});
|
||||
|
||||
type URLPath = Exclude<ToOptions['to'], undefined>;
|
||||
const ResolvedPathNames: Record<URLPath, string> = {
|
||||
'.': 'UNKNOWN',
|
||||
'..': 'UNKNOWN',
|
||||
'/': 'Viewing Home',
|
||||
'/app': 'Viewing Homepage',
|
||||
'/app/account': 'Viewing Account',
|
||||
'/app/account/skins': 'Viewing Skin Manager',
|
||||
'/app/cluster': 'Viewing Clusters',
|
||||
'/app/cluster/browser': 'Viewing {clusterName}\'s mods',
|
||||
'/app/cluster/browser/package': 'Browsing {packageName}',
|
||||
'/app/cluster/logs': 'Viewing {clusterName}\'s logs',
|
||||
'/app/cluster/mods': 'Viewing {clusterName}\'s mods',
|
||||
'/app/cluster/overview': 'Viewing {clusterName}',
|
||||
'/app/cluster/process': 'Viewing {clusterName}',
|
||||
'/app/cluster/settings': 'Viewing {clusterName}\'s settings',
|
||||
'/app/settings': 'Viewing Settings',
|
||||
'/app/settings/appearance': 'Viewing Settings',
|
||||
'/app/settings/developer': 'Viewing Settings',
|
||||
'/app/settings/minecraft': 'Viewing Settings',
|
||||
'/app/accounts': 'Viewing Accounts',
|
||||
'/app/clusters': 'Viewing Clusters',
|
||||
'/onboarding': 'Preparing OneClient',
|
||||
'/onboarding/account': 'Preparing OneClient',
|
||||
'/onboarding/finished': 'Preparing OneClient',
|
||||
'/onboarding/language': 'Preparing OneClient',
|
||||
'/onboarding/preferences/version': 'Preparing OneClient',
|
||||
'/onboarding/preferences/versionCategory': 'Preparing OneClient',
|
||||
'/onboarding/preferences': 'Preparing OneClient',
|
||||
};
|
||||
|
||||
// Credit - https://github.com/DuckySoLucky/hypixel-discord-chat-bridge/blob/d3ea84a26ebf094c8191d50b4954549e2dd4dc7f/src/contracts/helperFunctions.js#L216-L225
|
||||
function ReplaceVariables(template: string, variables: Record<string, any>) {
|
||||
return template.replace(/\{(\w+)\}/g, (match: any, name: string | number) => variables[name] ?? match);
|
||||
}
|
||||
|
||||
function useDiscordRPC() {
|
||||
const location = useLocation();
|
||||
const clusterId = location.search.clusterId ?? 0;
|
||||
const provider = location.search.provider ?? 'Modrinth';
|
||||
const packageId = location.search.packageId ?? '8pJYUDNi';
|
||||
const { data: cluster } = useCommand(['getClusterById', clusterId], () => bindings.core.getClusterById(clusterId));
|
||||
const { data: managedPackage } = useCommand(['getPackage', provider, packageId], () => bindings.core.getPackage(provider, packageId));
|
||||
useEffect(() => {
|
||||
bindings.core.setDiscordRPCMessage(ReplaceVariables(ResolvedPathNames[location.pathname as URLPath], { clusterName: cluster?.name ?? 'UNKNOWN', packageName: managedPackage?.name ?? 'UNKNOWN' }));
|
||||
}, [location.pathname, location.search.clusterId, cluster?.name, managedPackage?.name]);
|
||||
}
|
||||
|
||||
function RootRoute() {
|
||||
const router = useRouter();
|
||||
const { setting } = useSettings();
|
||||
useDiscordRPC();
|
||||
return (
|
||||
<RouterProvider
|
||||
navigate={(to, options) => router.navigate({ to, ...options })}
|
||||
|
|
@ -46,7 +98,7 @@ function DevTools() {
|
|||
return (
|
||||
<TanStackDevtools
|
||||
config={{
|
||||
position: 'top-left',
|
||||
position: 'bottom-left',
|
||||
}}
|
||||
plugins={[
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { MinecraftCredentials } from '@/bindings.gen';
|
||||
import { LoaderSuspense } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { MissingAccountData } from '@/routes/app/account/skins';
|
||||
import { createFileRoute, Outlet } from '@tanstack/react-router';
|
||||
import { MissingAccountData } from './skins';
|
||||
|
||||
export interface AccountsRouteSearchParams {
|
||||
profile: MinecraftCredentials | undefined;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import type { PlayerAnimation } from 'skinview3d';
|
||||
import { SheetPage, SkinViewer } from '@/components';
|
||||
import { ImportSkinModal, RemoveSkinCapeModal } from '@/components/overlay';
|
||||
import { Overlay } from '@/components/overlay/Overlay';
|
||||
import { ImportSkinModal, Overlay, RemoveSkinCapeModal, SheetPage, SkinViewer } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { getSkinUrl } from '@/utils/minecraft';
|
||||
import { toast } from '@/utils/toast';
|
||||
|
|
@ -12,7 +10,6 @@ import { save } from '@tauri-apps/plugin-dialog';
|
|||
import { exists, mkdir, readTextFile, writeFile, writeTextFile } from '@tauri-apps/plugin-fs';
|
||||
import { Download01Icon, PlusIcon, Trash01Icon } from '@untitled-theme/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { DialogTrigger } from 'react-aria-components';
|
||||
import { CrouchAnimation, FlyingAnimation, HitAnimation, IdleAnimation, WalkingAnimation } from 'skinview3d';
|
||||
|
||||
interface Skin {
|
||||
|
|
@ -283,7 +280,7 @@ function SkinHistoryRow({ selected, animation, setSelectedSkin, skins, setSkins,
|
|||
</div>
|
||||
|
||||
<div className="flex flex-row h-fit gap-2">
|
||||
<DialogTrigger>
|
||||
<Overlay.Trigger>
|
||||
<Button className="border border-component-border rounded-xl bg-component-border w-[75px] h-[120px]" color="ghost">
|
||||
<div className="flex flex-col justify-center items-center content-center h-full">
|
||||
<PlusIcon className="scale-200" />
|
||||
|
|
@ -292,7 +289,7 @@ function SkinHistoryRow({ selected, animation, setSelectedSkin, skins, setSkins,
|
|||
<Overlay>
|
||||
<ImportSkinModal importFromURL={importFromURL} importFromUsername={importFromUsername} />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
</Overlay.Trigger>
|
||||
{skins.map(skinData => (
|
||||
<RenderSkin
|
||||
animation={animation}
|
||||
|
|
@ -358,7 +355,7 @@ function RenderSkin({ skin, selected, animation, setSelectedSkin, setSkins, cape
|
|||
{selected.skin_url === skin.skin_url
|
||||
? <></>
|
||||
: (
|
||||
<DialogTrigger>
|
||||
<Overlay.Trigger>
|
||||
<Button className="group w-8 h-8 absolute top-0 right-0" color="ghost" size="icon">
|
||||
<Trash01Icon className="group-hover:stroke-danger" />
|
||||
</Button>
|
||||
|
|
@ -366,7 +363,7 @@ function RenderSkin({ skin, selected, animation, setSelectedSkin, setSkins, cape
|
|||
<Overlay>
|
||||
<RemoveSkinCapeModal onPress={() => setSkins(prev => prev.filter(skinData => skinData.skin_url !== skin.skin_url))} />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
</Overlay.Trigger>
|
||||
)}
|
||||
<Button
|
||||
className="group w-8 h-8 absolute bottom-0 right-0"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
import type { MinecraftCredentials } from '@/bindings.gen';
|
||||
import type { ButtonProps } from '@onelauncher/common/components';
|
||||
import { AccountAvatar, DeleteAccountButton, ManageSkinButton, SheetPage, SkinViewer } from '@/components';
|
||||
import { AddAccountModal } from '@/components/overlay';
|
||||
import { Overlay } from '@/components/overlay/Overlay';
|
||||
import { AccountAvatar, AddAccountModal, DeleteAccountButton, ManageSkinButton, Overlay, SheetPage, SkinViewer } from '@/components';
|
||||
import { usePlayerProfile } from '@/hooks/usePlayerProfile';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandMut, useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { Button as AriaButton, DialogTrigger } from 'react-aria-components';
|
||||
import { Button as AriaButton } from 'react-aria-components';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export const Route = createFileRoute('/app/accounts')({
|
||||
|
|
@ -166,7 +164,7 @@ function AddAccountButton({
|
|||
size: ButtonProps['size'];
|
||||
}) {
|
||||
return (
|
||||
<DialogTrigger>
|
||||
<Overlay.Trigger>
|
||||
<Button color="secondary" size={size}>
|
||||
Add Account
|
||||
</Button>
|
||||
|
|
@ -174,6 +172,6 @@ function AddAccountButton({
|
|||
<Overlay>
|
||||
<AddAccountModal />
|
||||
</Overlay>
|
||||
</DialogTrigger>
|
||||
</Overlay.Trigger>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import type { ManagedPackage, ManagedUser, ManagedVersion, PackageDonationUrl } from '@/bindings.gen';
|
||||
import { LoaderSuspense } from '@/components';
|
||||
import { ExternalLink } from '@/components/ExternalLink';
|
||||
import { Markdown } from '@/components/Markdown';
|
||||
import { ExternalLink, LoaderSuspense, Markdown } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { abbreviateNumber, formatAsRelative, upperFirst, useCommand, useCommandMut, useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button, Show, Tooltip } from '@onelauncher/common/components';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { Key } from 'react-aria-components';
|
||||
import { LoaderContainer, SheetPage, useSheetPageContext } from '@/components';
|
||||
import { LogViewer } from '@/components/LogViewer';
|
||||
import { LoaderContainer, LogViewer, SheetPage, useSheetPageContext } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { getMessageFromError, useCommand, useCommandSuspense } from '@onelauncher/common';
|
||||
import { Dropdown } from '@onelauncher/common/components';
|
||||
|
|
@ -17,7 +16,7 @@ function RouteComponent() {
|
|||
|
||||
const { data: fileNames } = useCommandSuspense(['getLogs', cluster.id], () => bindings.core.getLogs(cluster.id));
|
||||
|
||||
const [activeFileName, setActiveFileName] = useState<Key | undefined>(fileNames[0] || undefined);
|
||||
const [activeFileName, setActiveFileName] = useState<Key | null>(fileNames[0] || null);
|
||||
|
||||
return (
|
||||
<SheetPage.Content>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ModCardContextApi } from '@/components/Bundle';
|
||||
import { ModCardContext, ModList } from '@/components/Bundle';
|
||||
import type { ModCardContextApi } from '@/components';
|
||||
import { ModCardContext, ModList } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { SheetPage } from '@/components/SheetPage';
|
||||
import { SheetPage } from '@/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/app/cluster/overview')({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { LogViewerRef } from '@/components/LogViewer';
|
||||
import { LoaderContainer, SheetPage, useSheetPageContext } from '@/components';
|
||||
import { LogViewer } from '@/components/LogViewer';
|
||||
import type { LogViewerRef } from '@/components';
|
||||
import { LoaderContainer, LogViewer, SheetPage, useSheetPageContext } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { getMessageFromError, useAsyncEffect, useCommand } from '@onelauncher/common';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import { LoaderSuspense, Tab, TabList } from '@/components';
|
||||
import { LaunchButton } from '@/components/LaunchButton';
|
||||
import { SheetPage } from '@/components/SheetPage';
|
||||
import { LaunchButton, LoaderSuspense, SheetPage, Tab, TabList } from '@/components';
|
||||
import { useIsRunning } from '@/hooks/useClusters';
|
||||
import { bindings } from '@/main';
|
||||
import { prettifyLoader } from '@/utils/loaders';
|
||||
|
|
@ -128,7 +126,7 @@ function HeaderLarge() {
|
|||
</Button>
|
||||
|
||||
<LaunchButton
|
||||
clusterId={cluster.id}
|
||||
cluster={cluster}
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -155,7 +153,7 @@ function HeaderSmall() {
|
|||
</Button>
|
||||
|
||||
<LaunchButton
|
||||
clusterId={cluster.id}
|
||||
cluster={cluster}
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { SheetPage } from '@/components';
|
||||
import SettingsRow from '@/components/SettingsRow';
|
||||
import { SettingsRow, SheetPage } from '@/components';
|
||||
import { useClusterProfile } from '@/hooks/useSettings';
|
||||
import { Switch, TextField } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import type { GameLoader } from '@/bindings.gen';
|
||||
import { GameBackground } from '@/components';
|
||||
import { LaunchButton } from '@/components/LaunchButton';
|
||||
import { SheetPage } from '@/components/SheetPage';
|
||||
import { GameBackground, LaunchButton, SheetPage } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import useClusterStore from '@/stores/clusterStore';
|
||||
import { prettifyLoader } from '@/utils/loaders';
|
||||
|
|
@ -105,6 +103,21 @@ function RouteComponent() {
|
|||
});
|
||||
}, [cluster, navigate]);
|
||||
|
||||
if (!cluster)
|
||||
return (
|
||||
<SheetPage
|
||||
headerLarge={<HeaderLarge />}
|
||||
headerSmall={<HeaderSmall />}
|
||||
>
|
||||
<div className="relative flex flex-row gap-4">
|
||||
<SheetPage.Content className="sticky top-8 w-86 h-min flex flex-col p-2 gap-2 outline outline-ghost-overlay">
|
||||
<p>Something wen't wrong while getting a cluster</p>
|
||||
<p>Please reload and if this does not work please contact support</p>
|
||||
</SheetPage.Content>
|
||||
</div>
|
||||
</SheetPage>
|
||||
);
|
||||
|
||||
return (
|
||||
<SheetPage
|
||||
headerLarge={<HeaderLarge />}
|
||||
|
|
@ -139,7 +152,7 @@ function RouteComponent() {
|
|||
<GameBackground className="aspect-video w-full rounded-xl outline-2 outline-ghost-overlay" name={versionInfo.backgroundName} />
|
||||
|
||||
<div className="flex flex-col px-4 pt-2 pb-4 gap-2">
|
||||
<h2 className="text-xxl font-medium">Version {cluster?.mc_version}</h2>
|
||||
<h2 className="text-xxl font-medium">Version {cluster.mc_version}</h2>
|
||||
<p className="text-sm text-fg-secondary">{versionInfo.longDescription}</p>
|
||||
|
||||
{minorVersions.length > 1 && (
|
||||
|
|
@ -196,7 +209,7 @@ function RouteComponent() {
|
|||
)}
|
||||
|
||||
<div className="w-full flex flex-row gap-4 mt-2">
|
||||
<LaunchButton className="flex-1" clusterId={cluster?.id} size="large" />
|
||||
<LaunchButton className="flex-1" cluster={cluster} size="large" />
|
||||
|
||||
<Button
|
||||
className="flex-1"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import type { ClusterModel, GameLoader } from '@/bindings.gen';
|
||||
import type { ButtonProps } from 'react-aria-components';
|
||||
import { GameBackground } from '@/components';
|
||||
import { LaunchButton } from '@/components/LaunchButton';
|
||||
import { GameBackground, LaunchButton } from '@/components';
|
||||
import { useActiveCluster, useLastPlayedClusters } from '@/hooks/useClusters';
|
||||
import { bindings } from '@/main';
|
||||
import useAppShellStore from '@/stores/appShellStore';
|
||||
|
|
@ -40,7 +39,7 @@ function RouteComponent() {
|
|||
<motion.div {...animations.slideInUp} className="flex flex-row transition-[height] h-52 gap-6">
|
||||
{lastPlayedClusters.slice(0, 3).map(cluster => (
|
||||
<RecentsCard
|
||||
active={activeCluster?.id === cluster.id}
|
||||
active={activeCluster.id === cluster.id}
|
||||
key={cluster.folder_name}
|
||||
loader={cluster.mc_loader}
|
||||
onPress={() => setActiveClusterId(cluster.id)}
|
||||
|
|
@ -60,20 +59,11 @@ function RouteComponent() {
|
|||
);
|
||||
}
|
||||
|
||||
function ActiveClusterInfo({
|
||||
cluster,
|
||||
}: {
|
||||
cluster: ClusterModel | undefined;
|
||||
}) {
|
||||
const versionInfo = getVersionInfoOrDefault(cluster?.mc_version);
|
||||
const navigate = useNavigate({
|
||||
from: Route.id,
|
||||
});
|
||||
function ActiveClusterInfo({ cluster }: { cluster: ClusterModel }) {
|
||||
const versionInfo = getVersionInfoOrDefault(cluster.mc_version);
|
||||
const navigate = useNavigate({ from: Route.id });
|
||||
|
||||
const viewCluster = () => {
|
||||
if (!cluster)
|
||||
return;
|
||||
|
||||
navigate({
|
||||
to: '/app/cluster/overview',
|
||||
search: {
|
||||
|
|
@ -93,14 +83,14 @@ function ActiveClusterInfo({
|
|||
position: 'relative',
|
||||
left: '-50%',
|
||||
}}
|
||||
key={(cluster?.mc_version ?? Math.random()) + (cluster?.mc_loader ?? '')}
|
||||
key={(cluster.mc_version) + (cluster.mc_loader)}
|
||||
transition={{ ease: 'backInOut', duration: 0.35 }}
|
||||
>
|
||||
<h1 className="text-6xl font-bold text-fg-primary">{cluster?.mc_version} {prettifyLoader(cluster?.mc_loader ?? 'vanilla')}</h1>
|
||||
<h1 className="text-6xl font-bold text-fg-primary">{cluster.mc_version} {prettifyLoader(cluster.mc_loader)}</h1>
|
||||
<p className="text-lg font-medium text-fg-secondary">{versionInfo.shortDescription}</p>
|
||||
|
||||
<div className="flex flex-row justify-center items-center gap-2">
|
||||
<LaunchButton clusterId={cluster?.id} size="large" />
|
||||
<LaunchButton cluster={cluster} size="large" />
|
||||
|
||||
<Button color="ghost" onPress={viewCluster} size="iconLarge">
|
||||
<Settings04Icon />
|
||||
|
|
@ -174,7 +164,7 @@ function Card({
|
|||
onPress={onPress}
|
||||
style={blur
|
||||
? {
|
||||
// shitty hack because webkit breaks with css variables in its backdrop filter
|
||||
// shitty hack because webkit breaks with css variables in its backdrop filter
|
||||
backdropFilter: `blur(${BLUR})`,
|
||||
WebkitBackdropFilter: `blur(${BLUR})`,
|
||||
...style,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { PropsWithChildren } from 'react';
|
||||
import { LoaderSuspense, Navbar } from '@/components';
|
||||
import { GameBackground } from '@/components/GameBackground';
|
||||
import { GameBackground, LoaderSuspense, Navbar } from '@/components';
|
||||
import { useActiveCluster } from '@/hooks/useClusters';
|
||||
import { getVersionInfoOrDefault } from '@/utils/versionMap';
|
||||
import { createFileRoute, Outlet } from '@tanstack/react-router';
|
||||
|
|
@ -53,7 +52,7 @@ function AppShell({
|
|||
|
||||
function BackgroundGradient() {
|
||||
const cluster = useActiveCluster();
|
||||
const versionInfo = getVersionInfoOrDefault(cluster?.mc_version);
|
||||
const versionInfo = getVersionInfoOrDefault(cluster.mc_version);
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
|
|
@ -93,7 +92,7 @@ function BackgroundGradient() {
|
|||
opacity: 0,
|
||||
left: '-10%',
|
||||
}}
|
||||
key={(cluster?.mc_version ?? Math.random()) + (cluster?.mc_loader ?? '')}
|
||||
key={(cluster.mc_version) + (cluster.mc_loader)}
|
||||
>
|
||||
<GameBackground
|
||||
className="absolute left-0 top-0 w-screen h-screen scale-110"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
// import ScrollableContainer from '@/components/ScrollableContainer';
|
||||
import SettingsRow from '@/components/SettingsRow';
|
||||
import SettingsSwitch from '@/components/SettingSwitch';
|
||||
import { SettingsRow, SettingsSwitch } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { Sidebar } from '@/routes/app/settings/route';
|
||||
import { THEMES } from '@/utils/theming';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { Monitor01Icon, PackageIcon, Speedometer04Icon } from '@untitled-theme/icons-react';
|
||||
import Sidebar from './route';
|
||||
|
||||
export const Route = createFileRoute('/app/settings/appearance')({
|
||||
component: RouteComponent,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import { DebugInfo, Overlay } from '@/components/overlay';
|
||||
import SettingsRow from '@/components/SettingsRow';
|
||||
import SettingsSwitch from '@/components/SettingSwitch';
|
||||
import { DebugInfo, Overlay, SettingsRow, SettingsSwitch } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { Sidebar } from '@/routes/app/settings/route';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { createFileRoute, Link } from '@tanstack/react-router';
|
||||
import { BatteryEmptyIcon, BatteryFullIcon, Code02Icon, FileHeart02Icon, Truck01Icon } from '@untitled-theme/icons-react';
|
||||
import Sidebar from './route';
|
||||
|
||||
export const Route = createFileRoute('/app/settings/developer')({
|
||||
component: RouteComponent,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
// import DiscordIcon from '@/assets/logos/discord.svg';
|
||||
import SettingsRow from '@/components/SettingsRow';
|
||||
import SettingsSwitch from '@/components/SettingSwitch';
|
||||
import { SettingsRow, SettingsSwitch } from '@/components';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
// import useSettings from '@/hooks/useSettings';
|
||||
import { Sidebar } from '@/routes/app/settings/route';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { dataDir, join } from '@tauri-apps/api/path';
|
||||
import { FolderIcon, Link03Icon, LinkExternal01Icon } from '@untitled-theme/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Sidebar from './route';
|
||||
|
||||
export const Route = createFileRoute('/app/settings/')({
|
||||
component: RouteComponent,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
import type { SettingProfileModel } from '@/bindings.gen';
|
||||
// import ScrollableContainer from '@/components/ScrollableContainer';
|
||||
import SettingsRow from '@/components/SettingsRow';
|
||||
import { SettingsRow } from '@/components';
|
||||
import usePopState from '@/hooks/usePopState';
|
||||
import { useSettings } from '@/hooks/useSettings';
|
||||
import { bindings } from '@/main';
|
||||
import { Sidebar } from '@/routes/app/settings/route';
|
||||
import { useCommandMut, useCommandSuspense } from '@onelauncher/common';
|
||||
import { Switch, TextField } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { Database01Icon, FilePlus02Icon, FileX02Icon, LayoutTopIcon, Maximize01Icon, ParagraphWrapIcon, XIcon } from '@untitled-theme/icons-react';
|
||||
import { useMemo } from 'react';
|
||||
import Sidebar from './route';
|
||||
|
||||
export const Route = createFileRoute('/app/settings/minecraft')({
|
||||
component: RouteComponent,
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ interface SidebarProps {
|
|||
exact?: boolean;
|
||||
}
|
||||
|
||||
function Sidebar(props: SidebarProps) {
|
||||
export function Sidebar(props: SidebarProps) {
|
||||
const { base, links, exact } = props;
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import type { MinecraftCredentials } from '@/bindings.gen';
|
|||
import { AccountAvatar, SkinViewer } from '@/components';
|
||||
import { usePlayerProfile } from '@/hooks/usePlayerProfile';
|
||||
import { bindings } from '@/main';
|
||||
import { OnboardingNavigation } from '@/routes/onboarding/route';
|
||||
import { useCommandMut, useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { OnboardingNavigation } from './route';
|
||||
|
||||
export const Route = createFileRoute('/onboarding/account')({
|
||||
component: RouteComponent,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { GameLoader, OnlineCluster, OnlineClusterEntry } from '@/bindings.gen';
|
||||
import type { VersionInfo } from '@/utils/versionMap';
|
||||
import { bindings } from '@/main';
|
||||
import { OnboardingNavigation } from '@/routes/onboarding/route';
|
||||
import { getVersionInfoOrDefault } from '@/utils/versionMap';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
|
@ -8,7 +9,6 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
|||
import { useState } from 'react';
|
||||
import { Button as AriaButton } from 'react-aria-components';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { OnboardingNavigation } from '../route';
|
||||
|
||||
export interface StrippedCLuster {
|
||||
mc_version: string;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import type { ClusterModel, ModpackArchive, ModpackFile } from '@/bindings.gen';
|
||||
import type { DownloadModsRef } from '@/components';
|
||||
import type { ModCardContextApi, onClickOnMod } from '@/components/Bundle';
|
||||
import type { StrippedCLuster } from './version';
|
||||
import { DownloadMods } from '@/components';
|
||||
import { ModCardContext } from '@/components/Bundle';
|
||||
import { BundleModListModal, Overlay } from '@/components/overlay';
|
||||
import type { DownloadModsRef, ModCardContextApi, onClickOnMod } from '@/components';
|
||||
import type { StrippedCLuster } from '@/routes/onboarding/preferences/version';
|
||||
import { BundleModListModal, DownloadMods, ModCardContext, Overlay } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { OnboardingNavigation } from '@/routes/onboarding/route';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
|
@ -14,7 +12,6 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
|||
import { useMemo, useRef, useState } from 'react';
|
||||
import { Button as AriaButton } from 'react-aria-components';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { OnboardingNavigation } from '../route';
|
||||
|
||||
export const Route = createFileRoute('/onboarding/preferences/versionCategory')({
|
||||
component: RouteComponent,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import type { DownloadModsRef } from '@/components';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import LauncherLogo from '@/assets/logos/oneclient.svg?react';
|
||||
import { LoaderSuspense, NavbarButton } from '@/components';
|
||||
import { GameBackground } from '@/components/GameBackground';
|
||||
import { Overlay, SuperSecretDevOptions } from '@/components/overlay';
|
||||
import { Stepper } from '@/components/Stepper';
|
||||
import { GameBackground, LoaderSuspense, NavbarButton, Overlay, Stepper, SuperSecretDevOptions } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { useCommandSuspense } from '@onelauncher/common';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
|
|
|
|||
|
|
@ -21,6 +21,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
@utility partial-leftline-* {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
background: currentColor;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 3px;
|
||||
height: --spacing(--value(integer));
|
||||
height: --value(percentage, [percentage]);
|
||||
}
|
||||
}
|
||||
|
||||
@theme {
|
||||
/** border */
|
||||
--color-component-border: #ffffff1A;
|
||||
|
|
@ -34,7 +49,7 @@
|
|||
--radius-3xl: 2rem;
|
||||
}
|
||||
|
||||
.prose-invert{
|
||||
.prose-invert {
|
||||
--tw-prose-body: var(--color-fg-primary);
|
||||
--tw-prose-headings: var(--color-fg-primary);
|
||||
--tw-prose-bold: var(--color-fg-primary);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,3 @@
|
|||
use std::process::Command;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn main() {
|
||||
let output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.unwrap();
|
||||
let git_hash = String::from_utf8(output.stdout).unwrap();
|
||||
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
||||
|
||||
let start = SystemTime::now();
|
||||
let timestamp = start
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time went backwards")
|
||||
.as_secs();
|
||||
println!("cargo:rustc-env=BUILD_TIMESTAMP={}", timestamp);
|
||||
|
||||
tauri_build::build();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@
|
|||
"opener:allow-open-url",
|
||||
"opener:default",
|
||||
|
||||
"os:default"
|
||||
"os:allow-arch",
|
||||
"os:deny-exe-extension",
|
||||
"os:allow-family",
|
||||
"os:deny-hostname",
|
||||
"os:allow-locale",
|
||||
"os:allow-os-type",
|
||||
"os:allow-platform",
|
||||
"os:allow-version"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ gui = []
|
|||
[lints]
|
||||
workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
shadow-rs = { workspace = true, features = ["default"] }
|
||||
|
||||
[dependencies]
|
||||
# core
|
||||
interpulse = { workspace = true }
|
||||
|
|
@ -74,6 +77,7 @@ paste = { workspace = true }
|
|||
byteorder = { workspace = true }
|
||||
merge = { workspace = true }
|
||||
opener = { workspace = true }
|
||||
shadow-rs = { workspace = true }
|
||||
|
||||
# integration
|
||||
discord-rich-presence = { workspace = true }
|
||||
|
|
|
|||
5
packages/core/build.rs
Normal file
5
packages/core/build.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
use shadow_rs::ShadowBuilder;
|
||||
|
||||
fn main() {
|
||||
ShadowBuilder::builder().build().unwrap();
|
||||
}
|
||||
|
|
@ -196,6 +196,9 @@ pub trait TauriLauncherApi {
|
|||
provider: Provider,
|
||||
author: PackageAuthor,
|
||||
) -> LauncherResult<Vec<ManagedUser>>;
|
||||
|
||||
#[taurpc(alias = "getLinkedPackages")]
|
||||
async fn get_linked_packages(cluster_id: ClusterId) -> LauncherResult<Vec<packages::Model>>;
|
||||
// endregion: package
|
||||
|
||||
// MARK: API: modpack
|
||||
|
|
@ -248,6 +251,12 @@ pub trait TauriLauncherApi {
|
|||
) -> LauncherResult<crate::utils::minecraft::MowojangProfile>;
|
||||
// endregion: minecraft
|
||||
|
||||
// MARK: API: discord RPC
|
||||
// region: discord RPC
|
||||
#[taurpc(alias = "setDiscordRPCMessage")]
|
||||
async fn set_discord_rpc_message(message: String) -> LauncherResult<()>;
|
||||
// endregion: discord RPC
|
||||
|
||||
// MARK: API: Other
|
||||
async fn open(input: String) -> LauncherResult<()>;
|
||||
}
|
||||
|
|
@ -731,6 +740,19 @@ impl TauriLauncherApi for TauriLauncherApiImpl {
|
|||
|
||||
Ok(model)
|
||||
}
|
||||
|
||||
async fn get_linked_packages(
|
||||
self,
|
||||
cluster_id: ClusterId,
|
||||
) -> LauncherResult<Vec<packages::Model>> {
|
||||
let cluster = api::cluster::dao::get_cluster_by_id(cluster_id)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow::anyhow!("cluster with id {} not found", cluster_id))?;
|
||||
|
||||
let model = api::packages::dao::get_linked_packages(&cluster).await?;
|
||||
|
||||
Ok(model)
|
||||
}
|
||||
// endregion: package
|
||||
|
||||
// MARK: Impl: modpack
|
||||
|
|
@ -815,6 +837,22 @@ impl TauriLauncherApi for TauriLauncherApiImpl {
|
|||
}
|
||||
// endregion: minecraft
|
||||
|
||||
// MARK: Impl: discord RPC
|
||||
// region: discord RPC
|
||||
async fn set_discord_rpc_message(self, message: String) -> LauncherResult<()> {
|
||||
let state = State::get().await?;
|
||||
if let Some(discord) = &state.rpc {
|
||||
if !state.settings.read().await.discord_enabled {
|
||||
discord.clear_activity().await;
|
||||
return Ok(());
|
||||
}
|
||||
discord.set_message(&message, None).await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// endregion: discord RPC
|
||||
|
||||
// MARK: Impl: Other
|
||||
// region: other
|
||||
async fn open(self, input: String) -> LauncherResult<()> {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use tauri::Runtime;
|
||||
use tauri_plugin_os::{arch, family, locale, platform, type_, version};
|
||||
|
||||
use crate::error::LauncherResult;
|
||||
|
||||
#[taurpc::procedures(path = "debug")]
|
||||
pub trait TauriLauncherDebugApi {
|
||||
#[taurpc(alias = "openDevTools")]
|
||||
|
|
@ -11,9 +9,6 @@ pub trait TauriLauncherDebugApi {
|
|||
#[taurpc(alias = "isInDev")]
|
||||
async fn is_in_dev() -> bool;
|
||||
|
||||
#[taurpc(alias = "getPlatform")]
|
||||
async fn get_platform() -> String;
|
||||
|
||||
#[taurpc(alias = "getArch")]
|
||||
async fn get_arch() -> String;
|
||||
|
||||
|
|
@ -26,14 +21,20 @@ pub trait TauriLauncherDebugApi {
|
|||
#[taurpc(alias = "getType")]
|
||||
async fn get_type() -> String;
|
||||
|
||||
#[taurpc(alias = "getVersion")]
|
||||
#[taurpc(alias = "getPlatform")]
|
||||
async fn get_platform() -> String;
|
||||
|
||||
#[taurpc(alias = "getOsVersion")]
|
||||
async fn get_version() -> String;
|
||||
|
||||
#[taurpc(alias = "getCommitHash")]
|
||||
async fn get_commit_hash() -> LauncherResult<String>;
|
||||
#[taurpc(alias = "getGitCommitHash")]
|
||||
async fn get_git_commit_hash() -> String;
|
||||
|
||||
#[taurpc(alias = "getBuildTimestamp")]
|
||||
async fn get_build_timestamp() -> LauncherResult<String>;
|
||||
async fn get_build_timestamp() -> String;
|
||||
|
||||
#[taurpc(alias = "getPackageVersion")]
|
||||
async fn get_package_version() -> String;
|
||||
}
|
||||
|
||||
#[taurpc::ipc_type]
|
||||
|
|
@ -49,10 +50,6 @@ impl TauriLauncherDebugApi for TauriLauncherDebugApiImpl {
|
|||
tauri::is_dev()
|
||||
}
|
||||
|
||||
async fn get_platform(self) -> String {
|
||||
platform().to_string()
|
||||
}
|
||||
|
||||
async fn get_arch(self) -> String {
|
||||
arch().to_string()
|
||||
}
|
||||
|
|
@ -69,21 +66,23 @@ impl TauriLauncherDebugApi for TauriLauncherDebugApiImpl {
|
|||
type_().to_string()
|
||||
}
|
||||
|
||||
async fn get_platform(self) -> String {
|
||||
platform().to_string()
|
||||
}
|
||||
|
||||
async fn get_version(self) -> String {
|
||||
version().to_string()
|
||||
}
|
||||
|
||||
async fn get_commit_hash(self) -> LauncherResult<String> {
|
||||
if tauri::is_dev() {
|
||||
let hash = std::env::var("GIT_HASH").map_err(anyhow::Error::from)?;
|
||||
Ok(hash)
|
||||
} else {
|
||||
Ok("null".to_string())
|
||||
}
|
||||
async fn get_git_commit_hash(self) -> String {
|
||||
crate::build::COMMIT_HASH.to_string()
|
||||
}
|
||||
|
||||
async fn get_build_timestamp(self) -> LauncherResult<String> {
|
||||
let timestamp = std::env::var("BUILD_TIMESTAMP").map_err(anyhow::Error::from)?;
|
||||
Ok(timestamp)
|
||||
async fn get_build_timestamp(self) -> String {
|
||||
crate::build::BUILD_TIME.to_string()
|
||||
}
|
||||
|
||||
async fn get_package_version(self) -> String {
|
||||
crate::build::PKG_VERSION.to_string()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#![feature(slice_as_array)]
|
||||
#![allow(clippy::struct_excessive_bools)]
|
||||
|
||||
shadow_rs::shadow!(build);
|
||||
pub use build::*;
|
||||
|
||||
use api::proxy::LauncherProxy;
|
||||
use error::LauncherResult;
|
||||
pub use logger::start_logger;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ impl Default for Settings {
|
|||
Self {
|
||||
global_game_settings: setting_profiles::Model::default_global_profile(),
|
||||
allow_parallel_running_clusters: false,
|
||||
discord_enabled: false,
|
||||
discord_enabled: true,
|
||||
seen_onboarding: false,
|
||||
mod_list_use_grid: true,
|
||||
parallel_mod_downloading: true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue