Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.lock

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

21 changes: 13 additions & 8 deletions packages/oneclient_app/src/components/generic_prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use oneclient_java::JAVA_CHOICE_DOWNLOAD;

use crate::components::{Button, OverlayPopup};
use crate::hooks::{use_dispatch, use_notifications_snapshot};
use crate::microsoft_java::MICROSOFT_JAVA_CHOICE_INSTALL;
use crate::notifications::PendingPromptView;
use crate::theme::colors;
use crate::ui::border_all_color;
Expand All @@ -15,7 +16,9 @@ use crate::updater::UPDATE_CHOICE_INSTALL;
const CARD_BG: Color = Color::from_rgb(26, 34, 41);

fn claimed_elsewhere(prompt: &PendingPromptView) -> bool {
prompt.has_choice(JAVA_CHOICE_DOWNLOAD) || prompt.has_choice(UPDATE_CHOICE_INSTALL)
prompt.has_choice(JAVA_CHOICE_DOWNLOAD)
|| prompt.has_choice(UPDATE_CHOICE_INSTALL)
|| prompt.has_choice(MICROSOFT_JAVA_CHOICE_INSTALL)
}

#[derive(PartialEq)]
Expand Down Expand Up @@ -149,15 +152,17 @@ mod tests {
}

#[test]
fn the_two_rich_overlays_keep_their_own_prompts() {
assert!(claimed_elsewhere(&prompt(vec![Choice::primary(
fn the_rich_overlays_keep_their_own_prompts() {
for id in [
JAVA_CHOICE_DOWNLOAD,
"Download",
)])));
assert!(claimed_elsewhere(&prompt(vec![Choice::primary(
UPDATE_CHOICE_INSTALL,
"Download",
)])));
MICROSOFT_JAVA_CHOICE_INSTALL,
] {
assert!(
claimed_elsewhere(&prompt(vec![Choice::primary(id, "Download")])),
"{id} has its own overlay"
);
}
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::ui::border_all_color;

fn providers() -> Vec<(JavaVendor, &'static str)> {
vec![
(JavaVendor::Microsoft, "Microsoft Build of OpenJDK"),
(JavaVendor::Zulu, "Azul Zulu"),
(JavaVendor::Adoptium, "Eclipse Temurin"),
(JavaVendor::Corretto, "Amazon Corretto"),
Expand Down
189 changes: 189 additions & 0 deletions packages/oneclient_app/src/components/microsoft_java_prompt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
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()
}
}
2 changes: 2 additions & 0 deletions packages/oneclient_app/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod icons;
mod java_install_manager;
mod generic_prompt;
mod java_prompt;
mod microsoft_java_prompt;
mod link_confirm;
mod local_image;
mod log_viewer;
Expand Down Expand Up @@ -52,6 +53,7 @@ pub use icons::{Icon, IconType};
pub use java_install_manager::JavaInstallManager;
pub use generic_prompt::GenericPromptOverlay;
pub use java_prompt::JavaPromptOverlay;
pub use microsoft_java_prompt::MicrosoftJavaPromptOverlay;
pub use link_confirm::ConfirmLinkOverlay;
pub use local_image::LocalImage;
pub use log_viewer::LogViewer;
Expand Down
Loading