diff --git a/assets/cheatsheet.md b/assets/cheatsheet.md index 6cdb0dd37..d7dc0544b 100644 --- a/assets/cheatsheet.md +++ b/assets/cheatsheet.md @@ -26,4 +26,40 @@ * */ ThunkAction createUser({enableErrors = false}) {} +``` + +```dart + +// needed to test the recursive messaging 'catch-up' +if (true) { + printError('[fromMessageEvents] *** ${this.name} *** '); + print('[limited] now ${limited}, before ${this.limited}'); + print('[lastHash] now ${lastHash}, before ${this.lastHash}'); + print('[prevHash] now ${prevHash}'); +} + +``` + +```dart + // original initStore function without much regar + // for action types. Ideally, it would have none. + Future initStore() async { + // Configure redux persist instance + final persistor = Persistor( + storage: MemoryStorage(), + serializer: CacheSerializer(), + throttleDuration: Duration(milliseconds: 4500), + shouldSave: (Store store, dynamic action) { + switch (action.runtimeType) { + case SetSyncing: + case SetSynced: + // debugPrint('[Redux Persist] cache skip'); + return false; + default: + // debugPrint('[Redux Persist] caching'); + return true; + } + }, + ); + ``` \ No newline at end of file diff --git a/lib/store/index.dart b/lib/store/index.dart index 46594eed8..384380812 100644 --- a/lib/store/index.dart +++ b/lib/store/index.dart @@ -97,25 +97,6 @@ AppState appReducer(AppState state, action) => AppState( * this is why the "storage: MemoryStore()" property is set and * the Hive Serializer has been impliemented */ -// Future initStore() async { -// // Configure redux persist instance -// final persistor = Persistor( -// storage: MemoryStorage(), -// serializer: CacheSerializer(), -// throttleDuration: Duration(milliseconds: 4500), -// shouldSave: (Store store, dynamic action) { -// switch (action.runtimeType) { -// case SetSyncing: -// case SetSynced: -// // debugPrint('[Redux Persist] cache skip'); -// return false; -// default: -// // debugPrint('[Redux Persist] caching'); -// return true; -// } -// }, -// ); - Future initStore() async { // Configure redux persist instance final persistor = Persistor( diff --git a/lib/store/rooms/actions.dart b/lib/store/rooms/actions.dart index 7b2ce3b87..90af3ef61 100644 --- a/lib/store/rooms/actions.dart +++ b/lib/store/rooms/actions.dart @@ -109,9 +109,7 @@ class AddArchive { * Helper action that will determine how to update a room * from data formatted like a sync request */ -ThunkAction syncRooms( - Map roomData, -) { +ThunkAction syncRooms(Map roomData) { return (Store store) async { // init new store containers final rooms = store.state.roomStore.rooms ?? Map(); @@ -171,20 +169,17 @@ ThunkAction syncRooms( // and is not already at the end of the last known batch // the end would be room.prevHash == room.lastHash - final roomUpdated = store.state.roomStore.rooms[room.id]; - // fetch previous messages since last /sync (a gap) // determined by the fromSync function of room + final roomUpdated = store.state.roomStore.rooms[room.id]; if (roomUpdated != null && room.limited) { - debugPrint('[syncRooms] fetchMessageEvents called due to limited'); - store.dispatch( - fetchMessageEvents( - room: room, - from: room.lastHash, - ), - ); + store.dispatch(fetchMessageEvents( + room: room, + from: room.prevHash, + )); } + // update room store.dispatch(SetRoom(room: room)); }); }; diff --git a/lib/store/rooms/events/actions.dart b/lib/store/rooms/events/actions.dart index 8a0041631..31f1cbf4b 100644 --- a/lib/store/rooms/events/actions.dart +++ b/lib/store/rooms/events/actions.dart @@ -11,13 +11,10 @@ import 'package:redux/redux.dart'; import 'package:redux_thunk/redux_thunk.dart'; // Project imports: -import 'package:syphon/global/algos.dart'; -import 'package:syphon/global/libs/matrix/encryption.dart'; import 'package:syphon/global/libs/matrix/index.dart'; import 'package:syphon/store/alerts/actions.dart'; import 'package:syphon/store/crypto/actions.dart'; import 'package:syphon/store/crypto/events/actions.dart'; -import 'package:syphon/store/crypto/keys/model.dart'; import 'package:syphon/store/index.dart'; import 'package:syphon/store/rooms/actions.dart'; import 'package:syphon/store/rooms/events/model.dart'; @@ -61,9 +58,6 @@ ThunkAction fetchMessageEvents({ try { store.dispatch(UpdateRoom(id: room.id, syncing: true)); - // debugPrint('[to] $to'); - // debugPrint('[from] $from'); - final messagesJson = await compute(MatrixApi.fetchMessageEventsMapped, { "protocol": protocol, "homeserver": store.state.authStore.user.homeserver, @@ -83,12 +77,6 @@ ThunkAction fetchMessageEvents({ // The messages themselves final List messages = messagesJson['chunk'] ?? []; - // TODO: remove after 0.1.3 is merged - // messages.forEach((element) { - // printJson(element); - // }); - debugPrint('[OLDEST] ${oldest}'); - // reuse the logic for syncing await store.dispatch( syncRooms({ diff --git a/lib/store/rooms/room/model.dart b/lib/store/rooms/room/model.dart index bf710b4e1..63c151b0d 100644 --- a/lib/store/rooms/room/model.dart +++ b/lib/store/rooms/room/model.dart @@ -76,8 +76,7 @@ class Room { @HiveField(17) final Message draft; - // TODO: removed until state timeline work can be done - // @HiveField(19) + // TODO: removed until state timeline work can be done // final List state; @HiveField(20) @@ -326,9 +325,9 @@ class Room { accountEvents, ) .fromStateEvents( - events: stateEvents, invite: invite, limited: limited, + events: stateEvents, currentUser: currentUser, ) .fromMessageEvents( @@ -389,10 +388,8 @@ class Room { bool direct = this.direct ?? false; int lastUpdate = this.lastUpdate; int namePriority = this.namePriority != 4 ? this.namePriority : 4; - Map users = this.users ?? Map(); - // room state event filter try { events.forEach((event) { final timestamp = event.timestamp ?? 0; @@ -541,19 +538,27 @@ class Room { lastUpdate = messagesNew[0].timestamp; } - // Check to see if the new messages contain those existing in cache - if (messagesNew.isNotEmpty && - messagesExisting.isNotEmpty && - this.limited) { - final messageLatest = messagesExisting.firstWhere( - (msg) => msg.id == messagesNew[0].id, - orElse: () => null, - ); + // limited indicates need to fetch additional data for room timelines + if (this.limited) { + // Check to see if the new messages contain those existing in cache + if (messagesNew.isNotEmpty && messagesExisting.isNotEmpty) { + final messageLatest = messagesExisting.firstWhere( + (msg) => msg.id == messagesNew[0].id, + orElse: () => null, + ); + // Set limited to false if they now exist + limited = messageLatest != null; + } - // Set limited (used to recursively sync) to false if - // - new messages contains old ones - // - it's the first full /sync (lastHash == null) - limited = messageLatest != null || this.lastHash == null ? false : null; + // Set limited to false false if + // - the oldest hash (lastHash) is non-existant + // - the previous hash (most recent) is non-existant + // - the oldest hash equals the previously fetched hash + if (this.lastHash == null || + this.prevHash == null || + this.lastHash == this.prevHash) { + limited = false; + } } // Combine current and existing messages on unique ids @@ -572,14 +577,7 @@ class Room { // Filter to find startTime and endTime final messagesAll = List.from(messagesMap.values); - // TODO: remove after 0.1.5 :( - message catchup works - if (true) { - // print('[fromMessageEvents] *** ${this.name} *** '); - // print('[limited] now ${limited}, before ${this.limited}'); - // print('[lastHash] now ${lastHash}, before ${this.lastHash}'); - // print('[prevHash] now ${prevHash}'); - } - + // Save values to room return this.copyWith( outbox: outbox, messages: messagesAll, diff --git a/lib/views/home/chat/index.dart b/lib/views/home/chat/index.dart index 484dbb413..b3e7b9b2f 100644 --- a/lib/views/home/chat/index.dart +++ b/lib/views/home/chat/index.dart @@ -810,6 +810,7 @@ class _Props extends Equatable { onLoadMoreMessages: () { final room = store.state.roomStore.rooms[roomId] ?? Room(); + // fetch messages beyond the oldest known message - lastHash store.dispatch(fetchMessageEvents( room: room, from: room.lastHash, diff --git a/pubspec.yaml b/pubspec.yaml index 5fb754df6..95799be15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ description: a privacy focused matrix client # $ emulator -list-avds # $ emulator -avd Pixel_3a_API_29 # $ adb shell && run-as org.tether.tether # cache inspection +# $ adb logcat ActivityManager:I flutter:I *:S # desktop support options # $ flutter config --enable-macos-desktop