diff --git a/Cargo.lock b/Cargo.lock index d39df9f..eb22c22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,16 +18,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" -[[package]] -name = "accesskit" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74a4b14f3d99c1255dcba8f45621ab1a2e7540a0009652d33989005a4d0bfc6b" -dependencies = [ - "enumn", - "serde", -] - [[package]] name = "addr2line" version = "0.24.1" @@ -79,7 +69,6 @@ dependencies = [ "cfg-if", "getrandom", "once_cell", - "serde", "version_check", "zerocopy", ] @@ -107,9 +96,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-activity" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", "bitflags 2.6.0", @@ -121,7 +110,7 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "thiserror", ] @@ -132,6 +121,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -161,7 +156,7 @@ checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" dependencies = [ "clipboard-win", "log", - "objc2 0.5.2", + "objc2", "objc2-app-kit", "objc2-foundation", "parking_lot", @@ -199,11 +194,11 @@ checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] name = "ash" -version = "0.37.3+1.3.251" +version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "libloading 0.7.4", + "libloading", ] [[package]] @@ -231,9 +226,9 @@ dependencies = [ [[package]] name = "async-wsocket" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eee6fcc818b89848df37050215603de0e2e072734e4730c03060feb2d0abebb" +checksum = "5c0984bead67f20366bc8dd46018dfbe189b67eeefb0e5b86b9eade18d7c3c3b" dependencies = [ "async-utility", "futures", @@ -249,6 +244,15 @@ dependencies = [ "web-sys", ] +[[package]] +name = "atomic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] + [[package]] name = "atomic-destructor" version = "0.2.0" @@ -308,6 +312,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base58ck" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +dependencies = [ + "bitcoin-internals", + "bitcoin_hashes 0.14.0", +] + [[package]] name = "base64" version = "0.21.7" @@ -328,9 +342,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bech32" -version = "0.10.0-beta" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" [[package]] name = "bindgen" @@ -341,7 +355,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools", + "itertools 0.12.1", "lazy_static", "lazycell", "log", @@ -368,18 +382,18 @@ dependencies = [ [[package]] name = "bit-set" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" [[package]] name = "bit_field" @@ -389,13 +403,16 @@ checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" [[package]] name = "bitcoin" -version = "0.31.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae" +checksum = "0032b0e8ead7074cda7fc4f034409607e3f03a6f71d66ade8a307f79b4d99e73" dependencies = [ + "base58ck", "bech32", "bitcoin-internals", - "bitcoin_hashes 0.13.0", + "bitcoin-io", + "bitcoin-units", + "bitcoin_hashes 0.14.0", "hex-conservative", "hex_lit", "secp256k1", @@ -404,13 +421,29 @@ dependencies = [ [[package]] name = "bitcoin-internals" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" +checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" dependencies = [ "serde", ] +[[package]] +name = "bitcoin-io" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" + +[[package]] +name = "bitcoin-units" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" +dependencies = [ + "bitcoin-internals", + "serde", +] + [[package]] name = "bitcoin_hashes" version = "0.11.0" @@ -419,11 +452,11 @@ checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" [[package]] name = "bitcoin_hashes" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ - "bitcoin-internals", + "bitcoin-io", "hex-conservative", "serde", ] @@ -470,32 +503,13 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" -dependencies = [ - "objc-sys", -] - -[[package]] -name = "block2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" -dependencies = [ - "block-sys", - "objc2 0.4.1", -] - [[package]] name = "block2" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2 0.5.2", + "objc2", ] [[package]] @@ -548,20 +562,6 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" -[[package]] -name = "calloop" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" -dependencies = [ - "bitflags 2.6.0", - "log", - "polling", - "rustix", - "slab", - "thiserror", -] - [[package]] name = "calloop" version = "0.13.0" @@ -576,25 +576,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "calloop-wayland-source" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" -dependencies = [ - "calloop 0.12.4", - "rustix", - "wayland-backend", - "wayland-client", -] - [[package]] name = "calloop-wayland-source" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ - "calloop 0.13.0", + "calloop", "rustix", "wayland-backend", "wayland-client", @@ -657,6 +645,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + [[package]] name = "chacha20" version = "0.9.1" @@ -681,6 +684,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + [[package]] name = "cipher" version = "0.4.4" @@ -700,7 +717,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading 0.8.5", + "libloading", ] [[package]] @@ -712,6 +729,15 @@ dependencies = [ "error-code", ] +[[package]] +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +dependencies = [ + "cc", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -919,7 +945,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.5", + "libloading", ] [[package]] @@ -938,40 +964,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] -name = "ecolor" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" -dependencies = [ - "bytemuck", - "emath 0.27.2", -] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" [[package]] name = "ecolor" -version = "0.28.1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6b451ff1143f6de0f33fc7f1b68fecfd2c7de06e104de96c4514de3f5396f8" +checksum = "775cfde491852059e386c4e1deb4aef381c617dc364184c6f6afee99b87c402b" dependencies = [ - "emath 0.28.1", - "serde", + "bytemuck", + "emath", ] [[package]] name = "eframe" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ac2645a9bf4826eb4e91488b1f17b8eaddeef09396706b2f14066461338e24f" dependencies = [ "ahash", "bytemuck", "document-features", - "egui 0.27.2", + "egui", "egui-wgpu", "egui-winit", "egui_glow", + "glow 0.14.2", + "glutin", + "glutin-winit", "image", "js-sys", "log", - "objc2 0.5.2", + "objc2", "objc2-app-kit", "objc2-foundation", "parking_lot", @@ -985,45 +1012,52 @@ dependencies = [ "web-time", "wgpu", "winapi", + "windows-sys 0.52.0", "winit", ] [[package]] name = "egui" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53eafabcce0cb2325a59a98736efe0bf060585b437763f8c476957fb274bb974" dependencies = [ "ahash", - "emath 0.27.2", - "epaint 0.27.2", + "emath", + "epaint", "log", "nohash-hasher", ] [[package]] -name = "egui" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c97e70a2768de630f161bb5392cbd3874fcf72868f14df0e002e82e06cb798" +name = "egui-video" +version = "0.8.0" dependencies = [ - "accesskit", - "ahash", - "emath 0.28.1", - "epaint 0.28.1", - "nohash-hasher", - "serde", + "anyhow", + "atomic", + "bytemuck", + "chrono", + "egui", + "ffmpeg-the-third", + "itertools 0.13.0", + "nom", + "parking_lot", + "ringbuf", + "sdl2", + "timer", ] [[package]] name = "egui-wgpu" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00fd5d06d8405397e64a928fa0ef3934b3c30273ea7603e3dc4627b1f7a1a82" dependencies = [ "ahash", "bytemuck", "document-features", - "egui 0.27.2", - "epaint 0.27.2", + "egui", + "epaint", "log", "thiserror", "type-map", @@ -1034,12 +1068,13 @@ dependencies = [ [[package]] name = "egui-winit" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a9c430f4f816340e8e8c1b20eec274186b1be6bc4c7dfc467ed50d57abc36c6" dependencies = [ "ahash", "arboard", - "egui 0.27.2", + "egui", "log", "raw-window-handle", "smithay-clipboard", @@ -1050,11 +1085,12 @@ dependencies = [ [[package]] name = "egui_extras" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3c1f5cd8dfe2ade470a218696c66cf556fcfd701e7830fa2e9f4428292a2a1" dependencies = [ "ahash", - "egui 0.27.2", + "egui", "ehttp", "enum-map", "image", @@ -1063,29 +1099,16 @@ dependencies = [ "resvg", ] -[[package]] -name = "egui_extras" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb783d9fa348f69ed5c340aa25af78b5472043090e8b809040e30960cc2a746" -dependencies = [ - "ahash", - "egui 0.28.1", - "enum-map", - "log", - "mime_guess2", - "serde", -] - [[package]] name = "egui_glow" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e39bccc683cd43adab530d8f21a13eb91e80de10bcc38c3f1c16601b6f62b26" dependencies = [ "ahash", "bytemuck", - "egui 0.27.2", - "glow", + "egui", + "glow 0.14.2", "log", "memoffset", "wasm-bindgen", @@ -1094,12 +1117,13 @@ dependencies = [ ] [[package]] -name = "egui_nav" -version = "0.1.0" -source = "git+https://github.com/damus-io/egui-nav?branch=egui-0.28#b19742503329a13df660ac8c5a3ada4a25b7cc53" +name = "egui_inbox" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3616e93d38d5cdd4ef02fb0df5d6e982e3dc2eae71f7c93a31f6265f141be1da" dependencies = [ - "egui 0.28.1", - "egui_extras 0.28.1", + "egui", + "parking_lot", ] [[package]] @@ -1124,21 +1148,13 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "emath" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1fe0049ce51d0fb414d029e668dd72eb30bc2b739bf34296ed97bd33df544f3" dependencies = [ "bytemuck", ] -[[package]] -name = "emath" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6a21708405ea88f63d8309650b4d77431f4bc28fb9d8e6f77d3963b51249e6" -dependencies = [ - "serde", -] - [[package]] name = "enum-map" version = "2.7.3" @@ -1160,17 +1176,6 @@ dependencies = [ "syn 2.0.77", ] -[[package]] -name = "enumn" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -1186,33 +1191,26 @@ dependencies = [ [[package]] name = "epaint" -version = "0.27.2" -source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a32af8da821bd4f43f2c137e295459ee2e1661d87ca8779dfa0eaf45d870e20f" dependencies = [ "ab_glyph", "ahash", "bytemuck", - "ecolor 0.27.2", - "emath 0.27.2", + "ecolor", + "emath", + "epaint_default_fonts", "log", "nohash-hasher", "parking_lot", ] [[package]] -name = "epaint" -version = "0.28.1" +name = "epaint_default_fonts" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0dcc0a0771e7500e94cd1cb797bd13c9f23b9409bdc3c824e2cbc562b7fa01" -dependencies = [ - "ab_glyph", - "ahash", - "ecolor 0.28.1", - "emath 0.28.1", - "nohash-hasher", - "parking_lot", - "serde", -] +checksum = "483440db0b7993cf77a20314f08311dbe95675092405518c0677aa08c151a3ea" [[package]] name = "equivalent" @@ -1261,6 +1259,30 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "ffmpeg-sys-the-third" +version = "2.0.0+ffmpeg-7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82bfdb0a7925996707f0a7dc37b2f3251ff5a15d26e78c586adb60c240dedc5" +dependencies = [ + "bindgen", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ffmpeg-the-third" +version = "2.0.1+ffmpeg-7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4aa99eb55979d5c1db3b0b7a807a5e50dda07f5f6c2dbc6e9b50c205f611646" +dependencies = [ + "bitflags 2.6.0", + "ffmpeg-sys-the-third", + "libc", +] + [[package]] name = "flatbuffers" version = "23.5.26" @@ -1494,10 +1516,79 @@ dependencies = [ ] [[package]] -name = "glutin_wgl_sys" +name = "glow" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" +dependencies = [ + "bitflags 2.6.0", + "cfg_aliases 0.2.1", + "cgl", + "core-foundation", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases 0.2.1", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" dependencies = [ "gl_generator", ] @@ -1523,9 +1614,9 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" dependencies = [ "log", "presser", @@ -1583,7 +1674,7 @@ dependencies = [ "bitflags 2.6.0", "com", "libc", - "libloading 0.8.5", + "libloading", "thiserror", "widestring", "winapi", @@ -1609,9 +1700,12 @@ checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex-conservative" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] [[package]] name = "hex_lit" @@ -1747,14 +1841,26 @@ dependencies = [ ] [[package]] -name = "icrate" -version = "0.0.4" +name = "iana-time-zone" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ - "block2 0.3.0", - "dispatch", - "objc2 0.4.1", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", ] [[package]] @@ -1881,6 +1987,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1940,7 +2055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.8.5", + "libloading", "pkg-config", ] @@ -1994,16 +2109,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libloading" version = "0.8.5" @@ -2039,9 +2144,9 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lnurl-pay" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c042191c2e3f27147decfad8182eea2c7dd1c6c1733562e25d3d401369669d" +checksum = "536e7c782167a2d48346ca0b2677fad19eaef20f19a4ab868e4d5b96ca879def" dependencies = [ "bech32", "reqwest", @@ -2127,9 +2232,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" dependencies = [ "bitflags 2.6.0", "block", @@ -2195,18 +2300,18 @@ dependencies = [ [[package]] name = "naga" -version = "0.20.0" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" dependencies = [ "arrayvec", "bit-set", "bitflags 2.6.0", + "cfg_aliases 0.1.1", "codespan-reporting", "hexf-parse", "indexmap", "log", - "num-traits", "rustc-hash 1.1.0", "spirv", "termcolor", @@ -2216,14 +2321,14 @@ dependencies = [ [[package]] name = "ndk" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.6.0", "jni-sys", "log", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "raw-window-handle", "thiserror", @@ -2244,12 +2349,27 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + [[package]] name = "negentropy" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e664971378a3987224f7a0e10059782035e89899ae403718ee07de85bec42afe" +[[package]] +name = "negentropy" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a88da9dd148bbcdce323dd6ac47d369b4769d4a3b78c6c52389b9269f77932" + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -2280,12 +2400,13 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "nostr" -version = "0.34.1" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1c3c32439eef3ea4d9079b2a8f557992d27259c26527e43d4228dd321e43a77" +checksum = "56db234b2e07901e372f34e9463f91590579cd8e6dbd34ed2ccc7e461e4ba639" dependencies = [ "aes", - "base64 0.21.7", + "base64 0.22.1", + "bech32", "bip39", "bitcoin", "cbc", @@ -2294,13 +2415,13 @@ dependencies = [ "getrandom", "instant", "js-sys", - "negentropy", + "negentropy 0.3.1", + "negentropy 0.4.3", "once_cell", "reqwest", "scrypt", "serde", "serde_json", - "tracing", "unicode-normalization", "url", "wasm-bindgen", @@ -2310,9 +2431,9 @@ dependencies = [ [[package]] name = "nostr-database" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1926ef55392f3eea1bbe4a1358b64bbf12dd6eb554f40f483941a102c6263fc6" +checksum = "50de8cc5e77e7dafa7e2e0d0d67187ef19e191dcd1a68efffd3e05152d91b3c3" dependencies = [ "async-trait", "lru", @@ -2324,13 +2445,15 @@ dependencies = [ [[package]] name = "nostr-relay-pool" -version = "0.34.1" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e37c5ea991802a91728d4c09d5a7276938104ead8bf140a63a60acabc5c756" +checksum = "800b9ca169902977366f8243ec645b1fa4a128ab621331796d4a26bd7bc22a88" dependencies = [ "async-utility", "async-wsocket", "atomic-destructor", + "negentropy 0.3.1", + "negentropy 0.4.3", "nostr", "nostr-database", "thiserror", @@ -2341,9 +2464,9 @@ dependencies = [ [[package]] name = "nostr-sdk" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0c0c5f8ddbdfc064ea71883191ec53de6ed52b5dca10ab07f0810b99e91acc" +checksum = "d93036bf4c1e35145ca2cd6ee4cb7bb9c74f41cbca9cc4caff1e87b5e192f253" dependencies = [ "async-utility", "atomic-destructor", @@ -2361,9 +2484,9 @@ dependencies = [ [[package]] name = "nostr-signer" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c30294a7be7d9d5ac777954812f5c7b4ae2a1e583a62e33537f87d98ab23729" +checksum = "c1e132975a677a1c97a7695ef1161291dc06517a588b6e17e3aa05d3fb4056a0" dependencies = [ "async-utility", "nostr", @@ -2375,9 +2498,9 @@ dependencies = [ [[package]] name = "nostr-zapper" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf3ba30e807145e9cb924faf8fb0719e460f613088e99c753b67c2a9929c5b7" +checksum = "b60e7a3ecc9881ca418e772a6fc4410920653a9f0bf9457b6ddd732d2a3f64f1" dependencies = [ "async-trait", "nostr", @@ -2387,7 +2510,7 @@ dependencies = [ [[package]] name = "nostrdb" version = "0.3.4" -source = "git+https://github.com/damus-io/nostrdb-rs?rev=6d22af6d5159be4c9e4579f8c9d3af836e0d470a#6d22af6d5159be4c9e4579f8c9d3af836e0d470a" +source = "git+https://github.com/damus-io/nostrdb-rs#9bbafd8a2e904b77a51e7cfca71eb5bb5650e829" dependencies = [ "bindgen", "cc", @@ -2481,9 +2604,9 @@ dependencies = [ [[package]] name = "nwc" -version = "0.34.1" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a16ac06bc273fcd4ead47c0c5a58b6cc7db2247fc7a64dd9bc11cf18e3efeb4" +checksum = "2e962f52732a6d91c1e76d4de3f1daa186e77a849e98e5abe53ca7fe9796d04e" dependencies = [ "async-utility", "nostr", @@ -2508,16 +2631,6 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" -[[package]] -name = "objc2" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" -dependencies = [ - "objc-sys", - "objc2-encode 3.0.0", -] - [[package]] name = "objc2" version = "0.5.2" @@ -2525,7 +2638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ "objc-sys", - "objc2-encode 4.0.3", + "objc2-encode", ] [[package]] @@ -2535,15 +2648,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", + "block2", "libc", - "objc2 0.5.2", + "objc2", "objc2-core-data", "objc2-core-image", "objc2-foundation", "objc2-quartz-core", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + [[package]] name = "objc2-core-data" version = "0.2.2" @@ -2551,8 +2688,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", ] @@ -2562,17 +2699,23 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", "objc2-metal", ] [[package]] -name = "objc2-encode" -version = "3.0.0" +name = "objc2-core-location" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] [[package]] name = "objc2-encode" @@ -2587,9 +2730,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", + "block2", + "dispatch", "libc", - "objc2 0.5.2", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", ] [[package]] @@ -2599,8 +2755,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", ] @@ -2611,12 +2767,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", "objc2-metal", ] +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + [[package]] name = "object" version = "0.36.4" @@ -2807,6 +3018,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -3004,7 +3221,7 @@ dependencies = [ "built", "cfg-if", "interpolate_name", - "itertools", + "itertools 0.12.1", "libc", "libfuzzer-sys", "log", @@ -3071,15 +3288,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -3214,6 +3422,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ringbuf" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726bb493fe9cac765e8f96a144c3a8396bdf766dedad22e504b70b908dcbceb4" +dependencies = [ + "crossbeam-utils", + "portable-atomic", +] + [[package]] name = "roxmltree" version = "0.19.0" @@ -3351,12 +3569,36 @@ dependencies = [ ] [[package]] -name = "secp256k1" -version = "0.28.2" +name = "sdl2" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +checksum = "3b498da7d14d1ad6c839729bd4ad6fc11d90a57583605f3b4df2cd709a9cd380" dependencies = [ - "bitcoin_hashes 0.13.0", + "bitflags 1.3.2", + "lazy_static", + "libc", + "sdl2-sys", +] + +[[package]] +name = "sdl2-sys" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951deab27af08ed9c6068b7b0d05a93c91f0a8eb16b6b816a5e73452a43521d3" +dependencies = [ + "cfg-if", + "cmake", + "libc", + "version-compare 0.1.1", +] + +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" +dependencies = [ + "bitcoin_hashes 0.14.0", "rand", "secp256k1-sys", "serde", @@ -3364,9 +3606,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.9.2" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] @@ -3522,31 +3764,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "smithay-client-toolkit" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" -dependencies = [ - "bitflags 2.6.0", - "calloop 0.12.4", - "calloop-wayland-source 0.2.0", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix", - "thiserror", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols 0.31.2", - "wayland-protocols-wlr 0.2.0", - "wayland-scanner", - "xkeysym", -] - [[package]] name = "smithay-client-toolkit" version = "0.19.2" @@ -3554,8 +3771,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ "bitflags 2.6.0", - "calloop 0.13.0", - "calloop-wayland-source 0.3.0", + "calloop", + "calloop-wayland-source", "cursor-icon", "libc", "log", @@ -3566,8 +3783,8 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols 0.32.4", - "wayland-protocols-wlr 0.3.4", + "wayland-protocols", + "wayland-protocols-wlr", "wayland-scanner", "xkeysym", ] @@ -3579,7 +3796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" dependencies = [ "libc", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "wayland-backend", ] @@ -3692,7 +3909,7 @@ dependencies = [ "heck", "pkg-config", "toml", - "version-compare", + "version-compare 0.2.0", ] [[package]] @@ -3751,6 +3968,15 @@ dependencies = [ "weezl", ] +[[package]] +name = "timer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d42176308937165701f50638db1c31586f183f1aab416268216577aec7306b" +dependencies = [ + "chrono", +] + [[package]] name = "tiny-skia" version = "0.11.4" @@ -3855,9 +4081,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" dependencies = [ "futures-util", "log", @@ -4001,9 +4227,9 @@ checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" [[package]] name = "tungstenite" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" dependencies = [ "byteorder", "bytes", @@ -4193,6 +4419,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + [[package]] name = "version-compare" version = "0.2.0" @@ -4345,18 +4583,6 @@ dependencies = [ "xcursor", ] -[[package]] -name = "wayland-protocols" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" -dependencies = [ - "bitflags 2.6.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - [[package]] name = "wayland-protocols" version = "0.32.4" @@ -4371,27 +4597,14 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.2.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +checksum = "8a0a41a6875e585172495f7a96dfa42ca7e0213868f4f15c313f7c33221a7eff" dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.31.2", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" -dependencies = [ - "bitflags 2.6.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-scanner", ] @@ -4404,7 +4617,7 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.4", + "wayland-protocols", "wayland-scanner", ] @@ -4443,9 +4656,9 @@ dependencies = [ [[package]] name = "web-time" -version = "0.2.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -4457,13 +4670,13 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "425ba64c1e13b1c6e8c5d2541c8fac10022ca584f33da781db01b5756aef1f4e" dependencies = [ - "block2 0.5.1", + "block2", "core-foundation", "home", "jni", "log", "ndk-context", - "objc2 0.5.2", + "objc2", "objc2-foundation", "url", "web-sys", @@ -4486,13 +4699,12 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "wgpu" -version = "0.20.1" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c" +checksum = "e1d1c4ba43f80542cf63a0a6ed3134629ae73e8ab51e4b765a67f3aa062eb433" dependencies = [ "arrayvec", - "cfg-if", - "cfg_aliases", + "cfg_aliases 0.1.1", "document-features", "js-sys", "log", @@ -4512,15 +4724,14 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.21.1" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50819ab545b867d8a454d1d756b90cd5f15da1f2943334ca314af10583c9d39" +checksum = "0348c840d1051b8e86c3bcd31206080c5e71e5933dabd79be1ce732b0b2f089a" dependencies = [ "arrayvec", "bit-vec", "bitflags 2.6.0", - "cfg_aliases", - "codespan-reporting", + "cfg_aliases 0.1.1", "document-features", "indexmap", "log", @@ -4532,25 +4743,24 @@ dependencies = [ "rustc-hash 1.1.0", "smallvec", "thiserror", - "web-sys", "wgpu-hal", "wgpu-types", ] [[package]] name = "wgpu-hal" -version = "0.21.1" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172e490a87295564f3fcc0f165798d87386f6231b04d4548bca458cbbfd63222" +checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f" dependencies = [ "android_system_properties", "arrayvec", "ash", "bitflags 2.6.0", "block", - "cfg_aliases", + "cfg_aliases 0.1.1", "core-graphics-types", - "glow", + "glow 0.13.1", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", @@ -4559,11 +4769,11 @@ dependencies = [ "js-sys", "khronos-egl", "libc", - "libloading 0.8.5", + "libloading", "log", "metal", "naga", - "ndk-sys", + "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", "parking_lot", @@ -4581,9 +4791,9 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.20.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef" +checksum = "bc9d91f0e2c4b51434dfa6db77846f2793149d8e73f800fa2e41f52b8eac3c5d" dependencies = [ "bitflags 2.6.0", "js-sys", @@ -4697,15 +4907,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -4904,46 +5105,50 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.29.15" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67" dependencies = [ "ahash", "android-activity", "atomic-waker", "bitflags 2.6.0", + "block2", "bytemuck", - "calloop 0.12.4", - "cfg_aliases", + "calloop", + "cfg_aliases 0.2.1", + "concurrent-queue", "core-foundation", "core-graphics", "cursor-icon", - "icrate", + "dpi", "js-sys", "libc", - "log", "memmap2", "ndk", - "ndk-sys", - "objc2 0.4.1", - "once_cell", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", "orbclient", "percent-encoding", + "pin-project", "raw-window-handle", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix", - "smithay-client-toolkit 0.18.1", + "smithay-client-toolkit", "smol_str", + "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-protocols-plasma", "web-sys", "web-time", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "x11-dl", "x11rb", "xkbcommon-dl", @@ -4978,7 +5183,7 @@ dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "libloading 0.8.5", + "libloading", "once_cell", "rustix", "x11rb-protocol", @@ -5031,11 +5236,14 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" name = "zap_stream_app" version = "0.1.0" dependencies = [ + "bech32", "eframe", - "egui 0.27.2", - "egui_extras 0.27.2", - "egui_nav", + "egui", + "egui-video", + "egui_extras", + "egui_inbox", "image", + "libc", "log", "nostr-sdk", "nostrdb", diff --git a/Cargo.toml b/Cargo.toml index c98ad01..15f8ff4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,15 @@ edition = "2021" [dependencies] tokio = "1.40.0" -egui = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb" } -eframe = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb", package = "eframe", default-features = false, features = ["wgpu", "wayland", "x11", "android-native-activity"] } -nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "6d22af6d5159be4c9e4579f8c9d3af836e0d470a" } -nostr-sdk = { version = "0.34.0", features = ["all-nips"] } -egui_nav = { git = "https://github.com/damus-io/egui-nav", branch = "egui-0.28" } -egui_extras = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb", package = "egui_extras", features = ["all_loaders"] } +egui = { version = "0.29.1" } +eframe = { version = "0.29.1", default-features = false, features = ["glow", "wgpu", "wayland", "x11", "android-native-activity"] } +nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", version = "0.3.4" } +nostr-sdk = { version = "0.35.0", features = ["all-nips"] } +egui_extras = { version = "0.29.1", features = ["all_loaders"] } image = { version = "0.25", features = ["jpeg", "png", "webp"] } log = "0.4.22" pretty_env_logger = "0.5.0" +egui_inbox = "0.6.0" +bech32 = "0.11.0" +libc = "0.2.158" +egui-video = { path = "../egui-video" } diff --git a/src/app.rs b/src/app.rs index 97fb543..84ce454 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,20 +1,18 @@ -use crate::services::Services; -use crate::widget::NostrWidget; -use crate::widgets::header::Header; -use crate::widgets::stream_list::StreamList; +use crate::route::Router; use eframe::{App, CreationContext, Frame}; use egui::{Color32, Context, ScrollArea}; +use egui_inbox::UiInbox; +use log::warn; use nostr_sdk::database::{MemoryDatabase, MemoryDatabaseOptions}; -use nostr_sdk::{Client, Event, Filter, Kind, RelayPoolNotification}; -use nostrdb::{Config, Ndb, Transaction}; +use nostr_sdk::{Client, Filter, JsonUtil, Kind, RelayPoolNotification}; +use nostrdb::{Config, Ndb}; use tokio::sync::broadcast; pub struct ZapStreamApp { ndb: Ndb, client: Client, notifications: broadcast::Receiver, - events: Vec, - services: Services, + router: Router, } impl ZapStreamApp { @@ -41,12 +39,13 @@ impl ZapStreamApp { }); egui_extras::install_image_loaders(&cc.egui_ctx); + let inbox = UiInbox::new(); + let ndb = Ndb::new(".", &Config::default()).unwrap(); Self { - ndb: Ndb::new(".", &Config::default()).unwrap(), + ndb: ndb.clone(), client: client.clone(), notifications, - services: Services::new(client, cc.egui_ctx.clone()), - events: vec![], + router: Router::new(inbox, cc.egui_ctx.clone(), client.clone(), ndb.clone()), } } @@ -54,7 +53,9 @@ impl ZapStreamApp { while let Ok(msg) = self.notifications.try_recv() { match msg { RelayPoolNotification::Event { event, .. } => { - self.events.push(*event); + if let Err(e) = self.ndb.process_event(event.as_json().as_str()) { + warn!("Failed to process event: {:?}", e); + } } _ => { // dont care @@ -66,20 +67,17 @@ impl ZapStreamApp { impl App for ZapStreamApp { fn update(&mut self, ctx: &Context, frame: &mut Frame) { - let txn = Transaction::new(&self.ndb).expect("txn"); self.process_nostr(); let mut app_frame = egui::containers::Frame::default(); app_frame.stroke.color = Color32::BLACK; - ctx.set_debug_on_hover(true); + //ctx.set_debug_on_hover(true); + egui::CentralPanel::default() .frame(app_frame) .show(ctx, |ui| { - ScrollArea::vertical().show(ui, |ui| { - ui.add(Header::new(&self.services)); - ui.add(StreamList::new(&self.events, &self.services)); - }); + self.router.show(ui) }); } -} \ No newline at end of file +} diff --git a/src/link.rs b/src/link.rs new file mode 100644 index 0000000..2b64618 --- /dev/null +++ b/src/link.rs @@ -0,0 +1,119 @@ +use crate::note_util::NoteUtil; +use bech32::{Hrp, NoChecksum}; +use egui::TextBuffer; +use nostr_sdk::util::hex; +use nostrdb::{Filter, Note}; +use std::fmt::{Display, Formatter}; + +#[derive(Clone)] +pub struct NostrLink { + hrp: NostrLinkType, + id: IdOrStr, + kind: Option, + author: Option<[u8; 32]>, + relays: Vec, +} + +#[derive(Clone)] +pub enum IdOrStr { + Id([u8; 32]), + Str(String), +} + +#[derive(Clone)] +pub enum NostrLinkType { + Note, + PublicKey, + PrivateKey, + + // TLV kinds + Event, + Profile, + Coordinate, +} + +impl NostrLink { + pub fn new(hrp: NostrLinkType, id: IdOrStr, kind: Option, author: Option<[u8; 32]>, relays: Vec) -> Self { + Self { + hrp, + id, + kind, + author, + relays, + } + } + + pub fn from_note(note: &Note<'_>) -> Self { + if note.kind() >= 30_000 && note.kind() < 40_000 { + Self { + hrp: NostrLinkType::Coordinate, + id: IdOrStr::Str(note.get_tag_value("d").unwrap().variant().str().unwrap().to_string()), + kind: Some(note.kind()), + author: Some(note.pubkey().clone()), + relays: vec![], + } + } else { + Self { + hrp: NostrLinkType::Event, + id: IdOrStr::Id(note.id().clone()), + kind: Some(note.kind()), + author: Some(note.pubkey().clone()), + relays: vec![], + } + } + } +} + +impl TryInto for &NostrLink { + type Error = (); + fn try_into(self) -> Result { + match self.hrp { + NostrLinkType::Coordinate => { + Ok(Filter::new() + .tags([match self.id { + IdOrStr::Str(ref s) => s.to_owned(), + IdOrStr::Id(ref i) => hex::encode(i) + }], 'd') + .build()) + } + NostrLinkType::Event | NostrLinkType::Note => { + Ok(Filter::new().build()) + } + _ => Err(()) + } + } +} + +impl Display for NostrLinkType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Note => write!(f, "note"), + Self::PublicKey => write!(f, "npub"), + Self::PrivateKey => write!(f, "nsec"), + Self::Event => write!(f, "nevent"), + Self::Profile => write!(f, "nprofile"), + Self::Coordinate => write!(f, "naddr"), + } + } +} + +impl NostrLinkType { + pub fn to_hrp(&self) -> Hrp { + let str = self.to_string(); + Hrp::parse(str.as_str()).unwrap() + } +} + +impl Display for NostrLink { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.hrp { + NostrLinkType::Note | NostrLinkType::PrivateKey | NostrLinkType::PublicKey => { + Ok(bech32::encode_to_fmt::(f, self.hrp.to_hrp(), match &self.id { + IdOrStr::Str(s) => s.as_bytes(), + IdOrStr::Id(i) => i + }).map_err(|e| std::fmt::Error)?) + } + NostrLinkType::Event | NostrLinkType::Profile | NostrLinkType::Coordinate => todo!() + } + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 26d301f..c66d754 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,22 @@ +use eframe::Renderer; use crate::app::ZapStreamApp; use egui::Vec2; +use nostrdb::Note; mod app; -mod widget; -mod widgets; +pub mod widgets; mod services; +mod route; +mod note_util; +mod link; +mod stream_info; #[tokio::main] async fn main() { pretty_env_logger::init(); let mut options = eframe::NativeOptions::default(); + options.renderer = Renderer::Glow; options.viewport = options.viewport .with_inner_size(Vec2::new(360., 720.)); @@ -19,4 +25,4 @@ async fn main() { options, Box::new(move |cc| Ok(Box::new(ZapStreamApp::new(cc)))), ); -} +} \ No newline at end of file diff --git a/src/note_util.rs b/src/note_util.rs new file mode 100644 index 0000000..55eee32 --- /dev/null +++ b/src/note_util.rs @@ -0,0 +1,73 @@ +use libc::{malloc, memcpy}; +use nostr_sdk::util::hex; +use nostrdb::{NdbStr, Note, Tag, Tags}; +use std::fmt::Display; +use std::mem::transmute; +use std::{mem, ptr}; + +pub trait NoteUtil { + fn id_hex(&self) -> String; + fn get_tag_value(&self, key: &str) -> Option; + fn find_tag_value(&self, fx: F) -> Option + where + F: Fn(Vec) -> bool; +} + +impl<'a> NoteUtil for Note<'a> { + fn id_hex(&self) -> String { + hex::encode(self.id()) + } + + fn get_tag_value(&self, key: &str) -> Option { + self.find_tag_value(|t| t[0].variant().str() == Some(key)) + } + + fn find_tag_value(&self, fx: F) -> Option + where + F: Fn(Vec) -> bool, + { + let tag = self.tags().iter().find(|t| { + let tag_vec = TagIterBorrow::new(t).collect(); + fx(tag_vec) + }); + if let Some(t) = tag { + t.get(1) + } else { + None + } + } +} + + +#[derive(Debug, Clone)] +pub struct TagIterBorrow<'a> { + tag: &'a Tag<'a>, + index: u16, +} + +impl<'a> TagIterBorrow<'a> { + pub fn new(tag: &'a Tag<'a>) -> Self { + let index = 0; + TagIterBorrow { tag, index } + } + + pub fn done(&self) -> bool { + self.index >= self.tag.count() + } +} + +impl<'a> Iterator for TagIterBorrow<'a> { + type Item = NdbStr<'a>; + + fn next(&mut self) -> Option> { + let tag = self.tag.get(self.index); + if tag.is_some() { + self.index += 1; + tag + } else { + None + } + } +} + +pub struct OwnedNote; \ No newline at end of file diff --git a/src/route/home.rs b/src/route/home.rs new file mode 100644 index 0000000..de1b4fd --- /dev/null +++ b/src/route/home.rs @@ -0,0 +1,27 @@ +use crate::route::RouteServices; +use egui::{Response, Ui, Widget}; +use nostrdb::{Filter, Note}; +use crate::widgets; + +pub struct HomePage<'a> { + services: &'a RouteServices<'a>, +} + +impl<'a> HomePage<'a> { + pub fn new(services: &'a RouteServices) -> Self { + Self { services } + } +} + +impl<'a> Widget for HomePage<'a> { + fn ui(self, ui: &mut Ui) -> Response { + let events = self.services.ndb.query(&self.services.tx, &[ + Filter::new() + .kinds([30_311]) + .limit(10) + .build() + ], 10).unwrap(); + let events: Vec> = events.iter().map(|v| v.note.clone()).collect(); + widgets::StreamList::new(&events, &self.services).ui(ui) + } +} \ No newline at end of file diff --git a/src/route/mod.rs b/src/route/mod.rs new file mode 100644 index 0000000..efbee36 --- /dev/null +++ b/src/route/mod.rs @@ -0,0 +1,134 @@ +use crate::link::NostrLink; +use crate::note_util::OwnedNote; +use crate::route; +use crate::route::home::HomePage; +use crate::route::stream::StreamPage; +use crate::services::profile::ProfileService; +use crate::widgets::{Header, StreamList}; +use egui::{Context, Response, ScrollArea, Ui, Widget}; +use egui_inbox::{UiInbox, UiInboxSender}; +use egui_video::Player; +use log::{info, warn}; +use nostr_sdk::Client; +use nostrdb::{Filter, Ndb, Note, Transaction}; + +mod stream; +mod home; + +pub enum Routes { + HomePage, + Event { + link: NostrLink, + event: Option, + }, + ProfilePage { + link: NostrLink, + profile: Option, + }, + + // special kind for modifying route state + Action(RouteAction), +} + +pub enum RouteAction { + Login([u8; 32]), + StartPlayer(String), + PausePlayer, + SeekPlayer(f32), + StopPlayer, +} + +pub struct Router { + current: Routes, + router: UiInbox, + + ctx: Context, + profile_service: ProfileService, + ndb: Ndb, + login: Option<[u8; 32]>, + player: Option, +} + +impl Router { + pub fn new(rx: UiInbox, ctx: Context, client: Client, ndb: Ndb) -> Self { + Self { + current: Routes::HomePage, + router: rx, + ctx: ctx.clone(), + profile_service: ProfileService::new(client.clone(), ctx.clone()), + ndb, + login: None, + player: None, + } + } + + pub fn show(&mut self, ui: &mut Ui) -> Response { + let tx = Transaction::new(&self.ndb).unwrap(); + // handle app state changes + while let Some(r) = self.router.read(ui).next() { + if let Routes::Action(a) = r { + match a { + RouteAction::Login(k) => { + self.login = Some(k) + } + RouteAction::StartPlayer(u) => { + if self.player.is_none() { + if let Ok(p) = Player::new(&self.ctx, &u) { + self.player = Some(p) + } + } + } + _ => info!("Not implemented") + } + } else { + self.current = r; + } + } + + let mut svc = RouteServices { + context: self.ctx.clone(), + profile: &self.profile_service, + router: self.router.sender(), + ndb: self.ndb.clone(), + tx: &tx, + login: &self.login, + player: &mut self.player, + }; + + // display app + ScrollArea::vertical().show(ui, |ui| { + ui.add(Header::new(&svc)); + match &self.current { + Routes::HomePage => { + HomePage::new(&svc).ui(ui) + } + Routes::Event { link, event } => { + StreamPage::new(&mut svc, link, event) + .ui(ui) + } + _ => { + ui.label("Not found") + } + } + }).inner + } +} + +pub struct RouteServices<'a> { + pub context: Context, //cloned + pub router: UiInboxSender, //cloned + pub ndb: Ndb, //cloned + + pub player: &'a mut Option, + pub profile: &'a ProfileService, //ref + pub tx: &'a Transaction, //ref + pub login: &'a Option<[u8; 32]>, //ref +} + +impl<'a> RouteServices<'a> { + pub fn navigate(&self, route: Routes) { + if let Err(e) = self.router.send(route) { + warn!("Failed to navigate"); + } + } +} \ No newline at end of file diff --git a/src/route/stream.rs b/src/route/stream.rs new file mode 100644 index 0000000..0fc5160 --- /dev/null +++ b/src/route/stream.rs @@ -0,0 +1,51 @@ +use crate::link::NostrLink; +use crate::note_util::{NoteUtil, OwnedNote}; +use crate::route::{RouteAction, RouteServices, Routes}; +use crate::stream_info::StreamInfo; +use crate::widgets::StreamPlayer; +use egui::{Color32, Label, Response, RichText, TextWrapMode, Ui, Widget}; +use nostrdb::Note; +use std::ptr; + +pub struct StreamPage<'a> { + services: &'a mut RouteServices<'a>, + link: &'a NostrLink, + event: &'a Option, +} + +impl<'a> StreamPage<'a> { + pub fn new(services: &'a mut RouteServices<'a>, link: &'a NostrLink, event: &'a Option) -> Self { + Self { services, link, event } + } +} + +impl<'a> Widget for StreamPage<'a> { + fn ui(self, ui: &mut Ui) -> Response { + let event = if let Some(event) = self.event { + Note::Owned { + ptr: ptr::null_mut(), + size: 0, + } + } else { + let mut q = self.services.ndb.query(self.services.tx, &[ + self.link.try_into().unwrap() + ], 1).unwrap(); + let [e] = q.try_into().unwrap(); + e.note + }; + + if let Some(stream) = event.stream() { + if self.services.player.is_none() { + self.services.navigate(Routes::Action(RouteAction::StartPlayer(stream))); + } + } + StreamPlayer::new(self.services).ui(ui); + let title = RichText::new(match event.get_tag_value("title") { + Some(s) => s.variant().str().unwrap_or("Unknown"), + None => "Unknown", + }) + .size(16.) + .color(Color32::WHITE); + ui.add(Label::new(title).wrap_mode(TextWrapMode::Truncate)) + } +} \ No newline at end of file diff --git a/src/services/mod.rs b/src/services/mod.rs index 11893f4..5b3bafd 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,19 +1 @@ -use crate::services::profile::ProfileService; -use egui::Context; -use nostr_sdk::Client; - -pub mod profile; - -pub struct Services { - pub context: Context, - pub profile: ProfileService, -} - -impl Services { - pub fn new(client: Client, context: Context) -> Self { - Self { - context: context.clone(), - profile: ProfileService::new(client.clone(), context.clone()), - } - } -} \ No newline at end of file +pub mod profile; \ No newline at end of file diff --git a/src/services/profile.rs b/src/services/profile.rs index 22092b2..744f00d 100644 --- a/src/services/profile.rs +++ b/src/services/profile.rs @@ -1,23 +1,25 @@ use egui::load::BytesLoader; use log::{info, warn}; +use nostr_sdk::prelude::hex; use nostr_sdk::{Client, Metadata, PublicKey}; use std::collections::HashMap; use std::sync::Arc; +use std::time::Duration; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; use tokio::sync::Mutex; pub struct ProfileService { client: Client, - pub profiles: Arc>>>, + pub profiles: Arc>>>, ctx: egui::Context, - request_profile: UnboundedSender, + request_profile: UnboundedSender<[u8; 32]>, } struct Loader { client: Client, ctx: egui::Context, - profiles: Arc>>>, - queue: UnboundedReceiver, + profiles: Arc>>>, + queue: UnboundedReceiver<[u8; 32]>, } impl Loader { @@ -25,8 +27,9 @@ impl Loader { while let Some(key) = self.queue.recv().await { let mut profiles = self.profiles.lock().await; if !profiles.contains_key(&key) { - info!("Requesting profile {}", key); - match self.client.metadata(key).await { + info!("Requesting profile {}", hex::encode(key)); + match self.client.fetch_metadata(PublicKey::from_slice(&key).unwrap(), + Some(Duration::from_secs(3))).await { Ok(meta) => { profiles.insert(key, Some(meta)); self.ctx.request_repaint(); @@ -64,7 +67,7 @@ impl ProfileService { } } - pub fn get_profile(&self, public_key: &PublicKey) -> Option { + pub fn get_profile(&self, public_key: &[u8; 32]) -> Option { if let Ok(profiles) = self.profiles.try_lock() { return if let Some(p) = profiles.get(public_key) { if let Some(p) = p { diff --git a/src/stream_info.rs b/src/stream_info.rs new file mode 100644 index 0000000..a63ea37 --- /dev/null +++ b/src/stream_info.rs @@ -0,0 +1,38 @@ +use crate::note_util::NoteUtil; +use nostrdb::Note; + +pub trait StreamInfo { + fn title(&self) -> Option; + + fn summary(&self) -> Option; + + fn host(&self) -> [u8; 32]; + + fn stream(&self) -> Option; +} + +impl<'a> StreamInfo for Note<'a> { + fn title(&self) -> Option { + if let Some(s) = self.get_tag_value("title") { + s.variant().str().map(ToString::to_string) + } else { + None + } + } + + fn summary(&self) -> Option { + todo!() + } + + fn host(&self) -> [u8; 32] { + todo!() + } + + fn stream(&self) -> Option { + if let Some(s) = self.get_tag_value("streaming") { + s.variant().str().map(ToString::to_string) + } else { + None + } + } +} \ No newline at end of file diff --git a/src/widget.rs b/src/widget.rs deleted file mode 100644 index 61eaa5c..0000000 --- a/src/widget.rs +++ /dev/null @@ -1,5 +0,0 @@ -use nostr_sdk::Filter; - -pub trait NostrWidget { - fn subscribe(&self) -> Vec; -} \ No newline at end of file diff --git a/src/widgets/avatar.rs b/src/widgets/avatar.rs index 29e02cf..ddb45bc 100644 --- a/src/widgets/avatar.rs +++ b/src/widgets/avatar.rs @@ -1,6 +1,5 @@ -use crate::services::Services; use egui::{Color32, Image, Rect, Response, Rounding, Sense, Ui, Vec2, Widget}; -use nostr_sdk::PublicKey; +use crate::services::profile::ProfileService; pub struct Avatar<'a> { image: Option>, @@ -11,8 +10,8 @@ impl<'a> Avatar<'a> { Self { image: Some(img) } } - pub fn public_key(svc: &'a Services, pk: &PublicKey) -> Self { - if let Some(meta) = svc.profile.get_profile(pk) { + pub fn public_key(svc: &'a ProfileService, pk: &[u8; 32]) -> Self { + if let Some(meta) = svc.get_profile(pk) { if let Some(img) = &meta.picture { return Self { image: Some(Image::from_uri(img.clone())) }; } diff --git a/src/widgets/header.rs b/src/widgets/header.rs index eca07ed..f6763c2 100644 --- a/src/widgets/header.rs +++ b/src/widgets/header.rs @@ -1,23 +1,23 @@ -use crate::services::Services; +use crate::route::{RouteServices, Routes}; use crate::widgets::avatar::Avatar; use eframe::emath::Align; use eframe::epaint::Vec2; -use egui::{Frame, Image, Layout, Margin, Response, Ui, Widget}; -use nostr_sdk::PublicKey; +use egui::{Frame, Image, Layout, Margin, Response, Sense, Ui, Widget}; +use nostr_sdk::util::hex; pub struct Header<'a> { - services: &'a Services, + services: &'a RouteServices<'a>, } impl<'a> Header<'a> { - pub fn new(services: &'a Services) -> Self { + pub fn new(services: &'a RouteServices) -> Self { Self { services } } } impl Widget for Header<'_> { fn ui(self, ui: &mut Ui) -> Response { - let login = PublicKey::from_hex("63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed").unwrap(); + let login: [u8; 32] = hex::decode("63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed").unwrap().try_into().unwrap(); let logo_bytes = include_bytes!("../logo.svg"); Frame::none() .outer_margin(Margin::symmetric(16., 8.)) @@ -25,9 +25,13 @@ impl Widget for Header<'_> { ui.allocate_ui_with_layout(Vec2::new(ui.available_width(), 32.), Layout::left_to_right(Align::Center), |ui| { ui.style_mut() .spacing.item_spacing.x = 16.; - Image::from_bytes("logo.svg", logo_bytes) - .max_height(22.62).ui(ui); - ui.add(Avatar::public_key(&self.services, &login)); + if Image::from_bytes("logo.svg", logo_bytes) + .max_height(22.62) + .sense(Sense::click()) + .ui(ui).clicked() { + self.services.navigate(Routes::HomePage); + } + ui.add(Avatar::public_key(&self.services.profile, &login)); }) }).response } diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index aba8cb3..30645fd 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -1,4 +1,11 @@ -pub mod header; -pub mod stream; -pub mod stream_list; -mod avatar; \ No newline at end of file +mod header; +mod stream; +mod stream_list; +mod avatar; +mod stream_player; +mod video_placeholder; + +pub use self::header::Header; +pub use self::stream_list::StreamList; +pub use self::video_placeholder::VideoPlaceholder; +pub use self::stream_player::StreamPlayer; diff --git a/src/widgets/stream.rs b/src/widgets/stream.rs index 3ce286a..d896da3 100644 --- a/src/widgets/stream.rs +++ b/src/widgets/stream.rs @@ -1,21 +1,26 @@ -use crate::services::Services; +use crate::link::NostrLink; +use crate::note_util::NoteUtil; +use crate::route::{RouteServices, Routes}; use crate::widgets::avatar::Avatar; +use crate::widgets::VideoPlaceholder; use eframe::epaint::Vec2; -use egui::{Color32, Image, Label, Rect, Response, RichText, Rounding, Sense, TextWrapMode, Ui, Widget}; -use log::info; -use nostr_sdk::{Alphabet, Event, PublicKey, SingleLetterTag, TagKind}; +use egui::{Color32, Image, Label, Response, RichText, Rounding, Sense, TextWrapMode, Ui, Widget}; +use nostrdb::{NdbStrVariant, Note}; pub struct StreamEvent<'a> { - event: &'a Event, + event: &'a Note<'a>, picture: Option>, - services: &'a Services, + services: &'a RouteServices<'a>, } impl<'a> StreamEvent<'a> { - pub fn new(event: &'a Event, services: &'a Services) -> Self { - let image = event.get_tag_content(TagKind::Image); + pub fn new(event: &'a Note<'a>, services: &'a RouteServices) -> Self { + let image = event.get_tag_value("image"); let cover = match image { - Some(i) => Some(Image::from_uri(i)), + Some(i) => match i.variant().str() { + Some(i) => Some(Image::from_uri(i)), + None => None, + } None => None, }; Self { event, picture: cover, services } @@ -27,28 +32,39 @@ impl Widget for StreamEvent<'_> { ui.style_mut() .spacing.item_spacing = Vec2::new(12., 16.); - let host = match self.event.tags.iter().find(|t| t.kind() == TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::P)) && t.as_vec()[3] == "host") { - Some(t) => PublicKey::from_hex(t.as_vec().get(1).unwrap()).unwrap(), - None => self.event.author() + let host = match self.event.find_tag_value(|t| t[0].variant().str() == Some("p") && t[3].variant().str() == Some("host")) { + Some(t) => match t.variant() { + NdbStrVariant::Id(i) => i, + NdbStrVariant::Str(s) => self.event.pubkey(), + } + None => self.event.pubkey() }; let w = ui.available_width(); let h = (w / 16.0) * 9.0; let img_size = Vec2::new(w, h); let img = match self.picture { - Some(picture) => picture.fit_to_exact_size(img_size).rounding(Rounding::same(12.)).sense(Sense::click()).ui(ui), + Some(picture) => picture + .fit_to_exact_size(img_size) + .rounding(Rounding::same(12.)) + .sense(Sense::click()) + .ui(ui), None => { - let (response, painter) = ui.allocate_painter(img_size, Sense::click()); - painter.rect_filled(Rect::EVERYTHING, Rounding::same(12.), Color32::from_rgb(200, 200, 200)); - response + VideoPlaceholder.ui(ui) } }; if img.clicked() { - info!("Navigating to {}", self.event.id); + self.services.navigate(Routes::Event { + link: NostrLink::from_note(&self.event), + event: None, + }); } ui.horizontal(|ui| { - ui.add(Avatar::public_key(self.services, &host).size(40.)); - let title = RichText::new(self.event.get_tag_content(TagKind::Title).unwrap_or("Unknown")) + ui.add(Avatar::public_key(self.services.profile, &host).size(40.)); + let title = RichText::new(match self.event.get_tag_value("title") { + Some(s) => s.variant().str().unwrap_or("Unknown"), + None => "Unknown", + }) .size(16.) .color(Color32::WHITE); ui.add(Label::new(title).wrap_mode(TextWrapMode::Truncate)); diff --git a/src/widgets/stream_list.rs b/src/widgets/stream_list.rs index c984b5b..eb401e3 100644 --- a/src/widgets/stream_list.rs +++ b/src/widgets/stream_list.rs @@ -1,16 +1,15 @@ -use crate::services::Services; +use crate::route::RouteServices; use crate::widgets::stream::StreamEvent; use egui::{Frame, Margin, Response, Ui, Widget}; -use egui_extras::Column; -use nostr_sdk::Event; +use nostrdb::Note; pub struct StreamList<'a> { - streams: &'a Vec, - services: &'a Services, + streams: &'a Vec>, + services: &'a RouteServices<'a>, } impl<'a> StreamList<'a> { - pub fn new(streams: &'a Vec, services: &'a Services) -> Self { + pub fn new(streams: &'a Vec>, services: &'a RouteServices) -> Self { Self { streams, services } } } diff --git a/src/widgets/stream_player.rs b/src/widgets/stream_player.rs new file mode 100644 index 0000000..721d6e8 --- /dev/null +++ b/src/widgets/stream_player.rs @@ -0,0 +1,27 @@ +use crate::route::RouteServices; +use crate::widgets::VideoPlaceholder; +use egui::{Response, Ui, Vec2, Widget}; + +pub struct StreamPlayer<'a> { + services: &'a mut RouteServices<'a>, +} + +impl<'a> StreamPlayer<'a> { + pub fn new(services: &'a mut RouteServices<'a>) -> Self { + Self { services } + } +} + +impl<'a> Widget for StreamPlayer<'a> { + fn ui(self, ui: &mut Ui) -> Response { + let w = ui.available_width(); + let h = w / 16. * 9.; + let size = Vec2::new(w, h); + + if let Some(p) = self.services.player.as_mut() { + p.ui(ui, size) + } else { + VideoPlaceholder.ui(ui) + } + } +} \ No newline at end of file diff --git a/src/widgets/video_placeholder.rs b/src/widgets/video_placeholder.rs new file mode 100644 index 0000000..b650b6b --- /dev/null +++ b/src/widgets/video_placeholder.rs @@ -0,0 +1,15 @@ +use egui::{Color32, Rect, Response, Rounding, Sense, Ui, Vec2, Widget}; + +pub struct VideoPlaceholder; + +impl Widget for VideoPlaceholder { + fn ui(self, ui: &mut Ui) -> Response { + let w = ui.available_width(); + let h = (w / 16.0) * 9.0; + let img_size = Vec2::new(w, h); + + let (response, painter) = ui.allocate_painter(img_size, Sense::click()); + painter.rect_filled(Rect::EVERYTHING, Rounding::same(12.), Color32::from_rgb(200, 200, 200)); + response + } +} \ No newline at end of file