148 lines
4.7 KiB
Rust
148 lines
4.7 KiB
Rust
use freya::animation::*;
|
|
use freya::prelude::*;
|
|
use freya::router::RouterContext;
|
|
|
|
use crate::components::{Button, Icon, IconType};
|
|
use oneclient_common::parse_mc_version;
|
|
|
|
use crate::hooks::{settled_or_loading, use_active_cluster_id, use_clusters, use_dispatch, use_game_snapshot, use_launcher, use_version_metadata};
|
|
use crate::routes::Route;
|
|
use crate::theme::colors;
|
|
use crate::utils::sort_clusters_for_home;
|
|
use crate::view::app::launch_button_state;
|
|
|
|
#[derive(PartialEq)]
|
|
pub struct ActiveClusterPanel;
|
|
|
|
impl Component for ActiveClusterPanel {
|
|
fn render(&self) -> impl IntoElement {
|
|
let clusters_query = use_clusters();
|
|
let mut active_id = use_active_cluster_id();
|
|
let dispatch = use_dispatch();
|
|
let game = use_game_snapshot();
|
|
let launcher = use_launcher();
|
|
let syncing = launcher.fetching || launcher.syncing_bundles;
|
|
|
|
let clusters = settled_or_loading(&clusters_query).unwrap_or_default();
|
|
|
|
let sorted = sort_clusters_for_home(clusters);
|
|
|
|
if active_id.read().is_none()
|
|
&& let Some(first) = sorted.first()
|
|
{
|
|
*active_id.write() = Some(first.id);
|
|
}
|
|
|
|
let active = active_id
|
|
.read()
|
|
.and_then(|id| sorted.iter().find(|c| c.id == id).cloned())
|
|
.or_else(|| sorted.first().cloned());
|
|
|
|
let dep = active.as_ref().map(|c| c.id);
|
|
let intro = use_animation_with_dependencies(&dep, |conf, _| {
|
|
conf.on_creation(OnCreation::Run);
|
|
conf.on_change(OnChange::Rerun);
|
|
AnimNum::new(0., 1.)
|
|
.time(440)
|
|
.ease(Ease::Out)
|
|
.function(Function::Cubic)
|
|
});
|
|
let p = intro.get().value();
|
|
let slide_x = (p - 1.0) * 48.0;
|
|
|
|
let parsed = active
|
|
.as_ref()
|
|
.and_then(|c| parse_mc_version(&c.mc_version));
|
|
let metadata = use_version_metadata(
|
|
parsed.as_ref().map(|p| p.major),
|
|
parsed.and_then(|p| p.key()),
|
|
active.as_ref().map(|c| c.mc_loader),
|
|
);
|
|
|
|
let Some(cluster) = active else {
|
|
return rect()
|
|
.vertical()
|
|
.width(Size::fill())
|
|
.main_align(Alignment::Center)
|
|
.child(
|
|
label()
|
|
.text("No versions yet")
|
|
.font_size(24.)
|
|
.color(colors::fg_secondary()),
|
|
);
|
|
};
|
|
|
|
let title = format!("{} {}", cluster.mc_version, cluster.mc_loader);
|
|
let subtitle = metadata
|
|
.map(|m| m.name)
|
|
.unwrap_or_else(|| cluster.name.clone());
|
|
let cluster_id = cluster.id;
|
|
|
|
rect()
|
|
.vertical()
|
|
.width(Size::fill())
|
|
.main_align(Alignment::Center)
|
|
.cross_align(Alignment::Start)
|
|
.offset_x(slide_x)
|
|
.opacity(p)
|
|
.child(
|
|
label()
|
|
.text(title)
|
|
.font_size(56.)
|
|
.line_height(1.1)
|
|
.font_weight(FontWeight::BOLD)
|
|
.color(colors::fg_primary()),
|
|
)
|
|
.child(
|
|
label()
|
|
.text(subtitle)
|
|
.font_size(16.)
|
|
.font_weight(FontWeight::SEMI_BOLD)
|
|
.color(colors::fg_secondary()),
|
|
)
|
|
.child(
|
|
rect()
|
|
.horizontal()
|
|
.spacing(8.)
|
|
.cross_align(Alignment::Center)
|
|
.margin(Gaps::new(8., 0., 0., 0.))
|
|
.child(launch_button(
|
|
cluster_id,
|
|
dispatch,
|
|
launch_button_state(&game, cluster_id, syncing),
|
|
))
|
|
.child(cluster_settings_button(cluster_id)),
|
|
)
|
|
}
|
|
}
|
|
|
|
fn launch_button(
|
|
cluster_id: i64,
|
|
dispatch: crate::Actions,
|
|
state: (&'static str, bool),
|
|
) -> impl IntoElement {
|
|
let (label, enabled) = state;
|
|
Button::new()
|
|
.primary()
|
|
.medium()
|
|
.font_size(16.)
|
|
.font_weight(FontWeight::from(450))
|
|
.enabled(enabled)
|
|
.padding(Gaps::new_symmetric(8., 24.))
|
|
.on_press(move |_| {
|
|
if enabled {
|
|
dispatch.launch_cluster(cluster_id);
|
|
}
|
|
})
|
|
.text(label)
|
|
}
|
|
|
|
fn cluster_settings_button(cluster_id: i64) -> impl IntoElement {
|
|
Button::new()
|
|
.ghost()
|
|
.icon()
|
|
.on_press(move |_| {
|
|
let _ = RouterContext::get().push(Route::ClusterOverview { cluster_id });
|
|
})
|
|
.child(Icon::new(IconType::Settings04).size(20.))
|
|
}
|