diff --git a/css/glowingbear.css b/css/glowingbear.css index c00e615..1aac1f8 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -693,7 +693,7 @@ li.buffer.indent.private a { user-select: none; } -#toast { +.toast { position: fixed; left: 50%; bottom: 50px; @@ -704,7 +704,14 @@ li.buffer.indent.private a { border-radius: 3px; padding: 10px 15px; z-index: 100; - animation: fadein 0.5s, fadeout 0.5s 4.5s; +} + +.toast-short { + animation: fadein 0.5s, fadeout 0.5s 4.5s; +} + +.toast-long { + animation: fadein 0.5s, fadeout 0.5s 14.5s; } @keyframes fadein { diff --git a/css/themes/base16-default.css b/css/themes/base16-default.css index 2324240..b5afe88 100644 --- a/css/themes/base16-default.css +++ b/css/themes/base16-default.css @@ -423,7 +423,7 @@ button.close:hover { color: var(--base01); } -#toast { +.toast { background-color: var(--base01); } diff --git a/css/themes/blue.css b/css/themes/blue.css index cb666bc..3036162 100644 --- a/css/themes/blue.css +++ b/css/themes/blue.css @@ -134,7 +134,7 @@ input[type=text], input[type=password], #sendMessage, .badge, .btn-send, .btn-se border: 1px solid #363943; } -#toast { +.toast { background-color: #283244; border: 1px solid; border-color: rgb(29, 94, 152); diff --git a/css/themes/dark.css b/css/themes/dark.css index 4d845fe..982ab9b 100644 --- a/css/themes/dark.css +++ b/css/themes/dark.css @@ -2126,7 +2126,7 @@ code { color: #fff; } -#toast { +.toast { background-color: #333; } diff --git a/css/themes/light.css b/css/themes/light.css index 900404d..dcb475e 100644 --- a/css/themes/light.css +++ b/css/themes/light.css @@ -2092,7 +2092,7 @@ input[type=text].is-invalid{ font-weight: bold; } -#toast { +.toast { background-color: #ddd; } diff --git a/js/imgur.js b/js/imgur.js index 0ec0f97..3162cbc 100644 --- a/js/imgur.js +++ b/js/imgur.js @@ -90,7 +90,7 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting if( response.data && response.data.link ) { if (callback && typeof(callback) === "function") { - callback(response.data.link.replace(/^http:/, "https:")); + callback(response.data.link.replace(/^http:/, "https:"), response.data.deletehash); } } else { @@ -104,10 +104,8 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting }; if( "upload" in xhttp ) { - // Set progress xhttp.upload.onprogress = function (event) { - // Check if we can compute progress if (event.lengthComputable) { // Complete in percent @@ -117,12 +115,52 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting currentProgressBar.style.width = complete + '%'; } }; - } - // Send request with form data xhttp.send(fd); + }; + + // Delete an image from imgur with the deletion link + var deleteImage = function( deletehash, callback ) { + + // API authorization, either via Client ID (anonymous) or access token + // (add to user's imgur account), see also: + // https://github.com/glowing-bear/glowing-bear/wiki/Getting-an-imgur-token-&-album-hash + var accessToken = "164efef8979cd4b"; + var isClientID = true; + + // Check whether the user has provided an access token + if (settings.iToken.length > 37){ + accessToken = settings.iToken; + isClientID = false; + } + + // Create new XMLHttpRequest + var xhttp = new XMLHttpRequest(); + + // Post request to imgur api + xhttp.open("DELETE", "https://api.imgur.com/3/image/" + deletehash, true); + + // Set headers + if (isClientID) { + xhttp.setRequestHeader("Authorization", "Client-ID " + accessToken); + } else { + xhttp.setRequestHeader("Authorization", "Bearer " + accessToken); + } + xhttp.setRequestHeader("Accept", "application/json"); + // Handler for response + xhttp.onload = function() { + // Check state and response status + if(xhttp.status === 200) { + callback(deletehash); + } else { + showErrorMsg(); + } + }; + + // Send request with form data + xhttp.send(null); }; var showErrorMsg = function() { @@ -139,7 +177,8 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting }; return { - process: process + process: process, + deleteImage: deleteImage }; }]); diff --git a/js/inputbar.js b/js/inputbar.js index 380429b..b2725f9 100644 --- a/js/inputbar.js +++ b/js/inputbar.js @@ -14,10 +14,11 @@ weechat.directive('inputBar', function() { command: '=command' }, - controller: ['$rootScope', '$scope', '$element', '$log', 'connection', 'imgur', 'models', 'IrcUtils', 'settings', 'utils', function($rootScope, + controller: ['$rootScope', '$scope', '$element', '$log', '$compile', 'connection', 'imgur', 'models', 'IrcUtils', 'settings', 'utils', function($rootScope, $scope, $element, //XXX do we need this? don't seem to be using it $log, + $compile, connection, //XXX we should eliminate this dependency and use signals instead imgur, models, @@ -263,8 +264,8 @@ weechat.directive('inputBar', function() { $scope.uploadImage = function($event, files) { // Send image url after upload - var sendImageUrl = function(imageUrl) { - // Send image + var sendImageUrl = function(imageUrl, deleteHash) { + // Put link in input box if(imageUrl !== undefined && imageUrl !== '') { $rootScope.insertAtCaret(String(imageUrl)); } @@ -276,8 +277,27 @@ weechat.directive('inputBar', function() { // Process image imgur.process(files[i], sendImageUrl); } + } + }; + + var deleteCallback = function (deleteHash) { + // Image got sucessfully deleted. + // Show toast with delete link + var toastDeleted = $compile('
Successfully deleted.
')($scope)[0]; + document.body.appendChild(toastDeleted); + setTimeout(function() { document.body.removeChild(toastDeleted); }, 5000); + // Try to remove the toast with the deletion link (it stays 15s + // instead of the 5 of the deletion notification, so it could + // come back beneath it, which would be confusing) + var pasteToast = document.querySelector("[data-imgur-deletehash='" + deleteHash + "']"); + if (!!pasteToast) { + document.body.removeChild(pasteToast); } + } + + $scope.imgurDelete = function (deleteHash) { + imgur.deleteImage( deleteHash, deleteCallback ); }; // Send the message to the websocket @@ -351,7 +371,7 @@ weechat.directive('inputBar', function() { if (buffer.type === 'channel' && !is_online) { // show a toast that the user left var toast = document.createElement('div'); - toast.id = "toast"; + toast.className = "toast toast-short"; toast.innerHTML = nick + " has left the room"; document.body.appendChild(toast); setTimeout(function() { document.body.removeChild(toast); }, 5000); @@ -750,15 +770,24 @@ weechat.directive('inputBar', function() { return true; }; + $scope.inputPasted = function(e) { if (e.clipboardData && e.clipboardData.files && e.clipboardData.files.length) { e.stopPropagation(); e.preventDefault(); - var sendImageUrl = function(imageUrl) { + var sendImageUrl = function(imageUrl, deleteHash) { if(imageUrl !== undefined && imageUrl !== '') { $rootScope.insertAtCaret(String(imageUrl)); } + + // Show toast with delete link + var toastImgur = $compile('
Image uploaded to Imgur. Delete?
')($scope)[0]; + document.body.appendChild(toastImgur); + setTimeout(function() { document.body.removeChild(toastImgur); }, 15000); + + // Log the delete hash to the console in case the toast was missed. + console.log('An image was uploaded to imgur, delete it with $scope.imgurDelete(\'' + deleteHash + '\')'); }; for (var i = 0; i < e.clipboardData.files.length; i++) {