design: Floating input bar

onboarding
Krille Fear 4 years ago
parent f562a48daa
commit 4fc749015a

@ -1,5 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:fluffychat/config/themes.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -505,254 +506,269 @@ class ChatView extends StatelessWidget {
), ),
), ),
), ),
const Divider(height: 1), if (controller.showScrollDownButton)
const Divider(
height: 1,
),
if (controller.room.canSendDefaultMessages && if (controller.room.canSendDefaultMessages &&
controller.room.membership == Membership.join && controller.room.membership == Membership.join &&
!controller.showEmojiPicker) !controller.showEmojiPicker)
Container( Padding(
decoration: BoxDecoration( padding: EdgeInsets.all(
FluffyThemes.isColumnMode(context) ? 16.0 : 8.0),
child: Material(
borderRadius:
BorderRadius.circular(AppConfig.borderRadius),
elevation: 4,
color: Theme.of(context).scaffoldBackgroundColor, color: Theme.of(context).scaffoldBackgroundColor,
), child: Row(
child: Row( crossAxisAlignment: CrossAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: controller.selectMode
children: controller.selectMode ? <Widget>[
? <Widget>[ SizedBox(
SizedBox( height: 56,
height: 56, child: TextButton(
child: TextButton( onPressed:
onPressed: controller.forwardEventsAction, controller.forwardEventsAction,
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
const Icon(Icons const Icon(Icons
.keyboard_arrow_left_outlined), .keyboard_arrow_left_outlined),
Text(L10n.of(context).forward), Text(L10n.of(context).forward),
], ],
),
), ),
), ),
), controller.selectedEvents.length == 1
controller.selectedEvents.length == 1 ? controller.selectedEvents.first
? controller.selectedEvents.first .getDisplayEvent(
.getDisplayEvent( controller.timeline)
controller.timeline) .status
.status .isSent
.isSent ? SizedBox(
? SizedBox( height: 56,
height: 56, child: TextButton(
child: TextButton( onPressed:
onPressed: controller.replyAction,
controller.replyAction, child: Row(
child: Row( children: <Widget>[
children: <Widget>[ Text(L10n.of(context)
Text( .reply),
L10n.of(context).reply), const Icon(Icons
const Icon(Icons .keyboard_arrow_right),
.keyboard_arrow_right), ],
], ),
), ),
), )
) : SizedBox(
: SizedBox( height: 56,
height: 56, child: TextButton(
child: TextButton( onPressed: controller
onPressed: .sendAgainAction,
controller.sendAgainAction, child: Row(
child: Row( children: <Widget>[
children: <Widget>[ Text(L10n.of(context)
Text(L10n.of(context) .tryToSendAgain),
.tryToSendAgain), const SizedBox(width: 4),
const SizedBox(width: 4), const Icon(
const Icon( Icons.send_outlined,
Icons.send_outlined, size: 16),
size: 16), ],
], ),
), ),
), )
) : Container(),
: Container(), ]
] : <Widget>[
: <Widget>[ AnimatedContainer(
AnimatedContainer( duration:
duration: const Duration(milliseconds: 200), const Duration(milliseconds: 200),
height: 56, height: 56,
width: width:
controller.inputText.isEmpty ? 56 : 0, controller.inputText.isEmpty ? 56 : 0,
alignment: Alignment.center, alignment: Alignment.center,
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
decoration: const BoxDecoration(), decoration: const BoxDecoration(),
child: PopupMenuButton<String>( child: PopupMenuButton<String>(
icon: const Icon(Icons.add_outlined), icon: const Icon(Icons.add_outlined),
onSelected: controller onSelected: controller
.onAddPopupMenuButtonSelected, .onAddPopupMenuButtonSelected,
itemBuilder: (BuildContext context) => itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[ <PopupMenuEntry<String>>[
PopupMenuItem<String>(
value: 'file',
child: ListTile(
leading: const CircleAvatar(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
child: Icon(
Icons.attachment_outlined),
),
title:
Text(L10n.of(context).sendFile),
contentPadding:
const EdgeInsets.all(0),
),
),
PopupMenuItem<String>(
value: 'image',
child: ListTile(
leading: const CircleAvatar(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
child: Icon(Icons.image_outlined),
),
title: Text(
L10n.of(context).sendImage),
contentPadding:
const EdgeInsets.all(0),
),
),
if (PlatformInfos.isMobile)
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'camera', value: 'file',
child: ListTile( child: ListTile(
leading: const CircleAvatar( leading: const CircleAvatar(
backgroundColor: Colors.purple, backgroundColor: Colors.green,
foregroundColor: Colors.white, foregroundColor: Colors.white,
child: Icon( child: Icon(
Icons.camera_alt_outlined), Icons.attachment_outlined),
), ),
title: Text( title: Text(
L10n.of(context).openCamera), L10n.of(context).sendFile),
contentPadding: contentPadding:
const EdgeInsets.all(0), const EdgeInsets.all(0),
), ),
), ),
if (controller.room
.getImagePacks(
ImagePackUsage.sticker)
.isNotEmpty)
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'sticker', value: 'image',
child: ListTile( child: ListTile(
leading: const CircleAvatar( leading: const CircleAvatar(
backgroundColor: Colors.orange, backgroundColor: Colors.blue,
foregroundColor: Colors.white, foregroundColor: Colors.white,
child: Icon(Icons child:
.emoji_emotions_outlined), Icon(Icons.image_outlined),
), ),
title: Text( title: Text(
L10n.of(context).sendSticker), L10n.of(context).sendImage),
contentPadding: contentPadding:
const EdgeInsets.all(0), const EdgeInsets.all(0),
), ),
), ),
if (PlatformInfos.isMobile) if (PlatformInfos.isMobile)
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'voice', value: 'camera',
child: ListTile( child: ListTile(
leading: const CircleAvatar( leading: const CircleAvatar(
backgroundColor: Colors.red, backgroundColor:
foregroundColor: Colors.white, Colors.purple,
child: Icon( foregroundColor: Colors.white,
Icons.mic_none_outlined), child: Icon(Icons
.camera_alt_outlined),
),
title: Text(L10n.of(context)
.openCamera),
contentPadding:
const EdgeInsets.all(0),
), ),
title: Text(L10n.of(context)
.voiceMessage),
contentPadding:
const EdgeInsets.all(0),
), ),
), if (controller.room
if (PlatformInfos.isMobile) .getImagePacks(
PopupMenuItem<String>( ImagePackUsage.sticker)
value: 'location', .isNotEmpty)
child: ListTile( PopupMenuItem<String>(
leading: const CircleAvatar( value: 'sticker',
backgroundColor: Colors.brown, child: ListTile(
foregroundColor: Colors.white, leading: const CircleAvatar(
child: Icon( backgroundColor:
Icons.gps_fixed_outlined), Colors.orange,
foregroundColor: Colors.white,
child: Icon(Icons
.emoji_emotions_outlined),
),
title: Text(L10n.of(context)
.sendSticker),
contentPadding:
const EdgeInsets.all(0),
), ),
title: Text(L10n.of(context)
.shareLocation),
contentPadding:
const EdgeInsets.all(0),
), ),
), if (PlatformInfos.isMobile)
], PopupMenuItem<String>(
value: 'voice',
child: ListTile(
leading: const CircleAvatar(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
child: Icon(
Icons.mic_none_outlined),
),
title: Text(L10n.of(context)
.voiceMessage),
contentPadding:
const EdgeInsets.all(0),
),
),
if (PlatformInfos.isMobile)
PopupMenuItem<String>(
value: 'location',
child: ListTile(
leading: const CircleAvatar(
backgroundColor: Colors.brown,
foregroundColor: Colors.white,
child: Icon(
Icons.gps_fixed_outlined),
),
title: Text(L10n.of(context)
.shareLocation),
contentPadding:
const EdgeInsets.all(0),
),
),
],
),
), ),
),
Container(
height: 56,
alignment: Alignment.center,
child: EncryptionButton(controller.room),
),
if (controller.matrix.isMultiAccount &&
controller.matrix.hasComplexBundles &&
controller.matrix.currentBundle.length >
1)
Container( Container(
height: 56, height: 56,
alignment: Alignment.center, alignment: Alignment.center,
child: _ChatAccountPicker(controller), child: EncryptionButton(controller.room),
), ),
Expanded( if (controller.matrix.isMultiAccount &&
child: Padding( controller.matrix.hasComplexBundles &&
padding: const EdgeInsets.symmetric( controller.matrix.currentBundle.length >
vertical: 4.0), 1)
child: InputBar( Container(
room: controller.room, height: 56,
minLines: 1, alignment: Alignment.center,
maxLines: 8, child: _ChatAccountPicker(controller),
autofocus: !PlatformInfos.isMobile, ),
keyboardType: TextInputType.multiline, Expanded(
textInputAction: AppConfig.sendOnEnter child: Padding(
? TextInputAction.send padding: const EdgeInsets.symmetric(
: null, vertical: 4.0),
onSubmitted: child: InputBar(
controller.onInputBarSubmitted, room: controller.room,
focusNode: controller.inputFocus, minLines: 1,
controller: controller.sendController, maxLines: 8,
decoration: InputDecoration( autofocus: !PlatformInfos.isMobile,
hintText: keyboardType: TextInputType.multiline,
L10n.of(context).writeAMessage, textInputAction: AppConfig.sendOnEnter
hintMaxLines: 1, ? TextInputAction.send
border: InputBorder.none, : null,
enabledBorder: InputBorder.none, onSubmitted:
filled: false, controller.onInputBarSubmitted,
focusNode: controller.inputFocus,
controller: controller.sendController,
decoration: InputDecoration(
hintText:
L10n.of(context).writeAMessage,
hintMaxLines: 1,
border: InputBorder.none,
enabledBorder: InputBorder.none,
filled: false,
),
onChanged:
controller.onInputBarChanged,
), ),
onChanged: controller.onInputBarChanged,
), ),
), ),
), if (PlatformInfos.isMobile &&
if (PlatformInfos.isMobile && controller.inputText.isEmpty)
controller.inputText.isEmpty) Container(
Container( height: 56,
height: 56, alignment: Alignment.center,
alignment: Alignment.center, child: IconButton(
child: IconButton( tooltip:
tooltip: L10n.of(context).voiceMessage, L10n.of(context).voiceMessage,
icon: icon: const Icon(
const Icon(Icons.mic_none_outlined), Icons.mic_none_outlined),
onPressed: onPressed:
controller.voiceMessageAction, controller.voiceMessageAction,
),
), ),
), if (!PlatformInfos.isMobile ||
if (!PlatformInfos.isMobile || controller.inputText.isNotEmpty)
controller.inputText.isNotEmpty) Container(
Container( height: 56,
height: 56, alignment: Alignment.center,
alignment: Alignment.center, child: IconButton(
child: IconButton( icon: const Icon(Icons.send_outlined),
icon: const Icon(Icons.send_outlined), onPressed: controller.send,
onPressed: controller.send, tooltip: L10n.of(context).send,
tooltip: L10n.of(context).send, ),
), ),
), ],
], ),
), ),
), ),
AnimatedContainer( AnimatedContainer(

Loading…
Cancel
Save