[mob][photos] Use first letter avatar for contact in contacts section and all contacts screen if no person is linked to contact
This commit is contained in:
@@ -2,3 +2,4 @@ const kPersonParamID = 'person_id';
|
||||
const kPersonWidgetKey = 'person_widget_key';
|
||||
const kClusterParamId = 'cluster_id';
|
||||
const kFileID = 'file_id';
|
||||
const kContactEmail = 'contact_email';
|
||||
|
||||
@@ -1728,6 +1728,7 @@ class SearchService {
|
||||
),
|
||||
params: {
|
||||
kPersonParamID: key.linkedPersonID,
|
||||
kContactEmail: key.email,
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -1803,6 +1804,7 @@ class SearchService {
|
||||
),
|
||||
params: {
|
||||
kPersonParamID: key.linkedPersonID,
|
||||
kContactEmail: key.email,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import "dart:async";
|
||||
import "package:collection/collection.dart";
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:logging/logging.dart";
|
||||
import "package:photos/core/configuration.dart";
|
||||
import "package:photos/core/event_bus.dart";
|
||||
import "package:photos/events/people_changed_event.dart";
|
||||
import "package:photos/extensions/user_extension.dart";
|
||||
@@ -130,7 +131,7 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
_logger.severe("Error loading personID", snapshot.error);
|
||||
return _FirstLetterAvatar(
|
||||
return _FirstLetterCircularAvatar(
|
||||
user: widget.user,
|
||||
currentUserID: widget.currentUserID,
|
||||
thumbnailView: widget.thumbnailView,
|
||||
@@ -138,7 +139,7 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
|
||||
);
|
||||
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.data == null) {
|
||||
return _FirstLetterAvatar(
|
||||
return _FirstLetterCircularAvatar(
|
||||
user: widget.user,
|
||||
currentUserID: widget.currentUserID,
|
||||
thumbnailView: widget.thumbnailView,
|
||||
@@ -150,7 +151,7 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
|
||||
),
|
||||
),
|
||||
)
|
||||
: _FirstLetterAvatar(
|
||||
: _FirstLetterCircularAvatar(
|
||||
user: widget.user,
|
||||
currentUserID: widget.currentUserID,
|
||||
thumbnailView: widget.thumbnailView,
|
||||
@@ -159,12 +160,12 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
class _FirstLetterAvatar extends StatefulWidget {
|
||||
class _FirstLetterCircularAvatar extends StatefulWidget {
|
||||
final User user;
|
||||
final int currentUserID;
|
||||
final bool thumbnailView;
|
||||
final AvatarType type;
|
||||
const _FirstLetterAvatar({
|
||||
const _FirstLetterCircularAvatar({
|
||||
required this.user,
|
||||
required this.currentUserID,
|
||||
required this.thumbnailView,
|
||||
@@ -172,10 +173,12 @@ class _FirstLetterAvatar extends StatefulWidget {
|
||||
});
|
||||
|
||||
@override
|
||||
State<_FirstLetterAvatar> createState() => _FirstLetterAvatarState();
|
||||
State<_FirstLetterCircularAvatar> createState() =>
|
||||
_FirstLetterCircularAvatarState();
|
||||
}
|
||||
|
||||
class _FirstLetterAvatarState extends State<_FirstLetterAvatar> {
|
||||
class _FirstLetterCircularAvatarState
|
||||
extends State<_FirstLetterCircularAvatar> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
@@ -186,13 +189,12 @@ class _FirstLetterAvatarState extends State<_FirstLetterAvatar> {
|
||||
: widget.user.email.substring(0, 1))
|
||||
: widget.user.displayName!.substring(0, 1);
|
||||
Color decorationColor;
|
||||
if (widget.user.id == null ||
|
||||
widget.user.id! <= 0 ||
|
||||
widget.user.id == widget.currentUserID) {
|
||||
if ((widget.user.id != null && widget.user.id! < 0) ||
|
||||
widget.user.email == Configuration.instance.getEmail()) {
|
||||
decorationColor = Colors.black;
|
||||
} else {
|
||||
decorationColor = colorScheme.avatarColors[
|
||||
(widget.user.id!).remainder(colorScheme.avatarColors.length)];
|
||||
decorationColor = colorScheme.avatarColors[(widget.user.email.length)
|
||||
.remainder(colorScheme.avatarColors.length)];
|
||||
}
|
||||
|
||||
final avatarStyle = getAvatarStyle(context, widget.type);
|
||||
@@ -257,3 +259,57 @@ double getAvatarSize(
|
||||
return 18.0;
|
||||
}
|
||||
}
|
||||
|
||||
class FirstLetterUserAvatar extends StatefulWidget {
|
||||
final User user;
|
||||
const FirstLetterUserAvatar(this.user, {super.key});
|
||||
|
||||
@override
|
||||
State<FirstLetterUserAvatar> createState() => _FirstLetterUserAvatarState();
|
||||
}
|
||||
|
||||
class _FirstLetterUserAvatarState extends State<FirstLetterUserAvatar> {
|
||||
final currentUserEmail = Configuration.instance.getEmail();
|
||||
late User user;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
user = widget.user;
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant FirstLetterUserAvatar oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.user != widget.user) {
|
||||
setState(() {
|
||||
user = widget.user;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
final displayChar = (user.displayName == null || user.displayName!.isEmpty)
|
||||
? ((user.email.isEmpty) ? " " : user.email.substring(0, 1))
|
||||
: user.displayName!.substring(0, 1);
|
||||
Color decorationColor;
|
||||
if ((widget.user.id != null && widget.user.id! < 0) ||
|
||||
user.email == currentUserEmail) {
|
||||
decorationColor = Colors.black;
|
||||
} else {
|
||||
decorationColor = colorScheme.avatarColors[
|
||||
(user.email.length).remainder(colorScheme.avatarColors.length)];
|
||||
}
|
||||
return Container(
|
||||
color: decorationColor,
|
||||
child: Center(
|
||||
child: Text(
|
||||
displayChar.toUpperCase(),
|
||||
style: getEnteTextTheme(context).small.copyWith(color: Colors.white),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:logging/logging.dart";
|
||||
import "package:photos/models/api/collection/user.dart";
|
||||
import 'package:photos/models/file/file.dart';
|
||||
import "package:photos/models/search/generic_search_result.dart";
|
||||
import "package:photos/models/search/search_constants.dart";
|
||||
@@ -8,6 +9,7 @@ import "package:photos/models/search/search_types.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/common/loading_widget.dart";
|
||||
import "package:photos/ui/sharing/user_avator_widget.dart";
|
||||
import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
|
||||
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
|
||||
import 'package:photos/ui/viewer/search/result/person_face_widget.dart';
|
||||
@@ -73,14 +75,14 @@ class _ContactSearchThumbnailWidgetState
|
||||
extends State<ContactSearchThumbnailWidget> {
|
||||
Future<EnteFile?>? _mostRecentFileOfPerson;
|
||||
late String? _personID;
|
||||
late String _email;
|
||||
final _logger = Logger("_ContactSearchThumbnailWidgetState");
|
||||
late final EnteFile? _previewThumbnail;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_previewThumbnail = widget.searchResult.previewThumbnail();
|
||||
_personID = widget.searchResult.params[kPersonParamID];
|
||||
_email = widget.searchResult.params[kContactEmail];
|
||||
if (_personID != null) {
|
||||
_mostRecentFileOfPerson =
|
||||
PersonService.instance.getPerson(_personID!).then((person) {
|
||||
@@ -118,35 +120,38 @@ class _ContactSearchThumbnailWidgetState
|
||||
);
|
||||
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.data == null) {
|
||||
return _previewThumbnail != null
|
||||
? ThumbnailWidget(
|
||||
_previewThumbnail!,
|
||||
)
|
||||
: const NoFaceOrFileContactWidget();
|
||||
return NoFaceForContactWidget(
|
||||
user: User(email: _email),
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
_logger.severe(
|
||||
"Error loading personID",
|
||||
snapshot.error,
|
||||
);
|
||||
return const NoFaceOrFileContactWidget();
|
||||
return NoFaceForContactWidget(
|
||||
user: User(email: _email),
|
||||
);
|
||||
} else {
|
||||
return const EnteLoadingWidget();
|
||||
}
|
||||
},
|
||||
)
|
||||
: _previewThumbnail != null
|
||||
? ThumbnailWidget(
|
||||
_previewThumbnail!,
|
||||
)
|
||||
: const NoFaceOrFileContactWidget(),
|
||||
: NoFaceForContactWidget(
|
||||
user: User(email: _email),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoFaceOrFileContactWidget extends StatelessWidget {
|
||||
class NoFaceForContactWidget extends StatelessWidget {
|
||||
final User user;
|
||||
final bool addBorder;
|
||||
const NoFaceOrFileContactWidget({this.addBorder = true, super.key});
|
||||
const NoFaceForContactWidget({
|
||||
this.addBorder = true,
|
||||
required this.user,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -164,13 +169,7 @@ class NoFaceOrFileContactWidget extends StatelessWidget {
|
||||
: null,
|
||||
color: enteColorScheme.fillFaint,
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.person_2_outlined,
|
||||
color: enteColorScheme.strokeMuted,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
child: Center(child: FirstLetterUserAvatar(user)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import "package:logging/logging.dart";
|
||||
import "package:photos/core/constants.dart";
|
||||
import "package:photos/events/event.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/models/api/collection/user.dart";
|
||||
import "package:photos/models/file/file.dart";
|
||||
import "package:photos/models/search/generic_search_result.dart";
|
||||
import "package:photos/models/search/recent_searches.dart";
|
||||
@@ -14,8 +15,7 @@ import "package:photos/models/search/search_types.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/common/loading_widget.dart";
|
||||
import "package:photos/ui/viewer/file/no_thumbnail_widget.dart";
|
||||
import "package:photos/ui/viewer/file/thumbnail_widget.dart";
|
||||
import "package:photos/ui/sharing/user_avator_widget.dart";
|
||||
import "package:photos/ui/viewer/search/result/contact_result_page.dart";
|
||||
import "package:photos/ui/viewer/search/result/person_face_widget.dart";
|
||||
import "package:photos/ui/viewer/search/search_section_cta.dart";
|
||||
@@ -224,43 +224,34 @@ class _ContactRecommendationState extends State<ContactRecommendation> {
|
||||
} else if (snapshot.connectionState ==
|
||||
ConnectionState.done &&
|
||||
snapshot.data == null) {
|
||||
if (widget.contactSearchResult
|
||||
.previewThumbnail() !=
|
||||
null) {
|
||||
return Hero(
|
||||
tag: heroTag,
|
||||
child: ThumbnailWidget(
|
||||
widget.contactSearchResult
|
||||
.previewThumbnail()!,
|
||||
shouldShowArchiveStatus: false,
|
||||
shouldShowSyncStatus: false,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const NoThumbnailWidget();
|
||||
}
|
||||
return FirstLetterUserAvatar(
|
||||
User(
|
||||
email: widget.contactSearchResult
|
||||
.params[kContactEmail],
|
||||
),
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
_logger.severe(
|
||||
"Error loading personID",
|
||||
snapshot.error,
|
||||
);
|
||||
return const NoThumbnailWidget();
|
||||
return FirstLetterUserAvatar(
|
||||
User(
|
||||
email: widget.contactSearchResult
|
||||
.params[kContactEmail],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const EnteLoadingWidget();
|
||||
}
|
||||
},
|
||||
)
|
||||
: widget.contactSearchResult.previewThumbnail() != null
|
||||
? Hero(
|
||||
tag: heroTag,
|
||||
child: ThumbnailWidget(
|
||||
widget.contactSearchResult
|
||||
.previewThumbnail()!,
|
||||
shouldShowArchiveStatus: false,
|
||||
shouldShowSyncStatus: false,
|
||||
),
|
||||
)
|
||||
: const NoThumbnailWidget(),
|
||||
: FirstLetterUserAvatar(
|
||||
User(
|
||||
email: widget
|
||||
.contactSearchResult.params[kContactEmail],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10.5),
|
||||
|
||||
Reference in New Issue
Block a user