profile_drawer_header.dart 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
  3. import 'package:hooks_riverpod/hooks_riverpod.dart';
  4. import 'package:image_picker/image_picker.dart';
  5. import 'package:immich_mobile/modules/home/providers/upload_profile_image.provider.dart';
  6. import 'package:immich_mobile/shared/models/store.dart';
  7. import 'package:immich_mobile/shared/ui/user_circle_avatar.dart';
  8. import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
  9. import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
  10. import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
  11. class ProfileDrawerHeader extends HookConsumerWidget {
  12. const ProfileDrawerHeader({
  13. Key? key,
  14. }) : super(key: key);
  15. @override
  16. Widget build(BuildContext context, WidgetRef ref) {
  17. AuthenticationState authState = ref.watch(authenticationProvider);
  18. final uploadProfileImageStatus =
  19. ref.watch(uploadProfileImageProvider).status;
  20. final isDarkMode = Theme.of(context).brightness == Brightness.dark;
  21. final user = Store.tryGet(StoreKey.currentUser);
  22. buildUserProfileImage() {
  23. if (authState.profileImagePath.isEmpty || user == null) {
  24. return const CircleAvatar(
  25. radius: 35,
  26. backgroundImage: AssetImage('assets/immich-logo-no-outline.png'),
  27. backgroundColor: Colors.transparent,
  28. );
  29. }
  30. var userImage = UserCircleAvatar(
  31. radius: 35,
  32. size: 66,
  33. user: user,
  34. );
  35. if (uploadProfileImageStatus == UploadProfileStatus.idle) {
  36. if (authState.profileImagePath.isNotEmpty) {
  37. return userImage;
  38. } else {
  39. return const CircleAvatar(
  40. radius: 33,
  41. backgroundImage: AssetImage('assets/immich-logo-no-outline.png'),
  42. backgroundColor: Colors.transparent,
  43. );
  44. }
  45. }
  46. if (uploadProfileImageStatus == UploadProfileStatus.success) {
  47. return userImage;
  48. }
  49. if (uploadProfileImageStatus == UploadProfileStatus.failure) {
  50. return const CircleAvatar(
  51. radius: 35,
  52. backgroundImage: AssetImage('assets/immich-logo-no-outline.png'),
  53. backgroundColor: Colors.transparent,
  54. );
  55. }
  56. if (uploadProfileImageStatus == UploadProfileStatus.loading) {
  57. return const ImmichLoadingIndicator();
  58. }
  59. return const SizedBox();
  60. }
  61. pickUserProfileImage() async {
  62. final XFile? image = await ImagePicker().pickImage(
  63. source: ImageSource.gallery,
  64. maxHeight: 1024,
  65. maxWidth: 1024,
  66. );
  67. if (image != null) {
  68. var success =
  69. await ref.watch(uploadProfileImageProvider.notifier).upload(image);
  70. if (success) {
  71. ref.watch(authenticationProvider.notifier).updateUserProfileImagePath(
  72. ref.read(uploadProfileImageProvider).profileImagePath,
  73. );
  74. }
  75. }
  76. }
  77. useEffect(
  78. () {
  79. // buildUserProfileImage();
  80. return null;
  81. },
  82. [],
  83. );
  84. return DrawerHeader(
  85. decoration: BoxDecoration(
  86. gradient: LinearGradient(
  87. colors: isDarkMode
  88. ? [
  89. const Color.fromARGB(255, 22, 25, 48),
  90. const Color.fromARGB(255, 13, 13, 13),
  91. const Color.fromARGB(255, 0, 0, 0),
  92. ]
  93. : [
  94. const Color.fromARGB(255, 216, 219, 238),
  95. const Color.fromARGB(255, 242, 242, 242),
  96. Colors.white,
  97. ],
  98. begin: Alignment.centerRight,
  99. end: Alignment.centerLeft,
  100. ),
  101. ),
  102. child: Column(
  103. mainAxisAlignment: MainAxisAlignment.start,
  104. crossAxisAlignment: CrossAxisAlignment.start,
  105. children: [
  106. GestureDetector(
  107. onTap: pickUserProfileImage,
  108. child: Stack(
  109. clipBehavior: Clip.none,
  110. children: [
  111. buildUserProfileImage(),
  112. Positioned(
  113. bottom: 0,
  114. right: -5,
  115. child: Material(
  116. color: isDarkMode ? Colors.grey[700] : Colors.grey[100],
  117. elevation: 3,
  118. shape: RoundedRectangleBorder(
  119. borderRadius: BorderRadius.circular(50.0),
  120. ),
  121. child: Padding(
  122. padding: const EdgeInsets.all(5.0),
  123. child: Icon(
  124. Icons.edit,
  125. color: Theme.of(context).primaryColor,
  126. size: 14,
  127. ),
  128. ),
  129. ),
  130. ),
  131. ],
  132. ),
  133. ),
  134. Text(
  135. "${authState.firstName} ${authState.lastName}",
  136. style: TextStyle(
  137. color: Theme.of(context).primaryColor,
  138. fontWeight: FontWeight.bold,
  139. fontSize: 24,
  140. ),
  141. ),
  142. Text(
  143. authState.userEmail,
  144. style: Theme.of(context).textTheme.labelMedium,
  145. ),
  146. ],
  147. ),
  148. );
  149. }
  150. }