chore: add base language to public profile and display it in participant list (#2438)
This commit is contained in:
parent
ddbc215252
commit
672d8579a5
6 changed files with 43 additions and 154 deletions
|
|
@ -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#
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ class UserSettingsState extends State<UserSettingsPage> {
|
|||
),
|
||||
_pangeaController.userController.updatePublicProfile(
|
||||
targetLanguage: selectedTargetLanguage,
|
||||
baseLanguage: _systemLanguage,
|
||||
level: 1,
|
||||
),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue