Explorar o código

fix #2374: sort by author in dashboard

tophf hai 1 mes
pai
achega
1f2f0ca9bc

+ 1 - 1
src/common/options-defaults.js

@@ -69,7 +69,7 @@ export default {
     showOrder: false,
     showOrder: false,
     /** @type {boolean} */
     /** @type {boolean} */
     showVisit: false,
     showVisit: false,
-    /** @type {'exec'|'exec-' | 'alpha'|'alpha-' | 'update'|'update-' | 'visit'|'visit-'} */
+    /** @type {'exec'|'exec-' | 'alpha'|'alpha-' | 'author'|'author-' | 'update'|'update-' | 'visit'|'visit-'} */
     sort: 'exec',
     sort: 'exec',
     /** @type {boolean} */
     /** @type {boolean} */
     viewSingleColumn: false,
     viewSingleColumn: false,

+ 5 - 0
src/common/ui/util.js

@@ -4,6 +4,11 @@ import { debounce } from '@/common';
 
 
 export const NORMALIZE = Symbol();
 export const NORMALIZE = Symbol();
 
 
+export const getSortCollator = () => new Intl.Collator(undefined, {
+  numeric: true, // 100 > 2
+  sensitivity: 'accent', // ignore case
+});
+
 /** @this {object} enum */
 /** @this {object} enum */
 export function normalizeEnum(val) {
 export function normalizeEnum(val) {
   return hasOwnProperty(this, val) ? val : Object.keys(this)[0];
   return hasOwnProperty(this, val) ? val : Object.keys(this)[0];

+ 1 - 0
src/options/index.js

@@ -43,6 +43,7 @@ function initScript(script, sizes, code) {
     total += val;
     total += val;
     if (val) str += `${SIZE_TITLES[i]}: ${formatByteLength(val)}\n`;
     if (val) str += `${SIZE_TITLES[i]}: ${formatByteLength(val)}\n`;
   });
   });
+  $cache.author = meta.author || '';
   $cache.desc = desc;
   $cache.desc = desc;
   $cache.name = name;
   $cache.name = name;
   $cache.lowerName = name.toLocaleLowerCase();
   $cache.lowerName = name.toLocaleLowerCase();

+ 6 - 2
src/options/views/tab-installed.vue

@@ -188,6 +188,7 @@ import Tooltip from 'vueleton/lib/tooltip';
 import SettingCheck from '@/common/ui/setting-check';
 import SettingCheck from '@/common/ui/setting-check';
 import Icon from '@/common/ui/icon';
 import Icon from '@/common/ui/icon';
 import { customCssElem, findStyleSheetRules } from '@/common/ui/style';
 import { customCssElem, findStyleSheetRules } from '@/common/ui/style';
+import { getSortCollator } from '@/common/ui/util';
 import {
 import {
   createSearchRules, formatSizesStr, markRemove, performSearch, runInBatch, setLocationHash,
   createSearchRules, formatSizesStr, markRemove, performSearch, runInBatch, setLocationHash,
   SIZE_TITLES, store, TOGGLE_OFF, TOGGLE_ON,
   SIZE_TITLES, store, TOGGLE_OFF, TOGGLE_ON,
@@ -212,11 +213,14 @@ const RESTORE = 'restore';
 const TOGGLE = 'toggle';
 const TOGGLE = 'toggle';
 const UNDO = 'undo';
 const UNDO = 'undo';
 const UPDATE = 'update';
 const UPDATE = 'update';
+const collator = getSortCollator();
+const cmpName = (a, b) => collator.compare(a.$cache.lowerName, b.$cache.lowerName);
 /** @type {{ [key:string]: SortMode }} */
 /** @type {{ [key:string]: SortMode }} */
 const sortModes = [
 const sortModes = [
   ['exec', i18n('filterExecutionOrder')],
   ['exec', i18n('filterExecutionOrder')],
-  ['alpha', i18n('filterAlphabeticalOrder'), '',
-    ({ $cache: { lowerName: a } }, { $cache: { lowerName: b } }) => (a < b ? -1 : a > b)],
+  ['alpha', i18n('filterAlphabeticalOrder'), '', cmpName],
+  ['author', i18n('labelAuthor').replace(/\W+/, '').toLowerCase(), '',
+    (a, b) => collator.compare(a.$cache.author, b.$cache.author) || cmpName(a, b)],
   [UPDATE, i18n('filterLastUpdateOrder'), '',
   [UPDATE, i18n('filterLastUpdateOrder'), '',
     (a, b) => (+b.props.lastUpdated || 0) - (+a.props.lastUpdated || 0)],
     (a, b) => (+b.props.lastUpdated || 0) - (+a.props.lastUpdated || 0)],
   ['visit', i18n('filterLastVisitOrder'), i18n('filterLastVisitOrderTooltip'),
   ['visit', i18n('filterLastVisitOrder'), i18n('filterLastVisitOrderTooltip'),

+ 3 - 2
src/popup/views/app.vue

@@ -232,6 +232,7 @@ import { objectPick } from '@/common/object';
 import { EXTERNAL_LINK_PROPS, getActiveElement } from '@/common/ui';
 import { EXTERNAL_LINK_PROPS, getActiveElement } from '@/common/ui';
 import Icon from '@/common/ui/icon';
 import Icon from '@/common/ui/icon';
 import SettingsPopup from '@/common/ui/settings-popup.vue';
 import SettingsPopup from '@/common/ui/settings-popup.vue';
+import { getSortCollator } from '@/common/ui/util';
 import { keyboardService, isInput, handleTabNavigation } from '@/common/keyboard';
 import { keyboardService, isInput, handleTabNavigation } from '@/common/keyboard';
 import { isFullscreenPopup, store } from '../utils';
 import { isFullscreenPopup, store } from '../utils';
 
 
@@ -243,7 +244,7 @@ const TARDY_MATCH = i18n('msgTardyMatch');
 const SCRIPT_CLS = '.script';
 const SCRIPT_CLS = '.script';
 const RUN_AT_ORDER = ['start', 'body', 'end', 'idle'];
 const RUN_AT_ORDER = ['start', 'body', 'end', 'idle'];
 const needsReload = reactive({});
 const needsReload = reactive({});
-
+const collator = getSortCollator();
 const $extras = ref();
 const $extras = ref();
 const $topExtras = ref();
 const $topExtras = ref();
 const optionsData = reactive(objectPick(optionsDefaults, [
 const optionsData = reactive(objectPick(optionsDefaults, [
@@ -358,7 +359,7 @@ function makeInjectionScopes() {
         updatableScripts[id] = item;
         updatableScripts[id] = item;
       }
       }
       return item;
       return item;
-    }).sort((a, b) => (a.key < b.key ? -1 : a.key > b.key));
+    }).sort((a, b) => collator.compare(a.key, b.key));
     return numTotal && {
     return numTotal && {
       name,
       name,
       title,
       title,

+ 1 - 0
src/types.d.ts

@@ -191,6 +191,7 @@ declare interface VMScript {
     tags?: string;
     tags?: string;
   };
   };
   meta: {
   meta: {
+    author?: string;
     description?: string;
     description?: string;
     downloadURL?: string;
     downloadURL?: string;
     exclude: string[];
     exclude: string[];