chore: Adjust design
This commit is contained in:
parent
acda3e40ff
commit
65c3566dbd
5 changed files with 106 additions and 96 deletions
|
|
@ -37,7 +37,7 @@ enum AppSettings<T> {
|
||||||
sendPublicReadReceipts<bool>('chat.fluffy.send_public_read_receipts', true),
|
sendPublicReadReceipts<bool>('chat.fluffy.send_public_read_receipts', true),
|
||||||
swipeRightToLeftToReply<bool>('chat.fluffy.swipeRightToLeftToReply', true),
|
swipeRightToLeftToReply<bool>('chat.fluffy.swipeRightToLeftToReply', true),
|
||||||
sendOnEnter<bool>('chat.fluffy.send_on_enter', false),
|
sendOnEnter<bool>('chat.fluffy.send_on_enter', false),
|
||||||
showPresences<bool>('chat.fluffy.show_presences', false),
|
showPresences<bool>('chat.fluffy.show_presences', true),
|
||||||
displayNavigationRail<bool>('chat.fluffy.display_navigation_rail', false),
|
displayNavigationRail<bool>('chat.fluffy.display_navigation_rail', false),
|
||||||
experimentalVoip<bool>('chat.fluffy.experimental_voip', false),
|
experimentalVoip<bool>('chat.fluffy.experimental_voip', false),
|
||||||
shareKeysWith<String>('chat.fluffy.share_keys_with_2', 'all'),
|
shareKeysWith<String>('chat.fluffy.share_keys_with_2', 'all'),
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,17 @@ import 'input_bar.dart';
|
||||||
class ChatInputRow extends StatelessWidget {
|
class ChatInputRow extends StatelessWidget {
|
||||||
final ChatController controller;
|
final ChatController controller;
|
||||||
|
|
||||||
|
static const double height = 56.0;
|
||||||
|
|
||||||
const ChatInputRow(this.controller, {super.key});
|
const ChatInputRow(this.controller, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
final textMessageOnly =
|
||||||
const height = 48.0;
|
controller.sendController.text.isNotEmpty ||
|
||||||
|
controller.replyEvent != null ||
|
||||||
|
controller.editEvent != null;
|
||||||
|
|
||||||
if (!controller.room.otherPartyCanReceiveMessages) {
|
if (!controller.room.otherPartyCanReceiveMessages) {
|
||||||
return Center(
|
return Center(
|
||||||
|
|
@ -128,9 +132,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: FluffyThemes.animationDuration,
|
duration: FluffyThemes.animationDuration,
|
||||||
curve: FluffyThemes.animationCurve,
|
curve: FluffyThemes.animationCurve,
|
||||||
width: controller.sendController.text.isNotEmpty
|
width: textMessageOnly ? 0 : 48,
|
||||||
? 0
|
|
||||||
: height,
|
|
||||||
height: height,
|
height: height,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
|
|
@ -221,9 +223,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: FluffyThemes.animationDuration,
|
duration: FluffyThemes.animationDuration,
|
||||||
curve: FluffyThemes.animationCurve,
|
curve: FluffyThemes.animationCurve,
|
||||||
width: controller.sendController.text.isNotEmpty
|
width: textMessageOnly ? 0 : 48,
|
||||||
? 0
|
|
||||||
: height,
|
|
||||||
height: height,
|
height: height,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
|
|
@ -267,7 +267,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height: height,
|
height: height,
|
||||||
width: height,
|
width: 48,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip: L10n.of(context).emojis,
|
tooltip: L10n.of(context).emojis,
|
||||||
|
|
@ -302,13 +302,13 @@ class ChatInputRow extends StatelessWidget {
|
||||||
Matrix.of(context).currentBundle!.length > 1)
|
Matrix.of(context).currentBundle!.length > 1)
|
||||||
Container(
|
Container(
|
||||||
height: height,
|
height: height,
|
||||||
width: height,
|
width: 48,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: _ChatAccountPicker(controller),
|
child: _ChatAccountPicker(controller),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 0.0),
|
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
||||||
child: InputBar(
|
child: InputBar(
|
||||||
room: controller.room,
|
room: controller.room,
|
||||||
minLines: 1,
|
minLines: 1,
|
||||||
|
|
@ -358,9 +358,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
height: height,
|
height: height,
|
||||||
width: height,
|
width: height,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child:
|
child: PlatformInfos.platformCanRecord && !textMessageOnly
|
||||||
PlatformInfos.platformCanRecord &&
|
|
||||||
controller.sendController.text.isEmpty
|
|
||||||
? IconButton(
|
? IconButton(
|
||||||
tooltip: L10n.of(context).voiceMessage,
|
tooltip: L10n.of(context).voiceMessage,
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
|
import 'package:fluffychat/pages/chat/chat_input_row.dart';
|
||||||
import 'package:fluffychat/pages/chat/recording_view_model.dart';
|
import 'package:fluffychat/pages/chat/recording_view_model.dart';
|
||||||
|
|
||||||
class RecordingInputRow extends StatelessWidget {
|
class RecordingInputRow extends StatelessWidget {
|
||||||
|
|
@ -19,71 +20,81 @@ class RecordingInputRow extends StatelessWidget {
|
||||||
const maxDecibalWidth = 36.0;
|
const maxDecibalWidth = 36.0;
|
||||||
final time =
|
final time =
|
||||||
'${state.duration.inMinutes.toString().padLeft(2, '0')}:${(state.duration.inSeconds % 60).toString().padLeft(2, '0')}';
|
'${state.duration.inMinutes.toString().padLeft(2, '0')}:${(state.duration.inSeconds % 60).toString().padLeft(2, '0')}';
|
||||||
return Row(
|
return SizedBox(
|
||||||
children: [
|
height: ChatInputRow.height,
|
||||||
IconButton(
|
child: Padding(
|
||||||
tooltip: L10n.of(context).cancel,
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
icon: const Icon(Icons.delete_outlined),
|
child: Row(
|
||||||
color: theme.colorScheme.error,
|
crossAxisAlignment: .center,
|
||||||
onPressed: state.cancel,
|
mainAxisAlignment: .spaceBetween,
|
||||||
),
|
spacing: 8,
|
||||||
if (state.isPaused)
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: L10n.of(context).resume,
|
tooltip: L10n.of(context).cancel,
|
||||||
icon: const Icon(Icons.play_circle_outline_outlined),
|
icon: const Icon(Icons.delete_outlined),
|
||||||
onPressed: state.resume,
|
color: theme.colorScheme.error,
|
||||||
)
|
onPressed: state.cancel,
|
||||||
else
|
),
|
||||||
IconButton(
|
if (state.isPaused)
|
||||||
tooltip: L10n.of(context).pause,
|
IconButton(
|
||||||
icon: const Icon(Icons.pause_circle_outline_outlined),
|
tooltip: L10n.of(context).resume,
|
||||||
onPressed: state.pause,
|
icon: const Icon(Icons.play_circle_outline_outlined),
|
||||||
),
|
onPressed: state.resume,
|
||||||
Text(time),
|
)
|
||||||
const SizedBox(width: 8),
|
else
|
||||||
Expanded(
|
IconButton(
|
||||||
child: LayoutBuilder(
|
tooltip: L10n.of(context).pause,
|
||||||
builder: (context, constraints) {
|
icon: const Icon(Icons.pause_circle_outline_outlined),
|
||||||
const width = 4;
|
onPressed: state.pause,
|
||||||
return Row(
|
),
|
||||||
mainAxisSize: .min,
|
Text(time),
|
||||||
mainAxisAlignment: .end,
|
Expanded(
|
||||||
children: state.amplitudeTimeline.reversed
|
child: LayoutBuilder(
|
||||||
.take((constraints.maxWidth / (width + 2)).floor())
|
builder: (context, constraints) {
|
||||||
.toList()
|
const width = 4;
|
||||||
.reversed
|
return Row(
|
||||||
.map(
|
mainAxisSize: .min,
|
||||||
(amplitude) => Container(
|
mainAxisAlignment: .end,
|
||||||
margin: const EdgeInsets.only(left: 2),
|
children: state.amplitudeTimeline.reversed
|
||||||
width: width.toDouble(),
|
.take((constraints.maxWidth / (width + 2)).floor())
|
||||||
decoration: BoxDecoration(
|
.toList()
|
||||||
color: theme.colorScheme.primary,
|
.reversed
|
||||||
borderRadius: BorderRadius.circular(2),
|
.map(
|
||||||
),
|
(amplitude) => Container(
|
||||||
height: maxDecibalWidth * (amplitude / 100),
|
margin: const EdgeInsets.only(left: 2),
|
||||||
),
|
width: width.toDouble(),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: theme.colorScheme.primary,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
height: maxDecibalWidth * (amplitude / 100),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
style: IconButton.styleFrom(
|
||||||
|
disabledBackgroundColor: theme.bubbleColor.withAlpha(128),
|
||||||
|
backgroundColor: theme.bubbleColor,
|
||||||
|
foregroundColor: theme.onBubbleColor,
|
||||||
|
),
|
||||||
|
tooltip: L10n.of(context).sendAudio,
|
||||||
|
icon: state.isSending
|
||||||
|
? const SizedBox.square(
|
||||||
|
dimension: 24,
|
||||||
|
child: CircularProgressIndicator.adaptive(),
|
||||||
)
|
)
|
||||||
.toList(),
|
: const Icon(Icons.send_outlined),
|
||||||
);
|
onPressed: state.isSending
|
||||||
},
|
? null
|
||||||
),
|
: () => state.stopAndSend(onSend),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
IconButton(
|
),
|
||||||
style: IconButton.styleFrom(
|
|
||||||
disabledBackgroundColor: theme.bubbleColor.withAlpha(128),
|
|
||||||
backgroundColor: theme.bubbleColor,
|
|
||||||
foregroundColor: theme.onBubbleColor,
|
|
||||||
),
|
|
||||||
tooltip: L10n.of(context).sendAudio,
|
|
||||||
icon: state.isSending
|
|
||||||
? const SizedBox.square(
|
|
||||||
dimension: 24,
|
|
||||||
child: CircularProgressIndicator.adaptive(),
|
|
||||||
)
|
|
||||||
: const Icon(Icons.send_outlined),
|
|
||||||
onPressed: state.isSending ? null : () => state.stopAndSend(onSend),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,14 @@ class ChatListView extends StatelessWidget {
|
||||||
body: ChatListViewBody(controller),
|
body: ChatListViewBody(controller),
|
||||||
floatingActionButton:
|
floatingActionButton:
|
||||||
!controller.isSearchMode && controller.activeSpaceId == null
|
!controller.isSearchMode && controller.activeSpaceId == null
|
||||||
? FloatingActionButton.extended(
|
? FloatingActionButton(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||||
|
foregroundColor: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onPrimary,
|
||||||
onPressed: () => context.go('/rooms/newprivatechat'),
|
onPressed: () => context.go('/rooms/newprivatechat'),
|
||||||
icon: const Icon(Icons.add_outlined),
|
tooltip: L10n.of(context).newChat,
|
||||||
label: Text(
|
child: const Icon(Icons.edit_square),
|
||||||
L10n.of(context).chat,
|
|
||||||
overflow: TextOverflow.fade,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
24
pubspec.lock
24
pubspec.lock
|
|
@ -157,10 +157,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1072,18 +1072,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.18"
|
version: "0.12.17"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.0"
|
version: "0.11.1"
|
||||||
matrix:
|
matrix:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -1813,26 +1813,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test
|
name: test
|
||||||
sha256: "77cc98ea27006c84e71a7356cf3daf9ddbde2d91d84f77dbfe64cf0e4d9611ae"
|
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.28.0"
|
version: "1.26.3"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8"
|
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.8"
|
version: "0.7.7"
|
||||||
test_core:
|
test_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_core
|
name: test_core
|
||||||
sha256: f1072617a6657e5fc09662e721307f7fb009b4ed89b19f47175d11d5254a62d4
|
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.14"
|
version: "0.6.12"
|
||||||
timezone:
|
timezone:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue