You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fluffychat/lib/pages/chat/chat_view_frame.dart

176 lines
7.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/pinned_events.dart';
import 'package:fluffychat/pages/chat/reactions_picker.dart';
import 'package:fluffychat/pages/chat/reply_display.dart';
import 'package:fluffychat/pages/chat/tombstone_display.dart';
import 'package:fluffychat/widgets/connection_status_header.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'chat_emoji_picker.dart';
import 'chat_input_row.dart';
class ChatViewFrame extends StatelessWidget {
final ChatController controller;
final WidgetBuilder contentBuilder;
const ChatViewFrame(this.controller,
{super.key, required this.contentBuilder});
@override
Widget build(BuildContext context) {
final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0;
final scrollUpBannerEventId = controller.scrollUpBannerEventId;
return DropTarget(
onDragDone: controller.onDragDone,
onDragEntered: controller.onDragEntered,
onDragExited: controller.onDragExited,
child: Stack(
children: <Widget>[
if (Matrix.of(context).wallpaper != null)
Image.file(
Matrix.of(context).wallpaper!,
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
filterQuality: FilterQuality.medium,
),
SafeArea(
child: Column(
children: <Widget>[
TombstoneDisplay(controller),
if (scrollUpBannerEventId != null)
Material(
color: Theme.of(context).colorScheme.surfaceVariant,
shape: Border(
bottom: BorderSide(
width: 1,
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),
),
),
),
PinnedEvents(controller),
Expanded(
child: GestureDetector(
onTap: controller.clearSingleSelectedEvent,
child: Builder(
builder: contentBuilder.call,
),
),
),
if (controller.room.canSendDefaultMessages &&
controller.room.membership == Membership.join)
Container(
margin: EdgeInsets.only(
bottom: bottomSheetPadding,
left: bottomSheetPadding,
right: bottomSheetPadding,
),
constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 2.5,
),
alignment: Alignment.center,
child: Material(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(AppConfig.borderRadius),
bottomRight: Radius.circular(AppConfig.borderRadius),
),
elevation: 4,
shadowColor: Colors.black.withAlpha(64),
clipBehavior: Clip.hardEdge,
color: Theme.of(context).brightness == Brightness.light
? Colors.white
: Colors.black,
child: controller.room.isAbandonedDMRoom == true
? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton.icon(
style: TextButton.styleFrom(
padding: const EdgeInsets.all(16),
foregroundColor:
Theme.of(context).colorScheme.error,
),
icon: const Icon(
Icons.archive_outlined,
),
onPressed: controller.leaveChat,
label: Text(
L10n.of(context)!.leave,
),
),
TextButton.icon(
style: TextButton.styleFrom(
padding: const EdgeInsets.all(16),
),
icon: const Icon(
Icons.forum_outlined,
),
onPressed: controller.recreateChat,
label: Text(
L10n.of(context)!.reopenChat,
),
),
],
)
: Column(
mainAxisSize: MainAxisSize.min,
children: [
const ConnectionStatusHeader(),
ReactionsPicker(controller),
ReplyDisplay(controller),
ChatInputRow(controller),
ChatEmojiPicker(controller),
],
),
),
),
],
),
),
if (controller.dragging)
Container(
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9),
alignment: Alignment.center,
child: const Icon(
Icons.upload_outlined,
size: 100,
),
),
],
),
);
}
}