mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-09-20 06:34:00 +00:00
Compare commits
2 Commits
7bf17afc42
...
60e38f4868
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60e38f4868 | ||
|
|
0eb07ef9b6 |
517
composeApp/Cargo.lock
generated
517
composeApp/Cargo.lock
generated
@ -29,6 +29,20 @@ dependencies = [
|
||||
"cpufeatures 0.2.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes-gcm"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"aes",
|
||||
"cipher",
|
||||
"ctr",
|
||||
"ghash",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.103"
|
||||
@ -198,12 +212,24 @@ version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||
|
||||
[[package]]
|
||||
name = "base16ct"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
version = "0.1.10"
|
||||
@ -243,6 +269,15 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.3"
|
||||
@ -316,6 +351,15 @@ dependencies = [
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cbc"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.4.3"
|
||||
@ -350,6 +394,17 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures 0.2.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.10.1"
|
||||
@ -361,6 +416,19 @@ dependencies = [
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chacha20poly1305"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"chacha20 0.9.1",
|
||||
"cipher",
|
||||
"poly1305",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
@ -369,6 +437,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -379,6 +448,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"discord-rich-presence",
|
||||
"lofty",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"rtc",
|
||||
"thiserror 2.0.18",
|
||||
@ -396,6 +466,12 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
@ -453,6 +529,18 @@ version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core 0.6.4",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
@ -473,12 +561,49 @@ dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.2.17",
|
||||
"curve25519-dalek-derive",
|
||||
"fiat-crypto",
|
||||
"rustc_version",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der-parser"
|
||||
version = "9.0.0"
|
||||
@ -520,6 +645,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
@ -550,6 +676,41 @@ dependencies = [
|
||||
"syn 3.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.16.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
|
||||
dependencies = [
|
||||
"der",
|
||||
"digest",
|
||||
"elliptic-curve",
|
||||
"rfc6979",
|
||||
"signature",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve"
|
||||
version = "0.13.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"crypto-bigint",
|
||||
"digest",
|
||||
"ff",
|
||||
"generic-array",
|
||||
"group",
|
||||
"hkdf",
|
||||
"pem-rfc7468",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"sec1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@ -592,6 +753,22 @@ version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
|
||||
|
||||
[[package]]
|
||||
name = "ff"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fiat-crypto"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.11"
|
||||
@ -722,6 +899,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -747,6 +925,16 @@ dependencies = [
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghash"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
|
||||
dependencies = [
|
||||
"opaque-debug",
|
||||
"polyval",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
@ -764,6 +952,17 @@ dependencies = [
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "group"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
||||
dependencies = [
|
||||
"ff",
|
||||
"rand_core 0.6.4",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.1"
|
||||
@ -782,6 +981,15 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hkdf"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
|
||||
dependencies = [
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
@ -911,6 +1119,7 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
@ -1158,6 +1367,36 @@ version = "1.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "p256"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
|
||||
dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "p384"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6"
|
||||
dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.1"
|
||||
@ -1203,6 +1442,15 @@ dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
@ -1215,12 +1463,45 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||
dependencies = [
|
||||
"der",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "poly1305"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
|
||||
dependencies = [
|
||||
"cpufeatures 0.2.17",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.2.17",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.6"
|
||||
@ -1236,6 +1517,15 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "primeorder"
|
||||
version = "0.13.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
|
||||
dependencies = [
|
||||
"elliptic-curve",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
@ -1308,7 +1598,7 @@ version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
|
||||
dependencies = [
|
||||
"chacha20",
|
||||
"chacha20 0.10.1",
|
||||
"getrandom 0.4.3",
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
@ -1360,6 +1650,16 @@ dependencies = [
|
||||
"bytecheck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfc6979"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
||||
dependencies = [
|
||||
"hmac",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
@ -1406,15 +1706,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9005c36795ad076abd36db3ea9ae0275a60395944647d58c1f2bc3e118dddba"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hex",
|
||||
"log",
|
||||
"pem",
|
||||
"rand",
|
||||
"rcgen",
|
||||
"rtc-crypto",
|
||||
"ring",
|
||||
"rtc-datachannel",
|
||||
"rtc-dtls",
|
||||
"rtc-ice",
|
||||
@ -1433,31 +1734,16 @@ dependencies = [
|
||||
"sansio",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"unicase",
|
||||
"url",
|
||||
"x509-parser 0.16.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-crypto"
|
||||
version = "0.21.0-beta.1"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"ccm",
|
||||
"ctr",
|
||||
"hmac",
|
||||
"md-5",
|
||||
"rand",
|
||||
"ring",
|
||||
"sha1",
|
||||
"subtle",
|
||||
"thiserror 2.0.18",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-datachannel"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b61c7b8e9892094cba8a6c7fb8120ae863d32d432b00e560177b3d7ae6d2c6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"log",
|
||||
@ -1468,30 +1754,47 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-dtls"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c737b1dd17a0ff63884a2f466b9588f0cffadfce5a724c0c368764d7c27f9c74"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bytecheck",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"cbc",
|
||||
"ccm",
|
||||
"chacha20poly1305",
|
||||
"der-parser 9.0.0",
|
||||
"hmac",
|
||||
"log",
|
||||
"pem",
|
||||
"p256",
|
||||
"p384",
|
||||
"rand",
|
||||
"rand_core 0.6.4",
|
||||
"rcgen",
|
||||
"ring",
|
||||
"rkyv",
|
||||
"rtc-crypto",
|
||||
"rtc-shared",
|
||||
"rustls",
|
||||
"sec1",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"x25519-dalek",
|
||||
"x509-parser 0.16.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-ice"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c06eeabd250a7693e1e8b28222b78c4a81a7c6ca7fe3cb99bbdff2f6c0ff0ab"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"crc",
|
||||
"log",
|
||||
"rtc-crypto",
|
||||
"rand",
|
||||
"rtc-mdns",
|
||||
"rtc-shared",
|
||||
"rtc-stun",
|
||||
@ -1503,19 +1806,35 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-interceptor"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ec2776ab86c0c03c3de8ec742aa13ccc3b2c82317590d0624f251bd37eae3b9"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rand",
|
||||
"rtc-interceptor-derive",
|
||||
"rtc-rtcp",
|
||||
"rtc-rtp",
|
||||
"rtc-shared",
|
||||
"sansio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-interceptor-derive"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc31da3875839bc18e00997354a582e6decacdb23d39f8c004fc4fe2fd3fcd8b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-mdns"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28cd53120b83321c8b8310cce9512c685d2d6356acef34647a99ea420e6f2249"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"log",
|
||||
@ -1526,7 +1845,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-media"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0411e44fcdc1363487ae0c6a4612ec908b9b09175d05499c5de0b3c81f0b5e5"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
@ -1538,7 +1859,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-rtcp"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fceaadac17b114140368dd68478d186ccfc293970f79cb8dd28f94dbbc0300be"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"rtc-shared",
|
||||
@ -1546,7 +1869,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-rtp"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "babb45ac2263340e2bb412d1921aa07ca441ae9b5589477221d1a50d98750ba3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
@ -1557,7 +1882,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-sctp"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2513391b524b88b041277faba617e0531ad726729861ea8933015393fd68ab05"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"crc32c",
|
||||
@ -1571,7 +1898,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-sdp"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42d136a422965289e3d32d8e110789d8fa2ac669a4474a4084fa1eeac32758ee"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rtc-shared",
|
||||
@ -1580,12 +1909,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-shared"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce81c72adbce3a2f2ad8e2b97674d2482be83cb3bfd9a153341b04b1a87ca24"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"nix",
|
||||
"p256",
|
||||
"rand",
|
||||
"rcgen",
|
||||
"sec1",
|
||||
"serde",
|
||||
"substring",
|
||||
"thiserror 2.0.18",
|
||||
@ -1595,38 +1931,50 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rtc-srtp"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b880d5f6d436b3215c7bcfd3fb5ffe2a752fea0236440ccd98b6bf1c3561df8"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"rtc-crypto",
|
||||
"ctr",
|
||||
"hmac",
|
||||
"ring",
|
||||
"rtc-rtcp",
|
||||
"rtc-rtp",
|
||||
"rtc-shared",
|
||||
"sha1",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-stun"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06b19c36a200df6071b92a25583a19ab0f9c6d5ad036d8c3ff5d392802cc926e"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"crc",
|
||||
"lazy_static",
|
||||
"md-5",
|
||||
"rand",
|
||||
"rtc-crypto",
|
||||
"ring",
|
||||
"rtc-shared",
|
||||
"sansio",
|
||||
"subtle",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtc-turn"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebf0b5fbb94085c86be7277c38ae8f1c21ec75ab47ba975be0984409732020dd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"log",
|
||||
"rtc-crypto",
|
||||
"rtc-shared",
|
||||
"rtc-stun",
|
||||
"sansio",
|
||||
@ -1741,6 +2089,20 @@ dependencies = [
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sec1"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"der",
|
||||
"generic-array",
|
||||
"pkcs8",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.28"
|
||||
@ -1816,12 +2178,33 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.2.17",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.10"
|
||||
@ -1868,6 +2251,16 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.1"
|
||||
@ -2217,6 +2610,16 @@ dependencies = [
|
||||
"weedle2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
@ -2320,7 +2723,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webrtc"
|
||||
version = "0.21.0-beta.1"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3daa8f2f6366331ae3275a6c02a855c6fb3faa1d16960498d7daaf61c96e76bd"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-channel",
|
||||
@ -2468,6 +2873,18 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc"
|
||||
|
||||
[[package]]
|
||||
name = "x25519-dalek"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x509-parser"
|
||||
version = "0.16.0"
|
||||
@ -2562,6 +2979,20 @@ name = "zeroize"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
|
||||
@ -9,8 +9,9 @@ lofty = "0.24.0"
|
||||
discord-rich-presence = "1.1.0"
|
||||
thiserror = "2.0"
|
||||
parking_lot = "0.12"
|
||||
webrtc = { path = "../build/webrtc-rs" }
|
||||
rtc = { path = "../build/webrtc-rs/rtc" }
|
||||
log = "0.4"
|
||||
webrtc = "0.20.4"
|
||||
rtc = "0.20.4"
|
||||
async-trait = "0.1"
|
||||
bytes = "1"
|
||||
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
||||
|
||||
@ -74,6 +74,9 @@ class JamSessionService(
|
||||
private val _localParticipantId = MutableStateFlow<String?>(null)
|
||||
val localParticipantId: StateFlow<String?> = _localParticipantId.asStateFlow()
|
||||
|
||||
private val _isConnected = MutableStateFlow(false)
|
||||
val isConnected: StateFlow<Boolean> = _isConnected.asStateFlow()
|
||||
|
||||
private val _incomingMessages = MutableSharedFlow<JamMessage>(extraBufferCapacity = 64)
|
||||
val incomingMessages = _incomingMessages.asSharedFlow()
|
||||
|
||||
@ -121,7 +124,7 @@ class JamSessionService(
|
||||
log.i { "Generating invite $inviteId" }
|
||||
|
||||
val pc = createWebrtcPeerConnection(
|
||||
iceServers = listOf(defaultIceServer()),
|
||||
iceServers = defaultIceServers(),
|
||||
handler = guestEventHandler(inviteId),
|
||||
)
|
||||
|
||||
@ -174,18 +177,25 @@ class JamSessionService(
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun joinSession(offerSdp: String): String {
|
||||
suspend fun joinSession(offerSdp: String, hostName: String? = null): String {
|
||||
log.i { "Joining jam session" }
|
||||
val participantName = resolveParticipantName(defaultPrefix = "Guest")
|
||||
|
||||
val pc = createWebrtcPeerConnection(
|
||||
iceServers = listOf(defaultIceServer()),
|
||||
iceServers = defaultIceServers(),
|
||||
handler = eventHandler,
|
||||
)
|
||||
|
||||
hostConnection = pc
|
||||
_role.value = JamRole.Guest
|
||||
_localParticipantId.value = "guest"
|
||||
_participants.value = listOf(
|
||||
JamParticipant(
|
||||
id = "host",
|
||||
displayName = hostName?.ifBlank { null } ?: "Host",
|
||||
isHost = true,
|
||||
)
|
||||
)
|
||||
_isActive.value = true
|
||||
|
||||
// The data channel arrives in-band from the host's offer via on_data_channel;
|
||||
@ -226,6 +236,7 @@ class JamSessionService(
|
||||
_role.value = null
|
||||
_participants.value = emptyList()
|
||||
_isActive.value = false
|
||||
_isConnected.value = false
|
||||
_localParticipantId.value = null
|
||||
}
|
||||
|
||||
@ -254,10 +265,28 @@ class JamSessionService(
|
||||
sendMessage(JamMessage.SuggestPlaylist(tracks))
|
||||
}
|
||||
|
||||
private fun defaultIceServer() = IceServerConfig(
|
||||
urls = listOf("stun:stun.l.google.com:19302"),
|
||||
username = "",
|
||||
credential = "",
|
||||
/**
|
||||
* ICE servers for global peer-to-peer jam sessions: multiple STUN servers for
|
||||
* NAT traversal plus a TURN relay for symmetric NATs and strict firewalls.
|
||||
* Unreachable servers no longer stall offer/answer creation — the webrtc
|
||||
* driver completes gathering once every STUN client has answered or timed out,
|
||||
* and [WebrtcPeerConnection] bounds the wait anyway.
|
||||
*/
|
||||
private fun defaultIceServers(): List<IceServerConfig> = listOf(
|
||||
IceServerConfig(
|
||||
urls = listOf(
|
||||
"stun:stun.cloudflare.com:3478",
|
||||
"stun:stun1.l.google.com:19302",
|
||||
"stun:stun.l.google.com:19302",
|
||||
),
|
||||
username = "",
|
||||
credential = "",
|
||||
),
|
||||
IceServerConfig(
|
||||
urls = listOf("turn:openrelay.metered.ca:80"),
|
||||
username = "openrelayproject",
|
||||
credential = "openrelayproject",
|
||||
),
|
||||
)
|
||||
|
||||
private suspend fun resolveParticipantName(defaultPrefix: String): String {
|
||||
@ -271,10 +300,12 @@ class JamSessionService(
|
||||
* attributed back to that guest (needed for kick-on-leave and targeted sends).
|
||||
*/
|
||||
private fun guestEventHandler(guestId: String) = object : WebrtcEventHandler {
|
||||
override fun onIceCandidate(candidate: String) {}
|
||||
override fun onIceCandidate(candidate: String) {
|
||||
log.i { "[$guestId] ICE candidate: $candidate" }
|
||||
}
|
||||
|
||||
override fun onIceGatheringStateChange(state: String) {
|
||||
log.d { "[$guestId] ICE gathering state: $state" }
|
||||
log.i { "[$guestId] ICE gathering state: $state" }
|
||||
}
|
||||
|
||||
override fun onConnectionStateChange(state: String) {
|
||||
@ -283,6 +314,7 @@ class JamSessionService(
|
||||
|
||||
override fun onDataChannelOpen(label: String) {
|
||||
log.i { "[$guestId] Data channel '$label' open" }
|
||||
_isConnected.value = true
|
||||
}
|
||||
|
||||
override fun onDataChannelMessage(label: String, data: String) {
|
||||
@ -295,10 +327,12 @@ class JamSessionService(
|
||||
}
|
||||
|
||||
private val eventHandler = object : WebrtcEventHandler {
|
||||
override fun onIceCandidate(candidate: String) {}
|
||||
override fun onIceCandidate(candidate: String) {
|
||||
log.i { "ICE candidate: $candidate" }
|
||||
}
|
||||
|
||||
override fun onIceGatheringStateChange(state: String) {
|
||||
log.d { "ICE gathering state: $state" }
|
||||
log.i { "ICE gathering state: $state" }
|
||||
}
|
||||
|
||||
override fun onConnectionStateChange(state: String) {
|
||||
@ -307,6 +341,7 @@ class JamSessionService(
|
||||
|
||||
override fun onDataChannelOpen(label: String) {
|
||||
log.i { "Data channel '$label' open" }
|
||||
_isConnected.value = true
|
||||
}
|
||||
|
||||
override fun onDataChannelMessage(label: String, data: String) {
|
||||
|
||||
@ -128,17 +128,19 @@ fun HomeScreen(viewModel: HomeScreenViewModel) {
|
||||
Text("Browse")
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { navigationCommands.navigateTo(Routes.Devices) }) {
|
||||
Icon(
|
||||
imageVector = Iconsax.IconsaxMirroringScreen,
|
||||
contentDescription = "Devices",
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { navigationCommands.navigateTo(Routes.Jam) }) {
|
||||
Icon(
|
||||
imageVector = Iconsax.User,
|
||||
contentDescription = "Group Jam",
|
||||
)
|
||||
if (!isDesktop) {
|
||||
IconButton(onClick = { navigationCommands.navigateTo(Routes.Devices) }) {
|
||||
Icon(
|
||||
imageVector = Iconsax.IconsaxMirroringScreen,
|
||||
contentDescription = "Devices",
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { navigationCommands.navigateTo(Routes.Jam) }) {
|
||||
Icon(
|
||||
imageVector = Iconsax.User,
|
||||
contentDescription = "Group Jam",
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -355,7 +357,7 @@ private fun HomeSection(
|
||||
if (!subtitle.isNullOrEmpty()) Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.labelMedium.copy(
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
fontWeight = FontWeight.Medium,
|
||||
),
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
|
||||
@ -53,6 +53,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import dev.krtirtho.spotube.core.jam.JamRole
|
||||
import dev.krtirtho.spotube.core.navigation.NavigationCommands
|
||||
import dev.krtirtho.spotube.core.ui.component.ApplicationMainBar
|
||||
import dev.krtirtho.spotube.modules.shell.LocalAppShellBottomInset
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
|
||||
@Composable
|
||||
@ -61,6 +62,7 @@ fun JamScreen(
|
||||
) {
|
||||
val viewModel = koinViewModel<JamViewModel>()
|
||||
val state by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
val shellBottomInset = LocalAppShellBottomInset.current
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
@ -75,6 +77,7 @@ fun JamScreen(
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding)
|
||||
.padding(16.dp)
|
||||
.padding(bottom = shellBottomInset)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
@ -292,23 +295,35 @@ private fun GuestSessionView(
|
||||
ParticipantsSection(state.participants)
|
||||
|
||||
val answerLink = state.answerLink
|
||||
if (answerLink == null) {
|
||||
Text(
|
||||
text = "Connecting to the session...",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = "Almost there! Send your answer back to the host:",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
ShareableLinkBox(
|
||||
label = "Answer link",
|
||||
link = answerLink,
|
||||
onCopy = { clipboard.setText(AnnotatedString(answerLink)) },
|
||||
onShare = { onShare(answerLink) },
|
||||
)
|
||||
when {
|
||||
state.isConnected -> {
|
||||
Text(
|
||||
text = "Connected to the session",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
|
||||
answerLink == null -> {
|
||||
Text(
|
||||
text = "Connecting to the session...",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
Text(
|
||||
text = "Almost there! Send your answer back to the host:",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
ShareableLinkBox(
|
||||
label = "Answer link",
|
||||
link = answerLink,
|
||||
onCopy = { clipboard.setText(AnnotatedString(answerLink)) },
|
||||
onShare = { onShare(answerLink) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LeaveButton(onLeave)
|
||||
|
||||
@ -37,6 +37,7 @@ import kotlinx.coroutines.launch
|
||||
|
||||
data class JamUiState(
|
||||
val isActive: Boolean = false,
|
||||
val isConnected: Boolean = false,
|
||||
val role: JamRole? = null,
|
||||
val participants: List<JamParticipant> = emptyList(),
|
||||
/** Host: deep link containing this session's SDP offer, ready to share. */
|
||||
@ -69,6 +70,7 @@ class JamViewModel(
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isActive = active,
|
||||
isConnected = jamSession.isConnected.value,
|
||||
role = jamSession.role.value,
|
||||
participants = jamSession.participants.value,
|
||||
inviteLink = if (!active) null else it.inviteLink,
|
||||
@ -84,6 +86,11 @@ class JamViewModel(
|
||||
_uiState.update { it.copy(participants = participants) }
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
jamSession.isConnected.collect { connected ->
|
||||
_uiState.update { it.copy(isConnected = connected) }
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
deepLinks.pendingLink.collect { link ->
|
||||
handleDeepLink(link)
|
||||
@ -119,16 +126,17 @@ class JamViewModel(
|
||||
|
||||
fun joinWithIncomingInvite() {
|
||||
val sdp = _uiState.value.incomingOfferSdp ?: return
|
||||
join(sdp)
|
||||
join(sdp, _uiState.value.incomingHostName)
|
||||
}
|
||||
|
||||
fun joinWithPasted(input: String) {
|
||||
val sdp = JamInviteCodec.extractSdp(input)
|
||||
val parsed = JamInviteCodec.parse(input)
|
||||
val sdp = parsed?.sdp ?: JamInviteCodec.extractSdp(input)
|
||||
if (sdp == null) {
|
||||
_uiState.update { it.copy(error = "That doesn't look like a valid jam invite.") }
|
||||
return
|
||||
}
|
||||
join(sdp)
|
||||
join(sdp, (parsed as? JamInviteLink.HostInvite)?.peerName)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,10 +179,10 @@ class JamViewModel(
|
||||
_uiState.update { it.copy(incomingOfferSdp = null, incomingHostName = null) }
|
||||
}
|
||||
|
||||
private fun join(offerSdp: String) {
|
||||
private fun join(offerSdp: String, hostName: String? = null) {
|
||||
viewModelScope.launch {
|
||||
runCatching {
|
||||
val answer = jamSession.joinSession(offerSdp)
|
||||
val answer = jamSession.joinSession(offerSdp, hostName)
|
||||
JamInviteCodec.buildGuestAnswer(localName(), answer)
|
||||
}.onSuccess { link ->
|
||||
_uiState.update {
|
||||
|
||||
@ -16,9 +16,12 @@
|
||||
*/
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use rtc::ice::mdns::MulticastDnsMode;
|
||||
use rtc::peer_connection::configuration::interceptor_registry::register_default_interceptors;
|
||||
use rtc::peer_connection::configuration::setting_engine::SettingEngine;
|
||||
use webrtc::data_channel::{DataChannel, DataChannelEvent, RTCDataChannelInit};
|
||||
use webrtc::peer_connection::{
|
||||
MediaEngine, PeerConnection, PeerConnectionBuilder, PeerConnectionEventHandler,
|
||||
@ -111,6 +114,13 @@ pub async fn create_webrtc_peer_connection(
|
||||
)
|
||||
.build();
|
||||
|
||||
// mDNS adds a multicast UDP socket per peer connection. On some platforms
|
||||
// (notably Android) that socket can stall and ICE gathering then never
|
||||
// completes. Real-IP host candidates (no mDNS) work fine alongside STUN/TURN,
|
||||
// so mDNS is disabled.
|
||||
let mut setting_engine = SettingEngine::default();
|
||||
setting_engine.set_multicast_dns_mode(MulticastDnsMode::Disabled);
|
||||
|
||||
let (gather_tx, gather_rx) = channel::<()>(1);
|
||||
let pc_handler = Arc::new(PeerHandlerBridge {
|
||||
handler: Arc::clone(&handler),
|
||||
@ -119,6 +129,7 @@ pub async fn create_webrtc_peer_connection(
|
||||
|
||||
let pc = PeerConnectionBuilder::new()
|
||||
.with_configuration(config)
|
||||
.with_setting_engine(setting_engine)
|
||||
.with_media_engine(media_engine)
|
||||
.with_interceptor_registry(registry)
|
||||
.with_handler(pc_handler)
|
||||
@ -138,9 +149,20 @@ impl WebrtcPeerConnection {
|
||||
/// Waits for ICE gathering to reach `Complete` so the local SDP includes all
|
||||
/// candidates (non-trickle exchange). Must be called after `set_local_description`,
|
||||
/// which is what starts gathering.
|
||||
///
|
||||
/// Bounded by a timeout so a stalled gatherer (e.g. a platform that never reports
|
||||
/// completion) can never hang `create_offer`/`create_answer` forever — the SDP
|
||||
/// with the candidates gathered so far is returned instead.
|
||||
async fn wait_for_ice_gathering(&self) {
|
||||
let mut gather_rx = self.gather_rx.lock().clone();
|
||||
let _ = gather_rx.recv().await;
|
||||
match tokio::time::timeout(Duration::from_secs(5), gather_rx.recv()).await {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
log::warn!(
|
||||
"ICE gathering did not complete within 5s; returning SDP with the candidates gathered so far"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user