Sign in & Sign up redirection

This commit is contained in:
LittleSheep 2024-04-14 00:03:50 +08:00
parent 5c32f7856f
commit 1f415ec3ac
20 changed files with 609 additions and 46 deletions

View File

@ -1,9 +1,14 @@
PODS: PODS:
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_secure_storage (6.0.0):
- Flutter
- media_kit_video (0.0.1): - media_kit_video (0.0.1):
- Flutter - Flutter
- package_info_plus (0.4.5): - package_info_plus (0.4.5):
- Flutter - Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- screen_brightness_ios (0.1.0): - screen_brightness_ios (0.1.0):
- Flutter - Flutter
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
@ -15,24 +20,33 @@ PODS:
- Flutter - Flutter
- wakelock_plus (0.0.1): - wakelock_plus (0.0.1):
- Flutter - Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
DEPENDENCIES: DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`) - media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`) - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
- volume_controller (from `.symlinks/plugins/volume_controller/ios`) - volume_controller (from `.symlinks/plugins/volume_controller/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
EXTERNAL SOURCES: EXTERNAL SOURCES:
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
media_kit_video: media_kit_video:
:path: ".symlinks/plugins/media_kit_video/ios" :path: ".symlinks/plugins/media_kit_video/ios"
package_info_plus: package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios" :path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
screen_brightness_ios: screen_brightness_ios:
:path: ".symlinks/plugins/screen_brightness_ios/ios" :path: ".symlinks/plugins/screen_brightness_ios/ios"
url_launcher_ios: url_launcher_ios:
@ -43,16 +57,21 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/volume_controller/ios" :path: ".symlinks/plugins/volume_controller/ios"
wakelock_plus: wakelock_plus:
:path: ".symlinks/plugins/wakelock_plus/ios" :path: ".symlinks/plugins/wakelock_plus/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
media_kit_video: 26c5b265a4094a2df3e8d41e6724d9b964c13151 media_kit_video: 26c5b265a4094a2df3e8d41e6724d9b964c13151
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625 screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586 url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586
video_player_avfoundation: 2b4384f3b157206b5e150a0083cdc0c905d260d3 video_player_avfoundation: 2b4384f3b157206b5e150a0083cdc0c905d260d3
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9 volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
webview_flutter_wkwebview: be0f0d33777f1bfd0c9fdcb594786704dbf65f36
PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796

View File

@ -1,4 +1,9 @@
{ {
"solian": "Solian", "solian": "Solian",
"explore": "Explore" "explore": "Explore",
"account": "Account",
"signIn": "Sign In",
"signInCaption": "Sign in to create post, start a realm, message your friend and more!",
"signUp": "Sign Up",
"signUpCaption": "Create an account on Solarpass and then get the access of entire Solar Networks!"
} }

View File

@ -1,4 +1,9 @@
{ {
"solian": "索链", "solian": "索链",
"explore": "探索" "explore": "探索",
"account": "账号",
"signIn": "登陆",
"signInCaption": "登陆以发表帖子、文章、创建领域、和你的朋友聊天,以及获取更多功能!",
"signUp": "注册",
"signUpCaption": "在 Solarpass 注册一个账号以获得整个 Solar Networks 的存取权!"
} }

View File

@ -1,9 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:solian/providers/layout_provider.dart'; import 'package:solian/providers/auth.dart';
import 'package:solian/router.dart'; import 'package:solian/router.dart';
import 'package:solian/utils/timeago.dart'; import 'package:solian/utils/timeago.dart';
import 'package:solian/widgets/wrapper.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
void main() { void main() {
@ -33,11 +32,9 @@ class SolianApp extends StatelessWidget {
OverlayEntry(builder: (context) { OverlayEntry(builder: (context) {
return MultiProvider( return MultiProvider(
providers: [ providers: [
Provider(create: (_) => LayoutConfig(context)) Provider(create: (_) => AuthProvider()),
], ],
child: LayoutWrapper( child: child,
child: child,
),
); );
}) })
], ],

132
lib/providers/auth.dart Executable file
View File

@ -0,0 +1,132 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:solian/screens/auth.dart';
import 'package:oauth2/oauth2.dart' as oauth2;
import 'package:solian/utils/service_url.dart';
final authClient = AuthProvider();
class AuthProvider {
AuthProvider();
final deviceEndpoint =
getRequestUri('passport', '/api/notifications/subscribe');
final authorizationEndpoint = getRequestUri('passport', '/auth/o/connect');
final tokenEndpoint = getRequestUri('passport', '/api/auth/token');
final userinfoEndpoint = getRequestUri('passport', '/api/users/me');
final redirectUrl = Uri.parse('solian://auth');
static const clientId = "solian";
static const clientSecret = "_F4%q2Eea3";
static const storage = FlutterSecureStorage();
static const storageKey = "identity";
static const profileKey = "profiles";
oauth2.Client? client;
DateTime? lastRefreshedAt;
Future<bool> pickClient() async {
if (await storage.containsKey(key: storageKey)) {
try {
var credentials =
oauth2.Credentials.fromJson((await storage.read(key: storageKey))!);
client = oauth2.Client(credentials,
identifier: clientId, secret: clientSecret);
await fetchProfiles();
return true;
} catch (e) {
signOff();
return false;
}
} else {
return false;
}
}
Future<oauth2.Client> createClient(BuildContext context) async {
// If logged in
if (await pickClient()) {
return client!;
}
var grant = oauth2.AuthorizationCodeGrant(
clientId,
authorizationEndpoint,
tokenEndpoint,
secret: clientSecret,
basicAuth: false,
);
var authorizationUrl = grant.getAuthorizationUrl(redirectUrl, scopes: ["openid"]);
if (Platform.isAndroid || Platform.isIOS) {
// Use WebView to get authorization url
var responseUrl = await Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(
builder: (context) => AuthorizationScreen(authorizationUrl),
),
);
var responseUri = Uri.parse(responseUrl);
return await grant
.handleAuthorizationResponse(responseUri.queryParameters);
} else {
throw UnimplementedError("unsupported platform");
}
}
Future<void> fetchProfiles() async {
if (client != null) {
var userinfo = await client!.get(userinfoEndpoint);
storage.write(key: profileKey, value: utf8.decode(userinfo.bodyBytes));
}
}
Future<void> refreshToken() async {
if (client != null) {
var credentials = await client?.credentials.refresh(
identifier: clientId, secret: clientSecret, basicAuth: false);
storage.write(key: storageKey, value: credentials!.toJson());
}
}
Future<void> signIn(BuildContext context) async {
client = await createClient(context);
storage.write(key: storageKey, value: client!.credentials.toJson());
await fetchProfiles();
}
void signOff() {
storage.delete(key: profileKey);
storage.delete(key: storageKey);
}
Future<bool> isAuthorized() async {
const storage = FlutterSecureStorage();
if (await storage.containsKey(key: storageKey)) {
if (client != null) {
if (lastRefreshedAt == null ||
lastRefreshedAt!
.add(const Duration(minutes: 3))
.isAfter(DateTime.now())) {
await refreshToken();
lastRefreshedAt = DateTime.now();
}
}
return true;
} else {
return false;
}
}
Future<dynamic> getProfiles() async {
const storage = FlutterSecureStorage();
return jsonDecode(await storage.read(key: profileKey) ?? "{}");
}
}

View File

@ -1,10 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class LayoutConfig {
String title = "Solian";
LayoutConfig(BuildContext context) {
title = AppLocalizations.of(context)!.solian;
}
}

View File

@ -1,4 +1,5 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:solian/screens/account.dart';
import 'package:solian/screens/explore.dart'; import 'package:solian/screens/explore.dart';
final router = GoRouter( final router = GoRouter(
@ -8,5 +9,10 @@ final router = GoRouter(
name: 'explore', name: 'explore',
builder: (context, state) => const ExploreScreen(), builder: (context, state) => const ExploreScreen(),
), ),
GoRoute(
path: '/account',
name: 'account',
builder: (context, state) => const AccountScreen(),
),
], ],
); );

202
lib/screens/account.dart Normal file
View File

@ -0,0 +1,202 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:solian/providers/auth.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:solian/utils/service_url.dart';
import 'package:solian/widgets/wrapper.dart';
import 'package:url_launcher/url_launcher.dart';
class AccountScreen extends StatefulWidget {
const AccountScreen({super.key});
@override
State<AccountScreen> createState() => _AccountScreenState();
}
class _AccountScreenState extends State<AccountScreen> {
bool isAuthorized = false;
@override
void initState() {
Future.delayed(Duration.zero, () async {
var authorized = await context.read<AuthProvider>().isAuthorized();
setState(() => isAuthorized = authorized);
});
super.initState();
}
@override
Widget build(BuildContext context) {
final auth = context.watch<AuthProvider>();
return LayoutWrapper(
title: AppLocalizations.of(context)!.account,
child: isAuthorized
? Column(
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 24),
child: NameCard(),
),
InkWell(
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 18),
child: ListTile(
leading: Icon(Icons.logout),
title: Text("Sign out"),
),
),
onTap: () {
auth.signOff();
setState(() {
isAuthorized = false;
});
},
)
],
)
: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ActionCard(
icon: const Icon(Icons.login, color: Colors.white),
title: AppLocalizations.of(context)!.signIn,
caption: AppLocalizations.of(context)!.signInCaption,
onTap: () {
auth.signIn(context).then((_) {
authClient.isAuthorized().then((val) {
setState(() => isAuthorized = val);
});
});
},
),
ActionCard(
icon: const Icon(Icons.plus_one, color: Colors.white),
title: AppLocalizations.of(context)!.signUp,
caption: AppLocalizations.of(context)!.signUpCaption,
onTap: () {
launchUrl(getRequestUri('passport', '/auth/sign-up'));
},
),
],
),
),
);
}
}
class NameCard extends StatelessWidget {
const NameCard({super.key});
Future<Widget> renderAvatar() async {
final profiles = await authClient.getProfiles();
return CircleAvatar(backgroundImage: NetworkImage(profiles["picture"]));
}
Future<Column> renderLabel() async {
final profiles = await authClient.getProfiles();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
profiles["nick"],
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(profiles["email"])
],
);
}
@override
Widget build(BuildContext context) {
return Card(
child: InkWell(
splashColor: Colors.indigo.withAlpha(30),
child: Padding(
padding: const EdgeInsets.all(20),
child: Row(
children: [
FutureBuilder(
future: renderAvatar(),
builder:
(BuildContext context, AsyncSnapshot<Widget> snapshot) {
if (snapshot.hasData) {
return snapshot.data!;
} else {
return const CircularProgressIndicator();
}
},
),
const SizedBox(width: 20),
FutureBuilder(
future: renderLabel(),
builder:
(BuildContext context, AsyncSnapshot<Column> snapshot) {
if (snapshot.hasData) {
return snapshot.data!;
} else {
return const Column();
}
},
)
],
),
),
),
);
}
}
class ActionCard extends StatelessWidget {
final Widget icon;
final String title;
final String caption;
final Function onTap;
const ActionCard(
{super.key,
required this.onTap,
required this.title,
required this.caption,
required this.icon});
@override
Widget build(BuildContext context) {
return Card(
child: InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () => onTap(),
child: Container(
width: 320,
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: CircleAvatar(
backgroundColor: Colors.indigo,
child: icon,
),
),
Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w900,
),
),
Text(caption),
],
),
),
),
);
}
}

41
lib/screens/auth.dart Executable file
View File

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class AuthorizationScreen extends StatelessWidget {
final Uri authorizationUrl;
const AuthorizationScreen(this.authorizationUrl, {super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.signIn),
),
body: Stack(children: [
WebViewWidget(
controller: WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(Colors.white)
..setNavigationDelegate(NavigationDelegate(
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('solian')) {
Navigator.of(context).pop(request.url);
WebViewCookieManager().clearCookies();
return NavigationDecision.prevent;
} else if (request.url.contains("sign-up")) {
launchUrl(Uri.parse(request.url));
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
))
..loadRequest(authorizationUrl)
..clearCache(),
),
]),
);
}
}

View File

@ -1,15 +1,14 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:solian/models/pagination.dart'; import 'package:solian/models/pagination.dart';
import 'package:solian/models/post.dart'; import 'package:solian/models/post.dart';
import 'package:solian/utils/service_url.dart'; import 'package:solian/utils/service_url.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:solian/providers/layout_provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:solian/widgets/posts/item.dart'; import 'package:solian/widgets/posts/item.dart';
import 'package:solian/widgets/wrapper.dart';
class ExploreScreen extends StatefulWidget { class ExploreScreen extends StatefulWidget {
const ExploreScreen({super.key}); const ExploreScreen({super.key});
@ -51,12 +50,6 @@ class _ExploreScreenState extends State<ExploreScreen> {
@override @override
void initState() { void initState() {
Future.delayed(Duration.zero, () {
// Wait for the context
context.read<LayoutConfig>().title =
AppLocalizations.of(context)!.explore;
});
super.initState(); super.initState();
_pagingController.addPageRequestListener((pageKey) => fetchFeed(pageKey)); _pagingController.addPageRequestListener((pageKey) => fetchFeed(pageKey));
@ -64,18 +57,21 @@ class _ExploreScreenState extends State<ExploreScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return RefreshIndicator( return LayoutWrapper(
onRefresh: () => Future.sync( title: AppLocalizations.of(context)!.explore,
() => _pagingController.refresh(), child: RefreshIndicator(
), onRefresh: () => Future.sync(
child: Center( () => _pagingController.refresh(),
child: Container( ),
constraints: const BoxConstraints(maxWidth: 720), child: Center(
child: PagedListView<int, Post>.separated( child: Container(
pagingController: _pagingController, constraints: const BoxConstraints(maxWidth: 720),
separatorBuilder: (context, index) => const Divider(thickness: 0.3), child: PagedListView<int, Post>.separated(
builderDelegate: PagedChildBuilderDelegate<Post>( pagingController: _pagingController,
itemBuilder: (context, item, index) => PostItem(item: item), separatorBuilder: (context, index) => const Divider(thickness: 0.3),
builderDelegate: PagedChildBuilderDelegate<Post>(
itemBuilder: (context, item, index) => PostItem(item: item),
),
), ),
), ),
), ),

View File

@ -27,6 +27,13 @@ class _SolianNavigationDrawerState extends State<SolianNavigationDrawer> {
), ),
"explore", "explore",
), ),
(
NavigationDrawerDestination(
icon: const Icon(Icons.account_circle),
label: Text(AppLocalizations.of(context)!.account),
),
"account",
),
]; ];
return NavigationDrawer( return NavigationDrawer(

View File

@ -36,8 +36,6 @@ class _PostItemState extends State<PostItem> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const borderRadius = Radius.circular(16);
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Column( child: Column(

View File

@ -1,20 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:solian/providers/layout_provider.dart';
import 'package:solian/widgets/navigation_drawer.dart'; import 'package:solian/widgets/navigation_drawer.dart';
class LayoutWrapper extends StatelessWidget { class LayoutWrapper extends StatelessWidget {
final Widget? child; final Widget? child;
final String title;
const LayoutWrapper({super.key, this.child}); const LayoutWrapper({super.key, this.child, required this.title});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var cfg = context.watch<LayoutConfig>();
return Scaffold( return Scaffold(
drawer: const SolianNavigationDrawer(), drawer: const SolianNavigationDrawer(),
appBar: AppBar(title: Text(cfg.title)), appBar: AppBar(title: Text(title)),
body: child ?? Container(), body: child ?? Container(),
); );
} }

View File

@ -6,10 +6,14 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <media_kit_video/media_kit_video_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) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
g_autoptr(FlPluginRegistrar) media_kit_video_registrar = g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar); media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);

View File

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_linux
media_kit_video media_kit_video
url_launcher_linux url_launcher_linux
) )

View File

@ -5,16 +5,20 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import flutter_secure_storage_macos
import media_kit_video import media_kit_video
import package_info_plus import package_info_plus
import path_provider_foundation
import screen_brightness_macos import screen_brightness_macos
import url_launcher_macos import url_launcher_macos
import video_player_avfoundation import video_player_avfoundation
import wakelock_plus import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin")) MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))

View File

@ -163,6 +163,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.22+1" version: "0.6.22+1"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685
url: "https://pub.dev"
source: hosted
version: "9.0.0"
flutter_secure_storage_linux:
dependency: transitive
description:
name: flutter_secure_storage_linux
sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
flutter_secure_storage_macos:
dependency: transitive
description:
name: flutter_secure_storage_macos
sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
url: "https://pub.dev"
source: hosted
version: "3.0.1"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
flutter_staggered_grid_view: flutter_staggered_grid_view:
dependency: transitive dependency: transitive
description: description:
@ -341,6 +389,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
oauth2:
dependency: "direct main"
description:
name: oauth2
sha256: c4013ef62be37744efdc0861878fd9e9285f34db1f9e331cc34100d7674feb42
url: "https://pub.dev"
source: hosted
version: "2.0.2"
package_info_plus: package_info_plus:
dependency: transitive dependency: transitive
description: description:
@ -365,6 +421,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.9.0"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
url: "https://pub.dev"
source: hosted
version: "2.1.3"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
url: "https://pub.dev"
source: hosted
version: "2.2.4"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
@ -373,6 +477,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.2" version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -722,6 +834,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.5.1"
webview_flutter:
dependency: "direct main"
description:
name: webview_flutter
sha256: "25e1b6e839e8cbfbd708abc6f85ed09d1727e24e08e08c6b8590d7c65c9a8932"
url: "https://pub.dev"
source: hosted
version: "4.7.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: f038ee2fae73b509dde1bc9d2c5a50ca92054282de17631a9a3d515883740934
url: "https://pub.dev"
source: hosted
version: "3.16.0"
webview_flutter_platform_interface:
dependency: transitive
description:
name: webview_flutter_platform_interface
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
url: "https://pub.dev"
source: hosted
version: "2.10.0"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: f12f8d8a99784b863e8b85e4a9a5e3cf1839d6803d2c0c3e0533a8f3c5a992a7
url: "https://pub.dev"
source: hosted
version: "3.13.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:
@ -730,6 +874,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.4.0" version: "5.4.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.4"
xml: xml:
dependency: transitive dependency: transitive
description: description:

View File

@ -50,6 +50,9 @@ dependencies:
media_kit_video: ^1.2.4 media_kit_video: ^1.2.4
chewie: ^1.8.1 chewie: ^1.8.1
video_player: ^2.8.6 video_player: ^2.8.6
flutter_secure_storage: ^9.0.0
oauth2: ^2.0.2
webview_flutter: ^4.7.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -6,11 +6,14 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <media_kit_video/media_kit_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_brightness_windows/screen_brightness_windows_plugin.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) {
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
MediaKitVideoPluginCApiRegisterWithRegistrar( MediaKitVideoPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi")); registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi"));
ScreenBrightnessWindowsPluginRegisterWithRegistrar( ScreenBrightnessWindowsPluginRegisterWithRegistrar(

View File

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_windows
media_kit_video media_kit_video
screen_brightness_windows screen_brightness_windows
url_launcher_windows url_launcher_windows