Sound works

This commit is contained in:
2026-04-19 22:56:58 +03:00
parent f0379925f1
commit 7a7ec13cb2
5 changed files with 528 additions and 1 deletions
Generated
+441
View File
@@ -32,6 +32,28 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "alsa"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812947049edcd670a82cd5c73c3661d2e58468577ba8489de58e1a73c04cbd5d"
dependencies = [
"alsa-sys",
"bitflags 2.10.0",
"cfg-if",
"libc",
]
[[package]]
name = "alsa-sys"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad7569085a265dd3f607ebecce7458eaab2132a84393534c95b18dcbc3f31e04"
dependencies = [
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "android-activity" name = "android-activity"
version = "0.6.0" version = "0.6.0"
@@ -292,6 +314,15 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]]
name = "block-buffer"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
dependencies = [
"hybrid-array",
]
[[package]] [[package]]
name = "block2" name = "block2"
version = "0.5.1" version = "0.5.1"
@@ -529,6 +560,12 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "const-oid"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
[[package]] [[package]]
name = "const-random" name = "const-random"
version = "0.1.18" version = "0.1.18"
@@ -619,6 +656,20 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "coreaudio-rs"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16dd574a72a021b90c7656c474ea31d11a2f0366a8eff574186e761e0b9e3586"
dependencies = [
"bitflags 2.10.0",
"libc",
"objc2-audio-toolbox",
"objc2-core-audio",
"objc2-core-audio-types",
"objc2-core-foundation",
]
[[package]] [[package]]
name = "cosmic-text" name = "cosmic-text"
version = "0.15.0" version = "0.15.0"
@@ -643,6 +694,36 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "cpal"
version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8942da362c0f0d895d7cac616263f2f9424edc5687364dfd1d25ef7eba506d7"
dependencies = [
"alsa",
"coreaudio-rs",
"dasp_sample",
"jni",
"js-sys",
"libc",
"mach2",
"ndk",
"ndk-context",
"num-derive",
"num-traits",
"objc2 0.6.3",
"objc2-audio-toolbox",
"objc2-avf-audio",
"objc2-core-audio",
"objc2-core-audio-types",
"objc2-core-foundation",
"objc2-foundation 0.3.2",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows 0.62.2",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.3.0" version = "0.3.0"
@@ -677,6 +758,15 @@ dependencies = [
"wgpu", "wgpu",
] ]
[[package]]
name = "crypto-common"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
dependencies = [
"hybrid-array",
]
[[package]] [[package]]
name = "ctor-lite" name = "ctor-lite"
version = "0.1.1" version = "0.1.1"
@@ -689,6 +779,23 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
[[package]]
name = "dasp_sample"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
[[package]]
name = "digest"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
]
[[package]] [[package]]
name = "dirs" name = "dirs"
version = "6.0.0" version = "6.0.0"
@@ -865,6 +972,12 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
] ]
[[package]]
name = "extended"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365"
[[package]] [[package]]
name = "fallible-iterator" name = "fallible-iterator"
version = "0.3.0" version = "0.3.0"
@@ -1373,6 +1486,15 @@ version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "hybrid-array"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214"
dependencies = [
"typenum",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.9.0" version = "1.9.0"
@@ -1529,6 +1651,7 @@ dependencies = [
"iced_core", "iced_core",
"log", "log",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
"tokio",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasmtimer", "wasmtimer",
] ]
@@ -1807,13 +1930,17 @@ version = "0.1.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"dirs", "dirs",
"hex",
"iced", "iced",
"rand", "rand",
"reqwest", "reqwest",
"rhai", "rhai",
"rodio",
"rusqlite", "rusqlite",
"serde", "serde",
"serde_json", "serde_json",
"sha2",
"tokio",
] ]
[[package]] [[package]]
@@ -1885,6 +2012,12 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "leb128fmt" name = "leb128fmt"
version = "0.1.0" version = "0.1.0"
@@ -1994,6 +2127,15 @@ version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
[[package]]
name = "mach2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a1b95cd5421ec55b445b5ae102f5ea0e768de1f82bd3001e11f426c269c3aea"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "malloc_buf" name = "malloc_buf"
version = "0.0.6" version = "0.0.6"
@@ -2157,6 +2299,47 @@ dependencies = [
"jni-sys", "jni-sys",
] ]
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-bigint",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@@ -2270,6 +2453,31 @@ dependencies = [
"objc2-quartz-core 0.3.2", "objc2-quartz-core 0.3.2",
] ]
[[package]]
name = "objc2-audio-toolbox"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08"
dependencies = [
"bitflags 2.10.0",
"libc",
"objc2 0.6.3",
"objc2-core-audio",
"objc2-core-audio-types",
"objc2-core-foundation",
"objc2-foundation 0.3.2",
]
[[package]]
name = "objc2-avf-audio"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be"
dependencies = [
"objc2 0.6.3",
"objc2-foundation 0.3.2",
]
[[package]] [[package]]
name = "objc2-cloud-kit" name = "objc2-cloud-kit"
version = "0.2.2" version = "0.2.2"
@@ -2305,6 +2513,29 @@ dependencies = [
"objc2-foundation 0.2.2", "objc2-foundation 0.2.2",
] ]
[[package]]
name = "objc2-core-audio"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2"
dependencies = [
"dispatch2",
"objc2 0.6.3",
"objc2-core-audio-types",
"objc2-core-foundation",
"objc2-foundation 0.3.2",
]
[[package]]
name = "objc2-core-audio-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c"
dependencies = [
"bitflags 2.10.0",
"objc2 0.6.3",
]
[[package]] [[package]]
name = "objc2-core-data" name = "objc2-core-data"
version = "0.2.2" version = "0.2.2"
@@ -2335,7 +2566,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"block2 0.6.2",
"dispatch2", "dispatch2",
"libc",
"objc2 0.6.3", "objc2 0.6.3",
] ]
@@ -2864,6 +3097,16 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
[[package]]
name = "rand_distr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d431c2703ccf129de4d45253c03f49ebb22b97d6ad79ee3ecfc7e3f4862c1d8"
dependencies = [
"num-traits",
"rand",
]
[[package]] [[package]]
name = "range-alloc" name = "range-alloc"
version = "0.1.4" version = "0.1.4"
@@ -3022,6 +3265,22 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "rodio"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a536bb79db59098ef71a4dd4246c02eb87b316deceb1b68e0cde7167ec01eb"
dependencies = [
"cpal",
"dasp_sample",
"num-rational",
"rand",
"rand_distr",
"rtrb",
"symphonia",
"thiserror 2.0.18",
]
[[package]] [[package]]
name = "roxmltree" name = "roxmltree"
version = "0.20.0" version = "0.20.0"
@@ -3038,6 +3297,12 @@ dependencies = [
"thiserror 2.0.18", "thiserror 2.0.18",
] ]
[[package]]
name = "rtrb"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7204ed6420f698836b76d4d5c2ec5dec7585fd5c3a788fd1cde855d1de598239"
[[package]] [[package]]
name = "rusqlite" name = "rusqlite"
version = "0.39.0" version = "0.39.0"
@@ -3281,6 +3546,17 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "sha2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
@@ -3514,6 +3790,153 @@ dependencies = [
"zeno", "zeno",
] ]
[[package]]
name = "symphonia"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5773a4c030a19d9bfaa090f49746ff35c75dfddfa700df7a5939d5e076a57039"
dependencies = [
"lazy_static",
"symphonia-bundle-flac",
"symphonia-bundle-mp3",
"symphonia-codec-aac",
"symphonia-codec-pcm",
"symphonia-codec-vorbis",
"symphonia-core",
"symphonia-format-isomp4",
"symphonia-format-ogg",
"symphonia-format-riff",
"symphonia-metadata",
]
[[package]]
name = "symphonia-bundle-flac"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c91565e180aea25d9b80a910c546802526ffd0072d0b8974e3ebe59b686c9976"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-bundle-mp3"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4872dd6bb56bf5eac799e3e957aa1981086c3e613b27e0ac23b176054f7c57ed"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
"symphonia-metadata",
]
[[package]]
name = "symphonia-codec-aac"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c263845aa86881416849c1729a54c7f55164f8b96111dba59de46849e73a790"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-codec-pcm"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e89d716c01541ad3ebe7c91ce4c8d38a7cf266a3f7b2f090b108fb0cb031d95"
dependencies = [
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-codec-vorbis"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f025837c309cd69ffef572750b4a2257b59552c5399a5e49707cc5b1b85d1c73"
dependencies = [
"log",
"symphonia-core",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-core"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea00cc4f79b7f6bb7ff87eddc065a1066f3a43fe1875979056672c9ef948c2af"
dependencies = [
"arrayvec",
"bitflags 1.3.2",
"bytemuck",
"lazy_static",
"log",
]
[[package]]
name = "symphonia-format-isomp4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "243739585d11f81daf8dac8d9f3d18cc7898f6c09a259675fc364b382c30e0a5"
dependencies = [
"encoding_rs",
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-format-ogg"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b4955c67c1ed3aa8ae8428d04ca8397fbef6a19b2b051e73b5da8b1435639cb"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-format-riff"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2d7c3df0e7d94efb68401d81906eae73c02b40d5ec1a141962c592d0f11a96f"
dependencies = [
"extended",
"log",
"symphonia-core",
"symphonia-metadata",
]
[[package]]
name = "symphonia-metadata"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36306ff42b9ffe6e5afc99d49e121e0bd62fe79b9db7b9681d48e29fa19e6b16"
dependencies = [
"encoding_rs",
"lazy_static",
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-utils-xiph"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27c85ab799a338446b68eec77abf42e1a6f1bb490656e121c6e27bfbab9f16"
dependencies = [
"symphonia-core",
"symphonia-metadata",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.114" version = "2.0.114"
@@ -3726,9 +4149,21 @@ dependencies = [
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio-macros",
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "tokio-macros"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tokio-native-tls" name = "tokio-native-tls"
version = "0.3.1" version = "0.3.1"
@@ -3884,6 +4319,12 @@ dependencies = [
"core_maths", "core_maths",
] ]
[[package]]
name = "typenum"
version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]] [[package]]
name = "uds_windows" name = "uds_windows"
version = "1.1.0" version = "1.1.0"
+5 -1
View File
@@ -4,7 +4,7 @@ version = "0.1.1"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
iced = { version = "0.14.0"} iced = { version = "0.14.0", features = ["tokio"]}
rand = "0.10.0" rand = "0.10.0"
dirs = "6.0.0" dirs = "6.0.0"
serde = { version = "1.0.144", features = ["derive"] } serde = { version = "1.0.144", features = ["derive"] }
@@ -13,4 +13,8 @@ rhai = "1.24.0"
chrono = "0.4.44" chrono = "0.4.44"
rusqlite = { version = "0.39.0", features = ["chrono"] } rusqlite = { version = "0.39.0", features = ["chrono"] }
reqwest = { version = "0.12", features = ["json", "stream"] } reqwest = { version = "0.12", features = ["json", "stream"] }
rodio = "0.22.2"
sha2 = "0.11.0"
hex = "0.4.3"
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros"] }
+1
View File
@@ -1,4 +1,5 @@
pub(crate) mod words; pub(crate) mod words;
pub(crate) mod card_sets; pub(crate) mod card_sets;
pub(crate) mod card_stats; pub(crate) mod card_stats;
pub(crate) mod voice;
+39
View File
@@ -0,0 +1,39 @@
use crate::dictionary::app_data_dir;
use rodio::Decoder;
use sha2::{Digest, Sha256};
use std::fs::File;
use std::io::BufReader;
use reqwest::Client;
pub async fn get_voice(text: &str) -> BufReader<File> {
let mut path = app_data_dir();
path.push("voice");
if !path.exists() {
std::fs::create_dir(path.clone()).unwrap();
}
let hash = format!("{}.wav", hex::encode(Sha256::digest(text.as_bytes())));
path.push(hash);
if !path.exists() {
let engine_url = "http://127.0.0.1:50021";
let client = Client::new();
let query = client
.post(format!("{engine_url}/audio_query?text={text}&speaker=11"))
.send()
.await;
let query = query.unwrap().text().await.unwrap();
// Synthesis
let audio = client
.post(format!("{engine_url}/synthesis?speaker=11"))
.header("Content-Type", "application/json")
.body(query)
.send()
.await.unwrap()
.bytes()
.await.unwrap();
tokio::fs::write(&path, &audio).await.unwrap();
}
BufReader::new(File::open(path).unwrap())
}
+42
View File
@@ -1,3 +1,4 @@
use crate::data_provider::voice::get_voice;
use crate::lang::{CardSet, DictionaryElement, WordOpenMode}; use crate::lang::{CardSet, DictionaryElement, WordOpenMode};
use crate::repetitions::CardSetSettings; use crate::repetitions::CardSetSettings;
use crate::Page::PreviousPage; use crate::Page::PreviousPage;
@@ -6,7 +7,9 @@ use iced::alignment::Horizontal::Center;
use iced::keyboard::key::Physical::Code; use iced::keyboard::key::Physical::Code;
use iced::widget::{button, column, container, row, rule, space, text}; use iced::widget::{button, column, container, row, rule, space, text};
use iced::{alignment, keyboard, Element, Fill, Left, Task}; use iced::{alignment, keyboard, Element, Fill, Left, Task};
use rodio::MixerDeviceSink;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tokio::task::spawn_blocking;
pub struct RepetitionState { pub struct RepetitionState {
pub settings: CardSetSettings, pub settings: CardSetSettings,
@@ -14,6 +17,8 @@ pub struct RepetitionState {
pub state: Arc<Mutex<AppState>>, pub state: Arc<Mutex<AppState>>,
current_word: DictionaryElement, current_word: DictionaryElement,
open: bool, open: bool,
can_play: bool,
sink: Arc<MixerDeviceSink>,
} }
impl NavigatedPage<RepetitionMessage> for RepetitionState { impl NavigatedPage<RepetitionMessage> for RepetitionState {
@@ -30,12 +35,16 @@ impl RepetitionState {
pub(crate) fn new(set: CardSetSettings, state: Arc<Mutex<AppState>>) -> RepetitionState { pub(crate) fn new(set: CardSetSettings, state: Arc<Mutex<AppState>>) -> RepetitionState {
let mut card_set = CardSet::new(&set, state.clone()); let mut card_set = CardSet::new(&set, state.clone());
let word = card_set.next(); let word = card_set.next();
let sink_handle = rodio::DeviceSinkBuilder::open_default_sink().unwrap();
RepetitionState { RepetitionState {
settings: set, settings: set,
set: card_set, set: card_set,
state, state,
current_word: word, current_word: word,
open: false, open: false,
can_play: true,
sink: Arc::new(sink_handle)
} }
} }
} }
@@ -46,11 +55,26 @@ impl RepetitionState {
RepetitionMessage::Back => {} RepetitionMessage::Back => {}
RepetitionMessage::Next => self.next(), RepetitionMessage::Next => self.next(),
RepetitionMessage::Answer(m) => self.answer(m), RepetitionMessage::Answer(m) => self.answer(m),
RepetitionMessage::Play => {
if !self.can_play {
return Task::none()
}
self.can_play = false;
let value = self.current_word.key.clone();
return Task::perform(play_sound(self.sink.clone(), value), |_| RootMessage::Repetition(RepetitionMessage::PlayFinished));
},
RepetitionMessage::PlayFinished => {
self.can_play = true;
}
} }
Task::none() Task::none()
} }
fn next(&mut self) { fn next(&mut self) {
if self.open { if self.open {
self.set.open(WordOpenMode::None); self.set.open(WordOpenMode::None);
@@ -109,6 +133,7 @@ impl RepetitionState {
match self.settings.forward.as_str() { match self.settings.forward.as_str() {
"key" => self.draw_key(word), "key" => self.draw_key(word),
"value" => self.draw_value(word), "value" => self.draw_value(word),
"speech" => self.draw_voice(word),
_ => space().into(), _ => space().into(),
} }
} }
@@ -122,6 +147,7 @@ impl RepetitionState {
match self.settings.backward.as_str() { match self.settings.backward.as_str() {
"key" => self.draw_key(word), "key" => self.draw_key(word),
"value" => self.draw_value(word), "value" => self.draw_value(word),
"speech" => self.draw_voice(word),
_ => space().into(), _ => space().into(),
} }
} }
@@ -147,6 +173,12 @@ impl RepetitionState {
fn draw_value(&self, word: &DictionaryElement) -> Element<'_, RepetitionMessage> { fn draw_value(&self, word: &DictionaryElement) -> Element<'_, RepetitionMessage> {
text!("{}", word.value).size(24).into() text!("{}", word.value).size(24).into()
} }
fn draw_voice(&self, word: &DictionaryElement) -> Element<'_, RepetitionMessage> {
button("Воспроизвести")
.on_press(RepetitionMessage::Play)
.into()
}
} }
impl KeyPressedPage for RepetitionState { impl KeyPressedPage for RepetitionState {
@@ -180,4 +212,14 @@ pub enum RepetitionMessage {
Next, Next,
Back, Back,
Answer(WordOpenMode), Answer(WordOpenMode),
Play,
PlayFinished,
}
async fn play_sound(sink: Arc<MixerDeviceSink>, text: String) {
let data = get_voice(text.as_str()).await;
spawn_blocking(move || {
rodio::play(&sink.mixer(), data).unwrap().sleep_until_end();
}).await.unwrap();
} }