💄 Better sidebar navigation
This commit is contained in:
		@@ -52,6 +52,17 @@ class Realm {
 | 
			
		||||
        'is_community': isCommunity,
 | 
			
		||||
        'account_id': accountId,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) {
 | 
			
		||||
    if (other is Realm) {
 | 
			
		||||
      return other.id == id;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode => id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class RealmMember {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,16 +3,15 @@ import 'package:get/get.dart';
 | 
			
		||||
import 'package:solian/models/account_status.dart';
 | 
			
		||||
import 'package:solian/providers/account_status.dart';
 | 
			
		||||
import 'package:solian/providers/auth.dart';
 | 
			
		||||
import 'package:solian/providers/content/channel.dart';
 | 
			
		||||
import 'package:solian/providers/relation.dart';
 | 
			
		||||
import 'package:solian/router.dart';
 | 
			
		||||
import 'package:solian/shells/root_shell.dart';
 | 
			
		||||
import 'package:solian/theme.dart';
 | 
			
		||||
import 'package:solian/widgets/account/account_avatar.dart';
 | 
			
		||||
import 'package:solian/widgets/account/account_status_action.dart';
 | 
			
		||||
import 'package:solian/widgets/channel/channel_list.dart';
 | 
			
		||||
import 'package:solian/widgets/navigation/app_navigation.dart';
 | 
			
		||||
import 'package:badges/badges.dart' as badges;
 | 
			
		||||
import 'package:solian/widgets/navigation/app_navigation_regions.dart';
 | 
			
		||||
 | 
			
		||||
class AppNavigationDrawer extends StatefulWidget {
 | 
			
		||||
  final String? routeName;
 | 
			
		||||
@@ -24,12 +23,8 @@ class AppNavigationDrawer extends StatefulWidget {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
 | 
			
		||||
  int? _selectedIndex = 0;
 | 
			
		||||
 | 
			
		||||
  AccountStatus? _accountStatus;
 | 
			
		||||
 | 
			
		||||
  late final ChannelProvider _channels;
 | 
			
		||||
 | 
			
		||||
  Future<void> _getStatus() async {
 | 
			
		||||
    final StatusProvider provider = Get.find();
 | 
			
		||||
 | 
			
		||||
@@ -41,15 +36,6 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _detectSelectedIndex() {
 | 
			
		||||
    if (widget.routeName == null) return;
 | 
			
		||||
 | 
			
		||||
    final nameList = AppNavigation.destinations.map((x) => x.page).toList();
 | 
			
		||||
    final idx = nameList.indexOf(widget.routeName!);
 | 
			
		||||
 | 
			
		||||
    _selectedIndex = idx != -1 ? idx : null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _closeDrawer() {
 | 
			
		||||
    rootScaffoldKey.currentState!.closeDrawer();
 | 
			
		||||
  }
 | 
			
		||||
@@ -59,7 +45,6 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
 | 
			
		||||
        icon: const Icon(Icons.settings),
 | 
			
		||||
        onPressed: () {
 | 
			
		||||
          AppRouter.instance.pushNamed('settings');
 | 
			
		||||
          setState(() => _selectedIndex = null);
 | 
			
		||||
          _closeDrawer();
 | 
			
		||||
        });
 | 
			
		||||
  }
 | 
			
		||||
@@ -67,175 +52,139 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    _channels = Get.find();
 | 
			
		||||
    _detectSelectedIndex();
 | 
			
		||||
    _getStatus();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void didChangeDependencies() {
 | 
			
		||||
    super.didChangeDependencies();
 | 
			
		||||
    _detectSelectedIndex();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final AuthProvider auth = Get.find();
 | 
			
		||||
 | 
			
		||||
    return NavigationDrawer(
 | 
			
		||||
    return Drawer(
 | 
			
		||||
      backgroundColor:
 | 
			
		||||
          SolianTheme.isLargeScreen(context) ? Colors.transparent : null,
 | 
			
		||||
      selectedIndex: _selectedIndex,
 | 
			
		||||
      onDestinationSelected: (idx) {
 | 
			
		||||
        setState(() => _selectedIndex = idx);
 | 
			
		||||
        AppRouter.instance.goNamed(AppNavigation.destinations[idx].page);
 | 
			
		||||
        _closeDrawer();
 | 
			
		||||
      },
 | 
			
		||||
      children: [
 | 
			
		||||
        Obx(() {
 | 
			
		||||
          if (auth.isAuthorized.isFalse || auth.userProfile.value == null) {
 | 
			
		||||
            return ListTile(
 | 
			
		||||
              contentPadding: const EdgeInsets.symmetric(horizontal: 28),
 | 
			
		||||
              leading: const Icon(Icons.account_circle),
 | 
			
		||||
              title: Text('guest'.tr),
 | 
			
		||||
              subtitle: Text('unsignedIn'.tr),
 | 
			
		||||
              trailing: _buildSettingButton(),
 | 
			
		||||
              onTap: () {
 | 
			
		||||
                AppRouter.instance.goNamed('account');
 | 
			
		||||
                setState(() => _selectedIndex = null);
 | 
			
		||||
                _closeDrawer();
 | 
			
		||||
              },
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          return ListTile(
 | 
			
		||||
            contentPadding: const EdgeInsets.symmetric(horizontal: 24),
 | 
			
		||||
            title: Text(
 | 
			
		||||
              auth.userProfile.value!['nick'],
 | 
			
		||||
              maxLines: 1,
 | 
			
		||||
              overflow: TextOverflow.fade,
 | 
			
		||||
            ),
 | 
			
		||||
            subtitle: Builder(
 | 
			
		||||
              builder: (context) {
 | 
			
		||||
                if (_accountStatus == null) {
 | 
			
		||||
                  return Text('loading'.tr);
 | 
			
		||||
                }
 | 
			
		||||
                final info = StatusProvider.determineStatus(
 | 
			
		||||
                  _accountStatus!,
 | 
			
		||||
      child: SafeArea(
 | 
			
		||||
        child: Column(
 | 
			
		||||
          children: [
 | 
			
		||||
            Obx(() {
 | 
			
		||||
              if (auth.isAuthorized.isFalse || auth.userProfile.value == null) {
 | 
			
		||||
                return ListTile(
 | 
			
		||||
                  contentPadding: const EdgeInsets.symmetric(horizontal: 28),
 | 
			
		||||
                  leading: const Icon(Icons.account_circle),
 | 
			
		||||
                  title: Text('guest'.tr),
 | 
			
		||||
                  subtitle: Text('unsignedIn'.tr),
 | 
			
		||||
                  trailing: _buildSettingButton(),
 | 
			
		||||
                  onTap: () {
 | 
			
		||||
                    AppRouter.instance.goNamed('account');
 | 
			
		||||
                    _closeDrawer();
 | 
			
		||||
                  },
 | 
			
		||||
                );
 | 
			
		||||
                return Text(
 | 
			
		||||
                  info.$3,
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              return ListTile(
 | 
			
		||||
                contentPadding: const EdgeInsets.symmetric(horizontal: 24),
 | 
			
		||||
                title: Text(
 | 
			
		||||
                  auth.userProfile.value!['nick'],
 | 
			
		||||
                  maxLines: 1,
 | 
			
		||||
                  overflow: TextOverflow.fade,
 | 
			
		||||
                );
 | 
			
		||||
              },
 | 
			
		||||
            ),
 | 
			
		||||
            leading: Obx(() {
 | 
			
		||||
              final statusBadgeColor = _accountStatus != null
 | 
			
		||||
                  ? StatusProvider.determineStatus(
 | 
			
		||||
                ),
 | 
			
		||||
                subtitle: Builder(
 | 
			
		||||
                  builder: (context) {
 | 
			
		||||
                    if (_accountStatus == null) {
 | 
			
		||||
                      return Text('loading'.tr);
 | 
			
		||||
                    }
 | 
			
		||||
                    final info = StatusProvider.determineStatus(
 | 
			
		||||
                      _accountStatus!,
 | 
			
		||||
                    ).$2
 | 
			
		||||
                  : Colors.grey;
 | 
			
		||||
 | 
			
		||||
              final RelationshipProvider relations = Get.find();
 | 
			
		||||
              final accountNotifications = relations.friendRequestCount.value;
 | 
			
		||||
 | 
			
		||||
              return badges.Badge(
 | 
			
		||||
                badgeContent: Text(
 | 
			
		||||
                  accountNotifications.toString(),
 | 
			
		||||
                  style: const TextStyle(color: Colors.white),
 | 
			
		||||
                    );
 | 
			
		||||
                    return Text(
 | 
			
		||||
                      info.$3,
 | 
			
		||||
                      maxLines: 1,
 | 
			
		||||
                      overflow: TextOverflow.fade,
 | 
			
		||||
                    );
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
                showBadge: accountNotifications > 0,
 | 
			
		||||
                position: badges.BadgePosition.topEnd(
 | 
			
		||||
                  top: -10,
 | 
			
		||||
                  end: -6,
 | 
			
		||||
                ),
 | 
			
		||||
                child: badges.Badge(
 | 
			
		||||
                  showBadge: _accountStatus != null,
 | 
			
		||||
                  badgeStyle: badges.BadgeStyle(badgeColor: statusBadgeColor),
 | 
			
		||||
                  position: badges.BadgePosition.bottomEnd(
 | 
			
		||||
                    bottom: 0,
 | 
			
		||||
                    end: -2,
 | 
			
		||||
                  ),
 | 
			
		||||
                  child: AccountAvatar(
 | 
			
		||||
                    content: auth.userProfile.value!['avatar'],
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              );
 | 
			
		||||
            }),
 | 
			
		||||
            trailing: _buildSettingButton(),
 | 
			
		||||
            onTap: () {
 | 
			
		||||
              AppRouter.instance.goNamed('account');
 | 
			
		||||
              setState(() => _selectedIndex = null);
 | 
			
		||||
              _closeDrawer();
 | 
			
		||||
            },
 | 
			
		||||
            onLongPress: () {
 | 
			
		||||
              showModalBottomSheet(
 | 
			
		||||
                useRootNavigator: true,
 | 
			
		||||
                context: context,
 | 
			
		||||
                builder: (context) => AccountStatusAction(
 | 
			
		||||
                  currentStatus: _accountStatus!.status,
 | 
			
		||||
                ),
 | 
			
		||||
              ).then((val) {
 | 
			
		||||
                if (val == true) _getStatus();
 | 
			
		||||
              });
 | 
			
		||||
            },
 | 
			
		||||
          );
 | 
			
		||||
        }).paddingOnly(top: 8),
 | 
			
		||||
        const Divider(thickness: 0.3, height: 1).paddingOnly(
 | 
			
		||||
          bottom: 12,
 | 
			
		||||
          top: 8,
 | 
			
		||||
        ),
 | 
			
		||||
        ...AppNavigation.destinations.map(
 | 
			
		||||
          (e) => NavigationDrawerDestination(
 | 
			
		||||
            icon: e.icon,
 | 
			
		||||
            label: Text(e.label),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        const Divider(thickness: 0.3, height: 1).paddingOnly(
 | 
			
		||||
          top: 12,
 | 
			
		||||
        ),
 | 
			
		||||
        Obx(() {
 | 
			
		||||
          if (auth.isAuthorized.isFalse || auth.userProfile.value == null) {
 | 
			
		||||
            return const SizedBox();
 | 
			
		||||
          }
 | 
			
		||||
                leading: Obx(() {
 | 
			
		||||
                  final statusBadgeColor = _accountStatus != null
 | 
			
		||||
                      ? StatusProvider.determineStatus(
 | 
			
		||||
                          _accountStatus!,
 | 
			
		||||
                        ).$2
 | 
			
		||||
                      : Colors.grey;
 | 
			
		||||
 | 
			
		||||
          final selfId = auth.userProfile.value!['id'];
 | 
			
		||||
                  final RelationshipProvider relations = Get.find();
 | 
			
		||||
                  final accountNotifications =
 | 
			
		||||
                      relations.friendRequestCount.value;
 | 
			
		||||
 | 
			
		||||
          return Column(
 | 
			
		||||
            children: [
 | 
			
		||||
              Theme(
 | 
			
		||||
                data: Theme.of(context)
 | 
			
		||||
                    .copyWith(dividerColor: Colors.transparent),
 | 
			
		||||
                child: ExpansionTile(
 | 
			
		||||
                  title: Text('channels'.tr),
 | 
			
		||||
                  tilePadding: const EdgeInsets.symmetric(horizontal: 24),
 | 
			
		||||
                  children: [
 | 
			
		||||
                    Obx(
 | 
			
		||||
                      () => SizedBox(
 | 
			
		||||
                        height: 360,
 | 
			
		||||
                        child: RefreshIndicator(
 | 
			
		||||
                          onRefresh: () => _channels.refreshAvailableChannel(),
 | 
			
		||||
                          child: ChannelListWidget(
 | 
			
		||||
                            channels: _channels.groupChannels,
 | 
			
		||||
                            selfId: selfId,
 | 
			
		||||
                            isDense: true,
 | 
			
		||||
                            useReplace: true,
 | 
			
		||||
                            onSelected: (_) {
 | 
			
		||||
                              setState(() => _selectedIndex = null);
 | 
			
		||||
                              _closeDrawer();
 | 
			
		||||
                            },
 | 
			
		||||
                          ),
 | 
			
		||||
                        ),
 | 
			
		||||
                  return badges.Badge(
 | 
			
		||||
                    badgeContent: Text(
 | 
			
		||||
                      accountNotifications.toString(),
 | 
			
		||||
                      style: const TextStyle(color: Colors.white),
 | 
			
		||||
                    ),
 | 
			
		||||
                    showBadge: accountNotifications > 0,
 | 
			
		||||
                    position: badges.BadgePosition.topEnd(
 | 
			
		||||
                      top: -10,
 | 
			
		||||
                      end: -6,
 | 
			
		||||
                    ),
 | 
			
		||||
                    child: badges.Badge(
 | 
			
		||||
                      showBadge: _accountStatus != null,
 | 
			
		||||
                      badgeStyle:
 | 
			
		||||
                          badges.BadgeStyle(badgeColor: statusBadgeColor),
 | 
			
		||||
                      position: badges.BadgePosition.bottomEnd(
 | 
			
		||||
                        bottom: 0,
 | 
			
		||||
                        end: -2,
 | 
			
		||||
                      ),
 | 
			
		||||
                      child: AccountAvatar(
 | 
			
		||||
                        content: auth.userProfile.value!['avatar'],
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
                  );
 | 
			
		||||
                }),
 | 
			
		||||
                trailing: _buildSettingButton(),
 | 
			
		||||
                onTap: () {
 | 
			
		||||
                  AppRouter.instance.goNamed('account');
 | 
			
		||||
                  _closeDrawer();
 | 
			
		||||
                },
 | 
			
		||||
                onLongPress: () {
 | 
			
		||||
                  showModalBottomSheet(
 | 
			
		||||
                    useRootNavigator: true,
 | 
			
		||||
                    context: context,
 | 
			
		||||
                    builder: (context) => AccountStatusAction(
 | 
			
		||||
                      currentStatus: _accountStatus!.status,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ).then((val) {
 | 
			
		||||
                    if (val == true) _getStatus();
 | 
			
		||||
                  });
 | 
			
		||||
                },
 | 
			
		||||
              );
 | 
			
		||||
            }).paddingOnly(top: 8),
 | 
			
		||||
            const Divider(thickness: 0.3, height: 1),
 | 
			
		||||
            Column(
 | 
			
		||||
              children: AppNavigation.destinations
 | 
			
		||||
                  .map(
 | 
			
		||||
                    (e) => ListTile(
 | 
			
		||||
                      contentPadding: const EdgeInsets.symmetric(
 | 
			
		||||
                        horizontal: 20,
 | 
			
		||||
                      ),
 | 
			
		||||
                      leading: e.icon,
 | 
			
		||||
                      title: Text(e.label),
 | 
			
		||||
                      enabled: true,
 | 
			
		||||
                      onTap: () {
 | 
			
		||||
                        AppRouter.instance.goNamed(e.page);
 | 
			
		||||
                        _closeDrawer();
 | 
			
		||||
                      },
 | 
			
		||||
                    ),
 | 
			
		||||
                  )
 | 
			
		||||
                  .toList(),
 | 
			
		||||
            ).paddingSymmetric(vertical: 8),
 | 
			
		||||
            const Divider(thickness: 0.3, height: 1),
 | 
			
		||||
            Expanded(
 | 
			
		||||
              child: AppNavigationRegions(
 | 
			
		||||
                onSelected: (item) {
 | 
			
		||||
                  _closeDrawer();
 | 
			
		||||
                },
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          );
 | 
			
		||||
        }),
 | 
			
		||||
      ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										87
									
								
								lib/widgets/navigation/app_navigation_regions.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								lib/widgets/navigation/app_navigation_regions.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:get/get.dart';
 | 
			
		||||
import 'package:solian/models/channel.dart';
 | 
			
		||||
import 'package:solian/providers/content/channel.dart';
 | 
			
		||||
import 'package:solian/router.dart';
 | 
			
		||||
import 'package:collection/collection.dart';
 | 
			
		||||
 | 
			
		||||
class AppNavigationRegions extends StatelessWidget {
 | 
			
		||||
  final Function(Channel item) onSelected;
 | 
			
		||||
 | 
			
		||||
  const AppNavigationRegions({super.key, required this.onSelected});
 | 
			
		||||
 | 
			
		||||
  void _gotoChannel(Channel item) {
 | 
			
		||||
    AppRouter.instance.pushReplacementNamed(
 | 
			
		||||
      'channelChat',
 | 
			
		||||
      pathParameters: {'alias': item.alias},
 | 
			
		||||
      queryParameters: {
 | 
			
		||||
        if (item.realmId != null) 'realm': item.realm!.alias,
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    onSelected(item);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildEntry(BuildContext context, Channel item) {
 | 
			
		||||
    const padding = EdgeInsets.symmetric(horizontal: 20);
 | 
			
		||||
 | 
			
		||||
    return ListTile(
 | 
			
		||||
      minTileHeight: 0,
 | 
			
		||||
      leading: const Icon(Icons.tag_outlined),
 | 
			
		||||
      contentPadding: padding,
 | 
			
		||||
      title: Text(item.name),
 | 
			
		||||
      subtitle: Text(
 | 
			
		||||
        item.description,
 | 
			
		||||
        maxLines: 1,
 | 
			
		||||
        overflow: TextOverflow.ellipsis,
 | 
			
		||||
      ),
 | 
			
		||||
      onTap: () => _gotoChannel(item),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final ChannelProvider channels = Get.find();
 | 
			
		||||
 | 
			
		||||
    return Obx(() {
 | 
			
		||||
      final List<Channel> noRealmGroupChannels = channels.availableChannels
 | 
			
		||||
          .where((x) => x.type == 0 && x.realmId == null)
 | 
			
		||||
          .toList();
 | 
			
		||||
      final List<Channel> hasRealmGroupChannels = channels.availableChannels
 | 
			
		||||
          .where((x) => x.type == 0 && x.realmId != null)
 | 
			
		||||
          .toList();
 | 
			
		||||
 | 
			
		||||
      return CustomScrollView(
 | 
			
		||||
        slivers: [
 | 
			
		||||
          const SliverPadding(padding: EdgeInsets.only(top: 8)),
 | 
			
		||||
          SliverList.builder(
 | 
			
		||||
            itemCount: noRealmGroupChannels.length,
 | 
			
		||||
            itemBuilder: (context, index) {
 | 
			
		||||
              final element = noRealmGroupChannels[index];
 | 
			
		||||
              return _buildEntry(context, element);
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
          SliverList.list(
 | 
			
		||||
            children: hasRealmGroupChannels
 | 
			
		||||
                .groupListsBy((x) => x.realm)
 | 
			
		||||
                .entries
 | 
			
		||||
                .map((element) {
 | 
			
		||||
              return ExpansionTile(
 | 
			
		||||
                minTileHeight: 0,
 | 
			
		||||
                tilePadding: const EdgeInsets.only(left: 20, right: 24),
 | 
			
		||||
                backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
 | 
			
		||||
                collapsedBackgroundColor:
 | 
			
		||||
                    Theme.of(context).colorScheme.surfaceContainer,
 | 
			
		||||
                title: Text(element.value.first.realm!.name),
 | 
			
		||||
                leading: const Icon(Icons.workspaces, size: 16)
 | 
			
		||||
                    .paddingSymmetric(horizontal: 4),
 | 
			
		||||
                children:
 | 
			
		||||
                    element.value.map((x) => _buildEntry(context, x)).toList(),
 | 
			
		||||
              );
 | 
			
		||||
            }).toList(),
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -226,7 +226,7 @@ packages:
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.10.0"
 | 
			
		||||
  collection:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: collection
 | 
			
		||||
      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
 | 
			
		||||
@@ -405,10 +405,10 @@ packages:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: file_picker
 | 
			
		||||
      sha256: "824f5b9f389bfc4dddac3dea76cd70c51092d9dff0b2ece7ef4f53db8547d258"
 | 
			
		||||
      sha256: "825aec673606875c33cd8d3c4083f1a3c3999015a84178b317b7ef396b7384f3"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "8.0.6"
 | 
			
		||||
    version: "8.0.7"
 | 
			
		||||
  file_selector_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -740,10 +740,10 @@ packages:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: flutter_webrtc
 | 
			
		||||
      sha256: f46bd76cef6e8d787dc707d0c591f0e89c912a2970c7b5e68a55b9cca1bdde4c
 | 
			
		||||
      sha256: "67faa07cf49392b50b1aa14590a83caa64d2109345fabd29899dcd8da8538348"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.11.6"
 | 
			
		||||
    version: "0.11.6+hotfix.1"
 | 
			
		||||
  font_awesome_flutter:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@@ -788,10 +788,10 @@ packages:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: go_router
 | 
			
		||||
      sha256: d380de0355788c5c784fe9f81b43fc833b903991c25ecc4e2a416a67faefa722
 | 
			
		||||
      sha256: ddc16d34b0d74cb313986918c0f0885a7ba2fc24d8fb8419de75f0015144ccfe
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "14.2.2"
 | 
			
		||||
    version: "14.2.3"
 | 
			
		||||
  graphs:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -876,10 +876,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: image_picker_android
 | 
			
		||||
      sha256: "3fe99e3a459b969f657565a853353bdea7e3d3cae34f7dd124836267d426ec87"
 | 
			
		||||
      sha256: c0e72ecd170b00a5590bb71238d57dc8ad22ee14c60c6b0d1a4e05cafbc5db4b
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.8.12+10"
 | 
			
		||||
    version: "0.8.12+11"
 | 
			
		||||
  image_picker_for_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -1276,10 +1276,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: permission_handler_android
 | 
			
		||||
      sha256: b29a799ca03be9f999aa6c39f7de5209482d638e6f857f6b93b0875c618b7e54
 | 
			
		||||
      sha256: eaf2a1ec4472775451e88ca6a7b86559ef2f1d1ed903942ed135e38ea0097dca
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "12.0.7"
 | 
			
		||||
    version: "12.0.8"
 | 
			
		||||
  permission_handler_apple:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -1300,10 +1300,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: permission_handler_platform_interface
 | 
			
		||||
      sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
 | 
			
		||||
      sha256: fe0ffe274d665be8e34f9c59705441a7d248edebbe5d9e3ec2665f88b79358ea
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.2.1"
 | 
			
		||||
    version: "4.2.2"
 | 
			
		||||
  permission_handler_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -1897,10 +1897,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_web
 | 
			
		||||
      sha256: a36e2d7981122fa185006b216eb6b5b97ede3f9a54b7a511bc966971ab98d049
 | 
			
		||||
      sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.2"
 | 
			
		||||
    version: "2.3.3"
 | 
			
		||||
  url_launcher_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,7 @@ dependencies:
 | 
			
		||||
  async: ^2.11.0
 | 
			
		||||
  field_suggestion: ^0.2.5
 | 
			
		||||
  flutter_typeahead: ^5.2.0
 | 
			
		||||
  collection: ^1.18.0
 | 
			
		||||
 | 
			
		||||
dev_dependencies:
 | 
			
		||||
  flutter_test:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user