show style version, size, and update age in manager

This commit is contained in:
tophf 2020-11-16 20:02:52 +03:00
parent 15eb1b890b
commit 044907fa35
4 changed files with 136 additions and 16 deletions

View File

@ -260,6 +260,42 @@
"message": "Stop using customized name, switch to the style's own name",
"description": "Tooltip of 'x' button shown in editor when changing the name input of a) styles updated from a URL i.e. not locally created, b) UserCSS styles"
},
"dateAbbrDay": {
"message": "$value$d",
"description": "Day suffix in a short relative date, for example: 8d",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrHour": {
"message": "$value$h",
"description": "Hour suffix in a short relative date, for example: 8h",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrMonth": {
"message": "$value$m",
"description": "Month suffix in a short relative date, for example: 8m",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrYear": {
"message": "$value$y",
"description": "Year suffix in a short relative date, for example: 8y",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateInstalled": {
"message": "Date installed",
"description": "Option text for the user to sort the style by install date"

View File

@ -32,7 +32,10 @@
<template data-id="style">
<div class="entry">
<h2 class="style-name">
<a class="style-name-link"></a>
<a class="style-name-link">
&nbsp;
<span class="style-info" data-type="version"></span>
</a>
<a target="_blank" class="homepage"></a>
</h2>
<p class="applies-to">
@ -54,15 +57,20 @@
</div>
</template>
<template data-id="styleCompact">
<template data-id="styleNewUI">
<div class="entry">
<h2 class="style-name">
<div class="checkmate">
<input class="checker" type="checkbox" i18n-title="toggleStyle">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</div>
<a class="style-name-link"></a>
<div class="checkmate">
<input class="checker" type="checkbox" i18n-title="toggleStyle">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</div>
<a class="style-name-link">
&nbsp;
<span class="style-info" data-type="version"></span>
</a>
</h2>
<p class="style-info" data-type="age"></p>
<p class="style-info" data-type="size"></p>
<p class="actions">
<a target="_blank" class="homepage" tabindex="0"></a>
<a href="#" class="delete" i18n-title="deleteStyleLabel" tabindex="0">

View File

@ -177,6 +177,25 @@ a:hover {
text-decoration: none;
}
.style-info {
text-align: right;
padding: 0 .25em;
font-weight: normal;
color: #999;
}
.style-info[data-type=version] {
padding-left: .5em;
}
.newUI .style-info[data-type=version][data-value="1.0.0"] {
display: none;
}
.newUI .style-info[data-type=size][title^=" "] {
opacity: .25;
}
.newUI .style-info[data-type=size][title^=" "]:hover {
opacity: 1;
}
.applies-to {
overflow-wrap: break-word;
}
@ -357,6 +376,10 @@ a:hover {
vertical-align: middle;
}
.newUI .entry > .style-info {
padding-right: .5em;
}
.newUI .entry .actions {
position: relative;
}
@ -629,7 +652,7 @@ a:hover {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: calc(100vw - var(--header-width) - var(--actions-width) - var(--name-padding-left) - 25vw - var(--name-padding-right));
max-width: calc(75vw - var(--header-width) - var(--actions-width) - var(--name-padding-left) - var(--name-padding-right) - 6rem);
box-sizing: border-box;
padding-right: 1rem;
line-height: 18px;
@ -1026,6 +1049,12 @@ a:hover {
}
}
@media (max-width: 1000px) {
.newUI .entry > .style-info {
display: none;
}
}
@media (max-width: 850px) {
body {
display: table;

View File

@ -32,6 +32,7 @@ let installed;
const ENTRY_ID_PREFIX_RAW = 'style-';
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
const REVEAL_DATES_FOR = 'h2.style-name, [data-type=age]';
const BULK_THROTTLE_MS = 100;
const bulkChangeQueue = [];
@ -60,6 +61,12 @@ newUI.renderClass();
const TARGET_TYPES = ['domains', 'urls', 'urlPrefixes', 'regexps'];
const GET_FAVICON_URL = 'https://www.google.com/s2/favicons?domain=';
const OWN_ICON = chrome.runtime.getManifest().icons['16'];
const AGES = [
[24, 'h', t('dateAbbrHour', '\x01')],
[30, 'd', t('dateAbbrDay', '\x01')],
[12, 'm', t('dateAbbrMonth', '\x01')],
[Infinity, 'y', t('dateAbbrYear', '\x01')],
];
const handleEvent = {};
@ -184,7 +191,7 @@ function showStyles(styles = [], matchUrlIds) {
function createStyleElement({style, name: nameLC}) {
// query the sub-elements just once, then reuse the references
if ((createStyleElement.parts || {}).newUI !== newUI.enabled) {
const entry = t.template[`style${newUI.enabled ? 'Compact' : ''}`];
const entry = t.template[newUI.enabled ? 'styleNewUI' : 'style'];
createStyleElement.parts = {
newUI: newUI.enabled,
entry,
@ -195,6 +202,9 @@ function createStyleElement({style, name: nameLC}) {
editHrefBase: 'edit.html?id=',
homepage: $('.homepage', entry),
homepageIcon: t.template[`homepageIcon${newUI.enabled ? 'Small' : 'Big'}`],
infoAge: $('[data-type=age]', entry),
infoVer: $('[data-type=version]', entry),
infoSize: $('[data-type=size]', entry),
appliesTo: $('.applies-to', entry),
targets: $('.targets', entry),
expander: $('.expander', entry),
@ -209,13 +219,19 @@ function createStyleElement({style, name: nameLC}) {
};
}
const parts = createStyleElement.parts;
const configurable = style.usercssData && style.usercssData.vars && Object.keys(style.usercssData.vars).length > 0;
const ud = style.usercssData;
const configurable = ud && ud.vars && Object.keys(ud.vars).length > 0;
const name = style.customName || style.name;
parts.checker.checked = style.enabled;
parts.nameLink.textContent = t.breakWord(name);
parts.nameLink.firstChild.textContent = t.breakWord(name);
parts.nameLink.href = parts.editLink.href = parts.editHrefBase + style.id;
parts.homepage.href = parts.homepage.title = style.url || '';
if (!newUI.enabled) {
parts.infoVer.textContent = ud ? ud.version : '';
parts.infoVer.dataset.value = ud ? ud.version : '';
if (newUI.enabled) {
createSizeText(parts.infoSize, style);
createAgeText(parts.infoAge, style);
} else {
parts.oldConfigure.classList.toggle('hidden', !configurable);
parts.oldCheckUpdate.classList.toggle('hidden', !style.updateUrl);
parts.oldUpdate.classList.toggle('hidden', !style.updateUrl);
@ -234,7 +250,7 @@ function createStyleElement({style, name: nameLC}) {
entry.className = parts.entryClassBase + ' ' +
(style.enabled ? 'enabled' : 'disabled') +
(style.updateUrl ? ' updatable' : '') +
(style.usercssData ? ' usercss' : '');
(ud ? ' usercss' : '');
if (style.url) {
$('.homepage', entry).appendChild(parts.homepageIcon.cloneNode(true));
@ -315,6 +331,37 @@ function createStyleTargetsElement({entry, expanded, style = entry.styleMeta}) {
entry._numTargets = numTargets;
}
function createSizeText(el, style) {
const size = (style.sourceCode || '').length ||
style.sections.reduce((sum, sec) => sum + (sec.code || '').length, 0);
if (size) {
el.textContent = size < 1000 ? '<1k' : `${size / 1000 | 0}k`;
el.title = addBigness(size);
}
}
function createAgeText(el, style) {
let val = style.updateDate;
if (val) {
val = (Date.now() - val) / 3600e3; // age in hours
for (const [max, unit, text] of AGES) {
const rounded = Math.round(val);
if (rounded < max) {
el.textContent = text.replace('\x01', rounded);
el.dataset.value = addBigness(Math.round(rounded), 2) + unit;
break;
}
val /= max;
}
} else if (el.firstChild) {
el.textContent = '';
delete el.dataset.value;
}
}
function addBigness(val, max = 8) {
return ' '.repeat(max - Math.ceil(Math.log10(val))) + val;
}
function getFaviconImgSrc(container = installed) {
if (!newUI.enabled || !newUI.favicons) return;
@ -505,9 +552,9 @@ Object.assign(handleEvent, {
},
lazyAddEntryTitle({type, target}) {
const cell = target.closest('h2.style-name');
const cell = target.closest(REVEAL_DATES_FOR);
if (cell) {
const link = $('.style-name-link', cell);
const link = $('.style-name-link', cell) || cell;
if (type === 'mouseover' && !link.title) {
debounce(handleEvent.addEntryTitle, 50, link);
} else {
@ -541,7 +588,7 @@ function handleBulkChange() {
}
function handleUpdateForId(id, opts) {
return API.getStyle(id, true).then(style => {
return API.getStyle(id).then(style => {
handleUpdate(style, opts);
bulkChangeQueue.time = performance.now();
});