refactor: use icu for datetime
This commit is contained in:
parent
0600931abf
commit
37cff18672
7 changed files with 686 additions and 89 deletions
440
Cargo.lock
generated
440
Cargo.lock
generated
|
|
@ -327,6 +327,16 @@ dependencies = [
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-fn-stream"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e71711442f1016c768c259bec59300a10efe753bc3e686ec19e2c6a54a97c29b"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-fs"
|
name = "async-fs"
|
||||||
version = "2.1.2"
|
version = "2.1.2"
|
||||||
|
|
@ -722,6 +732,16 @@ version = "1.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "calendrical_calculations"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e97f73e95d668625c9b28a3072e6326773785a0cf807de9f3d632778438f3d38"
|
||||||
|
dependencies = [
|
||||||
|
"core_maths",
|
||||||
|
"displaydoc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "calloop"
|
name = "calloop"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
|
|
@ -820,6 +840,27 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono-tz"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"chrono-tz-build",
|
||||||
|
"phf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono-tz-build"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402"
|
||||||
|
dependencies = [
|
||||||
|
"parse-zoneinfo",
|
||||||
|
"phf_codegen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clang-sys"
|
name = "clang-sys"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
|
|
@ -1019,6 +1060,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core_maths"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30"
|
||||||
|
dependencies = [
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-bg-config"
|
name = "cosmic-bg-config"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -1118,7 +1168,10 @@ dependencies = [
|
||||||
name = "cosmic-greeter"
|
name = "cosmic-greeter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-fn-stream",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"chrono-tz",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
"cosmic-bg-config",
|
"cosmic-bg-config",
|
||||||
"cosmic-comp-config",
|
"cosmic-comp-config",
|
||||||
|
|
@ -1133,6 +1186,7 @@ dependencies = [
|
||||||
"greetd_ipc",
|
"greetd_ipc",
|
||||||
"i18n-embed",
|
"i18n-embed",
|
||||||
"i18n-embed-fl",
|
"i18n-embed-fl",
|
||||||
|
"icu",
|
||||||
"libcosmic",
|
"libcosmic",
|
||||||
"log",
|
"log",
|
||||||
"logind-zbus",
|
"logind-zbus",
|
||||||
|
|
@ -1142,6 +1196,7 @@ dependencies = [
|
||||||
"ron 0.10.1",
|
"ron 0.10.1",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"shlex",
|
"shlex",
|
||||||
|
"timedate-zbus",
|
||||||
"tokio",
|
"tokio",
|
||||||
"upower_dbus",
|
"upower_dbus",
|
||||||
"vergen",
|
"vergen",
|
||||||
|
|
@ -1699,7 +1754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1816,6 +1871,17 @@ dependencies = [
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fixed_decimal"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0febbeb1118a9ecdee6e4520ead6b54882e843dd0592ad233247dbee84c53db8"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"smallvec",
|
||||||
|
"writeable",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
|
@ -2726,6 +2792,100 @@ dependencies = [
|
||||||
"xkeysym",
|
"xkeysym",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dff5e3018d703f168b00dcefa540a65f1bbc50754ae32f3f5f0e43fe5ee51502"
|
||||||
|
dependencies = [
|
||||||
|
"icu_calendar",
|
||||||
|
"icu_casemap",
|
||||||
|
"icu_collator",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_datetime",
|
||||||
|
"icu_decimal",
|
||||||
|
"icu_experimental",
|
||||||
|
"icu_list",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_normalizer",
|
||||||
|
"icu_plurals",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"icu_segmenter",
|
||||||
|
"icu_timezone",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_calendar"
|
||||||
|
version = "1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7265b2137f9a36f7634a308d91f984574bbdba8cfd95ceffe1c345552275a8ff"
|
||||||
|
dependencies = [
|
||||||
|
"calendrical_calculations",
|
||||||
|
"displaydoc",
|
||||||
|
"icu_calendar_data",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_provider",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_calendar_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "820499e77e852162190608b4f444e7b4552619150eafc39a9e39333d9efae9e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_casemap"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ff0c8ae9f8d31b12e27fc385ff9ab1f3cd9b17417c665c49e4ec958c37da75f"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_casemap_data",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"writeable",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_casemap_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02bd9f6276270c85a5cd54611adbbf94e993ec464a2a86a452a6c565b7ded5d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_collator"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d370371887d31d56f361c3eaa15743e54f13bc677059c9191c77e099ed6966b2"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_collator_data",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_normalizer",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"smallvec",
|
||||||
|
"utf16_iter",
|
||||||
|
"utf8_iter",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_collator_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b353986d77d28991eca4dea5ef2b8982f639342ae19ca81edc44f048bc38ebb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
|
@ -2738,6 +2898,112 @@ dependencies = [
|
||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_datetime"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d115efb85e08df3fd77e77f52e7e087545a783fffba8be80bfa2102f306b1780"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"either",
|
||||||
|
"fixed_decimal",
|
||||||
|
"icu_calendar",
|
||||||
|
"icu_datetime_data",
|
||||||
|
"icu_decimal",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_plurals",
|
||||||
|
"icu_provider",
|
||||||
|
"icu_timezone",
|
||||||
|
"litemap",
|
||||||
|
"smallvec",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_datetime_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef5f04076123cab1b7a926a7083db27fe0d7a0e575adb984854aae3f3a6507d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_decimal"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb8fd98f86ec0448d85e1edf8884e4e318bb2e121bd733ec929a05c0a5e8b0eb"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"fixed_decimal",
|
||||||
|
"icu_decimal_data",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_provider",
|
||||||
|
"writeable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_decimal_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67c95dd97f5ccf6d837a9c115496ec7d36646fa86ca18e7f1412115b4c820ae2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_experimental"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "844ad7b682a165c758065d694bc4d74ac67f176da1c499a04d85d492c0f193b7"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"fixed_decimal",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_decimal",
|
||||||
|
"icu_experimental_data",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_normalizer",
|
||||||
|
"icu_pattern",
|
||||||
|
"icu_plurals",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"litemap",
|
||||||
|
"num-bigint",
|
||||||
|
"num-rational",
|
||||||
|
"num-traits",
|
||||||
|
"smallvec",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"zerofrom",
|
||||||
|
"zerotrie",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_experimental_data"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "121df92eafb8f5286d4e8ff401c1e7db8384377f806db3f8db77b91e5b7bd4dd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_list"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbfeda1d7775b6548edd4e8b7562304a559a91ed56ab56e18961a053f367c365"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_list_data",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_provider",
|
||||||
|
"regex-automata 0.2.0",
|
||||||
|
"writeable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_list_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52b1a7fbdbf3958f1be8354cb59ac73f165b7b7082d447ff2090355c9a069120"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_locid"
|
name = "icu_locid"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
|
@ -2795,6 +3061,39 @@ version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_pattern"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb7f36aafd098d6717de34e668a8120822275c1fba22b936e757b7de8a2fd7e4"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"either",
|
||||||
|
"writeable",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_plurals"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba5a70e7c025dbd5c501b0a5c188cd11666a424f0dadcd4f0a95b7dafde3b114"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"fixed_decimal",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_plurals_data",
|
||||||
|
"icu_provider",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_plurals_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a483403238cb7d6a876a77a5f8191780336d80fe7b8b00bfdeb20be6abbfd112"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_properties"
|
name = "icu_properties"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
|
@ -2844,6 +3143,49 @@ dependencies = [
|
||||||
"syn 2.0.100",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_segmenter"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a717725612346ffc2d7b42c94b820db6908048f39434504cb130e8b46256b0de"
|
||||||
|
dependencies = [
|
||||||
|
"core_maths",
|
||||||
|
"displaydoc",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_provider",
|
||||||
|
"icu_segmenter_data",
|
||||||
|
"utf8_iter",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_segmenter_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1e52775179941363cc594e49ce99284d13d6948928d8e72c755f55e98caa1eb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_timezone"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa91ba6a585939a020c787235daa8aee856d9bceebd6355e283c0c310bc6de96"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_calendar",
|
||||||
|
"icu_provider",
|
||||||
|
"icu_timezone_data",
|
||||||
|
"tinystr",
|
||||||
|
"zerotrie",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_timezone_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1adcf7b613a268af025bc2a2532b4b9ee294e6051c5c0832d8bff20ac0232e68"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
@ -3005,7 +3347,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.5.0",
|
"hermit-abi 0.5.0",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3214,7 +3556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3611,12 +3953,42 @@ version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-bigint"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||||
|
dependencies = [
|
||||||
|
"num-bigint",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
|
@ -3652,7 +4024,7 @@ version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate 1.3.1",
|
"proc-macro-crate 3.3.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.100",
|
"syn 2.0.100",
|
||||||
|
|
@ -4075,6 +4447,15 @@ dependencies = [
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parse-zoneinfo"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24"
|
||||||
|
dependencies = [
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
|
|
@ -4097,6 +4478,16 @@ dependencies = [
|
||||||
"phf_shared",
|
"phf_shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_codegen"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf_generator"
|
name = "phf_generator"
|
||||||
version = "0.11.3"
|
version = "0.11.3"
|
||||||
|
|
@ -4504,10 +4895,19 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
"regex-automata 0.4.9",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e9368763f5a9b804326f3af749e16f9abf378d227bcdee7634b13d8f17793782"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
|
@ -4711,7 +5111,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.4.15",
|
"linux-raw-sys 0.4.15",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4724,7 +5124,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.9.3",
|
"linux-raw-sys 0.9.3",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -5189,7 +5589,7 @@ dependencies = [
|
||||||
"getrandom 0.3.2",
|
"getrandom 0.3.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.3",
|
"rustix 1.0.3",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -5274,6 +5674,14 @@ dependencies = [
|
||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "timedate-zbus"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||||
|
dependencies = [
|
||||||
|
"zbus 4.4.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-skia"
|
name = "tiny-skia"
|
||||||
version = "0.11.4"
|
version = "0.11.4"
|
||||||
|
|
@ -6081,7 +6489,7 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -6486,6 +6894,9 @@ name = "writeable"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x11-dl"
|
name = "x11-dl"
|
||||||
|
|
@ -6823,6 +7234,17 @@ dependencies = [
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerotrie"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb594dd55d87335c5f60177cee24f19457a5ec10a065e0a3014722ad252d0a1f"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerovec"
|
name = "zerovec"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,14 @@ edition = "2024"
|
||||||
vergen = { version = "8", features = ["git", "gitcl"] }
|
vergen = { version = "8", features = ["git", "gitcl"] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1"
|
||||||
|
async-fn-stream = "0.2.2"
|
||||||
|
icu = { version = "1.5.0", features = [
|
||||||
|
"experimental",
|
||||||
|
"compiled_data",
|
||||||
|
"icu_datetime_experimental",
|
||||||
|
] }
|
||||||
|
chrono-tz = "0.10"
|
||||||
chrono = { version = "0.4", features = ["unstable-locales"] }
|
chrono = { version = "0.4", features = ["unstable-locales"] }
|
||||||
cosmic-bg-config.workspace = true
|
cosmic-bg-config.workspace = true
|
||||||
cosmic-comp-config.workspace = true
|
cosmic-comp-config.workspace = true
|
||||||
|
|
@ -55,6 +63,7 @@ i18n-embed = { version = "0.14", features = [
|
||||||
i18n-embed-fl = "0.7"
|
i18n-embed-fl = "0.7"
|
||||||
rust-embed = "8"
|
rust-embed = "8"
|
||||||
futures-util = "0.3.30"
|
futures-util = "0.3.30"
|
||||||
|
timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" }
|
||||||
|
|
||||||
[dependencies.greetd_ipc]
|
[dependencies.greetd_ipc]
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ use cosmic::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
iced_runtime::core::window::Id as SurfaceId,
|
iced_runtime::core::window::Id as SurfaceId,
|
||||||
style, theme, widget,
|
theme, widget,
|
||||||
};
|
};
|
||||||
use cosmic_comp_config::CosmicCompConfig;
|
use cosmic_comp_config::CosmicCompConfig;
|
||||||
use cosmic_greeter_config::Config as CosmicGreeterConfig;
|
use cosmic_greeter_config::Config as CosmicGreeterConfig;
|
||||||
|
|
@ -417,6 +417,8 @@ pub enum Message {
|
||||||
Socket(SocketState),
|
Socket(SocketState),
|
||||||
Surface(surface::Action),
|
Surface(surface::Action),
|
||||||
Suspend,
|
Suspend,
|
||||||
|
Tick,
|
||||||
|
Tz(chrono_tz::Tz),
|
||||||
Username(String),
|
Username(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -444,47 +446,23 @@ pub struct App {
|
||||||
dropdown_opt: Option<Dropdown>,
|
dropdown_opt: Option<Dropdown>,
|
||||||
window_size: HashMap<SurfaceId, Size>,
|
window_size: HashMap<SurfaceId, Size>,
|
||||||
heartbeat_handle: Option<cosmic::iced::task::Handle>,
|
heartbeat_handle: Option<cosmic::iced::task::Handle>,
|
||||||
|
time: crate::time::Time,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn menu(&self, id: SurfaceId) -> Element<Message> {
|
fn menu(&self, id: SurfaceId) -> Element<Message> {
|
||||||
let left_element = {
|
let left_element = {
|
||||||
let date_time_column = {
|
let military_time = self
|
||||||
let mut column = widget::column::with_capacity(2).padding(16.0).spacing(12.0);
|
.selected_username
|
||||||
|
.data_idx
|
||||||
let dt = chrono::Local::now();
|
.and_then(|i| {
|
||||||
let locale = *crate::localize::LANGUAGE_CHRONO;
|
self.flags
|
||||||
|
.user_datas
|
||||||
let date = dt.format_localized("%A, %B %-d", locale);
|
.get(i)
|
||||||
column = column
|
.map(|user| user.clock_military_time)
|
||||||
.push(widget::text::title2(format!("{}", date)).class(style::Text::Accent));
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
let (time, time_size) = if self
|
let date_time_column = self.time.date_time_widget(military_time);
|
||||||
.selected_username
|
|
||||||
.data_idx
|
|
||||||
.and_then(|i| {
|
|
||||||
self.flags
|
|
||||||
.user_datas
|
|
||||||
.get(i)
|
|
||||||
.map(|user| user.clock_military_time)
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
{
|
|
||||||
(dt.format_localized("%R", locale), 112.0)
|
|
||||||
} else {
|
|
||||||
// xxx format_localized doesn't seem to show am/pm for some languages, such as
|
|
||||||
// French or Hungarian. This is apparently correct
|
|
||||||
// Also, time size needs to be reduced a bit here so that it fits on one line
|
|
||||||
(dt.format_localized("%I:%M %p", locale), 75.0)
|
|
||||||
};
|
|
||||||
column = column.push(
|
|
||||||
widget::text(format!("{}", time))
|
|
||||||
.size(time_size)
|
|
||||||
.class(style::Text::Accent),
|
|
||||||
);
|
|
||||||
|
|
||||||
column
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut status_row = widget::row::with_capacity(2).padding(16.0).spacing(12.0);
|
let mut status_row = widget::row::with_capacity(2).padding(16.0).spacing(12.0);
|
||||||
|
|
||||||
|
|
@ -1071,8 +1049,15 @@ impl cosmic::Application for App {
|
||||||
dropdown_opt: None,
|
dropdown_opt: None,
|
||||||
window_size: HashMap::new(),
|
window_size: HashMap::new(),
|
||||||
heartbeat_handle: None,
|
heartbeat_handle: None,
|
||||||
|
time: crate::time::Time::new(),
|
||||||
};
|
};
|
||||||
(app, Task::none())
|
(
|
||||||
|
app,
|
||||||
|
Task::batch(vec![
|
||||||
|
crate::time::tick().map(|_| cosmic::Action::App(Message::Tick)),
|
||||||
|
crate::time::tz_updates().map(|tz| cosmic::Action::App(Message::Tz(tz))),
|
||||||
|
]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle application events here.
|
/// Handle application events here.
|
||||||
|
|
@ -1489,7 +1474,6 @@ impl cosmic::Application for App {
|
||||||
cosmic::app::Action::Surface(a),
|
cosmic::app::Action::Surface(a),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::Focus(surface_id) => {
|
Message::Focus(surface_id) => {
|
||||||
self.active_surface_id_opt = Some(surface_id);
|
self.active_surface_id_opt = Some(surface_id);
|
||||||
if let Some(text_input_id) = self
|
if let Some(text_input_id) = self
|
||||||
|
|
@ -1500,6 +1484,12 @@ impl cosmic::Application for App {
|
||||||
return widget::text_input::focus(text_input_id.clone());
|
return widget::text_input::focus(text_input_id.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::Tick => {
|
||||||
|
self.time.tick();
|
||||||
|
}
|
||||||
|
Message::Tz(tz) => {
|
||||||
|
self.time.set_tz(tz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,3 +14,5 @@ mod networkmanager;
|
||||||
|
|
||||||
#[cfg(feature = "upower")]
|
#[cfg(feature = "upower")]
|
||||||
mod upower;
|
mod upower;
|
||||||
|
|
||||||
|
mod time;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use std::{
|
use std::sync::OnceLock;
|
||||||
str::FromStr,
|
|
||||||
sync::{LazyLock, OnceLock},
|
|
||||||
};
|
|
||||||
|
|
||||||
use i18n_embed::{
|
use i18n_embed::{
|
||||||
fluent::{fluent_language_loader, FluentLanguageLoader},
|
|
||||||
DefaultLocalizer, LanguageLoader, Localizer,
|
DefaultLocalizer, LanguageLoader, Localizer,
|
||||||
|
fluent::{FluentLanguageLoader, fluent_language_loader},
|
||||||
};
|
};
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
|
|
||||||
|
|
@ -16,19 +13,6 @@ use rust_embed::RustEmbed;
|
||||||
struct Localizations;
|
struct Localizations;
|
||||||
|
|
||||||
pub static LANGUAGE_LOADER: OnceLock<FluentLanguageLoader> = OnceLock::new();
|
pub static LANGUAGE_LOADER: OnceLock<FluentLanguageLoader> = OnceLock::new();
|
||||||
pub static LANGUAGE_CHRONO: LazyLock<chrono::Locale> = LazyLock::new(|| {
|
|
||||||
std::env::var("LC_TIME")
|
|
||||||
.ok()
|
|
||||||
.or_else(|| std::env::var("LANG").ok())
|
|
||||||
.and_then(|locale_full| {
|
|
||||||
// Split LANG because it may be set to a locale such as en_US.UTF8
|
|
||||||
locale_full
|
|
||||||
.split('.')
|
|
||||||
.next()
|
|
||||||
.and_then(|locale| chrono::Locale::from_str(locale).ok())
|
|
||||||
})
|
|
||||||
.unwrap_or(chrono::Locale::en_US)
|
|
||||||
});
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fl {
|
macro_rules! fl {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use cosmic::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
iced_runtime::core::window::Id as SurfaceId,
|
iced_runtime::core::window::Id as SurfaceId,
|
||||||
style, widget,
|
widget,
|
||||||
};
|
};
|
||||||
use cosmic_config::CosmicConfigEntry;
|
use cosmic_config::CosmicConfigEntry;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
@ -35,7 +35,7 @@ use std::{
|
||||||
process,
|
process,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use tokio::{sync::mpsc, task};
|
use tokio::{sync::mpsc, task, time};
|
||||||
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
||||||
|
|
||||||
fn lockfile_opt() -> Option<PathBuf> {
|
fn lockfile_opt() -> Option<PathBuf> {
|
||||||
|
|
@ -232,6 +232,8 @@ pub enum Message {
|
||||||
Suspend,
|
Suspend,
|
||||||
Error(String),
|
Error(String),
|
||||||
Lock,
|
Lock,
|
||||||
|
Tick,
|
||||||
|
Tz(chrono_tz::Tz),
|
||||||
Unlock,
|
Unlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,30 +275,15 @@ pub struct App {
|
||||||
value_tx_opt: Option<mpsc::Sender<String>>,
|
value_tx_opt: Option<mpsc::Sender<String>>,
|
||||||
prompt_opt: Option<(String, bool, Option<String>)>,
|
prompt_opt: Option<(String, bool, Option<String>)>,
|
||||||
error_opt: Option<String>,
|
error_opt: Option<String>,
|
||||||
|
time: crate::time::Time,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn menu(&self, surface_id: SurfaceId) -> Element<Message> {
|
fn menu(&self, surface_id: SurfaceId) -> Element<Message> {
|
||||||
let left_element = {
|
let left_element = {
|
||||||
let date_time_column = {
|
// TODO how should we get user preference for military time here?
|
||||||
let mut column = widget::column::with_capacity(2).padding(16.0);
|
let military_time = false;
|
||||||
|
let date_time_column = self.time.date_time_widget(military_time);
|
||||||
let dt = chrono::Local::now();
|
|
||||||
let locale = *crate::localize::LANGUAGE_CHRONO;
|
|
||||||
|
|
||||||
let date = dt.format_localized("%A, %B %-d", locale);
|
|
||||||
column = column
|
|
||||||
.push(widget::text::title2(format!("{}", date)).class(style::Text::Accent));
|
|
||||||
|
|
||||||
let time = dt.format_localized("%R", locale);
|
|
||||||
column = column.push(
|
|
||||||
widget::text(format!("{}", time))
|
|
||||||
.size(112.0)
|
|
||||||
.class(style::Text::Accent),
|
|
||||||
);
|
|
||||||
|
|
||||||
column
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut status_row = widget::row::with_capacity(2).padding(16.0).spacing(12.0);
|
let mut status_row = widget::row::with_capacity(2).padding(16.0).spacing(12.0);
|
||||||
|
|
||||||
|
|
@ -555,9 +542,10 @@ impl cosmic::Application for App {
|
||||||
value_tx_opt: None,
|
value_tx_opt: None,
|
||||||
prompt_opt: None,
|
prompt_opt: None,
|
||||||
error_opt: None,
|
error_opt: None,
|
||||||
|
time: crate::time::Time::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let command = if cfg!(feature = "logind") {
|
let task = if cfg!(feature = "logind") {
|
||||||
if already_locked {
|
if already_locked {
|
||||||
// Recover previously locked state
|
// Recover previously locked state
|
||||||
log::info!("recovering previous locked state");
|
log::info!("recovering previous locked state");
|
||||||
|
|
@ -574,7 +562,14 @@ impl cosmic::Application for App {
|
||||||
lock()
|
lock()
|
||||||
};
|
};
|
||||||
|
|
||||||
(app, command)
|
(
|
||||||
|
app,
|
||||||
|
Task::batch(vec![
|
||||||
|
task,
|
||||||
|
crate::time::tick().map(|_| cosmic::Action::App(Message::Tick)),
|
||||||
|
crate::time::tz_updates().map(|tz| cosmic::Action::App(Message::Tz(tz))),
|
||||||
|
]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle application events here.
|
/// Handle application events here.
|
||||||
|
|
@ -998,6 +993,12 @@ impl cosmic::Application for App {
|
||||||
cosmic::app::Action::Surface(a),
|
cosmic::app::Action::Surface(a),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Message::Tick => {
|
||||||
|
self.time.tick();
|
||||||
|
}
|
||||||
|
Message::Tz(tz) => {
|
||||||
|
self.time.set_tz(tz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
189
src/time.rs
Normal file
189
src/time.rs
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
use std::{str::FromStr, time::Duration};
|
||||||
|
|
||||||
|
use anyhow::bail;
|
||||||
|
use async_fn_stream::StreamEmitter;
|
||||||
|
use chrono::{Datelike, Timelike};
|
||||||
|
use cosmic::{
|
||||||
|
Task,
|
||||||
|
iced_core::Element,
|
||||||
|
style,
|
||||||
|
widget::{self, column, text::title2},
|
||||||
|
};
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use icu::{
|
||||||
|
calendar::DateTime,
|
||||||
|
datetime::{
|
||||||
|
DateTimeFormatter, DateTimeFormatterOptions,
|
||||||
|
options::{
|
||||||
|
components::{self, Bag},
|
||||||
|
preferences,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
locid::Locale,
|
||||||
|
};
|
||||||
|
use timedate_zbus::TimeDateProxy;
|
||||||
|
use tokio::time;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Time {
|
||||||
|
locale: Locale,
|
||||||
|
timezone: Option<chrono_tz::Tz>,
|
||||||
|
now: chrono::DateTime<chrono::FixedOffset>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Time {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
fn get_local() -> Result<Locale, Box<dyn std::error::Error>> {
|
||||||
|
let locale = std::env::var("LC_TIME").or_else(|_| std::env::var("LANG"))?;
|
||||||
|
let locale = locale
|
||||||
|
.split('.')
|
||||||
|
.next()
|
||||||
|
.ok_or(format!("Can't split the locale {locale}"))?;
|
||||||
|
|
||||||
|
let locale = Locale::from_str(locale).map_err(|e| format!("{e:?}"))?;
|
||||||
|
Ok(locale)
|
||||||
|
}
|
||||||
|
|
||||||
|
let locale = match get_local() {
|
||||||
|
Ok(locale) => locale,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("can't get locale {e}");
|
||||||
|
Locale::default()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let now = chrono::Local::now().fixed_offset();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
locale,
|
||||||
|
timezone: None,
|
||||||
|
now,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_tz(&mut self, tz: chrono_tz::Tz) {
|
||||||
|
self.timezone = Some(tz);
|
||||||
|
self.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(&mut self) {
|
||||||
|
self.now = self
|
||||||
|
.timezone
|
||||||
|
.map(|tz| chrono::Local::now().with_timezone(&tz).fixed_offset())
|
||||||
|
.unwrap_or_else(|| chrono::Local::now().into());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format<D: Datelike>(&self, bag: Bag, date: &D) -> String {
|
||||||
|
let options = DateTimeFormatterOptions::Components(bag);
|
||||||
|
|
||||||
|
let dtf =
|
||||||
|
DateTimeFormatter::try_new_experimental(&self.locale.clone().into(), options).unwrap();
|
||||||
|
|
||||||
|
let datetime = DateTime::try_new_gregorian_datetime(
|
||||||
|
date.year(),
|
||||||
|
date.month() as u8,
|
||||||
|
date.day() as u8,
|
||||||
|
// hack cause we know that we will only use "now"
|
||||||
|
// when we need hours (NaiveDate don't support this functions)
|
||||||
|
self.now.hour() as u8,
|
||||||
|
self.now.minute() as u8,
|
||||||
|
self.now.second() as u8,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.to_iso()
|
||||||
|
.to_any();
|
||||||
|
|
||||||
|
dtf.format(&datetime)
|
||||||
|
.expect("can't format value")
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn date_time_widget<'a, M: 'a>(&self, military_time: bool) -> cosmic::Element<'a, M> {
|
||||||
|
let mut top_bag = Bag::empty();
|
||||||
|
|
||||||
|
top_bag.weekday = Some(components::Text::Long);
|
||||||
|
|
||||||
|
top_bag.day = Some(components::Day::NumericDayOfMonth);
|
||||||
|
top_bag.month = Some(components::Month::Long);
|
||||||
|
|
||||||
|
let mut bottom_bag = Bag::empty();
|
||||||
|
|
||||||
|
bottom_bag.hour = Some(components::Numeric::Numeric);
|
||||||
|
bottom_bag.minute = Some(components::Numeric::Numeric);
|
||||||
|
|
||||||
|
let hour_cycle = if military_time {
|
||||||
|
preferences::HourCycle::H23
|
||||||
|
} else {
|
||||||
|
preferences::HourCycle::H12
|
||||||
|
};
|
||||||
|
|
||||||
|
top_bag.preferences = Some(preferences::Bag::from_hour_cycle(hour_cycle));
|
||||||
|
|
||||||
|
Element::from(
|
||||||
|
column()
|
||||||
|
.padding(16.)
|
||||||
|
.spacing(12.0)
|
||||||
|
.push(title2(self.format(top_bag, &self.now)).class(style::Text::Accent))
|
||||||
|
.push(
|
||||||
|
widget::text(self.format(bottom_bag, &self.now))
|
||||||
|
.size(if military_time { 112. } else { 75. })
|
||||||
|
.class(style::Text::Accent),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tz_updates() -> Task<chrono_tz::Tz> {
|
||||||
|
Task::stream(async_fn_stream::fn_stream(|emitter| async move {
|
||||||
|
loop {
|
||||||
|
if let Err(err) = tz_stream(&emitter).await {
|
||||||
|
log::error!("{err:?}");
|
||||||
|
}
|
||||||
|
_ = time::sleep(Duration::from_secs(60)).await;
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick() -> Task<()> {
|
||||||
|
Task::stream(async_fn_stream::fn_stream(|emitter| async move {
|
||||||
|
let mut timer = time::interval(time::Duration::from_secs(60));
|
||||||
|
timer.set_missed_tick_behavior(time::MissedTickBehavior::Skip);
|
||||||
|
|
||||||
|
emitter.emit(()).await;
|
||||||
|
loop {
|
||||||
|
timer.tick().await;
|
||||||
|
emitter.emit(()).await;
|
||||||
|
|
||||||
|
// Calculate a delta if we're ticking per minute to keep ticks stable
|
||||||
|
// Based on i3status-rust
|
||||||
|
let current = chrono::Local::now().second() as u64 % 60;
|
||||||
|
if current != 0 {
|
||||||
|
timer.reset_after(time::Duration::from_secs(60 - current));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn tz_stream(emitter: &StreamEmitter<chrono_tz::Tz>) -> anyhow::Result<()> {
|
||||||
|
let Ok(conn) = zbus::Connection::system().await else {
|
||||||
|
bail!("No zbus system connection.");
|
||||||
|
};
|
||||||
|
let Ok(proxy) = TimeDateProxy::new(&conn).await else {
|
||||||
|
bail!("No timezone proxy");
|
||||||
|
};
|
||||||
|
|
||||||
|
// The stream always returns the current timezone as its first item even if it wasn't
|
||||||
|
// updated. If the proxy is recreated in a loop somehow, the resulting stream will
|
||||||
|
// always yield an update immediately which could lead to spammed false updates.
|
||||||
|
let mut s = proxy.receive_timezone_changed().await;
|
||||||
|
|
||||||
|
while let Some(property) = s.next().await {
|
||||||
|
let Ok(tz) = property.get().await else {
|
||||||
|
bail!("Failed to get property");
|
||||||
|
};
|
||||||
|
let Ok(tz) = tz.parse::<chrono_tz::Tz>() else {
|
||||||
|
bail!("Failed to parse timezone.");
|
||||||
|
};
|
||||||
|
emitter.emit(tz).await;
|
||||||
|
}
|
||||||
|
bail!("Timezone property stream ended.");
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue