Use SSE for get_guilds
This commit is contained in:
parent
6b6c047b68
commit
a8c0969a71
2 changed files with 80 additions and 46 deletions
|
@ -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] {
|
||||||
let user_id: u64 = match cookies.get_private(USER_ID_COOKIE) {
|
// EventStream![] is shorthand for EventStream[Event],
|
||||||
Some(id) => match id.value().parse() {
|
// but we need to pass in a lifetime parameter.
|
||||||
Ok(id) => id,
|
EventStream! {
|
||||||
Err(_) => return Err(Status::BadRequest),
|
// TODO: Proper error handling
|
||||||
},
|
let user_id: u64 = match cookies.get_private(USER_ID_COOKIE) {
|
||||||
None => return Err(Status::Unauthorized),
|
Some(id) => match id.value().parse() {
|
||||||
};
|
Ok(id) => id,
|
||||||
Ok(Json({
|
Err(_) => panic!("BadRequest"),
|
||||||
let mut guild_statuses = HashMap::with_capacity(settings.guilds.len());
|
// Err(_) => return Err(Status::BadRequest),
|
||||||
|
},
|
||||||
|
None => panic!("Unauthorized"),
|
||||||
|
// None => return Err(Status::Unauthorized),
|
||||||
|
};
|
||||||
for guild in &settings.guilds {
|
for guild in &settings.guilds {
|
||||||
guild_statuses.insert(guild.id, {
|
if guild.hidden {
|
||||||
if guild.hidden {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
yield Event::data(format!("{},{}", guild.id, http.get_member(guild.id, user_id).await.is_ok()));
|
||||||
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,18 +72,29 @@ 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) {
|
|
||||||
const button = document.createElement("button");
|
|
||||||
button.tagName = "button";
|
|
||||||
button.className = "joinButton";
|
|
||||||
button.disabled = true;
|
|
||||||
button.innerHTML = "Joined"
|
|
||||||
element.querySelector("a").replaceWith(button);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
// 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");
|
||||||
|
button.tagName = "button";
|
||||||
|
button.className = "joinButton";
|
||||||
|
button.disabled = true;
|
||||||
|
button.innerHTML = "Joined"
|
||||||
|
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…
Add table
Reference in a new issue