Attachment rendering

This commit is contained in:
LittleSheep 2025-04-23 00:07:20 +08:00
parent 8bb365c974
commit 36905e0cd5
18 changed files with 519 additions and 113 deletions

View File

@ -1,7 +1,13 @@
PODS: PODS:
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_platform_alert (0.0.1):
- Flutter
- Kingfisher (8.3.1) - 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 - Flutter
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
@ -14,15 +20,24 @@ PODS:
- FlutterMacOS - FlutterMacOS
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
- volume_controller (0.0.1):
- Flutter
- wakelock_plus (0.0.1):
- Flutter
DEPENDENCIES: DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_platform_alert (from `.symlinks/plugins/flutter_platform_alert/ios`)
- Kingfisher (~> 8.0) - 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`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - 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: SPEC REPOS:
trunk: trunk:
@ -31,8 +46,14 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
Flutter: Flutter:
:path: Flutter :path: Flutter
native_video_player: flutter_platform_alert:
:path: ".symlinks/plugins/native_video_player/ios" :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_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin" :path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation: shared_preferences_foundation:
@ -41,16 +62,25 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite_darwin/darwin" :path: ".symlinks/plugins/sqflite_darwin/darwin"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/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: SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_platform_alert: bf3b5fcd4ac14bd637e20527e9c471633071afd3
Kingfisher: 3204d23de16b5ea53541c44ca5a8efb55741dec3 Kingfisher: 3204d23de16b5ea53541c44ca5a8efb55741dec3
native_video_player: e363dd14f6a498ad8a8f7e6486a0db046ad19f13 media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
PODFILE CHECKSUM: b9d63df345d0c6f260ddc467a83ae5f9c8a6cd6f PODFILE CHECKSUM: 4c3fad73fbbc9053a824d880097bda7884240991
COCOAPODS: 1.16.2 COCOAPODS: 1.16.2

View File

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 70; objectVersion = 54;
objects = { objects = {
/* Begin PBXBuildFile section */ /* 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; }; F6D834CA86410B09796B312B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
737E91D52DB6866B00BE9CDB /* NativeViews */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = NativeViews; sourceTree = "<group>"; };
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
1DFF8FEBBD0CF5A990600776 /* Frameworks */ = { 1DFF8FEBBD0CF5A990600776 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
@ -158,7 +154,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */, 737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */,
737E91D52DB6866B00BE9CDB /* NativeViews */,
97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@ -210,9 +205,6 @@
); );
dependencies = ( dependencies = (
); );
fileSystemSynchronizedGroups = (
737E91D52DB6866B00BE9CDB /* NativeViews */,
);
name = Runner; name = Runner;
productName = Runner; productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productReference = 97C146EE1CF9000F007C117D /* Runner.app */;

View File

@ -8,11 +8,6 @@ import UIKit
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool { ) -> Bool {
GeneratedPluginRegistrant.register(with: self) GeneratedPluginRegistrant.register(with: self)
guard let pluginRegistrar = self.registrar(forPlugin: "plugin-name") else { return false }
pluginRegistrar.register(FLNativeImageFactory(messenger: pluginRegistrar.messenger()), withId: "native-image")
return super.application(application, didFinishLaunchingWithOptions: launchOptions) return super.application(application, didFinishLaunchingWithOptions: launchOptions)
} }
} }

10
lib/widgets/alert.dart Normal file
View File

@ -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,
);
}

View File

@ -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<SnCloudFile> 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),
),
),
);
}
}

View File

@ -2,13 +2,19 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:island/models/file.dart'; import 'package:island/models/file.dart';
import 'package:island/pods/config.dart'; import 'package:island/pods/config.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'image.dart'; import 'image.dart';
import 'video.dart'; import 'video.dart';
class CloudFileWidget extends ConsumerWidget { class CloudFileWidget extends ConsumerWidget {
final SnCloudFile item; 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 @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -23,10 +29,36 @@ class CloudFileWidget extends ConsumerWidget {
case "video": case "video":
return AspectRatio( return AspectRatio(
aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(), aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(),
child: UniversalVideo(uri: uri), child: UniversalVideo(
uri: uri,
aspectRatio: (item.fileMeta?['ratio'] ?? 16 / 9).toDouble(),
),
); );
default: default:
return Placeholder(); 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!),
),
);
}
}

View File

@ -1,33 +1,26 @@
import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_blurhash/flutter_blurhash.dart';
class UniversalImage extends StatelessWidget { class UniversalImage extends StatelessWidget {
final String uri; final String uri;
final String? blurHash; 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final params = {'src': uri, 'blur': blurHash}; return Stack(
if (Platform.isAndroid) { fit: StackFit.expand,
return AndroidView( children: [
viewType: 'native-image', if (blurHash != null) BlurHash(hash: blurHash!),
layoutDirection: TextDirection.ltr, CachedNetworkImage(imageUrl: uri, fit: fit),
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);
} }
} }

View File

@ -3,15 +3,18 @@ import 'package:flutter/material.dart';
class UniversalImage extends StatelessWidget { class UniversalImage extends StatelessWidget {
final String uri; final String uri;
const UniversalImage({super.key, required this.uri}); final String? blurHash;
const UniversalImage({super.key, required this.uri, this.blurHash});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return HtmlElementView( return HtmlElementView.fromTagName(
viewType: 'native-image', tagName: 'img',
onPlatformViewCreated: (int viewId) { onElementCreated: (element) {
final element = web.HTMLImageElement()..src = uri; element as web.HTMLImageElement;
web.document.body!.append(element); element.src = uri;
element.style.width = '100%';
element.style.height = '100%';
}, },
); );
} }

View File

@ -1,65 +1,88 @@
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.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 { class UniversalVideo extends StatefulWidget {
final String uri; 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 @override
State<UniversalVideo> createState() => _UniversalVideoState(); State<UniversalVideo> createState() => _UniversalVideoState();
} }
class _UniversalVideoState extends State<UniversalVideo> { class _UniversalVideoState extends State<UniversalVideo> {
NativeVideoPlayerController? _controller; Player? _player;
bool _isPlaying = false; VideoController? _videoController;
Future<void> _togglePlayback() async { void _openVideo() async {
final controller = _controller; final url = widget.uri;
if (controller == null) return; MediaKit.ensureInitialized();
if (_isPlaying) { _player = Player();
await controller.pause(); _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 { } 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(); _player!.open(Media(uri));
setState(() { }
_isPlaying = isPlaying;
}); @override
void initState() {
super.initState();
_openVideo();
}
@override
void dispose() {
super.dispose();
_player?.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (Platform.isAndroid || Platform.isIOS) { if (_videoController == null) {
return Stack( return Center(child: CircularProgressIndicator());
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,
),
),
),
),
],
);
} }
return Image.network(widget.uri);
return Video(
controller: _videoController!,
aspectRatio: widget.aspectRatio,
controls:
!kIsWeb && (Platform.isAndroid || Platform.isIOS)
? MaterialVideoControls
: MaterialDesktopVideoControls,
);
} }
} }

View File

@ -7,12 +7,14 @@ class UniversalVideo extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return HtmlElementView( return HtmlElementView.fromTagName(
viewType: 'native-video', tagName: 'video',
onPlatformViewCreated: (int viewId) { onElementCreated: (element) {
final element = web.HTMLVideoElement()..src = uri; element as web.HTMLVideoElement;
element.src = uri;
element.style.width = '100%';
element.style.height = '100%';
element.controls = true; element.controls = true;
web.document.body!.append(element);
}, },
); );
} }

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:island/models/post.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/cloud_files.dart';
import 'package:island/widgets/content/markdown.dart'; import 'package:island/widgets/content/markdown.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
@ -17,15 +18,18 @@ class PostItem extends StatelessWidget {
return Padding( return Padding(
padding: renderingPadding, padding: renderingPadding,
child: Column( child: Column(
spacing: 8,
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 12,
children: [ children: [
// Avatar... ProfilePictureWidget(item: item.publisher.picture),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(item.publisher.name).bold(), Text(item.publisher.nick).bold(),
if (item.content.isNotEmpty) if (item.content.isNotEmpty)
MarkdownTextContent(content: item.content), MarkdownTextContent(content: item.content),
], ],
@ -33,8 +37,8 @@ class PostItem extends StatelessWidget {
), ),
], ],
), ),
for (final attachment in item.attachments) if (item.attachments.isNotEmpty)
CloudFileWidget(item: attachment), CloudFileList(files: item.attachments),
], ],
), ),
); );

View File

@ -7,12 +7,24 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h> #include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
#include <flutter_platform_alert/flutter_platform_alert_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <media_kit_video/media_kit_video_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar = g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar); 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 = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@ -4,6 +4,9 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
bitsdojo_window_linux bitsdojo_window_linux
flutter_platform_alert
media_kit_libs_linux
media_kit_video
url_launcher_linux url_launcher_linux
) )

View File

@ -6,15 +6,27 @@ import FlutterMacOS
import Foundation import Foundation
import bitsdojo_window_macos 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 path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import sqflite_darwin import sqflite_darwin
import url_launcher_macos import url_launcher_macos
import volume_controller
import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) 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")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
} }

View File

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.4.1" version: "7.4.1"
archive:
dependency: transitive
description:
name: archive
sha256: a7f37ff061d7abc2fcf213554b9dcaca713c5853afa5c065c44888bc9ccaf813
url: "https://pub.dev"
source: hosted
version: "4.0.6"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -257,6 +265,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.1"
dbus:
dependency: transitive
description:
name: dbus
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
url: "https://pub.dev"
source: hosted
version: "0.7.11"
dio: dio:
dependency: "direct main" dependency: "direct main"
description: description:
@ -310,8 +326,16 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" 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: flutter_cache_manager:
dependency: transitive dependency: "direct main"
description: description:
name: flutter_cache_manager name: flutter_cache_manager
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
@ -366,6 +390,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.3" 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: flutter_riverpod:
dependency: "direct main" dependency: "direct main"
description: description:
@ -488,6 +520,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.2" version: "4.1.2"
image:
dependency: transitive
description:
name: image
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
url: "https://pub.dev"
source: hosted
version: "4.5.4"
io: io:
dependency: transitive dependency: transitive
description: description:
@ -592,6 +632,78 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.11.1" 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: meta:
dependency: transitive dependency: transitive
description: description:
@ -608,14 +720,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" 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: nested:
dependency: transitive dependency: transitive
description: description:
@ -640,6 +744,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" 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: path:
dependency: transitive dependency: transitive
description: description:
@ -736,6 +856,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.5.1" version: "1.5.1"
posix:
dependency: transitive
description:
name: posix
sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62
url: "https://pub.dev"
source: hosted
version: "6.0.2"
provider: provider:
dependency: transitive dependency: transitive
description: description:
@ -784,6 +912,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.28.0" 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: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1029,6 +1181,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" 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: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1149,6 +1317,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.3.1" 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: watcher:
dependency: transitive dependency: transitive
description: description:

View File

@ -57,7 +57,13 @@ dependencies:
gap: ^3.0.1 gap: ^3.0.1
cached_network_image: ^3.4.1 cached_network_image: ^3.4.1
web: ^1.1.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: dev_dependencies:
flutter_test: flutter_test:

View File

@ -7,11 +7,23 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h> #include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
#include <flutter_platform_alert/flutter_platform_alert_plugin.h>
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
#include <media_kit_video/media_kit_video_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <volume_controller/volume_controller_plugin_c_api.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
BitsdojoWindowPluginRegisterWithRegistrar( BitsdojoWindowPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
FlutterPlatformAlertPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterPlatformAlertPlugin"));
MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi"));
MediaKitVideoPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
VolumeControllerPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("VolumeControllerPluginCApi"));
} }

View File

@ -4,7 +4,11 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
bitsdojo_window_windows bitsdojo_window_windows
flutter_platform_alert
media_kit_libs_windows_video
media_kit_video
url_launcher_windows url_launcher_windows
volume_controller
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST