basic desktop imp module
This commit is contained in:
@@ -31,6 +31,5 @@ futures-channel = "0.3.30"
|
|||||||
sir = { version = "0.5.0", features = ["dioxus"] }
|
sir = { version = "0.5.0", features = ["dioxus"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["web"]
|
|
||||||
web = ["dioxus/web", "dioxus-web", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "serde-wasm-bindgen", "js-sys", "web-sys"]
|
web = ["dioxus/web", "dioxus-web", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "serde-wasm-bindgen", "js-sys", "web-sys"]
|
||||||
desktop = ["dioxus/desktop"]
|
desktop = ["dioxus/desktop"]
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use ordermap::OrderSet;
|
use ordermap::OrderSet;
|
||||||
use sir::{css, global_css};
|
use sir::{css, global_css};
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub type ChannelId = u32;
|
pub type ChannelId = u32;
|
||||||
pub type UserId = u32;
|
pub type UserId = u32;
|
||||||
|
|||||||
+59
-1
@@ -1,6 +1,64 @@
|
|||||||
|
use crate::app::Command;
|
||||||
|
use dioxus::hooks::UnboundedReceiver;
|
||||||
|
use std::{fmt, io};
|
||||||
|
|
||||||
|
pub struct Error(anyhow::Error);
|
||||||
|
|
||||||
|
impl From<anyhow::Error> for Error {
|
||||||
|
fn from(value: anyhow::Error) -> Self {
|
||||||
|
Error(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(value: io::Error) -> Self {
|
||||||
|
Error(value.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn new(text: String) -> Self {
|
||||||
|
Self(anyhow::Error::msg(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log(&self) {
|
||||||
|
eprintln!("{}", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Debug::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AudioContext();
|
||||||
|
|
||||||
|
pub struct AudioPlayer();
|
||||||
|
|
||||||
|
impl AudioPlayer {
|
||||||
|
pub fn play_opus(&mut self, payload: &[u8]) {
|
||||||
|
dbg!("todo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn network_connect(
|
pub async fn network_connect(
|
||||||
address: String,
|
address: String,
|
||||||
username: String,
|
username: String,
|
||||||
event_rx: &mut UnboundedReceiver<Command>,
|
event_rx: &mut UnboundedReceiver<Command>,
|
||||||
) -> Result<(), JsValue> {
|
) -> Result<(), Error> {
|
||||||
|
dbg!("todo");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_player(ctx: &AudioContext) -> Result<AudioPlayer, Error> {
|
||||||
|
Ok(AudioPlayer())
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-30
@@ -1,8 +1,4 @@
|
|||||||
use crate::app::ChannelId;
|
|
||||||
use crate::app::Chat;
|
|
||||||
use crate::app::Command;
|
use crate::app::Command;
|
||||||
use crate::app::ConnectionState;
|
|
||||||
use crate::app::STATE;
|
|
||||||
use crate::bail;
|
use crate::bail;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use futures::select;
|
use futures::select;
|
||||||
@@ -11,18 +7,15 @@ use futures::SinkExt;
|
|||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use futures_channel::mpsc::UnboundedSender;
|
use futures_channel::mpsc::UnboundedSender;
|
||||||
use gloo_timers::future::TimeoutFuture;
|
use gloo_timers::future::TimeoutFuture;
|
||||||
use manganis::{file, mg};
|
|
||||||
use markdown;
|
|
||||||
use mumble_protocol::control::ControlPacket;
|
use mumble_protocol::control::ControlPacket;
|
||||||
use mumble_protocol::control::{msgs, ClientControlCodec};
|
use mumble_protocol::control::{msgs, ClientControlCodec};
|
||||||
use mumble_protocol::voice::VoicePacket;
|
use mumble_protocol::voice::VoicePacket;
|
||||||
use mumble_protocol::voice::VoicePacketPayload;
|
use mumble_protocol::voice::VoicePacketPayload;
|
||||||
use std::collections::hash_map::Entry;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen_futures::spawn_local as spawn;
|
use wasm_bindgen_futures::spawn_local as spawn;
|
||||||
use wasm_bindgen_futures::{future_to_promise, JsFuture};
|
use wasm_bindgen_futures::JsFuture;
|
||||||
use web_sys::console;
|
use web_sys::console;
|
||||||
use web_sys::js_sys::Promise;
|
use web_sys::js_sys::Promise;
|
||||||
use web_sys::js_sys::Reflect;
|
use web_sys::js_sys::Reflect;
|
||||||
@@ -52,22 +45,6 @@ use web_sys::WorkletOptions;
|
|||||||
|
|
||||||
pub use web_sys::AudioContext;
|
pub use web_sys::AudioContext;
|
||||||
|
|
||||||
pub struct AudioPlayer(AudioDecoder);
|
|
||||||
|
|
||||||
impl AudioPlayer {
|
|
||||||
pub fn play_opus(&mut self, payload: &[u8]) {
|
|
||||||
let js_audio_payload = Uint8Array::from(payload);
|
|
||||||
let _ = self.0.decode(
|
|
||||||
&EncodedAudioChunk::new(&EncodedAudioChunkInit::new(
|
|
||||||
&js_audio_payload.into(),
|
|
||||||
0.0,
|
|
||||||
EncodedAudioChunkType::Key,
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Error(JsValue);
|
pub struct Error(JsValue);
|
||||||
|
|
||||||
impl From<anyhow::Error> for Error {
|
impl From<anyhow::Error> for Error {
|
||||||
@@ -114,6 +91,22 @@ impl fmt::Debug for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AudioPlayer(AudioDecoder);
|
||||||
|
|
||||||
|
impl AudioPlayer {
|
||||||
|
pub fn play_opus(&mut self, payload: &[u8]) {
|
||||||
|
let js_audio_payload = Uint8Array::from(payload);
|
||||||
|
let _ = self.0.decode(
|
||||||
|
&EncodedAudioChunk::new(&EncodedAudioChunkInit::new(
|
||||||
|
&js_audio_payload.into(),
|
||||||
|
0.0,
|
||||||
|
EncodedAudioChunkType::Key,
|
||||||
|
))
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Borrowed from
|
// Borrowed from
|
||||||
// https://github.com/security-union/videocall-rs/blob/main/videocall-client/src/decode/config.rs#L6
|
// https://github.com/security-union/videocall-rs/blob/main/videocall-client/src/decode/config.rs#L6
|
||||||
fn configure_audio_context() -> AudioContext {
|
fn configure_audio_context() -> AudioContext {
|
||||||
@@ -167,7 +160,7 @@ async fn create_encoder_worklet(
|
|||||||
|
|
||||||
let error: Closure<dyn FnMut(JsValue)> = Closure::new(|e| console::error_1(&e));
|
let error: Closure<dyn FnMut(JsValue)> = Closure::new(|e| console::error_1(&e));
|
||||||
|
|
||||||
let mut download_buffer = std::cell::RefCell::new(Vec::new());
|
let download_buffer = std::cell::RefCell::new(Vec::new());
|
||||||
|
|
||||||
// This knows what MediaStreamTrackGenerator to use as it closes around it
|
// This knows what MediaStreamTrackGenerator to use as it closes around it
|
||||||
let mut sequence_num = 0;
|
let mut sequence_num = 0;
|
||||||
@@ -215,7 +208,7 @@ async fn create_encoder_worklet(
|
|||||||
audio_encoder.configure(&encoder_config);
|
audio_encoder.configure(&encoder_config);
|
||||||
console::log_1(&"Created Audio Encoder".into());
|
console::log_1(&"Created Audio Encoder".into());
|
||||||
|
|
||||||
let mut download_buffer = std::cell::RefCell::new(Vec::new());
|
let download_buffer = std::cell::RefCell::new(Vec::new());
|
||||||
|
|
||||||
let onmessage: Closure<dyn FnMut(MessageEvent)> = Closure::new(move |event: MessageEvent| {
|
let onmessage: Closure<dyn FnMut(MessageEvent)> = Closure::new(move |event: MessageEvent| {
|
||||||
match AudioData::new(event.data().unchecked_ref()) {
|
match AudioData::new(event.data().unchecked_ref()) {
|
||||||
@@ -312,9 +305,6 @@ pub async fn network_connect(
|
|||||||
username: String,
|
username: String,
|
||||||
event_rx: &mut UnboundedReceiver<Command>,
|
event_rx: &mut UnboundedReceiver<Command>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
*STATE.server.write() = Default::default();
|
|
||||||
*STATE.status.write() = ConnectionState::Connecting;
|
|
||||||
|
|
||||||
console::log_1(&"Rust via WASM!".into());
|
console::log_1(&"Rust via WASM!".into());
|
||||||
|
|
||||||
let Ok(server_hash): Result<Vec<u8>, _> = include_str!("../../server_hash.txt")
|
let Ok(server_hash): Result<Vec<u8>, _> = include_str!("../../server_hash.txt")
|
||||||
@@ -483,6 +473,5 @@ pub async fn network_connect(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = send_chan.close();
|
let _ = send_chan.close();
|
||||||
*STATE.status.write() = ConnectionState::Disconnected;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-13
@@ -1,25 +1,16 @@
|
|||||||
use app::ChannelId;
|
|
||||||
use app::Chat;
|
use app::Chat;
|
||||||
use app::Command;
|
use app::Command;
|
||||||
use app::ConnectionState;
|
use app::ConnectionState;
|
||||||
use app::STATE;
|
use app::STATE;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use futures::select;
|
|
||||||
use futures::FutureExt;
|
|
||||||
use futures::SinkExt;
|
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use futures_channel::mpsc::UnboundedSender;
|
use futures_channel::mpsc::UnboundedSender;
|
||||||
use gloo_timers::future::TimeoutFuture;
|
|
||||||
pub use imp::Error;
|
pub use imp::Error;
|
||||||
use manganis::{file, mg};
|
use mumble_protocol::control::msgs;
|
||||||
use markdown;
|
|
||||||
use mumble_protocol::control::ControlPacket;
|
use mumble_protocol::control::ControlPacket;
|
||||||
use mumble_protocol::control::{msgs, ClientControlCodec};
|
|
||||||
use mumble_protocol::voice::VoicePacket;
|
|
||||||
use mumble_protocol::voice::VoicePacketPayload;
|
use mumble_protocol::voice::VoicePacketPayload;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
|
||||||
@@ -27,16 +18,14 @@ pub mod app;
|
|||||||
#[path = "imp/web.rs"]
|
#[path = "imp/web.rs"]
|
||||||
pub mod imp;
|
pub mod imp;
|
||||||
|
|
||||||
/*
|
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
#[path = "imp/desktop.rs"]
|
#[path = "imp/desktop.rs"]
|
||||||
pub mod imp;
|
pub mod imp;
|
||||||
*/
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! bail {
|
macro_rules! bail {
|
||||||
($($x:tt)*) => {
|
($($x:tt)*) => {
|
||||||
return Err(crate::Error::new(format!($($x)*)))
|
return Err(Error::new(format!($($x)*)))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +40,13 @@ pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>) {
|
|||||||
panic!("Did not receive connect command")
|
panic!("Did not receive connect command")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
*STATE.server.write() = Default::default();
|
||||||
|
*STATE.status.write() = ConnectionState::Connecting;
|
||||||
if let Err(error) = imp::network_connect(address, username, &mut event_rx).await {
|
if let Err(error) = imp::network_connect(address, username, &mut event_rx).await {
|
||||||
error.log();
|
error.log();
|
||||||
*STATE.status.write() = ConnectionState::Failed(error.to_string());
|
*STATE.status.write() = ConnectionState::Failed(error.to_string());
|
||||||
|
} else {
|
||||||
|
*STATE.status.write() = ConnectionState::Disconnected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user