Compare commits
1 commit
dfc2a9e137
...
3b3423bec8
| Author | SHA1 | Date | |
|---|---|---|---|
|
3b3423bec8 |
9 changed files with 99 additions and 43 deletions
16
lib/controllers/account_data_controller.dart
Normal file
16
lib/controllers/account_data_controller.dart
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import "package:collection/collection.dart";
|
||||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||||
import "package:ffi/ffi.dart";
|
import "package:ffi/ffi.dart";
|
||||||
import "package:flutter/foundation.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/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/init_complete_controller.dart";
|
import "package:nexus/controllers/init_complete_controller.dart";
|
||||||
import "package:nexus/controllers/rooms_controller.dart";
|
import "package:nexus/controllers/rooms_controller.dart";
|
||||||
|
|
@ -66,16 +67,26 @@ class ClientController extends AsyncNotifier<int> {
|
||||||
case "sync_complete":
|
case "sync_complete":
|
||||||
final syncData = SyncData.fromJson(decodedMuksEvent);
|
final syncData = SyncData.fromJson(decodedMuksEvent);
|
||||||
final roomProvider = RoomsController.provider;
|
final roomProvider = RoomsController.provider;
|
||||||
|
final accountDataProvider = AccountDataController.provider;
|
||||||
|
|
||||||
|
if (syncData.clearState) {
|
||||||
|
ref.invalidate(roomProvider);
|
||||||
|
ref.invalidate(accountDataProvider);
|
||||||
|
}
|
||||||
|
|
||||||
if (syncData.clearState) ref.invalidate(roomProvider);
|
|
||||||
ref
|
ref
|
||||||
.watch(roomProvider.notifier)
|
.watch(roomProvider.notifier)
|
||||||
.update(syncData.rooms, syncData.leftRooms);
|
.update(syncData.rooms, syncData.leftRooms);
|
||||||
|
ref
|
||||||
|
.watch(accountDataProvider.notifier)
|
||||||
|
.update(syncData.accountData);
|
||||||
|
|
||||||
if (syncData.topLevelSpaces != null) {
|
if (syncData.topLevelSpaces != null) {
|
||||||
ref
|
ref
|
||||||
.watch(TopLevelSpacesController.provider.notifier)
|
.watch(TopLevelSpacesController.provider.notifier)
|
||||||
.set(syncData.topLevelSpaces!);
|
.set(syncData.topLevelSpaces!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syncData.spaceEdges != null) {
|
if (syncData.spaceEdges != null) {
|
||||||
ref
|
ref
|
||||||
.watch(SpaceEdgesController.provider.notifier)
|
.watch(SpaceEdgesController.provider.notifier)
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ class MessageController extends AsyncNotifier<Message?> {
|
||||||
"body": newContent?["body"] ?? content["body"],
|
"body": newContent?["body"] ?? content["body"],
|
||||||
"eventType": type,
|
"eventType": type,
|
||||||
"avatarUrl": author?.content["avatar_url"],
|
"avatarUrl": author?.content["avatar_url"],
|
||||||
|
"editSource": event.localContent?.editSource,
|
||||||
"displayName": author?.content["displayname"]?.isNotEmpty == true
|
"displayName": author?.content["displayname"]?.isNotEmpty == true
|
||||||
? author?.content["displayname"]
|
? author?.content["displayname"]
|
||||||
: event.authorId.substring(1).split(":")[0],
|
: event.authorId.substring(1).split(":")[0],
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,37 @@ class RoomChatController extends AsyncNotifier<ChatController> {
|
||||||
final room = ref.read(RoomsController.provider)[roomId];
|
final room = ref.read(RoomsController.provider)[roomId];
|
||||||
if (room == null) return InMemoryChatController();
|
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(
|
final messages = await ref.watch(
|
||||||
MessagesController.provider(
|
MessagesController.provider(
|
||||||
MessagesConfig(
|
MessagesConfig(
|
||||||
|
|
@ -103,37 +134,6 @@ class RoomChatController extends AsyncNotifier<ChatController> {
|
||||||
if (messages.length < 20) await loadOlder(controller);
|
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;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.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/rooms_controller.dart";
|
||||||
import "package:nexus/controllers/top_level_spaces_controller.dart";
|
import "package:nexus/controllers/top_level_spaces_controller.dart";
|
||||||
import "package:nexus/controllers/space_edges_controller.dart";
|
import "package:nexus/controllers/space_edges_controller.dart";
|
||||||
|
|
@ -57,12 +58,28 @@ class SpacesController extends Notifier<IList<Space>> {
|
||||||
)
|
)
|
||||||
.map((e) => e.value);
|
.map((e) => e.value);
|
||||||
|
|
||||||
|
final accountData = ref.watch(AccountDataController.provider);
|
||||||
|
|
||||||
|
final directMessages = IMap(
|
||||||
|
accountData["m.direct"]?.content ?? {},
|
||||||
|
).values.expand((element) => element);
|
||||||
|
|
||||||
final homeRooms = otherRooms
|
final homeRooms = otherRooms
|
||||||
.where((room) => room.metadata?.dmUserId == null)
|
.where(
|
||||||
|
(room) =>
|
||||||
|
directMessages.any(
|
||||||
|
(directMessage) => directMessage == room.metadata?.id,
|
||||||
|
) ==
|
||||||
|
false,
|
||||||
|
)
|
||||||
.toIList();
|
.toIList();
|
||||||
|
|
||||||
final dmRooms = otherRooms
|
final dmRooms = otherRooms
|
||||||
.where((room) => room.metadata?.dmUserId != null)
|
.where(
|
||||||
|
(room) => directMessages.any(
|
||||||
|
(directMessage) => directMessage == room.metadata?.id,
|
||||||
|
),
|
||||||
|
)
|
||||||
.toIList();
|
.toIList();
|
||||||
|
|
||||||
final topLevelSpacesList = topLevelSpaceIds
|
final topLevelSpacesList = topLevelSpaceIds
|
||||||
|
|
|
||||||
16
lib/models/account_data.dart
Normal file
16
lib/models/account_data.dart
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,7 @@ abstract class Event with _$Event {
|
||||||
abstract class LocalContent with _$LocalContent {
|
abstract class LocalContent with _$LocalContent {
|
||||||
const factory LocalContent({
|
const factory LocalContent({
|
||||||
String? sanitizedHtml,
|
String? sanitizedHtml,
|
||||||
|
String? editSource,
|
||||||
bool? wasPlaintext,
|
bool? wasPlaintext,
|
||||||
bool? bigEmoji,
|
bool? bigEmoji,
|
||||||
bool? hasMath,
|
bool? hasMath,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||||
import "package:freezed_annotation/freezed_annotation.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/room.dart";
|
||||||
import "package:nexus/models/space_edge.dart";
|
import "package:nexus/models/space_edge.dart";
|
||||||
part "sync_data.freezed.dart";
|
part "sync_data.freezed.dart";
|
||||||
|
|
@ -9,7 +10,7 @@ part "sync_data.g.dart";
|
||||||
abstract class SyncData with _$SyncData {
|
abstract class SyncData with _$SyncData {
|
||||||
const factory SyncData({
|
const factory SyncData({
|
||||||
@Default(false) bool clearState,
|
@Default(false) bool clearState,
|
||||||
// required IMap<String, AccountData> accountData,
|
@Default(IMap.empty()) IMap<String, AccountData> accountData,
|
||||||
@Default(IMap.empty()) IMap<String, Room> rooms,
|
@Default(IMap.empty()) IMap<String, Room> rooms,
|
||||||
@Default(ISet.empty()) ISet<String> leftRooms,
|
@Default(ISet.empty()) ISet<String> leftRooms,
|
||||||
// required IList<InvitedRoom> invitedRooms,
|
// required IList<InvitedRoom> invitedRooms,
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,7 @@ class ChatBox extends HookConsumerWidget {
|
||||||
if (relationType == RelationType.edit &&
|
if (relationType == RelationType.edit &&
|
||||||
relatedMessage is TextMessage &&
|
relatedMessage is TextMessage &&
|
||||||
controller.value.text.isEmpty) {
|
controller.value.text.isEmpty) {
|
||||||
final text = (relatedMessage as TextMessage).text;
|
controller.value.text = relatedMessage?.metadata?["editSource"];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void send() {
|
void send() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue