Solian/lib/widgets/navigation/app_navigation_region.dart

126 lines
3.9 KiB
Dart
Raw Normal View History

2024-08-07 10:24:16 +00:00
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';
2024-08-21 11:11:27 +00:00
class AppNavigationRegion extends StatelessWidget {
2024-08-21 09:00:59 +00:00
final bool isCollapsed;
2024-08-07 10:24:16 +00:00
final Function(Channel item) onSelected;
2024-08-21 11:11:27 +00:00
const AppNavigationRegion({
2024-08-21 09:00:59 +00:00
super.key,
required this.onSelected,
this.isCollapsed = false,
});
2024-08-07 10:24:16 +00:00
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);
2024-08-21 09:00:59 +00:00
if (isCollapsed) {
return InkWell(
2024-08-21 11:11:27 +00:00
child: const Icon(Icons.tag_outlined, size: 20).paddingSymmetric(
2024-08-21 09:00:59 +00:00
horizontal: 20,
vertical: 16,
),
onTap: () => _gotoChannel(item),
);
}
2024-08-07 10:24:16 +00:00
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();
2024-08-21 09:00:59 +00:00
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 Tooltip(
message: element.name,
child: _buildEntry(context, element),
);
2024-08-21 09:00:59 +00:00
},
),
],
);
}
2024-08-07 10:24:16 +00:00
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,
2024-08-09 16:51:54 +00:00
initiallyExpanded: true,
2024-08-07 10:24:16 +00:00
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(),
),
2024-08-09 16:51:54 +00:00
const SliverPadding(padding: EdgeInsets.only(bottom: 8)),
2024-08-07 10:24:16 +00:00
],
);
});
}
}