mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-11-03 22:07:23 +01:00 
			
		
		
		
	feat: Display progress value for initial sync
This commit is contained in:
		
							parent
							
								
									ec9155d8f0
								
							
						
					
					
						commit
						299aac134d
					
				@ -32,6 +32,11 @@ class ChatListViewBody extends StatelessWidget {
 | 
			
		||||
    final roomSearchResult = controller.roomSearchResult;
 | 
			
		||||
    final userSearchResult = controller.userSearchResult;
 | 
			
		||||
    final client = Matrix.of(context).client;
 | 
			
		||||
    const dummyChatCount = 4;
 | 
			
		||||
    final titleColor =
 | 
			
		||||
        Theme.of(context).textTheme.bodyLarge!.color!.withAlpha(100);
 | 
			
		||||
    final subtitleColor =
 | 
			
		||||
        Theme.of(context).textTheme.bodyLarge!.color!.withAlpha(50);
 | 
			
		||||
 | 
			
		||||
    return PageTransitionSwitcher(
 | 
			
		||||
      transitionBuilder: (
 | 
			
		||||
@ -65,157 +70,214 @@ class ChatListViewBody extends StatelessWidget {
 | 
			
		||||
              key: Key(controller.activeSpaceId ?? 'Spaces'),
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
          if (controller.waitForFirstSync && client.prevBatch != null) {
 | 
			
		||||
            final rooms = controller.filteredRooms;
 | 
			
		||||
            final displayStoriesHeader = {
 | 
			
		||||
                  ActiveFilter.allChats,
 | 
			
		||||
                  ActiveFilter.messages,
 | 
			
		||||
                }.contains(controller.activeFilter) &&
 | 
			
		||||
                client.storiesRooms.isNotEmpty;
 | 
			
		||||
            return SafeArea(
 | 
			
		||||
              child: CustomScrollView(
 | 
			
		||||
                controller: controller.scrollController,
 | 
			
		||||
                slivers: [
 | 
			
		||||
                  ChatListHeader(controller: controller),
 | 
			
		||||
                  SliverList(
 | 
			
		||||
                    delegate: SliverChildListDelegate(
 | 
			
		||||
                      [
 | 
			
		||||
                        if (controller.isSearchMode) ...[
 | 
			
		||||
                          SearchTitle(
 | 
			
		||||
                            title: L10n.of(context)!.publicRooms,
 | 
			
		||||
                            icon: const Icon(Icons.explore_outlined),
 | 
			
		||||
                          ),
 | 
			
		||||
                          AnimatedContainer(
 | 
			
		||||
                            clipBehavior: Clip.hardEdge,
 | 
			
		||||
                            decoration: const BoxDecoration(),
 | 
			
		||||
                            height: roomSearchResult == null ||
 | 
			
		||||
                                    roomSearchResult.chunk.isEmpty
 | 
			
		||||
                                ? 0
 | 
			
		||||
                                : 106,
 | 
			
		||||
                            duration: FluffyThemes.animationDuration,
 | 
			
		||||
                            curve: FluffyThemes.animationCurve,
 | 
			
		||||
                            child: roomSearchResult == null
 | 
			
		||||
                                ? null
 | 
			
		||||
                                : ListView.builder(
 | 
			
		||||
                                    scrollDirection: Axis.horizontal,
 | 
			
		||||
                                    itemCount: roomSearchResult.chunk.length,
 | 
			
		||||
                                    itemBuilder: (context, i) => _SearchItem(
 | 
			
		||||
                                      title: roomSearchResult.chunk[i].name ??
 | 
			
		||||
                                          roomSearchResult.chunk[i]
 | 
			
		||||
                                              .canonicalAlias?.localpart ??
 | 
			
		||||
                                          L10n.of(context)!.group,
 | 
			
		||||
                                      avatar:
 | 
			
		||||
                                          roomSearchResult.chunk[i].avatarUrl,
 | 
			
		||||
                                      onPressed: () => showAdaptiveBottomSheet(
 | 
			
		||||
                                        context: context,
 | 
			
		||||
                                        builder: (c) => PublicRoomBottomSheet(
 | 
			
		||||
                                          roomAlias: roomSearchResult
 | 
			
		||||
                                                  .chunk[i].canonicalAlias ??
 | 
			
		||||
                                              roomSearchResult.chunk[i].roomId,
 | 
			
		||||
                                          outerContext: context,
 | 
			
		||||
                                          chunk: roomSearchResult.chunk[i],
 | 
			
		||||
                                        ),
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ),
 | 
			
		||||
                          ),
 | 
			
		||||
                          SearchTitle(
 | 
			
		||||
                            title: L10n.of(context)!.users,
 | 
			
		||||
                            icon: const Icon(Icons.group_outlined),
 | 
			
		||||
                          ),
 | 
			
		||||
                          AnimatedContainer(
 | 
			
		||||
                            clipBehavior: Clip.hardEdge,
 | 
			
		||||
                            decoration: const BoxDecoration(),
 | 
			
		||||
                            height: userSearchResult == null ||
 | 
			
		||||
                                    userSearchResult.results.isEmpty
 | 
			
		||||
                                ? 0
 | 
			
		||||
                                : 106,
 | 
			
		||||
                            duration: FluffyThemes.animationDuration,
 | 
			
		||||
                            curve: FluffyThemes.animationCurve,
 | 
			
		||||
                            child: userSearchResult == null
 | 
			
		||||
                                ? null
 | 
			
		||||
                                : ListView.builder(
 | 
			
		||||
                                    scrollDirection: Axis.horizontal,
 | 
			
		||||
                                    itemCount: userSearchResult.results.length,
 | 
			
		||||
                                    itemBuilder: (context, i) => _SearchItem(
 | 
			
		||||
                                      title: userSearchResult
 | 
			
		||||
                                              .results[i].displayName ??
 | 
			
		||||
                                          userSearchResult
 | 
			
		||||
                                              .results[i].userId.localpart ??
 | 
			
		||||
                                          L10n.of(context)!.unknownDevice,
 | 
			
		||||
                                      avatar:
 | 
			
		||||
                                          userSearchResult.results[i].avatarUrl,
 | 
			
		||||
                                      onPressed: () => showAdaptiveBottomSheet(
 | 
			
		||||
                                        context: context,
 | 
			
		||||
                                        builder: (c) => ProfileBottomSheet(
 | 
			
		||||
                                          userId: userSearchResult
 | 
			
		||||
                                              .results[i].userId,
 | 
			
		||||
                                          outerContext: context,
 | 
			
		||||
                                        ),
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ),
 | 
			
		||||
                          ),
 | 
			
		||||
                          SearchTitle(
 | 
			
		||||
                            title: L10n.of(context)!.stories,
 | 
			
		||||
                            icon: const Icon(Icons.camera_alt_outlined),
 | 
			
		||||
                          ),
 | 
			
		||||
                        ],
 | 
			
		||||
                        if (displayStoriesHeader)
 | 
			
		||||
                          StoriesHeader(
 | 
			
		||||
                            key: const Key('stories_header'),
 | 
			
		||||
                            filter: controller.searchController.text,
 | 
			
		||||
                          ),
 | 
			
		||||
                        const ConnectionStatusHeader(),
 | 
			
		||||
          final rooms = controller.filteredRooms;
 | 
			
		||||
          final displayStoriesHeader = {
 | 
			
		||||
                ActiveFilter.allChats,
 | 
			
		||||
                ActiveFilter.messages,
 | 
			
		||||
              }.contains(controller.activeFilter) &&
 | 
			
		||||
              client.storiesRooms.isNotEmpty;
 | 
			
		||||
          return SafeArea(
 | 
			
		||||
            child: CustomScrollView(
 | 
			
		||||
              controller: controller.scrollController,
 | 
			
		||||
              slivers: [
 | 
			
		||||
                ChatListHeader(controller: controller),
 | 
			
		||||
                SliverList(
 | 
			
		||||
                  delegate: SliverChildListDelegate(
 | 
			
		||||
                    [
 | 
			
		||||
                      if (controller.isSearchMode) ...[
 | 
			
		||||
                        SearchTitle(
 | 
			
		||||
                          title: L10n.of(context)!.publicRooms,
 | 
			
		||||
                          icon: const Icon(Icons.explore_outlined),
 | 
			
		||||
                        ),
 | 
			
		||||
                        AnimatedContainer(
 | 
			
		||||
                          height: controller.isTorBrowser ? 64 : 0,
 | 
			
		||||
                          duration: FluffyThemes.animationDuration,
 | 
			
		||||
                          curve: FluffyThemes.animationCurve,
 | 
			
		||||
                          clipBehavior: Clip.hardEdge,
 | 
			
		||||
                          decoration: const BoxDecoration(),
 | 
			
		||||
                          child: Material(
 | 
			
		||||
                            color: Theme.of(context).colorScheme.surface,
 | 
			
		||||
                            child: ListTile(
 | 
			
		||||
                              leading: const Icon(Icons.vpn_key),
 | 
			
		||||
                              title: Text(L10n.of(context)!.dehydrateTor),
 | 
			
		||||
                              subtitle:
 | 
			
		||||
                                  Text(L10n.of(context)!.dehydrateTorLong),
 | 
			
		||||
                              trailing:
 | 
			
		||||
                                  const Icon(Icons.chevron_right_outlined),
 | 
			
		||||
                              onTap: controller.dehydrate,
 | 
			
		||||
                            ),
 | 
			
		||||
                          height: roomSearchResult == null ||
 | 
			
		||||
                                  roomSearchResult.chunk.isEmpty
 | 
			
		||||
                              ? 0
 | 
			
		||||
                              : 106,
 | 
			
		||||
                          duration: FluffyThemes.animationDuration,
 | 
			
		||||
                          curve: FluffyThemes.animationCurve,
 | 
			
		||||
                          child: roomSearchResult == null
 | 
			
		||||
                              ? null
 | 
			
		||||
                              : ListView.builder(
 | 
			
		||||
                                  scrollDirection: Axis.horizontal,
 | 
			
		||||
                                  itemCount: roomSearchResult.chunk.length,
 | 
			
		||||
                                  itemBuilder: (context, i) => _SearchItem(
 | 
			
		||||
                                    title: roomSearchResult.chunk[i].name ??
 | 
			
		||||
                                        roomSearchResult.chunk[i].canonicalAlias
 | 
			
		||||
                                            ?.localpart ??
 | 
			
		||||
                                        L10n.of(context)!.group,
 | 
			
		||||
                                    avatar: roomSearchResult.chunk[i].avatarUrl,
 | 
			
		||||
                                    onPressed: () => showAdaptiveBottomSheet(
 | 
			
		||||
                                      context: context,
 | 
			
		||||
                                      builder: (c) => PublicRoomBottomSheet(
 | 
			
		||||
                                        roomAlias: roomSearchResult
 | 
			
		||||
                                                .chunk[i].canonicalAlias ??
 | 
			
		||||
                                            roomSearchResult.chunk[i].roomId,
 | 
			
		||||
                                        outerContext: context,
 | 
			
		||||
                                        chunk: roomSearchResult.chunk[i],
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ),
 | 
			
		||||
                                ),
 | 
			
		||||
                        ),
 | 
			
		||||
                        SearchTitle(
 | 
			
		||||
                          title: L10n.of(context)!.users,
 | 
			
		||||
                          icon: const Icon(Icons.group_outlined),
 | 
			
		||||
                        ),
 | 
			
		||||
                        AnimatedContainer(
 | 
			
		||||
                          clipBehavior: Clip.hardEdge,
 | 
			
		||||
                          decoration: const BoxDecoration(),
 | 
			
		||||
                          height: userSearchResult == null ||
 | 
			
		||||
                                  userSearchResult.results.isEmpty
 | 
			
		||||
                              ? 0
 | 
			
		||||
                              : 106,
 | 
			
		||||
                          duration: FluffyThemes.animationDuration,
 | 
			
		||||
                          curve: FluffyThemes.animationCurve,
 | 
			
		||||
                          child: userSearchResult == null
 | 
			
		||||
                              ? null
 | 
			
		||||
                              : ListView.builder(
 | 
			
		||||
                                  scrollDirection: Axis.horizontal,
 | 
			
		||||
                                  itemCount: userSearchResult.results.length,
 | 
			
		||||
                                  itemBuilder: (context, i) => _SearchItem(
 | 
			
		||||
                                    title: userSearchResult
 | 
			
		||||
                                            .results[i].displayName ??
 | 
			
		||||
                                        userSearchResult
 | 
			
		||||
                                            .results[i].userId.localpart ??
 | 
			
		||||
                                        L10n.of(context)!.unknownDevice,
 | 
			
		||||
                                    avatar:
 | 
			
		||||
                                        userSearchResult.results[i].avatarUrl,
 | 
			
		||||
                                    onPressed: () => showAdaptiveBottomSheet(
 | 
			
		||||
                                      context: context,
 | 
			
		||||
                                      builder: (c) => ProfileBottomSheet(
 | 
			
		||||
                                        userId:
 | 
			
		||||
                                            userSearchResult.results[i].userId,
 | 
			
		||||
                                        outerContext: context,
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ),
 | 
			
		||||
                                ),
 | 
			
		||||
                        ),
 | 
			
		||||
                        SearchTitle(
 | 
			
		||||
                          title: L10n.of(context)!.stories,
 | 
			
		||||
                          icon: const Icon(Icons.camera_alt_outlined),
 | 
			
		||||
                        ),
 | 
			
		||||
                      ],
 | 
			
		||||
                      if (displayStoriesHeader)
 | 
			
		||||
                        StoriesHeader(
 | 
			
		||||
                          key: const Key('stories_header'),
 | 
			
		||||
                          filter: controller.searchController.text,
 | 
			
		||||
                        ),
 | 
			
		||||
                      const ConnectionStatusHeader(),
 | 
			
		||||
                      AnimatedContainer(
 | 
			
		||||
                        height: controller.isTorBrowser ? 64 : 0,
 | 
			
		||||
                        duration: FluffyThemes.animationDuration,
 | 
			
		||||
                        curve: FluffyThemes.animationCurve,
 | 
			
		||||
                        clipBehavior: Clip.hardEdge,
 | 
			
		||||
                        decoration: const BoxDecoration(),
 | 
			
		||||
                        child: Material(
 | 
			
		||||
                          color: Theme.of(context).colorScheme.surface,
 | 
			
		||||
                          child: ListTile(
 | 
			
		||||
                            leading: const Icon(Icons.vpn_key),
 | 
			
		||||
                            title: Text(L10n.of(context)!.dehydrateTor),
 | 
			
		||||
                            subtitle: Text(L10n.of(context)!.dehydrateTorLong),
 | 
			
		||||
                            trailing: const Icon(Icons.chevron_right_outlined),
 | 
			
		||||
                            onTap: controller.dehydrate,
 | 
			
		||||
                          ),
 | 
			
		||||
                        ),
 | 
			
		||||
                        if (controller.isSearchMode)
 | 
			
		||||
                          SearchTitle(
 | 
			
		||||
                            title: L10n.of(context)!.chats,
 | 
			
		||||
                            icon: const Icon(Icons.forum_outlined),
 | 
			
		||||
                      ),
 | 
			
		||||
                      if (controller.isSearchMode)
 | 
			
		||||
                        SearchTitle(
 | 
			
		||||
                          title: L10n.of(context)!.chats,
 | 
			
		||||
                          icon: const Icon(Icons.forum_outlined),
 | 
			
		||||
                        ),
 | 
			
		||||
                      if (client.prevBatch != null &&
 | 
			
		||||
                          rooms.isEmpty &&
 | 
			
		||||
                          !controller.isSearchMode) ...[
 | 
			
		||||
                        Padding(
 | 
			
		||||
                          padding: const EdgeInsets.all(32.0),
 | 
			
		||||
                          child: Column(
 | 
			
		||||
                            mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
                            children: [
 | 
			
		||||
                              Image.asset(
 | 
			
		||||
                                'assets/start_chat.png',
 | 
			
		||||
                                height: 256,
 | 
			
		||||
                              ),
 | 
			
		||||
                              const Divider(height: 1),
 | 
			
		||||
                            ],
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (rooms.isEmpty && !controller.isSearchMode) ...[
 | 
			
		||||
                          Padding(
 | 
			
		||||
                            padding: const EdgeInsets.all(32.0),
 | 
			
		||||
                            child: Column(
 | 
			
		||||
                              mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
                              children: [
 | 
			
		||||
                                Image.asset(
 | 
			
		||||
                                  'assets/start_chat.png',
 | 
			
		||||
                                  height: 256,
 | 
			
		||||
                                ),
 | 
			
		||||
                                const Divider(height: 1),
 | 
			
		||||
                              ],
 | 
			
		||||
                            ),
 | 
			
		||||
                        ),
 | 
			
		||||
                        Center(
 | 
			
		||||
                          child: StartChatFloatingActionButton(
 | 
			
		||||
                            activeFilter: controller.activeFilter,
 | 
			
		||||
                            roomsIsEmpty: true,
 | 
			
		||||
                            scrolledToTop: controller.scrolledToTop,
 | 
			
		||||
                          ),
 | 
			
		||||
                          Center(
 | 
			
		||||
                            child: StartChatFloatingActionButton(
 | 
			
		||||
                              activeFilter: controller.activeFilter,
 | 
			
		||||
                              roomsIsEmpty: true,
 | 
			
		||||
                              scrolledToTop: controller.scrolledToTop,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        ],
 | 
			
		||||
                        ),
 | 
			
		||||
                      ],
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                if (client.prevBatch == null)
 | 
			
		||||
                  SliverList(
 | 
			
		||||
                    delegate: SliverChildBuilderDelegate(
 | 
			
		||||
                      (context, i) => Opacity(
 | 
			
		||||
                        opacity: (dummyChatCount - i) / dummyChatCount,
 | 
			
		||||
                        child: ListTile(
 | 
			
		||||
                          leading: CircleAvatar(
 | 
			
		||||
                            backgroundColor: titleColor,
 | 
			
		||||
                            child: CircularProgressIndicator(
 | 
			
		||||
                              strokeWidth: 1,
 | 
			
		||||
                              color:
 | 
			
		||||
                                  Theme.of(context).textTheme.bodyLarge!.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),
 | 
			
		||||
                          ),
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      childCount: dummyChatCount,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                if (client.prevBatch != null)
 | 
			
		||||
                  SliverList(
 | 
			
		||||
                    delegate: SliverChildBuilderDelegate(
 | 
			
		||||
                      (BuildContext context, int i) {
 | 
			
		||||
@ -245,68 +307,7 @@ class ChatListViewBody extends StatelessWidget {
 | 
			
		||||
                      childCount: rooms.length,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
          const dummyChatCount = 5;
 | 
			
		||||
          final titleColor =
 | 
			
		||||
              Theme.of(context).textTheme.bodyLarge!.color!.withAlpha(100);
 | 
			
		||||
          final subtitleColor =
 | 
			
		||||
              Theme.of(context).textTheme.bodyLarge!.color!.withAlpha(50);
 | 
			
		||||
          return ListView.builder(
 | 
			
		||||
            key: const Key('dummychats'),
 | 
			
		||||
            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.bodyLarge!.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),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          );
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user