Fix cloud storage errors not reported in user interface

Related feedback:
- https://www.reddit.com/r/uBlockOrigin/comments/i6e7lr/
This commit is contained in:
Raymond Hill 2020-08-10 08:30:52 -04:00
parent 3bcd970e07
commit b01cc6ca4f
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 44 additions and 49 deletions

View File

@ -1599,28 +1599,14 @@ vAPI.cloud = (( ) => {
}
bin[dataKey + chunkCount.toString()] = ''; // Sentinel
let result;
let errorStr;
try {
result = await webext.storage.sync.set(bin);
await webext.storage.sync.set(bin);
} catch (reason) {
errorStr = reason;
}
// https://github.com/gorhill/uBlock/issues/3006#issuecomment-332597677
// - Delete all that was pushed in case of failure.
// - It's unknown whether such issue applies only to Firefox:
// until such cases are reported for other browsers, we will
// reset the (now corrupted) content of the cloud storage
// only on Firefox.
if ( errorStr !== undefined && vAPI.webextFlavor.soup.has('firefox') ) {
chunkCount = 0;
return String(reason);
}
// Remove potentially unused trailing chunks
deleteChunks(dataKey, chunkCount);
return errorStr;
};
const pull = async function(dataKey) {
@ -1638,7 +1624,7 @@ vAPI.cloud = (( ) => {
try {
bin = await webext.storage.sync.get(chunkKeys);
} catch (reason) {
return reason;
return String(reason);
}
// Assemble chunks into a single string.

View File

@ -5,14 +5,16 @@
<title></title>
</head>
<body>
<button id="cloudPush" type="button" data-i18n-title="cloudPush"><span class="fa-icon">cloud-upload</span></button>
<span id="cloudInfo" data-i18n="cloudNoData"></span>
<button id="cloudPull" type="button" data-i18n-title="cloudPull" disabled><span class="fa-icon">cloud-download</span></button>
<button id="cloudPullAndMerge" type="button" data-i18n-title="cloudPullAndMerge" disabled><span class="fa-icon">cloud-download</span><span class="fa-icon">plus</span></button>
<span id="cloudError"></span>
<span id="cloudCog" class="fa-icon">cog</span>
<div id="cloudOptions">
<label data-i18n="cloudDeviceNamePrompt"></label> <input id="cloudDeviceName" type="text" value=""> <button id="cloudOptionsSubmit" class="vflex" type="button" data-i18n="genericSubmit"></button>
<div id="cloudToolbar">
<button id="cloudPush" type="button" data-i18n-title="cloudPush"><span class="fa-icon">cloud-upload</span></button>
<span id="cloudInfo" data-i18n="cloudNoData"></span>
<button id="cloudPull" type="button" data-i18n-title="cloudPull" disabled><span class="fa-icon">cloud-download</span></button>
<button id="cloudPullAndMerge" type="button" data-i18n-title="cloudPullAndMerge" disabled><span class="fa-icon">cloud-download</span><span class="fa-icon">plus</span></button>
<span id="cloudCog" class="fa-icon">cog</span>
<div id="cloudOptions">
<label data-i18n="cloudDeviceNamePrompt"></label> <input id="cloudDeviceName" type="text" value=""> <button id="cloudOptionsSubmit" class="vflex" type="button" data-i18n="genericSubmit"></button>
</div>
</div>
<div id="cloudError"></div>
</body>
</html>

View File

@ -9,20 +9,19 @@
#cloudWidget.hide {
display: none;
}
#cloudWidget > button {
#cloudToolbar > button {
font-size: 180%;
padding: 0 0.25em;
position: relative;
}
#cloudWidget {
align-items: center;
#cloudToolbar {
display: flex;
flex-wrap: nowrap;
}
#cloudWidget button[disabled] {
#cloudToolbar button[disabled] {
visibility: hidden;
}
#cloudWidget button.error {
#cloudToolbar button.error {
color: var(--fg-icon-info-lvl-4);
}
#cloudPullAndMerge {
@ -47,21 +46,26 @@
color: var(--fg-icon-info-lvl-4);
flex-grow: 1;
flex-shrink: 2;
font-size: x-small;
margin: 0 1em;
font-size: small;
margin: 0.5em 0.5em 0 0;
}
#cloudWidget #cloudCog {
#cloudError:empty {
display: none;
}
#cloudToolbar #cloudCog {
color: var(--fg-0-50);
cursor: pointer;
fill: var(--fg-0-50);
flex-grow: 1;
font-size: 110%;
justify-content: flex-end;
padding: 0.4em;
}
#cloudWidget #cloudCog:hover {
#cloudToolbar #cloudCog:hover {
color: inherit;
fill: inherit;
}
#cloudWidget #cloudOptions {
#cloudToolbar #cloudOptions {
background-color: var(--default-surface);
border: 1px solid var(--bg-1-border);
bottom: 0;
@ -74,6 +78,6 @@
top: 0;
z-index: 10;
}
#cloudWidget #cloudOptions.show {
#cloudToolbar #cloudOptions.show {
display: block;
}

View File

@ -52,7 +52,7 @@ const fetchCloudData = async function() {
what: 'cloudPull',
datakey: self.cloud.datakey,
});
if ( entry instanceof Object === false ) { return; }
if ( entry instanceof Object === false ) { return entry; }
self.cloud.data = entry.data;
@ -92,20 +92,23 @@ const pushData = async function() {
.toggle('error', failed);
document.querySelector('#cloudError')
.textContent = failed ? error : '';
if ( failed ) { return; }
fetchCloudData();
};
/******************************************************************************/
var pullData = function() {
const pullData = function() {
if ( typeof self.cloud.onPull === 'function' ) {
self.cloud.onPull(self.cloud.data, false);
}
document.getElementById('cloudPush').classList.remove('error');
document.querySelector('#cloudError').textContent = '';
};
/******************************************************************************/
var pullAndMergeData = function() {
const pullAndMergeData = function() {
if ( typeof self.cloud.onPull === 'function' ) {
self.cloud.onPull(self.cloud.data, true);
}
@ -113,8 +116,8 @@ var pullAndMergeData = function() {
/******************************************************************************/
var openOptions = function() {
var input = uDom.nodeFromId('cloudDeviceName');
const openOptions = function() {
const input = uDom.nodeFromId('cloudDeviceName');
input.value = self.cloud.options.deviceName;
input.setAttribute('placeholder', self.cloud.options.defaultDeviceName);
uDom.nodeFromId('cloudOptions').classList.add('show');
@ -122,11 +125,9 @@ var openOptions = function() {
/******************************************************************************/
var closeOptions = function(ev) {
var root = uDom.nodeFromId('cloudOptions');
if ( ev.target !== root ) {
return;
}
const closeOptions = function(ev) {
const root = uDom.nodeFromId('cloudOptions');
if ( ev.target !== root ) { return; }
root.classList.remove('show');
};
@ -180,9 +181,11 @@ const onInitialize = function(options) {
uDom('#cloudOptions').on('click', closeOptions);
uDom('#cloudOptionsSubmit').on('click', ( ) => { submitOptions(); });
// Patch 2018-01-05: Must not assume this XHR will always be faster
// than messaging
fetchCloudData();
fetchCloudData().then(result => {
if ( typeof result !== 'string' ) { return; }
document.getElementById('cloudPush').classList.add('error');
document.querySelector('#cloudError').textContent = result;
});
};
xhr.send();
};