Client side or purge room

Redirect to "goodbye" view. Issue #118.
This commit is contained in:
N-Pex 2021-07-05 18:16:21 +02:00
parent e324355b63
commit d39357401b
8 changed files with 193 additions and 60 deletions

View file

@ -0,0 +1,5 @@
<svg width="28" height="33" viewBox="0 0 28 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.4989 0C9.22596 0 8.16477 1.0612 8.16477 2.33409V4.66819C5.83219 4.66819 3.49962 4.66819 1.16705 4.66819C0.52251 4.66819 0 5.1907 0 5.83524C0 6.47977 0.52251 7.00228 1.16705 7.00228H2.32953V29.1762C2.32953 31.0956 3.91123 32.6773 5.83067 32.6773H22.1693C24.0888 32.6773 25.6705 31.0956 25.6705 29.1762V7.00228H26.833C27.4775 7.00228 28 6.47977 28 5.83524C28 5.1907 27.4775 4.66819 26.833 4.66819C24.5004 4.66819 22.1678 4.66819 19.8352 4.66819V2.33409C19.8352 1.0612 18.774 0 17.5011 0H10.4989ZM10.4989 2.33409H17.5011V4.66819H10.4989V2.33409ZM4.66362 7.00228C10.8879 7.00228 17.1121 7.00228 23.3364 7.00228V29.1762C23.3364 29.8429 22.8361 30.3432 22.1693 30.3432H5.83067C5.16394 30.3432 4.66362 29.8429 4.66362 29.1762V7.00228Z" fill="white"/>
<path d="M10.4991 12.8374C10.1896 12.8374 9.89272 12.9604 9.67385 13.1792C9.45499 13.3981 9.33203 13.6949 9.33203 14.0044V23.3408C9.33203 23.6503 9.45499 23.9472 9.67385 24.1661C9.89272 24.3849 10.1896 24.5079 10.4991 24.5079C10.8086 24.5079 11.1054 24.3849 11.3243 24.1661C11.5432 23.9472 11.6661 23.6503 11.6661 23.3408V14.0044C11.6661 13.6949 11.5432 13.3981 11.3243 13.1792C11.1054 12.9604 10.8086 12.8374 10.4991 12.8374Z" fill="white"/>
<path d="M17.5015 12.8374C17.192 12.8374 16.8952 12.9604 16.6763 13.1792C16.4574 13.3981 16.3345 13.6949 16.3345 14.0044V23.3408C16.3345 23.6503 16.4574 23.9472 16.6763 24.1661C16.8952 24.3849 17.192 24.5079 17.5015 24.5079C17.811 24.5079 18.1079 24.3849 18.3267 24.1661C18.5456 23.9472 18.6686 23.6503 18.6686 23.3408V14.0044C18.6686 13.6949 18.5456 13.3981 18.3267 13.1792C18.1079 12.9604 17.811 12.8374 17.5015 12.8374Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,5 @@
<svg width="28" height="33" viewBox="0 0 28 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.4989 0C9.22596 0 8.16477 1.0612 8.16477 2.33409V4.66819C5.83219 4.66819 3.49962 4.66819 1.16705 4.66819C0.52251 4.66819 0 5.1907 0 5.83524C0 6.47977 0.52251 7.00228 1.16705 7.00228H2.32953V29.1762C2.32953 31.0956 3.91123 32.6773 5.83067 32.6773H22.1693C24.0888 32.6773 25.6705 31.0956 25.6705 29.1762V7.00228H26.833C27.4775 7.00228 28 6.47977 28 5.83524C28 5.1907 27.4775 4.66819 26.833 4.66819C24.5004 4.66819 22.1678 4.66819 19.8352 4.66819V2.33409C19.8352 1.0612 18.774 0 17.5011 0H10.4989ZM10.4989 2.33409H17.5011V4.66819H10.4989V2.33409ZM4.66362 7.00228C10.8879 7.00228 17.1121 7.00228 23.3364 7.00228V29.1762C23.3364 29.8429 22.8361 30.3432 22.1693 30.3432H5.83067C5.16394 30.3432 4.66362 29.8429 4.66362 29.1762V7.00228Z" fill="currentColor"/>
<path d="M10.4991 12.8374C10.1896 12.8374 9.89272 12.9604 9.67385 13.1792C9.45499 13.3981 9.33203 13.6949 9.33203 14.0044V23.3408C9.33203 23.6503 9.45499 23.9472 9.67385 24.1661C9.89272 24.3849 10.1896 24.5079 10.4991 24.5079C10.8086 24.5079 11.1054 24.3849 11.3243 24.1661C11.5432 23.9472 11.6661 23.6503 11.6661 23.3408V14.0044C11.6661 13.6949 11.5432 13.3981 11.3243 13.1792C11.1054 12.9604 10.8086 12.8374 10.4991 12.8374Z" fill="currentColor"/>
<path d="M17.5015 12.8374C17.192 12.8374 16.8952 12.9604 16.6763 13.1792C16.4574 13.3981 16.3345 13.6949 16.3345 14.0044V23.3408C16.3345 23.6503 16.4574 23.9472 16.6763 24.1661C16.8952 24.3849 17.192 24.5079 17.5015 24.5079C17.811 24.5079 18.1079 24.3849 18.3267 24.1661C18.5456 23.9472 18.6686 23.6503 18.6686 23.3408V14.0044C18.6686 13.6949 18.5456 13.3981 18.3267 13.1792C18.1079 12.9604 17.811 12.8374 17.5015 12.8374Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -156,8 +156,13 @@
},
"purge_room": {
"title": "Delete room?",
"info": "This will close the room for all members. It cannot be undone.",
"button": "Delete room"
"info": "All members and messages will be removed. This action cannot be undone.",
"button": "Delete"
},
"goodbye": {
"room_deleted": "Room deleted.",
"close_tab": "Close browser tab",
"view_other_rooms": "View other rooms"
},
"room_info": {
"title": "Room Details",

View file

@ -4,27 +4,35 @@
<template v-if="roomJoinRule == 'public'">
<h1>👋</h1>
<h2 class="dialog-title">
{{$t('leave.title_public',{user: $matrix.currentUserDisplayName})}}
{{
$t("leave.title_public", { user: $matrix.currentUserDisplayName })
}}
</h2>
<div
v-if="$matrix.currentUser.is_guest && lastRoom"
class="dialog-text"
>
<i18n path="leave.text_public_lastroom" tag="p">
<template v-slot:user>
<span>{{ $matrix.currentUserDisplayName }}</span>
</template>
<template v-slot:action>
<a @click.prevent="viewProfile">{{ $t('leave.create_account') }}</a>
</template>
<i18n path="leave.text_public_lastroom" tag="p">
<template v-slot:user>
<span>{{ $matrix.currentUserDisplayName }}</span>
</template>
<template v-slot:action>
<a @click.prevent="viewProfile">{{
$t("leave.create_account")
}}</a>
</template>
</i18n>
</div>
<div v-else class="dialog-text">{{$t('leave.text_public')}}</div>
<div v-else class="dialog-text">{{ $t("leave.text_public") }}</div>
</template>
<template v-else>
<v-icon color="black" size="30">lock</v-icon>
<h2 class="dialog-title">{{$t('leave.title_invite',{user: $matrix.currentUserDisplayName})}}</h2>
<div class="dialog-text">{{$t('leave.text_invite')}}</div>
<h2 class="dialog-title">
{{
$t("leave.title_invite", { user: $matrix.currentUserDisplayName })
}}
</h2>
<div class="dialog-text">{{ $t("leave.text_invite") }}</div>
</template>
<v-container fluid>
<v-row cols="12">
@ -35,7 +43,7 @@
block
class="text-button"
@click="showDialog = false"
>{{$t('leave.go_back')}}</v-btn
>{{ $t("leave.go_back") }}</v-btn
>
</v-col>
<v-col cols="6" align="center">
@ -45,7 +53,7 @@
block
class="filled-button"
@click.stop="onLeaveRoom()"
>{{$t('leave.leave')}}</v-btn
>{{ $t("leave.leave") }}</v-btn
>
</v-col>
</v-row>

View file

@ -2,6 +2,7 @@
<v-dialog v-model="showDialog" v-show="room" class="ma-0 pa-0" width="80%">
<div 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>
<div class="dialog-text">
{{ $t("purge_room.info") }}
@ -101,4 +102,4 @@ export default {
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>
</style>

View file

@ -1,49 +1,130 @@
<template>
<transition name="slow-fade">
<div
v-if="mounted"
style="
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 100;
background-color: black;
align-items: center;
justify-content: center;
padding: 40px;
"
class="text-center d-flex flex-column"
>
<div class="quote white--text">{{ quote }}</div>
<div class="author white--text mt-4">- {{ author }}</div>
<v-btn color="white" text class="close" @click.stop="closeBrowserTab">Close your browser tab</v-btn>
</div>
</transition>
<div>
<transition name="slow-fade">
<div
v-if="mounted"
style="
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 100;
background-color: black;
align-items: center;
justify-content: center;
padding: 40px;
"
class="text-center d-flex flex-column"
>
<div v-if="roomWasPurged" style="width: 28px">
<v-img src="@/assets/icons/trash.svg" />
</div>
<h2 v-if="roomWasPurged" class="white--text mt-2 mb-8">
{{ $t("goodbye.room_deleted") }}
</h2>
<div class="quote white--text">{{ quote }}</div>
<div class="author white--text mt-4">- {{ author }}</div>
<v-btn
v-if="joinedToAnyRoom"
color="white"
text
class="close"
@click.stop="viewOtherRooms"
>{{ $t("goodbye.view_other_rooms") }}</v-btn
>
<v-btn
v-else
color="white"
text
class="close"
@click.stop="closeBrowserTab"
>{{ $t("goodbye.close_tab") }}</v-btn
>
</div>
</transition>
<!-- PROFILE INFO IN TOP RIGHT -->
<transition name="slow-fade">
<div
v-if="mounted"
style="
position: fixed;
top: 24px;
right: 24px;
z-index: 101;
padding: 10px 20px;
height: 50px;
border-radius: 25px;
background-color: #242424;
"
>
<div class="d-inline-block me-2 white--text">
{{ $t("profile_info_popup.you_are") }}
</div>
<div
v-if="$matrix.currentUser.is_guest"
class="d-inline-block me-2 white--text"
>
<i18n path="profile_info_popup.identity_temporary" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
<div v-else class="d-inline-block me-2 white--text">
<i18n path="profile_info_popup.identity" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
<v-avatar
class="avatar-32 d-inline-block"
size="32"
color="#e0e0e0"
@click.stop="showProfileInfo = true"
>
<img v-if="userAvatar" :src="userAvatar" />
<span v-else class="white--text">{{ userAvatarLetter }}</span>
</v-avatar>
</div>
</transition>
</div>
</template>
<script>
import profileInfoMixin from "./profileInfoMixin";
export default {
name: "QuoteView",
mixins: [profileInfoMixin],
props: {
roomWasPurged: {
type: Boolean,
default: function () {
return false;
},
},
},
data() {
return {
mounted: false,
quote: "",
author: "",
}
};
},
mounted() {
var quotes;
try {
quotes = require('@/assets/quotes/' + this.$i18n.locale + '/quotes');
} catch (error) {
console.error("No quotes for language");
quotes = undefined;
quotes = require("@/assets/quotes/" + this.$i18n.locale + "/quotes");
} catch (error) {
console.error("No quotes for language");
quotes = undefined;
}
if (!quotes) {
quotes = require('@/assets/quotes/en/quotes'); // Default fallback
quotes = require("@/assets/quotes/en/quotes"); // Default fallback
}
const n = quotes.quotes.length;
const quote = quotes.quotes[Math.floor(Math.random() * n)];
@ -52,12 +133,24 @@ export default {
this.mounted = true;
},
computed: {
/**
* Return true if we are still joined to any rooms
*/
joinedToAnyRoom() {
const joinedRooms = this.$matrix.joinedRooms;
return joinedRooms.length > 0;
},
},
methods: {
closeBrowserTab() {
window.location.href="about:blank";
}
}
window.location.href = "about:blank";
},
viewOtherRooms() {
this.$navigation.push({ name: "Home" }, -1);
},
},
};
</script>
@ -80,5 +173,4 @@ export default {
.slow-fade-enter, .slow-fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
</style>

View file

@ -74,6 +74,7 @@ const routes = [
path: '/goodbye',
name: 'Goodbye',
component: () => import('../components/QuoteView.vue'),
props: true
}
]
@ -82,7 +83,7 @@ const router = new VueRouter({
});
router.beforeEach((to, from, next) => {
const publicPages = ['/login','/createroom'];
const publicPages = ['/login', '/createroom'];
var authRequired = !publicPages.includes(to.path);
const loggedIn = router.app.$store.state.auth.user;
@ -113,7 +114,7 @@ router.beforeEach((to, from, next) => {
}
});
router.getRoomLink = function(roomId) {
router.getRoomLink = function (roomId) {
return window.location.origin + window.location.pathname + "#/room/" + encodeURIComponent(util.sanitizeRoomId(roomId));
}

View file

@ -303,6 +303,7 @@ 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);
}
},
@ -312,6 +313,7 @@ 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);
}
},
@ -351,6 +353,17 @@ 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) {
@ -502,7 +515,7 @@ export default {
);
const self = this;
console.log("Purge: set invite only");
//console.log("Purge: set invite only");
statusCallback(this.$t('room.purge_set_room_state'));
this.matrixClient.sendStateEvent(
roomId,
@ -511,7 +524,7 @@ export default {
""
)
.then(() => {
console.log("Purge: forbid guest access");
//console.log("Purge: forbid guest access");
return this.matrixClient.sendStateEvent(
roomId,
"m.room.guest_access",
@ -520,20 +533,20 @@ export default {
);
})
.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", {
history_visibility: "joined",
});
})
.then(() => {
console.log("Purge: create timeline");
//console.log("Purge: create timeline");
return timelineWindow.load(null, 100)
})
.then(() => {
const getMoreIfAvailable = function _getMoreIfAvailable() {
if (timelineWindow.canPaginate(EventTimeline.BACKWARDS)
) {
console.log("Purge: page back");
//console.log("Purge: page back");
return timelineWindow
.paginate(EventTimeline.BACKWARDS, 100, true, 5)
.then((ignoredsuccess) => {
@ -546,7 +559,7 @@ export default {
return getMoreIfAvailable();
})
.then(() => {
console.log("Purge: redact events");
//console.log("Purge: redact events");
statusCallback(this.$t('room.purge_redacting_events'));
// First ignore unknown device errors
this.matrixClient.setGlobalErrorOnUnknownDevices(false);
@ -560,7 +573,7 @@ export default {
return Promise.all(redactionPromises);
})
.then(() => {
console.log("Purge: kick members");
//console.log("Purge: kick members");
statusCallback(this.$t('room.purge_removing_members'));
var joined = room.getMembersWithMembership("join");
var invited = room.getMembersWithMembership("invite");
@ -577,6 +590,9 @@ export default {
.then(() => {
statusCallback(null);
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
return this.leaveRoom(roomId);
})
.then(() => {
resolve(true); // Done!
})
.catch((err) => {