From 3c1bb6896fbfd589811e1d750456694146aa5b6d Mon Sep 17 00:00:00 2001 From: Jeremy Mahieu Date: Fri, 1 May 2020 00:58:07 +0200 Subject: [PATCH 1/7] Show toast with deletion link for imgur uploads --- css/glowingbear.css | 2 +- css/themes/base16-default.css | 2 +- css/themes/blue.css | 2 +- css/themes/dark.css | 2 +- css/themes/light.css | 2 +- js/imgur.js | 59 +++++++++++++++++++++++++++++++++-- js/inputbar.js | 33 ++++++++++++++++---- 7 files changed, 89 insertions(+), 13 deletions(-) diff --git a/css/glowingbear.css b/css/glowingbear.css index 2541ee4..fb67eb7 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -708,7 +708,7 @@ img.emojione { width: auto; } -#toast { +.toast { position: fixed; left: 50%; bottom: 50px; 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..aa0db4d 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 { @@ -125,6 +125,60 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting }; + // 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; + } + + // Add the image to the provided album if configured to do so + if (!isClientID && settings.iAlb.length >= 6) { + fd.append("album", settings.iAlb); + } + + // 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(); + + } else { + showErrorMsg(); + } + + }; + + + // Send request with form data + xhttp.send(null); + + }; + var showErrorMsg = function() { // Show error msg $rootScope.uploadError = true; @@ -139,7 +193,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..6324685 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,10 +277,21 @@ weechat.directive('inputBar', function() { // Process image imgur.process(files[i], sendImageUrl); } - } }; + var deleteCallback = function () { + // 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); + } + + $scope.imgurDelete = function (deleteHash) { + imgur.deleteImage( deleteHash, deleteCallback ); + }; + // Send the message to the websocket $scope.sendMessage = function() { //XXX Use a signal here @@ -351,7 +363,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.innerHTML = nick + " has left the room"; document.body.appendChild(toast); setTimeout(function() { document.body.removeChild(toast); }, 5000); @@ -750,15 +762,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); }, 5000); + + // 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++) { From 820b9fd762a9b394686e2c9a91b5b8aece67e320 Mon Sep 17 00:00:00 2001 From: Jeremy Mahieu Date: Fri, 1 May 2020 01:11:47 +0200 Subject: [PATCH 2/7] Delete unneeded code from imgurDelete --- js/imgur.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/js/imgur.js b/js/imgur.js index aa0db4d..877ef0a 100644 --- a/js/imgur.js +++ b/js/imgur.js @@ -140,11 +140,6 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting isClientID = false; } - // Add the image to the provided album if configured to do so - if (!isClientID && settings.iAlb.length >= 6) { - fd.append("album", settings.iAlb); - } - // Create new XMLHttpRequest var xhttp = new XMLHttpRequest(); From 8518f9881216a9b13e75658e135dbb44d7821b04 Mon Sep 17 00:00:00 2001 From: Jeremy Mahieu Date: Fri, 1 May 2020 23:23:47 +0200 Subject: [PATCH 3/7] Close div --- js/inputbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/inputbar.js b/js/inputbar.js index 6324685..c4561f3 100644 --- a/js/inputbar.js +++ b/js/inputbar.js @@ -283,7 +283,7 @@ weechat.directive('inputBar', function() { var deleteCallback = function () { // Image got sucessfully deleted. // Show toast with delete link - var toastDeleted = $compile('
Successfully deleted.')($scope)[0]; + var toastDeleted = $compile('
Successfully deleted.
')($scope)[0]; document.body.appendChild(toastDeleted); setTimeout(function() { document.body.removeChild(toastDeleted); }, 5000); } From a2912b94b6c89ee6abaddfa04383456dd3e98a01 Mon Sep 17 00:00:00 2001 From: Jeremy Mahieu Date: Fri, 1 May 2020 23:28:54 +0200 Subject: [PATCH 4/7] Remove some whitelines --- js/imgur.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/js/imgur.js b/js/imgur.js index 877ef0a..f743bc3 100644 --- a/js/imgur.js +++ b/js/imgur.js @@ -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,9 @@ 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 @@ -156,22 +151,16 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting // Handler for response xhttp.onload = function() { - // Check state and response status if(xhttp.status === 200) { - callback(); - } else { showErrorMsg(); } - }; - - + // Send request with form data xhttp.send(null); - }; var showErrorMsg = function() { From 3e38d6d74fec76e3dd34a6eedb528c83399358ab Mon Sep 17 00:00:00 2001 From: Jeremy Mahieu Date: Fri, 1 May 2020 23:33:49 +0200 Subject: [PATCH 5/7] Longer toast time after upload --- js/inputbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/inputbar.js b/js/inputbar.js index c4561f3..3444fde 100644 --- a/js/inputbar.js +++ b/js/inputbar.js @@ -776,7 +776,7 @@ weechat.directive('inputBar', function() { // 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); }, 5000); + setTimeout(function() { document.body.removeChild(toastImgur); }, 10000); // 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 + '\')'); From 696c08200bf1f6ba76273da77190c07783128223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Mon, 4 May 2020 17:01:30 +0200 Subject: [PATCH 6/7] Split toasts into short (5s) and long (15s) toasts --- css/glowingbear.css | 9 ++++++++- js/inputbar.js | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/css/glowingbear.css b/css/glowingbear.css index 3bbbf6a..1aac1f8 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -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/js/inputbar.js b/js/inputbar.js index 3444fde..f84afac 100644 --- a/js/inputbar.js +++ b/js/inputbar.js @@ -283,7 +283,7 @@ weechat.directive('inputBar', function() { var deleteCallback = function () { // Image got sucessfully deleted. // Show toast with delete link - var toastDeleted = $compile('
Successfully deleted.
')($scope)[0]; + var toastDeleted = $compile('
Successfully deleted.
')($scope)[0]; document.body.appendChild(toastDeleted); setTimeout(function() { document.body.removeChild(toastDeleted); }, 5000); } @@ -363,7 +363,7 @@ weechat.directive('inputBar', function() { if (buffer.type === 'channel' && !is_online) { // show a toast that the user left var toast = document.createElement('div'); - toast.className = "toast"; + toast.className = "toast toast-short"; toast.innerHTML = nick + " has left the room"; document.body.appendChild(toast); setTimeout(function() { document.body.removeChild(toast); }, 5000); @@ -774,9 +774,9 @@ weechat.directive('inputBar', function() { } // Show toast with delete link - var toastImgur = $compile('
Image uploaded to Imgur. Delete?
')($scope)[0]; + var toastImgur = $compile('
Image uploaded to Imgur. Delete?
')($scope)[0]; document.body.appendChild(toastImgur); - setTimeout(function() { document.body.removeChild(toastImgur); }, 10000); + 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 + '\')'); From 6214e1373cf0715be01de1837daf73cfc5043c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Mon, 4 May 2020 17:13:17 +0200 Subject: [PATCH 7/7] Remove deletion toast after deletion --- js/imgur.js | 2 +- js/inputbar.js | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/js/imgur.js b/js/imgur.js index f743bc3..3162cbc 100644 --- a/js/imgur.js +++ b/js/imgur.js @@ -153,7 +153,7 @@ weechat.factory('imgur', ['$rootScope', 'settings', function($rootScope, setting xhttp.onload = function() { // Check state and response status if(xhttp.status === 200) { - callback(); + callback(deletehash); } else { showErrorMsg(); } diff --git a/js/inputbar.js b/js/inputbar.js index f84afac..b2725f9 100644 --- a/js/inputbar.js +++ b/js/inputbar.js @@ -280,12 +280,20 @@ weechat.directive('inputBar', function() { } }; - var deleteCallback = function () { + 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) { @@ -774,7 +782,7 @@ weechat.directive('inputBar', function() { } // Show toast with delete link - var toastImgur = $compile('
Image uploaded to Imgur. Delete?
')($scope)[0]; + var toastImgur = $compile('
Image uploaded to Imgur. Delete?
')($scope)[0]; document.body.appendChild(toastImgur); setTimeout(function() { document.body.removeChild(toastImgur); }, 15000);