Merge branch 'main' of gitlab.com:keanuapp/keanuapp-weblite into main
This commit is contained in:
commit
bee3b37449
22 changed files with 603 additions and 107 deletions
24
src/App.vue
24
src/App.vue
|
|
@ -11,13 +11,11 @@ import config from "./assets/config";
|
|||
|
||||
export default {
|
||||
name: "App",
|
||||
beforeMount() {
|
||||
// Set language
|
||||
this.$i18n.locale = this.$store.state.language || "en";
|
||||
},
|
||||
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 (
|
||||
window.location.protocol == "http" &&
|
||||
!window.location.hostname.endsWith(".onion")
|
||||
|
|
@ -63,6 +61,20 @@ export default {
|
|||
},
|
||||
},
|
||||
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) {
|
||||
document.title = title;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,6 +3,27 @@
|
|||
$admin-bg: black;
|
||||
$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 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
@ -445,6 +466,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;
|
||||
|
|
@ -962,6 +996,10 @@ $admin-fg: white;
|
|||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.avatar-22 {
|
||||
font-size: 14 * $chat-text-size !important;
|
||||
}
|
||||
|
||||
.avatar-32 {
|
||||
font-size: 18 * $chat-text-size !important;
|
||||
}
|
||||
|
|
@ -971,7 +1009,8 @@ $admin-fg: white;
|
|||
}
|
||||
|
||||
.avatar-32.clickable,
|
||||
.avatar-48.clickable {
|
||||
.avatar-48.clickable,
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
|
|
|
|||
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 |
5
src/assets/icons/trash.svg
Normal file
5
src/assets/icons/trash.svg
Normal 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 |
5
src/assets/icons/trash_black.svg
Normal file
5
src/assets/icons/trash_black.svg
Normal 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 |
|
|
@ -6,25 +6,26 @@
|
|||
"video_file": "བརྙན་ཟློས་ཡིག་ཆ།"
|
||||
},
|
||||
"room_info": {
|
||||
"title": "གནས་ཚུལ།",
|
||||
"title": "ཁ་བརྡ་ཁང་གི་ཞིབ་ཕྲའི་གནས་ཚུལ།",
|
||||
"version_info": "གྷར་ཌིན་ལས་འཆར་གྱིས་ནུས་ཤུགས་བསྩལ། ཐོན་རིམ། : {version}",
|
||||
"leave_room_info": "གསལ་བཤད། གོ་རིམ་འདི་ཕྱིར་ཟློག་ཐབས་མེད། ཁྱེད་རང་ཕྱིར་ཐོན་རྒྱུ་ཡིན་མིན་དང་གླེང་མོལ་ཁག་གཏན་དུ་གསུབ་རྒྱུ་ཡིན་མིན་ཁག་ཐེག་བྱོས།",
|
||||
"leave_room": "ཚོགས་པ་ནས་ཕྱིར་ཐོན།",
|
||||
"leave_room": "ཕྱིར་ཐོན།",
|
||||
"view_profile": "ལྟ་ཞིབ།",
|
||||
"identity_temporary": "ཁྱེད་ཀྱི་ངོ་བོ {displayName} འདི་གནས་སྐབས་ཙམ་ཡིན། ཁྱེད་ཀྱིས་སོ་སོའི་མིང་དང་གསང་ཚིག་བརྗེས་ཏེ་འདི་ཉར་ཚགས་བྱེད་ཆོག",
|
||||
"identity": "ཁྱེད་རང་{displayName} མིང་ཐོག་ནས་ནང་འཛུལ་བྱེད་བཞིན་འདུག",
|
||||
"my_profile": "ངའི་ཡིག་ཆ།",
|
||||
"show_all": "ཚང་མ་སྟོན།",
|
||||
"show_all": "ཚང་མ་སྟོན། >",
|
||||
"hide_all": "སྦེད།",
|
||||
"user_you": "{user} (ཁྱེད་རང་།)",
|
||||
"user": "{user}",
|
||||
"members": "ཚོགས་མི་ཁག",
|
||||
"purge": "ཁ་བརྡ་ཁང་གཏོར།",
|
||||
"purge": "ཁ་བརྡ་ཁང་མེད་པར་བཟོས།",
|
||||
"link_copied": "འབྲེལ་ཐག་པར་བཤུས་བརྒྱབ་ཚར།",
|
||||
"join_public": "འབྲེལ་ཐག་ཡོད་པའི་མི་གང་རུང་འཛུལ་ཆོག",
|
||||
"join_invite": "གདན་ཞུ་ཁོ་ན་བརྒྱུད་དེ་མ་གཏོགས་ཁ་བརྡ་ཁང་ནང་དུ་འཛུལ་མི་ཐུབ།",
|
||||
"permissions": "ཆོག་མཆན་ཁག",
|
||||
"created_by": "{user} བཟོས།"
|
||||
"join_public": "འབྲེལ་ཐག་ཡོད་པའི་མི་གང་རུང་།",
|
||||
"join_invite": "ཁ་སྣོན་བྱས་པའི་གྲོགས་ཁོ་ན།",
|
||||
"permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག",
|
||||
"created_by": "{user} བཟོས།",
|
||||
"copy_link": "གདན་ཞུ་འབྲེལ་ཐག་པར་བཤུས་རྒྱོབས།"
|
||||
},
|
||||
"invite": {
|
||||
"done": "ཚར་སོང་།",
|
||||
|
|
@ -57,8 +58,10 @@
|
|||
"join_permissions_info": "ཆོག་མཆན་འདི་དག་གིས་ཚོགས་པའི་ནང་མི་ཇི་ལྟར་འཛུལ་ཐུབ་མིན་དང་། མི་གཞན་དག་ཇི་ལྟར་ལས་སླ་པོའི་ཐོག་ནས་གདན་ཞུ་བྱེད་ཐུབ་མིན་སོགས་ཐག་གཅོད་བྱེད་ཀྱི་ཡོད། ཆོག་མཆན་དེ་དག་ག་དུས་ཡིན་ཡང་འགྱུར་བ་གཏོང་ཆོག",
|
||||
"set_join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་སྒྲིག་འགོད་བྱོས།",
|
||||
"join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག",
|
||||
"new_room": "ཚོགས་པ་གསར་པ།",
|
||||
"name_room": "ཚོགས་པར་མིང་ཐོགས།"
|
||||
"new_room": "ཁ་བརྡ་ཁང་གསར་པ།",
|
||||
"name_room": "ཚོགས་པར་མིང་ཐོགས།",
|
||||
"room_topic": "གལ་ཏེ་འདོད་པ་ཡོད་ན། ཚོགས་པའི་སྐོར་གྱི་འགྲེལ་བཤད་ཐུང་ངུ་ཞིག་འབྲི་ཆོག",
|
||||
"create": "བཟོས།"
|
||||
},
|
||||
"menu": {
|
||||
"logout": "ཕྱིར་ཐོན།",
|
||||
|
|
@ -70,8 +73,9 @@
|
|||
"send": "ཐོངས།",
|
||||
"back": "ཕྱིར་ལོག",
|
||||
"cancel": "ཕྱིར་འཐེན།",
|
||||
"reply": "ལན་འདེབས། ཡ་ལན།",
|
||||
"start_private_chat": "སྤྱོད་མཁན་འདི་སྒེར་ལ་ཁ་བརྡ་བྱོས།"
|
||||
"reply": "ཡ་ལན།",
|
||||
"start_private_chat": "སྤྱོད་མཁན་འདི་སྒེར་ལ་ཁ་བརྡ་བྱོས།",
|
||||
"new_room": "ཁ་བརྡ་ཁང་གསར་པ།"
|
||||
},
|
||||
"profile": {
|
||||
"change_password": "གསང་ཚིག་རྗེས།",
|
||||
|
|
@ -91,16 +95,25 @@
|
|||
"title": "ཡོ་ཆས་ཁག"
|
||||
},
|
||||
"room_welcome": {
|
||||
"info_permissions": "ཁྱེད་ཀྱིས་ག་དུས་ཡིན་ཡང་ཚོགས་པའི་སྒྲིག་བཀོད་ཀྱི་ནང་ནས་'ནང་འཛུལ་གྱི་ཆོག་མཆན' དང 'ཁ་བརྡའི་ཟིན་ཐོར'འགྱུར་བ་གཏོང་ཆོག",
|
||||
"info_permissions": "ཁྱེད་ཀྱིས་ག་དུས་ཡིན་ཡང་སྒྲིག་བཀོད་ཀྱི་ཁོངས་ནས་ཁ་བརྡ་ཁང་གི་'ནང་འཛུལ་གྱི་ཆོག་མཆན'ལ་འགྱུར་བ་གཏོང་ཆོག",
|
||||
"join_invite": "ཁྱེད་ཀྱིས་གདན་ཞུ་གནང་བའི་མི་ཁོ་ན་མ་གཏོགས་འཛུལ་མི་ཐུབ།",
|
||||
"join_public": "སུ་ཡིན་རུང་འབྲེལ་ཐག་འདིའི་ཐོག་ལ་མནན་ཏེ་འཛུལ་ཆོག: {link}",
|
||||
"info": "འདིར་ཁྱེད་ཀྱི་ཚོགས་པའི་སྐོར་ལ་ཤེས་དགོས་པའི་དོན་དག་འགའ་ཡོད།:",
|
||||
"join_public": "སུ་ཡིན་རུང་འབྲེལ་ཐག་འདིའི་ཐོག་ལ་མནན་ཏེ་འཛུལ་ཆོག: {link}.",
|
||||
"info": "འདིར་ཁྱེད་ཀྱིས་སོ་སོའི་ཚོགས་པའི་སྐོར་ལ་ཤེས་དགོས་པའི་དོན་དག་འགའ་ཡོད།:",
|
||||
"welcome": "དགའ་བསུ་ཞུ།",
|
||||
"got_it": "ཧ་གོ་སོང་།"
|
||||
"got_it": "ཧ་གོ་སོང་།",
|
||||
"room_history_joined": "ཚོགས་མི་ཁག་ཁ་བརྡ་ཁང་དུ་ཞུགས་པའི་རྗེས་སུ། ད་གཟོད་དེའི་ནང་དུ་བཏང་ཡོད་པའི་འཕྲིན་ཐུང་ཁག་མཐོང་ཐུབ།",
|
||||
"room_history_is": "ཁ་བརྡ་ཁང་གི་ཟིན་ཐོ་ནི། {type}.",
|
||||
"encrypted": "འཕྲིན་ཐུང་ཁག་ལ་སྣེ་གཉིས་བར་གྱི་གསང་སྡོམ་བྱས་ཡོད།"
|
||||
},
|
||||
"room": {
|
||||
"leave": "ཕྱིར་ཐོན།",
|
||||
"members": "ཚོགས་མི་མི་འདུག| ཚོགས་མི༡| ཚོགས་མིའི {count}"
|
||||
"members": "ཚོགས་མི་མི་འདུག| ཚོགས་མི༡| ཚོགས་མིའི {count}",
|
||||
"room_list_rooms": "ཁ་བརྡ་ཁང་།",
|
||||
"room_list_invites": "གདན་ཞུ་ཁག",
|
||||
"purge_failed": "ཁ་བརྡ་ཁང་བཤིག་ཐུབ་མ་སོང་།",
|
||||
"purge_removing_members": "ཚོགས་མི་ཁག་ཕྱིར་འདོན།",
|
||||
"purge_redacting_events": "ཁ་བརྡ་གཙང་གསུབ།",
|
||||
"purge_set_room_state": "ཁ་བརྡ་ཁང་གི་རྣམ་པ་སྒྲིག་འགོད།"
|
||||
},
|
||||
"message": {
|
||||
"users_are_typing": "{count} ཚོགས་མི་ཡིས་གཏགས་བཞིན་འདུག",
|
||||
|
|
@ -136,7 +149,9 @@
|
|||
"user_created_room": "{user} ཁ་བརྡ་བྱ་སའི་ཁང་པ་བཟོས་སོང་།",
|
||||
"you": "ཁྱེད་རང་།",
|
||||
"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": "ཀེ་ཨ་ནུ་དྲ་གནས།",
|
||||
"power_level": {
|
||||
|
|
@ -160,8 +175,8 @@
|
|||
},
|
||||
"purge_room": {
|
||||
"button": "ཁ་བརྡ་ཁང་གཏོར།",
|
||||
"info": "བྱེད་ལས་འདིས་ཚོགས་མི་ཚང་མ་ཡོད་པའི་ཚོགས་པ་འདི་སྒོ་རྒྱག་ངེས། དེ་ཕྱིར་ལྡོག་ཐབས་མེད།",
|
||||
"title": "ཁ་བརྡ་ཁང་གཏོར་རྒྱུ་ཡིན་ནམ།"
|
||||
"info": "འདིས་ཚོགས་མི་ཚང་མ་ཡོད་པའི་ཚོགས་པ་འདི་སྒོ་རྒྱག་ངེས། དེ་ཕྱིར་ཟློག་ཐབས་མེད།",
|
||||
"title": "ཁ་བརྡ་ཁང་མེད་པར་བཟོ་རྒྱུ་ཡིན་ནམ།"
|
||||
},
|
||||
"leave": {
|
||||
"leave": "ཕྱིར་ཐོན།",
|
||||
|
|
@ -182,5 +197,15 @@
|
|||
"shared_computer": "མཉམ་སྤྱོད་བྱས་པའི་རྩིས་འཕྲུལ་ཞིག་བཀོལ་བཞིན་པ།",
|
||||
"user_name_label": "སྤྱོད་མིང་།",
|
||||
"title": "{roomName} ནང་དུ་ཕེབས་པར་དགའ་བསུ་ཞུ།"
|
||||
},
|
||||
"profile_info_popup": {
|
||||
"powered_by": "ཁ་བརྡ་ཁང་འདི་{product} ནུས་ཤུགས་བསྩལ་ཡོད། {productLink} ནས་དེ་ལས་མང་བ་སྦྱོང་ཆོག་ལ། མདུན་དུ་བསྐྱོད་དེ་ཁ་བརྡ་ཁང་གཞན་ཞིག་བསྐྲུན་ཆོག",
|
||||
"new_room": "ཁ་བརྡ་ཁང་གསར་པ།",
|
||||
"want_more": "དེ་ལས་མང་བ་དགོས་སམ།",
|
||||
"logout": "ཕྱིར་ཐོན།",
|
||||
"edit_profile": "སྒེར་གྱི་ཡིག་ཆ་བཅོས་སྒྲིག",
|
||||
"identity_temporary": "{displayName}",
|
||||
"identity": "{displayName}",
|
||||
"you_are": "ཁྱེད་ནི་"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"language_display_name": "English",
|
||||
"Keanu Weblite": "Keanu Weblite",
|
||||
"menu": {
|
||||
"start_private_chat": "Private chat with this user",
|
||||
|
|
@ -12,7 +13,8 @@
|
|||
"back": "BACK",
|
||||
"login": "Login",
|
||||
"logout": "Logout",
|
||||
"new_room": "New Room"
|
||||
"new_room": "New Room",
|
||||
"undo": "Undo"
|
||||
},
|
||||
"message": {
|
||||
"you": "You",
|
||||
|
|
@ -112,6 +114,7 @@
|
|||
"set_password": "Set password",
|
||||
"change_name": "Change name",
|
||||
"change_password": "Change password",
|
||||
"select_language": "Language",
|
||||
"password_old": "Old password",
|
||||
"password_new": "New password",
|
||||
"password_repeat": "Repeat new password",
|
||||
|
|
@ -135,7 +138,8 @@
|
|||
"join": "Join room",
|
||||
"join_guest": "Join as guest",
|
||||
"status_logging_in": "Logging in...",
|
||||
"status_joining": "Joining room..."
|
||||
"status_joining": "Joining room...",
|
||||
"join_failed": "Failed to join room."
|
||||
},
|
||||
"invite": {
|
||||
"title": "Add Friends",
|
||||
|
|
@ -156,8 +160,18 @@
|
|||
},
|
||||
"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",
|
||||
"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": {
|
||||
"title": "Room Details",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"language_display_name": "Español",
|
||||
"room_info": {
|
||||
"identity": "Has iniciado sesión como {displayName}.",
|
||||
"my_profile": "Mi perfil",
|
||||
|
|
@ -183,4 +184,4 @@
|
|||
"view_details": "Ver detalles",
|
||||
"this_room": "Este grupo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"language_is_rtl": true,
|
||||
"menu": {
|
||||
"ok": "تامام",
|
||||
"download": "چۈشۈرۈش",
|
||||
|
|
@ -6,4 +7,4 @@
|
|||
"edit": "تەھرىر"
|
||||
},
|
||||
"Keanu Weblite": "Keanu Weblite"
|
||||
}
|
||||
}
|
||||
|
|
@ -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,13 +1,24 @@
|
|||
<template>
|
||||
<div class="pa-4">
|
||||
<RoomList showInvites showCreate :title="$t('room.room_list_rooms')" :invitesTitle="$t('room.room_list_invites')" v-on:newroom="createRoom" />
|
||||
<v-btn block depressed class="outlined-button" @click.stop="logout">{{$t('menu.logout')}}</v-btn>
|
||||
<div class="home">
|
||||
<YouAre class="mt-4" v-if="!loading" />
|
||||
<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 -->
|
||||
<v-container
|
||||
fluid
|
||||
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-row align="center" justify="center">
|
||||
|
|
@ -23,30 +34,32 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import RoomList from '../components/RoomList';
|
||||
import RoomList from "../components/RoomList";
|
||||
import YouAre from "../components/YouAre.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
RoomList
|
||||
RoomList,
|
||||
YouAre,
|
||||
},
|
||||
computed: {
|
||||
loading() {
|
||||
return !this.$matrix.ready;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
//TODO - For guest accounts, show warning about not being able to rejoin.
|
||||
this.$store.dispatch("logout");
|
||||
this.$nextTick(() => {
|
||||
this.$navigation.push({path: "/login"}, -1);
|
||||
})
|
||||
this.$navigation.push({ path: "/login" }, -1);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
createRoom() {
|
||||
this.$navigation.push({ name: "CreateRoom" });
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ export default {
|
|||
// TODO - handle error
|
||||
console.log("Failed to join room", err);
|
||||
this.loading = false;
|
||||
this.loadingMessage = err.toString();
|
||||
this.loadingMessage = this.$t("join.join_failed");
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@
|
|||
:icon="'edit'"
|
||||
:text="$t('profile.change_name')"
|
||||
/>
|
||||
<ActionRow
|
||||
@click="showSelectLanguageDialog = true"
|
||||
:icon="'language'"
|
||||
:text="$t('profile.select_language')"
|
||||
/>
|
||||
</v-container>
|
||||
|
||||
<!-- edit password dialog -->
|
||||
|
|
@ -138,10 +143,16 @@
|
|||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<SelectLanguageDialog
|
||||
v-model="showSelectLanguageDialog"
|
||||
v-on:close="showSelectLanguageDialog = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectLanguageDialog from "./SelectLanguageDialog.vue";
|
||||
import dataUriToBuffer from "data-uri-to-buffer";
|
||||
import ActionRow from "./ActionRow.vue";
|
||||
import ImageResize from "image-resize";
|
||||
|
|
@ -153,11 +164,13 @@ export default {
|
|||
name: "Profile",
|
||||
components: {
|
||||
ActionRow,
|
||||
SelectLanguageDialog,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showEditPasswordDialog: false,
|
||||
showEditDisplaynameDialog: false,
|
||||
showSelectLanguageDialog: false,
|
||||
editValue: null,
|
||||
password: null,
|
||||
newPassword1: null,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<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>
|
||||
<div class="dialog-text">
|
||||
{{ $t("purge_room.info") }}
|
||||
|
|
@ -37,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>
|
||||
|
|
@ -55,6 +98,8 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
timeout: -1,
|
||||
timeoutTimer: null,
|
||||
showDialog: false,
|
||||
isPurging: false,
|
||||
status: null,
|
||||
|
|
@ -74,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)
|
||||
|
|
@ -101,4 +180,4 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
58
src/components/SelectLanguageDialog.vue
Normal file
58
src/components/SelectLanguageDialog.vue
Normal 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
59
src/components/YouAre.vue
Normal 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") }}
|
||||
<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>
|
||||
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>
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -332,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();
|
||||
},
|
||||
|
|
@ -502,7 +513,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 +522,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 +531,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 +557,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 +571,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");
|
||||
|
|
@ -569,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);
|
||||
|
|
@ -577,6 +588,9 @@ export default {
|
|||
.then(() => {
|
||||
statusCallback(null);
|
||||
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
|
||||
return this.leaveRoom(roomId);
|
||||
})
|
||||
.then(() => {
|
||||
resolve(true); // Done!
|
||||
})
|
||||
.catch((err) => {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ const vuexPersistLocalStorage = new VuexPersist({
|
|||
reducer: state => {
|
||||
if (state.useLocalStorage) {
|
||||
return {
|
||||
language: state.language,
|
||||
currentRoomId: state.currentRoomId,
|
||||
};
|
||||
} else {
|
||||
|
|
@ -51,6 +52,7 @@ const vuexPersistSessionStorage = new VuexPersist({
|
|||
reducer: state => {
|
||||
if (!state.useLocalStorage) {
|
||||
return {
|
||||
language: state.language,
|
||||
currentRoomId: state.currentRoomId,
|
||||
};
|
||||
} else {
|
||||
|
|
@ -62,7 +64,7 @@ const vuexPersistSessionStorage = new VuexPersist({
|
|||
const defaultUseSessionStorage = (sessionStorage.getItem('user') != null);
|
||||
|
||||
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: {
|
||||
loginSuccess(state, user) {
|
||||
state.auth.status.loggedIn = true;
|
||||
|
|
@ -76,6 +78,9 @@ export default new Vuex.Store({
|
|||
state.auth.status.loggedIn = false;
|
||||
state.auth.user = null;
|
||||
},
|
||||
setLanguage(state, locale) {
|
||||
state.language = locale;
|
||||
},
|
||||
setCurrentRoomId(state, roomId) {
|
||||
state.currentRoomId = roomId;
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue