mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-11-03 22:07:23 +01:00 
			
		
		
		
	fix: chat list view animation
- fix the chat list view animation - move chat list view body to separate file Signed-off-by: TheOneWithTheBraid <the-one@with-the-braid.cf>
This commit is contained in:
		
							parent
							
								
									cc2bbd1928
								
							
						
					
					
						commit
						bfbf425663
					
				
							
								
								
									
										219
									
								
								lib/pages/chat_list/chat_list_body.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								lib/pages/chat_list/chat_list_body.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,219 @@
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:animations/animations.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/spaces_bottom_bar.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/stories_header.dart';
 | 
			
		||||
import '../../utils/stream_extension.dart';
 | 
			
		||||
import '../../widgets/matrix.dart';
 | 
			
		||||
 | 
			
		||||
class ChatListViewBody extends StatefulWidget {
 | 
			
		||||
  final ChatListController controller;
 | 
			
		||||
 | 
			
		||||
  const ChatListViewBody(this.controller, {Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<ChatListViewBody> createState() => _ChatListViewBodyState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _ChatListViewBodyState extends State<ChatListViewBody> {
 | 
			
		||||
  // the matrix sync stream
 | 
			
		||||
  late StreamSubscription _subscription;
 | 
			
		||||
  late StreamSubscription _clientSubscription;
 | 
			
		||||
 | 
			
		||||
  // used to check the animation direction
 | 
			
		||||
  String? _lastUserId;
 | 
			
		||||
  String? _lastSpaceId;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    _subscription = Matrix.of(context)
 | 
			
		||||
        .client
 | 
			
		||||
        .onSync
 | 
			
		||||
        .stream
 | 
			
		||||
        .where((s) => s.hasRoomUpdate)
 | 
			
		||||
        .rateLimit(const Duration(seconds: 1))
 | 
			
		||||
        .listen((d) => setState(() {}));
 | 
			
		||||
    _clientSubscription =
 | 
			
		||||
        widget.controller.clientStream.listen((d) => setState(() {}));
 | 
			
		||||
    super.initState();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final reversed = !_animationReversed();
 | 
			
		||||
    Widget child;
 | 
			
		||||
    if (widget.controller.waitForFirstSync &&
 | 
			
		||||
        Matrix.of(context).client.prevBatch != null) {
 | 
			
		||||
      final rooms = widget.controller.activeSpacesEntry.getRooms(context);
 | 
			
		||||
      if (rooms.isEmpty) {
 | 
			
		||||
        child = Column(
 | 
			
		||||
          key: const ValueKey(null),
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
          mainAxisSize: MainAxisSize.min,
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            Image.asset(
 | 
			
		||||
              'assets/private_chat_wallpaper.png',
 | 
			
		||||
              width: 160,
 | 
			
		||||
              height: 160,
 | 
			
		||||
            ),
 | 
			
		||||
            Center(
 | 
			
		||||
              child: Text(
 | 
			
		||||
                L10n.of(context)!.startYourFirstChat,
 | 
			
		||||
                textAlign: TextAlign.start,
 | 
			
		||||
                style: const TextStyle(
 | 
			
		||||
                  color: Colors.grey,
 | 
			
		||||
                  fontSize: 16,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        final displayStoriesHeader = widget.controller.activeSpacesEntry
 | 
			
		||||
            .shouldShowStoriesHeader(context);
 | 
			
		||||
        child = ListView.builder(
 | 
			
		||||
          key: ValueKey(Matrix.of(context).client.userID.toString() +
 | 
			
		||||
              widget.controller.activeSpaceId.toString()),
 | 
			
		||||
          controller: widget.controller.scrollController,
 | 
			
		||||
          itemCount: rooms.length + (displayStoriesHeader ? 1 : 0),
 | 
			
		||||
          itemBuilder: (BuildContext context, int i) {
 | 
			
		||||
            if (displayStoriesHeader) {
 | 
			
		||||
              if (i == 0) {
 | 
			
		||||
                return const StoriesHeader();
 | 
			
		||||
              }
 | 
			
		||||
              i--;
 | 
			
		||||
            }
 | 
			
		||||
            return ChatListItem(
 | 
			
		||||
              rooms[i],
 | 
			
		||||
              selected: widget.controller.selectedRoomIds.contains(rooms[i].id),
 | 
			
		||||
              onTap: widget.controller.selectMode == SelectMode.select
 | 
			
		||||
                  ? () => widget.controller.toggleSelection(rooms[i].id)
 | 
			
		||||
                  : null,
 | 
			
		||||
              onLongPress: () => widget.controller.toggleSelection(rooms[i].id),
 | 
			
		||||
              activeChat: widget.controller.activeChat == rooms[i].id,
 | 
			
		||||
            );
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      const dummyChatCount = 5;
 | 
			
		||||
      final titleColor =
 | 
			
		||||
          Theme.of(context).textTheme.bodyText1!.color!.withAlpha(100);
 | 
			
		||||
      final subtitleColor =
 | 
			
		||||
          Theme.of(context).textTheme.bodyText1!.color!.withAlpha(50);
 | 
			
		||||
      child = ListView.builder(
 | 
			
		||||
        itemCount: dummyChatCount,
 | 
			
		||||
        itemBuilder: (context, i) => Opacity(
 | 
			
		||||
          opacity: (dummyChatCount - i) / dummyChatCount,
 | 
			
		||||
          child: ListTile(
 | 
			
		||||
            leading: CircleAvatar(
 | 
			
		||||
              backgroundColor: titleColor,
 | 
			
		||||
              child: CircularProgressIndicator(
 | 
			
		||||
                strokeWidth: 1,
 | 
			
		||||
                color: Theme.of(context).textTheme.bodyText1!.color,
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            title: Row(
 | 
			
		||||
              children: [
 | 
			
		||||
                Expanded(
 | 
			
		||||
                  child: Container(
 | 
			
		||||
                    height: 14,
 | 
			
		||||
                    decoration: BoxDecoration(
 | 
			
		||||
                      color: titleColor,
 | 
			
		||||
                      borderRadius: BorderRadius.circular(3),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(width: 36),
 | 
			
		||||
                Container(
 | 
			
		||||
                  height: 14,
 | 
			
		||||
                  width: 14,
 | 
			
		||||
                  decoration: BoxDecoration(
 | 
			
		||||
                    color: subtitleColor,
 | 
			
		||||
                    borderRadius: BorderRadius.circular(14),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(width: 12),
 | 
			
		||||
                Container(
 | 
			
		||||
                  height: 14,
 | 
			
		||||
                  width: 14,
 | 
			
		||||
                  decoration: BoxDecoration(
 | 
			
		||||
                    color: subtitleColor,
 | 
			
		||||
                    borderRadius: BorderRadius.circular(14),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
            subtitle: Container(
 | 
			
		||||
              decoration: BoxDecoration(
 | 
			
		||||
                color: subtitleColor,
 | 
			
		||||
                borderRadius: BorderRadius.circular(3),
 | 
			
		||||
              ),
 | 
			
		||||
              height: 12,
 | 
			
		||||
              margin: const EdgeInsets.only(right: 22),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    return PageTransitionSwitcher(
 | 
			
		||||
      reverse: reversed,
 | 
			
		||||
      transitionBuilder: (
 | 
			
		||||
        Widget child,
 | 
			
		||||
        Animation<double> primaryAnimation,
 | 
			
		||||
        Animation<double> secondaryAnimation,
 | 
			
		||||
      ) {
 | 
			
		||||
        return SharedAxisTransition(
 | 
			
		||||
          animation: primaryAnimation,
 | 
			
		||||
          secondaryAnimation: secondaryAnimation,
 | 
			
		||||
          transitionType:
 | 
			
		||||
              widget.controller.snappingSheetController.currentPosition ==
 | 
			
		||||
                      kSpacesBottomBarHeight
 | 
			
		||||
                  ? SharedAxisTransitionType.horizontal
 | 
			
		||||
                  : SharedAxisTransitionType.vertical,
 | 
			
		||||
          fillColor: Theme.of(context).scaffoldBackgroundColor,
 | 
			
		||||
          child: child,
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
      child: child,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void dispose() {
 | 
			
		||||
    _subscription.cancel();
 | 
			
		||||
    _clientSubscription.cancel();
 | 
			
		||||
    super.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool _animationReversed() {
 | 
			
		||||
    bool reversed;
 | 
			
		||||
    // in case the matrix id changes, check the indexOf the matrix id
 | 
			
		||||
    final newClient = Matrix.of(context).client;
 | 
			
		||||
    if (_lastUserId != newClient.userID) {
 | 
			
		||||
      reversed = Matrix.of(context)
 | 
			
		||||
              .currentBundle!
 | 
			
		||||
              .indexWhere((element) => element!.userID == _lastUserId) <
 | 
			
		||||
          Matrix.of(context)
 | 
			
		||||
              .currentBundle!
 | 
			
		||||
              .indexWhere((element) => element!.userID == newClient.userID);
 | 
			
		||||
    }
 | 
			
		||||
    // otherwise, the space changed...
 | 
			
		||||
    else {
 | 
			
		||||
      reversed = widget.controller.spaces
 | 
			
		||||
              .indexWhere((element) => element.id == _lastSpaceId) <
 | 
			
		||||
          widget.controller.spaces.indexWhere(
 | 
			
		||||
              (element) => element.id == widget.controller.activeSpaceId);
 | 
			
		||||
    }
 | 
			
		||||
    _lastUserId = newClient.userID;
 | 
			
		||||
    _lastSpaceId = widget.controller.activeSpaceId;
 | 
			
		||||
    return reversed;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,25 +1,19 @@
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:animations/animations.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:keyboard_shortcuts/keyboard_shortcuts.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
import 'package:snapping_sheet/snapping_sheet.dart';
 | 
			
		||||
import 'package:vrouter/vrouter.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/app_config.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/client_chooser_button.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/spaces_bottom_bar.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/stories_header.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/connection_status_header.dart';
 | 
			
		||||
import '../../utils/stream_extension.dart';
 | 
			
		||||
import '../../widgets/matrix.dart';
 | 
			
		||||
import 'chat_list_body.dart';
 | 
			
		||||
 | 
			
		||||
class ChatListView extends StatelessWidget {
 | 
			
		||||
  final ChatListController controller;
 | 
			
		||||
@ -231,7 +225,7 @@ class ChatListView extends StatelessWidget {
 | 
			
		||||
                          ),
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      Expanded(child: _ChatListViewBody(controller)),
 | 
			
		||||
                      Expanded(child: ChatListViewBody(controller)),
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                  initialSnappingPosition: showSpaces
 | 
			
		||||
@ -288,210 +282,6 @@ class ChatListView extends StatelessWidget {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _ChatListViewBody extends StatefulWidget {
 | 
			
		||||
  final ChatListController controller;
 | 
			
		||||
 | 
			
		||||
  const _ChatListViewBody(this.controller, {Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<_ChatListViewBody> createState() => _ChatListViewBodyState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _ChatListViewBodyState extends State<_ChatListViewBody> {
 | 
			
		||||
  // the matrix sync stream
 | 
			
		||||
  late StreamSubscription _subscription;
 | 
			
		||||
  late StreamSubscription _clientSubscription;
 | 
			
		||||
 | 
			
		||||
  // used to check the animation direction
 | 
			
		||||
  String? _lastUserId;
 | 
			
		||||
  String? _lastSpaceId;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    _subscription = Matrix.of(context)
 | 
			
		||||
        .client
 | 
			
		||||
        .onSync
 | 
			
		||||
        .stream
 | 
			
		||||
        .where((s) => s.hasRoomUpdate)
 | 
			
		||||
        .rateLimit(const Duration(seconds: 1))
 | 
			
		||||
        .listen((d) => setState(() {}));
 | 
			
		||||
    _clientSubscription =
 | 
			
		||||
        widget.controller.clientStream.listen((d) => setState(() {}));
 | 
			
		||||
    super.initState();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final reversed = _animationReversed();
 | 
			
		||||
    Widget child;
 | 
			
		||||
    if (widget.controller.waitForFirstSync &&
 | 
			
		||||
        Matrix.of(context).client.prevBatch != null) {
 | 
			
		||||
      final rooms = widget.controller.activeSpacesEntry.getRooms(context);
 | 
			
		||||
      if (rooms.isEmpty) {
 | 
			
		||||
        child = Column(
 | 
			
		||||
          key: const ValueKey(null),
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
          mainAxisSize: MainAxisSize.min,
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            Image.asset(
 | 
			
		||||
              'assets/private_chat_wallpaper.png',
 | 
			
		||||
              width: 160,
 | 
			
		||||
              height: 160,
 | 
			
		||||
            ),
 | 
			
		||||
            Center(
 | 
			
		||||
              child: Text(
 | 
			
		||||
                L10n.of(context)!.startYourFirstChat,
 | 
			
		||||
                textAlign: TextAlign.start,
 | 
			
		||||
                style: const TextStyle(
 | 
			
		||||
                  color: Colors.grey,
 | 
			
		||||
                  fontSize: 16,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        final displayStoriesHeader = widget.controller.activeSpacesEntry
 | 
			
		||||
            .shouldShowStoriesHeader(context);
 | 
			
		||||
        child = ListView.builder(
 | 
			
		||||
          key: ValueKey(Matrix.of(context).client.userID.toString() +
 | 
			
		||||
              widget.controller.activeSpaceId.toString()),
 | 
			
		||||
          controller: widget.controller.scrollController,
 | 
			
		||||
          itemCount: rooms.length + (displayStoriesHeader ? 1 : 0),
 | 
			
		||||
          itemBuilder: (BuildContext context, int i) {
 | 
			
		||||
            if (displayStoriesHeader) {
 | 
			
		||||
              if (i == 0) {
 | 
			
		||||
                return const StoriesHeader();
 | 
			
		||||
              }
 | 
			
		||||
              i--;
 | 
			
		||||
            }
 | 
			
		||||
            return ChatListItem(
 | 
			
		||||
              rooms[i],
 | 
			
		||||
              selected: widget.controller.selectedRoomIds.contains(rooms[i].id),
 | 
			
		||||
              onTap: widget.controller.selectMode == SelectMode.select
 | 
			
		||||
                  ? () => widget.controller.toggleSelection(rooms[i].id)
 | 
			
		||||
                  : null,
 | 
			
		||||
              onLongPress: () => widget.controller.toggleSelection(rooms[i].id),
 | 
			
		||||
              activeChat: widget.controller.activeChat == rooms[i].id,
 | 
			
		||||
            );
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      const dummyChatCount = 5;
 | 
			
		||||
      final titleColor =
 | 
			
		||||
          Theme.of(context).textTheme.bodyText1!.color!.withAlpha(100);
 | 
			
		||||
      final subtitleColor =
 | 
			
		||||
          Theme.of(context).textTheme.bodyText1!.color!.withAlpha(50);
 | 
			
		||||
      child = ListView.builder(
 | 
			
		||||
        itemCount: dummyChatCount,
 | 
			
		||||
        itemBuilder: (context, i) => Opacity(
 | 
			
		||||
          opacity: (dummyChatCount - i) / dummyChatCount,
 | 
			
		||||
          child: ListTile(
 | 
			
		||||
            leading: CircleAvatar(
 | 
			
		||||
              backgroundColor: titleColor,
 | 
			
		||||
              child: CircularProgressIndicator(
 | 
			
		||||
                strokeWidth: 1,
 | 
			
		||||
                color: Theme.of(context).textTheme.bodyText1!.color,
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            title: Row(
 | 
			
		||||
              children: [
 | 
			
		||||
                Expanded(
 | 
			
		||||
                  child: Container(
 | 
			
		||||
                    height: 14,
 | 
			
		||||
                    decoration: BoxDecoration(
 | 
			
		||||
                      color: titleColor,
 | 
			
		||||
                      borderRadius: BorderRadius.circular(3),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(width: 36),
 | 
			
		||||
                Container(
 | 
			
		||||
                  height: 14,
 | 
			
		||||
                  width: 14,
 | 
			
		||||
                  decoration: BoxDecoration(
 | 
			
		||||
                    color: subtitleColor,
 | 
			
		||||
                    borderRadius: BorderRadius.circular(14),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(width: 12),
 | 
			
		||||
                Container(
 | 
			
		||||
                  height: 14,
 | 
			
		||||
                  width: 14,
 | 
			
		||||
                  decoration: BoxDecoration(
 | 
			
		||||
                    color: subtitleColor,
 | 
			
		||||
                    borderRadius: BorderRadius.circular(14),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
            subtitle: Container(
 | 
			
		||||
              decoration: BoxDecoration(
 | 
			
		||||
                color: subtitleColor,
 | 
			
		||||
                borderRadius: BorderRadius.circular(3),
 | 
			
		||||
              ),
 | 
			
		||||
              height: 12,
 | 
			
		||||
              margin: const EdgeInsets.only(right: 22),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    child = Material(
 | 
			
		||||
      color: Theme.of(context).scaffoldBackgroundColor,
 | 
			
		||||
      child: child,
 | 
			
		||||
    );
 | 
			
		||||
    return PageTransitionSwitcher(
 | 
			
		||||
      reverse: reversed,
 | 
			
		||||
      transitionBuilder: (
 | 
			
		||||
        Widget child,
 | 
			
		||||
        Animation<double> primaryAnimation,
 | 
			
		||||
        Animation<double> secondaryAnimation,
 | 
			
		||||
      ) {
 | 
			
		||||
        return SharedAxisTransition(
 | 
			
		||||
          animation: primaryAnimation,
 | 
			
		||||
          secondaryAnimation: secondaryAnimation,
 | 
			
		||||
          transitionType: SharedAxisTransitionType.horizontal,
 | 
			
		||||
          child: child,
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
      child: child,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void dispose() {
 | 
			
		||||
    _subscription.cancel();
 | 
			
		||||
    _clientSubscription.cancel();
 | 
			
		||||
    super.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool _animationReversed() {
 | 
			
		||||
    bool reversed;
 | 
			
		||||
    // in case the matrix id changes, check the indexOf the matrix id
 | 
			
		||||
    final newClient = Matrix.of(context).client;
 | 
			
		||||
    if (_lastUserId != newClient.userID) {
 | 
			
		||||
      reversed = Matrix.of(context)
 | 
			
		||||
              .currentBundle!
 | 
			
		||||
              .indexWhere((element) => element!.userID == _lastUserId) <
 | 
			
		||||
          Matrix.of(context)
 | 
			
		||||
              .currentBundle!
 | 
			
		||||
              .indexWhere((element) => element!.userID == newClient.userID);
 | 
			
		||||
    }
 | 
			
		||||
    // otherwise, the space changed...
 | 
			
		||||
    else {
 | 
			
		||||
      reversed = widget.controller.spaces
 | 
			
		||||
              .indexWhere((element) => element.id == _lastSpaceId) <
 | 
			
		||||
          widget.controller.spaces.indexWhere(
 | 
			
		||||
              (element) => element.id == widget.controller.activeSpaceId);
 | 
			
		||||
    }
 | 
			
		||||
    _lastUserId = newClient.userID;
 | 
			
		||||
    _lastSpaceId = widget.controller.activeSpaceId;
 | 
			
		||||
    return reversed;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum ChatListPopupMenuItemActions {
 | 
			
		||||
  createGroup,
 | 
			
		||||
  createSpace,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user