🐛 Fix bugs and don't know what has been fixed
This commit is contained in:
		@@ -45,10 +45,10 @@ PODS:
 | 
			
		||||
  - Firebase/Messaging (11.15.0):
 | 
			
		||||
    - Firebase/CoreOnly
 | 
			
		||||
    - FirebaseMessaging (~> 11.15.0)
 | 
			
		||||
  - firebase_core (3.15.0):
 | 
			
		||||
  - firebase_core (3.15.1):
 | 
			
		||||
    - Firebase/CoreOnly (= 11.15.0)
 | 
			
		||||
    - Flutter
 | 
			
		||||
  - firebase_messaging (15.2.8):
 | 
			
		||||
  - firebase_messaging (15.2.9):
 | 
			
		||||
    - Firebase/Messaging (= 11.15.0)
 | 
			
		||||
    - firebase_core
 | 
			
		||||
    - Flutter
 | 
			
		||||
@@ -130,7 +130,7 @@ PODS:
 | 
			
		||||
    - Flutter
 | 
			
		||||
  - irondash_engine_context (0.0.1):
 | 
			
		||||
    - Flutter
 | 
			
		||||
  - Kingfisher (8.3.3)
 | 
			
		||||
  - Kingfisher (8.4.0)
 | 
			
		||||
  - livekit_client (2.4.9):
 | 
			
		||||
    - Flutter
 | 
			
		||||
    - flutter_webrtc
 | 
			
		||||
@@ -178,18 +178,18 @@ PODS:
 | 
			
		||||
  - sqflite_darwin (0.0.4):
 | 
			
		||||
    - Flutter
 | 
			
		||||
    - FlutterMacOS
 | 
			
		||||
  - sqlite3 (3.50.1):
 | 
			
		||||
    - sqlite3/common (= 3.50.1)
 | 
			
		||||
  - sqlite3/common (3.50.1)
 | 
			
		||||
  - sqlite3/dbstatvtab (3.50.1):
 | 
			
		||||
  - sqlite3 (3.50.2):
 | 
			
		||||
    - sqlite3/common (= 3.50.2)
 | 
			
		||||
  - sqlite3/common (3.50.2)
 | 
			
		||||
  - sqlite3/dbstatvtab (3.50.2):
 | 
			
		||||
    - sqlite3/common
 | 
			
		||||
  - sqlite3/fts5 (3.50.1):
 | 
			
		||||
  - sqlite3/fts5 (3.50.2):
 | 
			
		||||
    - sqlite3/common
 | 
			
		||||
  - sqlite3/math (3.50.1):
 | 
			
		||||
  - sqlite3/math (3.50.2):
 | 
			
		||||
    - sqlite3/common
 | 
			
		||||
  - sqlite3/perf-threadsafe (3.50.1):
 | 
			
		||||
  - sqlite3/perf-threadsafe (3.50.2):
 | 
			
		||||
    - sqlite3/common
 | 
			
		||||
  - sqlite3/rtree (3.50.1):
 | 
			
		||||
  - sqlite3/rtree (3.50.2):
 | 
			
		||||
    - sqlite3/common
 | 
			
		||||
  - sqlite3_flutter_libs (0.0.1):
 | 
			
		||||
    - Flutter
 | 
			
		||||
@@ -362,8 +362,8 @@ SPEC CHECKSUMS:
 | 
			
		||||
  DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
 | 
			
		||||
  file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
 | 
			
		||||
  Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
 | 
			
		||||
  firebase_core: c727a02c560a53f1f1e56e18f16515eb5753c492
 | 
			
		||||
  firebase_messaging: 4158969b04b667f5435731ec9d6e453bb58b0c4c
 | 
			
		||||
  firebase_core: ece862f94b2bc72ee0edbeec7ab5c7cb09fe1ab5
 | 
			
		||||
  firebase_messaging: e1a5fae495603115be1d0183bc849da748734e2b
 | 
			
		||||
  FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
 | 
			
		||||
  FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
 | 
			
		||||
  FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
 | 
			
		||||
@@ -382,9 +382,9 @@ SPEC CHECKSUMS:
 | 
			
		||||
  GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
 | 
			
		||||
  image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
 | 
			
		||||
  irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
 | 
			
		||||
  Kingfisher: ff82cb91d9266ddb56cbb2f72d32c26f00d3e5be
 | 
			
		||||
  Kingfisher: b14cc47bbfa7a3c150dd12962ee9c86338545629
 | 
			
		||||
  livekit_client: 3f79d79233a5bd13d5b541732624ef959d7c538e
 | 
			
		||||
  local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
 | 
			
		||||
  local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
 | 
			
		||||
  media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
 | 
			
		||||
  media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
 | 
			
		||||
  nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
 | 
			
		||||
@@ -403,7 +403,7 @@ SPEC CHECKSUMS:
 | 
			
		||||
  shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
 | 
			
		||||
  sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
 | 
			
		||||
  sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
 | 
			
		||||
  sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5
 | 
			
		||||
  sqlite3: 3e82a2daae39ba3b41ae6ee84a130494585460fc
 | 
			
		||||
  sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2
 | 
			
		||||
  super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
 | 
			
		||||
  SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ import UIKit
 | 
			
		||||
        UNUserNotificationCenter.current().setNotificationCategories([replyableMessageCategory])
 | 
			
		||||
        
 | 
			
		||||
        GeneratedPluginRegistrant.register(with: self)
 | 
			
		||||
        
 | 
			
		||||
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
 | 
			
		||||
    <device id="retina6_12" orientation="portrait" appearance="light"/>
 | 
			
		||||
    <dependencies>
 | 
			
		||||
        <deployment identifier="iOS"/>
 | 
			
		||||
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
 | 
			
		||||
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
 | 
			
		||||
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
    <scenes>
 | 
			
		||||
        <!--Flutter View Controller-->
 | 
			
		||||
@@ -14,13 +16,14 @@
 | 
			
		||||
                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
 | 
			
		||||
                    </layoutGuides>
 | 
			
		||||
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
 | 
			
		||||
                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
 | 
			
		||||
                        <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
 | 
			
		||||
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
 | 
			
		||||
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
 | 
			
		||||
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
 | 
			
		||||
                    </view>
 | 
			
		||||
                </viewController>
 | 
			
		||||
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
 | 
			
		||||
            </objects>
 | 
			
		||||
            <point key="canvasLocation" x="-26" y="-76"/>
 | 
			
		||||
        </scene>
 | 
			
		||||
    </scenes>
 | 
			
		||||
</document>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										200
									
								
								ios/Runner/Views/VideoPlayerView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								ios/Runner/Views/VideoPlayerView.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,200 @@
 | 
			
		||||
import Flutter
 | 
			
		||||
import UIKit
 | 
			
		||||
import AVKit
 | 
			
		||||
 | 
			
		||||
// Factory to create the native video player view
 | 
			
		||||
class VideoPlayerViewFactory: NSObject, FlutterPlatformViewFactory {
 | 
			
		||||
    private var messenger: FlutterBinaryMessenger
 | 
			
		||||
 | 
			
		||||
    init(messenger: FlutterBinaryMessenger) {
 | 
			
		||||
        self.messenger = messenger
 | 
			
		||||
        super.init()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func create(
 | 
			
		||||
        withFrame frame: CGRect,
 | 
			
		||||
        viewIdentifier viewId: Int64,
 | 
			
		||||
        arguments args: Any?
 | 
			
		||||
    ) -> FlutterPlatformView {
 | 
			
		||||
        return VideoPlayerView(
 | 
			
		||||
            frame: frame,
 | 
			
		||||
            viewIdentifier: viewId,
 | 
			
		||||
            arguments: args,
 | 
			
		||||
            binaryMessenger: messenger)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This is required by the protocol, but we don't need to implement it for this case
 | 
			
		||||
    public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
 | 
			
		||||
        return FlutterStandardMessageCodec.sharedInstance()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The actual PlatformView that holds the AVPlayerViewController
 | 
			
		||||
class VideoPlayerView: NSObject, FlutterPlatformView {
 | 
			
		||||
    private var playerViewController: AVPlayerViewController?
 | 
			
		||||
    private var player: AVPlayer?
 | 
			
		||||
    private var activityIndicator: UIActivityIndicatorView!
 | 
			
		||||
    private var progressLabel: UILabel!
 | 
			
		||||
    private var progressStack: UIStackView!
 | 
			
		||||
 | 
			
		||||
    // KVO contexts
 | 
			
		||||
    private var playerStatusContext = 0
 | 
			
		||||
    private var playerLoadedTimeRangesContext = 0
 | 
			
		||||
 | 
			
		||||
    init(
 | 
			
		||||
        frame: CGRect,
 | 
			
		||||
        viewIdentifier viewId: Int64,
 | 
			
		||||
        arguments args: Any?,
 | 
			
		||||
        binaryMessenger messenger: FlutterBinaryMessenger?
 | 
			
		||||
    ) {
 | 
			
		||||
        super.init()
 | 
			
		||||
 | 
			
		||||
        // Ensure we have a valid URL from Flutter
 | 
			
		||||
        guard let args = args as? [String: Any],
 | 
			
		||||
              let videoUrlString = args["videoUrl"] as? String,
 | 
			
		||||
              let videoUrl = URL(string: videoUrlString) else {
 | 
			
		||||
            // Initialize playerViewController even if URL is invalid
 | 
			
		||||
            playerViewController = AVPlayerViewController()
 | 
			
		||||
            playerViewController!.showsPlaybackControls = false // Hide controls for invalid URL
 | 
			
		||||
 | 
			
		||||
            let label = UILabel()
 | 
			
		||||
            label.text = "Invalid video URL"
 | 
			
		||||
            label.textAlignment = .center
 | 
			
		||||
            label.textColor = .white
 | 
			
		||||
            label.translatesAutoresizingMaskIntoConstraints = false
 | 
			
		||||
            playerViewController!.contentOverlayView?.addSubview(label)
 | 
			
		||||
            
 | 
			
		||||
            NSLayoutConstraint.activate([
 | 
			
		||||
                label.centerXAnchor.constraint(equalTo: playerViewController!.contentOverlayView!.centerXAnchor),
 | 
			
		||||
                label.centerYAnchor.constraint(equalTo: playerViewController!.contentOverlayView!.centerYAnchor)
 | 
			
		||||
            ])
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // --- Player ---
 | 
			
		||||
        player = AVPlayer(url: videoUrl)
 | 
			
		||||
 | 
			
		||||
        // --- PlayerViewController ---
 | 
			
		||||
        playerViewController = AVPlayerViewController()
 | 
			
		||||
        playerViewController!.player = player
 | 
			
		||||
        playerViewController!.view.frame = frame // Set the frame directly
 | 
			
		||||
        playerViewController!.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 | 
			
		||||
        playerViewController!.showsPlaybackControls = true
 | 
			
		||||
        
 | 
			
		||||
        // --- Loading Indicator (spinner) ---
 | 
			
		||||
        activityIndicator = UIActivityIndicatorView(style: .large)
 | 
			
		||||
        activityIndicator.color = .white
 | 
			
		||||
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
 | 
			
		||||
        activityIndicator.isUserInteractionEnabled = false // Allow touches to pass through
 | 
			
		||||
 | 
			
		||||
        // --- Progress Percentage Label ---
 | 
			
		||||
        progressLabel = UILabel()
 | 
			
		||||
        progressLabel.textColor = .white
 | 
			
		||||
        progressLabel.textAlignment = .center
 | 
			
		||||
        progressLabel.translatesAutoresizingMaskIntoConstraints = false
 | 
			
		||||
        progressLabel.isUserInteractionEnabled = false // Allow touches to pass through
 | 
			
		||||
 | 
			
		||||
        playerViewController!.contentOverlayView?.addSubview(activityIndicator)
 | 
			
		||||
        playerViewController!.contentOverlayView?.addSubview(progressLabel)
 | 
			
		||||
        
 | 
			
		||||
        // Center the activity indicator and place the progress label below it
 | 
			
		||||
        NSLayoutConstraint.activate([
 | 
			
		||||
            activityIndicator.centerXAnchor.constraint(equalTo: playerViewController!.contentOverlayView!.centerXAnchor),
 | 
			
		||||
            activityIndicator.centerYAnchor.constraint(equalTo: playerViewController!.contentOverlayView!.centerYAnchor),
 | 
			
		||||
 | 
			
		||||
            progressLabel.topAnchor.constraint(equalTo: activityIndicator.bottomAnchor, constant: 16),
 | 
			
		||||
            progressLabel.centerXAnchor.constraint(equalTo: playerViewController!.contentOverlayView!.centerXAnchor),
 | 
			
		||||
        ])
 | 
			
		||||
 | 
			
		||||
        // Add Key-Value Observers
 | 
			
		||||
        addObservers()
 | 
			
		||||
 | 
			
		||||
        activityIndicator.startAnimating()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func view() -> UIView {
 | 
			
		||||
        return playerViewController!.view
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func addObservers() {
 | 
			
		||||
        player?.addObserver(self, forKeyPath: #keyPath(AVPlayer.status), options: [.new, .initial], context: &playerStatusContext)
 | 
			
		||||
        player?.currentItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.loadedTimeRanges), options: [.new], context: &playerLoadedTimeRangesContext)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func removeObservers() {
 | 
			
		||||
        // Check if observers are registered before removing them to avoid crashes.
 | 
			
		||||
        // A simple way is to use a flag or check the player object, but for KVO,
 | 
			
		||||
        // it's often safer to just ensure they are added once and removed once.
 | 
			
		||||
        // Given the lifecycle here, direct removal in deinit is okay.
 | 
			
		||||
        player?.removeObserver(self, forKeyPath: #keyPath(AVPlayer.status), context: &playerStatusContext)
 | 
			
		||||
        player?.currentItem?.removeObserver(self, forKeyPath: #keyPath(AVPlayerItem.loadedTimeRanges), context: &playerLoadedTimeRangesContext)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
 | 
			
		||||
        // Dispatch to main queue to ensure thread safety
 | 
			
		||||
        DispatchQueue.main.async {
 | 
			
		||||
            guard self.player != nil else {
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if context == &self.playerStatusContext {
 | 
			
		||||
                self.handlePlayerStatusChange(change: change)
 | 
			
		||||
            } else if context == &self.playerLoadedTimeRangesContext {
 | 
			
		||||
                self.handleLoadedTimeRangesChange()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func handlePlayerStatusChange(change: [NSKeyValueChangeKey : Any]?) {
 | 
			
		||||
        guard let statusValue = change?[.newKey] as? Int, let status = AVPlayer.Status(rawValue: statusValue) else { return }
 | 
			
		||||
        
 | 
			
		||||
        DispatchQueue.main.async {
 | 
			
		||||
            switch status {
 | 
			
		||||
            case .readyToPlay:
 | 
			
		||||
                self.activityIndicator.stopAnimating()
 | 
			
		||||
                self.progressLabel.isHidden = true
 | 
			
		||||
                self.player?.play()
 | 
			
		||||
            case .failed:
 | 
			
		||||
                self.activityIndicator.stopAnimating()
 | 
			
		||||
                // Optionally: show an error message to the user
 | 
			
		||||
                let label = UILabel()
 | 
			
		||||
                label.text = "Failed to load video"
 | 
			
		||||
                label.textColor = .white
 | 
			
		||||
                label.textAlignment = .center
 | 
			
		||||
                label.frame = self.playerViewController!.view.bounds
 | 
			
		||||
                self.playerViewController!.view.addSubview(label)
 | 
			
		||||
            case .unknown:
 | 
			
		||||
                self.activityIndicator.startAnimating()
 | 
			
		||||
            @unknown default:
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func handleLoadedTimeRangesChange() {
 | 
			
		||||
        guard let playerItem = player?.currentItem,
 | 
			
		||||
              let timeRange = playerItem.loadedTimeRanges.first?.timeRangeValue,
 | 
			
		||||
              !CMTIME_IS_INDEFINITE(playerItem.duration) else {
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let startSeconds = CMTimeGetSeconds(timeRange.start)
 | 
			
		||||
        let durationSeconds = CMTimeGetSeconds(timeRange.duration)
 | 
			
		||||
        let totalBuffer = startSeconds + durationSeconds
 | 
			
		||||
        let totalDuration = CMTimeGetSeconds(playerItem.duration)
 | 
			
		||||
        
 | 
			
		||||
        let progress = Float(totalBuffer / totalDuration)
 | 
			
		||||
        
 | 
			
		||||
        DispatchQueue.main.async {
 | 
			
		||||
            self.progressLabel.text = "\(Int(progress * 100))%"
 | 
			
		||||
 | 
			
		||||
            if progress >= 0.99 {
 | 
			
		||||
                self.progressLabel.isHidden = true
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    deinit {
 | 
			
		||||
        removeObservers()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -29,9 +29,12 @@ class AttachmentPreview extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    var ratio =
 | 
			
		||||
        (item.isOnCloud ? (item.data.fileMeta?['ratio'] ?? 1) : 1).toDouble();
 | 
			
		||||
    if (ratio == 0) ratio = 1.0;
 | 
			
		||||
 | 
			
		||||
    return AspectRatio(
 | 
			
		||||
      aspectRatio:
 | 
			
		||||
          (item.isOnCloud ? (item.data.fileMeta?['ratio'] ?? 1) : 1).toDouble(),
 | 
			
		||||
      aspectRatio: ratio,
 | 
			
		||||
      child: ClipRRect(
 | 
			
		||||
        borderRadius: BorderRadius.circular(8),
 | 
			
		||||
        child: Stack(
 | 
			
		||||
 
 | 
			
		||||
@@ -37,13 +37,10 @@ class CloudFileList extends HookConsumerWidget {
 | 
			
		||||
 | 
			
		||||
  double calculateAspectRatio() {
 | 
			
		||||
    double total = 0;
 | 
			
		||||
    for (var ratio in files.map(
 | 
			
		||||
      (e) =>
 | 
			
		||||
          e.fileMeta?['ratio'] ??
 | 
			
		||||
          ((e.mimeType?.startsWith('image') ?? false) ? 1 : 16 / 9),
 | 
			
		||||
    )) {
 | 
			
		||||
    for (var ratio in files.map((e) => e.fileMeta?['ratio'] ?? 1)) {
 | 
			
		||||
      total += ratio;
 | 
			
		||||
    }
 | 
			
		||||
    if (total == 0) return 1;
 | 
			
		||||
    return total / files.length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,20 +27,19 @@ class CloudFileWidget extends ConsumerWidget {
 | 
			
		||||
    final serverUrl = ref.watch(serverUrlProvider);
 | 
			
		||||
    final uri = '$serverUrl/api/files/${item.id}';
 | 
			
		||||
 | 
			
		||||
    var ratio = (item.fileMeta?['ratio'] ?? 1).toDouble();
 | 
			
		||||
    if (ratio == 0) ratio = 1.0;
 | 
			
		||||
    final content = switch (item.mimeType?.split('/').firstOrNull) {
 | 
			
		||||
      "image" => AspectRatio(
 | 
			
		||||
        aspectRatio: (item.fileMeta?['ratio'] ?? 1).toDouble(),
 | 
			
		||||
        aspectRatio: ratio,
 | 
			
		||||
        child: UniversalImage(
 | 
			
		||||
          uri: uri,
 | 
			
		||||
          blurHash: noBlurhash ? null : item.fileMeta?['blur'],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
      "video" => AspectRatio(
 | 
			
		||||
        aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(),
 | 
			
		||||
        child: UniversalVideo(
 | 
			
		||||
          uri: uri,
 | 
			
		||||
          aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(),
 | 
			
		||||
        ),
 | 
			
		||||
        aspectRatio: ratio,
 | 
			
		||||
        child: UniversalVideo(uri: uri, aspectRatio: ratio),
 | 
			
		||||
      ),
 | 
			
		||||
      _ => Text('Unable render for ${item.mimeType}'),
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ class _UniversalVideoState extends ConsumerState<UniversalVideo> {
 | 
			
		||||
 | 
			
		||||
    return Video(
 | 
			
		||||
      controller: _videoController!,
 | 
			
		||||
      aspectRatio: widget.aspectRatio,
 | 
			
		||||
      aspectRatio: widget.aspectRatio != 1 ? widget.aspectRatio : null,
 | 
			
		||||
      controls:
 | 
			
		||||
          !kIsWeb && (Platform.isAndroid || Platform.isIOS)
 | 
			
		||||
              ? MaterialVideoControls
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
 | 
			
		||||
  GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
 | 
			
		||||
  IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin"))
 | 
			
		||||
  LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin"))
 | 
			
		||||
  FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin"))
 | 
			
		||||
  LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin"))
 | 
			
		||||
  MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
 | 
			
		||||
  MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
 | 
			
		||||
  FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,10 @@ PODS:
 | 
			
		||||
  - Firebase/Messaging (11.15.0):
 | 
			
		||||
    - Firebase/CoreOnly
 | 
			
		||||
    - FirebaseMessaging (~> 11.15.0)
 | 
			
		||||
  - firebase_core (3.15.0):
 | 
			
		||||
  - firebase_core (3.15.1):
 | 
			
		||||
    - Firebase/CoreOnly (~> 11.15.0)
 | 
			
		||||
    - FlutterMacOS
 | 
			
		||||
  - firebase_messaging (15.2.8):
 | 
			
		||||
  - firebase_messaging (15.2.9):
 | 
			
		||||
    - Firebase/CoreOnly (~> 11.15.0)
 | 
			
		||||
    - Firebase/Messaging (~> 11.15.0)
 | 
			
		||||
    - firebase_core
 | 
			
		||||
@@ -292,8 +292,8 @@ SPEC CHECKSUMS:
 | 
			
		||||
  file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
 | 
			
		||||
  file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
 | 
			
		||||
  Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
 | 
			
		||||
  firebase_core: 177f51be1650b15d2d5b9f1abf48792619288070
 | 
			
		||||
  firebase_messaging: 8748a5d4bb435993cffa7f5501292f3e914a23d7
 | 
			
		||||
  firebase_core: 8dc569d17b3a9fc3ee5ebc21b322411b4a796833
 | 
			
		||||
  firebase_messaging: adaf7fc22897a7aa49410d15f8a595bef2dbca2d
 | 
			
		||||
  FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
 | 
			
		||||
  FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
 | 
			
		||||
  FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
 | 
			
		||||
@@ -310,7 +310,7 @@ SPEC CHECKSUMS:
 | 
			
		||||
  GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
 | 
			
		||||
  irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba
 | 
			
		||||
  livekit_client: c9d9f41996f5cf22b9ba0e8483e6af4ca5094059
 | 
			
		||||
  local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
 | 
			
		||||
  local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
 | 
			
		||||
  media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65
 | 
			
		||||
  media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
 | 
			
		||||
  nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -13,10 +13,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: _flutterfire_internals
 | 
			
		||||
      sha256: "50e24b769bd1e725732f0aff18b806b8731c1fbcf4e8018ab98e7c4805a2a52f"
 | 
			
		||||
      sha256: a5788040810bd84400bc209913fbc40f388cded7cdf95ee2f5d2bff7e38d5241
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.3.57"
 | 
			
		||||
    version: "1.3.58"
 | 
			
		||||
  analyzer:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -349,10 +349,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: coverage
 | 
			
		||||
      sha256: aa07dbe5f2294c827b7edb9a87bba44a9c15a3cc81bc8da2ca19b37322d30080
 | 
			
		||||
      sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.14.1"
 | 
			
		||||
    version: "1.15.0"
 | 
			
		||||
  croppy:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@@ -629,50 +629,50 @@ packages:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: firebase_core
 | 
			
		||||
      sha256: "5bba5924139e91d26446fd2601c18a6aa62c1161c768a989bb5e245dcdc20644"
 | 
			
		||||
      sha256: c6e8a6bf883d8ddd0dec39be90872daca65beaa6f4cff0051ed3b16c56b82e9f
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.15.0"
 | 
			
		||||
    version: "3.15.1"
 | 
			
		||||
  firebase_core_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: firebase_core_platform_interface
 | 
			
		||||
      sha256: "5d2ab45779d91af2aa0252dec9fe4ee1caa015d83377de255454dcaa1526a0e0"
 | 
			
		||||
      sha256: "5dbc900677dcbe5873d22ad7fbd64b047750124f1f9b7ebe2a33b9ddccc838eb"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "5.4.1"
 | 
			
		||||
    version: "6.0.0"
 | 
			
		||||
  firebase_core_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: firebase_core_web
 | 
			
		||||
      sha256: eb3afccfc452b2b2075acbe0c4b27de62dd596802b4e5e19869c1e926cbb20b3
 | 
			
		||||
      sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.24.0"
 | 
			
		||||
    version: "2.24.1"
 | 
			
		||||
  firebase_messaging:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: firebase_messaging
 | 
			
		||||
      sha256: c6711cf2f455532b84a94022c7aaf85088849763af2f01b775ca79d82d10a01a
 | 
			
		||||
      sha256: "0f3363f97672eb9f65609fa00ed2f62cc8ec93e7e2d4def99726f9165d3d8a73"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "15.2.8"
 | 
			
		||||
    version: "15.2.9"
 | 
			
		||||
  firebase_messaging_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: firebase_messaging_platform_interface
 | 
			
		||||
      sha256: "1c9dacccb1aee1bf17ba519dda5563a16fdd2ec1e79b5f2e421cb4bf75a166f7"
 | 
			
		||||
      sha256: "7a05ef119a14c5f6a9440d1e0223bcba20c8daf555450e119c4c477bf2c3baa9"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.6.8"
 | 
			
		||||
    version: "4.6.9"
 | 
			
		||||
  firebase_messaging_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: firebase_messaging_web
 | 
			
		||||
      sha256: "54317c26fa92f0d90a2017977ac791cb0504eca29fcf397f06adf727d4a7a2d5"
 | 
			
		||||
      sha256: a4547f76da2a905190f899eb4d0150e1d0fd52206fce469d9f05ae15bb68b2c5
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.10.8"
 | 
			
		||||
    version: "3.10.9"
 | 
			
		||||
  fixnum:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -1049,18 +1049,18 @@ packages:
 | 
			
		||||
    dependency: "direct dev"
 | 
			
		||||
    description:
 | 
			
		||||
      name: freezed
 | 
			
		||||
      sha256: "6022db4c7bfa626841b2a10f34dd1e1b68e8f8f9650db6112dcdeeca45ca793c"
 | 
			
		||||
      sha256: "2d399f823b8849663744d2a9ddcce01c49268fb4170d0442a655bf6a2f47be22"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.6"
 | 
			
		||||
    version: "3.1.0"
 | 
			
		||||
  freezed_annotation:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: freezed_annotation
 | 
			
		||||
      sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b
 | 
			
		||||
      sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.0"
 | 
			
		||||
    version: "3.1.0"
 | 
			
		||||
  frontend_server_client:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -1385,10 +1385,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: local_auth_darwin
 | 
			
		||||
      sha256: "630996cd7b7f28f5ab92432c4b35d055dd03a747bc319e5ffbb3c4806a3e50d2"
 | 
			
		||||
      sha256: "25163ce60a5a6c468cf7a0e3dc8a165f824cabc2aa9e39a5e9fc5c2311b7686f"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.4.3"
 | 
			
		||||
    version: "1.5.0"
 | 
			
		||||
  local_auth_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -2174,10 +2174,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: source_helper
 | 
			
		||||
      sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
 | 
			
		||||
      sha256: "4f81479fe5194a622cdd1713fe1ecb683a6e6c85cd8cec8e2e35ee5ab3fdf2a1"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.3.5"
 | 
			
		||||
    version: "1.3.6"
 | 
			
		||||
  source_map_stack_trace:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
 | 
			
		||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 | 
			
		||||
# In Windows, build-name is used as the major, minor, and patch parts
 | 
			
		||||
# of the product and file versions while build-number is used as the build suffix.
 | 
			
		||||
version: 3.0.0+112
 | 
			
		||||
version: 3.1.0+113
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
  sdk: ^3.7.2
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user