This commit is contained in:
JOLIMAITRE Matthieu 2022-09-03 03:36:52 +02:00
commit 5b3923b990
24 changed files with 4352 additions and 0 deletions

4
src-tauri/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/

3767
src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

22
src-tauri/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "hello-tauri-webdriver"
version = "0.1.0"
edition = "2021"
rust-version = "1.56"
[build-dependencies]
tauri-build = { version = "1", features = [] }
[dependencies]
anyhow = "1.0.50"
serde = "1.0"
serde_json = "1.0"
tokio = { version = "1.20", features = ["full"] }
tauri = { version = "1", features = ["api-all", "custom-protocol"] }
[profile.release]
incremental = false
codegen-units = 1
panic = "abort"
opt-level = "s"
lto = true

3
src-tauri/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

BIN
src-tauri/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src-tauri/icons/16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src-tauri/icons/256x256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src-tauri/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src-tauri/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

172
src-tauri/src/main.rs Normal file
View file

@ -0,0 +1,172 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use std::time::Duration;
use tauri::{Manager, State, Window};
use tokio::time::sleep;
#[tauri::command]
fn channel_select(id: u64, state: State<StateLock>) {
println!("e");
state.set_current_channel(id.into());
}
#[tokio::main]
async fn main() {
tauri::Builder::default()
.setup(|app| {
let window = app.get_window("main").unwrap();
window.manage(StateLock::new(window.clone()));
tokio::spawn(backend(window));
Ok(())
})
.invoke_handler(tauri::generate_handler![channel_select])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
mod utils;
pub use utils::Id;
pub use state::{Channel, HarmoniumState, Message, StateLock, User};
mod state {
use std::{
collections::HashMap,
sync::{Mutex, MutexGuard},
};
use serde::{Deserialize, Serialize};
use serde_json::json;
use tauri::Window;
use crate::Id;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub id: Id<User>,
pub name: String,
pub image_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
pub id: Id<Message>,
pub channel_id: Id<Channel>,
pub author_id: Id<User>,
pub content: String,
}
impl Message {
pub fn new(
id: Id<Message>,
content: String,
channel_id: Id<Channel>,
author_id: Id<User>,
) -> Self {
Self {
author_id,
channel_id,
content,
id,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Channel {
pub id: Id<Channel>,
pub name: String,
pub messages: Vec<Id<Message>>,
}
impl Channel {
pub fn new(id: Id<Channel>, name: String) -> Self {
let messages = vec![];
Self { id, name, messages }
}
}
#[derive(Debug, Default)]
pub struct HarmoniumState {
current_channel: Option<Id<Channel>>,
users: HashMap<Id<User>, User>,
channels: HashMap<Id<Channel>, Channel>,
messages: HashMap<Id<Message>, Message>,
}
pub struct StateLock {
state: Mutex<HarmoniumState>,
win_handle: Window,
}
impl StateLock {
pub fn new(win_handle: Window) -> Self {
let state = Default::default();
Self { win_handle, state }
}
pub fn lck(&self) -> MutexGuard<HarmoniumState> {
self.state.lock().unwrap()
}
pub fn add_channel(&self, channel: Channel) {
self.win_handle.emit("add_channel", &channel).unwrap();
self.lck()
.channels
.insert(channel.id.clone(), channel.clone());
println!("sent {channel:?}")
}
pub fn get_channel(&self, id: &Id<Channel>) -> Option<Channel> {
self.lck().channels.get(id).cloned()
}
pub fn add_message(&self, message: Message) {
self.lck()
.channels
.get_mut(&message.channel_id)
.unwrap()
.messages
.push(message.id.clone());
self.lck().messages.insert(message.id.clone(), message);
}
pub fn get_message(&self, id: &Id<Message>) -> Option<Message> {
self.lck().messages.get(id).cloned()
}
pub fn set_current_channel(&self, id: Id<Channel>) {
self.lck().current_channel = Some(id.clone());
let channel = self.get_channel(&id).unwrap();
let messages = (channel.messages.iter())
.map(|id| self.get_message(id))
.collect::<Vec<_>>();
self.win_handle
.emit(
"set_current_channel",
json!({"channel": channel, "messages": messages}),
)
.unwrap();
}
}
}
async fn backend(window: Window) {
sleep(Duration::from_millis(500)).await;
let lck = window.state::<StateLock>();
lck.add_channel(Channel::new(87689376.into(), "a channel".into()));
lck.add_channel(Channel::new(876893766.into(), "another channel".into()));
lck.add_channel(Channel::new(8768937644.into(), "a third channel".into()));
for i in 7896..7996 {
lck.add_message(Message::new(
i.into(),
format!("hello from 'a channel' #{i}"),
87689376.into(),
876869376.into(),
))
}
}

85
src-tauri/src/utils.rs Normal file
View file

@ -0,0 +1,85 @@
use std::{hash::Hash, marker::PhantomData};
use serde::{de::Visitor, Deserialize, Serialize};
#[derive(Debug)]
pub struct Id<T: 'static>(u64, PhantomData<&'static T>);
impl<T> Id<T> {
pub fn new(inner: u64) -> Self {
Self(inner, PhantomData)
}
pub fn into_u64(self) -> u64 {
self.0
}
}
impl<T: 'static> Clone for Id<T> {
fn clone(&self) -> Self {
Self(self.0, PhantomData)
}
}
impl<T: 'static> PartialEq for Id<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T: 'static> Eq for Id<T> {}
impl<T: 'static> Hash for Id<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<T: 'static> Serialize for Id<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u64(self.0)
}
}
pub struct IdVisitor<T: 'static> {
_phantom: PhantomData<fn() -> T>,
}
impl<T> IdVisitor<T> {
pub fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<'de, T> Visitor<'de> for IdVisitor<T> {
type Value = Id<T>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an integer in the u64 range")
}
}
impl<'de, T: 'static> Deserialize<'de> for Id<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_u64(IdVisitor::new())
}
}
impl<T> From<u64> for Id<T> {
fn from(input: u64) -> Self {
Self::new(input)
}
}
impl<T> From<Id<T>> for u64 {
fn from(input: Id<T>) -> Self {
let Id(inner, _) = input;
inner
}
}

66
src-tauri/tauri.conf.json Normal file
View file

@ -0,0 +1,66 @@
{
"build": {
"beforeDevCommand": "",
"beforeBuildCommand": "",
"devPath": "../src",
"distDir": "../src",
"withGlobalTauri": true
},
"package": {
"productName": "harmonium",
"version": "0.0.0"
},
"tauri": {
"allowlist": {
"all": true
},
"bundle": {
"active": true,
"category": "DeveloperTool",
"copyright": "",
"deb": {
"depends": []
},
"externalBin": [],
"icon": [
"icons/16x16.png",
"icons/32x32.png",
"icons/64x64.png",
"icons/128x128.png",
"icons/256x256.png"
],
"identifier": "com.majorbarnulf.dev",
"longDescription": "",
"macOS": {
"entitlements": null,
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"resources": [],
"shortDescription": "",
"targets": "all",
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"security": {
"csp": null
},
"updater": {
"active": false
},
"windows": [
{
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "harmonium",
"width": 800
}
]
}
}