mirror of
https://github.com/feeddeck/feeddeck.git
synced 2026-04-27 10:47:42 -05:00
[mastodon] Add Support for Videos (#51)
It is now possible to play videos from toots within FeedDeck. For that we are using the "madia_kit" package, which is already used for the Podcast player on Windows and Linux. The videos from a toot are saved within the "options.videos" field of an item next to the "options.media" field. In the "ItemDetailsMastodon" widget we are then checking if this field is present and contains a list of video urls. These urls can then be played via the "ItemVideos" widget.
This commit is contained in:
@@ -13,8 +13,12 @@ PODS:
|
||||
- FMDB/standard (2.7.5)
|
||||
- just_audio (0.0.1):
|
||||
- Flutter
|
||||
- media_kit_libs_ios_video (1.0.4):
|
||||
- Flutter
|
||||
- media_kit_native_event_loop (1.0.0):
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
- Flutter
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_foundation (0.0.1):
|
||||
@@ -26,6 +30,8 @@ PODS:
|
||||
- PurchasesHybridCommon (7.0.0):
|
||||
- RevenueCat (= 4.27.0)
|
||||
- RevenueCat (4.27.0)
|
||||
- screen_brightness_ios (0.1.0):
|
||||
- Flutter
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
@@ -36,6 +42,10 @@ PODS:
|
||||
- FMDB (>= 2.7.5)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- volume_controller (0.0.1):
|
||||
- Flutter
|
||||
- wakelock_plus (0.0.1):
|
||||
- Flutter
|
||||
- webview_flutter_wkwebview (0.0.1):
|
||||
- Flutter
|
||||
|
||||
@@ -46,14 +56,19 @@ DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/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`)
|
||||
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
|
||||
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/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`)
|
||||
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
@@ -75,14 +90,20 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||
just_audio:
|
||||
:path: ".symlinks/plugins/just_audio/ios"
|
||||
media_kit_libs_ios_video:
|
||||
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
||||
media_kit_native_event_loop:
|
||||
:path: ".symlinks/plugins/media_kit_native_event_loop/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"
|
||||
purchases_flutter:
|
||||
:path: ".symlinks/plugins/purchases_flutter/ios"
|
||||
screen_brightness_ios:
|
||||
:path: ".symlinks/plugins/screen_brightness_ios/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
sign_in_with_apple:
|
||||
@@ -91,6 +112,10 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
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"
|
||||
webview_flutter_wkwebview:
|
||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
|
||||
|
||||
@@ -102,16 +127,21 @@ SPEC CHECKSUMS:
|
||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
|
||||
media_kit_native_event_loop: f1ee9f941ec0af371b245969a3e010901c375480
|
||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
|
||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||
purchases_flutter: 549ccfbbaf5e7cd195043c714b69a35e278c00f1
|
||||
PurchasesHybridCommon: af3b2413f9cb999bc1fdca44770bdaf39dfb89fa
|
||||
RevenueCat: 84fbe2eb9bbf63e1abf346ccd3ff9ee45d633e3b
|
||||
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
|
||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
||||
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
|
||||
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
||||
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
|
||||
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
|
||||
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
|
||||
webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a
|
||||
|
||||
PODFILE CHECKSUM: ec83c31511fbc978a9918c6fda235238118483f5
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
import 'package:flutter_web_plugins/url_strategy.dart';
|
||||
import 'package:just_audio_background/just_audio_background.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
@@ -45,13 +46,23 @@ void main() async {
|
||||
});
|
||||
}
|
||||
|
||||
/// Initialize the [media_kit] packages, so that we can play audio and video
|
||||
/// files.
|
||||
MediaKit.ensureInitialized();
|
||||
|
||||
/// Initialize the [just_audio_background] package, so that we can play audio
|
||||
/// files in the background.
|
||||
await JustAudioBackground.init(
|
||||
androidNotificationChannelId: 'com.ryanheise.bg_demo.channel.audio',
|
||||
androidNotificationChannelName: 'Audio playback',
|
||||
androidNotificationOngoing: true,
|
||||
);
|
||||
///
|
||||
/// We can not initialize the [just_audio_background] package on Windows and
|
||||
/// Linux, because then the returned duration in the `_player.durationStream`
|
||||
/// isn't working correctly in the [ItemAudioPlayer] widget.
|
||||
if (kIsWeb || Platform.isAndroid || Platform.isIOS || Platform.isIOS) {
|
||||
await JustAudioBackground.init(
|
||||
androidNotificationChannelId: 'com.ryanheise.bg_demo.channel.audio',
|
||||
androidNotificationChannelName: 'Audio playback',
|
||||
androidNotificationOngoing: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// For the ewb we have to use the path url strategy, so that the redirect
|
||||
/// within Supabase is working in all cases. On all other platforms this is a
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:feeddeck/utils/constants.dart';
|
||||
import 'package:feeddeck/widgets/item/details/utils/item_description.dart';
|
||||
import 'package:feeddeck/widgets/item/details/utils/item_media_gallery.dart';
|
||||
import 'package:feeddeck/widgets/item/details/utils/item_subtitle.dart';
|
||||
import 'package:feeddeck/widgets/item/details/utils/item_videos.dart';
|
||||
|
||||
class ItemDetailsMastodon extends StatelessWidget {
|
||||
const ItemDetailsMastodon({
|
||||
@@ -36,12 +37,23 @@ class ItemDetailsMastodon extends StatelessWidget {
|
||||
height: Constants.spacingExtraSmall,
|
||||
),
|
||||
ItemMediaGallery(
|
||||
itemMedias: item.options != null && item.options!.containsKey('media')
|
||||
itemMedias: item.options != null &&
|
||||
item.options!.containsKey('media') &&
|
||||
item.options!['media'] != null
|
||||
? (item.options!['media'] as List)
|
||||
.map((item) => item as String)
|
||||
.toList()
|
||||
: null,
|
||||
),
|
||||
ItemVideos(
|
||||
videos: item.options != null &&
|
||||
item.options!.containsKey('videos') &&
|
||||
item.options!['videos'] != null
|
||||
? (item.options!['videos'] as List)
|
||||
.map((item) => item as String)
|
||||
.toList()
|
||||
: null,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
93
app/lib/widgets/item/details/utils/item_videos.dart
Normal file
93
app/lib/widgets/item/details/utils/item_videos.dart
Normal file
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:media_kit_video/media_kit_video.dart';
|
||||
|
||||
import 'package:feeddeck/utils/constants.dart';
|
||||
|
||||
/// The [ItemVideos] widget is used to display a list of videos, which can be
|
||||
/// played by the user. If the [videos] list is empty or null, the widget will
|
||||
/// not be displayed.
|
||||
class ItemVideos extends StatelessWidget {
|
||||
const ItemVideos({
|
||||
super.key,
|
||||
required this.videos,
|
||||
});
|
||||
|
||||
final List<String>? videos;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (videos == null || videos!.isEmpty) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: Constants.spacingMiddle,
|
||||
),
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
separatorBuilder: (context, index) {
|
||||
return const SizedBox(
|
||||
height: Constants.spacingMiddle,
|
||||
);
|
||||
},
|
||||
itemCount: videos!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ItemVideoPlayer(video: videos![index]);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The [ItemVideoPlayer] widget is used to display a video, which can be played
|
||||
/// by the user. It should be used in combination with the [ItemVideos] widget
|
||||
/// and is responsible for the actual implementation of the video player.
|
||||
class ItemVideoPlayer extends StatefulWidget {
|
||||
const ItemVideoPlayer({
|
||||
super.key,
|
||||
required this.video,
|
||||
});
|
||||
|
||||
final String video;
|
||||
|
||||
@override
|
||||
State<ItemVideoPlayer> createState() => _ItemVideoPlayerState();
|
||||
}
|
||||
|
||||
class _ItemVideoPlayerState extends State<ItemVideoPlayer> {
|
||||
late final player = Player();
|
||||
late final controller = VideoController(player);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
player.open(
|
||||
Media(widget.video),
|
||||
play: false,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
player.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: constraints.maxWidth,
|
||||
height: constraints.maxWidth * 9.0 / 16.0,
|
||||
child: Video(controller: controller),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,9 @@ class ItemPreviewMastodon extends StatelessWidget {
|
||||
tagetFormat: DescriptionFormat.markdown,
|
||||
),
|
||||
ItemMediaGallery(
|
||||
itemMedias: item.options != null && item.options!.containsKey('media')
|
||||
itemMedias: item.options != null &&
|
||||
item.options!.containsKey('media') &&
|
||||
item.options!['media'] != null
|
||||
? (item.options!['media'] as List)
|
||||
.map((item) => item as String)
|
||||
.toList()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||
#include <media_kit_video/media_kit_video_plugin.h>
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
@@ -15,6 +16,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
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) screen_retriever_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
||||
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
media_kit_libs_linux
|
||||
media_kit_video
|
||||
screen_retriever
|
||||
url_launcher_linux
|
||||
window_manager
|
||||
|
||||
@@ -9,14 +9,18 @@ import app_links
|
||||
import audio_service
|
||||
import audio_session
|
||||
import just_audio
|
||||
import media_kit_libs_macos_video
|
||||
import media_kit_video
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import purchases_flutter
|
||||
import screen_brightness_macos
|
||||
import screen_retriever
|
||||
import shared_preferences_foundation
|
||||
import sign_in_with_apple
|
||||
import sqflite
|
||||
import url_launcher_macos
|
||||
import wakelock_plus
|
||||
import window_manager
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
@@ -24,13 +28,17 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin"))
|
||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
||||
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
|
||||
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
PurchasesFlutterPlugin.register(with: registry.registrar(forPlugin: "PurchasesFlutterPlugin"))
|
||||
ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin"))
|
||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||
}
|
||||
|
||||
@@ -11,8 +11,12 @@ PODS:
|
||||
- FMDB/standard (2.7.5)
|
||||
- just_audio (0.0.1):
|
||||
- FlutterMacOS
|
||||
- media_kit_libs_macos_video (1.0.4):
|
||||
- FlutterMacOS
|
||||
- media_kit_native_event_loop (1.0.0):
|
||||
- FlutterMacOS
|
||||
- media_kit_video (0.0.1):
|
||||
- FlutterMacOS
|
||||
- package_info_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- path_provider_foundation (0.0.1):
|
||||
@@ -24,6 +28,8 @@ PODS:
|
||||
- PurchasesHybridCommon (7.0.0):
|
||||
- RevenueCat (= 4.27.0)
|
||||
- RevenueCat (4.27.0)
|
||||
- screen_brightness_macos (0.1.0):
|
||||
- FlutterMacOS
|
||||
- screen_retriever (0.0.1):
|
||||
- FlutterMacOS
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
@@ -36,6 +42,8 @@ PODS:
|
||||
- FMDB (>= 2.7.5)
|
||||
- url_launcher_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- wakelock_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- window_manager (0.2.0):
|
||||
- FlutterMacOS
|
||||
|
||||
@@ -45,15 +53,19 @@ DEPENDENCIES:
|
||||
- audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/macos`)
|
||||
- media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`)
|
||||
- media_kit_native_event_loop (from `Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos`)
|
||||
- media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`)
|
||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- purchases_flutter (from `Flutter/ephemeral/.symlinks/plugins/purchases_flutter/macos`)
|
||||
- screen_brightness_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos`)
|
||||
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
|
||||
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- sign_in_with_apple (from `Flutter/ephemeral/.symlinks/plugins/sign_in_with_apple/macos`)
|
||||
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
|
||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
|
||||
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
|
||||
|
||||
SPEC REPOS:
|
||||
@@ -73,14 +85,20 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral
|
||||
just_audio:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/just_audio/macos
|
||||
media_kit_libs_macos_video:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos
|
||||
media_kit_native_event_loop:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_native_event_loop/macos
|
||||
media_kit_video:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos
|
||||
package_info_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||
path_provider_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
||||
purchases_flutter:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/purchases_flutter/macos
|
||||
screen_brightness_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos
|
||||
screen_retriever:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
|
||||
shared_preferences_foundation:
|
||||
@@ -91,6 +109,8 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
|
||||
url_launcher_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||
wakelock_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
|
||||
window_manager:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
|
||||
|
||||
@@ -101,17 +121,21 @@ SPEC CHECKSUMS:
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
just_audio: 9b67ca7b97c61cfc9784ea23cd8cc55eb226d489
|
||||
media_kit_native_event_loop: d20622d35dd6d06fe71223976bd70a2bcf595dce
|
||||
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
||||
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
||||
media_kit_video: c75b07f14d59706c775778e4dd47dd027de8d1e5
|
||||
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
|
||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||
purchases_flutter: 9aad80bf27960c38fdeafc27ab066cb55615aed5
|
||||
PurchasesHybridCommon: af3b2413f9cb999bc1fdca44770bdaf39dfb89fa
|
||||
RevenueCat: 84fbe2eb9bbf63e1abf346ccd3ff9ee45d633e3b
|
||||
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
|
||||
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
|
||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
||||
sign_in_with_apple: a9e97e744e8edc36aefc2723111f652102a7a727
|
||||
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
|
||||
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
||||
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
|
||||
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
||||
|
||||
PODFILE CHECKSUM: 8d40c19d3cbdb380d870685c3a564c989f1efa52
|
||||
|
||||
137
app/pubspec.lock
137
app/pubspec.lock
@@ -185,6 +185,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -403,10 +411,11 @@ packages:
|
||||
just_audio_media_kit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: just_audio_media_kit
|
||||
sha256: d6288e898bc5ed499a938c3cf1ea99eeca4264f9b6ef7bdf92ace3e8b804e259
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "5980ceac7cc385baf2269eda2dcb024d3e5203cc"
|
||||
url: "https://github.com/feeddeck/just_audio_media_kit.git"
|
||||
source: git
|
||||
version: "1.0.0"
|
||||
just_audio_platform_interface:
|
||||
dependency: transitive
|
||||
@@ -473,13 +482,29 @@ packages:
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
media_kit:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: media_kit
|
||||
sha256: "3289062540e3b8b9746e5c50d95bd78a9289826b7227e253dff806d002b9e67a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.10+1"
|
||||
media_kit_libs_android_video:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: media_kit_libs_android_video
|
||||
sha256: "9dd8012572e4aff47516e55f2597998f0a378e3d588d0fad0ca1f11a53ae090c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.6"
|
||||
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:
|
||||
@@ -488,11 +513,27 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
media_kit_libs_windows_audio:
|
||||
media_kit_libs_macos_video:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: media_kit_libs_windows_audio
|
||||
sha256: c2fd558cc87b9d89a801141fcdffe02e338a3b21a41a18fbd63d5b221a1b8e53
|
||||
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: "3688e0c31482074578652bf038ce6301a5d21e1eda6b54fc3117ffeb4bdba067"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
media_kit_libs_windows_video:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: media_kit_libs_windows_video
|
||||
sha256: "7bace5f35d9afcc7f9b5cdadb7541d2191a66bb3fc71bfa11c1395b3360f6122"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.9"
|
||||
@@ -504,6 +545,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
media_kit_video:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: media_kit_video
|
||||
sha256: c048d11a19e379aebbe810647636e3fc6d18374637e2ae12def4ff8a4b99a882
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.4"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -720,6 +769,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
screen_brightness:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_brightness
|
||||
sha256: ed8da4a4511e79422fc1aa88138e920e4008cd312b72cdaa15ccb426c0faaedd
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.2+1"
|
||||
screen_brightness_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_brightness_android
|
||||
sha256: "3df10961e3a9e968a5e076fe27e7f4741fa8a1d3950bdeb48cf121ed529d0caf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0+2"
|
||||
screen_brightness_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_brightness_ios
|
||||
sha256: "99adc3ca5490b8294284aad5fcc87f061ad685050e03cf45d3d018fe398fd9a2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
screen_brightness_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_brightness_macos
|
||||
sha256: "64b34e7e3f4900d7687c8e8fb514246845a73ecec05ab53483ed025bd4a899fd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0+1"
|
||||
screen_brightness_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_brightness_platform_interface
|
||||
sha256: b211d07f0c96637a15fb06f6168617e18030d5d74ad03795dd8547a52717c171
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
screen_brightness_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_brightness_windows
|
||||
sha256: "9261bf33d0fc2707d8cf16339ce25768100a65e70af0fcabaf032fc12408ba86"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
screen_retriever:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1053,6 +1150,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
volume_controller:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: volume_controller
|
||||
sha256: "189bdc7a554f476b412e4c8b2f474562b09d74bc458c23667356bce3ca1d48c9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.7"
|
||||
wakelock_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_plus
|
||||
sha256: "268e56b9c63f850406f54e9acb2a7d2ddf83c26c8ff9e7a125a96c3a513bf65f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -47,7 +47,16 @@ dependencies:
|
||||
intl: ^0.18.1
|
||||
just_audio: ^0.9.32
|
||||
just_audio_background: ^0.0.1-beta.10
|
||||
just_audio_media_kit: ^1.0.0
|
||||
# We use our own fork of the "just_audio_media_kit" package, where we
|
||||
# replaced the "media_kit_libs_windows_audio" with
|
||||
# "media_kit_libs_windows_video" package, so that we can play video files on
|
||||
# Windows via the "media_kit" package.
|
||||
just_audio_media_kit:
|
||||
git:
|
||||
url: https://github.com/feeddeck/just_audio_media_kit.git
|
||||
media_kit: ^1.1.10+1
|
||||
media_kit_video: ^1.2.4
|
||||
media_kit_libs_video: ^1.0.4
|
||||
package_info_plus: ^4.1.0
|
||||
provider: ^6.0.4
|
||||
purchases_flutter: ^6.0.0
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <app_links/app_links_plugin_c_api.h>
|
||||
#include <media_kit_libs_windows_audio/media_kit_libs_windows_audio_plugin_c_api.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 <screen_brightness_windows/screen_brightness_windows_plugin.h>
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
@@ -15,8 +17,12 @@
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AppLinksPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
|
||||
MediaKitLibsWindowsAudioPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("MediaKitLibsWindowsAudioPluginCApi"));
|
||||
MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi"));
|
||||
MediaKitVideoPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi"));
|
||||
ScreenBrightnessWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin"));
|
||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
app_links
|
||||
media_kit_libs_windows_audio
|
||||
media_kit_libs_windows_video
|
||||
media_kit_video
|
||||
screen_brightness_windows
|
||||
screen_retriever
|
||||
url_launcher_windows
|
||||
window_manager
|
||||
|
||||
@@ -114,10 +114,22 @@ export const getMastodonFeed = async (
|
||||
|
||||
/**
|
||||
* Create the item object and add it to the `items` array. Before the item is created we also try to get a list of
|
||||
* media fils (images) and add it to the options. Since there could be multiple media files we add it to the options
|
||||
* and not to the media field.
|
||||
* media fils (images) and videos which will then be added to the `options`. Since there could be multiple media
|
||||
* files we add it to the options and not to the media field.
|
||||
*
|
||||
* The implementation to generate the options field is not ideal, but is required to be compatible with older
|
||||
* clients, where we just check if the options are defined and if it contains a media field, but we do not check if
|
||||
* the media field is null.
|
||||
*/
|
||||
const options: { media?: string[]; videos?: string[] } = {};
|
||||
const media = getMedia(entry);
|
||||
if (media && media.length > 0) {
|
||||
options["media"] = media;
|
||||
}
|
||||
const videos = getVideos(entry);
|
||||
if (videos && videos.length > 0) {
|
||||
options["videos"] = videos;
|
||||
}
|
||||
|
||||
items.push({
|
||||
id: itemId,
|
||||
@@ -126,7 +138,7 @@ export const getMastodonFeed = async (
|
||||
sourceId: source.id,
|
||||
title: "",
|
||||
link: entry.links[0].href!,
|
||||
options: media && media.length > 0 ? { media: media } : undefined,
|
||||
options: Object.keys(options).length === 0 ? undefined : options,
|
||||
description: entry.description?.value
|
||||
? unescape(entry.description.value)
|
||||
: undefined,
|
||||
@@ -187,8 +199,8 @@ const generateItemId = (sourceId: string, identifier: string): string => {
|
||||
};
|
||||
|
||||
/**
|
||||
* `getMedia` returns an image for the provided feed entry from it's description. If we could not get an image from the
|
||||
* description we return `undefined`.
|
||||
* `getMedia` returns all images for the provided feed entry from it's `media:content` field. If we could not get an
|
||||
* image we return `undefined`.
|
||||
*/
|
||||
const getMedia = (entry: FeedEntry): string[] | undefined => {
|
||||
if (entry["media:content"]) {
|
||||
@@ -205,6 +217,25 @@ const getMedia = (entry: FeedEntry): string[] | undefined => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* `getVideos` returns all videos for the provided feed entry from it's `media:content` field. If we could not get a
|
||||
* video we return `undefined`.
|
||||
*/
|
||||
const getVideos = (entry: FeedEntry): string[] | undefined => {
|
||||
if (entry["media:content"]) {
|
||||
const videos = [];
|
||||
for (const media of entry["media:content"]) {
|
||||
if (media.medium === "video" && media.url) {
|
||||
videos.push(media.url);
|
||||
}
|
||||
}
|
||||
|
||||
return videos;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* `getAuthor` returns the author for the provided feed entry based on the link to the entry.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user