Merge branch 'get-dm-link' into 'dev'
Get dm link See merge request keanuapp/keanuapp-weblite!234
This commit is contained in:
commit
7ed3e80b9c
14 changed files with 422 additions and 26 deletions
|
|
@ -48,5 +48,6 @@
|
|||
"experimental_file_mode": true,
|
||||
"experimental_read_only_room": true,
|
||||
"experimental_public_room": true,
|
||||
"show_status_messages": "never"
|
||||
"show_status_messages": "never",
|
||||
"hide_add_room_on_home": false
|
||||
}
|
||||
|
|
@ -1405,6 +1405,24 @@ body {
|
|||
transition: opacity 0.3s linear;
|
||||
}
|
||||
|
||||
.toast-at-bottom {
|
||||
position: fixed;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
background-color: rgba(black, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 40;
|
||||
color: white;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.auto-audio-player-root {
|
||||
position: absolute;
|
||||
top: 72px;
|
||||
|
|
@ -1534,18 +1552,6 @@ body {
|
|||
.mic-button.dimmed {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.toast-read-only {
|
||||
position: fixed;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
background-color: rgba(black, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 40;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.audio-layout.voice-recorder {
|
||||
|
|
|
|||
82
src/assets/css/getlink.scss
Normal file
82
src/assets/css/getlink.scss
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
@import "@/assets/css/main.scss";
|
||||
|
||||
.getlink-root {
|
||||
background-color: $background;
|
||||
|
||||
.getlink-loggedin {
|
||||
text-align: center;
|
||||
button {
|
||||
min-width: 200px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.getlink-title {
|
||||
color: #000;
|
||||
text-align: center;
|
||||
font-family: "Poppins";
|
||||
font-size: 28px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 108.5%; /* 30.38px */
|
||||
letter-spacing: -0.8px;
|
||||
white-space: pre-line;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.getlink-subtitle {
|
||||
color: #000;
|
||||
text-align: center;
|
||||
font-feature-settings: "clig" off, "liga" off;
|
||||
font-family: "Inter";
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 117%; /* 18.72px */
|
||||
letter-spacing: 0.4px;
|
||||
margin: 13px 20px 18px 20px;
|
||||
}
|
||||
|
||||
.qr-container {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
border-radius: 18px;
|
||||
border: 1px solid #ededed;
|
||||
background: #fff;
|
||||
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.07);
|
||||
|
||||
.col:nth-child(1) {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
||||
text-align: center;
|
||||
.qr {
|
||||
width: 120px !important;
|
||||
height: 120px !important;
|
||||
}
|
||||
}
|
||||
.public-link {
|
||||
background-color: transparent;
|
||||
border: none !important;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
#btn-copy-room-link {
|
||||
background-color: var(--v-primary-base) !important;
|
||||
}
|
||||
|
||||
.link-copied-in-place .v-btn__content {
|
||||
font-family: "Inter", sans-serif !important;
|
||||
font-size: 12px !important;
|
||||
text-transform: none !important;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.getlink-share {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 24px;
|
||||
width: 24px;
|
||||
height: 17px;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
3
src/assets/icons/ic_share.svg
Normal file
3
src/assets/icons/ic_share.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="17" viewBox="0 0 24 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2477 0.000670823C16.1384 0.00531075 16.0311 0.0307591 15.9314 0.0754688C15.7815 0.142957 15.6546 0.25192 15.5656 0.389005C15.4766 0.526231 15.4291 0.685951 15.4291 0.849038V3.32107C14.7529 3.28142 14.0829 3.28494 13.4234 3.33598C6.62122 3.86253 0.885374 9.07191 0.00664931 16.0431H0.00679109C-0.0251098 16.2933 0.0564145 16.5444 0.229528 16.7288C0.402641 16.9133 0.649181 17.0122 0.902999 16.9988C1.15679 16.9853 1.39143 16.8609 1.54355 16.6591C4.61977 12.5918 9.44481 10.1994 14.572 10.1994H15.4292V12.7494C15.4295 12.9682 15.5147 13.1784 15.6674 13.3364C15.8199 13.4945 16.0281 13.5881 16.2484 13.5978C16.4687 13.6075 16.6845 13.5326 16.8505 13.3886L23.7079 7.43851C23.8935 7.2771 24 7.04413 24 6.79934C24 6.55455 23.8935 6.3216 23.7079 6.16016L16.8505 0.210072C16.6844 0.0659577 16.4685 -0.00898088 16.2478 0.000859754L16.2477 0.000670823Z" fill="#074EE8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1,017 B |
|
|
@ -188,6 +188,17 @@
|
|||
"send_token": "Send token",
|
||||
"token_not_valid": "Invalid token"
|
||||
},
|
||||
"getlink": {
|
||||
"title": "Get a Direct Link",
|
||||
"password": "Set your password",
|
||||
"password_repeat": "Confirm your password",
|
||||
"create": "Create",
|
||||
"hello": "Hello {user},\nHere’s your Direct Link",
|
||||
"ready_to_share": "It’s ready to share! A new direct room will open each time someone opens the link.",
|
||||
"scan_title": "Scan this code to start a direct chat",
|
||||
"continue": "Continue",
|
||||
"qr_image_copied": "Image copied to clipboard"
|
||||
},
|
||||
"profile": {
|
||||
"title": "My Profile",
|
||||
"temporary_identity": "This identity is temporary. Set a password to use it again",
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
<v-icon class="clickable" @click="loadNext" color="white" size="28">expand_more</v-icon>
|
||||
</div>
|
||||
|
||||
<div v-if="showReadOnlyToast" class="toast-read-only">{{ $t("message.not_allowed_to_send") }}</div>
|
||||
<div v-if="showReadOnlyToast" class="toast-at-bottom visible">{{ $t("message.not_allowed_to_send") }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,12 @@
|
|||
<v-row cols="12" class="qr-container ma-3">
|
||||
<v-col cols="auto">
|
||||
<canvas
|
||||
@click.stop="showFullScreenQR = true"
|
||||
v-longTap:250="[
|
||||
()=> {
|
||||
showFullScreenQR = true;
|
||||
},
|
||||
(el) => { $emit('long-tap', el); }
|
||||
]"
|
||||
ref="roomQr"
|
||||
class="qr"
|
||||
id="room-qr"
|
||||
|
|
@ -32,7 +37,7 @@
|
|||
</v-container>
|
||||
</v-card>
|
||||
</v-expand-transition>
|
||||
<QRCodePopup :show="showFullScreenQR" :message="locationLink" @close="showFullScreenQR = false" />
|
||||
<QRCodePopup :show="showFullScreenQR" :message="locationLink" :title="popupTitle" @close="showFullScreenQR = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -51,7 +56,12 @@ export default {
|
|||
i18nCopyLinkKey: {
|
||||
type: String,
|
||||
default: 'copy_link'
|
||||
},
|
||||
i18nQrPopupTitleKey: {
|
||||
type: String,
|
||||
default: 'room_info.scan_code'
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -59,6 +69,11 @@ export default {
|
|||
showFullScreenQR: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
popupTitle() {
|
||||
return this.$t(this.i18nQrPopupTitleKey);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyRoomLink() {
|
||||
if(this.locationLinkCopied) return
|
||||
|
|
@ -87,7 +102,7 @@ export default {
|
|||
{
|
||||
type: "image/png",
|
||||
margin: 1,
|
||||
width: 60,
|
||||
width: canvas.getBoundingClientRect().width,
|
||||
},
|
||||
function (error) {
|
||||
if (error) console.error(error);
|
||||
|
|
|
|||
254
src/components/GetLink.vue
Normal file
254
src/components/GetLink.vue
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
<template>
|
||||
<div class="pa-4 getlink-root fill-height">
|
||||
<div v-if="!loggedIn">
|
||||
<div class="getlink-title">{{ $t("getlink.title") }}</div>
|
||||
<div color="rgba(255,255,255,0.1)" class="text-center">
|
||||
<v-form v-model="isValid">
|
||||
<v-text-field v-model="user.user_id" :label="$t('login.username')" color="black" background-color="white" solo
|
||||
:rules="[(v) => !!v || $t('login.username_required')]" :error="userErrorMessage != null"
|
||||
:error-messages="userErrorMessage" required v-on:keyup.enter="onUsernameEnter" v-on:keydown="hasError = false"
|
||||
v-on:blur="onUsernameBlur"></v-text-field>
|
||||
|
||||
<div class="error--text" v-if="loadingLoginFlows">Loading login flows...</div>
|
||||
|
||||
<v-text-field v-show="showPasswordField" solo v-model="user.password"
|
||||
:append-icon="showPassword1 ? 'visibility' : 'visibility_off'" :hint="$t('global.password_hint')"
|
||||
:rules="[(v) => v ? !!v.match(passwordValidation) || $t('global.password_hint') : true]"
|
||||
:label="$t('getlink.password')" counter="20" maxlength="20" :type="showPassword1 ? 'text' : 'password'"
|
||||
@click:append="showPassword1 = !showPassword1" ref="password" :error="passErrorMessage != null"
|
||||
:error-messages="passErrorMessage" required v-on:keydown="hasError = false"
|
||||
v-on:keyup.enter="onPasswordEntered" v-on:blur="onPasswordEntered" />
|
||||
<v-text-field v-show="showPasswordConfirmField" solo v-model="passwordConfirm"
|
||||
:append-icon="showPassword2 ? 'visibility' : 'visibility_off'"
|
||||
:rules="[(v) => v === user.password || $t('global.password_didnot_match')]"
|
||||
:label="$t('getlink.password_repeat')" counter="20" maxlength="20"
|
||||
:type="showPassword2 ? 'text' : 'password'" @click:append="showPassword2 = !showPassword2"
|
||||
ref="passwordConfirm" :error="passErrorMessage != null" :error-messages="passErrorMessage" required
|
||||
v-on:keydown="hasError = false" v-on:keyup.enter="() => {
|
||||
if (isValid && !loading) {
|
||||
handleLogin();
|
||||
}
|
||||
}
|
||||
" />
|
||||
|
||||
<div class="error--text" v-if="hasError">{{ this.message }}</div>
|
||||
|
||||
<interactive-auth ref="interactiveAuth" />
|
||||
<!--
|
||||
<v-checkbox
|
||||
id="chk-remember-me"
|
||||
class="mt-0"
|
||||
v-model="rememberMe"
|
||||
@change="onRememberMe"
|
||||
:label="$t('join.remember_me')"
|
||||
/>
|
||||
-->
|
||||
<v-btn id="btn-login" :disabled="!isValid || !passwordsSetAndMatching || loading || loadingLoginFlows" color="primary" depressed block
|
||||
@click.stop="handleLogin" :loading="loading" class="filled-button mt-4">{{ $t("getlink.create") }}</v-btn>
|
||||
</v-form>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else style="position:relative" class="getlink-loggedin">
|
||||
<!-- Logged in/account created -->
|
||||
<div class="getlink-title">{{ $t("getlink.hello", { user: $matrix.currentUserDisplayName }) }}</div>
|
||||
<div class="getlink-subtitle">{{ $t("getlink.ready_to_share") }}</div>
|
||||
<copy-link ref="qr" :locationLink="directMessageLink" i18nQrPopupTitleKey="getlink.scan_title"
|
||||
v-on:long-tap="copyQRImage">
|
||||
<v-img v-if="shareSupported" class="clickable getlink-share" src="@/assets/icons/ic_share.svg"
|
||||
@click="shareLink" />
|
||||
</copy-link>
|
||||
<v-btn color="black" depressed @click.stop="goHome" class="outlined-button">{{ $t("getlink.continue") }}</v-btn>
|
||||
|
||||
</div>
|
||||
<div :class="{ 'toast-at-bottom': true, 'visible': showQRCopiedToast }">{{ $t("getlink.qr_image_copied") }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import User from "../models/user";
|
||||
import rememberMeMixin from "./rememberMeMixin";
|
||||
import * as sdk from "matrix-js-sdk";
|
||||
import logoMixin from "./logoMixin";
|
||||
import InteractiveAuth from './InteractiveAuth.vue';
|
||||
import CopyLink from "./CopyLink.vue"
|
||||
import utils from "../plugins/utils";
|
||||
|
||||
export default {
|
||||
name: "GetLink",
|
||||
mixins: [rememberMeMixin, logoMixin],
|
||||
components: { InteractiveAuth, CopyLink },
|
||||
data() {
|
||||
return {
|
||||
user: new User(this.$config.defaultServer, "", ""),
|
||||
isValid: false,
|
||||
loading: false,
|
||||
message: "",
|
||||
userErrorMessage: null,
|
||||
passErrorMessage: null,
|
||||
hasError: false,
|
||||
currentLoginServer: "",
|
||||
loadingLoginFlows: false,
|
||||
loginFlows: null,
|
||||
showPasswordField: false,
|
||||
showPasswordConfirmField: false,
|
||||
passwordConfirm: "",
|
||||
showPassword1: false,
|
||||
showPassword2: false,
|
||||
passwordValidation: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{12,20}$/,
|
||||
showQRCopiedToast: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
loggedIn() {
|
||||
return this.$store.state.auth.status.loggedIn;
|
||||
},
|
||||
currentUser() {
|
||||
return this.$store.state.auth.user;
|
||||
},
|
||||
showCloseButton() {
|
||||
return this.$navigation && this.$navigation.canPop();
|
||||
},
|
||||
directMessageLink() {
|
||||
return `${window.location.origin + window.location.pathname}#/user/${encodeURIComponent(this.$matrix.currentUser.user_id)}`
|
||||
},
|
||||
shareSupported() {
|
||||
return !!navigator.share;
|
||||
},
|
||||
passwordsSetAndMatching() {
|
||||
return this.user.password.match(this.passwordValidation) && this.user.password == this.passwordConfirm;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
user: {
|
||||
handler() {
|
||||
// Reset manual errors
|
||||
this.userErrorMessage = null;
|
||||
this.passErrorMessage = null;
|
||||
},
|
||||
deep: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$navigation.push({ name: "Home" }, -1);
|
||||
},
|
||||
handleLogin() {
|
||||
if (this.user.user_id && this.user.password) {
|
||||
// Reset errors
|
||||
this.message = null;
|
||||
|
||||
// Is it a full matrix user id? Modify a copy, so that the UI will still show the full ID.
|
||||
const userDisplayName = this.user.user_id;
|
||||
|
||||
var user = Object.assign({}, this.user);
|
||||
user.user_id = utils.randomUser(this.$config.userIdPrefix);
|
||||
user.normalize();
|
||||
|
||||
this.loading = true;
|
||||
this.$store.dispatch("createUser", { user, registrationFlowHandler: this.$refs.interactiveAuth.registrationFlowHandler }).then(
|
||||
(ignoreduser) => {
|
||||
this.$matrix.setUserDisplayName(userDisplayName);
|
||||
this.loading = false;
|
||||
},
|
||||
(error) => {
|
||||
console.error(error);
|
||||
this.loading = false;
|
||||
this.message =
|
||||
(error.data && error.data.error) ||
|
||||
error.message ||
|
||||
error.toString();
|
||||
if (error.data && error.data.errcode === 'M_FORBIDDEN') {
|
||||
this.message = this.$i18n.messages[this.$i18n.locale].login.invalid_message;
|
||||
this.hasError = true;
|
||||
}
|
||||
console.log("Message set to ", this.message);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
handleCreateRoom() {
|
||||
this.$navigation.push({ name: "CreateRoom" });
|
||||
},
|
||||
onUsernameEnter() {
|
||||
this.$refs.password.focus();
|
||||
this.onUsernameBlur();
|
||||
},
|
||||
validPassword(pass) {
|
||||
return !!pass;
|
||||
},
|
||||
onPasswordEntered() {
|
||||
if (this.validPassword(this.user.password)) {
|
||||
this.showPasswordConfirmField = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.passwordConfirm.focus();
|
||||
});
|
||||
}
|
||||
},
|
||||
onUsernameBlur() {
|
||||
var user = Object.assign({}, this.user);
|
||||
user.normalize();
|
||||
const server = user.home_server || this.$config.defaultServer;
|
||||
if (server !== this.currentLoginServer) {
|
||||
|
||||
this.showPasswordField = false;
|
||||
this.showPasswordConfirmField = false;
|
||||
|
||||
this.currentLoginServer = server;
|
||||
this.loadingLoginFlows = true;
|
||||
|
||||
const matrixClient = sdk.createClient({ baseUrl: server });
|
||||
matrixClient.loginFlows().then((response) => {
|
||||
console.log("FLOWS", response.flows);
|
||||
this.loginFlows = response.flows.filter(this.supportedLoginFlow);
|
||||
this.loadingLoginFlows = false;
|
||||
if (this.loginFlows.length == 0) {
|
||||
this.message = this.$t('login.no_supported_flow')
|
||||
this.hasError = true;
|
||||
} else {
|
||||
this.message = "";
|
||||
this.hasError = false;
|
||||
this.showPasswordField = this.loginFlows.some(f => f.type == "m.login.password");
|
||||
if (this.showPasswordField) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.password.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
supportedLoginFlow(flow) {
|
||||
return ["m.login.password"].includes(flow.type);
|
||||
},
|
||||
shareLink() {
|
||||
const canvas = this.$refs.qr.$refs.roomQr;
|
||||
if (canvas) {
|
||||
canvas.toBlob((blob) => {
|
||||
let file = new File([blob], encodeURIComponent(this.$matrix.currentUserDisplayName || User.localPart(this.currentUser.user_id)) + ".png", { type: "image/png" })
|
||||
const shareData = { files: [file] };
|
||||
if (navigator.canShare && navigator.canShare(shareData)) {
|
||||
navigator.share(shareData);
|
||||
}
|
||||
}, 'image/png');
|
||||
}
|
||||
},
|
||||
copyQRImage(canvas) {
|
||||
if (canvas && typeof window.ClipboardItem !== "undefined" && navigator.clipboard) {
|
||||
canvas.toBlob(blob => {
|
||||
const clipboardItemInput = new window.ClipboardItem({ "image/png": blob });
|
||||
navigator.clipboard.write([clipboardItemInput]).then(() => {
|
||||
this.showQRCopiedToast = true;
|
||||
setTimeout(() => {
|
||||
this.showQRCopiedToast = false;
|
||||
}, 3000);
|
||||
}).catch(err => console.error(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/getlink.scss";
|
||||
</style>
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
<v-card-text class="pa-0">
|
||||
<RoomList
|
||||
showInvites
|
||||
showCreate
|
||||
:showCreate="!$config.hide_add_room_on_home"
|
||||
v-on:newroom="createRoom"
|
||||
/>
|
||||
</v-card-text>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="d-flex justify-center">
|
||||
<canvas ref="qr" class="qr" id="qr" :style="qrStyle"></canvas>
|
||||
</div>
|
||||
<div>{{ $t("room_info.scan_code") }}</div>
|
||||
<div>{{ title }}</div>
|
||||
</div>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
|
@ -32,6 +32,12 @@ export default {
|
|||
return null;
|
||||
},
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: function () {
|
||||
return "";
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ Vue.directive('longTap', {
|
|||
*/
|
||||
const touchTimerElapsed = function () {
|
||||
el.longTapHandled = true;
|
||||
el.longTapCallbacks[1] && el.longTapCallbacks[1].call();
|
||||
el.longTapCallbacks[1] && el.longTapCallbacks[1].call(el, el);
|
||||
el.longTapTimer = null;
|
||||
el.classList.remove("waiting-for-long-tap");
|
||||
};
|
||||
|
|
@ -127,7 +127,7 @@ Vue.directive('longTap', {
|
|||
el.longTapTimer = null;
|
||||
if (!el.longTapHandled) {
|
||||
// Not canceled or long tapped. Just a single tap. Do we have a handler?
|
||||
el.longTapCallbacks[0] && el.longTapCallbacks[0].call();
|
||||
el.longTapCallbacks[0] && el.longTapCallbacks[0].call(el, el);
|
||||
}
|
||||
el.classList.remove("waiting-for-long-tap");
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import Join from '../components/Join.vue'
|
|||
import Login from '../components/Login.vue'
|
||||
import Profile from '../components/Profile.vue'
|
||||
import CreateRoom from '../components/CreateRoom.vue'
|
||||
import GetLink from '../components/GetLink.vue'
|
||||
|
||||
import util from '../plugins/utils'
|
||||
|
||||
|
|
@ -54,6 +55,11 @@ const routes = [
|
|||
title: 'Create room'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/getlink',
|
||||
name: 'GetLink',
|
||||
component: GetLink,
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
|
|
@ -91,7 +97,7 @@ const router = new VueRouter({
|
|||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const publicPages = ['/login', '/createroom'];
|
||||
const publicPages = ['/login', '/createroom', '/getlink'];
|
||||
var authRequired = !publicPages.includes(to.path);
|
||||
const loggedIn = router.app.$store.state.auth.user;
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export default {
|
|||
console.log("create crypto store");
|
||||
return new LocalStorageCryptoStore(this.$store.getters.storage);
|
||||
},
|
||||
login(user, registrationFlowHandler) {
|
||||
login(user, registrationFlowHandler, createUser = false) {
|
||||
const tempMatrixClient = sdk.createClient({baseUrl: user.home_server, idBaseUrl: this.$config.identityServer});
|
||||
var promiseLogin;
|
||||
|
||||
|
|
@ -121,14 +121,14 @@ export default {
|
|||
if (user.access_token) {
|
||||
// Logged in on "real" account
|
||||
promiseLogin = Promise.resolve(user);
|
||||
} else if (user.is_guest && (!user.user_id || user.registration_session)) {
|
||||
} else if (createUser || (user.is_guest && (!user.user_id || user.registration_session))) {
|
||||
// Generate random username and password. We don't user REAL matrix
|
||||
// guest accounts because 1. They are not allowed to post media, 2. They
|
||||
// can not use avatars and 3. They can not seamlessly be upgraded to real accounts.
|
||||
//
|
||||
// Instead, we use an ILAG approach, Improved Landing as Guest.
|
||||
const userId = user.registration_session ? user.user_id : util.randomUser(this.$config.userIdPrefix);
|
||||
const pass = user.registration_session ? user.password : util.randomPass();
|
||||
const userId = (createUser || user.registration_session) ? user.user_id : util.randomUser(this.$config.userIdPrefix);
|
||||
const pass = (createUser || user.registration_session) ? user.password : util.randomPass();
|
||||
|
||||
const extractAndSaveUser = (response) => {
|
||||
var u = Object.assign({}, response);
|
||||
|
|
|
|||
|
|
@ -113,6 +113,18 @@ export default new Vuex.Store({
|
|||
}
|
||||
);
|
||||
},
|
||||
createUser({ commit }, { user, registrationFlowHandler }) {
|
||||
return this._vm.$matrix.login(user, registrationFlowHandler, true).then(
|
||||
user => {
|
||||
commit('loginSuccess', user);
|
||||
return Promise.resolve(user);
|
||||
},
|
||||
error => {
|
||||
commit('loginFailure');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
},
|
||||
logout({ commit }) {
|
||||
this._vm.$matrix.logout();
|
||||
commit('logout');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue