websocket_message.dart 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 'reply':
  48. return ReplyMessage(
  49. text: json['text'] as String? ?? '',
  50. );
  51. case 'reply_partial':
  52. return ReplyPartialMessage(
  53. text: json['text'] as String? ?? '',
  54. );
  55. case 'cleared':
  56. return const ClearedMessage();
  57. case 'error':
  58. return ErrorMessage(
  59. message: json['message'] as String? ?? 'Unknown error',
  60. );
  61. default:
  62. return ErrorMessage(message: 'Unknown message type: $type');
  63. }
  64. }
  65. static ServerMessage fromJsonString(String source) {
  66. try {
  67. final json = jsonDecode(source) as Map<String, dynamic>;
  68. return fromJson(json);
  69. } on FormatException catch (e) {
  70. return ErrorMessage(message: 'Invalid JSON: $e');
  71. }
  72. }
  73. }
  74. final class ConnectedMessage extends ServerMessage {
  75. const ConnectedMessage({required this.model});
  76. final Map<String, dynamic> model;
  77. }
  78. final class PartialMessage extends ServerMessage {
  79. const PartialMessage({required this.text, this.seq = 0});
  80. final String text;
  81. final int seq;
  82. }
  83. final class UtteranceMessage extends ServerMessage {
  84. const UtteranceMessage({required this.text, this.seq = 0});
  85. final String text;
  86. final int seq;
  87. }
  88. final class ReplyMessage extends ServerMessage {
  89. const ReplyMessage({required this.text});
  90. final String text;
  91. }
  92. final class ReplyPartialMessage extends ServerMessage {
  93. const ReplyPartialMessage({required this.text});
  94. final String text;
  95. }
  96. final class ClearedMessage extends ServerMessage {
  97. const ClearedMessage();
  98. }
  99. final class ErrorMessage extends ServerMessage {
  100. const ErrorMessage({required this.message});
  101. final String message;
  102. }