add theming workaround for navigation_rail_m3e

This commit is contained in:
Henry Hiles 2026-08-22 15:12:35 -04:00
commit a090d88a23
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 189 additions and 167 deletions

View file

@ -12,6 +12,9 @@ import "package:nexus/widgets/divider_widget.dart";
import "package:nexus/widgets/join_dialog.dart"; import "package:nexus/widgets/join_dialog.dart";
import "package:nexus/widgets/room_menu.dart"; import "package:nexus/widgets/room_menu.dart";
// Needed for navigation_rail_m3e (#65).
import "package:flutter/material.dart" as old_mat;
class const Sidebar({required final bool isDesktop, super.key}) class const Sidebar({required final bool isDesktop, super.key})
extends HookConsumerWidget { extends HookConsumerWidget {
@override @override
@ -72,126 +75,137 @@ class const Sidebar({required final bool isDesktop, super.key})
shape: Border(), shape: Border(),
child: Row( child: Row(
children: [ children: [
Theme( MaterialUiCompatibilityBridge(
data: Theme.of(context).copyWith( child: Builder(
extensions: [ builder: (context) => old_mat.Theme(
NavigationRailM3ETheme( data: old_mat.Theme.of(context).copyWith(
itemCollapsedHeight: 48, extensions: [
itemVerticalGap: 0, NavigationRailM3ETheme(
itemCollapsedHeight: 48,
itemVerticalGap: 0,
),
],
), ),
], child: Container(
), color: NavigationRailTokensAdapter(context).containerColor,
child: Container( padding: EdgeInsets.only(top: 16),
color: NavigationRailTokensAdapter(context).containerColor, child: NavigationRailM3E(
padding: EdgeInsets.only(top: 16), type: .alwaysCollapse,
child: NavigationRailM3E( labelBehavior: .alwaysHide,
type: .alwaysCollapse, scrollable: true,
labelBehavior: .alwaysHide, onDestinationSelected: (value) {
scrollable: true, selectedSpaceIdNotifier.set(spaces[value].id);
onDestinationSelected: (value) { selectedRoomIdNotifier.set(
selectedSpaceIdNotifier.set(spaces[value].id); spaces[value].children.firstOrNull?.metadata?.id,
selectedRoomIdNotifier.set( );
spaces[value].children.firstOrNull?.metadata?.id, },
); sections: [
}, .new(
sections: [ destinations: spaces
.new( .map(
destinations: spaces (space) => NavigationRailM3EDestination(
.map( badgeCount: switch (space.children
(space) => NavigationRailM3EDestination( .addAll(
badgeCount: switch (space.children space.subSpaces
.addAll( .map((element) => element.children)
space.subSpaces .flattened,
.map((element) => element.children) )
.flattened, .fold(
) 0,
.fold( (previousValue, room) =>
0, previousValue +
(previousValue, room) => (room.metadata?.unreadNotifications ??
previousValue + 0),
(room.metadata?.unreadNotifications ?? 0), )) {
)) { 0 =>
0 => space.children
space.children .addAll(
.addAll( space.subSpaces
space.subSpaces .map(
.map( (element) =>
(element) => element.children, element.children,
) )
.flattened, .flattened,
) )
.any( .any(
(room) => (room) =>
room.metadata?.unreadMessages != room
0, .metadata
) ?.unreadMessages !=
? 0 0,
: null, )
int badgeCount => badgeCount, ? 0
}, : null,
short: true, int badgeCount => badgeCount,
icon: AvatarOrHash( },
height: 28, short: true,
space.room?.metadata?.avatar, icon: AvatarOrHash(
fallback: space.icon == null height: 28,
? null space.room?.metadata?.avatar,
: Icon(space.icon), fallback: space.icon == null
space.title, ? null
), : Icon(space.icon),
label: space.title, space.title,
), ),
) label: space.title,
.toList(), ),
), )
], .toList(),
selectedIndex: selectedIndex,
trailingAtBottom: true,
trailing: Padding(
padding: .symmetric(vertical: 16),
child: Column(
spacing: 8,
children: [
PopupMenuButton(
itemBuilder: (_) => [
PopupMenuItem(
onTap: () => showDialog(
context: context,
builder: (_) => JoinDialog(ref),
),
child: ListTile(
title: Text("Join an existing room (or space)"),
leading: Icon(Icons.numbers),
),
),
PopupMenuItem(
onTap: null,
child: ListTile(
title: Text("Create a new room"),
leading: Icon(Icons.add),
),
),
],
icon: Icon(Icons.add),
),
IconButton(
tooltip: "Explore other rooms",
onPressed: null,
icon: Icon(Icons.explore),
),
IconButton(
tooltip: "Open settings",
onPressed: () => showDialog(
context: context,
builder: (_) => SettingsPage(),
),
icon: Icon(Icons.settings),
), ),
], ],
selectedIndex: selectedIndex,
trailingAtBottom: true,
trailing: Padding(
padding: .symmetric(vertical: 16),
child: Column(
spacing: 8,
children: [
PopupMenuButton(
itemBuilder: (_) => [
PopupMenuItem(
onTap: () => showDialog(
context: context,
builder: (_) => JoinDialog(ref),
),
child: ListTile(
title: Text(
"Join an existing room (or space)",
),
leading: Icon(Icons.numbers),
),
),
PopupMenuItem(
onTap: null,
child: ListTile(
title: Text("Create a new room"),
leading: Icon(Icons.add),
),
),
],
icon: Icon(Icons.add),
),
IconButton(
tooltip: "Explore other rooms",
onPressed: null,
icon: Icon(Icons.explore),
),
IconButton(
tooltip: "Open settings",
onPressed: () => showDialog(
context: context,
builder: (_) => SettingsPage(),
),
icon: Icon(Icons.settings),
),
],
),
),
), ),
), ),
), ),
), ),
), ),
Expanded( Expanded(
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
@ -217,67 +231,75 @@ class const Sidebar({required final bool isDesktop, super.key})
), ),
], ],
), ),
body: Theme( body: MaterialUiCompatibilityBridge(
data: Theme.of(context).copyWith( child: Builder(
extensions: [ builder: (context) => old_mat.Theme(
NavigationRailM3ETheme( data: old_mat.Theme.of(context).copyWith(
itemExpandedHeight: 48, extensions: [
iconLabelGap: 16, NavigationRailM3ETheme(
itemExpandedHeight: 48,
iconLabelGap: 16,
),
],
), ),
], child: NavigationRailM3E(
), expandedWidth: double.infinity,
child: NavigationRailM3E( scrollable: true,
expandedWidth: double.infinity, background: Colors.transparent,
scrollable: true, type: .alwaysExpand,
background: Colors.transparent, selectedIndex: selectedRoomIndex ?? 0,
type: .alwaysExpand, sections: [
selectedIndex: selectedRoomIndex ?? 0, .new(
sections: [ header: selectedSpace.room == null
.new( ? null
header: selectedSpace.room == null : DividerWidget(Text("Rooms")),
? null destinations: roomsToDestinations(
: DividerWidget(Text("Rooms")), selectedSpace.children,
destinations: roomsToDestinations(selectedSpace.children),
),
for (final subSpace in selectedSpace.subSpaces)
.new(
header: DividerWidget(
Row(
mainAxisSize: MainAxisSize.min,
spacing: 8,
children: [
if (subSpace.room.metadata?.avatar != null)
AvatarOrHash(
subSpace.room.metadata?.avatar,
subSpace.room.metadata?.name ??
"Unnamed Room",
height: 16,
),
Flexible(
child: Text(
subSpace.room.metadata?.name ??
"Unnamed Space",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
), ),
), ),
destinations: roomsToDestinations(subSpace.children), for (final subSpace in selectedSpace.subSpaces)
), .new(
], header: DividerWidget(
onDestinationSelected: (value) { Row(
final children = selectedSpace.children.addAll( mainAxisSize: MainAxisSize.min,
selectedSpace.subSpaces spacing: 8,
.map((element) => element.children) children: [
.flattened, if (subSpace.room.metadata?.avatar != null)
); AvatarOrHash(
selectedRoomIdNotifier.set( subSpace.room.metadata?.avatar,
children[value].metadata?.id, // subSpace.room.metadata?.name ??
); "Unnamed Room",
if (!isDesktop) Navigator.of(context).pop(); height: 16,
}, ),
Flexible(
child: Text(
subSpace.room.metadata?.name ??
"Unnamed Space",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
destinations: roomsToDestinations(
subSpace.children,
),
),
],
onDestinationSelected: (value) {
final children = selectedSpace.children.addAll(
selectedSpace.subSpaces
.map((element) => element.children)
.flattened,
);
selectedRoomIdNotifier.set(
children[value].metadata?.id, //
);
if (!isDesktop) Navigator.of(context).pop();
},
),
),
), ),
), ),
), ),

View file

@ -1004,7 +1004,7 @@ packages:
description: description:
path: "packages/navigation_rail_m3e" path: "packages/navigation_rail_m3e"
ref: HEAD ref: HEAD
resolved-ref: c9edb0be7251e1a31e2336444f00557eb93ca09d resolved-ref: da860a413d5cf78b9c9c967215250bcdbfe5191d
url: "https://github.com/Henry-Hiles/material_3_expressive" url: "https://github.com/Henry-Hiles/material_3_expressive"
source: git source: git
version: "0.3.5" version: "0.3.5"