resolve merge conflict

This commit is contained in:
ggurdin 2024-11-01 10:30:22 -04:00
commit de927aa6b4
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
25 changed files with 248 additions and 133 deletions

View file

@ -4303,6 +4303,7 @@
"grammarCopyAccDat": "Accusative, Dative",
"grammarCopyInf": "Infinitive",
"grammarCopyLong": "Long",
"grammarCopyLoc": "Locative",
"grammarCopyInd": "Indicative",
"grammarCopyCmp": "Comparative",
"grammarCopyRelative_case": "Relative Case",

View file

@ -4962,6 +4962,7 @@
"grammarCopyAccDat": "Acusativo, Dativo",
"grammarCopyInf": "Infinitivo",
"grammarCopyLong": "Largo",
"grammarCopyLoc": "Locativa",
"grammarCopyInd": "Indicativo",
"grammarCopyCmp": "Comparativa",
"grammarCopyRelative_case": "Caso relativo",
@ -5008,4 +5009,4 @@
"spaceCapacityNotSet": "Este espacio no tiene límite de capacidad.",
"chatExceedsCapacity": "Este chat supera su capacidad.",
"spaceExceedsCapacity": "Este espacio supera su capacidad."
}
}

View file

@ -7,7 +7,6 @@ import 'package:fluffychat/pangea/pages/class_settings/class_name_header.dart';
import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_description_button.dart';
import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart';
import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart';
import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_name_button.dart';
import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart';
import 'package:fluffychat/pangea/utils/lock_room.dart';
import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart';
@ -213,11 +212,6 @@ class ChatDetailsView extends StatelessWidget {
),
Divider(color: theme.dividerColor),
// #Pangea
if (room.isRoomAdmin)
ClassNameButton(
room: room,
controller: controller,
),
if (room.canSendEvent('m.room.topic'))
ClassDescriptionButton(
room: room,

View file

@ -542,9 +542,9 @@ class Choreographer {
chatController.room,
);
bool get itAutoPlayEnabled {
return pangeaController.userController.profile.userSettings.itAutoPlay;
}
// bool get itAutoPlayEnabled {
// return pangeaController.userController.profile.userSettings.itAutoPlay;
// }
bool get definitionsEnabled =>
pangeaController.permissionsController.isToolEnabled(

View file

@ -99,7 +99,7 @@ class IgcController {
final PangeaMatch match = igcTextData!.matches[firstMatchIndex];
if (match.isITStart &&
choreographer.itAutoPlayEnabled &&
// choreographer.itAutoPlayEnabled &&
igcTextData != null) {
choreographer.onITStart(igcTextData!.matches[firstMatchIndex]);
return;

View file

@ -352,7 +352,7 @@ class ITChoices extends StatelessWidget {
void selectContinuance(int index, BuildContext context) {
final Continuance continuance =
controller.currentITStep!.continuances[index];
if (continuance.level == 1 || continuance.wasClicked) {
if (continuance.level == 1) {
Future.delayed(
const Duration(milliseconds: 500),
() => controller.selectTranslation(index),

View file

@ -24,7 +24,7 @@ class ModelKey {
// making this a random string so that it's harder to guess
static const String activatedTrialKey = '7C4EuKIsph';
static const String autoPlayMessages = 'autoPlayMessages';
static const String itAutoPlay = 'itAutoPlay';
static const String itAutoPlay = 'autoPlayIT';
static const String clientClassCity = "city";
static const String clientClassCountry = "country";

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:developer';
import 'dart:math';
import 'package:fluffychat/pangea/constants/bot_mode.dart';
import 'package:fluffychat/pangea/constants/class_default_values.dart';
import 'package:fluffychat/pangea/constants/pangea_event_types.dart';
import 'package:fluffychat/pangea/controllers/class_controller.dart';
@ -22,6 +23,7 @@ import 'package:fluffychat/pangea/controllers/user_controller.dart';
import 'package:fluffychat/pangea/controllers/word_net_controller.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/guard/p_vguard.dart';
import 'package:fluffychat/pangea/models/bot_options_model.dart';
import 'package:fluffychat/pangea/utils/bot_name.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
@ -205,15 +207,88 @@ class PangeaController {
if (botDMs.isEmpty) {
try {
await matrixState.client.startDirectChat(
BotName.byEnvironment,
enableEncryption: false,
// Copied from client.dart.startDirectChat
final directChatRoomId =
matrixState.client.getDirectChatFromUserId(BotName.byEnvironment);
if (directChatRoomId != null) {
final room = matrixState.client.getRoomById(directChatRoomId);
if (room != null) {
if (room.membership == Membership.join) {
return null;
} else if (room.membership == Membership.invite) {
// we might already have an invite into a DM room. If that is the case, we should try to join. If the room is
// unjoinable, that will automatically leave the room, so in that case we need to continue creating a new
// room. (This implicitly also prevents the room from being returned as a DM room by getDirectChatFromUserId,
// because it only returns joined or invited rooms atm.)
await room.join();
if (room.membership != Membership.leave) {
if (room.membership != Membership.join) {
// Wait for room actually appears in sync with the right membership
await matrixState.client
.waitForRoomInSync(directChatRoomId, join: true);
}
return null;
}
}
}
}
// enableEncryption ??=
// encryptionEnabled && await userOwnsEncryptionKeys(mxid);
// if (enableEncryption) {
// initialState ??= [];
// if (!initialState.any((s) => s.type == EventTypes.Encryption)) {
// initialState.add(
// StateEvent(
// content: {
// 'algorithm': supportedGroupEncryptionAlgorithms.first,
// },
// type: EventTypes.Encryption,
// ),
// );
// }
// }
// Start a new direct chat
final roomId = await matrixState.client.createRoom(
invite: [], // intentionally not invite bot yet
isDirect: true,
preset: CreateRoomPreset.trustedPrivateChat,
initialState: [
BotOptionsModel(mode: BotMode.directChat).toStateEvent,
],
);
final room = matrixState.client.getRoomById(roomId);
if (room == null || room.membership != Membership.join) {
// Wait for room actually appears in sync
await matrixState.client.waitForRoomInSync(roomId, join: true);
}
final botOptions = room!.getState(PangeaEventTypes.botOptions);
if (botOptions == null) {
await matrixState.client.setRoomStateWithKey(
roomId,
PangeaEventTypes.botOptions,
"",
BotOptionsModel(mode: BotMode.directChat).toJson(),
);
await matrixState.client
.getRoomStateWithKey(roomId, PangeaEventTypes.botOptions, "");
}
// invite bot to direct chat
await matrixState.client.setRoomStateWithKey(
roomId, EventTypes.RoomMember, BotName.byEnvironment, {
"membership": Membership.invite.name,
"is_direct": true,
});
await room.addToDirectChat(BotName.byEnvironment);
return null;
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
}
return;
}
final Room botDMWithLatestActivity = botDMs.reduce((a, b) {

View file

@ -105,23 +105,23 @@ extension ConstructUseTypeExtension on ConstructUseTypeEnum {
return 2;
case ConstructUseTypeEnum.corIt:
return 1;
case ConstructUseTypeEnum.ignIt:
case ConstructUseTypeEnum.ignIGC:
case ConstructUseTypeEnum.ignPA:
case ConstructUseTypeEnum.ignWL:
return 1;
case ConstructUseTypeEnum.unk:
case ConstructUseTypeEnum.nan:
return 0;
case ConstructUseTypeEnum.incIt:
case ConstructUseTypeEnum.incIGC:
return -1;
return -2;
case ConstructUseTypeEnum.incPA:
case ConstructUseTypeEnum.incWL:
return -2;
return -3;
}
}
}

View file

@ -26,6 +26,10 @@ class ConstructListModel {
/// All unique lemmas used in the construct events
List<String> get lemmas => constructList.map((e) => e.lemma).toSet().toList();
/// All unique lemmas used in the construct events with non-zero points
List<String> get lemmasWithPoints =>
constructListWithPoints.map((e) => e.lemma).toSet().toList();
/// A map of lemmas to ConstructUses, each of which contains a lemma
/// key = lemmma + constructType.string, value = ConstructUses
void _buildConstructMap() {
@ -72,6 +76,9 @@ class ConstructListModel {
return _constructList!;
}
List<ConstructUses> get constructListWithPoints =>
constructList.where((constructUse) => constructUse.points > 0).toList();
get maxXPPerLemma {
return type != null
? type!.maxXPPerLemma

View file

@ -12,7 +12,7 @@ class UserSettings {
DateTime? dateOfBirth;
DateTime? createdAt;
bool autoPlayMessages;
bool itAutoPlay;
// bool itAutoPlay;
bool activatedFreeTrial;
bool publicProfile;
String? targetLanguage;
@ -23,7 +23,7 @@ class UserSettings {
this.dateOfBirth,
this.createdAt,
this.autoPlayMessages = false,
this.itAutoPlay = false,
// this.itAutoPlay = true,
this.activatedFreeTrial = false,
this.publicProfile = false,
this.targetLanguage,
@ -37,7 +37,7 @@ class UserSettings {
? DateTime.parse(json[ModelKey.userCreatedAt])
: null,
autoPlayMessages: json[ModelKey.autoPlayMessages] ?? false,
itAutoPlay: json[ModelKey.itAutoPlay] ?? false,
// itAutoPlay: json[ModelKey.itAutoPlay] ?? true,
activatedFreeTrial: json[ModelKey.activatedTrialKey] ?? false,
publicProfile: json[ModelKey.publicProfile] ?? false,
targetLanguage: json[ModelKey.l2LanguageKey],
@ -50,7 +50,7 @@ class UserSettings {
data[ModelKey.userDateOfBirth] = dateOfBirth?.toIso8601String();
data[ModelKey.userCreatedAt] = createdAt?.toIso8601String();
data[ModelKey.autoPlayMessages] = autoPlayMessages;
data[ModelKey.itAutoPlay] = itAutoPlay;
// data[ModelKey.itAutoPlay] = itAutoPlay;
data[ModelKey.activatedTrialKey] = activatedFreeTrial;
data[ModelKey.publicProfile] = publicProfile;
data[ModelKey.l2LanguageKey] = targetLanguage;
@ -96,9 +96,9 @@ class UserSettings {
autoPlayMessages: (accountData[ModelKey.autoPlayMessages]
?.content[ModelKey.autoPlayMessages] as bool?) ??
false,
itAutoPlay: (accountData[ModelKey.itAutoPlay]
?.content[ModelKey.itAutoPlay] as bool?) ??
false,
// itAutoPlay: (accountData[ModelKey.itAutoPlay]
// ?.content[ModelKey.itAutoPlay] as bool?) ??
// true,
activatedFreeTrial: (accountData[ModelKey.activatedTrialKey]
?.content[ModelKey.activatedTrialKey] as bool?) ??
false,

View file

@ -42,7 +42,7 @@ class ClassDescriptionButton extends StatelessWidget {
? (room.isRoomAdmin
? (room.isSpace
? L10n.of(context)!.classDescriptionDesc
: L10n.of(context)!.chatTopicDesc)
: L10n.of(context)!.setChatDescription)
: L10n.of(context)!.topicNotSet)
: room.topic,
),

View file

@ -2,7 +2,6 @@ import 'dart:developer';
import 'package:fluffychat/pangea/constants/age_limits.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart';
import 'package:fluffychat/pangea/pages/p_user_age/p_user_age_view.dart';
import 'package:fluffychat/pangea/utils/p_extension.dart';
import 'package:fluffychat/widgets/fluffy_chat_app.dart';
@ -11,7 +10,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../../utils/bot_name.dart';
import '../../utils/error_handler.dart';
class PUserAge extends StatefulWidget {
@ -34,20 +32,7 @@ class PUserAgeController extends State<PUserAge> {
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
if (!(await Matrix.of(context).client.hasBotDM)) {
Matrix.of(context)
.client
.startDirectChat(
BotName.byEnvironment,
enableEncryption: false,
)
.onError(
(error, stackTrace) =>
ErrorHandler.logError(e: error, s: stackTrace),
);
}
});
pangeaController.startChatWithBotIfNotPresent();
}
String? dobValidator() {

View file

@ -48,19 +48,19 @@ class SettingsLearningView extends StatelessWidget {
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.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,

View file

@ -41,14 +41,16 @@ class InlineTooltip extends StatelessWidget {
),
const SizedBox(width: 8),
// Text in the middle
Center(
child: Text(
instructionsEnum.body(L10n.of(context)!),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
height: 1.5,
Flexible(
child: Center(
child: Text(
instructionsEnum.body(L10n.of(context)!),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
height: 1.5,
),
textAlign: TextAlign.left,
),
textAlign: TextAlign.left,
),
),
// Close button on the right

View file

@ -40,21 +40,27 @@ class MissingVoiceButton extends StatelessWidget {
),
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.only(top: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
L10n.of(context)!.voiceNotAvailable,
textAlign: TextAlign.center,
),
TextButton(
onPressed: () => launchTTSSettings,
style: const ButtonStyle(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: SizedBox(
width: AppConfig.toolbarMinWidth,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
L10n.of(context)!.voiceNotAvailable,
textAlign: TextAlign.center,
),
child: Text(L10n.of(context)!.openVoiceSettings),
),
],
TextButton(
onPressed: () => launchTTSSettings,
// commenting out as suspecting this is causing an issue
// #freeze-activity
style: const ButtonStyle(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Text(L10n.of(context)!.openVoiceSettings),
),
],
),
),
);
}

View file

@ -65,33 +65,71 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
);
}
int lastEnd = 0;
// Convert the entire message into a list of characters
final Characters messageCharacters =
widget.pangeaMessageEvent.event.body.characters;
// When building token positions, use grapheme cluster indices
final List<TokenPosition> tokenPositions = [];
int globalIndex = 0;
for (int i = 0; i < tokens!.length; i++) {
final token = tokens![i];
final start = token.start;
final end = token.end;
if (lastEnd < start) {
tokenPositions.add(TokenPosition(start: lastEnd, end: start));
// Calculate the number of grapheme clusters up to the start and end positions
final int startIndex = messageCharacters.take(start).length;
final int endIndex = messageCharacters.take(end).length;
if (globalIndex < startIndex) {
tokenPositions.add(TokenPosition(start: globalIndex, end: startIndex));
}
tokenPositions.add(
TokenPosition(
start: start,
end: end,
start: startIndex,
end: endIndex,
tokenIndex: i,
token: token,
),
);
lastEnd = end;
globalIndex = endIndex;
}
// debug prints for fixing words sticking together
// void printEscapedString(String input) {
// // Escaped string using Unicode escape sequences
// final String escapedString = input.replaceAllMapped(
// RegExp(r'[^\w\s]', unicode: true),
// (match) {
// final codeUnits = match.group(0)!.runes;
// String unicodeEscapes = '';
// for (final rune in codeUnits) {
// unicodeEscapes += '\\u{${rune.toRadixString(16)}}';
// }
// return unicodeEscapes;
// },
// );
// print("Escaped String: $escapedString");
// // Printing each character with its index
// int index = 0;
// for (final char in input.characters) {
// print("Index $index: $char");
// index++;
// }
// }
//TODO - take out of build function of every message
return RichText(
text: TextSpan(
children: tokenPositions.map((tokenPosition) {
final substring = messageCharacters
.skip(tokenPosition.start)
.take(tokenPosition.end - tokenPosition.start)
.toString();
if (tokenPosition.token != null) {
final isSelected =
widget.overlayController.isTokenSelected(tokenPosition.token!);
@ -106,7 +144,7 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
);
setState(() {});
},
text: tokenPosition.token!.text.content,
text: substring,
style: style.merge(
TextStyle(
backgroundColor: isSelected
@ -119,10 +157,7 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
);
} else {
return TextSpan(
text: widget.pangeaMessageEvent.event.body.substring(
tokenPosition.start,
tokenPosition.end,
),
text: substring,
style: style,
);
}

View file

@ -36,31 +36,32 @@ class AnalyticsPopup extends StatelessWidget {
),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: constructsModel.constructList.isEmpty
child: constructsModel.constructListWithPoints.isEmpty
? Center(
child: Text(L10n.of(context)!.noDataFound),
)
: ListView.builder(
itemCount: constructsModel.constructList.length,
itemCount: constructsModel.constructListWithPoints.length,
itemBuilder: (context, index) {
return Tooltip(
message:
"${constructsModel.constructList[index].points} / ${constructsModel.maxXPPerLemma}",
"${constructsModel.constructListWithPoints[index].points} / ${constructsModel.maxXPPerLemma}",
child: ListTile(
onTap: () {},
title: Text(
constructsModel.type == ConstructTypeEnum.morph
? getGrammarCopy(
constructsModel
.constructList[index].lemma,
.constructListWithPoints[index].lemma,
context,
)
: constructsModel.constructList[index].lemma,
: constructsModel
.constructListWithPoints[index].lemma,
),
subtitle: LinearProgressIndicator(
value:
constructsModel.constructList[index].points /
constructsModel.maxXPPerLemma,
value: constructsModel
.constructListWithPoints[index].points /
constructsModel.maxXPPerLemma,
minHeight: 20,
borderRadius: const BorderRadius.all(
Radius.circular(AppConfig.borderRadius),

View file

@ -111,9 +111,9 @@ class LearningProgressIndicatorsState
int? getProgressPoints(ProgressIndicatorEnum indicator) {
switch (indicator) {
case ProgressIndicatorEnum.wordsUsed:
return words?.lemmas.length;
return words?.lemmasWithPoints.length;
case ProgressIndicatorEnum.morphsUsed:
return morphs?.lemmas.length;
return morphs?.lemmasWithPoints.length;
case ProgressIndicatorEnum.level:
return level;
}

View file

@ -24,6 +24,7 @@ class ConversationBotModeDynamicZone extends StatelessWidget {
Widget build(BuildContext context) {
final discussionChildren = [
TextFormField(
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
decoration: InputDecoration(
hintText: L10n.of(context)!
.conversationBotDiscussionZone_discussionTopicPlaceholder,
@ -43,6 +44,7 @@ class ConversationBotModeDynamicZone extends StatelessWidget {
),
const SizedBox(height: 12),
TextFormField(
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
decoration: InputDecoration(
hintText: L10n.of(context)!
.conversationBotDiscussionZone_discussionKeywordsPlaceholder,
@ -58,6 +60,7 @@ class ConversationBotModeDynamicZone extends StatelessWidget {
final customChildren = [
TextFormField(
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
decoration: InputDecoration(
hintText: L10n.of(context)!
.conversationBotCustomZone_customSystemPromptPlaceholder,

View file

@ -200,27 +200,31 @@ class ConversationBotSettingsDialogState
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 20),
AnimatedOpacity(
duration: FluffyThemes.animationDuration,
opacity: addBot ? 1.0 : 0.5,
child: ConversationBotSettingsForm(
botOptions: botOptions,
discussionKeywordsController:
discussionKeywordsController,
discussionTopicController: discussionTopicController,
customSystemPromptController:
customSystemPromptController,
enabled: addBot,
onUpdateBotMode: onUpdateChatMode,
onUpdateBotLanguage: onUpdateBotLanguage,
onUpdateBotVoice: onUpdateBotVoice,
onUpdateBotLanguageLevel: onUpdateBotLanguageLevel,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
const SizedBox(height: 20),
AnimatedOpacity(
duration: FluffyThemes.animationDuration,
opacity: addBot ? 1.0 : 0.5,
child: ConversationBotSettingsForm(
botOptions: botOptions,
discussionKeywordsController:
discussionKeywordsController,
discussionTopicController:
discussionTopicController,
customSystemPromptController:
customSystemPromptController,
enabled: addBot,
onUpdateBotMode: onUpdateChatMode,
onUpdateBotLanguage: onUpdateBotLanguage,
onUpdateBotVoice: onUpdateBotVoice,
onUpdateBotLanguageLevel: onUpdateBotLanguageLevel,
),
),
),
],
],
),
),
),
),

View file

@ -90,7 +90,7 @@ class PangeaTextController extends TextEditingController {
// if autoplay on and it start then just start it
if (matchIndex != -1 &&
choreographer.itAutoPlayEnabled &&
// choreographer.itAutoPlayEnabled &&
choreographer.igc.igcTextData!.matches[matchIndex].isITStart) {
return choreographer.onITStart(
choreographer.igc.igcTextData!.matches[matchIndex],

View file

@ -355,16 +355,16 @@ 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;
});
},
),
// if (controller.widget.scm.pangeaMatch!.isITStart)
// DontShowSwitchListTile(
// controller: pangeaController,
// onSwitch: (bool value) {
// pangeaController.userController.updateProfile((profile) {
// profile.userSettings.itAutoPlay = value;
// return profile;
// });
// },
// ),
],
),
],

View file

@ -162,7 +162,7 @@ packages:
source: hosted
version: "1.1.2"
characters:
dependency: transitive
dependency: "direct main"
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"

View file

@ -6,7 +6,7 @@ description: Learn a language while texting your friends.
# Pangea#
publish_to: none
# On version bump also increase the build number for F-Droid
version: 1.23.2+3561
version: 1.23.3+3562
environment:
sdk: ">=3.0.0 <4.0.0"
@ -19,6 +19,7 @@ dependencies:
badges: ^3.1.2
blurhash_dart: ^1.2.1
callkeep: ^0.3.2
characters: ^1.2.0
chewie: ^1.8.1
collection: ^1.18.0
cupertino_icons: any