diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 77e068d..13b5e01 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ diff --git a/lib/main.dart b/lib/main.dart index 43f99fd..7ce03e1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,6 +8,7 @@ import 'constants/colors.dart'; import 'constants/routes.dart'; import 'models/hive/hive_helper/register_adapters.dart'; import 'models/hive/models/show_preview.dart'; +import 'models/hive/models/user.dart'; import 'modules/cache/cache_data.dart'; import 'pages/main/home/home_data_controller.dart'; import 'pages/main/main_controller.dart'; @@ -21,6 +22,7 @@ void main() async { // Initialize Hive and Hive Flutter await Hive.initFlutter(); registerAdapters(); + Hive.openBox('user'); Hive.openBox('collection'); Hive.openBox('watchlist'); Hive.openBox('history'); diff --git a/lib/models/hive/convertor.dart b/lib/models/hive/convertor.dart index b4d13bc..72c8406 100644 --- a/lib/models/hive/convertor.dart +++ b/lib/models/hive/convertor.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:movielab/models/hive/models/show_preview.dart'; import 'package:movielab/models/show_models/show_preview_model.dart'; +import 'package:movielab/models/user_model/user_model.dart'; import '../show_models/full_show_model.dart'; +import 'models/user.dart'; ShowPreview convertHiveToShowPreview(HiveShowPreview hive) { return ShowPreview( @@ -153,3 +155,22 @@ Future getShowCrew({required FullShow fullShow}) async { crew = crewList.join(", "); return crew; } + +User convertHiveToUser(HiveUser hive) { + return User( + name: hive.name, + username: hive.username, + email: hive.email, + imageUrl: hive.imageUrl, + phone: hive.phone, + ); +} + +HiveUser convertUserToHive(User user) { + return HiveUser() + ..name = user.name + ..username = user.username + ..email = user.email + ..imageUrl = user.imageUrl + ..phone = user.phone; +} diff --git a/lib/models/hive/hive_helper/fields/user_fields.dart b/lib/models/hive/hive_helper/fields/user_fields.dart new file mode 100644 index 0000000..3de9887 --- /dev/null +++ b/lib/models/hive/hive_helper/fields/user_fields.dart @@ -0,0 +1,7 @@ +class UserFields { + static const int name = 0; + static const int username = 1; + static const int email = 2; + static const int phone = 3; + static const int imageUrl = 4; +} diff --git a/lib/models/hive/hive_helper/hive_adapters.dart b/lib/models/hive/hive_helper/hive_adapters.dart index 232f058..198759b 100644 --- a/lib/models/hive/hive_helper/hive_adapters.dart +++ b/lib/models/hive/hive_helper/hive_adapters.dart @@ -1,4 +1,5 @@ class HiveAdapters { static const String showPreview = 'ShowPreviewAdapter'; static const String timeOfDay = 'TimeOfDayAdapter'; + static const String user = 'UserAdapter'; } diff --git a/lib/models/hive/hive_helper/hive_types.dart b/lib/models/hive/hive_helper/hive_types.dart index a8eebfa..9c0c215 100644 --- a/lib/models/hive/hive_helper/hive_types.dart +++ b/lib/models/hive/hive_helper/hive_types.dart @@ -1,4 +1,5 @@ class HiveTypes { static const int showPreview = 0; static const int timeOfDay = 1; + static const int user = 2; } diff --git a/lib/models/hive/hive_helper/register_adapters.dart b/lib/models/hive/hive_helper/register_adapters.dart index 452be4e..e99c15d 100644 --- a/lib/models/hive/hive_helper/register_adapters.dart +++ b/lib/models/hive/hive_helper/register_adapters.dart @@ -1,8 +1,10 @@ import 'package:hive/hive.dart'; import 'package:movielab/models/hive/models/show_preview.dart'; import 'package:movielab/models/hive/models/time_of_day.g.dart'; +import 'package:movielab/models/hive/models/user.dart'; void registerAdapters() { - Hive.registerAdapter(HiveShowPreviewAdapter()); + Hive.registerAdapter(ShowPreviewAdapter()); + Hive.registerAdapter(UserAdapter()); Hive.registerAdapter(TimeOfDayAdapter()); } diff --git a/lib/models/hive/models/show_preview.g.dart b/lib/models/hive/models/show_preview.g.dart index 57057f8..1b719b8 100644 --- a/lib/models/hive/models/show_preview.g.dart +++ b/lib/models/hive/models/show_preview.g.dart @@ -6,7 +6,7 @@ part of 'show_preview.dart'; // TypeAdapterGenerator // ************************************************************************** -class HiveShowPreviewAdapter extends TypeAdapter { +class ShowPreviewAdapter extends TypeAdapter { @override final int typeId = 0; @@ -79,7 +79,7 @@ class HiveShowPreviewAdapter extends TypeAdapter { @override bool operator ==(Object other) => identical(this, other) || - other is HiveShowPreviewAdapter && + other is ShowPreviewAdapter && runtimeType == other.runtimeType && typeId == other.typeId; } diff --git a/lib/models/hive/models/user.dart b/lib/models/hive/models/user.dart new file mode 100644 index 0000000..4047a69 --- /dev/null +++ b/lib/models/hive/models/user.dart @@ -0,0 +1,20 @@ +import 'package:hive/hive.dart'; +import 'package:movielab/models/hive/hive_helper/fields/user_fields.dart'; +import 'package:movielab/models/hive/hive_helper/hive_adapters.dart'; +import 'package:movielab/models/hive/hive_helper/hive_types.dart'; + +part 'user.g.dart'; + +@HiveType(typeId: HiveTypes.user, adapterName: HiveAdapters.user) +class HiveUser extends HiveObject { + @HiveField(UserFields.name) + late String name; + @HiveField(UserFields.username) + late String username; + @HiveField(UserFields.email) + late String email; + @HiveField(UserFields.phone) + late String phone; + @HiveField(UserFields.imageUrl) + late String imageUrl; +} diff --git a/lib/models/hive/models/user.g.dart b/lib/models/hive/models/user.g.dart new file mode 100644 index 0000000..68ac1c6 --- /dev/null +++ b/lib/models/hive/models/user.g.dart @@ -0,0 +1,52 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class UserAdapter extends TypeAdapter { + @override + final int typeId = 2; + + @override + HiveUser read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return HiveUser() + ..name = fields[0] as String + ..username = fields[1] as String + ..email = fields[2] as String + ..phone = fields[3] as String + ..imageUrl = fields[4] as String; + } + + @override + void write(BinaryWriter writer, HiveUser obj) { + writer + ..writeByte(5) + ..writeByte(0) + ..write(obj.name) + ..writeByte(1) + ..write(obj.username) + ..writeByte(2) + ..write(obj.email) + ..writeByte(3) + ..write(obj.phone) + ..writeByte(4) + ..write(obj.imageUrl); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is UserAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/models/episode_model.dart b/lib/models/show_models/episode_model.dart similarity index 100% rename from lib/models/episode_model.dart rename to lib/models/show_models/episode_model.dart diff --git a/lib/models/external_sites_model.dart b/lib/models/show_models/external_sites_model.dart similarity index 100% rename from lib/models/external_sites_model.dart rename to lib/models/show_models/external_sites_model.dart diff --git a/lib/models/search_result_model.dart b/lib/models/show_models/search_result_model.dart similarity index 100% rename from lib/models/search_result_model.dart rename to lib/models/show_models/search_result_model.dart diff --git a/lib/models/user_model/user_model.dart b/lib/models/user_model/user_model.dart new file mode 100644 index 0000000..2e1e4cd --- /dev/null +++ b/lib/models/user_model/user_model.dart @@ -0,0 +1,16 @@ +// Movie or TV show preview model class +class User { + final String name; + final String username; + final String email; + final String phone; + final String imageUrl; + + const User({ + required this.name, + required this.username, + required this.email, + required this.phone, + required this.imageUrl, + }); +} diff --git a/lib/modules/api/api_requester.dart b/lib/modules/api/api_requester.dart index f2e79f8..d3f3a0a 100644 --- a/lib/modules/api/api_requester.dart +++ b/lib/modules/api/api_requester.dart @@ -5,9 +5,9 @@ import 'package:get/get.dart'; import 'package:http/http.dart' as http; import 'package:movielab/constants/types.dart'; import 'package:movielab/models/actor_models/full_actor_model.dart'; -import 'package:movielab/models/episode_model.dart'; -import 'package:movielab/models/external_sites_model.dart'; -import 'package:movielab/models/search_result_model.dart'; +import 'package:movielab/models/show_models/episode_model.dart'; +import 'package:movielab/models/show_models/external_sites_model.dart'; +import 'package:movielab/models/show_models/search_result_model.dart'; import 'package:movielab/models/show_models/full_show_model.dart'; import 'package:movielab/models/show_models/show_preview_model.dart'; import 'package:movielab/modules/api/api_keys.dart'; diff --git a/lib/modules/preferences/preferences_shareholder.dart b/lib/modules/preferences/preferences_shareholder.dart index 5033415..79c13e6 100644 --- a/lib/modules/preferences/preferences_shareholder.dart +++ b/lib/modules/preferences/preferences_shareholder.dart @@ -1,7 +1,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; +import 'package:movielab/models/hive/models/user.dart'; import 'package:movielab/models/show_models/show_preview_model.dart'; +import 'package:movielab/models/user_model/user_model.dart'; import 'package:movielab/modules/Recommender/Recommender.dart'; import 'package:movielab/pages/splash/get_user_data.dart'; import '../../models/hive/convertor.dart'; @@ -110,4 +112,29 @@ class PreferencesShareholder { } return result; } + + Future getUser() async { + Box userBox = Hive.box("user"); + late HiveUser user; + if (userBox.isNotEmpty) { + user = userBox.getAt(0)!; + } else { + user = HiveUser() + ..name = "Your name" + ..username = "Your username" + ..email = "Your email" + ..phone = "Your phone" + ..imageUrl = "Empty"; + userBox.put(0, user); + } + + return convertHiveToUser(user); + } + + Future updateUser({required User user}) async { + Box userBox = Hive.box("user"); + HiveUser hiveUser = convertUserToHive(user); + userBox.put(0, hiveUser); + return true; + } } diff --git a/lib/pages/main/profile/profile_controller.dart b/lib/pages/main/profile/profile_controller.dart index 561251c..56a56c6 100644 --- a/lib/pages/main/profile/profile_controller.dart +++ b/lib/pages/main/profile/profile_controller.dart @@ -1,6 +1,26 @@ import 'package:get/get.dart'; class ProfileController extends GetxController { + // User info + late String name; + late String username; + late String email; + late String phone; + late String imageUrl; + updateUserInfo( + {String? name, + String? username, + String? email, + String? phone, + String? imageUrl}) { + this.name = name ?? this.name; + this.username = username ?? this.username; + this.email = email ?? this.email; + this.phone = phone ?? this.phone; + this.imageUrl = imageUrl ?? this.imageUrl; + update(); + } + int watchedMoviesCount = 0; int watchedSeriesCount = 0; updateWatchedMoviesCount(int count) { diff --git a/lib/pages/main/profile/sections/user_profile/edit_user_profile.dart b/lib/pages/main/profile/sections/user_profile/edit_user_profile.dart index 0a36f85..aafdd78 100644 --- a/lib/pages/main/profile/sections/user_profile/edit_user_profile.dart +++ b/lib/pages/main/profile/sections/user_profile/edit_user_profile.dart @@ -1,5 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:movielab/constants/colors.dart'; +import 'package:movielab/models/user_model/user_model.dart'; +import 'package:movielab/modules/preferences/preferences_shareholder.dart'; +import 'package:movielab/pages/main/profile/profile_controller.dart'; +import 'package:movielab/pages/splash/get_user_data.dart'; import 'package:movielab/widgets/buttons/glassmorphism_button.dart'; import 'package:movielab/widgets/textfield_widget.dart'; @@ -7,52 +13,97 @@ import 'user_profile_image.dart'; class ProfilePageEditUserProfile extends StatelessWidget { const ProfilePageEditUserProfile({Key? key}) : super(key: key); + Future _onWillPop() async { + getUserInformation(); + return true; + } @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: kBackgroundColor, - appBar: AppBar( - leading: const BackButton(), - backgroundColor: Colors.transparent, - elevation: 0, - ), - body: ListView( - padding: const EdgeInsets.symmetric(horizontal: 32), - physics: const BouncingScrollPhysics(), - children: [ - userProfileImage(context, icon: Icons.add_a_photo, onTap: () {}), - const SizedBox(height: 24), - TextFieldWidget( - label: 'Full Name', - text: "user.name", - onChanged: (name) {}, + return GetBuilder(builder: (_) { + return WillPopScope( + onWillPop: _onWillPop, + child: Scaffold( + backgroundColor: kBackgroundColor, + appBar: AppBar( + leading: const BackButton(), + backgroundColor: Colors.transparent, + elevation: 0, ), - const SizedBox(height: 24), - TextFieldWidget( - label: 'Email', - text: "user.email", - onChanged: (email) {}, + body: ListView( + padding: const EdgeInsets.symmetric(horizontal: 32), + physics: const BouncingScrollPhysics(), + children: [ + userProfileImage(context, icon: Icons.add_a_photo, + onTap: () async { + final ImagePicker picker = ImagePicker(); + final XFile? image = + await picker.pickImage(source: ImageSource.gallery); + if (image != null) { + _.updateUserInfo(imageUrl: image.path); + } + }), + const SizedBox(height: 24), + TextFieldWidget( + label: 'Full Name', + text: _.name, + onChanged: (name) { + _.name = name; + }, + ), + const SizedBox(height: 24), + TextFieldWidget( + label: 'Username', + text: _.username, + onChanged: (username) { + _.username = username; + }, + ), + const SizedBox(height: 24), + TextFieldWidget( + label: 'Email', + text: _.email, + onChanged: (email) { + _.email = email; + }, + ), + const SizedBox(height: 24), + TextFieldWidget( + label: 'Phone number', + text: _.phone, + onChanged: (email) { + _.phone = email; + }, + ), + const SizedBox(height: 40), + GmButton( + text: "Save", + onTap: () { + PreferencesShareholder preferencesShareholder = + PreferencesShareholder(); + preferencesShareholder.updateUser( + user: User( + name: _.name, + username: _.username, + email: _.email, + phone: _.phone, + imageUrl: _.imageUrl)); + _.updateUserInfo( + name: _.name, + username: _.username, + email: _.email, + phone: _.phone, + imageUrl: _.imageUrl); + Navigator.pop(context); + }, + padding: EdgeInsets.symmetric( + horizontal: MediaQuery.of(context).size.width / 5), + backgroundColor: Colors.blue, + color: Colors.white) + ], ), - const SizedBox(height: 24), - TextFieldWidget( - label: 'About', - text: "user.about", - maxLines: 5, - onChanged: (about) {}, - ), - const SizedBox(height: 40), - GmButton( - text: "Save", - onTap: () { - Navigator.pop(context); - }, - padding: EdgeInsets.symmetric( - horizontal: MediaQuery.of(context).size.width / 5), - backgroundColor: Colors.blue, - color: Colors.white) - ], - ), - ); + ), + ); + }); } } diff --git a/lib/pages/main/profile/sections/user_profile/user_profile.dart b/lib/pages/main/profile/sections/user_profile/user_profile.dart index 60ba0ff..485fe76 100644 --- a/lib/pages/main/profile/sections/user_profile/user_profile.dart +++ b/lib/pages/main/profile/sections/user_profile/user_profile.dart @@ -29,16 +29,16 @@ class ProfilePageUserProfile extends StatelessWidget { duration: const Duration(milliseconds: 150), child: Column( children: [ - const Text( - "Erfan Rahmati", - style: TextStyle( + Text( + _.name, + style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24), ), const SizedBox(height: 4), Text( - "@ErfanRht", + _.username, style: TextStyle( color: Colors.white.withOpacity(0.5), fontWeight: FontWeight.w600, diff --git a/lib/pages/main/profile/sections/user_profile/user_profile_image.dart b/lib/pages/main/profile/sections/user_profile/user_profile_image.dart index 8ae6dc6..9f8cbb7 100644 --- a/lib/pages/main/profile/sections/user_profile/user_profile_image.dart +++ b/lib/pages/main/profile/sections/user_profile/user_profile_image.dart @@ -1,46 +1,53 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:movielab/constants/colors.dart'; +import 'package:movielab/pages/main/profile/profile_controller.dart'; Widget userProfileImage(BuildContext context, {required IconData icon, void Function()? onTap}) => - Center( - child: Stack( - children: [ - ClipOval( - child: Material( - color: Colors.transparent, - child: Ink.image( - image: const AssetImage("assets/images/no_picture.png"), - fit: BoxFit.cover, - width: 128, - height: 128, - child: InkWell(onTap: () {}), - ), - ), - ), - Positioned( - bottom: 0, - right: 4, - child: InkWell( - onTap: onTap, - child: buildCircle( - color: kSecondaryColor, - all: 3, - child: buildCircle( - color: Colors.blue, - all: 8, - child: Icon( - icon, - color: Colors.white, - size: 20, + GetBuilder( + builder: (_) => Center( + child: Stack( + children: [ + ClipOval( + child: Material( + color: Colors.transparent, + child: Ink.image( + image: _.imageUrl != "Empty" + ? FileImage(File(_.imageUrl)) as ImageProvider + : const AssetImage("assets/images/no_picture.png"), + fit: BoxFit.cover, + width: 128, + height: 128, + child: InkWell(onTap: () {}), + ), + ), ), - ), + Positioned( + bottom: 0, + right: 4, + child: InkWell( + onTap: onTap, + child: buildCircle( + color: kSecondaryColor, + all: 3, + child: buildCircle( + color: Colors.blue, + all: 8, + child: Icon( + icon, + color: Colors.white, + size: 20, + ), + ), + ), + ), + ), + ], ), - ), - ), - ], - ), - ); + )); Widget buildCircle({ required Widget child, required double all, diff --git a/lib/pages/show/show_box/episode_show_box.dart b/lib/pages/show/show_box/episode_show_box.dart index 1c91eab..ef7dc1a 100644 --- a/lib/pages/show/show_box/episode_show_box.dart +++ b/lib/pages/show/show_box/episode_show_box.dart @@ -3,7 +3,7 @@ import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:movielab/constants/colors.dart'; -import 'package:movielab/models/episode_model.dart'; +import 'package:movielab/models/show_models/episode_model.dart'; import 'package:movielab/pages/show/show_box/show_box_common.dart'; class EpisodeShowBox extends StatelessWidget { diff --git a/lib/pages/show/show_box/search_show_box.dart b/lib/pages/show/show_box/search_show_box.dart index c8275eb..0554f56 100644 --- a/lib/pages/show/show_box/search_show_box.dart +++ b/lib/pages/show/show_box/search_show_box.dart @@ -4,7 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:movielab/pages/actor/actor_page/actor_page.dart'; import 'package:movielab/pages/show/show_box/show_box_common.dart'; import 'package:movielab/pages/show/show_page/show_page.dart'; -import '../../../models/search_result_model.dart'; +import '../../../models/show_models/search_result_model.dart'; import '../../../modules/tools/navigate.dart'; class SearchShowBox extends StatelessWidget { diff --git a/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart b/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart index f8091e9..9a8b5f3 100644 --- a/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart +++ b/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:movielab/constants/colors.dart'; -import 'package:movielab/models/external_sites_model.dart'; +import 'package:movielab/models/show_models/external_sites_model.dart'; import 'package:movielab/models/show_models/full_show_model.dart'; import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/widgets/section_title.dart'; diff --git a/lib/pages/splash/get_user_data.dart b/lib/pages/splash/get_user_data.dart index 4b7cff0..6ed2b31 100644 --- a/lib/pages/splash/get_user_data.dart +++ b/lib/pages/splash/get_user_data.dart @@ -1,12 +1,29 @@ import 'package:get/get.dart'; import 'package:movielab/models/show_models/show_preview_model.dart'; +import 'package:movielab/models/user_model/user_model.dart'; import 'package:movielab/modules/preferences/preferences_shareholder.dart'; import 'package:movielab/pages/main/profile/profile_controller.dart'; Future getUserData() async { + await getUserInformation(); await updateUserStats(); } +Future getUserInformation() async { + PreferencesShareholder preferencesShareholder = PreferencesShareholder(); + ProfileController controller = Get.find(); + + User user = await preferencesShareholder.getUser(); + controller.updateUserInfo( + name: user.name, + username: user.username, + email: user.email, + phone: user.phone, + imageUrl: user.imageUrl, + ); + return true; +} + Future updateUserStats() async { PreferencesShareholder preferencesShareholder = PreferencesShareholder(); List> allLists = await preferencesShareholder.getAllLists(); diff --git a/lib/widgets/textfield_widget.dart b/lib/widgets/textfield_widget.dart index 1094ed9..ebb8cd6 100644 --- a/lib/widgets/textfield_widget.dart +++ b/lib/widgets/textfield_widget.dart @@ -62,6 +62,7 @@ class TextFieldWidgetState extends State { const BorderSide(color: Colors.blue, width: 2.5), borderRadius: BorderRadius.circular(12))), maxLines: widget.maxLines, + onChanged: widget.onChanged, ), ], ); diff --git a/pubspec.lock b/pubspec.lock index 3047cd8..e242c60 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -183,6 +183,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3" + cross_file: + dependency: transitive + description: + name: cross_file + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3+1" crypto: dependency: transitive description: @@ -272,6 +279,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" flutter_rating_bar: dependency: "direct main" description: @@ -415,6 +429,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + image_picker: + dependency: "direct main" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+3" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+2" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.8" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+6" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" io: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 26fe569..d9cbf6f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: url_launcher: ^6.1.4 fl_chart: ^0.55.0 share_plus: ^4.0.10 + image_picker: ^0.8.5+3