didvan-app/lib/views/direct/widgets/message_box.dart

270 lines
8.6 KiB
Dart

import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/views/ai/widgets/audio_wave.dart';
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
import 'package:didvan/views/direct/direct_state.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MessageBox extends StatefulWidget {
const MessageBox({Key? key}) : super(key: key);
@override
State<MessageBox> createState() => _MessageBoxState();
}
class _MessageBoxState extends State<MessageBox> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Consumer<DirectState>(
builder: (context, state, child) => state.replyRadar != null ||
state.replyNews != null
? _MessageBoxContainer(
isMessage: false,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const DidvanText(
'لینک به مطلب:',
),
DidvanText(
state.replyRadar != null
? state.replyRadar!.title
: state.replyNews!.title,
overflow: TextOverflow.ellipsis,
maxLines: 1,
color: Theme.of(context).colorScheme.primary,
),
],
),
),
DidvanIconButton(
icon: DidvanIcons.close_regular,
gestureSize: 24,
onPressed: () {
state.replyRadar = null;
state.replyNews = null;
state.update();
},
),
],
),
),
)
: const SizedBox(),
),
_MessageBoxContainer(
isMessage: true,
child: Consumer<DirectState>(
builder: (context, state, child) {
if (state.mRecorder!.isRecording) {
return const _Recording();
} else if (!(state.mRecorder!.isRecording) &&
state.path != null) {
return const _RecordChecking();
}
return const _Typing();
},
),
),
],
);
}
}
class _MessageBoxContainer extends StatelessWidget {
final Widget child;
final bool isMessage;
const _MessageBoxContainer({
Key? key,
required this.child,
required this.isMessage,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: child,
);
}
}
class _Typing extends StatefulWidget {
const _Typing({Key? key}) : super(key: key);
@override
State<_Typing> createState() => _TypingState();
}
class _TypingState extends State<_Typing> {
@override
void initState() {
super.initState();
context.read<DirectState>().textController.addListener(_rebuild);
}
@override
void dispose() {
context.read<DirectState>().textController.removeListener(_rebuild);
super.dispose();
}
void _rebuild() {
setState(() {});
}
@override
Widget build(BuildContext context) {
final state = context.watch<DirectState>();
return Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: TextFormField(
controller: state.textController,
textInputAction: TextInputAction.send,
style: Theme.of(context).textTheme.bodyMedium,
decoration: InputDecoration(
filled: true,
fillColor: const Color.fromARGB(255, 234, 235, 235),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide.none,
),
hintText: 'پیام خود را بنویسید...',
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: const Color.fromARGB(255, 102, 102, 102)),
contentPadding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
prefixIcon: Padding(
padding: const EdgeInsets.only(left: 5.0, right: 5.0),
child: AnimatedSwitcher(
duration: DesignConfig.lowAnimationDuration,
transitionBuilder: (child, animation) => ScaleTransition(
scale: animation,
child: child,
),
child: state.textController.text.isNotEmpty
? DidvanIconButton(
key: const ValueKey('sendBtn'),
isSvg: true,
icon: 'lib/assets/icons/send.svg',
onPressed: () async {
await state.sendMessage();
},
size: 28,
color: Theme.of(context).colorScheme.primary,
)
: DidvanIconButton(
key: const ValueKey('micBtn'),
isSvg: true,
icon: 'lib/assets/icons/microphone-2.svg',
onPressed: state.startRecording,
size: 28,
color: Theme.of(context).colorScheme.primary,
),
),
),
),
),
),
)
],
);
}
}
class _Recording extends StatelessWidget {
const _Recording({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final state = context.read<DirectState>();
return Row(
children: [
DidvanIconButton(
icon: DidvanIcons.send_solid,
onPressed: () => state.stopRecording(sendImidiately: true),
gestureSize: 52,
),
Expanded(
child: DidvanText(
'در حال ضبط صدا ...',
style: Theme.of(context).textTheme.bodySmall,
),
),
DidvanIconButton(
icon: DidvanIcons.stop_circle_solid,
color: Theme.of(context).colorScheme.secondary,
onPressed: () => state.stopRecording(sendImidiately: false),
size: 32,
),
],
);
}
}
class _RecordChecking extends StatelessWidget {
const _RecordChecking({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final state = context.read<DirectState>();
return Row(
children: [
DidvanIconButton(
icon: DidvanIcons.send_solid,
onPressed: () async {
await state.sendMessage();
state.update();
},
color: Theme.of(context).colorScheme.focusedBorder,
),
const SizedBox(
width: 12,
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: AudioWave(
file: state.path!,
totalDuration: state.countTimer.value,
),
),
),
const SizedBox(
width: 12,
),
MessageBarBtn(
enable: true,
icon: DidvanIcons.trash_solid,
click: () => state.deleteRecordedFile()),
const SizedBox(
width: 12,
),
],
);
}
}