Merge branch 'main' of gitlab.com:keanuapp/keanuapp-weblite into main
This commit is contained in:
commit
c621777a32
55 changed files with 870 additions and 329 deletions
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -32,6 +32,7 @@
|
||||||
"v-emoji-picker": "^2.3.1",
|
"v-emoji-picker": "^2.3.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-clipboard2": "^0.3.1",
|
"vue-clipboard2": "^0.3.1",
|
||||||
|
"vue-i18n": "^8.24.4",
|
||||||
"vue-resize": "^0.5.0",
|
"vue-resize": "^0.5.0",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vue-sanitize": "^0.2.1",
|
"vue-sanitize": "^0.2.1",
|
||||||
|
|
@ -13991,6 +13992,11 @@
|
||||||
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
|
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-i18n": {
|
||||||
|
"version": "8.24.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.4.tgz",
|
||||||
|
"integrity": "sha512-RZE94WUAGxEiBAANxQ0pptbRwDkNKNSXl3fnJslpFOxVMF6UkUtMDSuYGuW2blDrVgweIXVpethOVkYoNNT9xw=="
|
||||||
|
},
|
||||||
"node_modules/vue-loader": {
|
"node_modules/vue-loader": {
|
||||||
"version": "15.9.6",
|
"version": "15.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
||||||
|
|
@ -26854,6 +26860,11 @@
|
||||||
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
|
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"vue-i18n": {
|
||||||
|
"version": "8.24.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.4.tgz",
|
||||||
|
"integrity": "sha512-RZE94WUAGxEiBAANxQ0pptbRwDkNKNSXl3fnJslpFOxVMF6UkUtMDSuYGuW2blDrVgweIXVpethOVkYoNNT9xw=="
|
||||||
|
},
|
||||||
"vue-loader": {
|
"vue-loader": {
|
||||||
"version": "15.9.6",
|
"version": "15.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "keanuapp-weblite",
|
"name": "keanuapp-weblite",
|
||||||
"version": "0.1.5",
|
"version": "0.1.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
"v-emoji-picker": "^2.3.1",
|
"v-emoji-picker": "^2.3.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-clipboard2": "^0.3.1",
|
"vue-clipboard2": "^0.3.1",
|
||||||
|
"vue-i18n": "^8.24.4",
|
||||||
"vue-resize": "^0.5.0",
|
"vue-resize": "^0.5.0",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vue-sanitize": "^0.2.1",
|
"vue-sanitize": "^0.2.1",
|
||||||
|
|
|
||||||
87
package.json.bak
Normal file
87
package.json.bak
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
"name": "keanuapp-weblite",
|
||||||
|
"version": "0.1.6",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"aes-js": "^3.1.2",
|
||||||
|
"axios": "^0.21.0",
|
||||||
|
"clean-insights-sdk": "^2.4.1",
|
||||||
|
"core-js": "^3.6.5",
|
||||||
|
"data-uri-to-buffer": "^3.0.1",
|
||||||
|
"dayjs": "^1.10.3",
|
||||||
|
"fix-webm-duration": "^1.0.0",
|
||||||
|
"image-resize": "^1.1.5",
|
||||||
|
"image-size": "^1.0.0",
|
||||||
|
"intersection-observer": "^0.11.0",
|
||||||
|
"js-sha256": "^0.9.0",
|
||||||
|
"json-web-key": "^0.4.0",
|
||||||
|
"linkifyjs": "^2.1.9",
|
||||||
|
"material-design-icons-iconfont": "^5.0.1",
|
||||||
|
"matrix-js-sdk": "^9.4.1",
|
||||||
|
"md-gum-polyfill": "^1.0.0",
|
||||||
|
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
|
||||||
|
"pretty-bytes": "^5.6.0",
|
||||||
|
"qrcode": "^1.4.4",
|
||||||
|
"raw-loader": "^4.0.2",
|
||||||
|
"recordrtc": "^5.6.2",
|
||||||
|
"roboto-fontface": "*",
|
||||||
|
"v-emoji-picker": "^2.3.1",
|
||||||
|
"vue": "^2.6.11",
|
||||||
|
"vue-clipboard2": "^0.3.1",
|
||||||
|
"vue-i18n": "^8.24.4",
|
||||||
|
"vue-resize": "^0.5.0",
|
||||||
|
"vue-router": "^3.2.0",
|
||||||
|
"vue-sanitize": "^0.2.1",
|
||||||
|
"vue-swipeable-bottom-sheet": "^0.0.5",
|
||||||
|
"vuetify": "^2.2.11",
|
||||||
|
"vuex": "^3.5.1",
|
||||||
|
"vuex-persist": "^3.1.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||||
|
"@vue/cli-service": "~4.5.0",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"eslint": "^6.7.2",
|
||||||
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
|
"sass": "^1.19.0",
|
||||||
|
"sass-loader": "^8.0.0",
|
||||||
|
"vue-cli-plugin-vuetify": "~2.0.7",
|
||||||
|
"vue-template-compiler": "^2.6.11",
|
||||||
|
"vuetify-loader": "^1.3.0"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"vars": "all",
|
||||||
|
"args": "after-used",
|
||||||
|
"ignoreRestSiblings": false,
|
||||||
|
"argsIgnorePattern": "[iI]gnored"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import config from "./assets/config";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -31,7 +33,7 @@ export default {
|
||||||
return this.$store.state.auth.user;
|
return this.$store.state.auth.user;
|
||||||
},
|
},
|
||||||
title() {
|
title() {
|
||||||
var title = "Keanu Weblite";
|
var title = this.$t(config.appName);
|
||||||
if (this.$matrix.notificationCount > 0) {
|
if (this.$matrix.notificationCount > 0) {
|
||||||
title += " [" + this.$matrix.notificationCount + "]";
|
title += " [" + this.$matrix.notificationCount + "]";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"appName": "Keanu Weblite",
|
||||||
"defaultServer": "https://neo.keanu.im",
|
"defaultServer": "https://neo.keanu.im",
|
||||||
"useShortCodeStickers": false,
|
"useShortCodeStickers": false,
|
||||||
"analytics": {
|
"analytics": {
|
||||||
|
|
|
||||||
185
src/assets/translations/en.js
Normal file
185
src/assets/translations/en.js
Normal file
|
|
@ -0,0 +1,185 @@
|
||||||
|
export default {
|
||||||
|
"Keanu Weblite": "Keanu Weblite",
|
||||||
|
menu: {
|
||||||
|
start_private_chat: "Private chat with this user",
|
||||||
|
reply: "Reply",
|
||||||
|
edit: "Edit",
|
||||||
|
delete: "Delete",
|
||||||
|
download: "Download",
|
||||||
|
ok: "Ok",
|
||||||
|
cancel: "Cancel",
|
||||||
|
send: "Send",
|
||||||
|
back: "BACK",
|
||||||
|
login: "Login",
|
||||||
|
logout: "Logout",
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
you: "You",
|
||||||
|
user_created_room: "{user} created the room",
|
||||||
|
user_aliased_room: "{user} made the room alias {alias}",
|
||||||
|
user_changed_display_name: "{user} changed display name to {displayName}",
|
||||||
|
user_changed_avatar: "{user} changed the avatar",
|
||||||
|
user_changed_room_avatar: "{user} changed the room avatar",
|
||||||
|
user_encrypted_room: "{user} made the room encrypted",
|
||||||
|
user_was_invited: "{user} was invited to the chat...",
|
||||||
|
user_joined: "{user} joined the chat",
|
||||||
|
user_left: "{user} left the chat",
|
||||||
|
user_said: "{user} said:",
|
||||||
|
file_prefix: "File: ",
|
||||||
|
edited: "(edited)",
|
||||||
|
download_progress: "{percentage}% downloaded",
|
||||||
|
upload_progress: "Uploaded {count}",
|
||||||
|
upload_progress_with_total: "Uploaded {count} of {total}",
|
||||||
|
user_changed_room_history: "{user} made room history {type}",
|
||||||
|
room_history_world_readable: "readable by anyone",
|
||||||
|
room_history_shared: "readable to all members in the room",
|
||||||
|
room_history_invited: "readable to members from when they were invited",
|
||||||
|
room_history_joined: "readable to members from when they joined",
|
||||||
|
user_changed_join_rules: "{user} made the room {type}",
|
||||||
|
room_joinrule_invite: "invite only",
|
||||||
|
room_joinrule_public: "public",
|
||||||
|
user_changed_room_name: "{user} changed room name to {name}",
|
||||||
|
user_changed_room_topic: "{user} changed room topic to {topic}",
|
||||||
|
unread_messages: "Unread messages",
|
||||||
|
replying_to_event: "REPLYING TO EVENT: {message}",
|
||||||
|
your_message: "Your message...",
|
||||||
|
scale_image: "Scale image",
|
||||||
|
user_is_typing: "{user} is typing",
|
||||||
|
users_are_typing: "{count} members are typing",
|
||||||
|
room_powerlevel_change: "{user} changed powerlevel of {changes}",
|
||||||
|
user_powerlevel_change_from_to: "{user} from {powerOld} to {powerNew}"
|
||||||
|
},
|
||||||
|
room: {
|
||||||
|
members: "no members | 1 member | {count} members",
|
||||||
|
leave: "Leave"
|
||||||
|
},
|
||||||
|
room_welcome: {
|
||||||
|
welcome: "Welcome!",
|
||||||
|
info: "Here are a few things to know about your group:",
|
||||||
|
join_public: "Anyone can join by opening this link: {link}",
|
||||||
|
join_invite: "Only people you invite can join.",
|
||||||
|
info_permissions: "You can change 'join permissions' and 'message history' at any time in the group settings.",
|
||||||
|
got_it: "Got it",
|
||||||
|
},
|
||||||
|
new_room: {
|
||||||
|
new_room: "New Group",
|
||||||
|
done: "Done",
|
||||||
|
next: "Next",
|
||||||
|
name_room: "Name group",
|
||||||
|
join_permissions: "Join permissions",
|
||||||
|
set_join_permissions: "Set Join Permissions",
|
||||||
|
join_permissions_info: "These permissions determine how people can join the group and how easily others can be invited. They can be changed anytime.",
|
||||||
|
get_link: "Get link",
|
||||||
|
add_people: "Add people",
|
||||||
|
link_copied: "Link copied!",
|
||||||
|
public_info: "Anyone with a link",
|
||||||
|
public_description: "Get a link to share",
|
||||||
|
invite_info: "Only people added",
|
||||||
|
invite_description: "Choose from a list or search by account ID",
|
||||||
|
status_creating: "Creating room",
|
||||||
|
status_avatar_total: "Uploading avatar: {count} of {total}",
|
||||||
|
status_avatar: "Uploading avatar: {count}",
|
||||||
|
},
|
||||||
|
device_list: {
|
||||||
|
title: "DEVICES",
|
||||||
|
blocked: "Blocked",
|
||||||
|
verified: "Verified",
|
||||||
|
not_verified: "Not verified",
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: "Login",
|
||||||
|
username: "Username",
|
||||||
|
password: "Password",
|
||||||
|
username_required: "Username is required",
|
||||||
|
password_required: "Password is required",
|
||||||
|
login: "Login"
|
||||||
|
},
|
||||||
|
profile: {
|
||||||
|
title: "My Profile",
|
||||||
|
temporary_identity: "This identity is temporary. Set a password to use it again",
|
||||||
|
set_password: "Set password",
|
||||||
|
change_name: "Change name",
|
||||||
|
change_password: "Change password",
|
||||||
|
password_old: "Old password",
|
||||||
|
password_new: "New password",
|
||||||
|
password_repeat: "Repeat new password",
|
||||||
|
display_name: "Display name",
|
||||||
|
|
||||||
|
},
|
||||||
|
join: {
|
||||||
|
title: "Welcome to {roomName}",
|
||||||
|
user_name_label: "User name",
|
||||||
|
shared_computer: "Using a shared computer",
|
||||||
|
joining_as: "You are joining as:",
|
||||||
|
join: "Join room",
|
||||||
|
join_guest: "Join as guest",
|
||||||
|
status_logging_in: "Logging in...",
|
||||||
|
status_joining: "Joining room...",
|
||||||
|
},
|
||||||
|
invite: {
|
||||||
|
title: "Add Friends",
|
||||||
|
done: "Done",
|
||||||
|
send_invites_to: "Send invites to",
|
||||||
|
status_inviting: "Inviting friend {index} of {count}",
|
||||||
|
status_error: "Failed to invite one or or more friends!",
|
||||||
|
},
|
||||||
|
leave: {
|
||||||
|
title_public: "Goodbye, {user}",
|
||||||
|
text_public: "You can always join this room again if you know the link.",
|
||||||
|
text_public_lastroom: "If you want to join this group again, you can join under a new identity. To keep {user}, {action}.",
|
||||||
|
title_invite: "Are you sure you want to leave?",
|
||||||
|
text_invite: "This group is locked. You cannot rejoin without a special permission.",
|
||||||
|
create_account: "create an account",
|
||||||
|
go_back: "Go back",
|
||||||
|
leave: "Leave"
|
||||||
|
},
|
||||||
|
purge_room: {
|
||||||
|
title: "Purge room?",
|
||||||
|
info: "This operation will close the room for all members. It cannot be undone.",
|
||||||
|
button: "Purge room"
|
||||||
|
},
|
||||||
|
room_info: {
|
||||||
|
title: "Info",
|
||||||
|
created_by: "Created by {user}",
|
||||||
|
permissions: "Permissions",
|
||||||
|
join_invite: "Room can be joined by invitation only",
|
||||||
|
join_public: "Anyone with the link can join",
|
||||||
|
link_copied: "Link copied!",
|
||||||
|
purge: "Purge room",
|
||||||
|
members: "Members",
|
||||||
|
user: "{user}",
|
||||||
|
user_you: "{user} (you)",
|
||||||
|
hide_all: "Hide",
|
||||||
|
show_all: "Show all",
|
||||||
|
my_profile: "My Profile",
|
||||||
|
identity: "You are logged in as {displayName}.",
|
||||||
|
identity_temporary: "Your identity {displayName} is temporary. You can change your name or set a password to keep it.",
|
||||||
|
view_profile: "View",
|
||||||
|
leave_room: "Leave group",
|
||||||
|
leave_room_info: "Note: This step cannot be undone. Make sure you want to logout and delete the chat forever.",
|
||||||
|
version_info: "Powered by Guardian Project. Version: {version}",
|
||||||
|
},
|
||||||
|
room_info_sheet: {
|
||||||
|
this_room: "This group",
|
||||||
|
view_details: "View details",
|
||||||
|
create_room: "Create group"
|
||||||
|
},
|
||||||
|
voice_recorder: {
|
||||||
|
swipe_to_cancel: "Swipe to cancel",
|
||||||
|
release_to_cancel: "Release to cancel",
|
||||||
|
failed_to_record: "Failed to record audio"
|
||||||
|
},
|
||||||
|
power_level: {
|
||||||
|
admin: "administrator",
|
||||||
|
moderator: "moderator",
|
||||||
|
default: "default",
|
||||||
|
custom: "custom ({level})",
|
||||||
|
restricted: "restricted"
|
||||||
|
},
|
||||||
|
fallbacks: {
|
||||||
|
audio_file: "Audio file",
|
||||||
|
video_file: "Video file",
|
||||||
|
original_text: "<original text>",
|
||||||
|
download_name: "Download",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
<div
|
<div
|
||||||
v-if="event.getId() == readMarker && index < events.length - 1"
|
v-if="event.getId() == readMarker && index < events.length - 1"
|
||||||
class="read-marker"
|
class="read-marker"
|
||||||
title="Unread messages"
|
:title="$t('message.unread_messages')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -135,7 +135,7 @@
|
||||||
|
|
||||||
<v-row class="ma-0 pa-0">
|
<v-row class="ma-0 pa-0">
|
||||||
<div v-if="replyToEvent">
|
<div v-if="replyToEvent">
|
||||||
REPLYING TO EVENT: {{ replyToEvent.getContent().body }}
|
{{$t('message.replying_to_event',{message: replyToEvent.getContent().body}) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CONTACT IS TYPING -->
|
<!-- CONTACT IS TYPING -->
|
||||||
|
|
@ -154,7 +154,7 @@
|
||||||
v-model="currentInput"
|
v-model="currentInput"
|
||||||
no-resize
|
no-resize
|
||||||
class="input-area-text"
|
class="input-area-text"
|
||||||
placeholder="Your message..."
|
:placeholder="$t('message.your_message')"
|
||||||
hide-details
|
hide-details
|
||||||
background-color="white"
|
background-color="white"
|
||||||
v-on:keydown.enter.prevent="
|
v-on:keydown.enter.prevent="
|
||||||
|
|
@ -308,7 +308,7 @@
|
||||||
>
|
>
|
||||||
<v-switch
|
<v-switch
|
||||||
v-if="currentImageInput && currentImageInput.scaled"
|
v-if="currentImageInput && currentImageInput.scaled"
|
||||||
label="Scale image"
|
:label="$('message.scale_image')"
|
||||||
v-model="currentImageInput.useScaled"
|
v-model="currentImageInput.useScaled"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -319,7 +319,7 @@
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn color="primary" text @click="cancelSendAttachment"
|
<v-btn color="primary" text @click="cancelSendAttachment"
|
||||||
>Cancel</v-btn
|
>{{$t('menu.cancel')}}</v-btn
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -327,7 +327,7 @@
|
||||||
@click="sendAttachment"
|
@click="sendAttachment"
|
||||||
v-if="currentSendShowSendButton"
|
v-if="currentSendShowSendButton"
|
||||||
:disabled="currentSendOperation != null"
|
:disabled="currentSendOperation != null"
|
||||||
>Send</v-btn
|
>{{$t('menu.send')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
@ -336,7 +336,6 @@
|
||||||
|
|
||||||
<MessageOperationsBottomSheet
|
<MessageOperationsBottomSheet
|
||||||
ref="messageOperationsSheet"
|
ref="messageOperationsSheet"
|
||||||
xv-show="showEmojiPicker"
|
|
||||||
>
|
>
|
||||||
<MessageOperationsPicker
|
<MessageOperationsPicker
|
||||||
v-on:close="showEmojiPicker = false"
|
v-on:close="showEmojiPicker = false"
|
||||||
|
|
@ -362,23 +361,6 @@
|
||||||
v-on:selectSticker="sendSticker"
|
v-on:selectSticker="sendSticker"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- "NOT ALLOWED FOR GUEST ACCOUNTS" dialog -->
|
|
||||||
<v-dialog v-model="showNotAllowedForGuests" class="ma-0 pa-0" width="50%">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>You are logged in as a guest</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<div>Unfortunately guests are not allowed to upload files.</div>
|
|
||||||
</v-card-text>
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn color="primary" text @click="showNotAllowedForGuests = false"
|
|
||||||
>Ok</v-btn
|
|
||||||
>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
|
|
||||||
<!-- Loading indicator -->
|
<!-- Loading indicator -->
|
||||||
<v-container
|
<v-container
|
||||||
fluid
|
fluid
|
||||||
|
|
@ -419,11 +401,15 @@ import ContactJoin from "./messages/ContactJoin.vue";
|
||||||
import ContactLeave from "./messages/ContactLeave.vue";
|
import ContactLeave from "./messages/ContactLeave.vue";
|
||||||
import ContactInvited from "./messages/ContactInvited.vue";
|
import ContactInvited from "./messages/ContactInvited.vue";
|
||||||
import ContactChanged from "./messages/ContactChanged.vue";
|
import ContactChanged from "./messages/ContactChanged.vue";
|
||||||
|
import RoomCreated from "./messages/RoomCreated.vue";
|
||||||
|
import RoomAliased from "./messages/RoomAliased.vue";
|
||||||
import RoomNameChanged from "./messages/RoomNameChanged.vue";
|
import RoomNameChanged from "./messages/RoomNameChanged.vue";
|
||||||
import RoomTopicChanged from "./messages/RoomTopicChanged.vue";
|
import RoomTopicChanged from "./messages/RoomTopicChanged.vue";
|
||||||
import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue";
|
import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue";
|
||||||
import RoomHistoryVisibility from "./messages/RoomHistoryVisibility.vue";
|
import RoomHistoryVisibility from "./messages/RoomHistoryVisibility.vue";
|
||||||
import RoomJoinRules from "./messages/RoomJoinRules.vue";
|
import RoomJoinRules from "./messages/RoomJoinRules.vue";
|
||||||
|
import RoomPowerLevelsChanged from "./messages/RoomPowerLevelsChanged.vue";
|
||||||
|
import RoomEncrypted from "./messages/RoomEncrypted.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";
|
||||||
|
|
@ -494,11 +480,15 @@ export default {
|
||||||
ContactLeave,
|
ContactLeave,
|
||||||
ContactInvited,
|
ContactInvited,
|
||||||
ContactChanged,
|
ContactChanged,
|
||||||
|
RoomCreated,
|
||||||
|
RoomAliased,
|
||||||
RoomNameChanged,
|
RoomNameChanged,
|
||||||
RoomTopicChanged,
|
RoomTopicChanged,
|
||||||
RoomAvatarChanged,
|
RoomAvatarChanged,
|
||||||
RoomHistoryVisibility,
|
RoomHistoryVisibility,
|
||||||
RoomJoinRules,
|
RoomJoinRules,
|
||||||
|
RoomPowerLevelsChanged,
|
||||||
|
RoomEncrypted,
|
||||||
DebugEvent,
|
DebugEvent,
|
||||||
MessageOperations,
|
MessageOperations,
|
||||||
MessageOperationsPicker,
|
MessageOperationsPicker,
|
||||||
|
|
@ -555,9 +545,6 @@ export default {
|
||||||
*/
|
*/
|
||||||
showScrollToEnd: false,
|
showScrollToEnd: false,
|
||||||
|
|
||||||
/** Shows a dialog with info about an operation being disallowed for guests */
|
|
||||||
showNotAllowedForGuests: false,
|
|
||||||
|
|
||||||
/** A timer for read receipts. */
|
/** A timer for read receipts. */
|
||||||
rrTimer: null,
|
rrTimer: null,
|
||||||
|
|
||||||
|
|
@ -641,9 +628,9 @@ export default {
|
||||||
typingMembersString() {
|
typingMembersString() {
|
||||||
const count = this.typingMembers.length;
|
const count = this.typingMembers.length;
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
return "" + count + " members are typing";
|
return this.$t('message.users_are_typing',{count: count});
|
||||||
} else if (count > 0) {
|
} else if (count > 0) {
|
||||||
return this.typingMembers[0].name + " is typing";
|
return this.$t('message.user_is_typing',{user: this.typingMembers[0].name});
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
@ -776,7 +763,6 @@ export default {
|
||||||
this.timelineWindow
|
this.timelineWindow
|
||||||
.load(initialEventId, 20)
|
.load(initialEventId, 20)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("This is", self);
|
|
||||||
self.events = self.timelineWindow.getEvents();
|
self.events = self.timelineWindow.getEvents();
|
||||||
|
|
||||||
const getMoreIfNeeded = function _getMoreIfNeeded() {
|
const getMoreIfNeeded = function _getMoreIfNeeded() {
|
||||||
|
|
@ -994,6 +980,12 @@ export default {
|
||||||
return MessageOutgoingText;
|
return MessageOutgoingText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "m.room.create":
|
||||||
|
return RoomCreated;
|
||||||
|
|
||||||
|
case "m.room.canonical_alias":
|
||||||
|
return RoomAliased;
|
||||||
|
|
||||||
case "m.room.name":
|
case "m.room.name":
|
||||||
return RoomNameChanged;
|
return RoomNameChanged;
|
||||||
|
|
||||||
|
|
@ -1008,6 +1000,12 @@ export default {
|
||||||
|
|
||||||
case "m.room.join_rules":
|
case "m.room.join_rules":
|
||||||
return RoomJoinRules;
|
return RoomJoinRules;
|
||||||
|
|
||||||
|
case "m.room.power_levels":
|
||||||
|
return RoomPowerLevelsChanged;
|
||||||
|
|
||||||
|
case "m.room.encryption":
|
||||||
|
return RoomEncrypted;
|
||||||
}
|
}
|
||||||
return this.debugging ? DebugEvent : null;
|
return this.debugging ? DebugEvent : null;
|
||||||
},
|
},
|
||||||
|
|
@ -1046,7 +1044,7 @@ export default {
|
||||||
this.restartRRTimer();
|
this.restartRRTimer();
|
||||||
},
|
},
|
||||||
onEvent(event) {
|
onEvent(event) {
|
||||||
console.log("OnEvent", JSON.stringify(event));
|
//console.log("OnEvent", JSON.stringify(event));
|
||||||
if (event.getRoomId() !== this.roomId) {
|
if (event.getRoomId() !== this.roomId) {
|
||||||
return; // Not for this room
|
return; // Not for this room
|
||||||
}
|
}
|
||||||
|
|
@ -1083,7 +1081,7 @@ export default {
|
||||||
this.typingMembers.splice(index, 1);
|
this.typingMembers.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("Typing: ", this.typingMembers);
|
//console.log("Typing: ", this.typingMembers);
|
||||||
},
|
},
|
||||||
|
|
||||||
sendCurrentTextMessage() {
|
sendCurrentTextMessage() {
|
||||||
|
|
@ -1119,12 +1117,6 @@ export default {
|
||||||
* Show attachment picker to select file
|
* Show attachment picker to select file
|
||||||
*/
|
*/
|
||||||
showAttachmentPicker() {
|
showAttachmentPicker() {
|
||||||
// Guests not currently allowed to send attachments (=actually upload them)
|
|
||||||
// See https://matrix.org/docs/spec/client_server/r0.2.0#guest-access
|
|
||||||
// if (this.$matrix.currentUser && this.$matrix.currentUser.is_guest) {
|
|
||||||
// this.showNotAllowedForGuests = true;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
this.$refs.attachment.click();
|
this.$refs.attachment.click();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1202,9 +1194,9 @@ export default {
|
||||||
onUploadProgress(p) {
|
onUploadProgress(p) {
|
||||||
if (p.total) {
|
if (p.total) {
|
||||||
this.currentSendProgress =
|
this.currentSendProgress =
|
||||||
"Uploaded " + (p.loaded || 0) + " of " + p.total;
|
this.$t('message.upload_progress_with_total',{count: (p.loaded || 0), total: p.total});
|
||||||
} else {
|
} else {
|
||||||
this.currentSendProgress = "Uploaded " + (p.loaded || 0);
|
this.currentSendProgress = this.$t('message.upload_progress',{count: (p.loaded || 0)});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1390,7 +1382,7 @@ export default {
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
link.href = url;
|
link.href = url;
|
||||||
link.target = "_blank";
|
link.target = "_blank";
|
||||||
link.download = event.getContent().body || "Download";
|
link.download = event.getContent().body || this.$t('fallbacks.download_name');
|
||||||
link.click();
|
link.click();
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
})
|
})
|
||||||
|
|
@ -1436,10 +1428,6 @@ export default {
|
||||||
|
|
||||||
showContextMenuForEvent(e) {
|
showContextMenuForEvent(e) {
|
||||||
const event = e.event;
|
const event = e.event;
|
||||||
const ref = this.$refs[event.getId()];
|
|
||||||
if (ref) {
|
|
||||||
console.log("Got the ref", ref);
|
|
||||||
}
|
|
||||||
this.selectedEvent = event;
|
this.selectedEvent = event;
|
||||||
this.updateRecentEmojis();
|
this.updateRecentEmojis();
|
||||||
this.showContextMenu = true;
|
this.showContextMenu = true;
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
<v-col class="ma-0 pa-0 flex-shrink-1 flex-nowrap" style="overflow:hidden;cursor:pointer" @click.stop="onHeaderClicked">
|
<v-col class="ma-0 pa-0 flex-shrink-1 flex-nowrap" style="overflow:hidden;cursor:pointer" @click.stop="onHeaderClicked">
|
||||||
<div class="d-flex flex-nowrap room-name-inline">{{ room.summary.info.title }} <!--<v-icon>expand_more</v-icon>--></div>
|
<div class="d-flex flex-nowrap room-name-inline">{{ room.summary.info.title }} <!--<v-icon>expand_more</v-icon>--></div>
|
||||||
<div class="num-members">{{ memberCount }}{{ memberCount > 1 ? " members" : " member" }}</div>
|
<div class="num-members">{{ $tc('room.members', memberCount) }}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="auto" class="text-end ma-0 pa-0">
|
<v-col cols="auto" class="text-end ma-0 pa-0">
|
||||||
<v-btn text class="leave-button" @click.stop="leaveRoom">Leave</v-btn>
|
<v-btn text class="leave-button" @click.stop="leaveRoom">{{$t('room.leave')}}</v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="create-room">
|
<div class="create-room">
|
||||||
<div>
|
<div>
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<div class="room-name">New Group</div>
|
<div class="room-name">{{ $t("new_room.new_room") }}</div>
|
||||||
<v-btn
|
<v-btn
|
||||||
text
|
text
|
||||||
class="header-button-left"
|
class="header-button-left"
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
:disabled="step > steps.NAME_SET"
|
:disabled="step > steps.NAME_SET"
|
||||||
>
|
>
|
||||||
<v-icon>arrow_back</v-icon>
|
<v-icon>arrow_back</v-icon>
|
||||||
<span>BACK</span>
|
<span>{{ $t("menu.back") }}</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
text
|
text
|
||||||
|
|
@ -21,10 +21,58 @@
|
||||||
class="header-button-right"
|
class="header-button-right"
|
||||||
@click.stop="next"
|
@click.stop="next"
|
||||||
>
|
>
|
||||||
<span>{{ step == steps.CREATED ? "Done" : "Next" }}</span>
|
<span>{{
|
||||||
|
step == steps.CREATED ? $t("new_room.done") : $t("new_room.next")
|
||||||
|
}}</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
|
<v-container class="join-user-info">
|
||||||
|
<v-row v-if="canEditProfile">
|
||||||
|
<v-col class="flex-grow-0 flex-shrink-0">
|
||||||
|
<v-avatar @click="showAvatarPickerList">
|
||||||
|
<v-img v-if="selectedProfile" :src="selectedProfile.image" />
|
||||||
|
</v-avatar>
|
||||||
|
</v-col>
|
||||||
|
<v-col class="flex-shrink-1 flex-grow-1">
|
||||||
|
<v-select
|
||||||
|
ref="avatar"
|
||||||
|
:items="availableAvatars"
|
||||||
|
cache-items
|
||||||
|
:label="$t('join.user_name_label')"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
@change="selectAvatar"
|
||||||
|
:value="availableAvatars[0]"
|
||||||
|
single-line
|
||||||
|
>
|
||||||
|
<template v-slot:selection>
|
||||||
|
<v-text-field
|
||||||
|
background-color="transparent"
|
||||||
|
solo
|
||||||
|
flat
|
||||||
|
hide-details
|
||||||
|
@click.native.stop="
|
||||||
|
{
|
||||||
|
}
|
||||||
|
"
|
||||||
|
v-model="selectedProfile.name"
|
||||||
|
></v-text-field>
|
||||||
|
</template>
|
||||||
|
<template v-slot:item="data">
|
||||||
|
<v-avatar size="32">
|
||||||
|
<v-img :src="data.item.image" />
|
||||||
|
</v-avatar>
|
||||||
|
<div class="ml-2">{{ data.item.name }}</div>
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
<v-switch
|
||||||
|
v-model="sharedComputer"
|
||||||
|
:label="$t('join.shared_computer')"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
|
||||||
<v-container fluid style="margin-top: 40px">
|
<v-container fluid style="margin-top: 40px">
|
||||||
<v-row>
|
<v-row>
|
||||||
|
|
@ -37,7 +85,7 @@
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="roomName"
|
v-model="roomName"
|
||||||
label="Name group"
|
:label="$t('new_room.name_room')"
|
||||||
color="black"
|
color="black"
|
||||||
background-color="white"
|
background-color="white"
|
||||||
v-on:keyup.enter="$refs.topic.focus()"
|
v-on:keyup.enter="$refs.topic.focus()"
|
||||||
|
|
@ -49,12 +97,11 @@
|
||||||
|
|
||||||
<v-fade-transition>
|
<v-fade-transition>
|
||||||
<div class="section ma-3" flat v-if="step > steps.INITIAL">
|
<div class="section ma-3" flat v-if="step > steps.INITIAL">
|
||||||
<div class="h4 text-left">Join permissions</div>
|
<div class="h4 text-left">{{ $t("new_room.join_permissions") }}</div>
|
||||||
<div class="h2 text-left">Set Join Permissions</div>
|
<div class="h2 text-left">
|
||||||
<div>
|
{{ $t("new_room.set_join_permissions") }}
|
||||||
These permissions determine how people can join the group and how
|
|
||||||
easily others can be invited. They can be changed anytime.
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>{{ $t("new_room.join_permissions_info") }}</div>
|
||||||
<v-select
|
<v-select
|
||||||
:disabled="step >= steps.CREATING"
|
:disabled="step >= steps.CREATING"
|
||||||
:items="joinRules"
|
:items="joinRules"
|
||||||
|
|
@ -65,7 +112,7 @@
|
||||||
<template v-slot:selection="{ item }">
|
<template v-slot:selection="{ item }">
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:item="{ active, item, attrs, on }">
|
<template v-slot:item="{ item, attrs, on }">
|
||||||
<v-list-item v-on="on" v-bind="attrs" #default="{ active }">
|
<v-list-item v-on="on" v-bind="attrs" #default="{ active }">
|
||||||
<v-list-item-avatar>
|
<v-list-item-avatar>
|
||||||
<v-icon class="grey lighten-1" dark>{{ item.icon }}</v-icon>
|
<v-icon class="grey lighten-1" dark>{{ item.icon }}</v-icon>
|
||||||
|
|
@ -105,7 +152,8 @@
|
||||||
depressed
|
depressed
|
||||||
class="outlined-button"
|
class="outlined-button"
|
||||||
@click.stop="getPublicLink"
|
@click.stop="getPublicLink"
|
||||||
><v-icon class="mr-2">link</v-icon>Get link</v-btn
|
><v-icon class="mr-2">link</v-icon
|
||||||
|
>{{ $t("new_room.get_link") }}</v-btn
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-else-if="joinRule == 'invite'"
|
v-else-if="joinRule == 'invite'"
|
||||||
|
|
@ -113,10 +161,13 @@
|
||||||
depressed
|
depressed
|
||||||
class="outlined-button"
|
class="outlined-button"
|
||||||
@click.stop="addPeople"
|
@click.stop="addPeople"
|
||||||
><v-icon class="mr-2">person_add</v-icon>Add people</v-btn
|
><v-icon class="mr-2">person_add</v-icon
|
||||||
|
>{{ $t("new_room.add_people") }}</v-btn
|
||||||
>
|
>
|
||||||
|
|
||||||
<div v-if="publicRoomLinkCopied" class="link-copied">Link copied!</div>
|
<div v-if="publicRoomLinkCopied" class="link-copied">
|
||||||
|
{{ $t("new_room.link_copied") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="status">{{ status }}</div>
|
<div v-if="status">{{ status }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -158,24 +209,32 @@ export default {
|
||||||
joinRules: [
|
joinRules: [
|
||||||
{
|
{
|
||||||
id: "public",
|
id: "public",
|
||||||
text: "Anyone with a link",
|
text: this.$t("new_room.public_info"),
|
||||||
icon: "link",
|
icon: "link",
|
||||||
descr: "Get a link to share",
|
descr: this.$t("new_room.public_description"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "invite",
|
id: "invite",
|
||||||
text: "Only people added",
|
text: this.$t("new_room.invite_info"),
|
||||||
icon: "person_add",
|
icon: "person_add",
|
||||||
descr: "Choose from a list or search by account ID",
|
descr: this.$t("new_room.invite_description"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
publicRoomLink: null,
|
publicRoomLink: null,
|
||||||
publicRoomLinkCopied: false,
|
publicRoomLinkCopied: false,
|
||||||
|
availableAvatars: [],
|
||||||
|
selectedProfile: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.joinRule = this.joinRules[0].id; // Set default
|
this.joinRule = this.joinRules[0].id; // Set default
|
||||||
|
this.availableAvatars = util.getDefaultAvatars();
|
||||||
|
this.selectAvatar(
|
||||||
|
this.availableAvatars[
|
||||||
|
Math.floor(Math.random() * this.availableAvatars.length)
|
||||||
|
]
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -190,6 +249,16 @@ export default {
|
||||||
}
|
}
|
||||||
return this.roomName.substring(0, 1).toUpperCase();
|
return this.roomName.substring(0, 1).toUpperCase();
|
||||||
},
|
},
|
||||||
|
currentUser() {
|
||||||
|
return this.$store.state.auth.user;
|
||||||
|
},
|
||||||
|
canEditProfile() {
|
||||||
|
// If we have an account already, we can't edit profile here (need to go into profile view)
|
||||||
|
if (this.currentUser) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -264,8 +333,12 @@ export default {
|
||||||
},
|
},
|
||||||
createRoom() {
|
createRoom() {
|
||||||
this.step = steps.CREATING;
|
this.step = steps.CREATING;
|
||||||
|
|
||||||
|
const hasUser = this.currentUser ? true : false;
|
||||||
|
var setProfileData = false;
|
||||||
|
|
||||||
var roomId;
|
var roomId;
|
||||||
this.status = "Creating room";
|
this.status = this.$t("new_room.status_creating");
|
||||||
var createRoomOptions = {};
|
var createRoomOptions = {};
|
||||||
if (this.joinRule == "public") {
|
if (this.joinRule == "public") {
|
||||||
createRoomOptions = {
|
createRoomOptions = {
|
||||||
|
|
@ -311,27 +384,87 @@ export default {
|
||||||
// Add topic
|
// Add topic
|
||||||
createRoomOptions.topic = this.roomTopic;
|
createRoomOptions.topic = this.roomTopic;
|
||||||
}
|
}
|
||||||
return this.$matrix.matrixClient
|
|
||||||
.createRoom(createRoomOptions)
|
return this.$matrix
|
||||||
.then(({ room_id, room_alias }) => {
|
.getLoginPromise()
|
||||||
roomId = room_alias || room_id;
|
.then(
|
||||||
if (!this.roomAvatarFile) {
|
function (user) {
|
||||||
return true;
|
if (user.is_guest && !hasUser) {
|
||||||
}
|
// Newly created account, joining first room.
|
||||||
const self = this;
|
// Set avatar and display name to either the randomly chosen ones, or the
|
||||||
return util.setRoomAvatar(
|
// ones the users has changed to.
|
||||||
this.$matrix.matrixClient,
|
setProfileData = true;
|
||||||
room_id,
|
|
||||||
this.roomAvatarFile,
|
// Set display name and avatar directly on the matrix object.
|
||||||
function (p) {
|
if (
|
||||||
if (p.total) {
|
this.selectedProfile.name &&
|
||||||
self.status =
|
this.selectedProfile.name.length > 0
|
||||||
"Uploading avatar: " + (p.loaded || 0) + " of " + p.total;
|
) {
|
||||||
} else {
|
this.$matrix.userDisplayName = this.selectedProfile.name;
|
||||||
self.status = "Uploading avatar: " + (p.loaded || 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
if (
|
||||||
|
!setProfileData ||
|
||||||
|
!this.selectedProfile.name ||
|
||||||
|
this.selectedProfile.name.length == 0
|
||||||
|
) {
|
||||||
|
return Promise.resolve(user);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
"CreateRoom: Set display name to: " + this.selectedProfile.name
|
||||||
|
);
|
||||||
|
return this.$matrix.matrixClient.setDisplayName(
|
||||||
|
this.selectedProfile.name,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}.bind(this)
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
function () {
|
||||||
|
if (!setProfileData || !this.selectedProfile.image) {
|
||||||
|
console.log("CreateRoom: No avatar change");
|
||||||
|
return Promise.resolve("no avatar");
|
||||||
|
} else {
|
||||||
|
console.log("CreateRoom: Updating avatar");
|
||||||
|
return util.setAvatar(
|
||||||
|
this.$matrix,
|
||||||
|
this.selectedProfile.image,
|
||||||
|
function (progress) {
|
||||||
|
console.log("Progress: " + JSON.stringify(progress));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}.bind(this)
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
return this.$matrix.matrixClient
|
||||||
|
.createRoom(createRoomOptions)
|
||||||
|
.then(({ room_id, room_alias }) => {
|
||||||
|
roomId = room_alias || room_id;
|
||||||
|
if (!this.roomAvatarFile) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const self = this;
|
||||||
|
return util.setRoomAvatar(
|
||||||
|
this.$matrix.matrixClient,
|
||||||
|
room_id,
|
||||||
|
this.roomAvatarFile,
|
||||||
|
function (p) {
|
||||||
|
if (p.total) {
|
||||||
|
self.status = this.$t("new_room.status_avatar_total", {
|
||||||
|
count: p.loaded || 0,
|
||||||
|
total: p.total,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.status = this.$t("new_room.status_avatar", {
|
||||||
|
count: p.loaded || 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.status = "";
|
this.status = "";
|
||||||
|
|
@ -388,6 +521,14 @@ export default {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
selectAvatar(value) {
|
||||||
|
this.selectedProfile = Object.assign({}, value); // Make a copy, so editing does not destroy data
|
||||||
|
},
|
||||||
|
|
||||||
|
showAvatarPickerList() {
|
||||||
|
this.$refs.avatar.$refs.input.click();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="created-room-welcome-header">
|
<div class="created-room-welcome-header">
|
||||||
<div class="h4">Welcome!</div>
|
<div class="h4">{{$t('room_welcome.welcome')}}</div>
|
||||||
<div class="mt-2">Here are a few things to know about your group:</div>
|
<div class="mt-2">{{$t('room_welcome.info')}}</div>
|
||||||
<div class="mt-2" v-if="roomJoinRule == 'public'">Anyone can join by opening this link: {{ publicRoomLink }}</div>
|
<div class="mt-2" v-if="roomJoinRule == 'public'">{{$t('room_welcome.join_public', {link: publicRoomLink}) }}</div>
|
||||||
<div class="mt-2" v-else-if="roomJoinRule == 'invite'">Only people you invite can join.</div>
|
<div class="mt-2" v-else-if="roomJoinRule == 'invite'">{{$t('room_welcome.join_invite')}}</div>
|
||||||
<div class="mt-2">You can change 'join permissions' and 'message history' at any time in the group settings.</div>
|
<div class="mt-2">{{$t('room_welcome.info_permissions')}}</div>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<v-btn text @click.stop="$emit('close')">Got it</v-btn>
|
<v-btn text @click.stop="$emit('close')">{{$t('room_welcome.got_it')}}</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<v-list dense @click.native.stop="nullEvent">
|
<v-list dense @click.native.stop="nullEvent">
|
||||||
<v-subheader>DEVICES</v-subheader>
|
<v-subheader>{{$t('device_list.title')}}</v-subheader>
|
||||||
<v-list-item-group color="primary">
|
<v-list-item-group color="primary">
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-for="device in devices"
|
v-for="device in devices"
|
||||||
|
|
@ -84,11 +84,11 @@ export default {
|
||||||
|
|
||||||
verificationStatus(device) {
|
verificationStatus(device) {
|
||||||
if (device.isBlocked()) {
|
if (device.isBlocked()) {
|
||||||
return "Blocked";
|
return this.$t('device_list.blocked');
|
||||||
} else if (device.isVerified()) {
|
} else if (device.isVerified()) {
|
||||||
return "Verified";
|
return this.$t('device_list.verified');
|
||||||
} else {
|
} else {
|
||||||
return "Not verified";
|
return this.$t('device_list.not_verified');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pa-4">
|
<div class="pa-4">
|
||||||
<RoomList showInvites />
|
<RoomList showInvites />
|
||||||
<v-btn block depressed class="outlined-button" @click.stop="logout">Logout</v-btn>
|
<v-btn block depressed class="outlined-button" @click.stop="logout">{{$t('menu.logout')}}</v-btn>
|
||||||
|
|
||||||
<!-- Loading indicator -->
|
<!-- Loading indicator -->
|
||||||
<v-container
|
<v-container
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="d-flex flex-column pa-4" style="overflow: hidden">
|
<div class="d-flex flex-column pa-4" style="overflow: hidden">
|
||||||
<div class="flex-grow-0 flex-shrink-0">
|
<div class="flex-grow-0 flex-shrink-0">
|
||||||
<div class="room-name">Add Friends</div>
|
<div class="room-name">{{$t('invite.title')}}</div>
|
||||||
<v-btn
|
<v-btn
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
text
|
text
|
||||||
class="header-button-right"
|
class="header-button-right"
|
||||||
@click.stop="done"
|
@click.stop="done"
|
||||||
>
|
>
|
||||||
<span>Done</span>
|
<span>{{$t('invite.done')}}</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
class="flex-grow-0 flex-shrink-0"
|
class="flex-grow-0 flex-shrink-0"
|
||||||
style="min-height: 100px; max-height: 30vh"
|
style="min-height: 100px; max-height: 30vh"
|
||||||
>
|
>
|
||||||
<div class="h4">Send invites to</div>
|
<div class="h4">{{$t('invite.send_invites_to')}}</div>
|
||||||
<div>{{ status }}</div>
|
<div>{{ status }}</div>
|
||||||
<v-chip-group active-class="primary--text" column>
|
<v-chip-group active-class="primary--text" column>
|
||||||
<v-chip
|
<v-chip
|
||||||
|
|
@ -102,14 +102,14 @@ export default {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (this.selectedMembers.length > 0) {
|
if (this.selectedMembers.length > 0) {
|
||||||
// Error.
|
// Error.
|
||||||
this.status = "Failed to invite one or or more friends!";
|
this.status = this.$t('invite.status_error');
|
||||||
} else {
|
} else {
|
||||||
this.status = "";
|
this.status = "";
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.status = `Inviting friend ${index + 1} of ${memberArray.length}`;
|
this.status = this.$t('invite.status_error', {index: index + 1, count: memberArray.length});
|
||||||
const member = memberArray[index];
|
const member = memberArray[index];
|
||||||
|
|
||||||
// Is this userId already a member of this room? In that case don't send an invite.
|
// Is this userId already a member of this room? In that case don't send an invite.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
@click.stop="handleLogin"
|
@click.stop="handleLogin"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
v-if="!currentUser"
|
v-if="!currentUser"
|
||||||
>Login</v-btn
|
>{{$t('menu.login')}}</v-btn
|
||||||
>
|
>
|
||||||
|
|
||||||
<v-avatar class="join-avatar">
|
<v-avatar class="join-avatar">
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
roomName.substring(0, 1).toUpperCase()
|
roomName.substring(0, 1).toUpperCase()
|
||||||
}}</span>
|
}}</span>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
<div class="join-title">Welcome to {{ roomName }}</div>
|
<div class="join-title">{{$t('join.title', {roomName: roomName})}}</div>
|
||||||
<div class="join-message">
|
<div class="join-message">
|
||||||
<!-- Join the group chat in a web browser or with the Keanu app. -->
|
<!-- Join the group chat in a web browser or with the Keanu app. -->
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
ref="avatar"
|
ref="avatar"
|
||||||
:items="availableAvatars"
|
:items="availableAvatars"
|
||||||
cache-items
|
cache-items
|
||||||
label="User name"
|
:label="$t('join.user_name_label')"
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
@change="selectAvatar"
|
@change="selectAvatar"
|
||||||
|
|
@ -60,12 +60,12 @@
|
||||||
<div class="ml-2">{{ data.item.name }}</div>
|
<div class="ml-2">{{ data.item.name }}</div>
|
||||||
</template>
|
</template>
|
||||||
</v-select>
|
</v-select>
|
||||||
<v-switch v-model="sharedComputer" label="Using a shared computer" />
|
<v-switch v-model="sharedComputer" :label="$t('join.shared_computer')" />
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row v-else>
|
<v-row v-else>
|
||||||
<v-col>
|
<v-col>
|
||||||
You are joining as:
|
{{$t('join.joining_as')}}
|
||||||
<div style="display: inline-block">
|
<div style="display: inline-block">
|
||||||
<v-avatar color="#e0e0e0" style="">
|
<v-avatar color="#e0e0e0" style="">
|
||||||
<v-img v-if="userAvatar" :src="userAvatar" />
|
<v-img v-if="userAvatar" :src="userAvatar" />
|
||||||
|
|
@ -97,7 +97,7 @@
|
||||||
@click.stop="handleJoin"
|
@click.stop="handleJoin"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
v-if="!currentUser"
|
v-if="!currentUser"
|
||||||
>Join as guest</v-btn
|
>{{$t('join.join_guest')}}</v-btn
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
class="btn-dark"
|
class="btn-dark"
|
||||||
|
|
@ -106,7 +106,7 @@
|
||||||
@click.stop="handleJoin"
|
@click.stop="handleJoin"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
v-else
|
v-else
|
||||||
>Join room</v-btn
|
>{{$t('join.join')}}</v-btn
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- <div class="join-privacy">
|
<!-- <div class="join-privacy">
|
||||||
|
|
@ -119,9 +119,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import User from "../models/user";
|
|
||||||
import util from "../plugins/utils";
|
import util from "../plugins/utils";
|
||||||
import config from "../assets/config";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Join",
|
name: "Join",
|
||||||
|
|
@ -129,7 +127,6 @@ export default {
|
||||||
return {
|
return {
|
||||||
roomName: null,
|
roomName: null,
|
||||||
roomAvatar: null,
|
roomAvatar: null,
|
||||||
guestUser: new User(config.defaultServer, "", "", true),
|
|
||||||
loading: false,
|
loading: false,
|
||||||
loadingMessage: null,
|
loadingMessage: null,
|
||||||
waitingForInfo: true,
|
waitingForInfo: true,
|
||||||
|
|
@ -226,7 +223,7 @@ export default {
|
||||||
const self = this;
|
const self = this;
|
||||||
this.waitingForMembership = true;
|
this.waitingForMembership = true;
|
||||||
if (this.currentUser) {
|
if (this.currentUser) {
|
||||||
this.getLoginPromise()
|
this.$matrix.getLoginPromise()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
self.$matrix.setCurrentRoomId(self.roomAliasOrId); // Go to this room, now or when joined.
|
self.$matrix.setCurrentRoomId(self.roomAliasOrId); // Go to this room, now or when joined.
|
||||||
const room = self.$matrix.getRoom(self.roomAliasOrId);
|
const room = self.$matrix.getRoom(self.roomAliasOrId);
|
||||||
|
|
@ -263,19 +260,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
|
||||||
* Returns a promise that will log us into the Matrix.
|
|
||||||
*
|
|
||||||
* Will use a real account, if we have one, otherwise will create
|
|
||||||
* a random account.
|
|
||||||
*/
|
|
||||||
getLoginPromise() {
|
|
||||||
if (this.$matrix.ready) {
|
|
||||||
return Promise.resolve(this.$matrix.currentUser);
|
|
||||||
}
|
|
||||||
return this.$store.dispatch("login", this.currentUser || this.guestUser);
|
|
||||||
},
|
|
||||||
|
|
||||||
getRoomInfo() {
|
getRoomInfo() {
|
||||||
if (this.roomId.startsWith("#")) {
|
if (this.roomId.startsWith("#")) {
|
||||||
this.$matrix
|
this.$matrix
|
||||||
|
|
@ -325,10 +309,10 @@ export default {
|
||||||
|
|
||||||
handleJoin() {
|
handleJoin() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.loadingMessage = "Logging in...";
|
this.loadingMessage = this.$t('join.status_logging_in');
|
||||||
const hasUser = this.currentUser ? true : false;
|
const hasUser = this.currentUser ? true : false;
|
||||||
var setProfileData = false;
|
var setProfileData = false;
|
||||||
return this.getLoginPromise()
|
return this.$matrix.getLoginPromise()
|
||||||
.then(
|
.then(
|
||||||
function (user) {
|
function (user) {
|
||||||
if (user.is_guest && !hasUser) {
|
if (user.is_guest && !hasUser) {
|
||||||
|
|
@ -374,7 +358,7 @@ export default {
|
||||||
.then(
|
.then(
|
||||||
function (ignoreduser) {
|
function (ignoreduser) {
|
||||||
console.log("Join: joining room");
|
console.log("Join: joining room");
|
||||||
this.loadingMessage = "Joining room...";
|
this.loadingMessage = this.$t('join.status_joining');
|
||||||
return this.$matrix.matrixClient.joinRoom(this.roomId);
|
return this.$matrix.matrixClient.joinRoom(this.roomId);
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,26 +4,27 @@
|
||||||
<template v-if="roomJoinRule == 'public'">
|
<template v-if="roomJoinRule == 'public'">
|
||||||
<h1>👋</h1>
|
<h1>👋</h1>
|
||||||
<h2 class="dialog-title">
|
<h2 class="dialog-title">
|
||||||
Goodbye, {{ $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"
|
||||||
class="dialog-text"
|
class="dialog-text"
|
||||||
>
|
>
|
||||||
If you want to join this group again, you can join under a new
|
<i18n path="leave.text_public_lastroom" tag="p">
|
||||||
identity. To keep {{ $matrix.currentUserDisplayName }},
|
<template v-slot:user>
|
||||||
<a @click.prevent="viewProfile">create an account</a>.
|
<span>{{ $matrix.currentUserDisplayName }}</span>
|
||||||
</div>
|
</template>
|
||||||
<div v-else class="dialog-text">
|
<template v-slot:action>
|
||||||
You can always join this room again if you know the link.
|
<a @click.prevent="viewProfile">{{ $t('leave.create_account') }}</a>
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
</div>
|
</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">Are you sure you want to leave?</h2>
|
<h2 class="dialog-title">{{$t('leave.title_invite',{user: $matrix.currentUserDisplayName})}}</h2>
|
||||||
<div class="dialog-text">
|
<div class="dialog-text">{{$t('leave.text_invite')}}</div>
|
||||||
This group is locked. You cannot rejoin without a special permission.
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<v-row cols="12">
|
<v-row cols="12">
|
||||||
|
|
@ -34,7 +35,7 @@
|
||||||
block
|
block
|
||||||
class="text-button"
|
class="text-button"
|
||||||
@click="showDialog = false"
|
@click="showDialog = false"
|
||||||
>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">
|
||||||
|
|
@ -44,7 +45,7 @@
|
||||||
block
|
block
|
||||||
class="filled-button"
|
class="filled-button"
|
||||||
@click.stop="onLeaveRoom()"
|
@click.stop="onLeaveRoom()"
|
||||||
>Leave</v-btn
|
>{{$t('leave.leave')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,15 @@
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<div color="rgba(255,255,255,0.1)" class="text-center">
|
<div color="rgba(255,255,255,0.1)" class="text-center">
|
||||||
<div class="h2">Login</div>
|
<div class="h2">{{$t('login.title')}}</div>
|
||||||
<v-form v-model="isValid">
|
<v-form v-model="isValid">
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="user.user_id"
|
v-model="user.user_id"
|
||||||
label="Username"
|
:label="$t('login.username')"
|
||||||
color="black"
|
color="black"
|
||||||
background-color="white"
|
background-color="white"
|
||||||
outlined
|
outlined
|
||||||
:rules="[(v) => !!v || 'Username is required']"
|
:rules="[(v) => !!v || $t('login.username_required')]"
|
||||||
:error="userErrorMessage != null"
|
:error="userErrorMessage != null"
|
||||||
:error-messages="userErrorMessage"
|
:error-messages="userErrorMessage"
|
||||||
required
|
required
|
||||||
|
|
@ -22,12 +22,12 @@
|
||||||
<v-text-field
|
<v-text-field
|
||||||
ref="password"
|
ref="password"
|
||||||
v-model="user.password"
|
v-model="user.password"
|
||||||
label="Password"
|
:label="$t('login.password')"
|
||||||
color="black"
|
color="black"
|
||||||
background-color="white"
|
background-color="white"
|
||||||
outlined
|
outlined
|
||||||
type="password"
|
type="password"
|
||||||
:rules="[(v) => !!v || 'Password is required']"
|
:rules="[(v) => !!v || $t('login.password_required')]"
|
||||||
:error="passErrorMessage != null"
|
:error="passErrorMessage != null"
|
||||||
:error-messages="passErrorMessage"
|
:error-messages="passErrorMessage"
|
||||||
required
|
required
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
block
|
block
|
||||||
@click.stop="handleLogin"
|
@click.stop="handleLogin"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>Login</v-btn
|
>{{$t('login.login')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-form>
|
</v-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div v-if="user" class="profile">
|
<div v-if="user" class="profile">
|
||||||
<div class="chat-header">
|
<div class="chat-header">
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<div class="room-name">My Profile</div>
|
<div class="room-name">{{$t('profile.title')}}</div>
|
||||||
<v-btn
|
<v-btn
|
||||||
text
|
text
|
||||||
class="header-button-right"
|
class="header-button-right"
|
||||||
|
|
@ -29,31 +29,29 @@
|
||||||
<v-col class="flex-shrink-1 flex-grow-1">
|
<v-col class="flex-shrink-1 flex-grow-1">
|
||||||
<div class="h1">{{ displayName }}</div>
|
<div class="h1">{{ displayName }}</div>
|
||||||
<div class="text-center">{{ $matrix.currentUser.user_id }}</div>
|
<div class="text-center">{{ $matrix.currentUser.user_id }}</div>
|
||||||
<div v-if="$matrix.currentUser.is_guest">
|
<div v-if="$matrix.currentUser.is_guest">{{$t('profile.temporary_identity')}}</div>
|
||||||
This identity is temporary. Set a password to use it again.
|
<v-btn depressed block class="outlined-button" @click.stop="logout">{{$t('menu.logout')}}</v-btn>
|
||||||
</div>
|
|
||||||
<v-btn depressed block class="outlined-button" @click.stop="logout">Logout</v-btn>
|
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
<div class="action" @click="showEditPasswordDialog = true"><v-icon>lock</v-icon><span>Set password</span></div>
|
<div class="action" @click="showEditPasswordDialog = true"><v-icon>lock</v-icon><span>{{$t('profile.set_password')}}</span></div>
|
||||||
<div class="action" @click="editValue = displayName;showEditDisplaynameDialog = true"><v-icon>edit</v-icon><span>Change name</span></div>
|
<div class="action" @click="editValue = displayName;showEditDisplaynameDialog = true"><v-icon>edit</v-icon><span>{{$t('profile.change_name')}}</span></div>
|
||||||
|
|
||||||
<!-- edit password dialog -->
|
<!-- edit password dialog -->
|
||||||
<v-dialog v-model="showEditPasswordDialog" class="ma-0 pa-0" width="50%">
|
<v-dialog v-model="showEditPasswordDialog" class="ma-0 pa-0" width="50%">
|
||||||
<v-card :disabled="settingPassword">
|
<v-card :disabled="settingPassword">
|
||||||
<v-card-title>Change password</v-card-title>
|
<v-card-title>{{$t('profile.change_password')}}</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-text-field v-if="!$matrix.currentUser.is_guest" v-model="password" label="Old password" type="password" />
|
<v-text-field v-if="!$matrix.currentUser.is_guest" v-model="password" :label="$t('profile.password_old')" type="password" />
|
||||||
<v-text-field v-model="newPassword1" label="New password" type="password" />
|
<v-text-field v-model="newPassword1" :label="$t('profile.password_new')" type="password" />
|
||||||
<v-text-field v-model="newPassword2" label="Repeat new password" type="password" />
|
<v-text-field v-model="newPassword2" :label="$t('profile.password_repeat')" type="password" />
|
||||||
<div class="red--text" v-if="passwordErrorMessage">{{ passwordErrorMessage }}</div>
|
<div class="red--text" v-if="passwordErrorMessage">{{ passwordErrorMessage }}</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn text @click="closeEditPasswordDialog">Cancel</v-btn>
|
<v-btn text @click="closeEditPasswordDialog">{{$t('menu.cancel')}}</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
:disabled="!passwordsMatch"
|
:disabled="!passwordsMatch"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -61,7 +59,7 @@
|
||||||
@click="
|
@click="
|
||||||
setPassword($matrix.currentUser.is_guest ? $matrix.currentUser.password : password, newPassword1);
|
setPassword($matrix.currentUser.is_guest ? $matrix.currentUser.password : password, newPassword1);
|
||||||
"
|
"
|
||||||
>Ok</v-btn
|
>{{$t('menu.ok')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
@ -70,14 +68,14 @@
|
||||||
<!-- edit display name dialog -->
|
<!-- edit display name dialog -->
|
||||||
<v-dialog v-model="showEditDisplaynameDialog" class="ma-0 pa-0" width="50%">
|
<v-dialog v-model="showEditDisplaynameDialog" class="ma-0 pa-0" width="50%">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>Display name</v-card-title>
|
<v-card-title>{{$t('profile.display_name')}}</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-text-field v-model="editValue" />
|
<v-text-field v-model="editValue" />
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn text @click="showEditDisplaynameDialog = false">Cancel</v-btn>
|
<v-btn text @click="showEditDisplaynameDialog = false">{{$t('menu.cancel')}}</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
color="primary"
|
color="primary"
|
||||||
text
|
text
|
||||||
|
|
@ -85,7 +83,7 @@
|
||||||
setDisplayName(editValue);
|
setDisplayName(editValue);
|
||||||
showEditDisplaynameDialog = false;
|
showEditDisplaynameDialog = false;
|
||||||
"
|
"
|
||||||
>Ok</v-btn
|
>{{$t('menu.ok')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,9 @@
|
||||||
<div class="dialog-content text-center">
|
<div class="dialog-content text-center">
|
||||||
<template>
|
<template>
|
||||||
<v-icon color="black" size="30">lock</v-icon>
|
<v-icon color="black" size="30">lock</v-icon>
|
||||||
<h2 class="dialog-title">Purge room?</h2>
|
<h2 class="dialog-title">{{$t('purge_room.title')}}</h2>
|
||||||
<div class="dialog-text">
|
<div class="dialog-text">
|
||||||
This operation will close the room for all members. It cannot be
|
{{$t('purge_room.info')}}
|
||||||
undone.
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
|
|
@ -18,7 +17,7 @@
|
||||||
block
|
block
|
||||||
class="text-button"
|
class="text-button"
|
||||||
@click="showDialog = false"
|
@click="showDialog = false"
|
||||||
>Cancel</v-btn
|
>{{$t('menu.cancel')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="6" align="center">
|
<v-col cols="6" align="center">
|
||||||
|
|
@ -28,7 +27,7 @@
|
||||||
block
|
block
|
||||||
class="filled-button"
|
class="filled-button"
|
||||||
@click.stop="onPurgeRoom()"
|
@click.stop="onPurgeRoom()"
|
||||||
>Purge room</v-btn
|
>{{$t('purge_room.button')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import quotes from "../assets/quotes";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "QuoteView",
|
name: "QuoteView",
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -37,6 +35,16 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
var quotes;
|
||||||
|
try {
|
||||||
|
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
|
||||||
|
}
|
||||||
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)];
|
||||||
this.quote = quote.quote;
|
this.quote = quote.quote;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div v-if="room" class="room-info">
|
<div v-if="room" class="room-info">
|
||||||
<div class="chat-header">
|
<div class="chat-header">
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<div class="room-name">Info</div>
|
<div class="room-name">{{ $t("room_info.title") }}</div>
|
||||||
<v-btn
|
<v-btn
|
||||||
text
|
text
|
||||||
class="header-button-left"
|
class="header-button-left"
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
@click.stop="$navigation.pop"
|
@click.stop="$navigation.pop"
|
||||||
>
|
>
|
||||||
<v-icon>arrow_back</v-icon>
|
<v-icon>arrow_back</v-icon>
|
||||||
<span>BACK</span>
|
<span>{{ $t("menu.back") }}</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -25,31 +25,30 @@
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
<div class="h1">{{ roomName }}</div>
|
<div class="h1">{{ roomName }}</div>
|
||||||
<div class="h3">{{ roomTopic }}</div>
|
<div class="h3">{{ roomTopic }}</div>
|
||||||
<div class="small">Created by {{ creator }}</div>
|
<div class="small">
|
||||||
|
{{ $t("room_info.created_by", { user: creator }) }}
|
||||||
|
</div>
|
||||||
<v-expand-transition>
|
<v-expand-transition>
|
||||||
<canvas
|
<canvas
|
||||||
v-show="publicRoomLink"
|
v-show="publicRoomLink"
|
||||||
ref="roomQr"
|
ref="roomQr"
|
||||||
class="qr"
|
class="qr"
|
||||||
id="room-qr"
|
id="room-qr"
|
||||||
></canvas>
|
></canvas>
|
||||||
</v-expand-transition>
|
</v-expand-transition>
|
||||||
</div>
|
</div>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-card class="account ma-3" flat>
|
<v-card class="account ma-3" flat>
|
||||||
<v-card-title class="h2">Permissions</v-card-title>
|
<v-card-title class="h2">{{ $t("room_info.permissions") }})</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-radio-group
|
<v-radio-group
|
||||||
v-model="roomJoinRule"
|
v-model="roomJoinRule"
|
||||||
v-if="roomJoinRule"
|
v-if="roomJoinRule"
|
||||||
:disabled="!userCanChangeJoinRule || updatingJoinRule"
|
:disabled="!userCanChangeJoinRule || updatingJoinRule"
|
||||||
>
|
>
|
||||||
<v-radio
|
<v-radio :label="$t('room_info.join_invite')" :value="'invite'" />
|
||||||
label="Room can be joined by invitation only"
|
<v-radio :label="$t('room_info.join_public')" :value="'public'">
|
||||||
:value="'invite'"
|
|
||||||
/>
|
|
||||||
<v-radio label="Anyone with the link can join" :value="'public'">
|
|
||||||
</v-radio>
|
</v-radio>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-if="publicRoomLink"
|
v-if="publicRoomLink"
|
||||||
|
|
@ -60,7 +59,9 @@
|
||||||
type="text"
|
type="text"
|
||||||
@click:append="copyRoomLink"
|
@click:append="copyRoomLink"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
<div v-if="publicRoomLinkCopied" class="link-copied">Link copied!</div>
|
<div v-if="publicRoomLinkCopied" class="link-copied">
|
||||||
|
{{ $t("room_info.link_copied") }}
|
||||||
|
</div>
|
||||||
</v-radio-group>
|
</v-radio-group>
|
||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
|
|
@ -70,7 +71,7 @@
|
||||||
block
|
block
|
||||||
class="filled-button"
|
class="filled-button"
|
||||||
@click.stop="showPurgeConfirmation = true"
|
@click.stop="showPurgeConfirmation = true"
|
||||||
>Purge room</v-btn
|
>{{ $("room_info.purge") }}</v-btn
|
||||||
>
|
>
|
||||||
<!-- <div v-if="anyoneCanJoin">
|
<!-- <div v-if="anyoneCanJoin">
|
||||||
<div>Anyone with a link can join.</div>
|
<div>Anyone with a link can join.</div>
|
||||||
|
|
@ -88,7 +89,7 @@
|
||||||
|
|
||||||
<v-card class="members ma-3" flat>
|
<v-card class="members ma-3" flat>
|
||||||
<v-card-title class="h2"
|
<v-card-title class="h2"
|
||||||
>Members<v-spacer></v-spacer>
|
>{{ $t("room_info.members") }}<v-spacer></v-spacer>
|
||||||
<div>{{ memberCount }}</div></v-card-title
|
<div>{{ memberCount }}</div></v-card-title
|
||||||
>
|
>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
|
|
@ -105,37 +106,52 @@
|
||||||
member.name.substring(0, 1).toUpperCase()
|
member.name.substring(0, 1).toUpperCase()
|
||||||
}}</span>
|
}}</span>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
{{ member.user ? member.user.displayName : member.name
|
{{
|
||||||
}}{{ member.userId == $matrix.currentUserId ? " (you)" : "" }}
|
member.userId == $matrix.currentUserId
|
||||||
|
? $t("room_info.user_you", {
|
||||||
|
user: member.user ? member.user.displayName : member.name,
|
||||||
|
})
|
||||||
|
: $t("room_info.user", {
|
||||||
|
user: member.user ? member.user.displayName : member.name,
|
||||||
|
})
|
||||||
|
}}
|
||||||
<DeviceList
|
<DeviceList
|
||||||
v-if="expandedMembers.includes(member)"
|
v-if="expandedMembers.includes(member)"
|
||||||
:member="member"
|
:member="member"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="show-all" @click="showAllMembers = !showAllMembers">
|
<div class="show-all" @click="showAllMembers = !showAllMembers">
|
||||||
{{ showAllMembers ? "Hide" : "Show all" }}
|
{{
|
||||||
|
showAllMembers ? $t("room_info.hide_all") : $t("room_info.show_all")
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-card class="account ma-3" flat>
|
<v-card class="account ma-3" flat>
|
||||||
<v-card-title class="h2">My Profile</v-card-title>
|
<v-card-title class="h2">{{ $t("room_info.my_profile") }}</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="$matrix.currentUser.is_guest">
|
<div v-if="$matrix.currentUser.is_guest">
|
||||||
Your identity <b>{{ displayName }}</b> is temporary. You can change
|
<i18n path="room_info.identity_temporary" tag="span">
|
||||||
your name or set a password to keep it.
|
<template v-slot:displayName>
|
||||||
|
<b>{{ displayName }}</b>
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
Your are logged in as <b>{{ displayName }}</b
|
<i18n path="room_info.identity" tag="span">
|
||||||
>.
|
<template v-slot:displayName>
|
||||||
|
<b>{{ displayName }}</b>
|
||||||
|
</template>
|
||||||
|
</i18n>
|
||||||
</div>
|
</div>
|
||||||
<v-btn
|
<v-btn
|
||||||
depressed
|
depressed
|
||||||
block
|
block
|
||||||
class="outlined-button"
|
class="outlined-button"
|
||||||
@click.stop="viewProfile"
|
@click.stop="viewProfile"
|
||||||
>View</v-btn
|
>{{$t('room_info.view_profile')}}</v-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
@ -149,18 +165,13 @@
|
||||||
block
|
block
|
||||||
class="filled-button"
|
class="filled-button"
|
||||||
@click.stop="showLeaveConfirmation = true"
|
@click.stop="showLeaveConfirmation = true"
|
||||||
>Leave group</v-btn
|
>{{$t('room_info.leave_room')}}</v-btn
|
||||||
>
|
>
|
||||||
<div>
|
<div>{{$t('room_info.leave_room_info')}}</div>
|
||||||
Note: This step cannot be undone. Make sure you want to logout and
|
|
||||||
delete the chat forever.
|
|
||||||
</div>
|
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<div class="build-version">
|
<div class="build-version">{{$t('room_info.version_info',{version: buildVersion})}}</div>
|
||||||
Powered by Guardian Project. Version: {{ buildVersion }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<LeaveRoomDialog
|
<LeaveRoomDialog
|
||||||
:show="showLeaveConfirmation"
|
:show="showLeaveConfirmation"
|
||||||
|
|
@ -173,7 +184,6 @@
|
||||||
:room="room"
|
:room="room"
|
||||||
@close="showPurgeConfirmation = false"
|
@close="showPurgeConfirmation = false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -340,7 +350,8 @@ export default {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
// Hide again
|
// Hide again
|
||||||
self.publicRoomLinkCopied = false;
|
self.publicRoomLinkCopied = false;
|
||||||
}, 3000); },
|
}, 3000);
|
||||||
|
},
|
||||||
function (e) {
|
function (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@
|
||||||
roomName.substring(0, 1).toUpperCase()
|
roomName.substring(0, 1).toUpperCase()
|
||||||
}}</span>
|
}}</span>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
<div class="h4">This group</div>
|
<div class="h4">{{$t('room_info_sheet.this_room')}}</div>
|
||||||
<div class="h2">{{ roomName }}</div>
|
<div class="h2">{{ roomName }}</div>
|
||||||
<v-btn
|
<v-btn
|
||||||
height="20px"
|
height="20px"
|
||||||
color="black"
|
color="black"
|
||||||
class="filled-button"
|
class="filled-button"
|
||||||
@click.stop="showDetails"
|
@click.stop="showDetails"
|
||||||
>View details</v-btn
|
>{{$t('room_info_sheet.view_details')}}</v-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<room-list :title="'Other groups'" v-on:close="close" />
|
<room-list :title="'Other groups'" v-on:close="close" />
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
color="black"
|
color="black"
|
||||||
class="outlined-button"
|
class="outlined-button"
|
||||||
@click.stop="createRoom"
|
@click.stop="createRoom"
|
||||||
>Create group</v-btn
|
>{{$t('room_info_sheet.create_room')}}</v-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</BottomSheet>
|
</BottomSheet>
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="6" v-if="ptt">
|
<v-col cols="6" v-if="ptt">
|
||||||
<div class="swipe-info"><< Swipe to cancel</div>
|
<div class="swipe-info"><< {{$t('voice_recorder.swipe_to_cancel')}}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
<v-icon color="white">delete_outline</v-icon>
|
<v-icon color="white">delete_outline</v-icon>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="6">
|
<v-col cols="6">
|
||||||
<div class="swipe-info">Release to cancel</div>
|
<div class="swipe-info">{{$t('voice_recorder.release_to_cancel')}}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="3">
|
<v-col cols="3">
|
||||||
<v-btn @click.stop="cancelRecording" text class="swipe-info"
|
<v-btn @click.stop="cancelRecording" text class="swipe-info"
|
||||||
>Cancel</v-btn
|
>{{$t('menu.cancel')}}</v-btn
|
||||||
>
|
>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="3">
|
<v-col cols="3">
|
||||||
|
|
@ -116,7 +116,7 @@
|
||||||
<v-row align="center">
|
<v-row align="center">
|
||||||
<v-col>
|
<v-col>
|
||||||
<div class="swipe-info">
|
<div class="swipe-info">
|
||||||
{{ errorMessage || "Failed to record audio" }}
|
{{ errorMessage || $t('voice_recorder.failed_to_record') }}
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col align="right">
|
<v-col align="right">
|
||||||
|
|
|
||||||
|
|
@ -115,71 +115,3 @@ export default {
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "@/assets/css/chat.scss";
|
@import "@/assets/css/chat.scss";
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function playPauseAudio() {
|
|
||||||
if (player.src) {
|
|
||||||
if (player.paused || player.ended) {
|
|
||||||
// Change the button to a pause button
|
|
||||||
changeButtonType(btnPlayPause, 'pause');
|
|
||||||
player.play();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Change the button to a play button
|
|
||||||
changeButtonType(btnPlayPause, 'play');
|
|
||||||
player.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop the current media from playing, and return it to the start position
|
|
||||||
function stopAudio() {
|
|
||||||
if (player.src) {
|
|
||||||
player.pause();
|
|
||||||
if (player.currentTime) player.currentTime = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggles the media player's mute and unmute status
|
|
||||||
function muteVolume() {
|
|
||||||
if (player.src) {
|
|
||||||
if (player.muted) {
|
|
||||||
// Change the button to a mute button
|
|
||||||
changeButtonType(btnMute, 'mute');
|
|
||||||
player.muted = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Change the button to an unmute button
|
|
||||||
changeButtonType(btnMute, 'unmute');
|
|
||||||
player.muted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replays the media currently loaded in the player
|
|
||||||
function replayAudio() {
|
|
||||||
if (player.src) {
|
|
||||||
resetPlayer();
|
|
||||||
player.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Updates a button's title, innerHTML and CSS class
|
|
||||||
function changeButtonType(btn, value) {
|
|
||||||
btn.title = value;
|
|
||||||
btn.innerHTML = value;
|
|
||||||
btn.className = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetPlayer() {
|
|
||||||
progressBar.value = 0;
|
|
||||||
//clear the current song
|
|
||||||
player.src = '';
|
|
||||||
// Move the media back to the start
|
|
||||||
player.currentTime = 0;
|
|
||||||
// Set the play/pause button to 'play'
|
|
||||||
changeButtonType(btnPlayPause, 'play');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<v-btn v-if="incoming" text @click.stop="startPrivateChat" class="ma-0 pa-0"
|
<v-btn v-if="incoming" text @click.stop="startPrivateChat" class="ma-0 pa-0"
|
||||||
>Private chat with this user</v-btn
|
>{{ $t("menu.start_private_chat") }}</v-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
<!-- Contact joined the chat -->
|
<!-- Contact joined the chat -->
|
||||||
<div class="messageJoin">
|
<div class="messageJoin">
|
||||||
<div v-if="displayNameChange">
|
<div v-if="displayNameChange">
|
||||||
{{ changer }} changed display name to {{ event.getContent().displayname }}
|
{{ $t('message.user_changed_display_name', { user: changer, displayName: event.getContent().displayname})}}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="avatarChange">
|
<div v-if="avatarChange">
|
||||||
{{ changer }} changed the avatar
|
{{ $t('message.user_changed_avatar', { user: changer})}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -28,7 +28,7 @@ export default {
|
||||||
},
|
},
|
||||||
changer() {
|
changer() {
|
||||||
if (this.event.getSender() == this.$matrix.currentUserId) {
|
if (this.event.getSender() == this.$matrix.currentUserId) {
|
||||||
return "You";
|
return this.$t("message.you");
|
||||||
}
|
}
|
||||||
if (this.displayNameChange) {
|
if (this.displayNameChange) {
|
||||||
return this.event.getPrevContent().displayname;
|
return this.event.getPrevContent().displayname;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- Contact invited to the chat -->
|
<!-- Contact invited to the chat -->
|
||||||
<div class="messageJoin">
|
<div class="messageJoin">
|
||||||
{{ event.getContent().displayname || stateEventDisplayName(event) }} was invited to the chat...
|
{{ $t('message.user_was_invited', {user: event.getContent().displayname || stateEventDisplayName(event)}) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- Contact joined the chat -->
|
<!-- Contact joined the chat -->
|
||||||
<div class="messageJoin">
|
<div class="messageJoin">
|
||||||
{{ stateEventDisplayName(event) }} joined the chat
|
{{ $t('message.user_joined',{user: stateEventDisplayName(event)}) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- Contact left the chat -->
|
<!-- Contact left the chat -->
|
||||||
<div class="messageJoin">
|
<div class="messageJoin">
|
||||||
{{ stateEventDisplayName(event) }} left the chat
|
{{ $t('message.user_left',{user: stateEventDisplayName(event)}) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<message-incoming v-bind="{...$props, ...$attrs}" v-on="$listeners">
|
<message-incoming v-bind="{...$props, ...$attrs}" v-on="$listeners">
|
||||||
<div class="bubble audio-bubble">
|
<div class="bubble audio-bubble">
|
||||||
<audio-player :src="src">Audio file</audio-player>
|
<audio-player :src="src">{{ $t('fallbacks.audio_file')}}</audio-player>
|
||||||
</div>
|
</div>
|
||||||
</message-incoming>
|
</message-incoming>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bubble">
|
<div class="bubble">
|
||||||
<div class="original-message" v-if="inReplyToText">
|
<div class="original-message" v-if="inReplyToText">
|
||||||
<div class="original-message-sender">
|
<div class="original-message-sender">
|
||||||
{{ inReplyToSender || "Someone" }} said:
|
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="original-message-text"
|
class="original-message-text"
|
||||||
|
|
@ -11,14 +11,14 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<span>File: </span>
|
<span>{{ $t('file_prefix') }}</span>
|
||||||
<span
|
<span
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
@click.stop="$emit('download')"
|
@click.stop="$emit('download')"
|
||||||
v-html="linkify($sanitize(messageText))"
|
v-html="linkify($sanitize(messageText))"
|
||||||
/>
|
/>
|
||||||
<span class="edit-marker" v-if="event.replacingEventId()"
|
<span class="edit-marker" v-if="event.replacingEventId()"
|
||||||
>(edited)</span
|
>{{ $t('edited') }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bubble">
|
<div class="bubble">
|
||||||
<div class="original-message" v-if="inReplyToText">
|
<div class="original-message" v-if="inReplyToText">
|
||||||
<div class="original-message-sender">
|
<div class="original-message-sender">
|
||||||
{{ inReplyToSender || "Someone" }} said:
|
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="original-message-text"
|
class="original-message-text"
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<span v-html="linkify($sanitize(messageText))" />
|
<span v-html="linkify($sanitize(messageText))" />
|
||||||
<span class="edit-marker" v-if="event.replacingEventId()"
|
<span class="edit-marker" v-if="event.replacingEventId()"
|
||||||
>(edited)</span
|
>{{ $t('edited') }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div>{{ JSON.stringify(event) }}</div> -->
|
<!-- <div>{{ JSON.stringify(event) }}</div> -->
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
<div class="bubble image-bubble">
|
<div class="bubble image-bubble">
|
||||||
<v-responsive :aspect-ratio="16 / 9" :src="src">
|
<v-responsive :aspect-ratio="16 / 9" :src="src">
|
||||||
<video :src="src" controls style="width: 100%; height: 100%">
|
<video :src="src" controls style="width: 100%; height: 100%">
|
||||||
Video file
|
{{$t('fallbacks.video_file')}}
|
||||||
</video>
|
</video>
|
||||||
<div v-if="downloadProgress" class="download-overlay">
|
<div v-if="downloadProgress" class="download-overlay">
|
||||||
<div class="text-center download-text">
|
<div class="text-center download-text">
|
||||||
{{ downloadProgress }}% downloaded
|
{{ $t('message.download_progress',{percentage: downloadProgress}) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-responsive>
|
</v-responsive>
|
||||||
|
|
|
||||||
|
|
@ -12,25 +12,25 @@
|
||||||
<v-btn icon @click.stop="addReply" class="ma-0 pa-0">
|
<v-btn icon @click.stop="addReply" class="ma-0 pa-0">
|
||||||
<v-icon>reply</v-icon>
|
<v-icon>reply</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<div>Reply</div>
|
<div>{{$t('menu.reply')}}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col v-if="isEditable">
|
<v-col v-if="isEditable">
|
||||||
<v-btn icon @click.stop="edit" class="ma-0 pa-0">
|
<v-btn icon @click.stop="edit" class="ma-0 pa-0">
|
||||||
<v-icon>edit</v-icon>
|
<v-icon>edit</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<div>Edit</div>
|
<div>{{$t('menu.edit')}}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col v-if="isRedactable">
|
<v-col v-if="isRedactable">
|
||||||
<v-btn icon @click.stop="redact" class="ma-0 pa-0">
|
<v-btn icon @click.stop="redact" class="ma-0 pa-0">
|
||||||
<v-icon>delete</v-icon>
|
<v-icon>delete</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<div>Delete</div>
|
<div>{{$t('menu.delete')}}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col v-if="isDownloadable">
|
<v-col v-if="isDownloadable">
|
||||||
<v-btn icon @click.stop="download" class="ma-0 pa-0">
|
<v-btn icon @click.stop="download" class="ma-0 pa-0">
|
||||||
<v-icon>get_app</v-icon>
|
<v-icon>get_app</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<div>Download</div>
|
<div>{{$t('menu.download')}}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<img v-if="userAvatar" :src="userAvatar" />
|
<img v-if="userAvatar" :src="userAvatar" />
|
||||||
<span v-else class="white--text headline">{{ userAvatarLetter }}</span>
|
<span v-else class="white--text headline">{{ userAvatarLetter }}</span>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
<!-- <div class="sender">{{ "You" }}</div> -->
|
<!-- <div class="sender">{{ $t('message.you') }}</div> -->
|
||||||
<div class="senderAndTime">
|
<div class="senderAndTime">
|
||||||
<div class="time">
|
<div class="time">
|
||||||
{{ formatTime(event.event.origin_server_ts) }}
|
{{ formatTime(event.event.origin_server_ts) }}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||||
<div class="audio-bubble">
|
<div class="audio-bubble">
|
||||||
<audio-player :src="src">Audio file</audio-player>
|
<audio-player :src="src">{{ $t('fallbacks.audio_file')}}</audio-player>
|
||||||
</div>
|
</div>
|
||||||
</message-outgoing>
|
</message-outgoing>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bubble">
|
<div class="bubble">
|
||||||
<div class="original-message" v-if="inReplyToText">
|
<div class="original-message" v-if="inReplyToText">
|
||||||
<div class="original-message-sender">
|
<div class="original-message-sender">
|
||||||
{{ inReplyToSender || "Someone" }} said:
|
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="original-message-text"
|
class="original-message-text"
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
v-html="linkify($sanitize(messageText))"
|
v-html="linkify($sanitize(messageText))"
|
||||||
/>
|
/>
|
||||||
<span class="edit-marker" v-if="event.replacingEventId()"
|
<span class="edit-marker" v-if="event.replacingEventId()"
|
||||||
>(edited)</span
|
>{{ $t('edited') }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bubble">
|
<div class="bubble">
|
||||||
<div class="original-message" v-if="inReplyToText">
|
<div class="original-message" v-if="inReplyToText">
|
||||||
<div class="original-message-sender">
|
<div class="original-message-sender">
|
||||||
{{ inReplyToSender || "Someone" }} said:
|
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="original-message-text"
|
class="original-message-text"
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<span v-html="linkify($sanitize(messageText))" />
|
<span v-html="linkify($sanitize(messageText))" />
|
||||||
<span class="edit-marker" v-if="event.replacingEventId()"
|
<span class="edit-marker" v-if="event.replacingEventId()"
|
||||||
>(edited)</span
|
>{{ $t('edited') }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bubble image-bubble">
|
<div class="bubble image-bubble">
|
||||||
<v-responsive :aspect-ratio="16 / 9" class="ma-0 pa-0">
|
<v-responsive :aspect-ratio="16 / 9" class="ma-0 pa-0">
|
||||||
<video :src="src" controls style="width: 100%; height: 100%">
|
<video :src="src" controls style="width: 100%; height: 100%">
|
||||||
Video file
|
{{$t('fallbacks.video_file')}}
|
||||||
</video>
|
</video>
|
||||||
</v-responsive>
|
</v-responsive>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
17
src/components/messages/RoomAliased.vue
Normal file
17
src/components/messages/RoomAliased.vue
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<template>
|
||||||
|
<div class="statusEvent">
|
||||||
|
{{ $t('message.user_aliased_room', {user: stateEventDisplayName(event), alias: event.getContent().alias}) }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import messageMixin from "./messageMixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [messageMixin],
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "@/assets/css/chat.scss";
|
||||||
|
</style>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- ROOM AVATAR CHANGED -->
|
<!-- ROOM AVATAR CHANGED -->
|
||||||
<div class="statusEvent">
|
<div class="statusEvent">
|
||||||
{{ stateEventDisplayName(event) }} changed the room avatar
|
{{ $t('message.user_changed_room_avatar',{user: stateEventDisplayName(event)}) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
17
src/components/messages/RoomCreated.vue
Normal file
17
src/components/messages/RoomCreated.vue
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<template>
|
||||||
|
<div class="statusEvent">
|
||||||
|
{{ $t('message.user_created_room', {user: stateEventDisplayName(event)}) }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import messageMixin from "./messageMixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [messageMixin],
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "@/assets/css/chat.scss";
|
||||||
|
</style>
|
||||||
17
src/components/messages/RoomEncrypted.vue
Normal file
17
src/components/messages/RoomEncrypted.vue
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<template>
|
||||||
|
<div class="statusEvent">
|
||||||
|
{{ $t('message.user_encrypted_room', {user: stateEventDisplayName(event)}) }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import messageMixin from "./messageMixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [messageMixin],
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "@/assets/css/chat.scss";
|
||||||
|
</style>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- ROOM AVATAR CHANGED -->
|
<!-- ROOM AVATAR CHANGED -->
|
||||||
<div class="statusEvent">
|
<div class="statusEvent">
|
||||||
{{ stateEventDisplayName(event) }} made room history {{ history(event) }}
|
{{ $t('message.user_changed_room_history',{user: stateEventDisplayName(event), type: history(event)}) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -15,13 +15,13 @@ export default {
|
||||||
const visibility = event.getContent().history_visibility;
|
const visibility = event.getContent().history_visibility;
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case "world_readable":
|
case "world_readable":
|
||||||
return "readable by anyone";
|
return this.$t('message.room_history_world_readable');
|
||||||
case "shared":
|
case "shared":
|
||||||
return "readable to all members in the room";
|
return this.$t('message.room_history_shared');
|
||||||
case "invited":
|
case "invited":
|
||||||
return "readable to members from when they were invited";
|
return this.$t('message.room_history_invited');
|
||||||
case "joined":
|
case "joined":
|
||||||
return "readable to members from when they joined";
|
return this.$t('message.room_history_joined');
|
||||||
}
|
}
|
||||||
return visibility;
|
return visibility;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- ROOM JOIN RULES CHANGED -->
|
<!-- ROOM JOIN RULES CHANGED -->
|
||||||
<div class="statusEvent">
|
<div class="statusEvent">
|
||||||
{{ stateEventDisplayName(event) }} made the room {{ joinRule(event) }}
|
{{ $t('message.user_changed_join_rules', { user: stateEventDisplayName(event), type: joinRule(event)}) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -15,9 +15,9 @@ export default {
|
||||||
const joinRule = event.getContent().join_rule;
|
const joinRule = event.getContent().join_rule;
|
||||||
switch (joinRule) {
|
switch (joinRule) {
|
||||||
case "invite":
|
case "invite":
|
||||||
return "invite only";
|
return this.$t('message.room_joinrule_invite');
|
||||||
case "public":
|
case "public":
|
||||||
return "public";
|
return this.$t('message.room_joinrule_public');
|
||||||
}
|
}
|
||||||
return joinRule;
|
return joinRule;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- ROOM NAME CHANGED -->
|
<!-- ROOM NAME CHANGED -->
|
||||||
<div class="statusEvent">
|
<div class="statusEvent">
|
||||||
{{ stateEventDisplayName(event) }} changed room name to
|
{{ $t('message.user_changed_room_name', {user: stateEventDisplayName(event), name: event.getContent().name}) }}
|
||||||
{{ event.getContent().name }}
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
86
src/components/messages/RoomPowerLevelsChanged.vue
Normal file
86
src/components/messages/RoomPowerLevelsChanged.vue
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<div class="messageJoin">
|
||||||
|
<div>
|
||||||
|
{{ allChanges }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import messageMixin from "./messageMixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [messageMixin],
|
||||||
|
computed: {
|
||||||
|
allChanges() {
|
||||||
|
const content = this.event.getContent();
|
||||||
|
const prevContent = this.event.getPrevContent();
|
||||||
|
if (!prevContent || !prevContent.users || !content || !content.users) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const userDefault = this.event.getContent().users_default || 0;
|
||||||
|
|
||||||
|
// Construct set of userIds
|
||||||
|
const users = [];
|
||||||
|
Object.keys(content.users).forEach((userId) => {
|
||||||
|
if (users.indexOf(userId) === -1) users.push(userId);
|
||||||
|
});
|
||||||
|
Object.keys(prevContent.users).forEach((userId) => {
|
||||||
|
if (users.indexOf(userId) === -1) users.push(userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
const diff = [];
|
||||||
|
users.forEach((userId) => {
|
||||||
|
// Previous power level
|
||||||
|
const from = prevContent.users[userId];
|
||||||
|
// Current power level
|
||||||
|
const to = content.users[userId];
|
||||||
|
if (to !== from) {
|
||||||
|
diff.push(
|
||||||
|
this.$t("message.user_powerlevel_change_from_to", {
|
||||||
|
user: userId,
|
||||||
|
powerOld: this.powerLevelString(from, userDefault),
|
||||||
|
powerNew: this.powerLevelString(to, userDefault),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!diff.length) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return this.$t("message.room_powerlevel_change", {
|
||||||
|
user: this.changer,
|
||||||
|
changes: diff.join(", "),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changer() {
|
||||||
|
if (this.event.getSender() == this.$matrix.currentUserId) {
|
||||||
|
return this.$t("message.you");
|
||||||
|
}
|
||||||
|
return this.event.sender
|
||||||
|
? this.event.sender.name
|
||||||
|
: this.event.getSender();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
powerLevelString(level, defaultUserLevel) {
|
||||||
|
const map = {
|
||||||
|
undefined: this.$t("power_level.default"),
|
||||||
|
0: this.$t("power_level.restricted"),
|
||||||
|
[defaultUserLevel]: this.$t("power_level.default"),
|
||||||
|
50: this.$t("power_level.moderator"),
|
||||||
|
100: this.$t("power_level.admin"),
|
||||||
|
};
|
||||||
|
if (map[level]) {
|
||||||
|
return map[level];
|
||||||
|
} else {
|
||||||
|
return this.$t("power_level.custom", { level: level });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "@/assets/css/chat.scss";
|
||||||
|
</style>
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- ROOM TOPIC CHANGED -->
|
<!-- ROOM TOPIC CHANGED -->
|
||||||
<div class="statusEvent">
|
<div class="statusEvent">
|
||||||
{{ stateEventDisplayName(event) }} changed topic to
|
{{ $t('message.user_changed_room_topic', {user: stateEventDisplayName(event), topic: event.getContent().topic}) }}
|
||||||
{{ event.getContent().topic }}
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import QuickReactions from './QuickReactions.vue';
|
||||||
var linkify = require('linkifyjs');
|
var linkify = require('linkifyjs');
|
||||||
var linkifyHtml = require('linkifyjs/html');
|
var linkifyHtml = require('linkifyjs/html');
|
||||||
linkify.options.defaults.className = "link";
|
linkify.options.defaults.className = "link";
|
||||||
linkify.options.defaults.target = null;
|
linkify.options.defaults.target = { url: '_blank' };
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -102,7 +102,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't have the original text (at the moment at least)
|
// We don't have the original text (at the moment at least)
|
||||||
return "<original text>";
|
return this.$t('fallbacks.original_text');
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
@ -169,7 +169,7 @@ export default {
|
||||||
*/
|
*/
|
||||||
stateEventDisplayName(event) {
|
stateEventDisplayName(event) {
|
||||||
if (event.getSender() == this.$matrix.currentUserId) {
|
if (event.getSender() == this.$matrix.currentUserId) {
|
||||||
return "You";
|
return this.$t('message.you');
|
||||||
}
|
}
|
||||||
if (this.room) {
|
if (this.room) {
|
||||||
const member = this.room.getMember(event.getSender());
|
const member = this.room.getMember(event.getSender());
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import VueResize from 'vue-resize';
|
||||||
import 'vue-resize/dist/vue-resize.css';
|
import 'vue-resize/dist/vue-resize.css';
|
||||||
import VueClipboard from 'vue-clipboard2'
|
import VueClipboard from 'vue-clipboard2'
|
||||||
import VueSanitize from "vue-sanitize";
|
import VueSanitize from "vue-sanitize";
|
||||||
|
import i18n from './plugins/lang';
|
||||||
|
|
||||||
var defaultOptions = VueSanitize.defaults;
|
var defaultOptions = VueSanitize.defaults;
|
||||||
defaultOptions.disallowedTagsMode = "recursiveEscape";
|
defaultOptions.disallowedTagsMode = "recursiveEscape";
|
||||||
|
|
@ -153,6 +154,7 @@ new Vue({
|
||||||
vuetify,
|
vuetify,
|
||||||
store,
|
store,
|
||||||
router,
|
router,
|
||||||
|
i18n,
|
||||||
matrix,
|
matrix,
|
||||||
cleaninsights,
|
cleaninsights,
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
|
|
|
||||||
24
src/plugins/lang.js
Normal file
24
src/plugins/lang.js
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueI18n from 'vue-i18n'
|
||||||
|
|
||||||
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
|
var messages = {}
|
||||||
|
|
||||||
|
function importAll(r) {
|
||||||
|
return r.keys().map(res => {
|
||||||
|
// Remove"./"
|
||||||
|
const parts = res.split("/");
|
||||||
|
const locale = parts[1].split(".")[0];
|
||||||
|
messages[locale] = r(res).default;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
importAll(require.context('@/assets/translations/', true, /\.js$/));
|
||||||
|
|
||||||
|
|
||||||
|
export default new VueI18n({
|
||||||
|
locale: 'en',
|
||||||
|
fallbackLocale: 'en',
|
||||||
|
silentFallbackWarn: true,
|
||||||
|
messages: messages
|
||||||
|
})
|
||||||
|
|
@ -82,7 +82,7 @@ const router = new VueRouter({
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
const publicPages = ['/login'];
|
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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,19 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a promise that will log us into the Matrix.
|
||||||
|
*
|
||||||
|
* Will use a real account, if we have one, otherwise will create
|
||||||
|
* a random account.
|
||||||
|
*/
|
||||||
|
getLoginPromise() {
|
||||||
|
if (this.ready) {
|
||||||
|
return Promise.resolve(this.currentUser);
|
||||||
|
}
|
||||||
|
return this.$store.dispatch("login", this.currentUser || new User(config.defaultServer, "", "", true));
|
||||||
|
},
|
||||||
|
|
||||||
addMatrixClientListeners(client) {
|
addMatrixClientListeners(client) {
|
||||||
if (client) {
|
if (client) {
|
||||||
client.on("event", this.onEvent);
|
client.on("event", this.onEvent);
|
||||||
|
|
|
||||||
10
update_version.sh
Executable file
10
update_version.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# Get version from file
|
||||||
|
echo "Get version from package.json"
|
||||||
|
v=`egrep "^[[:space:]]*\"version\"" package.json | cut -d \" -f 4`
|
||||||
|
# Increment
|
||||||
|
echo "Increment value"
|
||||||
|
v=`echo "${v%.*}.$((${v##*.}+1))"`
|
||||||
|
# Update file
|
||||||
|
echo "Update file"
|
||||||
|
sed -i .bak "s/\(\"version\": \"\)[^\"]*\(\"\)/\1${v}\2/g" package.json
|
||||||
|
|
@ -7,7 +7,15 @@ module.exports = {
|
||||||
? './'
|
? './'
|
||||||
: './',
|
: './',
|
||||||
|
|
||||||
devServer: {
|
chainWebpack: config => {
|
||||||
https: true
|
config.plugin('html').tap(args => {
|
||||||
},
|
var c = require("./src/assets/config.json");
|
||||||
|
args[0].title = c.appName;
|
||||||
|
return args;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
devServer: {
|
||||||
|
//https: true
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue