Merge pull request #948 from pangeachat/sentry
reset room in startBotChat function after waiting for it in sync
This commit is contained in:
commit
2d2f063ba9
9 changed files with 91 additions and 74 deletions
|
|
@ -7,7 +7,6 @@ import 'package:fluffychat/config/themes.dart';
|
|||
import 'package:fluffychat/pages/chat/send_file_dialog.dart';
|
||||
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
|
||||
import 'package:fluffychat/pangea/constants/pangea_room_types.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart';
|
||||
|
|
@ -1016,7 +1015,7 @@ class ChatListController extends State<ChatList>
|
|||
}
|
||||
|
||||
// #Pangea
|
||||
await _initPangeaControllers(client);
|
||||
_initPangeaControllers(client);
|
||||
// Pangea#
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
|
|
@ -1025,22 +1024,12 @@ class ChatListController extends State<ChatList>
|
|||
}
|
||||
|
||||
// #Pangea
|
||||
Future<void> _initPangeaControllers(Client client) async {
|
||||
MatrixState.pangeaController.putAnalytics.initialize();
|
||||
MatrixState.pangeaController.getAnalytics.initialize();
|
||||
void _initPangeaControllers(Client client) {
|
||||
GoogleAnalytics.analyticsUserUpdate(client.userID);
|
||||
client.migrateAnalyticsRooms();
|
||||
MatrixState.pangeaController.initControllers();
|
||||
if (mounted) {
|
||||
final PangeaController pangeaController = MatrixState.pangeaController;
|
||||
GoogleAnalytics.analyticsUserUpdate(client.userID);
|
||||
pangeaController.startChatWithBotIfNotPresent();
|
||||
await pangeaController.subscriptionController.initialize();
|
||||
pangeaController.afterSyncAndFirstLoginInitialization(context);
|
||||
await pangeaController.inviteBotToExistingSpaces();
|
||||
await pangeaController.setPangeaPushRules();
|
||||
client.migrateAnalyticsRooms();
|
||||
} else {
|
||||
ErrorHandler.logError(
|
||||
m: "didn't run afterSyncAndFirstLoginInitialization because not mounted",
|
||||
);
|
||||
MatrixState.pangeaController.classController.joinCachedSpaceCode(context);
|
||||
}
|
||||
}
|
||||
// Pangea#
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class ClassController extends BaseController {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> checkForClassCodeAndSubscription(BuildContext context) async {
|
||||
Future<void> joinCachedSpaceCode(BuildContext context) async {
|
||||
final String? classCode = _pangeaController.pStoreService.read(
|
||||
PLocalKey.cachedClassCodeToJoin,
|
||||
isAccountData: false,
|
||||
|
|
@ -53,6 +53,7 @@ class ClassController extends BaseController {
|
|||
context,
|
||||
classCode,
|
||||
);
|
||||
|
||||
await _pangeaController.pStoreService.delete(
|
||||
PLocalKey.cachedClassCodeToJoin,
|
||||
isAccountData: false,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class GetAnalyticsController {
|
|||
StreamController.broadcast();
|
||||
|
||||
ConstructListModel constructListModel = ConstructListModel(uses: []);
|
||||
Completer<void>? initCompleter;
|
||||
|
||||
GetAnalyticsController(PangeaController pangeaController) {
|
||||
_pangeaController = pangeaController;
|
||||
|
|
@ -34,13 +35,19 @@ class GetAnalyticsController {
|
|||
Client get _client => _pangeaController.matrixState.client;
|
||||
|
||||
// the minimum XP required for a given level
|
||||
double get _minXPForLevel {
|
||||
return 12.5 * (2 * pow(constructListModel.level - 1, 2) - 1);
|
||||
int get _minXPForLevel {
|
||||
return _calculateMinXpForLevel(constructListModel.level);
|
||||
}
|
||||
|
||||
// the minimum XP required for the next level
|
||||
double get _minXPForNextLevel {
|
||||
return 12.5 * (2 * pow(constructListModel.level, 2) - 1);
|
||||
int get _minXPForNextLevel {
|
||||
return _calculateMinXpForLevel(constructListModel.level + 1);
|
||||
}
|
||||
|
||||
/// Calculates the minimum XP required for a specific level.
|
||||
int _calculateMinXpForLevel(int level) {
|
||||
if (level == 1) return 0; // Ensure level 1 starts at 0 XP
|
||||
return ((100 / 8) * (2 * pow(level - 1, 2))).floor();
|
||||
}
|
||||
|
||||
// the progress within the current level as a percentage (0.0 to 1.0)
|
||||
|
|
@ -50,20 +57,23 @@ class GetAnalyticsController {
|
|||
return progress >= 0 ? progress : 0;
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
Future<void> initialize() async {
|
||||
if (initCompleter != null) return;
|
||||
initCompleter = Completer<void>();
|
||||
|
||||
_analyticsUpdateSubscription ??= _pangeaController
|
||||
.putAnalytics.analyticsUpdateStream.stream
|
||||
.listen(_onAnalyticsUpdate);
|
||||
|
||||
_pangeaController.putAnalytics.lastUpdatedCompleter.future.then((_) {
|
||||
_getConstructs().then((_) {
|
||||
constructListModel.updateConstructs([
|
||||
...(_getConstructsLocal() ?? []),
|
||||
..._locallyCachedConstructs,
|
||||
]);
|
||||
_updateAnalyticsStream();
|
||||
});
|
||||
});
|
||||
await _pangeaController.putAnalytics.lastUpdatedCompleter.future;
|
||||
await _getConstructs();
|
||||
constructListModel.updateConstructs([
|
||||
...(_getConstructsLocal() ?? []),
|
||||
..._locallyCachedConstructs,
|
||||
]);
|
||||
_updateAnalyticsStream();
|
||||
|
||||
initCompleter!.complete();
|
||||
}
|
||||
|
||||
/// Clear all cached analytics data.
|
||||
|
|
@ -71,6 +81,7 @@ class GetAnalyticsController {
|
|||
constructListModel.dispose();
|
||||
_analyticsUpdateSubscription?.cancel();
|
||||
_analyticsUpdateSubscription = null;
|
||||
initCompleter = null;
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import 'package:fluffychat/pangea/utils/bot_name.dart';
|
|||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/instructions.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
|
@ -80,11 +79,19 @@ class PangeaController {
|
|||
_addRefInObjects();
|
||||
}
|
||||
|
||||
Future<void> afterSyncAndFirstLoginInitialization(
|
||||
BuildContext context,
|
||||
) async {
|
||||
await classController.checkForClassCodeAndSubscription(context);
|
||||
/// Initializes various controllers and settings.
|
||||
/// While many of these functions are asynchronous, they are not awaited here,
|
||||
/// because of order of execution does not matter,
|
||||
/// and running them at the same times speeds them up.
|
||||
void initControllers() {
|
||||
putAnalytics.initialize();
|
||||
getAnalytics.initialize();
|
||||
subscriptionController.initialize();
|
||||
classController.fixClassPowerLevels();
|
||||
|
||||
startChatWithBotIfNotPresent();
|
||||
inviteBotToExistingSpaces();
|
||||
setPangeaPushRules();
|
||||
}
|
||||
|
||||
/// Initialize controllers
|
||||
|
|
@ -243,13 +250,23 @@ class PangeaController {
|
|||
],
|
||||
);
|
||||
|
||||
final room = matrixState.client.getRoomById(roomId);
|
||||
Room? 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);
|
||||
room = matrixState.client.getRoomById(roomId);
|
||||
if (room == null) {
|
||||
ErrorHandler.logError(
|
||||
e: "Bot chat null after waiting for room in sync",
|
||||
data: {
|
||||
"roomId": roomId,
|
||||
},
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final botOptions = room!.getState(PangeaEventTypes.botOptions);
|
||||
final botOptions = room.getState(PangeaEventTypes.botOptions);
|
||||
if (botOptions == null) {
|
||||
await matrixState.client.setRoomStateWithKey(
|
||||
roomId,
|
||||
|
|
@ -277,7 +294,10 @@ class PangeaController {
|
|||
}
|
||||
|
||||
final Room botDMWithLatestActivity = botDMs.reduce((a, b) {
|
||||
if (a.timeline == null || b.timeline == null) {
|
||||
if (a.timeline == null ||
|
||||
b.timeline == null ||
|
||||
a.timeline!.events.isEmpty ||
|
||||
b.timeline!.events.isEmpty) {
|
||||
return a;
|
||||
}
|
||||
final aLastEvent = a.timeline!.events.last;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _onUpdateLanguages(String previousL2) async {
|
||||
Future<void> _onUpdateLanguages(String? previousL2) async {
|
||||
await sendLocalAnalyticsToAnalyticsRoom(
|
||||
l2Override: previousL2,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -137,11 +137,11 @@ class SignupPageController extends State<SignupPage> {
|
|||
displayname,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, s) {
|
||||
//#Pangea
|
||||
const cancelledString = "Exception: Request has been canceled";
|
||||
if (e.toString() != cancelledString) {
|
||||
ErrorHandler.logError(e: e);
|
||||
ErrorHandler.logError(e: e, s: s);
|
||||
error = (e).toLocalizedString(context);
|
||||
}
|
||||
// Pangea#
|
||||
|
|
|
|||
|
|
@ -41,13 +41,8 @@ Future<void> downloadChat(
|
|||
timeline,
|
||||
room,
|
||||
);
|
||||
} catch (err) {
|
||||
ErrorHandler.logError(
|
||||
e: Exception(
|
||||
"Failed to fetch messages for chat ${room.id} in while downloading chat",
|
||||
),
|
||||
s: StackTrace.current,
|
||||
);
|
||||
} catch (err, s) {
|
||||
ErrorHandler.logError(e: err, s: s);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
|
|
@ -214,12 +209,9 @@ Future<void> downloadFile(
|
|||
directory = await getExternalStorageDirectory();
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err, s) {
|
||||
debugPrint("Failed to get download folder path");
|
||||
ErrorHandler.logError(
|
||||
e: Exception("Failed to get download folder path"),
|
||||
s: StackTrace.current,
|
||||
);
|
||||
ErrorHandler.logError(e: err, s: s);
|
||||
}
|
||||
if (directory != null) {
|
||||
final File f = File("${directory.path}/$filename");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
|
||||
|
|
@ -24,26 +23,24 @@ class OverlayMessageText extends StatefulWidget {
|
|||
}
|
||||
|
||||
class OverlayMessageTextState extends State<OverlayMessageText> {
|
||||
final PangeaController pangeaController = MatrixState.pangeaController;
|
||||
List<PangeaToken>? tokens;
|
||||
List<PangeaToken>? _tokens;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_setTokens();
|
||||
}
|
||||
|
||||
Future<void> _setTokens() async {
|
||||
final repEvent = widget.pangeaMessageEvent.messageDisplayRepresentation;
|
||||
if (repEvent != null) {
|
||||
tokens = repEvent.tokens;
|
||||
if (tokens == null) {
|
||||
repEvent
|
||||
.tokensGlobal(
|
||||
widget.pangeaMessageEvent.senderId,
|
||||
widget.pangeaMessageEvent.originServerTs,
|
||||
)
|
||||
.then((tokens) {
|
||||
setState(() => this.tokens = tokens);
|
||||
});
|
||||
}
|
||||
_tokens = repEvent.tokens;
|
||||
_tokens ??= await repEvent.tokensGlobal(
|
||||
widget.pangeaMessageEvent.senderId,
|
||||
widget.pangeaMessageEvent.originServerTs,
|
||||
);
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -60,7 +57,7 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
|
|||
fontSize: AppConfig.messageFontSize * AppConfig.fontSizeFactor,
|
||||
);
|
||||
|
||||
if (tokens == null || tokens!.isEmpty) {
|
||||
if (_tokens == null || _tokens!.isEmpty) {
|
||||
return Text(
|
||||
widget.pangeaMessageEvent.event.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
|
|
@ -83,8 +80,8 @@ class OverlayMessageTextState extends State<OverlayMessageText> {
|
|||
final List<TokenPosition> tokenPositions = [];
|
||||
int globalIndex = 0;
|
||||
|
||||
for (int i = 0; i < tokens!.length; i++) {
|
||||
final token = tokens![i];
|
||||
for (int i = 0; i < _tokens!.length; i++) {
|
||||
final token = _tokens![i];
|
||||
final start = token.start;
|
||||
final end = token.end;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ class LearningProgressIndicatorsState
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// if getAnalytics has already finished initializing,
|
||||
// the data is loaded and should be displayed.
|
||||
if (MatrixState.pangeaController.getAnalytics.initCompleter?.isCompleted ??
|
||||
false) {
|
||||
updateData(null);
|
||||
}
|
||||
_analyticsSubscription = MatrixState
|
||||
.pangeaController.getAnalytics.analyticsStream.stream
|
||||
.listen(updateData);
|
||||
|
|
@ -48,7 +55,7 @@ class LearningProgressIndicatorsState
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
void updateData(AnalyticsStreamUpdate _) {
|
||||
void updateData(AnalyticsStreamUpdate? _) {
|
||||
if (_loading) _loading = false;
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue