Solian/lib/widgets/navigation/app_navigation_drawer.dart

218 lines
6.7 KiB
Dart
Raw Normal View History

2024-07-12 03:39:44 +00:00
import 'package:flutter/material.dart';
2024-07-12 05:15:46 +00:00
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';
2024-07-12 13:59:16 +00:00
import 'package:solian/providers/content/channel.dart';
2024-07-12 03:39:44 +00:00
import 'package:solian/router.dart';
import 'package:solian/shells/root_shell.dart';
import 'package:solian/theme.dart';
2024-07-12 05:15:46 +00:00
import 'package:solian/widgets/account/account_avatar.dart';
import 'package:solian/widgets/account/account_status_action.dart';
2024-07-12 13:59:16 +00:00
import 'package:solian/widgets/channel/channel_list.dart';
2024-07-12 03:39:44 +00:00
import 'package:solian/widgets/navigation/app_navigation.dart';
2024-07-12 05:15:46 +00:00
import 'package:badges/badges.dart' as badges;
2024-07-12 03:39:44 +00:00
class AppNavigationDrawer extends StatefulWidget {
2024-07-12 05:15:46 +00:00
final String? routeName;
const AppNavigationDrawer({super.key, this.routeName});
2024-07-12 03:39:44 +00:00
@override
State<AppNavigationDrawer> createState() => _AppNavigationDrawerState();
}
class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
2024-07-12 08:19:54 +00:00
int? _selectedIndex = 0;
2024-07-12 13:59:16 +00:00
2024-07-12 05:15:46 +00:00
AccountStatus? _accountStatus;
2024-07-12 13:59:16 +00:00
late final ChannelProvider _channels;
2024-07-12 05:15:46 +00:00
void getStatus() async {
final StatusProvider provider = Get.find();
final resp = await provider.getCurrentStatus();
final status = AccountStatus.fromJson(resp.body);
setState(() {
_accountStatus = status;
});
}
void detectSelectedIndex() {
if (widget.routeName == null) return;
final nameList = AppNavigation.destinations.map((x) => x.page).toList();
final idx = nameList.indexOf(widget.routeName!);
2024-07-12 08:19:54 +00:00
_selectedIndex = idx != -1 ? idx : null;
}
void closeDrawer() {
rootScaffoldKey.currentState!.closeDrawer();
2024-07-12 05:15:46 +00:00
}
@override
void initState() {
super.initState();
2024-07-12 13:59:16 +00:00
_channels = Get.find();
2024-07-12 05:15:46 +00:00
detectSelectedIndex();
getStatus();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
detectSelectedIndex();
}
2024-07-12 03:39:44 +00:00
@override
Widget build(BuildContext context) {
2024-07-12 05:15:46 +00:00
final AuthProvider auth = Get.find();
2024-07-12 03:39:44 +00:00
return NavigationDrawer(
backgroundColor:
SolianTheme.isLargeScreen(context) ? Colors.transparent : null,
2024-07-12 03:39:44 +00:00
selectedIndex: _selectedIndex,
onDestinationSelected: (idx) {
setState(() => _selectedIndex = idx);
AppRouter.instance.goNamed(AppNavigation.destinations[idx].page);
2024-07-12 08:19:54 +00:00
closeDrawer();
2024-07-12 03:39:44 +00:00
},
children: [
2024-07-24 17:18:47 +00:00
Obx(() {
if (auth.isAuthorized.isFalse) {
2024-07-12 08:19:54 +00:00
return ListTile(
2024-07-24 17:18:47 +00:00
contentPadding: const EdgeInsets.symmetric(horizontal: 28),
leading: const Icon(Icons.account_circle),
title: Text('guest'.tr),
subtitle: Text('unsignedIn'.tr),
2024-07-12 08:19:54 +00:00
onTap: () {
AppRouter.instance.goNamed('account');
setState(() => _selectedIndex = null);
2024-07-12 08:19:54 +00:00
closeDrawer();
},
);
2024-07-24 17:18:47 +00:00
}
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!,
);
return Text(
info.$3,
maxLines: 1,
overflow: TextOverflow.fade,
);
},
),
leading: Builder(builder: (context) {
final badgeColor = _accountStatus != null
? StatusProvider.determineStatus(
_accountStatus!,
).$2
: Colors.grey;
return badges.Badge(
showBadge: _accountStatus != null,
badgeStyle: badges.BadgeStyle(badgeColor: badgeColor),
position: badges.BadgePosition.bottomEnd(
bottom: 0,
end: -2,
),
child: AccountAvatar(
content: auth.userProfile.value!['avatar'],
),
);
}),
trailing: IconButton(
icon: const Icon(Icons.face_retouching_natural),
onPressed: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
builder: (context) => AccountStatusAction(
currentStatus: _accountStatus!.status,
),
).then((val) {
if (val == true) getStatus();
});
},
),
onTap: () {
AppRouter.instance.goNamed('account');
setState(() => _selectedIndex = null);
closeDrawer();
},
);
}).paddingOnly(top: 8),
2024-07-12 08:19:54 +00:00
const Divider(thickness: 0.3, height: 1).paddingOnly(
bottom: 12,
top: 8,
),
2024-07-12 03:39:44 +00:00
...AppNavigation.destinations.map(
(e) => NavigationDrawerDestination(
icon: e.icon,
label: Text(e.label),
),
2024-07-12 08:19:54 +00:00
),
const Divider(thickness: 0.3, height: 1).paddingOnly(
top: 12,
2024-07-12 13:59:16 +00:00
),
2024-07-24 17:18:47 +00:00
Obx(() {
if (auth.isAuthorized.isFalse) {
return const SizedBox();
}
final selfId = auth.userProfile.value!['id'];
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();
},
),
2024-07-12 13:59:16 +00:00
),
),
2024-07-24 17:18:47 +00:00
),
],
2024-07-12 13:59:16 +00:00
),
2024-07-24 17:18:47 +00:00
),
],
);
}),
2024-07-12 03:39:44 +00:00
],
);
}
}