diff --git a/Cargo.lock b/Cargo.lock index 36998bcbb..2e91ad04f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 4 [[package]] name = "ab_glyph_rasterizer" version = "0.1.8" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "accessory" @@ -41,7 +41,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cipher", "cpufeatures 0.2.17", ] @@ -203,7 +203,7 @@ dependencies = [ "askar-storage", "async-lock", "ciborium", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "serde_json", "zeroize", @@ -224,6 +224,11 @@ dependencies = [ "serde", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "as_variant" version = "1.3.0" @@ -233,10 +238,9 @@ checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a" [[package]] name = "ash" version = "0.38.0+1.3.281" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "libloading", + "libloading 0.8.9", ] [[package]] @@ -316,7 +320,7 @@ dependencies = [ "hex", "hmac", "itertools 0.14.0", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding", "serde", "serde_json", @@ -428,7 +432,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ - "num-traits", + "num-traits 0.2.19", ] [[package]] @@ -465,7 +469,7 @@ dependencies = [ "cmake", "dunce", "fs_extra", - "libloading", + "libloading 0.8.8", ] [[package]] @@ -567,7 +571,7 @@ dependencies = [ "cexpr", "clang-sys", "itertools 0.13.0", - "log", + "log 0.4.28", "prettyplease", "proc-macro2", "quote", @@ -580,8 +584,7 @@ dependencies = [ [[package]] name = "bit-set" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "bit-vec", ] @@ -589,8 +592,7 @@ dependencies = [ [[package]] name = "bit-vec" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "bitflags" @@ -604,7 +606,7 @@ dependencies = [ [[package]] name = "bitflags" version = "2.10.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "bitmaps" @@ -637,9 +639,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" dependencies = [ "arrayref", - "arrayvec", + "arrayvec 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "cc", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq", ] @@ -722,7 +724,7 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" version = "1.25.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "byteorder" @@ -733,7 +735,7 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "byteorder" version = "1.5.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "bytes" @@ -789,19 +791,29 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "chacha20" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cipher", "cpufeatures 0.2.17", ] @@ -812,7 +824,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures 0.3.0", "rand_core 0.10.0", ] @@ -838,7 +850,7 @@ checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", "js-sys", - "num-traits", + "num-traits 0.2.19", "serde", "wasm-bindgen", "windows-link 0.2.0", @@ -890,7 +902,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading", + "libloading 0.8.8", ] [[package]] @@ -942,15 +954,6 @@ dependencies = [ "cc", ] -[[package]] -name = "codespan-reporting" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" -dependencies = [ - "unicode-width", -] - [[package]] name = "colorchoice" version = "1.0.4" @@ -1103,7 +1106,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1136,6 +1139,11 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1235,7 +1243,7 @@ version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", @@ -1441,7 +1449,7 @@ dependencies = [ "serde_json", "serde_json_canonicalizer", "sha2 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "url", ] @@ -1514,8 +1522,7 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "downcast-rs" version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "dunce" @@ -1611,7 +1618,7 @@ version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1620,6 +1627,11 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "errno" version = "0.3.14" @@ -1636,7 +1648,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "home", "windows-sys 0.48.0", ] @@ -1694,7 +1706,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809fa2e8e59c25a41f5b2440aa937f1e84df6ae48b707e65f69ce259b1c44bda" dependencies = [ - "arrayvec", + "arrayvec 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "eyeball-im", "futures-core", "imbl", @@ -1793,6 +1805,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "foreign-types" version = "0.3.2" @@ -1948,9 +1965,9 @@ dependencies = [ [[package]] name = "fxhash" version = "0.2.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "byteorder 1.5.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "byteorder 1.5.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] @@ -1960,9 +1977,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc", - "log", + "log 0.4.28", "rustversion", "windows 0.61.3", ] @@ -1984,7 +2001,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys", "libc", "wasi 0.11.1+wasi-snapshot-preview1", @@ -1997,7 +2014,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys", "libc", "r-efi 5.3.0", @@ -2011,7 +2028,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys", "libc", "r-efi 6.0.0", @@ -2097,7 +2114,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab", "tokio", "tokio-util", @@ -2110,10 +2127,9 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ - "cfg-if", - "crunchy", - "num-traits", - "zerocopy", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "zerocopy 0.8.27", ] [[package]] @@ -2129,7 +2145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", - "equivalent", + "equivalent 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "foldhash 0.1.5", ] @@ -2140,8 +2156,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", - "equivalent", - "foldhash 0.2.0", + "equivalent 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "foldhash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" +dependencies = [ + "foldhash 0.2.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] @@ -2174,8 +2198,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hexf-parse" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "hilog-sys" @@ -2237,7 +2260,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" dependencies = [ - "log", + "log 0.4.28", "markup5ever", ] @@ -2401,7 +2424,7 @@ dependencies = [ "core-foundation-sys", "iana-time-zone-haiku", "js-sys", - "log", + "log 0.4.28", "wasm-bindgen", "windows-core 0.61.2", ] @@ -2605,12 +2628,21 @@ version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ - "equivalent", - "hashbrown 0.16.1", + "equivalent 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "serde_core", ] +[[package]] +name = "indexmap" +version = "2.13.0" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" +dependencies = [ + "equivalent 1.0.2 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "hashbrown 0.16.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", +] + [[package]] name = "inout" version = "0.1.4" @@ -2683,10 +2715,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "combine", "jni-sys", - "log", + "log 0.4.28", "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", @@ -2714,9 +2746,9 @@ version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen", ] @@ -2744,7 +2776,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "ecdsa", "elliptic-curve", "sha2 0.10.9", @@ -2793,10 +2825,19 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "windows-targets 0.53.4", ] +[[package]] +name = "libloading" +version = "0.8.9" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" +dependencies = [ + "cfg-if 1.0.4 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "windows-link 0.2.1", +] + [[package]] name = "libm" version = "0.2.15" @@ -2821,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" dependencies = [ "cc", - "pkg-config", + "pkg-config 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg", ] @@ -2862,15 +2903,20 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +[[package]] +name = "log" +version = "0.4.29" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "loom" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "generator", - "scoped-tls", + "scoped-tls 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", "tracing-subscriber", ] @@ -2941,7 +2987,7 @@ dependencies = [ [[package]] name = "makepad-apple-sys" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-objc-sys", ] @@ -2949,12 +2995,12 @@ dependencies = [ [[package]] name = "makepad-byteorder-lite" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-code-editor" version = "2.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-widgets", ] @@ -2962,7 +3008,7 @@ dependencies = [ [[package]] name = "makepad-derive-wasm-bridge" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-micro-proc-macro", ] @@ -2970,7 +3016,7 @@ dependencies = [ [[package]] name = "makepad-derive-widget" version = "2.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-live-id", "makepad-micro-proc-macro", @@ -2979,7 +3025,7 @@ dependencies = [ [[package]] name = "makepad-draw" version = "2.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "ab_glyph_rasterizer", "fxhash", @@ -2996,15 +3042,15 @@ dependencies = [ "rustybuzz", "sdfer", "serde", - "unicode-bidi 0.3.18 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "unicode-bidi 0.3.18 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "unicode-linebreak", - "unicode-segmentation 1.12.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "unicode-segmentation 1.12.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] name = "makepad-error-log" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-micro-serde", ] @@ -3012,30 +3058,41 @@ dependencies = [ [[package]] name = "makepad-filesystem-watcher" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-futures" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-futures-legacy" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-gif" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "weezl", ] +[[package]] +name = "makepad-half" +version = "2.7.1" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" +dependencies = [ + "cfg-if 1.0.4 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "crunchy 0.2.4 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "num-traits 0.2.20", + "zerocopy 0.8.39", +] + [[package]] name = "makepad-html" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-live-id", ] @@ -3049,7 +3106,7 @@ checksum = "9775cbec5fa0647500c3e5de7c850280a88335d1d2d770e5aa2332b801ba7064" [[package]] name = "makepad-latex-math" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "ttf-parser", ] @@ -3057,7 +3114,7 @@ dependencies = [ [[package]] name = "makepad-live-id" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-live-id-macros", "serde", @@ -3066,7 +3123,7 @@ dependencies = [ [[package]] name = "makepad-live-id-macros" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-micro-proc-macro", ] @@ -3074,7 +3131,7 @@ dependencies = [ [[package]] name = "makepad-live-reload-core" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-filesystem-watcher", ] @@ -3082,7 +3139,7 @@ dependencies = [ [[package]] name = "makepad-math" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-micro-serde", ] @@ -3090,12 +3147,12 @@ dependencies = [ [[package]] name = "makepad-micro-proc-macro" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-micro-serde" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-live-id", "makepad-micro-serde-derive", @@ -3104,7 +3161,7 @@ dependencies = [ [[package]] name = "makepad-micro-serde-derive" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-micro-proc-macro", ] @@ -3112,7 +3169,7 @@ dependencies = [ [[package]] name = "makepad-network" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-apple-sys", "makepad-error-log", @@ -3126,15 +3183,15 @@ dependencies = [ [[package]] name = "makepad-objc-sys" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-platform" version = "2.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "ash", - "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "ctrlc", "hilog-sys", "makepad-android-state", @@ -3156,7 +3213,7 @@ dependencies = [ "napi-derive-ohos", "napi-ohos", "ohos-sys", - "smallvec 1.15.1 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "smallvec 1.15.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "wayland-client", "wayland-egl", "wayland-protocols", @@ -3168,12 +3225,12 @@ dependencies = [ [[package]] name = "makepad-regex" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-script" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-error-log", "makepad-html", @@ -3181,13 +3238,13 @@ dependencies = [ "makepad-math", "makepad-regex", "makepad-script-derive", - "smallvec 1.15.1 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "smallvec 1.15.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] name = "makepad-script-derive" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-micro-proc-macro", ] @@ -3195,7 +3252,7 @@ dependencies = [ [[package]] name = "makepad-script-std" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-network", "makepad-script", @@ -3204,14 +3261,14 @@ dependencies = [ [[package]] name = "makepad-shared-bytes" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "makepad-studio-protocol" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "makepad-error-log", "makepad-live-id", "makepad-micro-serde", @@ -3221,7 +3278,7 @@ dependencies = [ [[package]] name = "makepad-svg" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-html", "makepad-live-id", @@ -3230,7 +3287,7 @@ dependencies = [ [[package]] name = "makepad-tsdf" version = "0.1.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-math", "makepad-micro-serde", @@ -3239,7 +3296,7 @@ dependencies = [ [[package]] name = "makepad-wasm-bridge" version = "1.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-derive-wasm-bridge", "makepad-live-id", @@ -3248,7 +3305,7 @@ dependencies = [ [[package]] name = "makepad-webp" version = "0.2.4" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-byteorder-lite", ] @@ -3256,7 +3313,7 @@ dependencies = [ [[package]] name = "makepad-widgets" version = "2.0.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-derive-widget", "makepad-draw", @@ -3265,30 +3322,30 @@ dependencies = [ "pulldown-cmark 0.12.2", "serde", "ttf-parser", - "unicode-segmentation 1.12.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "unicode-segmentation 1.12.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] name = "makepad-zune-bmp" version = "0.5.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "log", + "log 0.4.28", "makepad-zune-core", ] [[package]] name = "makepad-zune-core" version = "0.5.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "log", + "log 0.4.28", ] [[package]] name = "makepad-zune-inflate" version = "0.2.54" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "simd-adler32", ] @@ -3296,7 +3353,7 @@ dependencies = [ [[package]] name = "makepad-zune-jpeg" version = "0.5.15" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-zune-core", ] @@ -3304,7 +3361,7 @@ dependencies = [ [[package]] name = "makepad-zune-png" version = "0.5.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-zune-core", "makepad-zune-inflate", @@ -3313,7 +3370,7 @@ dependencies = [ [[package]] name = "makepad-zune-qoi" version = "0.5.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "makepad-zune-core", ] @@ -3330,7 +3387,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" dependencies = [ - "log", + "log 0.4.28", "tendril", "web_atoms", ] @@ -3388,7 +3445,7 @@ dependencies = [ "backon", "bytes", "bytesize", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "event-listener", "eyeball", "eyeball-im", @@ -3397,7 +3454,7 @@ dependencies = [ "gloo-timers", "http", "imbl", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.14.0", "js_int", "language-tags", @@ -3419,7 +3476,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tokio-stream", "tokio-util", @@ -3451,7 +3508,7 @@ dependencies = [ "ruma", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tracing", "unicode-normalization", @@ -3471,7 +3528,7 @@ dependencies = [ "ruma", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tracing", "tracing-subscriber", @@ -3491,7 +3548,7 @@ dependencies = [ "async-trait", "bs58", "byteorder 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "ctr", "eyeball", "futures-core", @@ -3509,7 +3566,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "subtle", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "time", "tokio", "tokio-stream", @@ -3542,7 +3599,7 @@ dependencies = [ "serde-wasm-bindgen", "serde_json", "sha2 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tracing", "uuid", @@ -3571,7 +3628,7 @@ dependencies = [ "serde", "serde_json", "serde_path_to_error", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tracing", "vodozemac", @@ -3595,7 +3652,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize", ] @@ -3619,7 +3676,7 @@ dependencies = [ "fuzzy-matcher", "growable-bloom-filter", "imbl", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.14.0", "matrix-sdk", "matrix-sdk-base", @@ -3629,7 +3686,7 @@ dependencies = [ "ruma", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tokio-stream", "tracing", @@ -3644,7 +3701,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245ff6a224b4df7b0c90dda2dd5a6eb46112708d49e8bdd8b007fccb09fea8e4" dependencies = [ "accessory", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "delegate-display", "derive_more 2.0.1", "fancy_constructor", @@ -3655,7 +3712,7 @@ dependencies = [ "serde", "serde-wasm-bindgen", "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "wasm-bindgen", "wasm-bindgen-futures", @@ -3682,7 +3739,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.10.7", ] @@ -3695,7 +3752,7 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memchr" version = "2.7.6" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "mime" @@ -3758,26 +3815,23 @@ dependencies = [ [[package]] name = "naga" version = "27.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "arrayvec", + "arrayvec 0.7.6 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "bit-set", "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if", - "cfg_aliases", - "codespan-reporting", - "half", - "hashbrown 0.16.1", + "cfg-if 1.0.4 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "cfg_aliases 0.2.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "hashbrown 0.16.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "hexf-parse", - "indexmap 2.13.0", - "libm", - "log", - "num-traits", - "once_cell", + "indexmap 2.13.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "makepad-error-log", + "makepad-half", + "num-traits 0.2.20", + "once_cell 1.21.3 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "rustc-hash 1.1.0", "spirv", - "thiserror 2.0.18", + "thiserror 2.0.18 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "unicode-ident", ] @@ -3788,7 +3842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b18d697bedddd2d4c9f8f76b49fe65bd81ed1c55a7eec21ba40c176c236ddc" dependencies = [ "convert_case", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2", "quote", "regex", @@ -3801,7 +3855,7 @@ version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8462d74a2d6c7a671bd610f99f9ba34c739aadd2da4d8dd9f109a7e666cc2ad2" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "convert_case", "napi-derive-backend-ohos", "proc-macro2", @@ -3818,7 +3872,7 @@ dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ctor", "napi-sys-ohos", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3827,7 +3881,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f101404db01422d034db5afa63eefff6d9c8f66c0894278bc456b4c30954e166" dependencies = [ - "libloading", + "libloading 0.8.8", ] [[package]] @@ -3837,7 +3891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", - "log", + "log 0.4.28", "openssl", "openssl-probe 0.1.6", "openssl-sys", @@ -3866,8 +3920,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if", - "cfg_aliases", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg_aliases 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc", ] @@ -3900,7 +3954,7 @@ dependencies = [ "libm", "num-integer", "num-iter", - "num-traits", + "num-traits 0.2.19", "rand 0.8.5", "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize", @@ -3918,7 +3972,7 @@ version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "num-traits", + "num-traits 0.2.19", ] [[package]] @@ -3929,7 +3983,7 @@ checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", - "num-traits", + "num-traits 0.2.19", ] [[package]] @@ -3942,6 +3996,11 @@ dependencies = [ "libm", ] +[[package]] +name = "num-traits" +version = "0.2.20" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "num_cpus" version = "1.17.0" @@ -4101,6 +4160,11 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell" +version = "1.21.3" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "once_cell_polyfill" version = "1.70.1" @@ -4120,10 +4184,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types", "libc", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-macros", "openssl-sys", ] @@ -4159,7 +4223,7 @@ checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", - "pkg-config", + "pkg-config 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg", ] @@ -4215,7 +4279,7 @@ version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc", "redox_syscall", "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4385,6 +4449,11 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "pollster" version = "0.4.0" @@ -4408,7 +4477,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures 0.2.17", "opaque-debug", "universal-hash", @@ -4435,7 +4504,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy", + "zerocopy 0.8.27", ] [[package]] @@ -4528,10 +4597,10 @@ dependencies = [ [[package]] name = "pulldown-cmark" version = "0.12.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", - "memchr 2.7.6 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", + "memchr 2.7.6 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "unicase 2.9.0", ] @@ -4560,14 +4629,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", - "cfg_aliases", + "cfg_aliases 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", "rustls", "socket2", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tracing", "web-time", @@ -4589,7 +4658,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tinyvec", "tracing", "web-time", @@ -4601,9 +4670,9 @@ version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "cfg_aliases", + "cfg_aliases 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "socket2", "tracing", "windows-sys 0.60.2", @@ -4759,7 +4828,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4831,7 +4900,7 @@ dependencies = [ "hyper-tls", "hyper-util", "js-sys", - "log", + "log 0.4.28", "mime", "native-tls", "percent-encoding", @@ -4876,7 +4945,7 @@ dependencies = [ "hyper-rustls", "hyper-util", "js-sys", - "log", + "log 0.4.28", "percent-encoding", "pin-project-lite", "quinn", @@ -4917,7 +4986,7 @@ dependencies = [ "dispatch2", "js-sys", "libc", - "log", + "log 0.4.28", "objc2", "objc2-app-kit", "objc2-core-foundation", @@ -4938,7 +5007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "getrandom 0.2.16", "libc", "untrusted 0.9.0", @@ -4952,7 +5021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" dependencies = [ "byteorder 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits", + "num-traits 0.2.19", "paste", ] @@ -5000,7 +5069,7 @@ source = "git+https://github.com/project-robius/robius#f697e566310a201528afbac66 dependencies = [ "android-build", "block2", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "dispatch2", "jni", "mime_guess", @@ -5021,7 +5090,7 @@ version = "0.3.0" source = "git+https://github.com/project-robius/robius#f697e566310a201528afbac665359d53914ffc0c" dependencies = [ "android-build", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "jni", "objc2", "objc2-core-location", @@ -5036,7 +5105,7 @@ version = "0.3.0" source = "git+https://github.com/project-robius/robius#f697e566310a201528afbac665359d53914ffc0c" dependencies = [ "block2", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "dispatch2", "jni", "objc2", @@ -5053,7 +5122,7 @@ version = "0.3.0" source = "git+https://github.com/project-robius/robius#f697e566310a201528afbac665359d53914ffc0c" dependencies = [ "android-build", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "dispatch2", "jni", "libc", @@ -5081,7 +5150,7 @@ version = "0.3.0" source = "git+https://github.com/project-robius/robius#f697e566310a201528afbac665359d53914ffc0c" dependencies = [ "block2", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "dispatch2", "objc2", "objc2-authentication-services", @@ -5106,10 +5175,10 @@ dependencies = [ "eyeball-im", "futures", "futures-util", - "hashbrown 0.16.1", + "hashbrown 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "htmlize", "imbl", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc", "linkify", "makepad-code-editor", @@ -5136,7 +5205,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "toml", "tracing-subscriber", @@ -5157,7 +5226,7 @@ dependencies = [ "digest 0.10.7", "num-bigint-dig", "num-integer", - "num-traits", + "num-traits 0.2.19", "pkcs1", "pkcs8", "rand_core 0.6.4", @@ -5199,7 +5268,7 @@ dependencies = [ "serde", "serde_html_form", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "url", "web-time", ] @@ -5216,7 +5285,7 @@ dependencies = [ "form_urlencoded", "getrandom 0.4.2", "http", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "js_int", "konst", "percent-encoding", @@ -5227,7 +5296,7 @@ dependencies = [ "serde", "serde_html_form", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "time", "tracing", "url", @@ -5243,7 +5312,7 @@ version = "0.34.0" source = "git+https://github.com/project-robius/ruma.git?branch=tsp#921e2886367b371068aa3c079ce434db608600cf" dependencies = [ "as_variant", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "js_int", "js_option", "pulldown-cmark 0.13.0", @@ -5252,7 +5321,7 @@ dependencies = [ "ruma-macros", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", "web-time", "wildmatch", @@ -5276,7 +5345,7 @@ version = "0.12.1" source = "git+https://github.com/project-robius/ruma.git?branch=tsp#921e2886367b371068aa3c079ce434db608600cf" dependencies = [ "js_int", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5285,7 +5354,7 @@ version = "0.19.0" source = "git+https://github.com/project-robius/ruma.git?branch=tsp#921e2886367b371068aa3c079ce434db608600cf" dependencies = [ "as_variant", - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate", "proc-macro2", "quote", @@ -5312,8 +5381,7 @@ dependencies = [ [[package]] name = "rustc-hash" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "rustc-hash" @@ -5350,8 +5418,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", - "log", - "once_cell", + "log 0.4.28", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring", "rustls-pki-types", "rustls-webpki", @@ -5399,8 +5467,8 @@ dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", "jni", - "log", - "once_cell", + "log 0.4.28", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustls", "rustls-native-certs", "rustls-platform-verifier-android", @@ -5438,12 +5506,12 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rustybuzz" version = "0.18.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "bitflags 2.10.0 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "bytemuck", "makepad-error-log", - "smallvec 1.15.1 (git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures)", + "smallvec 1.15.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "ttf-parser", "unicode-bidi-mirroring", "unicode-ccc", @@ -5529,6 +5597,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "scopeguard" version = "1.2.0" @@ -5538,7 +5611,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sdfer" version = "0.2.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "sealed" @@ -5673,7 +5746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0946d52b4b7e28823148aebbeceb901012c595ad737920d504fa8634bb099e6f" dependencies = [ "form_urlencoded", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "itoa", "ryu", "serde_core", @@ -5745,7 +5818,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "schemars 0.9.0", "schemars 1.1.0", "serde", @@ -5773,7 +5846,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -5784,7 +5857,7 @@ version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -5795,7 +5868,7 @@ version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d43dc0354d88b791216bb5c1bfbb60c0814460cc653ae0ebd71f286d0bd927" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures 0.2.17", "digest 0.11.0-rc.4", ] @@ -5837,7 +5910,7 @@ dependencies = [ [[package]] name = "simd-adler32" version = "0.3.9" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "siphasher" @@ -5863,7 +5936,7 @@ dependencies = [ [[package]] name = "smallvec" version = "1.15.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "socket2" @@ -5887,8 +5960,7 @@ dependencies = [ [[package]] name = "spirv" version = "0.3.0+sdk-1.3.268.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5933,16 +6005,16 @@ dependencies = [ "futures-util", "hashbrown 0.15.5", "hashlink", - "indexmap 2.13.0", - "log", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.28", "memchr 2.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding", "serde", "serde_json", "sha2 0.10.9", "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tokio-stream", "tracing", @@ -5970,7 +6042,7 @@ dependencies = [ "either", "heck", "hex", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2", "quote", "serde", @@ -6009,10 +6081,10 @@ dependencies = [ "hkdf", "hmac", "itoa", - "log", + "log 0.4.28", "md-5", "memchr 2.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding", "rand 0.8.5", "rsa", @@ -6022,7 +6094,7 @@ dependencies = [ "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "sqlx-core", "stringprep", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", "whoami", ] @@ -6048,10 +6120,10 @@ dependencies = [ "hmac", "home", "itoa", - "log", + "log 0.4.28", "md-5", "memchr 2.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.8.5", "serde", "serde_json", @@ -6059,7 +6131,7 @@ dependencies = [ "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "sqlx-core", "stringprep", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", "whoami", ] @@ -6078,12 +6150,12 @@ dependencies = [ "futures-intrusive", "futures-util", "libsqlite3-sys", - "log", + "log 0.4.28", "percent-encoding", "serde", "serde_urlencoded", "sqlx-core", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", "url", ] @@ -6212,7 +6284,7 @@ checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.3", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustix", "windows-sys 0.60.2", ] @@ -6242,7 +6314,15 @@ version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" +dependencies = [ + "thiserror-impl 2.0.18 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] @@ -6267,13 +6347,21 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" +dependencies = [ + "makepad-micro-proc-macro", +] + [[package]] name = "thread_local" version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "cfg-if", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6398,7 +6486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ "futures-util", - "log", + "log 0.4.28", "rustls", "rustls-native-certs", "rustls-pki-types", @@ -6426,7 +6514,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_core", "serde_spanned", "toml_datetime 1.1.1+spec-1.1.0", @@ -6459,7 +6547,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7211ff1b8f0d3adae1663b7da9ffe396eabe1ca25f0b0bee42b0da29a9ddce93" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml_datetime 0.7.3", "toml_parser", "winnow 0.7.13", @@ -6537,7 +6625,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "log", + "log 0.4.28", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -6560,7 +6648,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "valuable", ] @@ -6570,8 +6658,8 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "log", - "once_cell", + "log 0.4.28", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-core", ] @@ -6583,7 +6671,7 @@ checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata", "sharded-slab", "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6617,7 +6705,7 @@ dependencies = [ "futures", "getrandom 0.2.16", "hpke", - "once_cell", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "quinn", "rand 0.8.5", "rand_core 0.6.4", @@ -6630,7 +6718,7 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.11.0-rc.3", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tokio-rustls", "tokio-tungstenite", @@ -6644,7 +6732,7 @@ dependencies = [ [[package]] name = "ttf-parser" version = "0.24.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "tungstenite" @@ -6656,12 +6744,12 @@ dependencies = [ "data-encoding", "http", "httparse", - "log", + "log 0.4.28", "rand 0.9.2", "rustls", "rustls-pki-types", "sha1", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "utf-8", ] @@ -6696,7 +6784,7 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicase" version = "2.9.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-bidi" @@ -6707,17 +6795,17 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-bidi" version = "0.3.18" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-bidi-mirroring" version = "0.3.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-ccc" version = "0.3.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-ident" @@ -6728,7 +6816,7 @@ checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-linebreak" version = "0.1.5" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-normalization" @@ -6748,12 +6836,12 @@ checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-properties" version = "0.1.4" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-script" version = "0.5.8" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-segmentation" @@ -6764,13 +6852,7 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-segmentation" version = "1.12.0" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "unicode-xid" @@ -6879,7 +6961,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98bf83c0992966775b8012f194b07b44928996163e5a05b741b43891571ae5b" dependencies = [ "aes", - "arrayvec", + "arrayvec 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "base64", "base64ct", "cbc", @@ -6897,7 +6979,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "subtle", - "thiserror 2.0.18", + "thiserror 2.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek", "zeroize", ] @@ -6966,8 +7048,8 @@ version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ - "cfg-if", - "once_cell", + "cfg-if 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 1.21.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion", "wasm-bindgen-macro", "wasm-bindgen-shared", @@ -7032,7 +7114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-encoder", "wasmparser", ] @@ -7089,18 +7171,18 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver", ] [[package]] name = "wayland-backend" version = "0.3.12" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "downcast-rs", "libc", - "scoped-tls", + "scoped-tls 1.0.1 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", "smallvec 1.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-sys", ] @@ -7108,7 +7190,7 @@ dependencies = [ [[package]] name = "wayland-client" version = "0.31.12" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc", @@ -7118,7 +7200,7 @@ dependencies = [ [[package]] name = "wayland-egl" version = "0.32.9" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "wayland-backend", "wayland-sys", @@ -7127,7 +7209,7 @@ dependencies = [ [[package]] name = "wayland-protocols" version = "0.32.10" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-backend", @@ -7137,10 +7219,10 @@ dependencies = [ [[package]] name = "wayland-sys" version = "0.31.8" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ - "log", - "pkg-config", + "log 0.4.29", + "pkg-config 0.3.32 (git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback)", ] [[package]] @@ -7188,7 +7270,7 @@ dependencies = [ [[package]] name = "weezl" version = "0.1.12" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "whoami" @@ -7241,7 +7323,7 @@ dependencies = [ [[package]] name = "windows" version = "0.62.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "windows-collections 0.3.2", "windows-core 0.62.2", @@ -7260,7 +7342,7 @@ dependencies = [ [[package]] name = "windows-collections" version = "0.3.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "windows-core 0.62.2", ] @@ -7293,7 +7375,7 @@ dependencies = [ [[package]] name = "windows-core" version = "0.62.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "windows-link 0.2.1", "windows-result 0.4.1", @@ -7314,7 +7396,7 @@ dependencies = [ [[package]] name = "windows-future" version = "0.3.2" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "windows-core 0.62.2", ] @@ -7378,7 +7460,7 @@ checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" [[package]] name = "windows-link" version = "0.2.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" [[package]] name = "windows-numerics" @@ -7422,7 +7504,7 @@ dependencies = [ [[package]] name = "windows-result" version = "0.4.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "windows-link 0.2.1", ] @@ -7439,7 +7521,7 @@ dependencies = [ [[package]] name = "windows-strings" version = "0.5.1" -source = "git+https://github.com/kevinaboos/makepad?branch=view_optimize_dont_redraw_cached_textures#19ff922e6f4a5d9f9ec974fb43683250049135fb" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" dependencies = [ "windows-link 0.2.1", ] @@ -7809,7 +7891,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap 2.13.0", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettyplease", "syn 2.0.106", "wasm-metadata", @@ -7840,8 +7922,8 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 2.13.0", - "log", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.28", "serde", "serde_derive", "serde_json", @@ -7859,8 +7941,8 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.0", - "log", + "indexmap 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.28", "semver", "serde", "serde_derive", @@ -7926,6 +8008,11 @@ dependencies = [ "zerocopy-derive", ] +[[package]] +name = "zerocopy" +version = "0.8.39" +source = "git+https://github.com/kevinaboos/makepad?branch=gl_sampling_fallback#7148c4166b7e0a60b59364af68311db41bdade41" + [[package]] name = "zerocopy-derive" version = "0.8.27" diff --git a/Cargo.toml b/Cargo.toml index 4822aa6c0..6a01c52f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,8 @@ metadata.makepad-auto-version = "zqpv-Yj-K7WNVK2I8h5Okhho46Q=" # makepad-widgets = { git = "https://github.com/makepad/makepad", branch = "dev", features = ["serde"] } # makepad-code-editor = { git = "https://github.com/makepad/makepad", branch = "dev" } -makepad-widgets = { git = "https://github.com/kevinaboos/makepad", branch = "view_optimize_dont_redraw_cached_textures", features = ["serde"] } -makepad-code-editor = { git = "https://github.com/kevinaboos/makepad", branch = "view_optimize_dont_redraw_cached_textures" } +makepad-widgets = { git = "https://github.com/kevinaboos/makepad", branch = "gl_sampling_fallback", features = ["serde"] } +makepad-code-editor = { git = "https://github.com/kevinaboos/makepad", branch = "gl_sampling_fallback" } ## Including this crate automatically configures all `robius-*` crates to work with Makepad. diff --git a/resources/icons/add.svg b/resources/icons/add.svg index d9b0c3644..17adbcd92 100644 --- a/resources/icons/add.svg +++ b/resources/icons/add.svg @@ -1,4 +1,6 @@ - - - + + + + diff --git a/resources/icons/upload.svg b/resources/icons/upload.svg index 07226e4d9..6664005db 100644 --- a/resources/icons/upload.svg +++ b/resources/icons/upload.svg @@ -1,5 +1,5 @@ - - - - - \ No newline at end of file + + + + + diff --git a/src/home/add_room.rs b/src/home/add_room.rs index 35818e340..5ce56ea50 100644 --- a/src/home/add_room.rs +++ b/src/home/add_room.rs @@ -585,11 +585,11 @@ impl Widget for AddRoomScreen { FetchedRoomAvatar::Text(text) => { room_avatar.show_text(cx, None, None, text); } - FetchedRoomAvatar::Image(image_data) => { + FetchedRoomAvatar::Image(avatar_image) => { let res = room_avatar.show_image( cx, None, - |cx, img_ref| utils::load_image(&img_ref, cx, image_data), + |cx, img_ref| utils::load_avatar_image(&img_ref, cx, avatar_image), ); if res.is_err() { room_avatar.show_text( diff --git a/src/home/home_screen.rs b/src/home/home_screen.rs index 2531fe82d..304b94e37 100644 --- a/src/home/home_screen.rs +++ b/src/home/home_screen.rs @@ -640,6 +640,11 @@ impl HomeScreen { fn sync_effective_view_mode(&mut self, cx: &mut Cx, app_state: &mut AppState) { let is_desktop = effective_is_desktop(cx); let Some(was_desktop) = self.last_effective_is_desktop.replace(is_desktop) else { + // Mobile mode starts on the rooms list with no room open, so no + // room should be drawn as selected until one is actually clicked. + if !is_desktop { + cx.action(AppStateAction::FocusNone); + } return; }; if was_desktop == is_desktop { @@ -661,6 +666,12 @@ impl HomeScreen { } self.clear_mobile_navigation_state(cx); + + // Switching into mobile mode lands on the rooms list, so no room should + // be drawn as selected until one is actually clicked. + if !is_desktop { + cx.action(AppStateAction::FocusNone); + } } fn update_active_page_from_selection( @@ -771,6 +782,8 @@ impl HomeScreen { let stack_navigation_view = stack_navigation.view_by_id(cx, view_id); Self::hide_displayed_stack_screen(cx, &stack_navigation_view); } + // Also go back to the root stack view to ensure no old roomscreens persist. + stack_navigation.pop_to_root(cx); } fn hide_displayed_stack_screen(cx: &mut Cx, stack_navigation_view: &WidgetRef) { @@ -827,6 +840,9 @@ impl HomeScreen { return; } let Some(current_screen) = app_state.selected_room.take() else { + // If we didn't have a current screen, something's buggy, + // so the safest option is to clear the mobile stack and start over. nbd. + self.mobile_screen_history.clear(); return; }; match self.mobile_screen_history.pop() { diff --git a/src/home/invite_screen.rs b/src/home/invite_screen.rs index 02e54c6e4..a4bab8ff1 100644 --- a/src/home/invite_screen.rs +++ b/src/home/invite_screen.rs @@ -392,11 +392,11 @@ impl Widget for InviteScreen { let (is_visible, invite_text) = if let Some(inviter) = info.inviter.as_ref() { let inviter_avatar = inviter_view.avatar(cx, ids!(inviter_avatar)); let mut drew_avatar = false; - if let Some(avatar_bytes) = inviter.avatar.as_ref() { + if let Some(avatar_image) = inviter.avatar.as_ref() { drew_avatar = inviter_avatar.show_image( cx, None, // don't make this avatar clickable. - |cx, img| utils::load_image(&img, cx, avatar_bytes), + |cx, img| utils::load_avatar_image(&img, cx, avatar_image), ).is_ok(); } if !drew_avatar { @@ -441,11 +441,11 @@ impl Widget for InviteScreen { text, ); } - FetchedRoomAvatar::Image(avatar_bytes) => { + FetchedRoomAvatar::Image(avatar_image) => { let _ = room_avatar.show_image( cx, None, // don't make this avatar clickable. - |cx, img| utils::load_image(&img, cx, avatar_bytes), + |cx, img| utils::load_avatar_image(&img, cx, avatar_image), ); } } diff --git a/src/home/light_themed_dock.rs b/src/home/light_themed_dock.rs index 8b2e03334..0ee9c7ed5 100644 --- a/src/home/light_themed_dock.rs +++ b/src/home/light_themed_dock.rs @@ -149,9 +149,14 @@ script_mod! { draw_bg +: { // Light blue-ish color, de-saturated from COLOR_ACTIVE_PRIMARY color: #E1EEFA + color_2: #E1EEFA // A slightly darker shade of the tab color for hover visibility color_hover: #C8DDEF - color_active: COLOR_ACTIVE_PRIMARY + color_2_hover: #C8DDEF + // Active (selected) tabs are a deeper blue, with a vertical gradient + // to a slightly lighter blue. + color_active: #0660FE + color_2_active: #398CFE // Remove the border and rounded corners from the default Tab style border_size: 0.0 border_radius: 3.0 diff --git a/src/home/navigation_tab_bar.rs b/src/home/navigation_tab_bar.rs index 037c8988d..05046f35c 100644 --- a/src/home/navigation_tab_bar.rs +++ b/src/home/navigation_tab_bar.rs @@ -140,8 +140,8 @@ script_mod! { margin: 0, icon_walk: Walk { margin: 0, - width: 30, - height: 30 + width: 27, + height: 27 } draw_icon +: { color: (COLOR_NAVIGATION_TAB_FG) @@ -173,6 +173,7 @@ script_mod! { mod.widgets.NavigationTabBar = #(NavigationTabBar::register_widget(vm)) { Desktop := RoundedView { + new_batch: true, flow: Down, align: Align{x: 0.5} padding: Inset{ @@ -206,6 +207,7 @@ script_mod! { } Mobile := RoundedView { + new_batch: true, flow: Right align: Align{x: 0.5, y: 0.5} width: Fill, @@ -417,11 +419,11 @@ impl Widget for ProfileIcon { }; let mut drew_avatar = false; - if let Some(avatar_img_data) = own_profile.avatar_state.data() { + if let Some(avatar_image) = own_profile.avatar_state.image() { drew_avatar = our_own_avatar.show_image( cx, None, // don't make this avatar clickable; we handle clicks on this ProfileIcon widget directly. - |cx, img| utils::load_image(&img, cx, avatar_img_data), + |cx, img| utils::load_avatar_image(&img, cx, avatar_image), ).is_ok(); } if !drew_avatar { @@ -673,7 +675,7 @@ pub fn get_own_profile(cx: &mut Cx) -> Option { if let Some(Some(avatar_uri)) = avatar_uri_to_fetch { if let AvatarCacheEntry::Loaded(data) = avatar_cache::get_or_fetch_avatar(cx, &avatar_uri) { if let Some(p) = own_profile.as_mut() { - p.avatar_state = AvatarState::Loaded(data); + p.avatar_state = AvatarState::Loaded((avatar_uri.clone(), data).into()); // Update the user profile cache with the new avatar data. user_profile_cache::enqueue_user_profile_update( UserProfileUpdate::UserProfileOnly(p.clone()) diff --git a/src/home/room_read_receipt.rs b/src/home/room_read_receipt.rs index 42cb29995..8d4985f40 100644 --- a/src/home/room_read_receipt.rs +++ b/src/home/room_read_receipt.rs @@ -85,7 +85,15 @@ pub struct AvatarRow { } impl Widget for AvatarRow { - fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { + // The avatars aren't children of this widget (they're created from a template), + // so we have to manually forward events to them (mostly async image loads). + if let Event::Actions(_) = event { + for (avatar_ref, _) in self.buttons.iter() { + avatar_ref.handle_event(cx, event, scope); + } + } + let Some(read_receipts) = &self.read_receipts else { return; }; diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index 603df2bd2..776a0ed81 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -30,9 +30,9 @@ use crate::{ user_profile::{ShowUserProfileAction, UserProfile, UserProfileAndRoomId, UserProfilePaneInfo, UserProfileSlidingPaneRef, UserProfileSlidingPaneWidgetExt}, user_profile_cache, }, - room::{BasicRoomDetails, reply_preview::CollapsiblePreviewWidgetRefExt, room_input_bar::{RoomInputBarState, RoomInputBarWidgetRefExt}, typing_notice::TypingNoticeWidgetExt}, + room::{BasicRoomDetails, reply_preview::{CollapsiblePreviewRef, CollapsiblePreviewWidgetRefExt}, room_input_bar::{RoomInputBarState, RoomInputBarWidgetRefExt}, typing_notice::TypingNoticeWidgetExt}, shared::{ - attachment_download::{enqueue_already_downloading_notification, DownloadDisplayState, DownloadKind, DownloadableAttachment, PendingDownload, PendingDownloadState, TimelineUpdateSenderOption, TransferKind, media_source_mxc, start_attachment_download, start_attachment_share}, avatar::{AvatarState, AvatarWidgetRefExt}, confirmation_modal::ConfirmationModalContent, file_upload_modal::FileUploadAttemptId, html_or_plaintext::{HtmlOrPlaintextRef, HtmlOrPlaintextWidgetRefExt, RobrixHtmlLinkAction}, image_viewer::{ImageViewerAction, ImageViewerMetaData, LoadState}, jump_to_bottom_button::{JumpToBottomButtonWidgetExt, UnreadMessageCount}, popup_list::{PopupKind, enqueue_popup_notification}, restore_status_view::RestoreStatusViewWidgetExt, room_input_popup_menu::{RoomInputPopupMenuAction, RoomInputPopupMenuWidgetExt}, styles::*, text_or_image::{TextOrImageAction, TextOrImageRef, TextOrImageStatus, TextOrImageWidgetRefExt}, timestamp::TimestampWidgetRefExt + attachment_download::{enqueue_already_downloading_notification, DownloadDisplayState, DownloadKind, DownloadableAttachment, PendingDownload, PendingDownloadState, TimelineUpdateSenderOption, TransferKind, media_source_mxc, start_attachment_download, start_attachment_share}, avatar::{AvatarState, AvatarWidgetRefExt}, confirmation_modal::ConfirmationModalContent, file_upload_modal::FileUploadAttemptId, html_or_plaintext::{HtmlOrPlaintextRef, HtmlOrPlaintextWidgetRefExt, RobrixHtmlLinkAction}, image_viewer::{ImageViewerAction, ImageViewerMetaData, LoadState}, jump_to_bottom_button::{JumpToBottomButtonWidgetExt, UnreadMessageCount}, popup_list::{PopupKind, enqueue_popup_notification}, restore_status_view::RestoreStatusViewWidgetExt, room_input_popup_menu::{RoomInputPopupMenuAction, RoomInputPopupMenuRef, RoomInputPopupMenuWidgetExt}, styles::*, text_or_image::{TextOrImageAction, TextOrImageRef, TextOrImageStatus, TextOrImageWidgetRefExt}, timestamp::TimestampWidgetRefExt }, sliding_sync::{BackwardsPaginateUntilEventRequest, MatrixRequest, PaginationDirection, TimelineEndpoints, TimelineKind, TimelineRequestSender, UserPowerLevels, submit_async_request, take_timeline_endpoints}, utils::{self, MEDIA_THUMBNAIL_FORMAT, RoomNameId, unix_time_millis_to_datetime} }; @@ -634,6 +634,7 @@ script_mod! { height: Fill, align: Align{x: 0.5, y: 0.0} // center horizontally, align to top vertically flow: Overlay, + new_batch: true list := PortalList { height: Fill, @@ -641,7 +642,13 @@ script_mod! { flow: Down auto_tail: true, // set to `true` to lock the view to the last item. - max_pull_down: 0.0, // set to `0.0` to disable the pulldown bounce animation. + // only bounce at the end, not the start because that triggers back pagination. + bounce_at_start: false, + bounce_at_end: true, + // Read-receipt logic listens for scroll position changes. + emit_scroll_actions: true, + // Prefetch older history shortly before the user actually hits the top. + reached_start_margin: 2, // TODO: enable `reuse_items: true` once Makepad's Html/TextFlow widget // properly resets all internal state during `script_apply(Reload)`. // Currently, stale TextFlow layout state (particularly related to @@ -759,6 +766,16 @@ pub struct RoomScreen { #[rust] relayout_redraws_left: u8, #[rust] relayout_last_first_id: usize, #[rust] relayout_last_scroll: f64, + #[rust] cached_refs: Option, +} + +/// Cached references to RoomScreen child widgets used in every event handler. +#[derive(Clone)] +struct RoomScreenWidgetRefs { + portal_list: PortalListRef, + user_profile_sliding_pane: UserProfileSlidingPaneRef, + loading_pane: LoadingPaneRef, + room_input_popup_menu: RoomInputPopupMenuRef, } impl Drop for RoomScreen { @@ -774,6 +791,8 @@ impl Drop for RoomScreen { impl ScriptHook for RoomScreen { fn on_after_reload(&mut self, vm: &mut ScriptVm) { + // A script reload changes the RoomScreen's children; invalidate the ones we cached. + self.cached_refs = None; vm.with_cx_mut(|cx| { if let Some(tl_state) = &mut self.tl_state.as_mut() { // Clear the timeline's drawn items caches and redraw it. @@ -794,10 +813,12 @@ impl Widget for RoomScreen { } let room_screen_widget_uid = self.widget_uid(); - let portal_list = self.portal_list(cx, ids!(timeline.list)); - let user_profile_sliding_pane = self.user_profile_sliding_pane(cx, ids!(user_profile_sliding_pane)); - let loading_pane = self.loading_pane(cx, ids!(loading_pane)); - let room_input_popup_menu = self.room_input_popup_menu(cx, ids!(room_input_popup_menu)); + let RoomScreenWidgetRefs { + portal_list, + user_profile_sliding_pane, + loading_pane, + room_input_popup_menu, + } = self.cached_widget_refs(cx); // Handle actions here before processing timeline updates. // Normally (in most other widgets), the order of event handling doesn't matter much. @@ -994,8 +1015,8 @@ impl Widget for RoomScreen { } */ - // Set visibility of loading message banner based of pagination logic - self.send_pagination_request_based_on_scroll_pos(cx, actions, &portal_list); + // Back paginate the timeline when the start of the timeline comes into view. + self.send_pagination_request_on_reached_start(cx, actions, &portal_list); // Handle sending any read receipts for the current logged-in user. self.send_user_read_receipts_based_on_scroll_pos(cx, actions, &portal_list); @@ -1379,8 +1400,12 @@ impl Widget for RoomScreen { // If the list is not filling the viewport, we need to back paginate the timeline // until we have enough events items to fill the viewport. - if !tl_state.fully_paginated && !list.is_filling_viewport() { + if !tl_state.fully_paginated + && !tl_state.is_paginating + && !list.is_filling_viewport() + { log!("Automatically paginating timeline to fill viewport for room {:?}", self.room_name_id); + tl_state.is_paginating = true; submit_async_request(MatrixRequest::PaginateTimeline { timeline_kind: tl_state.kind.clone(), num_events: 50, @@ -1489,7 +1514,9 @@ impl RoomScreen { TimelineUpdate::FirstUpdate { initial_items } => { tl.content_drawn_since_last_update.clear(); tl.profile_drawn_since_last_update.clear(); + // Upon first showing a timeline, assume it's not fully paginated nor currently paginating. tl.fully_paginated = false; + tl.is_paginating = false; // Set the portal list to the very bottom of the timeline. portal_list.set_first_id_and_scroll(initial_items.len().saturating_sub(1), 0.0); portal_list.set_tail_range(true); @@ -1607,7 +1634,15 @@ impl RoomScreen { if clear_cache { tl.content_drawn_since_last_update.clear(); tl.profile_drawn_since_last_update.clear(); + let has_more_history = !tl.fully_paginated; tl.fully_paginated = false; + tl.is_paginating = false; + // If the top of the timeline is still visible after getting new items, + // go ahead and fetch more items proactively so that the user + // doesn't have to do some kind of annoying scroll-up gesture again. + if has_more_history && portal_list.first_id() <= 2 { + should_continue_backwards_pagination = true; + } } else { tl.content_drawn_since_last_update.remove(changed_indices.clone()); tl.profile_drawn_since_last_update.remove(changed_indices.clone()); @@ -1673,6 +1708,7 @@ impl RoomScreen { } TimelineUpdate::PaginationRunning(direction) => { if direction == PaginationDirection::Backwards { + tl.is_paginating = true; top_space.set_visible(cx, true); done_loading = false; } else { @@ -1687,6 +1723,10 @@ impl RoomScreen { PopupKind::Error, Some(10.0), ); + tl.is_paginating = false; + // We could automatically retry here after a failure, but it's not + // really that valuable when the user can just try to scroll again. + tl.pending_reached_start = false; done_loading = true; } TimelineUpdate::PaginationIdle { fully_paginated, direction } => { @@ -1694,8 +1734,13 @@ impl RoomScreen { // Don't set `done_loading` to `true` here, because we want to keep the top space visible // (with the "loading" message) until the corresponding `NewItems` update is received. tl.fully_paginated = fully_paginated; + tl.is_paginating = false; if fully_paginated { + tl.pending_reached_start = false; done_loading = true; + } else if tl.pending_reached_start || portal_list.first_id() <= 2 { + tl.pending_reached_start = false; + should_continue_backwards_pagination = true; } } else { error!("Unexpected PaginationIdle update in the Forwards direction"); @@ -1851,6 +1896,7 @@ impl RoomScreen { } if should_continue_backwards_pagination { + tl.is_paginating = true; submit_async_request(MatrixRequest::PaginateTimeline { timeline_kind: tl.kind.clone(), num_events: 50, @@ -2601,6 +2647,7 @@ impl RoomScreen { room_members: None, // We assume timelines being viewed for the first time haven't been fully paginated. fully_paginated: false, + is_paginating: false, items: Vector::new(), content_drawn_since_last_update: RangeSet::new(), profile_drawn_since_last_update: RangeSet::new(), @@ -2612,7 +2659,7 @@ impl RoomScreen { pending_thread_summary_fetches: HashSet::new(), saved_state: SavedState::default(), message_highlight_animation_state: MessageHighlightAnimationState::default(), - last_scrolled_index: usize::MAX, + pending_reached_start: false, prev_first_index: None, scrolled_past_read_marker: false, latest_own_user_receipt: None, @@ -2651,8 +2698,9 @@ impl RoomScreen { // because we want to show the user some messages as soon as possible // when they first open the room, and there might not be any messages yet. if is_first_time_being_loaded { - if !tl_state.fully_paginated { + if !tl_state.fully_paginated && !tl_state.is_paginating { log!("Sending a first-time backwards pagination request for {}", tl_state.kind); + tl_state.is_paginating = true; submit_async_request(MatrixRequest::PaginateTimeline { timeline_kind: tl_state.kind.clone(), num_events: 50, @@ -2848,8 +2896,8 @@ impl RoomScreen { } // If this timeline is already displayed, we don't need to do anything major, - // but we do need update the `room_name_id` in case it has changed, or it has been cleared. - if self.timeline_kind.as_ref().is_some_and(|kind| kind == &timeline_kind) { + // but we do need update the `room_name_id` in case it has changed/cleared. + if self.tl_state.is_some() && self.timeline_kind.as_ref().is_some_and(|k| k == &timeline_kind) { self.room_name_id = Some(room_name_id.clone()); return; } @@ -2960,30 +3008,43 @@ impl RoomScreen { } } - /// Sends a backwards pagination request if the user is scrolling up - /// and is approaching the top of the timeline. - fn send_pagination_request_based_on_scroll_pos( + /// Returns the widget refs used on every event, caching them if None. + fn cached_widget_refs(&mut self, cx: &mut Cx) -> RoomScreenWidgetRefs { + if let Some(refs) = &self.cached_refs { + return refs.clone(); + } + let refs = RoomScreenWidgetRefs { + portal_list: self.portal_list(cx, ids!(timeline.list)), + user_profile_sliding_pane: self.user_profile_sliding_pane(cx, ids!(user_profile_sliding_pane)), + loading_pane: self.loading_pane(cx, ids!(loading_pane)), + room_input_popup_menu: self.room_input_popup_menu(cx, ids!(room_input_popup_menu)), + }; + self.cached_refs = Some(refs.clone()); + refs + } + + /// Sends a backwards pagination request if the first item(s) in the timeline are visible. + fn send_pagination_request_on_reached_start( &mut self, _cx: &mut Cx, actions: &ActionsBuf, portal_list: &PortalListRef, ) { let Some(tl) = self.tl_state.as_mut() else { return }; + if !portal_list.reached_start(actions) { return }; if tl.fully_paginated { return }; - if !portal_list.scrolled(actions) { return }; - - let first_index = portal_list.first_id(); - if first_index == 0 && tl.last_scrolled_index > 0 { - log!("Scrolled up from item {} --> 0, sending back pagination request for room {}", - tl.last_scrolled_index, tl.kind, - ); - submit_async_request(MatrixRequest::PaginateTimeline { - timeline_kind: tl.kind.clone(), - num_events: 50, - direction: PaginationDirection::Backwards, - }); + if tl.is_paginating { + tl.pending_reached_start = true; + return; } - tl.last_scrolled_index = first_index; + + log!("Timeline hit first item, sending back pagination request for room {}", tl.kind); + tl.is_paginating = true; + submit_async_request(MatrixRequest::PaginateTimeline { + timeline_kind: tl.kind.clone(), + num_events: 50, + direction: PaginationDirection::Backwards, + }); } } @@ -3327,6 +3388,9 @@ struct TimelineUiState { /// This must be reset to `false` whenever the timeline is fully cleared. fully_paginated: bool, + /// Whether a pagination request is currently in flight. + is_paginating: bool, + /// The list of items (events) in this room's timeline that our client currently knows about. items: Vector>, @@ -3384,11 +3448,9 @@ struct TimelineUiState { /// If the animation was triggered, the state goes back to Off. message_highlight_animation_state: MessageHighlightAnimationState, - /// The index of the timeline item that was most recently scrolled up past it. - /// This is used to detect when the user has scrolled up past the second visible item (index 1) - /// upwards to the first visible item (index 0), which is the top of the timeline, - /// at which point we submit a backwards pagination request to fetch more events. - last_scrolled_index: usize, + /// Whether the first item(s) in the timeline became visible while an existing + /// pagination request was already in flight. + pending_reached_start: bool, /// The index of the first item shown in the timeline's PortalList from *before* the last "jump". /// @@ -4403,9 +4465,12 @@ fn populate_image_message_content( let mut fetch_and_show_media_source = |cx: &mut Cx, media_source: MediaSource, image_info: Box| { match media_cache.try_get_media_or_fetch(&media_source, MEDIA_THUMBNAIL_FORMAT.into()) { - (MediaCacheEntry::Loaded(data), _media_format) => { + (MediaCacheEntry::Loaded(data), media_format) => { + // Include the file type (full or thumbnail) in the cache key to disambiguate. + let variant = if matches!(media_format, MediaFormat::File) { "full" } else { "thumb" }; + let cache_key = format!("{}#{variant}", media_source_mxc(&media_source)); let show_image_result = text_or_image_ref.show_image(cx, Some(media_source), |cx, img| { - utils::load_image(&img, cx, &data) + utils::load_image_with_cache_key(&img, cx, std::path::Path::new(&cache_key), Arc::clone(&data)) .map(|()| img.size_in_pixels(cx).unwrap_or_default()) }); if let Err(e) = show_image_result { @@ -5350,7 +5415,7 @@ impl ActionDefaultRef for MessageAction { } /// A widget representing a single message of any kind within a room timeline. -#[derive(Script, ScriptHook, Widget, Animator)] +#[derive(Script, Widget, Animator)] pub struct Message { #[source] source: ScriptObjectRef, #[deref] view: View, @@ -5364,6 +5429,18 @@ pub struct Message { /// Cached so `set_data` can reset_hover only on the button that just /// transitioned into visibility, not on every redraw. #[rust] download_state: DownloadDisplayState, + + // Belowhere: cached references to child widgets, for efficiency. + #[rust] replied_to_message_view: Option, + #[rust] thread_root_summary_view: Option, +} + +impl ScriptHook for Message { + fn on_after_reload(&mut self, _vm: &mut ScriptVm) { + // A script reload changes the Message's children; invalidate the ones we cached. + self.replied_to_message_view = None; + self.thread_root_summary_view = None; + } } impl Widget for Message { @@ -5380,7 +5457,10 @@ impl Widget for Message { let Some(details) = self.details.clone() else { return }; - let reply = self.view.widget(cx, ids!(replied_to_message)).as_collapsible_preview(); + // We first handle a click on the replied-to message preview, if present, + // because we don't want any widgets within the replied-to message to be + // clickable or otherwise interactive. + let reply = self.replied_to_message_view(cx); let reply_content_area = reply.content_area(cx); match event.hits(cx, reply_content_area) { Hit::FingerHoverIn(..) => { @@ -5422,7 +5502,7 @@ impl Widget for Message { // Handle clicks on the thread summary shown beneath a thread-root message. if let Some(thread_root_event_id) = details.thread_root_event_id.as_ref() { - let thread_root_summary = self.view(cx, ids!(thread_root_summary)); + let thread_root_summary = self.thread_root_summary_view(cx); let apply_hover = |cx: &mut Cx, bg_color: Vec4| { let mut thread_root_summary_ref = thread_root_summary.clone(); script_apply_eval!(cx, thread_root_summary_ref, { @@ -5575,8 +5655,26 @@ impl Widget for Message { } impl Message { + fn replied_to_message_view(&mut self, cx: &mut Cx) -> CollapsiblePreviewRef { + if let Some(reply) = &self.replied_to_message_view { + return reply.clone(); + } + let reply = self.view.widget(cx, ids!(replied_to_message)).as_collapsible_preview(); + self.replied_to_message_view = Some(reply.clone()); + reply + } + + fn thread_root_summary_view(&mut self, cx: &mut Cx) -> ViewRef { + if let Some(view) = &self.thread_root_summary_view { + return view.clone(); + } + let view = self.view(cx, ids!(thread_root_summary)); + self.thread_root_summary_view = Some(view.clone()); + view + } + /// Called every time `populate_message_view` runs, including on cached - /// items, so all state must be re-set unconditionally. + /// items, so all states must be re-set unconditionally. fn set_data( &mut self, cx: &mut Cx, diff --git a/src/home/rooms_list.rs b/src/home/rooms_list.rs index 2c9e11859..066aaf1a2 100644 --- a/src/home/rooms_list.rs +++ b/src/home/rooms_list.rs @@ -34,6 +34,7 @@ use crate::{ room_display_filter::{RoomDisplayFilter, RoomDisplayFilterBuilder, RoomFilterCriteria, SortFn}, }, shared::{ + avatar::AvatarImage, collapsible_header::{CollapsibleHeaderAction, CollapsibleHeaderWidgetRefExt, HeaderCategory}, jump_to_bottom_button::UnreadMessageCount, popup_list::{PopupKind, enqueue_popup_notification}, @@ -120,6 +121,8 @@ script_mod! { list := PortalList { keep_invisible: false, + // Nothing here listens for scroll position changes. + emit_scroll_actions: false, auto_tail: false, width: Fill, height: Fill flow: Down, @@ -337,7 +340,7 @@ pub struct InvitedRoomInfo { pub struct InviterInfo { pub user_id: OwnedUserId, pub display_name: Option, - pub avatar: Option>, + pub avatar: Option, } impl std::fmt::Debug for InviterInfo { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -1184,12 +1187,8 @@ impl Widget for RoomsList { // First, we handle any actions that came from widgets within the room list, // e.g., the user clicking on a RoomsListEntry to select a room. - // We use Scope `props` to pass down the current scrolling state of the PortalList. - let props = RoomsListScopeProps { - was_scrolling: self.view.portal_list(cx, ids!(list)).was_scrolling(), - }; let rooms_list_actions = cx.capture_actions( - |cx| self.view.handle_event(cx, event, &mut Scope::with_props(&props)) + |cx| self.view.handle_event(cx, event, &mut Scope::empty()) ); for action in rooms_list_actions { // Handle a regular room (joined or invited) being clicked. @@ -1636,11 +1635,6 @@ impl RoomsListRef { } } -pub struct RoomsListScopeProps { - /// Whether the RoomsList's inner PortalList was scrolling - /// when the latest finger down event occurred. - pub was_scrolling: bool, -} /// The set of indexes for each room category in the the RoomsList's PortalList. /// diff --git a/src/home/rooms_list_entry.rs b/src/home/rooms_list_entry.rs index 01f5441b1..85e8ea6c7 100644 --- a/src/home/rooms_list_entry.rs +++ b/src/home/rooms_list_entry.rs @@ -2,13 +2,15 @@ use makepad_widgets::*; use matrix_sdk::ruma::OwnedRoomId; use crate::{ - room::FetchedRoomAvatar, settings::app_preferences::effective_is_desktop, shared::{ - avatar::AvatarWidgetExt, + room::FetchedRoomAvatar, + shared::{ + avatar::AvatarWidgetExt, html_or_plaintext::HtmlOrPlaintextWidgetExt, unread_badge::UnreadBadgeWidgetExt as _, - }, utils::{self, relative_format} + }, + utils::{self, relative_format} }; -use super::rooms_list::{InvitedRoomInfo, InviterInfo, JoinedRoomInfo, RoomsListScopeProps}; +use super::rooms_list::{InvitedRoomInfo, InviterInfo, JoinedRoomInfo}; script_mod! { use mod.prelude.widgets.* use mod.widgets.* @@ -180,6 +182,8 @@ script_mod! { height: Fit flow: Overlay align: Align{ x: 1.0 } + // Don't clip (cut-off) the unread badge's glow + clip_x: false, clip_y: false avatar := Avatar {} unread_badge := UnreadBadge {} tombstone_icon := mod.widgets.TombstoneIcon {} @@ -200,6 +204,8 @@ script_mod! { flow: Down width: Fill, height: 56 align: Align{ x: 0.0, y: 0.0 } + // Don't clip (cut-off) the unread badge's glow + clip_x: false, clip_y: false top := View { width: Fill, height: Fit, spacing: 3, @@ -211,12 +217,16 @@ script_mod! { width: Fill, height: Fill, spacing: 2, flow: Right, + // Don't clip (cut-off) the unread badge's glow + clip_x: false, clip_y: false preview := mod.widgets.MessagePreview { margin: Inset{ top: 2.5 } } View { width: Fit, height: Fit align: Align{ x: 1.0 } + // Don't clip the unread badge's glow off the top/bottom. + clip_x: false, clip_y: false unread_badge := UnreadBadge {} tombstone_icon := mod.widgets.TombstoneIcon {} } @@ -268,8 +278,6 @@ impl RoomsListEntry { impl Widget for RoomsListEntry { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { let uid = self.widget_uid(); - let rooms_list_props = scope.props.get::().unwrap(); - // We handle hits on this widget first to ensure that any clicks on it // will just select the room, rather than resulting in a click on any child view // within the RoomsListEntry content itself, such as links or avatars. @@ -291,7 +299,7 @@ impl Widget for RoomsListEntry { RoomsListEntryAction::SecondaryClicked(room_id.clone(), fe.abs), ); } - Hit::FingerUp(fe) if !rooms_list_props.was_scrolling && fe.is_over && fe.is_primary_hit() && fe.was_tap() => { + Hit::FingerUp(fe) if fe.is_over && fe.is_primary_hit() && fe.was_tap() => { cx.widget_action(uid, RoomsListEntryAction::PrimaryClicked(room_id.clone())); } _ => { } @@ -318,6 +326,15 @@ pub struct RoomsListEntryContent { #[source] source: ScriptObjectRef, #[deref] view: View, #[apply_default] animator: Animator, + + /// The preview colors that were last drawn for this entry. + /// * Some(true): this entry was last drawn as selected. + /// * Some(false): this entry was last drawn as not selected. + /// * None: this entry hasn't been drawn yet. + #[rust] last_selection_drawn: Option, + + /// The avatar content that was last drawn for this room. + #[rust] last_avatar: Option, } impl Widget for RoomsListEntryContent { @@ -385,19 +402,6 @@ impl RoomsListEntryContent { }; self.view.html_or_plaintext(cx, ids!(latest_message)).show_html(cx, &inviter_string); - match room_info.room_avatar { - FetchedRoomAvatar::Text(ref text) => { - self.view.avatar(cx, ids!(avatar)).show_text(cx, None, None, text); - } - FetchedRoomAvatar::Image(ref img_bytes) => { - let _ = self.view.avatar(cx, ids!(avatar)).show_image( - cx, - None, // Avatars in a RoomsListEntry shouldn't be clickable. - |cx, img| utils::load_image(&img, cx, img_bytes), - ); - } - } - self.view .unread_badge(cx, ids!(unread_badge)) .update_counts(false, 1, 0); @@ -412,31 +416,48 @@ impl RoomsListEntryContent { room_avatar: &FetchedRoomAvatar, is_selected: bool, ) { - match room_avatar { - FetchedRoomAvatar::Text(text) => { - self.view.avatar(cx, ids!(avatar)).show_text(cx, None, None, text); - } - FetchedRoomAvatar::Image(img_bytes) => { - let _ = self.view.avatar(cx, ids!(avatar)).show_image( - cx, - None, // Avatars in a RoomsListEntry shouldn't be clickable. - |cx, img| utils::load_image(&img, cx, img_bytes), - ); + // Only redraw the avatar if it changed + if self.last_avatar.as_ref() != Some(room_avatar) { + match room_avatar { + FetchedRoomAvatar::Text(text) => { + self.view.avatar(cx, ids!(avatar)).show_text(cx, None, None, text); + } + FetchedRoomAvatar::Image(avatar_image) => { + let _ = self.view.avatar(cx, ids!(avatar)).show_image( + cx, + None, // Avatars in a RoomsListEntry shouldn't be clickable. + |cx, img| utils::load_avatar_image(&img, cx, avatar_image), + ); + } } + self.last_avatar = Some(room_avatar.clone()); } - if effective_is_desktop(cx) { - self.update_preview_colors(cx, is_selected); - } else { - // Mobile doesn't have a selected state. Always use the default colors. - // We call the update in case the app was resized from desktop to mobile while the room was selected. - // This can be optimized by only calling this when the app is resized. - self.update_preview_colors(cx, false); - } + self.update_latest_event_colors(cx, is_selected); } - /// Updates the styling of the preview based on whether the room is selected or not. - pub fn update_preview_colors(&mut self, cx: &mut Cx, is_selected: bool) { + /// Updates styling of the latest event preview based on whether the room is selected or not. + pub fn update_latest_event_colors(&mut self, cx: &mut Cx, is_selected: bool) { + // Link colors must be re-applied on every draw because the HTML's link widgets + // get created dynamically during the draw walk. + // + // * If selected, set link color to None so links inherit the font_color (white) + // for better contrast against the selected background(blue). + // * If not selected, restore the default blue link color. + self.view.html_or_plaintext(cx, ids!(latest_message)).set_link_color( + cx, + if is_selected { + None + } else { + Some(HTML_LINK_COLOR) + }); + + // Skip redrawing if nothing changed. + if self.last_selection_drawn == Some(is_selected) { + return; + } + self.last_selection_drawn = Some(is_selected); + let message_text_color; let room_name_color; let timestamp_color; @@ -458,49 +479,17 @@ impl RoomsListEntryContent { // Toggle the background color via the animator (handles selected/deselected bg). self.animator_toggle(cx, is_selected, Animate::No, ids!(selected.on), ids!(selected.off)); - // Update text colors for room name. - let mut room_name_label = self.view.label(cx, ids!(room_name)); - script_apply_eval!(cx, room_name_label, { - draw_text +: { - color: #(room_name_color) - } - }); - - // Update text colors for timestamp. - let mut timestamp_label = self.view.label(cx, ids!(timestamp)); - script_apply_eval!(cx, timestamp_label, { - draw_text +: { - color: #(timestamp_color) - } - }); + // Update the text colors for the room name and timestamp. + self.view.label(cx, ids!(room_name)).set_text_color(cx, room_name_color); + self.view.label(cx, ids!(timestamp)).set_text_color(cx, timestamp_color); // Update text colors for the latest message preview (both HTML and plaintext variants). - let mut html_widget = self.view.html(cx, ids!(latest_message.html_view.html)); - script_apply_eval!(cx, html_widget, { - font_color: #(message_text_color), - draw_text +: { color: #(message_text_color) }, - draw_block +: { - quote_bg_color: #(code_bg_color), - code_color: #(code_bg_color), - } - }); - - // When selected, set link color to None so links inherit font_color (white) - // for better contrast against the blue selected background. - // When not selected, restore the default blue link color. - self.view - .html_or_plaintext(cx, ids!(latest_message)) - .set_link_color(cx, if is_selected { - None - } else { - Some(vec4(0., 0., 0.933, 1.0)) // #0000EE, default HtmlLink color - }); - - let mut pt_label = self.view.label(cx, ids!(latest_message.plaintext_view.pt_label)); - script_apply_eval!(cx, pt_label, { - draw_text +: { - color: #(message_text_color) - } - }); + if let Some(mut html) = self.view.html(cx, ids!(latest_message.html_view.html)).borrow_mut() { + html.set_font_color(cx, message_text_color); + html.set_code_color(cx, code_bg_color); + html.set_quote_bg_color(cx, code_bg_color); + } + self.view.label(cx, ids!(latest_message.plaintext_view.pt_label)) + .set_text_color(cx, message_text_color); } } diff --git a/src/home/space_lobby.rs b/src/home/space_lobby.rs index d78395445..d00ad13a7 100644 --- a/src/home/space_lobby.rs +++ b/src/home/space_lobby.rs @@ -15,7 +15,7 @@ use matrix_sdk::{RoomDisplayName, RoomState, ruma::OwnedRoomId}; use matrix_sdk_ui::spaces::SpaceRoom; use ruma::{OwnedRoomAliasId, room::JoinRuleSummary}; use tokio::sync::mpsc::UnboundedSender; -use crate::shared::avatar::AvatarState; +use crate::shared::avatar::{AvatarImage, AvatarState}; use crate::shared::expand_arrow::ExpandArrow; use crate::utils::replace_linebreaks_separators; /// The horizontal indent width (in pixels) per tree level. @@ -576,7 +576,10 @@ script_mod! { // The hierarchical tree list tree_list := PortalList { keep_invisible: false, - max_pull_down: 0.0, + bounce_at_start: true, + bounce_at_end: true, + // Nothing here listens for scroll position changes. + emit_scroll_actions: false, auto_tail: false, width: Fill, height: Fill flow: Down, @@ -621,6 +624,9 @@ pub struct SpaceLobbyEntry { impl Widget for SpaceLobbyEntry { fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + if !self.visible { + return; + } if self.animator_handle_event(cx, event).must_redraw() { self.redraw(cx); } @@ -1148,11 +1154,11 @@ impl Widget for SpaceLobbyScreen { fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { // Draw parent avatar from the SpaceRoom's avatar URL, or show initials. let parent_avatar_ref = self.view.avatar(cx, ids!(parent_avatar)); - if self.space_avatar_state.update_from_cache(cx).is_none_or(|data| { + if self.space_avatar_state.update_from_cache(cx).is_none_or(|image| { parent_avatar_ref.show_image( cx, None, - |cx, img| utils::load_image(&img, cx, data), + |cx, img| utils::load_avatar_image(&img, cx, image), ).is_err() }) { let first_char = self.space_name_id.as_ref().and_then(|sni| sni.name_for_avatar()) @@ -1260,22 +1266,23 @@ impl Widget for SpaceLobbyScreen { let mut drew_avatar = false; match &info.avatar { - AvatarState::Loaded(data) => { + AvatarState::Loaded(image) => { drew_avatar = avatar_ref.show_image( cx, None, - |cx, img| utils::load_image(&img, cx, data), + |cx, img| utils::load_avatar_image(&img, cx, image), ).is_ok(); } AvatarState::Known(Some(uri)) => { match avatar_cache::get_or_fetch_avatar(cx, uri) { AvatarCacheEntry::Loaded(data) => { + let image = AvatarImage::from((uri.clone(), data)); drew_avatar = avatar_ref.show_image( cx, None, - |cx, img| utils::load_image(&img, cx, &data), + |cx, img| utils::load_avatar_image(&img, cx, &image), ).is_ok(); - info.avatar = AvatarState::Loaded(data); + info.avatar = AvatarState::Loaded(image); } AvatarCacheEntry::Failed => { info.avatar = AvatarState::Failed; diff --git a/src/home/spaces_bar.rs b/src/home/spaces_bar.rs index 73259e6d7..a3ecc5353 100644 --- a/src/home/spaces_bar.rs +++ b/src/home/spaces_bar.rs @@ -102,7 +102,10 @@ script_mod! { align: Align{x: 0.5, y: 0.5} auto_tail: false, - max_pull_down: 0.0, + bounce_at_start: false, + bounce_at_end: false, + // Nothing here listens for scroll position changes. + emit_scroll_actions: false, scroll_bar: ScrollBar { // hide the scroll bar bar_size: 0.0, min_handle_size: 0.0 @@ -475,11 +478,11 @@ impl Widget for SpacesBar { FetchedRoomAvatar::Text(text) => { avatar_ref.show_text(cx, None, None, text); } - FetchedRoomAvatar::Image(image_data) => { + FetchedRoomAvatar::Image(avatar_image) => { let res = avatar_ref.show_image( cx, None, - |cx, img_ref| utils::load_image(&img_ref, cx, image_data), + |cx, img_ref| utils::load_avatar_image(&img_ref, cx, avatar_image), ); if res.is_err() { avatar_ref.show_text( diff --git a/src/home/tombstone_footer.rs b/src/home/tombstone_footer.rs index 4b5391faa..c055f50e9 100644 --- a/src/home/tombstone_footer.rs +++ b/src/home/tombstone_footer.rs @@ -178,11 +178,11 @@ impl TombstoneFooter { FetchedRoomAvatar::Text(text) => { successor_room_avatar.show_text(cx, None, None, text); } - FetchedRoomAvatar::Image(image_data) => { + FetchedRoomAvatar::Image(avatar_image) => { let res = successor_room_avatar.show_image( cx, None, - |cx, img_ref| utils::load_image(&img_ref, cx, image_data), + |cx, img_ref| utils::load_avatar_image(&img_ref, cx, avatar_image), ); if res.is_err() { successor_room_avatar.show_text( diff --git a/src/profile/user_profile.rs b/src/profile/user_profile.rs index 269b47df8..a7a98be18 100644 --- a/src/profile/user_profile.rs +++ b/src/profile/user_profile.rs @@ -534,8 +534,8 @@ impl Widget for UserProfileSlidingPane { // Set the avatar image, using the user name as a fallback. let avatar_ref = self.avatar(cx, ids!(avatar)); info.avatar_state - .data() - .and_then(|data| avatar_ref.show_image(cx, None, |cx, img| utils::load_image(&img, cx, data)).ok()) + .image() + .and_then(|image| avatar_ref.show_image(cx, None, |cx, img| utils::load_avatar_image(&img, cx, image)).ok()) .unwrap_or_else(|| avatar_ref.show_text(cx, None, None, info.displayable_name())); // Set the membership status and role in the room. diff --git a/src/room/mod.rs b/src/room/mod.rs index 68b20bae9..740c08641 100644 --- a/src/room/mod.rs +++ b/src/room/mod.rs @@ -5,6 +5,7 @@ use makepad_widgets::ScriptVm; use matrix_sdk::{RoomDisplayName, RoomHero, RoomState, SuccessorRoom, room_preview::RoomPreview}; use ruma::{OwnedRoomAliasId, OwnedRoomId, room::{JoinRuleSummary, RoomType}}; +use crate::shared::avatar::AvatarImage; use crate::utils::RoomNameId; pub mod reply_preview; @@ -159,13 +160,18 @@ static EMPTY_AVATAR: FetchedRoomAvatar = FetchedRoomAvatar::Text(String::new()); #[derive(Clone)] pub enum FetchedRoomAvatar { Text(String), - Image(Arc<[u8]>), + Image(AvatarImage), } impl Default for FetchedRoomAvatar { fn default() -> Self { FetchedRoomAvatar::Text(String::from("?")) } } +impl From for FetchedRoomAvatar { + fn from(image: AvatarImage) -> Self { + FetchedRoomAvatar::Image(image) + } +} impl std::fmt::Debug for FetchedRoomAvatar { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -174,3 +180,15 @@ impl std::fmt::Debug for FetchedRoomAvatar { } } } +impl PartialEq for FetchedRoomAvatar { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (FetchedRoomAvatar::Text(t1), FetchedRoomAvatar::Text(t2)) => t1 == t2, + (FetchedRoomAvatar::Image(i1), FetchedRoomAvatar::Image(i2)) => { + Arc::ptr_eq(&i1.data, &i2.data) + } + _ => false, + } + } +} +impl Eq for FetchedRoomAvatar { } diff --git a/src/room/room_input_bar.rs b/src/room/room_input_bar.rs index 3277ec030..0b1760caf 100644 --- a/src/room/room_input_bar.rs +++ b/src/room/room_input_bar.rs @@ -38,6 +38,7 @@ script_mod! { width: Fill, height: Fit{max: FitBound.Rel{base: Base.Full, factor: 0.75}} flow: Down, + new_batch: true // These margins are a hack to make the borders of the RoomInputBar // line up with the boundaries of its parent widgets. diff --git a/src/settings/account_settings.rs b/src/settings/account_settings.rs index ff2c699f1..4dc44352d 100644 --- a/src/settings/account_settings.rs +++ b/src/settings/account_settings.rs @@ -621,11 +621,11 @@ impl AccountSettings { let our_own_avatar = self.view.avatar(cx, ids!(our_own_avatar)); let mut drew_avatar = false; - if let Some(avatar_img_data) = own_profile.avatar_state.data() { + if let Some(avatar_image) = own_profile.avatar_state.image() { drew_avatar = our_own_avatar.show_image( cx, None, // don't make this avatar clickable; we handle clicks on this ProfileIcon widget directly. - |cx, img| utils::load_image(&img, cx, avatar_img_data), + |cx, img| utils::load_avatar_image(&img, cx, avatar_image), ).is_ok(); } if !drew_avatar { diff --git a/src/settings/settings_screen.rs b/src/settings/settings_screen.rs index 9af69c45b..319ad9c8f 100644 --- a/src/settings/settings_screen.rs +++ b/src/settings/settings_screen.rs @@ -1,7 +1,7 @@ use makepad_widgets::*; -use crate::{app::AppState, home::navigation_tab_bar::{NavigationBarAction, get_own_profile}, profile::user_profile::UserProfile, settings::{PopulateMode, account_settings::AccountSettingsWidgetExt, app_settings::AppSettingsWidgetExt}}; +use crate::{app::AppState, home::navigation_tab_bar::{NavigationBarAction, SelectedTab, get_own_profile}, profile::user_profile::UserProfile, settings::{PopulateMode, account_settings::AccountSettingsWidgetExt, app_settings::AppSettingsWidgetExt}}; script_mod! { use mod.prelude.widgets.* @@ -112,14 +112,17 @@ impl Widget for SettingsScreen { // 1. The close button is clicked, // 2. The back navigational gesture/action occurs (e.g., Back on Android), // 3. The escape key is pressed if this pane has key focus, - // 4. The back mouse button is clicked within this view. + // 4. The back mouse button is clicked while this settings view is actively shown. let area = self.view.area(); let close_pane = { matches!( event, Event::Actions(actions) if self.button(cx, ids!(close_button)).clicked(actions) ) - || event.back_pressed() + || ( + scope.data.get::().is_some_and(|a| a.selected_tab == SelectedTab::Settings) + && event.back_pressed() + ) || match event.hits(cx, area) { Hit::KeyUp(key) => key.key_code == KeyCode::Escape, Hit::FingerDown(_fde) => { diff --git a/src/shared/avatar.rs b/src/shared/avatar.rs index 7b05a6420..4f289fa4a 100644 --- a/src/shared/avatar.rs +++ b/src/shared/avatar.rs @@ -90,12 +90,29 @@ pub struct Avatar { /// Information about the user profile being shown in this Avatar. /// If `Some`, this Avatar will respond to clicks/taps. #[rust] info: Option, + + /// Whether this avatar's image is still being fetched or decoded. + #[rust] is_image_pending: bool, } impl Widget for Avatar { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { self.view.handle_event(cx, event, scope); + // Check to see if this image has been loaded/decoded. + if self.is_image_pending { + if let Event::Actions(actions) = event { + if actions.iter().any(|a| a.downcast_ref::().is_some()) + && self.image(cx, ids!(img_view.img)).has_content() + { + self.is_image_pending = false; + self.view(cx, ids!(img_view)).set_visible(cx, true); + self.view(cx, ids!(text_view)).set_visible(cx, false); + self.view.redraw(cx); + } + } + } + let Some(info) = self.info.clone() else { return }; let area = self.view.area(); let widget_uid = self.widget_uid(); @@ -144,6 +161,7 @@ impl Avatar { info: Option, username: T, ) { + self.is_image_pending = false; if let Some(AvatarTextInfo { user_id, username, room_id }) = info { self.info = Some(UserProfileAndRoomId { user_profile: UserProfile { @@ -172,6 +190,9 @@ impl Avatar { /// Sets the image content of this avatar, making the image visible /// and the user name text invisible. /// + /// If the image is still being loaded/decoded asynchronously and isn't ready yet, + /// the text label will still be shown until the image is ready. + /// /// ## Arguments /// * `info`: information about the user represented by this avatar: /// the user name, user ID, room ID, and avatar image data. @@ -190,10 +211,13 @@ impl Avatar { where F: FnOnce(&mut Cx, ImageRef) -> Result<(), E> { let img_ref = self.image(cx, ids!(img_view.img)); - let res = image_set_function(cx, img_ref); + let res = image_set_function(cx, img_ref.clone()); if res.is_ok() { - self.view(cx, ids!(img_view)).set_visible(cx, true); - self.view(cx, ids!(text_view)).set_visible(cx, false); + // Don't show the avatar image until it's been decoded in full (which is async). + let has_content = img_ref.has_content(); + self.is_image_pending = !has_content; + self.view(cx, ids!(img_view)).set_visible(cx, has_content); + self.view(cx, ids!(text_view)).set_visible(cx, !has_content); if let Some(AvatarImageInfo { user_id, username, room_id, img_data }) = info { self.info = Some(UserProfileAndRoomId { @@ -301,10 +325,10 @@ impl Avatar { .or_else(try_get_cached_username_avatar) .unwrap_or((None, AvatarState::Unknown)); - let (avatar_img_data_opt, profile_drawn) = match avatar_state { - AvatarState::Loaded(data) => (Some(data), true), + let (avatar_img_opt, profile_drawn) = match avatar_state { + AvatarState::Loaded(image) => (Some(image), true), AvatarState::Known(Some(uri)) => match avatar_cache::get_or_fetch_avatar(cx, &uri) { - AvatarCacheEntry::Loaded(data) => (Some(data), true), + AvatarCacheEntry::Loaded(data) => (Some((uri, data).into()), true), AvatarCacheEntry::Failed => (None, true), AvatarCacheEntry::Requested => (None, false), }, @@ -318,32 +342,34 @@ impl Avatar { .unwrap_or_else(|| avatar_user_id.to_string()); // Set the sender's avatar image, or use the username if no image is available. - avatar_img_data_opt - .and_then(|data| { - self.show_image( - cx, - is_clickable.then(|| AvatarImageInfo::from(( - avatar_user_id.to_owned(), - username_opt.clone(), - timeline_kind.room_id().to_owned(), - data.clone() - ))), - |cx, img| utils::load_image(&img, cx, &data), - ) - .ok() - }) - .unwrap_or_else(|| { - self.show_text( - cx, - None, - is_clickable.then(|| AvatarTextInfo::from(( - avatar_user_id.to_owned(), - username_opt, - timeline_kind.room_id().to_owned(), - ))), - &username, - ) - }); + avatar_img_opt.and_then(|image| { + self.show_image( + cx, + is_clickable.then(|| AvatarImageInfo::from(( + avatar_user_id.to_owned(), + username_opt.clone(), + timeline_kind.room_id().to_owned(), + image.clone() + ))), + |cx, img| utils::load_avatar_image(&img, cx, &image), + ) + .ok() + }).map(|_| { + if self.is_image_pending { + self.set_text(cx, &username); + } + }).unwrap_or_else(|| { + self.show_text( + cx, + None, + is_clickable.then(|| AvatarTextInfo::from(( + avatar_user_id.to_owned(), + username_opt, + timeline_kind.room_id().to_owned(), + ))), + &username, + ) + }); (username, profile_drawn) } } @@ -437,15 +463,36 @@ pub struct AvatarImageInfo { pub user_id: OwnedUserId, pub username: Option, pub room_id: OwnedRoomId, - pub img_data: Arc<[u8]>, + pub img_data: AvatarImage, } -impl From<(OwnedUserId, Option, OwnedRoomId, Arc<[u8]>)> for AvatarImageInfo { - fn from((user_id, username, room_id, img_data): (OwnedUserId, Option, OwnedRoomId, Arc<[u8]>)) -> Self { +impl From<(OwnedUserId, Option, OwnedRoomId, AvatarImage)> for AvatarImageInfo { + fn from((user_id, username, room_id, img_data): (OwnedUserId, Option, OwnedRoomId, AvatarImage)) -> Self { Self { user_id, username, room_id, img_data } } } +/// A fetched avatar: its image data and its MxcUri. +#[derive(Clone)] +pub struct AvatarImage { + pub uri: OwnedMxcUri, + pub data: Arc<[u8]>, +} +impl From<(U, D)> for AvatarImage +where + U: Into, + D: Into>, +{ + fn from((uri, data): (U, D)) -> Self { + Self { uri: uri.into(), data: data.into() } + } +} +impl From for AvatarState { + fn from(image: AvatarImage) -> Self { + Self::Loaded(image) + } +} + /// The currently-known state of an avatar for a user, room, or space. #[derive(Clone, Default)] pub enum AvatarState { @@ -454,7 +501,7 @@ pub enum AvatarState { /// It is known that this user/room/space does or does not have an avatar. Known(Option), /// The avatar is known to exist and has been fetched successfully. - Loaded(Arc<[u8]>), + Loaded(AvatarImage), /// The avatar is known to exist but could not be fetched. Failed, } @@ -464,7 +511,7 @@ impl std::fmt::Debug for AvatarState { AvatarState::Unknown => write!(f, "Unknown"), AvatarState::Known(Some(_)) => write!(f, "Known(Some)"), AvatarState::Known(None) => write!(f, "Known(None)"), - AvatarState::Loaded(data) => write!(f, "Loaded({} bytes)", data.len()), + AvatarState::Loaded(image) => write!(f, "Loaded({} bytes)", image.data.len()), AvatarState::Failed => write!(f, "Failed"), } } @@ -473,20 +520,20 @@ impl AvatarState { /// Tries to update this `AvatarState` if it has a known avatar URI /// by loading the avatar from the cache. /// - /// Returns the image data if this `AvatarState` is in the `Loaded` state. - pub fn update_from_cache(&mut self, cx: &mut Cx) -> Option<&Arc<[u8]>> { + /// Returns the fetched avatar if this `AvatarState` is in the `Loaded` state. + pub fn update_from_cache(&mut self, cx: &mut Cx) -> Option<&AvatarImage> { if let Self::Known(Some(uri)) = self { if let AvatarCacheEntry::Loaded(data) = avatar_cache::get_or_fetch_avatar(cx, uri) { - *self = Self::Loaded(data.clone()); + *self = Self::Loaded((uri.clone(), data).into()); } } - self.data() + self.image() } - /// Returns the avatar data, if in the `Loaded` state. - pub fn data(&self) -> Option<&Arc<[u8]>> { - if let Self::Loaded(data) = self { - Some(data) + /// Returns the fetched avatar, if in the `Loaded` state. + pub fn image(&self) -> Option<&AvatarImage> { + if let Self::Loaded(image) = self { + Some(image) } else { None } diff --git a/src/shared/collapsible_header.rs b/src/shared/collapsible_header.rs index fb0d029cc..30859103b 100644 --- a/src/shared/collapsible_header.rs +++ b/src/shared/collapsible_header.rs @@ -10,7 +10,6 @@ use makepad_widgets::*; use makepad_widgets::animator::Animate; -use crate::home::rooms_list::RoomsListScopeProps; use super::expand_arrow::ExpandArrow; use super::unread_badge::UnreadBadgeWidgetRefExt as _; @@ -116,13 +115,12 @@ pub struct CollapsibleHeader { impl Widget for CollapsibleHeader { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { // Handle hits on this view as a whole before passing the event to the inner view. - let rooms_list_props = scope.props.get::().unwrap(); match event.hits(cx, self.view.area()) { Hit::FingerDown(..) => { cx.set_key_focus(self.view.area()); } Hit::FingerUp(fe) - if !rooms_list_props.was_scrolling && fe.is_over && fe.is_primary_hit() && fe.was_tap() => + if fe.is_over && fe.is_primary_hit() && fe.was_tap() => { self.toggle_collapse(cx, scope); } diff --git a/src/shared/html_or_plaintext.rs b/src/shared/html_or_plaintext.rs index dab7bf404..d57baa4c6 100644 --- a/src/shared/html_or_plaintext.rs +++ b/src/shared/html_or_plaintext.rs @@ -1,13 +1,12 @@ //! A `HtmlOrPlaintext` view can display either plaintext or rich HTML content. -use std::sync::Arc; use makepad_widgets::*; use matrix_sdk::{ruma::{matrix_uri::MatrixId, MatrixToUri, MatrixUri, RoomOrAliasId}, OwnedServerName}; use crate::{avatar_cache::{self, AvatarCacheEntry}, profile::user_profile_cache, room_preview_cache::{self, CachedRoomPreview}, sliding_sync::current_user_id, utils}; -use super::avatar::{AvatarState, AvatarWidgetExt}; +use super::avatar::{AvatarImage, AvatarState, AvatarWidgetExt}; /// The color of the text used to print the spoiler reason before the hidden text. const COLOR_SPOILER_REASON: Vec4 = vec4(0.6, 0.6, 0.6, 1.0); @@ -357,13 +356,15 @@ struct MatrixLinkPill { #[rust] matrix_id: Option, #[rust] via: Vec, #[rust] url: String, + /// Whether this pill is still waiting for its name or avatar to arrive. + #[rust] is_waiting_for_data: bool, } impl Widget for MatrixLinkPill { fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { if matches!(event, Event::Signal) { room_preview_cache::process_room_preview_updates(cx); - if self.matrix_id.is_some() { + if self.matrix_id.is_some() && self.is_waiting_for_data { self.redraw(cx); } } @@ -426,18 +427,19 @@ impl MatrixLinkPill { // Handle a user ID link by querying the user profile cache. if let MatrixId::User(user_id) = matrix_id { - let (name, avatar_state) = match user_profile_cache::with_user_profile( + let profile_pair = user_profile_cache::with_user_profile( cx, user_id.clone(), None, true, |profile, _| { (profile.displayable_name().to_owned(), profile.avatar_state.clone()) } - ) { - Some(pair) => pair, - None => (user_id.to_string(), AvatarState::Unknown), - }; + ); + let profile_found = profile_pair.is_some(); + let (name, avatar_state) = profile_pair + .unwrap_or_else(|| (user_id.to_string(), AvatarState::Unknown)); self.set_text(cx, &name); - self.populate_avatar(cx, &avatar_state, &name); + let avatar_final = self.populate_avatar(cx, &avatar_state, &name); + self.is_waiting_for_data = !(profile_found && avatar_final); return; } @@ -463,7 +465,8 @@ impl MatrixLinkPill { // For @room mentions, show "@room" as the title, not the room name. let display_name = if is_room_mention { "@room" } else { resolved_name.as_str() }; self.label(cx, ids!(title)).set_text(cx, display_name); - self.populate_avatar(cx, &room_avatar, display_name); + let avatar_final = self.populate_avatar(cx, &room_avatar, display_name); + self.is_waiting_for_data = !avatar_final; return; } } @@ -480,6 +483,7 @@ impl MatrixLinkPill { }; self.set_text(cx, &fallback_name); self.populate_avatar(cx, &AvatarState::Unknown, &fallback_name); + self.is_waiting_for_data = true; } /// Renders the pill avatar from the given [`AvatarState`], falling back to @@ -489,27 +493,36 @@ impl MatrixLinkPill { /// * `Loaded(bytes)` — paint bytes directly (room link cache). /// * `Known(Some(uri))` — fetch bytes via [`avatar_cache`] (user link). /// * `Known(None)` / `Unknown` / `Failed` — text fallback. - fn populate_avatar(&self, cx: &mut Cx, avatar: &AvatarState, display_name: &str) { + /// + /// Returns whether the avatar is "finished": + /// * `true` if the image was fully drawn or there is no image to draw. + /// * `false` if there is an image to draw but it hasn't arrived yet. + fn populate_avatar(&self, cx: &mut Cx, avatar: &AvatarState, display_name: &str) -> bool { let avatar_ref = self.avatar(cx, ids!(avatar)); - let bytes: Option> = match avatar { - AvatarState::Loaded(data) => Some(data.clone()), + let (image, can_improve): (Option, bool) = match avatar { + AvatarState::Loaded(image) => (Some(image.clone()), false), AvatarState::Known(Some(uri)) => match avatar_cache::get_or_fetch_avatar(cx, uri) { - AvatarCacheEntry::Loaded(data) => Some(data), - _ => None, + AvatarCacheEntry::Loaded(data) => { + (Some((uri.clone(), data).into()), false) + } + AvatarCacheEntry::Failed => (None, false), + _ => (None, true), }, - _ => None, + AvatarState::Known(None) | AvatarState::Failed => (None, false), + AvatarState::Unknown => (None, true), }; - if let Some(data) = bytes { + if let Some(image) = image { let res = avatar_ref.show_image( cx, None, // Don't make this avatar clickable - |cx, img_ref| utils::load_image(&img_ref, cx, &data), + |cx, img_ref| utils::load_avatar_image(&img_ref, cx, &image), ); if res.is_ok() { - return; + return true; } } avatar_ref.show_text(cx, None, None, display_name); + !can_improve } } @@ -757,6 +770,25 @@ impl HtmlOrPlaintext { } } +impl HtmlOrPlaintext { + /// Sets the color of all links in the HTML content. + /// + /// This modifies the cached `HtmlLink` widget instances inside the inner + /// `Html` widget's `TextFlow` items. + /// This does nothing on the very first draw (before items are created), + /// but future draws will have the given color. + pub fn set_link_color(&mut self, cx: &mut Cx, color: Option) { + let html_ref = self.html(cx, ids!(html_view.html)); + let Some(html) = html_ref.borrow() else { return }; + // Visit all of the TextFlow's cached items to see if any are RobrixHtmlLinks. + html.text_flow.children(&mut |_id, item| { + if let Some(link) = item.borrow_mut::() { + link.html_link(cx, ids!(html_link)).set_color(cx, color); + } + }); + } +} + impl HtmlOrPlaintextRef { /// See [`HtmlOrPlaintext::show_plaintext()`]. pub fn show_plaintext>(&self, cx: &mut Cx, text: T) { @@ -772,47 +804,10 @@ impl HtmlOrPlaintextRef { } } - /// Sets the color of links in the HTML content. - /// - /// This modifies the cached `HtmlLink` widget instances inside the inner - /// `Html` widget's `TextFlow` items. On the very first draw (before items - /// are created), this is a no-op, but subsequent frames will have the - /// correct color. + /// See [`HtmlOrPlaintext::set_link_color()`]. pub fn set_link_color(&self, cx: &mut Cx, color: Option) { if let Some(mut inner) = self.borrow_mut() { inner.set_link_color(cx, color); } } } - -impl HtmlOrPlaintext { - /// See [`HtmlOrPlaintextRef::set_link_color()`]. - pub fn set_link_color(&mut self, cx: &mut Cx, color: Option) { - let html_ref = self.html(cx, ids!(html_view.html)); - let Some(mut html) = html_ref.borrow_mut() else { return }; - // Iterate over cached TextFlow items (auto-generated IDs start at 1) - // until we hit a non-existent item. - let mut i = 1u64; - loop { - let item = html.existing_item(LiveId(i)); - if item.is_empty() { break; } - // Check if this item is a RobrixHtmlLink and modify its inner HtmlLink. - if let Some(link) = item.borrow_mut::() { - let mut html_link = link.html_link(cx, ids!(html_link)); - match color { - Some(c) => { - script_apply_eval!(cx, html_link, { - color: #(c) - }); - } - None => { - script_apply_eval!(cx, html_link, { - color: nil - }); - } - } - } - i += 1; - } - } -} diff --git a/src/shared/mention_popup.rs b/src/shared/mention_popup.rs index e7ee7e98c..a97e0840f 100644 --- a/src/shared/mention_popup.rs +++ b/src/shared/mention_popup.rs @@ -15,7 +15,7 @@ use crate::{ avatar_cache::{get_or_fetch_avatar, process_avatar_updates, AvatarCacheEntry}, home::rooms_list::RoomsListRef, room::FetchedRoomAvatar, - shared::{avatar::AvatarWidgetRefExt, slash_commands::SlashCommand, styles::*}, + shared::{avatar::{AvatarImage, AvatarWidgetRefExt}, slash_commands::SlashCommand, styles::*}, utils::{self, RoomNameId}, }; use matrix_sdk::ruma::{OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId}; @@ -606,7 +606,8 @@ fn set_user_avatar(cx: &mut Cx, row: &WidgetRef, avatar_url: Option<&OwnedMxcUri match avatar_url { Some(mxc) => match get_or_fetch_avatar(cx, mxc) { AvatarCacheEntry::Loaded(data) => { - let _ = avatar.show_image(cx, None, |cx, img| utils::load_image(&img, cx, &data)); + let image = AvatarImage::from((mxc.clone(), data)); + let _ = avatar.show_image(cx, None, |cx, img| utils::load_avatar_image(&img, cx, &image)); true } AvatarCacheEntry::Requested => { @@ -629,8 +630,8 @@ fn set_user_avatar(cx: &mut Cx, row: &WidgetRef, avatar_url: Option<&OwnedMxcUri fn set_room_avatar(cx: &mut Cx, row: &WidgetRef, room_id: &OwnedRoomId, avatar_url: Option<&OwnedMxcUri>, name_for_avatar: Option<&str>) -> bool { let avatar = row.avatar(cx, ids!(avatar)); if cx.has_global::() { - if let Some(FetchedRoomAvatar::Image(data)) = cx.get_global::().get_room_avatar(room_id) { - let _ = avatar.show_image(cx, None, |cx, img| utils::load_image(&img, cx, &data)); + if let Some(FetchedRoomAvatar::Image(image)) = cx.get_global::().get_room_avatar(room_id) { + let _ = avatar.show_image(cx, None, |cx, img| utils::load_avatar_image(&img, cx, &image)); return true; } } @@ -638,7 +639,8 @@ fn set_room_avatar(cx: &mut Cx, row: &WidgetRef, room_id: &OwnedRoomId, avatar_u if let Some(mxc) = avatar_url { match get_or_fetch_avatar(cx, mxc) { AvatarCacheEntry::Loaded(data) => { - let _ = avatar.show_image(cx, None, |cx, img| utils::load_image(&img, cx, &data)); + let image = AvatarImage::from((mxc.clone(), data)); + let _ = avatar.show_image(cx, None, |cx, img| utils::load_avatar_image(&img, cx, &image)); return true; } AvatarCacheEntry::Requested => fully_drawn = false, diff --git a/src/shared/unread_badge.rs b/src/shared/unread_badge.rs index ab184fa57..b508d7531 100644 --- a/src/shared/unread_badge.rs +++ b/src/shared/unread_badge.rs @@ -10,30 +10,64 @@ script_mod! { mod.widgets.UnreadBadge = #(UnreadBadge::register_widget(vm)) { - width: 30, height: 20, + width: 27, height: 18, align: Align{ x: 0.5, y: 0.5 } flow: Overlay, + // Let the badge's fade-out/glow effect render beyond its bounding rect + clip_x: false, + clip_y: false, rounded_view := View { width: Fill, height: Fill, show_bg: true, + clip_x: false, + clip_y: false, + draw_bg +: { badge_color: instance((COLOR_UNREAD_BADGE_MESSAGES)), border_radius: instance(4.0) - // Set this border_size to a larger value to make the oval smaller + // A larger border size results in a smaller oval border_size: instance(2.0) + // For unread mention badges only, we fade through a lighter color to reduce aliasing effects + // on lower-res screens, since red on purple looks blocky/pixellated otherwise. + fade_color: instance(#xFFC8B0) + fade_radius: uniform(5.0) + // Controls the transition of the outer border. + // 0.0 is a crisp solid badge, 1.0 is a soft fading/dissolve transition. + soft: instance(0.0) - pixel: fn() { - let sdf = Sdf2d.viewport(self.pos * self.rect_size) - sdf.box( - self.border_size, - 1.0, - self.rect_size.x - (self.border_size * 2.0), - self.rect_size.y - 2.0, - max(1.0, self.border_radius) + vertex: fn() { + let m = self.fade_radius + return self.clip_and_transform_vertex( + self.rect_pos - vec2(m), + self.rect_size + vec2(m * 2.0) ) - sdf.fill_keep(self.badge_color); + } + + pixel: fn() { + let m = self.fade_radius + let rs3 = self.rect_size + vec2(m * 2.0) + let sdf = Sdf2d.viewport(self.pos * rs3) + let bw = self.rect_size.x - (self.border_size * 2.0) + let bh = self.rect_size.y - 2.0 + let bx = m + self.border_size + let by = m + 1.0 + let rad = max(1.0, self.border_radius) + sdf.box(bx, by, bw, bh, rad) + let dist = sdf.shape + // Note: this must NOT be named `half`, as that is a reserved + // type keyword in MSL and HLSL (shader compilation fails). + let half_bh = bh * 0.5 + let aa = clamp(0.5 - dist, 0.0, 1.0) + let band_start = -half_bh * 0.45 + let t = clamp((dist - band_start) / (m - band_start), 0.0, 1.0) + let s = t * t * t * (t * (t * 6.0 - 15.0) + 10.0) + let warm = mix(self.badge_color.rgb, self.fade_color.rgb, s) + let dissolve = 1.0 - s + let color = mix(self.badge_color.rgb, warm, self.soft) + let alpha = mix(aa, dissolve, self.soft) + sdf.clear(vec4(color, alpha)) return sdf.result; } } @@ -94,7 +128,10 @@ impl Widget for UnreadBadge { script_apply_eval!(cx, rounded_view, { draw_bg +: { border_size: #(border_size), - badge_color: mod.widgets.COLOR_UNREAD_BADGE_MENTIONS + // Solid red core fading out through a lighter warm color. + badge_color: #xFF1133, + fade_color: #xFFC8B0, + soft: 1.0 } }); self.visible = true; @@ -105,8 +142,9 @@ impl Widget for UnreadBadge { let mut rounded_view = self.view(cx, ids!(rounded_view)); script_apply_eval!(cx, rounded_view, { draw_bg +: { - border_size: 6.0, // larger value = smaller dot - badge_color: mod.widgets.COLOR_UNREAD_BADGE_MARKED + border_size: 6.0, // larger value = smaller badge size + badge_color: mod.widgets.COLOR_UNREAD_BADGE_MARKED, + soft: 0.0 } }); self.visible = true; @@ -120,7 +158,8 @@ impl Widget for UnreadBadge { script_apply_eval!(cx, rounded_view, { draw_bg +: { border_size: #(border_size), - badge_color: mod.widgets.COLOR_UNREAD_BADGE_MESSAGES + badge_color: mod.widgets.COLOR_UNREAD_BADGE_MESSAGES, + soft: 0.0 } }); self.visible = true; diff --git a/src/sliding_sync.rs b/src/sliding_sync.rs index 2608afa77..086da62ea 100644 --- a/src/sliding_sync.rs +++ b/src/sliding_sync.rs @@ -3714,15 +3714,19 @@ async fn add_new_room( // Start with a basic text avatar; the avatar image will be fetched asynchronously below. let room_avatar = avatar_from_room_name(room_name_id.name_for_avatar()); let inviter_info = if let Some(inviter) = invite_details.and_then(|d| d.inviter) { - Some(InviterInfo { - user_id: inviter.user_id().to_owned(), - display_name: inviter.display_name().map(|n| n.to_string()), - avatar: inviter + let avatar = match inviter.avatar_url() { + Some(uri) => inviter .avatar(AVATAR_THUMBNAIL_FORMAT.into()) .await .ok() .flatten() - .map(Into::into), + .map(|data| (uri, data).into()), + None => None, + }; + Some(InviterInfo { + user_id: inviter.user_id().to_owned(), + display_name: inviter.display_name().map(|n| n.to_string()), + avatar, }) } else { None @@ -4107,13 +4111,13 @@ async fn fetch_room_preview_with_avatar( // If this room has an avatar URL, fetch it. let room_avatar = if let Some(avatar_url) = room_preview.avatar_url.clone() { let media_request = MediaRequestParameters { - source: MediaSource::Plain(avatar_url), + source: MediaSource::Plain(avatar_url.clone()), format: AVATAR_THUMBNAIL_FORMAT.into(), }; match client.media().get_media_content(&media_request, true).await { Ok(avatar_content) => { log!("Fetched avatar for room preview {:?} ({})", room_preview.name, room_preview.room_id); - FetchedRoomAvatar::Image(avatar_content.into()) + FetchedRoomAvatar::Image((avatar_url, avatar_content).into()) } Err(e) => { log!("Failed to fetch avatar for room preview {:?} ({}), error: {e:?}", @@ -4775,18 +4779,20 @@ fn spawn_fetch_room_avatar_inner(room: Room, room_name_id: RoomNameId) { /// Fetches and returns the avatar image for the given room (if one exists), /// otherwise returns a text avatar string of the first character of the room name. async fn room_avatar(room: &Room, room_name_id: &RoomNameId) -> FetchedRoomAvatar { - if let Ok(Some(avatar)) = room.avatar(AVATAR_THUMBNAIL_FORMAT.into()).await { - return FetchedRoomAvatar::Image(avatar.into()); + if let Some(avatar_url) = room.avatar_url() { + if let Ok(Some(avatar)) = room.avatar(AVATAR_THUMBNAIL_FORMAT.into()).await { + return FetchedRoomAvatar::Image((avatar_url, avatar).into()); + } } // For rooms without an avatar that have only one hero (i.e., a 2-member DM), use their avatar. if let Ok([one_hero]) = <[_; 1]>::try_from(room.heroes()) { if let Some(avatar_url) = one_hero.avatar_url { let request = MediaRequestParameters { - source: MediaSource::Plain(avatar_url), + source: MediaSource::Plain(avatar_url.clone()), format: AVATAR_THUMBNAIL_FORMAT.into(), }; if let Ok(avatar) = room.client().media().get_media_content(&request, true).await { - return FetchedRoomAvatar::Image(avatar.into()); + return FetchedRoomAvatar::Image((avatar_url, avatar).into()); } } } diff --git a/src/space_service_sync.rs b/src/space_service_sync.rs index 7e4fd3927..0d339d544 100644 --- a/src/space_service_sync.rs +++ b/src/space_service_sync.rs @@ -581,13 +581,13 @@ fn remove_space(space: &SpaceRoom) { /// Returns `Some` if the avatar image was successfully fetched. async fn fetch_space_avatar(url: OwnedMxcUri, client: &Client) -> matrix_sdk::Result { let request = MediaRequestParameters { - source: MediaSource::Plain(url), + source: MediaSource::Plain(url.clone()), format: utils::AVATAR_THUMBNAIL_FORMAT.into(), }; client.media() .get_media_content(&request, true) .await - .map(|img_data| FetchedRoomAvatar::Image(img_data.into())) + .map(|img_data| FetchedRoomAvatar::Image((url, img_data).into())) } diff --git a/src/utils.rs b/src/utils.rs index a933b3bc2..f1e682bb3 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,12 +4,13 @@ use url::Url; use unicode_segmentation::UnicodeSegmentation; use chrono::{DateTime, Duration, Local, TimeZone}; -use makepad_widgets::{Cx, Event, ImageRef, image_cache::ImageError}; +use makepad_widgets::{Cx, Event, ImageRef, image_cache::{looks_like_svg, ImageError}}; use matrix_sdk::{media::{MediaFormat, MediaThumbnailSettings}, ruma::{api::client::media::get_content_thumbnail::v3::Method, MilliSecondsSinceUnixEpoch, OwnedRoomAliasId, OwnedRoomId, RoomId}, RoomDisplayName}; use matrix_sdk_ui::timeline::{EventTimelineItem, PaginationError, TimelineDetails}; use crate::{ room::FetchedRoomAvatar, + shared::avatar::AvatarImage, sliding_sync::{submit_async_request, MatrixRequest, TimelineKind}, }; @@ -106,12 +107,32 @@ pub fn is_supported_image_mimetype(mimetype: &str) -> bool { ) } -/// Loads the given image `data` into the given `ImageRef`, auto-detecting any -/// image format that makepad supports (PNG, JPEG, GIF, WebP, BMP, ICO, QOI). -/// -/// Returns an error if the format is unsupported or decoding fails. -pub fn load_image(img: &ImageRef, cx: &mut Cx, data: &[u8]) -> Result<(), ImageError> { - img.load_image_from_data(cx, data) +/// Loads the given fetched avatar into the given `ImageRef`. +pub fn load_avatar_image( + img: &ImageRef, + cx: &mut Cx, + avatar: &AvatarImage, +) -> Result<(), ImageError> { + load_image_with_cache_key( + img, + cx, + std::path::Path::new(avatar.uri.as_str()), + std::sync::Arc::clone(&avatar.data), + ) +} + +/// Loads the encoded image `data` into the given `ImageRef`, +/// auto-detecting and handling any image format that makepad supports. +pub fn load_image_with_cache_key( + img: &ImageRef, + cx: &mut Cx, + cache_key: &std::path::Path, + data: std::sync::Arc<[u8]>, +) -> Result<(), ImageError> { + if looks_like_svg(&data) { + return img.load_svg_from_shared_data(cx, data); + } + img.load_image_from_data_async(cx, cache_key, data) } @@ -645,8 +666,10 @@ impl From for MediaThumbnailSettings { pub const AVATAR_THUMBNAIL_FORMAT: MediaFormatConst = MediaFormatConst::Thumbnail( MediaThumbnailSettingsConst { method: Method::Scale, - width: 40, - height: 40, + // while we typically show avatars at around 40x40, + // fetching a higher quality one is needed for good downscaling. + width: 192, + height: 192, animated: false, } );