diff --git a/src/domain/session/room/RoomViewModel.js b/src/domain/session/room/RoomViewModel.js index 5616505c..1d2f3725 100644 --- a/src/domain/session/room/RoomViewModel.js +++ b/src/domain/session/room/RoomViewModel.js @@ -139,6 +139,14 @@ export class RoomViewModel extends ViewModel { leaveRoom() { this._room.leave(); } + + get canForget() { + return this._room.isArchived; + } + + forgetRoom() { + this._room.forget(); + } async _sendMessage(message) { if (!this._room.isArchived && message) { @@ -270,7 +278,6 @@ export class RoomViewModel extends ViewModel { } } - get composerViewModel() { return this._composerVM; } diff --git a/src/matrix/Session.js b/src/matrix/Session.js index 3cf1df65..38771c87 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -85,6 +85,7 @@ export class Session { }); } this._createRoomEncryption = this._createRoomEncryption.bind(this); + this._forgetArchivedRoom = this._forgetArchivedRoom.bind(this); this.needsSessionBackup = new ObservableValue(false); } @@ -407,6 +408,7 @@ export class Session { storage: this._storage, emitCollectionChange: () => {}, releaseCallback: () => this._activeArchivedRooms.delete(roomId), + forgetCallback: this._forgetArchivedRoom, hsApi: this._hsApi, mediaRepository: this._mediaRepository, user: this._user, @@ -555,6 +557,13 @@ export class Session { } } + _forgetArchivedRoom(roomId) { + const statusObservable = this._observedRoomStatus.get(roomId); + if (statusObservable) { + statusObservable.set(statusObservable.get().withoutArchived()); + } + } + /** @internal */ get syncToken() { return this._syncInfo?.token; diff --git a/src/matrix/net/HomeServerApi.js b/src/matrix/net/HomeServerApi.js index 77e02d76..a3fe1bc9 100644 --- a/src/matrix/net/HomeServerApi.js +++ b/src/matrix/net/HomeServerApi.js @@ -193,6 +193,10 @@ export class HomeServerApi { leave(roomId, options = null) { return this._post(`/rooms/${encodeURIComponent(roomId)}/leave`, null, null, options); } + + forget(roomId, options = null) { + return this._post(`/rooms/${encodeURIComponent(roomId)}/forget`, null, null, options); + } } import {Request as MockRequest} from "../../mocks/Request.js"; diff --git a/src/matrix/room/ArchivedRoom.js b/src/matrix/room/ArchivedRoom.js index 553f5a60..a87bd774 100644 --- a/src/matrix/room/ArchivedRoom.js +++ b/src/matrix/room/ArchivedRoom.js @@ -24,6 +24,7 @@ export class ArchivedRoom extends BaseRoom { // archived rooms are reference counted, // as they are not kept in memory when not needed this._releaseCallback = options.releaseCallback; + this._forgetCallback = options.forgetCallback; this._retentionCount = 1; /** Some details from our own member event when being kicked or banned. @@ -126,8 +127,40 @@ export class ArchivedRoom extends BaseRoom { return true; } - forget() { + forget(log = null) { + return this._platform.logger.wrapOrRun(log, "forget room", async log => { + log.set("id", this.id); + await this._hsApi.forget(this.id, {log}).response(); + const storeNames = this._storage.storeNames; + const txn = await this._storage.readWriteTxn([ + storeNames.roomState, + storeNames.archivedRoomSummary, + storeNames.roomMembers, + storeNames.timelineEvents, + storeNames.timelineFragments, + storeNames.pendingEvents, + storeNames.inboundGroupSessions, + storeNames.groupSessionDecryptions, + storeNames.operations, + ]); + txn.roomState.removeAllForRoom(this.id); + txn.archivedRoomSummary.remove(this.id); + txn.roomMembers.removeAllForRoom(this.id); + txn.timelineEvents.removeAllForRoom(this.id); + txn.timelineFragments.removeAllForRoom(this.id); + txn.pendingEvents.removeAllForRoom(this.id); + txn.inboundGroupSessions.removeAllForRoom(this.id); + txn.groupSessionDecryptions.removeAllForRoom(this.id); + await txn.operations.removeAllForScope(this.id); + + await txn.complete(); + + this._retentionCount = 0; + this._releaseCallback(); + + this._forgetCallback(this.id); + }); } } diff --git a/src/matrix/room/RoomStatus.js b/src/matrix/room/RoomStatus.js index b03b3177..884103e2 100644 --- a/src/matrix/room/RoomStatus.js +++ b/src/matrix/room/RoomStatus.js @@ -42,6 +42,16 @@ export class RoomStatus { return RoomStatus.none; } } + + withoutArchived() { + if (!this.archived) { + return this; + } else if (this.invited) { + return RoomStatus.invited; + } else { + return RoomStatus.none; + } + } } RoomStatus.joined = new RoomStatus(true, false, false); diff --git a/src/platform/web/ui/session/room/RoomView.js b/src/platform/web/ui/session/room/RoomView.js index 0fdf4bb4..e2ef0de7 100644 --- a/src/platform/web/ui/session/room/RoomView.js +++ b/src/platform/web/ui/session/room/RoomView.js @@ -70,6 +70,9 @@ export class RoomView extends TemplateView { if (vm.canLeave) { options.push(Menu.option(vm.i18n`Leave room`, () => vm.leaveRoom())); } + if (vm.canForget) { + options.push(Menu.option(vm.i18n`Forget room`, () => vm.forgetRoom())); + } if (!options.length) { return; }