Merge pull request #619 from pangeachat/revert-574-story-game

Revert "Story game"
pull/1384/head
ggurdin 1 year ago committed by GitHub
commit b22c451cc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -21,12 +21,10 @@ import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dar
import 'package:fluffychat/pangea/models/choreo_record.dart'; import 'package:fluffychat/pangea/models/choreo_record.dart';
import 'package:fluffychat/pangea/models/representation_content_model.dart'; import 'package:fluffychat/pangea/models/representation_content_model.dart';
import 'package:fluffychat/pangea/models/tokens_event_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/error_handler.dart';
import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
import 'package:fluffychat/pangea/utils/report_message.dart'; import 'package:fluffychat/pangea/utils/report_message.dart';
import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart'; import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
import 'package:fluffychat/pangea/widgets/chat/round_timer.dart';
import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart'; import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart';
import 'package:fluffychat/utils/error_reporter.dart'; import 'package:fluffychat/utils/error_reporter.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
@ -114,20 +112,9 @@ class ChatController extends State<ChatPageWithRoom>
with WidgetsBindingObserver { with WidgetsBindingObserver {
// #Pangea // #Pangea
final PangeaController pangeaController = MatrixState.pangeaController; final PangeaController pangeaController = MatrixState.pangeaController;
late Choreographer choreographer = Choreographer(pangeaController, this);
final GlobalKey<RoundTimerState> roundTimerStateKey =
GlobalKey<RoundTimerState>();
RoundTimer? timer;
final List<GameRoundModel> gameRounds = [];
List<String> get completedRoundEventIds => gameRounds late Choreographer choreographer = Choreographer(pangeaController, this);
.where((round) => round.isCompleted)
.map((round) => round.messageIDs)
.expand((x) => x)
.toList();
// Pangea# // Pangea#
Room get room => sendingClient.getRoomById(roomId) ?? widget.room; Room get room => sendingClient.getRoomById(roomId) ?? widget.room;
late Client sendingClient; late Client sendingClient;
@ -307,17 +294,6 @@ class ChatController extends State<ChatPageWithRoom>
} }
} }
// #Pangea
void addRound() {
debugPrint("ADDING A ROUND. Rounds so far: ${gameRounds.length}");
final newRound = GameRoundModel(controller: this, timer: timer!);
gameRounds.add(newRound);
newRound.roundCompleter.future.then((_) {
if (mounted) addRound();
});
}
// Pangea#
@override @override
void initState() { void initState() {
scrollController.addListener(_updateScrollController); scrollController.addListener(_updateScrollController);
@ -333,8 +309,6 @@ class ChatController extends State<ChatPageWithRoom>
sendingClient = Matrix.of(context).client; sendingClient = Matrix.of(context).client;
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
// #Pangea // #Pangea
timer = RoundTimer(key: roundTimerStateKey);
addRound();
if (!mounted) return; if (!mounted) return;
Future.delayed(const Duration(seconds: 1), () async { Future.delayed(const Duration(seconds: 1), () async {
if (!mounted) return; if (!mounted) return;
@ -421,8 +395,7 @@ class ChatController extends State<ChatPageWithRoom>
List<Event> get visibleEvents => List<Event> get visibleEvents =>
timeline?.events timeline?.events
.where( .where(
(x) => (x) => x.isVisibleInGui,
x.isVisibleInGui && !completedRoundEventIds.contains(x.eventId),
) )
.toList() ?? .toList() ??
<Event>[]; <Event>[];

@ -27,15 +27,7 @@ class ChatEventList extends StatelessWidget {
final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0; final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0;
final events = controller.timeline!.events final events = controller.timeline!.events
.where( .where((event) => event.isVisibleInGui)
(event) =>
event.isVisibleInGui
// #Pangea
&&
!controller.completedRoundEventIds.contains(event.eventId)
// Pangea#
,
)
.toList(); .toList();
final animateInEventIndex = controller.animateInEventIndex; final animateInEventIndex = controller.animateInEventIndex;

@ -13,7 +13,6 @@ import 'package:fluffychat/pangea/choreographer/widgets/it_bar.dart';
import 'package:fluffychat/pangea/choreographer/widgets/start_igc_button.dart'; import 'package:fluffychat/pangea/choreographer/widgets/start_igc_button.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/widgets/chat/chat_floating_action_button.dart'; import 'package:fluffychat/pangea/widgets/chat/chat_floating_action_button.dart';
import 'package:fluffychat/pangea/widgets/chat/round_timer.dart';
import 'package:fluffychat/utils/account_config.dart'; import 'package:fluffychat/utils/account_config.dart';
import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart';
import 'package:fluffychat/widgets/connection_status_header.dart'; import 'package:fluffychat/widgets/connection_status_header.dart';
@ -120,10 +119,6 @@ class ChatView extends StatelessWidget {
// #Pangea // #Pangea
} else { } else {
return [ return [
controller.timer ?? const SizedBox(),
const SizedBox(
width: 10,
),
ChatSettingsPopupMenu( ChatSettingsPopupMenu(
controller.room, controller.room,
(!controller.room.isDirectChat && !controller.room.isArchived), (!controller.room.isDirectChat && !controller.room.isArchived),

@ -1,12 +1,14 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
extension EventInfoDialogExtension on Event { extension EventInfoDialogExtension on Event {
void showInfoDialog(BuildContext context) => showAdaptiveBottomSheet( void showInfoDialog(BuildContext context) => showAdaptiveBottomSheet(
@ -47,16 +49,15 @@ class EventInfoDialog extends StatelessWidget {
children: [ children: [
ListTile( ListTile(
leading: Avatar( leading: Avatar(
// mxContent: event.senderFromMemoryOrFallback.avatarUrl, mxContent: event.senderFromMemoryOrFallback.avatarUrl,
// name: event.senderFromMemoryOrFallback.calcDisplayname(), name: event.senderFromMemoryOrFallback.calcDisplayname(),
name: "?",
client: event.room.client, client: event.room.client,
// presenceUserId: event.senderId, presenceUserId: event.senderId,
), ),
title: Text(L10n.of(context)!.sender), title: Text(L10n.of(context)!.sender),
// subtitle: Text( subtitle: Text(
// '${event.senderFromMemoryOrFallback.calcDisplayname()} [${event.senderId}]', '${event.senderFromMemoryOrFallback.calcDisplayname()} [${event.senderId}]',
// ), ),
), ),
ListTile( ListTile(
title: Text(L10n.of(context)!.time), title: Text(L10n.of(context)!.time),

@ -263,10 +263,9 @@ class Message extends StatelessWidget {
final user = snapshot.data ?? final user = snapshot.data ??
event.senderFromMemoryOrFallback; event.senderFromMemoryOrFallback;
return Avatar( return Avatar(
// mxContent: user.avatarUrl, mxContent: user.avatarUrl,
// name: user.calcDisplayname(), name: user.calcDisplayname(),
// presenceUserId: user.stateKey, presenceUserId: user.stateKey,
name: "?",
presenceBackgroundColor: presenceBackgroundColor:
avatarPresenceBackgroundColor, avatarPresenceBackgroundColor,
onTap: () => onAvatarTab(event), onTap: () => onAvatarTab(event),
@ -289,11 +288,10 @@ class Message extends StatelessWidget {
: FutureBuilder<User?>( : FutureBuilder<User?>(
future: event.fetchSenderUser(), future: event.fetchSenderUser(),
builder: (context, snapshot) { builder: (context, snapshot) {
// final displayname = snapshot.data final displayname = snapshot.data
// ?.calcDisplayname() ?? ?.calcDisplayname() ??
// event.senderFromMemoryOrFallback event.senderFromMemoryOrFallback
// .calcDisplayname(); .calcDisplayname();
const displayname = "?";
return Text( return Text(
displayname, displayname,
style: TextStyle( style: TextStyle(

@ -96,16 +96,12 @@ class MessageContent extends StatelessWidget {
ListTile( ListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
leading: Avatar( leading: Avatar(
// mxContent: sender.avatarUrl, mxContent: sender.avatarUrl,
// name: sender.calcDisplayname(), name: sender.calcDisplayname(),
// presenceUserId: sender.stateKey, presenceUserId: sender.stateKey,
name: "?",
client: event.room.client, client: event.room.client,
), ),
title: const Text( title: Text(sender.calcDisplayname()),
// sender.calcDisplayname(),
"?",
),
subtitle: Text(event.originServerTs.localizedTime(context)), subtitle: Text(event.originServerTs.localizedTime(context)),
trailing: const Icon(Icons.lock_outlined), trailing: const Icon(Icons.lock_outlined),
), ),
@ -269,10 +265,9 @@ class MessageContent extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
final reason = final reason =
event.redactedBecause?.content.tryGet<String>('reason'); event.redactedBecause?.content.tryGet<String>('reason');
// final redactedBy = snapshot.data?.calcDisplayname() ?? final redactedBy = snapshot.data?.calcDisplayname() ??
// event.redactedBecause?.senderId.localpart ?? event.redactedBecause?.senderId.localpart ??
// L10n.of(context)!.user; L10n.of(context)!.user;
const redactedBy = "?";
return _ButtonContent( return _ButtonContent(
label: reason == null label: reason == null
? L10n.of(context)!.redactedBy(redactedBy) ? L10n.of(context)!.redactedBy(redactedBy)
@ -390,9 +385,8 @@ class MessageContent extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
return _ButtonContent( return _ButtonContent(
label: L10n.of(context)!.userSentUnknownEvent( label: L10n.of(context)!.userSentUnknownEvent(
// snapshot.data?.calcDisplayname() ?? snapshot.data?.calcDisplayname() ??
// event.senderFromMemoryOrFallback.calcDisplayname(), event.senderFromMemoryOrFallback.calcDisplayname(),
"?",
event.type, event.type,
), ),
icon: '', icon: '',

@ -59,8 +59,7 @@ class ReplyContent extends StatelessWidget {
future: displayEvent.fetchSenderUser(), future: displayEvent.fetchSenderUser(),
builder: (context, snapshot) { builder: (context, snapshot) {
return Text( return Text(
// '${snapshot.data?.calcDisplayname() ?? displayEvent.senderFromMemoryOrFallback.calcDisplayname()}:', '${snapshot.data?.calcDisplayname() ?? displayEvent.senderFromMemoryOrFallback.calcDisplayname()}:',
'?:',
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(

@ -37,10 +37,9 @@ class SeenByRow extends StatelessWidget {
? seenByUsers.sublist(0, maxAvatars) ? seenByUsers.sublist(0, maxAvatars)
: seenByUsers) : seenByUsers)
.map( .map(
(user) => const Avatar( (user) => Avatar(
// mxContent: user.avatarUrl, mxContent: user.avatarUrl,
// name: user.calcDisplayname(), name: user.calcDisplayname(),
name: "?",
size: 16, size: 16,
), ),
), ),

@ -1,11 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
class TypingIndicators extends StatelessWidget { class TypingIndicators extends StatelessWidget {
final ChatController controller; final ChatController controller;
@ -55,11 +56,10 @@ class TypingIndicators extends StatelessWidget {
child: Stack( child: Stack(
children: [ children: [
if (typingUsers.isNotEmpty) if (typingUsers.isNotEmpty)
const Avatar( Avatar(
size: avatarSize, size: avatarSize,
// mxContent: typingUsers.first.avatarUrl, mxContent: typingUsers.first.avatarUrl,
// name: typingUsers.first.calcDisplayname(), name: typingUsers.first.calcDisplayname(),
name: "?",
), ),
if (typingUsers.length == 2) if (typingUsers.length == 2)
Padding( Padding(
@ -69,10 +69,9 @@ class TypingIndicators extends StatelessWidget {
mxContent: typingUsers.length == 2 mxContent: typingUsers.length == 2
? typingUsers.last.avatarUrl ? typingUsers.last.avatarUrl
: null, : null,
// name: typingUsers.length == 2 name: typingUsers.length == 2
// ? typingUsers.last.calcDisplayname() ? typingUsers.last.calcDisplayname()
// : '+${typingUsers.length - 1}', : '+${typingUsers.length - 1}',
name: "?",
), ),
), ),
], ],

@ -39,10 +39,9 @@ class ParticipantListItem extends StatelessWidget {
), ),
title: Row( title: Row(
children: <Widget>[ children: <Widget>[
const Expanded( Expanded(
child: Text( child: Text(
// user.calcDisplayname(), user.calcDisplayname(),
"?",
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
@ -89,9 +88,8 @@ class ParticipantListItem extends StatelessWidget {
subtitle: Text(user.id), subtitle: Text(user.id),
leading: Avatar( leading: Avatar(
mxContent: user.avatarUrl, mxContent: user.avatarUrl,
// name: user.calcDisplayname(), name: user.calcDisplayname(),
// presenceUserId: user.stateKey, presenceUserId: user.stateKey,
name: "?",
), ),
), ),
); );

@ -1,9 +1,11 @@
import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/utils/get_chat_list_item_subtitle.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/room_status_extension.dart'; import 'package:fluffychat/utils/room_status_extension.dart';
import 'package:fluffychat/widgets/hover_builder.dart'; import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.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';
import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart';
@ -238,52 +240,51 @@ class ChatListItem extends StatelessWidget {
softWrap: false, softWrap: false,
) )
// #Pangea // #Pangea
: const SizedBox(), : FutureBuilder<String>(
// FutureBuilder<String>( future: room.lastEvent != null
// future: room.lastEvent != null ? GetChatListItemSubtitle().getSubtitle(
// ? GetChatListItemSubtitle().getSubtitle( L10n.of(context)!,
// L10n.of(context)!, room.lastEvent,
// room.lastEvent, MatrixState.pangeaController,
// MatrixState.pangeaController, )
// ) : Future.value(L10n.of(context)!.emptyChat),
// : Future.value(L10n.of(context)!.emptyChat), builder: (context, snapshot) {
// builder: (context, snapshot) { // Pangea#
// // Pangea# return Text(
// return Text( room.membership == Membership.invite
// room.membership == Membership.invite ? isDirectChat
// ? isDirectChat ? L10n.of(context)!.invitePrivateChat
// ? L10n.of(context)!.invitePrivateChat : L10n.of(context)!.inviteGroupChat
// : L10n.of(context)!.inviteGroupChat // #Pangea
// // #Pangea : snapshot.data ??
// : snapshot.data ?? // Pangea#
// // Pangea# room.lastEvent
// room.lastEvent ?.calcLocalizedBodyFallback(
// ?.calcLocalizedBodyFallback( MatrixLocals(L10n.of(context)!),
// MatrixLocals(L10n.of(context)!), hideReply: true,
// hideReply: true, hideEdit: true,
// hideEdit: true, plaintextBody: true,
// plaintextBody: true, removeMarkdown: true,
// removeMarkdown: true, withSenderNamePrefix: !isDirectChat ||
// withSenderNamePrefix: !isDirectChat || directChatMatrixId !=
// directChatMatrixId != room.lastEvent?.senderId,
// room.lastEvent?.senderId, ) ??
// ) ?? L10n.of(context)!.emptyChat,
// L10n.of(context)!.emptyChat, softWrap: false,
// softWrap: false, maxLines: 1,
// maxLines: 1, overflow: TextOverflow.ellipsis,
// overflow: TextOverflow.ellipsis, style: TextStyle(
// style: TextStyle( fontWeight: unread || room.hasNewMessages
// fontWeight: unread || room.hasNewMessages ? FontWeight.bold
// ? FontWeight.bold : null,
// : null, color: theme.colorScheme.onSurfaceVariant,
// color: theme.colorScheme.onSurfaceVariant, decoration: room.lastEvent?.redacted == true
// decoration: room.lastEvent?.redacted == true ? TextDecoration.lineThrough
// ? TextDecoration.lineThrough : null,
// : null, ),
// ), );
// ); },
// }, ),
// ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
// #Pangea // #Pangea

@ -1,13 +1,15 @@
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.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';
import 'package:flutter_linkify/flutter_linkify.dart'; import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.dart';
class ChatSearchMessageTab extends StatelessWidget { class ChatSearchMessageTab extends StatelessWidget {
final String searchQuery; final String searchQuery;
final Room room; final Room room;
@ -96,10 +98,9 @@ class ChatSearchMessageTab extends StatelessWidget {
} }
final event = events[i]; final event = events[i];
final sender = event.senderFromMemoryOrFallback; final sender = event.senderFromMemoryOrFallback;
// final displayname = sender.calcDisplayname( final displayname = sender.calcDisplayname(
// i18n: MatrixLocals(L10n.of(context)!), i18n: MatrixLocals(L10n.of(context)!),
// ); );
const displayname = "?";
return _MessageSearchResultListTile( return _MessageSearchResultListTile(
sender: sender, sender: sender,
displayname: displayname, displayname: displayname,

@ -22,10 +22,9 @@ class UserBottomSheetView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final user = controller.widget.user; final user = controller.widget.user;
final userId = (user?.id ?? controller.widget.profile?.userId)!; final userId = (user?.id ?? controller.widget.profile?.userId)!;
// final displayname = (user?.calcDisplayname() ?? final displayname = (user?.calcDisplayname() ??
// controller.widget.profile?.displayName ?? controller.widget.profile?.displayName ??
// controller.widget.profile?.userId.localpart)!; controller.widget.profile?.userId.localpart)!;
const displayname = "?";
final avatarUrl = user?.avatarUrl ?? controller.widget.profile?.avatarUrl; final avatarUrl = user?.avatarUrl ?? controller.widget.profile?.avatarUrl;
final client = Matrix.of(controller.widget.outerContext).client; final client = Matrix.of(controller.widget.outerContext).client;
@ -40,7 +39,7 @@ class UserBottomSheetView extends StatelessWidget {
title: Column( title: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text(displayname), Text(displayname),
PresenceBuilder( PresenceBuilder(
userId: userId, userId: userId,
client: client, client: client,
@ -214,7 +213,7 @@ class UserBottomSheetView extends StatelessWidget {
foregroundColor: foregroundColor:
Theme.of(context).colorScheme.onSurface, Theme.of(context).colorScheme.onSurface,
), ),
label: const Text( label: Text(
displayname, displayname,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,

@ -1,18 +1,85 @@
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
extension MembershipUpdate on SyncUpdate { extension MembershipUpdate on SyncUpdate {
List<Event> messages(Room chat) { bool isMembershipUpdate(String userId) {
if (rooms?.join == null || return isMembershipUpdateByType(Membership.join, userId) ||
!rooms!.join!.containsKey(chat.id) || isMembershipUpdateByType(Membership.leave, userId) ||
rooms!.join![chat.id]!.timeline?.events == null) { isMembershipUpdateByType(Membership.invite, userId);
return []; }
bool isMembershipUpdateByType(Membership type, String userId) {
final List<SyncRoomUpdate>? updates = getRoomUpdates(type);
if (updates?.isEmpty ?? true) {
return false;
}
for (final SyncRoomUpdate update in updates!) {
final List<dynamic>? events = getRoomUpdateEvents(type, update);
if (hasMembershipUpdate(
events,
type.name,
userId,
)) {
return true;
}
}
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;
}
}
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;
}
}
return rooms!.join![chat.id]!.timeline!.events! bool hasMembershipUpdate(
.where( List<dynamic>? events,
(event) => event.type == EventTypes.Message, String membershipType,
) String userId,
.map((event) => Event.fromMatrixEvent(event, chat)) ) {
.toList(); if (events == null) {
return false;
} }
return events.any(
(event) =>
event.type == EventTypes.RoomMember &&
event.stateKey == userId &&
event.content['membership'] == membershipType,
);
} }

@ -1,87 +0,0 @@
import 'dart:async';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pangea/extensions/sync_update_extension.dart';
import 'package:fluffychat/pangea/utils/bot_name.dart';
import 'package:fluffychat/pangea/widgets/chat/round_timer.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
enum RoundState { notStarted, inProgress, completed }
class GameRoundModel {
static const int timerMaxSeconds = 180;
final ChatController controller;
final Completer<void> roundCompleter = Completer<void>();
late DateTime createdAt;
RoundTimer timer;
DateTime? startTime;
DateTime? endTime;
RoundState state = RoundState.notStarted;
StreamSubscription? syncSubscription;
final Set<String> messageIDs = {};
GameRoundModel({
required this.controller,
required this.timer,
}) {
createdAt = DateTime.now();
debugPrint("timeline: ${controller.room.timeline}");
syncSubscription ??= client.onSync.stream.listen((update) {
final newMessages = update.messages(controller.room);
final botMessages = newMessages
.where((msg) => msg.senderId == BotName.byEnvironment)
.toList();
if (botMessages.isNotEmpty &&
botMessages.any(
(msg) =>
msg.originServerTs.isAfter(createdAt) &&
!messageIDs.contains(msg.eventId),
)) {
if (state == RoundState.notStarted) {
startRound();
} else if (state == RoundState.inProgress) {
endRound();
return;
}
}
for (final message in newMessages) {
if (message.originServerTs.isAfter(createdAt) &&
!messageIDs.contains(message.eventId) &&
!message.eventId.startsWith("Pangea Chat")) {
messageIDs.add(message.eventId);
}
}
});
}
Client get client => controller.pangeaController.matrixState.client;
bool get isCompleted => roundCompleter.isCompleted;
void startRound() {
debugPrint("starting round");
state = RoundState.inProgress;
startTime = DateTime.now();
controller.roundTimerStateKey.currentState?.resetTimer(
roundLength: timerMaxSeconds,
);
controller.roundTimerStateKey.currentState?.startTimer();
}
void endRound() {
debugPrint("ending round, message IDs: $messageIDs");
endTime = DateTime.now();
state = RoundState.completed;
controller.roundTimerStateKey.currentState?.resetTimer();
syncSubscription?.cancel();
roundCompleter.complete();
}
void dispose() {
syncSubscription?.cancel();
}
}

@ -1,113 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
/// Create a timer that counts down to the given time
/// Default duration is 180 seconds
class RoundTimer extends StatefulWidget {
final int timerMaxSeconds;
final Duration roundDuration;
const RoundTimer({
super.key,
this.timerMaxSeconds = 180,
this.roundDuration = const Duration(seconds: 1),
});
@override
RoundTimerState createState() => RoundTimerState();
}
class RoundTimerState extends State<RoundTimer> {
int currentSeconds = 0;
Timer? _timer;
bool isTiming = false;
Duration? duration;
int timerMaxSeconds = 180;
void resetTimer({Duration? roundDuration, int? roundLength}) {
if (_timer != null) {
_timer!.cancel();
isTiming = false;
}
if (roundDuration != null) {
duration = roundDuration;
}
if (roundLength != null) {
timerMaxSeconds = roundLength;
}
setState(() {
currentSeconds = 0;
});
}
int get remainingTime => timerMaxSeconds - currentSeconds;
String get timerText =>
'${(remainingTime ~/ 60).toString().padLeft(2, '0')}: ${(remainingTime % 60).toString().padLeft(2, '0')}';
startTimer() {
_timer = Timer.periodic(duration ?? widget.roundDuration, (timer) {
setState(() {
currentSeconds++;
if (currentSeconds >= timerMaxSeconds) timer.cancel();
});
});
setState(() {
isTiming = true;
});
}
stopTimer() {
if (_timer != null) {
_timer!.cancel();
}
setState(() {
isTiming = false;
});
}
@override
void initState() {
duration = widget.roundDuration;
timerMaxSeconds = widget.timerMaxSeconds;
super.initState();
}
@override
void dispose() {
if (_timer != null) {
_timer!.cancel();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Material(
color: const Color.fromARGB(255, 126, 22, 14),
child: Padding(
padding: const EdgeInsets.all(
5,
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(timerText),
// Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// IconButton(
// onPressed: isTiming ? stopTimeout : startTimeout,
// icon: Icon(isTiming ? Icons.pause_circle : Icons.play_circle),
// ),
// ],
// ),
],
),
),
),
);
}
}

@ -184,9 +184,9 @@ class MatrixLocals extends MatrixLocalizations {
@override @override
String redactedAnEvent(Event redactedEvent) { String redactedAnEvent(Event redactedEvent) {
return l10n.redactedAnEvent( return l10n.redactedAnEvent(
// redactedEvent.redactedBecause?.senderFromMemoryOrFallback redactedEvent.redactedBecause?.senderFromMemoryOrFallback
// .calcDisplayname() ?? .calcDisplayname() ??
l10n.user, l10n.user,
); );
} }
@ -198,8 +198,7 @@ class MatrixLocals extends MatrixLocalizations {
@override @override
String removedBy(Event redactedEvent) { String removedBy(Event redactedEvent) {
return l10n.redactedBy( return l10n.redactedBy(
// redactedEvent.senderFromMemoryOrFallback.calcDisplayname(), redactedEvent.senderFromMemoryOrFallback.calcDisplayname(),
"?",
); );
} }

@ -1,4 +1,5 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.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';
@ -19,21 +20,17 @@ extension RoomStatusExtension on Room {
} else if (typingUsers.length == 1) { } else if (typingUsers.length == 1) {
typingText = L10n.of(context)!.isTyping; typingText = L10n.of(context)!.isTyping;
if (typingUsers.first.id != directChatMatrixID) { if (typingUsers.first.id != directChatMatrixID) {
typingText = L10n.of(context)!.userIsTyping( typingText =
// typingUsers.first.calcDisplayname(), L10n.of(context)!.userIsTyping(typingUsers.first.calcDisplayname());
"?",
);
} }
} else if (typingUsers.length == 2) { } else if (typingUsers.length == 2) {
typingText = L10n.of(context)!.userAndUserAreTyping( typingText = L10n.of(context)!.userAndUserAreTyping(
// typingUsers.first.calcDisplayname(), typingUsers.first.calcDisplayname(),
// typingUsers[1].calcDisplayname(), typingUsers[1].calcDisplayname(),
"?", "?",
); );
} else if (typingUsers.length > 2) { } else if (typingUsers.length > 2) {
typingText = L10n.of(context)!.userAndOthersAreTyping( typingText = L10n.of(context)!.userAndOthersAreTyping(
// typingUsers.first.calcDisplayname(), typingUsers.first.calcDisplayname(),
"?",
(typingUsers.length - 1).toString(), (typingUsers.length - 1).toString(),
); );
} }

Loading…
Cancel
Save