157 lines
6.5 KiB
Dart
157 lines
6.5 KiB
Dart
import "package:collection/collection.dart";
|
|
import "package:flutter/material.dart";
|
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
|
import "package:nexus/controllers/current_room_controller.dart";
|
|
import "package:nexus/controllers/selected_room_controller.dart";
|
|
import "package:nexus/controllers/selected_space_controller.dart";
|
|
import "package:nexus/controllers/spaces_controller.dart";
|
|
import "package:nexus/helpers/extension_helper.dart";
|
|
import "package:nexus/pages/settings_page.dart";
|
|
import "package:nexus/widgets/avatar_or_hash.dart";
|
|
|
|
class Sidebar extends HookConsumerWidget {
|
|
const Sidebar({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final selectedSpaceProvider = SelectedSpaceController.provider;
|
|
final selectedSpace = ref.watch(selectedSpaceProvider);
|
|
final selectedSpaceNotifier = ref.watch(selectedSpaceProvider.notifier);
|
|
|
|
final selectedRoomController = SelectedRoomController.provider;
|
|
final selectedRoom = ref.watch(selectedRoomController);
|
|
final selectedRoomNotifier = ref.watch(selectedRoomController.notifier);
|
|
|
|
return Drawer(
|
|
shape: Border(),
|
|
child: Row(
|
|
children: [
|
|
ref
|
|
.watch(SpacesController.provider)
|
|
.when(
|
|
loading: SizedBox.shrink,
|
|
error: (error, stack) {
|
|
debugPrintStack(label: error.toString(), stackTrace: stack);
|
|
throw error;
|
|
},
|
|
data: (spaces) => NavigationRail(
|
|
scrollable: true,
|
|
onDestinationSelected: (value) {
|
|
selectedRoomNotifier.set(0);
|
|
selectedSpaceNotifier.set(value);
|
|
ref
|
|
.watch(CurrentRoomController.provider.notifier)
|
|
.set(spaces[value].children[0]);
|
|
},
|
|
destinations: spaces
|
|
.map(
|
|
(space) => NavigationRailDestination(
|
|
icon: AvatarOrHash(
|
|
space.avatar,
|
|
fallback: space.icon,
|
|
space.title,
|
|
headers: space.client.headers,
|
|
hasBadge:
|
|
space.children.firstWhereOrNull(
|
|
(room) => room.roomData.hasNewMessages,
|
|
) !=
|
|
null,
|
|
),
|
|
label: Text(space.title),
|
|
padding: EdgeInsets.only(top: 4),
|
|
),
|
|
)
|
|
.toList(),
|
|
selectedIndex: selectedSpace,
|
|
trailingAtBottom: true,
|
|
trailing: Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 16),
|
|
child: Column(
|
|
spacing: 8,
|
|
children: [
|
|
IconButton(
|
|
onPressed: () => Navigator.of(context).push(
|
|
// TODO: join or create room/space
|
|
MaterialPageRoute(builder: (_) => SettingsPage()),
|
|
),
|
|
icon: Icon(Icons.add),
|
|
),
|
|
IconButton(
|
|
onPressed: () => Navigator.of(context).push(
|
|
// TODO: explore public rooms/spaces
|
|
MaterialPageRoute(builder: (_) => SettingsPage()),
|
|
),
|
|
icon: Icon(Icons.explore),
|
|
),
|
|
IconButton(
|
|
onPressed: () => Navigator.of(context).push(
|
|
// TODO: explore public rooms/spaces
|
|
MaterialPageRoute(builder: (_) => SettingsPage()),
|
|
),
|
|
icon: Icon(Icons.settings),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: ref
|
|
.watch(SpacesController.provider)
|
|
.betterWhen(
|
|
data: (spaces) {
|
|
final space = spaces[selectedSpace];
|
|
return Scaffold(
|
|
backgroundColor: Colors.transparent,
|
|
appBar: AppBar(
|
|
leading: AvatarOrHash(
|
|
space.avatar,
|
|
fallback: space.icon,
|
|
space.title,
|
|
headers: space.client.headers,
|
|
),
|
|
title: Text(
|
|
space.title,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
backgroundColor: Colors.transparent,
|
|
),
|
|
body: NavigationRail(
|
|
scrollable: true,
|
|
backgroundColor: Colors.transparent,
|
|
extended: true,
|
|
selectedIndex: space.children.isEmpty
|
|
? null
|
|
: selectedRoom,
|
|
destinations: space.children
|
|
.map(
|
|
(room) => NavigationRailDestination(
|
|
label: Text(room.title),
|
|
icon: AvatarOrHash(
|
|
hasBadge: room.roomData.hasNewMessages,
|
|
room.avatar,
|
|
room.title,
|
|
fallback: selectedSpace == 1
|
|
? null
|
|
: Icon(Icons.numbers),
|
|
headers: space.client.headers,
|
|
),
|
|
),
|
|
)
|
|
.toList(),
|
|
onDestinationSelected: (value) {
|
|
selectedRoomNotifier.set(value);
|
|
ref
|
|
.watch(CurrentRoomController.provider.notifier)
|
|
.set(space.children[value]);
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|