Merge branch '563-add-timed-message-retention-feature' into 'dev'
Add timed message retention feature See merge request keanuapp/keanuapp-weblite!279
This commit is contained in:
commit
42ef05a804
5 changed files with 404 additions and 47 deletions
|
|
@ -314,6 +314,20 @@
|
|||
"download_chat": "Download chat",
|
||||
"read_only_room": "Read only room",
|
||||
"read_only_room_info": "Only admins and moderators are allowed to send to the room",
|
||||
"message_retention": "Disappearing messages",
|
||||
"message_retention_info": "You can set a timeout for automatically removing messages from the room.\nNote: the server must support this feature.",
|
||||
"message_retention_none": "Off",
|
||||
"message_retention_1_hour": "1 Hour",
|
||||
"message_retention_1_day": "1 Day",
|
||||
"message_retention_1_week": "1 Week",
|
||||
"message_retention_30_days": "30 Days",
|
||||
"message_retention_365_days": "365 Days",
|
||||
"message_retention_other": "Other",
|
||||
"message_retention_other_seconds": "{count} Seconds",
|
||||
"message_retention_other_seconds_unit": "Seconds",
|
||||
"message_retention_other_required": "Value can not be empty",
|
||||
"message_retention_other_too_small": "Value must be at least {count} seconds",
|
||||
"message_retention_other_too_large": "Value can be at most {count} seconds",
|
||||
"make_public": "Make Public",
|
||||
"make_public_warning": "warning: Full message history will be visible to new participants",
|
||||
"direct_link": "My Direct Link",
|
||||
|
|
|
|||
|
|
@ -483,6 +483,11 @@ export default {
|
|||
Places: this.$t("emoji.categories.places")
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A timer to handle message retention/auto deletion
|
||||
*/
|
||||
retentionTimer: null
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -511,6 +516,10 @@ export default {
|
|||
this.$root.$off('audio-playback-ended', this.audioPlaybackEnded);
|
||||
this.$audioPlayer.pause();
|
||||
this.stopRRTimer();
|
||||
if (this.retentionTimer) {
|
||||
clearInterval(this.retentionTimer);
|
||||
this.retentionTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
|
|
@ -774,6 +783,12 @@ export default {
|
|||
this.events.filter(event => (event.threadRootId && !event.parentThread)).forEach(event => this.setParentThread(event));
|
||||
this.events.filter(event => (event.replyEventId && !event.replyEvent)).forEach(event => this.setReplyToEvent(event));
|
||||
console.log("Loading finished!");
|
||||
this.updateRetentionTimer();
|
||||
} else if (!value) {
|
||||
if (this.retentionTimer) {
|
||||
clearInterval(this.retentionTimer);
|
||||
this.retentionTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -871,6 +886,52 @@ export default {
|
|||
this.initialLoadDone = true;
|
||||
console.log("Loading finished!");
|
||||
},
|
||||
|
||||
/**
|
||||
* Set events to display. At the same time, filter out messages that are past rentention period etc.
|
||||
*/
|
||||
setEvents(events) {
|
||||
this.events = this.removeTimedOutEvents(events);
|
||||
},
|
||||
|
||||
updateRetentionTimer(maybeEvent) {
|
||||
const retentionEvent = maybeEvent || (this.room && this.room.currentState.getStateEvents("m.room.retention", ""));
|
||||
if (retentionEvent) {
|
||||
const maxLifetime = parseInt(retentionEvent.getContent().max_lifetime);
|
||||
if (maxLifetime) {
|
||||
if (!this.retentionTimer) {
|
||||
this.retentionTimer = setInterval(this.onRetentionTimer, 60000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.retentionTimer) {
|
||||
clearInterval(this.retentionTimer);
|
||||
this.retentionTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
removeTimedOutEvents(events) {
|
||||
const retentionEvent = this.room && this.room.currentState.getStateEvents("m.room.retention", "");
|
||||
let maxLifetime = 0;
|
||||
if (retentionEvent) {
|
||||
maxLifetime = parseInt(retentionEvent.getContent().max_lifetime);
|
||||
}
|
||||
return events.filter((e) => {
|
||||
if (maxLifetime > 0 && !e.isState()) { // Keep all state events
|
||||
return e.getLocalAge() < maxLifetime;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
onRetentionTimer() {
|
||||
const events = this.removeTimedOutEvents(this.events);
|
||||
if (events.length != this.events.length) {
|
||||
this.events = events; // Changed
|
||||
}
|
||||
},
|
||||
|
||||
onRoomJoined(initialEventId) {
|
||||
// Listen to events
|
||||
this.$matrix.on("Room.timeline", this.onEvent);
|
||||
|
|
@ -885,7 +946,7 @@ export default {
|
|||
this.timelineWindow
|
||||
.load(initialEventId, 20)
|
||||
.then(() => {
|
||||
self.events = self.timelineWindow.getEvents();
|
||||
self.setEvents(self.timelineWindow.getEvents());
|
||||
|
||||
const getMoreIfNeeded = function _getMoreIfNeeded() {
|
||||
const container = self.$refs.chatContainer;
|
||||
|
|
@ -896,7 +957,7 @@ export default {
|
|||
self.timelineWindow.canPaginate(EventTimeline.BACKWARDS)
|
||||
) {
|
||||
return self.timelineWindow.paginate(EventTimeline.BACKWARDS, 10, true, 5).then((success) => {
|
||||
self.events = self.timelineWindow.getEvents();
|
||||
self.setEvents(self.timelineWindow.getEvents());
|
||||
if (success) {
|
||||
return _getMoreIfNeeded.call(self);
|
||||
} else {
|
||||
|
|
@ -943,7 +1004,7 @@ export default {
|
|||
this.onRoomJoined(null);
|
||||
} else {
|
||||
// Error. Done loading.
|
||||
this.events = this.timelineWindow.getEvents();
|
||||
this.setEvents(this.timelineWindow.getEvents());
|
||||
this.setInitialLoadDone();
|
||||
}
|
||||
})
|
||||
|
|
@ -976,7 +1037,7 @@ export default {
|
|||
.then(() => {
|
||||
self.timelineSet = timelineSet;
|
||||
self.timelineWindow = timelineWindow;
|
||||
self.events = self.timelineWindow.getEvents();
|
||||
self.setEvents(self.timelineWindow.getEvents());
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
|
|
@ -1090,7 +1151,7 @@ export default {
|
|||
if (tl) {
|
||||
const parentEvent = tl.getEvents().find((e) => e.getId() === event.threadRootId);
|
||||
if (parentEvent) {
|
||||
this.events = this.timelineWindow.getEvents();
|
||||
this.setEvents(this.timelineWindow.getEvents());
|
||||
const fn = () => {
|
||||
Vue.set(parentEvent, "isMxThread", true);
|
||||
Vue.set(event, "parentThread", parentEvent);
|
||||
|
|
@ -1123,7 +1184,7 @@ export default {
|
|||
if (tl) {
|
||||
const parentEvent = tl.getEvents().find((e) => e.getId() === event.replyEventId);
|
||||
if (parentEvent) {
|
||||
this.events = this.timelineWindow.getEvents();
|
||||
this.setEvents(this.timelineWindow.getEvents());
|
||||
const fn = () => {Vue.set(event, "replyEvent", parentEvent);};
|
||||
if (this.initialLoadDone) {
|
||||
const sel = "[eventId=\"" + parentEvent.getId() + "\"]";
|
||||
|
|
@ -1162,7 +1223,7 @@ export default {
|
|||
this.paginateBackIfNeeded();
|
||||
}
|
||||
|
||||
if (loadingDone && event.forwardLooking && (!event.isRelation() || event.isMxThread || event.threadRootId || event.parentThread )) {
|
||||
if (loadingDone && event.forwardLooking && (!event.isRelation() || event.isMxThread || event.threadRootId || event.parentThread)) {
|
||||
// If we are at bottom, scroll to see new events...
|
||||
var scrollToSeeNew = event.getSender() == this.$matrix.currentUserId; // When we sent, scroll
|
||||
const container = this.chatContainer;
|
||||
|
|
@ -1179,13 +1240,17 @@ export default {
|
|||
(event.getPrevContent() || {}).membership == "join" &&
|
||||
(
|
||||
(event.getContent().membership == "leave" && event.getSender() != this.currentUserId) ||
|
||||
(event.getContent().membership == "ban" ))
|
||||
) {
|
||||
this.$store.commit("setCurrentRoomId", null);
|
||||
const wasPurged = event.getContent().reason == "Room Deleted";
|
||||
this.$navigation.push({ name: "Goodbye", params: { roomWasPurged: wasPurged } }, -1);
|
||||
}
|
||||
(event.getContent().membership == "ban"))
|
||||
) {
|
||||
this.$store.commit("setCurrentRoomId", null);
|
||||
const wasPurged = event.getContent().reason == "Room Deleted";
|
||||
this.$navigation.push({ name: "Goodbye", params: { roomWasPurged: wasPurged } }, -1);
|
||||
}
|
||||
|
||||
else if (event.getType() === "m.room.retention") {
|
||||
this.updateRetentionTimer(event);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onUserTyping(event, member) {
|
||||
|
|
@ -1404,7 +1469,7 @@ export default {
|
|||
.then((success) => {
|
||||
if (success && this.scrollPosition) {
|
||||
this.scrollPosition.prepareFor("up");
|
||||
this.events = this.timelineWindow.getEvents();
|
||||
this.setEvents(this.timelineWindow.getEvents());
|
||||
this.$nextTick(() => {
|
||||
// restore scroll position!
|
||||
console.log("Restore scroll!");
|
||||
|
|
@ -1429,7 +1494,7 @@ export default {
|
|||
.paginate(EventTimeline.FORWARDS, 10, true)
|
||||
.then((success) => {
|
||||
if (success) {
|
||||
this.events = this.timelineWindow.getEvents();
|
||||
this.setEvents(this.timelineWindow.getEvents());
|
||||
if (!this.useVoiceMode && this.scrollPosition) {
|
||||
this.scrollPosition.prepareFor("down");
|
||||
this.$nextTick(() => {
|
||||
|
|
|
|||
219
src/components/MessageRetentionDialog.vue
Normal file
219
src/components/MessageRetentionDialog.vue
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
<template>
|
||||
<v-dialog persistent v-model="showDialog" v-show="room" class="ma-0 pa-0"
|
||||
:width="$vuetify.breakpoint.smAndUp ? '688px' : '95%'">
|
||||
<div class="dialog-content text-center">
|
||||
<template>
|
||||
<h2 class="dialog-title">{{ $t("room_info.message_retention") }}</h2>
|
||||
<div class="dialog-text">
|
||||
{{ $t("room_info.message_retention_info") }}
|
||||
</div>
|
||||
</template>
|
||||
<v-container fluid>
|
||||
<v-row cols="12">
|
||||
<v-col cols="12">
|
||||
<v-form v-model="isValid">
|
||||
<v-radio-group v-model="retention" :value-comparator="compareValue">
|
||||
<v-radio active-class="radio-active" v-for="p in retentionPeriods" :key="p.text" :label="p.text"
|
||||
:value="p.value">
|
||||
<template v-slot:label v-if="p.value === ''">
|
||||
<div :class="{ 'other': true, 'visible': selectedOther }"><span>{{ p.text }}</span>
|
||||
<v-text-field :show="selectedOther" ref="otherInput" background-color="transparent" height="20px"
|
||||
dense outlined x-hide-details autofocus v-model="retentionOther" single-line type="number"
|
||||
hide-spin-buttons :rules="otherInputRules"
|
||||
:suffix="$t('room_info.message_retention_other_seconds_unit')"></v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
</v-radio>
|
||||
</v-radio-group>
|
||||
</v-form>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row cols="12">
|
||||
<v-col cols="6">
|
||||
<v-btn depressed text block class="text-button" @click="showDialog = false">{{
|
||||
$t("menu.cancel") }}</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="6" align="center">
|
||||
<v-btn color="primary" :disabled="!isValid" depressed block class="filled-button"
|
||||
@click.stop="setRetention()">{{
|
||||
$t("menu.ok") }}</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
|
||||
export default {
|
||||
name: "MessageRetentionDialog",
|
||||
mixins: [roomInfoMixin],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
isValid: true,
|
||||
selectedOther: false,
|
||||
retention: 0,
|
||||
retentionOther: 60, // Set same as min below
|
||||
retentionMinValue: 60,
|
||||
retentionMaxValue: 60 * 60 * 24 * 500,
|
||||
retentionPeriods: [
|
||||
{
|
||||
text: this.$t("room_info.message_retention_none"),
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
text: this.$t("room_info.message_retention_1_hour"),
|
||||
value: 3600 * 1000
|
||||
},
|
||||
{
|
||||
text: this.$t("room_info.message_retention_1_day"),
|
||||
value: 3600 * 24 * 1000
|
||||
},
|
||||
{
|
||||
text: this.$t("room_info.message_retention_30_days"),
|
||||
value: 3600 * 24 * 30 * 1000
|
||||
},
|
||||
{
|
||||
text: this.$t("room_info.message_retention_365_days"),
|
||||
value: 3600 * 24 * 365 * 1000
|
||||
},
|
||||
{
|
||||
text: this.$t("room_info.message_retention_other"),
|
||||
value: ''
|
||||
},
|
||||
],
|
||||
otherInputRules: [
|
||||
v => !!v || this.$t("room_info.message_retention_other_required"),
|
||||
v => (v && v >= this.retentionMinValue) || this.$t("room_info.message_retention_other_too_small", { count: this.retentionMinValue }),
|
||||
v => (v && v <= this.retentionMaxValue) || this.$t("room_info.message_retention_other_too_large", { count: this.retentionMaxValue }),
|
||||
]
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog(val, oldVal) {
|
||||
if (!val && oldVal) {
|
||||
this.$emit("close");
|
||||
} else if (val && !oldVal) {
|
||||
// Showing, reset
|
||||
this.setInitialValue();
|
||||
}
|
||||
},
|
||||
retention(val) {
|
||||
if (val === '') {
|
||||
this.selectedOther = true;
|
||||
this.retentionOther = this.retentionMaxValue;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.otherInput[0].focus();
|
||||
});
|
||||
} else {
|
||||
// If one of the other, it's not "other"
|
||||
for (var i = 0; i < this.retentionPeriods.length; i++) {
|
||||
if (this.retentionPeriods[i].value === val) {
|
||||
this.selectedOther = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setInitialValue();
|
||||
},
|
||||
methods: {
|
||||
setInitialValue() {
|
||||
this.isValid = true;
|
||||
this.retention = this.roomMessageRetention();
|
||||
let found = false;
|
||||
for (var i = 0; i < this.retentionPeriods.length; i++) {
|
||||
if (this.retentionPeriods[i].value !== '' && this.retentionPeriods[i].value === this.retention) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
this.selectedOther = true;
|
||||
}
|
||||
},
|
||||
compareValue(a, b) {
|
||||
if (this.selectedOther) {
|
||||
if (b === '') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (a === b) return true;
|
||||
if (b === '') {
|
||||
// If none of the other, it's "other"
|
||||
for (var i = 0; i < this.retentionPeriods.length; i++) {
|
||||
if (this.retentionPeriods[i].value === a) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
setRetention() {
|
||||
let ms = this.retention;
|
||||
if (this.selectedOther) {
|
||||
ms = this.retentionOther * 1000;
|
||||
}
|
||||
if (ms === 0 || !ms) {
|
||||
// No expiry
|
||||
this.$matrix.matrixClient.sendStateEvent(
|
||||
this.room.roomId,
|
||||
"m.room.retention",
|
||||
{ max_lifetime: 0 }
|
||||
);
|
||||
this.showDialog = false;
|
||||
} else if (ms >= 1000 * this.retentionMinValue && ms <= 1000 * this.retentionMaxValue) {
|
||||
this.$matrix.matrixClient.sendStateEvent(
|
||||
this.room.roomId,
|
||||
"m.room.retention",
|
||||
{ max_lifetime: ms }
|
||||
);
|
||||
this.showDialog = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
|
||||
.v-radio:last-of-type {
|
||||
align-items: start !important;
|
||||
}
|
||||
|
||||
.v-radio .other {
|
||||
display: flex;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.v-radio .v-text-field {
|
||||
display: none;
|
||||
margin-left: 8px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.v-radio.radio-active {
|
||||
.v-text-field {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -159,6 +159,14 @@
|
|||
v-model="readOnlyRoom"
|
||||
></v-switch>
|
||||
</v-card-text>
|
||||
<v-card-text class="with-right-label" style="align-items:center" v-if="canViewRetentionPolicy">
|
||||
<div>
|
||||
<div class="option-title">{{ $t('room_info.message_retention') }}</div>
|
||||
<div class="option-text">{{ $t('room_info.message_retention_info') }}</div>
|
||||
</div>
|
||||
<div class="text-right">{{ messageRetention }}</div>
|
||||
<v-btn v-on:click="showMessageRetentionDialog = true" v-if="canChangeRetentionPolicy" icon size="x-small"><v-icon color="black">edit</v-icon></v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-card class="members ma-3" flat>
|
||||
|
|
@ -261,6 +269,12 @@
|
|||
@close="showPurgeConfirmation = false"
|
||||
/>
|
||||
|
||||
<MessageRetentionDialog
|
||||
:show="showMessageRetentionDialog"
|
||||
:room="room"
|
||||
@close="showMessageRetentionDialog = false"
|
||||
/>
|
||||
|
||||
<RoomExport :room="room" v-if="exporting" v-on:close="exporting = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -268,6 +282,7 @@
|
|||
<script>
|
||||
import LeaveRoomDialog from "../components/LeaveRoomDialog";
|
||||
import PurgeRoomDialog from "../components/PurgeRoomDialog";
|
||||
import MessageRetentionDialog from "../components/MessageRetentionDialog";
|
||||
import DeviceList from "../components/DeviceList";
|
||||
import RoomExport from "../components/RoomExport";
|
||||
import RoomAvatarPicker from "../components/RoomAvatarPicker";
|
||||
|
|
@ -283,6 +298,7 @@ export default {
|
|||
components: {
|
||||
LeaveRoomDialog,
|
||||
PurgeRoomDialog,
|
||||
MessageRetentionDialog,
|
||||
DeviceList,
|
||||
RoomExport,
|
||||
RoomAvatarPicker,
|
||||
|
|
@ -296,6 +312,8 @@ export default {
|
|||
showAllMembers: false,
|
||||
showLeaveConfirmation: false,
|
||||
showPurgeConfirmation: false,
|
||||
showMessageRetentionDialog: false,
|
||||
messageRetention: "",
|
||||
buildVersion: "",
|
||||
updatingJoinRule: false, // Flag if we are processing update curerntly
|
||||
joinRules: [
|
||||
|
|
@ -311,12 +329,13 @@ export default {
|
|||
},
|
||||
],
|
||||
SHOW_MEMBER_LIMIT: 5,
|
||||
exporting: false,
|
||||
};
|
||||
exporting: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$matrix.on("Room.timeline", this.onEvent);
|
||||
this.updateMembers();
|
||||
this.updateMessageRetention();
|
||||
this.user = this.$matrix.matrixClient.getUser(this.$matrix.currentUserId);
|
||||
|
||||
// Display build version
|
||||
|
|
@ -395,6 +414,7 @@ export default {
|
|||
handler() {
|
||||
console.log("RoomInfo: Current room changed");
|
||||
this.updateMembers();
|
||||
this.updateMessageRetention();
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -404,11 +424,17 @@ export default {
|
|||
if (this.room && this.room.roomId == event.getRoomId()) {
|
||||
// For this room
|
||||
if (event.getType() == "m.room.member") {
|
||||
this.updateMembers();
|
||||
}
|
||||
this.updateMembers();
|
||||
} else if (event.getType() == "m.room.retention") {
|
||||
this.updateMessageRetention(event);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateMessageRetention(event) {
|
||||
this.messageRetention = this.roomMessageRetentionDisplay(event);
|
||||
},
|
||||
|
||||
updateMembers() {
|
||||
if (this.room) {
|
||||
const myUserId = this.$matrix.currentUserId;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default {
|
|||
editedRoomTopic: "",
|
||||
isRoomTopicEditMode: false,
|
||||
roomTopicErrorMessage: null,
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$matrix.on("Room.timeline", this.roomInfoMixinOnEvent);
|
||||
|
|
@ -61,7 +61,10 @@ export default {
|
|||
publicRoomLink() {
|
||||
if (this.room && this.roomJoinRule == "public") {
|
||||
return this.$router.getRoomLink(
|
||||
this.room.getCanonicalAlias(), this.room.roomId, this.room.name, utils.roomDisplayTypeToQueryParam(this.room, this.roomDisplayType)
|
||||
this.room.getCanonicalAlias(),
|
||||
this.room.roomId,
|
||||
this.room.name,
|
||||
utils.roomDisplayTypeToQueryParam(this.room, this.roomDisplayType)
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
|
@ -69,7 +72,7 @@ export default {
|
|||
|
||||
roomHistory() {
|
||||
if (this.room) {
|
||||
return this.room.shouldEncryptForInvitedMembers()
|
||||
return this.room.shouldEncryptForInvitedMembers();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
|
@ -92,13 +95,24 @@ export default {
|
|||
*/
|
||||
privateParty() {
|
||||
if (this.isPrivate) {
|
||||
const membersButMe = this.room.getMembers().filter(m => m.userId != this.$matrix.currentUserId);
|
||||
const membersButMe = this.room.getMembers().filter((m) => m.userId != this.$matrix.currentUserId);
|
||||
if (membersButMe.length == 1) {
|
||||
return membersButMe[0];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
canViewRetentionPolicy() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return true if we can set message retention policy in the room.
|
||||
*/
|
||||
canChangeRetentionPolicy() {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
room: {
|
||||
|
|
@ -115,14 +129,48 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Get a string describing current room retention setting.
|
||||
* Can be "None", "1 week", "1 hour" etc...
|
||||
*/
|
||||
roomMessageRetentionDisplay(maybeEvent) {
|
||||
const retention = this.roomMessageRetention(maybeEvent);
|
||||
if (retention == 0) {
|
||||
return this.$t("room_info.message_retention_none");
|
||||
} else if (retention == 60 * 60 * 1000) {
|
||||
return this.$t("room_info.message_retention_1_hour");
|
||||
} else if (retention == 24 * 60 * 60 * 1000) {
|
||||
return this.$t("room_info.message_retention_1_day");
|
||||
} else if (retention == 7 * 24 * 60 * 60 * 1000) {
|
||||
return this.$t("room_info.message_retention_1_week");
|
||||
} else if (retention == 30 * 24 * 60 * 60 * 1000) {
|
||||
return this.$t("room_info.message_retention_30_days");
|
||||
} else if (retention == 365 * 24 * 60 * 60 * 1000) {
|
||||
return this.$t("room_info.message_retention_365_days");
|
||||
}
|
||||
return this.$t("room_info.message_retention_other_seconds", { count: retention / 1000 });
|
||||
},
|
||||
|
||||
roomMessageRetention(maybeEvent) {
|
||||
const retentionEvent = maybeEvent || (this.room && this.room.currentState.getStateEvents("m.room.retention", ""));
|
||||
if (retentionEvent) {
|
||||
console.log("Retention event found", JSON.stringify(retentionEvent));
|
||||
const maxLifetime = parseInt(retentionEvent.getContent().max_lifetime);
|
||||
if (maxLifetime) {
|
||||
return maxLifetime;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
onRoomNameClicked() {
|
||||
if(this.userCanPurgeRoom) {
|
||||
if (this.userCanPurgeRoom) {
|
||||
this.isRoomNameEditMode = !this.isRoomNameEditMode;
|
||||
this.editedRoomName = this.roomName;
|
||||
}
|
||||
},
|
||||
updateRoomName() {
|
||||
if(this.editedRoomName) {
|
||||
if (this.editedRoomName) {
|
||||
this.$matrix.matrixClient.setRoomName(this.room.roomId, this.editedRoomName);
|
||||
this.isRoomNameEditMode = !this.isRoomNameEditMode;
|
||||
} else {
|
||||
|
|
@ -130,13 +178,13 @@ export default {
|
|||
}
|
||||
},
|
||||
onRoomTopicClicked() {
|
||||
if(this.userCanPurgeRoom) {
|
||||
if (this.userCanPurgeRoom) {
|
||||
this.isRoomTopicEditMode = !this.isRoomTopicEditMode;
|
||||
this.editedRoomTopic = this.roomTopic;
|
||||
}
|
||||
},
|
||||
updateRoomTopic() {
|
||||
if(this.editedRoomTopic) {
|
||||
if (this.editedRoomTopic) {
|
||||
this.$matrix.matrixClient.setRoomTopic(this.room.roomId, this.editedRoomTopic);
|
||||
this.isRoomTopicEditMode = !this.isRoomTopicEditMode;
|
||||
} else {
|
||||
|
|
@ -154,14 +202,8 @@ export default {
|
|||
if (this.room) {
|
||||
this.roomJoinRule = this.getRoomJoinRule();
|
||||
const canChangeAccess =
|
||||
this.room.currentState.mayClientSendStateEvent(
|
||||
"m.room.join_rules",
|
||||
this.$matrix.matrixClient
|
||||
) &&
|
||||
this.room.currentState.mayClientSendStateEvent(
|
||||
"m.room.guest_access",
|
||||
this.$matrix.matrixClient
|
||||
);
|
||||
this.room.currentState.mayClientSendStateEvent("m.room.join_rules", this.$matrix.matrixClient) &&
|
||||
this.room.currentState.mayClientSendStateEvent("m.room.guest_access", this.$matrix.matrixClient);
|
||||
this.userCanChangeJoinRule = canChangeAccess;
|
||||
this.userCanPurgeRoom = canChangeAccess; //TODO - need different permissions here?
|
||||
} else {
|
||||
|
|
@ -175,10 +217,7 @@ export default {
|
|||
if (event.getRoomId() !== this.roomId) {
|
||||
return; // Not for this room
|
||||
}
|
||||
if (
|
||||
event.getType() == "m.room.join_rules" ||
|
||||
event.getType() == "m.room.guest_access"
|
||||
) {
|
||||
if (event.getType() == "m.room.join_rules" || event.getType() == "m.room.guest_access") {
|
||||
this.updatePermissions();
|
||||
}
|
||||
},
|
||||
|
|
@ -186,15 +225,9 @@ export default {
|
|||
privatePartyAvatar(size) {
|
||||
const other = this.privateParty;
|
||||
if (other) {
|
||||
return other.getAvatarUrl(
|
||||
this.$matrix.matrixClient.getHomeserverUrl(),
|
||||
size,
|
||||
size,
|
||||
"scale",
|
||||
true
|
||||
);
|
||||
return other.getAvatarUrl(this.$matrix.matrixClient.getHomeserverUrl(), size, size, "scale", true);
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue