master #63

Merged
emre.kartal merged 12 commits from master into PROD-WEB 1 year ago

@ -1,6 +1,8 @@
import 'dart:io'; import 'dart:io';
import 'package:animated_appear/animated_appear.dart'; import 'package:animated_appear/animated_appear.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -60,8 +62,8 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
} }
Future pickImage(ImageSource source) async { Future pickImage(ImageSource source) async {
try {
try {
final image = await ImagePicker().pickImage(source: source, imageQuality: 20); final image = await ImagePicker().pickImage(source: source, imageQuality: 20);
if (image == null) return; if (image == null) return;
final imageTemp = File(image.path); final imageTemp = File(image.path);
@ -72,6 +74,7 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
} on PlatformException catch (e) { } on PlatformException catch (e) {
print('Failed to pick image: $e'); print('Failed to pick image: $e');
} }
} }
void _updateDescription(String text) { void _updateDescription(String text) {
@ -182,7 +185,10 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
child: InstaImageViewer( child: InstaImageViewer(
backgroundIsTransparent: true, backgroundIsTransparent: true,
child: Image( child: kIsWeb?InstaImageViewer(
backgroundIsTransparent: true,
child: Image.network(image!.path)
):Image(
image: FileImage(image!), image: FileImage(image!),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
@ -250,8 +256,8 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
width: double.infinity, width: double.infinity,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [ kIsWeb?Container()
Expanded( :Expanded(
flex: 5, flex: 5,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
@ -262,7 +268,7 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
), ),
), ),
), ),
SizedBox( kIsWeb?Container():SizedBox(
width: 15, width: 15,
), ),
Expanded( Expanded(

@ -34,7 +34,9 @@ class _HistoricComponentState extends State<HistoricComponent> {
.getHistoryCapsulesMonthWhitIdUser(MyApp.userViewModel.userCurrent.id, widget.month, widget.year), .getHistoryCapsulesMonthWhitIdUser(MyApp.userViewModel.userCurrent.id, widget.month, widget.year),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
return Wrap( return Container(
constraints: const BoxConstraints( maxWidth: 600),
child: Wrap(
spacing: 14, spacing: 14,
runSpacing: 14, runSpacing: 14,
children: List.generate(getNumberOfDaysInMonth(widget.year, widget.month), (index) { children: List.generate(getNumberOfDaysInMonth(widget.year, widget.month), (index) {
@ -63,13 +65,19 @@ class _HistoricComponentState extends State<HistoricComponent> {
); );
} }
if (checkCapsule != null) { if (checkCapsule != null) {
return Container( return Tooltip(
message: "${checkCapsule.item2.artists.first.name} - ${checkCapsule.item2.title}".length < 30? "${checkCapsule.item2.artists.first.name} - ${checkCapsule.item2.title}": "${checkCapsule.item2.artists.first.name} - ${checkCapsule.item2.title}".substring(0,30)+"...",
decoration: const BoxDecoration(
border: Border.fromBorderSide(BorderSide(color: Color(0xFF3A3A3A), width: 1)),
color: tooltipBackground, borderRadius: BorderRadius.all(Radius.circular(20))
),
child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage(image: NetworkImage((checkCapsule.item2.cover)!)), image: DecorationImage(image: NetworkImage((checkCapsule.item2.cover)!)),
borderRadius: BorderRadius.circular(5)), borderRadius: BorderRadius.circular(5)),
height: 60, height: 60,
width: 60, width: 60,
); ));
} else { } else {
return Container( return Container(
color: bgColor, color: bgColor,
@ -87,6 +95,7 @@ class _HistoricComponentState extends State<HistoricComponent> {
// Generate widgets // Generate widgets
}), }),
),
); );
} else { } else {
return CupertinoActivityIndicator(); return CupertinoActivityIndicator();

@ -152,10 +152,8 @@ class _PostComponentState extends State<PostComponent> with TickerProviderStateM
children: [ children: [
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: FadeInImage.assetNetwork( child: Image.network(
image: widget.post.music.cover!, widget.post.music.cover!,
fadeInDuration: const Duration(milliseconds: 100),
placeholder: "assets/images/loadingPlaceholder.gif",
), ),
), ),
Image( Image(
@ -196,11 +194,9 @@ class _PostComponentState extends State<PostComponent> with TickerProviderStateM
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(13), borderRadius: BorderRadius.circular(13),
// implement image // implement image
child: FadeInImage.assetNetwork( child: Image.network(
image: widget.post.selfie!, widget.post.selfie!,
fit: BoxFit.cover, fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 100),
placeholder: "assets/images/loadingPlaceholder.gif",
), ),
), ),
), ),

@ -80,9 +80,7 @@ class _MyAppState extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
Paint.enableDithering = true; Paint.enableDithering = true; // enter fullscreen
FullScreenWindow.setFullScreen(true); // enter fullscreen
return ScreenUtilInit( return ScreenUtilInit(
useInheritedMediaQuery: true, useInheritedMediaQuery: true,

@ -77,8 +77,9 @@ class _CapsuleHistoricScreenState extends State<CapsuleHistoricScreen> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Padding( Container(
padding: const EdgeInsets.only(top: 80, left: 60, right: 60), padding: const EdgeInsets.only(top: 80, left: 30, right: 30),
constraints: const BoxConstraints( maxWidth: 700),
child: Align( child: Align(
alignment: Alignment.center, alignment: Alignment.center,
child: Row( child: Row(
@ -130,8 +131,6 @@ class _CapsuleHistoricScreenState extends State<CapsuleHistoricScreen> {
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
child: Container( child: Container(
padding: EdgeInsets.symmetric(horizontal: 15),
constraints: BoxConstraints(maxWidth: 600),
child: Column( child: Column(
children: [ children: [
HistoricComponent( HistoricComponent(

@ -612,6 +612,7 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
Expanded( Expanded(
child: TextField( child: TextField(
keyboardAppearance: Brightness.dark, keyboardAppearance: Brightness.dark,
keyboardType: TextInputType.text,
controller: _textController, controller: _textController,
focusNode: myFocusNode, focusNode: myFocusNode,
onSubmitted: (value) async { onSubmitted: (value) async {
@ -626,7 +627,6 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
setState(() {}); setState(() {});
}, },
cursorColor: primaryColor, cursorColor: primaryColor,
keyboardType: TextInputType.emailAddress,
style: GoogleFonts.plusJakartaSans(color: Colors.white), style: GoogleFonts.plusJakartaSans(color: Colors.white),
decoration: InputDecoration( decoration: InputDecoration(
suffixIcon: _textController.text.isEmpty suffixIcon: _textController.text.isEmpty

@ -25,13 +25,15 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
late Animation<double> animation; late Animation<double> animation;
late List<Post> friendFeed; late List<Post> friendFeed;
Timer? timer; Timer? timer;
var pageFriend = 0;
late List<Post> discoveryFeed; late List<Post> discoveryFeed;
late Tuple2<List<Post>, List<Post>> displayFeed; late Tuple2<List<Post>, List<Post>> displayFeed;
bool isDismissed = true; bool isDismissed = true;
bool choiceFeed = true; bool choiceFeed = true;
PageController controller = PageController(); PageController controller = PageController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -124,9 +126,26 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
displayFeed = displayFeed =
Tuple2(MyApp.postViewModel.postsFriends.reversed.toList(), MyApp.postViewModel.bestPosts.reversed.toList()); Tuple2(MyApp.postViewModel.postsFriends.toList(), MyApp.postViewModel.bestPosts.toList());
bool empty = bool empty =
(choiceFeed == true && displayFeed.item1.isEmpty) || (choiceFeed == false && displayFeed.item2.isEmpty); (choiceFeed == true && displayFeed.item1.isEmpty) || (choiceFeed == false && displayFeed.item2.isEmpty);
ScrollController _scrollController = ScrollController();
_scrollController.addListener(() {
if (_scrollController.position.maxScrollExtent ==
_scrollController.position.pixels) {
print("fin");
if (choiceFeed) {
setState(() {
MyApp.postViewModel.getMorePostsFriends();
});
} else {
setState(() {
MyApp.postViewModel.getMoreBestPosts();
});
}
}
});
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
backgroundColor: bgColor, backgroundColor: bgColor,
@ -185,6 +204,7 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
clipBehavior: Clip.none, clipBehavior: Clip.none,
shrinkWrap: false, shrinkWrap: false,
controller: _scrollController,
itemCount: displayFeed.item1.length, itemCount: displayFeed.item1.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return Padding( return Padding(
@ -193,6 +213,7 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
PostComponent(callback: openDetailPost, post: displayFeed.item1[index], index: index), PostComponent(callback: openDetailPost, post: displayFeed.item1[index], index: index),
); );
}, },
), ),
), ),
), ),
@ -212,6 +233,7 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
triggerMode: RefreshIndicatorTriggerMode.onEdge, triggerMode: RefreshIndicatorTriggerMode.onEdge,
onRefresh: _refresh, onRefresh: _refresh,
child: ListView.builder( child: ListView.builder(
controller: _scrollController,
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
clipBehavior: Clip.none, clipBehavior: Clip.none,
shrinkWrap: false, shrinkWrap: false,

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/services/AuthService.dart';
import 'package:justmusic/values/icons.dart'; import 'package:justmusic/values/icons.dart';
import '../components/profile_component.dart'; import '../components/profile_component.dart';
import '../components/setting_part_component.dart'; import '../components/setting_part_component.dart';
@ -32,7 +33,40 @@ class _ProfileScreenState extends State<ProfileScreen> {
Navigator.of(context).push(routeUser(MyApp.userViewModel.userCurrent)); Navigator.of(context).push(routeUser(MyApp.userViewModel.userCurrent));
} }
void _openPassword() { void openConfirmationDelete() {
showCupertinoModalPopup<void>(
context: context,
barrierColor: Colors.black.withOpacity(0.7),
builder: (BuildContext context) => Container(
child: CupertinoActionSheet(
title: Text(
'Supprimer mon compte',
style: GoogleFonts.plusJakartaSans(fontWeight: FontWeight.bold),
),
actions: <CupertinoActionSheetAction>[
CupertinoActionSheetAction(
onPressed: () {
MyApp.userViewModel.delete();
Navigator.pop(context);
Navigator.of(context).push(routeWelcome());
},
child: Text('Confirmer', style: TextStyle(color: Colors.blue),),
),
],
cancelButton: CupertinoActionSheetAction(
isDestructiveAction: true,
onPressed: () {
Navigator.pop(context);
},
child: const Text('Annuler'),
),
),
),
);
}
void openPassword() {
Navigator.of(context).push(routePassword()); Navigator.of(context).push(routePassword());
} }
@ -122,12 +156,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.password, icon: JustMusicIcon.password,
label: 'Modifier mon mot de passe', label: 'Modifier mon mot de passe',
action: _openPassword, action: openPassword,
), ),
const SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.trash, icon: JustMusicIcon.trash,
label: 'Supprimer mon compte', label: 'Supprimer mon compte',
action: null, action: openConfirmationDelete,
), ),
SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.cross, icon: JustMusicIcon.cross,

@ -143,10 +143,11 @@ class _UserScreenState extends State<UserScreen> {
padding: const EdgeInsets.symmetric(horizontal: settingPadding), padding: const EdgeInsets.symmetric(horizontal: settingPadding),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Padding( Container(
padding: EdgeInsets.only(top: 68.h, bottom: 40), padding: EdgeInsets.only(top: 68.h, bottom: 40),
constraints: const BoxConstraints( maxWidth: 500),
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
@ -249,7 +250,11 @@ class _UserScreenState extends State<UserScreen> {
SizedBox( SizedBox(
height: 40, height: 40,
), ),
RecapComponent(user: widget.user) Container(
constraints: const BoxConstraints( maxWidth: 500),
child: RecapComponent(user: widget.user),
)
], ],
), ),
), ),

@ -42,16 +42,41 @@ class PostService {
deletePost() {} deletePost() {}
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPopularPosts( Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPopularPosts(int limit) async {
{int limit = 10, DateTime twentyFourHoursAgo = DateTime.now().subtract(Duration(hours: 24));
QueryDocumentSnapshot<Map<String, dynamic>>? offset}) async { var response = await FirebaseFirestore.instance
.collection("posts")
.where("date", isGreaterThan: twentyFourHoursAgo)
.orderBy("date", descending: true)
.limit(limit)
.get();
MyApp.postViewModel.lastPostDiscovery = response.docs.isNotEmpty
? response.docs.last
: MyApp.postViewModel.lastPostDiscovery;
var filteredPosts = response.docs.where((doc) {
String user = doc["user_id"];
return user != MyApp.userViewModel.userCurrent.id;
}).toList();
return filteredPosts;
}
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getMorePopularPosts(int limit) async {
DateTime twentyFourHoursAgo = DateTime.now().subtract(Duration(hours: 24));
QuerySnapshot<Map<String, dynamic>> response; QuerySnapshot<Map<String, dynamic>> response;
response = await FirebaseFirestore.instance response = await FirebaseFirestore.instance
.collection("posts") .collection("posts")
.orderBy("date") .where("date", isGreaterThan: twentyFourHoursAgo)
.orderBy("date", descending: true)
.limit(limit) .limit(limit)
.startAfterDocument(MyApp.postViewModel.lastPostDiscovery)
.get(); .get();
MyApp.postViewModel.lastPostDiscovery = response.docs.isNotEmpty
? response.docs.last
: MyApp.postViewModel.lastPostDiscovery;
var filteredPosts = response.docs.where((doc) { var filteredPosts = response.docs.where((doc) {
String user = doc["user_id"]; String user = doc["user_id"];
return user != MyApp.userViewModel.userCurrent.id; return user != MyApp.userViewModel.userCurrent.id;
@ -59,18 +84,41 @@ class PostService {
return filteredPosts; return filteredPosts;
} }
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPostsFriends( Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPostsFriends(int limit) async {
{int limit = 10, int offset = 0}) async {
var response = await FirebaseFirestore.instance var response = await FirebaseFirestore.instance
.collection("posts") .collection("posts")
.where("user_id", whereIn: [ .where("user_id", whereIn: [
MyApp.userViewModel.userCurrent.id, MyApp.userViewModel.userCurrent.id,
...MyApp.userViewModel.userCurrent.followed ...MyApp.userViewModel.userCurrent.followed
]) ])
.orderBy("date") .where("")
.orderBy("date", descending: true)
.limit(limit) .limit(limit)
.get(); .get();
MyApp.postViewModel.lastPostFriend = response.docs.isNotEmpty
? response.docs.last
: MyApp.postViewModel.lastPostFriend;
return response.docs;
}
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getMorePostsFriends(int limit) async {
var response = await FirebaseFirestore.instance
.collection("posts")
.where("user_id", whereIn: [
MyApp.userViewModel.userCurrent.id,
...MyApp.userViewModel.userCurrent.followed
])
.orderBy("date", descending: true)
.limit(limit)
.startAfterDocument(MyApp.postViewModel.lastPostFriend)
.get();
MyApp.postViewModel.lastPostFriend = response.docs.isNotEmpty
? response.docs.last
: MyApp.postViewModel.lastPostFriend;
return response.docs; return response.docs;
} }

@ -24,6 +24,7 @@ const searchBarColor = Color(0xFF161616);
const postbutton = Color(0xFF1B1B1B); const postbutton = Color(0xFF1B1B1B);
const fillButton = Color(0xFF633AF4); const fillButton = Color(0xFF633AF4);
const selectedButton = Color(0xFF1F1B2E); const selectedButton = Color(0xFF1F1B2E);
const tooltipBackground = Color(0xFF2D2D2D);
// All constants important too us // All constants important too us
const defaultPadding = 30.0; const defaultPadding = 30.0;

@ -242,7 +242,6 @@ class MusicViewModel {
for (var capsule in capsulesData) { for (var capsule in capsulesData) {
var music = musics.firstWhere((music) => music.id == capsule.item2); var music = musics.firstWhere((music) => music.id == capsule.item2);
print(capsule.item1);
capsules.add(Tuple2(capsule.item1, music)); capsules.add(Tuple2(capsule.item1, music));
} }
return capsules; return capsules;

@ -11,6 +11,8 @@ import '../model/mapper/PostMapper.dart';
class PostViewModel { class PostViewModel {
List<Post> _postsFriends = []; List<Post> _postsFriends = [];
List<Post> _bestPosts = []; List<Post> _bestPosts = [];
var lastPostFriend;
var lastPostDiscovery;
final PostService _postService = PostService(); final PostService _postService = PostService();
// Constructor // Constructor
@ -26,10 +28,10 @@ class PostViewModel {
await _postService.createPost(description, idMusic, image, location); await _postService.createPost(description, idMusic, image, location);
} }
Future<List<Post>> getPostsFriends() async { Future<List<Post>> getPostsFriends({int limit = 10}) async {
try { try {
_postsFriends = []; _postsFriends = [];
var responseData = await _postService.getPostsFriends(); var responseData = await _postService.getPostsFriends(limit);
List<String> ids = []; List<String> ids = [];
var postsFutures = responseData.map((value) { var postsFutures = responseData.map((value) {
ids.add(value.data()["song_id"]); ids.add(value.data()["song_id"]);
@ -40,7 +42,7 @@ class PostViewModel {
for (int i = 0; i < posts.length; i++) { for (int i = 0; i < posts.length; i++) {
posts[i].music = musics[i]; posts[i].music = musics[i];
} }
_postsFriends = posts; _postsFriends.addAll(posts);
return _postsFriends; return _postsFriends;
} catch (e) { } catch (e) {
print(e); print(e);
@ -49,13 +51,29 @@ class PostViewModel {
} }
} }
List<Post> getMorePostsFriends() { void getMorePostsFriends({int limit = 10}) async {
throw new Error(); try {
var responseData = await _postService.getMorePostsFriends(limit);
List<String> ids = [];
var postsFutures = responseData.map((value) {
ids.add(value.data()["song_id"]);
return PostMapper.toModel(value);
}).toList();
var posts = await Future.wait(postsFutures);
List<Music> musics = await MyApp.musicViewModel.getMusicsWithIds(ids);
for (int i = 0; i < posts.length; i++) {
posts[i].music = musics[i];
}
_postsFriends.addAll(posts);
} catch (e) {
print(e);
}
} }
Future<List<Post>> getBestPosts() async { Future<List<Post>> getBestPosts({int limit = 10}) async {
try { try {
var responseData = await _postService.getPopularPosts(); _bestPosts = [];
var responseData = await _postService.getPopularPosts(limit);
List<String> ids = []; List<String> ids = [];
var postsFutures = responseData.map((value) async { var postsFutures = responseData.map((value) async {
ids.add(value.data()["song_id"]); ids.add(value.data()["song_id"]);
@ -66,7 +84,7 @@ class PostViewModel {
for (int i = 0; i < posts.length; i++) { for (int i = 0; i < posts.length; i++) {
posts[i].music = musics[i]; posts[i].music = musics[i];
} }
_bestPosts = posts; _bestPosts.addAll(posts);
return _bestPosts; return _bestPosts;
} catch (e) { } catch (e) {
print(e); print(e);
@ -75,8 +93,23 @@ class PostViewModel {
} }
} }
List<Post> getMoreBestPosts() { void getMoreBestPosts({int limit = 10}) async {
throw new Error(); try {
var responseData = await _postService.getMorePopularPosts(limit);
List<String> ids = [];
var postsFutures = responseData.map((value) async {
ids.add(value.data()["song_id"]);
return await PostMapper.toModel(value);
}).toList();
var posts = await Future.wait(postsFutures);
List<Music> musics = await MyApp.musicViewModel.getMusicsWithIds(ids);
for (int i = 0; i < posts.length; i++) {
posts[i].music = musics[i];
}
_bestPosts.addAll(posts);
} catch (e) {
print(e);
}
} }
Future<List<bool>> recapSevenDays(String id) async { Future<List<bool>> recapSevenDays(String id) async {

@ -745,7 +745,7 @@ packages:
source: hosted source: hosted
version: "0.8.7+4" version: "0.8.7+4"
image_picker_for_web: image_picker_for_web:
dependency: "direct main" dependency: transitive
description: description:
name: image_picker_for_web name: image_picker_for_web
sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7" sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7"

@ -78,7 +78,6 @@ dependencies:
google_sign_in: ^6.1.4 google_sign_in: ^6.1.4
flutter_launcher_icons: ^0.13.1 flutter_launcher_icons: ^0.13.1
fullscreen_window: ^1.0.3 fullscreen_window: ^1.0.3
image_picker_for_web: ^3.0.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Loading…
Cancel
Save