aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-04-11 08:32:50 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-04-11 08:32:50 +0100
commit4deb7470413a9d53323f6bedf26882ad2b0844a6 (patch)
tree2a3ca1b69a02300bbf0db40cd7e7fe410b8e938a
parent1299841ecb5648328a590658c2ea6ad18ecf46e3 (diff)
downloadmacaw-4deb7470413a9d53323f6bedf26882ad2b0844a6.tar.gz
macaw-4deb7470413a9d53323f6bedf26882ad2b0844a6.tar.bz2
macaw-4deb7470413a9d53323f6bedf26882ad2b0844a6.zip
feat: nicks and avatars
Diffstat (limited to '')
-rw-r--r--Cargo.lock943
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs724
-rw-r--r--src/message_view.rs93
4 files changed, 842 insertions, 920 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ae12778..2e2d829 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -35,6 +35,17 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "ahash"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
+dependencies = [
+ "getrandom 0.2.15",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
@@ -107,6 +118,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
+name = "approx"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
name = "arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -143,29 +163,11 @@ checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
[[package]]
name = "ash"
-version = "0.38.0+1.3.281"
+version = "0.37.3+1.3.251"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f"
+checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a"
dependencies = [
- "libloading",
-]
-
-[[package]]
-name = "ashpd"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3d60bee1a1d38c2077030f4788e1b4e31058d2e79a8cfc8f2b440bd44db290"
-dependencies = [
- "async-fs",
- "async-net",
- "enumflags2",
- "futures-channel",
- "futures-util",
- "rand",
- "serde",
- "serde_repr",
- "url",
- "zbus",
+ "libloading 0.7.4",
]
[[package]]
@@ -174,7 +176,7 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
dependencies = [
- "event-listener 5.4.0",
+ "event-listener",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
@@ -182,17 +184,6 @@ dependencies = [
[[package]]
name = "async-channel"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
-dependencies = [
- "concurrent-queue",
- "event-listener 2.5.3",
- "futures-core",
-]
-
-[[package]]
-name = "async-channel"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
@@ -228,21 +219,6 @@ dependencies = [
]
[[package]]
-name = "async-global-executor"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c"
-dependencies = [
- "async-channel 2.3.1",
- "async-executor",
- "async-io",
- "async-lock",
- "blocking",
- "futures-lite",
- "once_cell",
-]
-
-[[package]]
name = "async-io"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -267,36 +243,25 @@ version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
- "event-listener 5.4.0",
+ "event-listener",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
-name = "async-net"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
-dependencies = [
- "async-io",
- "blocking",
- "futures-lite",
-]
-
-[[package]]
name = "async-process"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb"
dependencies = [
- "async-channel 2.3.1",
+ "async-channel",
"async-io",
"async-lock",
"async-signal",
"async-task",
"blocking",
"cfg-if",
- "event-listener 5.4.0",
+ "event-listener",
"futures-lite",
"rustix 0.38.44",
"tracing",
@@ -332,32 +297,6 @@ dependencies = [
]
[[package]]
-name = "async-std"
-version = "1.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24"
-dependencies = [
- "async-channel 1.9.0",
- "async-global-executor",
- "async-io",
- "async-lock",
- "crossbeam-utils",
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-lite",
- "gloo-timers",
- "kv-log-macro",
- "log",
- "memchr",
- "once_cell",
- "pin-project-lite",
- "pin-utils",
- "slab",
- "wasm-bindgen-futures",
-]
-
-[[package]]
name = "async-task"
version = "4.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -447,18 +386,18 @@ checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3"
[[package]]
name = "bit-set"
-version = "0.8.0"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
-version = "0.8.0"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bit_field"
@@ -517,7 +456,7 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea"
dependencies = [
- "async-channel 2.3.1",
+ "async-channel",
"async-task",
"futures-io",
"futures-lite",
@@ -537,6 +476,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
+name = "by_address"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
+
+[[package]]
name = "bytemuck"
version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -635,6 +580,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
+
+[[package]]
+name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
@@ -726,6 +677,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
+name = "com"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6"
+dependencies = [
+ "com_macros",
+]
+
+[[package]]
+name = "com_macros"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5"
+dependencies = [
+ "com_macros_support",
+ "proc-macro2",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "com_macros_support"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -847,18 +829,18 @@ dependencies = [
[[package]]
name = "cosmic-text"
-version = "0.14.1"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1db686e755000c93f73a3acc78be56a71e3efb83ed92886f45faea2b9485bad7"
+checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2"
dependencies = [
"bitflags 2.9.0",
"fontdb",
"log",
"rangemap",
+ "rayon",
"rustc-hash 1.1.0",
"rustybuzz",
"self_cell",
- "smol_str",
"swash",
"sys-locale",
"ttf-parser 0.21.1",
@@ -942,18 +924,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
[[package]]
-name = "cryoglyph"
-version = "0.1.0"
-source = "git+https://github.com/iced-rs/cryoglyph.git?rev=a456d1c17bbcf33afcca41d9e5e299f9f1193819#a456d1c17bbcf33afcca41d9e5e299f9f1193819"
-dependencies = [
- "cosmic-text",
- "etagere",
- "lru",
- "rustc-hash 2.1.1",
- "wgpu",
-]
-
-[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -976,17 +946,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
[[package]]
+name = "d3d12"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307"
+dependencies = [
+ "bitflags 2.9.0",
+ "libloading 0.8.6",
+ "winapi",
+]
+
+[[package]]
name = "dark-light"
-version = "2.0.0"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18e1a09f280e29a8b00bc7e81eca5ac87dca0575639c9422a5fa25a07bb884b8"
+checksum = "2a76fa97167fa740dcdbfe18e8895601e1bc36525f09b044e00916e717c03a3c"
dependencies = [
- "ashpd",
- "async-std",
- "objc2",
- "objc2-foundation",
+ "dconf_rs",
+ "detect-desktop-environment",
+ "dirs 4.0.0",
+ "objc",
+ "rust-ini",
"web-sys",
- "winreg 0.52.0",
+ "winreg 0.10.1",
+ "zbus",
]
[[package]]
@@ -1020,6 +1003,12 @@ dependencies = [
]
[[package]]
+name = "dconf_rs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b"
+
+[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1031,6 +1020,12 @@ dependencies = [
]
[[package]]
+name = "detect-desktop-environment"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810"
+
+[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1053,6 +1048,15 @@ dependencies = [
[[package]]
name = "dirs"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
+dependencies = [
+ "dirs-sys 0.3.7",
+]
+
+[[package]]
+name = "dirs"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
@@ -1062,6 +1066,17 @@ dependencies = [
[[package]]
name = "dirs-sys"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
+dependencies = [
+ "libc",
+ "redox_users 0.4.6",
+ "winapi",
+]
+
+[[package]]
+name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
@@ -1107,17 +1122,14 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
- "libloading",
+ "libloading 0.8.6",
]
[[package]]
-name = "document-features"
-version = "0.2.11"
+name = "dlv-list"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
-dependencies = [
- "litrs",
-]
+checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
[[package]]
name = "dotenvy"
@@ -1134,7 +1146,8 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
name = "dpi"
version = "0.1.1"
-source = "git+https://github.com/iced-rs/winit.git?rev=11414b6aa45699f038114e61b4ddf5102b2d3b4b#11414b6aa45699f038114e61b4ddf5102b2d3b4b"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
[[package]]
name = "drm"
@@ -1277,12 +1290,6 @@ dependencies = [
[[package]]
name = "event-listener"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
-
-[[package]]
-name = "event-listener"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
@@ -1298,7 +1305,7 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [
- "event-listener 5.4.0",
+ "event-listener",
"pin-project-lite",
]
@@ -1318,6 +1325,12 @@ dependencies = [
]
[[package]]
+name = "fast-srgb8"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
+
+[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1335,13 +1348,13 @@ dependencies = [
[[package]]
name = "filamento"
version = "0.1.0"
-source = "git+https://bunny.garden/luz#aab4cd47b1d2da5539c50675be4c7a36898189ef"
+source = "git+https://bunny.garden/luz#15faa6b95ffb5c64a56e212cf386c29fef56efc8"
dependencies = [
"base64",
"chrono",
"futures",
"hex",
- "image",
+ "image 0.25.6",
"jid",
"lampada",
"sha1",
@@ -1384,9 +1397,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "font-types"
-version = "0.8.4"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fa6a5e5a77b5f3f7f9e32879f484aa5b3632ddfbe568a16266c904a6f32cdaf"
+checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492"
dependencies = [
"bytemuck",
]
@@ -1516,7 +1529,7 @@ checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
dependencies = [
"futures-core",
"lock_api",
- "parking_lot",
+ "parking_lot 0.12.3",
]
[[package]]
@@ -1656,22 +1669,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
[[package]]
-name = "gloo-timers"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994"
-dependencies = [
- "futures-channel",
- "futures-core",
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
name = "glow"
-version = "0.16.0"
+version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08"
+checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1"
dependencies = [
"js-sys",
"slotmap",
@@ -1681,9 +1682,9 @@ dependencies = [
[[package]]
name = "glutin_wgl_sys"
-version = "0.6.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e"
+checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead"
dependencies = [
"gl_generator",
]
@@ -1709,32 +1710,33 @@ dependencies = [
[[package]]
name = "gpu-allocator"
-version = "0.27.0"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd"
+checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884"
dependencies = [
"log",
"presser",
"thiserror 1.0.69",
+ "winapi",
"windows",
]
[[package]]
name = "gpu-descriptor"
-version = "0.3.1"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcf29e94d6d243368b7a56caa16bc213e4f9f8ed38c4d9557069527b5d5281ca"
+checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c"
dependencies = [
"bitflags 2.9.0",
"gpu-descriptor-types",
- "hashbrown",
+ "hashbrown 0.14.5",
]
[[package]]
name = "gpu-descriptor-types"
-version = "0.2.0"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91"
+checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c"
dependencies = [
"bitflags 2.9.0",
]
@@ -1761,6 +1763,25 @@ dependencies = [
[[package]]
name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash 0.7.8",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+dependencies = [
+ "ahash 0.8.11",
+ "allocator-api2",
+]
+
+[[package]]
+name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
@@ -1776,7 +1797,22 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
dependencies = [
- "hashbrown",
+ "hashbrown 0.15.2",
+]
+
+[[package]]
+name = "hassle-rs"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890"
+dependencies = [
+ "bitflags 2.9.0",
+ "com",
+ "libc",
+ "libloading 0.8.6",
+ "thiserror 1.0.69",
+ "widestring",
+ "winapi",
]
[[package]]
@@ -1879,32 +1915,33 @@ dependencies = [
[[package]]
name = "iced"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88acfabc84ec077eaf9ede3457ffa3a104626d79022a9bf7f296093b1d60c73f"
dependencies = [
"iced_core",
- "iced_debug",
"iced_futures",
"iced_renderer",
- "iced_runtime",
"iced_widget",
"iced_winit",
- "image",
+ "image 0.24.9",
"thiserror 1.0.69",
]
[[package]]
name = "iced_core"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0013a238275494641bf8f1732a23a808196540dc67b22ff97099c044ae4c8a1c"
dependencies = [
"bitflags 2.9.0",
"bytes",
"dark-light",
"glam",
- "lilt",
"log",
"num-traits",
+ "once_cell",
+ "palette",
"rustc-hash 2.1.1",
"smol_str",
"thiserror 1.0.69",
@@ -1912,18 +1949,10 @@ dependencies = [
]
[[package]]
-name = "iced_debug"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
-dependencies = [
- "iced_core",
- "log",
-]
-
-[[package]]
name = "iced_futures"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c04a6745ba2e80f32cf01e034fd00d853aa4f4cd8b91888099cb7aaee0d5d7c"
dependencies = [
"futures",
"iced_core",
@@ -1931,13 +1960,27 @@ dependencies = [
"rustc-hash 2.1.1",
"tokio",
"wasm-bindgen-futures",
- "wasmtimer",
+ "wasm-timer",
+]
+
+[[package]]
+name = "iced_glyphon"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41c3bb56f1820ca252bc1d0994ece33d233a55657c0c263ea7cb16895adbde82"
+dependencies = [
+ "cosmic-text",
+ "etagere",
+ "lru",
+ "rustc-hash 2.1.1",
+ "wgpu",
]
[[package]]
name = "iced_graphics"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba25a18cfa6d5cc160aca7e1b34f73ccdff21680fa8702168c09739767b6c66f"
dependencies = [
"bitflags 2.9.0",
"bytemuck",
@@ -1945,9 +1988,10 @@ dependencies = [
"half",
"iced_core",
"iced_futures",
- "image",
+ "image 0.24.9",
"kamadak-exif",
"log",
+ "once_cell",
"raw-window-handle",
"rustc-hash 2.1.1",
"thiserror 1.0.69",
@@ -1955,18 +1999,10 @@ dependencies = [
]
[[package]]
-name = "iced_program"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
-dependencies = [
- "iced_graphics",
- "iced_runtime",
-]
-
-[[package]]
name = "iced_renderer"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73558208059f9e622df2bf434e044ee2f838ce75201a023cf0ca3e1244f46c2a"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@@ -1977,12 +2013,12 @@ dependencies = [
[[package]]
name = "iced_runtime"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "348b5b2c61c934d88ca3b0ed1ed913291e923d086a66fa288ce9669da9ef62b5"
dependencies = [
"bytes",
"iced_core",
- "iced_debug",
"iced_futures",
"raw-window-handle",
"thiserror 1.0.69",
@@ -1990,12 +2026,12 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c625d368284fcc43b0b36b176f76eff1abebe7959dd58bd8ce6897d641962a50"
dependencies = [
"bytemuck",
"cosmic-text",
- "iced_debug",
"iced_graphics",
"kurbo",
"log",
@@ -2006,18 +2042,19 @@ dependencies = [
[[package]]
name = "iced_wgpu"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15708887133671d2bcc6c1d01d1f176f43a64d6cdc3b2bf893396c3ee498295f"
dependencies = [
"bitflags 2.9.0",
"bytemuck",
- "cryoglyph",
"futures",
"glam",
"guillotiere",
- "iced_debug",
+ "iced_glyphon",
"iced_graphics",
"log",
+ "once_cell",
"rustc-hash 2.1.1",
"thiserror 1.0.69",
"wgpu",
@@ -2025,13 +2062,14 @@ dependencies = [
[[package]]
name = "iced_widget"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81429e1b950b0e4bca65be4c4278fea6678ea782030a411778f26fa9f8983e1d"
dependencies = [
"iced_renderer",
"iced_runtime",
- "log",
"num-traits",
+ "once_cell",
"rustc-hash 2.1.1",
"thiserror 1.0.69",
"unicode-segmentation",
@@ -2039,17 +2077,20 @@ dependencies = [
[[package]]
name = "iced_winit"
-version = "0.14.0-dev"
-source = "git+https://github.com/iced-rs/iced#3ee9a1e18716aa25ab09458201e69c83d3df276c"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f44cd4e1c594b6334f409282937bf972ba14d31fedf03c23aa595d982a2fda28"
dependencies = [
- "iced_debug",
- "iced_program",
+ "iced_futures",
+ "iced_graphics",
+ "iced_runtime",
"log",
"rustc-hash 2.1.1",
"thiserror 1.0.69",
"tracing",
"wasm-bindgen-futures",
"web-sys",
+ "winapi",
"window_clipboard",
"winit",
]
@@ -2206,6 +2247,24 @@ dependencies = [
[[package]]
name = "image"
+version = "0.24.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "exr",
+ "gif",
+ "jpeg-decoder",
+ "num-traits",
+ "png",
+ "qoi",
+ "tiff",
+]
+
+[[package]]
+name = "image"
version = "0.25.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
@@ -2250,7 +2309,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
"equivalent",
- "hashbrown",
+ "hashbrown 0.15.2",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
+dependencies = [
+ "cfg-if",
]
[[package]]
@@ -2300,7 +2368,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jid"
version = "0.1.0"
-source = "git+https://bunny.garden/luz#aab4cd47b1d2da5539c50675be4c7a36898189ef"
+source = "git+https://bunny.garden/luz#15faa6b95ffb5c64a56e212cf386c29fef56efc8"
dependencies = [
"sqlx",
]
@@ -2342,6 +2410,9 @@ name = "jpeg-decoder"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
+dependencies = [
+ "rayon",
+]
[[package]]
name = "js-sys"
@@ -2392,7 +2463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
dependencies = [
"libc",
- "libloading",
+ "libloading 0.8.6",
"pkg-config",
]
@@ -2413,18 +2484,9 @@ dependencies = [
]
[[package]]
-name = "kv-log-macro"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
-dependencies = [
- "log",
-]
-
-[[package]]
name = "lampada"
version = "0.1.0"
-source = "git+https://bunny.garden/luz#aab4cd47b1d2da5539c50675be4c7a36898189ef"
+source = "git+https://bunny.garden/luz#15faa6b95ffb5c64a56e212cf386c29fef56efc8"
dependencies = [
"futures",
"jid",
@@ -2478,6 +2540,16 @@ dependencies = [
[[package]]
name = "libloading"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
+name = "libloading"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
@@ -2515,15 +2587,6 @@ dependencies = [
]
[[package]]
-name = "lilt"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f67562e5eff6b20553fa9be1c503356768420994e28f67e3eafe6f41910e57ad"
-dependencies = [
- "web-time",
-]
-
-[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2554,12 +2617,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
[[package]]
-name = "litrs"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
-
-[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2574,9 +2631,6 @@ name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
-dependencies = [
- "value-bag",
-]
[[package]]
name = "loop9"
@@ -2605,7 +2659,7 @@ dependencies = [
[[package]]
name = "luz"
version = "0.1.0"
-source = "git+https://bunny.garden/luz#aab4cd47b1d2da5539c50675be4c7a36898189ef"
+source = "git+https://bunny.garden/luz#15faa6b95ffb5c64a56e212cf386c29fef56efc8"
dependencies = [
"async-recursion",
"async-trait",
@@ -2634,7 +2688,7 @@ dependencies = [
"chrono",
"chrono-humanize",
"confy",
- "dirs",
+ "dirs 6.0.0",
"filamento",
"iced",
"indexmap",
@@ -2711,9 +2765,9 @@ dependencies = [
[[package]]
name = "metal"
-version = "0.31.0"
+version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e"
+checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25"
dependencies = [
"bitflags 2.9.0",
"block",
@@ -2759,23 +2813,21 @@ checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b"
[[package]]
name = "naga"
-version = "24.0.0"
+version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e"
+checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843"
dependencies = [
- "arrayvec",
"bit-set",
"bitflags 2.9.0",
- "cfg_aliases",
"codespan-reporting",
"hexf-parse",
"indexmap",
"log",
+ "num-traits",
"rustc-hash 1.1.0",
"spirv",
- "strum",
"termcolor",
- "thiserror 2.0.12",
+ "thiserror 1.0.69",
"unicode-xid",
]
@@ -2858,7 +2910,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.9.0",
"cfg-if",
- "cfg_aliases",
+ "cfg_aliases 0.2.1",
"libc",
"memoffset",
]
@@ -3029,6 +3081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
+ "objc_exception",
]
[[package]]
@@ -3235,6 +3288,15 @@ dependencies = [
]
[[package]]
+name = "objc_exception"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
+dependencies = [
+ "cc",
+]
+
+[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3309,12 +3371,13 @@ dependencies = [
]
[[package]]
-name = "ordered-float"
-version = "4.6.0"
+name = "ordered-multimap"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
+checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
dependencies = [
- "num-traits",
+ "dlv-list",
+ "hashbrown 0.12.3",
]
[[package]]
@@ -3343,6 +3406,30 @@ dependencies = [
]
[[package]]
+name = "palette"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6"
+dependencies = [
+ "approx",
+ "fast-srgb8",
+ "palette_derive",
+ "phf",
+]
+
+[[package]]
+name = "palette_derive"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30"
+dependencies = [
+ "by_address",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.100",
+]
+
+[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3350,12 +3437,37 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core 0.8.6",
+]
+
+[[package]]
+name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
- "parking_lot_core",
+ "parking_lot_core 0.9.10",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
+dependencies = [
+ "cfg-if",
+ "instant",
+ "libc",
+ "redox_syscall 0.2.16",
+ "smallvec",
+ "winapi",
]
[[package]]
@@ -3418,6 +3530,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_macros",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared",
+ "rand",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.100",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
name = "pin-project"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3726,9 +3880,9 @@ dependencies = [
[[package]]
name = "read-fonts"
-version = "0.25.3"
+version = "0.22.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f9e8a4f503e5c8750e4cd3b32a4e090035c46374b305a15c70bad833dca05f"
+checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f"
dependencies = [
"bytemuck",
"font-types",
@@ -3736,6 +3890,15 @@ dependencies = [
[[package]]
name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
@@ -3840,6 +4003,16 @@ dependencies = [
]
[[package]]
+name = "rust-ini"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
+dependencies = [
+ "cfg-if",
+ "ordered-multimap",
+]
+
+[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4143,10 +4316,16 @@ dependencies = [
]
[[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
name = "skrifa"
-version = "0.26.6"
+version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cc1aa86c26dbb1b63875a7180aa0819709b33348eb5b1491e4321fae388179d"
+checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe"
dependencies = [
"bytemuck",
"read-fonts",
@@ -4242,7 +4421,7 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
dependencies = [
"as-raw-xcb-connection",
"bytemuck",
- "cfg_aliases",
+ "cfg_aliases 0.2.1",
"core-graphics 0.24.0",
"drm",
"fastrand",
@@ -4318,12 +4497,12 @@ dependencies = [
"crc",
"crossbeam-queue",
"either",
- "event-listener 5.4.0",
+ "event-listener",
"futures-core",
"futures-intrusive",
"futures-io",
"futures-util",
- "hashbrown",
+ "hashbrown 0.15.2",
"hashlink",
"indexmap",
"log",
@@ -4498,7 +4677,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "stanza"
version = "0.1.0"
-source = "git+https://bunny.garden/luz#aab4cd47b1d2da5539c50675be4c7a36898189ef"
+source = "git+https://bunny.garden/luz#15faa6b95ffb5c64a56e212cf386c29fef56efc8"
dependencies = [
"chrono",
"jid",
@@ -4530,28 +4709,6 @@ dependencies = [
]
[[package]]
-name = "strum"
-version = "0.26.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
-dependencies = [
- "strum_macros",
-]
-
-[[package]]
-name = "strum_macros"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
-dependencies = [
- "heck 0.5.0",
- "proc-macro2",
- "quote",
- "rustversion",
- "syn 2.0.100",
-]
-
-[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4565,9 +4722,9 @@ checksum = "ce5d813d71d82c4cbc1742135004e4a79fd870214c155443451c139c9470a0aa"
[[package]]
name = "swash"
-version = "0.2.2"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fae9a562c7b46107d9c78cd78b75bbe1e991c16734c0aee8ff0ee711fb8b620a"
+checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2"
dependencies = [
"skrifa",
"yazi",
@@ -4758,7 +4915,7 @@ checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e"
dependencies = [
"as-raw-xcb-connection",
"ctor-lite",
- "libloading",
+ "libloading 0.8.6",
"pkg-config",
"tracing",
]
@@ -4798,7 +4955,7 @@ dependencies = [
"bytes",
"libc",
"mio",
- "parking_lot",
+ "parking_lot 0.12.3",
"pin-project-lite",
"signal-hook-registry",
"socket2",
@@ -4966,7 +5123,7 @@ dependencies = [
"ipconfig",
"lazy_static",
"lru-cache",
- "parking_lot",
+ "parking_lot 0.12.3",
"resolv-conf",
"smallvec",
"thiserror 1.0.69",
@@ -5094,7 +5251,6 @@ dependencies = [
"form_urlencoded",
"idna 1.0.3",
"percent-encoding",
- "serde",
]
[[package]]
@@ -5136,12 +5292,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
-name = "value-bag"
-version = "1.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5"
-
-[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5262,17 +5412,18 @@ dependencies = [
]
[[package]]
-name = "wasmtimer"
-version = "0.4.1"
+name = "wasm-timer"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0048ad49a55b9deb3953841fa1fc5858f0efbcb7a18868c899a360269fac1b23"
+checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
dependencies = [
"futures",
"js-sys",
- "parking_lot",
+ "parking_lot 0.11.2",
"pin-utils",
- "slab",
"wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
]
[[package]]
@@ -5412,18 +5563,17 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "wgpu"
-version = "24.0.3"
+version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35904fb00ba2d2e0a4d002fcbbb6e1b89b574d272a50e5fc95f6e81cf281c245"
+checksum = "cbd7311dbd2abcfebaabf1841a2824ed7c8be443a0f29166e5d3c6a53a762c01"
dependencies = [
"arrayvec",
- "bitflags 2.9.0",
- "cfg_aliases",
- "document-features",
+ "cfg-if",
+ "cfg_aliases 0.1.1",
"js-sys",
"log",
"naga",
- "parking_lot",
+ "parking_lot 0.12.3",
"profiling",
"raw-window-handle",
"smallvec",
@@ -5438,34 +5588,35 @@ dependencies = [
[[package]]
name = "wgpu-core"
-version = "24.0.2"
+version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "671c25545d479b47d3f0a8e373aceb2060b67c6eb841b24ac8c32348151c7a0c"
+checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a"
dependencies = [
"arrayvec",
"bit-vec",
"bitflags 2.9.0",
- "cfg_aliases",
- "document-features",
+ "cfg_aliases 0.1.1",
+ "codespan-reporting",
"indexmap",
"log",
"naga",
"once_cell",
- "parking_lot",
+ "parking_lot 0.12.3",
"profiling",
"raw-window-handle",
"rustc-hash 1.1.0",
"smallvec",
- "thiserror 2.0.12",
+ "thiserror 1.0.69",
+ "web-sys",
"wgpu-hal",
"wgpu-types",
]
[[package]]
name = "wgpu-hal"
-version = "24.0.4"
+version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259"
+checksum = "bfabcfc55fd86611a855816326b2d54c3b2fd7972c27ce414291562650552703"
dependencies = [
"android_system_properties",
"arrayvec",
@@ -5473,49 +5624,47 @@ dependencies = [
"bit-set",
"bitflags 2.9.0",
"block",
- "bytemuck",
- "cfg_aliases",
+ "cfg_aliases 0.1.1",
"core-graphics-types 0.1.3",
+ "d3d12",
"glow",
"glutin_wgl_sys",
"gpu-alloc",
"gpu-allocator",
"gpu-descriptor",
+ "hassle-rs",
"js-sys",
"khronos-egl",
"libc",
- "libloading",
+ "libloading 0.8.6",
"log",
"metal",
"naga",
"ndk-sys 0.5.0+25.2.9519653",
"objc",
"once_cell",
- "ordered-float",
- "parking_lot",
+ "parking_lot 0.12.3",
"profiling",
"range-alloc",
"raw-window-handle",
"renderdoc-sys",
"rustc-hash 1.1.0",
"smallvec",
- "thiserror 2.0.12",
+ "thiserror 1.0.69",
"wasm-bindgen",
"web-sys",
"wgpu-types",
- "windows",
- "windows-core 0.58.0",
+ "winapi",
]
[[package]]
name = "wgpu-types"
-version = "24.0.0"
+version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c"
+checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805"
dependencies = [
"bitflags 2.9.0",
"js-sys",
- "log",
"web-sys",
]
@@ -5582,24 +5731,20 @@ dependencies = [
[[package]]
name = "windows"
-version = "0.58.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
+checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
- "windows-core 0.58.0",
+ "windows-core 0.52.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
-version = "0.58.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
- "windows-implement 0.58.0",
- "windows-interface 0.58.0",
- "windows-result 0.2.0",
- "windows-strings 0.1.0",
"windows-targets 0.52.6",
]
@@ -5609,22 +5754,11 @@ version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
dependencies = [
- "windows-implement 0.60.0",
- "windows-interface 0.59.1",
+ "windows-implement",
+ "windows-interface",
"windows-link",
- "windows-result 0.3.2",
- "windows-strings 0.4.0",
-]
-
-[[package]]
-name = "windows-implement"
-version = "0.58.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.100",
+ "windows-result",
+ "windows-strings",
]
[[package]]
@@ -5640,17 +5774,6 @@ dependencies = [
[[package]]
name = "windows-interface"
-version = "0.58.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.100",
-]
-
-[[package]]
-name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
@@ -5668,15 +5791,6 @@ checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-result"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-result"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
@@ -5686,16 +5800,6 @@ dependencies = [
[[package]]
name = "windows-strings"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
-dependencies = [
- "windows-result 0.2.0",
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-strings"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
@@ -5919,17 +6023,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winit"
-version = "0.30.8"
-source = "git+https://github.com/iced-rs/winit.git?rev=11414b6aa45699f038114e61b4ddf5102b2d3b4b#11414b6aa45699f038114e61b4ddf5102b2d3b4b"
+version = "0.30.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0"
dependencies = [
- "ahash",
+ "ahash 0.8.11",
"android-activity",
"atomic-waker",
"bitflags 2.9.0",
"block2",
"bytemuck",
"calloop",
- "cfg_aliases",
+ "cfg_aliases 0.2.1",
"concurrent-queue",
"core-foundation 0.9.4",
"core-graphics 0.23.2",
@@ -5979,19 +6084,18 @@ dependencies = [
[[package]]
name = "winreg"
-version = "0.50.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
+ "winapi",
]
[[package]]
name = "winreg"
-version = "0.52.0"
+version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
@@ -6038,7 +6142,7 @@ dependencies = [
"as-raw-xcb-connection",
"gethostname",
"libc",
- "libloading",
+ "libloading 0.8.6",
"once_cell",
"rustix 0.38.44",
"x11rb-protocol",
@@ -6093,9 +6197,9 @@ checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda"
[[package]]
name = "yazi"
-version = "0.2.1"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
+checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1"
[[package]]
name = "yoke"
@@ -6123,9 +6227,9 @@ dependencies = [
[[package]]
name = "zbus"
-version = "5.5.0"
+version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236"
+checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
dependencies = [
"async-broadcast",
"async-executor",
@@ -6138,19 +6242,21 @@ dependencies = [
"async-trait",
"blocking",
"enumflags2",
- "event-listener 5.4.0",
+ "event-listener",
"futures-core",
- "futures-lite",
+ "futures-sink",
+ "futures-util",
"hex",
"nix",
"ordered-stream",
+ "rand",
"serde",
"serde_repr",
+ "sha1",
"static_assertions",
"tracing",
"uds_windows",
- "windows-sys 0.59.0",
- "winnow",
+ "windows-sys 0.52.0",
"xdg-home",
"zbus_macros",
"zbus_names",
@@ -6159,36 +6265,33 @@ dependencies = [
[[package]]
name = "zbus_macros"
-version = "5.5.0"
+version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f325ad10eb0d0a3eb060203494c3b7ec3162a01a59db75d2deee100339709fc0"
+checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.100",
- "zbus_names",
- "zvariant",
"zvariant_utils",
]
[[package]]
name = "zbus_names"
-version = "4.2.0"
+version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
+checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
dependencies = [
"serde",
"static_assertions",
- "winnow",
"zvariant",
]
[[package]]
name = "zeno"
-version = "0.3.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc0de2315dc13d00e5df3cd6b8d2124a6eaec6a2d4b6a1c5f37b7efad17fcc17"
+checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697"
[[package]]
name = "zerocopy"
@@ -6305,25 +6408,22 @@ dependencies = [
[[package]]
name = "zvariant"
-version = "5.4.0"
+version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2df9ee044893fcffbdc25de30546edef3e32341466811ca18421e3cd6c5a3ac"
+checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
dependencies = [
"endi",
"enumflags2",
"serde",
"static_assertions",
- "url",
- "winnow",
"zvariant_derive",
- "zvariant_utils",
]
[[package]]
name = "zvariant_derive"
-version = "5.4.0"
+version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74170caa85b8b84cc4935f2d56a57c7a15ea6185ccdd7eadb57e6edd90f94b2f"
+checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -6334,14 +6434,11 @@ dependencies = [
[[package]]
name = "zvariant_utils"
-version = "3.2.0"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34"
+checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
dependencies = [
"proc-macro2",
"quote",
- "serde",
- "static_assertions",
"syn 2.0.100",
- "winnow",
]
diff --git a/Cargo.toml b/Cargo.toml
index 2fc7ebe..8a324c9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-iced = { git = "https://github.com/iced-rs/iced", features = ["tokio", "image"] }
+iced = { version = "0.13.0", features = ["tokio", "image"] }
filamento = { version = "0.1.0", git = "https://bunny.garden/luz" }
jid = { version = "0.1.0", git = "https://bunny.garden/luz" }
tokio = "1.43.0"
diff --git a/src/main.rs b/src/main.rs
index 8b22ce3..0b8b3b8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,9 +17,7 @@ use filamento::{roster::Contact, user::User, UpdateMessage};
use iced::alignment::Horizontal::Right;
use iced::futures::{SinkExt, Stream, StreamExt};
use iced::keyboard::{on_key_press, on_key_release, Key, Modifiers};
-use iced::theme::palette::{
- Background, Danger, Extended, Pair, Primary, Secondary, Success, Warning,
-};
+use iced::theme::palette::{Background, Danger, Extended, Pair, Primary, Secondary, Success};
use iced::theme::{Custom, Palette};
use iced::widget::button::Status;
use iced::widget::text::{Fragment, IntoFragment, Wrapping};
@@ -70,92 +68,62 @@ impl Default for Config {
pub struct Macaw {
client: Account,
config: Config,
- // references users
- messages: HashMap<Uuid, Weak<RefCell<MacawMessage>>>,
- // references users
- roster: HashMap<JID, MacawContact>,
- // store count of how many things reference it. allows it to stay mutable.
- // or maybe store a bool that indicates whether it can be garbage collected
- // but then in that case, if you change the bool, then it can be dropped anyway....
- // realistically none of this stuff matters until there are group chats. and group chats will have a list of users anyway.
- // so whenever a group chat is closed any users that are both not in the roster and that one doesn't also have a chat with
- // can be dropped.
- // but then also users who are no longer in the chat but were loaded because of old messages must also be dropped.
- // so the set of users in the group chat must also include people who left, just marked as do-not-show/departed. solution!
- // this only doesn't work if there are multiple group chats open at the same time ig. in this case the other chats' user
- // lists would need to also be differenced.
- // i'm pretty sure this is just O(2 + n) where n = number of other group chats open for each drop attempt, and it can
- // happen in a separate thread in the background anyway so no slowdown.
- // TODO: add presences reference
- // references nothing, optionally contact
- users: HashMap<JID, Weak<RefCell<MacawUser>>>,
- // chat could have no messages, and therefore no latest message.
- // references users, latest message
- chats: IndexMap<JID, Rc<RefCell<MacawChat>>>,
- subscription_requests: HashSet<JID>,
- open_chat: Option<MessageView>,
+ presences: HashMap<JID, Presence>,
+ subscription_requests: HashSet<MacawUser>,
new_chat: Option<NewChat>,
+ // references chats, users, messages
+ open_chat: Option<MessageView>,
+ // references users, contacts
+ roster: HashMap<JID, MacawContact>,
+ // references chats, users, messages
+ chats_list: IndexMap<JID, ChatListItem>,
}
-#[derive(Debug)]
-pub struct MacawUser {
- inner: User,
- contact: Option<Rc<RefCell<MacawContact>>>,
+#[derive(Debug, Clone)]
+pub struct MacawMessage {
+ inner: ChatMessage,
+ from: MacawUser,
}
-impl Deref for MacawUser {
- type Target = User;
+impl Deref for MacawMessage {
+ type Target = ChatMessage;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl DerefMut for MacawUser {
+impl DerefMut for MacawMessage {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
-impl MacawUser {
- pub fn contact(&self) -> Option<Ref<'_, MacawContact>> {
- self.contact
- .as_ref()
- .map(|contact| contact.as_ref().borrow())
- }
-}
-
#[derive(Debug, Clone)]
-pub struct MacawMessage {
- inner: ChatMessage,
- user: Rc<RefCell<MacawUser>>,
+pub struct MacawUser {
+ inner: User,
+ // contact not needed, as can always query the roster store to get this option.
+ // contact: Option<Contact>,
}
-impl Deref for MacawMessage {
- type Target = ChatMessage;
+impl Deref for MacawUser {
+ type Target = User;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl DerefMut for MacawMessage {
+impl DerefMut for MacawUser {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
-impl MacawMessage {
- pub fn user(&self) -> Ref<'_, MacawUser> {
- let user = self.user.as_ref().borrow();
- user
- }
-}
-
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct MacawContact {
inner: Contact,
- user: Rc<RefCell<MacawUser>>,
+ user: User,
}
impl Deref for MacawContact {
@@ -172,45 +140,44 @@ impl DerefMut for MacawContact {
}
}
-impl MacawContact {
- pub fn user(&self) -> Ref<'_, MacawUser> {
- let user = self.user.as_ref().borrow();
- user
- }
-}
-
+#[derive(Debug, Clone)]
pub struct MacawChat {
inner: Chat,
- user: Rc<RefCell<MacawUser>>,
- message: Option<Rc<RefCell<MacawMessage>>>,
+ user: MacawUser,
}
-impl Deref for MacawChat {
- type Target = Chat;
+pub struct ChatListItem {
+ // references chats
+ inner: MacawChat,
+ // references users, messages
+ latest_message: Option<MacawMessage>,
+}
+
+impl Deref for ChatListItem {
+ type Target = MacawChat;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
-impl DerefMut for MacawChat {
+impl DerefMut for ChatListItem {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
-impl MacawChat {
- pub fn user(&self) -> Ref<'_, MacawUser> {
- let user = self.user.as_ref().borrow();
- user
+impl Deref for MacawChat {
+ type Target = Chat;
+
+ fn deref(&self) -> &Self::Target {
+ &self.inner
}
+}
- pub fn latest_message(&self) -> Option<Ref<'_, MacawMessage>> {
- let latest_message = self
- .message
- .as_ref()
- .map(|message| message.as_ref().borrow());
- latest_message
+impl DerefMut for MacawChat {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.inner
}
}
@@ -228,13 +195,12 @@ impl Macaw {
Self {
client: account,
config,
- roster: HashMap::new(),
- users: HashMap::new(),
- chats: IndexMap::new(),
+ presences: HashMap::new(),
subscription_requests: HashSet::new(),
- open_chat: None,
new_chat: None,
- messages: HashMap::new(),
+ open_chat: None,
+ roster: HashMap::new(),
+ chats_list: IndexMap::new(),
}
}
}
@@ -486,35 +452,41 @@ async fn main() -> iced::Result {
let luz_handle1 = luz_handle.clone();
let luz_handle2 = luz_handle.clone();
if cfg.auto_connect {
- Task::batch(
- [
- Task::batch([
- Task::perform(
- async move { luz_handle1.get_roster_with_users().await },
- |result| {
- let roster = result.unwrap();
- let mut macaw_roster = HashMap::new();
- for contact in roster {
- macaw_roster.insert(contact.0.user_jid.clone(), contact);
- }
- Message::RosterWithUsers(macaw_roster)
- },
- ),
- Task::perform(
- async move {
- luz_handle2.get_chats_ordered_with_latest_messages().await
- },
- |chats| {
- let chats = chats.unwrap();
- info!("got chats: {:?}", chats);
- Message::GotChats(chats)
- },
- ),
- ])
- .chain(Task::done(Message::Connect)),
- Task::stream(stream),
- ],
- )
+ Task::batch([
+ Task::batch([
+ Task::perform(
+ async move { luz_handle1.get_roster_with_users().await },
+ |result| {
+ let roster = result.unwrap();
+ let mut macaw_roster = HashMap::new();
+ for (contact, user) in roster {
+ macaw_roster.insert(
+ contact.user_jid.clone(),
+ MacawContact {
+ inner: contact,
+ user,
+ },
+ );
+ }
+ Message::Roster(macaw_roster)
+ },
+ ),
+ Task::perform(
+ async move {
+ luz_handle2
+ .get_chats_ordered_with_latest_messages_and_users()
+ .await
+ },
+ |chats| {
+ let chats = chats.unwrap();
+ info!("got chats: {:?}", chats);
+ Message::GotChats(chats)
+ },
+ ),
+ ])
+ .chain(Task::done(Message::Connect)),
+ Task::stream(stream),
+ ])
} else {
Task::batch([
Task::perform(
@@ -522,14 +494,24 @@ async fn main() -> iced::Result {
|result| {
let roster = result.unwrap();
let mut macaw_roster = HashMap::new();
- for contact in roster {
- macaw_roster.insert(contact.0.user_jid.clone(), contact);
+ for (contact, user) in roster {
+ macaw_roster.insert(
+ contact.user_jid.clone(),
+ MacawContact {
+ inner: contact,
+ user,
+ },
+ );
}
- Message::RosterWithUsers(macaw_roster)
+ Message::Roster(macaw_roster)
},
),
Task::perform(
- async move { luz_handle2.get_chats_ordered_with_latest_messages().await },
+ async move {
+ luz_handle2
+ .get_chats_ordered_with_latest_messages_and_users()
+ .await
+ },
|chats| {
let chats = chats.unwrap();
info!("got chats: {:?}", chats);
@@ -605,10 +587,10 @@ pub enum Message {
LoginModal(login_modal::Message),
ClientCreated(Client),
Luz(UpdateMessage),
- RosterWithUsers(HashMap<JID, (Contact, User)>),
+ Roster(HashMap<JID, MacawContact>),
Connect,
Disconnect,
- GotChats(Vec<(Chat, ChatMessage)>),
+ GotChats(Vec<((Chat, User), (ChatMessage, User))>),
ToggleChat(JID),
SendMessage(JID, String),
Error(Error),
@@ -668,58 +650,21 @@ impl Macaw {
presence: PresenceType::Online(online),
};
client.connection_state = ConnectionState::Online;
- let mut roster = HashMap::new();
- let mut get_users = Vec::new();
- for contact in vec {
- if let Some(Some(user)) =
- self.users.get(&contact.user_jid).map(|user| user.upgrade())
- {
- let contact = MacawContact {
- inner: contact,
- user,
- };
- roster.insert(contact.user_jid.clone(), contact);
- user.borrow_mut().contact = Some(Rc::new(RefCell::new(contact)))
- } else {
- match self.client {
- Account::LoggedIn(client) => get_users.push(Task::perform(
- client.get_user(contact.user_jid),
- |result| {
- let result = result.unwrap();
- (contact, result)
- },
- )),
- Account::LoggedOut(login_modal) => {}
- }
- }
- }
- if get_users.is_empty() {
- self.roster = roster;
- Task::none()
- } else {
- // TODO: potential race condition if two rosters are gotten at the same time?
- Task::batch(get_users).collect().then(|users| {
- for (contact, user) in users {
- let user = Rc::new(RefCell::new(MacawUser {
- inner: user,
- contact: None,
- }));
- let contact = MacawContact {
+ let roster = vec
+ .into_iter()
+ .map(|(contact, user)| {
+ (
+ contact.user_jid.clone(),
+ MacawContact {
inner: contact,
user,
- };
- roster.insert(contact.user_jid, contact);
- user.borrow_mut().contact =
- Some(Rc::new(RefCell::new(contact)));
- self.users.insert(
- contact.user_jid,
- Rc::<RefCell<MacawUser>>::downgrade(&user),
- );
- }
- self.roster = roster;
- Task::none()
+ },
+ )
})
- }
+ .collect();
+ // no need to also update users as any user updates will come in separately
+ self.roster = roster;
+ Task::none()
}
Account::LoggedOut(login_modal) => Task::none(),
},
@@ -737,99 +682,15 @@ impl Macaw {
Account::LoggedOut(login_modal) => Task::none(),
}
}
- UpdateMessage::FullRoster(vec) => {
- let mut roster = HashMap::new();
- let mut get_users = Vec::new();
- for contact in vec {
- if let Some(Some(user)) =
- self.users.get(&contact.user_jid).map(|user| user.upgrade())
- {
- let contact = MacawContact {
- inner: contact,
- user,
- };
- roster.insert(contact.user_jid.clone(), contact);
- user.borrow_mut().contact = Some(Rc::new(RefCell::new(contact)))
- } else {
- match self.client {
- Account::LoggedIn(client) => get_users.push(Task::perform(
- client.get_user(contact.user_jid),
- |result| {
- let result = result.unwrap();
- (contact, result)
- },
- )),
- Account::LoggedOut(login_modal) => {}
- }
- }
- }
- if get_users.is_empty() {
- self.roster = roster;
- Task::none()
- } else {
- // TODO: potential race condition if two rosters are gotten at the same time?
- Task::batch(get_users).collect().then(|users| {
- for (contact, user) in users {
- let user = Rc::new(RefCell::new(MacawUser {
- inner: user,
- contact: None,
- }));
- let contact = MacawContact {
- inner: contact,
- user,
- };
- roster.insert(contact.user_jid, contact);
- user.borrow_mut().contact = Some(Rc::new(RefCell::new(contact)));
- self.users.insert(
- contact.user_jid,
- Rc::<RefCell<MacawUser>>::downgrade(&user),
- );
- }
- self.roster = roster;
- Task::none()
- })
- }
- }
- UpdateMessage::RosterUpdate(contact) => {
- if let Some(Some(user)) =
- self.users.get(&contact.user_jid).map(|user| user.upgrade())
- {
- let contact = MacawContact {
+ UpdateMessage::RosterUpdate(contact, user) => {
+ self.roster.insert(
+ contact.user_jid.clone(),
+ MacawContact {
inner: contact,
user,
- };
- self.roster.insert(contact.user_jid.clone(), contact);
- user.borrow_mut().contact = Some(Rc::new(RefCell::new(contact)));
- Task::none()
- } else {
- match self.client {
- Account::LoggedIn(client) => {
- Task::perform(client.get_user(contact.user_jid), |result| {
- let result = result.unwrap();
- (contact, result)
- })
- .then(|(contact, user)| {
- let user = Rc::new(RefCell::new(MacawUser {
- inner: user,
- contact: None,
- }));
- let contact = MacawContact {
- inner: contact,
- user,
- };
- self.roster.insert(contact.user_jid.clone(), contact);
- user.borrow_mut().contact =
- Some(Rc::new(RefCell::new(contact)));
- self.users.insert(
- contact.user_jid,
- Rc::<RefCell<MacawUser>>::downgrade(&user),
- );
- Task::none()
- })
- }
- Account::LoggedOut(login_modal) => Task::none(),
- }
- }
+ },
+ );
+ Task::none()
}
UpdateMessage::RosterDelete(jid) => {
self.roster.remove(&jid);
@@ -837,123 +698,98 @@ impl Macaw {
}
UpdateMessage::Presence { from, presence } => {
// TODO: presence handling
+ self.presences.insert(from, presence);
Task::none()
}
- UpdateMessage::Message { to, message } => {
- if let Some(Some(user)) =
- self.users.get(&message.from).map(|user| user.upgrade())
+ UpdateMessage::Message { to, message, from } => {
+ let message = MacawMessage {
+ inner: message,
+ from: MacawUser { inner: from },
+ };
+ if let Some((chat_jid, mut chat_list_item)) =
+ self.chats_list.shift_remove_entry(&to)
{
- let message = MacawMessage {
- inner: message,
- user,
- };
- let message = Rc::new(RefCell::new(message));
- self.messages.insert(
- message.as_ref().borrow().id,
- Rc::<RefCell<MacawMessage>>::downgrade(&message),
- );
- if let Some((chat_jid, chat)) = self.chats.shift_remove_entry(&to) {
- chat.as_ref().borrow_mut().message = Some(message);
- self.chats.insert_before(0, chat_jid, chat);
- if let Some(open_chat) = &mut self.open_chat {
- if open_chat.chat().user().jid == to {
- open_chat.messages.push(message);
- }
+ chat_list_item.latest_message = Some(message.clone());
+ self.chats_list.insert_before(0, chat_jid, chat_list_item);
+ if let Some(open_chat) = &mut self.open_chat {
+ if open_chat.chat.user.jid == to {
+ open_chat.update(message_view::Message::Message(message));
}
- } else {
- let chat = Chat {
- correspondent: to.clone(),
- // TODO: should have a new chat event first...
- have_chatted: false,
- };
- let chat = MacawChat {
- inner: chat,
- user,
- message: Some(message),
- };
- self.chats.insert_before(0, to, Rc::new(RefCell::new(chat)));
}
- Task::none()
} else {
- match self.client {
- Account::LoggedIn(client) => {
- Task::perform(client.get_user(message.from), |result| {
- let result = result.unwrap();
- result
- })
- .then(|user| {
- let user = Rc::new(RefCell::new(MacawUser {
- inner: user,
- contact: None,
- }));
- self.users.insert(
- user.as_ref().borrow().jid,
- Rc::<RefCell<MacawUser>>::downgrade(&user),
- );
- let message = MacawMessage {
- inner: message,
- user,
- };
- let message = Rc::new(RefCell::new(message));
- self.messages.insert(
- message.as_ref().borrow().id,
- Rc::<RefCell<MacawMessage>>::downgrade(&message),
- );
- if let Some((chat_jid, chat)) =
- self.chats.shift_remove_entry(&to)
- {
- chat.as_ref().borrow_mut().message = Some(message);
- self.chats.insert_before(0, chat_jid, chat);
- if let Some(open_chat) = &mut self.open_chat {
- if open_chat.chat().user().jid == to {
- open_chat.messages.push(message);
- }
- }
- } else {
- let chat = Chat {
- correspondent: to.clone(),
- // TODO: should have a new chat event first...
- have_chatted: false,
- };
- let chat = MacawChat {
- inner: chat,
- user,
- message: Some(message),
- };
- self.chats.insert_before(
- 0,
- to,
- Rc::new(RefCell::new(chat)),
- );
- }
- Task::none()
- })
- }
- Account::LoggedOut(login_modal) => Task::none(),
- }
+ // TODO: get the actual chat from the thing, or send the chat first, from the client side.
+ let chat = Chat {
+ correspondent: to.clone(),
+ have_chatted: false,
+ };
+ let chat_list_item = ChatListItem {
+ inner: MacawChat {
+ inner: chat,
+ user: message.from.clone(),
+ },
+ latest_message: Some(message),
+ };
+ self.chats_list.insert_before(0, to, chat_list_item);
}
+ Task::none()
}
UpdateMessage::SubscriptionRequest(jid) => {
// TODO: subscription requests
Task::none()
}
- UpdateMessage::MessageDelivery { id, delivery } => {
- if let Some(Some(message)) =
- self.messages.get(&id).map(|message| message.upgrade())
- {
- message.as_ref().borrow_mut().delivery = Some(delivery)
+ UpdateMessage::MessageDelivery { chat, id, delivery } => {
+ if let Some(chat_list_item) = self.chats_list.get_mut(&chat) {
+ if let Some(latest_message) = &mut chat_list_item.latest_message {
+ if latest_message.id == id {
+ latest_message.delivery = Some(delivery)
+ }
+ }
+ }
+ if let Some(open_chat) = &mut self.open_chat {
+ if let Some(message) = open_chat.messages.get_mut(&id) {
+ message.delivery = Some(delivery)
+ }
}
Task::none()
}
UpdateMessage::NickChanged { jid, nick } => {
- if let Some(Some(user)) = self.users.get(&jid).map(|user| user.upgrade()) {
- user.as_ref().borrow_mut().nick = nick
+ // roster, chats_list, open chat
+ if let Some(contact) = self.roster.get_mut(&jid) {
+ contact.user.nick = nick.clone();
+ }
+ if let Some(chats_list_item) = self.chats_list.get_mut(&jid) {
+ chats_list_item.user.nick = nick.clone()
+ }
+ if let Some(open_chat) = &mut self.open_chat {
+ for (_, message) in &mut open_chat.messages {
+ if message.from.jid == jid {
+ message.from.nick = nick.clone()
+ }
+ }
+ if open_chat.chat.user.jid == jid {
+ open_chat.chat.user.nick = nick
+ }
}
Task::none()
}
UpdateMessage::AvatarChanged { jid, id } => {
- if let Some(Some(user)) = self.users.get(&jid).map(|user| user.upgrade()) {
- user.as_ref().borrow_mut().avatar = id
+ // roster, chats_list, open chat
+ if let Some(contact) = self.roster.get_mut(&jid) {
+ contact.user.avatar = id.clone();
+ }
+ if let Some(chats_list_item) = self.chats_list.get_mut(&jid) {
+ chats_list_item.user.avatar = id.clone()
+ }
+ if let Some(open_chat) = &mut self.open_chat {
+ // TODO: consider using an indexmap with two keys for speeding this up?
+ for (_, message) in &mut open_chat.messages {
+ if message.from.jid == jid {
+ message.from.avatar = id.clone()
+ }
+ }
+ if open_chat.chat.user.jid == jid {
+ open_chat.chat.user.avatar = id
+ }
}
Task::none()
}
@@ -970,17 +806,24 @@ impl Macaw {
|result| {
let roster = result.unwrap();
let mut macaw_roster = HashMap::new();
- for contact in roster {
- macaw_roster.insert(contact.0.user_jid.clone(), contact);
+ for (contact, user) in roster {
+ macaw_roster.insert(
+ contact.user_jid.clone(),
+ MacawContact {
+ inner: contact,
+ user,
+ },
+ );
}
- Message::RosterWithUsers(macaw_roster)
+ // TODO: clean this up
+ Message::Roster(macaw_roster)
},
),
Task::perform(
async move {
client2
.client
- .get_chats_ordered_with_latest_messages()
+ .get_chats_ordered_with_latest_messages_and_users()
.await
},
|chats| {
@@ -1002,17 +845,23 @@ impl Macaw {
|result| {
let roster = result.unwrap();
let mut macaw_roster = HashMap::new();
- for contact in roster {
- macaw_roster.insert(contact.0.user_jid.clone(), contact);
+ for (contact, user) in roster {
+ macaw_roster.insert(
+ contact.user_jid.clone(),
+ MacawContact {
+ inner: contact,
+ user,
+ },
+ );
}
- Message::RosterWithUsers(macaw_roster)
+ Message::Roster(macaw_roster)
},
),
Task::perform(
async move {
client2
.client
- .get_chats_ordered_with_latest_messages()
+ .get_chats_ordered_with_latest_messages_and_users()
.await
},
|chats| {
@@ -1028,22 +877,8 @@ impl Macaw {
])
}
}
- Message::RosterWithUsers(hash_map) => {
- for (_, (contact, user)) in hash_map {
- let user = MacawUser {
- inner: user,
- contact: None,
- };
- let user = Rc::new(RefCell::new(user));
- let contact = MacawContact {
- inner: contact,
- user,
- };
- self.roster.insert(contact.user_jid, contact);
- user.borrow_mut().contact = Some(Rc::new(RefCell::new(contact)));
- self.users
- .insert(contact.user_jid, Rc::<RefCell<MacawUser>>::downgrade(&user));
- }
+ Message::Roster(hash_map) => {
+ self.roster = hash_map;
Task::none()
}
Message::Connect => match &mut self.client {
@@ -1070,47 +905,34 @@ impl Macaw {
Message::ToggleChat(jid) => {
match &self.open_chat {
Some(message_view) => {
- if message_view.chat().user().jid == jid {
+ if message_view.chat.user.jid == jid {
self.open_chat = None;
return Task::none();
}
}
None => {}
}
- if let Some(chat) = self.chats.get(&jid) {
+ if let Some(chat) = self.chats_list.get(&jid) {
+ self.open_chat = Some(MessageView::new((*chat).clone(), &self.config));
match &self.client {
Account::LoggedIn(client) => {
let client = client.clone();
Task::perform(
- async move { client.get_messages(jid).await },
+ async move { client.get_messages_with_users(jid).await },
move |result| {
let message_history = result.unwrap();
- let messages = Vec::new();
- for message in message_history {
- // TODO: there must be users for the messages, but won't work for group chats.
- let user = self
- .users
- .get(&message.from)
- .unwrap()
- .upgrade()
- .unwrap();
- let message = MacawMessage {
+ let messages = message_history
+ .into_iter()
+ .map(|(message, user)| MacawMessage {
inner: message,
- user,
- };
- let message = Rc::new(RefCell::new(message));
- self.messages.insert(
- message.as_ref().borrow().id,
- Rc::<RefCell<MacawMessage>>::downgrade(&message),
- );
- messages.push(message)
- }
- let open_chat = MessageView::new(chat.clone(), &self.config);
- open_chat.messages = messages;
- self.open_chat = Some(open_chat);
+ from: MacawUser { inner: user },
+ })
+ .collect();
+ Message::MessageView(message_view::Message::MessageHistory(
+ messages,
+ ))
},
)
- .discard()
}
Account::LoggedOut(login_modal) => Task::none(),
}
@@ -1203,14 +1025,23 @@ impl Macaw {
return Task::none();
}
};
- for (chat, message) in chats {
+ for ((chat, chat_user), (message, message_user)) in chats {
let chat = MacawChat {
- inner: todo!(),
- user: todo!(),
- message: todo!(),
- }
- self.chats
- .insert(chat.0.correspondent.clone(), (chat.0.clone(), Some(chat.1)));
+ inner: chat,
+ user: MacawUser { inner: chat_user },
+ };
+ let latest_message = MacawMessage {
+ inner: message,
+ from: MacawUser {
+ inner: message_user,
+ },
+ };
+ let chat_list_item = ChatListItem {
+ inner: chat.clone(),
+ latest_message: Some(latest_message),
+ };
+ self.chats_list
+ .insert(chat.correspondent.clone(), chat_list_item);
}
Task::batch(tasks)
}
@@ -1238,10 +1069,9 @@ impl Macaw {
let action = message_view.update(message);
match action {
message_view::Action::None => Task::none(),
- message_view::Action::SendMessage(m) => Task::done(Message::SendMessage(
- message_view.chat().user().jid.clone(),
- m,
- )),
+ message_view::Action::SendMessage(m) => {
+ Task::done(Message::SendMessage(message_view.chat.user.jid.clone(), m))
+ }
}
} else {
Task::none()
@@ -1268,15 +1098,15 @@ impl Macaw {
let mut ui: Element<Message> = {
let mut chats_list: Column<Message> = column![];
if let Account::LoggedIn(client) = &self.client {
- for (jid, chat) in &self.chats {
+ for (jid, chat) in &self.chats_list {
let mut open = false;
if let Some(open_chat) = &self.open_chat {
- if open_chat.chat().user().jid == *jid {
+ if open_chat.chat.user.jid == *jid {
open = true;
}
}
let chat_list_item =
- chat_list_item(client.files_root(), chat.as_ref().borrow(), open);
+ chat_list_item(&self.roster, client.files_root(), chat, open);
chats_list = chats_list.push(chat_list_item);
}
}
@@ -1345,10 +1175,6 @@ impl Macaw {
color: color!(0x392c25),
text: color!(0xdcdcdc),
},
- weakest: Pair {
- color: color!(0xdcdcdc),
- text: color!(0x392c25),
- },
weak: Pair {
color: color!(0xdcdcdc),
text: color!(0x392c25),
@@ -1357,10 +1183,6 @@ impl Macaw {
color: color!(0x364b3b),
text: color!(0xdcdcdc),
},
- strongest: Pair {
- color: color!(0x364b3b),
- text: color!(0xdcdcdc),
- },
},
primary: Primary {
base: Pair {
@@ -1404,20 +1226,6 @@ impl Macaw {
text: color!(0xdcdcdc),
},
},
- warning: Warning {
- base: Pair {
- color: color!(0xFF9D00),
- text: color!(0x000000),
- },
- weak: Pair {
- color: color!(0xFF9D00),
- text: color!(0x000000),
- },
- strong: Pair {
- color: color!(0xFF9D00),
- text: color!(0x000000),
- },
- },
danger: Danger {
base: Pair {
color: color!(0xC1173C),
@@ -1479,28 +1287,33 @@ where
stack![base.into(), opaque(mouse_area)].into()
}
-fn chat_list_item<'a, C>(file_root: &'a Path, chat: C, open: bool) -> Element<'a, Message>
-where
- C: Deref<Target = MacawChat> + 'a,
-{
+fn chat_list_item<'a>(
+ roster: &HashMap<JID, MacawContact>,
+ file_root: &'a Path,
+ chat_list_item: &'a ChatListItem,
+ open: bool,
+) -> Element<'a, Message> {
let name: String;
- if let Some(Some(contact_name)) = chat.user().contact().map(|contact| contact.name.clone()) {
- name = contact_name
- } else if let Some(nick) = &chat.user().nick {
+ if let Some(Some(contact_name)) = roster
+ .get(chat_list_item.correspondent())
+ .map(|contact| &contact.name)
+ {
+ name = contact_name.clone()
+ } else if let Some(nick) = &chat_list_item.user.nick {
name = nick.clone()
} else {
- name = chat.correspondent().to_string();
+ name = chat_list_item.correspondent().to_string();
}
let avatar: Option<String>;
- if let Some(user_avatar) = &chat.user().avatar {
+ if let Some(user_avatar) = &chat_list_item.user.avatar {
avatar = Some(user_avatar.clone())
} else {
avatar = None
}
let latest_message_text: Option<(String, String)>;
- if let Some(latest_message) = chat.latest_message() {
+ if let Some(latest_message) = &chat_list_item.latest_message {
let message = latest_message.body.body.replace("\n", " ");
let date = latest_message.timestamp.naive_local();
let now = Local::now().naive_local();
@@ -1527,7 +1340,9 @@ where
}
let avatar_image = if let Some(avatar) = avatar {
- let path = file_root.join(avatar);
+ let mut path = file_root.join(avatar);
+ path.set_extension("jpg");
+ info!("got avatar: {:?}", path);
Some(image(path).width(48).height(48))
} else {
None
@@ -1570,7 +1385,8 @@ where
text(name).into()
}
};
- let mut button = button(content).on_press(Message::ToggleChat(chat.correspondent.clone()));
+ let mut button =
+ button(content).on_press(Message::ToggleChat(chat_list_item.correspondent().clone()));
if open {
button = button.style(|theme: &Theme, status| {
let palette = theme.extended_palette();
diff --git a/src/message_view.rs b/src/message_view.rs
index 4ebda83..e936b69 100644
--- a/src/message_view.rs
+++ b/src/message_view.rs
@@ -1,54 +1,27 @@
-use std::{
- borrow::{Borrow, Cow},
- cell::{Ref, RefCell},
- ops::Deref,
- rc::Rc,
-};
-
use chrono::NaiveDate;
-use filamento::chat::Message as ChatMessage;
use iced::{
- alignment::Horizontal::{self, Right},
border::Radius,
- color,
- theme::Palette,
- widget::{
- button, column, container, horizontal_space, row, scrollable, text, text_editor,
- text_editor::Content, text_input, Column,
- },
+ widget::{button, column, container, row, scrollable, text, text_editor, text_editor::Content},
Border, Color, Element,
Length::{Fill, Shrink},
Theme,
};
use indexmap::IndexMap;
-use jid::JID;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{MacawChat, MacawMessage};
pub struct MessageView {
+ // references chats, users
+ pub chat: MacawChat,
+ // references users, messages
+ pub messages: IndexMap<Uuid, MacawMessage>,
pub config: Config,
- pub chat: Rc<RefCell<MacawChat>>,
- pub messages: Vec<Rc<RefCell<MacawMessage>>>,
pub new_message: Content,
pub shift_pressed: bool,
}
-impl MessageView {
- pub fn chat(&self) -> Ref<'_, MacawChat> {
- self.chat.as_ref().borrow()
- }
-
- pub fn messages(
- &self,
- ) -> impl Iterator<Item = impl Deref<Target = MacawMessage> + use<'_>> + use<'_> {
- self.messages
- .iter()
- .map(|message| message.as_ref().borrow())
- }
-}
-
#[derive(Serialize, Deserialize, Clone)]
pub struct Config {
pub send_on_enter: bool,
@@ -64,8 +37,8 @@ impl Default for Config {
#[derive(Debug, Clone)]
pub enum Message {
- // MessageHistory(Vec<Rc<RefCell<MacawMessage>>>),
- // Message(Rc<RefCell<MacawMessage>>),
+ MessageHistory(Vec<MacawMessage>),
+ Message(MacawMessage),
MessageCompose(text_editor::Action),
SendMessage(String),
}
@@ -76,11 +49,11 @@ pub enum Action {
}
impl MessageView {
- pub fn new(chat: Rc<RefCell<MacawChat>>, config: &super::Config) -> Self {
+ pub fn new(chat: MacawChat, config: &super::Config) -> Self {
Self {
chat,
// TODO: save position in message history
- messages: Vec::new(),
+ messages: IndexMap::new(),
// TODO: save draft (as part of chat struct?)
new_message: Content::new(),
config: config.message_view_config.clone(),
@@ -120,13 +93,52 @@ impl MessageView {
self.new_message = Content::new();
Action::SendMessage(m)
}
+ Message::MessageHistory(macaw_messages) => {
+ if self.messages.is_empty() {
+ self.messages = macaw_messages
+ .into_iter()
+ .map(|message| (message.id, message))
+ .collect()
+ } else {
+ for message in macaw_messages {
+ let index = match self
+ .messages
+ .binary_search_by(|_, value| value.timestamp.cmp(&message.timestamp))
+ {
+ Ok(i) => i,
+ Err(i) => i,
+ };
+ self.messages.insert_before(index, message.id, message);
+ }
+ }
+ Action::None
+ }
+ Message::Message(macaw_message) => {
+ if let Some((_, last)) = self.messages.last() {
+ if last.timestamp < macaw_message.timestamp {
+ self.messages.insert(macaw_message.id, macaw_message);
+ } else {
+ let index = match self.messages.binary_search_by(|_, value| {
+ value.timestamp.cmp(&macaw_message.timestamp)
+ }) {
+ Ok(i) => i,
+ Err(i) => i,
+ };
+ self.messages
+ .insert_before(index, macaw_message.id, macaw_message);
+ }
+ } else {
+ self.messages.insert(macaw_message.id, macaw_message);
+ }
+ Action::None
+ }
}
}
pub fn view(&self) -> Element<Message> {
let mut messages_view = column![].spacing(8).padding(8);
let mut latest_date = NaiveDate::MIN;
- for message in self.messages() {
+ for (_id, message) in &self.messages {
let message_date = message.timestamp.naive_local().date();
if message_date > latest_date {
latest_date = message_date;
@@ -154,14 +166,11 @@ impl MessageView {
.into()
}
- pub fn message<'a, 'b, M>(&'a self, message: M) -> Element<'b, Message>
- where
- M: Deref<Target = MacawMessage> + 'b,
- {
+ pub fn message<'a>(&'a self, message: &MacawMessage) -> Element<'a, Message> {
let timestamp = message.timestamp.naive_local();
let timestamp = timestamp.time().format("%H:%M").to_string();
- if self.chat().user().jid == message.user().jid {
+ if self.chat.user.jid == message.from.jid {
container(
container(
column![