yumi-flutter/lib/shared/tools/sc_cp_relation_pair_utils.dart
2026-05-22 19:32:01 +08:00

119 lines
3.5 KiB
Dart

import 'package:yumi/shared/business_logic/models/res/login_res.dart';
import 'package:yumi/shared/tools/sc_cp_relation_level_utils.dart';
import 'package:yumi/shared/tools/sc_cp_relation_notice_utils.dart';
class SCCpRelationPairInfo {
const SCCpRelationPairInfo({required this.relationType, this.cpLevel});
final String relationType;
final int? cpLevel;
}
String? scCpRelationTypeBetweenProfiles(
SocialChatUserProfile? left,
SocialChatUserProfile? right,
) {
return scCpRelationInfoBetweenProfiles(left, right)?.relationType;
}
SCCpRelationPairInfo? scCpRelationInfoBetweenProfiles(
SocialChatUserProfile? left,
SocialChatUserProfile? right,
) {
if (!_hasRelationIdentity(left) || !_hasRelationIdentity(right)) {
return null;
}
SCCpRelationPairInfo? fallbackInfo;
for (final relation in _relationsForProfile(left)) {
final relationInfo = _relationInfoIfContainsBoth(relation, left!, right!);
if (relationInfo != null) {
if (relationInfo.relationType != "CP" || relationInfo.cpLevel != null) {
return relationInfo;
}
fallbackInfo ??= relationInfo;
}
}
for (final relation in _relationsForProfile(right)) {
final relationInfo = _relationInfoIfContainsBoth(relation, left!, right!);
if (relationInfo != null) {
if (relationInfo.relationType != "CP" || relationInfo.cpLevel != null) {
return relationInfo;
}
fallbackInfo ??= relationInfo;
}
}
return fallbackInfo;
}
int scCpProfileRelationVersion(SocialChatUserProfile? profile) {
if (profile == null) {
return 0;
}
return Object.hashAll(
_relationsForProfile(profile).map(
(relation) => Object.hash(
relation.meUserId ?? "",
relation.meAccount ?? "",
relation.cpUserId ?? "",
relation.cpAccount ?? "",
relation.relationType ?? "",
relation.status ?? "",
relation.levelText ?? "",
relation.cpValue ?? 0,
),
),
);
}
Iterable<CPRes> _relationsForProfile(SocialChatUserProfile? profile) sync* {
yield* profile?.cpList ?? const <CPRes>[];
yield* profile?.closeFriendList ?? const <CPRes>[];
}
SCCpRelationPairInfo? _relationInfoIfContainsBoth(
CPRes relation,
SocialChatUserProfile left,
SocialChatUserProfile right,
) {
final leftKeys = _profileKeys(left);
final rightKeys = _profileKeys(right);
if (leftKeys.isEmpty || rightKeys.isEmpty) {
return null;
}
final relationKeys = _relationKeys(relation);
if (!relationKeys.any(leftKeys.contains) ||
!relationKeys.any(rightKeys.contains)) {
return null;
}
final relationType = scNormalizeCpRelationType(relation.relationType);
return SCCpRelationPairInfo(
relationType: relationType,
cpLevel: relationType == "CP" ? _cpLevelFromRelation(relation) : null,
);
}
bool _hasRelationIdentity(SocialChatUserProfile? profile) =>
_profileKeys(profile).isNotEmpty;
Set<String> _profileKeys(SocialChatUserProfile? profile) {
return <String>{
_normalizedRelationKey(profile?.id),
_normalizedRelationKey(profile?.account),
}..remove("");
}
Set<String> _relationKeys(CPRes relation) {
return <String>{
_normalizedRelationKey(relation.meUserId),
_normalizedRelationKey(relation.meAccount),
_normalizedRelationKey(relation.cpUserId),
_normalizedRelationKey(relation.cpAccount),
}..remove("");
}
String _normalizedRelationKey(String? value) => value?.trim() ?? "";
int? _cpLevelFromRelation(CPRes relation) {
return scCpRelationLevelIndexOrNull(relation.levelText);
}