websocket_message.dart 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import 'dart:convert';
  2. sealed class WebSocketMessage {
  3. const WebSocketMessage();
  4. Map<String, dynamic> toJson();
  5. String toJsonString() => jsonEncode(toJson());
  6. }
  7. final class AudioMessage extends WebSocketMessage {
  8. const AudioMessage({required this.data});
  9. final String data;
  10. @override
  11. Map<String, dynamic> toJson() => {'type': 'audio', 'data': data};
  12. }
  13. final class TranscribeMessage extends WebSocketMessage {
  14. const TranscribeMessage();
  15. @override
  16. Map<String, dynamic> toJson() => {'type': 'transcribe'};
  17. }
  18. final class ClearMessage extends WebSocketMessage {
  19. const ClearMessage();
  20. @override
  21. Map<String, dynamic> toJson() => {'type': 'clear'};
  22. }
  23. final class FinalizeMessage extends WebSocketMessage {
  24. const FinalizeMessage();
  25. @override
  26. Map<String, dynamic> toJson() => {'type': 'finalize'};
  27. }
  28. sealed class ServerMessage {
  29. const ServerMessage();
  30. static ServerMessage fromJson(Map<String, dynamic> json) {
  31. final type = json['type'] as String?;
  32. switch (type) {
  33. case 'connected':
  34. return ConnectedMessage(
  35. model: json['model'] as Map<String, dynamic>? ?? const {},
  36. );
  37. case 'partial':
  38. return PartialMessage(
  39. text: json['text'] as String? ?? '',
  40. seq: json['seq'] as int? ?? 0,
  41. );
  42. case 'utterance':
  43. return UtteranceMessage(
  44. text: json['text'] as String? ?? '',
  45. seq: json['seq'] as int? ?? 0,
  46. );
  47. case 'transcript':
  48. return TranscriptMessage(
  49. text: json['text'] as String? ?? '',
  50. language: json['language'] as String? ?? '',
  51. );
  52. case 'reply':
  53. return ReplyMessage(
  54. text: json['text'] as String? ?? '',
  55. );
  56. case 'reply_partial':
  57. return ReplyPartialMessage(
  58. text: json['text'] as String? ?? '',
  59. );
  60. case 'cleared':
  61. return const ClearedMessage();
  62. case 'error':
  63. return ErrorMessage(
  64. message: json['message'] as String? ?? 'Unknown error',
  65. );
  66. default:
  67. return ErrorMessage(message: 'Unknown message type: $type');
  68. }
  69. }
  70. static ServerMessage fromJsonString(String source) {
  71. try {
  72. final json = jsonDecode(source) as Map<String, dynamic>;
  73. return fromJson(json);
  74. } on FormatException catch (e) {
  75. return ErrorMessage(message: 'Invalid JSON: $e');
  76. }
  77. }
  78. }
  79. final class ConnectedMessage extends ServerMessage {
  80. const ConnectedMessage({required this.model});
  81. final Map<String, dynamic> model;
  82. }
  83. final class PartialMessage extends ServerMessage {
  84. const PartialMessage({required this.text, this.seq = 0});
  85. final String text;
  86. final int seq;
  87. }
  88. final class UtteranceMessage extends ServerMessage {
  89. const UtteranceMessage({required this.text, this.seq = 0});
  90. final String text;
  91. final int seq;
  92. }
  93. final class ReplyMessage extends ServerMessage {
  94. const ReplyMessage({required this.text});
  95. final String text;
  96. }
  97. final class ReplyPartialMessage extends ServerMessage {
  98. const ReplyPartialMessage({required this.text});
  99. final String text;
  100. }
  101. final class ClearedMessage extends ServerMessage {
  102. const ClearedMessage();
  103. }
  104. final class TranscriptMessage extends ServerMessage {
  105. const TranscriptMessage({required this.text, this.language = ''});
  106. final String text;
  107. final String language;
  108. }
  109. final class ErrorMessage extends ServerMessage {
  110. const ErrorMessage({required this.message});
  111. final String message;
  112. }