From d44bba99f0b5c14c323598f3929ade8780d36f31 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 27 May 2024 17:09:50 +0200 Subject: [PATCH] Must be a temporary version => changed the front pageto be able to show the data from the database --- android/app/src/main/AndroidManifest.xml | 3 + lib/main.dart | 133 ++++++++++++- lib/screens/account_page.dart | 163 ++++++++++++++++ lib/screens/details.dart | 36 +++- lib/screens/home.dart | 2 +- lib/screens/login_page.dart | 102 ++++++++++ lib/screens/splash_page.dart | 38 ++++ lib/utils/constants.dart | 95 ++-------- lib/utils/data.dart | 177 +++++++++++++++++- linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Podfile.lock | 42 +++++ macos/Runner.xcodeproj/project.pbxproj | 100 +++++++++- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../contents.xcworkspacedata | 3 + pubspec.lock | 112 +++++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 20 files changed, 923 insertions(+), 97 deletions(-) create mode 100644 lib/screens/account_page.dart create mode 100644 lib/screens/login_page.dart create mode 100644 lib/screens/splash_page.dart create mode 100644 macos/Podfile.lock diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 4662933..a752976 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,4 +30,7 @@ android:name="flutterEmbedding" android:value="2" /> + + + diff --git a/lib/main.dart b/lib/main.dart index 94679f0..3dd3002 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,26 +1,80 @@ import 'package:flutter/material.dart'; import 'package:learn_project/screens/home.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:learn_project/screens/account_page.dart'; +import 'package:learn_project/screens/login_page.dart'; +import 'package:learn_project/screens/splash_page.dart'; +import 'utils/constants.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Supabase.initialize( - url: 'http://192.168.179.86:8000/', - anonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ2dGVmcWRxYWhjcHpnb2x2dXB2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTYwMjE2NTIsImV4cCI6MjAzMTU5NzY1Mn0.1bp5V61Oguo5zLUhCFJmCabUY1sujeISr_CR2XUKvh4', + url: 'http://192.168.179.86:8000/',//'https://vvtefqdqahcpzgolvupv.supabase.co',//'https://vvtefqdqahcpzgolvupv.supabase.co',// + anonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ2dGVmcWRxYWhjcHpnb2x2dXB2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTYwMjE2NTIsImV4cCI6MjAzMTU5NzY1Mn0.1bp5V61Oguo5zLUhCFJmCabUY1sujeISr_CR2XUKvh4',//'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ2dGVmcWRxYWhjcHpnb2x2dXB2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTYwMjE3ODksImV4cCI6MjAzMTU5Nzc4OX0.6g5EtS9HrgxC6cpCYgOT0HLpA4lEnASQbKs9mfnUM7k',//Constants.supabaseAnnonKey,// ); - runApp(const MyApp()); + runApp( MyApp()); } - /// Supabase client final supabase = Supabase.instance.client; /// Error message to display the user when unexpected error occurs. const unexpectedErrorMessage = 'Unexpected error occurred.'; + class MyApp extends StatelessWidget { const MyApp({super.key}); @override + Widget build(BuildContext context) { + return const MaterialApp( + title: 'Events', + home: HomePage(), + ); + } +} + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + final _future = Supabase.instance.client + .from('events') + .select(); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: FutureBuilder( + future: _future, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + final events = snapshot.data!; + return ListView.builder( + itemCount: events.length, + itemBuilder: ((context, index) { + final event = events[index]; + return ListTile( + title: Text(event['name']), + subtitle: Text(event['description']), + ); + }), + ); + }, + ), + ); + } +} + +/* class MyApp extends StatelessWidget { */ + //MyApp({super.key}); + + /* @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, @@ -33,5 +87,74 @@ class MyApp extends StatelessWidget { ), home: const HomePage(), ); - } + } */ + + + + /* @override + Widget build(BuildContext context) { + + return MaterialApp( + title: 'Supabase Flutter', + theme: ThemeData.dark().copyWith( + primaryColor: Colors.green, + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: Colors.green, + ), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: Colors.green, + ), + ), + ), + initialRoute: '/', + routes: { + '/': (_) => const SplashPage(), + '/login': (_) => const LoginPage(), + '/account': (_) => const AccountPage(), + }, + ); + } */ +/* Future readData() async { + final response = await Supabase.instance.client.from('events').select(); + if (response.error == null) { + final data = response.data; + print('Fetched data: $data'); + } else { + print('Error reading data: ${response.error!.message}'); + }} + + final _future = Supabase.instance.client + .from('events') + .select(); + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: Scaffold( + appBar: AppBar( + title: Text('Home Page'), + ), + body: FutureBuilder( + future: _future, + builder: (context, snapshot) { + } + final countries = snapshot.data!; + return ListView.builder( + itemCount: countries.length, + itemBuilder: ((context, index) { + final country = countries[index]; + return ListTile( + title: Text(country['name']), + ); + }), + );}))); + } +} + +class _execute { +}*/ \ No newline at end of file diff --git a/lib/screens/account_page.dart b/lib/screens/account_page.dart new file mode 100644 index 0000000..b8d8b4e --- /dev/null +++ b/lib/screens/account_page.dart @@ -0,0 +1,163 @@ +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:learn_project/main.dart'; + +class AccountPage extends StatefulWidget { + const AccountPage({super.key}); + + @override + State createState() => _AccountPageState(); +} + +class _AccountPageState extends State { + final _usernameController = TextEditingController(); + final _websiteController = TextEditingController(); + + var _loading = true; + + /// Called once a user id is received within `onAuthenticated()` + Future _getProfile() async { + setState(() { + _loading = true; + }); + + try { + final userId = supabase.auth.currentUser!.id; + final data = + await supabase.from('profiles').select().eq('id', userId).single(); + _usernameController.text = (data['username'] ?? '') as String; + _websiteController.text = (data['website'] ?? '') as String; + } on PostgrestException catch (error) { + if (mounted) { + SnackBar( + content: Text(error.message), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } catch (error) { + if (mounted) { + SnackBar( + content: const Text('Unexpected error occurred'), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } finally { + if (mounted) { + setState(() { + _loading = false; + }); + } + } + } + + /// Called when user taps `Update` button + Future _updateProfile() async { + setState(() { + _loading = true; + }); + final userName = _usernameController.text.trim(); + final website = _websiteController.text.trim(); + final user = supabase.auth.currentUser; + final updates = { + 'id': user!.id, + 'username': userName, + 'website': website, + 'updated_at': DateTime.now().toIso8601String(), + }; + try { + await supabase.from('profiles').upsert(updates); + if (mounted) { + const SnackBar( + content: Text('Successfully updated profile!'), + ); + } + } on PostgrestException catch (error) { + if (mounted) { + SnackBar( + content: Text(error.message), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } catch (error) { + if (mounted) { + SnackBar( + content: const Text('Unexpected error occurred'), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } finally { + if (mounted) { + setState(() { + _loading = false; + }); + } + } + } + + Future _signOut() async { + try { + await supabase.auth.signOut(); + } on AuthException catch (error) { + if (mounted) { + SnackBar( + content: Text(error.message), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } catch (error) { + if (mounted) { + SnackBar( + content: const Text('Unexpected error occurred'), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } finally { + if (mounted) { + Navigator.of(context).pushReplacementNamed('/login'); + } + } + } + + @override + void initState() { + super.initState(); + _getProfile(); + } + + @override + void dispose() { + _usernameController.dispose(); + _websiteController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Profile')), + body: _loading + ? const Center(child: CircularProgressIndicator()) + : ListView( + padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12), + children: [ + TextFormField( + controller: _usernameController, + decoration: const InputDecoration(labelText: 'User Name'), + ), + const SizedBox(height: 18), + TextFormField( + controller: _websiteController, + decoration: const InputDecoration(labelText: 'Website'), + ), + const SizedBox(height: 18), + ElevatedButton( + onPressed: _loading ? null : _updateProfile, + child: Text(_loading ? 'Saving...' : 'Update'), + ), + const SizedBox(height: 18), + TextButton(onPressed: _signOut, child: const Text('Sign Out')), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/details.dart b/lib/screens/details.dart index c18428a..9580eea 100644 --- a/lib/screens/details.dart +++ b/lib/screens/details.dart @@ -1,12 +1,38 @@ import 'package:flutter/material.dart'; import 'package:learn_project/utils/class.dart'; import 'package:learn_project/utils/widgets.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; class DetailsPage extends StatelessWidget { - final Recipe recipe; - const DetailsPage({required this.recipe}); - - @override + //final Recipe recipe; + final _future = Supabase.instance.client + .from('events') + .select(); + //const DetailsPage({required this.recipe}); + @override + Widget build(BuildContext context) { + return Scaffold( + body: FutureBuilder( + future: _future, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + final events = snapshot.data!; + return ListView.builder( + itemCount: events.length, + itemBuilder: ((context, index) { + final event = events[index]; + return ListTile( + title: Text(event['name']), + ); + }), + ); + }, + ), + ); + } + /* @override Widget build(BuildContext context) { return Scaffold( body: NestedScrollView( @@ -69,7 +95,7 @@ class DetailsPage extends StatelessWidget { ), ), ); - } + } */ } class RecipeSteps extends StatelessWidget { diff --git a/lib/screens/home.dart b/lib/screens/home.dart index f9411e9..0b5da6e 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -144,7 +144,7 @@ class HomePage extends StatelessWidget { context, MaterialPageRoute( builder: (context) => DetailsPage( - recipe: Data.recipes[index], + //_future: Data.recipes[index], ))); }, child: Card( diff --git a/lib/screens/login_page.dart b/lib/screens/login_page.dart new file mode 100644 index 0000000..23e01c0 --- /dev/null +++ b/lib/screens/login_page.dart @@ -0,0 +1,102 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:learn_project/main.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + bool _isLoading = false; + bool _redirecting = false; + late final TextEditingController _emailController = TextEditingController(); + late final StreamSubscription _authStateSubscription; + + Future _signIn() async { + try { + setState(() { + _isLoading = true; + }); + await supabase.auth.signInWithOtp( + email: _emailController.text.trim(), + emailRedirectTo: + kIsWeb ? null : 'io.supabase.flutterquickstart://login-callback/', + ); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Check your email for a login link!')), + ); + _emailController.clear(); + } + } on AuthException catch (error) { + if (mounted) { + SnackBar( + content: Text(error.message), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } catch (error) { + if (mounted) { + SnackBar( + content: const Text('Unexpected error occurred'), + backgroundColor: Theme.of(context).colorScheme.error, + ); + } + } finally { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } + } + + @override + void initState() { + _authStateSubscription = supabase.auth.onAuthStateChange.listen((data) { + if (_redirecting) return; + final session = data.session; + if (session != null) { + _redirecting = true; + Navigator.of(context).pushReplacementNamed('/account'); + } + }); + super.initState(); + } + + @override + void dispose() { + _emailController.dispose(); + _authStateSubscription.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Sign In')), + body: ListView( + padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12), + children: [ + const Text('Sign in via the magic link with your email below'), + const SizedBox(height: 18), + TextFormField( + controller: _emailController, + decoration: const InputDecoration(labelText: 'Email'), + ), + const SizedBox(height: 18), + ElevatedButton( + onPressed: _isLoading ? null : _signIn, + child: Text(_isLoading ? 'Loading' : 'Send Magic Link'), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/splash_page.dart b/lib/screens/splash_page.dart new file mode 100644 index 0000000..2bfffdf --- /dev/null +++ b/lib/screens/splash_page.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:learn_project/main.dart'; + +class SplashPage extends StatefulWidget { + const SplashPage({super.key}); + + @override + State createState() => _SplashPageState(); +} + +class _SplashPageState extends State { + @override + void initState() { + super.initState(); + _redirect(); + } + + Future _redirect() async { + await Future.delayed(Duration.zero); + if (!mounted) { + return; + } + + final session = supabase.auth.currentSession; + if (session != null) { + Navigator.of(context).pushReplacementNamed('/account'); + } else { + Navigator.of(context).pushReplacementNamed('/login'); + } + } + + @override + Widget build(BuildContext context) { + return const Scaffold( + body: Center(child: CircularProgressIndicator()), + ); + } +} \ No newline at end of file diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart index ec5ccce..8e26a98 100644 --- a/lib/utils/constants.dart +++ b/lib/utils/constants.dart @@ -1,83 +1,14 @@ -import 'package:flutter/material.dart'; -import 'package:supabase_flutter/supabase_flutter.dart'; +/// Environment variables and shared app constants. +abstract class Constants { + static const String supabaseUrl = String.fromEnvironment( + //'http://192.168.179.86:8000/', //local + 'https://vvtefqdqahcpzgolvupv.supabase.co', + //defaultValue: '', + ); -/// Supabase client -final supabase = Supabase.instance.client; - -/// Simple preloader inside a Center widget -const preloader = - Center(child: CircularProgressIndicator(color: Colors.orange)); - -/// Simple sized box to space out form elements -const formSpacer = SizedBox(width: 16, height: 16); - -/// Some padding for all the forms to use -const formPadding = EdgeInsets.symmetric(vertical: 20, horizontal: 16); - -/// Error message to display the user when unexpected error occurs. -const unexpectedErrorMessage = 'Unexpected error occurred.'; - -/// Basic theme to change the look and feel of the app -final appTheme = ThemeData.light().copyWith( - primaryColorDark: Colors.orange, - appBarTheme: const AppBarTheme( - elevation: 1, - backgroundColor: Colors.white, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - ), - ), - primaryColor: Colors.orange, - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: Colors.orange, - ), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.orange, - ), - ), - inputDecorationTheme: InputDecorationTheme( - floatingLabelStyle: const TextStyle( - color: Colors.orange, - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide( - color: Colors.grey, - width: 2, - ), - ), - focusColor: Colors.orange, - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide( - color: Colors.orange, - width: 2, - ), - ), - ), -); - -/// Set of extension methods to easily display a snackbar -extension ShowSnackBar on BuildContext { - /// Displays a basic snackbar - void showSnackBar({ - required String message, - Color backgroundColor = Colors.white, - }) { - ScaffoldMessenger.of(this).showSnackBar(SnackBar( - content: Text(message), - backgroundColor: backgroundColor, - )); - } - - /// Displays a red snackbar indicating error - void showErrorSnackBar({required String message}) { - showSnackBar(message: message, backgroundColor: Colors.red); - } -} + static const String supabaseAnnonKey = String.fromEnvironment( + //'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ2dGVmcWRxYWhjcHpnb2x2dXB2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTYwMjE2NTIsImV4cCI6MjAzMTU5NzY1Mn0.1bp5V61Oguo5zLUhCFJmCabUY1sujeISr_CR2XUKvh4', // local + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ2dGVmcWRxYWhjcHpnb2x2dXB2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTYwMjE3ODksImV4cCI6MjAzMTU5Nzc4OX0.6g5EtS9HrgxC6cpCYgOT0HLpA4lEnASQbKs9mfnUM7k', + //defaultValue: '', + ); +} \ No newline at end of file diff --git a/lib/utils/data.dart b/lib/utils/data.dart index a2ef953..a3ea1e2 100644 --- a/lib/utils/data.dart +++ b/lib/utils/data.dart @@ -1,5 +1,9 @@ -import 'package:learn_project/utils/class.dart'; +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:learn_project/utils/class.dart'; +const Duration fakeAPIDuration = Duration(milliseconds: 50); +const Duration debounceDuration = Duration(milliseconds: 50); class Data { static List recipes = [ Recipe( @@ -124,4 +128,175 @@ class Data { '4 ounces milk' ]), ]; + + + + } + + +/* class _AsyncAutocomplete extends StatefulWidget { + const _AsyncAutocomplete(); + + @override + State<_AsyncAutocomplete> createState() => _AsyncAutocompleteState(); +} + +class _AsyncAutocompleteState extends State<_AsyncAutocomplete> { + // The query currently being searched for. If null, there is no pending + // request. + String? _currentQuery; + + // The most recent options received from the API. + late Iterable _lastOptions = []; + + late final _Debounceable?, String> _debouncedSearch; + + // Whether to consider the fake network to be offline. + bool _networkEnabled = true; + + // A network error was recieved on the most recent query. + bool _networkError = false; + + // Calls the "remote" API to search with the given query. Returns null when + // the call has been made obsolete. + Future?> _search(String query) async { + _currentQuery = query; + + late final Iterable options; + try { + options = await _FakeAPI.search(_currentQuery!, _networkEnabled); + } catch (error) { + if (error is _NetworkException) { + setState(() { + _networkError = true; + }); + return []; + } + rethrow; + } + + // If another search happened after this one, throw away these options. + if (_currentQuery != query) { + return null; + } + _currentQuery = null; + + return options; + } + + @override + Widget build(BuildContext context) { + // TODO: implement build + throw UnimplementedError(); + } +} + // Mimics a remote API. +class _FakeAPI { + static const List _kOptions = [ + 'ingolstadt', + 'jesuitenstraße', + 'eiskeller', + ]; + + // Searches the options, but injects a fake "network" delay. + static Future> search( + String query, bool networkEnabled) async { + await Future.delayed(fakeAPIDuration); // Fake 1 second delay. + if (!networkEnabled) { + throw const _NetworkException(); + } + if (query == '') { + return const Iterable.empty(); + } + return _kOptions.where((String option) { + return option.contains(query.toLowerCase()); + }); + } +} + +typedef _Debounceable = Future Function(T parameter); + +/// Returns a new function that is a debounced version of the given function. +/// +/// This means that the original function will be called only after no calls +/// have been made for the given Duration. +_Debounceable _debounce(_Debounceable function) { + _DebounceTimer? debounceTimer; + + return (T parameter) async { + if (debounceTimer != null && !debounceTimer!.isCompleted) { + debounceTimer!.cancel(); + } + debounceTimer = _DebounceTimer(); + try { + await debounceTimer!.future; + } catch (error) { + if (error is _CancelException) { + return null; + } + rethrow; + } + return function(parameter); + }; +} + +// A wrapper around Timer used for debouncing. +class _DebounceTimer { + _DebounceTimer() { + _timer = Timer(debounceDuration, _onComplete); + } + + late final Timer _timer; + final Completer _completer = Completer(); + + void _onComplete() { + _completer.complete(); + } + + Future get future => _completer.future; + + bool get isCompleted => _completer.isCompleted; + + void cancel() { + _timer.cancel(); + _completer.completeError(const _CancelException()); + } +} + +// An exception indicating that the timer was canceled. +class _CancelException implements Exception { + const _CancelException(); +} + +// An exception indicating that a network request has failed. +class _NetworkException implements Exception { + const _NetworkException(); +} + final _future = Supabase.instance.client + .from('countries') + .select(); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: FutureBuilder( + future: _future, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + final countries = snapshot.data!; + return ListView.builder( + itemCount: countries.length, + itemBuilder: ((context, index) { + final country = countries[index]; + return ListTile( + title: Text(country['name']), + ); + }), + ); + }, + ), + ); + } */ \ No newline at end of file diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 3792af4..e12c657 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,10 +6,14 @@ #include "generated_plugin_registrant.h" +#include #include #include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); g_autoptr(FlPluginRegistrar) gtk_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); gtk_plugin_register_with_registrar(gtk_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 5d07423..4453582 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_linux gtk url_launcher_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 92b6497..d32ccbe 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,12 +6,14 @@ import FlutterMacOS import Foundation import app_links +import file_selector_macos import path_provider_foundation import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..1ecc3ee --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,42 @@ +PODS: + - app_links (1.0.0): + - FlutterMacOS + - FlutterMacOS (1.0.0) + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) + - FlutterMacOS (from `Flutter/ephemeral`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + +EXTERNAL SOURCES: + app_links: + :path: Flutter/ephemeral/.symlinks/plugins/app_links/macos + FlutterMacOS: + :path: Flutter/ephemeral + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + +SPEC CHECKSUMS: + app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 + +PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 + +COCOAPODS: 1.14.3 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 98b579c..aef2333 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -21,12 +21,14 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 0F01822AA9A9E9749238513B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 311DE641954640D99B1B4FE4 /* Pods_Runner.framework */; }; 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + C6804CBBFD4C528011277B05 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECFEDF50F009974C064DFA75 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +62,13 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2300B308B78E43D2FDF50990 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 311DE641954640D99B1B4FE4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* learn_project.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "learn_project.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* learn_project.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = learn_project.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -76,8 +80,14 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 4DDE30153BF6FBE35130B07A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + BF57888D5C07BC59C7600C12 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + C02918AD8AEC830CF0676619 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + D6246F994D1DCD4DC57DD5E5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + ECFEDF50F009974C064DFA75 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EEFA829C491B67BB2695D9B1 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C6804CBBFD4C528011277B05 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,12 +103,27 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0F01822AA9A9E9749238513B /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 04AF439F2AB063A1706FF61C /* Pods */ = { + isa = PBXGroup; + children = ( + 4DDE30153BF6FBE35130B07A /* Pods-Runner.debug.xcconfig */, + BF57888D5C07BC59C7600C12 /* Pods-Runner.release.xcconfig */, + C02918AD8AEC830CF0676619 /* Pods-Runner.profile.xcconfig */, + EEFA829C491B67BB2695D9B1 /* Pods-RunnerTests.debug.xcconfig */, + D6246F994D1DCD4DC57DD5E5 /* Pods-RunnerTests.release.xcconfig */, + 2300B308B78E43D2FDF50990 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 331C80D6294CF71000263BE5 /* RunnerTests */ = { isa = PBXGroup; children = ( @@ -125,6 +151,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + 04AF439F2AB063A1706FF61C /* Pods */, ); sourceTree = ""; }; @@ -175,6 +202,8 @@ D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + 311DE641954640D99B1B4FE4 /* Pods_Runner.framework */, + ECFEDF50F009974C064DFA75 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -186,6 +215,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 52B53316CDFDEB6B4041714D /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +234,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + C0C8FBDF1207306A464888E9 /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + B59A99DE8345B4DEFE849FE7 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -227,7 +259,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C80D4294CF70F00263BE5 = { @@ -328,6 +360,67 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 52B53316CDFDEB6B4041714D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + B59A99DE8345B4DEFE849FE7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + C0C8FBDF1207306A464888E9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -379,6 +472,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = EEFA829C491B67BB2695D9B1 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -393,6 +487,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D6246F994D1DCD4DC57DD5E5 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -407,6 +502,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 2300B308B78E43D2FDF50990 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 38981be..2635ffc 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + + diff --git a/pubspec.lock b/pubspec.lock index 3e4245a..0303ce0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + url: "https://pub.dev" + source: hosted + version: "0.3.4+1" crypto: dependency: transitive description: @@ -89,6 +97,38 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" + url: "https://pub.dev" + source: hosted + version: "0.9.2+1" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 + url: "https://pub.dev" + source: hosted + version: "0.9.4" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 + url: "https://pub.dev" + source: hosted + version: "0.9.3+1" flutter: dependency: "direct main" description: flutter @@ -102,6 +142,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" + url: "https://pub.dev" + source: hosted + version: "2.0.19" flutter_test: dependency: "direct dev" description: flutter @@ -152,6 +200,70 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: "33974eca2e87e8b4e3727f1b94fa3abcb25afe80b6bc2c4d449a0e150aedf720" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "0f57fee1e8bfadf8cc41818bbcd7f72e53bb768a54d9496355d5e8a5681a19f1" + url: "https://pub.dev" + source: hosted + version: "0.8.12+1" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3" + url: "https://pub.dev" + source: hosted + version: "3.0.4" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "4824d8c7f6f89121ef0122ff79bb00b009607faecc8545b86bca9ab5ce1e95bf" + url: "https://pub.dev" + source: hosted + version: "0.8.11+2" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" + url: "https://pub.dev" + source: hosted + version: "2.10.0" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" intl: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 340f2a9..93fbc08 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,7 @@ dependencies: cupertino_icons: ^1.0.2 supabase_flutter: ^2.5.2 timeago: ^3.1.0 + image_picker: ^1.0.5 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 785a046..5bbd4c3 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,11 +7,14 @@ #include "generated_plugin_registrant.h" #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { AppLinksPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("AppLinksPluginCApi")); + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 8f8ee4f..79001bc 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST app_links + file_selector_windows url_launcher_windows )