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) {
|
2024-09-08 08:03:50 +00:00
|
|
|
AppRouter.instance.goNamed(
|
2024-08-07 10:24:16 +00:00
|
|
|
'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];
|
2024-08-21 11:35:29 +00:00
|
|
|
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
|
|
|
],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|