removed any functionality attached to pangea profile, only use it to migrate. Made matrix profile a class with instance members.
This commit is contained in:
parent
ff468cb4bd
commit
ca9dcba4e7
23 changed files with 1171 additions and 1245 deletions
|
|
@ -513,8 +513,9 @@ class Choreographer {
|
|||
chatController.room,
|
||||
);
|
||||
|
||||
bool get itAutoPlayEnabled =>
|
||||
pangeaController.userController.matrixProfile.itAutoPlay;
|
||||
bool get itAutoPlayEnabled {
|
||||
return pangeaController.userController.profile.userSettings.itAutoPlay;
|
||||
}
|
||||
|
||||
bool get definitionsEnabled =>
|
||||
pangeaController.permissionsController.isToolEnabled(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class PLocalKey {
|
||||
static const String user = 'user';
|
||||
static const String access = "access";
|
||||
static const String cachedClassCodeToJoin = "cachedclasscodetojoin";
|
||||
static const String beganWebPayment = "beganWebPayment";
|
||||
static const String dismissedPaywall = 'dismissedPaywall';
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ class ModelKey {
|
|||
static const String l1LanguageKey = 'source_language';
|
||||
static const String publicProfile = 'public';
|
||||
static const String userId = 'user_id';
|
||||
static const String toolSettings = 'tool_settings';
|
||||
static const String userSettings = 'user_settings';
|
||||
static const String instructionsSettings = 'instructions_settings';
|
||||
|
||||
// matrix profile keys
|
||||
// making this a random string so that it's harder to guess
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/language_constants.dart';
|
||||
import 'package:fluffychat/pangea/controllers/language_list_controller.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/models/language_model.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import '../widgets/user_settings/p_language_dialog.dart';
|
||||
|
||||
|
|
@ -18,15 +14,6 @@ class LanguageController {
|
|||
}
|
||||
//show diloag when user does not have languages selected
|
||||
showDialogOnEmptyLanguage(BuildContext dialogContext, Function callback) {
|
||||
if (_pangeaController.userController.userModel?.profile == null) {
|
||||
debugger(when: kDebugMode);
|
||||
Sentry.addBreadcrumb(
|
||||
Breadcrumb(
|
||||
message: 'calling showDialogOnEmptyLanguagae with empty user',
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!languagesSet) {
|
||||
pLanguageDialog(dialogContext, callback);
|
||||
}
|
||||
|
|
@ -42,13 +29,13 @@ class LanguageController {
|
|||
|
||||
String? get _userL1Code {
|
||||
final source =
|
||||
_pangeaController.userController.userModel?.profile?.sourceLanguage;
|
||||
_pangeaController.userController.profile.userSettings.sourceLanguage;
|
||||
return source == null || source.isEmpty ? null : source;
|
||||
}
|
||||
|
||||
String? get _userL2Code {
|
||||
final target =
|
||||
_pangeaController.userController.userModel?.profile?.targetLanguage;
|
||||
_pangeaController.userController.profile.userSettings.targetLanguage;
|
||||
return target == null || target.isEmpty ? null : target;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,24 +204,24 @@ class MyAnalyticsController {
|
|||
|
||||
Completer<void>? _updateCompleter;
|
||||
Future<void> updateAnalytics() async {
|
||||
if (!(_updateCompleter?.isCompleted ?? true)) {
|
||||
await _updateCompleter!.future;
|
||||
return;
|
||||
}
|
||||
_updateCompleter = Completer<void>();
|
||||
try {
|
||||
await _updateAnalytics();
|
||||
clearMessagesSinceUpdate();
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(
|
||||
e: err,
|
||||
m: "Failed to update analytics",
|
||||
s: s,
|
||||
);
|
||||
} finally {
|
||||
_updateCompleter?.complete();
|
||||
_updateCompleter = null;
|
||||
}
|
||||
// if (!(_updateCompleter?.isCompleted ?? true)) {
|
||||
// await _updateCompleter!.future;
|
||||
// return;
|
||||
// }
|
||||
// _updateCompleter = Completer<void>();
|
||||
// try {
|
||||
// await _updateAnalytics();
|
||||
// clearMessagesSinceUpdate();
|
||||
// } catch (err, s) {
|
||||
// ErrorHandler.logError(
|
||||
// e: err,
|
||||
// m: "Failed to update analytics",
|
||||
// s: s,
|
||||
// );
|
||||
// } finally {
|
||||
// _updateCompleter?.complete();
|
||||
// _updateCompleter = null;
|
||||
// }
|
||||
}
|
||||
|
||||
String? get userL2 => _pangeaController.languageController.activeL2Code();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import 'package:fluffychat/pangea/controllers/base_controller.dart';
|
|||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/models/space_model.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/p_extension.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
|
|
@ -31,12 +30,11 @@ class PermissionsController extends BaseController {
|
|||
}
|
||||
|
||||
/// Returns false if user is null
|
||||
bool isUser18() =>
|
||||
_pangeaController.userController.matrixProfile.dateOfBirth
|
||||
?.isAtLeastYearsOld(
|
||||
AgeLimits.toAccessFeatures,
|
||||
) ??
|
||||
false;
|
||||
bool isUser18() {
|
||||
final DateTime? dob =
|
||||
_pangeaController.userController.profile.userSettings.dateOfBirth;
|
||||
return dob?.isAtLeastYearsOld(AgeLimits.toAccessFeatures) ?? false;
|
||||
}
|
||||
|
||||
/// A user can private chat if
|
||||
/// 1) they are 18 and outside a class context or
|
||||
|
|
@ -97,20 +95,22 @@ class PermissionsController extends BaseController {
|
|||
return classPermission == 0;
|
||||
}
|
||||
|
||||
bool userToolSetting(MatrixProfileEnum setting) {
|
||||
switch (setting.asToolSetting) {
|
||||
bool userToolSetting(ToolSetting setting) {
|
||||
switch (setting) {
|
||||
case ToolSetting.interactiveTranslator:
|
||||
return _pangeaController
|
||||
.userController.matrixProfile.interactiveTranslator;
|
||||
.userController.profile.toolSettings.interactiveTranslator;
|
||||
case ToolSetting.interactiveGrammar:
|
||||
return _pangeaController
|
||||
.userController.matrixProfile.interactiveGrammar;
|
||||
.userController.profile.toolSettings.interactiveGrammar;
|
||||
case ToolSetting.immersionMode:
|
||||
return _pangeaController.userController.matrixProfile.immersionMode;
|
||||
return _pangeaController
|
||||
.userController.profile.toolSettings.immersionMode;
|
||||
case ToolSetting.definitions:
|
||||
return _pangeaController.userController.matrixProfile.definitions;
|
||||
return _pangeaController
|
||||
.userController.profile.toolSettings.definitions;
|
||||
case ToolSetting.autoIGC:
|
||||
return _pangeaController.userController.matrixProfile.autoIGC;
|
||||
return _pangeaController.userController.profile.toolSettings.autoIGC;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -118,13 +118,13 @@ class PermissionsController extends BaseController {
|
|||
|
||||
bool isToolEnabled(ToolSetting setting, Room? room) {
|
||||
if (room?.isSpaceAdmin ?? false) {
|
||||
return userToolSetting(setting.asMatrixProfileField);
|
||||
return userToolSetting(setting);
|
||||
}
|
||||
final int? classPermission =
|
||||
room != null ? classLanguageToolPermission(room, setting) : 1;
|
||||
if (classPermission == 0) return false;
|
||||
if (classPermission == 2) return true;
|
||||
return userToolSetting(setting.asMatrixProfileField);
|
||||
return userToolSetting(setting);
|
||||
}
|
||||
|
||||
bool isWritingAssistanceEnabled(Room? room) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import 'package:fluffychat/pangea/controllers/base_controller.dart';
|
|||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/models/base_subscription_info.dart';
|
||||
import 'package:fluffychat/pangea/models/mobile_subscriptions.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/models/web_subscriptions.dart';
|
||||
import 'package:fluffychat/pangea/network/requests.dart';
|
||||
import 'package:fluffychat/pangea/network/urls.dart';
|
||||
|
|
@ -179,31 +178,35 @@ class SubscriptionController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
bool get _activatedNewUserTrial =>
|
||||
_pangeaController.userController.inTrialWindow &&
|
||||
_pangeaController.userController.matrixProfile.activatedFreeTrial;
|
||||
bool get _activatedNewUserTrial {
|
||||
final bool activated = _pangeaController
|
||||
.userController.profile.userSettings.activatedFreeTrial;
|
||||
return _pangeaController.userController.inTrialWindow && activated;
|
||||
}
|
||||
|
||||
void activateNewUserTrial() {
|
||||
_pangeaController.userController.matrixProfile.saveProfileData({
|
||||
MatrixProfileEnum.activatedFreeTrial.title: true,
|
||||
}).then((_) {
|
||||
setNewUserTrial();
|
||||
trialActivationStream.add(true);
|
||||
});
|
||||
_pangeaController.userController.updateProfile(
|
||||
(profile) {
|
||||
profile.userSettings.activatedFreeTrial = true;
|
||||
return profile;
|
||||
},
|
||||
);
|
||||
setNewUserTrial();
|
||||
trialActivationStream.add(true);
|
||||
}
|
||||
|
||||
void setNewUserTrial() {
|
||||
if (_pangeaController.userController.userModel?.profile == null) {
|
||||
final DateTime? createdAt =
|
||||
_pangeaController.userController.profile.userSettings.createdAt;
|
||||
if (createdAt == null) {
|
||||
ErrorHandler.logError(
|
||||
m: "Null user profile in subscription settings",
|
||||
m: "Null user profile createAt in subscription settings",
|
||||
s: StackTrace.current,
|
||||
);
|
||||
return;
|
||||
}
|
||||
final String profileCreatedAt =
|
||||
_pangeaController.userController.userModel!.profile!.createdAt;
|
||||
final DateTime creationTimestamp = DateTime.parse(profileCreatedAt);
|
||||
final DateTime expirationDate = creationTimestamp.add(
|
||||
|
||||
final DateTime expirationDate = createdAt.add(
|
||||
const Duration(days: 7),
|
||||
);
|
||||
subscription?.setTrial(expirationDate);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fluffychat/pangea/constants/language_constants.dart';
|
||||
import 'package:fluffychat/pangea/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/controllers/base_controller.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
|
|
@ -27,61 +26,62 @@ class UserController extends BaseController {
|
|||
String? get _matrixAccessToken =>
|
||||
_pangeaController.matrixState.client.accessToken;
|
||||
|
||||
/// An instance of matrix profile. Used to update and access info from the user's matrix profile.
|
||||
/// No information needs to be passing in the constructor as the matrix
|
||||
/// profile get all of it's internal data the accountData stored in the client.
|
||||
MatrixProfile matrixProfile = MatrixProfile();
|
||||
Profile? _cachedProfile;
|
||||
|
||||
/// Returns the [PUserModel] object representing the current user.
|
||||
///
|
||||
/// This method retrieves the user data from the local storage using the [PLocalKey.user] key.
|
||||
/// If the data exists, it is converted to a [PUserModel] object using the [PUserModel.fromJson] method.
|
||||
/// If the data is null, indicating that the user is not logged in (or that
|
||||
/// profile fetching has not yet completed, or had an error), null is returned.
|
||||
PUserModel? get userModel {
|
||||
final data = _pangeaController.pStoreService.read(PLocalKey.user);
|
||||
return data != null ? PUserModel.fromJson(data) : null;
|
||||
/// Listen for updates to account data in syncs and update the cached profile
|
||||
void addProfileListener() {
|
||||
_pangeaController.matrixState.client.onSync.stream
|
||||
.where((sync) => sync.accountData != null)
|
||||
.listen((sync) {
|
||||
final Profile? fromAccountData = Profile.fromAccountData();
|
||||
if (fromAccountData != null) {
|
||||
_cachedProfile = fromAccountData;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Creates a user pangea chat profile, saves the user's profile information
|
||||
/// locally, and set the user's DOB in their matrix profile.
|
||||
///
|
||||
/// The [dob] parameter is required and represents the date of birth of the user.
|
||||
/// This method creates a new [PUserModel] using the [PUserRepo.repoCreatePangeaUser] method,
|
||||
/// and saves the user model in local storage.
|
||||
/// It also updates the user's matrix profile using the [updateMatrixProfile] method.
|
||||
Future<void> createProfile({required String dob}) async {
|
||||
if (userId == null || _matrixAccessToken == null) {
|
||||
ErrorHandler.logError(
|
||||
e: "calling createProfile with userId == null or matrixAccessToken == null",
|
||||
);
|
||||
/// The user's profile. Will be empty if the client's accountData hasn't
|
||||
/// been loaded yet (if the first sync hasn't gone through yet)
|
||||
/// or if the user hasn't yer set their date of birth.
|
||||
Profile get profile {
|
||||
/// if the profile is cached, return it
|
||||
if (_cachedProfile != null) return _cachedProfile!;
|
||||
|
||||
/// if account data is empty, return an empty profile
|
||||
if (_pangeaController.matrixState.client.accountData.isEmpty) {
|
||||
return Profile.emptyProfile;
|
||||
}
|
||||
final PUserModel newUserModel = await PUserRepo.repoCreatePangeaUser(
|
||||
userID: userId!,
|
||||
fullName: fullname,
|
||||
dob: dob,
|
||||
matrixAccessToken: _matrixAccessToken!,
|
||||
);
|
||||
newUserModel.save(_pangeaController);
|
||||
await matrixProfile.saveProfileData(
|
||||
{MatrixProfileEnum.dateOfBirth.title: dob},
|
||||
waitForDataInSync: true,
|
||||
|
||||
/// try to get the account data in the up-to-date format
|
||||
final Profile? fromAccountData = Profile.fromAccountData();
|
||||
if (fromAccountData != null) {
|
||||
_cachedProfile = fromAccountData;
|
||||
return fromAccountData;
|
||||
}
|
||||
|
||||
_cachedProfile = Profile.migrateFromAccountData();
|
||||
_cachedProfile?.saveProfileData();
|
||||
return _cachedProfile ?? Profile.emptyProfile;
|
||||
}
|
||||
|
||||
void updateProfile(Profile Function(Profile) update) {
|
||||
final Profile updatedProfile = update(profile);
|
||||
updatedProfile.saveProfileData();
|
||||
}
|
||||
|
||||
Future<void> createProfile({required DateTime dob}) async {
|
||||
final userSettings = UserSettings(
|
||||
dateOfBirth: dob,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
final newProfile = Profile(userSettings: userSettings);
|
||||
await newProfile.saveProfileData(waitForDataInSync: true);
|
||||
}
|
||||
|
||||
/// A completer for the profile model of a user.
|
||||
Completer<PUserModel?>? _profileCompleter;
|
||||
Completer<void>? _profileCompleter;
|
||||
|
||||
/// Fetches the user model.
|
||||
///
|
||||
/// This method retrieves the user model asynchronously. If the profile completer is already completed,
|
||||
/// it returns the future value of the completer. If the user model is currently being fetched,
|
||||
/// it waits for the completion of the completer and returns the future value. Otherwise, it sets
|
||||
/// the fetching flag, fetches the user model, completes the profile completer with the fetched user model,
|
||||
/// and returns the future value of the completer.
|
||||
///
|
||||
/// Returns the future value of the user model completer.
|
||||
Future<PUserModel?> fetchUserModel() async {
|
||||
Future<void> initialize() async {
|
||||
if (_profileCompleter?.isCompleted ?? false) {
|
||||
return _profileCompleter!.future;
|
||||
}
|
||||
|
|
@ -91,213 +91,79 @@ class UserController extends BaseController {
|
|||
return _profileCompleter!.future;
|
||||
}
|
||||
|
||||
_profileCompleter = Completer<PUserModel?>();
|
||||
PUserModel? fetchedUserModel;
|
||||
_profileCompleter = Completer<void>();
|
||||
|
||||
try {
|
||||
fetchedUserModel = await _fetchUserModel();
|
||||
await _initialize();
|
||||
addProfileListener();
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(e: err, s: s);
|
||||
} finally {
|
||||
_profileCompleter!.complete(fetchedUserModel);
|
||||
_profileCompleter!.complete();
|
||||
}
|
||||
|
||||
return _profileCompleter!.future;
|
||||
}
|
||||
|
||||
/// Fetches the user model asynchronously.
|
||||
///
|
||||
/// This method fetches the user model by calling the [fetchPangeaUserInfo] method
|
||||
/// from the [PUserRepo] class. It requires the [_matrixAccessToken] and [userId]
|
||||
/// to be non-null. If either of them is null, an error is logged.
|
||||
///
|
||||
/// The fetched [newUserModel] is then saved locally.
|
||||
/// The [migrateMatrixProfile] method is called, to migrate any information that is
|
||||
/// already saved in the user's pangea profile but is not yet saved in the
|
||||
/// user's matrix profile. Finally, the [newUserModel] is returned.
|
||||
Future<PUserModel?> _fetchUserModel() async {
|
||||
if (_matrixAccessToken == null || userId == null) {
|
||||
ErrorHandler.logError(
|
||||
e: "calling fetchUserModel with userId == null or matrixAccessToken == null",
|
||||
);
|
||||
return null;
|
||||
Future<void> _initialize() async {
|
||||
await waitForAccountData();
|
||||
if (profile.userSettings.dateOfBirth != null) {
|
||||
return;
|
||||
}
|
||||
final PUserModel? newUserModel = await PUserRepo.fetchPangeaUserInfo(
|
||||
final PangeaProfileResponse? resp = await PUserRepo.fetchPangeaUserInfo(
|
||||
userID: userId!,
|
||||
matrixAccessToken: _matrixAccessToken!,
|
||||
);
|
||||
newUserModel?.save(_pangeaController);
|
||||
await migrateMatrixProfile();
|
||||
return newUserModel;
|
||||
if (resp?.profile == null) {
|
||||
return;
|
||||
}
|
||||
final userSetting = UserSettings.fromJson(resp!.profile.toJson());
|
||||
final newProfile = Profile(userSettings: userSetting);
|
||||
await newProfile.saveProfileData(waitForDataInSync: true);
|
||||
}
|
||||
|
||||
/// Reinitializes the user's profile
|
||||
/// This method should be called whenever the user's login status changes
|
||||
Future<void> reinitialize() async {
|
||||
_profileCompleter = null;
|
||||
await fetchUserModel();
|
||||
_cachedProfile = null;
|
||||
await initialize();
|
||||
}
|
||||
|
||||
/// Migrates the user's profile from Pangea to Matrix.
|
||||
///
|
||||
/// This method retrieves the user's profile / local settings information from Pangea and checks for corresponding information stored in Matrix.
|
||||
/// If any of the profile fields in Pangea have information, but the corresponding fields in Matrix are null, the values are updated in Matrix.
|
||||
/// The profile fields that are checked for migration include date of birth, creation date, target language, source language, country, and public profile.
|
||||
/// Additionally, several profile settings related to auto play, trial activation, interactive features, and instructional messages are also checked for migration.
|
||||
///
|
||||
/// This method calls the [updateMatrixProfile] method to update the user's profile in Matrix with the migrated values.
|
||||
///
|
||||
/// Note: This method assumes that the [userModel] and [_pangeaController] instances are properly initialized before calling this method.
|
||||
Future<void> migrateMatrixProfile() async {
|
||||
// This function relies on the client's account data being loaded.
|
||||
// The account data is loaded during
|
||||
// the first sync, so wait for that to complete.
|
||||
/// Account data comes through in the first sync, so wait for that
|
||||
Future<void> waitForAccountData() async {
|
||||
final client = _pangeaController.matrixState.client;
|
||||
if (client.prevBatch == null) {
|
||||
await client.onSync.stream.first;
|
||||
}
|
||||
|
||||
final Map<String, dynamic> profileUpdates = {};
|
||||
final Profile? pangeaProfile = userModel?.profile;
|
||||
|
||||
for (final field in MatrixProfile.pangeaProfileFields) {
|
||||
final dynamic matrixValue = matrixProfile.getProfileData(field);
|
||||
dynamic pangeaValue;
|
||||
switch (field) {
|
||||
case MatrixProfileEnum.dateOfBirth:
|
||||
pangeaValue = pangeaProfile?.dateOfBirth;
|
||||
break;
|
||||
case MatrixProfileEnum.createdAt:
|
||||
pangeaValue = pangeaProfile?.createdAt;
|
||||
break;
|
||||
case MatrixProfileEnum.targetLanguage:
|
||||
pangeaValue = pangeaProfile?.targetLanguage;
|
||||
break;
|
||||
case MatrixProfileEnum.sourceLanguage:
|
||||
pangeaValue = pangeaProfile?.sourceLanguage;
|
||||
break;
|
||||
case MatrixProfileEnum.country:
|
||||
pangeaValue = pangeaProfile?.country;
|
||||
break;
|
||||
case MatrixProfileEnum.publicProfile:
|
||||
pangeaValue = pangeaProfile?.publicProfile;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (pangeaValue != null && matrixValue == null) {
|
||||
profileUpdates[field.title] = pangeaValue;
|
||||
}
|
||||
}
|
||||
|
||||
for (final value in MatrixProfileEnum.values) {
|
||||
if (profileUpdates.containsKey(value.title)) continue;
|
||||
final dynamic localValue =
|
||||
_pangeaController.pStoreService.read(value.title);
|
||||
final dynamic matrixValue = matrixProfile.getProfileData(value);
|
||||
final dynamic unmigratedValue =
|
||||
localValue != null && matrixValue == null ? localValue : null;
|
||||
if (unmigratedValue != null) {
|
||||
profileUpdates[value.title] = unmigratedValue;
|
||||
}
|
||||
}
|
||||
|
||||
await matrixProfile.saveProfileData(
|
||||
profileUpdates,
|
||||
waitForDataInSync: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates the user's profile with the provided information.
|
||||
///
|
||||
/// The [dateOfBirth] parameter is the new date of birth for the user.
|
||||
/// The [targetLanguage] parameter is the new target language for the user.
|
||||
/// The [sourceLanguage] parameter is the new source language for the user.
|
||||
/// The [country] parameter is the new country for the user.
|
||||
/// The [interests] parameter is a list of new interests for the user.
|
||||
/// The [speaks] parameter is a list of new languages the user speaks.
|
||||
/// The [publicProfile] parameter indicates whether the user's profile should be public or not.
|
||||
Future<void> updateUserProfile({
|
||||
String? dateOfBirth,
|
||||
String? targetLanguage,
|
||||
String? sourceLanguage,
|
||||
String? country,
|
||||
List<String>? interests,
|
||||
List<String>? speaks,
|
||||
bool? publicProfile,
|
||||
}) async {
|
||||
if (userModel == null) {
|
||||
ErrorHandler.logError(
|
||||
e: "calling updateUserProfile with userModel == null",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final profileJson = userModel!.profile!.toJson();
|
||||
|
||||
if (dateOfBirth != null) {
|
||||
profileJson[ModelKey.userDateOfBirth] = dateOfBirth;
|
||||
}
|
||||
if (targetLanguage != null) {
|
||||
profileJson[ModelKey.userTargetLanguage] = targetLanguage;
|
||||
}
|
||||
if (sourceLanguage != null) {
|
||||
profileJson[ModelKey.userSourceLanguage] = sourceLanguage;
|
||||
}
|
||||
if (interests != null) {
|
||||
profileJson[ModelKey.userInterests] = interests.toString();
|
||||
}
|
||||
if (speaks != null) {
|
||||
profileJson[ModelKey.userSpeaks] = speaks.toString();
|
||||
}
|
||||
if (country != null) {
|
||||
profileJson[ModelKey.userCountry] = country;
|
||||
}
|
||||
if (publicProfile != null) {
|
||||
profileJson[ModelKey.publicProfile] = publicProfile;
|
||||
}
|
||||
|
||||
final Profile updatedUserProfile = await PUserRepo.updateUserProfile(
|
||||
Profile.fromJson(profileJson),
|
||||
await accessToken,
|
||||
);
|
||||
|
||||
PUserModel(
|
||||
access: await accessToken,
|
||||
refresh: userModel!.refresh,
|
||||
profile: updatedUserProfile,
|
||||
).save(_pangeaController);
|
||||
|
||||
matrixProfile.saveProfileData({
|
||||
MatrixProfileEnum.dateOfBirth.title: dateOfBirth,
|
||||
MatrixProfileEnum.targetLanguage.title: targetLanguage,
|
||||
MatrixProfileEnum.sourceLanguage.title: sourceLanguage,
|
||||
MatrixProfileEnum.country.title: country,
|
||||
MatrixProfileEnum.publicProfile.title: publicProfile,
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns a boolean value indicating whether a new JWT (JSON Web Token) is needed.
|
||||
/// It checks if the `userModel` has a non-null `access` token and if the token is expired using the `Jwt.isExpired()` method.
|
||||
/// If the `userModel` is null or the `access` token is null, it returns true indicating that a new JWT is needed.
|
||||
bool get needNewJWT =>
|
||||
userModel?.access != null ? Jwt.isExpired(userModel!.access) : true;
|
||||
bool needNewJWT(String token) => Jwt.isExpired(token);
|
||||
|
||||
/// Retrieves the access token for the user.
|
||||
///
|
||||
/// If the locally stored user model is null or the access token has
|
||||
/// expired, it fetches the user model.
|
||||
/// If the user model is still null after fetching, an error thrown.
|
||||
///
|
||||
/// Returns the access token as a string, or null if the user model is null.
|
||||
/// Retrieves the access token for the user. Looks for it locally,
|
||||
/// and if it's not found or expired, fetches it from the server.
|
||||
Future<String> get accessToken async {
|
||||
final PUserModel? useThisOne =
|
||||
needNewJWT ? await fetchUserModel() : userModel;
|
||||
final localAccessToken =
|
||||
_pangeaController.pStoreService.read(PLocalKey.access);
|
||||
|
||||
if (useThisOne == null) {
|
||||
throw ("Trying to get accessToken with null userModel");
|
||||
if (localAccessToken == null || needNewJWT(localAccessToken)) {
|
||||
final PangeaProfileResponse? userModel =
|
||||
await PUserRepo.fetchPangeaUserInfo(
|
||||
userID: userId!,
|
||||
matrixAccessToken: _matrixAccessToken!,
|
||||
);
|
||||
if (userModel?.access == null) {
|
||||
throw ("Trying to get accessToken with null userModel");
|
||||
}
|
||||
_pangeaController.pStoreService.save(
|
||||
PLocalKey.access,
|
||||
userModel!.access,
|
||||
);
|
||||
return userModel.access;
|
||||
}
|
||||
return useThisOne.access;
|
||||
|
||||
return localAccessToken;
|
||||
}
|
||||
|
||||
/// Returns the full name of the user.
|
||||
|
|
@ -314,19 +180,6 @@ class UserController extends BaseController {
|
|||
return userId!.substring(0, userId!.indexOf(":")).replaceAll("@", "");
|
||||
}
|
||||
|
||||
/// Checks if the user data is available.
|
||||
/// Returns a [Future] that completes with a [bool] value
|
||||
/// indicating whether the user data is available or not.
|
||||
Future<bool> get isPUserDataAvailable async {
|
||||
try {
|
||||
final PUserModel? toCheck = userModel ?? (await fetchUserModel());
|
||||
return toCheck != null;
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(e: err, s: s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if user data is available and the date of birth is set.
|
||||
/// Returns a [Future] that completes with a [bool] value indicating
|
||||
/// whether the user data is available and the date of birth is set.
|
||||
|
|
@ -334,8 +187,8 @@ class UserController extends BaseController {
|
|||
try {
|
||||
// the function fetchUserModel() uses a completer, so it shouldn't
|
||||
// re-call the endpoint if it has already been called
|
||||
await fetchUserModel();
|
||||
return matrixProfile.dateOfBirth != null;
|
||||
await initialize();
|
||||
return profile.userSettings.dateOfBirth != null;
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(e: err, s: s);
|
||||
return false;
|
||||
|
|
@ -344,11 +197,11 @@ class UserController extends BaseController {
|
|||
|
||||
/// Returns a boolean value indicating whether the user is currently in the trial window.
|
||||
bool get inTrialWindow {
|
||||
final String? createdAt = userModel?.profile?.createdAt;
|
||||
final DateTime? createdAt = profile.userSettings.createdAt;
|
||||
if (createdAt == null) {
|
||||
return false;
|
||||
}
|
||||
return DateTime.parse(createdAt).isAfter(
|
||||
return createdAt.isAfter(
|
||||
DateTime.now().subtract(const Duration(days: 7)),
|
||||
);
|
||||
}
|
||||
|
|
@ -363,12 +216,8 @@ class UserController extends BaseController {
|
|||
/// If an error occurs during the process, it logs the error and returns `false`.
|
||||
Future<bool> get areUserLanguagesSet async {
|
||||
try {
|
||||
final PUserModel? toCheck = userModel ?? (await fetchUserModel());
|
||||
if (toCheck?.profile == null) {
|
||||
return false;
|
||||
}
|
||||
final String? srcLang = toCheck!.profile!.sourceLanguage;
|
||||
final String? tgtLang = toCheck.profile!.targetLanguage;
|
||||
final String? srcLang = profile.userSettings.sourceLanguage;
|
||||
final String? tgtLang = profile.userSettings.targetLanguage;
|
||||
return srcLang != null &&
|
||||
tgtLang != null &&
|
||||
srcLang.isNotEmpty &&
|
||||
|
|
@ -382,7 +231,9 @@ class UserController extends BaseController {
|
|||
}
|
||||
|
||||
/// Returns a boolean value indicating whether the user's profile is public.
|
||||
bool get isPublic => userModel?.profile?.publicProfile ?? false;
|
||||
bool get isPublic {
|
||||
return profile.userSettings.publicProfile;
|
||||
}
|
||||
|
||||
/// Retrieves the user's email address.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -270,19 +269,4 @@ extension SettingCopy on ToolSetting {
|
|||
return L10n.of(context)!.autoIGCToolDescription;
|
||||
}
|
||||
}
|
||||
|
||||
MatrixProfileEnum get asMatrixProfileField {
|
||||
switch (this) {
|
||||
case ToolSetting.interactiveTranslator:
|
||||
return MatrixProfileEnum.interactiveTranslator;
|
||||
case ToolSetting.interactiveGrammar:
|
||||
return MatrixProfileEnum.interactiveGrammar;
|
||||
case ToolSetting.immersionMode:
|
||||
return MatrixProfileEnum.immersionMode;
|
||||
case ToolSetting.definitions:
|
||||
return MatrixProfileEnum.definitions;
|
||||
case ToolSetting.autoIGC:
|
||||
return MatrixProfileEnum.autoIGC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,7 @@ class UserProfileSearchResponse {
|
|||
int count;
|
||||
String? next;
|
||||
String? previous;
|
||||
List<Profile> results;
|
||||
List<PangeaProfile> results;
|
||||
|
||||
UserProfileSearchResponse({
|
||||
required this.count,
|
||||
|
|
@ -19,9 +19,9 @@ class UserProfileSearchResponse {
|
|||
next: json["next"],
|
||||
previous: json["previous"],
|
||||
results: json["results"]
|
||||
.map((p) => Profile.fromJson(p))
|
||||
.map((p) => PangeaProfile.fromJson(p))
|
||||
.toList()
|
||||
.cast<Profile>(),
|
||||
.cast<PangeaProfile>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class FindPartnerController extends State<FindPartner> {
|
|||
|
||||
Timer? coolDown;
|
||||
|
||||
final List<Profile> _userProfilesCache = [];
|
||||
final List<PangeaProfile> _userProfilesCache = [];
|
||||
|
||||
final scrollController = ScrollController();
|
||||
String? error;
|
||||
|
|
@ -83,7 +83,7 @@ class FindPartnerController extends State<FindPartner> {
|
|||
return FindPartnerView(this);
|
||||
}
|
||||
|
||||
List<Profile> get userProfiles => _userProfilesCache.where((p) {
|
||||
List<PangeaProfile> get userProfiles => _userProfilesCache.where((p) {
|
||||
return (p.targetLanguage != null &&
|
||||
targetLanguageSearch.langCode == p.targetLanguage) &&
|
||||
(p.sourceLanguage != null &&
|
||||
|
|
@ -127,8 +127,7 @@ class FindPartnerController extends State<FindPartner> {
|
|||
nextUrl = response.next;
|
||||
nextPage++;
|
||||
|
||||
final String? currentUserId =
|
||||
pangeaController.userController.userModel?.profile?.pangeaUserId;
|
||||
final String? currentUserId = pangeaController.matrixState.client.userID;
|
||||
_userProfilesCache.addAll(
|
||||
response.results.where(
|
||||
(p) =>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'package:country_picker/country_picker.dart';
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/country_display.dart';
|
||||
import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart';
|
||||
import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart';
|
||||
import 'package:fluffychat/pangea/widgets/user_settings/p_language_dropdown.dart';
|
||||
|
|
@ -244,7 +245,7 @@ class LanguageSelectionRow extends StatelessWidget {
|
|||
}
|
||||
|
||||
class UserProfileEntry extends StatelessWidget {
|
||||
final Profile pangeaProfile;
|
||||
final PangeaProfile pangeaProfile;
|
||||
final FindPartnerController controller;
|
||||
|
||||
const UserProfileEntry({
|
||||
|
|
@ -287,7 +288,7 @@ class UserProfileEntry extends StatelessWidget {
|
|||
const SizedBox(width: 20),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: pangeaProfile.flagEmoji,
|
||||
text: CountryDisplayUtil.flagEmoji(pangeaProfile.country),
|
||||
style: const TextStyle(fontSize: 15),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import 'package:fluffychat/widgets/matrix.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../utils/bot_name.dart';
|
||||
import '../../utils/error_handler.dart';
|
||||
|
|
@ -73,26 +72,24 @@ class PUserAgeController extends State<PUserAge> {
|
|||
}
|
||||
|
||||
//Note: used linear progress bar (also used in fluffychat signup button) for consistency
|
||||
createUserInPangea() async {
|
||||
Future<void> createUserInPangea() async {
|
||||
try {
|
||||
setState(() {
|
||||
error = dobValidator();
|
||||
});
|
||||
|
||||
setState(() => error = dobValidator());
|
||||
if (error?.isNotEmpty == true) return;
|
||||
setState(() => loading = true);
|
||||
|
||||
setState(() {
|
||||
loading = true;
|
||||
});
|
||||
final DateTime? dob =
|
||||
pangeaController.userController.profile.userSettings.dateOfBirth;
|
||||
|
||||
final String date = DateFormat('yyyy-MM-dd').format(selectedDate!);
|
||||
|
||||
if (pangeaController.userController.userModel?.access == null) {
|
||||
await pangeaController.userController.createProfile(dob: date);
|
||||
} else {
|
||||
await pangeaController.userController.updateUserProfile(
|
||||
dateOfBirth: date,
|
||||
if (dob == null) {
|
||||
await pangeaController.userController.createProfile(
|
||||
dob: selectedDate!,
|
||||
);
|
||||
} else {
|
||||
pangeaController.userController.updateProfile((profile) {
|
||||
profile.userSettings.dateOfBirth = selectedDate!;
|
||||
return profile;
|
||||
});
|
||||
}
|
||||
FluffyChatApp.router.go('/rooms');
|
||||
} catch (err, s) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import 'dart:async';
|
|||
|
||||
import 'package:country_picker/country_picker.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/models/space_model.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/pages/settings_learning/settings_learning_view.dart';
|
||||
import 'package:fluffychat/pangea/widgets/user_settings/p_language_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
|
@ -18,31 +20,55 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
late StreamSubscription _userSubscription;
|
||||
PangeaController pangeaController = MatrixState.pangeaController;
|
||||
|
||||
setPublicProfile(bool b) async {
|
||||
await pangeaController.userController.updateUserProfile(publicProfile: b);
|
||||
setState(() {});
|
||||
Future<void> changeLanguage() async {
|
||||
await pLanguageDialog(context, () {});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_userSubscription =
|
||||
pangeaController.userController.stateStream.listen((event) {
|
||||
setState(() {});
|
||||
Future<void> setPublicProfile(bool isPublic) async {
|
||||
pangeaController.userController.updateProfile((profile) {
|
||||
profile.userSettings.publicProfile = isPublic;
|
||||
return profile;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> changeLanguage() async {
|
||||
await pLanguageDialog(context, () {});
|
||||
setState(() {});
|
||||
Future<void> changeCountry(Country country) async {
|
||||
pangeaController.userController.updateProfile((profile) {
|
||||
profile.userSettings.country = country.displayNameNoCountryCode;
|
||||
return profile;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> changeCountry(Country country) async {
|
||||
await pangeaController.userController.updateUserProfile(
|
||||
country: country.displayNameNoCountryCode,
|
||||
);
|
||||
setState(() {});
|
||||
void updateToolSetting(ToolSetting toolSetting, bool value) {
|
||||
pangeaController.userController.updateProfile((Profile profile) {
|
||||
switch (toolSetting) {
|
||||
case ToolSetting.interactiveTranslator:
|
||||
return profile..toolSettings.interactiveTranslator = value;
|
||||
case ToolSetting.interactiveGrammar:
|
||||
return profile..toolSettings.interactiveGrammar = value;
|
||||
case ToolSetting.immersionMode:
|
||||
return profile..toolSettings.immersionMode = value;
|
||||
case ToolSetting.definitions:
|
||||
return profile..toolSettings.definitions = value;
|
||||
case ToolSetting.autoIGC:
|
||||
return profile..toolSettings.autoIGC = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool getToolSetting(ToolSetting toolSetting) {
|
||||
final toolSettings = pangeaController.userController.profile.toolSettings;
|
||||
switch (toolSetting) {
|
||||
case ToolSetting.interactiveTranslator:
|
||||
return toolSettings.interactiveTranslator;
|
||||
case ToolSetting.interactiveGrammar:
|
||||
return toolSettings.interactiveGrammar;
|
||||
case ToolSetting.immersionMode:
|
||||
return toolSettings.immersionMode;
|
||||
case ToolSetting.definitions:
|
||||
return toolSettings.definitions;
|
||||
case ToolSetting.autoIGC:
|
||||
return toolSettings.autoIGC;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:fluffychat/pangea/models/space_model.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/widgets/user_settings/country_picker_tile.dart';
|
||||
|
|
@ -18,71 +17,97 @@ class SettingsLearningView extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
L10n.of(context)!.learningSettings,
|
||||
),
|
||||
// rebuild this page each time a sync comes through with new account data
|
||||
// this prevents having to call setState each time an individual setting is changed
|
||||
return StreamBuilder(
|
||||
stream:
|
||||
controller.pangeaController.matrixState.client.onSync.stream.where(
|
||||
(update) => update.accountData != null,
|
||||
),
|
||||
body: ListTileTheme(
|
||||
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
|
||||
child: MaxWidthBody(
|
||||
withScrolling: true,
|
||||
child: Column(
|
||||
children: [
|
||||
LanguageTile(controller),
|
||||
CountryPickerTile(controller),
|
||||
const SizedBox(height: 8),
|
||||
const Divider(height: 1),
|
||||
const SizedBox(height: 8),
|
||||
if (controller.pangeaController.permissionsController.isUser18())
|
||||
SwitchListTile.adaptive(
|
||||
activeColor: AppConfig.activeToggleColor,
|
||||
title: Text(L10n.of(context)!.publicProfileTitle),
|
||||
subtitle: Text(L10n.of(context)!.publicProfileDesc),
|
||||
value: controller.pangeaController.userController.isPublic,
|
||||
onChanged: (bool isPublicProfile) => showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => controller.setPublicProfile(isPublicProfile),
|
||||
onError: (err) =>
|
||||
ErrorHandler.logError(e: err, s: StackTrace.current),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
subtitle: Text(L10n.of(context)!.toggleToolSettingsDescription),
|
||||
),
|
||||
for (final setting in MatrixProfile.toolSettings)
|
||||
setting.asToolSetting != null
|
||||
? ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller
|
||||
.pangeaController.permissionsController
|
||||
.userToolSetting(setting),
|
||||
title: setting.asToolSetting!.toolName(context),
|
||||
subtitle:
|
||||
setting.asToolSetting!.toolDescription(context),
|
||||
profileKey: setting.asToolSetting!.asMatrixProfileField,
|
||||
)
|
||||
: const SizedBox(),
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller
|
||||
.pangeaController.userController.matrixProfile.itAutoPlay,
|
||||
title:
|
||||
L10n.of(context)!.interactiveTranslatorAutoPlaySliderHeader,
|
||||
subtitle: L10n.of(context)!.interactiveTranslatorAutoPlayDesc,
|
||||
profileKey: MatrixProfileEnum.itAutoPlay,
|
||||
),
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller.pangeaController.userController
|
||||
.matrixProfile.autoPlayMessages,
|
||||
title: L10n.of(context)!.autoPlayTitle,
|
||||
subtitle: L10n.of(context)!.autoPlayDesc,
|
||||
profileKey: MatrixProfileEnum.autoPlayMessages,
|
||||
),
|
||||
],
|
||||
builder: (context, snapshot) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
L10n.of(context)!.learningSettings,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: ListTileTheme(
|
||||
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
|
||||
child: MaxWidthBody(
|
||||
withScrolling: true,
|
||||
child: Column(
|
||||
children: [
|
||||
LanguageTile(controller),
|
||||
CountryPickerTile(controller),
|
||||
const SizedBox(height: 8),
|
||||
const Divider(height: 1),
|
||||
const SizedBox(height: 8),
|
||||
if (controller.pangeaController.permissionsController
|
||||
.isUser18())
|
||||
SwitchListTile.adaptive(
|
||||
activeColor: AppConfig.activeToggleColor,
|
||||
title: Text(L10n.of(context)!.publicProfileTitle),
|
||||
subtitle: Text(L10n.of(context)!.publicProfileDesc),
|
||||
value:
|
||||
controller.pangeaController.userController.isPublic,
|
||||
onChanged: (bool isPublicProfile) =>
|
||||
showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () =>
|
||||
controller.setPublicProfile(isPublicProfile),
|
||||
onError: (err) => ErrorHandler.logError(
|
||||
e: err,
|
||||
s: StackTrace.current,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
subtitle:
|
||||
Text(L10n.of(context)!.toggleToolSettingsDescription),
|
||||
),
|
||||
for (final toolSetting in ToolSetting.values)
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller.getToolSetting(toolSetting),
|
||||
title: toolSetting.toolName(context),
|
||||
subtitle: toolSetting.toolDescription(context),
|
||||
onChange: (bool value) => controller.updateToolSetting(
|
||||
toolSetting,
|
||||
value,
|
||||
),
|
||||
),
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller.pangeaController.userController
|
||||
.profile.userSettings.itAutoPlay,
|
||||
title: L10n.of(context)!
|
||||
.interactiveTranslatorAutoPlaySliderHeader,
|
||||
subtitle:
|
||||
L10n.of(context)!.interactiveTranslatorAutoPlayDesc,
|
||||
onChange: (bool value) => controller
|
||||
.pangeaController.userController
|
||||
.updateProfile((profile) {
|
||||
profile.userSettings.itAutoPlay = value;
|
||||
return profile;
|
||||
}),
|
||||
),
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller.pangeaController.userController
|
||||
.profile.userSettings.autoPlayMessages,
|
||||
title: L10n.of(context)!.autoPlayTitle,
|
||||
subtitle: L10n.of(context)!.autoPlayDesc,
|
||||
onChange: (bool value) => controller
|
||||
.pangeaController.userController
|
||||
.updateProfile((profile) {
|
||||
profile.userSettings.autoPlayMessages = value;
|
||||
return profile;
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,37 +4,13 @@ import 'dart:developer';
|
|||
import 'package:fluffychat/pangea/constants/model_keys.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../widgets/matrix.dart';
|
||||
import '../models/user_model.dart';
|
||||
import '../models/user_profile_search_model.dart';
|
||||
import '../network/requests.dart';
|
||||
import '../network/urls.dart';
|
||||
|
||||
class PUserRepo {
|
||||
static Future<PUserModel> repoCreatePangeaUser({
|
||||
required String userID,
|
||||
required String dob,
|
||||
required fullName,
|
||||
required String matrixAccessToken,
|
||||
}) async {
|
||||
final Requests req = Requests(
|
||||
baseUrl: PApiUrls.baseAPI,
|
||||
matrixAccessToken: matrixAccessToken,
|
||||
);
|
||||
|
||||
final Map<String, dynamic> body = {
|
||||
ModelKey.userFullName: fullName,
|
||||
ModelKey.userPangeaUserId: userID,
|
||||
ModelKey.userDateOfBirth: dob,
|
||||
};
|
||||
final Response res = await req.post(
|
||||
url: PApiUrls.createUser,
|
||||
body: body,
|
||||
);
|
||||
return PUserModel.fromJson(jsonDecode(res.body));
|
||||
}
|
||||
|
||||
static Future<PUserModel?> fetchPangeaUserInfo({
|
||||
static Future<PangeaProfileResponse?> fetchPangeaUserInfo({
|
||||
required String userID,
|
||||
required String matrixAccessToken,
|
||||
}) async {
|
||||
|
|
@ -49,7 +25,7 @@ class PUserRepo {
|
|||
objectId: userID,
|
||||
);
|
||||
|
||||
return PUserModel.fromJson(jsonDecode(res.body));
|
||||
return PangeaProfileResponse.fromJson(jsonDecode(res.body));
|
||||
} catch (err) {
|
||||
//status code should be 400 - PTODO - check ffor this.
|
||||
log("Most likely a first signup and needs to make an account");
|
||||
|
|
@ -57,32 +33,6 @@ class PUserRepo {
|
|||
}
|
||||
}
|
||||
|
||||
//notes for jordan - only replace non-null fields, return whole profile
|
||||
//Jordan - should return pangeaUserId as well
|
||||
static Future<Profile> updateUserProfile(
|
||||
Profile userProfile,
|
||||
String accessToken,
|
||||
) async {
|
||||
final Requests req = Requests(
|
||||
baseUrl: PApiUrls.baseAPI,
|
||||
accessToken: accessToken,
|
||||
);
|
||||
final Response res = await req.put(
|
||||
url: PApiUrls.updateUserProfile,
|
||||
body: userProfile.toJson(),
|
||||
);
|
||||
|
||||
//temp fix
|
||||
final content = jsonDecode(res.body);
|
||||
//PTODO - try taking this out and see where bug occurs
|
||||
if (content[ModelKey.userPangeaUserId] == null) {
|
||||
content[ModelKey.userPangeaUserId] =
|
||||
MatrixState.pangeaController.matrixState.client.userID;
|
||||
}
|
||||
|
||||
return Profile.fromJson(content);
|
||||
}
|
||||
|
||||
static Future<UserProfileSearchResponse> searchUserProfiles({
|
||||
// List<String>? interests,
|
||||
String? targetLanguage,
|
||||
|
|
|
|||
515
lib/pangea/utils/country_display.dart
Normal file
515
lib/pangea/utils/country_display.dart
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
import 'package:country_picker/country_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class CountryDisplayUtil {
|
||||
/// used in find a partner page for display partner's country
|
||||
static String flagEmoji(String? countryName) {
|
||||
countryName = countryName?.split(' (')[0];
|
||||
final Country? country = CountryService().findByName(countryName);
|
||||
return country?.flagEmoji ?? "";
|
||||
}
|
||||
|
||||
static String? countryDisplayName(String? countryName, BuildContext context) {
|
||||
countryName = countryName?.split(' (')[0];
|
||||
final Country? country = CountryService().findByName(countryName);
|
||||
if (country?.countryCode == null) return null;
|
||||
switch (country!.countryCode) {
|
||||
case 'WW':
|
||||
return L10n.of(context)!.wwCountryDisplayName;
|
||||
case 'AF':
|
||||
return L10n.of(context)!.afCountryDisplayName;
|
||||
case 'AX':
|
||||
return L10n.of(context)!.axCountryDisplayName;
|
||||
case 'AL':
|
||||
return L10n.of(context)!.alCountryDisplayName;
|
||||
case 'DZ':
|
||||
return L10n.of(context)!.dzCountryDisplayName;
|
||||
case 'AS':
|
||||
return L10n.of(context)!.asCountryDisplayName;
|
||||
case 'AD':
|
||||
return L10n.of(context)!.adCountryDisplayName;
|
||||
case 'AO':
|
||||
return L10n.of(context)!.aoCountryDisplayName;
|
||||
case 'AI':
|
||||
return L10n.of(context)!.aiCountryDisplayName;
|
||||
case 'AG':
|
||||
return L10n.of(context)!.agCountryDisplayName;
|
||||
case 'AR':
|
||||
return L10n.of(context)!.arCountryDisplayName;
|
||||
case 'AM':
|
||||
return L10n.of(context)!.amCountryDisplayName;
|
||||
case 'AW':
|
||||
return L10n.of(context)!.awCountryDisplayName;
|
||||
case 'AC':
|
||||
return L10n.of(context)!.acCountryDisplayName;
|
||||
case 'AU':
|
||||
return L10n.of(context)!.auCountryDisplayName;
|
||||
case 'AT':
|
||||
return L10n.of(context)!.atCountryDisplayName;
|
||||
case 'AZ':
|
||||
return L10n.of(context)!.azCountryDisplayName;
|
||||
case 'BS':
|
||||
return L10n.of(context)!.bsCountryDisplayName;
|
||||
case 'BH':
|
||||
return L10n.of(context)!.bhCountryDisplayName;
|
||||
case 'BD':
|
||||
return L10n.of(context)!.bdCountryDisplayName;
|
||||
case 'BB':
|
||||
return L10n.of(context)!.bbCountryDisplayName;
|
||||
case 'BY':
|
||||
return L10n.of(context)!.byCountryDisplayName;
|
||||
case 'BE':
|
||||
return L10n.of(context)!.beCountryDisplayName;
|
||||
case 'BZ':
|
||||
return L10n.of(context)!.bzCountryDisplayName;
|
||||
case 'BJ':
|
||||
return L10n.of(context)!.bjCountryDisplayName;
|
||||
case 'BM':
|
||||
return L10n.of(context)!.bmCountryDisplayName;
|
||||
case 'BT':
|
||||
return L10n.of(context)!.btCountryDisplayName;
|
||||
case 'BO':
|
||||
return L10n.of(context)!.boCountryDisplayName;
|
||||
case 'BA':
|
||||
return L10n.of(context)!.baCountryDisplayName;
|
||||
case 'BW':
|
||||
return L10n.of(context)!.bwCountryDisplayName;
|
||||
case 'BR':
|
||||
return L10n.of(context)!.brCountryDisplayName;
|
||||
case 'IO':
|
||||
return L10n.of(context)!.ioCountryDisplayName;
|
||||
case 'VG':
|
||||
return L10n.of(context)!.vgCountryDisplayName;
|
||||
case 'BN':
|
||||
return L10n.of(context)!.bnCountryDisplayName;
|
||||
case 'BG':
|
||||
return L10n.of(context)!.bgCountryDisplayName;
|
||||
case 'BF':
|
||||
return L10n.of(context)!.bfCountryDisplayName;
|
||||
case 'BI':
|
||||
return L10n.of(context)!.biCountryDisplayName;
|
||||
case 'KH':
|
||||
return L10n.of(context)!.khCountryDisplayName;
|
||||
case 'CM':
|
||||
return L10n.of(context)!.cmCountryDisplayName;
|
||||
case 'CA':
|
||||
return L10n.of(context)!.caCountryDisplayName;
|
||||
case 'CV':
|
||||
return L10n.of(context)!.cvCountryDisplayName;
|
||||
case 'BQ':
|
||||
return L10n.of(context)!.bqCountryDisplayName;
|
||||
case 'KY':
|
||||
return L10n.of(context)!.kyCountryDisplayName;
|
||||
case 'CF':
|
||||
return L10n.of(context)!.cfCountryDisplayName;
|
||||
case 'TD':
|
||||
return L10n.of(context)!.tdCountryDisplayName;
|
||||
case 'CL':
|
||||
return L10n.of(context)!.clCountryDisplayName;
|
||||
case 'CN':
|
||||
return L10n.of(context)!.cnCountryDisplayName;
|
||||
case 'CX':
|
||||
return L10n.of(context)!.cxCountryDisplayName;
|
||||
case 'CC':
|
||||
return L10n.of(context)!.ccCountryDisplayName;
|
||||
case 'CO':
|
||||
return L10n.of(context)!.coCountryDisplayName;
|
||||
case 'KM':
|
||||
return L10n.of(context)!.kmCountryDisplayName;
|
||||
case 'CD':
|
||||
return L10n.of(context)!.cdCountryDisplayName;
|
||||
case 'CG':
|
||||
return L10n.of(context)!.cgCountryDisplayName;
|
||||
case 'CK':
|
||||
return L10n.of(context)!.ckCountryDisplayName;
|
||||
case 'CR':
|
||||
return L10n.of(context)!.crCountryDisplayName;
|
||||
case 'CI':
|
||||
return L10n.of(context)!.ciCountryDisplayName;
|
||||
case 'HR':
|
||||
return L10n.of(context)!.hrCountryDisplayName;
|
||||
case 'CU':
|
||||
return L10n.of(context)!.cuCountryDisplayName;
|
||||
case 'CW':
|
||||
return L10n.of(context)!.cwCountryDisplayName;
|
||||
case 'CY':
|
||||
return L10n.of(context)!.cyCountryDisplayName;
|
||||
case 'CZ':
|
||||
return L10n.of(context)!.czCountryDisplayName;
|
||||
case 'DK':
|
||||
return L10n.of(context)!.dkCountryDisplayName;
|
||||
case 'DJ':
|
||||
return L10n.of(context)!.djCountryDisplayName;
|
||||
case 'DM':
|
||||
return L10n.of(context)!.dmCountryDisplayName;
|
||||
case 'DO':
|
||||
return L10n.of(context)!.doCountryDisplayName;
|
||||
case 'TL':
|
||||
return L10n.of(context)!.tlCountryDisplayName;
|
||||
case 'EC':
|
||||
return L10n.of(context)!.ecCountryDisplayName;
|
||||
case 'EG':
|
||||
return L10n.of(context)!.egCountryDisplayName;
|
||||
case 'SV':
|
||||
return L10n.of(context)!.svCountryDisplayName;
|
||||
case 'GQ':
|
||||
return L10n.of(context)!.gqCountryDisplayName;
|
||||
case 'ER':
|
||||
return L10n.of(context)!.erCountryDisplayName;
|
||||
case 'EE':
|
||||
return L10n.of(context)!.eeCountryDisplayName;
|
||||
case 'SZ':
|
||||
return L10n.of(context)!.szCountryDisplayName;
|
||||
case 'ET':
|
||||
return L10n.of(context)!.etCountryDisplayName;
|
||||
case 'FK':
|
||||
return L10n.of(context)!.fkCountryDisplayName;
|
||||
case 'FO':
|
||||
return L10n.of(context)!.foCountryDisplayName;
|
||||
case 'FJ':
|
||||
return L10n.of(context)!.fjCountryDisplayName;
|
||||
case 'FI':
|
||||
return L10n.of(context)!.fiCountryDisplayName;
|
||||
case 'FR':
|
||||
return L10n.of(context)!.frCountryDisplayName;
|
||||
case 'GF':
|
||||
return L10n.of(context)!.gfCountryDisplayName;
|
||||
case 'PF':
|
||||
return L10n.of(context)!.pfCountryDisplayName;
|
||||
case 'GA':
|
||||
return L10n.of(context)!.gaCountryDisplayName;
|
||||
case 'GM':
|
||||
return L10n.of(context)!.gmCountryDisplayName;
|
||||
case 'GE':
|
||||
return L10n.of(context)!.geCountryDisplayName;
|
||||
case 'DE':
|
||||
return L10n.of(context)!.deCountryDisplayName;
|
||||
case 'GH':
|
||||
return L10n.of(context)!.ghCountryDisplayName;
|
||||
case 'GI':
|
||||
return L10n.of(context)!.giCountryDisplayName;
|
||||
case 'GR':
|
||||
return L10n.of(context)!.grCountryDisplayName;
|
||||
case 'GL':
|
||||
return L10n.of(context)!.glCountryDisplayName;
|
||||
case 'GD':
|
||||
return L10n.of(context)!.gdCountryDisplayName;
|
||||
case 'GP':
|
||||
return L10n.of(context)!.gpCountryDisplayName;
|
||||
case 'GU':
|
||||
return L10n.of(context)!.guCountryDisplayName;
|
||||
case 'GT':
|
||||
return L10n.of(context)!.gtCountryDisplayName;
|
||||
case 'GG':
|
||||
return L10n.of(context)!.ggCountryDisplayName;
|
||||
case 'GN':
|
||||
return L10n.of(context)!.gnCountryDisplayName;
|
||||
case 'GW':
|
||||
return L10n.of(context)!.gwCountryDisplayName;
|
||||
case 'GY':
|
||||
return L10n.of(context)!.gyCountryDisplayName;
|
||||
case 'HT':
|
||||
return L10n.of(context)!.htCountryDisplayName;
|
||||
case 'HM':
|
||||
return L10n.of(context)!.hmCountryDisplayName;
|
||||
case 'HN':
|
||||
return L10n.of(context)!.hnCountryDisplayName;
|
||||
case 'HK':
|
||||
return L10n.of(context)!.hkCountryDisplayName;
|
||||
case 'HU':
|
||||
return L10n.of(context)!.huCountryDisplayName;
|
||||
case 'IS':
|
||||
return L10n.of(context)!.isCountryDisplayName;
|
||||
case 'IN':
|
||||
return L10n.of(context)!.inCountryDisplayName;
|
||||
case 'ID':
|
||||
return L10n.of(context)!.idCountryDisplayName;
|
||||
case 'IR':
|
||||
return L10n.of(context)!.irCountryDisplayName;
|
||||
case 'IQ':
|
||||
return L10n.of(context)!.iqCountryDisplayName;
|
||||
case 'IE':
|
||||
return L10n.of(context)!.ieCountryDisplayName;
|
||||
case 'IM':
|
||||
return L10n.of(context)!.imCountryDisplayName;
|
||||
case 'IL':
|
||||
return L10n.of(context)!.ilCountryDisplayName;
|
||||
case 'IT':
|
||||
return L10n.of(context)!.itCountryDisplayName;
|
||||
case 'JM':
|
||||
return L10n.of(context)!.jmCountryDisplayName;
|
||||
case 'JP':
|
||||
return L10n.of(context)!.jpCountryDisplayName;
|
||||
case 'JE':
|
||||
return L10n.of(context)!.jeCountryDisplayName;
|
||||
case 'JO':
|
||||
return L10n.of(context)!.joCountryDisplayName;
|
||||
case 'KZ':
|
||||
return L10n.of(context)!.kzCountryDisplayName;
|
||||
case 'KE':
|
||||
return L10n.of(context)!.keCountryDisplayName;
|
||||
case 'KI':
|
||||
return L10n.of(context)!.kiCountryDisplayName;
|
||||
case 'XK':
|
||||
return L10n.of(context)!.xkCountryDisplayName;
|
||||
case 'KW':
|
||||
return L10n.of(context)!.kwCountryDisplayName;
|
||||
case 'KG':
|
||||
return L10n.of(context)!.kgCountryDisplayName;
|
||||
case 'LA':
|
||||
return L10n.of(context)!.laCountryDisplayName;
|
||||
case 'LV':
|
||||
return L10n.of(context)!.lvCountryDisplayName;
|
||||
case 'LB':
|
||||
return L10n.of(context)!.lbCountryDisplayName;
|
||||
case 'LS':
|
||||
return L10n.of(context)!.lsCountryDisplayName;
|
||||
case 'LR':
|
||||
return L10n.of(context)!.lrCountryDisplayName;
|
||||
case 'LY':
|
||||
return L10n.of(context)!.lyCountryDisplayName;
|
||||
case 'LI':
|
||||
return L10n.of(context)!.liCountryDisplayName;
|
||||
case 'LT':
|
||||
return L10n.of(context)!.ltCountryDisplayName;
|
||||
case 'LU':
|
||||
return L10n.of(context)!.luCountryDisplayName;
|
||||
case 'MO':
|
||||
return L10n.of(context)!.moCountryDisplayName;
|
||||
case 'MK':
|
||||
return L10n.of(context)!.mkCountryDisplayName;
|
||||
case 'MG':
|
||||
return L10n.of(context)!.mgCountryDisplayName;
|
||||
case 'MW':
|
||||
return L10n.of(context)!.mwCountryDisplayName;
|
||||
case 'MY':
|
||||
return L10n.of(context)!.myCountryDisplayName;
|
||||
case 'MV':
|
||||
return L10n.of(context)!.mvCountryDisplayName;
|
||||
case 'ML':
|
||||
return L10n.of(context)!.mlCountryDisplayName;
|
||||
case 'MT':
|
||||
return L10n.of(context)!.mtCountryDisplayName;
|
||||
case 'MH':
|
||||
return L10n.of(context)!.mhCountryDisplayName;
|
||||
case 'MQ':
|
||||
return L10n.of(context)!.mqCountryDisplayName;
|
||||
case 'MR':
|
||||
return L10n.of(context)!.mrCountryDisplayName;
|
||||
case 'MU':
|
||||
return L10n.of(context)!.muCountryDisplayName;
|
||||
case 'YT':
|
||||
return L10n.of(context)!.ytCountryDisplayName;
|
||||
case 'MX':
|
||||
return L10n.of(context)!.mxCountryDisplayName;
|
||||
case 'FM':
|
||||
return L10n.of(context)!.fmCountryDisplayName;
|
||||
case 'MD':
|
||||
return L10n.of(context)!.mdCountryDisplayName;
|
||||
case 'MC':
|
||||
return L10n.of(context)!.mcCountryDisplayName;
|
||||
case 'MN':
|
||||
return L10n.of(context)!.mnCountryDisplayName;
|
||||
case 'ME':
|
||||
return L10n.of(context)!.meCountryDisplayName;
|
||||
case 'MS':
|
||||
return L10n.of(context)!.msCountryDisplayName;
|
||||
case 'MA':
|
||||
return L10n.of(context)!.maCountryDisplayName;
|
||||
case 'MZ':
|
||||
return L10n.of(context)!.mzCountryDisplayName;
|
||||
case 'MM':
|
||||
return L10n.of(context)!.mmCountryDisplayName;
|
||||
case 'NA':
|
||||
return L10n.of(context)!.naCountryDisplayName;
|
||||
case 'NR':
|
||||
return L10n.of(context)!.nrCountryDisplayName;
|
||||
case 'NP':
|
||||
return L10n.of(context)!.npCountryDisplayName;
|
||||
case 'NL':
|
||||
return L10n.of(context)!.nlCountryDisplayName;
|
||||
case 'NC':
|
||||
return L10n.of(context)!.ncCountryDisplayName;
|
||||
case 'NZ':
|
||||
return L10n.of(context)!.nzCountryDisplayName;
|
||||
case 'NI':
|
||||
return L10n.of(context)!.niCountryDisplayName;
|
||||
case 'NE':
|
||||
return L10n.of(context)!.neCountryDisplayName;
|
||||
case 'NG':
|
||||
return L10n.of(context)!.ngCountryDisplayName;
|
||||
case 'NU':
|
||||
return L10n.of(context)!.nuCountryDisplayName;
|
||||
case 'NF':
|
||||
return L10n.of(context)!.nfCountryDisplayName;
|
||||
case 'KP':
|
||||
return L10n.of(context)!.kpCountryDisplayName;
|
||||
case 'MP':
|
||||
return L10n.of(context)!.mpCountryDisplayName;
|
||||
case 'NO':
|
||||
return L10n.of(context)!.noCountryDisplayName;
|
||||
case 'OM':
|
||||
return L10n.of(context)!.omCountryDisplayName;
|
||||
case 'PK':
|
||||
return L10n.of(context)!.pkCountryDisplayName;
|
||||
case 'PW':
|
||||
return L10n.of(context)!.pwCountryDisplayName;
|
||||
case 'PS':
|
||||
return L10n.of(context)!.psCountryDisplayName;
|
||||
case 'PA':
|
||||
return L10n.of(context)!.paCountryDisplayName;
|
||||
case 'PG':
|
||||
return L10n.of(context)!.pgCountryDisplayName;
|
||||
case 'PY':
|
||||
return L10n.of(context)!.pyCountryDisplayName;
|
||||
case 'PE':
|
||||
return L10n.of(context)!.peCountryDisplayName;
|
||||
case 'PH':
|
||||
return L10n.of(context)!.phCountryDisplayName;
|
||||
case 'PL':
|
||||
return L10n.of(context)!.plCountryDisplayName;
|
||||
case 'PT':
|
||||
return L10n.of(context)!.ptCountryDisplayName;
|
||||
case 'PR':
|
||||
return L10n.of(context)!.prCountryDisplayName;
|
||||
case 'QA':
|
||||
return L10n.of(context)!.qaCountryDisplayName;
|
||||
case 'RE':
|
||||
return L10n.of(context)!.reCountryDisplayName;
|
||||
case 'RO':
|
||||
return L10n.of(context)!.roCountryDisplayName;
|
||||
case 'RU':
|
||||
return L10n.of(context)!.ruCountryDisplayName;
|
||||
case 'RW':
|
||||
return L10n.of(context)!.rwCountryDisplayName;
|
||||
case 'BL':
|
||||
return L10n.of(context)!.blCountryDisplayName;
|
||||
case 'SH':
|
||||
return L10n.of(context)!.shCountryDisplayName;
|
||||
case 'KN':
|
||||
return L10n.of(context)!.knCountryDisplayName;
|
||||
case 'LC':
|
||||
return L10n.of(context)!.lcCountryDisplayName;
|
||||
case 'MF':
|
||||
return L10n.of(context)!.mfCountryDisplayName;
|
||||
case 'PM':
|
||||
return L10n.of(context)!.pmCountryDisplayName;
|
||||
case 'VC':
|
||||
return L10n.of(context)!.vcCountryDisplayName;
|
||||
case 'WS':
|
||||
return L10n.of(context)!.wsCountryDisplayName;
|
||||
case 'SM':
|
||||
return L10n.of(context)!.smCountryDisplayName;
|
||||
case 'ST':
|
||||
return L10n.of(context)!.stCountryDisplayName;
|
||||
case 'SA':
|
||||
return L10n.of(context)!.saCountryDisplayName;
|
||||
case 'SN':
|
||||
return L10n.of(context)!.snCountryDisplayName;
|
||||
case 'RS':
|
||||
return L10n.of(context)!.rsCountryDisplayName;
|
||||
case 'SC':
|
||||
return L10n.of(context)!.scCountryDisplayName;
|
||||
case 'SL':
|
||||
return L10n.of(context)!.slCountryDisplayName;
|
||||
case 'SG':
|
||||
return L10n.of(context)!.sgCountryDisplayName;
|
||||
case 'SX':
|
||||
return L10n.of(context)!.sxCountryDisplayName;
|
||||
case 'SK':
|
||||
return L10n.of(context)!.skCountryDisplayName;
|
||||
case 'SI':
|
||||
return L10n.of(context)!.siCountryDisplayName;
|
||||
case 'SB':
|
||||
return L10n.of(context)!.sbCountryDisplayName;
|
||||
case 'SO':
|
||||
return L10n.of(context)!.soCountryDisplayName;
|
||||
case 'ZA':
|
||||
return L10n.of(context)!.zaCountryDisplayName;
|
||||
case 'GS':
|
||||
return L10n.of(context)!.gsCountryDisplayName;
|
||||
case 'KR':
|
||||
return L10n.of(context)!.krCountryDisplayName;
|
||||
case 'SS':
|
||||
return L10n.of(context)!.ssCountryDisplayName;
|
||||
case 'ES':
|
||||
return L10n.of(context)!.esCountryDisplayName;
|
||||
case 'LK':
|
||||
return L10n.of(context)!.lkCountryDisplayName;
|
||||
case 'SD':
|
||||
return L10n.of(context)!.sdCountryDisplayName;
|
||||
case 'SR':
|
||||
return L10n.of(context)!.srCountryDisplayName;
|
||||
case 'SJ':
|
||||
return L10n.of(context)!.sjCountryDisplayName;
|
||||
case 'SE':
|
||||
return L10n.of(context)!.seCountryDisplayName;
|
||||
case 'CH':
|
||||
return L10n.of(context)!.chCountryDisplayName;
|
||||
case 'SY':
|
||||
return L10n.of(context)!.syCountryDisplayName;
|
||||
case 'TW':
|
||||
return L10n.of(context)!.twCountryDisplayName;
|
||||
case 'TJ':
|
||||
return L10n.of(context)!.tjCountryDisplayName;
|
||||
case 'TZ':
|
||||
return L10n.of(context)!.tzCountryDisplayName;
|
||||
case 'TH':
|
||||
return L10n.of(context)!.thCountryDisplayName;
|
||||
case 'TG':
|
||||
return L10n.of(context)!.tgCountryDisplayName;
|
||||
case 'TK':
|
||||
return L10n.of(context)!.tkCountryDisplayName;
|
||||
case 'TO':
|
||||
return L10n.of(context)!.toCountryDisplayName;
|
||||
case 'TT':
|
||||
return L10n.of(context)!.ttCountryDisplayName;
|
||||
case 'TN':
|
||||
return L10n.of(context)!.tnCountryDisplayName;
|
||||
case 'TR':
|
||||
return L10n.of(context)!.trCountryDisplayName;
|
||||
case 'TM':
|
||||
return L10n.of(context)!.tmCountryDisplayName;
|
||||
case 'TC':
|
||||
return L10n.of(context)!.tcCountryDisplayName;
|
||||
case 'TV':
|
||||
return L10n.of(context)!.tvCountryDisplayName;
|
||||
case 'VI':
|
||||
return L10n.of(context)!.viCountryDisplayName;
|
||||
case 'UG':
|
||||
return L10n.of(context)!.ugCountryDisplayName;
|
||||
case 'UA':
|
||||
return L10n.of(context)!.uaCountryDisplayName;
|
||||
case 'AE':
|
||||
return L10n.of(context)!.aeCountryDisplayName;
|
||||
case 'GB':
|
||||
return L10n.of(context)!.gbCountryDisplayName;
|
||||
case 'US':
|
||||
return L10n.of(context)!.usCountryDisplayName;
|
||||
case 'UY':
|
||||
return L10n.of(context)!.uyCountryDisplayName;
|
||||
case 'UZ':
|
||||
return L10n.of(context)!.uzCountryDisplayName;
|
||||
case 'VU':
|
||||
return L10n.of(context)!.vuCountryDisplayName;
|
||||
case 'VA':
|
||||
return L10n.of(context)!.vaCountryDisplayName;
|
||||
case 'VE':
|
||||
return L10n.of(context)!.veCountryDisplayName;
|
||||
case 'VN':
|
||||
return L10n.of(context)!.vnCountryDisplayName;
|
||||
case 'WF':
|
||||
return L10n.of(context)!.wfCountryDisplayName;
|
||||
case 'EH':
|
||||
return L10n.of(context)!.ehCountryDisplayName;
|
||||
case 'YE':
|
||||
return L10n.of(context)!.yeCountryDisplayName;
|
||||
case 'ZM':
|
||||
return L10n.of(context)!.zmCountryDisplayName;
|
||||
case 'ZW':
|
||||
return L10n.of(context)!.zwCountryDisplayName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -333,7 +333,8 @@ class MessageToolbarState extends State<MessageToolbar> {
|
|||
return;
|
||||
}
|
||||
|
||||
MatrixState.pangeaController.userController.matrixProfile.autoPlayMessages
|
||||
MatrixState.pangeaController.userController.profile.userSettings
|
||||
.autoPlayMessages
|
||||
? updateMode(MessageMode.textToSpeech)
|
||||
: updateMode(MessageMode.translation);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import 'dart:developer';
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/enum/span_data_type.dart';
|
||||
import 'package:fluffychat/pangea/models/span_data.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/bot_style.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/match_copy.dart';
|
||||
|
|
@ -341,6 +340,12 @@ class WordMatchContent extends StatelessWidget {
|
|||
if (controller.widget.scm.pangeaMatch!.isITStart)
|
||||
DontShowSwitchListTile(
|
||||
controller: pangeaController,
|
||||
onSwitch: (bool value) {
|
||||
pangeaController.userController.updateProfile((profile) {
|
||||
profile.userSettings.itAutoPlay = value;
|
||||
return profile;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
@ -483,10 +488,12 @@ class StartITButton extends StatelessWidget {
|
|||
|
||||
class DontShowSwitchListTile extends StatefulWidget {
|
||||
final PangeaController controller;
|
||||
final Function(bool) onSwitch;
|
||||
|
||||
const DontShowSwitchListTile({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.onSwitch,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -508,10 +515,7 @@ class DontShowSwitchListTileState extends State<DontShowSwitchListTile> {
|
|||
title: Text(L10n.of(context)!.interactiveTranslatorAutoPlaySliderHeader),
|
||||
value: switchValue,
|
||||
onChanged: (value) {
|
||||
MatrixState.pangeaController.userController.matrixProfile
|
||||
.saveProfileData(
|
||||
{MatrixProfileEnum.itAutoPlay.title: value},
|
||||
);
|
||||
widget.onSwitch(value);
|
||||
setState(() => switchValue = value);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'dart:developer';
|
|||
import 'package:country_picker/country_picker.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart';
|
||||
import 'package:fluffychat/pangea/utils/country_display.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -19,10 +20,13 @@ class CountryPickerTile extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Profile? profile = pangeaController.userController.userModel?.profile;
|
||||
final Profile profile = pangeaController.userController.profile;
|
||||
return ListTile(
|
||||
title: Text(
|
||||
"${L10n.of(context)!.countryInformation}: ${profile?.countryDisplayName(context) ?? ''} ${profile?.flagEmoji}",
|
||||
"${L10n.of(context)!.countryInformation}: ${CountryDisplayUtil.countryDisplayName(
|
||||
profile.userSettings.country,
|
||||
context,
|
||||
) ?? ''} ${CountryDisplayUtil.flagEmoji(profile.userSettings.country)}",
|
||||
),
|
||||
trailing: const Icon(Icons.edit_outlined),
|
||||
onTap: () => showCountryPicker(
|
||||
|
|
|
|||
|
|
@ -88,13 +88,14 @@ pLanguageDialog(BuildContext parentContext, Function callback) async {
|
|||
context: context,
|
||||
future: () async {
|
||||
try {
|
||||
await pangeaController.userController
|
||||
.updateUserProfile(
|
||||
sourceLanguage:
|
||||
selectedSourceLanguage.langCode,
|
||||
targetLanguage:
|
||||
selectedTargetLanguage.langCode,
|
||||
);
|
||||
pangeaController.userController
|
||||
.updateProfile((profile) {
|
||||
profile.userSettings.sourceLanguage =
|
||||
selectedSourceLanguage.langCode;
|
||||
profile.userSettings.targetLanguage =
|
||||
selectedTargetLanguage.langCode;
|
||||
return profile;
|
||||
});
|
||||
Navigator.pop(context);
|
||||
} catch (err, s) {
|
||||
debugger(when: kDebugMode);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/models/user_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ProfileSettingsSwitchListTile extends StatefulWidget {
|
||||
final bool defaultValue;
|
||||
final MatrixProfileEnum profileKey;
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final Function(bool) onChange;
|
||||
|
||||
const ProfileSettingsSwitchListTile.adaptive({
|
||||
super.key,
|
||||
this.defaultValue = false,
|
||||
required this.profileKey,
|
||||
required this.defaultValue,
|
||||
required this.title,
|
||||
required this.onChange,
|
||||
this.subtitle,
|
||||
});
|
||||
|
||||
|
|
@ -28,11 +26,7 @@ class PSettingsSwitchListTileState
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
currentValue = MatrixState.pangeaController.userController.matrixProfile
|
||||
.getProfileData(
|
||||
widget.profileKey,
|
||||
) ??
|
||||
widget.defaultValue;
|
||||
currentValue = widget.defaultValue;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
|
@ -45,15 +39,12 @@ class PSettingsSwitchListTileState
|
|||
subtitle: widget.subtitle != null ? Text(widget.subtitle!) : null,
|
||||
onChanged: (bool newValue) async {
|
||||
try {
|
||||
MatrixState.pangeaController.userController.matrixProfile
|
||||
.saveProfileData({
|
||||
widget.profileKey.title: newValue,
|
||||
});
|
||||
widget.onChange(newValue);
|
||||
setState(() => currentValue = newValue);
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(
|
||||
e: err,
|
||||
m: "Failed to updates user setting ${widget.profileKey.title}",
|
||||
m: "Failed to updates user setting",
|
||||
s: s,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue