feat(date-time): select timezones from searchable context drawer

This commit is contained in:
Michael Aaron Murphy 2024-08-06 12:34:59 +02:00 committed by Michael Murphy
parent 648c4e24ab
commit fa0ce598e5
5 changed files with 125 additions and 45 deletions

34
Cargo.lock generated
View file

@ -1369,7 +1369,7 @@ dependencies = [
[[package]]
name = "cosmic-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"atomicwrites",
"calloop 0.14.0",
@ -1392,7 +1392,7 @@ dependencies = [
[[package]]
name = "cosmic-config-derive"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"quote",
"syn 1.0.109",
@ -1602,7 +1602,7 @@ dependencies = [
[[package]]
name = "cosmic-theme"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"almost",
"cosmic-config",
@ -2888,7 +2888,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"dnd",
"iced_accessibility",
@ -2907,7 +2907,7 @@ dependencies = [
[[package]]
name = "iced_accessibility"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"accesskit",
"accesskit_unix",
@ -2916,7 +2916,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"bitflags 2.6.0",
"dnd",
@ -2938,7 +2938,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"futures",
"iced_core",
@ -2951,7 +2951,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
@ -2975,7 +2975,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@ -2987,7 +2987,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"dnd",
"iced_accessibility",
@ -3001,7 +3001,7 @@ dependencies = [
[[package]]
name = "iced_sctk"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"enum-repr",
"float-cmp",
@ -3027,7 +3027,7 @@ dependencies = [
[[package]]
name = "iced_style"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"iced_core",
"once_cell",
@ -3037,7 +3037,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"bytemuck",
"cosmic-text",
@ -3054,7 +3054,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"as-raw-xcb-connection",
"bitflags 2.6.0",
@ -3083,7 +3083,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"dnd",
"iced_renderer",
@ -3100,7 +3100,7 @@ dependencies = [
[[package]]
name = "iced_winit"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"dnd",
"iced_graphics",
@ -3907,7 +3907,7 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libcosmic"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#756f4b6ba69d11075eb0c34ea0fc837bd27ad63a"
source = "git+https://github.com/pop-os/libcosmic#4dd0f72f155b8705a30c2d42282f0bf1e5159e10"
dependencies = [
"apply",
"ashpd 0.9.1",

View file

@ -308,7 +308,9 @@ impl cosmic::Application for SettingsApp {
}
crate::pages::Message::DateAndTime(message) => {
page::update!(self.pages, message, time::date::Page);
if let Some(page) = self.pages.page_mut::<time::date::Page>() {
return page.update(message).map(Into::into);
}
}
crate::pages::Message::Desktop(message) => {

View file

@ -611,11 +611,11 @@ fn special_character_entry() -> Section<crate::pages::Message> {
let descriptions = &section.descriptions;
settings::view_section(&section.title)
.add(go_next_item(
.add(crate::widget::go_next_item(
&*descriptions[alternate],
Message::OpenSpecialCharacterContext(SpecialKey::AlternateCharacters),
))
.add(go_next_item(
.add(crate::widget::go_next_item(
&*descriptions[compose],
Message::OpenSpecialCharacterContext(SpecialKey::Compose),
))
@ -641,7 +641,7 @@ fn keyboard_shortcuts() -> Section<crate::pages::Message> {
.iter()
.find(|(_, v)| v.id == "keyboard-shortcuts")
{
section = section.add(go_next_item(
section = section.add(crate::widget::go_next_item(
&descriptions[shortcuts_desc],
crate::pages::Message::Page(shortcuts_entity),
));
@ -712,21 +712,3 @@ fn keyboard_typing_assist() -> Section<crate::pages::Message> {
.map(crate::pages::Message::Keyboard)
})
}
fn go_next_control<Msg: Clone + 'static>() -> cosmic::Element<'static, Msg> {
widget::row::with_children(vec![
widget::horizontal_space(Length::Fill).into(),
icon::from_name("go-next-symbolic").size(16).icon().into(),
])
.into()
}
fn go_next_item<Msg: Clone + 'static>(description: &str, msg: Msg) -> cosmic::Element<'_, Msg> {
settings::item(description, go_next_control())
.apply(widget::container)
.style(cosmic::theme::Container::List)
.apply(button)
.style(theme::Button::Transparent)
.on_press(msg)
.into()
}

View file

@ -6,8 +6,10 @@ use std::str::FromStr;
use chrono::{Datelike, Timelike};
use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet},
iced::Length,
iced_core::text::Wrap,
widget::{self, dropdown, settings},
Apply, Command,
Apply, Command, Element,
};
use cosmic_settings_page::Section;
use cosmic_settings_page::{self as page, section};
@ -16,6 +18,7 @@ use icu::{
datetime::DateTimeFormatter,
locid::Locale,
};
use itertools::Itertools;
use slab::Slab;
use slotmap::SlotMap;
pub use timedate_zbus::TimeDateProxy;
@ -38,9 +41,11 @@ pub struct Page {
military_time: bool,
ntp_enabled: bool,
show_date_in_top_panel: bool,
timezone_context: bool,
local_time: Option<DateTime<Iso>>,
timezone: Option<usize>,
timezone_list: Vec<String>,
timezone_search: String,
formatted_date: String,
}
@ -79,7 +84,9 @@ impl Default for Page {
ntp_enabled: false,
show_date_in_top_panel,
timezone: None,
timezone_context: false,
timezone_list: Vec::new(),
timezone_search: String::new(),
}
}
}
@ -136,6 +143,14 @@ impl page::Page<crate::pages::Message> for Page {
})
.map(crate::pages::Message::DateAndTime)
}
fn context_drawer(&self) -> Option<Element<'_, crate::pages::Message>> {
if self.timezone_context {
return Some(self.timezone_context_view());
}
None
}
}
impl Page {
@ -165,6 +180,14 @@ impl Page {
});
}
Message::TimezoneContext => {
self.timezone_search.clear();
self.timezone_context = true;
return cosmic::command::message(crate::app::Message::OpenContextDrawer(
fl!("time-zone").into(),
));
}
Message::MilitaryTime(enable) => {
self.military_time = enable;
self.update_local_time();
@ -193,6 +216,10 @@ impl Page {
}
}
Message::TimezoneSearch(text) => {
self.timezone_search = text;
}
Message::Timezone(timezone_id) => {
self.timezone = Some(timezone_id);
@ -242,7 +269,40 @@ impl Page {
Command::none()
}
pub fn update_local_time(&mut self) {
fn timezone_context_view(&self) -> Element<'_, crate::pages::Message> {
let search = widget::search_input(fl!("type-to-search"), &self.timezone_search)
.on_input(Message::TimezoneSearch)
.on_clear(Message::TimezoneSearch(String::new()));
let mut list = widget::list_column();
let search_input = &self.timezone_search.trim().to_lowercase();
for (id, timezone) in self.timezone_list.iter().enumerate() {
if search_input.is_empty() || timezone.to_lowercase().contains(search_input) {
list = list.add(self.timezone_context_item(id, timezone));
}
}
widget::column()
.spacing(32)
.push(search)
.push(widget::container(list).apply(widget::container))
.apply(Element::from)
.map(crate::pages::Message::DateAndTime)
}
fn timezone_context_item<'a>(&self, id: usize, timezone: &'a str) -> Element<'a, Message> {
widget::button(widget::settings::item_row(vec![
widget::text::body(timezone).wrap(Wrap::Word).into(),
widget::horizontal_space(Length::Fill).into(),
]))
.on_press(Message::Timezone(id))
.style(cosmic::theme::Button::Icon)
.into()
}
fn update_local_time(&mut self) {
self.local_time = Some(update_local_time());
self.formatted_date = match self.local_time {
@ -262,6 +322,8 @@ pub enum Message {
Refresh(Info),
ShowDate(bool),
Timezone(usize),
TimezoneContext,
TimezoneSearch(String),
UpdateTime,
}
@ -347,12 +409,30 @@ fn timezone() -> Section<crate::pages::Message> {
.title(fl!("time-zone"))
.descriptions(descriptions)
.view::<Page>(move |_binder, page, section| {
let timezone_context_button = settings::item_row(vec![
widget::text(
page.timezone
.map(|id| &*page.timezone_list[id])
.unwrap_or_default(),
)
.wrap(Wrap::Word)
.into(),
widget::icon::from_name("go-next-symbolic")
.size(16)
.icon()
.into(),
])
.apply(widget::container)
.style(cosmic::theme::Container::List)
.apply(widget::button)
.style(cosmic::theme::Button::Transparent)
.on_press(Message::TimezoneContext);
settings::view_section(&section.title)
// Time zone select
.add(
settings::item::builder(&*section.descriptions[time_zone]).control(
widget::dropdown(&page.timezone_list, page.timezone, Message::Timezone),
),
settings::item::builder(&*section.descriptions[time_zone])
.control(timezone_context_button),
)
.apply(cosmic::Element::from)
.map(crate::pages::Message::DateAndTime)

View file

@ -2,8 +2,10 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::iced::Length;
use cosmic::iced_core::text::Wrap;
use cosmic::widget::{
button, column, container, divider, horizontal_space, icon, row, settings, text, vertical_space,
self, button, column, container, divider, horizontal_space, icon, row, settings, text,
vertical_space,
};
use cosmic::{theme, Apply, Element};
use cosmic_settings_page as page;
@ -120,3 +122,17 @@ pub fn sub_page_header<'a, Message: 'static + Clone>(
.width(Length::Shrink)
.into()
}
pub fn go_next_item<Msg: Clone + 'static>(description: &str, msg: Msg) -> cosmic::Element<'_, Msg> {
settings::item_row(vec![
text(description).wrap(Wrap::Word).into(),
horizontal_space(Length::Fill).into(),
icon::from_name("go-next-symbolic").size(16).icon().into(),
])
.apply(widget::container)
.style(cosmic::theme::Container::List)
.apply(button)
.style(theme::Button::Transparent)
.on_press(msg)
.into()
}