From 4806dc76aa7ea775d76a9d7ae24cdd632791997d Mon Sep 17 00:00:00 2001
From: Peter Ombodi
Date: Wed, 15 Apr 2026 16:42:44 +0300
Subject: [PATCH] fix(mobile): remove redundant iOS code update code related to
LocalAsset model and asset viewer
---
mobile/ios/Runner/AppDelegate.swift | 1 -
.../ios/Runner/ViewIntent/ViewIntent.g.swift | 228 ------------------
.../Runner/ViewIntent/ViewIntentApiImpl.swift | 5 -
.../view_intent_attachment.model.dart | 27 ++-
mobile/lib/platform/view_intent_api.g.dart | 58 +++--
.../view_intent_handler.provider.dart | 20 +-
.../repositories/view_handler.repository.dart | 1 +
mobile/pigeon/view_intent_api.dart | 2 -
.../services/view_intent_service_test.dart | 1 +
9 files changed, 71 insertions(+), 272 deletions(-)
delete mode 100644 mobile/ios/Runner/ViewIntent/ViewIntent.g.swift
delete mode 100644 mobile/ios/Runner/ViewIntent/ViewIntentApiImpl.swift
diff --git a/mobile/ios/Runner/AppDelegate.swift b/mobile/ios/Runner/AppDelegate.swift
index 218c0b2832..81af41ab08 100644
--- a/mobile/ios/Runner/AppDelegate.swift
+++ b/mobile/ios/Runner/AppDelegate.swift
@@ -61,7 +61,6 @@ import UIKit
BackgroundWorkerFgHostApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: BackgroundWorkerApiImpl())
ConnectivityApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: ConnectivityApiImpl())
NetworkApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: NetworkApiImpl(viewController: controller))
- ViewIntentHostApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: ViewIntentApiImpl())
}
public static func cancelPlugins(with engine: FlutterEngine) {
diff --git a/mobile/ios/Runner/ViewIntent/ViewIntent.g.swift b/mobile/ios/Runner/ViewIntent/ViewIntent.g.swift
deleted file mode 100644
index b28332976c..0000000000
--- a/mobile/ios/Runner/ViewIntent/ViewIntent.g.swift
+++ /dev/null
@@ -1,228 +0,0 @@
-// Autogenerated from Pigeon (v26.0.2), do not edit directly.
-// See also: https://pub.dev/packages/pigeon
-
-import Foundation
-
-#if os(iOS)
- import Flutter
-#elseif os(macOS)
- import FlutterMacOS
-#else
- #error("Unsupported platform.")
-#endif
-
-private func wrapResult(_ result: Any?) -> [Any?] {
- return [result]
-}
-
-private func wrapError(_ error: Any) -> [Any?] {
- if let pigeonError = error as? PigeonError {
- return [
- pigeonError.code,
- pigeonError.message,
- pigeonError.details,
- ]
- }
- if let flutterError = error as? FlutterError {
- return [
- flutterError.code,
- flutterError.message,
- flutterError.details,
- ]
- }
- return [
- "\(error)",
- "\(type(of: error))",
- "Stacktrace: \(Thread.callStackSymbols)",
- ]
-}
-
-private func isNullish(_ value: Any?) -> Bool {
- return value is NSNull || value == nil
-}
-
-private func nilOrValue(_ value: Any?) -> T? {
- if value is NSNull { return nil }
- return value as! T?
-}
-
-func deepEqualsViewIntent(_ lhs: Any?, _ rhs: Any?) -> Bool {
- let cleanLhs = nilOrValue(lhs) as Any?
- let cleanRhs = nilOrValue(rhs) as Any?
- switch (cleanLhs, cleanRhs) {
- case (nil, nil):
- return true
-
- case (nil, _), (_, nil):
- return false
-
- case is (Void, Void):
- return true
-
- case let (cleanLhsHashable, cleanRhsHashable) as (AnyHashable, AnyHashable):
- return cleanLhsHashable == cleanRhsHashable
-
- case let (cleanLhsArray, cleanRhsArray) as ([Any?], [Any?]):
- guard cleanLhsArray.count == cleanRhsArray.count else { return false }
- for (index, element) in cleanLhsArray.enumerated() {
- if !deepEqualsViewIntent(element, cleanRhsArray[index]) {
- return false
- }
- }
- return true
-
- case let (cleanLhsDictionary, cleanRhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
- guard cleanLhsDictionary.count == cleanRhsDictionary.count else { return false }
- for (key, cleanLhsValue) in cleanLhsDictionary {
- guard cleanRhsDictionary.index(forKey: key) != nil else { return false }
- if !deepEqualsViewIntent(cleanLhsValue, cleanRhsDictionary[key]!) {
- return false
- }
- }
- return true
-
- default:
- // Any other type shouldn't be able to be used with pigeon. File an issue if you find this to be untrue.
- return false
- }
-}
-
-func deepHashViewIntent(value: Any?, hasher: inout Hasher) {
- if let valueList = value as? [AnyHashable] {
- for item in valueList { deepHashViewIntent(value: item, hasher: &hasher) }
- return
- }
-
- if let valueDict = value as? [AnyHashable: AnyHashable] {
- for key in valueDict.keys {
- hasher.combine(key)
- deepHashViewIntent(value: valueDict[key]!, hasher: &hasher)
- }
- return
- }
-
- if let hashableValue = value as? AnyHashable {
- hasher.combine(hashableValue.hashValue)
- }
-
- return hasher.combine(String(describing: value))
-}
-
-
-
-enum ViewIntentType: Int {
- case image = 0
- case video = 1
-}
-
-/// Generated class from Pigeon that represents data sent in messages.
-struct ViewIntentPayload: Hashable {
- var path: String
- var type: ViewIntentType
- var mimeType: String
- var localAssetId: String? = nil
-
-
- // swift-format-ignore: AlwaysUseLowerCamelCase
- static func fromList(_ pigeonVar_list: [Any?]) -> ViewIntentPayload? {
- let path = pigeonVar_list[0] as! String
- let type = pigeonVar_list[1] as! ViewIntentType
- let mimeType = pigeonVar_list[2] as! String
- let localAssetId: String? = nilOrValue(pigeonVar_list[3])
-
- return ViewIntentPayload(
- path: path,
- type: type,
- mimeType: mimeType,
- localAssetId: localAssetId
- )
- }
- func toList() -> [Any?] {
- return [
- path,
- type,
- mimeType,
- localAssetId,
- ]
- }
- static func == (lhs: ViewIntentPayload, rhs: ViewIntentPayload) -> Bool {
- return deepEqualsViewIntent(lhs.toList(), rhs.toList()) }
- func hash(into hasher: inout Hasher) {
- deepHashViewIntent(value: toList(), hasher: &hasher)
- }
-}
-
-private class ViewIntentPigeonCodecReader: FlutterStandardReader {
- override func readValue(ofType type: UInt8) -> Any? {
- switch type {
- case 129:
- let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
- if let enumResultAsInt = enumResultAsInt {
- return ViewIntentType(rawValue: enumResultAsInt)
- }
- return nil
- case 130:
- return ViewIntentPayload.fromList(self.readValue() as! [Any?])
- default:
- return super.readValue(ofType: type)
- }
- }
-}
-
-private class ViewIntentPigeonCodecWriter: FlutterStandardWriter {
- override func writeValue(_ value: Any) {
- if let value = value as? ViewIntentType {
- super.writeByte(129)
- super.writeValue(value.rawValue)
- } else if let value = value as? ViewIntentPayload {
- super.writeByte(130)
- super.writeValue(value.toList())
- } else {
- super.writeValue(value)
- }
- }
-}
-
-private class ViewIntentPigeonCodecReaderWriter: FlutterStandardReaderWriter {
- override func reader(with data: Data) -> FlutterStandardReader {
- return ViewIntentPigeonCodecReader(data: data)
- }
-
- override func writer(with data: NSMutableData) -> FlutterStandardWriter {
- return ViewIntentPigeonCodecWriter(data: data)
- }
-}
-
-class ViewIntentPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
- static let shared = ViewIntentPigeonCodec(readerWriter: ViewIntentPigeonCodecReaderWriter())
-}
-
-
-/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
-protocol ViewIntentHostApi {
- func consumeViewIntent(completion: @escaping (Result) -> Void)
-}
-
-/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
-class ViewIntentHostApiSetup {
- static var codec: FlutterStandardMessageCodec { ViewIntentPigeonCodec.shared }
- /// Sets up an instance of `ViewIntentHostApi` to handle messages through the `binaryMessenger`.
- static func setUp(binaryMessenger: FlutterBinaryMessenger, api: ViewIntentHostApi?, messageChannelSuffix: String = "") {
- let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : ""
- let consumeViewIntentChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.ViewIntentHostApi.consumeViewIntent\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
- if let api = api {
- consumeViewIntentChannel.setMessageHandler { _, reply in
- api.consumeViewIntent { result in
- switch result {
- case .success(let res):
- reply(wrapResult(res))
- case .failure(let error):
- reply(wrapError(error))
- }
- }
- }
- } else {
- consumeViewIntentChannel.setMessageHandler(nil)
- }
- }
-}
diff --git a/mobile/ios/Runner/ViewIntent/ViewIntentApiImpl.swift b/mobile/ios/Runner/ViewIntent/ViewIntentApiImpl.swift
deleted file mode 100644
index 07ff78a582..0000000000
--- a/mobile/ios/Runner/ViewIntent/ViewIntentApiImpl.swift
+++ /dev/null
@@ -1,5 +0,0 @@
-class ViewIntentApiImpl: ViewIntentHostApi {
- func consumeViewIntent(completion: @escaping (Result) -> Void) {
- completion(.success(nil))
- }
-}
diff --git a/mobile/lib/models/view_intent/view_intent_attachment.model.dart b/mobile/lib/models/view_intent/view_intent_attachment.model.dart
index 92f2b2f88c..c4bb4c259f 100644
--- a/mobile/lib/models/view_intent/view_intent_attachment.model.dart
+++ b/mobile/lib/models/view_intent/view_intent_attachment.model.dart
@@ -1,5 +1,6 @@
import 'dart:io';
+import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
import 'package:path/path.dart';
enum ViewIntentAttachmentType { image, video }
@@ -7,9 +8,15 @@ enum ViewIntentAttachmentType { image, video }
class ViewIntentAttachment {
final String path;
final ViewIntentAttachmentType type;
+ final String mimeType;
final String? localAssetId;
- const ViewIntentAttachment({required this.path, required this.type, this.localAssetId});
+ const ViewIntentAttachment({
+ required this.path,
+ required this.type,
+ required this.mimeType,
+ this.localAssetId,
+ });
File get file => File(path);
@@ -18,4 +25,22 @@ class ViewIntentAttachment {
bool get isImage => type == ViewIntentAttachmentType.image;
bool get isVideo => type == ViewIntentAttachmentType.video;
+
+ AssetPlaybackStyle get playbackStyle {
+ if (isVideo) {
+ return AssetPlaybackStyle.video;
+ }
+
+ final normalizedMimeType = mimeType.toLowerCase();
+ if (normalizedMimeType == 'image/gif' || normalizedMimeType == 'image/webp') {
+ return AssetPlaybackStyle.imageAnimated;
+ }
+
+ final normalizedPath = path.toLowerCase();
+ if (normalizedPath.endsWith('.gif') || normalizedPath.endsWith('.webp')) {
+ return AssetPlaybackStyle.imageAnimated;
+ }
+
+ return AssetPlaybackStyle.image;
+ }
}
diff --git a/mobile/lib/platform/view_intent_api.g.dart b/mobile/lib/platform/view_intent_api.g.dart
index bcc1f3a8ee..4190d2cc1c 100644
--- a/mobile/lib/platform/view_intent_api.g.dart
+++ b/mobile/lib/platform/view_intent_api.g.dart
@@ -14,25 +14,33 @@ PlatformException _createConnectionError(String channelName) {
message: 'Unable to establish connection on channel: "$channelName".',
);
}
-
bool _deepEquals(Object? a, Object? b) {
if (a is List && b is List) {
- return a.length == b.length && a.indexed.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
+ return a.length == b.length &&
+ a.indexed
+ .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
}
if (a is Map && b is Map) {
- return a.length == b.length &&
- a.entries.every(
- (MapEntry