Move PurgeDialog to Chat. Improve robustness of purge.

Also, set message retention to 60 seconds and make sure online user "forget"s room.
This commit is contained in:
N-Pex 2024-04-11 11:27:07 +02:00
parent 2d6f5d3df8
commit 12467f8a18
4 changed files with 32 additions and 24 deletions

View file

@ -3,10 +3,12 @@
<ChatHeaderPrivate class="chat-header flex-grow-0 flex-shrink-0" <ChatHeaderPrivate class="chat-header flex-grow-0 flex-shrink-0"
v-on:header-click="onHeaderClick" v-on:header-click="onHeaderClick"
v-on:view-room-details="viewRoomDetails" v-on:view-room-details="viewRoomDetails"
v-on:purge="showPurgeConfirmation = true"
v-if="!useFileModeNonAdmin && $matrix.isDirectRoom(room)" /> v-if="!useFileModeNonAdmin && $matrix.isDirectRoom(room)" />
<ChatHeader class="chat-header flex-grow-0 flex-shrink-0" <ChatHeader class="chat-header flex-grow-0 flex-shrink-0"
v-on:header-click="onHeaderClick" v-on:header-click="onHeaderClick"
v-on:view-room-details="viewRoomDetails" v-on:view-room-details="viewRoomDetails"
v-on:purge="showPurgeConfirmation = true"
v-else-if="!useFileModeNonAdmin" /> v-else-if="!useFileModeNonAdmin" />
<AudioLayout ref="chatContainer" class="auto-audio-player-root" v-if="useVoiceMode" :room="room" <AudioLayout ref="chatContainer" class="auto-audio-player-root" v-if="useVoiceMode" :room="room"
:events="events" :autoplay="!showRecorder" :events="events" :autoplay="!showRecorder"
@ -321,6 +323,9 @@
:room="room" :room="room"
@close="showProfileDialog = false" @close="showProfileDialog = false"
/> />
<!-- PURGE ROOM POPUP -->
<PurgeRoomDialog :show="showPurgeConfirmation" :room="room" @close="showPurgeConfirmation = false" />
</div> </div>
</template> </template>
@ -349,6 +354,7 @@ import AudioLayout from "./AudioLayout.vue";
import FileDropLayout from "./file_mode/FileDropLayout"; import FileDropLayout from "./file_mode/FileDropLayout";
import roomTypeMixin from "./roomTypeMixin"; import roomTypeMixin from "./roomTypeMixin";
import roomMembersMixin from "./roomMembersMixin"; import roomMembersMixin from "./roomMembersMixin";
import PurgeRoomDialog from "../components/PurgeRoomDialog";
const sizeOf = require("image-size"); const sizeOf = require("image-size");
const dataUriToBuffer = require("data-uri-to-buffer"); const dataUriToBuffer = require("data-uri-to-buffer");
@ -400,7 +406,8 @@ export default {
CreatePollDialog, CreatePollDialog,
AudioLayout, AudioLayout,
FileDropLayout, FileDropLayout,
UserProfileDialog UserProfileDialog,
PurgeRoomDialog,
}, },
data() { data() {
@ -483,7 +490,8 @@ export default {
* A timer to handle message retention/auto deletion * A timer to handle message retention/auto deletion
*/ */
retentionTimer: null, retentionTimer: null,
showProfileDialog: false showProfileDialog: false,
showPurgeConfirmation: false,
}; };
}, },

View file

@ -39,7 +39,7 @@
</v-col> </v-col>
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1"> <v-col cols="auto" class="text-end ma-0 pa-0 ms-1">
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red" <v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red"
@click.stop="showPurgeConfirmation = true"> @click.stop="$emit('purge')">
<v-icon light>$vuetify.icons.ic_moderator-delete</v-icon> <v-icon light>$vuetify.icons.ic_moderator-delete</v-icon>
</v-btn> </v-btn>
<v-btn id="btn-leave-room" class="mx-2 box-shadow-none" fab dark small color="red" @click.stop="leaveRoom" v-else> <v-btn id="btn-leave-room" class="mx-2 box-shadow-none" fab dark small color="red" @click.stop="leaveRoom" v-else>
@ -65,9 +65,6 @@
<MoreMenuPopup :show="showMoreMenu" :menuItems="moreMenuItems" @close="showMoreMenu = false" <MoreMenuPopup :show="showMoreMenu" :menuItems="moreMenuItems" @close="showMoreMenu = false"
v-on:leave="showLeaveConfirmation = true" /> v-on:leave="showLeaveConfirmation = true" />
<!-- PURGE ROOM POPUP -->
<PurgeRoomDialog :show="showPurgeConfirmation" :room="room" @close="showPurgeConfirmation = false" />
<RoomExport :room="room" v-if="downloadingChat" v-on:close="downloadingChat = false" /> <RoomExport :room="room" v-if="downloadingChat" v-on:close="downloadingChat = false" />
</v-container> </v-container>
@ -78,7 +75,6 @@ import LeaveRoomDialog from "../components/LeaveRoomDialog";
import ProfileInfoPopup from "../components/ProfileInfoPopup"; import ProfileInfoPopup from "../components/ProfileInfoPopup";
import MoreMenuPopup from "../components/MoreMenuPopup"; import MoreMenuPopup from "../components/MoreMenuPopup";
import profileInfoMixin from "../components/profileInfoMixin"; import profileInfoMixin from "../components/profileInfoMixin";
import PurgeRoomDialog from "../components/PurgeRoomDialog";
import RoomExport from "../components/RoomExport"; import RoomExport from "../components/RoomExport";
import roomInfoMixin from "./roomInfoMixin"; import roomInfoMixin from "./roomInfoMixin";
@ -90,7 +86,6 @@ export default {
LeaveRoomDialog, LeaveRoomDialog,
ProfileInfoPopup, ProfileInfoPopup,
MoreMenuPopup, MoreMenuPopup,
PurgeRoomDialog,
RoomExport RoomExport
}, },
data() { data() {
@ -98,7 +93,6 @@ export default {
memberCount: null, memberCount: null,
showLeaveConfirmation: false, showLeaveConfirmation: false,
showProfileInfo: false, showProfileInfo: false,
showPurgeConfirmation: false,
showMoreMenu: false, showMoreMenu: false,
downloadingChat: false, downloadingChat: false,
showMissedItemsInfo: false, showMissedItemsInfo: false,

View file

@ -44,7 +44,7 @@
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1"> <v-col cols="auto" class="text-end ma-0 pa-0 ms-1">
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red" <v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red"
@click.stop="showPurgeConfirmation = true"> @click.stop="$emit('purge')">
<v-icon light>$vuetify.icons.ic_moderator-delete</v-icon> <v-icon light>$vuetify.icons.ic_moderator-delete</v-icon>
</v-btn> </v-btn>
<template v-else> <template v-else>
@ -75,9 +75,6 @@
<MoreMenuPopup :show="showMoreMenu" :menuItems="moreMenuItems" @close="showMoreMenu = false" <MoreMenuPopup :show="showMoreMenu" :menuItems="moreMenuItems" @close="showMoreMenu = false"
v-on:leave="showLeaveConfirmation = true" /> v-on:leave="showLeaveConfirmation = true" />
<!-- PURGE ROOM POPUP -->
<PurgeRoomDialog :show="showPurgeConfirmation" :room="room" @close="showPurgeConfirmation = false" />
<RoomExport :room="room" v-if="downloadingChat" v-on:close="downloadingChat = false" /> <RoomExport :room="room" v-if="downloadingChat" v-on:close="downloadingChat = false" />
</v-container> </v-container>
@ -87,7 +84,6 @@
import LeaveRoomDialog from "../components/LeaveRoomDialog"; import LeaveRoomDialog from "../components/LeaveRoomDialog";
import ProfileInfoPopup from "../components/ProfileInfoPopup"; import ProfileInfoPopup from "../components/ProfileInfoPopup";
import MoreMenuPopup from "../components/MoreMenuPopup"; import MoreMenuPopup from "../components/MoreMenuPopup";
import PurgeRoomDialog from "../components/PurgeRoomDialog";
import RoomExport from "../components/RoomExport"; import RoomExport from "../components/RoomExport";
import ChatHeader from "./ChatHeader.vue"; import ChatHeader from "./ChatHeader.vue";
@ -99,7 +95,6 @@ export default {
LeaveRoomDialog, LeaveRoomDialog,
ProfileInfoPopup, ProfileInfoPopup,
MoreMenuPopup, MoreMenuPopup,
PurgeRoomDialog,
RoomExport RoomExport
}, },
}; };

View file

@ -1,7 +1,7 @@
import olm from "@matrix-org/olm/olm"; import olm from "@matrix-org/olm/olm";
global.Olm = olm; global.Olm = olm;
import * as sdk from "matrix-js-sdk"; import * as sdk from "matrix-js-sdk";
import { TimelineWindow, EventTimeline } from "matrix-js-sdk"; import { TimelineWindow, EventTimeline, EventStatus } from "matrix-js-sdk";
import util, { STATE_EVENT_ROOM_DELETED } from "../plugins/utils"; import util, { STATE_EVENT_ROOM_DELETED } from "../plugins/utils";
import User from "../models/user"; import User from "../models/user";
@ -403,7 +403,7 @@ export default {
if (room.currentState.maySendStateEvent("m.room.power_levels", event.getSender())) { if (room.currentState.maySendStateEvent("m.room.power_levels", event.getSender())) {
if (event.getSender() !== this.currentUserId) { if (event.getSender() !== this.currentUserId) {
this.leaveRoomAndNavigate(room.roomId).then(() => { this.leaveRoomAndNavigate(room.roomId).then(() => {
this.matrixClient.store.removeRoom(room.roomId); this.matrixClient.forget(room.roomId, true);
}); });
} }
} }
@ -716,6 +716,8 @@ export default {
purgeRoom(roomId, statusCallback) { purgeRoom(roomId, statusCallback) {
this.currentRoomBeingPurged = true; this.currentRoomBeingPurged = true;
//console.log("Purge room");
const sleep = (ms) => { const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
}; };
@ -744,30 +746,39 @@ export default {
return; return;
} }
// Remove any possible pending events
room.getLiveTimeline().getEvents().filter((e) => [EventStatus.ENCRYPTING, sdk.EventStatus.QUEUED].includes(e.status)).forEach((e) => {
//console.log("Cancel pending event!");
this.matrixClient.cancelPendingEvent(e);
});
const timelineWindow = new TimelineWindow(this.matrixClient, room.getUnfilteredTimelineSet(), {}); const timelineWindow = new TimelineWindow(this.matrixClient, room.getUnfilteredTimelineSet(), {});
const self = this; const self = this;
//console.log("Purge: set invite only"); //console.log("Purge: set invite only");
statusCallback(this.$t("room.purge_set_room_state")); statusCallback(this.$t("room.purge_set_room_state"));
this.matrixClient withRetry(() => this.matrixClient.sendStateEvent(roomId, "m.room.join_rules", { join_rule: "invite" }, ""))
.sendStateEvent(roomId, "m.room.join_rules", { join_rule: "invite" }, "")
.then(() => { .then(() => {
//console.log("Purge: forbid guest access"); //console.log("Purge: forbid guest access");
return this.matrixClient.sendStateEvent( return withRetry(() => this.matrixClient.sendStateEvent(
roomId, roomId,
"m.room.guest_access", "m.room.guest_access",
{ guest_access: "forbidden" }, { guest_access: "forbidden" },
"" ""
); ));
}) })
.then(() => { .then(() => {
//console.log("Purge: set history visibility to 'joined'"); //console.log("Purge: set history visibility to 'joined'");
return this.matrixClient.sendStateEvent(roomId, "m.room.history_visibility", { return withRetry(() => this.matrixClient.sendStateEvent(roomId, "m.room.history_visibility", {
history_visibility: "joined", history_visibility: "joined",
}); }));
}) })
.then(() => { .then(() => {
return this.matrixClient.sendStateEvent(roomId, STATE_EVENT_ROOM_DELETED, { status: "deleted" }); return withRetry(() => this.matrixClient.sendStateEvent(roomId, STATE_EVENT_ROOM_DELETED, { status: "deleted" }));
})
.then(() => {
// Set message retention 1 minute (may be limited by server)
return withRetry(() => this.matrixClient.sendStateEvent(roomId, "m.room.retention", { max_lifetime: 60000 }));
}) })
.then(() => { .then(() => {
//console.log("Purge: create timeline"); //console.log("Purge: create timeline");