Jelajahi Sumber

refactor!: simplify `TrayIconEvent` in JS by tagging it with `type` field (#11121)


Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
Amr Bashir 10 bulan lalu
induk
melakukan
0b4495996d

+ 0 - 5
.changes/api-tray-doubleClick-event.md

@@ -1,5 +0,0 @@
----
-"@tauri-apps/api": "patch:bug"
----
-
-Add missing `TrayIconDoubleClickEvent` type and `doubleClick` variant in `TrayIconEvent` type.

+ 7 - 0
.changes/api-tray-event-refactor.md

@@ -0,0 +1,7 @@
+---
+"tauri": "patch:breaking"
+"@tauri-apps/api": "patch:breaking"
+---
+
+Simplified emitted tray event JS value and updated `TrayIconEvent` type definition to match it.
+

+ 0 - 6
.changes/api-tray-icon-event-value-mismatch-type.md

@@ -1,6 +0,0 @@
----
-"@tauri-apps/api": "patch:bug"
----
-
-Fix invalid value passed to the callback `action` function that doesn't match the `TrayIconEvent` type.
-

+ 2 - 2
Cargo.lock

@@ -8190,9 +8190,9 @@ dependencies = [
 
 [[package]]
 name = "tray-icon"
-version = "0.18.0"
+version = "0.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1730884cee088bb1dc1570c0a8b70a59e740ee780563407fd249e3e11ef26ff"
+checksum = "533fc2d4105e0e3d96ce1c71f2d308c9fbbe2ef9c587cab63dd627ab5bde218f"
 dependencies = [
  "core-graphics 0.24.0",
  "crossbeam-channel",

+ 1 - 1
crates/tauri/Cargo.toml

@@ -92,7 +92,7 @@ specta = { version = "^2.0.0-rc.16", optional = true, default-features = false,
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
 muda = { version = "0.15", default-features = false, features = ["serde"] }
-tray-icon = { version = "0.18", default-features = false, features = [
+tray-icon = { version = "0.19", default-features = false, features = [
   "serde",
 ], optional = true }
 

File diff ditekan karena terlalu besar
+ 0 - 0
crates/tauri/scripts/bundle.global.js


+ 50 - 1
crates/tauri/src/tray/mod.rs

@@ -75,7 +75,7 @@ impl From<tray_icon::MouseButton> for MouseButton {
 /// - **Linux**: Unsupported. The event is not emmited even though the icon is shown
 ///   and will still show a context menu on right click.
 #[derive(Debug, Clone, Serialize)]
-#[serde(rename_all = "camelCase")]
+#[serde(tag = "type")]
 #[non_exhaustive]
 pub enum TrayIconEvent {
   /// A click happened on the tray icon.
@@ -563,3 +563,52 @@ impl<R: Runtime> Resource for TrayIcon<R> {
     self.app_handle.remove_tray_by_id(&self.id);
   }
 }
+
+#[cfg(test)]
+mod tests {
+  #[test]
+  fn tray_event_json_serialization() {
+    // NOTE: if this test is ever changed, you probably need to change `TrayIconEvent` in JS as well
+
+    use super::*;
+    let event = TrayIconEvent::Click {
+      button: MouseButton::Left,
+      button_state: MouseButtonState::Down,
+      id: TrayIconId::new("id"),
+      position: crate::PhysicalPosition::default(),
+      rect: crate::Rect {
+        position: tray_icon::Rect::default().position.into(),
+        size: tray_icon::Rect::default().size.into(),
+      },
+    };
+
+    let value = serde_json::to_value(&event).unwrap();
+    assert_eq!(
+      value,
+      serde_json::json!({
+          "type": "Click",
+          "button": "Left",
+          "buttonState": "Down",
+          "id": "id",
+          "position": {
+              "x": 0.0,
+              "y": 0.0,
+          },
+          "rect": {
+              "size": {
+                  "Physical": {
+                      "width": 0,
+                      "height": 0,
+                  }
+              },
+              "position": {
+                  "Physical": {
+                      "x": 0,
+                      "y": 0,
+                  }
+              },
+          }
+      })
+    );
+  }
+}

+ 47 - 112
packages/api/src/tray.ts

@@ -9,86 +9,32 @@ import { PhysicalPosition, PhysicalSize } from './dpi'
 
 export type MouseButtonState = 'Up' | 'Down'
 export type MouseButton = 'Left' | 'Right' | 'Middle'
+export type TrayIconEventType =
+  | 'Click'
+  | 'DoubleClick'
+  | 'Enter'
+  | 'Move'
+  | 'Leave'
 
-/** A click happened on the tray icon. */
-export interface TrayIconClickEvent {
+export type TrayIconEventBase<T extends TrayIconEventType> = {
+  /** The tray icon event type */
+  type: T
   /** Id of the tray icon which triggered this event. */
   id: string
-  /** Physical X Position of the click the triggered this event. */
-  x: number
-  /** Physical Y Position of the click the triggered this event. */
-  y: number
+  /** Physical position of the click the triggered this event. */
+  position: PhysicalPosition
   /** Position and size of the tray icon. */
   rect: {
     position: PhysicalPosition
     size: PhysicalSize
   }
-  /** Mouse button that triggered this event. */
-  button: MouseButton
-  /** Mouse button state when this event was triggered. */
-  buttonState: MouseButtonState
 }
 
-/** A double click happened on the tray icon. **Windows Only** */
-export interface TrayIconDoubleClickEvent {
-  /** Id of the tray icon which triggered this event. */
-  id: string
-  /** Physical X Position of the click the triggered this event. */
-  x: number
-  /** Physical Y Position of the click the triggered this event. */
-  y: number
-  /** Position and size of the tray icon. */
-  rect: {
-    position: PhysicalPosition
-    size: PhysicalSize
-  }
+export type TrayIconClickEvent = {
   /** Mouse button that triggered this event. */
   button: MouseButton
-}
-
-/** The mouse entered the tray icon region. */
-export interface TrayIconEnterEvent {
-  /** Id of the tray icon which triggered this event. */
-  id: string
-  /** Physical X Position of the click the triggered this event. */
-  x: number
-  /** Physical Y Position of the click the triggered this event. */
-  y: number
-  /** Position and size of the tray icon. */
-  rect: {
-    position: PhysicalPosition
-    size: PhysicalSize
-  }
-}
-
-/** The mouse moved over the tray icon region. */
-export interface TrayIconMoveEvent {
-  /** Id of the tray icon which triggered this event. */
-  id: string
-  /** Physical X Position of the click the triggered this event. */
-  x: number
-  /** Physical Y Position of the click the triggered this event. */
-  y: number
-  /** Position and size of the tray icon. */
-  rect: {
-    position: PhysicalPosition
-    size: PhysicalSize
-  }
-}
-
-/** The mouse left the tray icon region. */
-export interface TrayIconLeaveEvent {
-  /** Id of the tray icon which triggered this event. */
-  id: string
-  /** Physical X Position of the click the triggered this event. */
-  x: number
-  /** Physical Y Position of the click the triggered this event. */
-  y: number
-  /** Position and size of the tray icon. */
-  rect: {
-    position: PhysicalPosition
-    size: PhysicalSize
-  }
+  /** Mouse button state when this event was triggered. */
+  buttonState: MouseButtonState
 }
 
 /**
@@ -100,11 +46,22 @@ export interface TrayIconLeaveEvent {
  * the icon will still show a context menu on right click.
  */
 export type TrayIconEvent =
-  | { click: TrayIconClickEvent }
-  | { doubleClick: TrayIconDoubleClickEvent }
-  | { enter: TrayIconEnterEvent }
-  | { move: TrayIconMoveEvent }
-  | { leave: TrayIconLeaveEvent }
+  | (TrayIconEventBase<'Click'> & TrayIconClickEvent)
+  | (TrayIconEventBase<'DoubleClick'> & Omit<TrayIconClickEvent, 'buttonState'>)
+  | TrayIconEventBase<'Enter'>
+  | TrayIconEventBase<'Move'>
+  | TrayIconEventBase<'Leave'>
+
+type RustTrayIconEvent = Omit<TrayIconEvent, 'rect'> & {
+  rect: {
+    position: {
+      Physical: { x: number; y: number }
+    }
+    size: {
+      Physical: { width: number; height: number }
+    }
+  }
+}
 
 /**
  * Tray icon types and utilities.
@@ -223,38 +180,10 @@ export class TrayIcon extends Resource {
       options.icon = transformImage(options.icon)
     }
 
-    const handler = new Channel<TrayIconEvent>()
+    const handler = new Channel<RustTrayIconEvent>()
     if (options?.action) {
       const action = options.action
-      handler.onmessage = (e) => {
-        if ('click' in e) {
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.click.rect.position = mapPosition(e.click.rect.position)
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.click.rect.size = mapSize(e.click.rect.size)
-        } else if ('doubleClick' in e) {
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.doubleClick.rect.position = mapPosition(e.doubleClick.rect.position)
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.doubleClick.rect.size = mapSize(e.doubleClick.rect.size)
-        } else if ('enter' in e) {
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.enter.rect.position = mapPosition(e.enter.rect.position)
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.enter.rect.size = mapSize(e.enter.rect.size)
-        } else if ('move' in e) {
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.move.rect.position = mapPosition(e.move.rect.position)
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.move.rect.size = mapSize(e.move.rect.size)
-        } else if ('leave' in e) {
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.leave.rect.position = mapPosition(e.leave.rect.position)
-          // @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
-          e.leave.rect.size = mapSize(e.leave.rect.size)
-        }
-        action(e)
-      }
+      handler.onmessage = (e) => action(mapEvent(e))
       delete options.action
     }
 
@@ -358,13 +287,19 @@ export class TrayIcon extends Resource {
   }
 }
 
-function mapPosition(pos: {
-  Physical: { x: number; y: number }
-}): PhysicalPosition {
-  return new PhysicalPosition(pos.Physical.x, pos.Physical.y)
-}
-function mapSize(pos: {
-  Physical: { width: number; height: number }
-}): PhysicalSize {
-  return new PhysicalSize(pos.Physical.width, pos.Physical.height)
+function mapEvent(e: RustTrayIconEvent): TrayIconEvent {
+  const out = e as unknown as TrayIconEvent
+
+  out.position = new PhysicalPosition(e.position.x, e.position.y)
+
+  out.rect.position = new PhysicalPosition(
+    e.rect.position.Physical.x,
+    e.rect.position.Physical.y
+  )
+  out.rect.size = new PhysicalSize(
+    e.rect.size.Physical.width,
+    e.rect.size.Physical.height
+  )
+
+  return out
 }

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini