diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js index b8be140a7..6d782e01b 100644 --- a/platform/chromium/vapi-background.js +++ b/platform/chromium/vapi-background.js @@ -1649,6 +1649,28 @@ vAPI.cloud = (( ) => { 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) { if ( typeof callback !== 'function' ) { return; } callback(options); @@ -1665,7 +1687,7 @@ vAPI.cloud = (( ) => { getOptions(callback); }; - return { push, pull, getOptions, setOptions }; + return { push, pull, used, getOptions, setOptions }; })(); /******************************************************************************/ diff --git a/src/cloud-ui.html b/src/cloud-ui.html index f97a87fed..9f91a3f91 100644 --- a/src/cloud-ui.html +++ b/src/cloud-ui.html @@ -6,15 +6,18 @@
- - - - - cog +
+ + + + +
+
cog
- +
+
diff --git a/src/css/cloud-ui.css b/src/css/cloud-ui.css index 4e1f4c721..bf4505362 100644 --- a/src/css/cloud-ui.css +++ b/src/css/cloud-ui.css @@ -1,22 +1,29 @@ #cloudWidget { background: url("../img/cloud.png") hsl(216, 100%, 93%); - border-radius: 3px; margin: 0.5em 0; overflow: auto; - padding: 0.5em; position: relative; } #cloudWidget.hide { display: none; } -#cloudToolbar > button { - font-size: 180%; +#cloudWidget div { + 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; position: relative; } -#cloudToolbar { - display: flex; - flex-wrap: nowrap; +#cloudToolbar button .fa-icon { + font-size: 180%; } #cloudToolbar button[disabled] { visibility: hidden; @@ -28,13 +35,12 @@ margin-left: 0.25em; } #cloudPullAndMerge > span:nth-of-type(2) { - font-size: 50%; + font-size: 90%; position: absolute; right: 0; top: 0; } #cloudInfo { - color: var(--fg-0-60); flex-shrink: 0; font-size: 90%; margin: 0 1em; @@ -42,42 +48,52 @@ padding: 0; 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 { color: var(--fg-icon-info-lvl-4); flex-grow: 1; flex-shrink: 2; font-size: small; - margin: 0.5em 0.5em 0 0; + margin: 0 0.5em 0.5em 0.5em; } #cloudError:empty { display: none; } -#cloudToolbar #cloudCog { +#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; } -#cloudToolbar #cloudCog:hover { +#cloudCog:hover { color: inherit; fill: inherit; } -#cloudToolbar #cloudOptions { +#cloudWidget #cloudOptions { background-color: var(--default-surface); border: 1px solid var(--bg-1-border); - bottom: 0; display: none; - margin: 0.4em; - padding: 0.4em; + padding: 0.5em; position: absolute; right: 0; text-align: center; - top: 0; z-index: 10; } -#cloudToolbar #cloudOptions.show { +#cloudWidget #cloudOptions.show { display: block; + white-space: nowrap; + } +#cloudOptions button { + min-height: var(--default-gap-xlarge); } diff --git a/src/css/themes/default.css b/src/css/themes/default.css index 759d7abfc..de3f8f644 100644 --- a/src/css/themes/default.css +++ b/src/css/themes/default.css @@ -38,6 +38,7 @@ --light-gray-90: #80808f; --red-60: #e22850; --violet-40: #ab71ff; + --violet-60: #7542e5; --violet-70: #592acb; --violet-80: #45278d; --yellow-30: #ffd567; diff --git a/src/js/cloud-ui.js b/src/js/cloud-ui.js index 8a1edbb7c..49adc0ea3 100644 --- a/src/js/cloud-ui.js +++ b/src/js/cloud-ui.js @@ -34,7 +34,7 @@ self.cloud = { datakey: '', data: undefined, 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 entry = await vAPI.messaging.send('cloudWidget', { what: 'cloudPull', @@ -94,6 +113,7 @@ const pushData = async function() { .textContent = failed ? error : ''; if ( failed ) { return; } fetchCloudData(); + fetchStorageUsed(); }; /******************************************************************************/ @@ -151,7 +171,7 @@ const submitOptions = async function() { const onInitialize = function(options) { if ( options instanceof Object === false ) { return; } - if ( !options.enabled ) { return; } + if ( options.enabled !== true ) { return; } self.cloud.options = options; const xhr = new XMLHttpRequest(); @@ -180,12 +200,13 @@ const onInitialize = function(options) { uDom('#cloudCog').on('click', openOptions); uDom('#cloudOptions').on('click', closeOptions); uDom('#cloudOptionsSubmit').on('click', ( ) => { submitOptions(); }); - + fetchCloudData().then(result => { if ( typeof result !== 'string' ) { return; } document.getElementById('cloudPush').classList.add('error'); document.querySelector('#cloudError').textContent = result; }); + fetchStorageUsed(); }; xhr.send(); }; diff --git a/src/js/messaging.js b/src/js/messaging.js index a8d6128f0..cefd93f30 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -828,6 +828,11 @@ const onMessage = function(request, sender, callback) { callback(result); }); + case 'cloudUsed': + return vAPI.cloud.used(request.datakey).then(result => { + callback(result); + }); + default: break; }