feat: share stream

closes #33
This commit is contained in:
2025-05-19 12:42:35 +01:00
parent 86a8181aea
commit a500e0b3da
8 changed files with 78 additions and 21 deletions

View File

@ -34,10 +34,11 @@ class _StreamPage extends State<StreamPage> with RouteAware {
final router = GoRouter.of(context); final router = GoRouter.of(context);
final currentConfiguration = router.routerDelegate.currentConfiguration; final currentConfiguration = router.routerDelegate.currentConfiguration;
final match = currentConfiguration.matches.lastOrNull; final match = currentConfiguration.matches.lastOrNull;
final lastMatch = match is ShellRouteMatch ? match.matches.lastOrNull : match; final lastMatch =
match is ShellRouteMatch ? match.matches.lastOrNull : match;
return lastMatch != null && return lastMatch != null &&
(lastMatch.route is GoRoute && (lastMatch.route is GoRoute &&
(lastMatch.route as GoRoute).path == StreamPage.path); (lastMatch.route as GoRoute).path == StreamPage.path);
} }
@override @override
@ -122,10 +123,11 @@ class _StreamPage extends State<StreamPage> with RouteAware {
? ProxyImg(url: stream.info.image) ? ProxyImg(url: stream.info.image)
: Container(decoration: BoxDecoration(color: LAYER_1)), : Container(decoration: BoxDecoration(color: LAYER_1)),
), ),
Text( if (stream.info.title?.isNotEmpty ?? false)
stream.info.title ?? "", Text(
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18), stream.info.title!,
), style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18),
),
ProfileWidget.pubkey( ProfileWidget.pubkey(
stream.info.host, stream.info.host,
children: [ children: [

View File

@ -27,14 +27,22 @@ class BasicButton extends StatelessWidget {
void Function()? onTap, void Function()? onTap,
double? fontSize, double? fontSize,
bool? disabled, bool? disabled,
Icon? icon,
}) { }) {
return BasicButton( return BasicButton(
Text( Text.rich(
text, TextSpan(
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 255, 255, 255), color: Color.fromARGB(255, 255, 255, 255),
fontSize: fontSize, fontSize: fontSize,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
),
children: [
if (icon != null)
WidgetSpan(child: icon, alignment: PlaceholderAlignment.middle),
if (icon != null) TextSpan(text: " "),
TextSpan(text: text),
],
), ),
), ),
disabled: disabled, disabled: disabled,

View File

@ -1,8 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:share_plus/share_plus.dart';
import 'package:zap_stream_flutter/main.dart';
import 'package:zap_stream_flutter/theme.dart'; import 'package:zap_stream_flutter/theme.dart';
import 'package:zap_stream_flutter/utils.dart'; import 'package:zap_stream_flutter/utils.dart';
import 'package:zap_stream_flutter/widgets/button.dart';
import 'package:zap_stream_flutter/widgets/button_follow.dart'; import 'package:zap_stream_flutter/widgets/button_follow.dart';
import 'package:zap_stream_flutter/widgets/game_info.dart'; import 'package:zap_stream_flutter/widgets/game_info.dart';
import 'package:zap_stream_flutter/widgets/live_timer.dart'; import 'package:zap_stream_flutter/widgets/live_timer.dart';
@ -18,6 +21,8 @@ class StreamInfoWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isMe = ndk.accounts.getPublicKey() == stream.info.host;
final startedDate = final startedDate =
stream.info.starts != null stream.info.starts != null
? DateTime.fromMillisecondsSinceEpoch(stream.info.starts! * 1000) ? DateTime.fromMillisecondsSinceEpoch(stream.info.starts! * 1000)
@ -29,16 +34,35 @@ class StreamInfoWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ProfileWidget.pubkey(stream.info.host, linkToProfile: false), ProfileWidget.pubkey(stream.info.host, linkToProfile: false),
FollowButton( Row(
pubkey: stream.info.host, spacing: 8,
onTap: () { children: [
Navigator.pop(context); if (!isMe)
}, FollowButton(
), pubkey: stream.info.host,
Text( onTap: () {
stream.info.title ?? "", Navigator.pop(context);
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), },
),
BasicButton.text(
"Share",
icon: Icon(Icons.share, size: 16),
onTap: () {
SharePlus.instance.share(
ShareParams(
title: stream.info.title,
uri: Uri.parse("https://zap.stream/${stream.link}"),
),
);
},
),
],
), ),
if (stream.info.title?.isNotEmpty ?? false)
Text(
stream.info.title!,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
if (startedDate != null) if (startedDate != null)
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,

View File

@ -11,6 +11,7 @@ import flutter_secure_storage_macos
import objectbox_flutter_libs import objectbox_flutter_libs
import package_info_plus import package_info_plus
import path_provider_foundation import path_provider_foundation
import share_plus
import shared_preferences_foundation import shared_preferences_foundation
import sqflite_darwin import sqflite_darwin
import url_launcher_macos import url_launcher_macos
@ -24,6 +25,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin")) ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
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"))

View File

@ -811,6 +811,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.28.0" version: "0.28.0"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: b2961506569e28948d75ec346c28775bb111986bb69dc6a20754a457e3d97fa0
url: "https://pub.dev"
source: hosted
version: "11.0.0"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "1032d392bc5d2095a77447a805aa3f804d2ae6a4d5eef5e6ebb3bd94c1bc19ef"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
shared_preferences: shared_preferences:
dependency: transitive dependency: transitive
description: description:

View File

@ -33,6 +33,7 @@ dependencies:
bech32: ^0.2.2 bech32: ^0.2.2
intl: ^0.20.2 intl: ^0.20.2
flutter_markdown_plus: ^1.0.3 flutter_markdown_plus: ^1.0.3
share_plus: ^11.0.0
dependency_overrides: dependency_overrides:
ndk: ndk:

View File

@ -10,6 +10,7 @@
#include <file_selector_windows/file_selector_windows.h> #include <file_selector_windows/file_selector_windows.h>
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h> #include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
@ -21,6 +22,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
ObjectboxFlutterLibsPluginRegisterWithRegistrar( ObjectboxFlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ObjectboxFlutterLibsPlugin")); registry->GetRegistrarForPlugin("ObjectboxFlutterLibsPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows file_selector_windows
flutter_secure_storage_windows flutter_secure_storage_windows
objectbox_flutter_libs objectbox_flutter_libs
share_plus
url_launcher_windows url_launcher_windows
) )