fetchVoicesViaSocket function

Future<SocketVoiceResponse> fetchVoicesViaSocket(
  1. Socket socket,
  2. String provider,
  3. String language
)

Fetch voices via socket connection (keeps API keys server-side)

Implementation

Future<SocketVoiceResponse> fetchVoicesViaSocket(
  io.Socket socket,
  String provider,
  String language,
) async {
  final completer = Completer<SocketVoiceResponse>();

  // Set timeout
  final timeout = Timer(const Duration(seconds: 5), () {
    if (!completer.isCompleted) {
      // Return static voices as fallback
      completer.complete(SocketVoiceResponse(
        provider: provider,
        language: language,
        voices: getAvailableVoices(language, provider: provider),
        error: 'Request timed out, using static voices',
      ));
    }
  });

  socket.emitWithAck('translation:getVoices', {
    'provider': provider,
    'language': language,
  }, ack: (response) {
    timeout.cancel();
    if (!completer.isCompleted) {
      if (response is Map<String, dynamic>) {
        final maleVoices = (response['voices']?['male'] as List?)
                ?.map((v) => VoiceOption.fromMap(v as Map<String, dynamic>))
                .toList() ??
            [];
        final femaleVoices = (response['voices']?['female'] as List?)
                ?.map((v) => VoiceOption.fromMap(v as Map<String, dynamic>))
                .toList() ??
            [];

        completer.complete(SocketVoiceResponse(
          provider: response['provider'] as String? ?? provider,
          language: response['language'] as String? ?? language,
          voices: {'male': maleVoices, 'female': femaleVoices},
          error: response['error'] as String?,
        ));
      } else {
        completer.complete(SocketVoiceResponse(
          provider: provider,
          language: language,
          voices: getAvailableVoices(language, provider: provider),
          error: 'Invalid response format',
        ));
      }
    }
  });

  return completer.future;
}