Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
krille-chan
9735b6e20b
design: Experimental design 2024-03-17 19:25:37 +01:00
9 changed files with 164 additions and 128 deletions

View file

@ -97,9 +97,6 @@ abstract class FluffyThemes {
filled: true, filled: true,
), ),
appBarTheme: AppBarTheme( appBarTheme: AppBarTheme(
toolbarHeight: FluffyThemes.isColumnMode(context) ? 72 : 56,
shadowColor: Colors.grey.withAlpha(64),
surfaceTintColor: colorScheme.background,
systemOverlayStyle: SystemUiOverlayStyle( systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent, statusBarColor: Colors.transparent,
statusBarIconBrightness: brightness.reversed, statusBarIconBrightness: brightness.reversed,

View file

@ -79,14 +79,7 @@ class ChatPage extends StatelessWidget {
Container( Container(
width: FluffyThemes.columnWidth, width: FluffyThemes.columnWidth,
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
decoration: BoxDecoration( decoration: const BoxDecoration(),
border: Border(
left: BorderSide(
width: 1,
color: Theme.of(context).dividerColor,
),
),
),
child: ChatDetails(roomId: roomId), child: ChatDetails(roomId: roomId),
), ),
], ],

View file

@ -140,6 +140,10 @@ class ChatView extends StatelessWidget {
final accountConfig = Matrix.of(context).client.applicationAccountConfig; final accountConfig = Matrix.of(context).client.applicationAccountConfig;
final backgroundColor = FluffyThemes.isColumnMode(context)
? Theme.of(context).colorScheme.secondaryContainer
: Theme.of(context).colorScheme.background;
return PopScope( return PopScope(
canPop: controller.selectedEvents.isEmpty && !controller.showEmojiPicker, canPop: controller.selectedEvents.isEmpty && !controller.showEmojiPicker,
onPopInvoked: (pop) async { onPopInvoked: (pop) async {
@ -156,101 +160,150 @@ class ChatView extends StatelessWidget {
builder: (context, snapshot) => FutureBuilder( builder: (context, snapshot) => FutureBuilder(
future: controller.loadTimelineFuture, future: controller.loadTimelineFuture,
builder: (BuildContext context, snapshot) { builder: (BuildContext context, snapshot) {
return Scaffold( return Container(
appBar: AppBar( margin: FluffyThemes.isColumnMode(context)
actionsIconTheme: IconThemeData( ? const EdgeInsets.all(12)
color: controller.selectedEvents.isEmpty : null,
? null decoration: FluffyThemes.isColumnMode(context)
: Theme.of(context).colorScheme.primary, ? BoxDecoration(
), gradient: LinearGradient(
leading: controller.selectMode colors: [
? IconButton( Theme.of(context).colorScheme.primaryContainer,
icon: const Icon(Icons.close), Theme.of(context).colorScheme.secondaryContainer,
onPressed: controller.clearSelectedEvents, Theme.of(context).colorScheme.tertiaryContainer,
tooltip: L10n.of(context)!.close, ],
color: Theme.of(context).colorScheme.primary, stops: const [0.25, 0.5, 0.75],
) begin: Alignment.topLeft,
: UnreadRoomsBadge( end: Alignment.bottomRight,
filter: (r) => r.id != controller.roomId,
badgePosition: BadgePosition.topEnd(end: 8, top: 4),
child: const Center(child: BackButton()),
),
titleSpacing: 0,
title: ChatAppBarTitle(controller),
actions: _appBarActions(context),
),
floatingActionButton: controller.showScrollDownButton &&
controller.selectedEvents.isEmpty
? Padding(
padding: const EdgeInsets.only(bottom: 56.0),
child: FloatingActionButton(
onPressed: controller.scrollDown,
heroTag: null,
mini: true,
child: const Icon(Icons.arrow_downward_outlined),
), ),
borderRadius:
BorderRadius.circular(AppConfig.borderRadius),
) )
: null, : null,
body: DropTarget( clipBehavior: Clip.hardEdge,
onDragDone: controller.onDragDone, child: Scaffold(
onDragEntered: controller.onDragEntered, extendBody: true,
onDragExited: controller.onDragExited, extendBodyBehindAppBar: true,
child: Stack( backgroundColor: Colors.transparent,
children: <Widget>[ appBar: AppBar(
if (accountConfig.wallpaperUrl != null) elevation: 0,
Opacity( scrolledUnderElevation: 0,
opacity: accountConfig.wallpaperOpacity ?? 1, backgroundColor: backgroundColor.withOpacity(0.9),
child: MxcImage( surfaceTintColor: backgroundColor.withOpacity(0.9),
uri: accountConfig.wallpaperUrl, actionsIconTheme: IconThemeData(
fit: BoxFit.cover, color: controller.selectedEvents.isEmpty
isThumbnail: true, ? null
width: FluffyThemes.columnWidth * 4, : Theme.of(context).colorScheme.primary,
height: FluffyThemes.columnWidth * 4, ),
placeholder: (_) => Container(), leading: controller.selectMode
? IconButton(
icon: const Icon(Icons.close),
onPressed: controller.clearSelectedEvents,
tooltip: L10n.of(context)!.close,
color: Theme.of(context).colorScheme.primary,
)
: UnreadRoomsBadge(
filter: (r) => r.id != controller.roomId,
badgePosition: BadgePosition.topEnd(end: 8, top: 4),
child: const Center(child: BackButton()),
), ),
), titleSpacing: 0,
SafeArea( title: ChatAppBarTitle(controller),
child: Column( actions: _appBarActions(context),
children: <Widget>[ bottom: PreferredSize(
preferredSize: Size.fromHeight(
64 *
((controller.room
.getState(EventTypes.RoomTombstone) !=
null
? 1
: 0) +
(scrollUpBannerEventId != null ? 1 : 0) +
(controller.room.pinnedEventIds.isNotEmpty
? 1
: 0)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (controller.room
.getState(EventTypes.RoomTombstone) !=
null)
TombstoneDisplay(controller), TombstoneDisplay(controller),
if (scrollUpBannerEventId != null) if (scrollUpBannerEventId != null)
Material( Material(
color: color: Theme.of(context).colorScheme.surfaceVariant,
Theme.of(context).colorScheme.surfaceVariant, shape: Border(
shape: Border( bottom: BorderSide(
bottom: BorderSide( width: 1,
width: 1, color: Theme.of(context).dividerColor,
color: Theme.of(context).dividerColor,
),
),
child: ListTile(
leading: IconButton(
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
icon: const Icon(Icons.close),
tooltip: L10n.of(context)!.close,
onPressed: () {
controller.discardScrollUpBannerEventId();
controller.setReadMarker();
},
),
title: Text(
L10n.of(context)!.jumpToLastReadMessage,
),
contentPadding: const EdgeInsets.only(left: 8),
trailing: TextButton(
onPressed: () {
controller.scrollToEventId(
scrollUpBannerEventId,
);
controller.discardScrollUpBannerEventId();
},
child: Text(L10n.of(context)!.jump),
),
), ),
), ),
child: ListTile(
leading: IconButton(
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
icon: const Icon(Icons.close),
tooltip: L10n.of(context)!.close,
onPressed: () {
controller.discardScrollUpBannerEventId();
controller.setReadMarker();
},
),
title: Text(
L10n.of(context)!.jumpToLastReadMessage,
),
contentPadding: const EdgeInsets.only(left: 8),
trailing: TextButton(
onPressed: () {
controller.scrollToEventId(
scrollUpBannerEventId,
);
controller.discardScrollUpBannerEventId();
},
child: Text(L10n.of(context)!.jump),
),
),
),
if (controller.room.pinnedEventIds.isNotEmpty)
PinnedEvents(controller), PinnedEvents(controller),
],
),
),
),
floatingActionButton: controller.showScrollDownButton &&
controller.selectedEvents.isEmpty
? Padding(
padding: const EdgeInsets.only(bottom: 56.0),
child: FloatingActionButton(
onPressed: controller.scrollDown,
heroTag: null,
mini: true,
child: const Icon(Icons.arrow_downward_outlined),
),
)
: null,
body: DropTarget(
onDragDone: controller.onDragDone,
onDragEntered: controller.onDragEntered,
onDragExited: controller.onDragExited,
child: Stack(
children: <Widget>[
if (accountConfig.wallpaperUrl != null)
Opacity(
opacity: accountConfig.wallpaperOpacity ?? 1,
child: MxcImage(
uri: accountConfig.wallpaperUrl,
fit: BoxFit.cover,
isThumbnail: true,
width: FluffyThemes.columnWidth * 4,
height: FluffyThemes.columnWidth * 4,
placeholder: (_) => Container(),
),
),
Column(
children: <Widget>[
Expanded( Expanded(
child: GestureDetector( child: GestureDetector(
onTap: controller.clearSingleSelectedEvent, onTap: controller.clearSingleSelectedEvent,
@ -350,19 +403,19 @@ class ChatView extends StatelessWidget {
), ),
], ],
), ),
), if (controller.dragging)
if (controller.dragging) Container(
Container( color: Theme.of(context)
color: Theme.of(context) .scaffoldBackgroundColor
.scaffoldBackgroundColor .withOpacity(0.9),
.withOpacity(0.9), alignment: Alignment.center,
alignment: Alignment.center, child: const Icon(
child: const Icon( Icons.upload_outlined,
Icons.upload_outlined, size: 100,
size: 100, ),
), ),
), ],
], ),
), ),
), ),
); );

View file

@ -78,7 +78,7 @@ class Message extends StatelessWidget {
final client = Matrix.of(context).client; final client = Matrix.of(context).client;
final ownMessage = event.senderId == client.userID; final ownMessage = event.senderId == client.userID;
final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft; final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft;
var color = Theme.of(context).colorScheme.surfaceVariant; var color = Theme.of(context).colorScheme.background;
final displayTime = event.type == EventTypes.RoomCreate || final displayTime = event.type == EventTypes.RoomCreate ||
nextEvent == null || nextEvent == null ||
!event.originServerTs.sameEnvironment(nextEvent!.originServerTs); !event.originServerTs.sameEnvironment(nextEvent!.originServerTs);

View file

@ -57,10 +57,6 @@ class PinnedEvents extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final pinnedEventIds = controller.room.pinnedEventIds; final pinnedEventIds = controller.room.pinnedEventIds;
if (pinnedEventIds.isEmpty) {
return const SizedBox.shrink();
}
return FutureBuilder<Event?>( return FutureBuilder<Event?>(
future: controller.room.getEventById(pinnedEventIds.last), future: controller.room.getEventById(pinnedEventIds.last),
builder: (context, snapshot) { builder: (context, snapshot) {

View file

@ -11,9 +11,6 @@ class TombstoneDisplay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (controller.room.getState(EventTypes.RoomTombstone) == null) {
return const SizedBox.shrink();
}
return SizedBox( return SizedBox(
height: 72, height: 72,
child: Material( child: Material(

View file

@ -54,7 +54,7 @@ class ChatListViewBody extends StatelessWidget {
animation: primaryAnimation, animation: primaryAnimation,
secondaryAnimation: secondaryAnimation, secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.vertical, transitionType: SharedAxisTransitionType.vertical,
fillColor: Theme.of(context).scaffoldBackgroundColor, fillColor: Theme.of(context).colorScheme.background,
child: child, child: child,
); );
}, },

View file

@ -131,7 +131,13 @@ class ChatListView extends StatelessWidget {
.toList(); .toList();
final destinations = getNavigationDestinations(context); final destinations = getNavigationDestinations(context);
return SizedBox( return Container(
margin: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondaryContainer,
borderRadius:
BorderRadius.circular(AppConfig.borderRadius),
),
width: FluffyThemes.navRailWidth, width: FluffyThemes.navRailWidth,
child: ListView.builder( child: ListView.builder(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
@ -171,10 +177,6 @@ class ChatListView extends StatelessWidget {
); );
}, },
), ),
Container(
color: Theme.of(context).dividerColor,
width: 1,
),
], ],
Expanded( Expanded(
child: GestureDetector( child: GestureDetector(

View file

@ -15,6 +15,7 @@ class TwoColumnLayout extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ScaffoldMessenger( return ScaffoldMessenger(
child: Scaffold( child: Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
body: Row( body: Row(
children: [ children: [
Container( Container(
@ -23,12 +24,9 @@ class TwoColumnLayout extends StatelessWidget {
width: 360.0 + (displayNavigationRail ? 64 : 0), width: 360.0 + (displayNavigationRail ? 64 : 0),
child: mainView, child: mainView,
), ),
Container(
width: 1.0,
color: Theme.of(context).dividerColor,
),
Expanded( Expanded(
child: ClipRRect( child: ClipRRect(
clipBehavior: Clip.hardEdge,
child: sideView, child: sideView,
), ),
), ),