feat(menu): add more detail in Menu (#1570)

This commit is contained in:
Su-Yong
2023-12-31 20:56:24 +09:00
committed by GitHub
parent aa899d247a
commit 4d3e2c09da
10 changed files with 104 additions and 7 deletions

View File

@ -168,6 +168,7 @@
"node-html-parser": "6.1.12",
"node-id3": "0.2.6",
"peerjs": "1.5.2",
"semver": "7.5.4",
"serve": "14.2.1",
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
"ts-morph": "21.0.1",
@ -181,6 +182,7 @@
"@types/electron-localshortcut": "3.1.3",
"@types/howler": "2.2.11",
"@types/html-to-text": "9.0.4",
"@types/semver": "7.5.6",
"@typescript-eslint/eslint-plugin": "6.16.0",
"bufferutil": "4.0.8",
"builtin-modules": "3.3.0",

8
pnpm-lock.yaml generated
View File

@ -117,6 +117,9 @@ dependencies:
peerjs:
specifier: 1.5.2
version: 1.5.2
semver:
specifier: 7.5.4
version: 7.5.4
serve:
specifier: 14.2.1
version: 14.2.1
@ -152,6 +155,9 @@ devDependencies:
'@types/html-to-text':
specifier: 9.0.4
version: 9.0.4
'@types/semver':
specifier: 7.5.6
version: 7.5.6
'@typescript-eslint/eslint-plugin':
specifier: 6.16.0
version: 6.16.0(@typescript-eslint/parser@6.14.0)(eslint@8.56.0)(typescript@5.3.3)
@ -1113,7 +1119,7 @@ packages:
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: 4.9.1
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true

View File

@ -170,7 +170,8 @@
},
"plugins": {
"enabled": "Enabled",
"label": "Plugins"
"label": "Plugins",
"new": "NEW"
},
"view": {
"label": "View",

View File

@ -170,7 +170,8 @@
},
"plugins": {
"enabled": "활성화",
"label": "확장"
"label": "확장",
"new": "NEW"
},
"view": {
"label": "보기",

View File

@ -9,6 +9,7 @@ import {
shell,
} from 'electron';
import prompt from 'custom-electron-prompt';
import { satisfies } from 'semver';
import { allPlugins } from 'virtual:plugins';
@ -23,6 +24,8 @@ import promptOptions from './providers/prompt-options';
import { getAllMenuTemplate, loadAllMenuPlugins } from './loader/menu';
import { setLanguage, t } from '@/i18n';
import packageJson from '../package.json';
export type MenuTemplate = Electron.MenuItemConstructorOptions[];
// True only if in-app-menu was loaded on launch
@ -31,10 +34,14 @@ const inAppMenuActive = config.plugins.isEnabled('in-app-menu');
const pluginEnabledMenu = (
plugin: string,
label = '',
description: string | undefined = undefined,
isNew = false,
hasSubmenu = false,
refreshMenu: (() => void) | undefined = undefined,
): Electron.MenuItemConstructorOptions => ({
label: label || plugin,
sublabel: isNew ? t('main.menu.plugins.new') : undefined,
toolTip: description,
type: 'checkbox',
checked: config.plugins.isEnabled(plugin),
click(item: Electron.MenuItem) {
@ -66,12 +73,15 @@ export const mainMenuTemplate = async (
const menuResult = Object.entries(getAllMenuTemplate()).map(
([id, template]) => {
const pluginLabel = allPlugins[id]?.name?.() ?? id;
const plugin = allPlugins[id];
const pluginLabel = plugin?.name?.() ?? id;
const pluginDescription = plugin?.description?.() ?? undefined;
const isNew = plugin?.addedVersion ? satisfies(packageJson.version, plugin.addedVersion) : false;
if (!config.plugins.isEnabled(id)) {
return [
id,
pluginEnabledMenu(id, pluginLabel, true, innerRefreshMenu),
pluginEnabledMenu(id, pluginLabel, pluginDescription, isNew, true, innerRefreshMenu),
] as const;
}
@ -79,10 +89,14 @@ export const mainMenuTemplate = async (
id,
{
label: pluginLabel,
sublabel: isNew ? t('main.menu.plugins.new') : undefined,
toolTip: pluginDescription,
submenu: [
pluginEnabledMenu(
id,
t('main.menu.plugins.enabled'),
undefined,
false,
true,
innerRefreshMenu,
),
@ -106,9 +120,12 @@ export const mainMenuTemplate = async (
const predefinedTemplate = menuResult.find((it) => it[0] === id);
if (predefinedTemplate) return predefinedTemplate[1];
const pluginLabel = allPlugins[id]?.name?.() ?? id;
const plugin = allPlugins[id];
const pluginLabel = plugin?.name?.() ?? id;
const pluginDescription = plugin?.description?.() ?? undefined;
const isNew = plugin?.addedVersion ? satisfies(packageJson.version, plugin.addedVersion) : false;
return pluginEnabledMenu(id, pluginLabel, true, innerRefreshMenu);
return pluginEnabledMenu(id, pluginLabel, pluginDescription, isNew, true, innerRefreshMenu);
});
const availableLanguages = Object.keys(languageResources);

View File

@ -11,6 +11,7 @@ export default createPlugin({
name: () => t('plugins.album-actions.name'),
description: () => t('plugins.album-actions.description'),
restartNeeded: false,
addedVersion: '3.2.0',
config: {
enabled: false,
},

View File

@ -52,6 +52,18 @@ export const createPanel = (
menu.appendChild(iconWrapper);
menu.append(item.label);
if (item.sublabel) {
menu.classList.add('badge');
const menuBadge = document.createElement('menu-item-badge');
menuBadge.append(item.sublabel);
menu.append(menuBadge);
}
if (item.toolTip) {
const menuTooltip = document.createElement('menu-item-tooltip');
menuTooltip.append(item.toolTip);
menu.append(menuTooltip);
}
menu.addEventListener('click', async () => {
await window.ipcRenderer.invoke('menu-event', item.commandId);
const menuItem = (await window.ipcRenderer.invoke(

View File

@ -97,6 +97,8 @@ menu-panel.position-by-bottom {
}
menu-item {
position: relative;
-webkit-app-region: none;
min-height: 32px;
height: 32px;
@ -109,6 +111,9 @@ menu-item {
border-radius: 4px;
cursor: pointer;
}
menu-item.badge {
grid-template-columns: 32px 1fr auto minmax(32px, auto);
}
menu-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
@ -128,6 +133,56 @@ menu-separator {
background-color: rgba(255, 255, 255, 0.2);
}
menu-item-badge {
display: flex;
justify-content: center;
align-items: center;
min-width: 16px;
height: 16px;
padding: 0 4px;
margin-left: 8px;
border-radius: 4px;
background-color: rgba(255, 255, 255, 0.2);
color: #f1f1f1;
font-size: 10px;
font-weight: 500;
line-height: 1;
}
menu-item-tooltip {
position: absolute;
left: 0;
top: calc(100% + 4px);
display: flex;
justify-content: center;
align-items: center;
min-width: 32px;
padding: 4px;
border-radius: 4px;
background-color: rgba(25, 25, 25, 0.8);
color: #f1f1f1;
font-size: 10px;
pointer-events: none;
z-index: 1000;
opacity: 0;
scale: 0.9;
transform-origin: 50% 0;
transition: all 0.225s ease-out;
}
menu-item:hover > menu-item-tooltip {
opacity: 1;
scale: 1.0;
}
/* classes */
.title-bar-icon {

View File

@ -38,6 +38,7 @@ export default createPlugin({
name: () => t('plugins.music-together.name'),
description: () => t('plugins.music-together.description'),
restartNeeded: false,
addedVersion: '3.2.0',
config: {
enabled: false
},

View File

@ -47,6 +47,7 @@ export interface PluginDef<
name: () => string;
authors?: Author[];
description?: () => string;
addedVersion?: string;
config?: Config;
menu?: (