mirror of
https://github.com/krille-chan/fluffychat
synced 2024-09-19 03:35:12 +00:00
chore: Bring back navrail
This commit is contained in:
parent
282188f574
commit
b05eb891a6
11 changed files with 332 additions and 135 deletions
|
@ -92,8 +92,12 @@ abstract class AppRoutes {
|
||||||
FluffyThemes.isColumnMode(context) &&
|
FluffyThemes.isColumnMode(context) &&
|
||||||
state.fullPath?.startsWith('/rooms/settings') == false
|
state.fullPath?.startsWith('/rooms/settings') == false
|
||||||
? TwoColumnLayout(
|
? TwoColumnLayout(
|
||||||
|
displayNavigationRail:
|
||||||
|
state.path?.startsWith('/rooms/settings') != true,
|
||||||
mainView: ChatList(
|
mainView: ChatList(
|
||||||
activeChat: state.pathParameters['roomid'],
|
activeChat: state.pathParameters['roomid'],
|
||||||
|
displayNavigationRail:
|
||||||
|
state.path?.startsWith('/rooms/settings') != true,
|
||||||
),
|
),
|
||||||
sideView: child,
|
sideView: child,
|
||||||
)
|
)
|
||||||
|
@ -171,6 +175,7 @@ abstract class AppRoutes {
|
||||||
? TwoColumnLayout(
|
? TwoColumnLayout(
|
||||||
mainView: const Settings(),
|
mainView: const Settings(),
|
||||||
sideView: child,
|
sideView: child,
|
||||||
|
displayNavigationRail: false,
|
||||||
)
|
)
|
||||||
: child,
|
: child,
|
||||||
),
|
),
|
||||||
|
|
|
@ -182,10 +182,17 @@ class ChatView extends StatelessWidget {
|
||||||
tooltip: L10n.of(context)!.close,
|
tooltip: L10n.of(context)!.close,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
)
|
)
|
||||||
: UnreadRoomsBadge(
|
: StreamBuilder<Object>(
|
||||||
filter: (r) => r.id != controller.roomId,
|
stream: Matrix.of(context)
|
||||||
badgePosition: BadgePosition.topEnd(end: 8, top: 4),
|
.client
|
||||||
child: const Center(child: BackButton()),
|
.onSync
|
||||||
|
.stream
|
||||||
|
.where((syncUpdate) => syncUpdate.hasRoomUpdate),
|
||||||
|
builder: (context, _) => UnreadRoomsBadge(
|
||||||
|
filter: (r) => r.id != controller.roomId,
|
||||||
|
badgePosition: BadgePosition.topEnd(end: 8, top: 4),
|
||||||
|
child: const Center(child: BackButton()),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
titleSpacing: 0,
|
titleSpacing: 0,
|
||||||
title: ChatAppBarTitle(controller),
|
title: ChatAppBarTitle(controller),
|
||||||
|
|
|
@ -73,10 +73,12 @@ extension LocalizedActiveFilter on ActiveFilter {
|
||||||
class ChatList extends StatefulWidget {
|
class ChatList extends StatefulWidget {
|
||||||
static BuildContext? contextForVoip;
|
static BuildContext? contextForVoip;
|
||||||
final String? activeChat;
|
final String? activeChat;
|
||||||
|
final bool displayNavigationRail;
|
||||||
|
|
||||||
const ChatList({
|
const ChatList({
|
||||||
super.key,
|
super.key,
|
||||||
required this.activeChat,
|
required this.activeChat,
|
||||||
|
this.displayNavigationRail = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -667,7 +669,11 @@ class ChatListController extends State<ChatList>
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.navigate_next_outlined),
|
Avatar(
|
||||||
|
mxContent: space.avatar,
|
||||||
|
size: Avatar.defaultSize / 2,
|
||||||
|
name: space.getLocalizedDisplayname(),
|
||||||
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
|
@ -168,7 +168,8 @@ class ChatListViewBody extends StatelessWidget {
|
||||||
ActiveFilter.allChats,
|
ActiveFilter.allChats,
|
||||||
ActiveFilter.unread,
|
ActiveFilter.unread,
|
||||||
ActiveFilter.groups,
|
ActiveFilter.groups,
|
||||||
if (spaceDelegateCandidates.isNotEmpty)
|
if (spaceDelegateCandidates.isNotEmpty &&
|
||||||
|
!controller.widget.displayNavigationRail)
|
||||||
ActiveFilter.spaces,
|
ActiveFilter.spaces,
|
||||||
]
|
]
|
||||||
.map(
|
.map(
|
||||||
|
|
|
@ -171,12 +171,12 @@ class ChatListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
top: -2,
|
top: 0,
|
||||||
right: -2,
|
right: 0,
|
||||||
child: AnimatedScale(
|
child: AnimatedScale(
|
||||||
duration: FluffyThemes.animationDuration,
|
duration: FluffyThemes.animationDuration,
|
||||||
curve: FluffyThemes.animationCurve,
|
curve: FluffyThemes.animationCurve,
|
||||||
scale: listTileHovered ? 1.1 : 1.0,
|
scale: listTileHovered ? 1.0 : 0.0,
|
||||||
child: Material(
|
child: Material(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
|
|
@ -5,7 +5,12 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:keyboard_shortcuts/keyboard_shortcuts.dart';
|
import 'package:keyboard_shortcuts/keyboard_shortcuts.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
||||||
|
import 'package:fluffychat/pages/chat_list/navi_rail_item.dart';
|
||||||
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import '../../widgets/matrix.dart';
|
import '../../widgets/matrix.dart';
|
||||||
import 'chat_list_body.dart';
|
import 'chat_list_body.dart';
|
||||||
|
|
||||||
|
@ -35,32 +40,113 @@ class ChatListView extends StatelessWidget {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: GestureDetector(
|
child: Row(
|
||||||
onTap: FocusManager.instance.primaryFocus?.unfocus,
|
children: [
|
||||||
excludeFromSemantics: true,
|
if (FluffyThemes.isColumnMode(context) &&
|
||||||
behavior: HitTestBehavior.translucent,
|
controller.widget.displayNavigationRail) ...[
|
||||||
child: Scaffold(
|
Builder(
|
||||||
body: ChatListViewBody(controller),
|
builder: (context) {
|
||||||
floatingActionButton: KeyBoardShortcuts(
|
final allSpaces = Matrix.of(context)
|
||||||
keysToPress: {
|
.client
|
||||||
LogicalKeyboardKey.controlLeft,
|
.rooms
|
||||||
LogicalKeyboardKey.keyN,
|
.where((room) => room.isSpace);
|
||||||
},
|
final rootSpaces = allSpaces
|
||||||
onKeysPressed: () => context.go('/rooms/newprivatechat'),
|
.where(
|
||||||
helpLabel: L10n.of(context)!.newChat,
|
(space) => !allSpaces.any(
|
||||||
child:
|
(parentSpace) => parentSpace.spaceChildren
|
||||||
selectMode == SelectMode.normal && !controller.isSearchMode
|
.any((child) => child.roomId == space.id),
|
||||||
? FloatingActionButton.extended(
|
),
|
||||||
onPressed: controller.addChatAction,
|
)
|
||||||
icon: const Icon(Icons.add_outlined),
|
.toList();
|
||||||
label: Text(
|
|
||||||
L10n.of(context)!.chat,
|
return SizedBox(
|
||||||
overflow: TextOverflow.fade,
|
width: FluffyThemes.navRailWidth,
|
||||||
|
child: ListView.builder(
|
||||||
|
scrollDirection: Axis.vertical,
|
||||||
|
itemCount: rootSpaces.length + 2,
|
||||||
|
itemBuilder: (context, i) {
|
||||||
|
if (i == 0) {
|
||||||
|
return NaviRailItem(
|
||||||
|
isSelected: controller.activeSpaceId == null,
|
||||||
|
onTap: controller.clearActiveSpace,
|
||||||
|
icon: const Icon(Icons.forum_outlined),
|
||||||
|
selectedIcon: const Icon(Icons.forum),
|
||||||
|
toolTip: L10n.of(context)!.chats,
|
||||||
|
unreadBadgeFilter: (room) => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
if (i == rootSpaces.length) {
|
||||||
|
return NaviRailItem(
|
||||||
|
isSelected: false,
|
||||||
|
onTap: () => context.go('/rooms/newspace'),
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
toolTip: L10n.of(context)!.createNewSpace,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final space = rootSpaces[i];
|
||||||
|
final displayname =
|
||||||
|
rootSpaces[i].getLocalizedDisplayname(
|
||||||
|
MatrixLocals(L10n.of(context)!),
|
||||||
|
);
|
||||||
|
final spaceChildrenIds =
|
||||||
|
space.spaceChildren.map((c) => c.roomId).toSet();
|
||||||
|
return NaviRailItem(
|
||||||
|
toolTip: displayname,
|
||||||
|
isSelected: controller.activeSpaceId == space.id,
|
||||||
|
onTap: () =>
|
||||||
|
controller.setActiveSpace(rootSpaces[i].id),
|
||||||
|
unreadBadgeFilter: (room) =>
|
||||||
|
spaceChildrenIds.contains(room.id),
|
||||||
|
icon: Avatar(
|
||||||
|
mxContent: rootSpaces[i].avatar,
|
||||||
|
name: displayname,
|
||||||
|
size: 32,
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
AppConfig.borderRadius / 4,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
);
|
||||||
: const SizedBox.shrink(),
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
color: Theme.of(context).dividerColor,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: FocusManager.instance.primaryFocus?.unfocus,
|
||||||
|
excludeFromSemantics: true,
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
|
child: Scaffold(
|
||||||
|
body: ChatListViewBody(controller),
|
||||||
|
floatingActionButton: KeyBoardShortcuts(
|
||||||
|
keysToPress: {
|
||||||
|
LogicalKeyboardKey.controlLeft,
|
||||||
|
LogicalKeyboardKey.keyN,
|
||||||
|
},
|
||||||
|
onKeysPressed: () => context.go('/rooms/newprivatechat'),
|
||||||
|
helpLabel: L10n.of(context)!.newChat,
|
||||||
|
child: selectMode == SelectMode.normal &&
|
||||||
|
!controller.isSearchMode
|
||||||
|
? FloatingActionButton.extended(
|
||||||
|
onPressed: controller.addChatAction,
|
||||||
|
icon: const Icon(Icons.add_outlined),
|
||||||
|
label: Text(
|
||||||
|
L10n.of(context)!.chat,
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
95
lib/pages/chat_list/nav_rail_item.dart
Normal file
95
lib/pages/chat_list/nav_rail_item.dart
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import '../../config/themes.dart';
|
||||||
|
|
||||||
|
class NaviRailItem extends StatefulWidget {
|
||||||
|
final String toolTip;
|
||||||
|
final bool isSelected;
|
||||||
|
final void Function() onTap;
|
||||||
|
final Widget icon;
|
||||||
|
final Widget? selectedIcon;
|
||||||
|
|
||||||
|
const NaviRailItem({
|
||||||
|
required this.toolTip,
|
||||||
|
required this.isSelected,
|
||||||
|
required this.onTap,
|
||||||
|
required this.icon,
|
||||||
|
this.selectedIcon,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NaviRailItem> createState() => _NaviRailItemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NaviRailItemState extends State<NaviRailItem> {
|
||||||
|
bool _hovered = false;
|
||||||
|
|
||||||
|
void _onHover(bool hover) {
|
||||||
|
if (hover == _hovered) return;
|
||||||
|
setState(() {
|
||||||
|
_hovered = hover;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final borderRadius = BorderRadius.circular(AppConfig.borderRadius);
|
||||||
|
return SizedBox(
|
||||||
|
height: 64,
|
||||||
|
width: 64,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: 16,
|
||||||
|
bottom: 16,
|
||||||
|
left: 0,
|
||||||
|
child: AnimatedContainer(
|
||||||
|
width: widget.isSelected ? 4 : 0,
|
||||||
|
duration: FluffyThemes.animationDuration,
|
||||||
|
curve: FluffyThemes.animationCurve,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(90),
|
||||||
|
bottomRight: Radius.circular(90),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: AnimatedScale(
|
||||||
|
scale: _hovered ? 1.2 : 1.0,
|
||||||
|
duration: FluffyThemes.animationDuration,
|
||||||
|
curve: FluffyThemes.animationCurve,
|
||||||
|
child: Material(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
color: widget.isSelected
|
||||||
|
? Theme.of(context).colorScheme.primaryContainer
|
||||||
|
: Theme.of(context).colorScheme.surface,
|
||||||
|
child: Tooltip(
|
||||||
|
message: widget.toolTip,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
onTap: widget.onTap,
|
||||||
|
onHover: _onHover,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8.0,
|
||||||
|
vertical: 8.0,
|
||||||
|
),
|
||||||
|
child: widget.isSelected
|
||||||
|
? widget.selectedIcon ?? widget.icon
|
||||||
|
: widget.icon,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,20 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:badges/badges.dart';
|
||||||
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/widgets/hover_builder.dart';
|
||||||
|
import 'package:fluffychat/widgets/unread_rooms_badge.dart';
|
||||||
import '../../config/themes.dart';
|
import '../../config/themes.dart';
|
||||||
|
|
||||||
class NaviRailItem extends StatefulWidget {
|
class NaviRailItem extends StatelessWidget {
|
||||||
final String toolTip;
|
final String toolTip;
|
||||||
final bool isSelected;
|
final bool isSelected;
|
||||||
final void Function() onTap;
|
final void Function() onTap;
|
||||||
final Widget icon;
|
final Widget icon;
|
||||||
final Widget? selectedIcon;
|
final Widget? selectedIcon;
|
||||||
|
final bool Function(Room)? unreadBadgeFilter;
|
||||||
|
|
||||||
const NaviRailItem({
|
const NaviRailItem({
|
||||||
required this.toolTip,
|
required this.toolTip,
|
||||||
|
@ -16,80 +22,78 @@ class NaviRailItem extends StatefulWidget {
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
this.selectedIcon,
|
this.selectedIcon,
|
||||||
|
this.unreadBadgeFilter,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
State<NaviRailItem> createState() => _NaviRailItemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _NaviRailItemState extends State<NaviRailItem> {
|
|
||||||
bool _hovered = false;
|
|
||||||
|
|
||||||
void _onHover(bool hover) {
|
|
||||||
if (hover == _hovered) return;
|
|
||||||
setState(() {
|
|
||||||
_hovered = hover;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final borderRadius = BorderRadius.circular(AppConfig.borderRadius);
|
final borderRadius = BorderRadius.circular(AppConfig.borderRadius);
|
||||||
return SizedBox(
|
final icon = isSelected ? selectedIcon ?? this.icon : this.icon;
|
||||||
height: 64,
|
final unreadBadgeFilter = this.unreadBadgeFilter;
|
||||||
width: 64,
|
return HoverBuilder(
|
||||||
child: Stack(
|
builder: (context, hovered) {
|
||||||
children: [
|
return SizedBox(
|
||||||
Positioned(
|
height: 64,
|
||||||
top: 16,
|
width: 64,
|
||||||
bottom: 16,
|
child: Stack(
|
||||||
left: 0,
|
children: [
|
||||||
child: AnimatedContainer(
|
Positioned(
|
||||||
width: widget.isSelected ? 4 : 0,
|
top: 16,
|
||||||
duration: FluffyThemes.animationDuration,
|
bottom: 16,
|
||||||
curve: FluffyThemes.animationCurve,
|
left: 0,
|
||||||
decoration: BoxDecoration(
|
child: AnimatedContainer(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
width: isSelected ? 4 : 0,
|
||||||
borderRadius: const BorderRadius.only(
|
duration: FluffyThemes.animationDuration,
|
||||||
topRight: Radius.circular(90),
|
curve: FluffyThemes.animationCurve,
|
||||||
bottomRight: Radius.circular(90),
|
decoration: BoxDecoration(
|
||||||
),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
borderRadius: const BorderRadius.only(
|
||||||
),
|
topRight: Radius.circular(90),
|
||||||
),
|
bottomRight: Radius.circular(90),
|
||||||
Center(
|
|
||||||
child: AnimatedScale(
|
|
||||||
scale: _hovered ? 1.2 : 1.0,
|
|
||||||
duration: FluffyThemes.animationDuration,
|
|
||||||
curve: FluffyThemes.animationCurve,
|
|
||||||
child: Material(
|
|
||||||
borderRadius: borderRadius,
|
|
||||||
color: widget.isSelected
|
|
||||||
? Theme.of(context).colorScheme.primaryContainer
|
|
||||||
: Theme.of(context).colorScheme.surface,
|
|
||||||
child: Tooltip(
|
|
||||||
message: widget.toolTip,
|
|
||||||
child: InkWell(
|
|
||||||
borderRadius: borderRadius,
|
|
||||||
onTap: widget.onTap,
|
|
||||||
onHover: _onHover,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 8.0,
|
|
||||||
vertical: 8.0,
|
|
||||||
),
|
|
||||||
child: widget.isSelected
|
|
||||||
? widget.selectedIcon ?? widget.icon
|
|
||||||
: widget.icon,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Center(
|
||||||
|
child: AnimatedScale(
|
||||||
|
scale: hovered ? 1.2 : 1.0,
|
||||||
|
duration: FluffyThemes.animationDuration,
|
||||||
|
curve: FluffyThemes.animationCurve,
|
||||||
|
child: Material(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
color: isSelected
|
||||||
|
? Theme.of(context).colorScheme.primaryContainer
|
||||||
|
: Theme.of(context).colorScheme.surface,
|
||||||
|
child: Tooltip(
|
||||||
|
message: toolTip,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
onTap: onTap,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8.0,
|
||||||
|
vertical: 8.0,
|
||||||
|
),
|
||||||
|
child: unreadBadgeFilter == null
|
||||||
|
? icon
|
||||||
|
: UnreadRoomsBadge(
|
||||||
|
filter: unreadBadgeFilter,
|
||||||
|
badgePosition: BadgePosition.topEnd(
|
||||||
|
top: -12,
|
||||||
|
end: -8,
|
||||||
|
),
|
||||||
|
child: icon,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
);
|
||||||
),
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ import 'package:flutter/material.dart';
|
||||||
class TwoColumnLayout extends StatelessWidget {
|
class TwoColumnLayout extends StatelessWidget {
|
||||||
final Widget mainView;
|
final Widget mainView;
|
||||||
final Widget sideView;
|
final Widget sideView;
|
||||||
|
final bool displayNavigationRail;
|
||||||
|
|
||||||
const TwoColumnLayout({
|
const TwoColumnLayout({
|
||||||
super.key,
|
super.key,
|
||||||
required this.mainView,
|
required this.mainView,
|
||||||
required this.sideView,
|
required this.sideView,
|
||||||
|
required this.displayNavigationRail,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -18,7 +20,7 @@ class TwoColumnLayout extends StatelessWidget {
|
||||||
Container(
|
Container(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
width: 384.0,
|
width: 360.0 + (displayNavigationRail ? 64 : 0),
|
||||||
child: mainView,
|
child: mainView,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
|
|
@ -19,41 +19,32 @@ class UnreadRoomsBadge extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StreamBuilder(
|
final unreadCount = Matrix.of(context)
|
||||||
stream: Matrix.of(context)
|
.client
|
||||||
.client
|
.rooms
|
||||||
.onSync
|
.where(filter)
|
||||||
.stream
|
.where((r) => (r.isUnread || r.membership == Membership.invite))
|
||||||
.where((syncUpdate) => syncUpdate.hasRoomUpdate),
|
.length;
|
||||||
builder: (context, _) {
|
return b.Badge(
|
||||||
final unreadCount = Matrix.of(context)
|
badgeStyle: b.BadgeStyle(
|
||||||
.client
|
badgeColor: Theme.of(context).colorScheme.primary,
|
||||||
.rooms
|
elevation: 4,
|
||||||
.where(filter)
|
borderSide: BorderSide(
|
||||||
.where((r) => (r.isUnread || r.membership == Membership.invite))
|
color: Theme.of(context).colorScheme.surface,
|
||||||
.length;
|
width: 2,
|
||||||
return b.Badge(
|
),
|
||||||
badgeStyle: b.BadgeStyle(
|
),
|
||||||
badgeColor: Theme.of(context).colorScheme.primary,
|
badgeContent: Text(
|
||||||
elevation: 4,
|
unreadCount.toString(),
|
||||||
borderSide: BorderSide(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
width: 2,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
badgeContent: Text(
|
showBadge: unreadCount != 0,
|
||||||
unreadCount.toString(),
|
badgeAnimation: const b.BadgeAnimation.scale(),
|
||||||
style: TextStyle(
|
position: badgePosition ?? b.BadgePosition.bottomEnd(),
|
||||||
color: Theme.of(context).colorScheme.onPrimary,
|
child: child,
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
showBadge: unreadCount != 0,
|
|
||||||
badgeAnimation: const b.BadgeAnimation.scale(),
|
|
||||||
position: badgePosition ?? b.BadgePosition.bottomEnd(),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ static void my_application_activate(GApplication* application) {
|
||||||
gtk_window_set_title(window, "FluffyChat");
|
gtk_window_set_title(window, "FluffyChat");
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_window_set_default_size(window, 800, 600);
|
gtk_window_set_default_size(window, 864, 680);
|
||||||
gtk_widget_show(GTK_WIDGET(window));
|
gtk_widget_show(GTK_WIDGET(window));
|
||||||
|
|
||||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||||
|
|
Loading…
Reference in a new issue