2021-04-26 19:34:24 +02:00
"use strict" ;
2021-05-02 16:46:05 +02:00
let identityName = undefined ;
2021-04-26 19:34:24 +02:00
let socket = null ;
let notificationAllowed = false ;
2021-05-04 22:26:36 +02:00
let localIps = [ ] ;
2021-04-28 17:57:49 +02:00
let currentSessionId = - 1 ;
let sessionsData = new Map ( ) ;
let msgHistory = new Map ( ) ;
let pendingFiles = new Map ( ) ;
2021-04-26 19:34:24 +02:00
2021-04-28 17:57:49 +02:00
function onClickSession ( event ) {
let sessionId = event . currentTarget . getAttribute ( "data-sessionId" ) ;
if ( sessionId != null ) {
currentSessionId = sessionId ;
let session = sessionsData . get ( sessionId ) ;
2021-04-26 19:34:24 +02:00
if ( ! session . seen ) {
session . seen = true ;
2021-04-28 17:57:49 +02:00
socket . send ( "set_seen " + sessionId ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
displaySessions ( ) ;
displayHeader ( ) ;
displayChatBottom ( ) ;
2021-05-04 11:51:08 +02:00
dislayHistory ( ) ;
2021-04-26 19:34:24 +02:00
}
}
let ip _input = document . getElementById ( "ip_input" ) ;
ip _input . addEventListener ( "keyup" , function ( event ) {
2021-05-04 11:51:08 +02:00
if ( event . key === "Enter" ) {
2021-04-26 19:34:24 +02:00
socket . send ( "connect " + ip _input . value ) ;
ip _input . value = "" ;
}
} ) ;
2021-05-04 22:26:36 +02:00
document . getElementById ( "show_local_ips" ) . onclick = function ( ) {
let mainDiv = document . createElement ( "div" ) ;
let h2Title = document . createElement ( "h2" ) ;
h2Title . textContent = "Your IP addresses:" ;
mainDiv . appendChild ( h2Title ) ;
let ul = document . createElement ( "ul" ) ;
ul . classList . add ( "ips" ) ;
for ( let i = 0 ; i < localIps . length ; ++ i ) {
let li = document . createElement ( "li" ) ;
li . textContent = localIps [ i ] ;
ul . appendChild ( li ) ;
}
mainDiv . appendChild ( ul ) ;
showPopup ( mainDiv ) ;
}
2021-04-26 19:34:24 +02:00
let message _input = document . getElementById ( "message_input" ) ;
message _input . addEventListener ( "keyup" , function ( event ) {
2021-05-04 11:51:08 +02:00
if ( event . key === "Enter" ) {
2021-04-28 17:57:49 +02:00
socket . send ( "send " + currentSessionId + " " + message _input . value ) ;
2021-04-26 19:34:24 +02:00
message _input . value = "" ;
}
} ) ;
document . getElementById ( "delete_conversation" ) . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
let mainDiv = document . createElement ( "div" ) ;
mainDiv . appendChild ( generatePopupWarningTitle ( ) ) ;
2021-04-26 19:34:24 +02:00
let p1 = document . createElement ( "p" ) ;
p1 . textContent = "Deleting a conversation only affects you. Your contact will still have a copy of this conversation if he/she doesn't delete it too." ;
let p2 = document . createElement ( "p" ) ;
p2 . textContent = "Do you really want to delete all this conversation (messages and files) ?" ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( p1 ) ;
mainDiv . appendChild ( p2 ) ;
2021-04-26 19:34:24 +02:00
let button = document . createElement ( "button" ) ;
button . textContent = "Delete" ;
button . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
socket . send ( "delete_conversation " + currentSessionId ) ;
msgHistory . get ( currentSessionId ) . length = 0 ;
removePopup ( ) ;
dislayHistory ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( button ) ;
showPopup ( mainDiv ) ;
2021-04-26 19:34:24 +02:00
}
document . getElementById ( "add_contact" ) . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
socket . send ( "contact " + currentSessionId + " " + sessionsData . get ( currentSessionId ) . name ) ;
2021-05-02 16:46:05 +02:00
sessionsData . get ( currentSessionId ) . isContact = true ;
2021-04-28 17:57:49 +02:00
displayHeader ( ) ;
displaySessions ( ) ;
2021-04-26 19:34:24 +02:00
}
document . getElementById ( "remove_contact" ) . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
let mainDiv = document . createElement ( "div" ) ;
mainDiv . appendChild ( generatePopupWarningTitle ( ) ) ;
2021-04-26 19:34:24 +02:00
let p1 = document . createElement ( "p" ) ;
p1 . textContent = "Deleting contact will remove her/his identity key and your conversation (messages and files). You won\'t be able to recognize her/him anymore. This action only affects you." ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( p1 ) ;
2021-04-26 19:34:24 +02:00
let p2 = document . createElement ( "p" ) ;
p2 . textContent = "Do you really want to remove this contact ?" ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( p2 ) ;
2021-04-26 19:34:24 +02:00
let button = document . createElement ( "button" ) ;
button . textContent = "Delete" ;
button . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
socket . send ( "uncontact " + currentSessionId ) ;
let session = sessionsData . get ( currentSessionId ) ;
2021-05-02 16:46:05 +02:00
session . isContact = false ;
session . isVerified = false ;
if ( ! session . isOnline ) {
2021-04-28 17:57:49 +02:00
sessionsData . delete ( currentSessionId ) ;
msgHistory . get ( currentSessionId ) . length = 0 ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
displayHeader ( ) ;
displaySessions ( ) ;
dislayHistory ( ) ;
removePopup ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( button ) ;
showPopup ( mainDiv ) ;
2021-04-26 19:34:24 +02:00
}
document . getElementById ( "verify" ) . onclick = function ( ) {
2021-05-02 16:46:05 +02:00
let session = sessionsData . get ( currentSessionId ) ;
if ( typeof session !== "undefined" ) {
let mainDiv = document . createElement ( "div" ) ;
mainDiv . appendChild ( generatePopupWarningTitle ( ) ) ;
let instructions = document . createElement ( "p" ) ;
instructions . textContent = "Compare the following fingerprints by a trusted way of communication (such as real life) and be sure they match." ;
mainDiv . appendChild ( instructions ) ;
let p _local = document . createElement ( "p" ) ;
p _local . textContent = "Local fingerprint:" ;
mainDiv . appendChild ( p _local ) ;
let pre _local = document . createElement ( "pre" ) ;
pre _local . textContent = beautifyFingerprint ( identityFingerprint ) ;
mainDiv . appendChild ( pre _local ) ;
let p _peer = document . createElement ( "p" ) ;
p _peer . textContent = "Peer fingerprint:" ;
mainDiv . appendChild ( p _peer ) ;
let pre _peer = document . createElement ( "pre" ) ;
pre _peer . textContent = beautifyFingerprint ( session . fingerprint ) ;
mainDiv . appendChild ( pre _peer ) ;
let buttonRow = document . createElement ( "div" ) ;
buttonRow . classList . add ( "button_row" ) ;
let verifyButton = document . createElement ( "button" ) ;
verifyButton . textContent = "They match" ;
verifyButton . onclick = function ( ) {
socket . send ( "verify " + currentSessionId ) ;
sessionsData . get ( currentSessionId ) . isVerified = true ;
removePopup ( ) ;
displayHeader ( ) ;
displaySessions ( ) ;
} ;
buttonRow . appendChild ( verifyButton ) ;
let cancelButton = document . createElement ( "button" ) ;
cancelButton . textContent = "They don't match" ;
cancelButton . onclick = removePopup ;
buttonRow . appendChild ( cancelButton ) ;
mainDiv . appendChild ( buttonRow ) ;
showPopup ( mainDiv ) ;
}
2021-04-26 19:34:24 +02:00
}
document . getElementById ( "logout" ) . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
let mainDiv = document . createElement ( "div" ) ;
mainDiv . appendChild ( generatePopupWarningTitle ( ) ) ;
2021-04-26 19:34:24 +02:00
let p _warning = document . createElement ( "p" ) ;
p _warning . textContent = "If you log out, you will no longer receive messages and pending messages will not be sent until you log in back." ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( p _warning ) ;
2021-04-26 19:34:24 +02:00
let p _ask = document . createElement ( "p" ) ;
p _ask . textContent = "Do you really want to log out ?" ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( p _ask ) ;
2021-04-26 19:34:24 +02:00
let button = document . createElement ( "button" ) ;
button . textContent = "Log out" ;
button . onclick = logout ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( button ) ;
showPopup ( mainDiv ) ;
2021-04-26 19:34:24 +02:00
}
document . getElementById ( "attach_file" ) . onchange = function ( event ) {
let file = event . target . files [ 0 ] ;
if ( file . size > 32760000 ) {
2021-04-28 17:57:49 +02:00
if ( ! pendingFiles . has ( currentSessionId ) ) {
pendingFiles . set ( currentSessionId , {
"file" : file ,
"name" : file . name ,
"size" : file . size ,
"state" : "waiting" ,
"transferred" : 0 ,
"lastChunk" : Date . now ( )
} ) ;
socket . send ( "large_file " + currentSessionId + " " + file . size + " " + file . name ) ;
displayChatBottom ( ) ;
}
2021-04-26 19:34:24 +02:00
} else {
let formData = new FormData ( ) ;
2021-04-28 17:57:49 +02:00
formData . append ( "session_id" , currentSessionId ) ;
2021-04-26 19:34:24 +02:00
formData . append ( "" , file ) ;
fetch ( "/send_file" , { method : "POST" , body : formData } ) . then ( response => {
if ( response . ok ) {
2021-04-28 17:57:49 +02:00
response . text ( ) . then ( uuid => onFileSent ( currentSessionId , uuid , file . name ) ) ;
2021-04-26 19:34:24 +02:00
} else {
console . log ( response ) ;
}
} ) ;
}
}
2021-04-28 17:57:49 +02:00
document . getElementById ( "file_cancel" ) . onclick = function ( ) {
socket . send ( "abort " + currentSessionId ) ;
}
2021-04-26 19:34:24 +02:00
let msg _log = document . getElementById ( "msg_log" ) ;
msg _log . onscroll = function ( ) {
2021-05-02 16:46:05 +02:00
if ( sessionsData . get ( currentSessionId ) . isContact ) {
2021-04-26 19:34:24 +02:00
if ( msg _log . scrollTop < 30 ) {
2021-04-28 17:57:49 +02:00
socket . send ( "load_msgs " + currentSessionId ) ;
2021-04-26 19:34:24 +02:00
}
}
}
let profile _div = document . querySelector ( "#me>div" ) ;
profile _div . onclick = function ( ) {
2021-04-28 17:57:49 +02:00
let mainDiv = document . createElement ( "div" ) ;
2021-05-02 16:46:05 +02:00
let avatar = generateAvatar ( identityName ) ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( avatar ) ;
2021-05-02 16:46:05 +02:00
let fingerprint = document . createElement ( "pre" ) ;
fingerprint . id = "identity_fingerprint" ;
fingerprint . textContent = beautifyFingerprint ( identityFingerprint ) ;
mainDiv . appendChild ( fingerprint ) ;
2021-04-28 17:57:49 +02:00
let sectionName = document . createElement ( "section" ) ;
sectionName . textContent = "Name:" ;
let inputName = document . createElement ( "input" ) ;
inputName . id = "new_name" ;
inputName . type = "text" ;
2021-05-02 16:46:05 +02:00
inputName . value = identityName ;
2021-04-28 17:57:49 +02:00
sectionName . appendChild ( inputName ) ;
let saveNameButton = document . createElement ( "button" ) ;
saveNameButton . textContent = "Save" ;
saveNameButton . onclick = function ( ) {
2021-04-26 19:34:24 +02:00
socket . send ( "change_name " + document . getElementById ( "new_name" ) . value ) ;
} ;
2021-04-28 17:57:49 +02:00
sectionName . appendChild ( saveNameButton ) ;
mainDiv . appendChild ( sectionName ) ;
let sectionPassword = document . createElement ( "section" ) ;
sectionPassword . textContent = "Change your password:" ;
sectionPassword . style . paddingTop = "1em" ;
sectionPassword . style . borderTop = "1px solid black" ;
if ( isIdentityProtected ) {
2021-04-26 19:34:24 +02:00
let input _old _password = document . createElement ( "input" ) ;
input _old _password . type = "password" ;
input _old _password . placeholder = "Current password" ;
2021-04-28 17:57:49 +02:00
sectionPassword . appendChild ( input _old _password ) ;
}
let inputPassword1 = document . createElement ( "input" ) ;
let inputPassword2 = document . createElement ( "input" ) ;
inputPassword1 . type = "password" ;
inputPassword1 . placeholder = "New password (empty for no password)" ;
inputPassword2 . type = "password" ;
inputPassword2 . placeholder = "New password (confirmation)" ;
sectionPassword . appendChild ( inputPassword1 ) ;
sectionPassword . appendChild ( inputPassword2 ) ;
let errorMsg = document . createElement ( "p" ) ;
errorMsg . id = "password_errorMsg" ;
errorMsg . style . color = "red" ;
sectionPassword . appendChild ( errorMsg ) ;
let changePasswordButton = document . createElement ( "button" ) ;
changePasswordButton . textContent = "Change password" ;
changePasswordButton . onclick = function ( ) {
2021-04-26 19:34:24 +02:00
let inputs = document . querySelectorAll ( "input[type=\"password\"]" ) ;
2021-04-28 17:57:49 +02:00
let newPassword , newPasswordConfirm ;
if ( isIdentityProtected ) {
newPassword = inputs [ 1 ] ;
newPasswordConfirm = inputs [ 2 ] ;
2021-04-26 19:34:24 +02:00
} else {
2021-04-28 17:57:49 +02:00
newPassword = inputs [ 0 ] ;
newPasswordConfirm = inputs [ 1 ] ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
if ( newPassword . value == newPasswordConfirm . value ) {
let newPassword _set = newPassword . value . length > 0 ;
if ( isIdentityProtected || newPassword _set ) { //don't change password if identity is not protected and new password is blank
2021-04-26 19:34:24 +02:00
let msg = "change_password" ;
2021-04-28 17:57:49 +02:00
if ( isIdentityProtected ) {
2021-04-26 19:34:24 +02:00
msg += " " + btoa ( inputs [ 0 ] . value ) ;
}
2021-04-28 17:57:49 +02:00
if ( newPassword _set ) {
msg += " " + btoa ( newPassword . value ) ;
2021-04-26 19:34:24 +02:00
}
socket . send ( msg ) ;
} else {
2021-04-28 17:57:49 +02:00
removePopup ( ) ;
2021-04-26 19:34:24 +02:00
}
} else {
2021-04-28 17:57:49 +02:00
newPassword . value = "" ;
newPasswordConfirm . value = "" ;
errorMsg . textContent = "Passwords don't match" ;
2021-04-26 19:34:24 +02:00
}
} ;
2021-04-28 17:57:49 +02:00
sectionPassword . appendChild ( changePasswordButton ) ;
mainDiv . appendChild ( sectionPassword ) ;
let sectionDelete = document . createElement ( "section" ) ;
sectionDelete . textContent = "Delete identity:" ;
sectionDelete . style . paddingTop = "1em" ;
sectionDelete . style . borderTop = "1px solid red" ;
2021-04-26 19:34:24 +02:00
let p = document . createElement ( "p" ) ;
p . textContent = "Deleting your identity will delete all your conversations (messages and files), all your contacts, and your private key. You won't be able to be recognized by your contacts anymore." ;
p . style . color = "red" ;
2021-04-28 17:57:49 +02:00
sectionDelete . appendChild ( p ) ;
let deleteButton = document . createElement ( "button" ) ;
deleteButton . textContent = "Delete" ;
deleteButton . style . backgroundColor = "red" ;
deleteButton . onclick = function ( ) {
let mainDiv = document . createElement ( "div" ) ;
mainDiv . appendChild ( generatePopupWarningTitle ( ) ) ;
2021-04-26 19:34:24 +02:00
let p = document . createElement ( "p" ) ;
p . textContent = "This action is irreversible. Are you sure you want to delete all your data ?" ;
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( p ) ;
let deleteButton = document . createElement ( "button" ) ;
deleteButton . style . backgroundColor = "red" ;
deleteButton . textContent = "Delete" ;
deleteButton . onclick = function ( ) {
2021-04-26 19:34:24 +02:00
socket . send ( "disappear" ) ;
}
2021-04-28 17:57:49 +02:00
mainDiv . appendChild ( deleteButton ) ;
showPopup ( mainDiv ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
sectionDelete . appendChild ( deleteButton ) ;
mainDiv . appendChild ( sectionDelete ) ;
showPopup ( mainDiv ) ;
2021-04-26 19:34:24 +02:00
}
2021-05-02 16:46:05 +02:00
let chatHeader = document . getElementById ( "chat_header" ) ;
chatHeader . children [ 0 ] . onclick = function ( ) {
let session = sessionsData . get ( currentSessionId ) ;
if ( typeof session !== "undefined" ) {
let mainDiv = document . createElement ( "div" ) ;
mainDiv . classList . add ( "session_info" ) ;
mainDiv . appendChild ( generateAvatar ( session . name ) ) ;
let h2 = document . createElement ( "h2" ) ;
h2 . textContent = session . name ;
mainDiv . appendChild ( h2 ) ;
let pFingerprint = document . createElement ( "p" ) ;
pFingerprint . textContent = "Fingerprint:" ;
mainDiv . appendChild ( pFingerprint ) ;
let pre = document . createElement ( "pre" ) ;
pre . textContent = ' ' + beautifyFingerprint ( session . fingerprint ) ;
mainDiv . appendChild ( pre ) ;
if ( session . isOnline ) {
let pIp = document . createElement ( "p" ) ;
pIp . textContent = "IP: " + session . ip ;
mainDiv . appendChild ( pIp ) ;
let pConnection = document . createElement ( "p" ) ;
pConnection . textContent = "Connection: " ;
if ( session . outgoing ) {
pConnection . textContent += "outgoing" ;
} else {
pConnection . textContent += "incomming" ;
}
mainDiv . appendChild ( pConnection ) ;
}
showPopup ( mainDiv ) ;
}
}
2021-04-26 19:34:24 +02:00
document . querySelector ( "#refresher button" ) . onclick = function ( ) {
socket . send ( "refresh" ) ;
}
2021-05-02 16:46:05 +02:00
//source: https://stackoverflow.com/a/14919494
function humanFileSize ( bytes , dp = 1 ) {
const thresh = 1000 ;
if ( Math . abs ( bytes ) < thresh ) {
return bytes + ' B' ;
}
const units = [ 'kB' , 'MB' , 'GB' , 'TB' , 'PB' , 'EB' , 'ZB' , 'YB' ] ;
let u = - 1 ;
const r = 10 * * dp ;
do {
bytes /= thresh ;
++ u ;
} while ( Math . round ( Math . abs ( bytes ) * r ) / r >= thresh && u < units . length - 1 ) ;
return bytes . toFixed ( dp ) + ' ' + units [ u ] ;
}
//source: https://www.w3schools.com/js/js_cookies.asp
function getCookie ( cname ) {
var name = cname + "=" ;
var decodedCookie = decodeURIComponent ( document . cookie ) ;
var ca = decodedCookie . split ( ';' ) ;
for ( var i = 0 ; i < ca . length ; i ++ ) {
var c = ca [ i ] ;
while ( c . charAt ( 0 ) == ' ' ) {
c = c . substring ( 1 ) ;
}
if ( c . indexOf ( name ) == 0 ) {
return c . substring ( name . length , c . length ) ;
}
}
return "" ;
}
socket = new WebSocket ( "ws://" + location . hostname + ":" + websocketPort + "/ws" ) ;
socket . onopen = function ( ) {
console . log ( "Connected" ) ;
socket . send ( getCookie ( "aira_auth" ) ) ; //authenticating websocket connection
window . onfocus = function ( ) {
if ( currentSessionId != - 1 ) {
socket . send ( "set_seen " + currentSessionId ) ;
}
}
if ( Notification . permission === "granted" ) {
notificationAllowed = true ;
} else if ( Notification . permission !== "denied" ) {
Notification . requestPermission ( ) . then ( function ( permission ) {
if ( permission === "granted" ) {
notificationAllowed = true ;
}
} ) ;
}
} ;
socket . onmessage = function ( msg ) {
if ( typeof msg . data == "string" ) {
console . log ( "Message: " + msg . data ) ;
let args = msg . data . split ( " " ) ;
switch ( args [ 0 ] ) {
case "disconnected" :
onDisconnected ( args [ 1 ] ) ;
break ;
case "new_session" :
onNewSession ( args [ 1 ] , args [ 2 ] === "true" , args [ 3 ] , args [ 4 ] , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + args [ 2 ] . length + args [ 3 ] . length + args [ 4 ] . length + 5 ) ) ;
break ;
case "new_message" :
onNewMessage ( args [ 1 ] , args [ 2 ] === "true" , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + args [ 2 ] . length + 3 ) ) ;
break ;
case "file" :
onFileReceived ( args [ 1 ] , args [ 2 ] , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + args [ 2 ] . length + 3 ) ) ;
break ;
case "file_transfer" :
onNewFileTransfer ( args [ 1 ] , args [ 2 ] , args [ 3 ] , args [ 4 ] , args [ 5 ] , args [ 6 ] ) ;
break ;
case "ask_large_file" :
onAskLargeFile ( args [ 1 ] , args [ 2 ] , args [ 3 ] , args [ 4 ] ) ;
break ;
case "file_accepted" :
onFileAccepted ( args [ 1 ] ) ;
break ;
case "aborted" :
onFileAborted ( args [ 1 ] ) ;
break ;
case "inc_file_transfer" :
onIncFileTransfer ( args [ 1 ] , parseInt ( args [ 2 ] ) ) ;
break ;
case "load_sent_msg" :
onMsgLoad ( args [ 1 ] , args [ 2 ] === "true" , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + args [ 2 ] . length + 3 ) ) ;
break ;
case "load_sent_file" :
onFileLoad ( args [ 1 ] , args [ 2 ] === "true" , args [ 3 ] , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + args [ 2 ] . length + args [ 3 ] . length + 4 ) ) ;
break ;
case "name_told" :
onNameTold ( args [ 1 ] , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + 2 ) ) ;
break ;
case "is_contact" :
onIsContact ( args [ 1 ] , args [ 2 ] === "true" , args [ 3 ] , msg . data . slice ( args [ 0 ] . length + args [ 1 ] . length + args [ 2 ] . length + args [ 3 ] . length + 4 ) ) ;
break ;
case "not_seen" :
setNotSeen ( msg . data . slice ( args [ 0 ] . length + 1 ) ) ;
break ;
2021-05-04 22:26:36 +02:00
case "local_ips" :
setLocalIps ( msg . data . slice ( args [ 0 ] . length + 1 ) ) ;
break ;
2021-05-02 16:46:05 +02:00
case "set_name" :
onNameSet ( msg . data . slice ( args [ 0 ] . length + 1 ) ) ;
break ;
case "password_changed" :
onPasswordChanged ( args [ 1 ] === "true" , args [ 2 ] === "true" ) ;
break ;
case "logout" :
logout ( ) ;
}
}
}
socket . onclose = function ( ) {
console . log ( "Disconnected" ) ;
}
function onNewSession ( sessionId , outgoing , fingerprint , ip , name ) {
2021-04-28 17:57:49 +02:00
if ( sessionsData . has ( sessionId ) ) {
let session = sessionsData . get ( sessionId ) ;
2021-05-02 16:46:05 +02:00
session . isOnline = true ;
2021-04-26 19:34:24 +02:00
session . outgoing = outgoing ;
2021-05-02 16:46:05 +02:00
session . ip = ip ;
2021-04-28 17:57:49 +02:00
displaySessions ( ) ;
if ( currentSessionId == sessionId ) {
displayChatBottom ( ) ;
2021-04-26 19:34:24 +02:00
}
} else {
2021-05-02 16:46:05 +02:00
addSession ( sessionId , name , outgoing , fingerprint , ip , false , false , true ) ;
2021-04-26 19:34:24 +02:00
}
}
2021-04-28 17:57:49 +02:00
function onNameTold ( sessionId , name ) {
sessionsData . get ( sessionId ) . name = name ;
if ( sessionId == currentSessionId ) {
displayHeader ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
displaySessions ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
function setNotSeen ( str _sessionIds ) {
2021-05-04 22:26:36 +02:00
let sessionIds = str _sessionIds . split ( ' ' ) ;
2021-04-28 17:57:49 +02:00
for ( let i = 0 ; i < sessionIds . length ; ++ i ) {
sessionsData . get ( sessionIds [ i ] ) . seen = false ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
displaySessions ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-05-04 22:26:36 +02:00
function setLocalIps ( str _ips ) {
localIps = str _ips . split ( ' ' ) ;
}
2021-05-02 16:46:05 +02:00
function onIsContact ( sessionId , verified , fingerprint , name ) {
2021-04-28 17:57:49 +02:00
if ( sessionsData . has ( sessionId ) ) {
let session = sessionsData . get ( sessionId ) ;
2021-05-02 16:46:05 +02:00
session . isContact = true ;
session . isVerified = verified ;
2021-04-28 17:57:49 +02:00
onNameTold ( sessionId , name ) ;
2021-04-26 19:34:24 +02:00
} else {
2021-05-02 16:46:05 +02:00
addSession ( sessionId , name , undefined , fingerprint , undefined , true , verified , false ) ;
2021-04-26 19:34:24 +02:00
}
}
2021-04-28 17:57:49 +02:00
function onMsgOrFileReceived ( sessionId , outgoing , body ) {
if ( currentSessionId == sessionId ) {
dislayHistory ( ) ;
2021-04-26 19:34:24 +02:00
if ( ! document . hidden && ! outgoing ) {
2021-04-28 17:57:49 +02:00
socket . send ( "set_seen " + sessionId ) ;
2021-04-26 19:34:24 +02:00
}
} else {
2021-04-28 17:57:49 +02:00
sessionsData . get ( sessionId ) . seen = false ;
displaySessions ( ) ;
2021-04-26 19:34:24 +02:00
}
if ( document . hidden && ! outgoing ) {
if ( notificationAllowed ) {
2021-04-28 17:57:49 +02:00
new Notification ( sessionsData . get ( sessionId ) . name , {
2021-04-26 19:34:24 +02:00
"body" : body
} ) ;
}
}
}
2021-04-28 17:57:49 +02:00
function onNewMessage ( sessionId , outgoing , msg ) {
msgHistory . get ( sessionId ) . push ( [ outgoing , false , msg ] ) ;
onMsgOrFileReceived ( sessionId , outgoing , msg ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
function onNewFileTransfer ( sessionId , encodedFileName , fileSize , state , transferred , lastChunk ) {
pendingFiles . set ( sessionId , {
"file" : undefined ,
"name" : atob ( encodedFileName ) ,
"size" : parseInt ( fileSize ) ,
"state" : state ,
"transferred" : parseInt ( transferred ) ,
"lastChunk" : parseInt ( lastChunk )
} ) ;
if ( currentSessionId == sessionId ) {
displayChatBottom ( ) ;
2021-04-26 19:34:24 +02:00
}
}
2021-04-28 17:57:49 +02:00
function onAskLargeFile ( sessionId , fileSize , encodedFileName , encodedDownloadLocation ) {
let sessionName = sessionsData . get ( sessionId ) . name ;
let mainDiv = document . createElement ( "div" ) ;
let h2 = document . createElement ( "h2" ) ;
h2 . textContent = sessionName + " wants to send you a file:" ;
mainDiv . appendChild ( h2 ) ;
let fileName = atob ( encodedFileName ) ;
let fileInfo = document . createElement ( "p" ) ;
generateFileInfo ( fileName , fileSize , fileInfo ) ;
mainDiv . appendChild ( fileInfo ) ;
let spanDownloadLocation = document . createElement ( "span" ) ;
spanDownloadLocation . textContent = atob ( encodedDownloadLocation ) ;
let pQuestion = document . createElement ( "p" ) ;
pQuestion . appendChild ( document . createTextNode ( "Download it in " ) ) ;
pQuestion . appendChild ( spanDownloadLocation ) ;
pQuestion . appendChild ( document . createTextNode ( " ?" ) ) ;
mainDiv . appendChild ( pQuestion ) ;
let buttonRow = document . createElement ( "div" ) ;
buttonRow . classList . add ( "button_row" ) ;
let buttonDownload = document . createElement ( "button" ) ;
buttonDownload . textContent = "Download" ;
buttonDownload . onclick = function ( ) {
removePopup ( ) ;
pendingFiles . set ( sessionId , {
"file" : undefined ,
"name" : fileName ,
"size" : fileSize ,
"state" : "accepted" ,
"transferred" : 0 ,
"lastChunk" : Date . now ( )
} ) ;
socket . send ( "download " + sessionId ) ;
if ( currentSessionId == sessionId ) {
displayChatBottom ( ) ;
}
}
buttonRow . appendChild ( buttonDownload ) ;
let buttonRefuse = document . createElement ( "button" ) ;
buttonRefuse . textContent = "Refuse" ;
buttonRefuse . onclick = function ( ) {
removePopup ( ) ;
socket . send ( "abort " + sessionId ) ;
}
buttonRow . appendChild ( buttonRefuse ) ;
mainDiv . appendChild ( buttonRow ) ;
showPopup ( mainDiv , false ) ;
if ( document . hidden && notificationAllowed ) {
new Notification ( sessionName , {
"body" : fileName
} ) ;
2021-04-26 19:34:24 +02:00
}
}
2021-04-28 17:57:49 +02:00
function onFileAccepted ( sessionId ) {
if ( pendingFiles . has ( sessionId ) ) {
let file = pendingFiles . get ( sessionId ) ;
file . state = "sending" ;
file . lastChunk = Date . now ( ) ;
if ( currentSessionId == sessionId ) {
displayChatBottom ( ) ;
}
let formData = new FormData ( ) ;
formData . append ( "session_id" , currentSessionId ) ;
formData . append ( "" , file . file ) ;
fetch ( "/send_large_file" , { method : "POST" , body : formData } ) . then ( response => {
if ( ! response . ok ) {
console . log ( response ) ;
}
} ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
}
function onFileAborted ( sessionId ) {
if ( pendingFiles . has ( sessionId ) ) {
pendingFiles . get ( sessionId ) . state = "aborted" ;
if ( sessionId == currentSessionId ) {
displayChatBottom ( ) ;
}
}
}
2021-04-30 18:54:48 +02:00
function onIncFileTransfer ( sessionId , chunkSize ) {
2021-04-28 17:57:49 +02:00
if ( pendingFiles . has ( sessionId ) ) {
let file = pendingFiles . get ( sessionId ) ;
2021-04-30 18:54:48 +02:00
file . transferred += chunkSize ;
2021-04-28 17:57:49 +02:00
let now = Date . now ( ) ;
2021-04-30 18:54:48 +02:00
let speed = chunkSize / ( now - file . lastChunk ) * 1000 ;
2021-04-28 17:57:49 +02:00
file . lastChunk = now ;
if ( file . transferred >= file . size ) {
2021-04-30 18:54:48 +02:00
file . state = "completed" ;
2021-04-28 17:57:49 +02:00
} else {
file . state = "transferring" ;
}
if ( currentSessionId == sessionId ) {
displayChatBottom ( speed ) ;
}
}
}
function onMsgLoad ( sessionId , outgoing , msg ) {
msgHistory . get ( sessionId ) . unshift ( [ outgoing , false , msg ] ) ;
if ( currentSessionId == sessionId ) {
dislayHistory ( false ) ;
}
}
2021-04-30 18:54:48 +02:00
function onFileLoad ( sessionId , outgoing , uuid , fileName ) {
msgHistory . get ( sessionId ) . unshift ( [ outgoing , true , [ uuid , fileName ] ] ) ;
2021-04-28 17:57:49 +02:00
if ( currentSessionId == sessionId ) {
dislayHistory ( false ) ;
}
}
function onDisconnected ( sessionId ) {
2021-04-30 18:54:48 +02:00
pendingFiles . delete ( sessionId ) ;
2021-04-28 17:57:49 +02:00
let session = sessionsData . get ( sessionId ) ;
2021-05-02 16:46:05 +02:00
if ( session . isContact ) {
session . isOnline = false ;
2021-04-26 19:34:24 +02:00
} else {
2021-04-28 17:57:49 +02:00
sessionsData . delete ( sessionId ) ;
2021-04-30 18:54:48 +02:00
}
if ( currentSessionId == sessionId ) {
displayChatBottom ( ) ;
}
2021-05-02 16:46:05 +02:00
if ( currentSessionId == sessionId && ! session . isContact ) {
2021-04-30 18:54:48 +02:00
currentSessionId = - 1 ;
2021-05-02 16:46:05 +02:00
chatHeader . classList . add ( "offline" ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
displaySessions ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
function onFileReceived ( sessionId , uuid , file _name ) {
msgHistory . get ( sessionId ) . push ( [ false , true , [ uuid , file _name ] ] ) ;
onMsgOrFileReceived ( sessionId , false , file _name ) ;
}
function onFileSent ( sessionId , uuid , file _name ) {
msgHistory . get ( sessionId ) . push ( [ true , true , [ uuid , file _name ] ] ) ;
if ( currentSessionId == sessionId ) {
dislayHistory ( ) ;
}
}
2021-05-02 16:46:05 +02:00
function onNameSet ( newName ) {
2021-04-28 17:57:49 +02:00
removePopup ( ) ;
2021-05-02 16:46:05 +02:00
identityName = newName ;
2021-04-28 17:57:49 +02:00
displayProfile ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-05-02 16:46:05 +02:00
function onPasswordChanged ( success , isProtected ) {
2021-04-26 19:34:24 +02:00
if ( success ) {
2021-04-28 17:57:49 +02:00
removePopup ( ) ;
2021-05-02 16:46:05 +02:00
isIdentityProtected = isProtected ;
2021-04-26 19:34:24 +02:00
} else {
let input = document . querySelector ( "input[type=\"password\"]" ) ;
input . value = "" ;
2021-04-28 17:57:49 +02:00
let errorMsg = document . getElementById ( "password_errorMsg" ) ;
errorMsg . textContent = "Operation failed. Please check your old password." ;
2021-04-26 19:34:24 +02:00
}
}
2021-05-02 16:46:05 +02:00
function beautifyFingerprint ( f ) {
for ( let i = 4 ; i < f . length ; i += 5 ) {
f = f . slice ( 0 , i ) + " " + f . slice ( i ) ;
}
return f ;
} ;
function addSession ( sessionId , name , outgoing , fingerprint , ip , isContact , isVerified , isOnline ) {
2021-04-28 17:57:49 +02:00
sessionsData . set ( sessionId , {
2021-04-26 19:34:24 +02:00
"name" : name ,
"outgoing" : outgoing ,
2021-05-02 16:46:05 +02:00
"fingerprint" : fingerprint ,
"ip" : ip ,
"isContact" : isContact ,
"isVerified" : isVerified ,
2021-04-26 19:34:24 +02:00
"seen" : true ,
2021-05-02 16:46:05 +02:00
"isOnline" : isOnline ,
2021-04-26 19:34:24 +02:00
} ) ;
2021-04-28 17:57:49 +02:00
msgHistory . set ( sessionId , [ ] ) ;
displaySessions ( ) ;
2021-04-26 19:34:24 +02:00
}
2021-04-28 17:57:49 +02:00
function displaySessions ( ) {
2021-05-02 16:46:05 +02:00
let onlineSessions = document . getElementById ( "online_sessions" ) ;
onlineSessions . innerHTML = "" ;
let offlineSessions = document . getElementById ( "offline_sessions" ) ;
offlineSessions . innerHTML = "" ;
2021-04-28 17:57:49 +02:00
sessionsData . forEach ( function ( session , sessionId ) {
2021-05-02 16:46:05 +02:00
let sessionElement = generateSession ( sessionId , session ) ;
if ( session . isOnline ) {
onlineSessions . appendChild ( sessionElement ) ;
2021-04-26 19:34:24 +02:00
} else {
2021-05-02 16:46:05 +02:00
offlineSessions . appendChild ( sessionElement ) ;
2021-04-26 19:34:24 +02:00
}
} ) ;
}
function logout ( ) {
window . location = "/logout" ;
}
2021-04-28 17:57:49 +02:00
function displayProfile ( ) {
2021-04-26 19:34:24 +02:00
profile _div . innerHTML = "" ;
2021-05-02 16:46:05 +02:00
profile _div . appendChild ( generateAvatar ( identityName ) ) ;
2021-04-26 19:34:24 +02:00
let p = document . createElement ( "p" ) ;
2021-05-02 16:46:05 +02:00
p . textContent = identityName ;
2021-04-26 19:34:24 +02:00
profile _div . appendChild ( p ) ;
}
2021-04-28 17:57:49 +02:00
function displayHeader ( ) {
2021-05-02 16:46:05 +02:00
chatHeader . children [ 0 ] . innerHTML = "" ;
chatHeader . className = 0 ;
2021-04-28 17:57:49 +02:00
let session = sessionsData . get ( currentSessionId ) ;
2021-04-26 19:34:24 +02:00
if ( typeof session === "undefined" ) {
2021-05-02 16:46:05 +02:00
chatHeader . style . display = "none" ;
2021-04-26 19:34:24 +02:00
} else {
2021-05-02 16:46:05 +02:00
chatHeader . children [ 0 ] . appendChild ( generateAvatar ( session . name ) ) ;
chatHeader . children [ 0 ] . appendChild ( generateName ( session . name ) ) ;
chatHeader . style . display = "flex" ;
if ( session . isContact ) {
chatHeader . classList . add ( "is_contact" ) ;
if ( session . isVerified ) {
chatHeader . classList . add ( "is_verified" ) ;
2021-04-26 19:34:24 +02:00
}
}
}
}
2021-04-28 17:57:49 +02:00
function showPopup ( content , closeButton = true ) {
2021-04-26 19:34:24 +02:00
let popup _background = document . createElement ( "div" ) ;
popup _background . classList . add ( "popup_background" ) ;
2021-05-04 20:56:34 +02:00
popup _background . onclick = function ( e ) {
if ( e . target == popup _background ) {
removePopup ( ) ;
}
} ;
2021-04-26 19:34:24 +02:00
let popup = document . createElement ( "div" ) ;
popup . classList . add ( "popup" ) ;
2021-04-28 17:57:49 +02:00
if ( closeButton ) {
let close = document . createElement ( "button" ) ;
close . classList . add ( "close" ) ;
close . onclick = removePopup ;
popup . appendChild ( close ) ;
}
2021-04-26 19:34:24 +02:00
popup . appendChild ( content ) ;
popup _background . appendChild ( popup ) ;
let main = document . querySelector ( "main" ) ;
main . appendChild ( popup _background ) ;
}
2021-04-28 17:57:49 +02:00
function removePopup ( ) {
2021-04-26 19:34:24 +02:00
let popups = document . querySelectorAll ( ".popup_background" ) ;
if ( popups . length > 0 ) {
popups [ popups . length - 1 ] . remove ( ) ;
}
}
2021-04-28 17:57:49 +02:00
function generatePopupWarningTitle ( ) {
2021-04-26 19:34:24 +02:00
let h2 = document . createElement ( "h2" ) ;
2021-04-28 17:57:49 +02:00
h2 . classList . add ( "warning" ) ;
2021-04-26 19:34:24 +02:00
h2 . textContent = "Warning!" ;
return h2 ;
}
2021-04-28 17:57:49 +02:00
function generateName ( name ) {
2021-04-26 19:34:24 +02:00
let p = document . createElement ( "p" ) ;
if ( typeof name == "undefined" ) {
p . appendChild ( document . createTextNode ( "Unknown" ) ) ;
} else {
p . appendChild ( document . createTextNode ( name ) ) ;
}
return p ;
}
2021-04-28 17:57:49 +02:00
function generateSession ( sessionId , session ) {
2021-04-26 19:34:24 +02:00
let li = document . createElement ( "li" ) ;
2021-04-28 17:57:49 +02:00
li . setAttribute ( "data-sessionId" , sessionId ) ;
li . appendChild ( generateAvatar ( session . name ) ) ;
li . appendChild ( generateName ( session . name ) ) ;
2021-04-26 19:34:24 +02:00
if ( session . outgoing ) {
li . classList . add ( "outgoing" ) ;
} else {
li . classList . add ( "incomming" ) ;
}
2021-05-02 16:46:05 +02:00
if ( session . isContact ) {
2021-04-26 19:34:24 +02:00
li . classList . add ( "is_contact" ) ;
}
2021-05-02 16:46:05 +02:00
if ( session . isVerified ) {
2021-04-26 19:34:24 +02:00
li . classList . add ( "is_verified" ) ;
}
if ( ! session . seen ) {
let marker = document . createElement ( "div" ) ;
marker . classList . add ( "not_seen_marker" ) ;
li . appendChild ( marker ) ;
}
2021-04-28 17:57:49 +02:00
if ( sessionId == currentSessionId ) {
2021-04-26 19:34:24 +02:00
li . classList . add ( "current" ) ;
}
2021-04-28 17:57:49 +02:00
li . onclick = onClickSession ;
2021-04-26 19:34:24 +02:00
return li ;
}
2021-04-28 17:57:49 +02:00
function generateMsgHeader ( name ) {
2021-04-26 19:34:24 +02:00
let p = document . createElement ( "p" ) ;
2021-04-28 17:57:49 +02:00
p . appendChild ( document . createTextNode ( name ) ) ;
2021-04-26 19:34:24 +02:00
let div = document . createElement ( "div" ) ;
2021-05-04 11:51:08 +02:00
div . classList . add ( "header" ) ;
2021-04-28 17:57:49 +02:00
div . appendChild ( generateAvatar ( name ) ) ;
2021-04-26 19:34:24 +02:00
div . appendChild ( p ) ;
return div ;
}
2021-04-28 17:57:49 +02:00
function generateMessage ( name , msg ) {
2021-04-26 19:34:24 +02:00
let p = document . createElement ( "p" ) ;
2021-04-28 17:57:49 +02:00
p . appendChild ( document . createTextNode ( msg ) ) ;
2021-04-26 19:34:24 +02:00
let div = document . createElement ( "div" ) ;
2021-05-04 11:51:08 +02:00
div . classList . add ( "content" ) ;
2021-04-26 19:34:24 +02:00
div . appendChild ( linkifyElement ( p ) ) ;
let li = document . createElement ( "li" ) ;
2021-05-04 11:51:08 +02:00
if ( typeof name !== "undefined" ) {
li . appendChild ( generateMsgHeader ( name ) ) ;
}
2021-04-26 19:34:24 +02:00
li . appendChild ( div ) ;
return li ;
}
2021-04-28 17:57:49 +02:00
function generateFile ( name , outgoing , file _info ) {
2021-04-26 19:34:24 +02:00
let div1 = document . createElement ( "div" ) ;
div1 . classList . add ( "file" ) ;
2021-05-04 11:51:08 +02:00
div1 . classList . add ( "content" ) ;
2021-04-26 19:34:24 +02:00
let div2 = document . createElement ( "div" ) ;
let h4 = document . createElement ( "h4" ) ;
if ( outgoing ) {
h4 . textContent = "File sent:" ;
} else {
h4 . textContent = "File received:" ;
}
div2 . appendChild ( h4 ) ;
let p = document . createElement ( "p" ) ;
p . textContent = file _info [ 1 ] ;
div2 . appendChild ( p ) ;
div1 . appendChild ( div2 ) ;
let a = document . createElement ( "a" ) ;
a . href = "/load_file?uuid=" + file _info [ 0 ] + "&file_name=" + encodeURIComponent ( file _info [ 1 ] ) ;
a . target = "_blank" ;
div1 . appendChild ( a ) ;
let li = document . createElement ( "li" ) ;
2021-05-04 11:51:08 +02:00
if ( typeof name !== "undefined" ) {
li . appendChild ( generateMsgHeader ( name ) ) ;
}
2021-04-26 19:34:24 +02:00
li . appendChild ( div1 ) ;
return li ;
}
2021-04-28 17:57:49 +02:00
function generateFileInfo ( fileName , fileSize , p ) {
let span = document . createElement ( "span" ) ;
span . textContent = fileName ;
p . appendChild ( span ) ;
p . appendChild ( document . createTextNode ( " (" + humanFileSize ( fileSize ) + ")" ) ) ;
}
function displayChatBottom ( speed = undefined ) {
2021-04-30 18:54:48 +02:00
let msgBox = document . getElementById ( "message_box" ) ;
2021-04-28 17:57:49 +02:00
let session = sessionsData . get ( currentSessionId ) ;
2021-04-30 18:54:48 +02:00
if ( typeof session === "undefined" ) {
msgBox . removeAttribute ( "style" ) ;
2021-04-28 17:57:49 +02:00
} else {
2021-05-02 16:46:05 +02:00
if ( session . isOnline ) {
2021-04-30 18:54:48 +02:00
msgBox . style . display = "flex" ;
} else {
msgBox . removeAttribute ( "style" ) ;
}
let fileTransfer = document . getElementById ( "file_transfer" ) ;
if ( pendingFiles . has ( currentSessionId ) ) {
let file = pendingFiles . get ( currentSessionId ) ;
let fileInfo = document . getElementById ( "file_info" ) ;
fileInfo . innerHTML = "" ;
generateFileInfo ( file . name , file . size , fileInfo ) ;
let fileProgress = document . getElementById ( "file_progress" ) ;
fileProgress . style . display = "none" ; //hide by default
let fileStatus = document . getElementById ( "file_status" ) ;
fileStatus . removeAttribute ( "style" ) ; //show by default
let fileCancel = document . getElementById ( "file_cancel" ) ;
fileCancel . style . display = "none" ; //hide by default
document . querySelector ( "#file_progress_bar>div" ) . style . width = 0 ;
switch ( file . state ) {
case "transferring" :
fileCancel . removeAttribute ( "style" ) ; //show
fileStatus . style . display = "none" ;
fileProgress . removeAttribute ( "style" ) ; //show
let percent = ( file . transferred / file . size ) * 100 ;
document . getElementById ( "file_percent" ) . textContent = percent . toFixed ( 2 ) + "%" ;
if ( typeof speed !== "undefined" ) {
document . getElementById ( "file_speed" ) . textContent = humanFileSize ( speed ) + "/s" ;
}
document . querySelector ( "#file_progress_bar>div" ) . style . width = Math . round ( percent ) + "%" ;
break ;
case "waiting" :
fileStatus . textContent = "Waiting for peer confirmation..." ;
break ;
case "accepted" :
fileStatus . textContent = "Downloading file..." ;
break ;
case "aborted" :
fileStatus . textContent = "Transfer aborted." ;
pendingFiles . delete ( currentSessionId ) ;
break ;
case "sending" :
fileStatus . textContent = "Sending file..." ;
break ;
case "completed" :
fileStatus . textContent = "Transfer completed." ;
pendingFiles . delete ( currentSessionId ) ;
}
fileTransfer . classList . add ( "active" ) ;
} else {
fileTransfer . classList . remove ( "active" ) ;
2021-04-28 17:57:49 +02:00
}
}
}
function dislayHistory ( scrollToBottom = true ) {
2021-04-26 19:34:24 +02:00
msg _log . style . display = "block" ;
msg _log . innerHTML = "" ;
2021-05-04 11:51:08 +02:00
let previousOutgoing = undefined ;
2021-04-28 17:57:49 +02:00
msgHistory . get ( currentSessionId ) . forEach ( entry => {
2021-05-04 11:51:08 +02:00
let name = undefined ;
if ( previousOutgoing != entry [ 0 ] ) {
previousOutgoing = entry [ 0 ] ;
if ( entry [ 0 ] ) { //outgoing msg
name = identityName ;
} else {
name = sessionsData . get ( currentSessionId ) . name ;
}
2021-04-26 19:34:24 +02:00
}
2021-05-04 11:51:08 +02:00
if ( entry [ 1 ] ) { //is file
2021-04-28 17:57:49 +02:00
msg _log . appendChild ( generateFile ( name , entry [ 0 ] , entry [ 2 ] ) ) ;
2021-04-26 19:34:24 +02:00
} else {
2021-04-28 17:57:49 +02:00
msg _log . appendChild ( generateMessage ( name , entry [ 2 ] ) ) ;
2021-04-26 19:34:24 +02:00
}
} ) ;
if ( scrollToBottom ) {
msg _log . scrollTop = msg _log . scrollHeight ;
}
2021-04-30 18:54:48 +02:00
}