mirror of
https://github.com/onionshare/onionshare.git
synced 2025-05-02 14:36:15 -04:00
Add onionshare CLI to cli folder, move GUI to desktop folder, and start refactoring it to work with briefcase
This commit is contained in:
parent
b81a55f546
commit
f4abcf1be9
583 changed files with 14871 additions and 474 deletions
165
cli/onionshare_cli/resources/static/js/chat.js
Normal file
165
cli/onionshare_cli/resources/static/js/chat.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
$(function () {
|
||||
$(document).ready(function () {
|
||||
$('.chat-container').removeClass('no-js');
|
||||
var socket = io.connect('http://' + document.domain + ':' + location.port + '/chat');
|
||||
|
||||
// Store current username received from app context
|
||||
var current_username = $('#username').val();
|
||||
|
||||
// On browser connect, emit a socket event to be added to
|
||||
// room and assigned random username
|
||||
socket.on('connect', function () {
|
||||
socket.emit('joined', {});
|
||||
});
|
||||
|
||||
// Triggered on any status change by any user, such as some
|
||||
// user joined, or changed username, or left, etc.
|
||||
socket.on('status', function (data) {
|
||||
addMessageToRoom(data, current_username, 'status');
|
||||
console.log(data, current_username);
|
||||
});
|
||||
|
||||
// Triggered when message is received from a user. Even when sent
|
||||
// by self, it get triggered after the server sends back the emit.
|
||||
socket.on('message', function (data) {
|
||||
addMessageToRoom(data, current_username, 'chat');
|
||||
console.log(data, current_username);
|
||||
});
|
||||
|
||||
// Triggered when disconnected either by server stop or timeout
|
||||
socket.on('disconnect', function (data) {
|
||||
addMessageToRoom({ 'msg': 'The chat server is disconnected.' }, current_username, 'status');
|
||||
})
|
||||
socket.on('connect_error', function (error) {
|
||||
console.log("error");
|
||||
})
|
||||
|
||||
// Trigger new message on enter or click of send message button.
|
||||
$('#new-message').on('keypress', function (e) {
|
||||
var code = e.keyCode || e.which;
|
||||
if (code == 13) {
|
||||
emitMessage(socket);
|
||||
}
|
||||
});
|
||||
|
||||
// Keep buttons disabled unless changed or not empty
|
||||
$('#username').on('keyup', function (event) {
|
||||
if ($('#username').val() !== '' && $('#username').val() !== current_username) {
|
||||
if (event.keyCode == 13) {
|
||||
current_username = updateUsername(socket) || current_username;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Show warning of losing data
|
||||
$(window).on('beforeunload', function (e) {
|
||||
e.preventDefault();
|
||||
e.returnValue = '';
|
||||
return '';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var addMessageToRoom = function (data, current_username, messageType) {
|
||||
var scrollDiff = getScrollDiffBefore();
|
||||
if (messageType === 'status') {
|
||||
addStatusMessage(data.msg);
|
||||
if (data.connected_users) {
|
||||
addUserList(data.connected_users, current_username);
|
||||
}
|
||||
} else if (messageType === 'chat') {
|
||||
addChatMessage(data.username, data.msg)
|
||||
}
|
||||
scrollBottomMaybe(scrollDiff);
|
||||
}
|
||||
|
||||
var emitMessage = function (socket) {
|
||||
var text = $('#new-message').val();
|
||||
$('#new-message').val('');
|
||||
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||
socket.emit('text', { msg: text });
|
||||
}
|
||||
|
||||
var updateUsername = function (socket) {
|
||||
var username = $('#username').val();
|
||||
if (!checkUsernameExists(username)) {
|
||||
socket.emit('update_username', { username: username });
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: `http://${document.domain}:${location.port}/update-session-username`,
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({ 'username': username })
|
||||
}).done(function (response) {
|
||||
console.log(response);
|
||||
});
|
||||
return username;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/********* Util Functions ***********/
|
||||
/************************************/
|
||||
|
||||
var createUserListHTML = function (connected_users, current_user) {
|
||||
var userListHTML = '';
|
||||
connected_users.sort();
|
||||
connected_users.forEach(function (username) {
|
||||
if (username !== current_user) {
|
||||
userListHTML += `<li>${sanitizeHTML(username)}</li>`;
|
||||
}
|
||||
});
|
||||
return userListHTML;
|
||||
}
|
||||
|
||||
var checkUsernameExists = function (username) {
|
||||
$('#username-error').text('');
|
||||
var userMatches = $('#user-list li').filter(function () {
|
||||
return $(this).text() === username;
|
||||
});
|
||||
if (userMatches.length) {
|
||||
$('#username-error').text('User with that username exists!');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var getScrollDiffBefore = function () {
|
||||
return $('#chat').scrollTop() - ($('#chat')[0].scrollHeight - $('#chat')[0].offsetHeight);
|
||||
}
|
||||
|
||||
var scrollBottomMaybe = function (scrollDiff) {
|
||||
// Scrolls to bottom if the user is scrolled at bottom
|
||||
// if the user has scrolled upp, it wont scroll at bottom.
|
||||
// Note: when a user themselves send a message, it will still
|
||||
// scroll to the bottom even if they had scrolled up before.
|
||||
if (scrollDiff > 0) {
|
||||
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||
}
|
||||
}
|
||||
|
||||
var addStatusMessage = function (message) {
|
||||
$('#chat').append(
|
||||
`<p class="status">${sanitizeHTML(message)}</p>`
|
||||
);
|
||||
}
|
||||
|
||||
var addChatMessage = function (username, message) {
|
||||
$('#chat').append(`<p><span class="username">${sanitizeHTML(username)}</span><span class="message">${sanitizeHTML(message)}</span></p>`);
|
||||
}
|
||||
|
||||
var addUserList = function (connected_users, current_username) {
|
||||
$('#user-list').html(
|
||||
createUserListHTML(
|
||||
connected_users,
|
||||
current_username
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var sanitizeHTML = function (str) {
|
||||
var temp = document.createElement('span');
|
||||
temp.textContent = str;
|
||||
return temp.innerHTML;
|
||||
};
|
2
cli/onionshare_cli/resources/static/js/jquery-3.5.1.min.js
vendored
Normal file
2
cli/onionshare_cli/resources/static/js/jquery-3.5.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
130
cli/onionshare_cli/resources/static/js/receive.js
Normal file
130
cli/onionshare_cli/resources/static/js/receive.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
$(function(){
|
||||
// Add a flash message
|
||||
var flash = function(category, message) {
|
||||
$('#flashes').append($('<li>').addClass(category).text(message));
|
||||
};
|
||||
|
||||
var scriptSrc = document.getElementById('receive-script').src;
|
||||
var staticImgPath = scriptSrc.substr(0, scriptSrc.lastIndexOf( '/' )+1).replace('js', 'img');
|
||||
|
||||
// Intercept submitting the form
|
||||
$('#send').submit(function(event){
|
||||
event.preventDefault();
|
||||
|
||||
// Create form data, and list of filenames
|
||||
var files = $('#file-select').get(0).files;
|
||||
var filenames = [];
|
||||
var formData = new FormData();
|
||||
for(var i = 0; i < files.length; i++) {
|
||||
var file = files[i];
|
||||
filenames.push(file.name);
|
||||
formData.append('file[]', file, file.name);
|
||||
}
|
||||
|
||||
// Reset the upload form
|
||||
$('#send').get(0).reset();
|
||||
|
||||
// Don't use jQuery for ajax request, because the upload progress event doesn't
|
||||
// have access to the the XMLHttpRequest object
|
||||
var ajax = new XMLHttpRequest();
|
||||
|
||||
ajax.upload.addEventListener('progress', function(event){
|
||||
// Update progress bar for this specific upload
|
||||
if(event.lengthComputable) {
|
||||
$('progress', ajax.$upload_div).attr({
|
||||
value: event.loaded,
|
||||
max: event.total,
|
||||
});
|
||||
}
|
||||
|
||||
// If it's finished sending all data to the first Tor node, remove cancel button
|
||||
// and update the status
|
||||
if(event.loaded == event.total) {
|
||||
$('.cancel', ajax.$upload_div).remove();
|
||||
$('.upload-status', ajax.$upload_div).html('<img src="' + staticImgPath + '/ajax.gif" alt="" /> Waiting for data to finish traversing Tor network ...');
|
||||
}
|
||||
}, false);
|
||||
|
||||
ajax.addEventListener('load', function(event){
|
||||
// Remove the upload div
|
||||
ajax.$upload_div.remove();
|
||||
|
||||
// Parse response
|
||||
try {
|
||||
var response = JSON.parse(ajax.response);
|
||||
|
||||
// The 'new_body' response replaces the whole HTML document and ends
|
||||
if('new_body' in response) {
|
||||
$('body').html(response['new_body']);
|
||||
return;
|
||||
}
|
||||
|
||||
// Show error flashes
|
||||
if('error_flashes' in response) {
|
||||
for(var i=0; i<response['error_flashes'].length; i++) {
|
||||
flash('error', response['error_flashes'][i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Show info flashes
|
||||
if('info_flashes' in response) {
|
||||
for(var i=0; i<response['info_flashes'].length; i++) {
|
||||
flash('info', response['info_flashes'][i]);
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
flash('error', 'Invalid response from server: '+data);
|
||||
}
|
||||
}, false);
|
||||
|
||||
ajax.addEventListener('error', function(event){
|
||||
flash('error', 'Error uploading: '+filenames.join(', '));
|
||||
|
||||
// Remove the upload div
|
||||
ajax.$upload_div.remove()
|
||||
}, false);
|
||||
|
||||
ajax.addEventListener('abort', function(event){
|
||||
flash('error', 'Upload aborted: '+filenames.join(', '));
|
||||
}, false);
|
||||
|
||||
// Make the upload div
|
||||
|
||||
/* The DOM for an upload looks something like this:
|
||||
<div class="upload">
|
||||
<div class="upload-meta">
|
||||
<input class="cancel" type="button" value="Cancel" />
|
||||
<div class="upload-filename">educational-video.mp4, secret-plans.pdf</div>
|
||||
<div class="upload-status">Sending to first Tor node ...</div>
|
||||
</div>
|
||||
<progress value="25" max="100"></progress>
|
||||
</div> */
|
||||
var $progress = $('<progress>').attr({ value: '0', max: 100 });
|
||||
var $cancel_button = $('<input>').addClass('cancel').attr({ type: 'button', value: 'Cancel' });
|
||||
var $upload_filename = $('<div>').addClass('upload-filename').text(filenames.join(', '));
|
||||
var $upload_status = $('<div>').addClass('upload-status').text('Sending data to initial Tor node ...');
|
||||
|
||||
var $upload_div = $('<div>')
|
||||
.addClass('upload')
|
||||
.append(
|
||||
$('<div>').addClass('upload-meta')
|
||||
.append($cancel_button)
|
||||
.append($upload_filename)
|
||||
.append($upload_status)
|
||||
)
|
||||
.append($progress);
|
||||
|
||||
$cancel_button.click(function(){
|
||||
// Abort the upload, and remove the upload div
|
||||
ajax.abort();
|
||||
$upload_div.remove()
|
||||
});
|
||||
|
||||
ajax.$upload_div = $upload_div;
|
||||
$('#uploads').append($upload_div);
|
||||
|
||||
// Send the request
|
||||
ajax.open('POST', '/upload-ajax', true);
|
||||
ajax.send(formData);
|
||||
});
|
||||
});
|
75
cli/onionshare_cli/resources/static/js/send.js
Normal file
75
cli/onionshare_cli/resources/static/js/send.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Function to convert human-readable sizes back to bytes, for sorting
|
||||
function unhumanize(text) {
|
||||
var powers = {'b': 0, 'k': 1, 'm': 2, 'g': 3, 't': 4};
|
||||
var regex = /(\d+(?:\.\d+)?)\s?(B|K|M|G|T)?/i;
|
||||
var res = regex.exec(text);
|
||||
if(res[2] === undefined) {
|
||||
// Account for alphabetical words (file/dir names)
|
||||
return text;
|
||||
} else {
|
||||
return res[1] * Math.pow(1024, powers[res[2].toLowerCase()]);
|
||||
}
|
||||
}
|
||||
function sortTable(n) {
|
||||
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
|
||||
table = document.getElementById("file-list");
|
||||
switching = true;
|
||||
// Set the sorting direction to ascending:
|
||||
dir = "asc";
|
||||
/* Make a loop that will continue until
|
||||
no switching has been done: */
|
||||
while (switching) {
|
||||
// Start by saying: no switching is done:
|
||||
switching = false;
|
||||
rows = table.getElementsByTagName("TR");
|
||||
/* Loop through all table rows (except the
|
||||
first, which contains table headers): */
|
||||
for (i = 1; i < (rows.length - 1); i++) {
|
||||
// Start by saying there should be no switching:
|
||||
shouldSwitch = false;
|
||||
/* Get the two elements you want to compare,
|
||||
one from current row and one from the next: */
|
||||
x = rows[i].getElementsByTagName("TD")[n];
|
||||
y = rows[i + 1].getElementsByTagName("TD")[n];
|
||||
/* Check if the two rows should switch place,
|
||||
based on the direction, asc or desc: */
|
||||
if (dir == "asc") {
|
||||
if (unhumanize(x.innerHTML.toLowerCase()) > unhumanize(y.innerHTML.toLowerCase())) {
|
||||
// If so, mark as a switch and break the loop:
|
||||
shouldSwitch= true;
|
||||
break;
|
||||
}
|
||||
} else if (dir == "desc") {
|
||||
if (unhumanize(x.innerHTML.toLowerCase()) < unhumanize(y.innerHTML.toLowerCase())) {
|
||||
// If so, mark as a switch and break the loop:
|
||||
shouldSwitch= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldSwitch) {
|
||||
/* If a switch has been marked, make the switch
|
||||
and mark that a switch has been done: */
|
||||
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
|
||||
switching = true;
|
||||
// Each time a switch is done, increase this count by 1:
|
||||
switchcount ++;
|
||||
} else {
|
||||
/* If no switching has been done AND the direction is "asc",
|
||||
set the direction to "desc" and run the while loop again. */
|
||||
if (switchcount == 0 && dir == "asc") {
|
||||
dir = "desc";
|
||||
switching = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set click handlers
|
||||
document.getElementById("filename-header").addEventListener("click", function(){
|
||||
sortTable(0);
|
||||
});
|
||||
document.getElementById("size-header").addEventListener("click", function(){
|
||||
sortTable(1);
|
||||
});
|
3
cli/onionshare_cli/resources/static/js/socket.io.min.js
vendored
Normal file
3
cli/onionshare_cli/resources/static/js/socket.io.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue