Skip to content

Commit 4d3e2c0

Browse files
authored
feat(menu): add more detail in Menu (#1570)
1 parent aa899d2 commit 4d3e2c0

File tree

10 files changed

+104
-7
lines changed

10 files changed

+104
-7
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
"node-html-parser": "6.1.12",
169169
"node-id3": "0.2.6",
170170
"peerjs": "1.5.2",
171+
"semver": "7.5.4",
171172
"serve": "14.2.1",
172173
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
173174
"ts-morph": "21.0.1",
@@ -181,6 +182,7 @@
181182
"@types/electron-localshortcut": "3.1.3",
182183
"@types/howler": "2.2.11",
183184
"@types/html-to-text": "9.0.4",
185+
"@types/semver": "7.5.6",
184186
"@typescript-eslint/eslint-plugin": "6.16.0",
185187
"bufferutil": "4.0.8",
186188
"builtin-modules": "3.3.0",

pnpm-lock.yaml

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/i18n/resources/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@
170170
},
171171
"plugins": {
172172
"enabled": "Enabled",
173-
"label": "Plugins"
173+
"label": "Plugins",
174+
"new": "NEW"
174175
},
175176
"view": {
176177
"label": "View",

src/i18n/resources/ko.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@
170170
},
171171
"plugins": {
172172
"enabled": "활성화",
173-
"label": "확장"
173+
"label": "확장",
174+
"new": "NEW"
174175
},
175176
"view": {
176177
"label": "보기",

src/menu.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
shell,
1010
} from 'electron';
1111
import prompt from 'custom-electron-prompt';
12+
import { satisfies } from 'semver';
1213

1314
import { allPlugins } from 'virtual:plugins';
1415

@@ -23,6 +24,8 @@ import promptOptions from './providers/prompt-options';
2324
import { getAllMenuTemplate, loadAllMenuPlugins } from './loader/menu';
2425
import { setLanguage, t } from '@/i18n';
2526

27+
import packageJson from '../package.json';
28+
2629
export type MenuTemplate = Electron.MenuItemConstructorOptions[];
2730

2831
// True only if in-app-menu was loaded on launch
@@ -31,10 +34,14 @@ const inAppMenuActive = config.plugins.isEnabled('in-app-menu');
3134
const pluginEnabledMenu = (
3235
plugin: string,
3336
label = '',
37+
description: string | undefined = undefined,
38+
isNew = false,
3439
hasSubmenu = false,
3540
refreshMenu: (() => void) | undefined = undefined,
3641
): Electron.MenuItemConstructorOptions => ({
3742
label: label || plugin,
43+
sublabel: isNew ? t('main.menu.plugins.new') : undefined,
44+
toolTip: description,
3845
type: 'checkbox',
3946
checked: config.plugins.isEnabled(plugin),
4047
click(item: Electron.MenuItem) {
@@ -66,23 +73,30 @@ export const mainMenuTemplate = async (
6673

6774
const menuResult = Object.entries(getAllMenuTemplate()).map(
6875
([id, template]) => {
69-
const pluginLabel = allPlugins[id]?.name?.() ?? id;
76+
const plugin = allPlugins[id];
77+
const pluginLabel = plugin?.name?.() ?? id;
78+
const pluginDescription = plugin?.description?.() ?? undefined;
79+
const isNew = plugin?.addedVersion ? satisfies(packageJson.version, plugin.addedVersion) : false;
7080

7181
if (!config.plugins.isEnabled(id)) {
7282
return [
7383
id,
74-
pluginEnabledMenu(id, pluginLabel, true, innerRefreshMenu),
84+
pluginEnabledMenu(id, pluginLabel, pluginDescription, isNew, true, innerRefreshMenu),
7585
] as const;
7686
}
7787

7888
return [
7989
id,
8090
{
8191
label: pluginLabel,
92+
sublabel: isNew ? t('main.menu.plugins.new') : undefined,
93+
toolTip: pluginDescription,
8294
submenu: [
8395
pluginEnabledMenu(
8496
id,
8597
t('main.menu.plugins.enabled'),
98+
undefined,
99+
false,
86100
true,
87101
innerRefreshMenu,
88102
),
@@ -106,9 +120,12 @@ export const mainMenuTemplate = async (
106120
const predefinedTemplate = menuResult.find((it) => it[0] === id);
107121
if (predefinedTemplate) return predefinedTemplate[1];
108122

109-
const pluginLabel = allPlugins[id]?.name?.() ?? id;
123+
const plugin = allPlugins[id];
124+
const pluginLabel = plugin?.name?.() ?? id;
125+
const pluginDescription = plugin?.description?.() ?? undefined;
126+
const isNew = plugin?.addedVersion ? satisfies(packageJson.version, plugin.addedVersion) : false;
110127

111-
return pluginEnabledMenu(id, pluginLabel, true, innerRefreshMenu);
128+
return pluginEnabledMenu(id, pluginLabel, pluginDescription, isNew, true, innerRefreshMenu);
112129
});
113130

114131
const availableLanguages = Object.keys(languageResources);

src/plugins/album-actions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default createPlugin({
1111
name: () => t('plugins.album-actions.name'),
1212
description: () => t('plugins.album-actions.description'),
1313
restartNeeded: false,
14+
addedVersion: '3.2.0',
1415
config: {
1516
enabled: false,
1617
},

src/plugins/in-app-menu/menu/panel.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ export const createPanel = (
5252
menu.appendChild(iconWrapper);
5353
menu.append(item.label);
5454

55+
if (item.sublabel) {
56+
menu.classList.add('badge');
57+
const menuBadge = document.createElement('menu-item-badge');
58+
menuBadge.append(item.sublabel);
59+
menu.append(menuBadge);
60+
}
61+
if (item.toolTip) {
62+
const menuTooltip = document.createElement('menu-item-tooltip');
63+
menuTooltip.append(item.toolTip);
64+
menu.append(menuTooltip);
65+
}
66+
5567
menu.addEventListener('click', async () => {
5668
await window.ipcRenderer.invoke('menu-event', item.commandId);
5769
const menuItem = (await window.ipcRenderer.invoke(

src/plugins/in-app-menu/titlebar.css

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ menu-panel.position-by-bottom {
9797
}
9898

9999
menu-item {
100+
position: relative;
101+
100102
-webkit-app-region: none;
101103
min-height: 32px;
102104
height: 32px;
@@ -109,6 +111,9 @@ menu-item {
109111
border-radius: 4px;
110112
cursor: pointer;
111113
}
114+
menu-item.badge {
115+
grid-template-columns: 32px 1fr auto minmax(32px, auto);
116+
}
112117
menu-item:hover {
113118
background-color: rgba(255, 255, 255, 0.1);
114119
}
@@ -128,6 +133,56 @@ menu-separator {
128133
background-color: rgba(255, 255, 255, 0.2);
129134
}
130135

136+
menu-item-badge {
137+
display: flex;
138+
justify-content: center;
139+
align-items: center;
140+
141+
min-width: 16px;
142+
height: 16px;
143+
padding: 0 4px;
144+
margin-left: 8px;
145+
146+
border-radius: 4px;
147+
background-color: rgba(255, 255, 255, 0.2);
148+
color: #f1f1f1;
149+
font-size: 10px;
150+
font-weight: 500;
151+
line-height: 1;
152+
}
153+
154+
menu-item-tooltip {
155+
position: absolute;
156+
157+
left: 0;
158+
top: calc(100% + 4px);
159+
160+
display: flex;
161+
justify-content: center;
162+
align-items: center;
163+
164+
min-width: 32px;
165+
padding: 4px;
166+
167+
border-radius: 4px;
168+
background-color: rgba(25, 25, 25, 0.8);
169+
color: #f1f1f1;
170+
font-size: 10px;
171+
172+
pointer-events: none;
173+
z-index: 1000;
174+
175+
opacity: 0;
176+
scale: 0.9;
177+
178+
transform-origin: 50% 0;
179+
transition: all 0.225s ease-out;
180+
}
181+
menu-item:hover > menu-item-tooltip {
182+
opacity: 1;
183+
scale: 1.0;
184+
}
185+
131186
/* classes */
132187

133188
.title-bar-icon {

src/plugins/music-together/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export default createPlugin({
3838
name: () => t('plugins.music-together.name'),
3939
description: () => t('plugins.music-together.description'),
4040
restartNeeded: false,
41+
addedVersion: '3.2.0',
4142
config: {
4243
enabled: false
4344
},

src/types/plugins.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export interface PluginDef<
4747
name: () => string;
4848
authors?: Author[];
4949
description?: () => string;
50+
addedVersion?: string;
5051
config?: Config;
5152

5253
menu?: (

0 commit comments

Comments
 (0)