1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-07-19 03:05:22 +02:00

Add widget to convey the amount of sync storage in use

This commit is contained in:
Raymond Hill 2020-08-14 15:29:25 -04:00
parent ba833d3391
commit 2afcc13ca6
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
6 changed files with 97 additions and 29 deletions

View File

@ -1649,6 +1649,28 @@ vAPI.cloud = (( ) => {
return entry; return entry;
}; };
const used = async function(dataKey) {
if ( webext.storage.sync.getBytesInUse instanceof Function === false ) {
return;
}
const coarseCount = await getCoarseChunkCount(dataKey);
if ( typeof coarseCount !== 'number' ) { return; }
const keys = [];
for ( let i = 0; i < coarseCount; i++ ) {
keys.push(`${dataKey}${i}`);
}
let results;
try {
results = await Promise.all([
webext.storage.sync.getBytesInUse(keys),
webext.storage.sync.getBytesInUse(null),
]);
} catch(ex) {
}
if ( Array.isArray(results) === false ) { return; }
return { used: results[0], total: results[1], max: QUOTA_BYTES };
};
const getOptions = function(callback) { const getOptions = function(callback) {
if ( typeof callback !== 'function' ) { return; } if ( typeof callback !== 'function' ) { return; }
callback(options); callback(options);
@ -1665,7 +1687,7 @@ vAPI.cloud = (( ) => {
getOptions(callback); getOptions(callback);
}; };
return { push, pull, getOptions, setOptions }; return { push, pull, used, getOptions, setOptions };
})(); })();
/******************************************************************************/ /******************************************************************************/

View File

@ -6,15 +6,18 @@
</head> </head>
<body> <body>
<div id="cloudToolbar"> <div id="cloudToolbar">
<button id="cloudPush" type="button" data-i18n-title="cloudPush"><span class="fa-icon">cloud-upload</span></button> <div>
<span id="cloudInfo" data-i18n="cloudNoData"></span> <button id="cloudPush" type="button" data-i18n-title="cloudPush"><span class="fa-icon">cloud-upload</span></button>
<button id="cloudPull" type="button" data-i18n-title="cloudPull" disabled><span class="fa-icon">cloud-download</span></button> <span id="cloudInfo" data-i18n="cloudNoData"></span>
<button id="cloudPullAndMerge" type="button" data-i18n-title="cloudPullAndMerge" disabled><span class="fa-icon">cloud-download</span><span class="fa-icon">plus</span></button> <button id="cloudPull" type="button" data-i18n-title="cloudPull" disabled><span class="fa-icon">cloud-download</span></button>
<span id="cloudCog" class="fa-icon">cog</span> <button id="cloudPullAndMerge" type="button" data-i18n-title="cloudPullAndMerge" disabled><span class="fa-icon">cloud-download</span><span class="fa-icon">plus</span></button>
</div>
<div id="cloudCog" class="fa-icon">cog</div>
<div id="cloudOptions"> <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> <label data-i18n="cloudDeviceNamePrompt"></label> <input id="cloudDeviceName" type="text" value=""> <button id="cloudOptionsSubmit" type="button" data-i18n="genericSubmit"></button>
</div> </div>
</div> </div>
<div id="cloudError"></div> <div id="cloudError"></div>
<div id="cloudCapacity"><div><div></div></div></div>
</body> </body>
</html> </html>

View File

@ -1,22 +1,29 @@
#cloudWidget { #cloudWidget {
background: url("../img/cloud.png") hsl(216, 100%, 93%); background: url("../img/cloud.png") hsl(216, 100%, 93%);
border-radius: 3px;
margin: 0.5em 0; margin: 0.5em 0;
overflow: auto; overflow: auto;
padding: 0.5em;
position: relative; position: relative;
} }
#cloudWidget.hide { #cloudWidget.hide {
display: none; display: none;
} }
#cloudToolbar > button { #cloudWidget div {
font-size: 180%; display: flex;
}
#cloudToolbar {
align-items: flex-start;
flex-wrap: nowrap;
justify-content: space-between;
}
#cloudToolbar > div:first-of-type {
margin: 0.5em;
}
#cloudToolbar button {
padding: 0 0.25em; padding: 0 0.25em;
position: relative; position: relative;
} }
#cloudToolbar { #cloudToolbar button .fa-icon {
display: flex; font-size: 180%;
flex-wrap: nowrap;
} }
#cloudToolbar button[disabled] { #cloudToolbar button[disabled] {
visibility: hidden; visibility: hidden;
@ -28,13 +35,12 @@
margin-left: 0.25em; margin-left: 0.25em;
} }
#cloudPullAndMerge > span:nth-of-type(2) { #cloudPullAndMerge > span:nth-of-type(2) {
font-size: 50%; font-size: 90%;
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
} }
#cloudInfo { #cloudInfo {
color: var(--fg-0-60);
flex-shrink: 0; flex-shrink: 0;
font-size: 90%; font-size: 90%;
margin: 0 1em; margin: 0 1em;
@ -42,42 +48,52 @@
padding: 0; padding: 0;
white-space: pre-line; white-space: pre-line;
} }
#cloudCapacity {
background-color: var(--light-gray-30);
height: 4px;
}
#cloudCapacity > div {
background-color: var(--light-gray-60);
}
#cloudCapacity > div > div {
background-color: var(--violet-60);
}
#cloudError { #cloudError {
color: var(--fg-icon-info-lvl-4); color: var(--fg-icon-info-lvl-4);
flex-grow: 1; flex-grow: 1;
flex-shrink: 2; flex-shrink: 2;
font-size: small; font-size: small;
margin: 0.5em 0.5em 0 0; margin: 0 0.5em 0.5em 0.5em;
} }
#cloudError:empty { #cloudError:empty {
display: none; display: none;
} }
#cloudToolbar #cloudCog { #cloudCog {
color: var(--fg-0-50); color: var(--fg-0-50);
cursor: pointer; cursor: pointer;
fill: var(--fg-0-50); fill: var(--fg-0-50);
flex-grow: 1;
font-size: 110%; font-size: 110%;
justify-content: flex-end; justify-content: flex-end;
padding: 0.4em; padding: 0.4em;
} }
#cloudToolbar #cloudCog:hover { #cloudCog:hover {
color: inherit; color: inherit;
fill: inherit; fill: inherit;
} }
#cloudToolbar #cloudOptions { #cloudWidget #cloudOptions {
background-color: var(--default-surface); background-color: var(--default-surface);
border: 1px solid var(--bg-1-border); border: 1px solid var(--bg-1-border);
bottom: 0;
display: none; display: none;
margin: 0.4em; padding: 0.5em;
padding: 0.4em;
position: absolute; position: absolute;
right: 0; right: 0;
text-align: center; text-align: center;
top: 0;
z-index: 10; z-index: 10;
} }
#cloudToolbar #cloudOptions.show { #cloudWidget #cloudOptions.show {
display: block; display: block;
white-space: nowrap;
}
#cloudOptions button {
min-height: var(--default-gap-xlarge);
} }

View File

@ -38,6 +38,7 @@
--light-gray-90: #80808f; --light-gray-90: #80808f;
--red-60: #e22850; --red-60: #e22850;
--violet-40: #ab71ff; --violet-40: #ab71ff;
--violet-60: #7542e5;
--violet-70: #592acb; --violet-70: #592acb;
--violet-80: #45278d; --violet-80: #45278d;
--yellow-30: #ffd567; --yellow-30: #ffd567;

View File

@ -34,7 +34,7 @@ self.cloud = {
datakey: '', datakey: '',
data: undefined, data: undefined,
onPush: null, onPush: null,
onPull: null onPull: null,
}; };
/******************************************************************************/ /******************************************************************************/
@ -47,6 +47,25 @@ if ( self.cloud.datakey === '' ) { return; }
/******************************************************************************/ /******************************************************************************/
const fetchStorageUsed = async function() {
const elem = widget.querySelector('#cloudCapacity');
if ( elem.classList.contains('hide') ) { return; }
const result = await vAPI.messaging.send('cloudWidget', {
what: 'cloudUsed',
datakey: self.cloud.datakey,
});
if ( result instanceof Object === false ) {
elem.classList.add('hide');
return;
}
const total = (result.total / result.max * 100).toFixed(1);
elem.firstElementChild.style.width = `${total}%`;
const used = (result.used / result.total * 100).toFixed(1);
elem.firstElementChild.firstElementChild.style.width = `${used}%`;
};
/******************************************************************************/
const fetchCloudData = async function() { const fetchCloudData = async function() {
const entry = await vAPI.messaging.send('cloudWidget', { const entry = await vAPI.messaging.send('cloudWidget', {
what: 'cloudPull', what: 'cloudPull',
@ -94,6 +113,7 @@ const pushData = async function() {
.textContent = failed ? error : ''; .textContent = failed ? error : '';
if ( failed ) { return; } if ( failed ) { return; }
fetchCloudData(); fetchCloudData();
fetchStorageUsed();
}; };
/******************************************************************************/ /******************************************************************************/
@ -151,7 +171,7 @@ const submitOptions = async function() {
const onInitialize = function(options) { const onInitialize = function(options) {
if ( options instanceof Object === false ) { return; } if ( options instanceof Object === false ) { return; }
if ( !options.enabled ) { return; } if ( options.enabled !== true ) { return; }
self.cloud.options = options; self.cloud.options = options;
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
@ -180,12 +200,13 @@ const onInitialize = function(options) {
uDom('#cloudCog').on('click', openOptions); uDom('#cloudCog').on('click', openOptions);
uDom('#cloudOptions').on('click', closeOptions); uDom('#cloudOptions').on('click', closeOptions);
uDom('#cloudOptionsSubmit').on('click', ( ) => { submitOptions(); }); uDom('#cloudOptionsSubmit').on('click', ( ) => { submitOptions(); });
fetchCloudData().then(result => { fetchCloudData().then(result => {
if ( typeof result !== 'string' ) { return; } if ( typeof result !== 'string' ) { return; }
document.getElementById('cloudPush').classList.add('error'); document.getElementById('cloudPush').classList.add('error');
document.querySelector('#cloudError').textContent = result; document.querySelector('#cloudError').textContent = result;
}); });
fetchStorageUsed();
}; };
xhr.send(); xhr.send();
}; };

View File

@ -828,6 +828,11 @@ const onMessage = function(request, sender, callback) {
callback(result); callback(result);
}); });
case 'cloudUsed':
return vAPI.cloud.used(request.datakey).then(result => {
callback(result);
});
default: default:
break; break;
} }