Skip to content

Commit

Permalink
update profile picture functionality added
Browse files Browse the repository at this point in the history
  • Loading branch information
rudramistry001 committed Jan 23, 2024
1 parent 246381d commit 8d04894
Show file tree
Hide file tree
Showing 13 changed files with 328 additions and 17 deletions.
2 changes: 2 additions & 0 deletions login/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:label="ApnaChat"
android:name="${applicationName}"
Expand Down
Binary file added login/assets/images/camera.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added login/assets/images/images.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions login/lib/api/apis.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:login/model/chat_user_model.dart';

class APIs {
Expand All @@ -8,6 +11,8 @@ class APIs {

//for accessing cloud firestore database
static FirebaseFirestore firestore = FirebaseFirestore.instance;
//for accessing cloud firebase storage
static FirebaseStorage storage = FirebaseStorage.instance;

//for storing self information
static late ChatUser me;
Expand Down Expand Up @@ -62,4 +67,29 @@ class APIs {
'about': me.About,
});
}

//for updating the profile picture
// update profile picture of user
static Future<void> updateProfilePicture(File file) async {
//getting image file extension
final ext = file.path.split('.').last;
print('Extension: $ext');

//storage file ref with path
final ref = storage.ref().child('profile_pictures/${user.uid}.$ext');

//uploading image
await ref
.putFile(file, SettableMetadata(contentType: 'image/$ext'))
.then((p0) {
print('Data Transferred: ${p0.bytesTransferred / 1000} kb');
});

//updating image in firestore database
me.Image = await ref.getDownloadURL();
await firestore
.collection('users')
.doc(user.uid)
.update({'image': me.Image});
}
}
1 change: 1 addition & 0 deletions login/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'firebase_options.dart';

// global object for accessing device screen size
late Size mq;

void main() {
WidgetsFlutterBinding.ensureInitialized();
_initialiseFirebase();
Expand Down
149 changes: 132 additions & 17 deletions login/lib/screens/profile_screen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// ignore_for_file: avoid_print

import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:login/api/apis.dart';
import 'package:login/auth/loginscreen.dart';
import 'package:login/constants/strings.dart';
Expand All @@ -18,10 +23,10 @@ class ProfileScreen extends StatefulWidget {
}

class _ProfileScreenState extends State<ProfileScreen> {
String? _image;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
final _formKey = GlobalKey<FormState>();

return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
Expand Down Expand Up @@ -96,26 +101,43 @@ class _ProfileScreenState extends State<ProfileScreen> {
),
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(mq.height * .3),
child: CachedNetworkImage(
width: mq.height * .3,
height: mq.height * .3,
imageUrl: widget.user.Image,
placeholder: (context, url) =>
const CircularProgressIndicator(),
errorWidget: (context, url, error) =>
const CircleAvatar(
child: Icon(CupertinoIcons.person),
),
),
),
//profile picture
_image != null
?

//local image
ClipRRect(
borderRadius:
BorderRadius.circular(mq.height * .1),
child: Image.file(File(_image!),
width: mq.height * .2,
height: mq.height * .2,
fit: BoxFit.cover))
:

//image from server
ClipRRect(
borderRadius:
BorderRadius.circular(mq.height * .1),
child: CachedNetworkImage(
width: mq.height * .2,
height: mq.height * .2,
fit: BoxFit.cover,
imageUrl: widget.user.Image,
errorWidget: (context, url, error) =>
const CircleAvatar(
child: Icon(CupertinoIcons.person)),
),
),
// edit image button
Positioned(
bottom: 0,
right: 0,
child: MaterialButton(
elevation: 1,
onPressed: () {},
onPressed: () {
_showBottomSheet();
},
color: Colors.white,
shape: const CircleBorder(),
child: const Icon(
Expand Down Expand Up @@ -195,4 +217,97 @@ class _ProfileScreenState extends State<ProfileScreen> {
)),
);
}

void _showBottomSheet() {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
builder: (_) {
return ListView(
shrinkWrap: true,
padding:
EdgeInsets.only(top: mq.height * .03, bottom: mq.height * .05),
children: [
//pick profile picture label
const Text('Pick Profile Picture',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500)),

//for adding some space
SizedBox(height: mq.height * .02),

//buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//pick from gallery button
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: const CircleBorder(),
fixedSize: Size(mq.width * .3, mq.height * .15),
),
onPressed: () async {
final ImagePicker picker = ImagePicker();

// Pick an image
try {
final XFile? image = await picker.pickImage(
source: ImageSource.gallery,
// imageQuality: 80,
);

if (image != null) {
print('Image Path: ${image.path}');
setState(() {
_image = image.path;
});
}
} catch (e) {
print('Error picking image: $e');
}
APIs.updateProfilePicture(File(_image!));
//for hiding bottom sheet after image selection
// ignore: use_build_context_synchronously
Navigator.pop(context);
},
child: Image.asset('assets/images/images.png'),
),

//take picture from camera button
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: const CircleBorder(),
fixedSize: Size(mq.width * .3, mq.height * .15)),
onPressed: () async {
final ImagePicker picker = ImagePicker();

// Pick an image
try {
final XFile? photo = await picker.pickImage(
source: ImageSource.camera);

if (photo != null) {
setState(() {
_image = photo.path;
});
}
} catch (e) {
print('Error picking image: $e');
}
APIs.updateProfilePicture(File(_image!));
//for hiding bottom sheet after image selection
// ignore: use_build_context_synchronously
Navigator.pop(context);
},
child: Image.asset('assets/images/camera.png')),
],
)
],
);
});
}
}
4 changes: 4 additions & 0 deletions login/linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

#include "generated_plugin_registrant.h"

#include <file_selector_linux/file_selector_plugin.h>

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);
}
1 change: 1 addition & 0 deletions login/linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down
4 changes: 4 additions & 0 deletions login/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import FlutterMacOS
import Foundation

import cloud_firestore
import file_selector_macos
import firebase_auth
import firebase_core
import firebase_storage
import google_sign_in_ios
import path_provider_foundation
import sqflite

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin"))
FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
Expand Down
Loading

0 comments on commit 8d04894

Please sign in to comment.