Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
96fff60
intiial commit for rich presence
hitblast Feb 5, 2026
f6789f4
update to v0.1.5; https://github.com/Mrmayman/quantumlauncher/pull/139
hitblast Feb 5, 2026
c955595
communicate through message handlers
hitblast Feb 5, 2026
5804232
experimental windows addition
hitblast Feb 6, 2026
0dce1ef
chore: update to latest fr lib'
hitblast Feb 6, 2026
4015bec
experimental fix for failing unix pipe paths
hitblast Feb 6, 2026
69d259a
update lockfile
hitblast Feb 6, 2026
f2fcdd5
Merge branch 'main' into main
Mrmayman Feb 6, 2026
a7f37b8
Update quantum_launcher/src/state/mod.rs
hitblast Feb 8, 2026
933e64d
Merge branch 'Mrmayman:main' into main
hitblast Feb 14, 2026
80c48d4
iced message module integration; need review
hitblast Feb 14, 2026
6389f8a
remove anyhow since not needed
hitblast Feb 14, 2026
46fd76d
much simpler design; v0.2.0 -> DiscordIPC Clone impl
hitblast Feb 14, 2026
b09bea4
current playing version (exit not implemented)
hitblast Feb 14, 2026
babd765
achieved demo with iced model
hitblast Feb 15, 2026
18420e1
add new setting for discord rich presence
hitblast Feb 15, 2026
022baa8
chore: test with this version
hitblast Feb 16, 2026
4a3fcb2
LESGO
hitblast Feb 16, 2026
5cca181
remove bloat logs for IPC client
hitblast Feb 16, 2026
409a750
Merge branch 'Mrmayman:main' into main
hitblast Feb 17, 2026
78ac7a6
use v0.3.1 for JSON optimizations in RPC
hitblast Feb 17, 2026
44945fd
update to version 0.3.2 for strict changes
hitblast Feb 17, 2026
bcf6f42
remove unnecessary DEPLOYMENT_TARGET env var at root
hitblast Feb 17, 2026
ccfadaa
test with instantly toggleable rich presence
hitblast Feb 17, 2026
440d2c1
use v4 of library
hitblast Feb 18, 2026
9e3a31d
use v0.4.4 as it handles rate-limiting
hitblast Feb 18, 2026
5450c24
update architectural noise
hitblast Feb 18, 2026
1b5edfd
state machine changes to IPC handling
hitblast Feb 18, 2026
1738cbb
do not reuse initial activity for future ones
hitblast Feb 18, 2026
6a458ed
simpler state machine
hitblast Feb 18, 2026
34dca52
new build script for apple silicon macs
hitblast Feb 18, 2026
c8e9c7b
update version to v0.4.5 for better close()
hitblast Feb 19, 2026
7d75709
even more elegant rich presences
hitblast Feb 20, 2026
8374267
modify workflow files
hitblast Feb 20, 2026
2fc5100
update bundle name according to macOS schematics
hitblast Feb 21, 2026
9c9d55c
Merge branch 'main' into main
hitblast Feb 22, 2026
a02c6dc
fix: clippy
hitblast Feb 22, 2026
09ac0c2
Merge branch 'Mrmayman:main' into main
hitblast Feb 23, 2026
a07ece3
resolve merge conflict
hitblast Mar 3, 2026
b7a642e
Merge remote-tracking branch 'upstream/main'
hitblast Mar 6, 2026
55286cf
Merge branch 'main' into main
Mrmayman Mar 15, 2026
191ad03
Fix some dependency issues
Mrmayman Mar 15, 2026
8eba879
Merge branch 'main' into main
hitblast Mar 29, 2026
e5c2f90
v0.8.1; big updates for rich presence in QL
hitblast Apr 5, 2026
f7d99b9
remove unused activity import
hitblast Apr 5, 2026
c3cf09e
Merge remote-tracking branch 'origin/main' into pr-139
Mrmayman Apr 5, 2026
472152d
Dev: Minor code tweaks
Mrmayman Apr 5, 2026
20fdeec
Dev: Add rich presence toggle to welcome and changelog, update changelog
Mrmayman Apr 5, 2026
bf4a76e
fix: merge conflicts
hitblast Apr 6, 2026
a3c75d9
add separate tab for discord presence-related things
hitblast Apr 6, 2026
0dbeded
add state fixes for proper custom initial content
hitblast Apr 6, 2026
623b263
update basic discord presence handler; library needs some updates
hitblast Apr 6, 2026
d0b889a
add toggle functionality
hitblast Apr 6, 2026
09a22c9
update things
hitblast Apr 6, 2026
ba20190
chore: add event mechanism
hitblast Apr 6, 2026
f6b6f7c
chore: update tab presence
hitblast Apr 6, 2026
35488cb
fix crashes and mc version rules in presence
hitblast Apr 6, 2026
1a0549b
chore: update filthy-rich to v0.8.2
hitblast Apr 6, 2026
d445b34
Set Now button now available
hitblast Apr 7, 2026
66a76a3
chore: properly document instance name toggle
hitblast Apr 7, 2026
533c9e5
feat: new status line for rich presences in presence tab!
hitblast Apr 7, 2026
e648e3d
chore: state-driven toggles section
hitblast Apr 7, 2026
f027c47
customization go BRRRRRRRRRRR
hitblast Apr 7, 2026
fad43af
chore: aeven more concise UI for presence tab
hitblast Apr 7, 2026
50240c8
heftier advancements in presence tech
hitblast Apr 7, 2026
7e0ccaf
chore: disable presences if details for each type of presence is missing
hitblast Apr 11, 2026
1f264a6
chore: disabled indicator for presences
hitblast Apr 11, 2026
de3af7b
Dev: use get_or_insert_default everywhere (cleaner)
Mrmayman Apr 14, 2026
c9ab718
Dev: Major code tweaks...
Mrmayman Apr 14, 2026
bf40e7b
Merge remote-tracking branch 'origin/main' into pr-139
Mrmayman Apr 14, 2026
58b0f90
Update scripts/sequoia_arm64_build.sh
Mrmayman Apr 14, 2026
0349f29
Clean up code
Mrmayman Apr 14, 2026
7ccbaaa
chore: made some changes to things
hitblast Apr 14, 2026
1b9b24d
filled up some edge cases regarding missing client references
hitblast Apr 16, 2026
1fb0140
bump filthy-rich to v0.8.3
hitblast Apr 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ env:
REPO_NAME: Mrmayman/quantum-launcher
FINAL_NAME: quantum_launcher
CARGO_TERM_COLOR: always # Tell cargo to always use colors
MACOSX_DEPLOYMENT_TARGET: 10.15

jobs:
dist:
Expand Down Expand Up @@ -66,7 +65,7 @@ jobs:
shell: bash
run: |
mkdir dist
APP_DIR="build/quantum-launcher.app"
APP_DIR="build/QuantumLauncher.app"
MACOS_DIR="$APP_DIR/Contents/MacOS"
RESOURCES_DIR="$APP_DIR/Contents/Resources"
mkdir -p "$MACOS_DIR" "$RESOURCES_DIR"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ jobs:
if [[ "${{ matrix.build }}" =~ "windows" ]]; then
cp "target/${{ matrix.target }}/$PROFILE/${{ env.BIN_NAME }}.exe" "dist/"
elif [[ "${{ matrix.build }}" =~ "macos" ]]; then
APP_DIR="build/quantum-launcher.app"
APP_DIR="build/QuantumLauncher.app"
MACOS_DIR="$APP_DIR/Contents/MacOS"
RESOURCES_DIR="$APP_DIR/Contents/Resources"
mkdir -p "$MACOS_DIR" "$RESOURCES_DIR"
Expand Down
29 changes: 23 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions changelogs/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

TODO: Add screenshots

# Discord Rich Presence

- Added support for displaying your status in Discord through Rich Presence
- Customizable, can display any text or info (game version/instance name) of your choice

# UX

- You can now automatically create changelogs after updating mods,
Expand Down
3 changes: 1 addition & 2 deletions crates/ql_core/src/json/instance_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ impl InstanceConfigJson {

#[must_use]
pub fn c_global_settings(&mut self) -> &mut GlobalSettings {
self.global_settings
.get_or_insert_with(GlobalSettings::default)
self.global_settings.get_or_insert_default()
}

#[must_use]
Expand Down
9 changes: 2 additions & 7 deletions crates/ql_mod_manager/src/loaders/optifine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ use ql_core::{
LAUNCHER_DIR, Loader, OptifineUniqueVersion, Progress, RequestError, download,
file_utils::{self, exists},
impl_3_errs_jri, info, jarmod,
json::{
InstanceConfigJson, VersionDetails, instance_config::ModTypeInfo, optifine::JsonOptifine,
},
json::{InstanceConfigJson, VersionDetails, optifine::JsonOptifine},
no_window, pt,
};
use ql_java_handler::{JAVA, JavaInstallError, JavaVersion, get_java_binary};
Expand Down Expand Up @@ -120,10 +118,7 @@ pub async fn install(
tokio::fs::copy(&path_to_installer, &dest)
.await
.path(&path_to_installer)?;
config
.mod_type_info
.get_or_insert_with(ModTypeInfo::default)
.optifine_jar = Some(filename.to_owned());
config.mod_type_info.get_or_insert_default().optifine_jar = Some(filename.to_owned());
config.save_to_dir(&instance_path).await?;
return Ok(());
}
Expand Down
2 changes: 1 addition & 1 deletion crates/ql_packager/src/multimc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ fn setup_config(ini: &Ini, instance_recipe: &InstanceRecipe, config: &mut Instan
if let Ok(jvmargs) = general_get(ini, "JvmArgs") {
config
.java_args
.get_or_insert_with(Vec::new)
.get_or_insert_default()
.extend(jvmargs.split_whitespace().map(str::to_owned));
}

Expand Down
12 changes: 7 additions & 5 deletions quantum_launcher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ tokio.workspace = true
cfg-if.workspace = true
semver.workspace = true

constcat = "0.6"
rand = "0.10"
chrono.workspace = true # Logging time/date
paste = "1" # Icon widget macro
rfd.workspace = true # File picker
# For Discord Rich Presence management
filthy-rich = "0.8.3"
# Launcher Update
thiserror.workspace = true
zip.workspace = true
Expand All @@ -74,11 +81,6 @@ open = "5.3.2"
dark-light.git = "https://github.com/rust-dark-light/dark-light" # Less dependencies than the stable one
dirs.workspace = true

paste = "1" # icon widget macro
rfd.workspace = true # file picker
constcat = "0.6"
rand = "0.10"

[target.'cfg(not(target_os = "macos"))'.dependencies]
notify-rust = { version = "4", default-features = false, features = ["z-with-tokio"] }

Expand Down
64 changes: 64 additions & 0 deletions quantum_launcher/src/config/discord_rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

const BASIC_DETAILS: &str = "Opened Launcher";
const BASIC_STATE: &str = "";
const GAMEOPEN_DETAILS: &str = "Minecraft v${version}";
const GAMEOPEN_STATE: &str = "Instance name: ${instance}";
const GAMEEXIT_DETAILS: &str = "Just quit game";
const GAMEEXIT_STATE: &str = "Minecraft v${version}";

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RpcConfig {
/// Enable Discord Rich Presence support
// Since: TBD
pub enable: bool,
/// Details for the basic/initial rich presence activity
// Since: TBD
pub basic: RpcText,
/// Whether to change rich presence with instance open/exit events.
// Since: TBD
pub update_on_game_open: bool,
/// Activity on opening the game
// Since: TBD
pub on_gameopen: RpcText,
/// Activity on closing the game
// Since: TBD
pub on_gameexit: RpcText,
#[serde(flatten)]
_extra: HashMap<String, serde_json::Value>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RpcText {
pub top_text: Option<String>,
pub bottom_text: String,
#[serde(flatten)]
_extra: HashMap<String, serde_json::Value>,
}

impl Default for RpcConfig {
fn default() -> Self {
Self {
enable: false,
basic: RpcText {
top_text: Some(BASIC_DETAILS.to_owned()),
bottom_text: BASIC_STATE.to_owned(),
_extra: HashMap::new(),
},
update_on_game_open: true,
on_gameopen: RpcText {
top_text: Some(GAMEOPEN_DETAILS.to_owned()),
bottom_text: GAMEOPEN_STATE.to_owned(),
_extra: HashMap::new(),
},
on_gameexit: RpcText {
top_text: Some(GAMEEXIT_DETAILS.to_owned()),
bottom_text: GAMEEXIT_STATE.to_owned(),
_extra: HashMap::new(),
},
_extra: HashMap::new(),
}
}
}
26 changes: 19 additions & 7 deletions quantum_launcher/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::config::discord_rpc::RpcConfig;
use crate::config::sidebar::{SidebarConfig, SidebarNode, SidebarNodeKind};
use crate::stylesheet::styles::{LauncherTheme, LauncherThemeColor, LauncherThemeLightness};
use crate::{WINDOW_HEIGHT, WINDOW_WIDTH};
Expand All @@ -13,6 +14,7 @@ use std::{
path::Path,
};

pub mod discord_rpc;
pub mod sidebar;

pub const SIDEBAR_WIDTH: f32 = 0.33;
Expand Down Expand Up @@ -102,6 +104,8 @@ pub struct LauncherConfig {
pub persistent: Option<PersistentSettings>,
// Since: v0.5.1
pub sidebar: Option<SidebarConfig>,
// Since: TBD
pub discord_rpc: Option<RpcConfig>,
/// Time of last auto-update check result, in seconds since the Unix epoch.
// Since: TBD
#[cfg(feature = "auto_update")]
Expand Down Expand Up @@ -131,6 +135,7 @@ impl Default for LauncherConfig {
ui: None,
persistent: None,
sidebar: None,
discord_rpc: None,
_extra: HashMap::new(),
#[cfg(feature = "auto_update")]
last_update_check: None,
Expand Down Expand Up @@ -188,6 +193,11 @@ impl LauncherConfig {
Ok(())
}

/// Resets the Discord Rich Presence configuration to default.
pub fn reset_presence(&mut self) {
self.discord_rpc = Some(RpcConfig::default());
}

pub fn update_sidebar(&mut self, instances: &[String], kind: InstanceKind) {
let sidebar = self.sidebar.get_or_insert_with(SidebarConfig::default);

Expand Down Expand Up @@ -281,21 +291,19 @@ impl LauncherConfig {
}

pub fn c_window(&mut self) -> &mut WindowProperties {
self.window.get_or_insert_with(WindowProperties::default)
self.window.get_or_insert_default()
}

pub fn c_global(&mut self) -> &mut GlobalSettings {
self.global_settings
.get_or_insert_with(GlobalSettings::default)
self.global_settings.get_or_insert_default()
}

pub fn c_persistent(&mut self) -> &mut PersistentSettings {
self.persistent
.get_or_insert_with(PersistentSettings::default)
self.persistent.get_or_insert_default()
}

pub fn c_sidebar(&mut self) -> &mut SidebarConfig {
self.sidebar.get_or_insert_with(SidebarConfig::default)
self.sidebar.get_or_insert_default()
}

pub fn c_idle_fps(&self) -> u64 {
Expand All @@ -315,6 +323,10 @@ impl LauncherConfig {
}
}

pub fn c_rpc_enabled(&self) -> bool {
self.discord_rpc.as_ref().is_some_and(|n| n.enable)
}

#[cfg(feature = "auto_update")]
pub fn should_update_check(&self) -> bool {
const INTERVAL_SECS: u64 = 60 * 60;
Expand Down Expand Up @@ -445,7 +457,7 @@ pub struct UiSettings {
pub idle_fps: Option<u64>,
/// When the game is launched, the launcher can either
/// minimize itself, close itself, or do nothing (default).
// Since: v0.5.2
// Since: TBD
#[serde(default)]
pub after_game_opens: AfterLaunchBehavior,
#[serde(flatten)]
Expand Down
7 changes: 7 additions & 0 deletions quantum_launcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,20 @@ impl Launcher {
Task::none()
};

let presence_task = if launcher.config.c_rpc_enabled() {
launcher.start_discord_ipc_run()
} else {
Task::none()
};

(
launcher,
Task::batch([
check_for_updates_command,
Task::perform(get_entries(InstanceKind::Client), Message::CoreListLoaded),
Task::perform(get_entries(InstanceKind::Server), Message::CoreListLoaded),
load_notes_command,
presence_task,
Task::perform(ql_core::clean::dir("logs"), |n| {
Message::CoreCleanComplete(n.strerr())
}),
Expand Down
6 changes: 3 additions & 3 deletions quantum_launcher/src/menu_renderer/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use crate::menu_renderer::{
view_info_message,
};
use crate::state::{
GameLogMessage, InstanceNotes, LaunchModal, MainMenuMessage, NotesMessage, ShortcutMessage,
SidebarMessage, SidebarScroll, WindowMessage,
GameLogMessage, InstanceNotes, LaunchModal, LauncherSettingsTab, MainMenuMessage, NotesMessage,
ShortcutMessage, SidebarMessage, SidebarScroll, WindowMessage,
};
use crate::{
icons,
Expand Down Expand Up @@ -561,7 +561,7 @@ impl MenuLaunch {
)
.padding(0)
.style(|n, status| n.style_button(status, StyleButton::FlatExtraDark))
.on_press(LauncherSettingsMessage::Open.into());
.on_press(LauncherSettingsMessage::Open(LauncherSettingsTab::default()).into());

widget::mouse_area(
widget::container(
Expand Down
Loading