forked from eatvio/eatvio_app
feat(profile): User profile pic upload finished + BloC event for that
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
@@ -7,6 +9,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
part 'my_profile_event.dart';
|
||||
part 'my_profile_state.dart';
|
||||
@@ -15,6 +18,7 @@ part 'my_profile_state.dart';
|
||||
class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
MyProfileBloc(MyProfileState initialState) : super(initialState) {
|
||||
on<MyProfileInitialEvent>(_onInitialize);
|
||||
on<UploadAvatar>(_uploadAvatar);
|
||||
}
|
||||
|
||||
Future<void> _onInitialize(
|
||||
@@ -242,4 +246,35 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
return "экстремальный (несколько интенсивных тренировок в день)";
|
||||
}
|
||||
} // колхоз, но свитчкейсы в дарте странно ведут себя при сравнении double
|
||||
|
||||
Future<void> _uploadAvatar(
|
||||
UploadAvatar event, Emitter<MyProfileState> emit) async {
|
||||
if (state is MyProfileLoadedState) {
|
||||
var currentState = state as MyProfileLoadedState;
|
||||
|
||||
await uploadImageToServer(event.image.path, currentState.token);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> uploadImageToServer(String imagePath, String? token) async {
|
||||
String url = '${dotenv.env['SERVER_ROOT']!}/profile/photo/upload';
|
||||
print(url);
|
||||
var request = http.MultipartRequest('POST', Uri.parse(url));
|
||||
request.headers['Authorization'] = 'Bearer $token';
|
||||
|
||||
request.files.add(await http.MultipartFile.fromPath('photo', imagePath));
|
||||
|
||||
var client = http.Client();
|
||||
var streamedResponse = await client.send(request);
|
||||
|
||||
if (streamedResponse.statusCode == 200) {
|
||||
var response = await http.Response.fromStream(streamedResponse);
|
||||
var imageUrl = response.body;
|
||||
print('Image successfully uploaded');
|
||||
return imageUrl;
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to upload image. Status code: ${streamedResponse.statusCode} ${streamedResponse}}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,3 +14,10 @@ class MyProfileInitialEvent extends MyProfileEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class UploadAvatar extends MyProfileEvent {
|
||||
UploadAvatar(this.image);
|
||||
final XFile image;
|
||||
@override
|
||||
List<Object> get props => [image];
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:eatvio_app/widgets/app_bar/appbar_subtitle.dart';
|
||||
import 'package:eatvio_app/widgets/custom_bottom_bar.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -139,27 +140,41 @@ class MyProfileScreen extends StatelessWidget {
|
||||
|
||||
/// Section Widget
|
||||
_buildInfo(BuildContext context, MyProfileLoadedState state) {
|
||||
print(state.user?['profile_photo_url']);
|
||||
return Column(children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: state.user?['profile_photo_url'],
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 60,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.grey[200],
|
||||
radius: 60,
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: addImage(context),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl:
|
||||
dotenv.env['STORAGE_URL']! + state.user?['profile_photo_path'],
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 60,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.grey[200],
|
||||
radius: 60,
|
||||
),
|
||||
)),
|
||||
AppbarSubtitle(text: state.user?['name']),
|
||||
SizedBox(height: 20.v),
|
||||
Text(state.userDetails?['additional_info']),
|
||||
]);
|
||||
}
|
||||
|
||||
addImage(BuildContext context) {
|
||||
return () async {
|
||||
final picker = ImagePicker();
|
||||
List<XFile>? images = await picker.pickMultiImage();
|
||||
if (images.isNotEmpty) {
|
||||
for (var image in images) {
|
||||
context.read<MyProfileBloc>().add(UploadAvatar(image));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
onTapSettings(BuildContext context) {
|
||||
return () {
|
||||
Navigator.pushNamed(context, AppRoutes.mySettings);
|
||||
|
||||
Reference in New Issue
Block a user