From f0135cd4156f5835763b4cfb7abaafbf20bbfc91 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Fri, 17 Jan 2025 09:38:00 +0100 Subject: [PATCH] Inital library manager UI --- Cargo.lock | 1047 ++++++++++++++++++++++++++--------- Cargo.toml | 5 +- data/ui/library_manager.blp | 310 +++++++++-- src/library.rs | 111 +++- src/library_manager.rs | 339 +++++++++--- src/player.rs | 169 +++--- src/player_bar.rs | 10 +- src/window.rs | 23 +- 8 files changed, 1528 insertions(+), 486 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7b2665..6b03e63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -32,6 +32,155 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atomic_refcell" version = "0.1.13" @@ -44,12 +193,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.8.0" @@ -62,21 +205,49 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cairo-rs" version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae50b5510d86cf96ac2370e66d8dc960882f3df179d6a5a1e52bd94a1416c0f7" dependencies = [ - "bitflags 2.8.0", + "bitflags", "cairo-sys-rs", - "glib 0.20.7", + "glib", "libc", ] @@ -86,9 +257,9 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f18b6bb8e43c7eb0f2aac7976afe0c61b6f5fc2ab7bc4c139537ea56c92290df" dependencies = [ - "glib-sys 0.20.7", + "glib-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -100,16 +271,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cfg-expr" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" -dependencies = [ - "smallvec", - "target-lexicon", -] - [[package]] name = "cfg-expr" version = "0.17.2" @@ -126,6 +287,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.39" @@ -140,12 +307,46 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "darling" version = "0.20.10" @@ -167,7 +368,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.96", + "syn", ] [[package]] @@ -178,17 +379,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.96", -] - -[[package]] -name = "dbus" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48b5f0f36f1eebe901b0e6bee369a77ed3396334bf3f09abd46454a576f71819" -dependencies = [ - "libc", - "libdbus-sys", + "syn", ] [[package]] @@ -222,7 +413,7 @@ dependencies = [ "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -242,7 +433,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.96", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", ] [[package]] @@ -253,10 +454,10 @@ checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" dependencies = [ "darling", "either", - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -265,12 +466,76 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "field-offset" version = "0.3.6" @@ -325,6 +590,19 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.31" @@ -333,9 +611,15 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + [[package]] name = "futures-task" version = "0.3.31" @@ -349,8 +633,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -364,7 +651,7 @@ checksum = "b6efc7705f7863d37b12ad6974cbb310d35d054f5108cdc1e69037742f573c4c" dependencies = [ "gdk-pixbuf-sys", "gio", - "glib 0.20.7", + "glib", "libc", ] @@ -375,10 +662,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67f2587c9202bf997476bbba6aaed4f78a11538a2567df002a5f57f5331d0b5c" dependencies = [ "gio-sys", - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -391,7 +678,7 @@ dependencies = [ "gdk-pixbuf", "gdk4-sys", "gio", - "glib 0.20.7", + "glib", "libc", "pango", ] @@ -405,12 +692,22 @@ dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", "gio-sys", - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "libc", "pango-sys", "pkg-config", - "system-deps 7.0.3", + "system-deps", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", ] [[package]] @@ -455,7 +752,7 @@ dependencies = [ "futures-io", "futures-util", "gio-sys", - "glib 0.20.7", + "glib", "libc", "pin-project-lite", "smallvec", @@ -467,31 +764,11 @@ version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8446d9b475730ebef81802c1738d972db42fde1c5a36a627ebc4d665fc87db04" dependencies = [ - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "libc", - "system-deps 7.0.3", - "windows-sys", -] - -[[package]] -name = "glib" -version = "0.15.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" -dependencies = [ - "bitflags 1.3.2", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "glib-macros 0.15.13", - "glib-sys 0.15.10", - "gobject-sys 0.15.10", - "libc", - "once_cell", - "smallvec", - "thiserror 1.0.69", + "system-deps", + "windows-sys 0.59.0", ] [[package]] @@ -500,57 +777,32 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f969edf089188d821a30cde713b6f9eb08b20c63fc2e584aba2892a7984a8cc0" dependencies = [ - "bitflags 2.8.0", + "bitflags", "futures-channel", "futures-core", "futures-executor", "futures-task", "futures-util", "gio-sys", - "glib-macros 0.20.7", - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-macros", + "glib-sys", + "gobject-sys", "libc", "memchr", "smallvec", ] -[[package]] -name = "glib-macros" -version = "0.15.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a" -dependencies = [ - "anyhow", - "heck 0.4.1", - "proc-macro-crate 1.3.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "glib-macros" version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "715601f8f02e71baef9c1f94a657a9a77c192aea6097cf9ae7e5e177cd8cde68" dependencies = [ - "heck 0.5.0", - "proc-macro-crate 3.2.0", + "heck", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.96", -] - -[[package]] -name = "glib-sys" -version = "0.15.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" -dependencies = [ - "libc", - "system-deps 6.2.2", + "syn", ] [[package]] @@ -560,18 +812,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b360ff0f90d71de99095f79c526a5888c9c92fc9ee1b19da06c6f5e75f0c2a53" dependencies = [ "libc", - "system-deps 7.0.3", -] - -[[package]] -name = "gobject-sys" -version = "0.15.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" -dependencies = [ - "glib-sys 0.15.10", - "libc", - "system-deps 6.2.2", + "system-deps", ] [[package]] @@ -580,9 +821,9 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67a56235e971a63bfd75abb13ef70064e1346388723422a68580d8a6fbac6423" dependencies = [ - "glib-sys 0.20.7", + "glib-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -591,7 +832,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f39d3bcd2e24fd9c2874a56f277b72c03e728de9bdc95a8d4ef4c962f10ced98" dependencies = [ - "glib 0.20.7", + "glib", "graphene-sys", "libc", ] @@ -602,10 +843,10 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11a68d39515bf340e879b72cecd4a25c1332557757ada6e8aba8654b4b81d23a" dependencies = [ - "glib-sys 0.20.7", + "glib-sys", "libc", "pkg-config", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -616,7 +857,7 @@ checksum = "32b9188db0a6219e708b6b6e7225718e459def664023dbddb8395ca1486d8102" dependencies = [ "cairo-rs", "gdk4", - "glib 0.20.7", + "glib", "graphene-rs", "gsk4-sys", "libc", @@ -631,12 +872,12 @@ checksum = "bca10fc65d68528a548efa3d8747934adcbe7058b73695c9a7f43a25352fce14" dependencies = [ "cairo-sys-rs", "gdk4-sys", - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "graphene-sys", "libc", "pango-sys", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -649,7 +890,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "glib 0.20.7", + "glib", "gstreamer-sys", "itertools", "libc", @@ -661,7 +902,7 @@ dependencies = [ "paste", "pin-project-lite", "smallvec", - "thiserror 2.0.11", + "thiserror", ] [[package]] @@ -672,7 +913,7 @@ checksum = "d152db7983f98d5950cf64e53805286548063475fb61a5e5450fba4cec05899b" dependencies = [ "atomic_refcell", "cfg-if", - "glib 0.20.7", + "glib", "gstreamer", "gstreamer-base-sys", "libc", @@ -684,11 +925,11 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d47cc2d15f2a3d5eb129e5dacbbeec9600432b706805c15dff57b6aa11b2791c" dependencies = [ - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "gstreamer-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -697,7 +938,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d7a815750a28ac838bfd745d6da07cfd142bb2fa471397cd9992c8b6f235665" dependencies = [ - "glib 0.20.7", + "glib", "gstreamer", "gstreamer-play-sys", "gstreamer-video", @@ -710,12 +951,12 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1f8ef790b8a697c759a9bbbaa7b0c061f529c4581e0cc72839ae753af533591" dependencies = [ - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "gstreamer-sys", "gstreamer-video-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -724,10 +965,10 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16cf1ae0a869aa7066ce3c685b76053b4b4f48f364a5b18c4b1f36ef57469719" dependencies = [ - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -738,13 +979,13 @@ checksum = "8fa41e40319e923236e96f0b691711d1504746ab9c89607d77d22aa84777f33f" dependencies = [ "cfg-if", "futures-channel", - "glib 0.20.7", + "glib", "gstreamer", "gstreamer-base", "gstreamer-video-sys", "libc", "once_cell", - "thiserror 2.0.11", + "thiserror", ] [[package]] @@ -753,12 +994,12 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31dc0f49c117f4867b0f98c712aa55ebf25580151d794be8f9179ec2d877fd14" dependencies = [ - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "gstreamer-base-sys", "gstreamer-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -773,7 +1014,7 @@ dependencies = [ "gdk-pixbuf", "gdk4", "gio", - "glib 0.20.7", + "glib", "graphene-rs", "gsk4", "gtk4-macros", @@ -788,10 +1029,10 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ed1786c4703dd196baf7e103525ce0cf579b3a63a0570fe653b7ee6bac33999" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -804,13 +1045,13 @@ dependencies = [ "gdk-pixbuf-sys", "gdk4-sys", "gio-sys", - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "graphene-sys", "gsk4-sys", "libc", "pango-sys", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -819,18 +1060,24 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "iana-time-zone" version = "0.1.61" @@ -909,7 +1156,7 @@ checksum = "8611ee9fb85e7606c362b513afcaf5b59853f79e4d98caaaf581d99465014247" dependencies = [ "gdk4", "gio", - "glib 0.20.7", + "glib", "gtk4", "libadwaita-sys", "libc", @@ -924,12 +1171,12 @@ checksum = "b099a223560118d4d4fa04b6d23f3ea5b7171fe1d83dfb7e6b45b54cdfc83af9" dependencies = [ "gdk4-sys", "gio-sys", - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "gtk4-sys", "libc", "pango-sys", - "system-deps 7.0.3", + "system-deps", ] [[package]] @@ -938,15 +1185,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "libdbus-sys" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" -dependencies = [ - "pkg-config", -] - [[package]] name = "libsqlite3-sys" version = "0.30.1" @@ -957,6 +1195,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "locale_config" version = "0.3.0" @@ -1022,13 +1266,16 @@ dependencies = [ ] [[package]] -name = "mpris-player" -version = "0.6.3" +name = "mpris-server" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d661d96b263756adec7ca7035a5c03d7a0d11a54619e99f8a2eb108a3d0391d1" +checksum = "058bc2227727af394f34aa51da3e36aeecf2c808f39315d35f754872660750ae" dependencies = [ - "dbus", - "glib 0.15.12", + "async-channel", + "futures-channel", + "serde", + "trait-variant", + "zbus", ] [[package]] @@ -1047,12 +1294,13 @@ dependencies = [ "diesel_migrations", "fragile", "gettext-rs", + "glib", "gstreamer-play", "gtk4", "lazy_static", "libadwaita", "log", - "mpris-player", + "mpris-server", "once_cell", "serde", "serde_json", @@ -1060,6 +1308,19 @@ dependencies = [ "uuid", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1148,6 +1409,16 @@ dependencies = [ "paste", ] +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "overload" version = "0.1.1" @@ -1161,7 +1432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e89bd74250a03a05cec047b43465469102af803be2bf5e5a1088f8b8455e087" dependencies = [ "gio", - "glib 0.20.7", + "glib", "libc", "pango-sys", ] @@ -1172,12 +1443,18 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71787e0019b499a5eda889279e4adb455a4f3fdd6870cd5ab7f4a5aa25df6699" dependencies = [ - "glib-sys 0.20.7", - "gobject-sys 0.20.7", + "glib-sys", + "gobject-sys", "libc", - "system-deps 7.0.3", + "system-deps", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "paste" version = "1.0.15" @@ -1196,12 +1473,38 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1209,13 +1512,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] -name = "proc-macro-crate" -version = "1.3.1" +name = "ppv-lite86" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "zerocopy", ] [[package]] @@ -1224,31 +1526,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.22", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "toml_edit", ] [[package]] @@ -1269,6 +1547,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "regex" version = "1.11.1" @@ -1307,6 +1615,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + [[package]] name = "rustversion" version = "1.0.19" @@ -1342,7 +1663,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1357,6 +1678,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -1366,6 +1698,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -1381,6 +1724,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "slab" version = "0.4.9" @@ -1396,23 +1748,18 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.96" @@ -1424,27 +1771,14 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "system-deps" -version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" -dependencies = [ - "cfg-expr 0.15.8", - "heck 0.5.0", - "pkg-config", - "toml", - "version-compare", -] - [[package]] name = "system-deps" version = "7.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005" dependencies = [ - "cfg-expr 0.17.2", - "heck 0.5.0", + "cfg-expr", + "heck", "pkg-config", "toml", "version-compare", @@ -1463,12 +1797,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc1ee6eef34f12f765cb94725905c6312b6610ab2b0940889cfe58dae7bc3c72" [[package]] -name = "thiserror" -version = "1.0.69" +name = "tempfile" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ - "thiserror-impl 1.0.69", + "cfg-if", + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", ] [[package]] @@ -1477,18 +1816,7 @@ version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.11", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.96", + "thiserror-impl", ] [[package]] @@ -1499,7 +1827,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1552,7 +1880,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -1564,17 +1892,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.22" @@ -1585,7 +1902,29 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.24", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1623,6 +1962,34 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + [[package]] name = "unicode-ident" version = "1.0.14" @@ -1690,7 +2057,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.96", + "syn", "wasm-bindgen-shared", ] @@ -1712,7 +2079,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1757,6 +2124,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -1830,15 +2206,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.24" @@ -1847,3 +2214,133 @@ checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" dependencies = [ "memchr", ] + +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "zbus" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.52.0", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zvariant" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 0e9a13e..f9af588 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,10 +12,11 @@ diesel_migrations = "2.2" fragile = "2" gettext-rs = { version = "0.7", features = ["gettext-system"] } gstreamer-play = "0.23" -gtk = { package = "gtk4", version = "0.9", features = ["v4_12", "blueprint"] } +gtk = { package = "gtk4", version = "0.9", features = ["v4_18", "blueprint"] } +glib = { version = "0.20", features = ["v2_84"] } lazy_static = "1" log = "0.4" -mpris-player = "0.6" +mpris-server = "0.8" once_cell = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/data/ui/library_manager.blp b/data/ui/library_manager.blp index f43c697..00c73e8 100644 --- a/data/ui/library_manager.blp +++ b/data/ui/library_manager.blp @@ -1,7 +1,7 @@ using Gtk 4.0; using Adw 1; -template $MusicusLibraryManager : Adw.NavigationPage { +template $MusicusLibraryManager: Adw.NavigationPage { title: _("Music Library"); tag: "library"; @@ -9,49 +9,287 @@ template $MusicusLibraryManager : Adw.NavigationPage { [top] Adw.HeaderBar {} - Gtk.Box { - orientation: vertical; - spacing: 12; + Gtk.ScrolledWindow { + Adw.Clamp { + Gtk.Box { + orientation: vertical; + margin-bottom: 24; + margin-start: 12; + margin-end: 12; - Gtk.Button { - label: _("Add person"); - clicked => $add_person() swapped; - } + Gtk.Label { + label: _("Overview"); + xalign: 0; + margin-top: 24; - Gtk.Button { - label: _("Add role"); - clicked => $add_role() swapped; - } + styles [ + "heading" + ] + } - Gtk.Button { - label: _("Add instrument"); - clicked => $add_instrument() swapped; - } + Gtk.ListBox { + selection-mode: none; + margin-top: 12; - Gtk.Button { - label: _("Add work"); - clicked => $add_work() swapped; - } + styles [ + "boxed-list-separate" + ] - Gtk.Button { - label: _("Add ensemble"); - clicked => $add_ensemble() swapped; - } + Adw.ActionRow library_path_row { + title: _("Library path"); + activatable: true; + activated => $open_library() swapped; - Gtk.Button { - label: _("Add recording"); - clicked => $add_recording() swapped; - } + styles [ + "property" + ] - Gtk.Button { - label: _("Add album"); - clicked => $add_album() swapped; - } + [suffix] + Gtk.Image { + icon-name: "document-edit-symbolic"; + } + } - Gtk.Button { - label: _("Add medium"); - clicked => $add_medium() swapped; + Adw.ButtonRow { + title: _("Import from archive"); + end-icon-name: "go-next-symbolic"; + activated => $import_archive() swapped; + } + + Adw.ButtonRow { + title: _("Export to archive"); + end-icon-name: "go-next-symbolic"; + activated => $export_archive() swapped; + } + } + + Gtk.Label { + label: _("Contents"); + xalign: 0; + margin-top: 24; + + styles [ + "heading" + ] + } + + Gtk.ListBox { + selection-mode: none; + margin-top: 12; + + styles [ + "boxed-list" + ] + + Adw.ActionRow { + title: _("Persons"); + activatable: true; + activated => $show_persons() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_persons_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Roles"); + activatable: true; + activated => $show_roles() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_roles_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Instruments"); + activatable: true; + activated => $show_instruments() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_instruments_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Works"); + activatable: true; + activated => $show_works() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_works_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Ensembles"); + activatable: true; + activated => $show_ensembles() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_ensembles_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Recordings"); + activatable: true; + activated => $show_recordings() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_recordings_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Tracks"); + activatable: true; + activated => $show_tracks() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_tracks_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Mediums"); + activatable: true; + activated => $show_mediums() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_mediums_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + + Adw.ActionRow { + title: _("Albums"); + activatable: true; + activated => $show_albums() swapped; + + [suffix] + Gtk.Box { + spacing: 6; + + Gtk.Label n_albums_label { + label: "0"; + + styles [ + "numeric" + ] + } + + Gtk.Image { + icon-name: "go-next-symbolic"; + } + } + } + } + } } } } -} \ No newline at end of file +} diff --git a/src/library.rs b/src/library.rs index 3340ab6..17c5252 100644 --- a/src/library.rs +++ b/src/library.rs @@ -1,8 +1,9 @@ -use std::{ - cell::{OnceCell, RefCell}, - path::{Path, PathBuf}, +use crate::{ + db::{self, models::*, schema::*, tables, TranslatedString}, + program::Program, }; +use adw::gtk::{glib, glib::Properties, prelude::*, subclass::prelude::*}; use anyhow::Result; use chrono::prelude::*; use diesel::{ @@ -12,11 +13,10 @@ use diesel::{ sql_types::BigInt, QueryDsl, SqliteConnection, }; -use gtk::{glib, glib::Properties, prelude::*, subclass::prelude::*}; -use crate::{ - db::{self, models::*, schema::*, tables, TranslatedString}, - program::Program, +use std::{ + cell::{OnceCell, RefCell}, + path::{Path, PathBuf}, }; diesel::define_sql_function! { @@ -537,6 +537,15 @@ impl MusicusLibrary { Ok(persons) } + pub fn all_persons(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let persons = persons::table.order(persons::name).load(connection)?; + + Ok(persons) + } + pub fn search_roles(&self, search: &str) -> Result> { let search = format!("%{}%", search); let mut binding = self.imp().connection.borrow_mut(); @@ -551,6 +560,15 @@ impl MusicusLibrary { Ok(roles) } + pub fn all_roles(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let roles = roles::table.order(roles::name).load(connection)?; + + Ok(roles) + } + pub fn search_instruments(&self, search: &str) -> Result> { let search = format!("%{}%", search); let mut binding = self.imp().connection.borrow_mut(); @@ -565,6 +583,17 @@ impl MusicusLibrary { Ok(instruments) } + pub fn all_instruments(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let instruments = instruments::table + .order(instruments::name) + .load(connection)?; + + Ok(instruments) + } + pub fn search_works(&self, composer: &Person, search: &str) -> Result> { let search = format!("%{}%", search); let mut binding = self.imp().connection.borrow_mut(); @@ -588,6 +617,20 @@ impl MusicusLibrary { Ok(works) } + pub fn all_works(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let works = works::table + .order(works::name) + .load::(connection)? + .into_iter() + .map(|w| Work::from_table(w, connection)) + .collect::>>()?; + + Ok(works) + } + pub fn search_ensembles(&self, search: &str) -> Result> { let search = format!("%{}%", search); let mut binding = self.imp().connection.borrow_mut(); @@ -611,6 +654,60 @@ impl MusicusLibrary { Ok(ensembles) } + pub fn all_ensembles(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let ensembles = ensembles::table + .order(ensembles::name) + .load::(connection)? + .into_iter() + .map(|e| Ensemble::from_table(e, connection)) + .collect::>>()?; + + Ok(ensembles) + } + + pub fn all_recordings(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let recordings = recordings::table + .load::(connection)? + .into_iter() + .map(|e| Recording::from_table(e, connection)) + .collect::>>()?; + + Ok(recordings) + } + + pub fn all_tracks(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let tracks = tracks::table + .load::(connection)? + .into_iter() + .map(|e| Track::from_table(e, connection)) + .collect::>>()?; + + Ok(tracks) + } + + pub fn all_mediums(&self) -> Result> { + // TODO + Ok(vec![]) + } + + pub fn all_albums(&self) -> Result> { + let mut binding = self.imp().connection.borrow_mut(); + let connection = &mut *binding.as_mut().unwrap(); + + let albums = albums::table.load::(connection)?; + + Ok(albums) + } + pub fn composer_default_role(&self) -> Result { let mut binding = self.imp().connection.borrow_mut(); let connection = &mut *binding.as_mut().unwrap(); diff --git a/src/library_manager.rs b/src/library_manager.rs index 7b07b21..40e26a1 100644 --- a/src/library_manager.rs +++ b/src/library_manager.rs @@ -1,14 +1,20 @@ -use adw::subclass::prelude::*; -use gtk::glib; -use std::cell::OnceCell; - use crate::{ - editor::{ - ensemble_editor::MusicusEnsembleEditor, instrument_editor::MusicusInstrumentEditor, - person_editor::MusicusPersonEditor, recording_editor::MusicusRecordingEditor, - role_editor::MusicusRoleEditor, work_editor::MusicusWorkEditor, + db::{ + models::{Album, Ensemble, Instrument, Person, Recording, Role, Track, Work}, + tables::Medium, }, library::MusicusLibrary, + window::MusicusWindow, +}; + +use adw::{prelude::*, subclass::prelude::*}; +use gettextrs::gettext; +use gtk::glib; + +use std::{ + cell::{OnceCell, RefCell}, + ffi::OsStr, + path::Path, }; mod imp { @@ -19,6 +25,37 @@ mod imp { pub struct LibraryManager { pub navigation: OnceCell, pub library: OnceCell, + + pub persons: RefCell>, + pub roles: RefCell>, + pub instruments: RefCell>, + pub works: RefCell>, + pub ensembles: RefCell>, + pub recordings: RefCell>, + pub tracks: RefCell>, + pub mediums: RefCell>, + pub albums: RefCell>, + + #[template_child] + pub library_path_row: TemplateChild, + #[template_child] + pub n_persons_label: TemplateChild, + #[template_child] + pub n_roles_label: TemplateChild, + #[template_child] + pub n_instruments_label: TemplateChild, + #[template_child] + pub n_works_label: TemplateChild, + #[template_child] + pub n_ensembles_label: TemplateChild, + #[template_child] + pub n_recordings_label: TemplateChild, + #[template_child] + pub n_tracks_label: TemplateChild, + #[template_child] + pub n_mediums_label: TemplateChild, + #[template_child] + pub n_albums_label: TemplateChild, } #[glib::object_subclass] @@ -39,7 +76,13 @@ mod imp { impl ObjectImpl for LibraryManager {} impl WidgetImpl for LibraryManager {} - impl NavigationPageImpl for LibraryManager {} + + impl NavigationPageImpl for LibraryManager { + fn showing(&self) { + self.parent_showing(); + self.obj().update(); + } + } } glib::wrapper! { @@ -60,99 +103,215 @@ impl LibraryManager { } #[template_callback] - fn add_person(&self, _: >k::Button) { + async fn open_library(&self, _: &adw::ActionRow) { + let dialog = gtk::FileDialog::builder() + .title(gettext("Select music library folder")) + .modal(true) + .build(); + + let root = self.root(); + let window = root + .as_ref() + .and_then(|r| r.downcast_ref::()) + .and_then(|w| w.downcast_ref::()) + .unwrap(); + + match dialog.select_folder_future(Some(window)).await { + Err(err) => { + if !err.matches(gtk::DialogError::Dismissed) { + log::error!("Folder selection failed: {err}"); + } + } + Ok(folder) => window.set_library_folder(&folder), + } + } + + #[template_callback] + fn import_archive(&self, _: &adw::ButtonRow) {} + + #[template_callback] + fn export_archive(&self, _: &adw::ButtonRow) {} + + #[template_callback] + fn show_persons(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_roles(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_instruments(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_works(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_ensembles(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_recordings(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_tracks(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_mediums(&self, _: &adw::ActionRow) {} + + #[template_callback] + fn show_albums(&self, _: &adw::ActionRow) {} + + // TODO: Make this async. + fn update(&self) { + let library = self.imp().library.get().unwrap(); + + if let Some(Some(filename)) = Path::new(&library.folder()).file_name().map(OsStr::to_str) { + self.imp().library_path_row.set_subtitle(filename); + } + + let persons = library.all_persons().unwrap(); self.imp() - .navigation - .get() - .unwrap() - .push(&MusicusPersonEditor::new( - &self.imp().navigation.get().unwrap(), - &self.imp().library.get().unwrap(), - None, - )); - } + .n_persons_label + .set_label(&persons.len().to_string()); + self.imp().persons.replace(persons); - #[template_callback] - fn add_role(&self, _: >k::Button) { + let roles = library.all_roles().unwrap(); + self.imp().n_roles_label.set_label(&roles.len().to_string()); + self.imp().roles.replace(roles); + + let instruments = library.all_instruments().unwrap(); self.imp() - .navigation - .get() - .unwrap() - .push(&MusicusRoleEditor::new( - &self.imp().navigation.get().unwrap(), - &self.imp().library.get().unwrap(), - None, - )); - } + .n_instruments_label + .set_label(&instruments.len().to_string()); + self.imp().instruments.replace(instruments); - #[template_callback] - fn add_instrument(&self, _: >k::Button) { + let works = library.all_works().unwrap(); + self.imp().n_works_label.set_label(&works.len().to_string()); + self.imp().works.replace(works); + + let ensembles = library.all_ensembles().unwrap(); self.imp() - .navigation - .get() - .unwrap() - .push(&MusicusInstrumentEditor::new( - &self.imp().navigation.get().unwrap(), - &self.imp().library.get().unwrap(), - None, - )); - } + .n_ensembles_label + .set_label(&ensembles.len().to_string()); + self.imp().ensembles.replace(ensembles); - #[template_callback] - fn add_work(&self, _: >k::Button) { + let recordings = library.all_recordings().unwrap(); self.imp() - .navigation - .get() - .unwrap() - .push(&MusicusWorkEditor::new( - &self.imp().navigation.get().unwrap(), - &self.imp().library.get().unwrap(), - None, - )); - } + .n_recordings_label + .set_label(&recordings.len().to_string()); + self.imp().recordings.replace(recordings); - #[template_callback] - fn add_ensemble(&self, _: >k::Button) { + let tracks = library.all_tracks().unwrap(); self.imp() - .navigation - .get() - .unwrap() - .push(&MusicusEnsembleEditor::new( - &self.imp().navigation.get().unwrap(), - &self.imp().library.get().unwrap(), - None, - )); - } + .n_tracks_label + .set_label(&tracks.len().to_string()); + self.imp().tracks.replace(tracks); - #[template_callback] - fn add_recording(&self, _: >k::Button) { + let mediums = library.all_mediums().unwrap(); self.imp() - .navigation - .get() - .unwrap() - .push(&MusicusRecordingEditor::new( - &self.imp().navigation.get().unwrap(), - &self.imp().library.get().unwrap(), - None, - )); + .n_mediums_label + .set_label(&mediums.len().to_string()); + self.imp().mediums.replace(mediums); + + let albums = library.all_albums().unwrap(); + self.imp() + .n_albums_label + .set_label(&albums.len().to_string()); + self.imp().albums.replace(albums); } - #[template_callback] - fn add_medium(&self, _: >k::Button) { - todo!("Medium import"); - } + // #[template_callback] + // fn add_person(&self, _: >k::Button) { + // self.imp() + // .navigation + // .get() + // .unwrap() + // .push(&MusicusPersonEditor::new( + // &self.imp().navigation.get().unwrap(), + // &self.imp().library.get().unwrap(), + // None, + // )); + // } - #[template_callback] - fn add_album(&self, _: >k::Button) { - todo!("Album editor"); - // self.imp() - // .navigation - // .get() - // .unwrap() - // .push(&MusicusAlbumEditor::new( - // &self.imp().navigation.get().unwrap(), - // &self.imp().library.get().unwrap(), - // None, - // )); - } + // #[template_callback] + // fn add_role(&self, _: >k::Button) { + // self.imp() + // .navigation + // .get() + // .unwrap() + // .push(&MusicusRoleEditor::new( + // &self.imp().navigation.get().unwrap(), + // &self.imp().library.get().unwrap(), + // None, + // )); + // } + + // #[template_callback] + // fn add_instrument(&self, _: >k::Button) { + // self.imp() + // .navigation + // .get() + // .unwrap() + // .push(&MusicusInstrumentEditor::new( + // &self.imp().navigation.get().unwrap(), + // &self.imp().library.get().unwrap(), + // None, + // )); + // } + + // #[template_callback] + // fn add_work(&self, _: >k::Button) { + // self.imp() + // .navigation + // .get() + // .unwrap() + // .push(&MusicusWorkEditor::new( + // &self.imp().navigation.get().unwrap(), + // &self.imp().library.get().unwrap(), + // None, + // )); + // } + + // #[template_callback] + // fn add_ensemble(&self, _: >k::Button) { + // self.imp() + // .navigation + // .get() + // .unwrap() + // .push(&MusicusEnsembleEditor::new( + // &self.imp().navigation.get().unwrap(), + // &self.imp().library.get().unwrap(), + // None, + // )); + // } + + // #[template_callback] + // fn add_recording(&self, _: >k::Button) { + // self.imp() + // .navigation + // .get() + // .unwrap() + // .push(&MusicusRecordingEditor::new( + // &self.imp().navigation.get().unwrap(), + // &self.imp().library.get().unwrap(), + // None, + // )); + // } + + // #[template_callback] + // fn add_medium(&self, _: >k::Button) { + // todo!("Medium import"); + // } + + // #[template_callback] + // fn add_album(&self, _: >k::Button) { + // todo!("Album editor"); + // // self.imp() + // // .navigation + // // .get() + // // .unwrap() + // // .push(&MusicusAlbumEditor::new( + // // &self.imp().navigation.get().unwrap(), + // // &self.imp().library.get().unwrap(), + // // None, + // // )); + // } } diff --git a/src/player.rs b/src/player.rs index c6e3cfa..ad57d70 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,7 +1,6 @@ use std::{ cell::{Cell, OnceCell, RefCell}, path::PathBuf, - sync::Arc, }; use fragile::Fragile; @@ -12,7 +11,6 @@ use gtk::{ prelude::*, subclass::prelude::*, }; -use mpris_player::{Metadata, MprisPlayer, PlaybackStatus}; use once_cell::sync::Lazy; use crate::{ @@ -48,7 +46,7 @@ mod imp { pub play: OnceCell, pub play_signal_adapter: OnceCell, - pub mpris: OnceCell>, + pub mpris: OnceCell, } impl MusicusPlayer { @@ -75,10 +73,22 @@ mod imp { } let item = item.downcast::().unwrap(); - self.mpris.get().unwrap().set_metadata(Metadata { - artist: Some(vec![item.make_title()]), - title: item.make_subtitle(), - ..Default::default() + + let obj = self.obj().clone(); + let item_clone = item.clone(); + glib::spawn_future_local(async move { + obj.imp() + .mpris + .get() + .unwrap() + .set_metadata( + mpris_server::Metadata::builder() + .artist(vec![item_clone.make_title()]) + .title(item_clone.make_subtitle().unwrap_or_else(String::new)) + .build(), + ) + .await + .unwrap(); }); let uri = glib::filename_to_uri(item.path(), None) @@ -121,56 +131,13 @@ mod imp { fn constructed(&self) { self.parent_constructed(); + let obj = self.obj().clone(); + glib::spawn_future_local(async move { + obj.init_mpris().await; + }); + let play = gstreamer_play::Play::new(None::); - let mpris = MprisPlayer::new( - config::APP_ID.to_owned(), - config::NAME.to_owned(), - config::APP_ID.to_owned(), - ); - - mpris.set_can_raise(true); - mpris.set_can_play(true); - mpris.set_can_pause(true); - mpris.set_can_go_previous(true); - mpris.set_can_go_next(true); - mpris.set_can_seek(false); - mpris.set_can_set_fullscreen(false); - - let obj = self.obj(); - mpris.connect_raise(clone!( - #[weak] - obj, - move || obj.emit_by_name::<()>("raise", &[]) - )); - mpris.connect_play(clone!( - #[weak] - obj, - move || obj.play() - )); - mpris.connect_pause(clone!( - #[weak] - obj, - move || obj.pause() - )); - mpris.connect_play_pause(clone!( - #[weak] - obj, - move || obj.play_pause() - )); - mpris.connect_previous(clone!( - #[weak] - obj, - move || obj.previous() - )); - mpris.connect_next(clone!( - #[weak] - obj, - move || obj.next() - )); - - self.mpris.set(mpris).expect("mpris should not be set"); - let mut config = play.config(); config.set_position_update_interval(250); play.set_config(config).unwrap(); @@ -237,7 +204,11 @@ impl MusicusPlayer { } pub fn play_recording(&self, recording: &Recording) { - let tracks = &self.library().unwrap().tracks_for_recording(&recording.recording_id).unwrap(); + let tracks = &self + .library() + .unwrap() + .tracks_for_recording(&recording.recording_id) + .unwrap(); if tracks.is_empty() { log::warn!("Ignoring recording without tracks being added to the playlist."); @@ -330,20 +301,34 @@ impl MusicusPlayer { let imp = self.imp(); imp.play.get().unwrap().play(); self.set_playing(true); - imp.mpris - .get() - .unwrap() - .set_playback_status(PlaybackStatus::Playing); + + let obj = self.clone(); + glib::spawn_future_local(async move { + obj.imp() + .mpris + .get() + .unwrap() + .set_playback_status(mpris_server::PlaybackStatus::Playing) + .await + .unwrap(); + }); } pub fn pause(&self) { let imp = self.imp(); imp.play.get().unwrap().pause(); self.set_playing(false); - imp.mpris - .get() - .unwrap() - .set_playback_status(PlaybackStatus::Paused); + + let obj = self.clone(); + glib::spawn_future_local(async move { + obj.imp() + .mpris + .get() + .unwrap() + .set_playback_status(mpris_server::PlaybackStatus::Paused) + .await + .unwrap(); + }); } pub fn seek_to(&self, time_ms: u64) { @@ -378,6 +363,62 @@ impl MusicusPlayer { } } + async fn init_mpris(&self) { + let mpris = mpris_server::Player::builder(config::APP_ID) + .desktop_entry(config::APP_ID) + .can_raise(true) + .can_play(true) + .can_pause(true) + .can_go_previous(true) + .can_go_next(true) + .build() + .await + .unwrap(); + + let obj = self.clone(); + + mpris.connect_raise(clone!( + #[weak] + obj, + move |_| obj.emit_by_name::<()>("raise", &[]) + )); + + mpris.connect_play(clone!( + #[weak] + obj, + move |_| obj.play() + )); + + mpris.connect_pause(clone!( + #[weak] + obj, + move |_| obj.pause() + )); + + mpris.connect_play_pause(clone!( + #[weak] + obj, + move |_| obj.play_pause() + )); + + mpris.connect_previous(clone!( + #[weak] + obj, + move |_| obj.previous() + )); + + mpris.connect_next(clone!( + #[weak] + obj, + move |_| obj.next() + )); + + self.imp() + .mpris + .set(mpris) + .expect("mpris should not be set"); + } + fn generate_items(&self, program: &Program) { if let Some(library) = self.library() { // TODO: if program.play_full_recordings() { diff --git a/src/player_bar.rs b/src/player_bar.rs index b3d72fe..00122c7 100644 --- a/src/player_bar.rs +++ b/src/player_bar.rs @@ -6,7 +6,7 @@ use gtk::{ subclass::prelude::*, }; use once_cell::sync::Lazy; -use std::cell::{Cell, RefCell}; +use std::cell::{Cell, OnceCell}; mod imp { use super::*; @@ -16,7 +16,7 @@ mod imp { #[template(file = "data/ui/player_bar.blp")] pub struct PlayerBar { #[property(get, construct_only)] - pub player: RefCell, + pub player: OnceCell, pub seeking: Cell, @@ -42,7 +42,7 @@ mod imp { impl PlayerBar { fn update_item(&self) { - if let Some(item) = self.player.borrow().current_item() { + if let Some(item) = self.player.get().unwrap().current_item() { self.title_label.set_label(&item.make_title()); if let Some(subtitle) = item.make_subtitle() { @@ -55,7 +55,7 @@ mod imp { } fn update_time(&self) { - let player = self.player.borrow(); + let player = self.player.get().unwrap(); let current_time_ms = if self.seeking.get() { (self.slider.value() * player.duration_ms() as f64) as u64 @@ -106,7 +106,7 @@ mod imp { fn constructed(&self) { self.parent_constructed(); - let player = self.player.borrow(); + let player = self.player.get().unwrap(); player .bind_property("playing", &self.play_button.get(), "icon-name") diff --git a/src/window.rs b/src/window.rs index e16b6cf..4aad684 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,14 +1,14 @@ -use std::path::Path; - -use adw::subclass::prelude::*; -use gtk::{gio, glib, glib::clone, prelude::*}; - use crate::{ config, home_page::MusicusHomePage, library::MusicusLibrary, library_manager::LibraryManager, player::MusicusPlayer, player_bar::PlayerBar, playlist_page::MusicusPlaylistPage, welcome_page::MusicusWelcomePage, }; +use adw::subclass::prelude::*; +use gtk::{gio, glib, glib::clone, prelude::*}; + +use std::{cell::RefCell, path::Path}; + mod imp { use super::*; @@ -16,6 +16,7 @@ mod imp { #[template(file = "data/ui/window.blp")] pub struct MusicusWindow { pub player: MusicusPlayer, + pub library_manager: RefCell>, #[template_child] pub stack: TemplateChild, @@ -157,7 +158,7 @@ impl MusicusWindow { } #[template_callback] - fn set_library_folder(&self, folder: &gio::File) { + pub fn set_library_folder(&self, folder: &gio::File) { let path = folder.path().unwrap(); let settings = gio::Settings::new(config::APP_ID); @@ -173,8 +174,16 @@ impl MusicusWindow { self.imp().player.set_library(&library); let navigation = self.imp().navigation_view.get(); + if let Some(library_manager) = self.imp().library_manager.take() { + navigation.remove(&library_manager); + } + + let library_manager = LibraryManager::new(&navigation, &library); + navigation .replace(&[MusicusHomePage::new(&navigation, &library, &self.imp().player).into()]); - navigation.add(&LibraryManager::new(&navigation, &library)); + navigation.add(&library_manager); + + self.imp().library_manager.replace(Some(library_manager)); } }