diff --git a/packages/oneclient_app/src/components/active_cluster_panel.rs b/packages/oneclient_app/src/components/active_cluster_panel.rs index ba8c702e..8271a98e 100644 --- a/packages/oneclient_app/src/components/active_cluster_panel.rs +++ b/packages/oneclient_app/src/components/active_cluster_panel.rs @@ -4,6 +4,7 @@ use freya::router::RouterContext; use crate::components::{Button, Icon, IconType}; use oneclient_common::parse_mc_version; +use oneclient_core::clusters::ClusterKind; use crate::hooks::{ settled_or_loading, use_active_cluster_id, use_clusters, use_dispatch, use_game_snapshot, @@ -75,14 +76,19 @@ impl Component for ActiveClusterPanel { }; let version = format!("{} {}", cluster.mc_version, cluster.mc_loader); - let (title, subtitle) = if cluster.user_created { + let (title, subtitle) = if cluster.user_created && cluster.kind != ClusterKind::OneClient { (cluster.name.clone(), version) } else { let subtitle = match metadata { Some(m) => format!("OneClient ยท {}", m.name), None => "OneClient".to_string(), }; - (version, subtitle) + let title = if cluster.user_created { + cluster.name.clone() + } else { + version + }; + (title, subtitle) }; let cluster_id = cluster.id; let syncing = launch_syncing(&launcher, cluster.uses_bundles()); diff --git a/packages/oneclient_app/src/utils.rs b/packages/oneclient_app/src/utils.rs index cff1eb3c..894e8422 100644 --- a/packages/oneclient_app/src/utils.rs +++ b/packages/oneclient_app/src/utils.rs @@ -88,11 +88,11 @@ pub enum GridSelection { } pub fn split_clusters(clusters: &[Cluster]) -> (ClusterGroups, Vec) { - let (instances, provisioned): (Vec<&Cluster>, Vec<&Cluster>) = - clusters.iter().partition(|cluster| cluster.user_created); + let (instances, oneclient): (Vec<&Cluster>, Vec<&Cluster>) = + clusters.iter().partition(|cluster| cluster.is_isolated()); ( - group_clusters_by_release(provisioned), + group_clusters_by_release(oneclient), sort_clusters_for_home(instances.into_iter().cloned().collect()), ) } @@ -407,6 +407,26 @@ mod tests { } } + #[test] + fn user_created_oneclient_clusters_join_their_release_line() { + let provisioned = versioned(1, "26.1"); + let mine = Cluster { + user_created: true, + ..versioned(2, "26.1") + }; + let vanilla = Cluster { + user_created: true, + kind: oneclient_db::models::ClusterKind::Vanilla, + ..versioned(3, "26.1") + }; + + let (groups, instances) = split_clusters(&[provisioned, mine, vanilla]); + let line = ReleaseLine::from_version("26.1").unwrap(); + let grouped: Vec = groups[&line].iter().map(|c| c.id).collect(); + assert_eq!(grouped, vec![1, 2]); + assert_eq!(instances.iter().map(|c| c.id).collect::>(), vec![3]); + } + #[test] fn a_newly_created_instance_comes_first_on_home() { let now = chrono::Utc::now(); diff --git a/packages/oneclient_app/src/view/app/clusters/instance/data.rs b/packages/oneclient_app/src/view/app/clusters/instance/data.rs index de74ce63..7dd34168 100644 --- a/packages/oneclient_app/src/view/app/clusters/instance/data.rs +++ b/packages/oneclient_app/src/view/app/clusters/instance/data.rs @@ -271,7 +271,6 @@ fn kind_for(choice: TypeChoice, loader: Option) -> ClusterKind { fn suggested_name( version: Option<&String>, - choice: TypeChoice, kind: ClusterKind, loader: Option, ) -> String { @@ -279,11 +278,10 @@ fn suggested_name( return String::new(); }; - let full = match (choice, kind, loader) { - (TypeChoice::OneClient, _, _) => version.clone(), - (_, ClusterKind::Vanilla, _) => format!("{version} Vanilla"), - (_, _, Some(loader)) => format!("{version} {loader}"), - (_, _, None) => version.clone(), + let full = match (kind, loader) { + (ClusterKind::Vanilla, _) => format!("{version} Vanilla"), + (_, Some(loader)) => format!("{version} {loader}"), + (_, None) => version.clone(), }; if validate_instance_name(&full).is_ok() { return full; @@ -359,7 +357,7 @@ pub fn resolve(w: Wizard) -> Picks { let bundles = use_bundle_context(version.as_ref(), loader, oneclient, step == Step::Bundles); let kind = kind_for(choice, loader); - let suggested = suggested_name(version.as_ref(), choice, kind, loader); + let suggested = suggested_name(version.as_ref(), kind, loader); let declined = w.declined.read().clone().unwrap_or_else(|| { bundles .archives diff --git a/packages/oneclient_app/src/view/app/clusters/page.rs b/packages/oneclient_app/src/view/app/clusters/page.rs index bdca731f..75db20bf 100644 --- a/packages/oneclient_app/src/view/app/clusters/page.rs +++ b/packages/oneclient_app/src/view/app/clusters/page.rs @@ -92,8 +92,7 @@ impl Component for Clusters { let active_id = use_active_cluster_id(); let show_create = use_state(|| false); let mut selected = use_state(|| None::); - let mut selected_version = use_state(|| None::); - let mut selected_loader = use_state(|| None::); + let mut selected_cluster = use_state(|| None::); let mut filter = use_state(|| Filter::All); let query = use_state(String::new); let loaders = use_state(Vec::::new); @@ -145,7 +144,7 @@ impl Component for Clusters { if selected.read().is_none() { *selected.write() = match active_cluster.as_ref() { - Some(cluster) if cluster.user_created => Some(GridSelection::Instance(cluster.id)), + Some(cluster) if cluster.is_isolated() => Some(GridSelection::Instance(cluster.id)), other => default_line(&groups, other.cloned()) .map(GridSelection::Line) .or_else(fallback), @@ -172,25 +171,15 @@ impl Component for Clusters { .and_then(|line| groups.get(&line).cloned()) .unwrap_or_default(); - if line.is_some() && selected_version.read().is_none() { - let preferred = active_cluster - .as_ref() - .and_then(|c| parse_mc_version(&c.mc_version)) - .and_then(|p| p.key()); - *selected_version.write() = default_version_key(&clusters_for_line, preferred); + if line.is_some() && selected_cluster.read().is_none() { + *selected_cluster.write() = + default_line_cluster(&clusters_for_line, active_cluster.as_ref()); } - if line.is_some() && selected_loader.read().is_none() { - let preferred = active_cluster.as_ref().map(|c| c.mc_loader); - *selected_loader.write() = default_loader(&clusters_for_line, preferred); - } - - let cluster = resolve_cluster( - &clusters_for_line, - *selected_version.read(), - *selected_loader.read(), - ) - .or_else(|| clusters_for_line.first().cloned()); + let cluster = selected_cluster + .read() + .and_then(|id| clusters_for_line.iter().find(|c| c.id == id).cloned()) + .or_else(|| clusters_for_line.first().cloned()); let instance = match current { Some(GridSelection::Instance(id)) => instances.iter().find(|c| c.id == id).cloned(), @@ -268,8 +257,7 @@ impl Component for Clusters { }; VersionCard::new(line, list, caption, is_selected, move |_| { selected.set(Some(item)); - selected_version.set(None); - selected_loader.set(None); + selected_cluster.set(None); }) .into_element() }) @@ -293,14 +281,10 @@ impl Component for Clusters { major: line.major, key: parsed.and_then(|p| p.key()), loader: cluster.mc_loader, + user_created: cluster.user_created, base: Sidebar { - picker: line_picker( - line, - &cluster, - &clusters_for_line, - selected_version, - selected_loader, - ), + picker: line_picker(line, &cluster, &clusters_for_line, selected_cluster), + description: cluster.description.clone(), ..Sidebar::base(&cluster, sidebar_w) }, } @@ -431,6 +415,29 @@ fn cluster_caption(cluster: &Cluster) -> String { format!("{} \u{b7} {}", cluster.mc_version, cluster.mc_loader) } +fn picker_caption(cluster: &Cluster) -> String { + if cluster.user_created { + format!("{} \u{b7} {}", cluster.name, cluster_caption(cluster)) + } else { + cluster_caption(cluster) + } +} + +fn default_line_cluster(clusters: &[Cluster], active: Option<&Cluster>) -> Option { + if let Some(active) = active.filter(|a| clusters.iter().any(|c| c.id == a.id)) { + return Some(active.id); + } + let preferred_key = active + .and_then(|c| parse_mc_version(&c.mc_version)) + .and_then(|p| p.key()); + resolve_cluster( + clusters, + default_version_key(clusters, preferred_key), + default_loader(clusters, active.map(|c| c.mc_loader)), + ) + .map(|c| c.id) +} + fn bottom_border() -> Border { Border::new() .fill(colors::component_border()) @@ -554,25 +561,18 @@ fn line_picker( line: ReleaseLine, cluster: &Cluster, siblings: &[Cluster], - mut selected_version: State>, - mut selected_loader: State>, + mut selected_cluster: State>, ) -> Option { if siblings.len() <= 1 { return None; } - let options: Vec = siblings.iter().map(cluster_caption).collect(); + let options: Vec = siblings.iter().map(picker_caption).collect(); let current = siblings .iter() .position(|c| c.id == cluster.id) .unwrap_or(0); - let picks: Vec<(Option, GameLoader)> = siblings - .iter() - .map(|c| { - let key = parse_mc_version(&c.mc_version).and_then(|p| p.key()); - (key, c.mc_loader) - }) - .collect(); + let ids: Vec = siblings.iter().map(|c| c.id).collect(); Some( rect() @@ -596,9 +596,8 @@ fn line_picker( .width(Size::fill()) .height(Size::px(40.)) .on_select(move |idx: usize| { - if let Some((key, loader)) = picks.get(idx).copied() { - selected_version.set(key); - selected_loader.set(Some(loader)); + if let Some(id) = ids.get(idx).copied() { + selected_cluster.set(Some(id)); } }), ) @@ -663,6 +662,7 @@ struct LineSidebar { major: u32, key: Option, loader: GameLoader, + user_created: bool, base: Sidebar, } @@ -672,8 +672,10 @@ impl Component for LineSidebar { let mut sidebar = self.base.clone(); if let Some(metadata) = metadata { - sidebar.title = metadata.name; - sidebar.description = metadata.long_description; + if !self.user_created { + sidebar.title = metadata.name; + } + sidebar.description = sidebar.description.or(metadata.long_description); } sidebar }