* feat: added microsoft sdk provider * feat: changed the default provider to microsoft everywhere * feat: added checking for microsoft jdks and prompting user to install them (ui for discussion) * feat: added toast popup when user tries to remove runtime that is pinned to some cluster * feat: added 'migrating' user to the microsoft jdks * feat: changed reading mods from cluster folders on launch to having cluster folders symlinks in the shared .minecraft folder where mods stay per given cluster; changed resource packs and shader packs from working per cluster to global, every resource pack and shader pack is now being shared between clusters; added mods disabling whenever a mod is manually removed from the mods folder * fix/feat: fixed hardlinks counting as a duplicate of files it was pointing to (windows); added a progress bar to the disk storage view in settings * chore: connected microsoft jdk branch and package folder management one --------- Co-authored-by: LynithDev <61880709+LynithDev@users.noreply.github.com>
189 lines
8.1 KiB
Rust
189 lines
8.1 KiB
Rust
use std::time::Duration;
|
|
|
|
use freya::prelude::*;
|
|
use oneclient_events::Answer;
|
|
|
|
use crate::components::{Button, Icon, IconType, OverlayPopup};
|
|
use crate::hooks::{use_dispatch, use_notifications_snapshot};
|
|
use crate::microsoft_java::{MICROSOFT_JAVA_CHOICE_INSTALL, MICROSOFT_JAVA_CHOICE_NEVER};
|
|
use crate::theme::colors;
|
|
use crate::ui::border_all_color;
|
|
|
|
const CARD_BG: Color = Color::from_rgb(26, 34, 41);
|
|
|
|
const HOLD_SECONDS: u8 = 3;
|
|
|
|
#[derive(PartialEq)]
|
|
pub struct MicrosoftJavaPromptOverlay;
|
|
|
|
impl Component for MicrosoftJavaPromptOverlay {
|
|
fn render(&self) -> impl IntoElement {
|
|
let snapshot = use_notifications_snapshot();
|
|
let dispatch = use_dispatch();
|
|
let remaining = use_state(|| HOLD_SECONDS);
|
|
|
|
let showing = snapshot
|
|
.pending_prompt
|
|
.as_ref()
|
|
.is_some_and(|prompt| prompt.has_choice(MICROSOFT_JAVA_CHOICE_INSTALL));
|
|
|
|
use_side_effect_with_deps(&showing, move |&showing| {
|
|
let mut remaining = remaining;
|
|
|
|
if !showing {
|
|
remaining.set(HOLD_SECONDS);
|
|
return;
|
|
}
|
|
|
|
spawn(async move {
|
|
let mut remaining = remaining;
|
|
for step in (0..HOLD_SECONDS).rev() {
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
|
// Re-armed while this was sleeping so a newer prompt owns the
|
|
// hold now and this countdown is stale
|
|
if { *remaining.peek() } != step + 1 {
|
|
return;
|
|
}
|
|
|
|
remaining.set(step);
|
|
}
|
|
});
|
|
});
|
|
|
|
let Some(prompt) = snapshot.pending_prompt.clone() else {
|
|
return rect().into_element();
|
|
};
|
|
|
|
if !prompt.has_choice(MICROSOFT_JAVA_CHOICE_INSTALL) {
|
|
return rect().into_element();
|
|
}
|
|
|
|
let held = *remaining.read();
|
|
let locked = held > 0;
|
|
|
|
let dismiss_label = prompt
|
|
.dismiss
|
|
.clone()
|
|
.unwrap_or_else(|| "Cancel".to_string());
|
|
let never_label = prompt
|
|
.choice(MICROSOFT_JAVA_CHOICE_NEVER)
|
|
.map(|choice| choice.label.clone())
|
|
.unwrap_or_else(|| "Don't ask again".to_string());
|
|
let install_label = prompt
|
|
.choice(MICROSOFT_JAVA_CHOICE_INSTALL)
|
|
.map(|choice| choice.label.clone())
|
|
.unwrap_or_else(|| "Proceed".to_string());
|
|
|
|
let close = dispatch.clone();
|
|
let cancel = dispatch.clone();
|
|
let never = dispatch.clone();
|
|
let accept = dispatch.clone();
|
|
|
|
OverlayPopup::new()
|
|
// Closing from the backdrop is a dismissal too so it waits as well
|
|
.on_close(move |_| {
|
|
if !locked {
|
|
close.dismiss_prompt();
|
|
}
|
|
})
|
|
.child(
|
|
rect()
|
|
.width(Size::window_percent(100.))
|
|
.height(Size::window_percent(100.))
|
|
.center()
|
|
.child(
|
|
rect()
|
|
.vertical()
|
|
.width(Size::px(440.))
|
|
.max_width(Size::window_percent(90.))
|
|
.spacing(14.)
|
|
.padding(Gaps::new_all(20.))
|
|
.corner_radius(CornerRadius::new_all(14.))
|
|
.background(CARD_BG)
|
|
.border(border_all_color(1., colors::component_border()))
|
|
.child(
|
|
rect()
|
|
.horizontal()
|
|
.cross_align(Alignment::Center)
|
|
.spacing(10.)
|
|
.child(
|
|
Icon::new(IconType::DownloadCloud02)
|
|
.size(20.)
|
|
.color(colors::brand()),
|
|
)
|
|
.child(
|
|
label()
|
|
.text(prompt.title.clone())
|
|
.font_size(16.)
|
|
.font_weight(FontWeight::SEMI_BOLD)
|
|
.color(colors::fg_primary()),
|
|
),
|
|
)
|
|
.child(
|
|
label()
|
|
.text(prompt.question.clone())
|
|
.font_size(12.)
|
|
.max_lines(6)
|
|
.width(Size::fill())
|
|
.color(colors::fg_secondary()),
|
|
)
|
|
.child(
|
|
rect()
|
|
.horizontal()
|
|
.width(Size::fill())
|
|
.cross_align(Alignment::Center)
|
|
.main_align(Alignment::SpaceBetween)
|
|
.child(
|
|
label()
|
|
.text(if locked {
|
|
held.to_string()
|
|
} else {
|
|
String::new()
|
|
})
|
|
.font_size(12.)
|
|
.color(colors::fg_secondary()),
|
|
)
|
|
.child(
|
|
rect()
|
|
.horizontal()
|
|
.spacing(8.)
|
|
.child(
|
|
Button::new()
|
|
.secondary()
|
|
.disabled(locked)
|
|
.on_press(move |_| cancel.dismiss_prompt())
|
|
.text(dismiss_label),
|
|
)
|
|
.child(
|
|
Button::new()
|
|
.secondary()
|
|
.disabled(locked)
|
|
.on_press(move |_| {
|
|
never.answer_prompt(Answer::new(
|
|
MICROSOFT_JAVA_CHOICE_NEVER,
|
|
))
|
|
})
|
|
.text(never_label),
|
|
)
|
|
.child(
|
|
Button::new()
|
|
.primary()
|
|
.on_press(move |_| {
|
|
accept.answer_prompt(Answer::new(
|
|
MICROSOFT_JAVA_CHOICE_INSTALL,
|
|
))
|
|
})
|
|
.child(
|
|
Icon::new(IconType::DownloadCloud02)
|
|
.size(14.),
|
|
)
|
|
.text(install_label),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
.into_element()
|
|
}
|
|
}
|