Merge branch 'main' of gitlab.com:keanuapp/keanuapp-weblite into main

This commit is contained in:
Nathan Freitas 2021-07-08 10:42:41 -04:00
commit bee3b37449
No known key found for this signature in database
GPG key ID: A801183E69B37AA9
22 changed files with 603 additions and 107 deletions

View file

@ -11,13 +11,11 @@ import config from "./assets/config";
export default { export default {
name: "App", name: "App",
beforeMount() {
// Set language
this.$i18n.locale = this.$store.state.language || "en";
},
mounted() { mounted() {
// Set RTL mode if flag given in config. TODO: this should be based on language, not a global setting.
//
if (config.rtl) {
this.$vuetify.rtl = true;
document.documentElement.setAttribute("dir", "rtl");
}
if ( if (
window.location.protocol == "http" && window.location.protocol == "http" &&
!window.location.hostname.endsWith(".onion") !window.location.hostname.endsWith(".onion")
@ -63,6 +61,20 @@ export default {
}, },
}, },
watch: { watch: {
"$i18n.locale": {
handler(val) {
// Locale changed, check file if RTL
var isRTL = this.$i18n.messages[val].language_is_rtl || false;
if (isRTL) {
this.$vuetify.rtl = true;
document.documentElement.setAttribute("dir", "rtl");
} else {
this.$vuetify.rtl = false;
document.documentElement.removeAttribute("dir");
}
},
immediate: true,
},
title(title) { title(title) {
document.title = title; document.title = title;
}, },

View file

@ -3,6 +3,27 @@
$admin-bg: black; $admin-bg: black;
$admin-fg: white; $admin-fg: white;
.home {
.v-card {
background-color: white;
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25) !important;
border-radius: 18px;
padding-bottom: 10px;
.v-item-group > div:not(:last-of-type):after {
/* divider */
position: absolute;
content: " ";
display: block;
bottom: 0px;
height: 1px;
left: 0px;
right: 0px;
min-height: 1px;
background-color: #e1e1e1;
}
}
}
.chat-header { .chat-header {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -445,6 +466,19 @@ $admin-fg: white;
user-select: text; 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 { .audio-player {
width: 100%; width: 100%;
position: absolute; position: absolute;
@ -962,6 +996,10 @@ $admin-fg: white;
padding-top: 10px; padding-top: 10px;
} }
.avatar-22 {
font-size: 14 * $chat-text-size !important;
}
.avatar-32 { .avatar-32 {
font-size: 18 * $chat-text-size !important; font-size: 18 * $chat-text-size !important;
} }
@ -971,7 +1009,8 @@ $admin-fg: white;
} }
.avatar-32.clickable, .avatar-32.clickable,
.avatar-48.clickable { .avatar-48.clickable,
.clickable {
cursor: pointer; cursor: pointer;
&:hover { &:hover {
opacity: 0.7; opacity: 0.7;

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

@ -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

@ -6,25 +6,26 @@
"video_file": "བརྙན་ཟློས་ཡིག་ཆ།" "video_file": "བརྙན་ཟློས་ཡིག་ཆ།"
}, },
"room_info": { "room_info": {
"title": "གནས་ཚུལ།", "title": "ཁ་བརྡ་ཁང་གི་ཞིབ་ཕྲའི་གནས་ཚུལ།",
"version_info": "གྷར་ཌིན་ལས་འཆར་གྱིས་ནུས་ཤུགས་བསྩལ། ཐོན་རིམ། : {version}", "version_info": "གྷར་ཌིན་ལས་འཆར་གྱིས་ནུས་ཤུགས་བསྩལ། ཐོན་རིམ། : {version}",
"leave_room_info": "གསལ་བཤད། གོ་རིམ་འདི་ཕྱིར་ཟློག་ཐབས་མེད། ཁྱེད་རང་ཕྱིར་ཐོན་རྒྱུ་ཡིན་མིན་དང་གླེང་མོལ་ཁག་གཏན་དུ་གསུབ་རྒྱུ་ཡིན་མིན་ཁག་ཐེག་བྱོས།", "leave_room_info": "གསལ་བཤད། གོ་རིམ་འདི་ཕྱིར་ཟློག་ཐབས་མེད། ཁྱེད་རང་ཕྱིར་ཐོན་རྒྱུ་ཡིན་མིན་དང་གླེང་མོལ་ཁག་གཏན་དུ་གསུབ་རྒྱུ་ཡིན་མིན་ཁག་ཐེག་བྱོས།",
"leave_room": "ཚོགས་པ་ནས་ཕྱིར་ཐོན།", "leave_room": "ཕྱིར་ཐོན།",
"view_profile": "ལྟ་ཞིབ།", "view_profile": "ལྟ་ཞིབ།",
"identity_temporary": "ཁྱེད་ཀྱི་ངོ་བོ {displayName} འདི་གནས་སྐབས་ཙམ་ཡིན། ཁྱེད་ཀྱིས་སོ་སོའི་མིང་དང་གསང་ཚིག་བརྗེས་ཏེ་འདི་ཉར་ཚགས་བྱེད་ཆོག", "identity_temporary": "ཁྱེད་ཀྱི་ངོ་བོ {displayName} འདི་གནས་སྐབས་ཙམ་ཡིན། ཁྱེད་ཀྱིས་སོ་སོའི་མིང་དང་གསང་ཚིག་བརྗེས་ཏེ་འདི་ཉར་ཚགས་བྱེད་ཆོག",
"identity": "ཁྱེད་རང་{displayName} མིང་ཐོག་ནས་ནང་འཛུལ་བྱེད་བཞིན་འདུག", "identity": "ཁྱེད་རང་{displayName} མིང་ཐོག་ནས་ནང་འཛུལ་བྱེད་བཞིན་འདུག",
"my_profile": "ངའི་ཡིག་ཆ།", "my_profile": "ངའི་ཡིག་ཆ།",
"show_all": "ཚང་མ་སྟོན།", "show_all": "ཚང་མ་སྟོན། >",
"hide_all": "སྦེད།", "hide_all": "སྦེད།",
"user_you": "{user} (ཁྱེད་རང་།)", "user_you": "{user} (ཁྱེད་རང་།)",
"user": "{user}", "user": "{user}",
"members": "ཚོགས་མི་ཁག", "members": "ཚོགས་མི་ཁག",
"purge": "ཁ་བརྡ་ཁང་གཏོར།", "purge": "ཁ་བརྡ་ཁང་མེད་པར་བཟོས།",
"link_copied": "འབྲེལ་ཐག་པར་བཤུས་བརྒྱབ་ཚར།", "link_copied": "འབྲེལ་ཐག་པར་བཤུས་བརྒྱབ་ཚར།",
"join_public": "འབྲེལ་ཐག་ཡོད་པའི་མི་གང་རུང་འཛུལ་ཆོག", "join_public": "འབྲེལ་ཐག་ཡོད་པའི་མི་གང་རུང་།",
"join_invite": "གདན་ཞུ་ཁོ་ན་བརྒྱུད་དེ་མ་གཏོགས་ཁ་བརྡ་ཁང་ནང་དུ་འཛུལ་མི་ཐུབ།", "join_invite": "ཁ་སྣོན་བྱས་པའི་གྲོགས་ཁོ་ན།",
"permissions": "ཆོག་མཆན་ཁག", "permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག",
"created_by": "{user} བཟོས།" "created_by": "{user} བཟོས།",
"copy_link": "གདན་ཞུ་འབྲེལ་ཐག་པར་བཤུས་རྒྱོབས།"
}, },
"invite": { "invite": {
"done": "ཚར་སོང་།", "done": "ཚར་སོང་།",
@ -57,8 +58,10 @@
"join_permissions_info": "ཆོག་མཆན་འདི་དག་གིས་ཚོགས་པའི་ནང་མི་ཇི་ལྟར་འཛུལ་ཐུབ་མིན་དང་། མི་གཞན་དག་ཇི་ལྟར་ལས་སླ་པོའི་ཐོག་ནས་གདན་ཞུ་བྱེད་ཐུབ་མིན་སོགས་ཐག་གཅོད་བྱེད་ཀྱི་ཡོད། ཆོག་མཆན་དེ་དག་ག་དུས་ཡིན་ཡང་འགྱུར་བ་གཏོང་ཆོག", "join_permissions_info": "ཆོག་མཆན་འདི་དག་གིས་ཚོགས་པའི་ནང་མི་ཇི་ལྟར་འཛུལ་ཐུབ་མིན་དང་། མི་གཞན་དག་ཇི་ལྟར་ལས་སླ་པོའི་ཐོག་ནས་གདན་ཞུ་བྱེད་ཐུབ་མིན་སོགས་ཐག་གཅོད་བྱེད་ཀྱི་ཡོད། ཆོག་མཆན་དེ་དག་ག་དུས་ཡིན་ཡང་འགྱུར་བ་གཏོང་ཆོག",
"set_join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་སྒྲིག་འགོད་བྱོས།", "set_join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་སྒྲིག་འགོད་བྱོས།",
"join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག", "join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག",
"new_room": "ཚོགས་པ་གསར་པ།", "new_room": "ཁ་བརྡ་ཁང་གསར་པ།",
"name_room": "ཚོགས་པར་མིང་ཐོགས།" "name_room": "ཚོགས་པར་མིང་ཐོགས།",
"room_topic": "གལ་ཏེ་འདོད་པ་ཡོད་ན། ཚོགས་པའི་སྐོར་གྱི་འགྲེལ་བཤད་ཐུང་ངུ་ཞིག་འབྲི་ཆོག",
"create": "བཟོས།"
}, },
"menu": { "menu": {
"logout": "ཕྱིར་ཐོན།", "logout": "ཕྱིར་ཐོན།",
@ -70,8 +73,9 @@
"send": "ཐོངས།", "send": "ཐོངས།",
"back": "ཕྱིར་ལོག", "back": "ཕྱིར་ལོག",
"cancel": "ཕྱིར་འཐེན།", "cancel": "ཕྱིར་འཐེན།",
"reply": "ལན་འདེབས། ཡ་ལན།", "reply": "ཡ་ལན།",
"start_private_chat": "སྤྱོད་མཁན་འདི་སྒེར་ལ་ཁ་བརྡ་བྱོས།" "start_private_chat": "སྤྱོད་མཁན་འདི་སྒེར་ལ་ཁ་བརྡ་བྱོས།",
"new_room": "ཁ་བརྡ་ཁང་གསར་པ།"
}, },
"profile": { "profile": {
"change_password": "གསང་ཚིག་རྗེས།", "change_password": "གསང་ཚིག་རྗེས།",
@ -91,16 +95,25 @@
"title": "ཡོ་ཆས་ཁག" "title": "ཡོ་ཆས་ཁག"
}, },
"room_welcome": { "room_welcome": {
"info_permissions": "ཁྱེད་ཀྱིས་ག་དུས་ཡིན་ཡང་ཚོགས་པའི་སྒྲིག་བཀོད་ཀྱི་ནང་ནས་'ནང་འཛུལ་གྱི་ཆོག་མཆན' དང 'ཁ་བརྡའི་ཟིན་ཐོར'འགྱུར་བ་གཏོང་ཆོག", "info_permissions": "ཁྱེད་ཀྱིས་ག་དུས་ཡིན་ཡང་སྒྲིག་བཀོད་ཀྱི་ཁོངས་ནས་ཁ་བརྡ་ཁང་གི་'ནང་འཛུལ་གྱི་ཆོག་མཆན'ལ་འགྱུར་བ་གཏོང་ཆོག",
"join_invite": "ཁྱེད་ཀྱིས་གདན་ཞུ་གནང་བའི་མི་ཁོ་ན་མ་གཏོགས་འཛུལ་མི་ཐུབ།", "join_invite": "ཁྱེད་ཀྱིས་གདན་ཞུ་གནང་བའི་མི་ཁོ་ན་མ་གཏོགས་འཛུལ་མི་ཐུབ།",
"join_public": "སུ་ཡིན་རུང་འབྲེལ་ཐག་འདིའི་ཐོག་ལ་མནན་ཏེ་འཛུལ་ཆོག: {link}", "join_public": "སུ་ཡིན་རུང་འབྲེལ་ཐག་འདིའི་ཐོག་ལ་མནན་ཏེ་འཛུལ་ཆོག: {link}.",
"info": "འདིར་ཁྱེད་ཀྱི་ཚོགས་པའི་སྐོར་ལ་ཤེས་དགོས་པའི་དོན་དག་འགའ་ཡོད།:", "info": "འདིར་ཁྱེད་ཀྱིས་སོ་སོའི་ཚོགས་པའི་སྐོར་ལ་ཤེས་དགོས་པའི་དོན་དག་འགའ་ཡོད།:",
"welcome": "དགའ་བསུ་ཞུ།", "welcome": "དགའ་བསུ་ཞུ།",
"got_it": "ཧ་གོ་སོང་།" "got_it": "ཧ་གོ་སོང་།",
"room_history_joined": "ཚོགས་མི་ཁག་ཁ་བརྡ་ཁང་དུ་ཞུགས་པའི་རྗེས་སུ། ད་གཟོད་དེའི་ནང་དུ་བཏང་ཡོད་པའི་འཕྲིན་ཐུང་ཁག་མཐོང་ཐུབ།",
"room_history_is": "ཁ་བརྡ་ཁང་གི་ཟིན་ཐོ་ནི། {type}.",
"encrypted": "འཕྲིན་ཐུང་ཁག་ལ་སྣེ་གཉིས་བར་གྱི་གསང་སྡོམ་བྱས་ཡོད།"
}, },
"room": { "room": {
"leave": "ཕྱིར་ཐོན།", "leave": "ཕྱིར་ཐོན།",
"members": "ཚོགས་མི་མི་འདུག| ཚོགས་མི༡| ཚོགས་མིའི {count}" "members": "ཚོགས་མི་མི་འདུག| ཚོགས་མི༡| ཚོགས་མིའི {count}",
"room_list_rooms": "ཁ་བརྡ་ཁང་།",
"room_list_invites": "གདན་ཞུ་ཁག",
"purge_failed": "ཁ་བརྡ་ཁང་བཤིག་ཐུབ་མ་སོང་།",
"purge_removing_members": "ཚོགས་མི་ཁག་ཕྱིར་འདོན།",
"purge_redacting_events": "ཁ་བརྡ་གཙང་གསུབ།",
"purge_set_room_state": "ཁ་བརྡ་ཁང་གི་རྣམ་པ་སྒྲིག་འགོད།"
}, },
"message": { "message": {
"users_are_typing": "{count} ཚོགས་མི་ཡིས་གཏགས་བཞིན་འདུག", "users_are_typing": "{count} ཚོགས་མི་ཡིས་གཏགས་བཞིན་འདུག",
@ -136,7 +149,9 @@
"user_created_room": "{user} ཁ་བརྡ་བྱ་སའི་ཁང་པ་བཟོས་སོང་།", "user_created_room": "{user} ཁ་བརྡ་བྱ་སའི་ཁང་པ་བཟོས་སོང་།",
"you": "ཁྱེད་རང་།", "you": "ཁྱེད་རང་།",
"user_powerlevel_change_from_to": "{powerOld} ཡི{user} ནས {powerNew}་ལ།", "user_powerlevel_change_from_to": "{powerOld} ཡི{user} ནས {powerNew}་ལ།",
"room_powerlevel_change": "{user} {changes} ཡི་སྟོབས་ཤུགས་གནས་རིམ་བརྗེས་སོང་།" "room_powerlevel_change": "{user} {changes} ཡི་སྟོབས་ཤུགས་གནས་རིམ་བརྗེས་སོང་།",
"user_changed_guest_access_open": "{user} མགྲོན་པོ་ཁ་བརྡ་ཁང་དུ་འཛུལ་བཅུག་སོང་།",
"user_changed_guest_access_closed": "{user} མགྲོན་པོ་ཁ་བརྡ་ཁང་དུ་འཛུལ་བཅུག་མ་སོང་།"
}, },
"Keanu Weblite": "ཀེ་ཨ་ནུ་དྲ་གནས།", "Keanu Weblite": "ཀེ་ཨ་ནུ་དྲ་གནས།",
"power_level": { "power_level": {
@ -160,8 +175,8 @@
}, },
"purge_room": { "purge_room": {
"button": "ཁ་བརྡ་ཁང་གཏོར།", "button": "ཁ་བརྡ་ཁང་གཏོར།",
"info": "བྱེད་ལས་འདིས་ཚོགས་མི་ཚང་མ་ཡོད་པའི་ཚོགས་པ་འདི་སྒོ་རྒྱག་ངེས། དེ་ཕྱིར་ལྡོག་ཐབས་མེད།", "info": "འདིས་ཚོགས་མི་ཚང་མ་ཡོད་པའི་ཚོགས་པ་འདི་སྒོ་རྒྱག་ངེས། དེ་ཕྱིར་ཟློག་ཐབས་མེད།",
"title": "ཁ་བརྡ་ཁང་གཏོར་རྒྱུ་ཡིན་ནམ།" "title": "ཁ་བརྡ་ཁང་མེད་པར་བཟོ་རྒྱུ་ཡིན་ནམ།"
}, },
"leave": { "leave": {
"leave": "ཕྱིར་ཐོན།", "leave": "ཕྱིར་ཐོན།",
@ -182,5 +197,15 @@
"shared_computer": "མཉམ་སྤྱོད་བྱས་པའི་རྩིས་འཕྲུལ་ཞིག་བཀོལ་བཞིན་པ།", "shared_computer": "མཉམ་སྤྱོད་བྱས་པའི་རྩིས་འཕྲུལ་ཞིག་བཀོལ་བཞིན་པ།",
"user_name_label": "སྤྱོད་མིང་།", "user_name_label": "སྤྱོད་མིང་།",
"title": "{roomName} ནང་དུ་ཕེབས་པར་དགའ་བསུ་ཞུ།" "title": "{roomName} ནང་དུ་ཕེབས་པར་དགའ་བསུ་ཞུ།"
},
"profile_info_popup": {
"powered_by": "ཁ་བརྡ་ཁང་འདི་{product} ནུས་ཤུགས་བསྩལ་ཡོད། {productLink} ནས་དེ་ལས་མང་བ་སྦྱོང་ཆོག་ལ། མདུན་དུ་བསྐྱོད་དེ་ཁ་བརྡ་ཁང་གཞན་ཞིག་བསྐྲུན་ཆོག",
"new_room": "ཁ་བརྡ་ཁང་གསར་པ།",
"want_more": "དེ་ལས་མང་བ་དགོས་སམ།",
"logout": "ཕྱིར་ཐོན།",
"edit_profile": "སྒེར་གྱི་ཡིག་ཆ་བཅོས་སྒྲིག",
"identity_temporary": "{displayName}",
"identity": "{displayName}",
"you_are": "ཁྱེད་ནི་"
} }
} }

View file

@ -1,4 +1,5 @@
{ {
"language_display_name": "English",
"Keanu Weblite": "Keanu Weblite", "Keanu Weblite": "Keanu Weblite",
"menu": { "menu": {
"start_private_chat": "Private chat with this user", "start_private_chat": "Private chat with this user",
@ -12,7 +13,8 @@
"back": "BACK", "back": "BACK",
"login": "Login", "login": "Login",
"logout": "Logout", "logout": "Logout",
"new_room": "New Room" "new_room": "New Room",
"undo": "Undo"
}, },
"message": { "message": {
"you": "You", "you": "You",
@ -112,6 +114,7 @@
"set_password": "Set password", "set_password": "Set password",
"change_name": "Change name", "change_name": "Change name",
"change_password": "Change password", "change_password": "Change password",
"select_language": "Language",
"password_old": "Old password", "password_old": "Old password",
"password_new": "New password", "password_new": "New password",
"password_repeat": "Repeat new password", "password_repeat": "Repeat new password",
@ -135,7 +138,8 @@
"join": "Join room", "join": "Join room",
"join_guest": "Join as guest", "join_guest": "Join as guest",
"status_logging_in": "Logging in...", "status_logging_in": "Logging in...",
"status_joining": "Joining room..." "status_joining": "Joining room...",
"join_failed": "Failed to join room."
}, },
"invite": { "invite": {
"title": "Add Friends", "title": "Add Friends",
@ -156,8 +160,18 @@
}, },
"purge_room": { "purge_room": {
"title": "Delete room?", "title": "Delete room?",
"info": "This will close the room for all members. It cannot be undone.", "info": "All members and messages will be removed. This action cannot be undone.",
"button": "Delete room" "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.",
"close_tab": "Close browser tab",
"view_other_rooms": "View other rooms"
}, },
"room_info": { "room_info": {
"title": "Room Details", "title": "Room Details",

View file

@ -1,4 +1,5 @@
{ {
"language_display_name": "Español",
"room_info": { "room_info": {
"identity": "Has iniciado sesión como {displayName}.", "identity": "Has iniciado sesión como {displayName}.",
"my_profile": "Mi perfil", "my_profile": "Mi perfil",

View file

@ -1,4 +1,5 @@
{ {
"language_is_rtl": true,
"menu": { "menu": {
"ok": "تامام", "ok": "تامام",
"download": "چۈشۈرۈش", "download": "چۈشۈرۈش",

View file

@ -459,6 +459,7 @@ import RoomJoinRules from "./messages/RoomJoinRules.vue";
import RoomPowerLevelsChanged from "./messages/RoomPowerLevelsChanged.vue"; import RoomPowerLevelsChanged from "./messages/RoomPowerLevelsChanged.vue";
import RoomGuestAccessChanged from "./messages/RoomGuestAccessChanged.vue"; import RoomGuestAccessChanged from "./messages/RoomGuestAccessChanged.vue";
import RoomEncrypted from "./messages/RoomEncrypted.vue"; import RoomEncrypted from "./messages/RoomEncrypted.vue";
import RoomDeletionNotice from "./messages/RoomDeletionNotice.vue";
import DebugEvent from "./messages/DebugEvent.vue"; import DebugEvent from "./messages/DebugEvent.vue";
import util from "../plugins/utils"; import util from "../plugins/utils";
import MessageOperations from "./messages/MessageOperations.vue"; import MessageOperations from "./messages/MessageOperations.vue";
@ -539,6 +540,7 @@ export default {
RoomPowerLevelsChanged, RoomPowerLevelsChanged,
RoomGuestAccessChanged, RoomGuestAccessChanged,
RoomEncrypted, RoomEncrypted,
RoomDeletionNotice,
DebugEvent, DebugEvent,
MessageOperations, MessageOperations,
MessageOperationsPicker, MessageOperationsPicker,
@ -1064,6 +1066,23 @@ export default {
case "m.room.encryption": case "m.room.encryption":
return RoomEncrypted; 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; return this.debugging ? DebugEvent : null;
}, },

View file

@ -1,13 +1,24 @@
<template> <template>
<div class="pa-4"> <div class="home">
<RoomList showInvites showCreate :title="$t('room.room_list_rooms')" :invitesTitle="$t('room.room_list_invites')" v-on:newroom="createRoom" /> <YouAre class="mt-4" v-if="!loading" />
<v-btn block depressed class="outlined-button" @click.stop="logout">{{$t('menu.logout')}}</v-btn> <v-card class="members ma-3" flat>
<v-card-title class="h2">{{ $t("room.room_list_rooms") }}</v-card-title>
<v-card-text class="pa-0">
<RoomList
showInvites
showCreate
title=""
:invitesTitle="$t('room.room_list_invites')"
v-on:newroom="createRoom"
/>
</v-card-text>
</v-card>
<!-- Loading indicator --> <!-- Loading indicator -->
<v-container <v-container
fluid fluid
fill-height fill-height
style="position: absolute;background-color:rgba(0,0,0,0.2)" style="position: absolute; background-color: rgba(0, 0, 0, 0.2)"
v-if="loading" v-if="loading"
> >
<v-row align="center" justify="center"> <v-row align="center" justify="center">
@ -23,30 +34,32 @@
</template> </template>
<script> <script>
import RoomList from '../components/RoomList'; import RoomList from "../components/RoomList";
import YouAre from "../components/YouAre.vue";
export default { export default {
components: { components: {
RoomList RoomList,
YouAre,
}, },
computed: { computed: {
loading() { loading() {
return !this.$matrix.ready; return !this.$matrix.ready;
} },
}, },
methods: { methods: {
logout() { logout() {
//TODO - For guest accounts, show warning about not being able to rejoin. //TODO - For guest accounts, show warning about not being able to rejoin.
this.$store.dispatch("logout"); this.$store.dispatch("logout");
this.$nextTick(() => { this.$nextTick(() => {
this.$navigation.push({path: "/login"}, -1); this.$navigation.push({ path: "/login" }, -1);
}) });
}, },
createRoom() { createRoom() {
this.$navigation.push({ name: "CreateRoom" }); this.$navigation.push({ name: "CreateRoom" });
} },
} },
}; };
</script> </script>

View file

@ -399,7 +399,7 @@ export default {
// TODO - handle error // TODO - handle error
console.log("Failed to join room", err); console.log("Failed to join room", err);
this.loading = false; this.loading = false;
this.loadingMessage = err.toString(); this.loadingMessage = this.$t("join.join_failed");
}); });
}, },

View file

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

View file

@ -62,6 +62,11 @@
:icon="'edit'" :icon="'edit'"
:text="$t('profile.change_name')" :text="$t('profile.change_name')"
/> />
<ActionRow
@click="showSelectLanguageDialog = true"
:icon="'language'"
:text="$t('profile.select_language')"
/>
</v-container> </v-container>
<!-- edit password dialog --> <!-- edit password dialog -->
@ -138,10 +143,16 @@
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
<SelectLanguageDialog
v-model="showSelectLanguageDialog"
v-on:close="showSelectLanguageDialog = false"
/>
</div> </div>
</template> </template>
<script> <script>
import SelectLanguageDialog from "./SelectLanguageDialog.vue";
import dataUriToBuffer from "data-uri-to-buffer"; import dataUriToBuffer from "data-uri-to-buffer";
import ActionRow from "./ActionRow.vue"; import ActionRow from "./ActionRow.vue";
import ImageResize from "image-resize"; import ImageResize from "image-resize";
@ -153,11 +164,13 @@ export default {
name: "Profile", name: "Profile",
components: { components: {
ActionRow, ActionRow,
SelectLanguageDialog,
}, },
data() { data() {
return { return {
showEditPasswordDialog: false, showEditPasswordDialog: false,
showEditDisplaynameDialog: false, showEditDisplaynameDialog: false,
showSelectLanguageDialog: false,
editValue: null, editValue: null,
password: null, password: null,
newPassword1: null, newPassword1: null,

View file

@ -1,7 +1,8 @@
<template> <template>
<v-dialog v-model="showDialog" v-show="room" class="ma-0 pa-0" width="80%"> <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> <template>
<v-img contain height="28" src="@/assets/icons/trash_black.svg" />
<h2 class="dialog-title">{{ $t("purge_room.title") }}</h2> <h2 class="dialog-title">{{ $t("purge_room.title") }}</h2>
<div class="dialog-text"> <div class="dialog-text">
{{ $t("purge_room.info") }} {{ $t("purge_room.info") }}
@ -37,6 +38,48 @@
</v-row> </v-row>
</v-container> </v-container>
</div> </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> </v-dialog>
</template> </template>
<script> <script>
@ -55,6 +98,8 @@ export default {
}, },
data() { data() {
return { return {
timeout: -1,
timeoutTimer: null,
showDialog: false, showDialog: false,
isPurging: false, isPurging: false,
status: null, status: null,
@ -74,7 +119,41 @@ export default {
}, },
methods: { 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() { 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.isPurging = true;
this.$matrix this.$matrix
.purgeRoom(this.room.roomId, this.onPurgeStatus) .purgeRoom(this.room.roomId, this.onPurgeStatus)

View file

@ -1,4 +1,5 @@
<template> <template>
<div>
<transition name="slow-fade"> <transition name="slow-fade">
<div <div
v-if="mounted" v-if="mounted"
@ -16,34 +17,114 @@
" "
class="text-center d-flex flex-column" 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="quote white--text">{{ quote }}</div>
<div class="author white--text mt-4">- {{ author }}</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> <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> </div>
</transition> </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> </template>
<script> <script>
import profileInfoMixin from "./profileInfoMixin";
export default { export default {
name: "QuoteView", name: "QuoteView",
mixins: [profileInfoMixin],
props: {
roomWasPurged: {
type: Boolean,
default: function () {
return false;
},
},
},
data() { data() {
return { return {
mounted: false, mounted: false,
quote: "", quote: "",
author: "", author: "",
} };
}, },
mounted() { mounted() {
var quotes; var quotes;
try { try {
quotes = require('@/assets/quotes/' + this.$i18n.locale + '/quotes'); quotes = require("@/assets/quotes/" + this.$i18n.locale + "/quotes");
} catch (error) { } catch (error) {
console.error("No quotes for language"); console.error("No quotes for language");
quotes = undefined; quotes = undefined;
} }
if (!quotes) { if (!quotes) {
quotes = require('@/assets/quotes/en/quotes'); // Default fallback quotes = require("@/assets/quotes/en/quotes"); // Default fallback
} }
const n = quotes.quotes.length; const n = quotes.quotes.length;
const quote = quotes.quotes[Math.floor(Math.random() * n)]; const quote = quotes.quotes[Math.floor(Math.random() * n)];
@ -52,12 +133,24 @@ export default {
this.mounted = true; 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: { methods: {
closeBrowserTab() { closeBrowserTab() {
window.location.href="about:blank"; window.location.href = "about:blank";
} },
} viewOtherRooms() {
this.$navigation.push({ name: "Home" }, -1);
},
},
}; };
</script> </script>
@ -80,5 +173,4 @@ export default {
.slow-fade-enter, .slow-fade-leave-to /* .fade-leave-active below version 2.1.8 */ { .slow-fade-enter, .slow-fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0; opacity: 0;
} }
</style> </style>

View file

@ -0,0 +1,58 @@
<template>
<v-dialog
class="ma-0 pa-0"
width="80%"
v-bind="{ ...$props, ...$attrs }"
v-on="$listeners"
>
<v-card class="dialog-card">
<v-card-title class="dialog-title"
><h3>{{ $t("profile.select_language") }}</h3></v-card-title
>
<v-card-text>
<v-select
v-model="$i18n.locale"
:items="languages"
menu-props="auto"
:label="$t('profile.select_language')"
v-on:change="$store.commit('setLanguage', $i18n.locale)"
hide-details
prepend-icon="language"
single-line
></v-select>
</v-card-text>
<v-card-actions>
<v-btn
color="black"
depressed
block
class="filled-button"
@click="$emit('close')"
>{{ $t("menu.ok") }}</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
data() {
return {
languages: [],
};
},
mounted() {
for (const locale of Object.keys(this.$i18n.messages)) {
this.languages.push({
text: this.$i18n.messages[locale].language_display_name || locale,
value: locale,
});
}
},
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

59
src/components/YouAre.vue Normal file
View file

@ -0,0 +1,59 @@
<template>
<div class="d-flex flex-row-reverse">
<v-chip
@click="viewProfile"
class="ma-2"
:color="dark ? 'black' : '#ededed'"
:text-color="dark ? 'white' : 'black'"
:outlined="!dark"
style="white-space: pre"
>{{ $t("profile_info_popup.you_are") }}&nbsp;
<span v-if="$matrix.currentUser.is_guest">
<i18n path="profile_info_popup.identity_temporary" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</span>
<span v-else>
<i18n path="profile_info_popup.identity" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</span>
<v-avatar color="#e0e0e0" right @click.stop="showProfileInfo = true">
<img v-if="userAvatar" :src="userAvatar" />
<span v-else class="white--text">{{ userAvatarLetter }}</span>
</v-avatar>
</v-chip>
</div>
</template>
<script>
import profileInfoMixin from "./profileInfoMixin";
export default {
name: "YouAre",
mixins: [profileInfoMixin],
props: {
dark: {
type: Boolean,
default: function () {
return false;
},
},
},
data() {
return {};
},
methods: {
viewProfile() {
this.$navigation.push({ name: "Profile" }, 1);
},
},
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

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

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

View file

@ -332,6 +332,17 @@ export default {
} }
} }
break; 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(); this.updateNotificationCount();
}, },
@ -502,7 +513,7 @@ export default {
); );
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.sendStateEvent( this.matrixClient.sendStateEvent(
roomId, roomId,
@ -511,7 +522,7 @@ export default {
"" ""
) )
.then(() => { .then(() => {
console.log("Purge: forbid guest access"); //console.log("Purge: forbid guest access");
return this.matrixClient.sendStateEvent( return this.matrixClient.sendStateEvent(
roomId, roomId,
"m.room.guest_access", "m.room.guest_access",
@ -520,20 +531,20 @@ export default {
); );
}) })
.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 this.matrixClient.sendStateEvent(roomId, "m.room.history_visibility", {
history_visibility: "joined", history_visibility: "joined",
}); });
}) })
.then(() => { .then(() => {
console.log("Purge: create timeline"); //console.log("Purge: create timeline");
return timelineWindow.load(null, 100) return timelineWindow.load(null, 100)
}) })
.then(() => { .then(() => {
const getMoreIfAvailable = function _getMoreIfAvailable() { const getMoreIfAvailable = function _getMoreIfAvailable() {
if (timelineWindow.canPaginate(EventTimeline.BACKWARDS) if (timelineWindow.canPaginate(EventTimeline.BACKWARDS)
) { ) {
console.log("Purge: page back"); //console.log("Purge: page back");
return timelineWindow return timelineWindow
.paginate(EventTimeline.BACKWARDS, 100, true, 5) .paginate(EventTimeline.BACKWARDS, 100, true, 5)
.then((ignoredsuccess) => { .then((ignoredsuccess) => {
@ -546,7 +557,7 @@ export default {
return getMoreIfAvailable(); return getMoreIfAvailable();
}) })
.then(() => { .then(() => {
console.log("Purge: redact events"); //console.log("Purge: redact events");
statusCallback(this.$t('room.purge_redacting_events')); statusCallback(this.$t('room.purge_redacting_events'));
// First ignore unknown device errors // First ignore unknown device errors
this.matrixClient.setGlobalErrorOnUnknownDevices(false); this.matrixClient.setGlobalErrorOnUnknownDevices(false);
@ -560,7 +571,7 @@ export default {
return Promise.all(redactionPromises); return Promise.all(redactionPromises);
}) })
.then(() => { .then(() => {
console.log("Purge: kick members"); //console.log("Purge: kick members");
statusCallback(this.$t('room.purge_removing_members')); statusCallback(this.$t('room.purge_removing_members'));
var joined = room.getMembersWithMembership("join"); var joined = room.getMembersWithMembership("join");
var invited = room.getMembersWithMembership("invite"); var invited = room.getMembersWithMembership("invite");
@ -569,7 +580,7 @@ export default {
var kickPromises = []; var kickPromises = [];
members.forEach(member => { members.forEach(member => {
if (member.userId != self.currentUserId) { 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); return Promise.all(kickPromises);
@ -577,6 +588,9 @@ export default {
.then(() => { .then(() => {
statusCallback(null); statusCallback(null);
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting); this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
return this.leaveRoom(roomId);
})
.then(() => {
resolve(true); // Done! resolve(true); // Done!
}) })
.catch((err) => { .catch((err) => {

View file

@ -37,6 +37,7 @@ const vuexPersistLocalStorage = new VuexPersist({
reducer: state => { reducer: state => {
if (state.useLocalStorage) { if (state.useLocalStorage) {
return { return {
language: state.language,
currentRoomId: state.currentRoomId, currentRoomId: state.currentRoomId,
}; };
} else { } else {
@ -51,6 +52,7 @@ const vuexPersistSessionStorage = new VuexPersist({
reducer: state => { reducer: state => {
if (!state.useLocalStorage) { if (!state.useLocalStorage) {
return { return {
language: state.language,
currentRoomId: state.currentRoomId, currentRoomId: state.currentRoomId,
}; };
} else { } else {
@ -62,7 +64,7 @@ const vuexPersistSessionStorage = new VuexPersist({
const defaultUseSessionStorage = (sessionStorage.getItem('user') != null); const defaultUseSessionStorage = (sessionStorage.getItem('user') != null);
export default new Vuex.Store({ export default new Vuex.Store({
state: { currentRoomId: null, auth: null, tempuser: null, useLocalStorage: !defaultUseSessionStorage }, state: { language: 'en', currentRoomId: null, auth: null, tempuser: null, useLocalStorage: !defaultUseSessionStorage },
mutations: { mutations: {
loginSuccess(state, user) { loginSuccess(state, user) {
state.auth.status.loggedIn = true; state.auth.status.loggedIn = true;
@ -76,6 +78,9 @@ export default new Vuex.Store({
state.auth.status.loggedIn = false; state.auth.status.loggedIn = false;
state.auth.user = null; state.auth.user = null;
}, },
setLanguage(state, locale) {
state.language = locale;
},
setCurrentRoomId(state, roomId) { setCurrentRoomId(state, roomId) {
state.currentRoomId = roomId; state.currentRoomId = roomId;
}, },