more message view stuff

This commit is contained in:
Mike Schwörer 2024-06-08 20:01:23 +02:00
parent b00ba83370
commit 64709920f7
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
12 changed files with 205 additions and 69 deletions

View File

@ -11,46 +11,64 @@ class SCNAppBar extends StatelessWidget implements PreferredSizeWidget {
required this.showThemeSwitch, required this.showThemeSwitch,
required this.showDebug, required this.showDebug,
required this.showSearch, required this.showSearch,
required this.showShare,
this.onShare = null,
}) : super(key: key); }) : super(key: key);
final String? title; final String? title;
final bool showThemeSwitch; final bool showThemeSwitch;
final bool showDebug; final bool showDebug;
final bool showSearch; final bool showSearch;
final bool showShare;
final void Function()? onShare;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppBar( var actions = <Widget>[];
title: Text(title ?? 'Simple Cloud Notifier 2.0'),
actions: <Widget>[ if (showThemeSwitch) {
if (showThemeSwitch) actions.add(Consumer<AppTheme>(
Consumer<AppTheme>(
builder: (context, appTheme, child) => IconButton( builder: (context, appTheme, child) => IconButton(
icon: Icon(appTheme.darkMode ? FontAwesomeIcons.solidSun : FontAwesomeIcons.solidMoon), icon: Icon(appTheme.darkMode ? FontAwesomeIcons.solidSun : FontAwesomeIcons.solidMoon),
tooltip: 'Debug', tooltip: appTheme.darkMode ? 'Light mode' : 'Dark mode',
onPressed: () { onPressed: appTheme.switchDarkMode,
appTheme.switchDarkMode();
},
), ),
), ));
if (!showThemeSwitch) SizedBox.square(dimension: 40), } else {
if (showDebug) actions.add(SizedBox.square(dimension: 40));
IconButton( }
if (showDebug) {
actions.add(IconButton(
icon: const Icon(FontAwesomeIcons.solidSpiderBlackWidow), icon: const Icon(FontAwesomeIcons.solidSpiderBlackWidow),
tooltip: 'Debug', tooltip: 'Debug',
onPressed: () { onPressed: () {
Navigator.push(context, MaterialPageRoute<DebugMainPage>(builder: (context) => DebugMainPage())); Navigator.push(context, MaterialPageRoute<DebugMainPage>(builder: (context) => DebugMainPage()));
}, },
), ));
if (!showDebug) SizedBox.square(dimension: 40), } else {
if (showSearch) actions.add(SizedBox.square(dimension: 40));
IconButton( }
if (showSearch) {
actions.add(IconButton(
icon: const Icon(FontAwesomeIcons.solidMagnifyingGlass), icon: const Icon(FontAwesomeIcons.solidMagnifyingGlass),
tooltip: 'Search', tooltip: 'Search',
onPressed: () {}, onPressed: () {/*TODO*/},
), ));
if (!showSearch) SizedBox.square(dimension: 40), } else if (showShare) {
], actions.add(IconButton(
icon: const Icon(FontAwesomeIcons.solidShareNodes),
tooltip: 'Share',
onPressed: onShare ?? () {},
));
} else {
actions.add(SizedBox.square(dimension: 40));
}
return AppBar(
title: Text(title ?? 'Simple Cloud Notifier 2.0'),
actions: actions,
backgroundColor: Theme.of(context).secondaryHeaderColor, backgroundColor: Theme.of(context).secondaryHeaderColor,
); );
} }

View File

@ -9,6 +9,8 @@ class SCNScaffold extends StatelessWidget {
this.showThemeSwitch = true, this.showThemeSwitch = true,
this.showDebug = true, this.showDebug = true,
this.showSearch = true, this.showSearch = true,
this.showShare = false,
this.onShare = null,
}) : super(key: key); }) : super(key: key);
final Widget child; final Widget child;
@ -16,6 +18,8 @@ class SCNScaffold extends StatelessWidget {
final bool showThemeSwitch; final bool showThemeSwitch;
final bool showDebug; final bool showDebug;
final bool showSearch; final bool showSearch;
final bool showShare;
final void Function()? onShare;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -25,6 +29,8 @@ class SCNScaffold extends StatelessWidget {
showThemeSwitch: showThemeSwitch, showThemeSwitch: showThemeSwitch,
showDebug: showDebug, showDebug: showDebug,
showSearch: showSearch, showSearch: showSearch,
showShare: showShare,
onShare: onShare ?? () {},
), ),
body: child, body: child,
); );

View File

@ -61,6 +61,7 @@ class _SCNNavLayoutState extends State<SCNNavLayout> {
title: null, title: null,
showDebug: true, showDebug: true,
showSearch: _selectedIndex == 0 || _selectedIndex == 1, showSearch: _selectedIndex == 0 || _selectedIndex == 1,
showShare: false,
showThemeSwitch: true, showThemeSwitch: true,
), ),
body: IndexedStack( body: IndexedStack(

View File

@ -28,6 +28,7 @@ class _MessageListPageState extends State<MessageListPage> {
@override @override
void initState() { void initState() {
//TODO init with state from cache - also allow tho show cache on error
_pagingController.addPageRequestListener((pageKey) { _pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey); _fetchPage(pageKey);
}); });

View File

@ -1,7 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:simplecloudnotifier/api/api_client.dart'; import 'package:simplecloudnotifier/api/api_client.dart';
import 'package:simplecloudnotifier/api/api_exception.dart'; import 'package:simplecloudnotifier/api/api_exception.dart';
import 'package:simplecloudnotifier/components/layout/scaffold.dart'; import 'package:simplecloudnotifier/components/layout/scaffold.dart';
@ -10,6 +12,7 @@ import 'package:simplecloudnotifier/models/channel.dart';
import 'package:simplecloudnotifier/models/keytoken.dart'; import 'package:simplecloudnotifier/models/keytoken.dart';
import 'package:simplecloudnotifier/models/message.dart'; import 'package:simplecloudnotifier/models/message.dart';
import 'package:simplecloudnotifier/state/app_auth.dart'; import 'package:simplecloudnotifier/state/app_auth.dart';
import 'package:simplecloudnotifier/utils/toaster.dart';
import 'package:simplecloudnotifier/utils/ui.dart'; import 'package:simplecloudnotifier/utils/ui.dart';
class MessageViewPage extends StatefulWidget { class MessageViewPage extends StatefulWidget {
@ -23,8 +26,11 @@ class MessageViewPage extends StatefulWidget {
class _MessageViewPageState extends State<MessageViewPage> { class _MessageViewPageState extends State<MessageViewPage> {
late Future<(Message, ChannelWithSubscription?, KeyToken?)>? mainFuture; late Future<(Message, ChannelWithSubscription?, KeyToken?)>? mainFuture;
(Message, ChannelWithSubscription?, KeyToken?)? mainFutureSnapshot = null;
static final _dateFormat = DateFormat('yyyy-MM-dd kk:mm'); static final _dateFormat = DateFormat('yyyy-MM-dd kk:mm');
bool _monospaceMode = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -38,7 +44,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
ChannelWithSubscription? chn = null; ChannelWithSubscription? chn = null;
try { try {
chn = await APIClient.getChannel(acc, msg.channelID); chn = await APIClient.getChannel(acc, msg.channelID); //TODO getShortChannel (?) -> no perm
} on APIException catch (e) { } on APIException catch (e) {
if (e.error == APIError.USER_AUTH_FAILED) { if (e.error == APIError.USER_AUTH_FAILED) {
chn = null; chn = null;
@ -49,7 +55,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
KeyToken? tok = null; KeyToken? tok = null;
try { try {
tok = await APIClient.getKeyToken(acc, msg.usedKeyID); tok = await APIClient.getKeyToken(acc, msg.usedKeyID); //TODO getShortKeyToken (?) -> no perm
} on APIException catch (e) { } on APIException catch (e) {
if (e.error == APIError.USER_AUTH_FAILED) { if (e.error == APIError.USER_AUTH_FAILED) {
tok = null; tok = null;
@ -58,7 +64,15 @@ class _MessageViewPageState extends State<MessageViewPage> {
} }
} }
return (msg, chn, tok); //TODO getShortUser for sender
//await Future.delayed(const Duration(seconds: 2), () {});
final r = (msg, chn, tok);
mainFutureSnapshot = r;
return r;
} }
@override @override
@ -71,19 +85,18 @@ class _MessageViewPageState extends State<MessageViewPage> {
return SCNScaffold( return SCNScaffold(
title: 'Message', title: 'Message',
showSearch: false, showSearch: false,
//TODO showShare: true showShare: true,
onShare: _share,
child: FutureBuilder<(Message, ChannelWithSubscription?, KeyToken?)>( child: FutureBuilder<(Message, ChannelWithSubscription?, KeyToken?)>(
future: mainFuture, future: mainFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
final msg = snapshot.data!.$1; final (msg, chn, tok) = snapshot.data!;
final chn = snapshot.data!.$2; return _buildMessageView(context, msg, chn, tok, false);
final tok = snapshot.data!.$3;
return _buildMessageView(context, msg, chn, tok);
} else if (snapshot.hasError) { } else if (snapshot.hasError) {
return Center(child: Text('${snapshot.error}')); //TODO nice error page return Center(child: Text('${snapshot.error}')); //TODO nice error page
} else if (!widget.message.trimmed) { } else if (!widget.message.trimmed) {
return _buildLoadingView(context, widget.message); return _buildMessageView(context, widget.message, null, null, true);
} else { } else {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
@ -92,39 +105,58 @@ class _MessageViewPageState extends State<MessageViewPage> {
); );
} }
Widget _buildMessageView(BuildContext context, Message message, ChannelWithSubscription? channel, KeyToken? token) { void _share() async {
//TODO loading true/false indicator var msg = widget.message;
if (mainFutureSnapshot != null) {
(msg, _, _) = mainFutureSnapshot!;
}
if (msg.content != null) {
final result = await Share.share(msg.content!, subject: msg.title);
if (result.status == ShareResultStatus.unavailable) {
Toaster.error('Error', "Failed to open share dialog");
}
} else {
final result = await Share.share(msg.title);
if (result.status == ShareResultStatus.unavailable) {
Toaster.error('Error', "Failed to open share dialog");
}
}
}
Widget _buildMessageView(BuildContext context, Message message, ChannelWithSubscription? channel, KeyToken? token, bool loading) {
final userAccUserID = context.select<AppAuth, String?>((v) => v.userID);
return SingleChildScrollView( return SingleChildScrollView(
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16), padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
..._buildMessageHeader(context, message, channel, token), ..._buildMessageHeader(context, message, channel, token, loading),
SizedBox(height: 8), SizedBox(height: 8),
if (message.content != null) ..._buildMessageContent(context, message, channel, token), if (message.content != null) ..._buildMessageContent(context, message, channel, token),
SizedBox(height: 8), SizedBox(height: 8),
if (message.senderName != null) _buildMetaCard(context, FontAwesomeIcons.solidSignature, 'Sender', [message.senderName!], () => {/*TODO*/}), if (message.senderName != null) _buildMetaCard(context, FontAwesomeIcons.solidSignature, 'Sender', [message.senderName!], () => {/*TODO*/}),
if (token != null) _buildMetaCard(context, FontAwesomeIcons.solidGearCode, 'KeyToken', [token.keytokenID, token.name], () => {/*TODO*/}), _buildMetaCard(context, FontAwesomeIcons.solidGearCode, 'KeyToken', [message.usedKeyID, if (token != null) token.name], () => {/*TODO*/}),
_buildMetaCard(context, FontAwesomeIcons.solidIdCardClip, 'MessageID', [message.messageID, if (message.userMessageID != null) message.userMessageID!], null), _buildMetaCard(context, FontAwesomeIcons.solidIdCardClip, 'MessageID', [message.messageID, if (message.userMessageID != null) message.userMessageID!], null),
if (channel != null) _buildMetaCard(context, FontAwesomeIcons.solidSnake, 'Channel', [message.channelID, channel.channel.displayName], () => {/*TODO*/}), _buildMetaCard(context, FontAwesomeIcons.solidSnake, 'Channel', [message.channelID, channel?.channel.displayName ?? message.channelInternalName], () => {/*TODO*/}),
_buildMetaCard(context, FontAwesomeIcons.solidTimer, 'Timestamp', [message.timestamp], null), _buildMetaCard(context, FontAwesomeIcons.solidTimer, 'Timestamp', [message.timestamp], null),
_buildMetaCard(context, FontAwesomeIcons.solidUser, 'User', ['TODO'], () => {/*TODO*/}), //TODO
if (message.senderUserID == userAccUserID) UI.button(text: "Delete Message", onPressed: () {/*TODO*/}, color: Colors.red[900]),
], ],
), ),
), ),
); );
} }
Widget _buildLoadingView(BuildContext context, Message message) {
//TODO loading / skeleton use limitdata
return SizedBox();
}
String _resolveChannelName(ChannelWithSubscription? channel, Message message) { String _resolveChannelName(ChannelWithSubscription? channel, Message message) {
return channel?.channel.displayName ?? message.channelInternalName; return channel?.channel.displayName ?? message.channelInternalName;
} }
List<Widget> _buildMessageHeader(BuildContext context, Message message, ChannelWithSubscription? channel, KeyToken? token) { List<Widget> _buildMessageHeader(BuildContext context, Message message, ChannelWithSubscription? channel, KeyToken? token, bool loading) {
return [ return [
Row( Row(
children: [ children: [
@ -139,7 +171,24 @@ class _MessageViewPageState extends State<MessageViewPage> {
], ],
), ),
SizedBox(height: 8), SizedBox(height: 8),
Text(message.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), if (!loading) Text(message.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
if (loading)
Stack(
children: [
Row(
children: [
Flexible(child: Text(message.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold))),
SizedBox(height: 20, width: 20),
],
),
Row(
children: [
Expanded(child: SizedBox(width: 0)),
SizedBox(child: CircularProgressIndicator(), height: 20, width: 20),
],
),
],
),
]; ];
} }
@ -147,22 +196,45 @@ class _MessageViewPageState extends State<MessageViewPage> {
return [ return [
Row( Row(
children: [ children: [
if (message.priority == 2) FaIcon(FontAwesomeIcons.solidTriangleExclamation, size: 16, color: Colors.red[900]),
if (message.priority == 0) FaIcon(FontAwesomeIcons.solidDown, size: 16, color: Colors.lightBlue[900]),
Expanded(child: SizedBox()), Expanded(child: SizedBox()),
UI.buttonIconOnly( UI.buttonIconOnly(
onPressed: () {/*TODO*/}, onPressed: () {
Clipboard.setData(new ClipboardData(text: message.content ?? ''));
Toaster.info("Clipboard", 'Copied text to Clipboard');
},
icon: FontAwesomeIcons.copy, icon: FontAwesomeIcons.copy,
), ),
UI.buttonIconOnly( UI.buttonIconOnly(
icon: FontAwesomeIcons.lineColumns, icon: _monospaceMode ? FontAwesomeIcons.lineColumns : FontAwesomeIcons.alignLeft,
onPressed: () {/*TODO*/}, onPressed: () {
setState(() {
_monospaceMode = !_monospaceMode;
});
},
), ),
], ],
), ),
UI.box( _monospaceMode
? UI.box(
context: context,
padding: const EdgeInsets.all(4),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Text(
message.content ?? '',
style: TextStyle(fontFamily: "monospace", fontFamilyFallback: <String>["Courier"]),
),
),
borderColor: (message.priority == 2) ? Colors.red[900] : null,
)
: UI.box(
context: context, context: context,
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
child: Text(message.content ?? ''), child: Text(message.content ?? ''),
), borderColor: (message.priority == 2) ? Colors.red[900] : null,
)
]; ];
} }

View File

@ -1,5 +1,4 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simplecloudnotifier/api/api_client.dart'; import 'package:simplecloudnotifier/api/api_client.dart';
import 'package:simplecloudnotifier/api/api_exception.dart'; import 'package:simplecloudnotifier/api/api_exception.dart';
import 'package:simplecloudnotifier/models/client.dart'; import 'package:simplecloudnotifier/models/client.dart';
@ -63,6 +62,8 @@ class AppAuth extends ChangeNotifier implements TokenSource {
} }
void load() { void load() {
//final cdat = Globals().sharedPrefs.getString('auth.cdate');
//final mdat = Globals().sharedPrefs.getString('auth.mdate');
final uid = Globals().sharedPrefs.getString('auth.userid'); final uid = Globals().sharedPrefs.getString('auth.userid');
final cid = Globals().sharedPrefs.getString('auth.clientid'); final cid = Globals().sharedPrefs.getString('auth.clientid');
final toka = Globals().sharedPrefs.getString('auth.tokenadmin'); final toka = Globals().sharedPrefs.getString('auth.tokenadmin');
@ -85,17 +86,23 @@ class AppAuth extends ChangeNotifier implements TokenSource {
} }
Future<void> save() async { Future<void> save() async {
final prefs = await SharedPreferences.getInstance();
if (_clientID == null || _userID == null || _tokenAdmin == null || _tokenSend == null) { if (_clientID == null || _userID == null || _tokenAdmin == null || _tokenSend == null) {
await prefs.remove('auth.userid'); await Globals().sharedPrefs.remove('auth.userid');
await prefs.remove('auth.tokenadmin'); await Globals().sharedPrefs.remove('auth.clientid');
await prefs.remove('auth.tokensend'); await Globals().sharedPrefs.remove('auth.tokenadmin');
await Globals().sharedPrefs.remove('auth.tokensend');
await Globals().sharedPrefs.setString('auth.cdate', "");
await Globals().sharedPrefs.setString('auth.mdate', DateTime.now().toIso8601String());
} else { } else {
await prefs.setString('auth.userid', _userID!); await Globals().sharedPrefs.setString('auth.userid', _userID!);
await prefs.setString('auth.clientid', _clientID!); await Globals().sharedPrefs.setString('auth.clientid', _clientID!);
await prefs.setString('auth.tokenadmin', _tokenAdmin!); await Globals().sharedPrefs.setString('auth.tokenadmin', _tokenAdmin!);
await prefs.setString('auth.tokensend', _tokenSend!); await Globals().sharedPrefs.setString('auth.tokensend', _tokenSend!);
if (Globals().sharedPrefs.getString('auth.cdate') == null) await Globals().sharedPrefs.setString('auth.cdate', DateTime.now().toIso8601String());
await Globals().sharedPrefs.setString('auth.mdate', DateTime.now().toIso8601String());
} }
Globals().sharedPrefs.setString('auth.mdate', DateTime.now().toIso8601String());
} }
Future<User> loadUser({bool force = false}) async { Future<User> loadUser({bool force = false}) async {

View File

@ -96,11 +96,11 @@ class UI {
); );
} }
static Widget box({required BuildContext context, required Widget child, required EdgeInsets? padding}) { static Widget box({required BuildContext context, required Widget child, required EdgeInsets? padding, Color? borderColor = null}) {
return Container( return Container(
padding: padding ?? EdgeInsets.all(4), padding: padding ?? EdgeInsets.all(4),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).hintColor), border: Border.all(color: borderColor ?? Theme.of(context).hintColor),
borderRadius: BorderRadius.circular(DefaultBorderRadius), borderRadius: BorderRadius.circular(DefaultBorderRadius),
), ),
child: child, child: child,

View File

@ -10,6 +10,7 @@ import firebase_core
import firebase_messaging import firebase_messaging
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 url_launcher_macos import url_launcher_macos
@ -19,6 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
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"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View File

@ -161,6 +161,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
url: "https://pub.dev"
source: hosted
version: "0.3.4+1"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -687,6 +695,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.0" version: "4.1.0"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
url: "https://pub.dev"
source: hosted
version: "9.0.0"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -30,6 +30,7 @@ dependencies:
device_info_plus: ^10.1.0 device_info_plus: ^10.1.0
toastification: ^2.0.0 toastification: ^2.0.0
uuid: ^4.4.0 uuid: ^4.4.0
share_plus: ^9.0.0
dependency_overrides: dependency_overrides:

View File

@ -7,11 +7,14 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <firebase_core/firebase_core_plugin_c_api.h> #include <firebase_core/firebase_core_plugin_c_api.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) {
FirebaseCorePluginCApiRegisterWithRegistrar( FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
firebase_core firebase_core
share_plus
url_launcher_windows url_launcher_windows
) )