working sync complete

This commit is contained in:
Henry Hiles 2026-01-26 19:39:02 +00:00
commit 97f2673b55
No known key found for this signature in database
11 changed files with 61 additions and 100 deletions

View file

@ -25,7 +25,7 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
final gomuksBuildDir = buildDir.resolve("gomuks/");
final libFile = gomuksBuildDir.resolve(libFileName);
print("Building Gomuks shared library $libFileName...");
print("Building Gomuks shared library $libFileName from source...");
final result = await Process.run("go", [
"build",
"-o",
@ -48,6 +48,7 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
file: libFile,
),
)
..dependencies.add(libFile);
..dependencies.add(libFile)
..dependencies.add(gomuksBuildDir);
print("Done!");
});

View file

@ -9,7 +9,7 @@ import "package:nexus/controllers/sync_status_controller.dart";
import "package:nexus/helpers/extensions/gomuks_buffer.dart";
import "package:nexus/models/client_state.dart";
import "package:nexus/models/login.dart";
import "package:nexus/models/sync_complete.dart";
import "package:nexus/models/sync_data.dart";
import "package:nexus/models/sync_status.dart";
import "package:nexus/src/third_party/gomuks.g.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
@ -20,17 +20,18 @@ class ClientController extends AsyncNotifier<int> {
final handle = await Isolate.run(GomuksInit);
ref.onDispose(() => GomuksDestroy(handle));
GomuksStart(
final errorCode = GomuksStart(
handle,
NativeCallable<
Void Function(Pointer<Char>, Int64, GomuksBorrowedBuffer)
Void Function(Pointer<Char>, Int64, GomuksOwnedBuffer)
>.listener((
Pointer<Char> command,
int requestId,
GomuksBorrowedBuffer data,
GomuksOwnedBuffer data,
) {
try {
final muksEventType = command.cast<Utf8>().toDartString();
debugPrint("Handling $muksEventType...");
final Map<String, dynamic> decodedMuksEvent = data.toJson();
switch (muksEventType) {
@ -45,9 +46,9 @@ class ClientController extends AsyncNotifier<int> {
.set(SyncStatus.fromJson(decodedMuksEvent));
break;
case "sync_complete":
debugger(message: jsonEncode(decodedMuksEvent));
final thing = SyncComplete.fromJson(decodedMuksEvent);
debugger(message: jsonEncode(thing.toJson()));
final syncData = SyncData.fromJson(decodedMuksEvent);
debugPrint(jsonEncode(syncData.toJson()));
// ref
// .watch(SyncStatusController.provider.notifier)
// .set(SyncStatus.fromJson(decodedMuksEvent));
@ -58,14 +59,17 @@ class ClientController extends AsyncNotifier<int> {
default:
debugPrint("Unhandled event: $muksEventType");
}
debugPrint("Finished handling $muksEventType...");
} catch (error, stackTrace) {
debugger();
debugPrintStack(stackTrace: stackTrace, label: error.toString());
}
})
.nativeFunction,
);
return handle;
if (errorCode == 0) return handle;
throw Exception("GomuksStart returned error code $errorCode");
}
Future<Map<String, dynamic>> sendCommand(

View file

@ -1,13 +0,0 @@
import "package:matrix/matrix.dart";
import "package:nexus/models/full_room.dart";
extension GetFullRoom on Room {
Future<FullRoom> get fullRoom async {
await loadHeroUsers();
return FullRoom(
roomData: this,
title: getLocalizedDisplayname(),
avatar: await avatar?.getThumbnailUri(client, width: 24, height: 24),
);
}
}

View file

@ -1,23 +1,9 @@
import "dart:convert";
import "dart:ffi";
import "dart:typed_data";
import "package:ffi/ffi.dart";
import "package:nexus/src/third_party/gomuks.g.dart";
extension GomuksBorrowedBufferToJson on GomuksBorrowedBuffer {
Uint8List toBytes() {
if (base == nullptr || length <= 0) return Uint8List(0);
return base.asTypedList(length);
}
Map<String, dynamic> toJson() {
final bytes = toBytes();
if (bytes.isEmpty) return {};
return jsonDecode(utf8.decode(bytes));
}
}
extension GomuksOwnedBufferToJson on GomuksOwnedBuffer {
Uint8List toBytes() {
try {

View file

@ -1,14 +0,0 @@
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

@ -9,24 +9,24 @@ abstract class Event with _$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 eventId,
@JsonKey(name: "sender") required String authorId,
required String type,
required String stateKey,
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,
Map<String, dynamic>? decrypted,
String? decryptedType,
@Default({}) Map<String, dynamic> unsigned,
LocalContent? localContent,
String? transactionId,
String? redactedBy,
String? relatesTo,
String? relatesType,
String? decryptionError,
String? sendError,
@Default({}) Map<String, int> reactions,
int? lastEditRowId,
@UnreadTypeConverter() UnreadType? unreadType,
}) = _Event;
@ -36,13 +36,11 @@ abstract class Event with _$Event {
@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,
String? sanitizedHtml,
bool? wasPlaintext,
bool? bigEmoji,
bool? hasMath,
bool? replyFallbackRemoved,
}) = _LocalContent;
factory LocalContent.fromJson(Map<String, Object?> json) =>

View file

@ -5,7 +5,7 @@ part "lazy_load_summary.g.dart";
@freezed
abstract class LazyLoadSummary with _$LazyLoadSummary {
const factory LazyLoadSummary({
required List<String> heroes,
required List<String>? heroes,
required int? joinedMemberCount,
required int? invitedMemberCount,
}) = _LazyLoadSummary;

View file

@ -9,12 +9,12 @@ part "room.g.dart";
abstract class Room with _$Room {
const factory Room({
@JsonKey(name: "meta") RoomMetadata? metadata,
required List<TimelineRowTuple> timeline,
@Default([]) 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,
@Default({}) Map<String, List<ReadReceipt>> receipts,
required bool dismissNotifications,
// required List<Notification> notifications,
}) = _Room;
@ -26,7 +26,7 @@ abstract class Room with _$Room {
abstract class TimelineRowTuple with _$TimelineRowTuple {
const factory TimelineRowTuple({
@JsonKey(name: "timeline_rowid") required int timelineRowId,
@JsonKey(name: "timeline_eventid") required int eventRowId,
@JsonKey(name: "timeline_eventid") int? eventRowId,
}) = _TimelineRowTuple;
factory TimelineRowTuple.fromJson(Map<String, Object?> json) =>

View file

@ -1,5 +1,4 @@
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";
@ -12,12 +11,12 @@ abstract class RoomMetadata with _$RoomMetadata {
// required CreateEventContent creationContent,
// required TombstoneEventContent tombstoneEventContent,
String? name,
ContentUri? avatar,
Uri? avatar,
String? topic,
String? canonicalAlias,
LazyLoadSummary? lazyLoadSummary,
required bool hasMemberList,
@JsonKey(name: "preview_event_rowid") required String previewEventRowID,
@JsonKey(name: "preview_event_rowid") required int previewEventRowID,
@EpochDateTimeConverter() required DateTime sortingTimestamp,
@Default(false) bool markedUnread,
}) = _RoomMetadata;

View file

@ -1,20 +0,0 @@
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);
}

20
lib/models/sync_data.dart Normal file
View file

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