add: live browser notifications
This commit is contained in:
parent
58d206eb81
commit
98d6f21e6e
18 changed files with 291 additions and 15 deletions
|
@ -9,6 +9,7 @@ use crate::model::{
|
|||
};
|
||||
use crate::{auto_method, execute, get, query_row, params};
|
||||
use pathbufd::PathBufD;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::{exists, remove_file};
|
||||
use tetratto_shared::hash::{hash_salted, salt};
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
|
@ -44,6 +45,7 @@ impl DataManager {
|
|||
post_count: get!(x->15(i32)) as usize,
|
||||
request_count: get!(x->16(i32)) as usize,
|
||||
connections: serde_json::from_str(&get!(x->17(String)).to_string()).unwrap(),
|
||||
subscriptions: serde_json::from_str(&get!(x->18(String)).to_string()).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +140,7 @@ impl DataManager {
|
|||
|
||||
let res = execute!(
|
||||
&conn,
|
||||
"INSERT INTO users VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)",
|
||||
"INSERT INTO users VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)",
|
||||
params![
|
||||
&(data.id as i64),
|
||||
&(data.created as i64),
|
||||
|
@ -158,6 +160,7 @@ impl DataManager {
|
|||
&0_i32,
|
||||
&0_i32,
|
||||
&serde_json::to_string(&data.connections).unwrap(),
|
||||
&serde_json::to_string(&data.subscriptions).unwrap(),
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -634,6 +637,7 @@ impl DataManager {
|
|||
auto_method!(update_user_tokens(Vec<Token>)@get_user_by_id -> "UPDATE users SET tokens = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
|
||||
auto_method!(update_user_settings(UserSettings)@get_user_by_id -> "UPDATE users SET settings = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
|
||||
auto_method!(update_user_connections(UserConnections)@get_user_by_id -> "UPDATE users SET connections = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
|
||||
auto_method!(update_user_subscriptions(HashMap<usize, usize>)@get_user_by_id -> "UPDATE users SET subscriptions = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
|
||||
|
||||
auto_method!(incr_user_notifications()@get_user_by_id -> "UPDATE users SET notification_count = notification_count + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_user --incr);
|
||||
auto_method!(decr_user_notifications()@get_user_by_id -> "UPDATE users SET notification_count = notification_count - 1 WHERE id = $1" --cache-key-tmpl=cache_clear_user --decr);
|
||||
|
|
|
@ -16,5 +16,6 @@ CREATE TABLE IF NOT EXISTS users (
|
|||
recovery_codes TEXT NOT NULL,
|
||||
post_count INT NOT NULL,
|
||||
request_count INT NOT NULL,
|
||||
connections TEXT NOT NULL
|
||||
connections TEXT NOT NULL,
|
||||
subscriptions TEXT NOT NULL
|
||||
)
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use crate::model::socket::{CrudMessageType, PacketType, SocketMessage, SocketMethod};
|
||||
use crate::model::{Error, Result, auth::Notification, auth::User, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
|
||||
#[cfg(feature = "redis")]
|
||||
use redis::Commands;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
|
||||
|
@ -78,6 +82,20 @@ impl DataManager {
|
|||
// incr notification count
|
||||
self.incr_user_notifications(data.owner).await.unwrap();
|
||||
|
||||
// post event
|
||||
let mut con = self.2.get_con().await;
|
||||
|
||||
if let Err(e) = con.publish::<String, String, ()>(
|
||||
format!("{}/notifs", data.owner),
|
||||
serde_json::to_string(&SocketMessage {
|
||||
method: SocketMethod::Packet(PacketType::Crud(CrudMessageType::Create)),
|
||||
data: serde_json::to_string(&data).unwrap(),
|
||||
})
|
||||
.unwrap(),
|
||||
) {
|
||||
return Err(Error::MiscError(e.to_string()));
|
||||
}
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
}
|
||||
|
@ -115,6 +133,20 @@ impl DataManager {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
// post event
|
||||
let mut con = self.2.get_con().await;
|
||||
|
||||
if let Err(e) = con.publish::<String, String, ()>(
|
||||
format!("{}/notifs", notification.owner),
|
||||
serde_json::to_string(&SocketMessage {
|
||||
method: SocketMethod::Packet(PacketType::Crud(CrudMessageType::Delete)),
|
||||
data: notification.id.to_string(),
|
||||
})
|
||||
.unwrap(),
|
||||
) {
|
||||
return Err(Error::MiscError(e.to_string()));
|
||||
}
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ pub struct User {
|
|||
/// External service connection details.
|
||||
#[serde(default)]
|
||||
pub connections: UserConnections,
|
||||
/// Subscribed channels data. Each entry is a channel ID, as well as the ID of
|
||||
/// the last message the user saw in that channel.
|
||||
#[serde(default)]
|
||||
pub subscriptions: HashMap<usize, usize>,
|
||||
}
|
||||
|
||||
pub type UserConnections =
|
||||
|
@ -232,6 +236,7 @@ impl User {
|
|||
post_count: 0,
|
||||
request_count: 0,
|
||||
connections: HashMap::new(),
|
||||
subscriptions: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,14 +375,12 @@ pub struct ExternalConnectionInfo {
|
|||
pub show_on_profile: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[derive(Default)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
||||
pub struct ExternalConnectionData {
|
||||
pub external_urls: HashMap<String, String>,
|
||||
pub data: HashMap<String, String>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Notification {
|
||||
pub id: usize,
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
use serde::{Serialize, Deserialize, de::DeserializeOwned};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum CrudMessageType {
|
||||
Create,
|
||||
Delete,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum PacketType {
|
||||
/// A regular check to ensure the connection is still alive.
|
||||
Ping,
|
||||
/// General text which can be ignored.
|
||||
Text,
|
||||
/// A CRUD operation.
|
||||
Crud(CrudMessageType),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
@ -20,6 +28,8 @@ pub enum SocketMethod {
|
|||
Forward(PacketType),
|
||||
/// A general packet from client to server. (ws to Redis pubsub)
|
||||
Misc(PacketType),
|
||||
/// A general packet from client to server. (ws to Redis pubsub)
|
||||
Packet(PacketType),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue