kopia lustrzana https://github.com/cirospaciari/socketify.py
201 wiersze
5.6 KiB
JavaScript
201 wiersze
5.6 KiB
JavaScript
|
|
function get_room(name, token, on_history, on_message){
|
|
|
|
const ws = new WebSocket(`ws://localhost:3000?room=${name}&token=${token}`);
|
|
var status = 'pending';
|
|
const connection = new Promise((resolve)=>{
|
|
ws.onopen = function(){
|
|
status = 'connected';
|
|
resolve(true)
|
|
}
|
|
ws.onerror = function(){
|
|
status = 'error';
|
|
resolve(false)
|
|
}
|
|
});
|
|
|
|
ws.onclose = function(){
|
|
status = 'closed';
|
|
}
|
|
ws.onmessage = (event) => {
|
|
const message = JSON.parse(event.data);
|
|
if(message instanceof Array){
|
|
on_history(message)
|
|
}else{
|
|
on_message(message)
|
|
}
|
|
}
|
|
|
|
return {
|
|
send(message){
|
|
ws.send(JSON.stringify(message));
|
|
},
|
|
wait_connection(){
|
|
return connection;
|
|
},
|
|
is_connected(){
|
|
return status === 'connected';
|
|
},
|
|
close(){
|
|
ws.close()
|
|
}
|
|
}
|
|
}
|
|
|
|
function get_utc_date(){
|
|
return new Date().toLocaleTimeString('en-US', { hour12:false, hour: '2-digit', minute: '2-digit', timeZone: 'UTC', timeZoneName: 'short' })
|
|
}
|
|
|
|
function get_session() {
|
|
let name = "session=";
|
|
let decodedCookie = decodeURIComponent(document.cookie);
|
|
let ca = decodedCookie.split(';');
|
|
for (let i = 0; i < ca.length; i++) {
|
|
let c = ca[i];
|
|
while (c.charAt(0) == ' ') {
|
|
c = c.substring(1);
|
|
}
|
|
if (c.indexOf(name) == 0) {
|
|
return c.substring(name.length, c.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
async function get_user() {
|
|
const session = get_session()
|
|
if (!session) return null;
|
|
try {
|
|
const response = await fetch('https://api.github.com/user', {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${session}`,
|
|
'Accept': 'application/json'
|
|
}
|
|
})
|
|
return await response?.json()
|
|
} catch (err) {
|
|
console.error(err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function request_login(){
|
|
return document.location.href = 'https://github.com/login/oauth/authorize?scope=user:email&client_id=9481803176fb73d616b7';
|
|
}
|
|
let current_room = null;
|
|
let last_room_name = 'general';
|
|
async function send_message(event){
|
|
if(event && event.key?.toLowerCase() !== 'enter') return;
|
|
|
|
const message = document.querySelector("#chat-message");
|
|
await current_room?.wait_connection();
|
|
if(current_room?.is_connected()){
|
|
current_room.send({
|
|
text: message.value,
|
|
datetime: get_utc_date()
|
|
})
|
|
//clean
|
|
message.value = ''
|
|
}else {
|
|
await open_room(last_room_name)
|
|
send_message();
|
|
}
|
|
}
|
|
|
|
async function open_room(name){
|
|
last_room_name = name;
|
|
current_room?.close()
|
|
|
|
const user = await get_user();
|
|
if(!user){
|
|
return request_login();
|
|
}
|
|
const chat = document.querySelector('.chat-messages');
|
|
|
|
const room = get_room(name, get_session(), (history)=> {
|
|
//clear
|
|
chat.innerHTML = '';
|
|
//add messages
|
|
for(let message of history){
|
|
chat.appendChild(format_message(message, user));
|
|
}
|
|
chat.scroll(0, chat.scrollHeight)
|
|
}, (message)=>{
|
|
//add message
|
|
chat.appendChild(format_message(message, user));
|
|
|
|
//trim size
|
|
while(chat.childNodes.length > 100){
|
|
chat.firstChild.remove();
|
|
}
|
|
chat.scroll(0, chat.scrollHeight)
|
|
});
|
|
await room.wait_connection()
|
|
current_room = room;
|
|
}
|
|
const markdown = new showdown.Converter({simpleLineBreaks: true,openLinksInNewWindow: true, emoji: true, ghMentions: true, tables: true, strikethrough: true, tasklists: true});
|
|
|
|
function format_message(message, user){
|
|
const message_element = document.createElement("div");
|
|
if(message.login === user.login){
|
|
message.name = 'You';
|
|
message_element.classList.add('chat-message-right');
|
|
}else{
|
|
message.name = message.name || message.login;
|
|
message_element.classList.add('chat-message-left');
|
|
}
|
|
|
|
message_element.classList.add('pb-4');
|
|
|
|
const header = document.createElement("div");
|
|
image = new Image(40, 40);
|
|
image.src = message.avatar_url;
|
|
image.classList.add('rounded-circle');
|
|
image.classList.add('mr-1');
|
|
image.alt = message.name;
|
|
|
|
const date = document.createElement("div");
|
|
date.classList.add('text-muted');
|
|
date.classList.add('small');
|
|
date.classList.add('text-nowrap');
|
|
date.classList.add('mt-2');
|
|
date.textContent = message.datetime;
|
|
header.addEventListener("click", ()=> {
|
|
window.open(message.html_url, '_blank').focus();
|
|
});
|
|
header.appendChild(image);
|
|
header.appendChild(date);
|
|
|
|
message_element.appendChild(header);
|
|
|
|
const body = document.createElement("div");
|
|
body.classList.add('flex-shrink-1');
|
|
body.classList.add('bg-light');
|
|
body.classList.add('rounded');
|
|
body.classList.add('py-2');
|
|
body.classList.add('px-3');
|
|
body.classList.add('mr-3');
|
|
|
|
const author = document.createElement("div")
|
|
author.classList.add('font-weight-bold');
|
|
author.classList.add('mb-1');
|
|
author.textContent = message.name;
|
|
|
|
|
|
body.appendChild(author);
|
|
const content = document.createElement("div");
|
|
content.innerHTML = markdown.makeHtml(message.text);
|
|
body.appendChild(content);
|
|
|
|
message_element.appendChild(body);
|
|
|
|
return message_element;
|
|
}
|
|
|
|
get_user().then((is_logged_in)=>{
|
|
if(is_logged_in){
|
|
open_room("general");
|
|
}
|
|
});
|