Add onionshare CLI to cli folder, move GUI to desktop folder, and start refactoring it to work with briefcase

This commit is contained in:
Micah Lee 2020-10-12 22:40:55 -07:00
parent b81a55f546
commit f4abcf1be9
No known key found for this signature in database
GPG key ID: 403C2657CD994F73
583 changed files with 14871 additions and 474 deletions

View 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;
};

File diff suppressed because one or more lines are too long

View 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);
});
});

View 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);
});

File diff suppressed because one or more lines are too long