chore: add base language to public profile and display it in participant list (#2438)

This commit is contained in:
ggurdin 2025-04-14 12:35:38 -04:00 committed by GitHub
parent ddbc215252
commit 672d8579a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 43 additions and 154 deletions

View file

@ -5,8 +5,8 @@ import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/analytics_misc/level_display_name.dart';
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
import 'package:fluffychat/pangea/user/widgets/public_level_indicator.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/utils/url_launcher.dart';
@ -196,7 +196,10 @@ class UserBottomSheetView extends StatelessWidget {
},
),
// #Pangea
PublicLevelIndicator(userId: userId),
Padding(
padding: const EdgeInsets.all(8.0),
child: LevelDisplayName(userId: userId),
),
// Pangea#
],
),

View file

@ -58,6 +58,21 @@ class LevelDisplayNameState extends State<LevelDisplayName> {
Row(
spacing: 4.0,
children: [
if (_profile?.baseLanguage != null &&
_profile?.targetLanguage != null)
Text(
_profile!.baseLanguage!.langCodeShort.toUpperCase(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
if (_profile?.baseLanguage != null &&
_profile?.targetLanguage != null)
const Icon(
Icons.arrow_forward_outlined,
size: 16.0,
),
if (_profile?.targetLanguage != null)
Text(
_profile!.targetLanguage!.langCodeShort.toUpperCase(),

View file

@ -197,6 +197,7 @@ class UserSettingsState extends State<UserSettingsPage> {
),
_pangeaController.userController.updatePublicProfile(
targetLanguage: selectedTargetLanguage,
baseLanguage: _systemLanguage,
level: 1,
),
];

View file

@ -190,16 +190,20 @@ class UserController extends BaseController {
Future<void> updatePublicProfile({
required int level,
LanguageModel? baseLanguage,
LanguageModel? targetLanguage,
}) async {
targetLanguage ??= _pangeaController.languageController.userL2;
baseLanguage ??= _pangeaController.languageController.userL1;
if (targetLanguage == null || publicProfile == null) return;
if (publicProfile!.targetLanguage == targetLanguage &&
publicProfile!.baseLanguage == baseLanguage &&
publicProfile!.languageAnalytics?[targetLanguage]?.level == level) {
return;
}
publicProfile!.baseLanguage = baseLanguage;
publicProfile!.targetLanguage = targetLanguage;
publicProfile!.setLevel(targetLanguage, level);
await _savePublicProfile();

View file

@ -4,10 +4,15 @@ import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart';
class PublicProfileModel {
LanguageModel? baseLanguage;
LanguageModel? targetLanguage;
Map<LanguageModel, LanguageAnalyticsProfileEntry>? languageAnalytics;
PublicProfileModel({this.targetLanguage, this.languageAnalytics});
PublicProfileModel({
this.baseLanguage,
this.targetLanguage,
this.languageAnalytics,
});
factory PublicProfileModel.fromJson(Map<String, dynamic> json) {
if (!json.containsKey(PangeaEventTypes.profileAnalytics)) {
@ -16,6 +21,10 @@ class PublicProfileModel {
final profileJson = json[PangeaEventTypes.profileAnalytics];
final baseLanguage = profileJson[ModelKey.userSourceLanguage] != null
? PLanguageStore.byLangCode(profileJson[ModelKey.userSourceLanguage])
: null;
final targetLanguage = profileJson[ModelKey.userTargetLanguage] != null
? PLanguageStore.byLangCode(profileJson[ModelKey.userTargetLanguage])
: null;
@ -34,6 +43,7 @@ class PublicProfileModel {
}
final profile = PublicProfileModel(
baseLanguage: baseLanguage,
targetLanguage: targetLanguage,
languageAnalytics: languageAnalytics,
);
@ -42,10 +52,15 @@ class PublicProfileModel {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (targetLanguage != null) {
json[ModelKey.userTargetLanguage] = targetLanguage!.langCodeShort;
}
if (baseLanguage != null) {
json[ModelKey.userSourceLanguage] = baseLanguage!.langCodeShort;
}
final analytics = {};
if (languageAnalytics != null && languageAnalytics!.isNotEmpty) {
for (final entry in languageAnalytics!.entries) {
@ -61,7 +76,8 @@ class PublicProfileModel {
}
bool get isEmpty =>
targetLanguage == null &&
baseLanguage == null ||
targetLanguage == null ||
(languageAnalytics == null || languageAnalytics!.isEmpty);
void setLevel(LanguageModel language, int level) {

View file

@ -1,150 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/user/models/profile_model.dart';
import 'package:fluffychat/widgets/matrix.dart';
class PublicLevelIndicator extends StatelessWidget {
final String userId;
const PublicLevelIndicator({
required this.userId,
super.key,
});
@override
Widget build(BuildContext context) {
final profileFuture =
MatrixState.pangeaController.userController.getPublicProfile(userId);
return FutureBuilder<PublicProfileModel>(
future: profileFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Padding(
padding: EdgeInsets.all(16),
child: LinearProgressIndicator(),
);
}
if (snapshot.hasError) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.surfaceBright,
),
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
size: 14,
Icons.error_outline,
color: Theme.of(context).colorScheme.error,
weight: 1000,
),
const SizedBox(width: 5),
Text(
L10n.of(context).oopsSomethingWentWrong,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
if (snapshot.hasData &&
snapshot.data!.targetLanguage == null &&
snapshot.data!.level == null) {
return const SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (snapshot.data?.targetLanguage != null)
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.surfaceBright,
),
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
size: 14,
Icons.language,
color: Theme.of(context).colorScheme.primary,
weight: 1000,
),
const SizedBox(width: 5),
Text(
snapshot.data!.targetLanguage!.displayName,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
const SizedBox(width: 12),
if (snapshot.data?.level != null)
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.surfaceBright,
),
padding: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 2,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CircleAvatar(
backgroundColor: AppConfig.gold,
radius: 8,
child: Icon(
size: 12,
Icons.star,
color: Theme.of(context).colorScheme.surfaceBright,
weight: 1000,
),
),
const SizedBox(width: 4),
Text(
L10n.of(context).levelShort(snapshot.data!.level!),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
],
),
);
},
);
}
}