✨ Better dashboard design for large screen (and mobile device)
This commit is contained in:
		@@ -72,6 +72,15 @@ class Channel {
 | 
				
			|||||||
        'realm_id': realmId,
 | 
					        'realm_id': realmId,
 | 
				
			||||||
        'is_encrypted': isEncrypted,
 | 
					        'is_encrypted': isEncrypted,
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool operator ==(Object other) {
 | 
				
			||||||
 | 
					    if (other is! Channel) return false;
 | 
				
			||||||
 | 
					    return id == other.id;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  int get hashCode => id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ChannelMember {
 | 
					class ChannelMember {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,14 +12,20 @@ class LastReadProvider extends GetxController {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  set feedLastReadAt(int? value) {
 | 
					  set feedLastReadAt(int? value) {
 | 
				
			||||||
    if (value == _feedLastReadAt) return;
 | 
					    if (value == _feedLastReadAt) return;
 | 
				
			||||||
    _feedLastReadAt = max(_feedLastReadAt ?? 0, value ?? 0);
 | 
					    final newValue = max(_feedLastReadAt ?? 0, value ?? 0);
 | 
				
			||||||
    if (value != _feedLastReadAt) _saveToStorage();
 | 
					    if (newValue != _feedLastReadAt) {
 | 
				
			||||||
 | 
					      _feedLastReadAt = newValue;
 | 
				
			||||||
 | 
					      _saveToStorage();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  set messagesLastReadAt(int? value) {
 | 
					  set messagesLastReadAt(int? value) {
 | 
				
			||||||
    if (value == _messagesLastReadAt) return;
 | 
					    if (value == _messagesLastReadAt) return;
 | 
				
			||||||
    _messagesLastReadAt = max(_messagesLastReadAt ?? 0, value ?? 0);
 | 
					    final newValue = max(_messagesLastReadAt ?? 0, value ?? 0);
 | 
				
			||||||
    if (value != _messagesLastReadAt) _saveToStorage();
 | 
					    if (newValue != _messagesLastReadAt) {
 | 
				
			||||||
 | 
					      _messagesLastReadAt = newValue;
 | 
				
			||||||
 | 
					      _saveToStorage();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LastReadProvider() {
 | 
					  LastReadProvider() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,21 @@
 | 
				
			|||||||
import 'dart:developer';
 | 
					import 'dart:developer';
 | 
				
			||||||
import 'dart:math' hide log;
 | 
					import 'dart:math' hide log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:collection/collection.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart' hide Notification;
 | 
				
			||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
 | 
					import 'package:font_awesome_flutter/font_awesome_flutter.dart';
 | 
				
			||||||
 | 
					import 'package:gap/gap.dart';
 | 
				
			||||||
import 'package:get/get.dart';
 | 
					import 'package:get/get.dart';
 | 
				
			||||||
import 'package:google_fonts/google_fonts.dart';
 | 
					import 'package:google_fonts/google_fonts.dart';
 | 
				
			||||||
import 'package:intl/intl.dart';
 | 
					import 'package:intl/intl.dart';
 | 
				
			||||||
import 'package:solian/exts.dart';
 | 
					import 'package:solian/exts.dart';
 | 
				
			||||||
 | 
					import 'package:solian/models/channel.dart';
 | 
				
			||||||
import 'package:solian/models/daily_sign.dart';
 | 
					import 'package:solian/models/daily_sign.dart';
 | 
				
			||||||
import 'package:solian/models/event.dart';
 | 
					import 'package:solian/models/event.dart';
 | 
				
			||||||
 | 
					import 'package:solian/models/notification.dart';
 | 
				
			||||||
import 'package:solian/models/pagination.dart';
 | 
					import 'package:solian/models/pagination.dart';
 | 
				
			||||||
import 'package:solian/models/post.dart';
 | 
					import 'package:solian/models/post.dart';
 | 
				
			||||||
 | 
					import 'package:solian/providers/auth.dart';
 | 
				
			||||||
import 'package:solian/providers/content/posts.dart';
 | 
					import 'package:solian/providers/content/posts.dart';
 | 
				
			||||||
import 'package:solian/providers/daily_sign.dart';
 | 
					import 'package:solian/providers/daily_sign.dart';
 | 
				
			||||||
import 'package:solian/providers/last_read.dart';
 | 
					import 'package:solian/providers/last_read.dart';
 | 
				
			||||||
@@ -29,6 +34,7 @@ class DashboardScreen extends StatefulWidget {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _DashboardScreenState extends State<DashboardScreen> {
 | 
					class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			||||||
 | 
					  late final AuthProvider _auth = Get.find();
 | 
				
			||||||
  late final LastReadProvider _lastRead = Get.find();
 | 
					  late final LastReadProvider _lastRead = Get.find();
 | 
				
			||||||
  late final WebSocketProvider _ws = Get.find();
 | 
					  late final WebSocketProvider _ws = Get.find();
 | 
				
			||||||
  late final PostProvider _posts = Get.find();
 | 
					  late final PostProvider _posts = Get.find();
 | 
				
			||||||
@@ -37,6 +43,10 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
  Color get _unFocusColor =>
 | 
					  Color get _unFocusColor =>
 | 
				
			||||||
      Theme.of(context).colorScheme.onSurface.withOpacity(0.75);
 | 
					      Theme.of(context).colorScheme.onSurface.withOpacity(0.75);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  List<Notification> get _pendingNotifications =>
 | 
				
			||||||
 | 
					      List<Notification>.from(_ws.notifications)
 | 
				
			||||||
 | 
					        ..sort((a, b) => b.createdAt.compareTo(a.createdAt));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  List<Post>? _currentPosts;
 | 
					  List<Post>? _currentPosts;
 | 
				
			||||||
  int? _currentPostsCount;
 | 
					  int? _currentPostsCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -54,6 +64,9 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
  List<Event>? _currentMessages;
 | 
					  List<Event>? _currentMessages;
 | 
				
			||||||
  int? _currentMessagesCount;
 | 
					  int? _currentMessagesCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Map<Channel, List<Event>>? get _currentGroupedMessages =>
 | 
				
			||||||
 | 
					      _currentMessages?.groupListsBy((x) => x.channel!);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> _pullMessages() async {
 | 
					  Future<void> _pullMessages() async {
 | 
				
			||||||
    if (_lastRead.messagesLastReadAt == null) return;
 | 
					    if (_lastRead.messagesLastReadAt == null) return;
 | 
				
			||||||
    log('[Dashboard] Pulling messages with pivot: ${_lastRead.messagesLastReadAt}');
 | 
					    log('[Dashboard] Pulling messages with pivot: ${_lastRead.messagesLastReadAt}');
 | 
				
			||||||
@@ -90,24 +103,36 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
    setState(() => _signingDaily = false);
 | 
					    setState(() => _signingDaily = false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Future<void> _pullData() async {
 | 
				
			||||||
 | 
					    if (!_auth.isAuthorized.value) return;
 | 
				
			||||||
 | 
					    await Future.wait([
 | 
				
			||||||
 | 
					      _pullPosts(),
 | 
				
			||||||
 | 
					      _pullMessages(),
 | 
				
			||||||
 | 
					      _pullDaily(),
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
    _pullPosts();
 | 
					    _pullData();
 | 
				
			||||||
    _pullMessages();
 | 
					 | 
				
			||||||
    _pullDaily();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    final width = MediaQuery.of(context).size.width;
 | 
					    final width = MediaQuery.of(context).size.width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ListView(
 | 
					    return RefreshIndicator(
 | 
				
			||||||
 | 
					      onRefresh: _pullData,
 | 
				
			||||||
 | 
					      child: ListView(
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
          Column(
 | 
					          Column(
 | 
				
			||||||
            crossAxisAlignment: CrossAxisAlignment.start,
 | 
					            crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
            children: [
 | 
					            children: [
 | 
				
			||||||
            Text('today'.tr, style: Theme.of(context).textTheme.headlineSmall),
 | 
					              Text(
 | 
				
			||||||
 | 
					                'today'.tr,
 | 
				
			||||||
 | 
					                style: Theme.of(context).textTheme.headlineSmall,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
              Text(DateFormat('yyyy/MM/dd').format(DateTime.now())),
 | 
					              Text(DateFormat('yyyy/MM/dd').format(DateTime.now())),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
          ).paddingOnly(top: 8, left: 18, right: 18, bottom: 12),
 | 
					          ).paddingOnly(top: 8, left: 18, right: 18, bottom: 12),
 | 
				
			||||||
@@ -129,8 +154,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                        children: [
 | 
					                        children: [
 | 
				
			||||||
                          Text(
 | 
					                          Text(
 | 
				
			||||||
                            DateFormat('dd').format(DateTime.now()),
 | 
					                            DateFormat('dd').format(DateTime.now()),
 | 
				
			||||||
                          style:
 | 
					                            style: GoogleFonts.robotoMono(
 | 
				
			||||||
                              GoogleFonts.robotoMono(fontSize: 22, height: 1.2),
 | 
					                                fontSize: 22, height: 1.2),
 | 
				
			||||||
                          ),
 | 
					                          ),
 | 
				
			||||||
                          Text(
 | 
					                          Text(
 | 
				
			||||||
                            DateFormat('yy/MM').format(DateTime.now()),
 | 
					                            DateFormat('yy/MM').format(DateTime.now()),
 | 
				
			||||||
@@ -170,6 +195,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ).paddingSymmetric(horizontal: 8),
 | 
					          ).paddingSymmetric(horizontal: 8),
 | 
				
			||||||
          const Divider(thickness: 0.3).paddingSymmetric(vertical: 8),
 | 
					          const Divider(thickness: 0.3).paddingSymmetric(vertical: 8),
 | 
				
			||||||
 | 
					          // Unread notifications
 | 
				
			||||||
          Obx(
 | 
					          Obx(
 | 
				
			||||||
            () => Column(
 | 
					            () => Column(
 | 
				
			||||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
@@ -210,21 +236,25 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                if (_ws.notifications.isNotEmpty)
 | 
					                if (_ws.notifications.isNotEmpty)
 | 
				
			||||||
                  SizedBox(
 | 
					                  SizedBox(
 | 
				
			||||||
                    height: 76,
 | 
					                    height: 76,
 | 
				
			||||||
                  width: width,
 | 
					                    child: ListView.separated(
 | 
				
			||||||
                  child: ListView.builder(
 | 
					 | 
				
			||||||
                      scrollDirection: Axis.horizontal,
 | 
					                      scrollDirection: Axis.horizontal,
 | 
				
			||||||
                    itemCount: min(_ws.notifications.length, 3),
 | 
					                      padding: const EdgeInsets.symmetric(horizontal: 8),
 | 
				
			||||||
 | 
					                      itemCount: min(_pendingNotifications.length, 10),
 | 
				
			||||||
                      itemBuilder: (context, idx) {
 | 
					                      itemBuilder: (context, idx) {
 | 
				
			||||||
                      final x = _ws.notifications[idx];
 | 
					                        final x = _pendingNotifications[idx];
 | 
				
			||||||
                        return SizedBox(
 | 
					                        return SizedBox(
 | 
				
			||||||
                        width: width,
 | 
					                          width: min(360, width),
 | 
				
			||||||
                          child: Card(
 | 
					                          child: Card(
 | 
				
			||||||
                            child: ListTile(
 | 
					                            child: ListTile(
 | 
				
			||||||
                              contentPadding: const EdgeInsets.symmetric(
 | 
					                              contentPadding: const EdgeInsets.symmetric(
 | 
				
			||||||
                                horizontal: 24,
 | 
					                                horizontal: 24,
 | 
				
			||||||
                                vertical: 4,
 | 
					                                vertical: 4,
 | 
				
			||||||
                              ),
 | 
					                              ),
 | 
				
			||||||
                            title: Text(x.title),
 | 
					                              title: Text(
 | 
				
			||||||
 | 
					                                x.title,
 | 
				
			||||||
 | 
					                                maxLines: 1,
 | 
				
			||||||
 | 
					                                overflow: TextOverflow.ellipsis,
 | 
				
			||||||
 | 
					                              ),
 | 
				
			||||||
                              subtitle: Column(
 | 
					                              subtitle: Column(
 | 
				
			||||||
                                crossAxisAlignment: CrossAxisAlignment.start,
 | 
					                                crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
                                children: [
 | 
					                                children: [
 | 
				
			||||||
@@ -233,15 +263,17 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                                ],
 | 
					                                ],
 | 
				
			||||||
                              ),
 | 
					                              ),
 | 
				
			||||||
                            ),
 | 
					                            ),
 | 
				
			||||||
                        ).paddingSymmetric(horizontal: 8),
 | 
					                          ),
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
                      },
 | 
					                      },
 | 
				
			||||||
 | 
					                      separatorBuilder: (_, __) => const Gap(4),
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                  )
 | 
					                  )
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                  Card(
 | 
					                  Card(
 | 
				
			||||||
                    child: ListTile(
 | 
					                    child: ListTile(
 | 
				
			||||||
                    contentPadding: const EdgeInsets.symmetric(horizontal: 24),
 | 
					                      contentPadding:
 | 
				
			||||||
 | 
					                          const EdgeInsets.symmetric(horizontal: 24),
 | 
				
			||||||
                      trailing: const Icon(Icons.inbox_outlined),
 | 
					                      trailing: const Icon(Icons.inbox_outlined),
 | 
				
			||||||
                      title: Text('notifyEmpty'.tr),
 | 
					                      title: Text('notifyEmpty'.tr),
 | 
				
			||||||
                      subtitle: Text('notifyEmptyCaption'.tr),
 | 
					                      subtitle: Text('notifyEmptyCaption'.tr),
 | 
				
			||||||
@@ -250,6 +282,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
              ],
 | 
					              ],
 | 
				
			||||||
            ).paddingOnly(bottom: 12),
 | 
					            ).paddingOnly(bottom: 12),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          /// Unread friends / followed people posts
 | 
				
			||||||
          if (_currentPosts?.isNotEmpty ?? false)
 | 
					          if (_currentPosts?.isNotEmpty ?? false)
 | 
				
			||||||
            Column(
 | 
					            Column(
 | 
				
			||||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
@@ -284,14 +318,13 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                ).paddingOnly(left: 18, right: 18, bottom: 8),
 | 
					                ).paddingOnly(left: 18, right: 18, bottom: 8),
 | 
				
			||||||
                SizedBox(
 | 
					                SizedBox(
 | 
				
			||||||
                  height: 360,
 | 
					                  height: 360,
 | 
				
			||||||
                width: width,
 | 
					 | 
				
			||||||
                  child: ListView.builder(
 | 
					                  child: ListView.builder(
 | 
				
			||||||
                    scrollDirection: Axis.horizontal,
 | 
					                    scrollDirection: Axis.horizontal,
 | 
				
			||||||
                    itemCount: _currentPosts!.length,
 | 
					                    itemCount: _currentPosts!.length,
 | 
				
			||||||
                    itemBuilder: (context, idx) {
 | 
					                    itemBuilder: (context, idx) {
 | 
				
			||||||
                      final item = _currentPosts![idx];
 | 
					                      final item = _currentPosts![idx];
 | 
				
			||||||
                      return SizedBox(
 | 
					                      return SizedBox(
 | 
				
			||||||
                      width: width,
 | 
					                        width: min(480, width),
 | 
				
			||||||
                        child: Card(
 | 
					                        child: Card(
 | 
				
			||||||
                          child: PostListEntryWidget(
 | 
					                          child: PostListEntryWidget(
 | 
				
			||||||
                            item: item,
 | 
					                            item: item,
 | 
				
			||||||
@@ -301,8 +334,9 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                            onUpdate: (_) {
 | 
					                            onUpdate: (_) {
 | 
				
			||||||
                              _pullPosts();
 | 
					                              _pullPosts();
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                          backgroundColor:
 | 
					                            backgroundColor: Theme.of(context)
 | 
				
			||||||
                              Theme.of(context).colorScheme.surfaceContainerLow,
 | 
					                                .colorScheme
 | 
				
			||||||
 | 
					                                .surfaceContainerLow,
 | 
				
			||||||
                          ),
 | 
					                          ),
 | 
				
			||||||
                        ).paddingSymmetric(horizontal: 8),
 | 
					                        ).paddingSymmetric(horizontal: 8),
 | 
				
			||||||
                      );
 | 
					                      );
 | 
				
			||||||
@@ -311,6 +345,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                )
 | 
					                )
 | 
				
			||||||
              ],
 | 
					              ],
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          /// Unread messages part
 | 
				
			||||||
          if (_currentMessages?.isNotEmpty ?? false)
 | 
					          if (_currentMessages?.isNotEmpty ?? false)
 | 
				
			||||||
            Column(
 | 
					            Column(
 | 
				
			||||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
@@ -344,15 +380,17 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                  ],
 | 
					                  ],
 | 
				
			||||||
                ).paddingOnly(left: 18, right: 18, bottom: 8),
 | 
					                ).paddingOnly(left: 18, right: 18, bottom: 8),
 | 
				
			||||||
                SizedBox(
 | 
					                SizedBox(
 | 
				
			||||||
                height: 240,
 | 
					                  height: 360,
 | 
				
			||||||
                width: width,
 | 
					 | 
				
			||||||
                  child: ListView.builder(
 | 
					                  child: ListView.builder(
 | 
				
			||||||
                    scrollDirection: Axis.horizontal,
 | 
					                    scrollDirection: Axis.horizontal,
 | 
				
			||||||
                  itemCount: _currentMessages!.length,
 | 
					                    itemCount: _currentGroupedMessages!.length,
 | 
				
			||||||
                    itemBuilder: (context, idx) {
 | 
					                    itemBuilder: (context, idx) {
 | 
				
			||||||
                    final item = _currentMessages![idx];
 | 
					                      final channel =
 | 
				
			||||||
 | 
					                          _currentGroupedMessages!.keys.elementAt(idx);
 | 
				
			||||||
 | 
					                      final itemList =
 | 
				
			||||||
 | 
					                          _currentGroupedMessages!.values.elementAt(idx);
 | 
				
			||||||
                      return SizedBox(
 | 
					                      return SizedBox(
 | 
				
			||||||
                      width: width,
 | 
					                        width: min(520, width),
 | 
				
			||||||
                        child: Card(
 | 
					                        child: Card(
 | 
				
			||||||
                          child: Column(
 | 
					                          child: Column(
 | 
				
			||||||
                            children: [
 | 
					                            children: [
 | 
				
			||||||
@@ -366,37 +404,45 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
                                  topRight: Radius.circular(8),
 | 
					                                  topRight: Radius.circular(8),
 | 
				
			||||||
                                )),
 | 
					                                )),
 | 
				
			||||||
                                leading: CircleAvatar(
 | 
					                                leading: CircleAvatar(
 | 
				
			||||||
                                backgroundColor: item.channel!.realmId == null
 | 
					                                  backgroundColor: channel.realmId == null
 | 
				
			||||||
                                      ? Theme.of(context).colorScheme.primary
 | 
					                                      ? Theme.of(context).colorScheme.primary
 | 
				
			||||||
                                      : Colors.transparent,
 | 
					                                      : Colors.transparent,
 | 
				
			||||||
                                  radius: 20,
 | 
					                                  radius: 20,
 | 
				
			||||||
                                  child: FaIcon(
 | 
					                                  child: FaIcon(
 | 
				
			||||||
                                    FontAwesomeIcons.hashtag,
 | 
					                                    FontAwesomeIcons.hashtag,
 | 
				
			||||||
                                  color: item.channel!.realmId == null
 | 
					                                    color: channel.realmId == null
 | 
				
			||||||
                                      ? Theme.of(context).colorScheme.onPrimary
 | 
					                                        ? Theme.of(context)
 | 
				
			||||||
 | 
					                                            .colorScheme
 | 
				
			||||||
 | 
					                                            .onPrimary
 | 
				
			||||||
                                        : Theme.of(context).colorScheme.primary,
 | 
					                                        : Theme.of(context).colorScheme.primary,
 | 
				
			||||||
                                    size: 16,
 | 
					                                    size: 16,
 | 
				
			||||||
                                  ),
 | 
					                                  ),
 | 
				
			||||||
                                ),
 | 
					                                ),
 | 
				
			||||||
                                contentPadding:
 | 
					                                contentPadding:
 | 
				
			||||||
                                    const EdgeInsets.symmetric(horizontal: 16),
 | 
					                                    const EdgeInsets.symmetric(horizontal: 16),
 | 
				
			||||||
                              title: Text(item.channel!.name),
 | 
					                                title: Text(channel.name),
 | 
				
			||||||
                              subtitle: Text(item.channel!.description),
 | 
					                                subtitle: Text(channel.description),
 | 
				
			||||||
                                onTap: () {
 | 
					                                onTap: () {
 | 
				
			||||||
                                  AppRouter.instance.pushNamed(
 | 
					                                  AppRouter.instance.pushNamed(
 | 
				
			||||||
                                    'channelChat',
 | 
					                                    'channelChat',
 | 
				
			||||||
                                  pathParameters: {
 | 
					                                    pathParameters: {'alias': channel.alias},
 | 
				
			||||||
                                    'alias': item.channel!.alias
 | 
					 | 
				
			||||||
                                  },
 | 
					 | 
				
			||||||
                                    queryParameters: {
 | 
					                                    queryParameters: {
 | 
				
			||||||
                                    if (item.channel!.realmId != null)
 | 
					                                      if (channel.realmId != null)
 | 
				
			||||||
                                      'realm': item.channel!.realm!.alias,
 | 
					                                        'realm': channel.realm!.alias,
 | 
				
			||||||
                                    },
 | 
					                                    },
 | 
				
			||||||
                                  );
 | 
					                                  );
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                              ),
 | 
					                              ),
 | 
				
			||||||
                            ChatEvent(item: item).paddingOnly(
 | 
					                              Expanded(
 | 
				
			||||||
                                bottom: 8, top: 16, left: 8, right: 8),
 | 
					                                child: ListView.builder(
 | 
				
			||||||
 | 
					                                  itemCount: itemList.length,
 | 
				
			||||||
 | 
					                                  itemBuilder: (context, idx) {
 | 
				
			||||||
 | 
					                                    final item = itemList[idx];
 | 
				
			||||||
 | 
					                                    return ChatEvent(item: item).paddingOnly(
 | 
				
			||||||
 | 
					                                        bottom: 8, top: 16, left: 8, right: 8);
 | 
				
			||||||
 | 
					                                  },
 | 
				
			||||||
 | 
					                                ),
 | 
				
			||||||
 | 
					                              ),
 | 
				
			||||||
                            ],
 | 
					                            ],
 | 
				
			||||||
                          ),
 | 
					                          ),
 | 
				
			||||||
                        ).paddingSymmetric(horizontal: 8),
 | 
					                        ).paddingSymmetric(horizontal: 8),
 | 
				
			||||||
@@ -415,7 +461,13 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
              Text(
 | 
					              Text(
 | 
				
			||||||
                'dashboardFooter'.tr,
 | 
					                'dashboardFooter'.tr,
 | 
				
			||||||
              style: GoogleFonts.notoSerifHk(
 | 
					                style: [const Locale('zh', 'CN'), const Locale('zh', 'HK')]
 | 
				
			||||||
 | 
					                        .contains(Get.deviceLocale)
 | 
				
			||||||
 | 
					                    ? GoogleFonts.notoSerifHk(
 | 
				
			||||||
 | 
					                        color: _unFocusColor,
 | 
				
			||||||
 | 
					                        fontSize: 12,
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
 | 
					                    : TextStyle(
 | 
				
			||||||
                        color: _unFocusColor,
 | 
					                        color: _unFocusColor,
 | 
				
			||||||
                        fontSize: 12,
 | 
					                        fontSize: 12,
 | 
				
			||||||
                      ),
 | 
					                      ),
 | 
				
			||||||
@@ -423,6 +475,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
          ).paddingAll(8),
 | 
					          ).paddingAll(8),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ class AppNavigationDrawer extends StatefulWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class _AppNavigationDrawerState extends State<AppNavigationDrawer>
 | 
					class _AppNavigationDrawerState extends State<AppNavigationDrawer>
 | 
				
			||||||
    with TickerProviderStateMixin {
 | 
					    with TickerProviderStateMixin {
 | 
				
			||||||
  bool _isCollapsed = false;
 | 
					  bool _isCollapsed = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  late final AnimationController _drawerAnimationController =
 | 
					  late final AnimationController _drawerAnimationController =
 | 
				
			||||||
      AnimationController(
 | 
					      AnimationController(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -885,6 +885,14 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.3.0"
 | 
					    version: "2.3.0"
 | 
				
			||||||
 | 
					  gap:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: gap
 | 
				
			||||||
 | 
					      sha256: f19387d4e32f849394758b91377f9153a1b41d79513ef7668c088c77dbc6955d
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "3.0.1"
 | 
				
			||||||
  get:
 | 
					  get:
 | 
				
			||||||
    dependency: "direct main"
 | 
					    dependency: "direct main"
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,6 +76,7 @@ dependencies:
 | 
				
			|||||||
  google_fonts: ^6.2.1
 | 
					  google_fonts: ^6.2.1
 | 
				
			||||||
  freezed_annotation: ^2.4.4
 | 
					  freezed_annotation: ^2.4.4
 | 
				
			||||||
  json_annotation: ^4.9.0
 | 
					  json_annotation: ^4.9.0
 | 
				
			||||||
 | 
					  gap: ^3.0.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dev_dependencies:
 | 
					dev_dependencies:
 | 
				
			||||||
  flutter_test:
 | 
					  flutter_test:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user