* build: Reenable shrink resources and minify in gradle * build: (deps): bump image from 4.6.0 to 4.7.1 Bumps [image](https://github.com/brendan-duncan/image) from 4.6.0 to 4.7.1. - [Changelog](https://github.com/brendan-duncan/image/blob/main/CHANGELOG.md) - [Commits](https://github.com/brendan-duncan/image/commits) --- updated-dependencies: - dependency-name: image dependency-version: 4.7.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build: (deps): bump file_picker from 10.3.7 to 10.3.8 Bumps [file_picker](https://github.com/miguelpruivo/flutter_file_picker) from 10.3.7 to 10.3.8. - [Release notes](https://github.com/miguelpruivo/flutter_file_picker/releases) - [Changelog](https://github.com/miguelpruivo/flutter_file_picker/blob/master/CHANGELOG.md) - [Commits](https://github.com/miguelpruivo/flutter_file_picker/compare/v10.3.7...v10.3.8) --- updated-dependencies: - dependency-name: file_picker dependency-version: 10.3.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Improved search * build: Use matrix sdk vom pub.dev again * chore: Follow up better search * build: (deps): bump image from 4.7.1 to 4.7.2 Bumps [image](https://github.com/brendan-duncan/image) from 4.7.1 to 4.7.2. - [Changelog](https://github.com/brendan-duncan/image/blob/main/CHANGELOG.md) - [Commits](https://github.com/brendan-duncan/image/commits) --- updated-dependencies: - dependency-name: image dependency-version: 4.7.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * chore: Make cross signing self sign mandatory for bootstrap * chore: Update user device keys before creating bootstrap * fix: Better wait for secrets after verification bootstrap * refactor: Remove native imaging and enable web worker * refactor: Remove unused html onfocus streams * build: (deps): bump flutter_foreground_task from 9.1.0 to 9.2.0 Bumps [flutter_foreground_task](https://github.com/Dev-hwang/flutter_foreground_task) from 9.1.0 to 9.2.0. - [Changelog](https://github.com/Dev-hwang/flutter_foreground_task/blob/master/CHANGELOG.md) - [Commits](https://github.com/Dev-hwang/flutter_foreground_task/commits) --- updated-dependencies: - dependency-name: flutter_foreground_task dependency-version: 9.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * chore(translations): Translated using Weblate (Uzbek) Currently translated at 99.7% (823 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uz/ * chore(translations): Translated using Weblate (Russian) Currently translated at 99.8% (824 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ru/ * chore(translations): Translated using Weblate (Norwegian Bokmål) Currently translated at 90.9% (750 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/nb_NO/ * chore(translations): Translated using Weblate (Galician) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/gl/ * chore(translations): Translated using Weblate (Basque) Currently translated at 99.7% (823 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/eu/ * chore(translations): Translated using Weblate (Ukrainian) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uk/ * chore(translations): Translated using Weblate (Estonian) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/ * chore(translations): Translated using Weblate (Dutch) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/nl/ * chore(translations): Translated using Weblate (Russian) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ru/ * chore(translations): Translated using Weblate (Spanish) Currently translated at 95.2% (788 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/es/ * chore(translations): Translated using Weblate (Spanish) Currently translated at 96.3% (797 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/es/ * chore(translations): Translated using Weblate (Russian) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ru/ * chore(translations): Translated using Weblate (Russian) Currently translated at 100.0% (825 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ru/ * fix: Broken ruzzian plurals * chore(translations): Translated using Weblate (Norwegian Bokmål) Currently translated at 91.2% (753 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/nb_NO/ * chore(translations): Translated using Weblate (Bengali) Currently translated at 4.5% (38 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/bn/ * chore(translations): Translated using Weblate (French) Currently translated at 82.3% (679 of 825 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/fr/ * build: (deps): bump translations_cleaner from 0.0.5 to 0.1.0 Bumps [translations_cleaner](https://github.com/Chinmay-KB/translations_cleaner) from 0.0.5 to 0.1.0. - [Changelog](https://github.com/Chinmay-KB/translations_cleaner/blob/main/CHANGELOG.md) - [Commits](https://github.com/Chinmay-KB/translations_cleaner/commits) --- updated-dependencies: - dependency-name: translations_cleaner dependency-version: 0.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * chore(translations): Translated using Weblate (German) Currently translated at 99.2% (821 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/de/ * chore(translations): Translated using Weblate (Estonian) Currently translated at 100.0% (827 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/ * build: Bump version to 2.4.0 * build: (deps): bump sqflite_common_ffi from 2.3.6 to 2.3.7+1 Bumps [sqflite_common_ffi](https://github.com/tekartik/sqflite) from 2.3.6 to 2.3.7+1. - [Commits](https://github.com/tekartik/sqflite/compare/sqflite_common_ffi_v2.3.6...sqflite_common_ffi/v2.3.7) --- updated-dependencies: - dependency-name: sqflite_common_ffi dependency-version: 2.3.7+1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * chore(translations): Translated using Weblate (Czech) Currently translated at 66.1% (547 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/cs/ * chore(translations): Translated using Weblate (Czech) Currently translated at 72.7% (602 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/cs/ * chore(translations): Translated using Weblate (German) Currently translated at 99.8% (826 of 827 strings) Translation: FluffyChat/Translations Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/de/ * chore: Add security.md file * fix: Locale unlocalized strings * build: (deps): bump matrix from 4.1.0 to 5.0.0 Bumps [matrix](https://github.com/famedly/matrix-dart-sdk) from 4.1.0 to 5.0.0. - [Release notes](https://github.com/famedly/matrix-dart-sdk/releases) - [Changelog](https://github.com/famedly/matrix-dart-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/famedly/matrix-dart-sdk/compare/v4.1.0...v5.0.0) --- updated-dependencies: - dependency-name: matrix dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix: Notifications on web correctly managed when tab not focused * chore: Add changelog for android * chore: Remove duplicated localization * fix: Sign in label * chore: Versionize fcm shared isolate * build: Remove unused packag * build: (deps): bump package_info_plus from 8.3.1 to 9.0.0 Bumps [package_info_plus](https://github.com/fluttercommunity/plus_plugins/tree/main/packages/package_info_plus) from 8.3.1 to 9.0.0. - [Release notes](https://github.com/fluttercommunity/plus_plugins/releases) - [Commits](https://github.com/fluttercommunity/plus_plugins/commits/package_info_plus-v9.0.0/packages/package_info_plus) --- updated-dependencies: - dependency-name: package_info_plus dependency-version: 9.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Display particle animation on login page * chore: Use fixed version of fcm shared isolate * fix: apk crash on some platforms due new flutter version * chore: Correct kotlin format * fix iOS notifications * fluffychat merge * fluffychat merge * fluffychat merge * fluffychat merge * fluffychat merge * fluffychat merge * add missing type annotations * update matrix version * fluffychat merge * fluffychat merge * fix notification on click actions --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Christian Kußowski <c.kussowski@famedly.com> Co-authored-by: Krille-chan <christian-kussowski@posteo.de> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: BeMeritus <bemerituss@gmail.com> Co-authored-by: Frank Paul Silye <frankps@gmail.com> Co-authored-by: josé m. <correoxm@disroot.org> Co-authored-by: xabirequejo <xabi.rn@gmail.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org> Co-authored-by: Jelv <post@jelv.nl> Co-authored-by: Дмитрий Михирев <bizdelnick@gmail.com> Co-authored-by: Kimby <kimbyqs@gmail.com> Co-authored-by: Christian <christian-pauly@posteo.de> Co-authored-by: Kom nake <kominak310@svcache.com> Co-authored-by: hugues de keyzer <komputilisto@hugues.info> Co-authored-by: nautilusx <translate@disroot.org> Co-authored-by: Šebestová <ka.sebestova.cz@gmail.com>
476 lines
15 KiB
Dart
476 lines
15 KiB
Dart
import 'package:matrix/matrix.dart';
|
|
|
|
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
|
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
|
|
import 'package:fluffychat/pangea/instructions/instruction_settings.dart';
|
|
import 'package:fluffychat/pangea/learning_settings/gender_enum.dart';
|
|
import 'package:fluffychat/pangea/learning_settings/language_level_type_enum.dart';
|
|
import 'package:fluffychat/pangea/learning_settings/tool_settings_enum.dart';
|
|
import 'package:fluffychat/widgets/matrix.dart';
|
|
import '../languages/language_model.dart';
|
|
|
|
/// The user's settings learning settings.
|
|
class UserSettings {
|
|
DateTime? dateOfBirth;
|
|
DateTime? createdAt;
|
|
bool? publicProfile;
|
|
String? targetLanguage;
|
|
String? sourceLanguage;
|
|
GenderEnum gender;
|
|
String? country;
|
|
String? about;
|
|
LanguageLevelTypeEnum cefrLevel;
|
|
String? voice;
|
|
|
|
UserSettings({
|
|
this.dateOfBirth,
|
|
this.createdAt,
|
|
this.publicProfile,
|
|
this.targetLanguage,
|
|
this.sourceLanguage,
|
|
this.gender = GenderEnum.unselected,
|
|
this.country,
|
|
this.about,
|
|
this.cefrLevel = LanguageLevelTypeEnum.a1,
|
|
this.voice,
|
|
});
|
|
|
|
factory UserSettings.fromJson(Map<String, dynamic> json) => UserSettings(
|
|
dateOfBirth: json[ModelKey.userDateOfBirth] != null
|
|
? DateTime.parse(json[ModelKey.userDateOfBirth])
|
|
: null,
|
|
createdAt: json[ModelKey.userCreatedAt] != null
|
|
? DateTime.parse(json[ModelKey.userCreatedAt])
|
|
: null,
|
|
publicProfile: json[ModelKey.publicProfile],
|
|
targetLanguage: json[ModelKey.targetLanguage],
|
|
sourceLanguage: json[ModelKey.sourceLanguage],
|
|
gender: json[ModelKey.userGender] is String
|
|
? GenderEnumExtension.fromString(json[ModelKey.userGender])
|
|
: GenderEnum.unselected,
|
|
country: json[ModelKey.userCountry],
|
|
about: json[ModelKey.userAbout],
|
|
cefrLevel: json[ModelKey.cefrLevel] is String
|
|
? LanguageLevelTypeEnum.fromString(json[ModelKey.cefrLevel])
|
|
: LanguageLevelTypeEnum.a1,
|
|
voice: json[ModelKey.voice],
|
|
);
|
|
|
|
Map<String, dynamic> toJson() {
|
|
final Map<String, dynamic> data = <String, dynamic>{};
|
|
data[ModelKey.userDateOfBirth] = dateOfBirth?.toIso8601String();
|
|
data[ModelKey.userCreatedAt] = createdAt?.toIso8601String();
|
|
data[ModelKey.publicProfile] = publicProfile;
|
|
data[ModelKey.targetLanguage] = targetLanguage;
|
|
data[ModelKey.sourceLanguage] = sourceLanguage;
|
|
data[ModelKey.userGender] = gender.string;
|
|
data[ModelKey.userCountry] = country;
|
|
data[ModelKey.userAbout] = about;
|
|
data[ModelKey.cefrLevel] = cefrLevel.string;
|
|
data[ModelKey.voice] = voice;
|
|
return data;
|
|
}
|
|
|
|
static UserSettings? migrateFromAccountData() {
|
|
final accountData =
|
|
MatrixState.pangeaController.matrixState.client.accountData;
|
|
|
|
if (!accountData.containsKey(ModelKey.userDateOfBirth)) return null;
|
|
final dobContent = accountData[ModelKey.userDateOfBirth]!
|
|
.content[ModelKey.userDateOfBirth];
|
|
|
|
String? dobString;
|
|
if (dobContent != null) {
|
|
dobString = dobContent as String;
|
|
}
|
|
|
|
DateTime dob;
|
|
try {
|
|
dob = DateTime.parse(dobString!);
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
|
|
final createdAtContent =
|
|
accountData[ModelKey.userCreatedAt]?.content[ModelKey.userCreatedAt];
|
|
DateTime? createdAt;
|
|
if (createdAtContent != null) {
|
|
try {
|
|
createdAt = DateTime.parse(createdAtContent as String);
|
|
} catch (_) {
|
|
createdAt = null;
|
|
}
|
|
}
|
|
|
|
return UserSettings(
|
|
dateOfBirth: dob,
|
|
createdAt: createdAt,
|
|
publicProfile:
|
|
(accountData[ModelKey.publicProfile]?.content[ModelKey.publicProfile]
|
|
as bool?) ??
|
|
false,
|
|
targetLanguage:
|
|
accountData[ModelKey.targetLanguage]?.content[ModelKey.targetLanguage]
|
|
as String?,
|
|
sourceLanguage:
|
|
accountData[ModelKey.sourceLanguage]?.content[ModelKey.sourceLanguage]
|
|
as String?,
|
|
country:
|
|
accountData[ModelKey.userCountry]?.content[ModelKey.userCountry]
|
|
as String?,
|
|
);
|
|
}
|
|
|
|
UserSettings copy() {
|
|
return UserSettings(
|
|
dateOfBirth: dateOfBirth,
|
|
createdAt: createdAt,
|
|
publicProfile: publicProfile,
|
|
targetLanguage: targetLanguage,
|
|
sourceLanguage: sourceLanguage,
|
|
gender: gender,
|
|
country: country,
|
|
about: about,
|
|
cefrLevel: cefrLevel,
|
|
voice: voice,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is UserSettings &&
|
|
other.dateOfBirth == dateOfBirth &&
|
|
other.createdAt == createdAt &&
|
|
(other.publicProfile ?? false) == (publicProfile ?? false) &&
|
|
other.targetLanguage == targetLanguage &&
|
|
other.sourceLanguage == sourceLanguage &&
|
|
other.gender == gender &&
|
|
other.country == country &&
|
|
other.about == about &&
|
|
other.cefrLevel == cefrLevel &&
|
|
other.voice == voice;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => Object.hashAll([
|
|
dateOfBirth.hashCode,
|
|
createdAt.hashCode,
|
|
(publicProfile ?? false).hashCode,
|
|
targetLanguage.hashCode,
|
|
sourceLanguage.hashCode,
|
|
gender.hashCode,
|
|
country.hashCode,
|
|
about.hashCode,
|
|
cefrLevel.hashCode,
|
|
voice.hashCode,
|
|
]);
|
|
}
|
|
|
|
/// The user's language tool settings.
|
|
class UserToolSettings {
|
|
bool interactiveTranslator;
|
|
bool interactiveGrammar;
|
|
bool immersionMode;
|
|
bool definitions;
|
|
bool autoIGC;
|
|
bool enableTTS;
|
|
bool enableAutocorrect;
|
|
|
|
UserToolSettings({
|
|
this.interactiveTranslator = true,
|
|
this.interactiveGrammar = true,
|
|
this.immersionMode = false,
|
|
this.definitions = true,
|
|
this.autoIGC = true,
|
|
this.enableTTS = true,
|
|
this.enableAutocorrect = false,
|
|
});
|
|
|
|
factory UserToolSettings.fromJson(Map<String, dynamic> json) =>
|
|
UserToolSettings(
|
|
interactiveTranslator:
|
|
json[ToolSetting.interactiveTranslator.toString()] ?? true,
|
|
interactiveGrammar:
|
|
json[ToolSetting.interactiveGrammar.toString()] ?? true,
|
|
immersionMode: false,
|
|
definitions: json[ToolSetting.definitions.toString()] ?? true,
|
|
autoIGC: json[ModelKey.autoIGC] ?? true,
|
|
enableTTS: json[ToolSetting.enableTTS.toString()] ?? true,
|
|
enableAutocorrect: json["enableAutocorrect"] ?? false,
|
|
);
|
|
|
|
Map<String, dynamic> toJson() {
|
|
final Map<String, dynamic> data = <String, dynamic>{};
|
|
data[ToolSetting.interactiveTranslator.toString()] = interactiveTranslator;
|
|
data[ToolSetting.interactiveGrammar.toString()] = interactiveGrammar;
|
|
data[ToolSetting.immersionMode.toString()] = immersionMode;
|
|
data[ToolSetting.definitions.toString()] = definitions;
|
|
data[ModelKey.autoIGC] = autoIGC;
|
|
data[ToolSetting.enableTTS.toString()] = enableTTS;
|
|
data["enableAutocorrect"] = enableAutocorrect;
|
|
return data;
|
|
}
|
|
|
|
factory UserToolSettings.migrateFromAccountData() {
|
|
final accountData =
|
|
MatrixState.pangeaController.matrixState.client.accountData;
|
|
return UserToolSettings(
|
|
interactiveTranslator:
|
|
(accountData[ToolSetting.interactiveTranslator.toString()]
|
|
?.content[ToolSetting.interactiveTranslator.toString()]
|
|
as bool?) ??
|
|
true,
|
|
interactiveGrammar:
|
|
(accountData[ToolSetting.interactiveGrammar.toString()]
|
|
?.content[ToolSetting.interactiveGrammar.toString()]
|
|
as bool?) ??
|
|
true,
|
|
immersionMode: false,
|
|
definitions:
|
|
(accountData[ToolSetting.definitions.toString()]?.content[ToolSetting
|
|
.definitions
|
|
.toString()]
|
|
as bool?) ??
|
|
true,
|
|
autoIGC:
|
|
(accountData[ToolSetting.autoIGC.toString()]?.content[ToolSetting
|
|
.autoIGC
|
|
.toString()]
|
|
as bool?) ??
|
|
true,
|
|
);
|
|
}
|
|
|
|
UserToolSettings copy() {
|
|
return UserToolSettings(
|
|
interactiveTranslator: interactiveTranslator,
|
|
interactiveGrammar: interactiveGrammar,
|
|
immersionMode: immersionMode,
|
|
definitions: definitions,
|
|
autoIGC: autoIGC,
|
|
enableTTS: enableTTS,
|
|
enableAutocorrect: enableAutocorrect,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is UserToolSettings &&
|
|
other.interactiveTranslator == interactiveTranslator &&
|
|
other.interactiveGrammar == interactiveGrammar &&
|
|
other.immersionMode == immersionMode &&
|
|
other.definitions == definitions &&
|
|
other.autoIGC == autoIGC &&
|
|
other.enableTTS == enableTTS &&
|
|
other.enableAutocorrect == enableAutocorrect;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => Object.hashAll([
|
|
interactiveTranslator.hashCode,
|
|
interactiveGrammar.hashCode,
|
|
immersionMode.hashCode,
|
|
definitions.hashCode,
|
|
autoIGC.hashCode,
|
|
enableTTS.hashCode,
|
|
enableAutocorrect.hashCode,
|
|
]);
|
|
}
|
|
|
|
/// A wrapper around the matrix account data for the user profile.
|
|
/// Enables easy access to the profile data and saving new data.
|
|
class Profile {
|
|
late UserSettings userSettings;
|
|
late UserToolSettings toolSettings;
|
|
late InstructionSettings instructionSettings;
|
|
|
|
Profile({
|
|
required this.userSettings,
|
|
UserToolSettings? toolSettings,
|
|
InstructionSettings? instructionSettings,
|
|
}) {
|
|
this.toolSettings = toolSettings ?? UserToolSettings();
|
|
this.instructionSettings = instructionSettings ?? InstructionSettings();
|
|
}
|
|
|
|
/// Load an instance of profile from the client's account data.
|
|
static Profile? fromAccountData(Map<String, Object?>? profileData) {
|
|
if (profileData == null) return null;
|
|
|
|
final userSettingsContent = profileData[ModelKey.userSettings];
|
|
if (userSettingsContent == null) return null;
|
|
|
|
final toolSettingsContent = profileData[ModelKey.toolSettings];
|
|
final instructionSettingsContent =
|
|
profileData[ModelKey.instructionsSettings];
|
|
|
|
return Profile(
|
|
userSettings: UserSettings.fromJson(
|
|
userSettingsContent as Map<String, dynamic>,
|
|
),
|
|
toolSettings: toolSettingsContent != null
|
|
? UserToolSettings.fromJson(
|
|
toolSettingsContent as Map<String, dynamic>,
|
|
)
|
|
: UserToolSettings(),
|
|
instructionSettings: instructionSettingsContent != null
|
|
? InstructionSettings.fromJson(
|
|
instructionSettingsContent as Map<String, dynamic>,
|
|
)
|
|
: InstructionSettings(),
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
final Map<String, dynamic> json = {
|
|
ModelKey.userSettings: userSettings.toJson(),
|
|
ModelKey.toolSettings: toolSettings.toJson(),
|
|
ModelKey.instructionsSettings: instructionSettings.toJson(),
|
|
};
|
|
return json;
|
|
}
|
|
|
|
/// Migrate data from the old matrix account data
|
|
/// format to the new matrix account data format.
|
|
static Profile? migrateFromAccountData() {
|
|
final userSettings = UserSettings.migrateFromAccountData();
|
|
if (userSettings == null) return null;
|
|
|
|
final toolSettings = UserToolSettings.migrateFromAccountData();
|
|
final instructionSettings = InstructionSettings.migrateFromAccountData();
|
|
return Profile(
|
|
userSettings: userSettings,
|
|
toolSettings: toolSettings,
|
|
instructionSettings: instructionSettings,
|
|
);
|
|
}
|
|
|
|
/// Saves the current configuration of the profile to the client's account data.
|
|
/// If [waitForDataInSync] is true, the function will wait for the updated account
|
|
/// data to come through in a sync, indicating that it has been set on the matrix server.
|
|
Future<void> saveProfileData({bool waitForDataInSync = false}) async {
|
|
final PangeaController pangeaController = MatrixState.pangeaController;
|
|
final Client client = pangeaController.matrixState.client;
|
|
final List<String> profileKeys = [
|
|
ModelKey.userSettings,
|
|
ModelKey.toolSettings,
|
|
ModelKey.instructionsSettings,
|
|
];
|
|
|
|
Future<SyncUpdate>? waitForUpdate;
|
|
if (waitForDataInSync) {
|
|
waitForUpdate = client.onSync.stream.firstWhere(
|
|
(sync) =>
|
|
sync.accountData != null &&
|
|
sync.accountData!.any(
|
|
(event) => event.content.keys.any((k) => profileKeys.contains(k)),
|
|
),
|
|
);
|
|
}
|
|
await client.setAccountData(client.userID!, ModelKey.userProfile, toJson());
|
|
|
|
if (waitForDataInSync) {
|
|
await waitForUpdate;
|
|
}
|
|
}
|
|
|
|
static Profile get emptyProfile {
|
|
return Profile(
|
|
userSettings: UserSettings(),
|
|
toolSettings: UserToolSettings(),
|
|
instructionSettings: InstructionSettings(),
|
|
);
|
|
}
|
|
|
|
Profile copy() {
|
|
return Profile(
|
|
userSettings: userSettings.copy(),
|
|
toolSettings: toolSettings.copy(),
|
|
instructionSettings: instructionSettings.copy(),
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is Profile &&
|
|
other.userSettings == userSettings &&
|
|
other.toolSettings == toolSettings &&
|
|
other.instructionSettings == instructionSettings;
|
|
}
|
|
|
|
@override
|
|
int get hashCode =>
|
|
userSettings.hashCode ^
|
|
toolSettings.hashCode ^
|
|
instructionSettings.hashCode;
|
|
}
|
|
|
|
/// Model of data from pangea chat server. Not used anymore, in favor of matrix account data.
|
|
/// This class if used to read in data from the server to be migrated to matrix account data.
|
|
class PangeaProfile {
|
|
final String createdAt;
|
|
final String pangeaUserId;
|
|
String? dateOfBirth;
|
|
String? targetLanguage;
|
|
String? sourceLanguage;
|
|
|
|
String? country;
|
|
bool? publicProfile;
|
|
|
|
PangeaProfile({
|
|
required this.createdAt,
|
|
required this.pangeaUserId,
|
|
this.dateOfBirth,
|
|
this.targetLanguage,
|
|
this.sourceLanguage,
|
|
this.country,
|
|
this.publicProfile,
|
|
});
|
|
|
|
factory PangeaProfile.fromJson(Map<String, dynamic> json) {
|
|
final l2 = LanguageModel.codeFromNameOrCode(json[ModelKey.targetLanguage]);
|
|
final l1 = LanguageModel.codeFromNameOrCode(json[ModelKey.sourceLanguage]);
|
|
|
|
return PangeaProfile(
|
|
createdAt: json[ModelKey.userCreatedAt],
|
|
pangeaUserId: json[ModelKey.userPangeaUserId],
|
|
dateOfBirth: json[ModelKey.userDateOfBirth],
|
|
targetLanguage: l2,
|
|
sourceLanguage: l1,
|
|
publicProfile: json[ModelKey.publicProfile],
|
|
country: json[ModelKey.userCountry],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
final Map<String, dynamic> data = <String, dynamic>{};
|
|
data[ModelKey.userCreatedAt] = createdAt;
|
|
data[ModelKey.userPangeaUserId] = pangeaUserId;
|
|
data[ModelKey.userDateOfBirth] = dateOfBirth;
|
|
data[ModelKey.targetLanguage] = targetLanguage;
|
|
data[ModelKey.sourceLanguage] = sourceLanguage;
|
|
data[ModelKey.publicProfile] = publicProfile;
|
|
data[ModelKey.userCountry] = country;
|
|
return data;
|
|
}
|
|
}
|
|
|
|
class PangeaProfileResponse {
|
|
final PangeaProfile profile;
|
|
final String access;
|
|
|
|
PangeaProfileResponse({required this.profile, required this.access});
|
|
|
|
factory PangeaProfileResponse.fromJson(Map<String, dynamic> json) {
|
|
return PangeaProfileResponse(
|
|
profile: PangeaProfile.fromJson(json[ModelKey.userProfile]),
|
|
access: json[ModelKey.userAccess],
|
|
);
|
|
}
|
|
}
|