|
|
|
|
@ -1,6 +1,5 @@
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/api/etqan_ovr_api_client.dart';
|
|
|
|
|
@ -23,6 +22,8 @@ class EtqanOvrProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
|
final SpeechToText _speechToText = SpeechToText();
|
|
|
|
|
bool _speechEnabled = false;
|
|
|
|
|
bool _isListening = false;
|
|
|
|
|
String _currentLocaleId = '';
|
|
|
|
|
TextEditingController? _currentController;
|
|
|
|
|
|
|
|
|
|
// Getters for speech state
|
|
|
|
|
bool get speechEnabled => _speechEnabled;
|
|
|
|
|
@ -50,18 +51,25 @@ class EtqanOvrProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
|
Future<void> initSpeech() async {
|
|
|
|
|
_speechEnabled = await _speechToText.initialize(
|
|
|
|
|
onStatus: (String status) {
|
|
|
|
|
// Update listening state when speech recognition status changes
|
|
|
|
|
if (status == 'done' || status == 'notListening') {
|
|
|
|
|
_isListening = false;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
print('Speech status: $status, isListening: $_isListening');
|
|
|
|
|
// If user wants to keep listening but speech stopped, restart it
|
|
|
|
|
if ((status == 'done' || status == 'notListening') && _isListening && _currentController != null) {
|
|
|
|
|
// Automatically restart listening after a brief pause
|
|
|
|
|
Future.delayed(const Duration(milliseconds: 200), () {
|
|
|
|
|
if (_isListening && _currentController != null) {
|
|
|
|
|
_startListeningInternal(_currentLocaleId, _currentController!);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Start listening for speech input
|
|
|
|
|
Future<void> startListening(String localeId, TextEditingController controller) async {
|
|
|
|
|
/// Internal method to start listening
|
|
|
|
|
Future<void> _startListeningInternal(String localeId, TextEditingController controller) async {
|
|
|
|
|
if (!_speechEnabled) return;
|
|
|
|
|
|
|
|
|
|
await _speechToText.listen(
|
|
|
|
|
onResult: (SpeechRecognitionResult result) {
|
|
|
|
|
description = result.recognizedWords;
|
|
|
|
|
@ -70,19 +78,31 @@ class EtqanOvrProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
|
notifyListeners();
|
|
|
|
|
},
|
|
|
|
|
localeId: localeId,
|
|
|
|
|
listenFor: const Duration(seconds: 30),
|
|
|
|
|
pauseFor: const Duration(seconds: 3),
|
|
|
|
|
partialResults: true,
|
|
|
|
|
listenMode: ListenMode.confirmation,
|
|
|
|
|
listenFor: const Duration(seconds: 60),
|
|
|
|
|
pauseFor: const Duration(seconds: 10),
|
|
|
|
|
listenOptions: SpeechListenOptions(
|
|
|
|
|
partialResults: true,
|
|
|
|
|
listenMode: ListenMode.confirmation,
|
|
|
|
|
cancelOnError: false,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Start listening for speech input
|
|
|
|
|
Future<void> startListening(String localeId, TextEditingController controller) async {
|
|
|
|
|
_isListening = true;
|
|
|
|
|
_currentLocaleId = localeId;
|
|
|
|
|
_currentController = controller;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
await _startListeningInternal(localeId, controller);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Stop listening for speech input
|
|
|
|
|
Future<void> stopListening() async {
|
|
|
|
|
await _speechToText.stop();
|
|
|
|
|
_isListening = false;
|
|
|
|
|
_currentLocaleId = '';
|
|
|
|
|
_currentController = null;
|
|
|
|
|
await _speechToText.stop();
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -193,21 +213,7 @@ class EtqanOvrProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
if (response != null) {
|
|
|
|
|
getEtqanEmployeeRequestsList = await EtqanApiClient().getEmployeeEtqanRequests();
|
|
|
|
|
if (getEtqanEmployeeRequestsList != null) {
|
|
|
|
|
getEtqanEmployeeRequestsList!.sort((EtqanGetEmployeeOvrRequestsResponse a, EtqanGetEmployeeOvrRequestsResponse b) {
|
|
|
|
|
if (a.createdDate == null && b.createdDate == null) return 0;
|
|
|
|
|
if (a.createdDate == null) return 1;
|
|
|
|
|
if (b.createdDate == null) return -1;
|
|
|
|
|
try {
|
|
|
|
|
DateFormat dateFormat = DateFormat("dd-MMM-yyyy hh:mm a");
|
|
|
|
|
DateTime dateA = dateFormat.parse(a.createdDate!);
|
|
|
|
|
DateTime dateB = dateFormat.parse(b.createdDate!);
|
|
|
|
|
return dateA.compareTo(dateB);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return (b.createdDate ?? '').compareTo(a.createdDate ?? '');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
notifyListeners();
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
@ -217,4 +223,12 @@ class EtqanOvrProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
if (_isListening) {
|
|
|
|
|
_speechToText.stop();
|
|
|
|
|
}
|
|
|
|
|
super.dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|