This commit is contained in:
Henry Hiles 2026-01-26 11:35:45 +00:00
commit 27fba2cdb5
No known key found for this signature in database
11 changed files with 228 additions and 19 deletions

View file

@ -0,0 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart";
part "content_uri.freezed.dart";
part "content_uri.g.dart";
@freezed
abstract class ContentUri with _$ContentUri {
const factory ContentUri({
required String homeserver,
required String fileID,
}) = _ContentUri;
factory ContentUri.fromJson(Map<String, Object?> json) =>
_$ContentUriFromJson(json);
}

View file

@ -0,0 +1,11 @@
import "package:freezed_annotation/freezed_annotation.dart";
class EpochDateTimeConverter implements JsonConverter<DateTime, int> {
const EpochDateTimeConverter();
@override
DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json);
@override
int toJson(DateTime object) => object.millisecondsSinceEpoch;
}

79
lib/models/event.dart Normal file
View file

@ -0,0 +1,79 @@
import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/epoch_date_time_converter.dart";
part "event.freezed.dart";
part "event.g.dart";
@freezed
abstract class Event with _$Event {
const factory Event({
@JsonKey(name: "rowid") required int rowId,
@JsonKey(name: "timeline_rowid") required int timelineRowId,
required String roomId,
required int eventId,
@JsonKey(name: "sender") required int authorId,
required String type,
required String stateKey,
@EpochDateTimeConverter() required DateTime timestamp,
required Map<String, dynamic> content,
required Map<String, dynamic> decrypted,
required Map<String, dynamic> decryptedType,
required Map<String, dynamic> unsigned,
required LocalContent localContent,
required String transactionId,
required String redactedBy,
required String relatesTo,
required String relatesType,
required String decryptionError,
required String sendError,
required Map<String, int> reactions,
required int lastEditRowId,
@UnreadTypeConverter() UnreadType? unreadType,
}) = _Event;
factory Event.fromJson(Map<String, Object?> json) => _$EventFromJson(json);
}
@freezed
abstract class LocalContent with _$LocalContent {
const factory LocalContent({
required String sanitizedHtml,
required String htmlVersion,
required bool wasPlaintext,
required bool bigEmoji,
required bool hasMath,
required String editSource,
required String replyFallbackRemoved,
}) = _LocalContent;
factory LocalContent.fromJson(Map<String, Object?> json) =>
_$LocalContentFromJson(json);
}
class UnreadTypeConverter implements JsonConverter<UnreadType?, int?> {
const UnreadTypeConverter();
@override
UnreadType? fromJson(int? json) => json == null ? null : UnreadType(json);
@override
int? toJson(UnreadType? object) => object?.value;
}
@immutable
class UnreadType {
final int value;
const UnreadType(this.value);
static const none = UnreadType(0);
static const normal = UnreadType(1);
static const notify = UnreadType(2);
static const highlight = UnreadType(4);
static const sound = UnreadType(8);
bool get isNone => value == 0;
bool get isNormal => (value & 1) != 0;
bool get shouldNotify => (value & 2) != 0;
bool get isHighlighted => (value & 4) != 0;
bool get playsSound => (value & 8) != 0;
}

View file

@ -0,0 +1,15 @@
import "package:freezed_annotation/freezed_annotation.dart";
part "lazy_load_summary.freezed.dart";
part "lazy_load_summary.g.dart";
@freezed
abstract class LazyLoadSummary with _$LazyLoadSummary {
const factory LazyLoadSummary({
required List<String> heroes,
required int? joinedMemberCount,
required int? invitedMemberCount,
}) = _LazyLoadSummary;
factory LazyLoadSummary.fromJson(Map<String, Object?> json) =>
_$LazyLoadSummaryFromJson(json);
}

View file

@ -0,0 +1,18 @@
import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/epoch_date_time_converter.dart";
part "read_receipt.freezed.dart";
part "read_receipt.g.dart";
@freezed
abstract class ReadReceipt with _$ReadReceipt {
const factory ReadReceipt({
String? roomId,
required String userId,
String? threadId,
required String eventId,
@EpochDateTimeConverter() required DateTime timestamp,
}) = _ReadReceipt;
factory ReadReceipt.fromJson(Map<String, Object?> json) =>
_$ReadReceiptFromJson(json);
}

34
lib/models/room.dart Normal file
View file

@ -0,0 +1,34 @@
import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/event.dart";
import "package:nexus/models/read_receipt.dart";
import "package:nexus/models/room_metadata.dart";
part "room.freezed.dart";
part "room.g.dart";
@freezed
abstract class Room with _$Room {
const factory Room({
@JsonKey(name: "meta") RoomMetadata? metadata,
required List<TimelineRowTuple> timeline,
required bool reset,
required Map<String, Map> state,
// required Map<String, AccountData> accountData,
required List<Event> events,
required Map<String, List<ReadReceipt>> receipts,
required bool dismissNotifications,
// required List<Notification> notifications,
}) = _Room;
factory Room.fromJson(Map<String, Object?> json) => _$RoomFromJson(json);
}
@freezed
abstract class TimelineRowTuple with _$TimelineRowTuple {
const factory TimelineRowTuple({
@JsonKey(name: "timeline_rowid") required int timelineRowId,
@JsonKey(name: "timeline_eventid") required int eventRowId,
}) = _TimelineRowTuple;
factory TimelineRowTuple.fromJson(Map<String, Object?> json) =>
_$TimelineRowTupleFromJson(json);
}

View file

@ -0,0 +1,27 @@
import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content_uri.dart";
import "package:nexus/models/epoch_date_time_converter.dart";
import "package:nexus/models/lazy_load_summary.dart";
part "room_metadata.freezed.dart";
part "room_metadata.g.dart";
@freezed
abstract class RoomMetadata with _$RoomMetadata {
const factory RoomMetadata({
@JsonKey(name: "room_id") required String id,
// required CreateEventContent creationContent,
// required TombstoneEventContent tombstoneEventContent,
String? name,
ContentUri? avatar,
String? topic,
String? canonicalAlias,
LazyLoadSummary? lazyLoadSummary,
required bool hasMemberList,
@JsonKey(name: "preview_event_rowid") required String previewEventRowID,
@EpochDateTimeConverter() required DateTime sortingTimestamp,
@Default(false) bool markedUnread,
}) = _RoomMetadata;
factory RoomMetadata.fromJson(Map<String, Object?> json) =>
_$RoomMetadataFromJson(json);
}

View file

@ -0,0 +1,20 @@
import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/room.dart";
part "sync_complete.freezed.dart";
part "sync_complete.g.dart";
@freezed
abstract class SyncComplete with _$SyncComplete {
const factory SyncComplete({
@Default(false) bool clearState,
// required Map<String, AccountData> accountData,
required Map<String, Room> rooms,
required List<String> leftRooms,
// required List<InvitedRoom> invitedRooms,
// required List<SpaceEdge> spaceEdges,
required List<String> topLevelSpaces,
}) = _SyncComplete;
factory SyncComplete.fromJson(Map<String, Object?> json) =>
_$SyncCompleteFromJson(json);
}

View file

@ -6,8 +6,8 @@ part "sync_status.g.dart";
abstract class SyncStatus with _$SyncStatus {
const factory SyncStatus({
required SyncStatusType type,
String? error,
required int errorCount,
required int lastSync,
}) = _SyncStatus;
factory SyncStatus.fromJson(Map<String, Object?> json) =>