Fix fetching issue, use gomuks generated edit source

This commit is contained in:
Henry Hiles 2026-03-01 13:56:40 -05:00
commit 3b3423bec8
No known key found for this signature in database
9 changed files with 99 additions and 43 deletions

View file

@ -0,0 +1,16 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/models/account_data.dart";
class AccountDataController extends Notifier<IMap<String, AccountData>> {
@override
IMap<String, AccountData> build() => const IMap.empty();
void update(IMap<String, AccountData> newData) =>
state = IMap({...state.unlock, ...newData.unlock});
static final provider =
NotifierProvider<AccountDataController, IMap<String, AccountData>>(
AccountDataController.new,
);
}

View file

@ -5,6 +5,7 @@ import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:ffi/ffi.dart";
import "package:flutter/foundation.dart";
import "package:nexus/controllers/account_data_controller.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/init_complete_controller.dart";
import "package:nexus/controllers/rooms_controller.dart";
@ -66,16 +67,26 @@ class ClientController extends AsyncNotifier<int> {
case "sync_complete":
final syncData = SyncData.fromJson(decodedMuksEvent);
final roomProvider = RoomsController.provider;
final accountDataProvider = AccountDataController.provider;
if (syncData.clearState) {
ref.invalidate(roomProvider);
ref.invalidate(accountDataProvider);
}
if (syncData.clearState) ref.invalidate(roomProvider);
ref
.watch(roomProvider.notifier)
.update(syncData.rooms, syncData.leftRooms);
ref
.watch(accountDataProvider.notifier)
.update(syncData.accountData);
if (syncData.topLevelSpaces != null) {
ref
.watch(TopLevelSpacesController.provider.notifier)
.set(syncData.topLevelSpaces!);
}
if (syncData.spaceEdges != null) {
ref
.watch(SpaceEdgesController.provider.notifier)

View file

@ -70,6 +70,7 @@ class MessageController extends AsyncNotifier<Message?> {
"body": newContent?["body"] ?? content["body"],
"eventType": type,
"avatarUrl": author?.content["avatar_url"],
"editSource": event.localContent?.editSource,
"displayName": author?.content["displayname"]?.isNotEmpty == true
? author?.content["displayname"]
: event.authorId.substring(1).split(":")[0],

View file

@ -28,6 +28,37 @@ class RoomChatController extends AsyncNotifier<ChatController> {
final room = ref.read(RoomsController.provider)[roomId];
if (room == null) return InMemoryChatController();
final state = await client.getRoomState(
GetRoomStateRequest(
roomId: roomId,
fetchMembers: room.metadata?.hasMemberList == false,
includeMembers: true,
),
);
ref
.read(RoomsController.provider.notifier)
.update(
{
roomId: Room(
events: state,
state: state.fold(
const IMap.empty(),
(previousValue, stateEvent) => previousValue.add(
stateEvent.type,
(previousValue[stateEvent.type] ?? const IMap.empty()).addAll(
IMap({
if (stateEvent.stateKey != null)
stateEvent.stateKey!: stateEvent.rowId,
}),
),
),
),
),
}.toIMap(),
const ISet.empty(),
);
final messages = await ref.watch(
MessagesController.provider(
MessagesConfig(
@ -103,37 +134,6 @@ class RoomChatController extends AsyncNotifier<ChatController> {
if (messages.length < 20) await loadOlder(controller);
}
final state = await client.getRoomState(
GetRoomStateRequest(
roomId: roomId,
fetchMembers: room.metadata?.hasMemberList == false,
includeMembers: true,
),
);
ref
.read(RoomsController.provider.notifier)
.update(
{
roomId: Room(
events: state,
state: state.fold(
const IMap.empty(),
(previousValue, stateEvent) => previousValue.add(
stateEvent.type,
(previousValue[stateEvent.type] ?? const IMap.empty()).addAll(
IMap({
if (stateEvent.stateKey != null)
stateEvent.stateKey!: stateEvent.rowId,
}),
),
),
),
),
}.toIMap(),
const ISet.empty(),
);
return controller;
}

View file

@ -1,6 +1,7 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/account_data_controller.dart";
import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/controllers/top_level_spaces_controller.dart";
import "package:nexus/controllers/space_edges_controller.dart";
@ -57,12 +58,28 @@ class SpacesController extends Notifier<IList<Space>> {
)
.map((e) => e.value);
final accountData = ref.watch(AccountDataController.provider);
final directMessages = IMap(
accountData["m.direct"]?.content ?? {},
).values.expand((element) => element);
final homeRooms = otherRooms
.where((room) => room.metadata?.dmUserId == null)
.where(
(room) =>
directMessages.any(
(directMessage) => directMessage == room.metadata?.id,
) ==
false,
)
.toIList();
final dmRooms = otherRooms
.where((room) => room.metadata?.dmUserId != null)
.where(
(room) => directMessages.any(
(directMessage) => directMessage == room.metadata?.id,
),
)
.toIList();
final topLevelSpacesList = topLevelSpaceIds

View file

@ -0,0 +1,16 @@
import "package:freezed_annotation/freezed_annotation.dart";
part "account_data.freezed.dart";
part "account_data.g.dart";
@freezed
abstract class AccountData with _$AccountData {
const factory AccountData({
required String userId,
required String? roomId,
required String type,
required dynamic content,
}) = _AccountData;
factory AccountData.fromJson(Map<String, Object?> json) =>
_$AccountDataFromJson(json);
}

View file

@ -38,6 +38,7 @@ abstract class Event with _$Event {
abstract class LocalContent with _$LocalContent {
const factory LocalContent({
String? sanitizedHtml,
String? editSource,
bool? wasPlaintext,
bool? bigEmoji,
bool? hasMath,

View file

@ -1,5 +1,6 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/account_data.dart";
import "package:nexus/models/room.dart";
import "package:nexus/models/space_edge.dart";
part "sync_data.freezed.dart";
@ -9,7 +10,7 @@ part "sync_data.g.dart";
abstract class SyncData with _$SyncData {
const factory SyncData({
@Default(false) bool clearState,
// required IMap<String, AccountData> accountData,
@Default(IMap.empty()) IMap<String, AccountData> accountData,
@Default(IMap.empty()) IMap<String, Room> rooms,
@Default(ISet.empty()) ISet<String> leftRooms,
// required IList<InvitedRoom> invitedRooms,

View file

@ -34,14 +34,7 @@ class ChatBox extends HookConsumerWidget {
if (relationType == RelationType.edit &&
relatedMessage is TextMessage &&
controller.value.text.isEmpty) {
final text = (relatedMessage as TextMessage).text;
final splitText = relatedMessage?.replyToMessageId == null
? text
: text.split("\n\n").sublist(1).join("\n\n");
final notEmpty = splitText.isEmpty ? text : splitText;
controller.value.text = notEmpty.startsWith("* ")
? notEmpty.substring(2)
: notEmpty;
controller.value.text = relatedMessage?.metadata?["editSource"];
}
void send() {