commit 6b8eae051e61ae18273704d0350baf4e4ccb666d Author: Bnyro Date: Sun Jun 18 16:53:53 2023 +0200 Initial commit diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..3b5ff24 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +rustflags = ["-C", "link-arg=-fuse-ld=mold"] \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a78c7fc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2655 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "actix-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-http" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash 0.8.3", + "base64", + "bitflags", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1", + "smallvec", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "actix-router" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +dependencies = [ + "bytestring", + "http", + "regex", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" +dependencies = [ + "actix-macros", + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "num_cpus", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" +dependencies = [ + "actix-codec", + "actix-http", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "ahash 0.7.6", + "bytes", + "bytestring", + "cfg-if", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time", + "url", +] + +[[package]] +name = "actix-ws" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535aec173810be3ca6f25dd5b4d431ae7125d62000aa3cbae1ec739921b02cf3" +dependencies = [ + "actix-codec", + "actix-http", + "actix-web", + "futures-core", + "tokio", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "background-jobs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793a813f9145c5f3a27b8dcd834c0927de68bbd60d53a369e5894f3cc5759020" +dependencies = [ + "background-jobs-actix", + "background-jobs-core", +] + +[[package]] +name = "background-jobs-actix" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47263ad9c5679419347dae655c2fa2cba078b0eaa51ac758d4f0e9690c06910b" +dependencies = [ + "actix-rt", + "anyhow", + "async-mutex", + "async-trait", + "background-jobs-core", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "uuid", +] + +[[package]] +name = "background-jobs-core" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e78e842fe2ae461319e3d1843c12e301630e65650332b02032ac70b0dfc66f" +dependencies = [ + "actix-rt", + "anyhow", + "async-trait", + "event-listener", + "serde", + "serde_json", + "thiserror", + "time", + "tracing", + "tracing-futures", + "uuid", +] + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[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 = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "bytestring" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +dependencies = [ + "bytes", +] + +[[package]] +name = "cairo-rs" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-expr" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70d3ad08698a0568b0562f22710fe6bfc1f4a61a367c77d0398c562eadd453a" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "num-traits", + "serde", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[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 = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[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]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "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]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gio" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d80aa6ea7bba0baac79222204aa786a6293078c210abe69ef1336911d4bdc4f0" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9" +dependencies = [ + "glib", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b" +dependencies = [ + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "once_cell", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f" +dependencies = [ + "anyhow", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "gtk4-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "h2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lemmy-gtk" +version = "0.1.0" +dependencies = [ + "lemmy_api_common", + "relm4", + "relm4-components", + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "lemmy_api_common" +version = "0.17.2" +source = "git+https://github.com/LemmyNet/lemmy.git?tag=0.17.2#a24a4b3ddc7ac5af241d435a39abd9aac82591e0" +dependencies = [ + "actix-ws", + "anyhow", + "background-jobs", + "futures", + "lemmy_db_schema", + "lemmy_db_views", + "lemmy_db_views_actor", + "lemmy_db_views_moderator", + "opentelemetry", + "rand", + "regex", + "serde", + "serde_json", + "strum", + "strum_macros", + "tokio", + "tracing-opentelemetry", + "url", +] + +[[package]] +name = "lemmy_db_schema" +version = "0.17.2" +source = "git+https://github.com/LemmyNet/lemmy.git?tag=0.17.2#a24a4b3ddc7ac5af241d435a39abd9aac82591e0" +dependencies = [ + "async-trait", + "chrono", + "serde", + "strum", + "strum_macros", + "tokio", + "tracing", + "tracing-error", + "typed-builder", + "url", +] + +[[package]] +name = "lemmy_db_views" +version = "0.17.2" +source = "git+https://github.com/LemmyNet/lemmy.git?tag=0.17.2#a24a4b3ddc7ac5af241d435a39abd9aac82591e0" +dependencies = [ + "lemmy_db_schema", + "serde", + "typed-builder", + "url", +] + +[[package]] +name = "lemmy_db_views_actor" +version = "0.17.2" +source = "git+https://github.com/LemmyNet/lemmy.git?tag=0.17.2#a24a4b3ddc7ac5af241d435a39abd9aac82591e0" +dependencies = [ + "lemmy_db_schema", + "serde", + "typed-builder", +] + +[[package]] +name = "lemmy_db_views_moderator" +version = "0.17.2" +source = "git+https://github.com/LemmyNet/lemmy.git?tag=0.17.2#a24a4b3ddc7ac5af241d435a39abd9aac82591e0" +dependencies = [ + "lemmy_db_schema", + "serde", +] + +[[package]] +name = "libadwaita" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" +dependencies = [ + "bitflags", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "gtk4", + "libadwaita-sys", + "libc", + "pango", +] + +[[package]] +name = "libadwaita-sys" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404" +dependencies = [ + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "libc" +version = "0.2.146" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "local-channel" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6105e89802af13fdf48c49d7646d3b533a70e536d818aae7e78ba0433d01acb8" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "js-sys", + "lazy_static", + "percent-encoding", + "pin-project", + "rand", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "pango" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48" +dependencies = [ + "bitflags", + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[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", +] + +[[package]] +name = "proc-macro2" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +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 = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" + +[[package]] +name = "relm4" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c80ef6bb7a142b6aaa01b96961c33127fffcda4741eb0ad82f07e18c9186681d" +dependencies = [ + "async-trait", + "flume", + "fragile", + "futures", + "gtk4", + "libadwaita", + "once_cell", + "relm4-macros", + "tokio", + "tracing", +] + +[[package]] +name = "relm4-components" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a7265580b2a185254b9f129bff5fdca11a00730a6e075628c93502a4eced81" +dependencies = [ + "once_cell", + "relm4", + "reqwest", + "tracker", +] + +[[package]] +name = "relm4-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a6e1b4954b7aa8155d4a234516d46ed543a614666adc1ea73a922bc841e2a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "security-framework" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] +name = "serde" +version = "1.0.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "serde_json" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5fa6fb9ee296c0dc2df41a656ca7948546d061958115ddb0bcaae43ad0d17d2" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" + +[[package]] +name = "tempfile" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +dependencies = [ + "autocfg", + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "tracker" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff9636d15e370187f6bf55b79ce62ebf4221998bc0ba1774d7fa208b007f6bf8" +dependencies = [ + "tracker-macros", +] + +[[package]] +name = "tracker-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca029746fbe0efda3298205de77bf759d7fef23ac97902641e0b49a623b0455f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "uuid" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "valuable" +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_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 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", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b1162c0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "lemmy-gtk" +version = "0.1.0" +edition = "2021" + +[dependencies] +relm4 = "0.6.0" +relm4-components = { version = "0.6.0", features = ["web"] } +reqwest = { version = "0.11.16", features = ["json", "blocking"] } +serde = { version = "1.0.160", features = ["derive"] } +serde_json = "1.0.96" +lemmy_api_common = { git = "https://github.com/LemmyNet/lemmy.git", tag = "0.17.2" } \ No newline at end of file diff --git a/src/api/communities.rs b/src/api/communities.rs new file mode 100644 index 0000000..6560f32 --- /dev/null +++ b/src/api/communities.rs @@ -0,0 +1,20 @@ +use lemmy_api_common::{community::{ListCommunities, ListCommunitiesResponse}, lemmy_db_schema::{SortType, SearchType}, lemmy_db_views_actor::structs::CommunityView}; + +use crate::components::CLIENT; + +use super::search; + +pub fn fetch_communities(page: i64, query: Option) -> std::result::Result, reqwest::Error> { + if query.is_none() || query.clone().unwrap().trim().is_empty() { + let params = ListCommunities { + sort: Some(SortType::TopMonth), + page: Some(page), + ..Default::default() + }; + + let url = format!("{}/community/list", super::get_api_url()); + Ok(CLIENT.get(&url).query(¶ms).send()?.json::()?.communities) + } else { + Ok(search::fetch_search(page, query.unwrap(), Some(SearchType::Communities))?.communities) + } +} diff --git a/src/api/community.rs b/src/api/community.rs new file mode 100644 index 0000000..5d3ef7c --- /dev/null +++ b/src/api/community.rs @@ -0,0 +1,17 @@ +use lemmy_api_common::community::{GetCommunity, GetCommunityResponse}; + +use crate::components::CLIENT; + +pub fn get_community(name: String) -> std::result::Result { + let params = GetCommunity { + name: Some(name), + ..Default::default() + }; + + let url = format!("{}/community", super::get_api_url()); + CLIENT.get(&url).query(¶ms).send()?.json() +} + +pub fn default_community() -> GetCommunityResponse { + serde_json::from_str(include_str!("../examples/community.json")).unwrap() +} diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..48b6632 --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,14 @@ +use crate::settings::get_prefs; + +pub mod communities; +pub mod community; +pub mod post; +pub mod posts; +pub mod search; +pub mod user; + +static API_VERSION: &str = "v3"; + +pub fn get_api_url() -> String { + format!("{}/api/{}", get_prefs().instance_url, API_VERSION).to_string() +} diff --git a/src/api/post.rs b/src/api/post.rs new file mode 100644 index 0000000..c5043e9 --- /dev/null +++ b/src/api/post.rs @@ -0,0 +1,34 @@ +use lemmy_api_common::{post::{GetPost, GetPostResponse}, lemmy_db_schema::{newtypes::PostId, CommentSortType, ListingType}, comment::{GetComments, GetCommentsResponse}, lemmy_db_views::structs::CommentView}; + +use crate::components::CLIENT; + +pub fn get_post(id: PostId) -> std::result::Result { + let params = GetPost { + id: Some(id), + ..Default::default() + }; + + let url = format!("{}/post", super::get_api_url()); + CLIENT.get(&url).query(¶ms).send()?.json() +} + +pub fn get_comments(post_id: PostId) -> std::result::Result, reqwest::Error> { + let params = GetComments { + post_id: Some(post_id), + sort: Some(CommentSortType::Hot), + type_: Some(ListingType::All), + ..Default::default() + }; + + let url = format!("{}/comment/list", super::get_api_url()); + let mut comments = CLIENT.get(&url).query(¶ms).send()?.json::()?.comments; + + // hide removed comments + comments.retain(|c| !c.comment.deleted && !c.comment.removed); + + Ok(comments) +} + +pub fn default_post() -> GetPostResponse { + serde_json::from_str(include_str!("../examples/post.json")).unwrap() +} diff --git a/src/api/posts.rs b/src/api/posts.rs new file mode 100644 index 0000000..b6225a3 --- /dev/null +++ b/src/api/posts.rs @@ -0,0 +1,14 @@ +use lemmy_api_common::{post::{GetPostsResponse, GetPosts}, lemmy_db_views::structs::PostView}; + +use crate::components::CLIENT; + +pub fn list_posts(page: i64, community_name: Option) -> std::result::Result, reqwest::Error> { + let params = GetPosts { + page: Some(page), + community_name, + ..Default::default() + }; + + let url = format!("{}/post/list", super::get_api_url()); + Ok(CLIENT.get(&url).query(¶ms).send()?.json::()?.posts) +} diff --git a/src/api/search.rs b/src/api/search.rs new file mode 100644 index 0000000..c5a6e69 --- /dev/null +++ b/src/api/search.rs @@ -0,0 +1,16 @@ +use lemmy_api_common::{site::{SearchResponse, Search}, lemmy_db_schema::{SortType, SearchType}}; + +use crate::components::CLIENT; + +pub fn fetch_search(page: i64, query: String, search_type: Option) -> std::result::Result { + let params = Search { + q: query, + sort: Some(SortType::TopMonth), + page: Some(page), + type_: search_type, + ..Default::default() + }; + + let url = format!("{}/search", super::get_api_url()); + CLIENT.get(&url).query(¶ms).send()?.json() +} \ No newline at end of file diff --git a/src/api/user.rs b/src/api/user.rs new file mode 100644 index 0000000..1eb0a32 --- /dev/null +++ b/src/api/user.rs @@ -0,0 +1,17 @@ +use lemmy_api_common::{person::{GetPersonDetailsResponse, GetPersonDetails}}; +use crate::components::CLIENT; + +pub fn get_user(username: String, page: i64) -> std::result::Result { + let params = GetPersonDetails { + page: Some(page), + username: Some(username), + ..Default::default() + }; + + let url = format!("{}/user", super::get_api_url()); + CLIENT.get(&url).query(¶ms).send()?.json() +} + +pub fn default_person() -> GetPersonDetailsResponse { + serde_json::from_str(include_str!("../examples/person.json")).unwrap() +} \ No newline at end of file diff --git a/src/components/comment_row.rs b/src/components/comment_row.rs new file mode 100644 index 0000000..8bd16d7 --- /dev/null +++ b/src/components/comment_row.rs @@ -0,0 +1,101 @@ +use lemmy_api_common::lemmy_db_views::structs::CommentView; +use relm4::prelude::*; +use gtk::prelude::*; +use relm4_components::web_image::WebImage; + +use crate::util::get_web_image_url; + +#[derive(Debug)] +pub struct CommentRow { + comment: CommentView, + avatar: Controller +} + +#[derive(Debug)] +pub enum CommentRowMsg { + OpenPerson, +} + +#[relm4::factory(pub)] +impl FactoryComponent for CommentRow { + type Init = CommentView; + type Input = CommentRowMsg; + type Output = crate::AppMsg; + type CommandOutput = (); + type Widgets = PostViewWidgets; + type ParentInput = crate::AppMsg; + type ParentWidget = gtk::Box; + + view! { + root = gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 10, + set_margin_end: 10, + set_margin_start: 10, + set_margin_top: 10, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + set_vexpand: false, + + if self.comment.creator.avatar.is_some() { + gtk::Box { + set_hexpand: false, + #[local_ref] + community_image -> gtk::Box {} + } + } else { + gtk::Box {} + }, + + gtk::Button { + set_label: &self.comment.creator.name, + connect_clicked => CommentRowMsg::OpenPerson, + }, + }, + + gtk::Label { + set_label: &self.comment.comment.content, + set_halign: gtk::Align::Start, + }, + + gtk::Label { + set_label: &format!("{} score", self.comment.counts.score), + set_halign: gtk::Align::Start, + }, + + gtk::Separator {} + } + } + + fn forward_to_parent(output: Self::Output) -> Option { + Some(output) + } + + fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { + let avatar = WebImage::builder().launch(get_web_image_url(value.community.clone().icon)).detach(); + + Self { comment: value, avatar } + } + + fn init_widgets( + &mut self, + _index: &Self::Index, + root: &Self::Root, + _returned_widget: &::ReturnedWidget, + sender: FactorySender, + ) -> Self::Widgets { + let community_image = self.avatar.widget(); + let widgets = view_output!(); + widgets + } + + fn update(&mut self, message: Self::Input, sender: FactorySender) { + match message { + CommentRowMsg::OpenPerson => { + sender.output(crate::AppMsg::OpenPerson(self.comment.creator.name.clone())) + } + } + } +} \ No newline at end of file diff --git a/src/components/community_page.rs b/src/components/community_page.rs new file mode 100644 index 0000000..f1ae2bd --- /dev/null +++ b/src/components/community_page.rs @@ -0,0 +1,123 @@ +use lemmy_api_common::{community::GetCommunityResponse, lemmy_db_views::structs::PostView}; +use relm4::{prelude::*, factory::FactoryVecDeque}; +use gtk::prelude::*; +use relm4_components::web_image::WebImage; +use std::cell::RefCell; + +use crate::{api, util::get_web_image_msg}; + +use super::post_row::PostRow; + +pub struct CommunityPage { + info: RefCell, + avatar: Controller, + posts: FactoryVecDeque +} + +#[derive(Debug)] +pub enum CommunityInput { + UpdateCommunity(GetCommunityResponse), + DoneFetchPosts(Vec) +} + +#[relm4::component(pub)] +impl SimpleComponent for CommunityPage { + type Init = GetCommunityResponse; + type Input = CommunityInput; + type Output = crate::AppMsg; + + view! { + gtk::ScrolledWindow { + set_vexpand: false, + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_vexpand: false, + set_margin_all: 10, + + #[local_ref] + avatar -> gtk::Box { + set_size_request: (100, 100), + set_margin_bottom: 20, + set_margin_top: 20, + }, + gtk::Label { + #[watch] + set_text: &model.info.borrow().community_view.community.name, + add_css_class: "font-very-bold", + }, + gtk::Label { + #[watch] + set_text: &model.info.borrow().clone().community_view.community.description.unwrap_or("".to_string()), + }, + gtk::Label { + #[watch] + set_text: &format!("{} subscribers, ", model.info.borrow().community_view.counts.subscribers), + }, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_margin_top: 10, + set_margin_bottom: 10, + set_hexpand: false, + set_halign: gtk::Align::Center, + + gtk::Label { + #[watch] + set_text: &format!("{} posts, ", model.info.borrow().community_view.counts.posts), + }, + gtk::Label { + #[watch] + set_text: &format!("{} comments", model.info.borrow().clone().community_view.counts.comments), + }, + }, + + gtk::Separator {}, + + #[local_ref] + posts -> gtk::Box { + set_orientation: gtk::Orientation::Vertical, + } + } + + } + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: relm4::ComponentSender, + ) -> relm4::ComponentParts { + let avatar = WebImage::builder().launch("".to_string()).detach(); + let posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); + let model = CommunityPage { info: RefCell::new(init), avatar, posts }; + let avatar = model.avatar.widget(); + let posts = model.posts.widget(); + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, sender: ComponentSender) { + match message { + CommunityInput::UpdateCommunity(community) => { + *self.info.borrow_mut() = community.clone(); + self.avatar.emit(get_web_image_msg(community.community_view.community.icon)); + self.posts.guard().clear(); + + std::thread::spawn(move || { + if community.community_view.counts.posts == 0 { return; } + let community_posts = api::posts::list_posts(1, Some(community.community_view.community.name)); + if let Ok(community_posts) = community_posts { + sender.input(CommunityInput::DoneFetchPosts(community_posts)); + } + }); + } + CommunityInput::DoneFetchPosts(posts) => { + for post in posts { + self.posts.guard().push_back(post); + } + } + } + } +} diff --git a/src/components/community_row.rs b/src/components/community_row.rs new file mode 100644 index 0000000..5d6171d --- /dev/null +++ b/src/components/community_row.rs @@ -0,0 +1,102 @@ +use lemmy_api_common::lemmy_db_views_actor::structs::CommunityView; +use relm4::prelude::*; +use gtk::prelude::*; +use relm4_components::web_image::WebImage; + +use crate::util::get_web_image_url; + +#[derive(Debug)] +pub struct CommunityRow { + community: CommunityView, + community_image: Controller, +} + +#[derive(Debug)] +pub enum CommunityRowMsg { + OpenCommunity, +} + +#[relm4::factory(pub)] +impl FactoryComponent for CommunityRow { + type Init = CommunityView; + type Input = CommunityRowMsg; + type Output = crate::AppMsg; + type CommandOutput = (); + type Widgets = PostViewWidgets; + type ParentInput = crate::AppMsg; + type ParentWidget = gtk::Box; + + view! { + root = gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 10, + set_margin_end: 10, + set_margin_start: 10, + set_vexpand: false, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + + if self.community.community.icon.is_some() { + gtk::Box { + set_hexpand: false, + #[local_ref] + community_image -> gtk::Box {} + } + } else { + gtk::Box {} + }, + + gtk::Label { + set_label: &self.community.community.title, + }, + + gtk::Box { + set_hexpand: true, + }, + + gtk::Label { + set_label: &format!("{} subscribers, {} posts", self.community.counts.subscribers, self.community.counts.posts), + }, + + gtk::Button { + set_label: "View", + connect_clicked => CommunityRowMsg::OpenCommunity, + }, + }, + + gtk::Separator {} + } + } + + fn forward_to_parent(output: Self::Output) -> Option { + Some(output) + } + + fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { + let community_image= WebImage::builder().launch(get_web_image_url(value.community.clone().icon)).detach(); + + Self { community: value, community_image } + } + + fn init_widgets( + &mut self, + _index: &Self::Index, + root: &Self::Root, + _returned_widget: &::ReturnedWidget, + sender: FactorySender, + ) -> Self::Widgets { + let community_image = self.community_image.widget(); + let widgets = view_output!(); + widgets + } + + fn update(&mut self, message: Self::Input, sender: FactorySender) { + match message { + CommunityRowMsg::OpenCommunity => { + sender.output(crate::AppMsg::OpenCommunity(self.community.community.name.clone())) + } + } + } +} \ No newline at end of file diff --git a/src/components/mod.rs b/src/components/mod.rs new file mode 100644 index 0000000..78238b4 --- /dev/null +++ b/src/components/mod.rs @@ -0,0 +1,13 @@ +pub mod post_row; +pub mod community_row; +pub mod profile_page; +pub mod community_page; +pub mod post_page; +pub mod comment_row; + +use reqwest::blocking::Client; +use relm4::once_cell::sync::Lazy; + +pub static CLIENT: Lazy = Lazy::new(|| { + Client::new() +}); \ No newline at end of file diff --git a/src/components/post_page.rs b/src/components/post_page.rs new file mode 100644 index 0000000..bf102f6 --- /dev/null +++ b/src/components/post_page.rs @@ -0,0 +1,204 @@ +use lemmy_api_common::{lemmy_db_views::structs::{CommentView}, post::GetPostResponse}; +use relm4::{prelude::*, factory::FactoryVecDeque}; +use gtk::prelude::*; +use relm4_components::web_image::WebImage; +use std::cell::RefCell; + +use crate::{api, util::{get_web_image_msg, get_web_image_url}}; + +use super::comment_row::CommentRow; + +pub struct PostPage { + info: RefCell, + image: Controller, + creator_avatar: Controller, + community_avatar: Controller, + comments: FactoryVecDeque +} + +#[derive(Debug)] +pub enum PostInput { + UpdatePost(GetPostResponse), + DoneFetchComments(Vec), + OpenPerson, + OpenCommunity, + OpenLink +} + +#[relm4::component(pub)] +impl SimpleComponent for PostPage { + type Init = GetPostResponse; + type Input = PostInput; + type Output = crate::AppMsg; + + view! { + gtk::ScrolledWindow { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_vexpand: false, + set_margin_all: 10, + + #[local_ref] + image -> gtk::Box { + set_height_request: 100, + set_margin_bottom: 20, + set_margin_top: 20, + }, + gtk::Label { + #[watch] + set_text: &model.info.borrow().post_view.post.name, + add_css_class: "font-very-bold", + }, + gtk::Label { + #[watch] + set_text: &model.info.borrow().clone().post_view.post.body.unwrap_or("".to_string()), + set_margin_top: 10, + }, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_margin_top: 10, + set_spacing: 10, + set_vexpand: false, + + gtk::Label { + set_text: "posted by " + }, + + if model.info.borrow().post_view.creator.avatar.is_some() { + gtk::Box { + set_hexpand: false, + set_margin_start: 10, + #[local_ref] + creator_avatar -> gtk::Box {} + } + } else { + gtk::Box {} + }, + + gtk::Button { + set_label: &model.info.borrow().post_view.creator.name, + connect_clicked => PostInput::OpenPerson, + }, + + gtk::Label { + set_text: " in " + }, + + if model.info.borrow().community_view.community.icon.is_some() { + gtk::Box { + set_hexpand: false, + #[local_ref] + community_avatar -> gtk::Box {} + } + } else { + gtk::Box {} + }, + + gtk::Button { + set_label: &model.info.borrow().community_view.community.title, + connect_clicked => PostInput::OpenCommunity, + }, + + gtk::Box { + set_hexpand: true, + }, + + gtk::Button { + set_label: "View", + connect_clicked => PostInput::OpenLink, + } + }, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_margin_top: 10, + set_margin_bottom: 10, + + gtk::Label { + #[watch] + set_text: &format!("{} comments, ", model.info.borrow().post_view.counts.comments), + }, + gtk::Label { + #[watch] + set_text: &format!("{} score", model.info.borrow().post_view.counts.score), + }, + }, + + gtk::Separator {}, + + #[local_ref] + comments -> gtk::Box { + set_orientation: gtk::Orientation::Vertical, + } + } + } + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: relm4::ComponentSender, + ) -> relm4::ComponentParts { + let image = WebImage::builder().launch("".to_string()).detach(); + let comments = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); + let creator_avatar = WebImage::builder().launch("".to_string()).detach(); + let community_avatar = WebImage::builder().launch("".to_string()).detach(); + let model = PostPage { info: RefCell::new(init), image, comments, creator_avatar, community_avatar }; + + let image = model.image.widget(); + let comments = model.comments.widget(); + let creator_avatar = model.creator_avatar.widget(); + let community_avatar = model.community_avatar.widget(); + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, sender: ComponentSender) { + match message { + PostInput::UpdatePost(post) => { + *self.info.borrow_mut() = post.clone(); + + self.image.emit(get_web_image_msg(post.post_view.post.thumbnail_url)); + self.community_avatar.emit(get_web_image_msg(post.community_view.community.icon)); + self.creator_avatar.emit(get_web_image_msg(post.post_view.creator.avatar)); + + self.comments.guard().clear(); + + std::thread::spawn(move || { + if post.post_view.counts.comments == 0 { return; } + let comments = api::post::get_comments(post.post_view.post.id); + if let Ok(comments) = comments { + sender.input(PostInput::DoneFetchComments(comments)); + } + }); + } + PostInput::DoneFetchComments(comments) => { + for comment in comments { + self.comments.guard().push_back(comment); + } + } + PostInput::OpenPerson => { + let name = self.info.borrow().post_view.creator.name.clone(); + let _ = sender.output(crate::AppMsg::OpenPerson(name)); + } + PostInput::OpenCommunity => { + let community_name = self.info.borrow().community_view.community.name.clone(); + let _ = sender.output(crate::AppMsg::OpenCommunity(community_name)); + } + PostInput::OpenLink => { + let post = self.info.borrow().post_view.post.clone(); + let mut link = get_web_image_url(post.url); + if link.is_empty() { + link = get_web_image_url(post.thumbnail_url); + } + if link.is_empty() { + link = get_web_image_url(post.embed_video_url); + } + if link.is_empty() { return; } + gtk::show_uri(None::<&relm4::gtk::Window>, &link, 0); + } + } + } +} diff --git a/src/components/post_row.rs b/src/components/post_row.rs new file mode 100644 index 0000000..495b1ab --- /dev/null +++ b/src/components/post_row.rs @@ -0,0 +1,140 @@ +use lemmy_api_common::lemmy_db_views::structs::PostView; +use relm4::prelude::*; +use gtk::prelude::*; +use relm4_components::web_image::WebImage; + +use crate::util::get_web_image_url; + +#[derive(Debug)] +pub struct PostRow { + post: PostView, + author_image: Controller, + community_image: Controller, +} + +#[derive(Debug)] +pub enum PostViewMsg { + OpenPost, + OpenCommunity, + OpenPerson +} + +#[relm4::factory(pub)] +impl FactoryComponent for PostRow { + type Init = PostView; + type Input = PostViewMsg; + type Output = crate::AppMsg; + type CommandOutput = (); + type Widgets = PostViewWidgets; + type ParentInput = crate::AppMsg; + type ParentWidget = gtk::Box; + + view! { + root = gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 10, + set_margin_end: 10, + set_margin_start: 10, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_margin_top: 10, + set_spacing: 10, + set_vexpand: false, + set_hexpand: true, + + if self.post.community.icon.clone().is_some() { + gtk::Box { + set_hexpand: false, + #[local_ref] + community_image -> gtk::Box {} + } + } else { + gtk::Box {} + }, + + gtk::Button { + set_label: &self.post.community.title, + connect_clicked => PostViewMsg::OpenCommunity, + }, + + if self.post.creator.avatar.clone().is_some() { + gtk::Box { + set_hexpand: false, + set_margin_start: 10, + #[local_ref] + author_image -> gtk::Box {} + } + } else { + gtk::Box {} + }, + + gtk::Button { + set_label: &self.post.creator.name, + connect_clicked => PostViewMsg::OpenPerson, + }, + + gtk::Box { + set_hexpand: true, + }, + + gtk::Button { + set_label: "View", + set_margin_end: 10, + connect_clicked => PostViewMsg::OpenPost, + } + }, + + gtk::Label { + set_halign: gtk::Align::Start, + set_text: &self.post.post.name, + add_css_class: "font-bold", + }, + + gtk::Label { + set_halign: gtk::Align::Start, + set_text: &format!("{} score, {} comments", self.post.counts.score, self.post.clone().counts.comments), + }, + + gtk::Separator { + set_margin_top: 10, + } + } + } + + fn forward_to_parent(output: Self::Output) -> Option { Some(output) } + + fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { + let author_image= WebImage::builder().launch(get_web_image_url(value.creator.clone().avatar)).detach(); + let community_image= WebImage::builder().launch(get_web_image_url(value.creator.clone().avatar)).detach(); + + Self { post: value, author_image, community_image } + } + + fn init_widgets( + &mut self, + _index: &Self::Index, + root: &Self::Root, + _returned_widget: &::ReturnedWidget, + sender: FactorySender, + ) -> Self::Widgets { + let author_image = self.author_image.widget(); + let community_image = self.community_image.widget(); + let widgets = view_output!(); + widgets + } + + fn update(&mut self, message: Self::Input, sender: FactorySender) { + match message { + PostViewMsg::OpenCommunity => { + sender.output(crate::AppMsg::OpenCommunity(self.post.community.name.clone())) + } + PostViewMsg::OpenPerson => { + sender.output(crate::AppMsg::OpenPerson(self.post.creator.name.clone())) + } + PostViewMsg::OpenPost => { + sender.output(crate::AppMsg::OpenPost(self.post.post.id.clone())) + } + } + } +} \ No newline at end of file diff --git a/src/components/profile_page.rs b/src/components/profile_page.rs new file mode 100644 index 0000000..ab3cf82 --- /dev/null +++ b/src/components/profile_page.rs @@ -0,0 +1,106 @@ +use lemmy_api_common::person::GetPersonDetailsResponse; +use relm4::{prelude::*, factory::FactoryVecDeque}; +use gtk::prelude::*; +use relm4_components::web_image::WebImage; +use std::cell::RefCell; + +use crate::util::get_web_image_msg; + +use super::post_row::PostRow; + +pub struct ProfilePage { + info: RefCell, + avatar: Controller, + posts: FactoryVecDeque +} + +#[derive(Debug)] +pub enum ProfileInput { + UpdatePerson(GetPersonDetailsResponse), +} + +#[relm4::component(pub)] +impl SimpleComponent for ProfilePage { + type Init = GetPersonDetailsResponse; + type Input = ProfileInput; + type Output = crate::AppMsg; + + view! { + gtk::ScrolledWindow { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_vexpand: false, + set_margin_all: 10, + + #[local_ref] + avatar -> gtk::Box { + set_size_request: (100, 100), + set_margin_bottom: 20, + set_margin_top: 20, + }, + gtk::Label { + #[watch] + set_text: &model.info.borrow().person_view.person.name, + add_css_class: "font-very-bold", + }, + gtk::Label { + #[watch] + set_text: &model.info.borrow().clone().person_view.person.bio.unwrap_or("".to_string()), + }, + + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_margin_top: 10, + set_margin_bottom: 10, + set_hexpand: false, + set_halign: gtk::Align::Center, + + gtk::Label { + #[watch] + set_text: &format!("{} posts, ", model.info.borrow().person_view.counts.post_count), + }, + gtk::Label { + #[watch] + set_text: &format!("{} comments", model.info.borrow().person_view.counts.comment_count), + }, + }, + + gtk::Separator {}, + + #[local_ref] + posts -> gtk::Box { + set_orientation: gtk::Orientation::Vertical, + } + } + + } + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: relm4::ComponentSender, + ) -> relm4::ComponentParts { + let avatar = WebImage::builder().launch("".to_string()).detach(); + let posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); + let model = ProfilePage { info: RefCell::new(init), avatar, posts }; + let avatar = model.avatar.widget(); + let posts = model.posts.widget(); + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, message: Self::Input, _sender: ComponentSender) { + match message { + ProfileInput::UpdatePerson(person) => { + *self.info.borrow_mut() = person.clone(); + self.avatar.emit(get_web_image_msg(person.person_view.person.avatar)); + self.posts.guard().clear(); + for post in person.posts { + self.posts.guard().push_back(post); + } + } + } + } +} diff --git a/src/examples/community.json b/src/examples/community.json new file mode 100644 index 0000000..ece5bd2 --- /dev/null +++ b/src/examples/community.json @@ -0,0 +1 @@ +{"community_view":{"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"subscribed":"NotSubscribed","blocked":false,"counts":{"id":424,"community_id":8,"subscribers":15968,"posts":1667,"comments":29264,"published":"2019-04-25T04:58:33.886275","users_active_day":746,"users_active_week":4261,"users_active_month":5278,"users_active_half_year":5503,"hot_rank":0}},"site":null,"moderators":[{"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":32603,"name":"mekhos","display_name":"mekhos","avatar":"https://lemmy.ml/pictrs/image/d2b98e44-3728-44a8-8b10-96d771a0f159.png","banned":false,"published":"2021-07-28T10:54:22.350381","updated":"2022-04-14T10:03:57.643726","actor_id":"https://lemmy.ml/u/mekhos","bio":"only here for the lemmy bucks","local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/mekhos/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":36323,"name":"tmpod","display_name":"Tmpod","avatar":"https://lemmy.pt/pictrs/image/gIPQUt3mxw.png","banned":false,"published":"2021-09-10T19:37:20.367073","updated":"2022-08-04T16:23:06.747838","actor_id":"https://lemmy.pt/u/tmpod","bio":"Estudante de Engenharia Informática apaixonado pela área; algures em Portugal.\n\nAdministrador da instância lemmy.pt.\n\n---\n\nComputer Science student, passionate about the field; somewhere in Portugal.\n\nlemmy.pt instance administrator.\n\n---\n\nhttps://tmpod.dev","local":false,"banner":"https://lemmy.pt/pictrs/image/iLIlqIIuaW.jpg","deleted":false,"inbox_url":"https://lemmy.pt/u/tmpod/inbox","shared_inbox_url":"https://lemmy.pt/inbox","matrix_user_id":"@tmpod:matrix.org","admin":false,"bot_account":false,"ban_expires":null,"instance_id":9}}],"online":45,"discussion_languages":[],"default_post_language":null} \ No newline at end of file diff --git a/src/examples/person.json b/src/examples/person.json new file mode 100644 index 0000000..5dfc7c2 --- /dev/null +++ b/src/examples/person.json @@ -0,0 +1 @@ +{"person_view":{"person":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"counts":{"id":4582,"person_id":12911,"post_count":21,"post_score":458,"comment_count":243,"comment_score":838}},"comments":[{"comment":{"id":703646,"creator_id":12911,"post_id":1300288,"content":"This won't happen in an update pretty soon. Welcome, but please use [!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) in the future","removed":false,"published":"2023-06-16T19:30:04.120685","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/703646","local":true,"path":"0.703646","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1300288,"name":"Is there a fix for the scroll issue if I am using Lemmy.world on an iPhone?","url":null,"body":"When scrolling through post new posts are constantly popping up on the top which makes it jump around and hard to use. I have it set up using Safari and adding it to my Home Screen on my iPhone.","creator_id":771600,"community_id":8,"removed":true,"locked":false,"published":"2023-06-16T19:21:13.707193","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.world/post/199033","local":false,"language_id":37,"featured_community":false,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":616363,"comment_id":703646,"score":1,"upvotes":1,"downvotes":0,"published":"2023-06-16T19:30:04.120685","child_count":0,"hot_rank":1728},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":703743,"creator_id":12911,"post_id":1300289,"content":"I mean\n\n\n![](https://lemmy.ml/pictrs/image/66b81893-162e-46b3-9fb2-0de81ed30cc6.png)","removed":false,"published":"2023-06-16T19:32:58.170721","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/703743","local":true,"path":"0.703556.703573.703599.703743","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1300289,"name":"Do you want to moderate asklemmy?","url":null,"body":"Hello! We've reached 15k members (afaik we're still the largest community on lemmy). It's a lot for only a couple people, though there is admin support.\n\nI'm looking for a couple people to join and help moderate. Ideally you:\n\n1. Have a history of contributions to this community\n2. Have been on lemmy for a reasonable* amount of time and do not plan to leave any time soon\n\n*Genuinely not sure what constitutes reasonable, I suppose it will be case-by-case. It's a little frightening to appoint someone who just came via the reddit migration, but I understand that 4/5 of this community are newish so it's fine. The main hope is that you'll stick around.\n\nIdeally I'll pick a few people out in the coming days. I'm also going to correspond with the admins before changes.\n\nThanks","creator_id":12911,"community_id":8,"removed":false,"locked":false,"published":"2023-06-16T19:21:25.261189","updated":"2023-06-16T19:26:25.815593","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/1300289","local":true,"language_id":37,"featured_community":true,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":616449,"comment_id":703743,"score":1,"upvotes":1,"downvotes":0,"published":"2023-06-16T19:32:58.170721","child_count":1,"hot_rank":1728},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":708171,"creator_id":12911,"post_id":1269863,"content":"How does that work in multiplayer","removed":false,"published":"2023-06-16T22:10:52.923572","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/708171","local":true,"path":"0.652324.677468.685888.708171","distinguished":false,"language_id":0},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1269863,"name":"Starfield’s 30fps frame rate is “a choice,” God of War dev says","url":"https://www.pcgamesn.com/starfield/30-frames","body":null,"creator_id":768141,"community_id":33587,"removed":false,"locked":false,"published":"2023-06-15T10:17:02.560112","updated":null,"deleted":false,"nsfw":false,"embed_title":"Starfield’s 30fps frame rate is “a choice,” God of War dev says","embed_description":"Starfield's performance is locked on Xbox, Todd Howard says, causing worry about the space sim on PC, but a God of War Ragnarok dev comes to Bethesda’s defense.","embed_video_url":null,"thumbnail_url":"https://lemmy.ml/pictrs/image/0bc29afe-8985-463f-8f25-d6f598380707.jpeg","ap_id":"https://startrek.website/post/13940","local":false,"language_id":0,"featured_community":false,"featured_local":false},"community":{"id":33587,"name":"gaming","title":"Gaming","description":"All forms of game discussion go here, from video gaming, to card games, to tabletop gaming.\n\n---\n\nThis community's icon was made by Aaron Schneider, under the [CC-BY-NC-SA 4.0 license](https://creativecommons.org/licenses/by-nc-sa/4.0/).","removed":false,"published":"2022-01-28T13:31:12.294106","updated":"2023-06-15T16:58:27.928392","deleted":false,"nsfw":false,"actor_id":"https://beehaw.org/c/gaming","local":false,"icon":"https://beehaw.org/pictrs/image/fed50129-04e7-4dbc-8f54-4ba5bae58370.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":1520},"counts":{"id":620365,"comment_id":708171,"score":1,"upvotes":1,"downvotes":0,"published":"2023-06-16T22:10:52.923572","child_count":0,"hot_rank":1728},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":711579,"creator_id":12911,"post_id":1300289,"content":"There are rules in the sidebar.","removed":false,"published":"2023-06-17T00:17:09.830528","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/711579","local":true,"path":"0.710299.711579","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1300289,"name":"Do you want to moderate asklemmy?","url":null,"body":"Hello! We've reached 15k members (afaik we're still the largest community on lemmy). It's a lot for only a couple people, though there is admin support.\n\nI'm looking for a couple people to join and help moderate. Ideally you:\n\n1. Have a history of contributions to this community\n2. Have been on lemmy for a reasonable* amount of time and do not plan to leave any time soon\n\n*Genuinely not sure what constitutes reasonable, I suppose it will be case-by-case. It's a little frightening to appoint someone who just came via the reddit migration, but I understand that 4/5 of this community are newish so it's fine. The main hope is that you'll stick around.\n\nIdeally I'll pick a few people out in the coming days. I'm also going to correspond with the admins before changes.\n\nThanks","creator_id":12911,"community_id":8,"removed":false,"locked":false,"published":"2023-06-16T19:21:25.261189","updated":"2023-06-16T19:26:25.815593","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/1300289","local":true,"language_id":37,"featured_community":true,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":623397,"comment_id":711579,"score":1,"upvotes":1,"downvotes":0,"published":"2023-06-17T00:17:09.830528","child_count":0,"hot_rank":1728},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":703573,"creator_id":12911,"post_id":1300289,"content":"Are you talking about instance-wide admins? ","removed":false,"published":"2023-06-16T19:27:24.061391","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/703573","local":true,"path":"0.703556.703573","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1300289,"name":"Do you want to moderate asklemmy?","url":null,"body":"Hello! We've reached 15k members (afaik we're still the largest community on lemmy). It's a lot for only a couple people, though there is admin support.\n\nI'm looking for a couple people to join and help moderate. Ideally you:\n\n1. Have a history of contributions to this community\n2. Have been on lemmy for a reasonable* amount of time and do not plan to leave any time soon\n\n*Genuinely not sure what constitutes reasonable, I suppose it will be case-by-case. It's a little frightening to appoint someone who just came via the reddit migration, but I understand that 4/5 of this community are newish so it's fine. The main hope is that you'll stick around.\n\nIdeally I'll pick a few people out in the coming days. I'm also going to correspond with the admins before changes.\n\nThanks","creator_id":12911,"community_id":8,"removed":false,"locked":false,"published":"2023-06-16T19:21:25.261189","updated":"2023-06-16T19:26:25.815593","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/1300289","local":true,"language_id":37,"featured_community":true,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":616293,"comment_id":703573,"score":1,"upvotes":1,"downvotes":0,"published":"2023-06-16T19:27:24.061391","child_count":3,"hot_rank":1728},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":592697,"creator_id":12911,"post_id":1235950,"content":"Me, with my mac and vscode writing about rust and mastodon and posting on my RSS feed, typing on my model M","removed":false,"published":"2023-06-13T22:28:42.274937","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/592697","local":true,"path":"0.583032.592697","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1235950,"name":"Developer compass","url":"https://sh.itjust.works/pictrs/image/5c7d2df6-d66b-46fe-8d30-335a43980ed8.png","body":null,"creator_id":680581,"community_id":14751,"removed":false,"locked":false,"published":"2023-06-13T14:57:20.897201","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":"https://lemmy.ml/pictrs/image/c2d226d0-2465-4c29-ac16-e288fcbaf60b.png","ap_id":"https://sh.itjust.works/post/66335","local":false,"language_id":37,"featured_community":false,"featured_local":false},"community":{"id":14751,"name":"programmerhumor","title":"Programmer Humor","description":"Post funny things about programming here! (Or just rant about your favourite programming language.)\n\n# Rules:\n\n* Posts must be relevant to programming, programmers, or computer science.\n* No NSFW content.\n* Jokes must be in good taste. No hate speech, bigotry, etc.","removed":false,"published":"2019-08-19T09:46:48.488224","updated":"2022-03-08T19:55:12.303424","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/programmerhumor","local":true,"icon":"https://lemmy.ml/pictrs/image/c0ed0a36-2496-4b4d-ac77-7d2fd7f2b5b7.png","banner":"https://lemmy.ml/pictrs/image/dd918f22-84fa-48d5-975a-c94981058c18.jpeg","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":516807,"comment_id":592697,"score":3,"upvotes":3,"downvotes":0,"published":"2023-06-13T22:28:42.274937","child_count":0,"hot_rank":4},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":559273,"creator_id":12911,"post_id":1198265,"content":"> They’re probably simply overloaded right now\n\nExactly. Removed it now. Sorry for the growing pains.","removed":false,"published":"2023-06-13T00:05:19.755011","updated":"2023-06-13T00:47:36.333265","deleted":false,"ap_id":"https://lemmy.ml/comment/559273","local":true,"path":"0.541232.541747.541792.541828.541884.541908.542356.555610.559104.559273","distinguished":true,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1198265,"name":"What kinds of things from reddit would you like to see Lemmy avoid as the user base grows?","url":null,"body":"Personally I think not having karma limits is nice currently! I understand why they were used but grinding karma as a lurker on reddit was frustrating.","creator_id":663068,"community_id":8,"removed":false,"locked":false,"published":"2023-06-11T00:35:13.759748","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.fmhy.ml/post/13629","local":false,"language_id":0,"featured_community":false,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":486658,"comment_id":559273,"score":7,"upvotes":7,"downvotes":0,"published":"2023-06-13T00:05:19.755011","child_count":3,"hot_rank":3},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":584692,"creator_id":12911,"post_id":1237963,"content":"This question is better for [!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) ","removed":false,"published":"2023-06-13T18:07:22.234014","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/584692","local":true,"path":"0.584692","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1237963,"name":"Downvotes Disabled?","url":null,"body":"Someone mind explaining how downvotes are either disabled or don't work on many communities? Is this community dependent or does it vary per server?","creator_id":709460,"community_id":8,"removed":true,"locked":true,"published":"2023-06-13T17:22:07.759855","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.one/post/96235","local":false,"language_id":37,"featured_community":false,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":509622,"comment_id":584692,"score":4,"upvotes":4,"downvotes":0,"published":"2023-06-13T18:07:22.234014","child_count":0,"hot_rank":3},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":554994,"creator_id":12911,"post_id":1224547,"content":"Very soon (within a couple days) this feature will be disabled, which will also greatly improve performance. You can follow progress here: https://github.com/LemmyNet/lemmy-ui/pull/1081 For the future, this sort of question is better for [!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) ","removed":false,"published":"2023-06-12T21:30:11.151967","updated":"2023-06-12T21:46:13.721534","deleted":false,"ap_id":"https://lemmy.ml/comment/554994","local":true,"path":"0.554994","distinguished":true,"language_id":0},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1224547,"name":"Is there a way to make Lemmy stop refreshing feed automatically?","url":null,"body":"As the title said, I' going through the feed and new posts are adding pushing what I read down, which is annoying, is there a way to stop this?","creator_id":698784,"community_id":8,"removed":false,"locked":false,"published":"2023-06-12T21:01:23.878383","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.world/post/80909","local":false,"language_id":0,"featured_community":false,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":482702,"comment_id":554994,"score":14,"upvotes":14,"downvotes":0,"published":"2023-06-12T21:30:11.151967","child_count":3,"hot_rank":3},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null},{"comment":{"id":595170,"creator_id":12911,"post_id":1239589,"content":"I can't believe I had to add a rule just for this","removed":false,"published":"2023-06-14T00:04:51.965148","updated":null,"deleted":false,"ap_id":"https://lemmy.ml/comment/595170","local":true,"path":"0.595170","distinguished":false,"language_id":37},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"post":{"id":1239589,"name":"Lemmlors of Lemmy, what's the sexiest sex you've ever sexed?","url":null,"body":null,"creator_id":675670,"community_id":8,"removed":false,"locked":false,"published":"2023-06-13T19:34:59.601951","updated":null,"deleted":false,"nsfw":true,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://feddit.de/post/823040","local":false,"language_id":37,"featured_community":false,"featured_local":false},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"counts":{"id":519047,"comment_id":595170,"score":1,"upvotes":1,"downvotes":0,"published":"2023-06-14T00:04:51.965148","child_count":0,"hot_rank":3},"creator_banned_from_community":false,"subscribed":"NotSubscribed","saved":false,"creator_blocked":false,"my_vote":null}],"posts":[{"post":{"id":1300289,"name":"Do you want to moderate asklemmy?","url":null,"body":"Hello! We've reached 15k members (afaik we're still the largest community on lemmy). It's a lot for only a couple people, though there is admin support.\n\nI'm looking for a couple people to join and help moderate. Ideally you:\n\n1. Have a history of contributions to this community\n2. Have been on lemmy for a reasonable* amount of time and do not plan to leave any time soon\n\n*Genuinely not sure what constitutes reasonable, I suppose it will be case-by-case. It's a little frightening to appoint someone who just came via the reddit migration, but I understand that 4/5 of this community are newish so it's fine. The main hope is that you'll stick around.\n\nIdeally I'll pick a few people out in the coming days. I'm also going to correspond with the admins before changes.\n\nThanks","creator_id":12911,"community_id":8,"removed":false,"locked":false,"published":"2023-06-16T19:21:25.261189","updated":"2023-06-16T19:26:25.815593","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/1300289","local":true,"language_id":37,"featured_community":true,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":197738,"post_id":1300289,"comments":15,"score":49,"upvotes":50,"downvotes":1,"published":"2023-06-16T19:21:25.261189","newest_comment_time_necro":"2023-06-16T23:30:52.641769","newest_comment_time":"2023-06-17T00:17:09.830528","featured_community":true,"featured_local":false,"hot_rank":1728,"hot_rank_active":1728},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":15},{"post":{"id":1223478,"name":"This community is not for support! [Please report support posts]","url":null,"body":"There's been an influx of content surrounding lemmy here. Some of it is open ended:\n\n- \"What kinds of things from reddit would you like to see Lemmy avoid as the user base grows?\"\n- \"Lemmy, what do you call users of Lemmy?\"\n\nAnd these are a-ok! There's also been a lot of questions like\n\n- \"How do I block a user?\"\n- \"How do I join a community on a different instance\"\n\nThese aren't open ended (at least, relatively). They are objective based, and just need a resolution, rather than discussion. These sort of questions are more relevant to [!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support).\n\nI know there's also questions like \"What are you guys doing when there’s multiple communities for the same thing across instances?\". I'm inclined to let those stay, there is lots of opportunity for discussion. It's a game of discretion from a moderation perspective, but I assume most can easily guess what is cold hard support.\n\nAt least from me, moderation of support posts has been sporadic at best, despite the long standing rule. I will begin redirecting these questions to [!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support), however I'm of course willing to listen to the community here if that's not what is wanted, as well as other feedback.\n\nedit: support posts will now be removed, not locked","creator_id":12911,"community_id":8,"removed":false,"locked":false,"published":"2023-06-12T20:08:17.285824","updated":"2023-06-16T19:34:41.088050","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/1223478","local":true,"language_id":0,"featured_community":true,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":175791,"post_id":1223478,"comments":1,"score":39,"upvotes":39,"downvotes":0,"published":"2023-06-12T20:08:17.285824","newest_comment_time_necro":"2023-06-14T04:27:57.766833","newest_comment_time":"2023-06-14T04:27:57.766833","featured_community":true,"featured_local":false,"hot_rank":4,"hot_rank_active":9},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":1},{"post":{"id":1183528,"name":"Consider contributing to lemmy!","url":null,"body":"Hi everyone, welcome, ect... It might go without saying but lemmy is open source! The platform is written in rust and typescript (which is a big pro for me). I'm sure we all have our little gripes with the platform, and those are fixed with collective teamwork :)\n\n[These](https://github.com/LemmyNet/lemmy/issues?q=is:issue+is:open+label:%22good+first+issue%22) are \"good first issues\", [here](https://join-lemmy.org/docs/en/contributors/01-overview.html) is a contributing guide), and [here](https://matrix.to/#/#lemmydev:matrix.org) is a chat where developers coordinate.\n\nLet's make the best link aggregator! ","creator_id":12911,"community_id":14749,"removed":false,"locked":false,"published":"2023-06-09T17:34:49.928643","updated":"2023-06-09T19:48:40.307144","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/1183528","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":14749,"name":"opensource","title":"Open Source","description":"All about open source! Feel free to ask questions, and share news, and interesting stuff!\n\n# Useful Links\n* [Open Source Initiative](https://opensource.org/)\n* [Free Software Foundation](https://www.fsf.org/)\n* [Electronic Frontier Foundation](https://www.eff.org/)\n* [Software Freedom Conservancy](https://sfconservancy.org/)\n* [It's FOSS](https://itsfoss.com/)\n\n# Rules\n* Posts must be relevant to the open source ideology\n* No NSFW content\n* No hate speech, bigotry, etc \n\n# Related Communities\n* [!libre_culture@lemmy.ml](https://lemmy.ml/c/libre_culture) \n* [!libre_software@lemmy.ml](https://lemmy.ml/c/libre_software) \n* [!libre_hardware@lemmy.ml](https://lemmy.ml/c/libre_hardware) \n* [!linux@lemmy.ml](https://lemmy.ml/c/linux) \n* [!technology@lemmy.ml](https://lemmy.ml/c/technology) \n\nCommunity icon from opensource.org, but we are not affiliated with them. ","removed":false,"published":"2019-08-19T09:43:37.618982","updated":"2022-11-08T08:48:52.846612","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/opensource","local":true,"icon":"https://lemmy.ml/pictrs/image/a64z2tlDDD.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":165613,"post_id":1183528,"comments":11,"score":80,"upvotes":80,"downvotes":0,"published":"2023-06-09T17:34:49.928643","newest_comment_time_necro":"2023-06-10T03:28:56","newest_comment_time":"2023-06-14T21:21:16.772675","featured_community":false,"featured_local":false,"hot_rank":1,"hot_rank_active":2},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":11},{"post":{"id":82099,"name":"Resonate – the ethical music streaming co-op","url":"https://resonate.is/","body":"cross-posted from: https://lemmy.ml/post/81992\n\n> Resonate is a really cool co-op and they could really use some volunteers & users. \n> \n> I've been looking for a more ethical music streaming service since I discovered [Spotify and other streaming platforms are terrible for small artists](https://www.digitalmusicnews.com/2021/03/18/spotify-artist-earnings-figures/). Only the top 3% of artists make $1000/yr and only the top 1% make more than $5000/yr. You'd have to be in the top 0.2% to actually earn a living of $50,000/yr on Spotify.\n> \n> Resonate is the only platform I've found that's doing something radically different. They have a stream to own model in which listeners pay artists directly about 1/4 of one cent for their first stream then the price increases exponentially with each stream until the 9th stream at which point the listener has paid ~$1.50usd. At that point the user can download the song for offline listening and never has to pay to stream that song again.\n> \n> Perhaps the coolest part is they are a co-op, 45% of governance weight is reserved for artist shares, 35% for listener shares, and only 20% for staff.\n> \n> Resonate is a small project that could use all the help it can get. If anyone knows of any other cool music platforms, I'd love to know about them, too! \n\nhttps://github.com/resonatecoop/stream","creator_id":12911,"community_id":14749,"removed":false,"locked":false,"published":"2021-09-22T03:58:27.438554","updated":null,"deleted":false,"nsfw":false,"embed_title":"Resonate – the ethical music streaming co-op","embed_description":"Resonate is a streaming music service cooperative owned by the people that use it – musicians, indie labels, fans + developers. Stream it until you own it.","embed_video_url":null,"thumbnail_url":"https://lemmy.ml/pictrs/image/Rda2BpoLr6.png","ap_id":"https://lemmy.ml/post/82099","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":14749,"name":"opensource","title":"Open Source","description":"All about open source! Feel free to ask questions, and share news, and interesting stuff!\n\n# Useful Links\n* [Open Source Initiative](https://opensource.org/)\n* [Free Software Foundation](https://www.fsf.org/)\n* [Electronic Frontier Foundation](https://www.eff.org/)\n* [Software Freedom Conservancy](https://sfconservancy.org/)\n* [It's FOSS](https://itsfoss.com/)\n\n# Rules\n* Posts must be relevant to the open source ideology\n* No NSFW content\n* No hate speech, bigotry, etc \n\n# Related Communities\n* [!libre_culture@lemmy.ml](https://lemmy.ml/c/libre_culture) \n* [!libre_software@lemmy.ml](https://lemmy.ml/c/libre_software) \n* [!libre_hardware@lemmy.ml](https://lemmy.ml/c/libre_hardware) \n* [!linux@lemmy.ml](https://lemmy.ml/c/linux) \n* [!technology@lemmy.ml](https://lemmy.ml/c/technology) \n\nCommunity icon from opensource.org, but we are not affiliated with them. ","removed":false,"published":"2019-08-19T09:43:37.618982","updated":"2022-11-08T08:48:52.846612","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/opensource","local":true,"icon":"https://lemmy.ml/pictrs/image/a64z2tlDDD.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":44288,"post_id":82099,"comments":5,"score":30,"upvotes":30,"downvotes":0,"published":"2021-09-22T03:58:27.438554","newest_comment_time_necro":"2021-09-22T19:44:15.370291","newest_comment_time":"2021-09-22T19:44:15.370291","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":5},{"post":{"id":37923,"name":"Rocket league, after being bought by epic and dropping linux support, will become a f2b egs exclusive with next to no reward for people who bought the game","url":"https://www.rocketleague.com/news/rocket-league-going-free-to-play-this-summer/","body":null,"creator_id":12911,"community_id":14780,"removed":false,"locked":false,"published":"2020-07-21T18:39:55.233623","updated":"2020-07-21T20:14:42.879310","deleted":false,"nsfw":false,"embed_title":"Rocket League Going Free To Play This Summer","embed_description":null,"embed_video_url":null,"thumbnail_url":"https://lemmy.ml/pictrs/image/yOytiWAb9M.jpg","ap_id":"https://lemmy.ml/post/37923","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":14780,"name":"gaming","title":"Gaming","description":"Sub for any gaming related content!\n\nRules:\n- **No spam or advertising.** This basically means no linking to your own content on blogs, YouTube, Twitch, etc.\n- **No bigotry or gatekeeping.** This should be obvious, but neither of those things will be tolerated. This goes for linked content too; if the site has some heavy \"anti-woke\" energy, you probably shouldn't be posting it here.","removed":false,"published":"2019-10-16T20:31:00.900310","updated":"2021-11-23T02:10:36.089280","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/gaming","local":true,"icon":"https://lemmy.ml/pictrs/image/8nN0qtLEOJ.png","banner":"https://lemmy.ml/pictrs/image/lkmQLA9Kqx.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":7480,"post_id":37923,"comments":12,"score":20,"upvotes":21,"downvotes":1,"published":"2020-07-21T18:39:55.233623","newest_comment_time_necro":"2020-07-23T04:36:14.809216","newest_comment_time":"2020-07-23T04:36:14.809216","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":12},{"post":{"id":37916,"name":"Requesting c/asklemmy","url":"https://lemmy.ml/c/asklemmy","body":null,"creator_id":12911,"community_id":15113,"removed":false,"locked":false,"published":"2020-07-21T16:44:34.976716","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":"Lemmy","embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/37916","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":15113,"name":"community_requests","title":"Community Requests.","description":"This is to request dead / abandoned communities to be transferred.","removed":false,"published":"2020-05-16T19:11:31.381034","updated":null,"deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/community_requests","local":true,"icon":null,"banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":8909,"post_id":37916,"comments":1,"score":1,"upvotes":1,"downvotes":0,"published":"2020-07-21T16:44:34.976716","newest_comment_time_necro":"2020-07-22T14:56:41.871318","newest_comment_time":"2020-07-22T14:56:41.871318","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":1},{"post":{"id":39548,"name":"invidio.us main mirror is shutting down, with its main dev coming with it.","url":"https://invidio.us/","body":"The project will continue to be mantained, however, I guess, its future is uncertain. ","creator_id":12911,"community_id":14749,"removed":false,"locked":false,"published":"2020-08-25T14:11:34.277880","updated":null,"deleted":false,"nsfw":false,"embed_title":"\n \n Invidious\n \n","embed_description":"An alternative front-end to YouTube","embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/39548","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":14749,"name":"opensource","title":"Open Source","description":"All about open source! Feel free to ask questions, and share news, and interesting stuff!\n\n# Useful Links\n* [Open Source Initiative](https://opensource.org/)\n* [Free Software Foundation](https://www.fsf.org/)\n* [Electronic Frontier Foundation](https://www.eff.org/)\n* [Software Freedom Conservancy](https://sfconservancy.org/)\n* [It's FOSS](https://itsfoss.com/)\n\n# Rules\n* Posts must be relevant to the open source ideology\n* No NSFW content\n* No hate speech, bigotry, etc \n\n# Related Communities\n* [!libre_culture@lemmy.ml](https://lemmy.ml/c/libre_culture) \n* [!libre_software@lemmy.ml](https://lemmy.ml/c/libre_software) \n* [!libre_hardware@lemmy.ml](https://lemmy.ml/c/libre_hardware) \n* [!linux@lemmy.ml](https://lemmy.ml/c/linux) \n* [!technology@lemmy.ml](https://lemmy.ml/c/technology) \n\nCommunity icon from opensource.org, but we are not affiliated with them. ","removed":false,"published":"2019-08-19T09:43:37.618982","updated":"2022-11-08T08:48:52.846612","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/opensource","local":true,"icon":"https://lemmy.ml/pictrs/image/a64z2tlDDD.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":13144,"post_id":39548,"comments":-1,"score":13,"upvotes":13,"downvotes":0,"published":"2020-08-25T14:11:34.277880","newest_comment_time_necro":"2020-08-25T16:17:18.492938","newest_comment_time":"2020-08-25T16:17:18.492938","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":-1},{"post":{"id":37909,"name":"What is your favorite open source software?","url":null,"body":"Save for lemme, ofc","creator_id":12911,"community_id":8,"removed":false,"locked":false,"published":"2020-07-21T15:05:21.208101","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/37909","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":17209,"post_id":37909,"comments":3,"score":7,"upvotes":7,"downvotes":0,"published":"2020-07-21T15:05:21.208101","newest_comment_time_necro":"2020-07-23T19:11:12.612523","newest_comment_time":"2020-07-23T19:11:12.612523","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":3},{"post":{"id":37910,"name":"What is your favorite open source software?","url":null,"body":"Save for lemmy, duh.","creator_id":12911,"community_id":14749,"removed":false,"locked":false,"published":"2020-07-21T15:06:27.568730","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/37910","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":14749,"name":"opensource","title":"Open Source","description":"All about open source! Feel free to ask questions, and share news, and interesting stuff!\n\n# Useful Links\n* [Open Source Initiative](https://opensource.org/)\n* [Free Software Foundation](https://www.fsf.org/)\n* [Electronic Frontier Foundation](https://www.eff.org/)\n* [Software Freedom Conservancy](https://sfconservancy.org/)\n* [It's FOSS](https://itsfoss.com/)\n\n# Rules\n* Posts must be relevant to the open source ideology\n* No NSFW content\n* No hate speech, bigotry, etc \n\n# Related Communities\n* [!libre_culture@lemmy.ml](https://lemmy.ml/c/libre_culture) \n* [!libre_software@lemmy.ml](https://lemmy.ml/c/libre_software) \n* [!libre_hardware@lemmy.ml](https://lemmy.ml/c/libre_hardware) \n* [!linux@lemmy.ml](https://lemmy.ml/c/linux) \n* [!technology@lemmy.ml](https://lemmy.ml/c/technology) \n\nCommunity icon from opensource.org, but we are not affiliated with them. ","removed":false,"published":"2019-08-19T09:43:37.618982","updated":"2022-11-08T08:48:52.846612","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/opensource","local":true,"icon":"https://lemmy.ml/pictrs/image/a64z2tlDDD.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":17210,"post_id":37910,"comments":43,"score":52,"upvotes":52,"downvotes":0,"published":"2020-07-21T15:06:27.568730","newest_comment_time_necro":"2020-07-28T22:37:25.047780","newest_comment_time":"2021-03-26T00:44:21.281006","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":43},{"post":{"id":80941,"name":"Khan is massively flawed (We need a comprehensive free alternative!)","url":null,"body":"Today when talking on discord someone mentioned their approval for Khan Academy, stating that it was what allowed them to pass their class. I have too consulted Khan Academy on a few occasions, and I thought the teaching was well done. I believe education is a human right, and I thought I would see what I could do to contribute. I was alarmed to discover the lack of ways to do so.\n\nI voiced my thoughts in a brief way in discord, and was quickly attacked by nearly everyone there. People seem to all love khan, holding it as the savior of education, and in some way's, it is. Khan was the first platform I could find to offer **easily** accessible k-12-beyond learning for anyone, for free. It provides a central place with \"trusted\" content, but ultimately khan academy solves no issues in our education system, while getting all the support of the internet.\n\nI write this \"rant\" to be the first person on the internet to say khan is not so great.\n\n## A dictatorship\n\nThere is no public information on khan academies power structure, aside from the fact that it has [executives](https://www.khanacademy.org/about/our-board). There is no way to vote in leaders, and no real way to hold them accountable other than abstaining from donation. This leads to near unlimited power. Sal has networth in the millions alone, and due to its dictatorship structure a hostile takeover to broadcast information on a \"trusted\" site like khan is possible - as we saw in freenode. This power structure ultimately leaves not only the [people](https://youtu.be/q8zKgd1r8uI?t=46) but the teachers powerless, leaving for issues like the [traditional school board](https://www.youtube.com/watch?v=mJBlgIA3K24).\n\n## Closed source\n\nI don't give a shit about the website source code, but the curriculum is pretty close to closed source. This means if misinformation is spread on the site, we are unable to easily maintain a \"correct\" mirror. If the site goes down, so does the learning. For similar issues, offline users in low income countries especially are barred.\n\nWhile khan material is under CC BY-NC-SA 3.0 US, it's near impossible to effectively copy without using web crawlers.\n\n## Closed doors\n\nFinally, Khan contributors are always employees. This means we are relient on [bug reports](https://support.khanacademy.org/hc/en-us/articles/226373748-How-do-I-report-different-kinds-of-bugs-and-issues-#content) to fix issues, and who knows when or if it will be fixed. Additionally, raised issues are viewable only to khan staff removing even more accountability.\n\nWant to write more new content for khan for free because you love learning? You can't without giving up your job for a paid position.\n\n## Uncited\n\nI struggled to find citations for anything asserted on their site. This is especially needed in the sciences and social studies, where misinformation is rampant.\n\n# We can do better\n\nI dream of a curriculum where we are free. Free to and easy to clone, redistribute, and to modify. Where there is democratic government, so a hostile takeover is near impossible. Where changes are made in the open so that we hold those that make them more accountable. A curriculum that is modern and interactive, with a smaller focus on lectures.\n\nI don't think this exists today, but for a true radicle education platform something must change, to avoid all the issues we face today with the world's education in an online platform.\n\nAt the very least, the world must rid of the \"Khan will change the world\" mentality.\n\n---\n\nPS: Sorry if my thoughts are slightly raw, wrote this in a hurry\n\nPPS: These are flaws in khan, but they apply to many other \"free\" learning platforms. Hell, khan under it's license is \"free\", but in reality it's far from it. I am yet to find a alternative that really does what needs to be done, although I am hopeful this community is a step in the right direction\n\nThis post and all past material written by me that is hosted on lemmy is UNLICENSED. Do as you wish.\n","creator_id":12911,"community_id":23774,"removed":false,"locked":false,"published":"2021-09-14T21:39:38.849436","updated":"2021-09-14T21:41:27.208766","deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://lemmy.ml/post/80941","local":true,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394},"community":{"id":23774,"name":"open_e_resources","title":"Open Educational Resources","description":"A community focused on sharing and talking about free/libre/copyleft/public domain resources for educational use. Resources may include things like textbooks, audiobooks, web apps, apps and more.\n\nRules:\n- Follow Lemmy site-wide rules and [Code of Conduct](https://join-lemmy.org/docs/en/code_of_conduct.html)\n\n- Prior to posting and if possible, specify the license/nature of the resource(s) and anti-features. The resources should be at least \"redistributable\" and \"remixable\" by anyone and everyone.\n\n- Avoid sharing resources encouraging nationalism, fascism or one-sided views. International solidarity is key.\n","removed":false,"published":"2021-08-23T12:26:17.608239","updated":"2021-08-23T14:03:33.519296","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/open_e_resources","local":true,"icon":"https://lemmy.ml/pictrs/image/vloZna5fAV.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":43384,"post_id":80941,"comments":5,"score":28,"upvotes":30,"downvotes":2,"published":"2021-09-14T21:39:38.849436","newest_comment_time_necro":"2021-09-15T12:30:11.294713","newest_comment_time":"2023-06-13T17:57:24.885347","featured_community":false,"featured_local":false,"hot_rank":0,"hot_rank_active":0},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":5}],"moderates":[{"community":{"id":15968,"name":"unpopular","title":"Unpopular Opinions","description":"Please don't hate on people. this is not a hate community.","removed":false,"published":"2020-07-05T16:57:09.961096","updated":null,"deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/unpopular","local":true,"icon":null,"banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":15969,"name":"confession","title":"A place for confessions","description":null,"removed":false,"published":"2020-07-05T16:58:53.122309","updated":null,"deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/confession","local":true,"icon":null,"banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":15970,"name":"unitedstates","title":"AmArIcA","description":null,"removed":false,"published":"2020-07-05T18:48:16.175027","updated":null,"deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/unitedstates","local":true,"icon":null,"banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":8,"name":"asklemmy","title":"asklemmy","description":"A loosely moderated place to ask open ended questions\n\nIf your post is\n\n1. Open ended \n2. Not offensive (At this point, I do not have the bandwidth to moderate partisan political discussions)\n3. **Not regarding lemmy support** ([!lemmy_support@lemmy.ml](https://lemmy.ml/c/lemmy_support) )\n4. not ad nauseam inducing (please make sure its a question that would be new to most members)\n5. [An actual topic of discussion](https://lemmy.ml/post/1239589)\n\nit’s welcome here!","removed":false,"published":"2019-04-25T04:58:33.886275","updated":"2023-06-14T00:05:37.871496","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/asklemmy","local":true,"icon":"https://lemmy.ml/pictrs/image/UsuGsKF2fl.png","banner":"https://lemmy.ml/pictrs/image/XKAjSZCX2P.png","hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":14749,"name":"opensource","title":"Open Source","description":"All about open source! Feel free to ask questions, and share news, and interesting stuff!\n\n# Useful Links\n* [Open Source Initiative](https://opensource.org/)\n* [Free Software Foundation](https://www.fsf.org/)\n* [Electronic Frontier Foundation](https://www.eff.org/)\n* [Software Freedom Conservancy](https://sfconservancy.org/)\n* [It's FOSS](https://itsfoss.com/)\n\n# Rules\n* Posts must be relevant to the open source ideology\n* No NSFW content\n* No hate speech, bigotry, etc \n\n# Related Communities\n* [!libre_culture@lemmy.ml](https://lemmy.ml/c/libre_culture) \n* [!libre_software@lemmy.ml](https://lemmy.ml/c/libre_software) \n* [!libre_hardware@lemmy.ml](https://lemmy.ml/c/libre_hardware) \n* [!linux@lemmy.ml](https://lemmy.ml/c/linux) \n* [!technology@lemmy.ml](https://lemmy.ml/c/technology) \n\nCommunity icon from opensource.org, but we are not affiliated with them. ","removed":false,"published":"2019-08-19T09:43:37.618982","updated":"2022-11-08T08:48:52.846612","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/opensource","local":true,"icon":"https://lemmy.ml/pictrs/image/a64z2tlDDD.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":14680,"name":"programming","title":"General Programming Discussion","description":"A general programming discussion community.\n\n# Rules:\n\n1. Be civil.\n2. Please start discussions that spark conversation\n\n# Other communities\n\n- [!python@lemmy.ml](https://lemmy.ml/c/python)\n- [!powershell@lemmy.ml](https://lemmy.ml/c/powershell)\n- [!julia@lemmy.ml](https://lemmy.ml/c/julia)\n- [!iosprogramming@lemmy.ml](https://lemmy.ml/c/iosprogramming)\n\n### Systems\n\n- [!rust@lemmy.ml](https://lemmy.ml/c/rust)\n- [!cpp@lemmy.ml](https://lemmy.ml/c/cpp)\n- [!c_programming@lemmy.ml](https://lemmy.ml/c/c_programming)\n\n### Functional Programming\n\n- [!haskell@lemmy.ml](https://lemmy.ml/c/haskell)\n- [!fpcomplete@lemmy.ml](https://lemmy.ml/c/fpcomplete)\n\n### Also related\n\n- [!opensource@lemmy.ml](https://lemmy.ml/c/opensource) ","removed":false,"published":"2019-04-27T09:33:55.679254","updated":"2023-06-08T22:33:17.787198","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/programming","local":true,"icon":null,"banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":28434,"name":"sourcehut","title":"Sourcehut","description":"# Unofficial sourcehut discussion","removed":false,"published":"2021-12-10T22:28:55.943960","updated":null,"deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/sourcehut","local":true,"icon":null,"banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":12911,"name":"Cloak","display_name":"Evan","avatar":null,"banned":false,"published":"2020-07-05T16:11:40.290179","updated":"2022-02-01T02:01:10.936854","actor_id":"https://lemmy.ml/u/Cloak","bio":null,"local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/Cloak/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}}]} \ No newline at end of file diff --git a/src/examples/post.json b/src/examples/post.json new file mode 100644 index 0000000..a456e91 --- /dev/null +++ b/src/examples/post.json @@ -0,0 +1 @@ +{"post_view":{"post":{"id":1294498,"name":"Dang it, Boohauer!","url":"https://beehaw.org/pictrs/image/9d4be026-b6be-45ad-8b09-6ce0fab4c06f.jpeg","body":null,"creator_id":627342,"community_id":14,"removed":false,"locked":false,"published":"2023-06-16T15:10:15.351950","updated":null,"deleted":false,"nsfw":false,"embed_title":null,"embed_description":null,"embed_video_url":null,"thumbnail_url":null,"ap_id":"https://beehaw.org/post/590334","local":false,"language_id":0,"featured_community":false,"featured_local":false},"creator":{"id":627342,"name":"Infinitybiscuit","display_name":null,"avatar":"https://beehaw.org/pictrs/image/004f88c1-b52e-4f58-a7f5-b0fdaa85fe3a.jpeg","banned":false,"published":"2023-06-01T14:29:34.309346","updated":null,"actor_id":"https://beehaw.org/u/Infinitybiscuit","bio":null,"local":false,"banner":null,"deleted":false,"inbox_url":"https://beehaw.org/u/Infinitybiscuit/inbox","shared_inbox_url":"https://beehaw.org/inbox","matrix_user_id":null,"admin":false,"bot_account":false,"ban_expires":null,"instance_id":1520},"community":{"id":14,"name":"memes","title":"Memes","description":"#### Rules:\n\n\n01. Be civil and nice.\n02. Try not to excessively repost, as a rule of thumb, wait at least 2 months to do it if you *have* to.","removed":false,"published":"2019-04-25T16:54:42.997194","updated":"2022-01-12T13:43:29.936386","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/memes","local":true,"icon":"https://lemmy.ml/pictrs/image/CJ7moKL2SV.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"creator_banned_from_community":false,"counts":{"id":196246,"post_id":1294498,"comments":10,"score":147,"upvotes":152,"downvotes":5,"published":"2023-06-16T15:10:15.351950","newest_comment_time_necro":"2023-06-17T23:47:49.683249","newest_comment_time":"2023-06-17T23:47:49.683249","featured_community":false,"featured_local":false,"hot_rank":2678,"hot_rank_active":2678},"subscribed":"NotSubscribed","saved":false,"read":false,"creator_blocked":false,"my_vote":null,"unread_comments":10},"community_view":{"community":{"id":14,"name":"memes","title":"Memes","description":"#### Rules:\n\n\n01. Be civil and nice.\n02. Try not to excessively repost, as a rule of thumb, wait at least 2 months to do it if you *have* to.","removed":false,"published":"2019-04-25T16:54:42.997194","updated":"2022-01-12T13:43:29.936386","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/memes","local":true,"icon":"https://lemmy.ml/pictrs/image/CJ7moKL2SV.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"subscribed":"NotSubscribed","blocked":false,"counts":{"id":643,"community_id":14,"subscribers":15996,"posts":2973,"comments":12903,"published":"2019-04-25T16:54:42.997194","users_active_day":427,"users_active_week":2583,"users_active_month":3119,"users_active_half_year":3239,"hot_rank":0}},"moderators":[{"community":{"id":14,"name":"memes","title":"Memes","description":"#### Rules:\n\n\n01. Be civil and nice.\n02. Try not to excessively repost, as a rule of thumb, wait at least 2 months to do it if you *have* to.","removed":false,"published":"2019-04-25T16:54:42.997194","updated":"2022-01-12T13:43:29.936386","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/memes","local":true,"icon":"https://lemmy.ml/pictrs/image/CJ7moKL2SV.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":14884,"name":"gary_host_laptop","display_name":"明-3 NOMAD","avatar":"https://lemmy.ml/pictrs/image/BLmgZC3wOa.png","banned":false,"published":"2020-11-25T01:33:37.649417","updated":"2022-03-10T20:49:05.252101","actor_id":"https://lemmy.ml/u/gary_host_laptop","bio":" *Freedom is a synthetic enterprise, not a natural gift.* \n\n50","local":true,"banner":null,"deleted":false,"inbox_url":"https://lemmy.ml/u/gary_host_laptop/inbox","shared_inbox_url":"https://lemmy.ml/inbox","matrix_user_id":"@long_john_silver:matrix.org","admin":false,"bot_account":false,"ban_expires":null,"instance_id":394}},{"community":{"id":14,"name":"memes","title":"Memes","description":"#### Rules:\n\n\n01. Be civil and nice.\n02. Try not to excessively repost, as a rule of thumb, wait at least 2 months to do it if you *have* to.","removed":false,"published":"2019-04-25T16:54:42.997194","updated":"2022-01-12T13:43:29.936386","deleted":false,"nsfw":false,"actor_id":"https://lemmy.ml/c/memes","local":true,"icon":"https://lemmy.ml/pictrs/image/CJ7moKL2SV.png","banner":null,"hidden":false,"posting_restricted_to_mods":false,"instance_id":394},"moderator":{"id":40803,"name":"sexy_peach","display_name":null,"avatar":"https://feddit.de/pictrs/image/182505bd-d9c4-4a10-8329-4bec95d493d2.jpeg","banned":false,"published":"2021-11-01T11:05:36.938726","updated":"2022-10-07T16:03:26.259601","actor_id":"https://feddit.de/u/sexy_peach","bio":"peertube: https://diode.zone/a/sexy_peach/video-channels","local":false,"banner":"https://feddit.de/pictrs/image/FunRnZCeNJ.png","deleted":false,"inbox_url":"https://feddit.de/u/sexy_peach/inbox","shared_inbox_url":"https://feddit.de/inbox","matrix_user_id":"@sexy_peach:tchncs.de","admin":false,"bot_account":false,"ban_expires":null,"instance_id":286}}],"online":0} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..889f681 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,311 @@ +pub mod settings; +pub mod api; +pub mod components; +pub mod util; + +use api::{user::default_person, community::default_community, post::default_post}; +use components::{post_row::PostRow, community_row::CommunityRow, profile_page::{ProfilePage, self}, community_page::{CommunityPage, self}, post_page::{PostPage, self}}; +use gtk::prelude::*; +use lemmy_api_common::{lemmy_db_views_actor::structs::CommunityView, lemmy_db_views::structs::PostView, person::GetPersonDetailsResponse, lemmy_db_schema::newtypes::PostId, post::GetPostResponse, community::GetCommunityResponse}; +use relm4::{prelude::*, factory::FactoryVecDeque, set_global_css}; + +static APP_ID: &str = "com.lemmy-gtk.lemoa"; + +#[derive(Debug, Clone, Copy)] +enum AppState { + Loading, + Posts, + ChooseInstance, + Communities, + Community, + Person, + Post +} + +struct App { + state: AppState, + posts: FactoryVecDeque, + communities: FactoryVecDeque, + profile_page: Controller, + community_page: Controller, + post_page: Controller +} + +#[derive(Debug)] +pub enum AppMsg { + ChooseInstance, + DoneChoosingInstance(String), + StartFetchPosts, + DoneFetchPosts(Result, reqwest::Error>), + DoneFetchCommunities(Result, reqwest::Error>), + ViewCommunities(Option), + OpenCommunity(String), + DoneFetchCommunity(GetCommunityResponse), + OpenPerson(String), + DoneFetchPerson(GetPersonDetailsResponse), + OpenPost(PostId), + DoneFetchPost(GetPostResponse) +} + +#[relm4::component] +impl SimpleComponent for App { + type Init = (); + type Input = AppMsg; + type Output = (); + + view! { + gtk::Window { + set_title: Some("Lemoa"), + set_default_size: (300, 100), + + #[wrap(Some)] + set_titlebar = >k::HeaderBar { + pack_end = match model.state { + AppState::ChooseInstance => { + >k::Box {} + } + _ => { + >k::Button { + set_label: "Reset", + connect_clicked => AppMsg::ChooseInstance, + } + } + }, + pack_start = >k::Button { + set_label: "Posts", + connect_clicked => AppMsg::StartFetchPosts, + }, + pack_start = >k::Button { + set_label: "Communities", + connect_clicked => AppMsg::ViewCommunities(None), + }, + }, + + #[name(stack)] + match model.state { + AppState::Posts => gtk::ScrolledWindow { + set_vexpand: true, + set_hexpand: true, + + #[local_ref] + posts_box -> gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 5, + } + }, + AppState::Loading => gtk::Box { + set_hexpand: true, + set_orientation: gtk::Orientation::Vertical, + set_spacing: 12, + set_valign: gtk::Align::Center, + set_halign: gtk::Align::Center, + gtk::Spinner { + set_spinning: true, + set_height_request: 80, + }, + gtk::Label { + set_text: "Loading", + }, + }, + AppState::ChooseInstance => gtk::Box { + set_hexpand: true, + set_orientation: gtk::Orientation::Vertical, + set_spacing: 12, + set_margin_all: 20, + set_valign: gtk::Align::Center, + set_halign: gtk::Align::Center, + gtk::Label { + set_text: "Please enter the URL of a valid lemmy instance", + }, + #[name(instance_url)] + gtk::Entry { + set_tooltip_text: Some("Instance"), + }, + gtk::Button { + set_label: "Done", + connect_clicked[sender, instance_url] => move |_| { + let text = instance_url.buffer().text().as_str().to_string(); + instance_url.buffer().set_text(""); + sender.input(AppMsg::DoneChoosingInstance(text)); + }, + } + }, + AppState::Communities => gtk::Box { + gtk::ScrolledWindow { + set_vexpand: true, + set_hexpand: true, + + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 10, + + gtk::Box { + set_margin_all: 10, + + #[name(community_search_query)] + gtk::Entry { + set_hexpand: true, + set_tooltip_text: Some("Search"), + set_margin_end: 10, + }, + gtk::Button { + set_label: "Search", + connect_clicked[sender, community_search_query] => move |_| { + let text = community_search_query.buffer().text().as_str().to_string(); + sender.input(AppMsg::ViewCommunities(Some(text))); + }, + } + }, + + #[local_ref] + communities_box -> gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_spacing: 5, + } + } + } + } + AppState::Person => { + gtk::Box { + #[local_ref] + profile_page -> gtk::ScrolledWindow {} + } + } + AppState::Community => { + gtk::Box { + #[local_ref] + community_page -> gtk::ScrolledWindow {} + } + } + AppState::Post => { + gtk::Box { + #[local_ref] + post_page -> gtk::ScrolledWindow {} + } + } + } + } + } + + // Initialize the component. + fn init( + _init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let instance_url = settings::get_prefs().instance_url; + let state = if instance_url.is_empty() { AppState::ChooseInstance } else { AppState::Loading }; + + let posts = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); + let communities = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); + let profile_page = ProfilePage::builder().launch(default_person()).forward(sender.input_sender(), |msg| msg); + let community_page = CommunityPage::builder().launch(default_community()).forward(sender.input_sender(), |msg| msg); + let post_page = PostPage::builder().launch(default_post()).forward(sender.input_sender(), |msg| msg); + + let model = App { state, posts, communities, profile_page, community_page, post_page }; + + if !instance_url.is_empty() { sender.input(AppMsg::StartFetchPosts) }; + + let posts_box = model.posts.widget(); + let communities_box = model.communities.widget(); + let profile_page = model.profile_page.widget(); + let community_page = model.community_page.widget(); + let post_page = model.post_page.widget(); + + let widgets = view_output!(); + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: Self::Input, sender: ComponentSender) { + match msg { + AppMsg::DoneChoosingInstance(instance_url) => { + if instance_url.trim().is_empty() { return; } + let mut preferences = settings::get_prefs(); + preferences.instance_url = instance_url; + settings::save_prefs(&preferences); + self.state = AppState::Loading; + sender.input(AppMsg::StartFetchPosts); + } + AppMsg::ChooseInstance => { + self.state = AppState::ChooseInstance; + } + AppMsg::StartFetchPosts => { + std::thread::spawn(move || { + let posts = api::posts::list_posts(1, None); + sender.input(AppMsg::DoneFetchPosts(posts)); + }); + } + AppMsg::DoneFetchPosts(posts) => { + self.state = AppState::Posts; + if let Ok(posts) = posts { + self.posts.guard().clear(); + for post in posts { + self.posts.guard().push_back(post); + } + } + } + AppMsg::ViewCommunities(query) => { + self.state = AppState::Communities; + if (query.is_none() || query.clone().unwrap().trim().is_empty()) && !self.communities.is_empty() { return; } + std::thread::spawn(move || { + let communities = api::communities::fetch_communities(1, query); + sender.input(AppMsg::DoneFetchCommunities(communities)); + }); + } + AppMsg::DoneFetchCommunities(communities) => { + self.state = AppState::Communities; + if let Ok(communities) = communities { + self.communities.guard().clear(); + for community in communities { + self.communities.guard().push_back(community); + } + } + } + AppMsg::OpenPerson(person_name) => { + self.state = AppState::Loading; + std::thread::spawn(move || { + let person = api::user::get_user(person_name, 1); + if let Ok(person) = person { + sender.input(AppMsg::DoneFetchPerson(person)); + } + }); + } + AppMsg::DoneFetchPerson(person) => { + self.profile_page.sender().emit(profile_page::ProfileInput::UpdatePerson(person)); + self.state = AppState::Person; + } + AppMsg::OpenCommunity(community_name) => { + self.state = AppState::Loading; + std::thread::spawn(move || { + let community = api::community::get_community(community_name); + if let Ok(community) = community { + sender.input(AppMsg::DoneFetchCommunity(community)); + } + }); + } + AppMsg::DoneFetchCommunity(community) => { + self.community_page.sender().emit(community_page::CommunityInput::UpdateCommunity(community)); + self.state = AppState::Community; + } + AppMsg::OpenPost(post_id) => { + self.state = AppState::Loading; + std::thread::spawn(move || { + let post = api::post::get_post(post_id); + if let Ok(post) = post { + sender.input(AppMsg::DoneFetchPost(post)); + } + }); + } + AppMsg::DoneFetchPost(post) => { + self.post_page.sender().emit(post_page::PostInput::UpdatePost(post)); + self.state = AppState::Post; + } + } + } +} + +fn main() { + let app = RelmApp::new(APP_ID); + set_global_css(include_str!("style.css")); + app.run::(()); +} diff --git a/src/settings.rs b/src/settings.rs new file mode 100644 index 0000000..9dbf5a1 --- /dev/null +++ b/src/settings.rs @@ -0,0 +1,33 @@ +use std::{fs::File, path::PathBuf}; +use crate::gtk::glib; +use serde::{Deserialize, Serialize}; +use crate::APP_ID; + +#[derive(Deserialize, Serialize, Default)] +pub struct Preferences { + pub instance_url: String, +} + +pub fn data_path() -> PathBuf { + let mut path = glib::user_data_dir(); + path.push(APP_ID); + std::fs::create_dir_all(&path).expect("Could not create directory."); + path.push("data.json"); + path +} + +pub fn save_prefs(prefs: &Preferences) { + let file = File::create(data_path()).expect("Could not create json file."); + serde_json::to_writer(file, &prefs).expect("Could not write data to json file"); +} + +pub fn get_prefs() -> Preferences { + if let Ok(file) = File::open(data_path()) { + // Deserialize data from file to vector + let prefs: Result = serde_json::from_reader(file); + if prefs.is_ok() { + return prefs.unwrap(); + } + } + return Preferences::default(); +} diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..d48196b --- /dev/null +++ b/src/style.css @@ -0,0 +1,7 @@ +.font-bold { + font-size: 1.2rem; +} + +.font-very-bold { + font-size: 2rem; +} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..73000bf --- /dev/null +++ b/src/util.rs @@ -0,0 +1,14 @@ +use lemmy_api_common::lemmy_db_schema::newtypes::DbUrl; +use relm4_components::web_image::WebImageMsg; + +pub fn get_web_image_msg(url: Option) -> WebImageMsg { + return if let Some(url) = url { + WebImageMsg::LoadImage(url.to_string()) + } else { WebImageMsg::Unload }; +} + +pub fn get_web_image_url(url: Option) -> String { + return if let Some(url) = url { + url.to_string() + } else { String::from("") } +}