Externalize strings

Also some cleanup. Work on issue #41.
This commit is contained in:
N-Pex 2021-05-20 12:33:59 +02:00
parent 3c60ad4f14
commit a78659b206
43 changed files with 402 additions and 288 deletions

11
package-lock.json generated
View file

@ -32,6 +32,7 @@
"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",
@ -13997,6 +13998,11 @@
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
"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": {
"version": "15.9.6",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
@ -26866,6 +26872,11 @@
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
"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": {
"version": "15.9.6",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",

View file

@ -33,6 +33,7 @@
"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",

View file

@ -33,7 +33,7 @@ export default {
return this.$store.state.auth.user;
},
title() {
var title = config.appName;
var title = this.$t(config.appName);
if (this.$matrix.notificationCount > 0) {
title += " [" + this.$matrix.notificationCount + "]";
}

View file

@ -0,0 +1,173 @@
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_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_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: {
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"
},
fallbacks: {
audio_file: "Audio file",
video_file: "Video file",
original_text: "<original text>",
download_name: "Download",
}
}

View file

@ -111,7 +111,7 @@
<div
v-if="event.getId() == readMarker && index < events.length - 1"
class="read-marker"
title="Unread messages"
:title="$t('message.unread_messages')"
/>
</div>
</div>
@ -135,7 +135,7 @@
<v-row class="ma-0 pa-0">
<div v-if="replyToEvent">
REPLYING TO EVENT: {{ replyToEvent.getContent().body }}
{{$t('message.replying_to_event',{message: replyToEvent.getContent().body}) }}
</div>
<!-- CONTACT IS TYPING -->
@ -154,7 +154,7 @@
v-model="currentInput"
no-resize
class="input-area-text"
placeholder="Your message..."
:placeholder="$t('message.your_message')"
hide-details
background-color="white"
v-on:keydown.enter.prevent="
@ -308,7 +308,7 @@
>
<v-switch
v-if="currentImageInput && currentImageInput.scaled"
label="Scale image"
:label="$('message.scale_image')"
v-model="currentImageInput.useScaled"
/>
</div>
@ -319,7 +319,7 @@
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" text @click="cancelSendAttachment"
>Cancel</v-btn
>{{$t('menu.cancel')}}</v-btn
>
<v-btn
color="primary"
@ -327,7 +327,7 @@
@click="sendAttachment"
v-if="currentSendShowSendButton"
:disabled="currentSendOperation != null"
>Send</v-btn
>{{$t('menu.send')}}</v-btn
>
</v-card-actions>
</v-card>
@ -336,7 +336,6 @@
<MessageOperationsBottomSheet
ref="messageOperationsSheet"
xv-show="showEmojiPicker"
>
<MessageOperationsPicker
v-on:close="showEmojiPicker = false"
@ -362,23 +361,6 @@
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 -->
<v-container
fluid
@ -555,9 +537,6 @@ export default {
*/
showScrollToEnd: false,
/** Shows a dialog with info about an operation being disallowed for guests */
showNotAllowedForGuests: false,
/** A timer for read receipts. */
rrTimer: null,
@ -641,9 +620,9 @@ export default {
typingMembersString() {
const count = this.typingMembers.length;
if (count > 1) {
return "" + count + " members are typing";
return this.$t('message.users_are_typing',{count: count});
} else if (count > 0) {
return this.typingMembers[0].name + " is typing";
return this.$t('message.user_is_typing',{user: this.typingMembers[0].name});
} else {
return "";
}
@ -776,7 +755,6 @@ export default {
this.timelineWindow
.load(initialEventId, 20)
.then(() => {
console.log("This is", self);
self.events = self.timelineWindow.getEvents();
const getMoreIfNeeded = function _getMoreIfNeeded() {
@ -1046,7 +1024,7 @@ export default {
this.restartRRTimer();
},
onEvent(event) {
console.log("OnEvent", JSON.stringify(event));
//console.log("OnEvent", JSON.stringify(event));
if (event.getRoomId() !== this.roomId) {
return; // Not for this room
}
@ -1083,7 +1061,7 @@ export default {
this.typingMembers.splice(index, 1);
}
}
console.log("Typing: ", this.typingMembers);
//console.log("Typing: ", this.typingMembers);
},
sendCurrentTextMessage() {
@ -1119,12 +1097,6 @@ export default {
* Show attachment picker to select file
*/
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();
},
@ -1202,9 +1174,9 @@ export default {
onUploadProgress(p) {
if (p.total) {
this.currentSendProgress =
"Uploaded " + (p.loaded || 0) + " of " + p.total;
this.$t('message.upload_progress_with_total',{count: (p.loaded || 0), total: p.total});
} else {
this.currentSendProgress = "Uploaded " + (p.loaded || 0);
this.currentSendProgress = this.$t('message.upload_progress',{count: (p.loaded || 0)});
}
},
@ -1390,7 +1362,7 @@ export default {
const link = document.createElement("a");
link.href = url;
link.target = "_blank";
link.download = event.getContent().body || "Download";
link.download = event.getContent().body || this.$t('fallbacks.download_name');
link.click();
URL.revokeObjectURL(url);
})
@ -1436,10 +1408,6 @@ export default {
showContextMenuForEvent(e) {
const event = e.event;
const ref = this.$refs[event.getId()];
if (ref) {
console.log("Got the ref", ref);
}
this.selectedEvent = event;
this.updateRecentEmojis();
this.showContextMenu = true;

View file

@ -13,10 +13,10 @@
<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="num-members">{{ memberCount }}{{ memberCount > 1 ? " members" : " member" }}</div>
<div class="num-members">{{ $tc('room.members', memberCount) }}</div>
</v-col>
<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-row>

View file

@ -2,7 +2,7 @@
<div class="create-room">
<div>
<v-container fluid>
<div class="room-name">New Group</div>
<div class="room-name">{{$t('new_room.new_room')}}</div>
<v-btn
text
class="header-button-left"
@ -11,7 +11,7 @@
:disabled="step > steps.NAME_SET"
>
<v-icon>arrow_back</v-icon>
<span>BACK</span>
<span>{{$t('menu.back')}}</span>
</v-btn>
<v-btn
text
@ -21,7 +21,7 @@
class="header-button-right"
@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-container>
</div>
@ -37,7 +37,7 @@
<v-col>
<v-text-field
v-model="roomName"
label="Name group"
:label="$t('new_room.name_room')"
color="black"
background-color="white"
v-on:keyup.enter="$refs.topic.focus()"
@ -49,12 +49,9 @@
<v-fade-transition>
<div class="section ma-3" flat v-if="step > steps.INITIAL">
<div class="h4 text-left">Join permissions</div>
<div class="h2 text-left">Set Join Permissions</div>
<div>
These permissions determine how people can join the group and how
easily others can be invited. They can be changed anytime.
</div>
<div class="h4 text-left">{{$t('new_room.join_permissions')}}</div>
<div class="h2 text-left">{{$t('new_room.set_join_permissions')}}</div>
<div>{{$t('new_room.join_permissions_info')}}</div>
<v-select
:disabled="step >= steps.CREATING"
:items="joinRules"
@ -65,7 +62,7 @@
<template v-slot:selection="{ item }">
{{ item.text }}
</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-avatar>
<v-icon class="grey lighten-1" dark>{{ item.icon }}</v-icon>
@ -105,7 +102,7 @@
depressed
class="outlined-button"
@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-else-if="joinRule == 'invite'"
@ -113,10 +110,10 @@
depressed
class="outlined-button"
@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>
@ -158,15 +155,15 @@ export default {
joinRules: [
{
id: "public",
text: "Anyone with a link",
text: this.$t('new_room.public_info'),
icon: "link",
descr: "Get a link to share",
descr: this.$t('new_room.public_description'),
},
{
id: "invite",
text: "Only people added",
text: this.$t('new_room.invite_info'),
icon: "person_add",
descr: "Choose from a list or search by account ID",
descr: this.$t('new_room.invite_description'),
},
],
publicRoomLink: null,
@ -265,7 +262,7 @@ export default {
createRoom() {
this.step = steps.CREATING;
var roomId;
this.status = "Creating room";
this.status = this.$t('new_room.status_creating');
var createRoomOptions = {};
if (this.joinRule == "public") {
createRoomOptions = {
@ -325,10 +322,9 @@ export default {
this.roomAvatarFile,
function (p) {
if (p.total) {
self.status =
"Uploading avatar: " + (p.loaded || 0) + " of " + p.total;
self.status = this.$t('new_room.status_avatar_total', {count: (p.loaded || 0), total: p.total});
} else {
self.status = "Uploading avatar: " + (p.loaded || 0);
self.status = this.$t('new_room.status_avatar', {count: (p.loaded || 0)});
}
}
);

View file

@ -1,12 +1,12 @@
<template>
<div class="created-room-welcome-header">
<div class="h4">Welcome!</div>
<div class="mt-2">Here are a few things to know about your group:</div>
<div class="mt-2" v-if="roomJoinRule == 'public'">Anyone can join by opening this link: {{ publicRoomLink }}</div>
<div class="mt-2" v-else-if="roomJoinRule == 'invite'">Only people you invite can join.</div>
<div class="mt-2">You can change 'join permissions' and 'message history' at any time in the group settings.</div>
<div class="h4">{{$t('room_welcome.welcome')}}</div>
<div class="mt-2">{{$t('room_welcome.info')}}</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'">{{$t('room_welcome.join_invite')}}</div>
<div class="mt-2">{{$t('room_welcome.info_permissions')}}</div>
<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>
</template>

View file

@ -1,6 +1,6 @@
<template>
<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
v-for="device in devices"
@ -84,11 +84,11 @@ export default {
verificationStatus(device) {
if (device.isBlocked()) {
return "Blocked";
return this.$t('device_list.blocked');
} else if (device.isVerified()) {
return "Verified";
return this.$t('device_list.verified');
} else {
return "Not verified";
return this.$t('device_list.not_verified');
}
},

View file

@ -1,7 +1,7 @@
<template>
<div class="pa-4">
<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 -->
<v-container

View file

@ -1,14 +1,14 @@
<template>
<div class="d-flex flex-column pa-4" style="overflow: hidden">
<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
:loading="loading"
text
class="header-button-right"
@click.stop="done"
>
<span>Done</span>
<span>{{$t('invite.done')}}</span>
</v-btn>
</div>
@ -16,7 +16,7 @@
class="flex-grow-0 flex-shrink-0"
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>
<v-chip-group active-class="primary--text" column>
<v-chip
@ -102,14 +102,14 @@ export default {
this.loading = false;
if (this.selectedMembers.length > 0) {
// Error.
this.status = "Failed to invite one or or more friends!";
this.status = this.$t('invite.status_error');
} else {
this.status = "";
this.close();
}
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];
// Is this userId already a member of this room? In that case don't send an invite.

View file

@ -8,7 +8,7 @@
@click.stop="handleLogin"
:loading="loading"
v-if="!currentUser"
>Login</v-btn
>{{$t('menu.login')}}</v-btn
>
<v-avatar class="join-avatar">
@ -17,7 +17,7 @@
roomName.substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div class="join-title">Welcome to {{ roomName }}</div>
<div class="join-title">{{$t('join.title', {roomName: roomName})}}</div>
<div class="join-message">
<!-- Join the group chat in a web browser or with the Keanu app. -->
</div>
@ -33,7 +33,7 @@
ref="avatar"
:items="availableAvatars"
cache-items
label="User name"
:label="$t('join.user_name_label')"
outlined
dense
@change="selectAvatar"
@ -60,12 +60,12 @@
<div class="ml-2">{{ data.item.name }}</div>
</template>
</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-row>
<v-row v-else>
<v-col>
You are joining as:
{{$t('join.joining_as')}}
<div style="display: inline-block">
<v-avatar color="#e0e0e0" style="">
<v-img v-if="userAvatar" :src="userAvatar" />
@ -97,7 +97,7 @@
@click.stop="handleJoin"
:loading="loading"
v-if="!currentUser"
>Join as guest</v-btn
>{{$t('join.join_guest')}}</v-btn
>
<v-btn
class="btn-dark"
@ -106,7 +106,7 @@
@click.stop="handleJoin"
:loading="loading"
v-else
>Join room</v-btn
>{{$t('join.join')}}</v-btn
>
<!-- <div class="join-privacy">
@ -325,7 +325,7 @@ export default {
handleJoin() {
this.loading = true;
this.loadingMessage = "Logging in...";
this.loadingMessage = this.$t('join.status_logging_in');
const hasUser = this.currentUser ? true : false;
var setProfileData = false;
return this.getLoginPromise()
@ -374,7 +374,7 @@ export default {
.then(
function (ignoreduser) {
console.log("Join: joining room");
this.loadingMessage = "Joining room...";
this.loadingMessage = this.$t('join.status_joining');
return this.$matrix.matrixClient.joinRoom(this.roomId);
}.bind(this)
)

View file

@ -4,26 +4,27 @@
<template v-if="roomJoinRule == 'public'">
<h1>👋</h1>
<h2 class="dialog-title">
Goodbye, {{ $matrix.currentUserDisplayName }}.
{{$t('leave.title_public',{user: $matrix.currentUserDisplayName})}}
</h2>
<div
v-if="$matrix.currentUser.is_guest && lastRoom"
class="dialog-text"
>
If you want to join this group again, you can join under a new
identity. To keep {{ $matrix.currentUserDisplayName }},
<a @click.prevent="viewProfile">create an account</a>.
</div>
<div v-else class="dialog-text">
You can always join this room again if you know the link.
<i18n path="leave.text_public_lastroom" tag="p">
<template v-slot:user>
<span>{{ $matrix.currentUserDisplayName }}</span>
</template>
<template v-slot:action>
<a @click.prevent="viewProfile">{{ $t('leave.create_account') }}</a>
</template>
</i18n>
</div>
<div v-else class="dialog-text">{{$t('leave.text_public')}}</div>
</template>
<template v-else>
<v-icon color="black" size="30">lock</v-icon>
<h2 class="dialog-title">Are you sure you want to leave?</h2>
<div class="dialog-text">
This group is locked. You cannot rejoin without a special permission.
</div>
<h2 class="dialog-title">{{$t('leave.title_invite',{user: $matrix.currentUserDisplayName})}}</h2>
<div class="dialog-text">{{$t('leave.text_invite')}}</div>
</template>
<v-container fluid>
<v-row cols="12">
@ -34,7 +35,7 @@
block
class="text-button"
@click="showDialog = false"
>Go back</v-btn
>{{$t('leave.go_back')}}</v-btn
>
</v-col>
<v-col cols="6" align="center">
@ -44,7 +45,7 @@
block
class="filled-button"
@click.stop="onLeaveRoom()"
>Leave</v-btn
>{{$t('leave.leave')}}</v-btn
>
</v-col>
</v-row>

View file

@ -5,15 +5,15 @@
</v-btn>
<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-text-field
v-model="user.user_id"
label="Username"
:label="$t('login.username')"
color="black"
background-color="white"
outlined
:rules="[(v) => !!v || 'Username is required']"
:rules="[(v) => !!v || $t('login.username_required')]"
:error="userErrorMessage != null"
:error-messages="userErrorMessage"
required
@ -22,12 +22,12 @@
<v-text-field
ref="password"
v-model="user.password"
label="Password"
:label="$t('login.password')"
color="black"
background-color="white"
outlined
type="password"
:rules="[(v) => !!v || 'Password is required']"
:rules="[(v) => !!v || $t('login.password_required')]"
:error="passErrorMessage != null"
:error-messages="passErrorMessage"
required
@ -40,7 +40,7 @@
block
@click.stop="handleLogin"
:loading="loading"
>Login</v-btn
>{{$t('login.login')}}</v-btn
>
</v-form>
</div>

View file

@ -2,7 +2,7 @@
<div v-if="user" class="profile">
<div class="chat-header">
<v-container fluid>
<div class="room-name">My Profile</div>
<div class="room-name">{{$t('profile.title')}}</div>
<v-btn
text
class="header-button-right"
@ -29,31 +29,29 @@
<v-col class="flex-shrink-1 flex-grow-1">
<div class="h1">{{ displayName }}</div>
<div class="text-center">{{ $matrix.currentUser.user_id }}</div>
<div v-if="$matrix.currentUser.is_guest">
This identity is temporary. Set a password to use it again.
</div>
<v-btn depressed block class="outlined-button" @click.stop="logout">Logout</v-btn>
<div v-if="$matrix.currentUser.is_guest">{{$t('profile.temporary_identity')}}</div>
<v-btn depressed block class="outlined-button" @click.stop="logout">{{$t('menu.logout')}}</v-btn>
</v-col>
</v-row>
</v-container>
<div class="action" @click="showEditPasswordDialog = true"><v-icon>lock</v-icon><span>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="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>{{$t('profile.change_name')}}</span></div>
<!-- edit password dialog -->
<v-dialog v-model="showEditPasswordDialog" class="ma-0 pa-0" width="50%">
<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-text-field v-if="!$matrix.currentUser.is_guest" v-model="password" label="Old password" type="password" />
<v-text-field v-model="newPassword1" label="New password" type="password" />
<v-text-field v-model="newPassword2" label="Repeat new 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="$t('profile.password_new')" type="password" />
<v-text-field v-model="newPassword2" :label="$t('profile.password_repeat')" type="password" />
<div class="red--text" v-if="passwordErrorMessage">{{ passwordErrorMessage }}</div>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text @click="closeEditPasswordDialog">Cancel</v-btn>
<v-btn text @click="closeEditPasswordDialog">{{$t('menu.cancel')}}</v-btn>
<v-btn
:disabled="!passwordsMatch"
color="primary"
@ -61,7 +59,7 @@
@click="
setPassword($matrix.currentUser.is_guest ? $matrix.currentUser.password : password, newPassword1);
"
>Ok</v-btn
>{{$t('menu.ok')}}</v-btn
>
</v-card-actions>
</v-card>
@ -70,14 +68,14 @@
<!-- edit display name dialog -->
<v-dialog v-model="showEditDisplaynameDialog" class="ma-0 pa-0" width="50%">
<v-card>
<v-card-title>Display name</v-card-title>
<v-card-title>{{$t('profile.display_name')}}</v-card-title>
<v-card-text>
<v-text-field v-model="editValue" />
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<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
color="primary"
text
@ -85,7 +83,7 @@
setDisplayName(editValue);
showEditDisplaynameDialog = false;
"
>Ok</v-btn
>{{$t('menu.ok')}}</v-btn
>
</v-card-actions>
</v-card>

View file

@ -3,10 +3,9 @@
<div class="dialog-content text-center">
<template>
<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">
This operation will close the room for all members. It cannot be
undone.
{{$t('purge_room.info')}}
</div>
</template>
<v-container fluid>
@ -18,7 +17,7 @@
block
class="text-button"
@click="showDialog = false"
>Cancel</v-btn
>{{$t('menu.cancel')}}</v-btn
>
</v-col>
<v-col cols="6" align="center">
@ -28,7 +27,7 @@
block
class="filled-button"
@click.stop="onPurgeRoom()"
>Purge room</v-btn
>{{$t('purge_room.button')}}</v-btn
>
</v-col>
</v-row>

View file

@ -2,7 +2,7 @@
<div v-if="room" class="room-info">
<div class="chat-header">
<v-container fluid>
<div class="room-name">Info</div>
<div class="room-name">{{ $t("room_info.title") }}</div>
<v-btn
text
class="header-button-left"
@ -10,7 +10,7 @@
@click.stop="$navigation.pop"
>
<v-icon>arrow_back</v-icon>
<span>BACK</span>
<span>{{ $t("menu.back") }}</span>
</v-btn>
</v-container>
</div>
@ -25,31 +25,30 @@
</v-avatar>
<div class="h1">{{ roomName }}</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>
<canvas
v-show="publicRoomLink"
ref="roomQr"
class="qr"
id="room-qr"
></canvas>
<canvas
v-show="publicRoomLink"
ref="roomQr"
class="qr"
id="room-qr"
></canvas>
</v-expand-transition>
</div>
</v-card>
<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-radio-group
v-model="roomJoinRule"
v-if="roomJoinRule"
:disabled="!userCanChangeJoinRule || updatingJoinRule"
>
<v-radio
label="Room can be joined by invitation only"
:value="'invite'"
/>
<v-radio label="Anyone with the link can join" :value="'public'">
<v-radio :label="$t('room_info.join_invite')" :value="'invite'" />
<v-radio :label="$t('room_info.join_public')" :value="'public'">
</v-radio>
<v-text-field
v-if="publicRoomLink"
@ -60,7 +59,9 @@
type="text"
@click:append="copyRoomLink"
></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-btn
@ -70,7 +71,7 @@
block
class="filled-button"
@click.stop="showPurgeConfirmation = true"
>Purge room</v-btn
>{{ $("room_info.purge") }}</v-btn
>
<!-- <div v-if="anyoneCanJoin">
<div>Anyone with a link can join.</div>
@ -88,7 +89,7 @@
<v-card class="members ma-3" flat>
<v-card-title class="h2"
>Members<v-spacer></v-spacer>
>{{ $t("room_info.members") }}<v-spacer></v-spacer>
<div>{{ memberCount }}</div></v-card-title
>
<v-card-text>
@ -105,37 +106,52 @@
member.name.substring(0, 1).toUpperCase()
}}</span>
</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
v-if="expandedMembers.includes(member)"
:member="member"
/>
</div>
<div class="show-all" @click="showAllMembers = !showAllMembers">
{{ showAllMembers ? "Hide" : "Show all" }}
{{
showAllMembers ? $t("room_info.hide_all") : $t("room_info.show_all")
}}
</div>
</v-card-text>
</v-card>
<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>
<div>
<div v-if="$matrix.currentUser.is_guest">
Your identity <b>{{ displayName }}</b> is temporary. You can change
your name or set a password to keep it.
<i18n path="room_info.identity_temporary" tag="span">
<template v-slot:displayName>
<b>{{ displayName }}</b>
</template>
</i18n>
</div>
<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>
<v-btn
depressed
block
class="outlined-button"
@click.stop="viewProfile"
>View</v-btn
>{{$t('room_info.view_profile')}}</v-btn
>
</div>
</v-card-text>
@ -149,18 +165,13 @@
block
class="filled-button"
@click.stop="showLeaveConfirmation = true"
>Leave group</v-btn
>{{$t('room_info.leave_room')}}</v-btn
>
<div>
Note: This step cannot be undone. Make sure you want to logout and
delete the chat forever.
</div>
<div>{{$t('room_info.leave_room_info')}}</div>
</v-card-text>
</v-card>
<div class="build-version">
Powered by Guardian Project. Version: {{ buildVersion }}
</div>
<div class="build-version">{{$t('room_info.version_info',{version: buildVersion})}}</div>
<LeaveRoomDialog
:show="showLeaveConfirmation"
@ -173,7 +184,6 @@
:room="room"
@close="showPurgeConfirmation = false"
/>
</div>
</template>
@ -340,7 +350,8 @@ export default {
setInterval(() => {
// Hide again
self.publicRoomLinkCopied = false;
}, 3000); },
}, 3000);
},
function (e) {
console.log(e);
}

View file

@ -11,14 +11,14 @@
roomName.substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div class="h4">This group</div>
<div class="h4">{{$t('room_info_sheet.this_room')}}</div>
<div class="h2">{{ roomName }}</div>
<v-btn
height="20px"
color="black"
class="filled-button"
@click.stop="showDetails"
>View details</v-btn
>{{$t('room_info_sheet.view_details')}}</v-btn
>
</div>
<room-list :title="'Other groups'" v-on:close="close" />
@ -27,7 +27,7 @@
color="black"
class="outlined-button"
@click.stop="createRoom"
>Create group</v-btn
>{{$t('room_info_sheet.create_room')}}</v-btn
>
</div>
</BottomSheet>

View file

@ -56,7 +56,7 @@
</div>
</v-col>
<v-col cols="6" v-if="ptt">
<div class="swipe-info">&lt;&lt; Swipe to cancel</div>
<div class="swipe-info">&lt;&lt; {{$t('voice_recorder.swipe_to_cancel')}}</div>
</v-col>
</v-row>
</v-container>
@ -72,7 +72,7 @@
<v-icon color="white">delete_outline</v-icon>
</v-col>
<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-row>
</v-container>
@ -94,7 +94,7 @@
</v-col>
<v-col cols="3">
<v-btn @click.stop="cancelRecording" text class="swipe-info"
>Cancel</v-btn
>{{$t('menu.cancel')}}</v-btn
>
</v-col>
<v-col cols="3">
@ -116,7 +116,7 @@
<v-row align="center">
<v-col>
<div class="swipe-info">
{{ errorMessage || "Failed to record audio" }}
{{ errorMessage || $t('voice_recorder.failed_to_record') }}
</div>
</v-col>
<v-col align="right">

View file

@ -115,71 +115,3 @@ export default {
<style lang="scss">
@import "@/assets/css/chat.scss";
</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');
}

View file

@ -7,7 +7,7 @@
}"
>
<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>
</template>

View file

@ -2,10 +2,10 @@
<!-- Contact joined the chat -->
<div class="messageJoin">
<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 v-if="avatarChange">
{{ changer }} changed the avatar
{{ $t('message.user_changed_avatar', { user: changer})}}
</div>
</div>
</template>
@ -28,7 +28,7 @@ export default {
},
changer() {
if (this.event.getSender() == this.$matrix.currentUserId) {
return "You";
return this.$t("message.you");
}
if (this.displayNameChange) {
return this.event.getPrevContent().displayname;

View file

@ -1,7 +1,7 @@
<template>
<!-- Contact invited to the chat -->
<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>
</template>

View file

@ -1,7 +1,7 @@
<template>
<!-- Contact joined the chat -->
<div class="messageJoin">
{{ stateEventDisplayName(event) }} joined the chat
{{ $t('message.user_joined',{user: stateEventDisplayName(event)}) }}
</div>
</template>

View file

@ -1,7 +1,7 @@
<template>
<!-- Contact left the chat -->
<div class="messageJoin">
{{ stateEventDisplayName(event) }} left the chat
{{ $t('message.user_left',{user: stateEventDisplayName(event)}) }}
</div>
</template>

View file

@ -1,7 +1,7 @@
<template>
<message-incoming v-bind="{...$props, ...$attrs}" v-on="$listeners">
<div class="bubble audio-bubble">
<audio-player :src="src">Audio file</audio-player>
<audio-player :src="src">{{ $t('fallbacks.audio_file')}}</audio-player>
</div>
</message-incoming>
</template>

View file

@ -3,7 +3,7 @@
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
<div class="original-message-sender">
{{ inReplyToSender || "Someone" }} said:
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
</div>
<div
class="original-message-text"
@ -11,14 +11,14 @@
/>
</div>
<div class="message">
<span>File: </span>
<span>{{ $t('file_prefix') }}</span>
<span
style="cursor: pointer"
@click.stop="$emit('download')"
v-html="linkify($sanitize(messageText))"
/>
<span class="edit-marker" v-if="event.replacingEventId()"
>(edited)</span
>{{ $t('edited') }}</span
>
</div>
</div>

View file

@ -3,7 +3,7 @@
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
<div class="original-message-sender">
{{ inReplyToSender || "Someone" }} said:
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
</div>
<div
class="original-message-text"
@ -13,7 +13,7 @@
<div class="message">
<span v-html="linkify($sanitize(messageText))" />
<span class="edit-marker" v-if="event.replacingEventId()"
>(edited)</span
>{{ $t('edited') }}</span
>
</div>
<!-- <div>{{ JSON.stringify(event) }}</div> -->

View file

@ -3,11 +3,11 @@
<div class="bubble image-bubble">
<v-responsive :aspect-ratio="16 / 9" :src="src">
<video :src="src" controls style="width: 100%; height: 100%">
Video file
{{$t('fallbacks.video_file')}}
</video>
<div v-if="downloadProgress" class="download-overlay">
<div class="text-center download-text">
{{ downloadProgress }}% downloaded
{{ $t('message.download_progress',{percentage: downloadProgress}) }}
</div>
</div>
</v-responsive>

View file

@ -12,25 +12,25 @@
<v-btn icon @click.stop="addReply" class="ma-0 pa-0">
<v-icon>reply</v-icon>
</v-btn>
<div>Reply</div>
<div>{{$t('menu.reply')}}</div>
</v-col>
<v-col v-if="isEditable">
<v-btn icon @click.stop="edit" class="ma-0 pa-0">
<v-icon>edit</v-icon>
</v-btn>
<div>Edit</div>
<div>{{$t('menu.edit')}}</div>
</v-col>
<v-col v-if="isRedactable">
<v-btn icon @click.stop="redact" class="ma-0 pa-0">
<v-icon>delete</v-icon>
</v-btn>
<div>Delete</div>
<div>{{$t('menu.delete')}}</div>
</v-col>
<v-col v-if="isDownloadable">
<v-btn icon @click.stop="download" class="ma-0 pa-0">
<v-icon>get_app</v-icon>
</v-btn>
<div>Download</div>
<div>{{$t('menu.download')}}</div>
</v-col>
</v-row>
</v-container>

View file

@ -18,7 +18,7 @@
<img v-if="userAvatar" :src="userAvatar" />
<span v-else class="white--text headline">{{ userAvatarLetter }}</span>
</v-avatar>
<!-- <div class="sender">{{ "You" }}</div> -->
<!-- <div class="sender">{{ $t('message.you') }}</div> -->
<div class="senderAndTime">
<div class="time">
{{ formatTime(event.event.origin_server_ts) }}

View file

@ -1,7 +1,7 @@
<template>
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
<div class="audio-bubble">
<audio-player :src="src">Audio file</audio-player>
<audio-player :src="src">{{ $t('fallbacks.audio_file')}}</audio-player>
</div>
</message-outgoing>
</template>

View file

@ -3,7 +3,7 @@
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
<div class="original-message-sender">
{{ inReplyToSender || "Someone" }} said:
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
</div>
<div
class="original-message-text"
@ -19,7 +19,7 @@
v-html="linkify($sanitize(messageText))"
/>
<span class="edit-marker" v-if="event.replacingEventId()"
>(edited)</span
>{{ $t('edited') }}</span
>
</div>
</div>

View file

@ -3,7 +3,7 @@
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
<div class="original-message-sender">
{{ inReplyToSender || "Someone" }} said:
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
</div>
<div
class="original-message-text"
@ -14,7 +14,7 @@
<div class="message">
<span v-html="linkify($sanitize(messageText))" />
<span class="edit-marker" v-if="event.replacingEventId()"
>(edited)</span
>{{ $t('edited') }}</span
>
</div>
</div>

View file

@ -3,7 +3,7 @@
<div class="bubble image-bubble">
<v-responsive :aspect-ratio="16 / 9" class="ma-0 pa-0">
<video :src="src" controls style="width: 100%; height: 100%">
Video file
{{$t('fallbacks.video_file')}}
</video>
</v-responsive>
</div>

View file

@ -1,7 +1,7 @@
<template>
<!-- ROOM AVATAR CHANGED -->
<div class="statusEvent">
{{ stateEventDisplayName(event) }} changed the room avatar
{{ $t('message.user_changed_room_avatar',{user: stateEventDisplayName(event)}) }}
</div>
</template>

View file

@ -1,7 +1,7 @@
<template>
<!-- ROOM AVATAR CHANGED -->
<div class="statusEvent">
{{ stateEventDisplayName(event) }} made room history {{ history(event) }}
{{ $t('message.user_changed_room_history',{user: stateEventDisplayName(event), type: history(event)}) }}
</div>
</template>
@ -15,13 +15,13 @@ export default {
const visibility = event.getContent().history_visibility;
switch (visibility) {
case "world_readable":
return "readable by anyone";
return this.$t('message.room_history_world_readable');
case "shared":
return "readable to all members in the room";
return this.$t('message.room_history_shared');
case "invited":
return "readable to members from when they were invited";
return this.$t('message.room_history_invited');
case "joined":
return "readable to members from when they joined";
return this.$t('message.room_history_joined');
}
return visibility;
}

View file

@ -1,7 +1,7 @@
<template>
<!-- ROOM JOIN RULES CHANGED -->
<div class="statusEvent">
{{ stateEventDisplayName(event) }} made the room {{ joinRule(event) }}
{{ $t('message.user_changed_join_rules', { user: stateEventDisplayName(event), type: joinRule(event)}) }}
</div>
</template>
@ -15,9 +15,9 @@ export default {
const joinRule = event.getContent().join_rule;
switch (joinRule) {
case "invite":
return "invite only";
return this.$t('message.room_joinrule_invite');
case "public":
return "public";
return this.$t('message.room_joinrule_public');
}
return joinRule;
}

View file

@ -1,8 +1,7 @@
<template>
<!-- ROOM NAME CHANGED -->
<div class="statusEvent">
{{ stateEventDisplayName(event) }} changed room name to
{{ event.getContent().name }}
{{ $t('message.user_changed_room_name', {user: stateEventDisplayName(event), name: event.getContent().name}) }}
</div>
</template>

View file

@ -1,8 +1,7 @@
<template>
<!-- ROOM TOPIC CHANGED -->
<div class="statusEvent">
{{ stateEventDisplayName(event) }} changed topic to
{{ event.getContent().topic }}
{{ $t('message.user_changed_room_topic', {user: stateEventDisplayName(event), topic: event.getContent().topic}) }}
</div>
</template>

View file

@ -102,7 +102,7 @@ export default {
}
// We don't have the original text (at the moment at least)
return "<original text>";
return this.$t('fallbacks.original_text');
}
return null;
},
@ -169,7 +169,7 @@ export default {
*/
stateEventDisplayName(event) {
if (event.getSender() == this.$matrix.currentUserId) {
return "You";
return this.$t('message.you');
}
if (this.room) {
const member = this.room.getMember(event.getSender());

View file

@ -13,6 +13,7 @@ import VueResize from 'vue-resize';
import 'vue-resize/dist/vue-resize.css';
import VueClipboard from 'vue-clipboard2'
import VueSanitize from "vue-sanitize";
import i18n from './plugins/lang';
var defaultOptions = VueSanitize.defaults;
defaultOptions.disallowedTagsMode = "recursiveEscape";
@ -153,6 +154,7 @@ new Vue({
vuetify,
store,
router,
i18n,
matrix,
cleaninsights,
render: h => h(App)

24
src/plugins/lang.js Normal file
View 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
})