Merge branch 'main' into speech-to-text

pull/1116/head
William Jordan-Cooley 2 years ago
commit 821fda7365

@ -113,6 +113,14 @@ abstract class AppRoutes {
), ),
), ),
// #Pangea // #Pangea
GoRoute(
path: '/join_with_link',
pageBuilder: (context, state) => defaultPageBuilder(
context,
state,
const JoinClassWithLink(),
),
),
GoRoute( GoRoute(
path: '/user_age', path: '/user_age',
pageBuilder: (context, state) => defaultPageBuilder( pageBuilder: (context, state) => defaultPageBuilder(
@ -154,15 +162,6 @@ abstract class AppRoutes {
), ),
redirect: loggedOutRedirect, redirect: loggedOutRedirect,
), ),
GoRoute(
path: '/join_with_link',
pageBuilder: (context, state) => defaultPageBuilder(
context,
state,
const JoinClassWithLink(),
),
redirect: loggedOutRedirect,
),
// Pangea# // Pangea#
GoRoute( GoRoute(
path: '/rooms', path: '/rooms',

@ -575,70 +575,72 @@ class Message extends StatelessWidget {
), ),
child: container, child: container,
), ),
Positioned( // #Pangea
left: ownMessage ? null : 48, // Positioned(
right: ownMessage ? 4 : null, // left: ownMessage ? null : 48,
top: displayTime ? 38 : 0, // right: ownMessage ? 4 : null,
child: AnimatedScale( // top: displayTime ? 38 : 0,
duration: Duration( // child: AnimatedScale(
milliseconds: // duration: Duration(
(FluffyThemes.animationDuration.inMilliseconds / 2) // milliseconds:
.floor(), // (FluffyThemes.animationDuration.inMilliseconds / 2)
), // .floor(),
curve: FluffyThemes.animationCurve, // ),
scale: !longPressSelect && hovered ? 1 : 0, // curve: FluffyThemes.animationCurve,
alignment: Alignment.center, // scale: !longPressSelect && hovered ? 1 : 0,
child: Material( // alignment: Alignment.center,
color: Theme.of(context) // child: Material(
.colorScheme // color: Theme.of(context)
.secondaryContainer // .colorScheme
.withOpacity(0.9), // .secondaryContainer
elevation: // .withOpacity(0.9),
Theme.of(context).appBarTheme.scrolledUnderElevation ?? // elevation:
4, // Theme.of(context).appBarTheme.scrolledUnderElevation ??
borderRadius: BorderRadius.circular(AppConfig.borderRadius), // 4,
shadowColor: Theme.of(context).appBarTheme.shadowColor, // borderRadius: BorderRadius.circular(AppConfig.borderRadius),
child: Row( // shadowColor: Theme.of(context).appBarTheme.shadowColor,
mainAxisSize: MainAxisSize.min, // child: Row(
children: [ // mainAxisSize: MainAxisSize.min,
if (event.room.canSendDefaultMessages) // children: [
SizedBox( // if (event.room.canSendDefaultMessages)
width: 32, // SizedBox(
height: 32, // width: 32,
child: IconButton( // height: 32,
icon: Icon( // child: IconButton(
Icons.reply_outlined, // icon: Icon(
size: 16, // Icons.reply_outlined,
color: Theme.of(context) // size: 16,
.colorScheme // color: Theme.of(context)
.onTertiaryContainer, // .colorScheme
), // .onTertiaryContainer,
tooltip: L10n.of(context)!.reply, // ),
onPressed: event.room.canSendDefaultMessages // tooltip: L10n.of(context)!.reply,
? () => onSwipe() // onPressed: event.room.canSendDefaultMessages
: null, // ? () => onSwipe()
), // : null,
), // ),
SizedBox( // ),
width: 32, // SizedBox(
height: 32, // width: 32,
child: IconButton( // height: 32,
icon: Icon( // child: IconButton(
Icons.more_vert, // icon: Icon(
size: 16, // Icons.more_vert,
color: Theme.of(context) // size: 16,
.colorScheme // color: Theme.of(context)
.onTertiaryContainer, // .colorScheme
), // .onTertiaryContainer,
tooltip: L10n.of(context)!.select, // ),
onPressed: () => onSelect(event), // tooltip: L10n.of(context)!.select,
), // onPressed: () => onSelect(event),
), // ),
], // ),
), // ],
), // ),
), // ),
), // ),
// ),
// Pangea#
], ],
), ),
), ),

@ -50,11 +50,11 @@ class InputBar extends StatelessWidget {
List<Map<String, String?>> getSuggestions(String text) { List<Map<String, String?>> getSuggestions(String text) {
// #Pangea // #Pangea
final List<Map<String, String?>> ret = <Map<String, String?>>[]; final List<Map<String, String?>> ret = <Map<String, String?>>[];
// if (controller!.selection.baseOffset != if (controller!.selection.baseOffset !=
// controller!.selection.extentOffset || controller!.selection.extentOffset ||
// controller!.selection.baseOffset < 0) { controller!.selection.baseOffset < 0) {
// return []; // no entries if there is selected text return []; // no entries if there is selected text
// } }
// Pangea# // Pangea#
final searchText = final searchText =
controller!.text.substring(0, controller!.selection.baseOffset); controller!.text.substring(0, controller!.selection.baseOffset);

@ -205,7 +205,7 @@ class ChatListItem extends StatelessWidget {
// Future.value(L10n.of(context)!.emptyChat), // Future.value(L10n.of(context)!.emptyChat),
future: room.lastEvent != null future: room.lastEvent != null
? GetChatListItemSubtitle().getSubtitle( ? GetChatListItemSubtitle().getSubtitle(
context, L10n.of(context)!,
room.lastEvent, room.lastEvent,
MatrixState.pangeaController, MatrixState.pangeaController,
) )

@ -81,17 +81,25 @@ class _SpaceViewState extends State<SpaceView> {
nextBatch: null, nextBatch: null,
); );
} }
setState(() {
error = null;
loading = true;
});
// Pangea# // Pangea#
final activeSpaceId = widget.controller.activeSpaceId!; final activeSpaceId = widget.controller.activeSpaceId!;
final client = Matrix.of(context).client; final client = Matrix.of(context).client;
final activeSpace = client.getRoomById(activeSpaceId); final activeSpace = client.getRoomById(activeSpaceId);
await activeSpace?.postLoad(); await activeSpace?.postLoad();
setState(() { // #Pangea
error = null; // setState(() {
loading = true; // error = null;
}); // loading = true;
// });
// Pangea#
try { try {
final response = await client.getSpaceHierarchy( final response = await client.getSpaceHierarchy(

@ -86,6 +86,7 @@ class NewGroupView extends StatelessWidget {
// ), // ),
ConversationBotSettings( ConversationBotSettings(
key: controller.addConversationBotKey, key: controller.addConversationBotKey,
activeSpaceId: controller.activeSpaceId,
), ),
const Divider(height: 1), const Divider(height: 1),
AddToSpaceToggles( AddToSpaceToggles(

@ -52,6 +52,7 @@ class Choreographer {
String? _lastChecked; String? _lastChecked;
ChoreoMode choreoMode = ChoreoMode.igc; ChoreoMode choreoMode = ChoreoMode.igc;
final StreamController stateListener = StreamController(); final StreamController stateListener = StreamController();
StreamSubscription? trialStream;
Choreographer(this.pangeaController, this.chatController) { Choreographer(this.pangeaController, this.chatController) {
_initialize(); _initialize();
@ -64,6 +65,9 @@ class Choreographer {
errorService = ErrorService(this); errorService = ErrorService(this);
altTranslator = AlternativeTranslator(this); altTranslator = AlternativeTranslator(this);
_textController.addListener(_onChangeListener); _textController.addListener(_onChangeListener);
trialStream = pangeaController
.subscriptionController.trialActivationStream.stream
.listen((_) => _onChangeListener);
clear(); clear();
} }
@ -215,7 +219,7 @@ class Choreographer {
if (choreoMode == ChoreoMode.it && if (choreoMode == ChoreoMode.it &&
itController.isTranslationDone && itController.isTranslationDone &&
!tokensOnly) { !tokensOnly) {
debugger(when: kDebugMode); // debugger(when: kDebugMode);
} }
await (choreoMode == ChoreoMode.it && !itController.isTranslationDone await (choreoMode == ChoreoMode.it && !itController.isTranslationDone
@ -414,6 +418,7 @@ class Choreographer {
dispose() { dispose() {
_textController.dispose(); _textController.dispose();
trialStream?.cancel();
} }
LanguageModel? get l2Lang { LanguageModel? get l2Lang {

@ -105,6 +105,7 @@ class ClassController extends BaseController {
} }
Future<void> joinClasswithCode(BuildContext context, String classCode) async { Future<void> joinClasswithCode(BuildContext context, String classCode) async {
try {
final QueryPublicRoomsResponse queryPublicRoomsResponse = final QueryPublicRoomsResponse queryPublicRoomsResponse =
await Matrix.of(context).client.queryPublicRooms( await Matrix.of(context).client.queryPublicRooms(
limit: 1, limit: 1,
@ -118,7 +119,8 @@ class ClassController extends BaseController {
}); });
if (classChunk == null) { if (classChunk == null) {
ClassCodeUtil.messageSnack(context, L10n.of(context)!.unableToFindClass); ClassCodeUtil.messageSnack(
context, L10n.of(context)!.unableToFindClass);
return; return;
} }
@ -135,6 +137,12 @@ class ClassController extends BaseController {
setActiveSpaceIdInChatListController(classChunk.roomId); setActiveSpaceIdInChatListController(classChunk.roomId);
GoogleAnalytics.joinClass(classCode); GoogleAnalytics.joinClass(classCode);
return; return;
} catch (err) {
ClassCodeUtil.messageSnack(
context,
ErrorCopy(context, err).body,
);
}
// P-EPIC // P-EPIC
// prereq - server needs ability to invite to private room. how? // prereq - server needs ability to invite to private room. how?
// does server api have ability with admin token? // does server api have ability with admin token?

@ -33,9 +33,8 @@ enum CanSendStatus {
class SubscriptionController extends BaseController { class SubscriptionController extends BaseController {
late PangeaController _pangeaController; late PangeaController _pangeaController;
SubscriptionInfo? subscription; SubscriptionInfo? subscription;
bool initialized = false;
final StreamController subscriptionStream = StreamController.broadcast(); final StreamController subscriptionStream = StreamController.broadcast();
final StreamController trialActivationStream = StreamController.broadcast();
SubscriptionController(PangeaController pangeaController) : super() { SubscriptionController(PangeaController pangeaController) : super() {
_pangeaController = pangeaController; _pangeaController = pangeaController;
@ -46,7 +45,28 @@ class SubscriptionController extends BaseController {
(subscription!.currentSubscriptionId != null || (subscription!.currentSubscriptionId != null ||
subscription!.currentSubscription != null); subscription!.currentSubscription != null);
bool _isInitializing = false;
Completer<void> initialized = Completer<void>();
Future<void> initialize() async { Future<void> initialize() async {
if (initialized.isCompleted) return;
if (_isInitializing) {
await initialized.future;
return;
}
_isInitializing = true;
await _initialize();
_isInitializing = false;
initialized.complete();
}
Future<void> reinitialize() async {
initialized = Completer<void>();
_isInitializing = false;
await initialize();
}
Future<void> _initialize() async {
try { try {
if (_pangeaController.matrixState.client.userID == null) { if (_pangeaController.matrixState.client.userID == null) {
debugPrint( debugPrint(
@ -64,8 +84,6 @@ class SubscriptionController extends BaseController {
setNewUserTrial(); setNewUserTrial();
} }
initialized = true;
if (!kIsWeb) { if (!kIsWeb) {
Purchases.addCustomerInfoUpdateListener( Purchases.addCustomerInfoUpdateListener(
(CustomerInfo info) async { (CustomerInfo info) async {
@ -177,7 +195,10 @@ class SubscriptionController extends BaseController {
MatrixProfile.activatedFreeTrial.title, MatrixProfile.activatedFreeTrial.title,
true, true,
) )
.then((_) => setNewUserTrial()); .then((_) {
setNewUserTrial();
trialActivationStream.add(true);
});
} }
void setNewUserTrial() { void setNewUserTrial() {
@ -198,6 +219,9 @@ class SubscriptionController extends BaseController {
} }
Future<void> updateCustomerInfo() async { Future<void> updateCustomerInfo() async {
if (!initialized.isCompleted) {
await initialize();
}
if (subscription == null) { if (subscription == null) {
ErrorHandler.logError( ErrorHandler.logError(
m: "Null subscription info in subscription settings", m: "Null subscription info in subscription settings",
@ -234,7 +258,7 @@ class SubscriptionController extends BaseController {
} }
bool get _shouldShowPaywall { bool get _shouldShowPaywall {
return initialized && return initialized.isCompleted &&
!isSubscribed && !isSubscribed &&
(_lastDismissedPaywall == null || (_lastDismissedPaywall == null ||
DateTime.now().difference(_lastDismissedPaywall!).inHours > DateTime.now().difference(_lastDismissedPaywall!).inHours >
@ -265,7 +289,7 @@ class SubscriptionController extends BaseController {
Future<void> showPaywall(BuildContext context) async { Future<void> showPaywall(BuildContext context) async {
try { try {
if (!initialized) { if (!initialized.isCompleted) {
await initialize(); await initialize();
} }
if (subscription?.availableSubscriptions.isEmpty ?? true) { if (subscription?.availableSubscriptions.isEmpty ?? true) {

@ -100,7 +100,6 @@ class PangeaMessageEvent {
BuildContext context, BuildContext context,
) async { ) async {
final String text = (await representationByLanguageGlobal( final String text = (await representationByLanguageGlobal(
context: context,
langCode: langCode, langCode: langCode,
)) ))
?.text ?? ?.text ??
@ -476,7 +475,6 @@ class PangeaMessageEvent {
} }
Future<PangeaRepresentation?> representationByLanguageGlobal({ Future<PangeaRepresentation?> representationByLanguageGlobal({
required BuildContext context,
required String langCode, required String langCode,
}) async { }) async {
// try { // try {

@ -1,15 +1,13 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:fluffychat/pangea/config/environment.dart'; import 'package:fluffychat/pangea/config/environment.dart';
import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; import 'package:fluffychat/pangea/controllers/subscription_controller.dart';
import 'package:fluffychat/pangea/models/base_subscription_info.dart'; import 'package:fluffychat/pangea/models/base_subscription_info.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:flutter/material.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
class MobileSubscriptionInfo extends SubscriptionInfo { class MobileSubscriptionInfo extends SubscriptionInfo {
MobileSubscriptionInfo({required super.pangeaController}) : super(); MobileSubscriptionInfo({required super.pangeaController}) : super();
@ -119,11 +117,11 @@ class MobileSubscriptionInfo extends SubscriptionInfo {
Future<void> setCustomerInfo() async { Future<void> setCustomerInfo() async {
if (allProducts == null) { if (allProducts == null) {
ErrorHandler.logError( ErrorHandler.logError(
m: "Null appProducts in setCustomerInfo", m: "Null allProducts in setCustomerInfo",
s: StackTrace.current, s: StackTrace.current,
); );
debugPrint( debugPrint(
"Null appProducts in setCustomerInfo", "Null allProducts in setCustomerInfo",
); );
return; return;
} }

@ -30,7 +30,7 @@ class SubscriptionManagementController extends State<SubscriptionManagement> {
@override @override
void initState() { void initState() {
if (!subscriptionController.initialized) { if (!subscriptionController.initialized.isCompleted) {
subscriptionController.initialize().then((_) => setState(() {})); subscriptionController.initialize().then((_) => setState(() {}));
} }

@ -1,7 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -35,18 +34,10 @@ class ClassCodeUtil {
], ],
); );
if (classCode == null || classCode.single.isEmpty) return; if (classCode == null || classCode.single.isEmpty) return;
try {
await pangeaController.classController.joinClasswithCode( await pangeaController.classController.joinClasswithCode(
context, context,
classCode.first, classCode.first,
); );
} catch (err) {
messageSnack(
context,
ErrorCopy(context, err).body,
);
}
} }
static messageDialog( static messageDialog(

@ -4,7 +4,6 @@ import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/models/class_model.dart'; import 'package:fluffychat/pangea/models/class_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
@ -12,16 +11,17 @@ import '../../utils/matrix_sdk_extensions/matrix_locals.dart';
class GetChatListItemSubtitle { class GetChatListItemSubtitle {
Future<String> getSubtitle( Future<String> getSubtitle(
BuildContext context, L10n l10n,
Event? event, Event? event,
PangeaController pangeaController, PangeaController pangeaController,
) async { ) async {
if (event == null) return L10n.of(context)!.emptyChat; if (event == null) return l10n.emptyChat;
try { try {
String? eventContextId = event.eventId; String? eventContextId = event.eventId;
if (!event.eventId.isValidMatrixId || event.eventId.sigil != '\$') { if (!event.eventId.isValidMatrixId || event.eventId.sigil != '\$') {
eventContextId = null; eventContextId = null;
} }
final Timeline timeline = final Timeline timeline =
await event.room.getTimeline(eventContextId: eventContextId); await event.room.getTimeline(eventContextId: eventContextId);
@ -47,7 +47,7 @@ class GetChatListItemSubtitle {
!pangeaController.permissionsController !pangeaController.permissionsController
.isToolEnabled(ToolSetting.immersionMode, event.room)) { .isToolEnabled(ToolSetting.immersionMode, event.room)) {
return event.calcLocalizedBody( return event.calcLocalizedBody(
MatrixLocals(L10n.of(context)!), MatrixLocals(l10n),
hideReply: true, hideReply: true,
hideEdit: true, hideEdit: true,
plaintextBody: true, plaintextBody: true,
@ -71,14 +71,13 @@ class GetChatListItemSubtitle {
final String? text = final String? text =
(await pangeaMessageEvent.representationByLanguageGlobal( (await pangeaMessageEvent.representationByLanguageGlobal(
context: context,
langCode: l2Code, langCode: l2Code,
)) ))
?.text; ?.text;
final i18n = MatrixLocals(L10n.of(context)!); final i18n = MatrixLocals(l10n);
if (text == null) return L10n.of(context)!.emptyChat; if (text == null) return l10n.emptyChat;
if (!event.room.isDirectChat || if (!event.room.isDirectChat ||
event.room.directChatMatrixID != event.room.lastEvent?.senderId) { event.room.directChatMatrixID != event.room.lastEvent?.senderId) {
@ -95,7 +94,7 @@ class GetChatListItemSubtitle {
} catch (e, s) { } catch (e, s) {
// debugger(when: kDebugMode); // debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s); ErrorHandler.logError(e: e, s: s);
return event?.body ?? L10n.of(context)!.emptyChat; return event?.body ?? l10n.emptyChat;
} }
} }
} }

@ -283,8 +283,13 @@ class MessageToolbarState extends State<MessageToolbar> {
widget.textSelection.selectionStream.stream.listen((value) { widget.textSelection.selectionStream.stream.listen((value) {
timer?.cancel(); timer?.cancel();
timer = Timer(const Duration(milliseconds: 500), () { timer = Timer(const Duration(milliseconds: 500), () {
if (currentMode != null || value != null && value.isNotEmpty) { if (value != null && value.isNotEmpty) {
updateMode(currentMode ?? MessageMode.translation); final MessageMode newMode = currentMode == MessageMode.definition
? MessageMode.definition
: MessageMode.translation;
updateMode(newMode);
} else if (currentMode != null) {
updateMode(currentMode!);
} }
}); });
}); });

@ -52,7 +52,6 @@ class MessageTranslationCardState extends State<MessageTranslationCard> {
if (repEvent == null && mounted) { if (repEvent == null && mounted) {
repEvent = await widget.messageEvent.representationByLanguageGlobal( repEvent = await widget.messageEvent.representationByLanguageGlobal(
context: context,
langCode: langCode, langCode: langCode,
); );
} }

@ -34,7 +34,6 @@ class MessageUnsubscribedCard extends StatelessWidget {
MatrixState.pangeaController.subscriptionController MatrixState.pangeaController.subscriptionController
.showPaywall(context); .showPaywall(context);
} }
MatrixState.pAnyState.closeOverlay();
} }
return Column( return Column(

@ -72,7 +72,7 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
final activeSpace = final activeSpace =
Matrix.of(context).client.getRoomById(widget.activeSpaceId!); Matrix.of(context).client.getRoomById(widget.activeSpaceId!);
if (activeSpace != null && activeSpace.canIAddSpaceChild(null)) { if (activeSpace != null && activeSpace.canIAddSpaceChild(null)) {
parents.add(SuggestionStatus(false, activeSpace)); parents.add(SuggestionStatus(true, activeSpace));
} else { } else {
ErrorHandler.logError( ErrorHandler.logError(
e: Exception('activeSpaceId ${widget.activeSpaceId} not found'), e: Exception('activeSpaceId ${widget.activeSpaceId} not found'),
@ -111,12 +111,13 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
} }
} }
Future<void> _addSingleSpace(String roomToAddId, Room newParent) { Future<void> _addSingleSpace(String roomToAddId, Room newParent) async {
GoogleAnalytics.addParent(roomToAddId, newParent.classCode); GoogleAnalytics.addParent(roomToAddId, newParent.classCode);
return newParent.setSpaceChild( await newParent.setSpaceChild(
roomToAddId, roomToAddId,
suggested: isSuggestedInSpace(newParent), suggested: isSuggestedInSpace(newParent),
); );
await setSuggested(true, newParent);
} }
Future<void> addSpaces(String roomToAddId) async { Future<void> addSpaces(String roomToAddId) async {
@ -147,7 +148,7 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
setState( setState(
() => add () => add
? parents.add(SuggestionStatus(false, possibleParent)) ? parents.add(SuggestionStatus(true, possibleParent))
: parents.removeWhere( : parents.removeWhere(
(suggestionStatus) => (suggestionStatus) =>
suggestionStatus.room.id == possibleParent.id, suggestionStatus.room.id == possibleParent.id,

@ -1,14 +1,11 @@
import 'package:fluffychat/pangea/constants/url_query_parameter_keys.dart'; import 'package:fluffychat/pangea/constants/url_query_parameter_keys.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/utils/class_code.dart';
import 'package:fluffychat/widgets/layouts/empty_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import '../../../widgets/matrix.dart'; import '../../../widgets/matrix.dart';
import '../../constants/local.key.dart'; import '../../constants/local.key.dart';
import '../../utils/error_handler.dart';
//if on home with classcode in url and not logged in, then save it soemhow and after llogin, join class automatically //if on home with classcode in url and not logged in, then save it soemhow and after llogin, join class automatically
//if on home with classcode in url and logged in, then join class automatically //if on home with classcode in url and logged in, then join class automatically
@ -28,22 +25,21 @@ class _JoinClassWithLinkState extends State<JoinClassWithLink> {
void initState() { void initState() {
super.initState(); super.initState();
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () async {
classCode = GoRouterState.of(context) classCode = GoRouterState.of(context)
.uri .uri
.queryParameters[UrlQueryParameterKeys.classCode]; .queryParameters[UrlQueryParameterKeys.classCode];
if (classCode == null) { if (classCode == null) {
return ClassCodeUtil.messageDialog( Sentry.addBreadcrumb(
context, Breadcrumb(
L10n.of(context)!.unableToFindClassCode, message:
() => context.go("/rooms"), "Navigated to join_with_link without class code query parameter",
),
); );
return;
} }
if (!Matrix.of(context).client.isLogged()) {
return ClassCodeUtil.messageDialog(
context, L10n.of(context)!.pleaseLoginFirst, () async {
await _pangeaController.pStoreService.save( await _pangeaController.pStoreService.save(
PLocalKey.cachedClassCodeToJoin, PLocalKey.cachedClassCodeToJoin,
classCode, classCode,
@ -54,23 +50,6 @@ class _JoinClassWithLinkState extends State<JoinClassWithLink> {
}); });
} }
_pangeaController.classController
.joinClasswithCode(
context,
classCode!,
)
.onError(
(error, stackTrace) => ClassCodeUtil.messageSnack(
context,
ErrorCopy(context, error).body,
),
)
.whenComplete(
() => context.go("/rooms"),
);
});
}
@override @override
Widget build(BuildContext context) => const EmptyPage(); Widget build(BuildContext context) => const SizedBox();
} }

@ -20,12 +20,14 @@ import '../../utils/error_handler.dart';
class ConversationBotSettings extends StatefulWidget { class ConversationBotSettings extends StatefulWidget {
final Room? room; final Room? room;
final bool startOpen; final bool startOpen;
final String? activeSpaceId;
// final ClassSettingsModel? initialSettings; // final ClassSettingsModel? initialSettings;
const ConversationBotSettings({ const ConversationBotSettings({
super.key, super.key,
this.room, this.room,
this.startOpen = false, this.startOpen = false,
this.activeSpaceId,
// this.initialSettings, // this.initialSettings,
}); });
@ -37,6 +39,7 @@ class ConversationBotSettingsState extends State<ConversationBotSettings> {
late BotOptionsModel botOptions; late BotOptionsModel botOptions;
late bool isOpen; late bool isOpen;
bool addBot = false; bool addBot = false;
Room? parentSpace;
ConversationBotSettingsState({Key? key}); ConversationBotSettingsState({Key? key});
@ -50,6 +53,12 @@ class ConversationBotSettingsState extends State<ConversationBotSettings> {
addBot = isBotRoom; addBot = isBotRoom;
}); });
}); });
parentSpace = widget.activeSpaceId != null
? Matrix.of(context).client.getRoomById(widget.activeSpaceId!)
: null;
if (parentSpace != null && botOptions.languageLevel == null) {
botOptions.languageLevel = parentSpace?.classSettings?.languageLevel;
}
} }
Future<void> updateBotOption(void Function() makeLocalChange) async { Future<void> updateBotOption(void Function() makeLocalChange) async {

@ -87,7 +87,6 @@ class PangeaRichTextState extends State<PangeaRichText> {
widget.pangeaMessageEvent widget.pangeaMessageEvent
.representationByLanguageGlobal( .representationByLanguageGlobal(
context: context,
langCode: widget.pangeaMessageEvent.messageDisplayLangCode, langCode: widget.pangeaMessageEvent.messageDisplayLangCode,
) )
.onError( .onError(

@ -77,9 +77,9 @@ class SpanCardState extends State<SpanCard> {
if (mounted) { if (mounted) {
setState(() => fetchingData = false); setState(() => fetchingData = false);
} }
} catch (e) { } catch (e, s) {
// debugger(when: kDebugMode); // debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: StackTrace.current); ErrorHandler.logError(e: e, s: s);
if (mounted) { if (mounted) {
setState(() { setState(() {
error = e; error = e;

@ -344,6 +344,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
// #Pangea // #Pangea
if (state == LoginState.loggedIn) { if (state == LoginState.loggedIn) {
await (await pangeaController.userController.completer).future; await (await pangeaController.userController.completer).future;
await pangeaController.subscriptionController.reinitialize();
} }
String routeDestination; String routeDestination;
if (state == LoginState.loggedIn) { if (state == LoginState.loggedIn) {

Loading…
Cancel
Save