diff --git a/Cargo.lock b/Cargo.lock index 82e3f8e9e..445263e88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,12 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "async-channel" @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base64" @@ -68,7 +68,7 @@ version = "0.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.8.0", "cexpr", "clang-sys", "lazy_static", @@ -91,9 +91,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "block" @@ -109,15 +109,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.16.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder-lite" @@ -127,33 +121,35 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cairo-rs" -version = "0.19.4" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ac2a4d0e69036cf0062976f6efcba1aaee3e448594e6514bb2ddf87acce562" +checksum = "ae50b5510d86cf96ac2370e66d8dc960882f3df179d6a5a1e52bd94a1416c0f7" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.8.0", "cairo-sys-rs", "glib", "libc", - "thiserror", ] [[package]] name = "cairo-sys-rs" -version = "0.19.2" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3bb3119664efbd78b5e6c93957447944f16bdbced84c17a9f41c7829b81e64" +checksum = "f18b6bb8e43c7eb0f2aac7976afe0c61b6f5fc2ab7bc4c139537ea56c92290df" dependencies = [ "glib-sys", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "cc" -version = "1.0.99" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -174,6 +170,16 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cfg-expr" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d4ba6e40bd1184518716a6e1a781bf9160e286d219ccdb8ab2612e74cfe4789" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -182,9 +188,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -215,9 +221,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "crc32fast" @@ -230,15 +236,15 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -246,9 +252,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", @@ -260,9 +266,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", @@ -309,9 +315,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -320,9 +326,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ "event-listener", "pin-project-lite", @@ -330,9 +336,9 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] @@ -349,9 +355,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -365,9 +371,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -379,9 +385,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -389,15 +395,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -406,15 +412,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -423,21 +429,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-macro", @@ -450,9 +456,9 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.19.2" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6a23f8a0b5090494fd04924662d463f8386cc678dd3915015a838c1a3679b92" +checksum = "b6efc7705f7863d37b12ad6974cbb310d35d054f5108cdc1e69037742f573c4c" dependencies = [ "gdk-pixbuf-sys", "gio", @@ -462,22 +468,22 @@ dependencies = [ [[package]] name = "gdk-pixbuf-sys" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fdbf021f8b9d19e30fb9ea6d6e5f2b6a712fe4645417c69f86f6ff1e1444a8f" +checksum = "67f2587c9202bf997476bbba6aaed4f78a11538a2567df002a5f57f5331d0b5c" dependencies = [ "gio-sys", "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "gdk4" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db265c9dd42d6a371e09e52deab3a84808427198b86ac792d75fd35c07990a07" +checksum = "d0196720118f880f71fe7da971eff58cc43a89c9cf73f46076b7cb1e60889b15" dependencies = [ "cairo-rs", "gdk-pixbuf", @@ -490,9 +496,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9418fb4e8a67074919fe7604429c45aa74eb9df82e7ca529767c6d4e9dc66dd" +checksum = "60b0e1340bd15e7a78810cf39fed9e5d85f0a8f80b1d999d384ca17dcc452b60" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -502,7 +508,7 @@ dependencies = [ "libc", "pango-sys", "pkg-config", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -517,9 +523,9 @@ dependencies = [ [[package]] name = "gettext-sys" -version = "0.21.3" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c63ce2e00f56a206778276704bbe38564c8695249fdc8f354b4ef71c57c3839d" +checksum = "f7b8797f28f2dabfbe2caadb6db4f7fd739e251b5ede0a2ba49e506071edcf67" dependencies = [ "cc", "temp-dir", @@ -527,9 +533,9 @@ dependencies = [ [[package]] name = "gio" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be548be810e45dd31d3bbb89c6210980bb7af9bca3ea1292b5f16b75f8e394a7" +checksum = "a517657589a174be9f60c667f1fec8b7ac82ed5db4ebf56cf073a3b5955d8e2e" dependencies = [ "futures-channel", "futures-core", @@ -540,29 +546,28 @@ dependencies = [ "libc", "pin-project-lite", "smallvec", - "thiserror", ] [[package]] name = "gio-sys" -version = "0.19.5" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4bdbef451b0f0361e7f762987cc6bebd5facab1d535e85a3cf1115dfb08db40" +checksum = "8446d9b475730ebef81802c1738d972db42fde1c5a36a627ebc4d665fc87db04" dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 7.0.3", "windows-sys", ] [[package]] name = "glib" -version = "0.19.7" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52355166df21c7ed16b6a01f615669c7911ed74e27ef60eba339c0d2da12490" +checksum = "f969edf089188d821a30cde713b6f9eb08b20c63fc2e584aba2892a7984a8cc0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.8.0", "futures-channel", "futures-core", "futures-executor", @@ -575,14 +580,13 @@ dependencies = [ "libc", "memchr", "smallvec", - "thiserror", ] [[package]] name = "glib-macros" -version = "0.19.7" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70025dbfa1275cf7d0531c3317ba6270dae15d87e63342229d638246ff45202e" +checksum = "715601f8f02e71baef9c1f94a657a9a77c192aea6097cf9ae7e5e177cd8cde68" dependencies = [ "heck", "proc-macro-crate", @@ -593,36 +597,36 @@ dependencies = [ [[package]] name = "glib-sys" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767d23ead9bbdfcbb1c2242c155c8128a7d13dde7bf69c176f809546135e2282" +checksum = "b360ff0f90d71de99095f79c526a5888c9c92fc9ee1b19da06c6f5e75f0c2a53" dependencies = [ "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "gobject-sys" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3787b0bfacca12bb25f8f822b0dbee9f7e4a86e6469a29976d332d2c14c945b" +checksum = "67a56235e971a63bfd75abb13ef70064e1346388723422a68580d8a6fbac6423" dependencies = [ "glib-sys", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "graphene-rs" -version = "0.19.2" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4d388e96c5f29e2b2f67045d229ddf826d0a8d6d282f94ed3b34452222c91" +checksum = "f39d3bcd2e24fd9c2874a56f277b72c03e728de9bdc95a8d4ef4c962f10ced98" dependencies = [ "glib", "graphene-sys", @@ -631,21 +635,21 @@ dependencies = [ [[package]] name = "graphene-sys" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60e7381afdd7be43bd10a89d3b6741d162aabbca3a8db73505afb6a3aea59d" +checksum = "11a68d39515bf340e879b72cecd4a25c1332557757ada6e8aba8654b4b81d23a" dependencies = [ "glib-sys", "libc", "pkg-config", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "gsk4" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7563884bf6939f4468e5d94654945bdd9afcaf8c3ba4c5dd17b5342b747221be" +checksum = "32b9188db0a6219e708b6b6e7225718e459def664023dbddb8395ca1486d8102" dependencies = [ "cairo-rs", "gdk4", @@ -658,9 +662,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23024bf2636c38bbd1f822f58acc9d1c25b28da896ff0f291a1a232d4272b3dc" +checksum = "bca10fc65d68528a548efa3d8747934adcbe7058b73695c9a7f43a25352fce14" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -669,13 +673,13 @@ dependencies = [ "graphene-sys", "libc", "pango-sys", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "gtk-rlottie" -version = "0.8.1" -source = "git+https://github.com/paper-plane-developers/gtk-rlottie-rs.git?tag=v0.8.1#fc3116fe1bdac12bb3eb5bf7e6ce2affbe84f55b" +version = "0.9.0" +source = "git+https://github.com/paper-plane-developers/gtk-rlottie-rs.git?tag=v0.9.0#708a96256519f64da3b0f44ca8371f312f573893" dependencies = [ "async-channel", "flate2", @@ -685,9 +689,9 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b04e11319b08af11358ab543105a9e49b0c491faca35e2b8e7e36bfba8b671ab" +checksum = "b697ff938136625f6acf75f01951220f47a45adcf0060ee55b4671cf734dac44" dependencies = [ "cairo-rs", "field-offset", @@ -706,9 +710,9 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec655a7ef88d8ce9592899deb8b2d0fa50bab1e6dd69182deb764e643c522408" +checksum = "0ed1786c4703dd196baf7e103525ce0cf579b3a63a0570fe653b7ee6bac33999" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -718,9 +722,9 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.8.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c8aa86b7f85ea71d66ea88c1d4bae1cfacf51ca4856274565133838d77e57b5" +checksum = "3af4b680cee5d2f786a2f91f1c77e95ecf2254522f0ca4edf3a2dce6cb35cecf" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -732,7 +736,7 @@ dependencies = [ "gsk4-sys", "libc", "pango-sys", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -743,9 +747,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -755,9 +759,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -782,9 +786,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -811,12 +815,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "image" -version = "0.25.1" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", - "byteorder", + "byteorder-lite", "image-webp", "num-traits", "png", @@ -826,12 +830,12 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" dependencies = [ "byteorder-lite", - "thiserror", + "quick-error", ] [[package]] @@ -847,20 +851,20 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "serde", ] [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" dependencies = [ "hermit-abi", "libc", @@ -869,24 +873,25 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -896,11 +901,10 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libadwaita" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b4990248b9e1ec5e72094a2ccaea70ec3809f88f6fd52192f2af306b87c5d9" +checksum = "8611ee9fb85e7606c362b513afcaf5b59853f79e4d98caaaf581d99465014247" dependencies = [ - "gdk-pixbuf", "gdk4", "gio", "glib", @@ -912,9 +916,9 @@ dependencies = [ [[package]] name = "libadwaita-sys" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a748e4e92be1265cd9e93d569c0b5dfc7814107985aa6743d670ab281ea1a8" +checksum = "b099a223560118d4d4fa04b6d23f3ea5b7171fe1d83dfb7e6b45b54cdfc83af9" dependencies = [ "gdk4-sys", "gio-sys", @@ -923,20 +927,20 @@ dependencies = [ "gtk4-sys", "libc", "pango-sys", - "system-deps", + "system-deps 7.0.3", ] [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets", @@ -944,9 +948,9 @@ dependencies = [ [[package]] name = "libshumate" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd77c1202aaccef5460f4ca95b3b3c117f85986c942127e4e518c47058a6eaf6" +checksum = "fc9921cc829fb2d546bd6a3a158a4134002098887e0bb01ceb4535521af610ec" dependencies = [ "gdk-pixbuf", "gdk4", @@ -959,9 +963,9 @@ dependencies = [ [[package]] name = "libshumate-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5765221e416ebe7b5e9c5bd7e8dd09ca9e920b012474ca8f3da18f8e13c4a5" +checksum = "b238767323bdd28dc72471fa8a512ad0ae99a18d9668deb626c55f373f7aff81" dependencies = [ "gdk-pixbuf-sys", "gdk4-sys", @@ -970,7 +974,7 @@ dependencies = [ "gobject-sys", "gtk4-sys", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -988,9 +992,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "malloc_buf" @@ -1024,11 +1028,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -1088,14 +1092,14 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "origami" -version = "0.8.1" -source = "git+https://github.com/paper-plane-developers/origami.git?tag=v0.8.1#861cfa7a83375a35a569048e0f00b398ac290cc3" +version = "0.9.0" +source = "git+https://github.com/paper-plane-developers/origami.git?tag=v0.9.0#c375d18b62f33315f2184030007f52897adbd7c3" dependencies = [ "gtk4", "libadwaita", @@ -1104,9 +1108,9 @@ dependencies = [ [[package]] name = "pango" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504ce6e805439ea2c6791168fe7ef8e3da0c1b2ef82c44bc450dbc330592920d" +checksum = "9e89bd74250a03a05cec047b43465469102af803be2bf5e5a1088f8b8455e087" dependencies = [ "gio", "glib", @@ -1116,14 +1120,14 @@ dependencies = [ [[package]] name = "pango-sys" -version = "0.19.5" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4829555bdbb83692ddeaf5a6927fb2d025c8131e5ecaa4f7619fff6985d3505" +checksum = "71787e0019b499a5eda889279e4adb455a4f3fdd6870cd5ab7f4a5aa25df6699" dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -1138,7 +1142,7 @@ dependencies = [ "gtk-rlottie", "gtk4", "image", - "indexmap 2.2.6", + "indexmap 2.7.1", "libadwaita", "libshumate", "locale_config", @@ -1154,9 +1158,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "peeking_take_while" @@ -1166,9 +1170,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1178,15 +1182,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.13" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1213,9 +1217,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", "syn", @@ -1223,27 +1227,27 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "qrcode-generator" -version = "4.1.9" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d06cb9646c7a14096231a2474d7f21e5e8c13de090c68d13bde6157cfe7f159" +checksum = "faf0051849b5465059b75f59d388c7318aad6554701b74ecf02afc2573b0306c" dependencies = [ "html-escape", "qrcodegen", @@ -1255,20 +1259,26 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1278,9 +1288,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1289,15 +1299,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" [[package]] name = "rlottie" @@ -1327,13 +1337,19 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + [[package]] name = "ryu" version = "1.0.18" @@ -1342,24 +1358,24 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "semver" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -1368,35 +1384,36 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] [[package]] name = "serde_with" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.7.1", "serde", "serde_derive", "serde_json", @@ -1406,9 +1423,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ "darling", "proc-macro2", @@ -1451,9 +1468,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -1466,7 +1483,20 @@ version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ - "cfg-expr", + "cfg-expr 0.15.8", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "system-deps" +version = "7.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005" +dependencies = [ + "cfg-expr 0.17.2", "heck", "pkg-config", "toml", @@ -1475,9 +1505,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tdlib" @@ -1491,7 +1521,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "system-deps", + "system-deps 6.2.2", "tdlib-tl-gen", "tdlib-tl-parser", ] @@ -1513,9 +1543,9 @@ checksum = "32326b5315ed2b469f6dc688dc58e7e13a3adef9be08ed20f6e1135a6540bec1" [[package]] name = "temp-dir" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f227968ec00f0e5322f9b8173c7a0cbcff6181a0a5b28e9892491c286277231" +checksum = "bc1ee6eef34f12f765cb94725905c6312b6610ab2b0940889cfe58dae7bc3c72" [[package]] name = "termcolor" @@ -1528,18 +1558,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", @@ -1548,9 +1578,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -1569,9 +1599,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -1579,60 +1609,49 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.14", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" -dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.1", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow", ] [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "utf8-width" @@ -1648,23 +1667,24 @@ checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -1673,9 +1693,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1683,9 +1703,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -1696,9 +1716,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "winapi" @@ -1718,9 +1741,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys", ] @@ -1742,18 +1765,18 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1767,66 +1790,57 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "winnow" -version = "0.5.40" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" dependencies = [ "memchr", ] @@ -1839,9 +1853,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" [[package]] name = "zune-jpeg" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index 97d5744a4..f37bc7c4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,26 +5,26 @@ authors = ["Marco Melorio ", "Marcus Behrendt move |_, _| { - // This is needed to trigger the delete event and saving the window state - app.main_window().close(); - app.quit(); - })); + action_quit.connect_activate(clone!( + #[weak(rename_to = app)] + self, + move |_, _| { + // This is needed to trigger the delete event and saving the window state + app.main_window().close(); + app.quit(); + } + )); self.add_action(&action_quit); // About let action_about = gio::SimpleAction::new("about", None); - action_about.connect_activate(clone!(@weak self as app => move |_, _| { - app.show_about_dialog(); - })); + action_about.connect_activate(clone!( + #[weak(rename_to = app)] + self, + move |_, _| { + app.show_about_dialog(); + } + )); self.add_action(&action_about); // Select chat let action_select_chat = gio::SimpleAction::new("select-chat", Some(glib::VariantTy::new("(ix)").unwrap())); - action_select_chat.connect_activate(clone!(@weak self as app => move |_, data| { - let (client_id, chat_id) = data.unwrap().get().unwrap(); - app.main_window().select_chat(client_id, chat_id); - })); + action_select_chat.connect_activate(clone!( + #[weak(rename_to = app)] + self, + move |_, data| { + let (client_id, chat_id) = data.unwrap().get().unwrap(); + app.main_window().select_chat(client_id, chat_id); + } + )); self.add_action(&action_select_chat); // New login on production server let action_new_login_production_server = gio::SimpleAction::new("new-login-production-server", None); - action_new_login_production_server.connect_activate( - clone!(@weak self as app => move |_, _| { - app.main_window().client_manager_view().add_new_client(false); - }), - ); + action_new_login_production_server.connect_activate(clone!( + #[weak(rename_to = app)] + self, + move |_, _| { + app.main_window() + .client_manager_view() + .add_new_client(false); + } + )); self.add_action(&action_new_login_production_server); // New login on test server let action_new_login_test_server = gio::SimpleAction::new("new-login-test-server", None); - action_new_login_test_server.connect_activate(clone!(@weak self as app => move |_, _| { - app.main_window().client_manager_view().add_new_client(true); - })); + action_new_login_test_server.connect_activate(clone!( + #[weak(rename_to = app)] + self, + move |_, _| { + app.main_window().client_manager_view().add_new_client(true); + } + )); self.add_action(&action_new_login_test_server); } @@ -154,8 +175,7 @@ impl Application { } fn show_about_dialog(&self) { - let about = adw::AboutWindow::builder() - .transient_for(&self.main_window()) + let about = adw::AboutDialog::builder() .application_name("Paper Plane") .application_icon(config::APP_ID) .version(config::VERSION) @@ -201,6 +221,6 @@ impl Application { )), ); - about.present(); + about.present(Some(&self.main_window())); } } diff --git a/src/meson.build b/src/meson.build index ad2faf7ec..28d3be6f1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -72,7 +72,7 @@ test ( ], env: [ 'CARGO_HOME=@0@'.format(cargo_home), - 'PATH=/app/bin:/usr/bin:/usr/lib/sdk/llvm16/bin:/usr/lib/sdk/rust-stable/bin', + 'PATH=/app/bin:/usr/bin:/usr/lib/sdk/llvm18/bin:/usr/lib/sdk/rust-stable/bin', ], timeout: 300, # Give cargo more time ) diff --git a/src/model/chat_history_model.rs b/src/model/chat_history_model.rs index 82ca8946c..7ec019de6 100644 --- a/src/model/chat_history_model.rs +++ b/src/model/chat_history_model.rs @@ -88,12 +88,20 @@ impl ChatHistoryModel { obj.imp().chat.set(Some(chat)); - chat.connect_new_message(clone!(@weak obj => move |_, message| { - obj.push_front(message); - })); - chat.connect_deleted_message(clone!(@weak obj => move |_, message| { - obj.remove(message); - })); + chat.connect_new_message(clone!( + #[weak] + obj, + move |_, message| { + obj.push_front(message); + } + )); + chat.connect_deleted_message(clone!( + #[weak] + obj, + move |_, message| { + obj.remove(message); + } + )); obj } diff --git a/src/model/chat_list.rs b/src/model/chat_list.rs index 2d4edcae7..ff84b77e4 100644 --- a/src/model/chat_list.rs +++ b/src/model/chat_list.rs @@ -142,19 +142,27 @@ impl ChatList { } pub(crate) fn fetch(&self) { - utils::spawn(clone!(@weak self as obj => async move { - let result = tdlib::functions::load_chats(Some(obj.list_type().0), 20, obj.session_().client_().id()) + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + let result = tdlib::functions::load_chats( + Some(obj.list_type().0), + 20, + obj.session_().client_().id(), + ) .await; - if let Err(err) = result { - // Error 404 means that all chats have been loaded - if err.code != 404 { - log::error!("Received an error for LoadChats: {}", err.code); + if let Err(err) = result { + // Error 404 means that all chats have been loaded + if err.code != 404 { + log::error!("Received an error for LoadChats: {}", err.code); + } + } else { + obj.fetch(); } - } else { - obj.fetch(); } - })); + )); } pub(crate) fn update_chat_position( diff --git a/src/model/client.rs b/src/model/client.rs index fd99d6fad..38042889c 100644 --- a/src/model/client.rs +++ b/src/model/client.rs @@ -68,9 +68,13 @@ mod imp { let obj = &*self.obj(); - utils::spawn(clone!(@weak obj => async move { - obj.init().await; - })); + utils::spawn(clone!( + #[weak] + obj, + async move { + obj.init().await; + } + )); obj.set_state(model::ClientStateAuth::from(obj).upcast()); } } @@ -256,26 +260,36 @@ impl Client { match update { Update::AuthorizationState(state) => match state.authorization_state { AuthorizationState::WaitTdlibParameters => { - utils::spawn(clone!(@weak self as obj => async move { - if let Err(e) = obj.send_tdlib_parameters().await { - log::error!("Failed sensing tdlib parameters: {e:?}"); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + if let Err(e) = obj.send_tdlib_parameters().await { + log::error!("Failed sensing tdlib parameters: {e:?}"); + } } - })); + )); } AuthorizationState::Ready => { - utils::spawn(clone!(@weak self as obj => async move { - let tdlib::enums::User::User(me) = - tdlib::functions::get_me(obj.id()).await.unwrap(); - - let state = model::ClientStateSession::new(&obj, me); - while let Some(update) = obj.imp().queued_updates.borrow_mut().pop_front() { - state.handle_update(update); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + let tdlib::enums::User::User(me) = + tdlib::functions::get_me(obj.id()).await.unwrap(); + + let state = model::ClientStateSession::new(&obj, me); + while let Some(update) = + obj.imp().queued_updates.borrow_mut().pop_front() + { + state.handle_update(update); + } + + obj.set_state(state.upcast()); + + obj.client_manager_().on_client_logged_in(&obj); } - - obj.set_state(state.upcast()); - - obj.client_manager_().on_client_logged_in(&obj); - })); + )); } AuthorizationState::Closing => { self.set_state(model::ClientStateLoggingOut::default().upcast()); diff --git a/src/model/client_manager.rs b/src/model/client_manager.rs index 4984c70d3..584645fa6 100644 --- a/src/model/client_manager.rs +++ b/src/model/client_manager.rs @@ -267,17 +267,23 @@ impl ClientManager { fn start_tdlib_thread(&self) { let (sender, receiver) = async_channel::unbounded(); - glib::spawn_future_local(clone!(@weak self as obj => async move { - while let Ok((update, client_id)) = receiver.recv().await { - obj.handle_update(update, client_id); + glib::spawn_future_local(clone!( + #[weak(rename_to = obj)] + self, + async move { + while let Ok((update, client_id)) = receiver.recv().await { + obj.handle_update(update, client_id); + } } - })); + )); thread::spawn(move || loop { if let Some((update, client_id)) = tdlib::receive() { - glib::spawn_future(clone!(@strong sender => async move { - _ = sender.send((update, client_id)).await; - })); + glib::spawn_future(clone!( + #[strong] + sender, + async move { _ = sender.send((update, client_id)).await } + )); } }); } diff --git a/src/model/client_state_auth_code.rs b/src/model/client_state_auth_code.rs index 6f27c5044..b940f0f56 100644 --- a/src/model/client_state_auth_code.rs +++ b/src/model/client_state_auth_code.rs @@ -70,17 +70,23 @@ mod imp { let source_id = glib::timeout_add_seconds_local( 1, - clone!(@weak obj => @default-return glib::ControlFlow::Break, move || { - let imp = obj.imp(); - - imp.set_countdown(obj.countdown() - 1); - glib::ControlFlow::from(if obj.countdown() == 0 { - imp.stop_code_next_type_countdown(); - false - } else { - true - }) - }), + clone!( + #[weak] + obj, + #[upgrade_or] + glib::ControlFlow::Break, + move || { + let imp = obj.imp(); + + imp.set_countdown(obj.countdown() - 1); + glib::ControlFlow::from(if obj.countdown() == 0 { + imp.stop_code_next_type_countdown(); + false + } else { + true + }) + } + ), ); self.countdown_source_id.replace(Some(source_id)); } diff --git a/src/model/client_state_session.rs b/src/model/client_state_session.rs index 6689f2f51..7f39c4a6a 100644 --- a/src/model/client_state_session.rs +++ b/src/model/client_state_session.rs @@ -74,24 +74,28 @@ mod imp { let obj = &*self.obj(); - utils::spawn(clone!(@weak obj => async move { - if let Err(e) = tdlib::functions::set_option( - "notification_group_count_max".to_string(), - Some(tdlib::enums::OptionValue::Integer(tdlib::types::OptionValueInteger { - value: 5, - })), - obj.client_().id(), - ) - .await - { - log::warn!( - "Error setting the notification_group_count_max option: {:?}", - e - ); - } + utils::spawn(clone!( + #[weak] + obj, + async move { + if let Err(e) = tdlib::functions::set_option( + "notification_group_count_max".to_string(), + Some(tdlib::enums::OptionValue::Integer( + tdlib::types::OptionValueInteger { value: 5 }, + )), + obj.client_().id(), + ) + .await + { + log::warn!( + "Error setting the notification_group_count_max option: {:?}", + e + ); + } - obj.fetch_chats(); - })); + obj.fetch_chats(); + } + )); } } @@ -316,17 +320,23 @@ impl ClientStateSession { entry.insert(vec![sender]); let client_id = self.client_().id(); - utils::spawn(clone!(@weak self as obj => async move { - let result = tdlib::functions::download_file(file_id, 5, 0, 0, false, client_id).await; - match result { - Ok(tdlib::enums::File::File(file)) => { - obj.handle_file_update(file); - } - Err(e) => { - log::warn!("Error downloading a file: {:?}", e); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + let result = + tdlib::functions::download_file(file_id, 5, 0, 0, false, client_id) + .await; + match result { + Ok(tdlib::enums::File::File(file)) => { + obj.handle_file_update(file); + } + Err(e) => { + log::warn!("Error downloading a file: {:?}", e); + } } } - })); + )); } } } diff --git a/src/ui/client_manager_view.rs b/src/ui/client_manager_view.rs index 9b5751f61..905f5f2e1 100644 --- a/src/ui/client_manager_view.rs +++ b/src/ui/client_manager_view.rs @@ -65,12 +65,15 @@ mod imp { let obj = &*self.obj(); - self.client_manager - .connect_client_removed(clone!(@weak obj => move |_, client| { + self.client_manager.connect_client_removed(clone!( + #[weak] + obj, + move |_, client| { if Some(client) == obj.active_client().as_ref() { obj.restore_last_session() } - })); + } + )); obj.restore_last_session(); } @@ -156,18 +159,22 @@ impl ClientManagerView { /// Sets the online status for the active logged in client. This will be called from the /// application `Window` when its active state has changed. pub(crate) fn set_active_client_online(&self) { - utils::spawn(clone!(@weak self as obj => async move { - if let Some(client) = obj.active_client() { - client - .set_online( - obj.root() - .and_downcast::() - .unwrap() - .is_active() - ) - .await; + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + if let Some(client) = obj.active_client() { + client + .set_online( + obj.root() + .and_downcast::() + .unwrap() + .is_active(), + ) + .await; + } } - })); + )); } pub(crate) fn select_chat(&self, client_id: ClientId, chat_id: ChatId) { diff --git a/src/ui/components/avatar.rs b/src/ui/components/avatar.rs index a0a0dcba6..49e8078c5 100644 --- a/src/ui/components/avatar.rs +++ b/src/ui/components/avatar.rs @@ -115,43 +115,65 @@ impl Avatar { let user_signal_group = glib::SignalGroup::new::(); user_signal_group.connect_notify_local( Some("type"), - clone!(@weak self as obj => move |_, _| { - obj.update_display_name(); - obj.update_avatar(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_display_name(); + obj.update_avatar(); + } + ), ); user_signal_group.connect_notify_local( Some("first-name"), - clone!(@weak self as obj => move |_, _| { - obj.update_display_name(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_display_name(); + } + ), ); user_signal_group.connect_notify_local( Some("last-name"), - clone!(@weak self as obj => move |_, _| { - obj.update_display_name(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_display_name(); + } + ), ); user_signal_group.connect_notify_local( Some("avatar"), - clone!(@weak self as obj => move|_, _| { - obj.update_avatar(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_avatar(); + } + ), ); imp.user_signal_group.set(user_signal_group).unwrap(); let chat_signal_group = glib::SignalGroup::new::(); chat_signal_group.connect_notify_local( Some("title"), - clone!(@weak self as obj => move |_, _| { - obj.update_display_name() - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| obj.update_display_name() + ), ); chat_signal_group.connect_notify_local( Some("avatar"), - clone!(@weak self as obj => move|_, _| { - obj.update_avatar(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_avatar(); + } + ), ); imp.chat_signal_group.set(chat_signal_group).unwrap(); @@ -166,9 +188,15 @@ impl Avatar { } else { let file_id = file.id; - utils::spawn(clone!(@weak self as obj, @weak session => async move { - obj.download_avatar(file_id, &session).await; - })); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + #[weak] + session, + async move { + obj.download_avatar(file_id, &session).await; + } + )); } } else { self.imp().avatar.set_custom_image(gdk::Paintable::NONE); diff --git a/src/ui/components/avatar_map_marker.rs b/src/ui/components/avatar_map_marker.rs index d746081ab..06ee65d73 100644 --- a/src/ui/components/avatar_map_marker.rs +++ b/src/ui/components/avatar_map_marker.rs @@ -67,9 +67,13 @@ mod imp { self.avatar.connect_notify_local( Some("item"), - clone!(@weak obj => move |_, _| { - obj.notify("user"); - }), + clone!( + #[weak] + obj, + move |_, _| { + obj.notify("user"); + } + ), ); } diff --git a/src/ui/components/circular_progress_bar.rs b/src/ui/components/circular_progress_bar.rs index 689652417..ecad6d99a 100644 --- a/src/ui/components/circular_progress_bar.rs +++ b/src/ui/components/circular_progress_bar.rs @@ -71,9 +71,16 @@ mod imp { obj.set_valign(gtk::Align::Center); let adw_style_manager = adw::StyleManager::default(); - adw_style_manager - .connect_high_contrast_notify(clone!(@weak obj => move |_| obj.queue_draw())); - adw_style_manager.connect_dark_notify(clone!(@weak obj => move |_| obj.queue_draw())); + adw_style_manager.connect_high_contrast_notify(clone!( + #[weak] + obj, + move |_| obj.queue_draw() + )); + adw_style_manager.connect_dark_notify(clone!( + #[weak] + obj, + move |_| obj.queue_draw() + )); } } diff --git a/src/ui/components/map_window.rs b/src/ui/components/map_window.rs index fb8b60d70..e8a2bbacc 100644 --- a/src/ui/components/map_window.rs +++ b/src/ui/components/map_window.rs @@ -69,16 +69,28 @@ mod imp { let obj = &*self.obj(); let viewport = obj.map().viewport(); - viewport.connect_zoom_level_notify(clone!(@weak obj => move |viewport| { - obj.update_zoom_actions(viewport); - obj.update_center_marker_animations_action(viewport); - })); - viewport.connect_latitude_notify(clone!(@weak obj => move |viewport| { - obj.update_center_marker_animations_action(viewport); - })); - viewport.connect_longitude_notify(clone!(@weak obj => move |viewport| { - obj.update_center_marker_animations_action(viewport); - })); + viewport.connect_zoom_level_notify(clone!( + #[weak] + obj, + move |viewport| { + obj.update_zoom_actions(viewport); + obj.update_center_marker_animations_action(viewport); + } + )); + viewport.connect_latitude_notify(clone!( + #[weak] + obj, + move |viewport| { + obj.update_center_marker_animations_action(viewport); + } + )); + viewport.connect_longitude_notify(clone!( + #[weak] + obj, + move |viewport| { + obj.update_center_marker_animations_action(viewport); + } + )); obj.update_zoom_actions(&viewport); } } @@ -177,15 +189,33 @@ impl MapWindow { .value_to(lon) .build(); - animation_zoom.connect_state_notify(clone!(@weak self as obj => move |_| { - obj.update_center_marker_animations(obj.imp().center_marker_animations[0].borrow_mut()); - })); - animation_lat.connect_state_notify(clone!(@weak self as obj => move |_| { - obj.update_center_marker_animations(obj.imp().center_marker_animations[1].borrow_mut()); - })); - animation_lon.connect_state_notify(clone!(@weak self as obj => move |_| { - obj.update_center_marker_animations(obj.imp().center_marker_animations[2].borrow_mut()); - })); + animation_zoom.connect_state_notify(clone!( + #[weak(rename_to = obj)] + self, + move |_| { + obj.update_center_marker_animations( + obj.imp().center_marker_animations[0].borrow_mut(), + ); + } + )); + animation_lat.connect_state_notify(clone!( + #[weak(rename_to = obj)] + self, + move |_| { + obj.update_center_marker_animations( + obj.imp().center_marker_animations[1].borrow_mut(), + ); + } + )); + animation_lon.connect_state_notify(clone!( + #[weak(rename_to = obj)] + self, + move |_| { + obj.update_center_marker_animations( + obj.imp().center_marker_animations[2].borrow_mut(), + ); + } + )); map.set_interactive(false); diff --git a/src/ui/components/message_entry.rs b/src/ui/components/message_entry.rs index 84ba7b994..a5ac5f347 100644 --- a/src/ui/components/message_entry.rs +++ b/src/ui/components/message_entry.rs @@ -103,14 +103,21 @@ mod imp { let obj = self.obj(); - self.placeholder - .connect_text_notify(clone!(@weak obj => move |_| obj.notify("placeholder-text"))); + self.placeholder.connect_text_notify(clone!( + #[weak] + obj, + move |_| obj.notify("placeholder-text") + )); // Handle the enter key to emit the "activate" signal if neither the "ctrl" nor the // "shift" modifier are pressed at the same time. let key_events = gtk::EventControllerKey::new(); - key_events.connect_key_pressed( - clone!(@weak obj => @default-return glib::Propagation::Proceed, move |_, key, _, modifier| { + key_events.connect_key_pressed(clone!( + #[weak] + obj, + #[upgrade_or] + glib::Propagation::Proceed, + move |_, key, _, modifier| { if !modifier.contains(gdk::ModifierType::CONTROL_MASK) && !modifier.contains(gdk::ModifierType::SHIFT_MASK) && (key == gdk::Key::Return || key == gdk::Key::KP_Enter) @@ -120,26 +127,35 @@ mod imp { } else { glib::Propagation::Proceed } - }), - ); + } + )); self.text_view.add_controller(key_events); let press = gtk::GestureClick::new(); - press.connect_pressed(clone!(@weak obj => move |_, _, _, _| { - obj.emit_by_name::<()>("emoji-button-press", &[&*obj.imp().emoji_button]); - })); + press.connect_pressed(clone!( + #[weak] + obj, + move |_, _, _, _| { + obj.emit_by_name::<()>("emoji-button-press", &[&*obj.imp().emoji_button]); + } + )); self.emoji_button.add_controller(press); - self.text_view - .buffer() - .connect_changed(clone!(@weak obj => move |_| { + self.text_view.buffer().connect_changed(clone!( + #[weak] + obj, + move |_| { obj.text_buffer_changed(); - })); + } + )); - self.text_view - .connect_paste_clipboard(clone!(@weak obj => move |_| { + self.text_view.connect_paste_clipboard(clone!( + #[weak] + obj, + move |_| { obj.emit_by_name::<()>("paste-clipboard", &[]); - })); + } + )); } fn dispose(&self) { diff --git a/src/ui/components/phone_number_input.rs b/src/ui/components/phone_number_input.rs index 9c70a2af9..49e14945b 100644 --- a/src/ui/components/phone_number_input.rs +++ b/src/ui/components/phone_number_input.rs @@ -122,109 +122,119 @@ mod imp { let entry_handler = Rc::new(RefCell::new(None)); combo_row_handler.replace(Some(self.combo_row.connect_selected_item_notify(clone!( - @weak obj, - @strong entry_handler, - => move |combo_row| - { - combo_row.set_subtitle(""); - - let imp = obj.imp(); - - let entry_handler = entry_handler.borrow(); - let entry_handler = entry_handler.as_ref().unwrap(); - - let (pos_start, pos_end) = imp.calling_code_bounds.get(); - let number_prefix = (0..pos_start).map(|_| ' ') - .chain(Some('+')) - .collect::(); - - let (number, pos_start, pos_end) = obj - .selected_country_info() - .map(|selected_country_info| { - let calling_codes = selected_country_info.calling_codes(); - let first_calling_code = calling_codes.first_or_empty(); - ( - [ - number_prefix.as_str(), - first_calling_code, - obj.number() - .chars() - .skip(pos_end) - .collect::() - .as_str(), - ] - .concat(), - pos_start, - pos_start + first_calling_code.chars().count() + 1, - ) - }) - .unwrap_or((number_prefix, 0, 1)); - - imp.entry_row.block_signal(entry_handler); - obj.set_number(&number); - imp.entry_row.unblock_signal(entry_handler); + #[weak] + obj, + #[strong] + entry_handler, + move |combo_row| { + combo_row.set_subtitle(""); - imp.calling_code_bounds.set((pos_start, pos_end)); + let imp = obj.imp(); - obj.highlight_calling_code(); - })))); + let entry_handler = entry_handler.borrow(); + let entry_handler = entry_handler.as_ref().unwrap(); - // Format the phone number and reset the cursor. - entry_handler.replace(Some(self.entry_row.connect_changed(clone!( - @weak obj, - @strong combo_row_handler, - => move |_| - { - if let Some(ref model) = obj.model() { - let imp = obj.imp(); + let (pos_start, pos_end) = imp.calling_code_bounds.get(); + let number_prefix = (0..pos_start) + .map(|_| ' ') + .chain(Some('+')) + .collect::(); - let combo_row_handler = combo_row_handler.borrow(); - let combo_row_handler = combo_row_handler.as_ref().unwrap(); - - let number = obj.number(); - let (text_pos_start, text_pos_end, list_pos) = match number - .char_indices() - .find(|(_, c)| !c.is_whitespace()) - { - Some((text_pos_start, '+')) => { - let analysis = model.analyze_for_calling_code( - number - .chars() - .skip(text_pos_start + 1) - .collect::() - .trim_end(), - obj.preferred_country_code().as_deref(), - ); + let (number, pos_start, pos_end) = obj + .selected_country_info() + .map(|selected_country_info| { + let calling_codes = selected_country_info.calling_codes(); + let first_calling_code = calling_codes.first_or_empty(); ( - text_pos_start, - text_pos_start as u32 + analysis.code_len + 1, - analysis.list_pos, + [ + number_prefix.as_str(), + first_calling_code, + obj.number() + .chars() + .skip(pos_end) + .collect::() + .as_str(), + ] + .concat(), + pos_start, + pos_start + first_calling_code.chars().count() + 1, ) - } - _ => (0, 0, None), - }; + }) + .unwrap_or((number_prefix, 0, 1)); - imp.combo_row.block_signal(combo_row_handler); - obj.set_selected_country_code(list_pos); - imp.combo_row.unblock_signal(combo_row_handler); + imp.entry_row.block_signal(entry_handler); + obj.set_number(&number); + imp.entry_row.unblock_signal(entry_handler); - imp.calling_code_bounds.set((text_pos_start, text_pos_end as usize)); + imp.calling_code_bounds.set((pos_start, pos_end)); obj.highlight_calling_code(); } - })))); + )))); + + // Format the phone number and reset the cursor. + entry_handler.replace(Some(self.entry_row.connect_changed(clone!( + #[weak] + obj, + #[strong] + combo_row_handler, + move |_| { + if let Some(ref model) = obj.model() { + let imp = obj.imp(); + + let combo_row_handler = combo_row_handler.borrow(); + let combo_row_handler = combo_row_handler.as_ref().unwrap(); + + let number = obj.number(); + let (text_pos_start, text_pos_end, list_pos) = + match number.char_indices().find(|(_, c)| !c.is_whitespace()) { + Some((text_pos_start, '+')) => { + let analysis = model.analyze_for_calling_code( + number + .chars() + .skip(text_pos_start + 1) + .collect::() + .trim_end(), + obj.preferred_country_code().as_deref(), + ); + ( + text_pos_start, + text_pos_start as u32 + analysis.code_len + 1, + analysis.list_pos, + ) + } + _ => (0, 0, None), + }; + + imp.combo_row.block_signal(combo_row_handler); + obj.set_selected_country_code(list_pos); + imp.combo_row.unblock_signal(combo_row_handler); + + imp.calling_code_bounds + .set((text_pos_start, text_pos_end as usize)); + + obj.highlight_calling_code(); + } + } + )))); // We give focus the the phone number entry as soon as the user has selected an country // from the combo box. let focus_events = gtk::EventControllerFocus::new(); - focus_events.connect_leave(clone!(@weak obj => move |_| { - // We need to set the cursor position at the end on the next idle. - glib::idle_add_local_once(clone!( - @weak obj => move || { - obj.imp().entry_row.set_position(i32::MAX); - } - )); - })); + focus_events.connect_leave(clone!( + #[weak] + obj, + move |_| { + // We need to set the cursor position at the end on the next idle. + glib::idle_add_local_once(clone!( + #[weak] + obj, + move || { + obj.imp().entry_row.set_position(i32::MAX); + } + )); + } + )); self.combo_row.add_controller(focus_events); } diff --git a/src/ui/components/sticker.rs b/src/ui/components/sticker.rs index 2eee25942..3ccba0a91 100644 --- a/src/ui/components/sticker.rs +++ b/src/ui/components/sticker.rs @@ -116,13 +116,21 @@ impl Sticker { let format = sticker.format; - utils::spawn(clone!(@weak self as obj, @weak session => async move { + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + #[weak] + session, + async move { if sticker.sticker.local.is_downloading_completed { - obj.load_sticker(sticker.sticker.local.path, file_id, looped, format).await; + obj.load_sticker(sticker.sticker.local.path, file_id, looped, format) + .await; } else { - obj.download_sticker(file_id, &session, looped, format).await + obj.download_sticker(file_id, &session, looped, format) + .await + } } - })); + )); } pub(crate) fn play_animation(&self) { diff --git a/src/ui/login/code.rs b/src/ui/login/code.rs index 4b26318f7..d7341e3f8 100644 --- a/src/ui/login/code.rs +++ b/src/ui/login/code.rs @@ -203,9 +203,13 @@ impl Code { } pub(crate) fn focus_entry_row(&self) { - glib::idle_add_local_once(clone!(@weak self as obj => move || { - obj.imp().entry_row.grab_focus(); - })); + glib::idle_add_local_once(clone!( + #[weak(rename_to = obj)] + self, + move || { + obj.imp().entry_row.grab_focus(); + } + )); } fn freeze(&self, freeze: bool) { diff --git a/src/ui/login/mod.rs b/src/ui/login/mod.rs index 74674664f..5fafa5cdf 100644 --- a/src/ui/login/mod.rs +++ b/src/ui/login/mod.rs @@ -82,11 +82,15 @@ mod imp { if let Some(state) = model.state() { obj.update_state(state); } - model.connect_state_notify(clone!(@weak obj => move |auth| { - if let Some(state) = auth.state() { - obj.update_state(state); + model.connect_state_notify(clone!( + #[weak] + obj, + move |auth| { + if let Some(state) = auth.state() { + obj.update_state(state); + } } - })); + )); self.model.set(Some(model)); obj.notify_model(); @@ -112,16 +116,9 @@ impl Login { } pub(crate) fn reset(&self) { - let dialog = adw::MessageDialog::builder() + let dialog = adw::AlertDialog::builder() .heading(gettext("Reset Registration Process?")) .body(gettext("If you reset the registration process, the previous progress will be irrevocably lost.")) - .transient_for( - self - .root() - .unwrap() - .downcast_ref::() - .unwrap(), - ) .build(); dialog.add_responses(&[ @@ -134,12 +131,17 @@ impl Login { let model = self.model_(); dialog.choose( + self.root().unwrap().downcast_ref::().unwrap(), gio::Cancellable::NONE, - clone!(@weak model => move |response| { - if response == "reset" { - model.reset(); + clone!( + #[weak] + model, + move |response| { + if response == "reset" { + model.reset(); + } } - }), + ), ); } diff --git a/src/ui/login/other_device.rs b/src/ui/login/other_device.rs index 9b6a096f5..4ae2f3f89 100644 --- a/src/ui/login/other_device.rs +++ b/src/ui/login/other_device.rs @@ -93,11 +93,13 @@ mod imp { let client_manager = model.auth_().client_().client_manager_(); obj.action_set_enabled("login.exit", !client_manager.sessions().is_empty()); - client_manager.connect_items_changed( - clone!(@weak obj => move |client_manager, _, _, _| { + client_manager.connect_items_changed(clone!( + #[weak] + obj, + move |client_manager, _, _, _| { obj.action_set_enabled("login.exit", !client_manager.sessions().is_empty()); - }), - ); + } + )); } } } diff --git a/src/ui/login/password.rs b/src/ui/login/password.rs index 4dd3b9bcc..d166b9122 100644 --- a/src/ui/login/password.rs +++ b/src/ui/login/password.rs @@ -230,12 +230,11 @@ impl Password { } pub(crate) fn delete_account(&self) { - let dialog = adw::MessageDialog::builder() + let dialog = adw::AlertDialog::builder() .heading(gettext("Warning")) .body(gettext( "You will lose all your chats and messages, along with any media and files you shared!\n\nDo you want to delete your account?", )) - .transient_for(self.root().unwrap().downcast_ref::().unwrap()) .build(); dialog.add_responses(&[ @@ -246,36 +245,48 @@ impl Password { dialog.set_response_appearance("delete", adw::ResponseAppearance::Destructive); dialog.choose( + self.root().unwrap().downcast_ref::().unwrap(), gio::Cancellable::NONE, - clone!(@weak self as obj => move |response| { - if response == "delete" { - obj.freeze(true); - let client_id = obj.model().unwrap().auth().unwrap().client().unwrap().id(); - - utils::spawn(clone!(@weak obj => async move { - let result = tdlib::functions::delete_account( - "Cloud password lost and not recoverable".into(), - String::new(), - client_id, - ) - .await; - - // Just unfreeze in case of an error, else stay frozen until we are - // redirected to the welcome page. - if let Err(e) = result { - log::error!("Failed to delete account: {e:?}"); - utils::show_toast( - &obj, - gettext_f("Failed to delete account: {error}", &[("error", &e.message)]) - ); - - obj.freeze(false); - } - })); - } else { - obj.imp().password_entry_row.grab_focus(); + clone!( + #[weak(rename_to = obj)] + self, + move |response| { + if response == "delete" { + obj.freeze(true); + let client_id = obj.model().unwrap().auth().unwrap().client().unwrap().id(); + + utils::spawn(clone!( + #[weak] + obj, + async move { + let result = tdlib::functions::delete_account( + "Cloud password lost and not recoverable".into(), + String::new(), + client_id, + ) + .await; + + // Just unfreeze in case of an error, else stay frozen until we are + // redirected to the welcome page. + if let Err(e) = result { + log::error!("Failed to delete account: {e:?}"); + utils::show_toast( + &obj, + gettext_f( + "Failed to delete account: {error}", + &[("error", &e.message)], + ), + ); + + obj.freeze(false); + } + } + )); + } else { + obj.imp().password_entry_row.grab_focus(); + } } - }), + ), ); } @@ -312,31 +323,37 @@ impl Password { } pub(crate) fn show_no_email_access_dialog(&self) { - let dialog = adw::MessageDialog::builder() + let dialog = adw::AlertDialog::builder() .heading(gettext("Sorry")) .body(gettext( "If you can't restore access to the e-mail, your remaining options are either to remember your password or to delete and then recreate your account.", )) - .transient_for(self.root().unwrap().downcast_ref::().unwrap()) .build(); dialog.add_responses(&[("ok", &gettext("_OK"))]); dialog.set_default_response(Some("ok")); dialog.choose( + self.root().unwrap().downcast_ref::().unwrap(), gio::Cancellable::NONE, - clone!(@weak self as obj => move |_| { - obj.imp() - .password_recovery_code_entry_row - .grab_focus(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_| { + obj.imp().password_recovery_code_entry_row.grab_focus(); + } + ), ); } pub(crate) fn focus_password_entry_row(&self) { - glib::idle_add_local_once(clone!(@weak self as obj => move || { - obj.imp().password_entry_row.grab_focus(); - })); + glib::idle_add_local_once(clone!( + #[weak(rename_to = obj)] + self, + move || { + obj.imp().password_entry_row.grab_focus(); + } + )); } fn freeze(&self, freeze: bool) { diff --git a/src/ui/login/phone_number.rs b/src/ui/login/phone_number.rs index 977c1d01a..90d9fca6e 100644 --- a/src/ui/login/phone_number.rs +++ b/src/ui/login/phone_number.rs @@ -117,17 +117,23 @@ mod imp { .is_empty(), ); - utils::spawn(clone!(@weak obj, @weak model => async move { - if let Err(e) = model.load_country_codes().await { - utils::show_toast( - &obj, - gettext_f( - "Failed to load country codes: {error}", - &[("error", &e.message)], - ), - ); + utils::spawn(clone!( + #[weak] + obj, + #[weak] + model, + async move { + if let Err(e) = model.load_country_codes().await { + utils::show_toast( + &obj, + gettext_f( + "Failed to load country codes: {error}", + &[("error", &e.message)], + ), + ); + } } - })); + )); } } @@ -239,9 +245,13 @@ impl PhoneNumber { self.freeze(true, false); } pub(crate) fn focus_input(&self) { - glib::idle_add_local_once(clone!(@weak self as obj => move || { - obj.imp().input.select_number_without_calling_code(); - })); + glib::idle_add_local_once(clone!( + #[weak(rename_to = obj)] + self, + move || { + obj.imp().input.select_number_without_calling_code(); + } + )); } fn freeze(&self, qr: bool, freeze: bool) { diff --git a/src/ui/login/registration.rs b/src/ui/login/registration.rs index ca070e222..6cf93f783 100644 --- a/src/ui/login/registration.rs +++ b/src/ui/login/registration.rs @@ -156,12 +156,11 @@ impl Registration { fn show_tos_dialog(&self, user_needs_to_accept: bool) { let model = self.model_(); - let dialog = adw::MessageDialog::builder() + let dialog = adw::AlertDialog::builder() .body_use_markup(true) .body(utils::parse_formatted_text( model.data().0.terms_of_service.text, )) - .transient_for(self.root().unwrap().downcast_ref::().unwrap()) .build(); if user_needs_to_accept { @@ -175,27 +174,40 @@ impl Registration { } dialog.choose( + self.root().unwrap().downcast_ref::().unwrap(), gio::Cancellable::NONE, - clone!(@weak self as obj => move |response| { - if response == "no" { - // If the user declines the ToS, don't proceed and just stay in - // the view but unfreeze it again. - obj.freeze(false); - } else if response == "yes" { - // User has accepted the ToS, so we can proceed in the login - // flow. - utils::spawn(clone!(@weak obj => async move { - obj.next().await; - })); + clone!( + #[weak(rename_to = obj)] + self, + move |response| { + if response == "no" { + // If the user declines the ToS, don't proceed and just stay in + // the view but unfreeze it again. + obj.freeze(false); + } else if response == "yes" { + // User has accepted the ToS, so we can proceed in the login + // flow. + utils::spawn(clone!( + #[weak] + obj, + async move { + obj.next().await; + } + )); + } } - }), + ), ); } pub(crate) fn focus_first_name_entry_row(&self) { - glib::idle_add_local_once(clone!(@weak self as obj => move || { - obj.imp().first_name_entry_row.grab_focus(); - })); + glib::idle_add_local_once(clone!( + #[weak(rename_to = obj)] + self, + move || { + obj.imp().first_name_entry_row.grab_focus(); + } + )); } fn freeze(&self, freeze: bool) { diff --git a/src/ui/meson.build b/src/ui/meson.build index 8e9b07fe4..5c132d31e 100644 --- a/src/ui/meson.build +++ b/src/ui/meson.build @@ -45,7 +45,7 @@ blueprints = custom_target('blueprints', 'session/content/mod.blp', 'session/content/send_media_window.blp', 'session/mod.blp', - 'session/preferences_window.blp', + 'session/preferences_dialog.blp', 'session/row.blp', 'session/sidebar/avatar.blp', 'session/sidebar/chat_folder/bar.blp', diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 2e2f31eff..987316d37 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -54,7 +54,7 @@ pub(crate) use self::session::MessageSticker; pub(crate) use self::session::MessageText; pub(crate) use self::session::MessageVenue; pub(crate) use self::session::MessageVideo; -pub(crate) use self::session::PreferencesWindow; +pub(crate) use self::session::PreferencesDialog; pub(crate) use self::session::Row as SessionRow; pub(crate) use self::session::SendMediaWindow; pub(crate) use self::session::Session; @@ -121,7 +121,7 @@ pub(crate) fn init() { MessageVenue::static_type(); MessageVideo::static_type(); PhoneNumberInput::static_type(); - PreferencesWindow::static_type(); + PreferencesDialog::static_type(); SendMediaWindow::static_type(); Session::static_type(); SessionRow::static_type(); diff --git a/src/ui/session/contacts_window/mod.rs b/src/ui/session/contacts_window/mod.rs index 2fabc5e48..5227fb907 100644 --- a/src/ui/session/contacts_window/mod.rs +++ b/src/ui/session/contacts_window/mod.rs @@ -98,9 +98,13 @@ impl ContactsWindow { obj.imp().session.set(session).unwrap(); - utils::spawn(clone!(@weak obj => async move { - obj.fetch_contacts().await; - })); + utils::spawn(clone!( + #[weak] + obj, + async move { + obj.fetch_contacts().await; + } + )); obj } diff --git a/src/ui/session/content/background.rs b/src/ui/session/content/background.rs index c1567571e..a1d377b1b 100644 --- a/src/ui/session/content/background.rs +++ b/src/ui/session/content/background.rs @@ -90,34 +90,44 @@ mod imp { let style_manager = adw::StyleManager::default(); obj.set_theme(hard_coded_themes(style_manager.is_dark())); - style_manager.connect_dark_notify(clone!(@weak obj => move |style_manager| { - obj.set_theme(hard_coded_themes(style_manager.is_dark())) - })); + style_manager.connect_dark_notify(clone!( + #[weak] + obj, + move |style_manager| obj.set_theme(hard_coded_themes(style_manager.is_dark())) + )); if style_manager.is_high_contrast() { obj.add_css_class("fallback"); } - style_manager.connect_high_contrast_notify(clone!(@weak obj => move |style_manager| { - if style_manager.is_high_contrast() { - obj.add_css_class("fallback"); - } else if obj.imp().shader.borrow().is_some() { - obj.remove_css_class("fallback"); + style_manager.connect_high_contrast_notify(clone!( + #[weak] + obj, + move |style_manager| { + if style_manager.is_high_contrast() { + obj.add_css_class("fallback"); + } else if obj.imp().shader.borrow().is_some() { + obj.remove_css_class("fallback"); + } } - })); - - let target = adw::CallbackAnimationTarget::new(clone!(@weak obj => move |progress| { - let imp = obj.imp(); - imp.gradient_texture.take(); - let progress = progress as f32; - if progress >= 1.0 { - imp.progress.set(0.0); - imp.phase.set((imp.phase.get() + 1) % 8); - } else { - imp.progress.set(progress) + )); + + let target = adw::CallbackAnimationTarget::new(clone!( + #[weak] + obj, + move |progress| { + let imp = obj.imp(); + imp.gradient_texture.take(); + let progress = progress as f32; + if progress >= 1.0 { + imp.progress.set(0.0); + imp.phase.set((imp.phase.get() + 1) % 8); + } else { + imp.progress.set(progress) + } + obj.queue_draw(); } - obj.queue_draw(); - })); + )); let animation = adw::TimedAnimation::builder() .widget(&*obj) @@ -368,7 +378,7 @@ impl Background { imp.shader.replace(Some(shader)); } } - }; + } } } diff --git a/src/ui/session/content/chat_action_bar.rs b/src/ui/session/content/chat_action_bar.rs index 546b5fa33..d6b2631a6 100644 --- a/src/ui/session/content/chat_action_bar.rs +++ b/src/ui/session/content/chat_action_bar.rs @@ -202,8 +202,10 @@ mod imp { .unwrap() .set_orientation(gtk::Orientation::Vertical); - self.message_entry.connect_formatted_text_notify( - clone!(@weak obj => move |message_entry, _| { + self.message_entry.connect_formatted_text_notify(clone!( + #[weak] + obj, + move |message_entry, _| { // Enable the send-message action only when the message entry contains // at least one non-whitespace character let should_enable = message_entry @@ -213,30 +215,44 @@ mod imp { obj.action_set_enabled("chat-action-bar.send-message", should_enable); // Send typing action - utils::spawn(clone!(@weak obj => async move { - obj.send_chat_action(tdlib::enums::ChatAction::Typing).await; - })); - }), - ); + utils::spawn(clone!( + #[weak] + obj, + async move { + obj.send_chat_action(tdlib::enums::ChatAction::Typing).await; + } + )); + } + )); - self.message_entry - .connect_paste_clipboard(clone!(@weak obj => move |_| { + self.message_entry.connect_paste_clipboard(clone!( + #[weak] + obj, + move |_| { obj.handle_paste_action(); - })); + } + )); - self.message_entry - .connect_emoji_button_press(clone!(@weak obj => move |_, button| { + self.message_entry.connect_emoji_button_press(clone!( + #[weak] + obj, + move |_, button| { obj.show_emoji_chooser(&button); - })); + } + )); // The message entry is always empty at this point, so disable the // send-message action obj.action_set_enabled("chat-action-bar.send-message", false); - self.message_entry - .connect_activate(clone!(@weak obj => move |_| { - obj.activate_action("chat-action-bar.send-message", None).unwrap() - })); + self.message_entry.connect_activate(clone!( + #[weak] + obj, + move |_| { + obj.activate_action("chat-action-bar.send-message", None) + .unwrap() + } + )); obj.create_signal_groups(); } @@ -275,24 +291,36 @@ impl ChatActionBar { let chat_signal_group = glib::SignalGroup::new::(); chat_signal_group.connect_notify_local( Some("notification-settings"), - clone!(@weak self as obj => move |_, _| { - obj.update_stack_page(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_stack_page(); + } + ), ); chat_signal_group.connect_notify_local( Some("block-list"), - clone!(@weak self as obj => move |_, _| { - obj.update_stack_page(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_stack_page(); + } + ), ); imp.chat_signal_group.set(chat_signal_group).unwrap(); let basic_group_signal_group = glib::SignalGroup::new::(); basic_group_signal_group.connect_notify_local( Some("status"), - clone!(@weak self as obj => move |_, _| { - obj.update_stack_page(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_stack_page(); + } + ), ); imp.basic_group_signal_group .set(basic_group_signal_group) @@ -301,9 +329,13 @@ impl ChatActionBar { let supergroup_signal_group = glib::SignalGroup::new::(); supergroup_signal_group.connect_notify_local( Some("status"), - clone!(@weak self as obj => move |_, _| { - obj.update_stack_page(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_stack_page(); + } + ), ); imp.supergroup_signal_group .set(supergroup_signal_group) @@ -467,12 +499,20 @@ impl ChatActionBar { if emoji_chooser.is_none() { let chooser = gtk::EmojiChooser::new(); chooser.set_parent(parent); - chooser.connect_emoji_picked(clone!(@weak self as obj => move |_, emoji| { - obj.imp().message_entry.insert_at_cursor(emoji); - })); - chooser.connect_hide(clone!(@weak self as obj => move |_| { - obj.imp().message_entry.grab_focus(); - })); + chooser.connect_emoji_picked(clone!( + #[weak(rename_to = obj)] + self, + move |_, emoji| { + obj.imp().message_entry.insert_at_cursor(emoji); + } + )); + chooser.connect_hide(clone!( + #[weak(rename_to = obj)] + self, + move |_| { + obj.imp().message_entry.grab_focus(); + } + )); *emoji_chooser = Some(chooser); } emoji_chooser.as_ref().unwrap().popup(); @@ -663,9 +703,13 @@ impl ChatActionBar { if result.is_ok() { glib::timeout_add_seconds_local_once( 5, - clone!(@weak self as obj =>move || { - obj.imp().chat_action_in_cooldown.set(false); - }), + clone!( + #[weak(rename_to = obj)] + self, + move || { + obj.imp().chat_action_in_cooldown.set(false); + } + ), ); } else { imp.chat_action_in_cooldown.set(false); @@ -675,11 +719,15 @@ impl ChatActionBar { pub(crate) fn handle_paste_action(&self) { if let Some(chat) = self.chat() { - utils::spawn(clone!(@weak self as obj => async move { - if let Err(e) = obj.handle_image_clipboard(chat).await { - log::warn!("Error on pasting an image: {:?}", e); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + if let Err(e) = obj.handle_image_clipboard(chat).await { + log::warn!("Error on pasting an image: {:?}", e); + } } - })); + )); } } @@ -719,9 +767,13 @@ impl ChatActionBar { return; } - utils::spawn(clone!(@weak self as obj => async move { - obj.save_message_as_draft().await; - })); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + obj.save_message_as_draft().await; + } + )); let imp = self.imp(); let mut bindings = imp.bindings.borrow_mut(); diff --git a/src/ui/session/content/chat_history.rs b/src/ui/session/content/chat_history.rs index b155d21c0..2ef81e0f5 100644 --- a/src/ui/session/content/chat_history.rs +++ b/src/ui/session/content/chat_history.rs @@ -136,48 +136,64 @@ mod imp { obj.setup_expressions(); let adj = self.list_view.vadjustment().unwrap(); - adj.connect_value_changed(clone!(@weak obj => move |adj| { - obj.view_messages(); + adj.connect_value_changed(clone!( + #[weak] + obj, + move |adj| { + obj.view_messages(); - let imp = obj.imp(); + let imp = obj.imp(); - if imp.is_loading_messages.get() { - return; - } - - if imp.is_auto_scrolling.get() { - if adj.value() + adj.page_size() >= adj.upper() { - imp.is_auto_scrolling.set(false); - obj.set_sticky(true); - } - } else { - obj.set_sticky(adj.value() + adj.page_size() >= adj.upper()); - - if adj.value() >= adj.page_size() * 2.0 && adj.upper() > adj.page_size() * 2.0 { + if imp.is_loading_messages.get() { return; } - if let Some(model) = imp.model.borrow().as_ref() { - imp.is_loading_messages.set(true); + if imp.is_auto_scrolling.get() { + if adj.value() + adj.page_size() >= adj.upper() { + imp.is_auto_scrolling.set(false); + obj.set_sticky(true); + } + } else { + obj.set_sticky(adj.value() + adj.page_size() >= adj.upper()); - utils::spawn(clone!(@weak obj, @weak model => async move { - obj.imp().is_loading_messages.set(false); + if adj.value() >= adj.page_size() * 2.0 + && adj.upper() > adj.page_size() * 2.0 + { + return; + } - if let Err(model::ChatHistoryError::Tdlib(e)) = - model.load_older_messages(2).await - { - log::warn!("Couldn't load more chat messages: {:?}", e); - } - })); + if let Some(model) = imp.model.borrow().as_ref() { + imp.is_loading_messages.set(true); + + utils::spawn(clone!( + #[weak] + obj, + #[weak] + model, + async move { + obj.imp().is_loading_messages.set(false); + + if let Err(model::ChatHistoryError::Tdlib(e)) = + model.load_older_messages(2).await + { + log::warn!("Couldn't load more chat messages: {:?}", e); + } + } + )); + } } } - })); - - adj.connect_upper_notify(clone!(@weak obj => move |_| { - if obj.sticky() || obj.imp().is_auto_scrolling.get() { - obj.scroll_down(); + )); + + adj.connect_upper_notify(clone!( + #[weak] + obj, + move |_| { + if obj.sticky() || obj.imp().is_auto_scrolling.get() { + obj.scroll_down(); + } } - })); + )); } fn dispose(&self) { @@ -243,8 +259,7 @@ impl ChatHistory { async fn show_leave_chat_dialog(&self) { if let Some(chat) = self.chat() { - let dialog = adw::MessageDialog::new( - Some(&self.parent_window().unwrap()), + let dialog = adw::AlertDialog::new( Some(&gettext("Leave chat?")), Some(&gettext("Do you want to leave this chat?")), ); @@ -253,7 +268,7 @@ impl ChatHistory { dialog.set_close_response("no"); dialog.set_response_appearance("yes", adw::ResponseAppearance::Destructive); - if dialog.choose_future().await == "yes" { + if dialog.choose_future(&self.parent_window().unwrap()).await == "yes" { match tdlib::functions::leave_chat(chat.id(), chat.session_().client_().id()).await { Ok(_) => { @@ -272,20 +287,26 @@ impl ChatHistory { } fn request_sponsored_message(&self, chat: &model::Chat, list: &gio::ListStore) { - utils::spawn(clone!(@weak chat, @weak list => async move { - match model::SponsoredMessage::request(&chat).await { - Ok(sponsored_message) => { - if let Some(sponsored_message) = sponsored_message { - list.append(&sponsored_message); + utils::spawn(clone!( + #[weak] + chat, + #[weak] + list, + async move { + match model::SponsoredMessage::request(&chat).await { + Ok(sponsored_message) => { + if let Some(sponsored_message) = sponsored_message { + list.append(&sponsored_message); + } } - } - Err(e) => { - if e.code != 404 { - log::warn!("Failed to request a SponsoredMessage: {:?}", e); + Err(e) => { + if e.code != 404 { + log::warn!("Failed to request a SponsoredMessage: {:?}", e); + } } } } - })); + )); } pub(crate) fn add_to_viewed_message_ids(&self, message_id: i64) { @@ -375,42 +396,54 @@ impl ChatHistory { model.clone().upcast() }; - utils::spawn(clone!(@weak self as obj, @weak model => async move { - let imp = obj.imp(); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + #[weak] + model, + async move { + let imp = obj.imp(); - imp.is_loading_messages.set(true); + imp.is_loading_messages.set(true); - let scrollbar = imp.scrolled_window.vscrollbar(); - scrollbar.set_visible(false); + let scrollbar = imp.scrolled_window.vscrollbar(); + scrollbar.set_visible(false); - let adj = imp.list_view.vadjustment().unwrap(); - adj.set_value(0.0); + let adj = imp.list_view.vadjustment().unwrap(); + adj.set_value(0.0); - while adj.value() == 0.0 { - match model.load_older_messages(2).await { - Ok(can_load_more) => if !can_load_more { - break; - } - Err(e) => { - log::warn!("Couldn't load initial history messages: {}", e); - break; + while adj.value() == 0.0 { + match model.load_older_messages(2).await { + Ok(can_load_more) => { + if !can_load_more { + break; + } + } + Err(e) => { + log::warn!("Couldn't load initial history messages: {}", e); + break; + } } } - } - - scrollbar.set_visible(true); - imp.is_loading_messages.set(false); - obj.set_sticky(true); + scrollbar.set_visible(true); - obj.view_messages(); - })); + imp.is_loading_messages.set(false); + obj.set_sticky(true); - let handler = chat.connect_new_message(clone!(@weak self as obj => move |_, msg| { - if msg.is_outgoing() { - obj.imp().background.animate(); + obj.view_messages(); } - })); + )); + + let handler = chat.connect_new_message(clone!( + #[weak(rename_to = obj)] + self, + move |_, msg| { + if msg.is_outgoing() { + obj.imp().background.animate(); + } + } + )); imp.chat_handler.replace(Some(handler)); let selection = gtk::NoSelection::new(Some(list_view_model)); @@ -473,12 +506,11 @@ where F: Fn(i64, i32) -> Fut + 'static, Fut: Future>, { - utils::spawn(clone!(@weak chat => async move { - op( - chat.id(), - chat.session_().client_().id(), - ) - .await - .unwrap(); - })); + utils::spawn(clone!( + #[weak] + chat, + async move { + op(chat.id(), chat.session_().client_().id()).await.unwrap(); + } + )); } diff --git a/src/ui/session/content/chat_info_window.rs b/src/ui/session/content/chat_info_window.rs index e94ccefa9..6d5a16090 100644 --- a/src/ui/session/content/chat_info_window.rs +++ b/src/ui/session/content/chat_info_window.rs @@ -199,17 +199,22 @@ impl ChatInfoWindow { self.update_info_list_visibility(); // Full info - utils::spawn(clone!(@weak self as obj => async move { - let result = tdlib::functions::get_basic_group_full_info(basic_group_id, client_id).await; - match result { - Ok(tdlib::enums::BasicGroupFullInfo::BasicGroupFullInfo(full_info)) => { - obj.setup_basic_group_full_info(full_info); - } - Err(e) => { - log::warn!("Failed to get basic group full info: {e:?}"); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + let result = + tdlib::functions::get_basic_group_full_info(basic_group_id, client_id).await; + match result { + Ok(tdlib::enums::BasicGroupFullInfo::BasicGroupFullInfo(full_info)) => { + obj.setup_basic_group_full_info(full_info); + } + Err(e) => { + log::warn!("Failed to get basic group full info: {e:?}"); + } } } - })); + )); } fn setup_basic_group_full_info(&self, basic_group_full_info: tdlib::types::BasicGroupFullInfo) { @@ -255,17 +260,22 @@ impl ChatInfoWindow { self.update_info_list_visibility(); // Full info - utils::spawn(clone!(@weak self as obj => async move { - let result = tdlib::functions::get_supergroup_full_info(supergroup_id, client_id).await; - match result { - Ok(tdlib::enums::SupergroupFullInfo::SupergroupFullInfo(full_info)) => { - obj.setup_supergroup_full_info(full_info); - } - Err(e) => { - log::warn!("Failed to get supergroup full info: {e:?}"); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + let result = + tdlib::functions::get_supergroup_full_info(supergroup_id, client_id).await; + match result { + Ok(tdlib::enums::SupergroupFullInfo::SupergroupFullInfo(full_info)) => { + obj.setup_supergroup_full_info(full_info); + } + Err(e) => { + log::warn!("Failed to get supergroup full info: {e:?}"); + } } } - })); + )); } fn setup_supergroup_full_info(&self, supergroup_full_info: tdlib::types::SupergroupFullInfo) { @@ -288,12 +298,16 @@ impl ChatInfoWindow { fn make_row_copyable(&self, action_row: &adw::ActionRow) { action_row.set_activatable(true); - action_row.connect_activated(clone!(@weak self as obj => move |action_row| { - action_row.clipboard().set_text(&action_row.title()); - - let toast = adw::Toast::new(&gettext("Copied to clipboard")); - obj.imp().toast_overlay.add_toast(toast); - })); + action_row.connect_activated(clone!( + #[weak(rename_to = obj)] + self, + move |action_row| { + action_row.clipboard().set_text(&action_row.title()); + + let toast = adw::Toast::new(&gettext("Copied to clipboard")); + obj.imp().toast_overlay.add_toast(toast); + } + )); } pub(crate) fn chat(&self) -> Option<&model::Chat> { diff --git a/src/ui/session/content/message_row/document/mod.rs b/src/ui/session/content/message_row/document/mod.rs index 699bffb52..cb47e460a 100644 --- a/src/ui/session/content/message_row/document/mod.rs +++ b/src/ui/session/content/message_row/document/mod.rs @@ -114,10 +114,13 @@ impl ui::MessageBaseExt for MessageDocument { imp.message_bubble.update_from_message(message, false); - let handler_id = - message.connect_content_notify(clone!(@weak self as obj => move |message| { + let handler_id = message.connect_content_notify(clone!( + #[weak(rename_to = obj)] + self, + move |message| { obj.update_document(message); - })); + } + )); imp.handler_id.replace(Some(handler_id)); self.update_document(message); @@ -175,23 +178,43 @@ impl MessageDocument { } FileStatus::CanBeDownloaded => { // Download file - click.connect_released(clone!(@weak self as obj, @weak session => move |click, _, _, _| { - // TODO: Fix bug mentioned here - // https://github.com/paper-plane-developers/paper-plane/pull/372#discussion_r968841370 - session.download_file_with_updates(file_id, clone!(@weak obj, @weak session => move |file| { - obj.update_status(file, session); - })); - - let imp = obj.imp(); - - imp.status_indicator.set_status(FileStatus::Downloading(0.0)); - let handler_id = click.connect_released(clone!(@weak session => move |_, _, _, _| { - session.cancel_download_file(file_id); - })); - if let Some(handler_id) = imp.status_handler_id.replace(Some(handler_id)) { - click.disconnect(handler_id); + click.connect_released(clone!( + #[weak(rename_to = obj)] + self, + #[weak] + session, + move |click, _, _, _| { + // TODO: Fix bug mentioned here + // https://github.com/paper-plane-developers/paper-plane/pull/372#discussion_r968841370 + session.download_file_with_updates( + file_id, + clone!( + #[weak] + obj, + #[weak] + session, + move |file| { + obj.update_status(file, session); + } + ), + ); + + let imp = obj.imp(); + + imp.status_indicator + .set_status(FileStatus::Downloading(0.0)); + let handler_id = click.connect_released(clone!( + #[weak] + session, + move |_, _, _, _| { + session.cancel_download_file(file_id); + } + )); + if let Some(handler_id) = imp.status_handler_id.replace(Some(handler_id)) { + click.disconnect(handler_id); + } } - })) + )) } FileStatus::Downloaded => { // Open file @@ -252,14 +275,17 @@ impl MessageDocument { } let session = message.chat_().session_(); - utils::spawn(clone!(@weak self as obj => async move { - if let Ok(file) = session.download_file(thumbnail.file.id).await - { - obj.imp() - .file_thumbnail_picture - .set_filename(Some(&file.local.path)); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + if let Ok(file) = session.download_file(thumbnail.file.id).await { + obj.imp() + .file_thumbnail_picture + .set_filename(Some(&file.local.path)); + } } - })); + )); } } else { imp.status_indicator.set_masked(true); diff --git a/src/ui/session/content/message_row/indicators.rs b/src/ui/session/content/message_row/indicators.rs index 534f82960..9ae3689ec 100644 --- a/src/ui/session/content/message_row/indicators.rs +++ b/src/ui/session/content/message_row/indicators.rs @@ -104,9 +104,13 @@ impl MessageIndicators { let message_signal_group = glib::SignalGroup::new::(); message_signal_group.connect_notify_local( Some("is-edited"), - clone!(@weak self as obj => move |_, _| { - obj.update_message_info(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_message_info(); + } + ), ); imp.message_signal_group.set(message_signal_group).unwrap(); @@ -114,9 +118,13 @@ impl MessageIndicators { glib::SignalGroup::new::(); interaction_info_signal_group.connect_notify_local( Some("reply-count"), - clone!(@weak self as obj => move |_, _| { - obj.update_reply_count(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_reply_count(); + } + ), ); imp.interaction_info_signal_group .set(interaction_info_signal_group) @@ -125,9 +133,13 @@ impl MessageIndicators { let chat_signal_group = glib::SignalGroup::new::(); chat_signal_group.connect_notify_local( Some("last-read-outbox-message-id"), - clone!(@weak self as obj => move |_, _| { - obj.update_sending_state(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_sending_state(); + } + ), ); imp.chat_signal_group.set(chat_signal_group).unwrap(); } diff --git a/src/ui/session/content/message_row/location.rs b/src/ui/session/content/message_row/location.rs index 274f7b196..3aa5ba596 100644 --- a/src/ui/session/content/message_row/location.rs +++ b/src/ui/session/content/message_row/location.rs @@ -133,11 +133,14 @@ impl MessageBaseExt for MessageLocation { imp.message_bubble.update_from_message(message, true); // Update the message. - let handler_id = - message.connect_content_notify(clone!(@weak self as obj => move |message| { + let handler_id = message.connect_content_notify(clone!( + #[weak(rename_to = obj)] + self, + move |message| { obj.update_row(message); obj.update_map_window(message); - })); + } + )); imp.handler_id.replace(Some(handler_id)); self.update_row(message); @@ -177,31 +180,38 @@ impl MessageLocation { let source_id = glib::timeout_add_seconds_local( 1, - clone!(@weak self as obj => @default-return glib::ControlFlow::Break, move || { - match obj.update_time(message_date, message_.live_period) { - Some(now) => { - let minutes = now.difference(&last_update_date).as_minutes(); - obj.imp().last_updated_label.set_label(&if minutes <= 1 { - gettext("updated just now") - } else if minutes < 60 { - gettext!("updated {} minutes ago", minutes) - } else if minutes == 60 { - gettext("updated an hour ago") - } else { - gettext_f( - "updated {hours} hours and {minutes} minutes ago", - &[ - ("hours", &(minutes / 60).to_string()), - ("minutes", &(minutes % 60).to_string()), - ], - ) - }); - - glib::ControlFlow::Continue + clone!( + #[weak(rename_to = obj)] + self, + #[upgrade_or] + glib::ControlFlow::Break, + move || { + match obj.update_time(message_date, message_.live_period) { + Some(now) => { + let minutes = + now.difference(&last_update_date).as_minutes(); + obj.imp().last_updated_label.set_label(&if minutes <= 1 { + gettext("updated just now") + } else if minutes < 60 { + gettext!("updated {} minutes ago", minutes) + } else if minutes == 60 { + gettext("updated an hour ago") + } else { + gettext_f( + "updated {hours} hours and {minutes} minutes ago", + &[ + ("hours", &(minutes / 60).to_string()), + ("minutes", &(minutes % 60).to_string()), + ], + ) + }); + + glib::ControlFlow::Continue + } + None => glib::ControlFlow::Break, } - None => glib::ControlFlow::Break, } - }), + ), ); imp.expire_source_id.replace(Some(source_id)); diff --git a/src/ui/session/content/message_row/media_picture.rs b/src/ui/session/content/message_row/media_picture.rs index 4a4b45fd5..8cfe42d23 100644 --- a/src/ui/session/content/message_row/media_picture.rs +++ b/src/ui/session/content/message_row/media_picture.rs @@ -78,10 +78,13 @@ mod imp { let obj = self.obj(); obj.set_overflow(gtk::Overflow::Hidden); - self.picture - .connect_paintable_notify(clone!(@weak obj => move |_| { + self.picture.connect_paintable_notify(clone!( + #[weak] + obj, + move |_| { obj.notify("paintable"); - })); + } + )); } fn dispose(&self) { diff --git a/src/ui/session/content/message_row/mod.rs b/src/ui/session/content/message_row/mod.rs index 000c79a2c..af212b2c4 100644 --- a/src/ui/session/content/message_row/mod.rs +++ b/src/ui/session/content/message_row/mod.rs @@ -172,11 +172,10 @@ impl Row { gettext("Do you want to delete this message?") }; - let dialog = adw::MessageDialog::builder() + let dialog = adw::AlertDialog::builder() .heading(gettext("Confirm Message Deletion")) .body_use_markup(true) .body(message) - .transient_for(&window) .build(); dialog.add_responses(&[("no", &gettext("_No")), ("yes", &gettext("_Yes"))]); @@ -184,18 +183,28 @@ impl Row { dialog.set_response_appearance("yes", adw::ResponseAppearance::Destructive); dialog.choose( + &window, gio::Cancellable::NONE, - clone!(@weak self as obj => move |response| { - if response == "yes" { - if let Ok(message) = obj.message().downcast::() { - utils::spawn(async move { - if let Err(e) = message.delete(revoke).await { - log::warn!("Error deleting a message (revoke = {}): {:?}", revoke, e); - } - }); + clone!( + #[weak(rename_to = obj)] + self, + move |response| { + if response == "yes" { + if let Ok(message) = obj.message().downcast::() { + utils::spawn(async move { + if let Err(e) = message.delete(revoke).await { + log::warn!( + "Error deleting a message (revoke = {}): {:?}", + revoke, + e + ); + } + }); + } } } - })); + ), + ); } pub(crate) fn message(&self) -> glib::Object { diff --git a/src/ui/session/content/message_row/photo.rs b/src/ui/session/content/message_row/photo.rs index 6862f5f55..b0bb1705b 100644 --- a/src/ui/session/content/message_row/photo.rs +++ b/src/ui/session/content/message_row/photo.rs @@ -129,10 +129,13 @@ impl ui::MessageBaseExt for MessagePhoto { imp.binding.replace(Some(caption_binding)); // Load photo - let handler_id = - message.connect_content_notify(clone!(@weak self as obj => move |message| { + let handler_id = message.connect_content_notify(clone!( + #[weak(rename_to = obj)] + self, + move |message| { obj.update_photo(message); - })); + } + )); imp.handler_id.replace(Some(handler_id)); self.update_photo(message); @@ -182,9 +185,15 @@ impl MessagePhoto { let file_id = photo_size.photo.id; let session = message.chat_().session_(); - utils::spawn(clone!(@weak self as obj, @weak session => async move { - obj.download_photo(file_id, &session).await; - })); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + #[weak] + session, + async move { + obj.download_photo(file_id, &session).await; + } + )); } } } @@ -202,27 +211,31 @@ impl MessagePhoto { fn load_photo(&self, path: String) { if let Some(message_id) = self.message_id() { - utils::spawn(clone!(@weak self as obj => async move { - let result = gio::spawn_blocking(move || utils::decode_image_from_path(&path)) - .await - .unwrap(); - - // Check if the current message id is the same as the one at - // the time of the request. It may be changed because of the - // ListView recycling while decoding the image. It may also - // that the message has been already removed from the history - // and the WeakRef is None (after successful sent) - if obj.message_id().filter(|id| *id == message_id).is_some() { - match result { - Ok(texture) => { - obj.imp().picture.set_paintable(Some(&texture)); - } - Err(e) => { - log::warn!("Error decoding a photo: {e:?}"); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + let result = gio::spawn_blocking(move || utils::decode_image_from_path(&path)) + .await + .unwrap(); + + // Check if the current message id is the same as the one at + // the time of the request. It may be changed because of the + // ListView recycling while decoding the image. It may also + // that the message has been already removed from the history + // and the WeakRef is None (after successful sent) + if obj.message_id().filter(|id| *id == message_id).is_some() { + match result { + Ok(texture) => { + obj.imp().picture.set_paintable(Some(&texture)); + } + Err(e) => { + log::warn!("Error decoding a photo: {e:?}"); + } } } } - })); + )); } } } diff --git a/src/ui/session/content/message_row/reply.rs b/src/ui/session/content/message_row/reply.rs index bc38ccdf2..c111aff09 100644 --- a/src/ui/session/content/message_row/reply.rs +++ b/src/ui/session/content/message_row/reply.rs @@ -70,9 +70,13 @@ mod imp { self.message_label.set_label(&gettext("Loading…")); let obj = self.obj(); - utils::spawn(clone!(@weak obj => async move { - obj.load_replied_message().await; - })); + utils::spawn(clone!( + #[weak] + obj, + async move { + obj.load_replied_message().await; + } + )); } fn dispose(&self) { diff --git a/src/ui/session/content/message_row/venue.rs b/src/ui/session/content/message_row/venue.rs index 529348524..52b3e7c01 100644 --- a/src/ui/session/content/message_row/venue.rs +++ b/src/ui/session/content/message_row/venue.rs @@ -125,11 +125,14 @@ impl MessageBaseExt for MessageVenue { imp.message_bubble.add_message_label_class("dim-label"); // Update the message. - let handler_id = - message.connect_content_notify(clone!(@weak self as obj => move |message| { + let handler_id = message.connect_content_notify(clone!( + #[weak(rename_to = obj)] + self, + move |message| { obj.update_row(message); obj.update_map_window(message); - })); + } + )); imp.handler_id.replace(Some(handler_id)); self.update_row(message); diff --git a/src/ui/session/content/message_row/video.rs b/src/ui/session/content/message_row/video.rs index 7907720af..db72b4635 100644 --- a/src/ui/session/content/message_row/video.rs +++ b/src/ui/session/content/message_row/video.rs @@ -100,10 +100,13 @@ impl ui::MessageBaseExt for MessageVideo { imp.message_bubble.update_from_message(message, true); - let handler_id = - message.connect_content_notify(clone!(@weak self as obj => move |message| { + let handler_id = message.connect_content_notify(clone!( + #[weak(rename_to = obj)] + self, + move |message| { obj.update_content(message.content().0, &message.chat_().session_()); - })); + } + )); imp.handler_id.replace(Some(handler_id)); self.update_content(message.content().0, &message.chat_().session_()); @@ -164,9 +167,15 @@ impl MessageVideo { ); let file_id = file.id; - utils::spawn(clone!(@weak self as obj, @weak session => async move { - obj.download_video(file_id, &session).await; - })); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + #[weak] + session, + async move { + obj.download_video(file_id, &session).await; + } + )); } } @@ -190,10 +199,14 @@ impl MessageVideo { media.play(); if !imp.is_animation.get() { - media.connect_timestamp_notify(clone!(@weak self as obj => move |media| { - let time = (media.duration() - media.timestamp()) / i64::pow(10, 6); - obj.update_remaining_time(time); - })); + media.connect_timestamp_notify(clone!( + #[weak(rename_to = obj)] + self, + move |media| { + let time = (media.duration() - media.timestamp()) / i64::pow(10, 6); + obj.update_remaining_time(time); + } + )); } imp.picture.set_paintable(Some(&media)); diff --git a/src/ui/session/content/send_media_window.rs b/src/ui/session/content/send_media_window.rs index 03b7e8e65..3e3241ec4 100644 --- a/src/ui/session/content/send_media_window.rs +++ b/src/ui/session/content/send_media_window.rs @@ -66,15 +66,22 @@ mod imp { let obj = self.obj(); - self.caption_entry - .connect_activate(clone!(@weak obj => move |_| { - obj.activate_action("send-media-window.send-message", None).unwrap() - })); - - self.caption_entry - .connect_emoji_button_press(clone!(@weak obj => move |_, button| { + self.caption_entry.connect_activate(clone!( + #[weak] + obj, + move |_| { + obj.activate_action("send-media-window.send-message", None) + .unwrap() + } + )); + + self.caption_entry.connect_emoji_button_press(clone!( + #[weak] + obj, + move |_, button| { obj.show_emoji_chooser(&button); - })); + } + )); } fn dispose(&self) { @@ -142,12 +149,20 @@ impl SendMediaWindow { if emoji_chooser.is_none() { let chooser = gtk::EmojiChooser::new(); chooser.set_parent(parent); - chooser.connect_emoji_picked(clone!(@weak self as obj => move |_, emoji| { - obj.imp().caption_entry.insert_at_cursor(emoji); - })); - chooser.connect_hide(clone!(@weak self as obj => move |_| { - obj.imp().caption_entry.grab_focus(); - })); + chooser.connect_emoji_picked(clone!( + #[weak(rename_to = obj)] + self, + move |_, emoji| { + obj.imp().caption_entry.insert_at_cursor(emoji); + } + )); + chooser.connect_hide(clone!( + #[weak(rename_to = obj)] + self, + move |_| { + obj.imp().caption_entry.grab_focus(); + } + )); *emoji_chooser = Some(chooser); } emoji_chooser.as_ref().unwrap().popup(); diff --git a/src/ui/session/mod.rs b/src/ui/session/mod.rs index 44fc3574c..49400e11f 100644 --- a/src/ui/session/mod.rs +++ b/src/ui/session/mod.rs @@ -1,17 +1,17 @@ mod contacts_window; mod content; -mod preferences_window; +mod preferences_dialog; mod row; mod sidebar; mod switcher; use std::sync::OnceLock; +use adw::prelude::*; use adw::subclass::prelude::*; use glib::clone; use gtk::gdk; use gtk::glib; -use gtk::prelude::*; use gtk::CompositeTemplate; pub(crate) use self::contacts_window::ContactsWindow; @@ -41,7 +41,7 @@ pub(crate) use self::content::MessageText; pub(crate) use self::content::MessageVenue; pub(crate) use self::content::MessageVideo; pub(crate) use self::content::SendMediaWindow; -pub(crate) use self::preferences_window::PreferencesWindow; +pub(crate) use self::preferences_dialog::PreferencesDialog; pub(crate) use self::row::Row; pub(crate) use self::sidebar::Avatar as SidebarAvatar; pub(crate) use self::sidebar::ChatFolderBar as SidebarChatFolderBar; @@ -66,6 +66,7 @@ use crate::ui; use crate::utils; mod imp { + use super::*; #[derive(Debug, Default, CompositeTemplate)] @@ -89,18 +90,25 @@ mod imp { fn class_init(klass: &mut Self::Class) { klass.bind_template(); - klass.install_action("session.show-preferences", None, move |widget, _, _| { - let parent_window = widget.root().and_then(|r| r.downcast().ok()); - let preferences = ui::PreferencesWindow::new(parent_window.as_ref(), widget); - preferences.present(); + klass.install_action("session.show-preferences", None, move |session, _, _| { + ui::PreferencesDialog::from(session).present( + session + .root() + .and_then(|r| r.downcast::().ok()) + .as_ref(), + ); }); klass.install_action("session.show-contacts", None, move |widget, _, _| { let parent = widget.root().and_then(|r| r.downcast().ok()); let contacts = ui::ContactsWindow::new(parent.as_ref(), widget.clone()); - contacts.connect_contact_activated(clone!(@weak widget => move |_, user_id| { - widget.select_chat(user_id); - })); + contacts.connect_contact_activated(clone!( + #[weak] + widget, + move |_, user_id| { + widget.select_chat(user_id); + } + )); contacts.present(); }); @@ -180,12 +188,25 @@ impl Session { pub(crate) fn select_chat(&self, id: ChatId) { match self.model().unwrap().try_chat(id) { Some(chat) => self.imp().sidebar.set_selected_chat(Some(&chat)), - None => utils::spawn(clone!(@weak self as obj => async move { - match tdlib::functions::create_private_chat(id, true, obj.model().unwrap().client_().id()).await { - Ok(tdlib::enums::Chat::Chat(data)) => obj.imp().sidebar.set_selected_chat(obj.model().unwrap().try_chat(data.id).as_ref()), - Err(e) => log::warn!("Failed to create private chat: {:?}", e), + None => utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + match tdlib::functions::create_private_chat( + id, + true, + obj.model().unwrap().client_().id(), + ) + .await + { + Ok(tdlib::enums::Chat::Chat(data)) => obj + .imp() + .sidebar + .set_selected_chat(obj.model().unwrap().try_chat(data.id).as_ref()), + Err(e) => log::warn!("Failed to create private chat: {:?}", e), + } } - })), + )), } } diff --git a/src/ui/session/preferences_window.blp b/src/ui/session/preferences_dialog.blp similarity index 93% rename from src/ui/session/preferences_window.blp rename to src/ui/session/preferences_dialog.blp index 069110646..b6f197f5c 100644 --- a/src/ui/session/preferences_window.blp +++ b/src/ui/session/preferences_dialog.blp @@ -1,7 +1,7 @@ using Gtk 4.0; using Adw 1; -template $PaplPreferencesWindow : Adw.PreferencesWindow { +template $PaplPreferencesDialog : Adw.PreferencesDialog { Adw.PreferencesPage { Adw.PreferencesGroup { title: _("Color Scheme"); diff --git a/src/ui/session/preferences_window.rs b/src/ui/session/preferences_dialog.rs similarity index 84% rename from src/ui/session/preferences_window.rs rename to src/ui/session/preferences_dialog.rs index 4ff64438c..db0321a5d 100644 --- a/src/ui/session/preferences_window.rs +++ b/src/ui/session/preferences_dialog.rs @@ -17,8 +17,8 @@ mod imp { use super::*; #[derive(Debug, Default, CompositeTemplate)] - #[template(resource = "/app/drey/paper-plane/ui/session/preferences_window.ui")] - pub(crate) struct PreferencesWindow { + #[template(resource = "/app/drey/paper-plane/ui/session/preferences_dialog.ui")] + pub(crate) struct PreferencesDialog { pub(super) session: OnceCell, #[template_child] pub(super) follow_system_colors_switch: TemplateChild, @@ -29,10 +29,10 @@ mod imp { } #[glib::object_subclass] - impl ObjectSubclass for PreferencesWindow { - const NAME: &'static str = "PaplPreferencesWindow"; - type Type = super::PreferencesWindow; - type ParentType = adw::PreferencesWindow; + impl ObjectSubclass for PreferencesDialog { + const NAME: &'static str = "PaplPreferencesDialog"; + type Type = super::PreferencesDialog; + type ParentType = adw::PreferencesDialog; fn class_init(klass: &mut Self::Class) { klass.bind_template(); @@ -51,7 +51,7 @@ mod imp { } } - impl ObjectImpl for PreferencesWindow { + impl ObjectImpl for PreferencesDialog { fn properties() -> &'static [glib::ParamSpec] { static PROPERTIES: OnceLock> = OnceLock::new(); PROPERTIES.get_or_init(|| { @@ -96,31 +96,33 @@ mod imp { obj.setup_bindings(); - utils::spawn(clone!(@weak obj => async move { - obj.calculate_cache_size().await; - })); + utils::spawn(clone!( + #[weak] + obj, + async move { + obj.calculate_cache_size().await; + } + )); } } - impl WidgetImpl for PreferencesWindow {} - impl WindowImpl for PreferencesWindow {} - impl AdwWindowImpl for PreferencesWindow {} - impl PreferencesWindowImpl for PreferencesWindow {} + impl WidgetImpl for PreferencesDialog {} + impl AdwDialogImpl for PreferencesDialog {} + impl PreferencesDialogImpl for PreferencesDialog {} } glib::wrapper! { - pub(crate) struct PreferencesWindow(ObjectSubclass) - @extends gtk::Widget, gtk::Window, adw::Window, adw::PreferencesWindow; + pub(crate) struct PreferencesDialog(ObjectSubclass) + @extends gtk::Widget, adw::Dialog, adw::PreferencesDialog; } -impl PreferencesWindow { - pub(crate) fn new(parent_window: Option<>k::Window>, session: &ui::Session) -> Self { - glib::Object::builder() - .property("transient-for", parent_window) - .property("session", session) - .build() +impl From<&ui::Session> for PreferencesDialog { + fn from(session: &ui::Session) -> Self { + glib::Object::builder().property("session", session).build() } +} +impl PreferencesDialog { fn setup_bindings(&self) { let imp = self.imp(); @@ -142,8 +144,10 @@ impl PreferencesWindow { // 'Dark theme' switch state handling let follow_system_colors_switch = &*imp.follow_system_colors_switch; - imp.dark_theme_switch.connect_active_notify( - clone!(@weak follow_system_colors_switch => move |switch| { + imp.dark_theme_switch.connect_active_notify(clone!( + #[weak] + follow_system_colors_switch, + move |switch| { if !follow_system_colors_switch.is_active() { let style_manager = adw::StyleManager::default(); let settings = gio::Settings::new(config::APP_ID); @@ -157,8 +161,8 @@ impl PreferencesWindow { settings.set_string("color-scheme", "light").unwrap(); } } - }), - ); + } + )); // Make the 'Dark theme' switch insensitive if the 'Follow system colors' // switch is active diff --git a/src/ui/session/row.rs b/src/ui/session/row.rs index 038df1aba..6fec150e4 100644 --- a/src/ui/session/row.rs +++ b/src/ui/session/row.rs @@ -93,7 +93,7 @@ impl Row { pub(crate) async fn log_out(&self) { if let Some(session) = self.session() { - let dialog: adw::MessageDialog = adw::MessageDialog::builder() + let dialog = adw::AlertDialog::builder() .heading_use_markup(true) .heading(gettext_f( "Log out {display_name}", @@ -103,7 +103,6 @@ impl Row { )], )) .body(gettext("Are you sure you want to log out?")) - .transient_for(self.root().unwrap().downcast_ref::().unwrap()) .build(); dialog.add_responses(&[ @@ -113,7 +112,11 @@ impl Row { dialog.set_default_response(Some("cancel")); dialog.set_response_appearance("log-out", adw::ResponseAppearance::Destructive); - if dialog.choose_future().await == "log-out" { + if dialog + .choose_future(self.root().unwrap().downcast_ref::().unwrap()) + .await + == "log-out" + { let imp = self.imp(); imp.stack.set_visible_child(&imp.spinner.get()); diff --git a/src/ui/session/sidebar/chat_folder/selection.rs b/src/ui/session/sidebar/chat_folder/selection.rs index 14b82aa22..ea9f07e1e 100644 --- a/src/ui/session/sidebar/chat_folder/selection.rs +++ b/src/ui/session/sidebar/chat_folder/selection.rs @@ -106,9 +106,13 @@ mod imp { self.disconnect_model_signal(); let n_items = if let Some(ref model) = model { - let handler = model.connect_items_changed(clone!(@weak obj => move |_, p, r, a| { - obj.imp().model_items_changed(p, r, a); - })); + let handler = model.connect_items_changed(clone!( + #[weak] + obj, + move |_, p, r, a| { + obj.imp().model_items_changed(p, r, a); + } + )); self.signal_handler.replace(Some(handler)); model.n_items() diff --git a/src/ui/session/sidebar/chat_list.rs b/src/ui/session/sidebar/chat_list.rs index 5249fdc68..61e29e64a 100644 --- a/src/ui/session/sidebar/chat_list.rs +++ b/src/ui/session/sidebar/chat_list.rs @@ -83,22 +83,30 @@ mod imp { Some(chat) => { let handler_id = chat.connect_notify_local( Some("is-marked-as-unread"), - clone!(@weak self as obj => move |chat, _| { - if chat.is_marked_as_unread() { - obj.set_selected_chat(None); + clone!( + #[weak(rename_to = obj)] + self, + move |chat, _| { + if chat.is_marked_as_unread() { + obj.set_selected_chat(None); + } } - }), + ), ); self.marked_as_unread_handler_id.replace(Some(handler_id)); self.selection.set_selected_chat(Some(chat)); if chat.is_marked_as_unread() { - utils::spawn(clone!(@weak chat => async move { - if let Err(e) = chat.mark_as_read().await { - log::warn!("Error on toggling chat's unread state: {e:?}"); + utils::spawn(clone!( + #[weak] + chat, + async move { + if let Err(e) = chat.mark_as_read().await { + log::warn!("Error on toggling chat's unread state: {e:?}"); + } } - })); + )); } } None => self.selection.set_selected_chat(None), diff --git a/src/ui/session/sidebar/mod.rs b/src/ui/session/sidebar/mod.rs index 6ed87283d..a02394804 100644 --- a/src/ui/session/sidebar/mod.rs +++ b/src/ui/session/sidebar/mod.rs @@ -103,13 +103,15 @@ mod imp { } if let Some(session) = session { - session.archive_chat_list().connect_items_changed( - clone!(@weak obj, @weak session => move |chat_list, _, _, _| { + session.archive_chat_list().connect_items_changed(clone!( + #[weak] + obj, + move |chat_list, _, _, _| { if chat_list.n_items() == 0 { obj.imp().navigation_view.pop_to_tag("chats"); } - }), - ); + } + )); } self.session.set(session); diff --git a/src/ui/session/sidebar/row.rs b/src/ui/session/sidebar/row.rs index 730926bda..eb964f884 100644 --- a/src/ui/session/sidebar/row.rs +++ b/src/ui/session/sidebar/row.rs @@ -173,21 +173,25 @@ impl Row { pub(crate) fn toggle_chat_is_archived(&self) { if let Some(item) = self.item() { let chat = item.chat_(); - utils::spawn(clone!(@weak self as obj => async move { - if let Err(e) = tdlib::functions::add_chat_to_list( - chat.id(), - match item.chat_list_type().0 { - tdlib::enums::ChatList::Main => tdlib::enums::ChatList::Archive, - tdlib::enums::ChatList::Archive => tdlib::enums::ChatList::Main, - _ => return, - }, - chat.session_().client_().id(), - ) - .await - { - utils::show_toast(&obj, e.message); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + if let Err(e) = tdlib::functions::add_chat_to_list( + chat.id(), + match item.chat_list_type().0 { + tdlib::enums::ChatList::Main => tdlib::enums::ChatList::Archive, + tdlib::enums::ChatList::Archive => tdlib::enums::ChatList::Main, + _ => return, + }, + chat.session_().client_().id(), + ) + .await + { + utils::show_toast(&obj, e.message); + } } - })); + )); } } @@ -246,93 +250,141 @@ impl Row { let item_signal_group = glib::SignalGroup::new::(); item_signal_group.connect_notify_local( Some("is-pinned"), - clone!(@weak self as obj => move |_, _| { - obj.update_status_stack(); - obj.update_actions(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_status_stack(); + obj.update_actions(); + } + ), ); imp.item_signal_group.set(item_signal_group).unwrap(); let chat_signal_group = glib::SignalGroup::new::(); chat_signal_group.connect_notify_local( Some("is-marked-as-unread"), - clone!(@weak self as obj => move |_, _| { - obj.update_status_stack(); - obj.update_actions(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_status_stack(); + obj.update_actions(); + } + ), ); chat_signal_group.connect_notify_local( Some("unread-count"), - clone!(@weak self as obj => move |_, _| { - obj.update_status_stack(); - obj.update_actions(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_status_stack(); + obj.update_actions(); + } + ), ); chat_signal_group.connect_notify_local( Some("unread-mention-count"), - clone!(@weak self as obj => move |_, _| { - obj.update_status_stack(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_status_stack(); + } + ), ); chat_signal_group.connect_notify_local( Some("last-read-outbox-message-id"), - clone!(@weak self as obj => move |_, _| { - obj.update_message_status_icon(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_message_status_icon(); + } + ), ); chat_signal_group.connect_notify_local( Some("last-message"), - clone!(@weak self as obj => move |_, _| { - obj.update_message_status_icon(); - obj.update_timestamp(); - obj.update_subtitle_prefix_label(); - obj.update_minithumbnail(); - obj.update_subtitle_label(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_message_status_icon(); + obj.update_timestamp(); + obj.update_subtitle_prefix_label(); + obj.update_minithumbnail(); + obj.update_subtitle_label(); + } + ), ); chat_signal_group.connect_notify_local( Some("draft-message"), - clone!(@weak self as obj => move |_, _| { - obj.update_timestamp(); - obj.update_subtitle_prefix_label(); - obj.update_minithumbnail(); - obj.update_subtitle_label(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_timestamp(); + obj.update_subtitle_prefix_label(); + obj.update_minithumbnail(); + obj.update_subtitle_label(); + } + ), ); chat_signal_group.connect_notify_local( Some("actions"), - clone!(@weak self as obj => move |_, _| { - obj.update_subtitle_prefix_label(); - obj.update_minithumbnail(); - obj.update_subtitle_label(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_subtitle_prefix_label(); + obj.update_minithumbnail(); + obj.update_subtitle_label(); + } + ), ); chat_signal_group.connect_notify_local( Some("notification-settings"), - clone!(@weak self as obj => move |_, _| { - obj.update_unread_count_style(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_unread_count_style(); + } + ), ); imp.chat_signal_group.set(chat_signal_group).unwrap(); let session_signal_group = glib::SignalGroup::new::(); session_signal_group.connect_notify_local( Some("private-chats-notification-settings"), - clone!(@weak self as obj => move |_, _| { - obj.update_unread_count_style(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_unread_count_style(); + } + ), ); session_signal_group.connect_notify_local( Some("group-chats-notification-settings"), - clone!(@weak self as obj => move |_, _| { - obj.update_unread_count_style(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_unread_count_style(); + } + ), ); session_signal_group.connect_notify_local( Some("channel-chats-notification-settings"), - clone!(@weak self as obj => move |_, _| { - obj.update_unread_count_style(); - }), + clone!( + #[weak(rename_to = obj)] + self, + move |_, _| { + obj.update_unread_count_style(); + } + ), ); imp.session_signal_group.set(session_signal_group).unwrap(); } diff --git a/src/ui/session/sidebar/search/mod.rs b/src/ui/session/sidebar/search/mod.rs index 3ca08e10a..d97aa7d4d 100644 --- a/src/ui/session/sidebar/search/mod.rs +++ b/src/ui/session/sidebar/search/mod.rs @@ -133,9 +133,13 @@ impl Search { let imp = self.imp(); if imp.search_entry.text().is_empty() { // Update recently found chats - utils::spawn(clone!(@weak self as obj => async move { - obj.search().await; - })); + utils::spawn(clone!( + #[weak(rename_to = obj)] + self, + async move { + obj.search().await; + } + )); } else { // Reset the search entry. This will also start the search // for getting the recently found chats. @@ -166,13 +170,19 @@ impl Search { const MAX_KNOWN_CHATS: i32 = 50; imp.selection.set_model(Some(&list)); - list.connect_items_changed(clone!(@weak self as obj => move |list, _, _, _| { - obj.imp().stack.set_visible_child_name(if list.n_items() > 0 { - "results" - } else { - "empty" - }); - })); + list.connect_items_changed(clone!( + #[weak(rename_to = obj)] + self, + move |list, _, _, _| { + obj.imp() + .stack + .set_visible_child_name(if list.n_items() > 0 { + "results" + } else { + "empty" + }); + } + )); // Show the results page prematurely, so that we don't show the empty page // before even starting the search. diff --git a/src/ui/session/sidebar/selection.rs b/src/ui/session/sidebar/selection.rs index 26db3ce7c..8a6171f72 100644 --- a/src/ui/session/sidebar/selection.rs +++ b/src/ui/session/sidebar/selection.rs @@ -191,10 +191,13 @@ impl Selection { let imp = self.imp(); let n_items = if let Some(ref model) = model { - let handler = - model.connect_items_changed(clone!(@weak self as obj => move |_, p, r, a| { + let handler = model.connect_items_changed(clone!( + #[weak(rename_to = obj)] + self, + move |_, p, r, a| { obj.model_items_changed(p, r, a); - })); + } + )); imp.signal_handler.replace(Some(handler)); model.n_items() diff --git a/src/ui/session/switcher.rs b/src/ui/session/switcher.rs index 1e8935e16..3a0dab943 100644 --- a/src/ui/session/switcher.rs +++ b/src/ui/session/switcher.rs @@ -77,9 +77,13 @@ mod imp { let client_manager_view = obj.client_manager_view(); self.set_selected(&client_manager_view); - client_manager_view.connect_active_client_notify(clone!(@weak obj => move |manager| { - obj.imp().set_selected(manager); - })); + client_manager_view.connect_active_client_notify(clone!( + #[weak] + obj, + move |manager| { + obj.imp().set_selected(manager); + } + )); } } @@ -116,9 +120,13 @@ mod imp { gtk::FilterListModel::new(obj.client_manager(), Some(filter.clone())); if let Some(client_manager) = obj.client_manager() { - client_manager.connect_client_logged_in(clone!(@weak filter => move |_, _| { - filter.changed(gtk::FilterChange::Different); - })); + client_manager.connect_client_logged_in(clone!( + #[weak] + filter, + move |_, _| { + filter.changed(gtk::FilterChange::Different); + } + )); } self.selection.set_model(Some(&filter_list_model)); diff --git a/src/ui/ui-resources.gresource.xml b/src/ui/ui-resources.gresource.xml index d0fd052ed..b6aac0bd6 100644 --- a/src/ui/ui-resources.gresource.xml +++ b/src/ui/ui-resources.gresource.xml @@ -48,7 +48,7 @@ session/content/mod.ui session/content/send_media_window.ui session/mod.ui - session/preferences_window.ui + session/preferences_dialog.ui session/row.ui session/sidebar/avatar.ui session/sidebar/chat_folder/bar.ui diff --git a/src/ui/window.rs b/src/ui/window.rs index 2960d2f97..f2f7b13dd 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -51,11 +51,13 @@ mod imp { obj.client_manager_view() .client_manager() - .connect_update_notification_group( - clone!(@weak obj => move |_, notification_group, session| { + .connect_update_notification_group(clone!( + #[weak] + obj, + move |_, notification_group, session| { obj.handle_notifications(notification_group, session); - }), - ); + } + )); // Devel profile if config::PROFILE == "Devel" { @@ -183,25 +185,31 @@ impl Window { app.send_notification(Some(¬ification_id.to_string()), ¬ification); let file_id = avatar_file.id; - utils::spawn( - clone!(@weak self as obj, @weak session, @weak app => async move { + utils::spawn(clone!( + #[weak(rename_to = _obj)] + self, + #[weak] + session, + #[weak] + app, + async move { match session.download_file(file_id).await { Ok(file) => { - let texture = gdk::Texture::from_filename(file.local.path) - .unwrap(); + let texture = + gdk::Texture::from_filename(file.local.path).unwrap(); notification.set_icon(&texture); app.send_notification( Some(¬ification_id.to_string()), - ¬ification + ¬ification, ); } Err(e) => { log::warn!("Failed to download an avatar: {e:?}"); } } - }), - ); + } + )); } } } diff --git a/src/utils.rs b/src/utils.rs index b2a7f08cf..a837617b4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -8,7 +8,7 @@ use gtk::gdk; use gtk::gio; use gtk::glib; use gtk::prelude::*; -use image::io::Reader as ImageReader; +use image::ImageReader; use regex::Regex; use thiserror::Error;