added logic for auto-starting round on bot message
This commit is contained in:
parent
ea1c1a6840
commit
ac6ddc6d0e
3 changed files with 46 additions and 80 deletions
|
|
@ -21,6 +21,7 @@ import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dar
|
|||
import 'package:fluffychat/pangea/models/choreo_record.dart';
|
||||
import 'package:fluffychat/pangea/models/representation_content_model.dart';
|
||||
import 'package:fluffychat/pangea/models/tokens_event_content_model.dart';
|
||||
import 'package:fluffychat/pangea/pages/games/story_game/round_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
||||
import 'package:fluffychat/pangea/utils/report_message.dart';
|
||||
|
|
@ -112,9 +113,10 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
with WidgetsBindingObserver {
|
||||
// #Pangea
|
||||
final PangeaController pangeaController = MatrixState.pangeaController;
|
||||
|
||||
late Choreographer choreographer = Choreographer(pangeaController, this);
|
||||
final List<GameRoundModel> gameRounds = [];
|
||||
// Pangea#
|
||||
|
||||
Room get room => sendingClient.getRoomById(roomId) ?? widget.room;
|
||||
|
||||
late Client sendingClient;
|
||||
|
|
@ -309,6 +311,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
sendingClient = Matrix.of(context).client;
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
// #Pangea
|
||||
gameRounds.add(GameRoundModel(controller: this));
|
||||
if (!mounted) return;
|
||||
Future.delayed(const Duration(seconds: 1), () async {
|
||||
if (!mounted) return;
|
||||
|
|
@ -533,6 +536,9 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
//#Pangea
|
||||
choreographer.stateListener.close();
|
||||
choreographer.dispose();
|
||||
for (final round in gameRounds) {
|
||||
round.timer?.cancel();
|
||||
}
|
||||
//Pangea#
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,85 +1,26 @@
|
|||
import 'package:fluffychat/pangea/utils/bot_name.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
extension MembershipUpdate on SyncUpdate {
|
||||
bool isMembershipUpdate(String userId) {
|
||||
return isMembershipUpdateByType(Membership.join, userId) ||
|
||||
isMembershipUpdateByType(Membership.leave, userId) ||
|
||||
isMembershipUpdateByType(Membership.invite, userId);
|
||||
}
|
||||
|
||||
bool isMembershipUpdateByType(Membership type, String userId) {
|
||||
final List<SyncRoomUpdate>? updates = getRoomUpdates(type);
|
||||
if (updates?.isEmpty ?? true) {
|
||||
return false;
|
||||
List<String> botMessages(String roomID) {
|
||||
if (rooms?.join == null ||
|
||||
!rooms!.join!.containsKey(roomID) ||
|
||||
rooms!.join![roomID]!.timeline?.events == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
for (final SyncRoomUpdate update in updates!) {
|
||||
final List<dynamic>? events = getRoomUpdateEvents(type, update);
|
||||
if (hasMembershipUpdate(
|
||||
events,
|
||||
type.name,
|
||||
userId,
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
final messageEvents = rooms!.join![roomID]!.timeline!.events!
|
||||
.where(
|
||||
(event) => event.type == EventTypes.Message,
|
||||
)
|
||||
.toList();
|
||||
if (messageEvents.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
List<SyncRoomUpdate>? getRoomUpdates(Membership type) {
|
||||
switch (type) {
|
||||
case Membership.join:
|
||||
return rooms?.join?.values.toList();
|
||||
case Membership.leave:
|
||||
return rooms?.leave?.values.toList();
|
||||
case Membership.invite:
|
||||
return rooms?.invite?.values.toList();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool isSpaceChildUpdate(String activeSpaceId) {
|
||||
if (rooms?.join?.isEmpty ?? true) {
|
||||
return false;
|
||||
}
|
||||
for (final update in rooms!.join!.entries) {
|
||||
final String spaceId = update.key;
|
||||
final List<MatrixEvent>? timelineEvents = update.value.timeline?.events;
|
||||
final bool isUpdate = timelineEvents != null &&
|
||||
spaceId == activeSpaceId &&
|
||||
timelineEvents.any((event) => event.type == EventTypes.SpaceChild);
|
||||
if (isUpdate) return true;
|
||||
}
|
||||
return false;
|
||||
return messageEvents
|
||||
.where((event) => event.senderId == BotName.byEnvironment)
|
||||
.map((event) => event.eventId)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic>? getRoomUpdateEvents(Membership type, SyncRoomUpdate update) {
|
||||
switch (type) {
|
||||
case Membership.join:
|
||||
return (update as JoinedRoomUpdate).timeline?.events;
|
||||
case Membership.leave:
|
||||
return (update as LeftRoomUpdate).timeline?.events;
|
||||
case Membership.invite:
|
||||
return (update as InvitedRoomUpdate).inviteState;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasMembershipUpdate(
|
||||
List<dynamic>? events,
|
||||
String membershipType,
|
||||
String userId,
|
||||
) {
|
||||
if (events == null) {
|
||||
return false;
|
||||
}
|
||||
return events.any(
|
||||
(event) =>
|
||||
event.type == EventTypes.RoomMember &&
|
||||
event.stateKey == userId &&
|
||||
event.content['membership'] == membershipType,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,47 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
import 'package:fluffychat/pangea/extensions/sync_update_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
enum RoundState { notStarted, inProgress, completed }
|
||||
|
||||
class GameRoundModel {
|
||||
static const Duration roundLength = Duration(minutes: 3);
|
||||
|
||||
final ChatController controller;
|
||||
Timer? timer;
|
||||
DateTime? startTime;
|
||||
DateTime? endTime;
|
||||
RoundState state = RoundState.notStarted;
|
||||
|
||||
GameRoundModel() {
|
||||
timer = Timer(roundLength, () => endRound());
|
||||
startTime = DateTime.now();
|
||||
final Set<String> messageIDs = {};
|
||||
|
||||
GameRoundModel({
|
||||
required this.controller,
|
||||
}) {
|
||||
client.onSync.stream.firstWhere((update) {
|
||||
final botEventIDs = update.botMessages(controller.roomId);
|
||||
return botEventIDs.isNotEmpty;
|
||||
}).then((_) => startRound());
|
||||
}
|
||||
|
||||
Client get client => controller.pangeaController.matrixState.client;
|
||||
|
||||
void startRound() {
|
||||
debugPrint("starting round");
|
||||
state = RoundState.inProgress;
|
||||
startTime = DateTime.now();
|
||||
timer = Timer(roundLength, () => endRound());
|
||||
}
|
||||
|
||||
void endRound() {
|
||||
debugPrint("ending round");
|
||||
endTime = DateTime.now();
|
||||
state = RoundState.completed;
|
||||
timer?.cancel();
|
||||
}
|
||||
|
||||
void dispose() {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue