From 00f95adb096752f9d77d84513a473726a9a88a18 Mon Sep 17 00:00:00 2001 From: N Pex Date: Fri, 29 Sep 2023 15:13:12 +0000 Subject: [PATCH] Get dm link --- src/assets/config.json | 3 +- src/assets/css/chat.scss | 30 ++-- src/assets/css/getlink.scss | 82 +++++++++++ src/assets/icons/ic_share.svg | 3 + src/assets/translations/en.json | 11 ++ src/components/AudioLayout.vue | 2 +- src/components/CopyLink.vue | 21 ++- src/components/GetLink.vue | 254 ++++++++++++++++++++++++++++++++ src/components/Home.vue | 2 +- src/components/QRCodePopup.vue | 8 +- src/main.js | 4 +- src/router/index.js | 8 +- src/services/matrix.service.js | 8 +- src/store/index.js | 12 ++ 14 files changed, 422 insertions(+), 26 deletions(-) create mode 100644 src/assets/css/getlink.scss create mode 100644 src/assets/icons/ic_share.svg create mode 100644 src/components/GetLink.vue diff --git a/src/assets/config.json b/src/assets/config.json index 42d5c8e..74739ee 100644 --- a/src/assets/config.json +++ b/src/assets/config.json @@ -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 } \ No newline at end of file diff --git a/src/assets/css/chat.scss b/src/assets/css/chat.scss index 80ef2cf..650e324 100644 --- a/src/assets/css/chat.scss +++ b/src/assets/css/chat.scss @@ -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 { diff --git a/src/assets/css/getlink.scss b/src/assets/css/getlink.scss new file mode 100644 index 0000000..37074d3 --- /dev/null +++ b/src/assets/css/getlink.scss @@ -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; + } +} diff --git a/src/assets/icons/ic_share.svg b/src/assets/icons/ic_share.svg new file mode 100644 index 0000000..f0e38d5 --- /dev/null +++ b/src/assets/icons/ic_share.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index 2c73064..f515341 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -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", diff --git a/src/components/AudioLayout.vue b/src/components/AudioLayout.vue index 24b04d9..df629b3 100644 --- a/src/components/AudioLayout.vue +++ b/src/components/AudioLayout.vue @@ -78,7 +78,7 @@ expand_more -
{{ $t("message.not_allowed_to_send") }}
+
{{ $t("message.not_allowed_to_send") }}
diff --git a/src/components/CopyLink.vue b/src/components/CopyLink.vue index fcd975a..8cd7f34 100644 --- a/src/components/CopyLink.vue +++ b/src/components/CopyLink.vue @@ -7,7 +7,12 @@ - + @@ -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); diff --git a/src/components/GetLink.vue b/src/components/GetLink.vue new file mode 100644 index 0000000..c08a99d --- /dev/null +++ b/src/components/GetLink.vue @@ -0,0 +1,254 @@ + + + + + \ No newline at end of file diff --git a/src/components/Home.vue b/src/components/Home.vue index 34f8e67..4a98061 100644 --- a/src/components/Home.vue +++ b/src/components/Home.vue @@ -14,7 +14,7 @@ diff --git a/src/components/QRCodePopup.vue b/src/components/QRCodePopup.vue index c23a560..bce7a80 100644 --- a/src/components/QRCodePopup.vue +++ b/src/components/QRCodePopup.vue @@ -8,7 +8,7 @@
-
{{ $t("room_info.scan_code") }}
+
{{ title }}
@@ -32,6 +32,12 @@ export default { return null; }, }, + title: { + type: String, + default: function () { + return ""; + }, + }, }, data() { return { diff --git a/src/main.js b/src/main.js index dd30e8c..4d0cef6 100644 --- a/src/main.js +++ b/src/main.js @@ -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"); }; diff --git a/src/router/index.js b/src/router/index.js index ce5a865..877d816 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -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; diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js index 5533c0a..e0978ab 100644 --- a/src/services/matrix.service.js +++ b/src/services/matrix.service.js @@ -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); diff --git a/src/store/index.js b/src/store/index.js index 293c7b8..9024acc 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -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');