fix(api): transform icon when creating icon menu item and predefined about menu item with icon (#11741)

This commit is contained in:
Amr Bashir
2024-11-21 14:22:51 +02:00
committed by GitHub
parent 020ea05561
commit 12a48d1e26
8 changed files with 67 additions and 78 deletions

View File

@@ -0,0 +1,6 @@
---
"@tauri-apps/api": "patch:bug"
---
Fix error when calling `PredefinedMenuItem.new` to create an `About` menu item that uses an `Image` instance for the about icon.

View File

@@ -0,0 +1,6 @@
---
"@tauri-apps/api": "patch:bug"
---
Fix error when calling `IconMenuItem.new` using an `Image` instance for the icon.

File diff suppressed because one or more lines are too long

View File

@@ -28,7 +28,7 @@
"packageManager": "pnpm@9.9.0",
"pnpm": {
"overrides": {
"rollup@>=4.0.0 <4.22.4": ">=4.22.4",
"cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5",
"cookie@<0.7.0": ">=0.7.0"
}
}

View File

@@ -6,6 +6,7 @@ import { Channel, invoke, Resource } from '../core'
import { transformImage } from '../image'
import { CheckMenuItemOptions } from './checkMenuItem'
import { IconMenuItemOptions } from './iconMenuItem'
import { MenuOptions } from './menu'
import { MenuItemOptions } from './menuItem'
import { PredefinedMenuItemOptions } from './predefinedMenuItem'
import { SubmenuOptions } from './submenu'
@@ -18,19 +19,16 @@ export type ItemKind =
| 'Submenu'
| 'Menu'
function injectChannel(
i:
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| CheckMenuItemOptions
):
type MenuItemOptionsAlias =
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| ((MenuItemOptions | IconMenuItemOptions | CheckMenuItemOptions) & {
handler?: Channel<string>
}) {
| CheckMenuItemOptions
function injectChannel(i: MenuItemOptionsAlias): MenuItemOptionsAlias & {
handler?: Channel<string>
} {
if ('items' in i) {
i.items = i.items?.map((item) =>
'rid' in item ? item : injectChannel(item)
@@ -46,7 +44,13 @@ function injectChannel(
export async function newMenu(
kind: ItemKind,
opts?: unknown
opts?:
| MenuOptions
| MenuItemOptions
| SubmenuOptions
| PredefinedMenuItemOptions
| CheckMenuItemOptions
| IconMenuItemOptions
): Promise<[number, string]> {
const handler = new Channel<string>()
@@ -56,22 +60,30 @@ export async function newMenu(
delete opts.action
}
// about predefined menu item icon
if (
'item' in opts &&
opts.item &&
typeof opts.item === 'object' &&
'About' in opts.item &&
opts.item.About &&
typeof opts.item.About === 'object' &&
'icon' in opts.item.About &&
opts.item.About.icon
) {
opts.item.About.icon = transformImage(opts.item.About.icon)
}
// icon menu item icon
if ('icon' in opts && opts.icon) {
opts.icon = transformImage(opts.icon)
}
// submenu items
if ('items' in opts && opts.items) {
function prepareItem(
i:
| { rid: number; kind: string }
| MenuItemOptions
| SubmenuOptions
| IconMenuItemOptions
| PredefinedMenuItemOptions
| CheckMenuItemOptions
):
| [number, string]
| SubmenuOptions
| PredefinedMenuItemOptions
| MenuItemOptions
| IconMenuItemOptions
| CheckMenuItemOptions {
i: { rid: number; kind: string } | MenuItemOptionsAlias
): [number, string] | MenuItemOptionsAlias {
if ('rid' in i) {
return [i.rid, i.kind]
}
@@ -93,6 +105,8 @@ export async function newMenu(
return injectChannel(i)
}
// @ts-expect-error the `prepareItem` return doesn't exactly match
// this is fine, because the difference is in `[number, string]` variant
opts.items = (opts.items as []).map(prepareItem)
}
}

View File

@@ -13,40 +13,12 @@ import { MenuItem } from './menuItem'
import { CheckMenuItem } from './checkMenuItem'
import { IconMenuItem } from './iconMenuItem'
import { PredefinedMenuItem } from './predefinedMenuItem'
import { Submenu } from './submenu'
import { itemFromKind, Submenu } from './submenu'
import { type LogicalPosition, PhysicalPosition, Position } from '../dpi'
import { type Window } from '../window'
import { invoke } from '../core'
import { type ItemKind, MenuItemBase, newMenu } from './base'
function itemFromKind([rid, id, kind]: [number, string, ItemKind]):
| Submenu
| MenuItem
| PredefinedMenuItem
| CheckMenuItem
| IconMenuItem {
/* eslint-disable @typescript-eslint/no-unsafe-return */
switch (kind) {
case 'Submenu':
// @ts-expect-error constructor is protected for external usage only
return new Submenu(rid, id)
case 'Predefined':
// @ts-expect-error constructor is protected for external usage only
return new PredefinedMenuItem(rid, id)
case 'Check':
// @ts-expect-error constructor is protected for external usage only
return new CheckMenuItem(rid, id)
case 'Icon':
// @ts-expect-error constructor is protected for external usage only
return new IconMenuItem(rid, id)
case 'MenuItem':
default:
// @ts-expect-error constructor is protected for external usage only
return new MenuItem(rid, id)
}
/* eslint-enable @typescript-eslint/no-unsafe-return */
}
/** Options for creating a new menu. */
export interface MenuOptions {
/** Specify an id to use for the new menu. */

View File

@@ -17,7 +17,8 @@ import { type ItemKind, MenuItemBase, newMenu } from './base'
import { type MenuOptions } from './menu'
import { Position } from '../dpi'
function itemFromKind([rid, id, kind]: [number, string, ItemKind]):
/** @ignore */
export function itemFromKind([rid, id, kind]: [number, string, ItemKind]):
| Submenu
| MenuItem
| PredefinedMenuItem

30
pnpm-lock.yaml generated
View File

@@ -5,7 +5,7 @@ settings:
excludeLinksFromLockfile: false
overrides:
rollup@>=4.0.0 <4.22.4: '>=4.22.4'
cross-spawn@>=7.0.0 <7.0.5: '>=7.0.5'
cookie@<0.7.0: '>=0.7.0'
importers:
@@ -843,7 +843,7 @@ packages:
resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: '>=4.22.4'
rollup: ^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
@@ -852,7 +852,7 @@ packages:
resolution: {integrity: sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: '>=4.22.4'
rollup: ^2.14.0||^3.0.0||^4.0.0
tslib: '*'
typescript: '>=3.7.0'
peerDependenciesMeta:
@@ -865,7 +865,7 @@ packages:
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: '>=4.22.4'
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
@@ -1416,19 +1416,15 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
cookie@0.7.1:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'}
cookie@1.0.1:
resolution: {integrity: sha512-Xd8lFX4LM9QEEwxQpF9J9NTUh8pmdJO0cyRJhFiDoLTk2eH8FXlRv2IFGYVadZpqI3j8fhNrSdKCeYPxiAhLXw==}
engines: {node: '>=18'}
cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
hasBin: true
cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -3603,17 +3599,11 @@ snapshots:
convert-source-map@2.0.0: {}
cookie@0.7.1: {}
cookie@1.0.1: {}
cross-env@7.0.3:
dependencies:
cross-spawn: 7.0.3
cross-spawn@7.0.3:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
cross-spawn: 7.0.6
cross-spawn@7.0.6:
dependencies:
@@ -4645,7 +4635,7 @@ snapshots:
youch@3.3.3:
dependencies:
cookie: 0.7.1
cookie: 1.0.1
mustache: 4.2.0
stacktracey: 2.1.8