From 3325ebcad7a7bfaf9ffd2171a9dc44f89b5f2d3b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 15 May 2026 20:07:08 -0400 Subject: [PATCH] implement all msgtypes --- .vscode/settings.json | 1 + lib/models/content/message.dart | 67 ++++++++++++++++++++++++++++++++- lib/models/info/audio.dart | 17 +++++++++ lib/models/info/file.dart | 15 ++++++++ lib/models/info/image.dart | 17 +++++++++ lib/models/info/video.dart | 19 ++++++++++ lib/models/ms_duration.dart | 11 ++++++ 7 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 lib/models/info/audio.dart create mode 100644 lib/models/info/file.dart create mode 100644 lib/models/info/image.dart create mode 100644 lib/models/info/video.dart create mode 100644 lib/models/ms_duration.dart diff --git a/.vscode/settings.json b/.vscode/settings.json index da80f4b..855ee97 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ "Gomuks", "Homeserver", "localpart", + "msgtype", "muks", "prefs" ] diff --git a/lib/models/content/message.dart b/lib/models/content/message.dart index 629f21c..e98dbf5 100644 --- a/lib/models/content/message.dart +++ b/lib/models/content/message.dart @@ -1,14 +1,77 @@ import "package:freezed_annotation/freezed_annotation.dart"; +import "package:nexus/models/info/audio.dart"; import "package:nexus/models/content/content.dart"; +import "package:nexus/models/info/file.dart"; +import "package:nexus/models/info/image.dart"; part "message.freezed.dart"; part "message.g.dart"; -@freezed +@Freezed(unionKey: "msgtype", fallbackUnion: "default") abstract class MessageContent extends Content with _$MessageContent { static const type = "m.room.message"; MessageContent._(); - const factory MessageContent({required String msgtype}) = _MessageContent; + const factory MessageContent({ + required String msgtype, + required String body, + String? format, + String? formattedBody, + }) = _TextMessageContent; + + @FreezedUnionValue("m.image") + const factory MessageContent.image({ + required String msgtype, + required String body, + String? format, + String? formattedBody, + // EncryptedFile? file + String? filename, + ImageInfo? info, + String? url, + }) = _ImageMessageContent; + + @FreezedUnionValue("m.file") + const factory MessageContent.file({ + required String msgtype, + required String body, + String? format, + String? formattedBody, + // EncryptedFile? file + String? filename, + FileInfo? info, + String? url, + }) = _FileMessageContent; + + @FreezedUnionValue("m.audio") + const factory MessageContent.audio({ + required String msgtype, + required String body, + String? format, + String? formattedBody, + // EncryptedFile? file + String? filename, + AudioInfo? info, + String? url, + }) = _AudioMessageContent; + + @FreezedUnionValue("m.video") + const factory MessageContent.video({ + required String msgtype, + required String body, + String? format, + String? formattedBody, + // EncryptedFile? file + String? filename, + AudioInfo? info, + String? url, + }) = _AudioMessageContent; + + @FreezedUnionValue("m.location") + const factory MessageContent.location({ + required String msgtype, + required String body, + required Uri geoUri, + }) = _LocationMessageContent; factory MessageContent.fromJson(Map json) => _$MessageContentFromJson(json); diff --git a/lib/models/info/audio.dart b/lib/models/info/audio.dart new file mode 100644 index 0000000..ccfcf7a --- /dev/null +++ b/lib/models/info/audio.dart @@ -0,0 +1,17 @@ +import "package:freezed_annotation/freezed_annotation.dart"; +import "package:nexus/models/ms_duration.dart"; +part "audio.freezed.dart"; +part "audio.g.dart"; + +@freezed +abstract class AudioInfo with _$AudioInfo { + /// Information for images, [size] is in bytes. + const factory AudioInfo({ + @MSDuration() Duration? duration, + @JsonKey(name: "mimetype") String? mimeType, + int? size, + }) = _AudioInfo; + + factory AudioInfo.fromJson(Map json) => + _$AudioInfoFromJson(json); +} diff --git a/lib/models/info/file.dart b/lib/models/info/file.dart new file mode 100644 index 0000000..1509c99 --- /dev/null +++ b/lib/models/info/file.dart @@ -0,0 +1,15 @@ +import "package:freezed_annotation/freezed_annotation.dart"; +part "file.freezed.dart"; +part "file.g.dart"; + +@freezed +abstract class FileInfo with _$FileInfo { + /// Information for images, [size] is in bytes. + const factory FileInfo({ + @JsonKey(name: "mimetype") String? mimeType, + int? size, + }) = _FileInfo; + + factory FileInfo.fromJson(Map json) => + _$FileInfoFromJson(json); +} diff --git a/lib/models/info/image.dart b/lib/models/info/image.dart new file mode 100644 index 0000000..9397aa8 --- /dev/null +++ b/lib/models/info/image.dart @@ -0,0 +1,17 @@ +import "package:freezed_annotation/freezed_annotation.dart"; +part "image.freezed.dart"; +part "image.g.dart"; + +@freezed +abstract class ImageInfo with _$ImageInfo { + /// Information for images, [size] is in bytes. + const factory ImageInfo({ + @JsonKey(name: "h") int? height, + @JsonKey(name: "w") int? width, + @JsonKey(name: "mimetype") String? mimeType, + int? size, + }) = _ImageInfo; + + factory ImageInfo.fromJson(Map json) => + _$ImageInfoFromJson(json); +} diff --git a/lib/models/info/video.dart b/lib/models/info/video.dart new file mode 100644 index 0000000..6ff3547 --- /dev/null +++ b/lib/models/info/video.dart @@ -0,0 +1,19 @@ +import "package:freezed_annotation/freezed_annotation.dart"; +import "package:nexus/models/ms_duration.dart"; +part "video.freezed.dart"; +part "video.g.dart"; + +@freezed +abstract class VideoInfo with _$VideoInfo { + /// Information for images, [size] is in bytes. + const factory VideoInfo({ + @JsonKey(name: "h") int? height, + @JsonKey(name: "w") int? width, + @JsonKey(name: "mimetype") String? mimeType, + @MSDuration() Duration? duration, + int? size, + }) = _VideoInfo; + + factory VideoInfo.fromJson(Map json) => + _$VideoInfoFromJson(json); +} diff --git a/lib/models/ms_duration.dart b/lib/models/ms_duration.dart new file mode 100644 index 0000000..de12943 --- /dev/null +++ b/lib/models/ms_duration.dart @@ -0,0 +1,11 @@ +import "package:freezed_annotation/freezed_annotation.dart"; + +class MSDuration implements JsonConverter { + const MSDuration(); + + @override + Duration fromJson(int ms) => Duration(milliseconds: ms); + + @override + int toJson(Duration duration) => duration.inMilliseconds; +}