Timeout on room deletion
And custom deletion notice state event. Issue #118.
This commit is contained in:
parent
d39357401b
commit
abd3892349
7 changed files with 164 additions and 17 deletions
|
|
@ -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;
|
||||
|
|
|
|||
10
src/assets/icons/timer.svg
Normal file
10
src/assets/icons/timer.svg
Normal 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 |
|
|
@ -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.",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
23
src/components/messages/RoomDeletionNotice.vue
Normal file
23
src/components/messages/RoomDeletionNotice.vue
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<!-- ROOM WILL BE DELETED -->
|
||||
<div class="notice">
|
||||
👋
|
||||
{{
|
||||
$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>
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue