From 36905e0cd5d27dd88861b3cb1f64ab5f0390f724 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Wed, 23 Apr 2025 00:07:20 +0800 Subject: [PATCH] :sparkles: Attachment rendering --- ios/Podfile.lock | 42 +++- ios/Runner.xcodeproj/project.pbxproj | 10 +- ios/Runner/AppDelegate.swift | 7 +- lib/widgets/alert.dart | 10 + .../content/cloud_file_collection.dart | 81 +++++++ lib/widgets/content/cloud_files.dart | 36 ++- lib/widgets/content/image.native.dart | 39 ++-- lib/widgets/content/image.web.dart | 15 +- lib/widgets/content/video.native.dart | 107 +++++---- lib/widgets/content/video.web.dart | 12 +- lib/widgets/post/post_item.dart | 12 +- linux/flutter/generated_plugin_registrant.cc | 12 + linux/flutter/generated_plugins.cmake | 3 + macos/Flutter/GeneratedPluginRegistrant.swift | 12 + pubspec.lock | 210 +++++++++++++++++- pubspec.yaml | 8 +- .../flutter/generated_plugin_registrant.cc | 12 + windows/flutter/generated_plugins.cmake | 4 + 18 files changed, 519 insertions(+), 113 deletions(-) create mode 100644 lib/widgets/alert.dart create mode 100644 lib/widgets/content/cloud_file_collection.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 87ad3ea..3ccaaeb 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,7 +1,13 @@ PODS: - Flutter (1.0.0) + - flutter_platform_alert (0.0.1): + - Flutter - Kingfisher (8.3.1) - - native_video_player (1.0.0): + - media_kit_libs_ios_video (1.0.4): + - Flutter + - media_kit_video (0.0.1): + - Flutter + - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): - Flutter @@ -14,15 +20,24 @@ PODS: - FlutterMacOS - url_launcher_ios (0.0.1): - Flutter + - volume_controller (0.0.1): + - Flutter + - wakelock_plus (0.0.1): + - Flutter DEPENDENCIES: - Flutter (from `Flutter`) + - flutter_platform_alert (from `.symlinks/plugins/flutter_platform_alert/ios`) - Kingfisher (~> 8.0) - - native_video_player (from `.symlinks/plugins/native_video_player/ios`) + - media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`) + - media_kit_video (from `.symlinks/plugins/media_kit_video/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - volume_controller (from `.symlinks/plugins/volume_controller/ios`) + - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) SPEC REPOS: trunk: @@ -31,8 +46,14 @@ SPEC REPOS: EXTERNAL SOURCES: Flutter: :path: Flutter - native_video_player: - :path: ".symlinks/plugins/native_video_player/ios" + flutter_platform_alert: + :path: ".symlinks/plugins/flutter_platform_alert/ios" + media_kit_libs_ios_video: + :path: ".symlinks/plugins/media_kit_libs_ios_video/ios" + media_kit_video: + :path: ".symlinks/plugins/media_kit_video/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" shared_preferences_foundation: @@ -41,16 +62,25 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqflite_darwin/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" + volume_controller: + :path: ".symlinks/plugins/volume_controller/ios" + wakelock_plus: + :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_platform_alert: bf3b5fcd4ac14bd637e20527e9c471633071afd3 Kingfisher: 3204d23de16b5ea53541c44ca5a8efb55741dec3 - native_video_player: e363dd14f6a498ad8a8f7e6486a0db046ad19f13 + media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854 + media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474 + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 url_launcher_ios: 694010445543906933d732453a59da0a173ae33d + volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12 + wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 -PODFILE CHECKSUM: b9d63df345d0c6f260ddc467a83ae5f9c8a6cd6f +PODFILE CHECKSUM: 4c3fad73fbbc9053a824d880097bda7884240991 COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ed3f311..146020e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 70; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -68,10 +68,6 @@ F6D834CA86410B09796B312B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ -/* Begin PBXFileSystemSynchronizedRootGroup section */ - 737E91D52DB6866B00BE9CDB /* NativeViews */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = NativeViews; sourceTree = ""; }; -/* End PBXFileSystemSynchronizedRootGroup section */ - /* Begin PBXFrameworksBuildPhase section */ 1DFF8FEBBD0CF5A990600776 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -158,7 +154,6 @@ isa = PBXGroup; children = ( 737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */, - 737E91D52DB6866B00BE9CDB /* NativeViews */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -210,9 +205,6 @@ ); dependencies = ( ); - fileSystemSynchronizedGroups = ( - 737E91D52DB6866B00BE9CDB /* NativeViews */, - ); name = Runner; productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index c3c2bdb..1fe35f8 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -7,12 +7,7 @@ import UIKit _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - - guard let pluginRegistrar = self.registrar(forPlugin: "plugin-name") else { return false } - - pluginRegistrar.register(FLNativeImageFactory(messenger: pluginRegistrar.messenger()), withId: "native-image") - + GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } diff --git a/lib/widgets/alert.dart b/lib/widgets/alert.dart new file mode 100644 index 0000000..9d29652 --- /dev/null +++ b/lib/widgets/alert.dart @@ -0,0 +1,10 @@ +import 'package:flutter_platform_alert/flutter_platform_alert.dart'; + +void showErrorAlert(dynamic err) async { + FlutterPlatformAlert.showAlert( + windowTitle: 'Something went wrong...', + text: err.toString(), + alertStyle: AlertButtonStyle.ok, + iconStyle: IconStyle.error, + ); +} diff --git a/lib/widgets/content/cloud_file_collection.dart b/lib/widgets/content/cloud_file_collection.dart new file mode 100644 index 0000000..36ed8f6 --- /dev/null +++ b/lib/widgets/content/cloud_file_collection.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:island/models/file.dart'; +import 'package:island/widgets/content/cloud_files.dart'; +import 'package:styled_widget/styled_widget.dart'; + +class CloudFileList extends StatelessWidget { + final List files; + final double maxHeight; + const CloudFileList({super.key, required this.files, this.maxHeight = 360}); + + double calculateAspectRatio() { + double total = 0; + for (var ratio in files.map( + (e) => + e.fileMeta?['ratio'] ?? + ((e.mimeType?.startsWith('image') ?? false) ? 1 : 16 / 9), + )) { + total += ratio; + } + return total / files.length; + } + + @override + Widget build(BuildContext context) { + if (files.isEmpty) return const SizedBox.shrink(); + if (files.length == 1) { + return ConstrainedBox( + constraints: BoxConstraints(maxHeight: maxHeight), + child: AspectRatio( + aspectRatio: calculateAspectRatio(), + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(16)), + child: CloudFileWidget(item: files.first), + ), + ), + ).padding(horizontal: 3); + } + + final allImages = + !files.any( + (e) => e.mimeType == null || !e.mimeType!.startsWith('image'), + ); + + if (allImages) { + return ConstrainedBox( + constraints: BoxConstraints(maxHeight: maxHeight), + child: AspectRatio( + aspectRatio: calculateAspectRatio(), + child: CarouselView( + itemExtent: MediaQuery.of(context).size.width * 0.85, + itemSnapping: true, + shape: RoundedRectangleBorder( + borderRadius: const BorderRadius.all(Radius.circular(16)), + ), + children: [for (final item in files) CloudFileWidget(item: item)], + ), + ), + ); + } + + return ConstrainedBox( + constraints: BoxConstraints(maxHeight: maxHeight), + child: AspectRatio( + aspectRatio: calculateAspectRatio(), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: files.length, + padding: EdgeInsets.symmetric(horizontal: 3), + itemBuilder: (context, index) { + return ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(16)), + child: CloudFileWidget(item: files[index]), + ); + }, + separatorBuilder: (_, __) => const Gap(8), + ), + ), + ); + } +} diff --git a/lib/widgets/content/cloud_files.dart b/lib/widgets/content/cloud_files.dart index d439e06..828d15d 100644 --- a/lib/widgets/content/cloud_files.dart +++ b/lib/widgets/content/cloud_files.dart @@ -2,13 +2,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:island/models/file.dart'; import 'package:island/pods/config.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'image.dart'; import 'video.dart'; class CloudFileWidget extends ConsumerWidget { final SnCloudFile item; - const CloudFileWidget({super.key, required this.item}); + final BoxFit fit; + const CloudFileWidget({ + super.key, + required this.item, + this.fit = BoxFit.cover, + }); @override Widget build(BuildContext context, WidgetRef ref) { @@ -23,10 +29,36 @@ class CloudFileWidget extends ConsumerWidget { case "video": return AspectRatio( aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(), - child: UniversalVideo(uri: uri), + child: UniversalVideo( + uri: uri, + aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(), + ), ); default: return Placeholder(); } } } + +class ProfilePictureWidget extends ConsumerWidget { + final SnCloudFile? item; + final double radius; + const ProfilePictureWidget({super.key, required this.item, this.radius = 24}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + if (item == null) return const SizedBox.shrink(); + return ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(radius)), + child: Container( + width: radius * 2, + height: radius * 2, + color: Theme.of(context).colorScheme.primaryContainer, + child: + item == null + ? Icon(MdiIcons.account) + : CloudFileWidget(item: item!), + ), + ); + } +} diff --git a/lib/widgets/content/image.native.dart b/lib/widgets/content/image.native.dart index 29e540d..575554d 100644 --- a/lib/widgets/content/image.native.dart +++ b/lib/widgets/content/image.native.dart @@ -1,33 +1,26 @@ -import 'dart:io'; - -import 'package:flutter/services.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_blurhash/flutter_blurhash.dart'; class UniversalImage extends StatelessWidget { final String uri; final String? blurHash; - const UniversalImage({super.key, required this.uri, this.blurHash}); + final BoxFit fit; + const UniversalImage({ + super.key, + required this.uri, + this.blurHash, + this.fit = BoxFit.cover, + }); @override Widget build(BuildContext context) { - final params = {'src': uri, 'blur': blurHash}; - if (Platform.isAndroid) { - return AndroidView( - viewType: 'native-image', - layoutDirection: TextDirection.ltr, - creationParams: params, - creationParamsCodec: const StandardMessageCodec(), - ); - } - if (Platform.isIOS) { - // For iOS: Use UiKitView to embed a native iOS image view - return UiKitView( - viewType: 'native-image', - layoutDirection: TextDirection.ltr, - creationParams: params, - creationParamsCodec: const StandardMessageCodec(), - ); - } - return Image.network(uri); + return Stack( + fit: StackFit.expand, + children: [ + if (blurHash != null) BlurHash(hash: blurHash!), + CachedNetworkImage(imageUrl: uri, fit: fit), + ], + ); } } diff --git a/lib/widgets/content/image.web.dart b/lib/widgets/content/image.web.dart index 2b45f3a..5cacb2a 100644 --- a/lib/widgets/content/image.web.dart +++ b/lib/widgets/content/image.web.dart @@ -3,15 +3,18 @@ import 'package:flutter/material.dart'; class UniversalImage extends StatelessWidget { final String uri; - const UniversalImage({super.key, required this.uri}); + final String? blurHash; + const UniversalImage({super.key, required this.uri, this.blurHash}); @override Widget build(BuildContext context) { - return HtmlElementView( - viewType: 'native-image', - onPlatformViewCreated: (int viewId) { - final element = web.HTMLImageElement()..src = uri; - web.document.body!.append(element); + return HtmlElementView.fromTagName( + tagName: 'img', + onElementCreated: (element) { + element as web.HTMLImageElement; + element.src = uri; + element.style.width = '100%'; + element.style.height = '100%'; }, ); } diff --git a/lib/widgets/content/video.native.dart b/lib/widgets/content/video.native.dart index 738e71b..9236df7 100644 --- a/lib/widgets/content/video.native.dart +++ b/lib/widgets/content/video.native.dart @@ -1,65 +1,88 @@ +import 'dart:developer'; import 'dart:io'; - +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:native_video_player/native_video_player.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:island/widgets/alert.dart'; +import 'package:media_kit/media_kit.dart'; +import 'package:media_kit_video/media_kit_video.dart'; class UniversalVideo extends StatefulWidget { final String uri; - const UniversalVideo({super.key, required this.uri}); + final double aspectRatio; + const UniversalVideo({ + super.key, + required this.uri, + this.aspectRatio = 16 / 9, + }); @override State createState() => _UniversalVideoState(); } class _UniversalVideoState extends State { - NativeVideoPlayerController? _controller; - bool _isPlaying = false; + Player? _player; + VideoController? _videoController; - Future _togglePlayback() async { - final controller = _controller; - if (controller == null) return; + void _openVideo() async { + final url = widget.uri; + MediaKit.ensureInitialized(); - if (_isPlaying) { - await controller.pause(); + _player = Player(); + _videoController = VideoController(_player!); + + String? uri; + final inCacheInfo = await DefaultCacheManager().getFileFromCache(url); + if (inCacheInfo == null) { + log('[MediaPlayer] Miss cache: $url'); + final fileStream = DefaultCacheManager().getFileStream( + url, + // headers: {'Authorization': 'Bearer ${await ua.atk}'}, + withProgress: true, + ); + await for (var fileInfo in fileStream) { + if (fileInfo is FileInfo) { + uri = fileInfo.file.path; + break; + } + } } else { - await controller.play(); + uri = inCacheInfo.file.path; + log('[MediaPlayer] Hit cache: $url'); + } + if (uri == null) { + showErrorAlert('Failed to open media... $url'); + return; } - final isPlaying = await controller.isPlaying(); - setState(() { - _isPlaying = isPlaying; - }); + _player!.open(Media(uri)); + } + + @override + void initState() { + super.initState(); + _openVideo(); + } + + @override + void dispose() { + super.dispose(); + _player?.dispose(); } @override Widget build(BuildContext context) { - if (Platform.isAndroid || Platform.isIOS) { - return Stack( - children: [ - NativeVideoPlayerView( - onViewReady: (controller) async { - _controller = controller; - await controller.loadVideo( - VideoSource(path: widget.uri, type: VideoSourceType.network), - ); - }, - ), - Material( - type: MaterialType.transparency, - child: InkWell( - onTap: _togglePlayback, - child: Center( - child: Icon( - _isPlaying ? Icons.pause : Icons.play_arrow, - size: 64, - color: Colors.white, - ), - ), - ), - ), - ], - ); + if (_videoController == null) { + return Center(child: CircularProgressIndicator()); } - return Image.network(widget.uri); + + return Video( + controller: _videoController!, + aspectRatio: widget.aspectRatio, + controls: + !kIsWeb && (Platform.isAndroid || Platform.isIOS) + ? MaterialVideoControls + : MaterialDesktopVideoControls, + ); } } diff --git a/lib/widgets/content/video.web.dart b/lib/widgets/content/video.web.dart index dc311d7..6cf4233 100644 --- a/lib/widgets/content/video.web.dart +++ b/lib/widgets/content/video.web.dart @@ -7,12 +7,14 @@ class UniversalVideo extends StatelessWidget { @override Widget build(BuildContext context) { - return HtmlElementView( - viewType: 'native-video', - onPlatformViewCreated: (int viewId) { - final element = web.HTMLVideoElement()..src = uri; + return HtmlElementView.fromTagName( + tagName: 'video', + onElementCreated: (element) { + element as web.HTMLVideoElement; + element.src = uri; + element.style.width = '100%'; + element.style.height = '100%'; element.controls = true; - web.document.body!.append(element); }, ); } diff --git a/lib/widgets/post/post_item.dart b/lib/widgets/post/post_item.dart index 93cd21b..fa0d04f 100644 --- a/lib/widgets/post/post_item.dart +++ b/lib/widgets/post/post_item.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:island/models/post.dart'; +import 'package:island/widgets/content/cloud_file_collection.dart'; import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/markdown.dart'; import 'package:styled_widget/styled_widget.dart'; @@ -17,15 +18,18 @@ class PostItem extends StatelessWidget { return Padding( padding: renderingPadding, child: Column( + spacing: 8, children: [ Row( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 12, children: [ - // Avatar... + ProfilePictureWidget(item: item.publisher.picture), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(item.publisher.name).bold(), + Text(item.publisher.nick).bold(), if (item.content.isNotEmpty) MarkdownTextContent(content: item.content), ], @@ -33,8 +37,8 @@ class PostItem extends StatelessWidget { ), ], ), - for (final attachment in item.attachments) - CloudFileWidget(item: attachment), + if (item.attachments.isNotEmpty) + CloudFileList(files: item.attachments), ], ), ); diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index bb3345d..0623e53 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,12 +7,24 @@ #include "generated_plugin_registrant.h" #include +#include +#include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin"); bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar); + g_autoptr(FlPluginRegistrar) flutter_platform_alert_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterPlatformAlertPlugin"); + flutter_platform_alert_plugin_register_with_registrar(flutter_platform_alert_registrar); + g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin"); + media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar); + g_autoptr(FlPluginRegistrar) media_kit_video_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin"); + media_kit_video_plugin_register_with_registrar(media_kit_video_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 9674f4f..e552af4 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,9 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_linux + flutter_platform_alert + media_kit_libs_linux + media_kit_video url_launcher_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index a18a921..ca4aec5 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,15 +6,27 @@ import FlutterMacOS import Foundation import bitsdojo_window_macos +import flutter_platform_alert +import media_kit_libs_macos_video +import media_kit_video +import package_info_plus import path_provider_foundation import shared_preferences_foundation import sqflite_darwin import url_launcher_macos +import volume_controller +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) + FlutterPlatformAlertPlugin.register(with: registry.registrar(forPlugin: "FlutterPlatformAlertPlugin")) + MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin")) + MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 7fc0899..7af5626 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -17,6 +17,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.4.1" + archive: + dependency: transitive + description: + name: archive + sha256: a7f37ff061d7abc2fcf213554b9dcaca713c5853afa5c065c44888bc9ccaf813 + url: "https://pub.dev" + source: hosted + version: "4.0.6" args: dependency: transitive description: @@ -257,6 +265,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" dio: dependency: "direct main" description: @@ -310,8 +326,16 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_blurhash: + dependency: "direct main" + description: + name: flutter_blurhash + sha256: d472467141a279885be558335fe36a782e515f96cc5e372eee2c558ff2c2fb39 + url: "https://pub.dev" + source: hosted + version: "0.9.0" flutter_cache_manager: - dependency: transitive + dependency: "direct main" description: name: flutter_cache_manager sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" @@ -366,6 +390,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.3" + flutter_platform_alert: + dependency: "direct main" + description: + name: flutter_platform_alert + sha256: c4b509956346ce9666512b700354de4c6f8fdff94cd47c12368e4a6b1c25a02c + url: "https://pub.dev" + source: hosted + version: "0.7.0" flutter_riverpod: dependency: "direct main" description: @@ -488,6 +520,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + url: "https://pub.dev" + source: hosted + version: "4.5.4" io: dependency: transitive description: @@ -592,6 +632,78 @@ packages: url: "https://pub.dev" source: hosted version: "0.11.1" + material_design_icons_flutter: + dependency: "direct main" + description: + name: material_design_icons_flutter + sha256: "6f986b7a51f3ad4c00e33c5c84e8de1bdd140489bbcdc8b66fc1283dad4dea5a" + url: "https://pub.dev" + source: hosted + version: "7.0.7296" + media_kit: + dependency: "direct main" + description: + name: media_kit + sha256: "48c10c3785df5d88f0eef970743f8c99b2e5da2b34b9d8f9876e598f62d9e776" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + media_kit_libs_android_video: + dependency: transitive + description: + name: media_kit_libs_android_video + sha256: adff9b571b8ead0867f9f91070f8df39562078c0eb3371d88b9029a2d547d7b7 + url: "https://pub.dev" + source: hosted + version: "1.3.7" + media_kit_libs_ios_video: + dependency: transitive + description: + name: media_kit_libs_ios_video + sha256: b5382994eb37a4564c368386c154ad70ba0cc78dacdd3fb0cd9f30db6d837991 + url: "https://pub.dev" + source: hosted + version: "1.1.4" + media_kit_libs_linux: + dependency: transitive + description: + name: media_kit_libs_linux + sha256: "2b473399a49ec94452c4d4ae51cfc0f6585074398d74216092bf3d54aac37ecf" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + media_kit_libs_macos_video: + dependency: transitive + description: + name: media_kit_libs_macos_video + sha256: f26aa1452b665df288e360393758f84b911f70ffb3878032e1aabba23aa1032d + url: "https://pub.dev" + source: hosted + version: "1.1.4" + media_kit_libs_video: + dependency: "direct main" + description: + name: media_kit_libs_video + sha256: "958cc55e7065d9d01f52a2842dab2a0812a92add18489f1006d864fb5e42a3ef" + url: "https://pub.dev" + source: hosted + version: "1.0.6" + media_kit_libs_windows_video: + dependency: transitive + description: + name: media_kit_libs_windows_video + sha256: dff76da2778729ab650229e6b4ec6ec111eb5151431002cbd7ea304ff1f112ab + url: "https://pub.dev" + source: hosted + version: "1.0.11" + media_kit_video: + dependency: "direct main" + description: + name: media_kit_video + sha256: a656a9463298c1adc64c57f2d012874f7f2900f0c614d9545a3e7b8bb9e2137b + url: "https://pub.dev" + source: hosted + version: "1.3.0" meta: dependency: transitive description: @@ -608,14 +720,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - native_video_player: - dependency: "direct main" - description: - name: native_video_player - sha256: "64ac4086c50f13306c7ebca70372b2c2c67c063caae25f0c486dbec16d666e9a" - url: "https://pub.dev" - source: hosted - version: "3.0.0" nested: dependency: transitive description: @@ -640,6 +744,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" + url: "https://pub.dev" + source: hosted + version: "8.3.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" + url: "https://pub.dev" + source: hosted + version: "3.2.0" path: dependency: transitive description: @@ -736,6 +856,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62 + url: "https://pub.dev" + source: hosted + version: "6.0.2" provider: dependency: transitive description: @@ -784,6 +912,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.28.0" + safe_local_storage: + dependency: transitive + description: + name: safe_local_storage + sha256: e9a21b6fec7a8aa62cc2585ff4c1b127df42f3185adbd2aca66b47abe2e80236 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + screen_brightness_android: + dependency: transitive + description: + name: screen_brightness_android + sha256: "6ba1b5812f66c64e9e4892be2d36ecd34210f4e0da8bdec6a2ea34f1aa42683e" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + screen_brightness_platform_interface: + dependency: transitive + description: + name: screen_brightness_platform_interface + sha256: "737bd47b57746bc4291cab1b8a5843ee881af499514881b0247ec77447ee769c" + url: "https://pub.dev" + source: hosted + version: "2.1.0" shared_preferences: dependency: "direct main" description: @@ -1029,6 +1181,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + uri_parser: + dependency: transitive + description: + name: uri_parser + sha256: ff4d2c720aca3f4f7d5445e23b11b2d15ef8af5ddce5164643f38ff962dcb270 + url: "https://pub.dev" + source: hosted + version: "3.0.0" url_launcher: dependency: "direct main" description: @@ -1149,6 +1317,30 @@ packages: url: "https://pub.dev" source: hosted version: "14.3.1" + volume_controller: + dependency: transitive + description: + name: volume_controller + sha256: e82fd689bb8e1fe8e64be3fa5946ff8699058f8cf9f4c1679acdba20cda7f5bd + url: "https://pub.dev" + source: hosted + version: "3.3.3" + wakelock_plus: + dependency: transitive + description: + name: wakelock_plus + sha256: b6962cd9fc15e4843b573ba7b53bc46dd8a787594cf9ed5c5182581924656a58 + url: "https://pub.dev" + source: hosted + version: "1.3.1" + wakelock_plus_platform_interface: + dependency: transitive + description: + name: wakelock_plus_platform_interface + sha256: e10444072e50dbc4999d7316fd303f7ea53d31c824aa5eb05d7ccbdd98985207 + url: "https://pub.dev" + source: hosted + version: "1.2.3" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index cb8fad7..32ca5c6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -57,7 +57,13 @@ dependencies: gap: ^3.0.1 cached_network_image: ^3.4.1 web: ^1.1.1 - native_video_player: ^3.0.0 + flutter_blurhash: ^0.9.0 + media_kit: ^1.2.0 + media_kit_video: ^1.3.0 + media_kit_libs_video: ^1.0.6 + flutter_cache_manager: ^3.4.1 + flutter_platform_alert: ^0.7.0 + material_design_icons_flutter: ^7.0.7296 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 4ada1f5..2e98137 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,11 +7,23 @@ #include "generated_plugin_registrant.h" #include +#include +#include +#include #include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { BitsdojoWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); + FlutterPlatformAlertPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterPlatformAlertPlugin")); + MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi")); + MediaKitVideoPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); + VolumeControllerPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("VolumeControllerPluginCApi")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 72a37b6..39b5d23 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,7 +4,11 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_windows + flutter_platform_alert + media_kit_libs_windows_video + media_kit_video url_launcher_windows + volume_controller ) list(APPEND FLUTTER_FFI_PLUGIN_LIST