feat(ui): Hide changelog indicator in the settings sidebar if changelog was read
This commit is contained in:
parent
7f8b62eb15
commit
a4753fb06b
9 changed files with 78 additions and 6 deletions
|
|
@ -17,6 +17,9 @@ pub enum BridgeCommand {
|
|||
RecordSeenVersion {
|
||||
version: String,
|
||||
},
|
||||
SetSeenChangelogVersion {
|
||||
version: String,
|
||||
},
|
||||
SetOnboardingSeen {
|
||||
seen: bool,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -315,6 +315,23 @@ impl CoreBridgeRuntime {
|
|||
}
|
||||
})?;
|
||||
}
|
||||
BridgeCommand::SetSeenChangelogVersion { version } => {
|
||||
let mut changed = false;
|
||||
mutate_settings(snapshots, |settings| {
|
||||
if settings.seen_changelog_version.as_deref() != Some(version.as_str()) {
|
||||
settings.seen_changelog_version = Some(version);
|
||||
changed = true;
|
||||
}
|
||||
})?;
|
||||
|
||||
if changed {
|
||||
let state = LauncherState::get()?;
|
||||
let snapshot = state.settings.read().clone();
|
||||
if let Err(err) = save_settings(&snapshot).await {
|
||||
snapshots.settings.error = Some(err.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
BridgeCommand::SetOnboardingSeen { seen } => {
|
||||
mutate_settings(snapshots, |settings| {
|
||||
settings.seen_onboarding = seen;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ impl BridgeDispatch {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn set_seen_changelog_version(&self, version: impl Into<String>) {
|
||||
self.send(BridgeCommand::SetSeenChangelogVersion {
|
||||
version: version.into(),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_onboarding_seen(&self, seen: bool) {
|
||||
self.send(BridgeCommand::SetOnboardingSeen { seen });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ pub use queries::{
|
|||
category_list, changelog_error, changelog_groups, changelog_is_loading, cluster_content_items,
|
||||
content_type_for_slug, has_migration_data, invalidate_cluster_queries, invalidate_java_queries,
|
||||
invalidate_logs_queries, invalidate_profile_queries, invalidate_screenshots_queries,
|
||||
java_runtimes, loader_versions, login_code_already_handled, migration_detections,
|
||||
java_runtimes, latest_changelog_version, loader_versions, login_code_already_handled,
|
||||
migration_detections,
|
||||
mutation_error, mutation_is_pending, onboarding_bundles_items, package_meta_batch,
|
||||
pick_version_metadata, project_detail, provider_versions, reset_login_code_dedup, search_items,
|
||||
search_pending, search_total, terms_document, terms_error, terms_is_loading, try_account,
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ pub fn changelog_groups(query: &UseQuery<ChangelogQuery>) -> Option<Vec<Changelo
|
|||
}
|
||||
}
|
||||
|
||||
pub fn latest_changelog_version(query: &UseQuery<ChangelogQuery>) -> Option<String> {
|
||||
changelog_groups(query).and_then(|groups| groups.first().map(|group| group.version.clone()))
|
||||
}
|
||||
|
||||
pub fn changelog_error(query: &UseQuery<ChangelogQuery>) -> Option<String> {
|
||||
match &*query.read().state() {
|
||||
QueryStateData::Settled { res: Err(err), .. } => Some(err.to_string()),
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ pub use bundles::{
|
|||
onboarding_bundles_items, use_bundle_overrides, use_bundle_updates, use_bundles_with_status,
|
||||
use_onboarding_bundles,
|
||||
};
|
||||
pub use changelog::{changelog_error, changelog_groups, changelog_is_loading, use_changelog};
|
||||
pub use changelog::{
|
||||
changelog_error, changelog_groups, changelog_is_loading, latest_changelog_version, use_changelog,
|
||||
};
|
||||
pub use cluster_content::{cluster_content_items, use_cluster_content};
|
||||
pub use clusters::use_clusters;
|
||||
pub use image::{CachedImageQuery, use_cached_image};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use sysinfo::RefreshKind;
|
|||
use sysinfo::System;
|
||||
|
||||
use crate::components::{Icon, IconType, ScrollArea, ScrollAreaCtx, TextInput};
|
||||
use crate::hooks::{latest_changelog_version, use_changelog, use_settings_snapshot};
|
||||
use crate::routes::Route;
|
||||
use crate::theme::colors;
|
||||
use crate::use_dispatch;
|
||||
|
|
@ -360,6 +361,8 @@ impl Component for SettingsShell {
|
|||
let route = use_route::<Route>();
|
||||
let active = route_tab(&route);
|
||||
|
||||
let changelog_unread = has_unread_changelog();
|
||||
|
||||
let search = use_state(String::new);
|
||||
let query = search.read().trim().to_string();
|
||||
let scroll = use_scroll_controller(ScrollConfig::default);
|
||||
|
|
@ -400,7 +403,7 @@ impl Component for SettingsShell {
|
|||
.overflow(Overflow::Clip)
|
||||
.padding(Gaps::new(0., 40., 40., 32.))
|
||||
.spacing(40.)
|
||||
.child(sidebar(active))
|
||||
.child(sidebar(active, changelog_unread))
|
||||
.child(
|
||||
rect()
|
||||
.vertical()
|
||||
|
|
@ -574,7 +577,20 @@ fn search_results(query: String, mut search: State<String>) -> Vec<Element> {
|
|||
out
|
||||
}
|
||||
|
||||
fn sidebar(active: SettingsTab) -> impl IntoElement {
|
||||
/// True when the newest changelog entry is newer than the one the user last read.
|
||||
/// While the changelog is still loading or failed to load we show no dot rather
|
||||
/// than guessing.
|
||||
fn has_unread_changelog() -> bool {
|
||||
let settings = use_settings_snapshot().settings;
|
||||
let query = use_changelog();
|
||||
|
||||
match latest_changelog_version(&query) {
|
||||
Some(latest) => settings.seen_changelog_version.as_deref() != Some(latest.as_str()),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn sidebar(active: SettingsTab, changelog_unread: bool) -> impl IntoElement {
|
||||
rect()
|
||||
.vertical()
|
||||
.width(Size::px(SIDEBAR_WIDTH_PX))
|
||||
|
|
@ -606,6 +622,7 @@ fn sidebar(active: SettingsTab) -> impl IntoElement {
|
|||
SidebarItem {
|
||||
tab: *tab,
|
||||
active: *tab == active,
|
||||
has_dot: matches!(tab, SettingsTab::Changelog) && changelog_unread,
|
||||
}
|
||||
.into_element()
|
||||
}))
|
||||
|
|
@ -713,6 +730,7 @@ impl Component for SidebarInfo {
|
|||
struct SidebarItem {
|
||||
tab: SettingsTab,
|
||||
active: bool,
|
||||
has_dot: bool,
|
||||
}
|
||||
|
||||
impl Component for SidebarItem {
|
||||
|
|
@ -734,7 +752,7 @@ impl Component for SidebarItem {
|
|||
Color::TRANSPARENT
|
||||
};
|
||||
|
||||
let has_dot = matches!(tab, SettingsTab::Changelog);
|
||||
let has_dot = self.has_dot;
|
||||
|
||||
let mut el = rect()
|
||||
.horizontal()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@ use freya::prelude::*;
|
|||
|
||||
use super::settings_page;
|
||||
use crate::components::{Icon, IconType};
|
||||
use crate::hooks::{changelog_error, changelog_groups, changelog_is_loading, use_changelog};
|
||||
use crate::hooks::{
|
||||
changelog_error, changelog_groups, changelog_is_loading, latest_changelog_version,
|
||||
use_changelog, use_dispatch, use_settings_snapshot,
|
||||
};
|
||||
use crate::theme::colors;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
|
@ -11,8 +14,24 @@ pub struct SettingsChangelog;
|
|||
impl Component for SettingsChangelog {
|
||||
fn render(&self) -> impl IntoElement {
|
||||
let query = use_changelog();
|
||||
let dispatch = use_dispatch();
|
||||
let settings = use_settings_snapshot().settings;
|
||||
let mut marked = use_state(|| None::<String>);
|
||||
let installed_version = env!("CARGO_PKG_VERSION").to_string();
|
||||
|
||||
// Opening this page counts as reading the changelog, so clear the sidebar
|
||||
// dot once the newest entry is known. `marked` keeps us from re-sending the
|
||||
// command while the settings snapshot catches up.
|
||||
if let Some(latest) = latest_changelog_version(&query) {
|
||||
let already_marked = marked.peek().as_deref() == Some(latest.as_str());
|
||||
let already_seen = settings.seen_changelog_version.as_deref() == Some(latest.as_str());
|
||||
|
||||
if !already_marked && !already_seen {
|
||||
marked.set(Some(latest.clone()));
|
||||
dispatch.set_seen_changelog_version(latest);
|
||||
}
|
||||
}
|
||||
|
||||
if changelog_is_loading(&query) {
|
||||
return settings_page()
|
||||
.child(
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ pub struct LauncherSettings {
|
|||
pub accepted_tos_version: u32,
|
||||
pub accepted_privacy_version: u32,
|
||||
pub seen_versions: Vec<String>,
|
||||
pub seen_changelog_version: Option<String>,
|
||||
pub modrinth_api_key: Option<String>,
|
||||
pub curseforge_api_key: Option<String>,
|
||||
pub custom_api_endpoint: Option<String>,
|
||||
|
|
@ -72,6 +73,7 @@ impl Default for LauncherSettings {
|
|||
accepted_tos_version: 0,
|
||||
accepted_privacy_version: 0,
|
||||
seen_versions: Vec::new(),
|
||||
seen_changelog_version: None,
|
||||
modrinth_api_key: None,
|
||||
curseforge_api_key: None,
|
||||
custom_api_endpoint: None,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue