Timeout on room deletion

And custom deletion notice state event.

Issue #118.
This commit is contained in:
N-Pex 2021-07-06 09:33:19 +02:00
parent d39357401b
commit abd3892349
7 changed files with 164 additions and 17 deletions

View file

@ -445,6 +445,19 @@ $admin-fg: white;
user-select: text;
}
.notice {
font-family: "Inter", sans-serif;
font-weight: 300;
font-size: 15 * $chat-text-size;
background-color: #090909;
color: white;
text-align: start;
margin: 20px;
user-select: text;
padding: 16px;
border-radius: 20px;
}
.audio-player {
width: 100%;
position: absolute;

View file

@ -0,0 +1,10 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.08333 5.77777H0.361111C0.161778 5.77777 0 5.93955 0 6.13888C0 6.33822 0.161778 6.49999 0.361111 6.49999H1.08333C1.28267 6.49999 1.44444 6.33822 1.44444 6.13888C1.44444 5.93955 1.28267 5.77777 1.08333 5.77777Z" fill="black"/>
<path d="M1.08333 5.77777H0.361111C0.161778 5.77777 0 5.93955 0 6.13888C0 6.33822 0.161778 6.49999 0.361111 6.49999H1.08333C1.28267 6.49999 1.44444 6.33822 1.44444 6.13888C1.44444 5.93955 1.28267 5.77777 1.08333 5.77777Z" fill="black"/>
<path d="M1.08333 8.66669H0.361111C0.161778 8.66669 0 8.82846 0 9.0278C0 9.22713 0.161778 9.38891 0.361111 9.38891H1.08333C1.28267 9.38891 1.44444 9.22713 1.44444 9.0278C1.44444 8.82846 1.28267 8.66669 1.08333 8.66669Z" fill="black"/>
<path d="M1.08333 8.66669H0.361111C0.161778 8.66669 0 8.82846 0 9.0278C0 9.22713 0.161778 9.38891 0.361111 9.38891H1.08333C1.28267 9.38891 1.44444 9.22713 1.44444 9.0278C1.44444 8.82846 1.28267 8.66669 1.08333 8.66669Z" fill="black"/>
<path d="M11.6553 4.02206L12.1724 3.50494C12.3132 3.36411 12.3132 3.13517 12.1724 2.99433C12.0316 2.8535 11.8026 2.8535 11.6618 2.99433L11.1447 3.51144C10.2766 2.75239 9.1658 2.26633 7.94453 2.18472V0.722222H9.02786C9.22719 0.722222 9.38897 0.560444 9.38897 0.361111C9.38897 0.161778 9.22719 0 9.02786 0H6.13897C5.93964 0 5.77786 0.161778 5.77786 0.361111C5.77786 0.560444 5.93964 0.722222 6.13897 0.722222H7.2223V2.18472C4.40419 2.37178 2.16675 4.71828 2.16675 7.58333C2.16675 10.5704 4.5963 13 7.58341 13C10.5705 13 13.0001 10.5704 13.0001 7.58333C13.0001 6.21978 12.4895 4.97611 11.6553 4.02206ZM7.58341 12.2778C4.99497 12.2778 2.88897 10.1718 2.88897 7.58333C2.88897 4.99489 4.99497 2.88889 7.58341 2.88889C10.1719 2.88889 12.2779 4.99489 12.2779 7.58333C12.2779 10.1718 10.1719 12.2778 7.58341 12.2778Z" fill="black"/>
<path d="M11.6553 4.02206L12.1724 3.50494C12.3132 3.36411 12.3132 3.13517 12.1724 2.99433C12.0316 2.8535 11.8026 2.8535 11.6618 2.99433L11.1447 3.51144C10.2766 2.75239 9.1658 2.26633 7.94453 2.18472V0.722222H9.02786C9.22719 0.722222 9.38897 0.560444 9.38897 0.361111C9.38897 0.161778 9.22719 0 9.02786 0H6.13897C5.93964 0 5.77786 0.161778 5.77786 0.361111C5.77786 0.560444 5.93964 0.722222 6.13897 0.722222H7.2223V2.18472C4.40419 2.37178 2.16675 4.71828 2.16675 7.58333C2.16675 10.5704 4.5963 13 7.58341 13C10.5705 13 13.0001 10.5704 13.0001 7.58333C13.0001 6.21978 12.4895 4.97611 11.6553 4.02206ZM7.58341 12.2778C4.99497 12.2778 2.88897 10.1718 2.88897 7.58333C2.88897 4.99489 4.99497 2.88889 7.58341 2.88889C10.1719 2.88889 12.2779 4.99489 12.2779 7.58333C12.2779 10.1718 10.1719 12.2778 7.58341 12.2778Z" fill="black"/>
<path d="M7.58328 4.33331C7.38395 4.33331 7.22217 4.49509 7.22217 4.69442V7.58331C7.22217 7.78265 7.38395 7.94442 7.58328 7.94442C7.78261 7.94442 7.94439 7.78265 7.94439 7.58331V4.69442C7.94439 4.49509 7.78261 4.33331 7.58328 4.33331Z" fill="black"/>
<path d="M7.58328 4.33331C7.38395 4.33331 7.22217 4.49509 7.22217 4.69442V7.58331C7.22217 7.78265 7.38395 7.94442 7.58328 7.94442C7.78261 7.94442 7.94439 7.78265 7.94439 7.58331V4.69442C7.94439 4.49509 7.78261 4.33331 7.58328 4.33331Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -12,7 +12,8 @@
"back": "BACK",
"login": "Login",
"logout": "Logout",
"new_room": "New Room"
"new_room": "New Room",
"undo": "Undo"
},
"message": {
"you": "You",
@ -157,7 +158,12 @@
"purge_room": {
"title": "Delete room?",
"info": "All members and messages will be removed. This action cannot be undone.",
"button": "Delete"
"button": "Delete",
"n_seconds": "{seconds} seconds",
"self_destruct": "Room will self destruct in seconds.",
"deleting": "Deleting room:",
"notified": "We've notified members.",
"room_deletion_notice": "Time to say goodbye! This room has been deleted by {user}. It will self destruct in seconds."
},
"goodbye": {
"room_deleted": "Room deleted.",

View file

@ -459,6 +459,7 @@ import RoomJoinRules from "./messages/RoomJoinRules.vue";
import RoomPowerLevelsChanged from "./messages/RoomPowerLevelsChanged.vue";
import RoomGuestAccessChanged from "./messages/RoomGuestAccessChanged.vue";
import RoomEncrypted from "./messages/RoomEncrypted.vue";
import RoomDeletionNotice from "./messages/RoomDeletionNotice.vue";
import DebugEvent from "./messages/DebugEvent.vue";
import util from "../plugins/utils";
import MessageOperations from "./messages/MessageOperations.vue";
@ -539,6 +540,7 @@ export default {
RoomPowerLevelsChanged,
RoomGuestAccessChanged,
RoomEncrypted,
RoomDeletionNotice,
DebugEvent,
MessageOperations,
MessageOperationsPicker,
@ -1064,6 +1066,23 @@ export default {
case "m.room.encryption":
return RoomEncrypted;
case "im.keanu.room_deletion_notice": {
// Custom event for notice 30 seconds before a room is deleted/purged.
const deletionNotices = this.room.currentState.getStateEvents(
"im.keanu.room_deletion_notice"
);
if (
deletionNotices &&
deletionNotices.length > 0 &&
deletionNotices[deletionNotices.length - 1] == event
) {
// This is the latest/last one. Look at the status flag. Show nothing if it is "cancel".
if (event.getContent().status != "cancel") {
return RoomDeletionNotice;
}
}
}
}
return this.debugging ? DebugEvent : null;
},

View file

@ -1,6 +1,6 @@
<template>
<v-dialog v-model="showDialog" v-show="room" class="ma-0 pa-0" width="80%">
<div class="dialog-content text-center">
<div v-if="timeout == -1" class="dialog-content text-center">
<template>
<v-img contain height="28" src="@/assets/icons/trash_black.svg" />
<h2 class="dialog-title">{{ $t("purge_room.title") }}</h2>
@ -38,6 +38,48 @@
</v-row>
</v-container>
</div>
<!-- Timer -->
<div v-if="timeout >= 0 && !isPurging" class="dialog-content text-center">
<template>
<v-img
contain
width="20"
class="d-inline-block me-2"
src="@/assets/icons/timer.svg"
/>{{ $t("purge_room.n_seconds", { seconds: timeout }) }}
<h2 class="dialog-title">{{ $t("purge_room.self_destruct") }}</h2>
<div class="dialog-text">
{{ $t("purge_room.notified") }}
</div>
<div class="dialog-text">
{{ status }}
</div>
</template>
<v-container fluid>
<v-row cols="12">
<v-col cols="12">
<v-btn
depressed
text
block
class="text-button"
:disabled="isPurging"
@click="undo"
>{{ $t("menu.undo") }}</v-btn
>
</v-col>
</v-row>
</v-container>
</div>
<!-- Purging -->
<div v-if="isPurging" class="dialog-content text-center">
<h2 class="dialog-title">{{ $t("purge_room.deleting") }}</h2>
<div class="dialog-text">
{{ status }}
</div>
</div>
</v-dialog>
</template>
<script>
@ -56,6 +98,8 @@ export default {
},
data() {
return {
timeout: -1,
timeoutTimer: null,
showDialog: false,
isPurging: false,
status: null,
@ -75,7 +119,41 @@ export default {
},
methods: {
undo() {
if (this.timeoutTimer) {
clearInterval(this.timeoutTimer);
this.timeoutTimer = null;
}
this.timeout = -1;
// Cancel the state event for deletion
this.$matrix.matrixClient.sendStateEvent(
this.room.roomId,
"im.keanu.room_deletion_notice",
{ status: "cancel" }
);
this.showDialog = false;
},
onPurgeRoom() {
// Send custom state event!
this.$matrix.matrixClient.sendStateEvent(
this.room.roomId,
"im.keanu.room_deletion_notice",
{ status: "delete" }
);
this.timeout = 30;
this.timeoutTimer = setInterval(() => {
this.timeout = this.timeout - 1;
if (this.timeout == 0) {
clearInterval(this.timeoutTimer);
this.timeoutTimer = null;
this.onDoPurgeRoom();
}
}, 1000);
},
onDoPurgeRoom() {
this.isPurging = true;
this.$matrix
.purgeRoom(this.room.roomId, this.onPurgeStatus)

View file

@ -0,0 +1,23 @@
<template>
<!-- ROOM WILL BE DELETED -->
<div class="notice">
👋&nbsp;
{{
$t("purge_room.room_deletion_notice", {
user: stateEventDisplayName(event),
})
}}
</div>
</template>
<script>
import messageMixin from "./messageMixin";
export default {
mixins: [messageMixin],
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

View file

@ -303,7 +303,6 @@ export default {
client.on("Room", this.onRoom);
client.on("Session.logged_out", this.onSessionLoggedOut);
client.on("Room.myMembership", this.onRoomMyMembership);
client.on("RoomMember.membership", this.onRoomMemberMembership);
}
},
@ -313,7 +312,6 @@ export default {
client.off("Room", this.onRoom);
client.off("Session.logged_out", this.onSessionLoggedOut);
client.off("Room.myMembership", this.onRoomMyMembership);
client.off("RoomMember.membership", this.onRoomMemberMembership);
}
},
@ -334,6 +332,17 @@ export default {
}
}
break;
case "m.room.member": {
if (this.currentRoom && event.getRoomId() == this.currentRoom.roomId) { // Don't use this.currentRoomId, may be an alias. We need the real id!
if (event.getContent().membership == "leave" && (event.getPrevContent() || {}).membership == "join" && event.getStateKey() == this.currentUserId && event.getSender() != this.currentUserId) {
// We were kicked
const wasPurged = (event.getContent().reason == "Room Deleted");
this.$navigation.push({ name: "Goodbye", params: { roomWasPurged: wasPurged } }, -1);
}
}
}
break;
}
this.updateNotificationCount();
},
@ -353,17 +362,6 @@ export default {
}
},
onRoomMemberMembership(event, member, ignoredoldMembership) {
if (member.userId == this.currentUserId && member.isKicked()) {
if (this.currentRoomId == event.getRoomId()) {
// We were kicked! Look at "reason", maybe a purge?
const reason = event.getContent().reason || "";
const roomWasPurged = (reason == "Room Deleted");
this.$navigation.push({ name: "Goodbye", params: { roomWasPurged: roomWasPurged } }, -1);
}
}
},
onSessionLoggedOut() {
console.log("Logged out!");
if (this.matrixClient) {
@ -582,7 +580,7 @@ export default {
var kickPromises = [];
members.forEach(member => {
if (member.userId != self.currentUserId) {
kickPromises.push(this.matrixClient.kick(roomId, member.userId));
kickPromises.push(this.matrixClient.kick(roomId, member.userId, "Room Deleted"));
}
});
return Promise.all(kickPromises);