Use SSE for get_guilds

rust
Elnu 1 year ago
parent 6b6c047b68
commit a8c0969a71

@ -1,35 +1,34 @@
use std::collections::HashMap;
use poise::serenity_prelude::Http; use poise::serenity_prelude::Http;
use rocket::{http::{CookieJar, Status}, State}; use rocket::{http::CookieJar, State};
use rocket::serde::json::Json; use rocket::response::stream::{Event, EventStream};
use crate::{cookies::user::USER_ID_COOKIE, models::Settings}; use crate::{cookies::user::USER_ID_COOKIE, models::Settings};
// TODO: Incrementally send guilds // TODO: Incrementally send guilds
#[get("/get_guilds")] #[get("/get_guilds")]
pub async fn get_guilds( pub async fn get_guilds<'a>(
cookies: &CookieJar<'_>, cookies: &'a CookieJar<'_>,
settings: &State<Settings>, settings: &'a State<Settings>,
http: &State<Http>, http: &'a State<Http>,
) -> Result<Json<HashMap<u64, bool>>, Status> { ) -> EventStream![Event + 'a] {
// EventStream![] is shorthand for EventStream[Event],
// but we need to pass in a lifetime parameter.
EventStream! {
// TODO: Proper error handling
let user_id: u64 = match cookies.get_private(USER_ID_COOKIE) { let user_id: u64 = match cookies.get_private(USER_ID_COOKIE) {
Some(id) => match id.value().parse() { Some(id) => match id.value().parse() {
Ok(id) => id, Ok(id) => id,
Err(_) => return Err(Status::BadRequest), Err(_) => panic!("BadRequest"),
// Err(_) => return Err(Status::BadRequest),
}, },
None => return Err(Status::Unauthorized), None => panic!("Unauthorized"),
// None => return Err(Status::Unauthorized),
}; };
Ok(Json({
let mut guild_statuses = HashMap::with_capacity(settings.guilds.len());
for guild in &settings.guilds { for guild in &settings.guilds {
guild_statuses.insert(guild.id, {
if guild.hidden { if guild.hidden {
continue; continue;
} }
http.get_member(guild.id, user_id).await.is_ok() yield Event::data(format!("{},{}", guild.id, http.get_member(guild.id, user_id).await.is_ok()));
}); }
} }
guild_statuses
}))
} }

@ -24,11 +24,43 @@
const dialog = document.querySelector("dialog"); const dialog = document.querySelector("dialog");
// Fetch guilds // Fetch guilds
let guilds = null; let guilds = null;
let is_in_participating_server = null;
const getGuilds = async () => { const getGuilds = async () => {
if (guilds === null) { if (guilds === null) {
const response = await fetch("/get_guilds"); // Create the guilds dictionary object
const raw_json = await response.text() guilds = {};
guilds = JSON.parse(raw_json);
// Create an EventSource object to listen to SSE events
const eventSource = new EventSource('/get_guilds');
// Event listener for 'message' events
eventSource.addEventListener('message', event => {
// Parse the data received from the event
const [id, is_member] = event.data.split(',');
// Add the key-value pair to the guilds dictionary
guilds[id] = is_member === 'true';
if (guilds[id]) {
setJoined(id);
is_in_participating_server = true;
}
});
// Function to block execution until SSE events are done
function waitForSSE() {
return new Promise(resolve => {
// Event listener for 'error' event
// For some reason errors when completing
eventSource.addEventListener('error', () => {
eventSource.close();
resolve();
});
});
}
// Call the function to block execution until SSE events are done
await waitForSSE()
} }
return guilds; return guilds;
} }
@ -40,8 +72,21 @@ const showServers = async () => {
const guilds = await getGuilds(); const guilds = await getGuilds();
Object.keys(guilds).forEach(id => { Object.keys(guilds).forEach(id => {
if (guilds[id]) { if (guilds[id]) {
const element = document.getElementById(id); setJoined(id);
if (element !== null) { }
})
};
// Switch Join button to Joined for server
const setJoined = id => {
element = document.getElementById(id);
if (element === null) {
return;
}
// Check if already set as joined
a = element.querySelector("a");
if (a === null) {
return;
}
const button = document.createElement("button"); const button = document.createElement("button");
button.tagName = "button"; button.tagName = "button";
button.className = "joinButton"; button.className = "joinButton";
@ -49,9 +94,7 @@ const showServers = async () => {
button.innerHTML = "Joined" button.innerHTML = "Joined"
element.querySelector("a").replaceWith(button); element.querySelector("a").replaceWith(button);
} }
}
})
};
// Check for welcomed cookie // Check for welcomed cookie
const welcomed = () => document.cookie.split("; ").includes("welcomed=true"); const welcomed = () => document.cookie.split("; ").includes("welcomed=true");
// Load welcome modal, check if it is necessary // Load welcome modal, check if it is necessary
@ -61,15 +104,7 @@ const loadServers = async () => {
// in case user pressed Join servers button // in case user pressed Join servers button
document.querySelector("dialog .welcome").style.display = "none"; document.querySelector("dialog .welcome").style.display = "none";
} else { } else {
let is_in_participating_server = false;
const guilds = await getGuilds(); const guilds = await getGuilds();
const ids = Object.keys(guilds);
for (let i = 0; i < ids.length; i++) {
if (guilds[ids[i]]) {
is_in_participating_server = true;
break;
}
}
if (!is_in_participating_server) { if (!is_in_participating_server) {
showServers(); showServers();
} }

Loading…
Cancel
Save