-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
base.ts
123 lines (110 loc) · 2.86 KB
/
base.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { Channel, invoke, Resource } from '../core'
import { transformImage } from '../image'
import { CheckMenuItemOptions } from './checkMenuItem'
import { IconMenuItemOptions } from './iconMenuItem'
import { MenuItemOptions } from './menuItem'
import { PredefinedMenuItemOptions } from './predefinedMenuItem'
import { SubmenuOptions } from './submenu'
export type ItemKind =
| 'MenuItem'
| 'Predefined'
| 'Check'
| 'Icon'
| 'Submenu'
| 'Menu'
function injectChannel(
i:
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| CheckMenuItemOptions
):
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| (CheckMenuItemOptions & { handler?: Channel<string> }) {
if ('items' in i) {
i.items = i.items?.map((item) =>
'rid' in item ? item : injectChannel(item)
)
} else if ('action' in i && i.action) {
const handler = new Channel<string>()
handler.onmessage = i.action
delete i.action
return { ...i, handler }
}
return i
}
export async function newMenu(
kind: ItemKind,
opts?: unknown
): Promise<[number, string]> {
const handler = new Channel<string>()
let items: null | Array<
| [number, string]
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| CheckMenuItemOptions
> = null
if (opts && typeof opts === 'object') {
if ('action' in opts && opts.action) {
handler.onmessage = opts.action as () => void
delete opts.action
}
if ('items' in opts && opts.items) {
items = (
opts.items as Array<
| { rid: number; kind: string }
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| CheckMenuItemOptions
>
).map((i) => {
if ('rid' in i) {
return [i.rid, i.kind]
}
if ('item' in i && typeof i.item === 'object' && i.item.About?.icon) {
i.item.About.icon = transformImage(i.item.About.icon)
}
if ('icon' in i && i.icon) {
i.icon = transformImage(i.icon)
}
return injectChannel(i)
})
}
}
return invoke('plugin:menu|new', {
kind,
options: opts ? { ...opts, items } : undefined,
handler
})
}
export class MenuItemBase extends Resource {
/** @ignore */
readonly #id: string
/** @ignore */
readonly #kind: ItemKind
/** The id of this item. */
get id(): string {
return this.#id
}
/** @ignore */
get kind(): string {
return this.#kind
}
/** @ignore */
protected constructor(rid: number, id: string, kind: ItemKind) {
super(rid)
this.#id = id
this.#kind = kind
}
}