Basis collapse sidebar

This commit is contained in:
LittleSheep 2024-08-21 17:00:59 +08:00
parent 0f1a02f65b
commit f834351ce2
2 changed files with 186 additions and 108 deletions

View File

@ -25,6 +25,8 @@ class AppNavigationDrawer extends StatefulWidget {
} }
class _AppNavigationDrawerState extends State<AppNavigationDrawer> { class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
bool _isCollapsed = true;
AccountStatus? _accountStatus; AccountStatus? _accountStatus;
Future<void> _getStatus() async { Future<void> _getStatus() async {
@ -40,42 +42,69 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
} }
} }
void _closeDrawer() { Widget _buildUserInfo() {
rootScaffoldKey.currentState!.closeDrawer(); return Obx(() {
} final AuthProvider auth = Get.find();
if (auth.isAuthorized.isFalse || auth.userProfile.value == null) {
if (_isCollapsed) {
return InkWell(
child: const Icon(Icons.account_circle).paddingAll(28),
onTap: () {
AppRouter.instance.goNamed('account');
_closeDrawer();
},
);
}
@override return ListTile(
void initState() { contentPadding: const EdgeInsets.symmetric(horizontal: 28),
super.initState(); leading: const Icon(Icons.account_circle),
_getStatus(); title: !_isCollapsed ? Text('guest'.tr) : null,
} subtitle: !_isCollapsed ? Text('unsignedIn'.tr) : null,
onTap: () {
AppRouter.instance.goNamed('account');
_closeDrawer();
},
);
}
@override final leading = Obx(() {
Widget build(BuildContext context) { final statusBadgeColor = _accountStatus != null
final AuthProvider auth = Get.find(); ? StatusProvider.determineStatus(
_accountStatus!,
).$2
: Colors.grey;
return Drawer( final RelationshipProvider relations = Get.find();
backgroundColor: final accountNotifications = relations.friendRequestCount.value;
SolianTheme.isLargeScreen(context) ? Colors.transparent : null,
child: SafeArea(
bottom: false,
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),
onTap: () {
AppRouter.instance.goNamed('account');
_closeDrawer();
},
);
}
return ListTile( 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'],
),
),
);
});
return InkWell(
child: !_isCollapsed
? ListTile(
contentPadding: const EdgeInsets.only(left: 20, right: 20), contentPadding: const EdgeInsets.only(left: 20, right: 20),
title: Text( title: Text(
auth.userProfile.value!['nick'], auth.userProfile.value!['nick'],
@ -97,80 +126,83 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
); );
}, },
), ),
leading: Obx(() { leading: leading,
final statusBadgeColor = _accountStatus != null )
? StatusProvider.determineStatus( : leading.paddingAll(20),
_accountStatus!, onTap: () {
).$2 AppRouter.instance.goNamed('account');
: Colors.grey; _closeDrawer();
},
onLongPress: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
builder: (context) => AccountStatusAction(
currentStatus: _accountStatus!.status,
),
).then((val) {
if (val == true) _getStatus();
});
},
);
});
}
final RelationshipProvider relations = Get.find(); void _closeDrawer() {
final accountNotifications = rootScaffoldKey.currentState!.closeDrawer();
relations.friendRequestCount.value; }
return badges.Badge( @override
badgeContent: Text( void initState() {
accountNotifications.toString(), super.initState();
style: const TextStyle(color: Colors.white), _getStatus();
), }
showBadge: accountNotifications > 0,
position: badges.BadgePosition.topEnd( @override
top: -10, Widget build(BuildContext context) {
end: -6, return Drawer(
), width: _isCollapsed ? 80 : null,
child: badges.Badge( backgroundColor:
showBadge: _accountStatus != null, SolianTheme.isLargeScreen(context) ? Colors.transparent : null,
badgeStyle: child: SafeArea(
badges.BadgeStyle(badgeColor: statusBadgeColor), bottom: false,
position: badges.BadgePosition.bottomEnd( child: Column(
bottom: 0, children: [
end: -2, _buildUserInfo().paddingSymmetric(vertical: 8),
),
child: AccountAvatar(
content: auth.userProfile.value!['avatar'],
),
),
);
}),
onTap: () {
AppRouter.instance.goNamed('account');
_closeDrawer();
},
onLongPress: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
builder: (context) => AccountStatusAction(
currentStatus: _accountStatus!.status,
),
).then((val) {
if (val == true) _getStatus();
});
},
);
}).paddingSymmetric(vertical: 8),
const Divider(thickness: 0.3, height: 1), const Divider(thickness: 0.3, height: 1),
Column( Column(
children: AppNavigation.destinations children: AppNavigation.destinations
.map( .map(
(e) => ListTile( (e) => _isCollapsed
contentPadding: const EdgeInsets.symmetric( ? InkWell(
horizontal: 20, child: Icon(e.icon, size: 22).paddingSymmetric(
), horizontal: 28,
leading: Icon(e.icon, size: 20).paddingAll(2), vertical: 16,
title: Text(e.label), ),
enabled: true, onTap: () {
onTap: () { AppRouter.instance.goNamed(e.page);
AppRouter.instance.goNamed(e.page); _closeDrawer();
_closeDrawer(); },
}, )
), : ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
),
leading: Icon(e.icon, size: 20).paddingAll(2),
title: !_isCollapsed ? Text(e.label) : null,
enabled: true,
onTap: () {
AppRouter.instance.goNamed(e.page);
_closeDrawer();
},
),
) )
.toList(), .toList(),
).paddingSymmetric(vertical: 8), ),
const Divider(thickness: 0.3, height: 1), const Divider(thickness: 0.3, height: 1),
Expanded( Expanded(
child: AppNavigationRegions( child: AppNavigationRegions(
isCollapsed: _isCollapsed,
onSelected: (item) { onSelected: (item) {
_closeDrawer(); _closeDrawer();
}, },
@ -179,18 +211,31 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
const Divider(thickness: 0.3, height: 1), const Divider(thickness: 0.3, height: 1),
Column( Column(
children: [ children: [
ListTile( _isCollapsed
minTileHeight: 0, ? InkWell(
contentPadding: const EdgeInsets.symmetric( child: const Icon(Icons.settings, size: 22)
horizontal: 20, .paddingSymmetric(
), horizontal: 28,
leading: const Icon(Icons.settings, size: 20).paddingAll(2), vertical: 16,
title: Text('settings'.tr), ),
onTap: () { onTap: () {
AppRouter.instance.pushNamed('settings'); AppRouter.instance.pushNamed('settings');
_closeDrawer(); _closeDrawer();
}, },
), )
: ListTile(
minTileHeight: 0,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
),
leading:
const Icon(Icons.settings, size: 20).paddingAll(2),
title: Text('settings'.tr),
onTap: () {
AppRouter.instance.pushNamed('settings');
_closeDrawer();
},
),
], ],
).paddingOnly( ).paddingOnly(
top: 8, top: 8,

View File

@ -6,9 +6,14 @@ import 'package:solian/router.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
class AppNavigationRegions extends StatelessWidget { class AppNavigationRegions extends StatelessWidget {
final bool isCollapsed;
final Function(Channel item) onSelected; final Function(Channel item) onSelected;
const AppNavigationRegions({super.key, required this.onSelected}); const AppNavigationRegions({
super.key,
required this.onSelected,
this.isCollapsed = false,
});
void _gotoChannel(Channel item) { void _gotoChannel(Channel item) {
AppRouter.instance.pushReplacementNamed( AppRouter.instance.pushReplacementNamed(
@ -25,6 +30,16 @@ class AppNavigationRegions extends StatelessWidget {
Widget _buildEntry(BuildContext context, Channel item) { Widget _buildEntry(BuildContext context, Channel item) {
const padding = EdgeInsets.symmetric(horizontal: 20); const padding = EdgeInsets.symmetric(horizontal: 20);
if (isCollapsed) {
return InkWell(
child: const Icon(Icons.tag_outlined).paddingSymmetric(
horizontal: 20,
vertical: 16,
),
onTap: () => _gotoChannel(item),
);
}
return ListTile( return ListTile(
minTileHeight: 0, minTileHeight: 0,
leading: const Icon(Icons.tag_outlined), leading: const Icon(Icons.tag_outlined),
@ -51,6 +66,24 @@ class AppNavigationRegions extends StatelessWidget {
.where((x) => x.type == 0 && x.realmId != null) .where((x) => x.type == 0 && x.realmId != null)
.toList(); .toList();
if (isCollapsed) {
return CustomScrollView(
slivers: [
const SliverPadding(padding: EdgeInsets.only(top: 8)),
SliverList.builder(
itemCount:
noRealmGroupChannels.length + hasRealmGroupChannels.length,
itemBuilder: (context, index) {
final element = index >= noRealmGroupChannels.length
? hasRealmGroupChannels[index - noRealmGroupChannels.length]
: noRealmGroupChannels[index];
return _buildEntry(context, element);
},
),
],
);
}
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
const SliverPadding(padding: EdgeInsets.only(top: 8)), const SliverPadding(padding: EdgeInsets.only(top: 8)),