234 lines
6.2 KiB
Dart
234 lines
6.2 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/message_data/message_data.dart';
|
|
import 'package:didvan/models/message_data/news_attachment.dart';
|
|
import 'package:didvan/models/message_data/radar_attachment.dart';
|
|
import 'package:didvan/providers/core.dart';
|
|
import 'package:didvan/services/media/media.dart';
|
|
import 'package:didvan/services/media/voice.dart';
|
|
import 'package:didvan/services/network/request.dart';
|
|
import 'package:didvan/services/network/request_helper.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_vibrate/flutter_vibrate.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:record/record.dart';
|
|
|
|
class DirectState extends CoreProvier {
|
|
final _recorder = AudioRecorder();
|
|
final List<MessageData> messages = [];
|
|
late final int typeId;
|
|
final Map<String, List<int>> dailyMessages = {};
|
|
final List<int> deletionQueue = [];
|
|
|
|
String? text;
|
|
NewsAttachment? replyNews;
|
|
RadarAttachment? replyRadar;
|
|
File? recordedFile;
|
|
Uint8List? recordedFileBytes;
|
|
int? audioDuration;
|
|
String? path;
|
|
|
|
bool isRecording = false;
|
|
|
|
Future<void> getMessages() async {
|
|
appState = AppState.busy;
|
|
|
|
final RequestService service = RequestService(RequestHelper.direct(typeId));
|
|
await service.httpGet();
|
|
if (service.isSuccess) {
|
|
messages.clear();
|
|
|
|
final messageDatas = service.result['messages'];
|
|
for (var i = 0; i < messageDatas.length; i++) {
|
|
messages.add(MessageData.fromJson(messageDatas[i]));
|
|
_addToDailyGrouped(messages.last);
|
|
}
|
|
appState = AppState.idle;
|
|
return;
|
|
}
|
|
appState = AppState.failed;
|
|
}
|
|
|
|
void deleteRecordedFile() {
|
|
recordedFile!.delete();
|
|
recordedFile = null;
|
|
notifyListeners();
|
|
update();
|
|
}
|
|
|
|
Future<void> startRecording() async {
|
|
text = null;
|
|
await _recorder.hasPermission();
|
|
if (!kIsWeb) {
|
|
Vibrate.feedback(FeedbackType.medium);
|
|
}
|
|
isRecording = true;
|
|
Directory? tempDir;
|
|
if (!kIsWeb) {
|
|
tempDir = await getApplicationDocumentsDirectory();
|
|
}
|
|
_recorder.start(const RecordConfig(),
|
|
path: kIsWeb
|
|
? ''
|
|
: '${tempDir!.path}/${DateTime.now().millisecondsSinceEpoch ~/ 1000}.m4a');
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> stopRecording({required bool sendImidiately}) async {
|
|
path = await _recorder.stop();
|
|
isRecording = false;
|
|
if (path == null) {
|
|
notifyListeners();
|
|
return;
|
|
}
|
|
if (kIsWeb) {
|
|
final Uri audioUri = Uri.parse(path!);
|
|
final http.Response audioResponse = await http.get(audioUri);
|
|
recordedFileBytes = audioResponse.bodyBytes;
|
|
} else {
|
|
recordedFile = File(path!);
|
|
}
|
|
if (sendImidiately) {
|
|
await sendMessage();
|
|
} else {
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
void delete() {
|
|
for (var i = 0; i < deletionQueue.length; i++) {
|
|
final service = RequestService(
|
|
RequestHelper.deleteDirect(typeId, deletionQueue[i]),
|
|
);
|
|
service.delete();
|
|
messages.removeWhere((element) => element.id == deletionQueue[i]);
|
|
}
|
|
deletionQueue.clear();
|
|
notifyListeners();
|
|
}
|
|
|
|
void _addToDailyGrouped(MessageData message) {
|
|
String createdAt = message.createdAt.replaceAll('T', ' ').split(' ').first;
|
|
if (!dailyMessages.containsKey(createdAt)) {
|
|
dailyMessages.addAll({
|
|
createdAt: [message.id]
|
|
});
|
|
} else {
|
|
dailyMessages[createdAt]!.add(message.id);
|
|
}
|
|
}
|
|
|
|
Future<void> sendMessage() async {
|
|
if ((text == null || text!.isEmpty) &&
|
|
(recordedFile == null && recordedFileBytes == null)) return;
|
|
MediaService.audioPlayer.stop();
|
|
|
|
final body = {};
|
|
|
|
if (text != null) {
|
|
body.addAll({'text': text});
|
|
}
|
|
|
|
if (replyRadar != null) {
|
|
body.addAll({'radarId': replyRadar!.id});
|
|
}
|
|
|
|
if (replyNews != null) {
|
|
body.addAll({'newsId': replyNews!.id});
|
|
}
|
|
|
|
if (replyNews != null) {
|
|
body.addAll({'newsId': replyNews!.id});
|
|
}
|
|
|
|
if (path != null) {
|
|
final duration = await VoiceService.getDuration(src: path!);
|
|
if (duration != null) {
|
|
body.addAll({'duration': duration.inSeconds.toString()});
|
|
}
|
|
}
|
|
|
|
final uploadFile = recordedFile;
|
|
final uploadFileBytes = recordedFileBytes;
|
|
text = null;
|
|
recordedFile = null;
|
|
recordedFileBytes = null;
|
|
replyRadar = null;
|
|
replyNews = null;
|
|
path = null;
|
|
notifyListeners();
|
|
|
|
final service =
|
|
RequestService(RequestHelper.sendDirectMessage(typeId), body: body);
|
|
|
|
if (uploadFile == null && uploadFileBytes == null) {
|
|
await service.post();
|
|
|
|
if (service.isSuccess) {
|
|
final message = service.result['message'];
|
|
messages.insert(0, MessageData.fromJson(message));
|
|
|
|
dailyMessages.clear();
|
|
|
|
for (var i = 0; i < messages.length; i++) {
|
|
_addToDailyGrouped(messages[i]);
|
|
}
|
|
}
|
|
} else {
|
|
messages.insert(
|
|
0,
|
|
MessageData(
|
|
id: 0,
|
|
writedByAdmin: false,
|
|
readed: false,
|
|
createdAt:
|
|
DateTime.now().subtract(const Duration(minutes: 210)).toString(),
|
|
text: text,
|
|
// audio: path,
|
|
// audioFile: uploadFile,
|
|
radar: replyRadar,
|
|
news: replyNews,
|
|
audioDuration: audioDuration,
|
|
),
|
|
);
|
|
|
|
dailyMessages.clear();
|
|
|
|
for (var i = 0; i < messages.length; i++) {
|
|
_addToDailyGrouped(messages[i]);
|
|
}
|
|
|
|
if (kIsWeb) {
|
|
await service.multipartBytes(
|
|
file: uploadFileBytes!,
|
|
method: 'POST',
|
|
fieldName: 'audio',
|
|
fileName: 'voice-message',
|
|
mediaExtension: 'm4a',
|
|
mediaFormat: 'audio',
|
|
);
|
|
} else {
|
|
await service.multipart(
|
|
file: Platform.isIOS
|
|
? File(uploadFile!.path.replaceAll('file://', ''))
|
|
: uploadFile,
|
|
method: 'POST',
|
|
fieldName: 'audio',
|
|
fileName: 'voice-message',
|
|
mediaExtension: 'm4a',
|
|
mediaFormat: 'audio',
|
|
);
|
|
}
|
|
|
|
if (service.isSuccess) {
|
|
final message = service.result['message'];
|
|
final m = MessageData.fromJson(message);
|
|
messages[0] = m;
|
|
update();
|
|
}
|
|
}
|
|
}
|
|
}
|