diff --git a/src/assets/config.json b/src/assets/config.json index cecc24f..ff4e750 100644 --- a/src/assets/config.json +++ b/src/assets/config.json @@ -9,24 +9,35 @@ "productLink": "letsconvene.im", "defaultServer": "https://neo.keanu.im", "rtl": false, - "analytics": { - "enabled": true, - "config": { - "server": "https://metrics.cleaninsights.org/cleaninsights.php", - "siteId": 14, - "timeout": 5, - "persistEveryNTimes": 1, - "debug": true, - "campaigns": { - "beta": { - "start": "2021-01-01T00:00:00-00:00", - "end": "2021-12-31T23:59:59-00:00", - "aggregationPeriodLength": 1, - "numberOfPeriods": 90, - "onlyRecordOnce": false, - "eventAggregationRule": "avg" + "analytics": [ + { + "enabled": true, + "type": "ci", + "config": { + "server": "https://metrics.cleaninsights.org/cleaninsights.php", + "siteId": 14, + "timeout": 5, + "persistEveryNTimes": 1, + "debug": true, + "campaigns": { + "beta": { + "start": "2021-01-01T00:00:00-00:00", + "end": "2021-12-31T23:59:59-00:00", + "aggregationPeriodLength": 1, + "numberOfPeriods": 90, + "onlyRecordOnce": false, + "eventAggregationRule": "avg" + } } } + }, + { + "enabled": true, + "type": "matomo", + "config": { + "server": "https://metrics.cleaninsights.org/", + "siteId": "17" + } } - } + ] } \ No newline at end of file diff --git a/src/assets/css/chat.scss b/src/assets/css/chat.scss index ef7a386..9b13b0c 100644 --- a/src/assets/css/chat.scss +++ b/src/assets/css/chat.scss @@ -1,4 +1,4 @@ -@import '~vuetify/src/styles/settings/_variables.scss'; +@import "~vuetify/src/styles/settings/_variables.scss"; @import "@/assets/css/main.scss"; @import "@/assets/css/vendors/v-emoji-picker"; @@ -6,1140 +6,1180 @@ $admin-bg: black; $admin-fg: white; .home { - .v-card { - background-color: white; - box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25) !important; - border-radius: 18px; - padding-bottom: 10px; - .v-item-group > div:not(:last-of-type):after { - /* divider */ - position: absolute; - content: " "; - display: block; - bottom: 0px; - height: 1px; - left: 0px; - right: 0px; - min-height: 1px; - background-color: #e1e1e1; - } + .v-card { + background-color: white; + box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25) !important; + border-radius: 18px; + padding-bottom: 10px; + .v-item-group > div:not(:last-of-type):after { + /* divider */ + position: absolute; + content: " "; + display: block; + bottom: 0px; + height: 1px; + left: 0px; + right: 0px; + min-height: 1px; + background-color: #e1e1e1; } + } } .chat-header { + margin: 0; + padding: 0; + height: 72px; + background-color: #ffffff; + border-bottom: 1px solid #eeeeee; + .chat-header-row { margin: 0; - padding: 0; - height: 72px; - background-color: #ffffff; - border-bottom: 1px solid #eeeeee; - .chat-header-row { - margin: 0; - padding: 4px 10px; - align-items: center; - height: 100%; - } - .chat-header-members, .chat-header-name { - overflow: hidden; - cursor: pointer; - } - .num-members { - font-family: "Inter", sans-serif; - font-weight: 400; - font-size: 12 * $chat-text-size; - color: black; - } - .v-btn.leave-button { - font-family: "Inter", sans-serif; - font-weight: 700; - font-size: 11 * $chat-text-size; - color: black; - background-color: white !important; - border: 1px solid black; - border-radius: $chat-standard-padding / 2; - height: $chat-standard-padding; - margin-top: $chat-standard-padding-xs; - margin-bottom: $chat-standard-padding-xs; - } - .v-btn.avatar { - font-family: "Inter", sans-serif; - font-weight: 700; - font-size: 11 * $chat-text-size; - color: black; - background-color: white !important; - border: 1px solid black; - border-radius: $chat-standard-padding / 2; - height: $chat-standard-padding; - margin-top: $chat-standard-padding-xs; - margin-bottom: $chat-standard-padding-xs; - } + padding: 4px 10px; + align-items: center; + height: 100%; + } + .chat-header-members, + .chat-header-name { + overflow: hidden; + cursor: pointer; + } + .num-members { + font-family: "Inter", sans-serif; + font-weight: 400; + font-size: 12 * $chat-text-size; + color: black; + } + .v-btn.leave-button { + font-family: "Inter", sans-serif; + font-weight: 700; + font-size: 11 * $chat-text-size; + color: black; + background-color: white !important; + border: 1px solid black; + border-radius: $chat-standard-padding / 2; + height: $chat-standard-padding; + margin-top: $chat-standard-padding-xs; + margin-bottom: $chat-standard-padding-xs; + } + .v-btn.avatar { + font-family: "Inter", sans-serif; + font-weight: 700; + font-size: 11 * $chat-text-size; + color: black; + background-color: white !important; + border: 1px solid black; + border-radius: $chat-standard-padding / 2; + height: $chat-standard-padding; + margin-top: $chat-standard-padding-xs; + margin-bottom: $chat-standard-padding-xs; + } - @media #{map-get($display-breakpoints, 'sm-and-down')} { - position: fixed; - z-index: 10; - } + @media #{map-get($display-breakpoints, 'sm-and-down')} { + position: fixed; + z-index: 10; + } } .room-list-notification-count { - position: absolute; - top: 10px; - left: 40px; - right: initial; - color: white; - background-color: black; - font-size: 10px; - min-width: 20px; - height: 20px; - border-radius: 10px; - border: 2px solid white; - text-align: center; - padding-left: 4px; - padding-right: 4px; - [dir="rtl"] & { - right: 40px; - left: initial; - } + position: absolute; + top: 10px; + left: 40px; + right: initial; + color: white; + background-color: black; + font-size: 10px; + min-width: 20px; + height: 20px; + border-radius: 10px; + border: 2px solid white; + text-align: center; + padding-left: 4px; + padding-right: 4px; + [dir="rtl"] & { + right: 40px; + left: initial; + } } .chat-root { - position: absolute; - left: 0px; - top: 0px; - right: 0px; - bottom: 0px; - width: 100%; - height: 100%; - padding: 0; - padding-bottom: 10px; + position: absolute; + left: 0px; + top: 0px; + right: 0px; + bottom: 0px; + width: 100%; + height: 100%; + padding: 0; + padding-bottom: 10px; + margin: 0; + + background-color: $chat-background; + overflow: hidden; + + .chat-room-invitations { + padding: 10px; + background-color: #f2f2f2; + } + + .chat-content { margin: 0; + padding-top: $chat-standard-padding-s; + padding-left: $chat-standard-padding-s; + padding-bottom: $chat-standard-padding-s; + padding-right: $chat-standard-padding-s; + overflow: hidden auto; - background-color: $chat-background; - overflow: hidden; - - .chat-room-invitations { - padding: 10px; - background-color: #f2f2f2; + &::-webkit-scrollbar { + width: 4px; + } + /* Track */ + &::-webkit-scrollbar-track { + background: #cccccc; + } + /* Handle */ + &::-webkit-scrollbar-thumb { + background: black; + } + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #4d4d4d; } - .chat-content { - margin: 0; - padding-top: $chat-standard-padding-s; - padding-left: $chat-standard-padding-s; - padding-bottom: $chat-standard-padding-s; - padding-right: $chat-standard-padding-s; - overflow: hidden auto; + @media #{map-get($display-breakpoints, 'sm-and-down')} { + margin-top: 72px; + margin-bottom: 70px; + z-index: 9; + } + } - &::-webkit-scrollbar { - width: 4px; - } - /* Track */ - &::-webkit-scrollbar-track { - background: #cccccc; - } - /* Handle */ - &::-webkit-scrollbar-thumb { - background: black; - } - /* Handle on hover */ - &::-webkit-scrollbar-thumb:hover { - background: #4d4d4d; + .input-area { + background-color: #e2e2e2; + margin: 0; + padding-left: $chat-standard-padding-s; + padding-right: $chat-standard-padding-s; + } + + .input-area-outer { + position: relative; + background-color: #ffffff; + margin: 0; + padding-left: 2 * $chat-standard-padding-s; + padding-right: 2 * $chat-standard-padding-s; + padding-top: 0; + + &.reply-to { + padding: 0; + + .reply-text { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + } + } + .iput-area-inner-box { + box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.1); + border-radius: 27px; + margin: 0px 20px; + padding: 20px; + + @media #{map-get($display-breakpoints, 'sm-and-down')} { + margin: 0px 5px; + padding: 15px; + } + } + + .typing { + font-family: "Inter", sans-serif; + font-weight: 300; + font-size: 12 * $chat-text-size; + color: #1c242a; + text-align: center; + min-height: 20px; + } + .input-area-inner { + background-color: white; + border: 1px solid #d4d4d4; + border-radius: 32px; + + @media #{map-get($display-breakpoints, 'sm-and-down')} { + margin-bottom: 2px; + } + } + .input-area-button { + margin: 0; + padding: 0; + min-width: 48px; + + &.input-more-icon { + svg { + fill: black; } @media #{map-get($display-breakpoints, 'sm-and-down')} { - margin-top: 72px; - margin-bottom: 70px; - z-index: 9; + display: none; } + } + } + .input-area-text { + max-height: 30vh; + overflow-x: hidden; + overflow-y: auto; + padding: 0 0 0px 20px; + [dir="rtl"] & { + padding: 0 20px 0px 0px; + } + margin: 6px 0; + font-family: "Inter", sans-serif; + font-weight: 300; + font-size: 18 * $chat-text-size; + .v-input__slot { + /* Remove text underline */ + color: transparent !important; + min-height: 20px; + } } - .input-area { - background-color: #e2e2e2; - margin: 0; - padding-left: $chat-standard-padding-s; - padding-right: $chat-standard-padding-s; + @media #{map-get($display-breakpoints, 'sm-and-down')} { + position: fixed; + bottom: 0px; + width: 100%; + z-index: 10; } + } - .input-area-outer { - position: relative; - background-color: #ffffff; - margin: 0; - padding-left: 2 * $chat-standard-padding-s; - padding-right: 2 * $chat-standard-padding-s; - padding-top: 0; + .scroll-to-end { + position: absolute; + top: -64px; + right: 16px; + } - &.reply-to { - padding: 0; - - .reply-text { - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 4; - -webkit-box-orient: vertical; - } - } - .iput-area-inner-box { - box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.1); - border-radius: 27px; - margin: 0px 20px; - padding: 20px; - - @media #{map-get($display-breakpoints, 'sm-and-down')} { - margin: 0px 5px; - padding: 15px; - } - } - - .typing { - font-family: "Inter", sans-serif; - font-weight: 300; - font-size: 12 * $chat-text-size; - color: #1c242a; - text-align: center; - min-height: 20px; - } - .input-area-inner { - background-color: white; - border: 1px solid #d4d4d4; - border-radius: 32px; - - @media #{map-get($display-breakpoints, 'sm-and-down')} { - margin-bottom: 2px; - } - } - .input-area-button { - margin: 0; - padding: 0; - min-width: 48px; - } - .input-area-text { - max-height: 30vh; - overflow-x: hidden; - overflow-y: auto; - padding: 0 0 0px 20px; - [dir="rtl"] & { - padding: 0 20px 0px 0px; - } - margin: 6px 0; - font-family: "Inter", sans-serif; - font-weight: 300; - font-size: 18 * $chat-text-size; - .v-input__slot { - /* Remove text underline */ - color: transparent !important; - min-height: 20px; - } - } - - @media #{map-get($display-breakpoints, 'sm-and-down')} { - position: fixed; - bottom: 0px; - width: 100%; - z-index: 10; - } - } - - .scroll-to-end { - position: absolute; - top: -64px; - right: 16px; - } - - .op-button { - position: relative; - display: inline-block; - vertical-align: top !important; - .v-icon { - color: #eeeeee; - &:hover { - color: #888888; - } - } + .op-button { + position: relative; + display: inline-block; + vertical-align: top !important; + .v-icon { + color: #eeeeee; + &:hover { + color: #888888; + } } + } } .messageJoin { - font-family: "Inter", sans-serif; - font-weight: 300; - font-size: 15 * $chat-text-size; - color: #1c242a; - text-align: center; - user-select: text; + font-family: "Inter", sans-serif; + font-weight: 300; + font-size: 15 * $chat-text-size; + color: #1c242a; + text-align: center; + user-select: text; } .message-wrapper { - position: relative; user-select: none + position: relative; + user-select: none; } .messageIn { - margin: 8px; - text-align: left; + margin: 8px; + text-align: left; + [dir="rtl"] & { + text-align: right; + } + position: relative; + .bubble { + background-color: #ededed; + border-radius: 0px 10px 10px 10px; [dir="rtl"] & { - text-align: right; + border-radius: 10px 0px 10px 0px; } + padding: 8px; + border-width: 1px !important; + border-style: solid !important; + border-color: #ededed !important; + display: inline-block; position: relative; - .bubble { - background-color: #ededed; - border-radius: 0px 10px 10px 10px; - [dir="rtl"] & { - border-radius: 10px 0px 10px 0px; - } - padding: 8px; - border-width: 1px !important; - border-style: solid !important; - border-color: #ededed !important; - display: inline-block; - position: relative; - max-width: 70%; + max-width: 70%; + } + &.from-admin .bubble { + background-color: $admin-bg; + } + .audio-bubble { + width: 70%; + height: 50px; + } + .bubble.image-bubble { + padding: 0px; + overflow: hidden; + display: inline-block; + width: 70%; + max-width: 70%; + cursor: pointer; + } + .bubble.sticker-bubble { + padding: 0px; + overflow: hidden; + display: inline-block; + width: 30%; + max-width: 30%; + background-color: transparent; + border: 0px solid transparent !important; + } + .avatar { + display: inline-block; + vertical-align: top !important; + margin-right: 10px; + [dir="rtl"] & { + margin-right: initial; + margin-left: 10px; } - &.from-admin .bubble { - background-color: $admin-bg; - } - .audio-bubble { - width: 70%; - height: 50px; - } - .bubble.image-bubble { - padding: 0px; - overflow: hidden; - display: inline-block; - width: 70%; - max-width: 70%; - cursor: pointer; - } - .bubble.sticker-bubble { - padding: 0px; - overflow: hidden; - display: inline-block; - width: 30%; - max-width: 30%; - background-color: transparent; - border: 0px solid transparent !important; - } - .avatar { - display: inline-block; - vertical-align: top !important; - margin-right: 10px; - [dir="rtl"] & { - margin-right: initial; - margin-left: 10px; - } - top: 0; - border: 2px solid white; - } - .senderAndTime { - display: block; - } - .sender { - font-family: "Inter", sans-serif; - font-weight: 400; - font-style: normal; - font-size: 10 * $chat-text-size; - color: rgba(#000000, 0.6); - margin-left: 40px; - margin-right: 8px; - [dir="rtl"] & { - margin-left: 8px; - margin-right: 40px; - } - display: inline-block; - } - .time { - font-family: "Inter", sans-serif; - font-weight: 400; - font-style: normal; - font-size: 10 * $chat-text-size; - color: rgba(#000000, 0.6); - display: inline-block; - } - .link { - color: inherit; + top: 0; + border: 2px solid white; + } + .senderAndTime { + display: block; + } + .sender { + font-family: "Inter", sans-serif; + font-weight: 400; + font-style: normal; + font-size: 10 * $chat-text-size; + color: rgba(#000000, 0.6); + margin-left: 40px; + margin-right: 8px; + [dir="rtl"] & { + margin-left: 8px; + margin-right: 40px; } + display: inline-block; + } + .time { + font-family: "Inter", sans-serif; + font-weight: 400; + font-style: normal; + font-size: 10 * $chat-text-size; + color: rgba(#000000, 0.6); + display: inline-block; + } + .link { + color: inherit; + } } .messageOut { - margin: 8px; - text-align: right; + margin: 8px; + text-align: right; + [dir="rtl"] & { + text-align: left; + } + position: relative; + .bubble { + background-color: #e5e5e5; + border-radius: 10px 10px 0 10px; [dir="rtl"] & { - text-align: left; + border-radius: 10px 10px 10px 0px; } + padding: 8px; + display: inline-block; position: relative; - .bubble { - background-color: #e5e5e5; - border-radius: 10px 10px 0 10px; - [dir="rtl"] & { - border-radius: 10px 10px 10px 0px; - } - padding: 8px; - display: inline-block; - position: relative; - max-width: 70%; + max-width: 70%; + } + .audio-bubble { + background-color: #e5e5e5; + border-radius: 10px 10px 0 10px; + [dir="rtl"] & { + border-radius: 10px 10px 10px 0px; } - .audio-bubble { - background-color: #e5e5e5; - border-radius: 10px 10px 0 10px; - [dir="rtl"] & { - border-radius: 10px 10px 10px 0px; - } - padding: 8px; - display: inline-block; - position: relative; - max-width: 70%; - width: 70%; - height: 50px; + padding: 8px; + display: inline-block; + position: relative; + max-width: 70%; + width: 70%; + height: 50px; + } + .video2-bubble { + background-color: #e5e5e5; + border-radius: 10px 10px 0 10px; + [dir="rtl"] & { + border-radius: 10px 10px 10px 0px; } - .video2-bubble { - background-color: #e5e5e5; - border-radius: 10px 10px 0 10px; - [dir="rtl"] & { - border-radius: 10px 10px 10px 0px; - } - } - .bubble.image-bubble { - padding: 0px; - display: inline-block; - width: 70%; - max-width: 70%; - cursor: pointer; + } + .bubble.image-bubble { + padding: 0px; + display: inline-block; + width: 70%; + max-width: 70%; + cursor: pointer; - .v-image, video { - border-radius: 10px 10px 0 10px; - [dir="rtl"] & { - border-radius: 10px 10px 10px 0px; - } - } + .v-image, + video { + border-radius: 10px 10px 0 10px; + [dir="rtl"] & { + border-radius: 10px 10px 10px 0px; + } } - .bubble.sticker-bubble { - padding: 0px; - display: inline-block; - width: 30%; - max-width: 30%; - background-color: transparent; + } + .bubble.sticker-bubble { + padding: 0px; + display: inline-block; + width: 30%; + max-width: 30%; + background-color: transparent; + } + .avatar { + display: inline-block; + vertical-align: bottom !important; + margin-left: 10px; + [dir="rtl"] & { + margin-left: initial; + margin-right: 10px; } - .avatar { - display: inline-block; - vertical-align: bottom !important; - margin-left: 10px; - [dir="rtl"] & { - margin-left: initial; - margin-right: 10px; - } - bottom: 0; - border: 2px solid white; - } - .senderAndTime { - display: block; - } - .sender { - font-family: "Inter", sans-serif; - font-weight: 400; - font-style: normal; - font-size: 10 * $chat-text-size; - color: rgba(#000000, 0.6); - display: inline-block; - margin-left: 40px; - margin-right: 8px; - [dir="rtl"] & { - margin-left: 8px; - margin-right: 40px; - } - } - .time { - font-family: "Inter", sans-serif; - font-weight: 400; - font-style: normal; - font-size: 10 * $chat-text-size; - color: rgba(#000000, 0.6); - display: inline-block; - } - .link { - color: inherit; + bottom: 0; + border: 2px solid white; + } + .senderAndTime { + display: block; + } + .sender { + font-family: "Inter", sans-serif; + font-weight: 400; + font-style: normal; + font-size: 10 * $chat-text-size; + color: rgba(#000000, 0.6); + display: inline-block; + margin-left: 40px; + margin-right: 8px; + [dir="rtl"] & { + margin-left: 8px; + margin-right: 40px; } + } + .time { + font-family: "Inter", sans-serif; + font-weight: 400; + font-style: normal; + font-size: 10 * $chat-text-size; + color: rgba(#000000, 0.6); + display: inline-block; + } + .link { + color: inherit; + } } .sender, .status { - font-family: "Inter", sans-serif; - font-weight: 300; - font-size: 15 * $chat-text-size; - color: #1c242a; - margin-bottom: 4px; + font-family: "Inter", sans-serif; + font-weight: 300; + font-size: 15 * $chat-text-size; + color: #1c242a; + margin-bottom: 4px; } .message { + font-family: "Inter", sans-serif; + font-weight: 400; + font-size: 16 * $chat-text-size; + color: #000000; + overflow-wrap: break-word; + word-wrap: break-word; + white-space: pre-wrap; + .edit-marker { + font-size: 0.8rem; + color: #888888; + } + .from-admin & { + color: $admin-fg; + } + user-select: text; +} + +.original-message { + background-color: white; + border: 1px solid black; + border-radius: 10px; + padding: 8px; + max-height: 200px; + overflow-x: hidden; + overflow-y: auto; + margin-bottom: 8px; + user-select: text; + .original-message-sender { + font-family: "Inter", sans-serif; + font-weight: 700; + font-size: 13 * $chat-text-size; + color: #000000; + overflow-wrap: break-word; + white-space: pre; + } + .original-message-text { font-family: "Inter", sans-serif; font-weight: 400; - font-size: 16 * $chat-text-size; + font-size: 11 * $chat-text-size; color: #000000; overflow-wrap: break-word; word-wrap: break-word; white-space: pre-wrap; - .edit-marker { - font-size: 0.8rem; - color: #888888; - } - .from-admin & { - color: $admin-fg; - } - user-select: text; -} - -.original-message { - background-color: white; - border: 1px solid black; - border-radius: 10px; - padding: 8px; - max-height: 200px; - overflow-x: hidden; - overflow-y: auto; - margin-bottom: 8px; - user-select: text; - .original-message-sender { - font-family: "Inter", sans-serif; - font-weight: 700; - font-size: 13 * $chat-text-size; - color: #000000; - overflow-wrap: break-word; - white-space: pre; - } - .original-message-text { - font-family: "Inter", sans-serif; - font-weight: 400; - font-size: 11 * $chat-text-size; - color: #000000; - overflow-wrap: break-word; - word-wrap: break-word; - white-space: pre-wrap; - } + } } .time { - font-family: "Inter", sans-serif; - font-weight: 300; - font-style: italic; - font-size: 15 * $chat-text-size; - color: #1c242a; - display: inline-block; + font-family: "Inter", sans-serif; + font-weight: 300; + font-style: italic; + font-size: 15 * $chat-text-size; + color: #1c242a; + display: inline-block; } .statusEvent { - font-family: "Inter", sans-serif; - font-weight: 300; - font-size: 15 * $chat-text-size; - color: #1c242a; - text-align: center; - margin: 20px; - user-select: text; - overflow-wrap: break-word; - word-break: break-word; + font-family: "Inter", sans-serif; + font-weight: 300; + font-size: 15 * $chat-text-size; + color: #1c242a; + text-align: center; + margin: 20px; + user-select: text; + overflow-wrap: break-word; + word-break: break-word; } .notice { - font-family: "Inter", sans-serif; - font-weight: 300; - font-size: 15 * $chat-text-size; - background-color: #090909; - color: white; - text-align: start; - margin: 20px; - user-select: text; - padding: 16px; - border-radius: 20px; + font-family: "Inter", sans-serif; + font-weight: 300; + font-size: 15 * $chat-text-size; + background-color: #090909; + color: white; + text-align: start; + margin: 20px; + user-select: text; + padding: 16px; + border-radius: 20px; } .audio-player { - width: 100%; - position: absolute; + width: 100%; + position: absolute; + .currentColor { + background-color: #000000 !important; + } + .v-icon { + color: black !important; + } + .from-admin & { + color: $admin-fg; .currentColor { - background-color: #000000 !important; + background-color: #555555 !important; } .v-icon { - color: black !important; + color: white !important; } - .from-admin & { - color: $admin-fg; - .currentColor { - background-color: #555555 !important; - } - .v-icon { - color: white !important; - } - } - .play-time { - font-family: "Inter", sans-serif; - font-weight: 400; - font-size: 13 * $chat-text-size; - flex: 1 0 80px; - } - .play-progress { - padding: 0px 10px; - flex: 1 1 100%; - height: 30px; + } + .play-time { + font-family: "Inter", sans-serif; + font-weight: 400; + font-size: 13 * $chat-text-size; + flex: 1 0 80px; + } + .play-progress { + padding: 0px 10px; + flex: 1 1 100%; + height: 30px; - .v-slider__thumb { - display: none; - } - &:hover .v-slider__thumb { - display: block; - } + .v-slider__thumb { + display: none; } + &:hover .v-slider__thumb { + display: block; + } + } } .message-operations-strut, .avatar-operations-strut { - position: relative; - height: 0px; + position: relative; + height: 0px; - z-index: 1; + z-index: 1; } .message-operations { - position: absolute; - width: fit-content; - background-color: white; - height: 34px; - border-radius: 22px; - box-shadow: 4px 4px 8px rgba(0,0,0,0.15); + position: absolute; + width: fit-content; + background-color: white; + height: 34px; + border-radius: 22px; + box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.15); } .avatar-operations { - position: absolute; - width: fit-content; - background-color: white; - height: 40px; - border-radius: 20px; - padding: 0px 20px; - box-shadow: 4px 4px 8px rgba(0,0,0,0.15); + position: absolute; + width: fit-content; + background-color: white; + height: 40px; + border-radius: 20px; + padding: 0px 20px; + box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.15); } .send-options { - z-index: 11; // Above mic button + z-index: 11; // Above mic button } .message-operations-picker { - background-color: white; - text-align: center; + background-color: white; + text-align: center; } .quick-reaction-container { - display: inline-block; + display: inline-block; + position: relative; + vertical-align: bottom; + transform: translateX(-20px) translateX(-100%); + top: 18px; + z-index: 2; + background-color: #f7f7f7; + border: 1px solid rgba(white, 0.9); + border-radius: 13px; + height: 26px; + width: max-content; + padding: 0px 6px; + .messageOut & { + transform: translateX(20px) translateX(100%); + } + .quick-reaction { position: relative; - vertical-align: bottom; - transform: translateX(-20px) translateX(-100%); - top: 18px; - z-index: 2; - background-color: #f7f7f7; - border: 1px solid rgba(white, 0.9); - border-radius: 13px; - height: 26px; - width: max-content; - padding: 0px 6px; - .messageOut & { - transform: translateX(20px) translateX(100%); + top: -2px; + margin: 0px 0px; + padding: 1px; + font-size: 10px; + &:hover { + //border: 1px solid #888888; + background-color: #e2e2e2; } - .quick-reaction { - position: relative; - top: -2px; - margin: 0px 0px; - padding: 1px; - font-size: 10px; - &:hover { - //border: 1px solid #888888; - background-color: #e2e2e2; - } - .quick-reaction-count { - color: #888888; - font-size: 0.7rem; - } - } - .sent .quick-reaction-count { - color: black; - font-weight: 700; - // background-color: palegreen; + .quick-reaction-count { + color: #888888; + font-size: 0.7rem; } + } + .sent .quick-reaction-count { + color: black; + font-weight: 700; + // background-color: palegreen; + } } .download-overlay { - position: absolute; - left: 0; - top: 0; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.4); + align-items: center; + display: flex; + .download-text { width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.4); - align-items: center; - display: flex; - .download-text { - width: 100%; - color: white; - } + color: white; + } } .room-name, .room-name-inline { - font-family: "Poppins", sans-serif; - font-weight: 700; - font-size: 18 * $chat-text-size; - text-transform: uppercase; - color: black; - text-align: center; + font-family: "Poppins", sans-serif; + font-weight: 700; + font-size: 18 * $chat-text-size; + text-transform: uppercase; + color: black; + text-align: center; } .room-name-inline { - text-align: start; + text-align: start; } .room-name.no-upper { - text-transform: none; + text-transform: none; } .read-marker { - margin-left: 20px; - margin-right: 20px; - height: 1px; - width: calc(100% - 40px); - line-height: var(--v-theme-title-featured-line-height); + margin-left: 20px; + margin-right: 20px; + height: 1px; + width: calc(100% - 40px); + line-height: var(--v-theme-title-featured-line-height); + position: absolute; + bottom: 0; + font-family: sans-serif; + font-style: normal; + font-weight: normal; + font-size: 8 * $chat-text-size; + line-height: 140%; + /* identical to box height, or 14px */ + letter-spacing: 0.29px; + color: #c0c0c0; + background-color: #c0c0c0; + text-align: center; + &::after { position: absolute; - bottom: 0; - font-family: sans-serif; - font-style: normal; - font-weight: normal; - font-size: 8 * $chat-text-size; - line-height: 140%; - /* identical to box height, or 14px */ - letter-spacing: 0.29px; - color: #c0c0c0; - background-color: #c0c0c0; - text-align: center; - &::after { - position: absolute; - top: -4px; - background: white; - transform: translate(-50%, 0); - [dir="rtl"] & { - transform: translate(50%, 0); - } - padding-left: 4px; - padding-right: 4px; - content: attr(title); + top: -4px; + background: white; + transform: translate(-50%, 0); + [dir="rtl"] & { + transform: translate(50%, 0); } + padding-left: 4px; + padding-right: 4px; + content: attr(title); + } } .day-marker { - margin-left: 20px; - margin-right: 20px; - margin-top: 20px; - margin-bottom: 20px; - height: 1px; - line-height: var(--v-theme-title-featured-line-height); - font-family: sans-serif; - font-style: normal; - font-weight: normal; - font-size: 10 * $chat-text-size; - line-height: 140%; - /* identical to box height, or 14px */ - letter-spacing: 0.29px; - color: black; - background-color: black; - text-align: center; - position: relative; - &::after { - position: absolute; - top: -8px; - background: white; - transform: translate(-50%, 0); - [dir="rtl"] & { - transform: translate(50%, 0); - } - padding-left: 10px; - padding-right: 10px; - content: attr(title); + margin-left: 20px; + margin-right: 20px; + margin-top: 20px; + margin-bottom: 20px; + height: 1px; + line-height: var(--v-theme-title-featured-line-height); + font-family: sans-serif; + font-style: normal; + font-weight: normal; + font-size: 10 * $chat-text-size; + line-height: 140%; + /* identical to box height, or 14px */ + letter-spacing: 0.29px; + color: black; + background-color: black; + text-align: center; + position: relative; + &::after { + position: absolute; + top: -8px; + background: white; + transform: translate(-50%, 0); + [dir="rtl"] & { + transform: translate(50%, 0); } + padding-left: 10px; + padding-right: 10px; + content: attr(title); + } } .room-info { - background-color: #e8e8e8; - height: 100%; - .chat-header { - background-color: transparent; - border: none; - position: relative; + background-color: #e8e8e8; + height: 100%; + .chat-header { + background-color: transparent; + border: none; + position: relative; + } + + .room-avatar { + background-color: #ededed; + width: 64px !important; + height: 64px !important; + margin-bottom: 20px; + .headline { + font-size: 70 * $chat-text-size !important; + } + } + + .name { + font-family: "Poppins", sans-serif; + font-size: 32px; + font-weight: 800; + } + + .topic { + font-family: "Inter", sans-serif; + font-size: 16px; + } + + .created-by { + font-family: "Poppins", sans-serif; + font-size: 12px; + font-weight: bold; + } + + .avatar .headline { + font-size: 16 * $chat-text-size !important; + } + + .qr-container { + background-color: white; + border-radius: 8px; + margin-top: 20px !important; + .qr { + width: 60px; + height: 60px; + background-color: #e0e0e0; + } + .link { + font-family: "Inter", sans-serif; + font-size: 16px; + text-decoration: underline; + color: #3d6eff; + overflow-wrap: anywhere; + } + } + .link-copied-in-place .v-btn__content { + font-family: "Inter", sans-serif !important; + font-size: 12px !important; + text-transform: none !important; + color: #3d6eff; + } + + .filled-button { + @media #{map-get($display-breakpoints, 'sm-and-up')} { + min-width: 180px !important; + } + } + + .v-card { + background-color: white; + border-radius: 20px; + } + + .member .user-name { + margin-left: 6px; + } + + .member .start-private-chat { + margin-left: 38px; + } + + .member::after { + content: " "; + display: block; + margin: 10px 0px; + bottom: 0px; + height: 1px; + background-color: #e1e1e1; + width: 100%; + } + + .show-all { + color: black; + font-size: 14 * $chat-text-size; + font-weight: bold; + margin-left: 10px; + [dir="rtl"] & { + margin-left: initial; + margin-right: 10px; } - .room-avatar { - background-color: #ededed; - width: 64px !important; - height: 64px !important; - margin-bottom: 20px; - .headline { - font-size: 70 * $chat-text-size !important; - } - } - - .name { - font-family: "Poppins", sans-serif; - font-size: 32px; - font-weight: 800; - } - - .topic { - font-family: "Inter", sans-serif; - font-size: 16px; - } - - .created-by { - font-family: "Poppins", sans-serif; - font-size: 12px; - font-weight: bold; - } - - .avatar .headline { - font-size: 16 * $chat-text-size !important; - } - - .qr-container { - background-color: white; - border-radius: 8px; - margin-top: 20px !important; - .qr { - width: 60px; - height: 60px; - background-color: #e0e0e0; - } - .link { - font-family: "Inter", sans-serif; - font-size: 16px; - text-decoration: underline; - color: #3d6eff; - overflow-wrap: anywhere; - } - } - .link-copied-in-place .v-btn__content { - font-family: "Inter", sans-serif !important; - font-size: 12px !important; - text-transform: none !important; - color: #3d6eff; - } - - .filled-button { - @media #{map-get($display-breakpoints, 'sm-and-up')} { - min-width: 180px !important; - } - } - - .v-card { - background-color: white; - border-radius: 20px; - } - - .member .user-name { - margin-left: 6px; - } - - .member .start-private-chat { - margin-left: 38px; - } - - .member::after { - content: " "; - display: block; - margin: 10px 0px; - bottom: 0px; - height: 1px; - background-color: #e1e1e1; - width: 100%; - } - - .show-all { - color: black; - font-size: 14 * $chat-text-size; - font-weight: bold; - margin-left: 10px; - [dir="rtl"] & { - margin-left: initial; - margin-right: 10px; - } - - text-decoration: underline; - } + text-decoration: underline; + } } .header-button-left { - position: absolute; - top: 0px; - left: 0px; - margin: 10px 0px; - font-weight: bold; - font-size: 12 * $chat-text-size; - [dir="rtl"] & { - right: 0px; - left: unset; - .v-icon { - // Mirror the icon - transform: scale(-1, 1); - } + position: absolute; + top: 0px; + left: 0px; + margin: 10px 0px; + font-weight: bold; + font-size: 12 * $chat-text-size; + [dir="rtl"] & { + right: 0px; + left: unset; + .v-icon { + // Mirror the icon + transform: scale(-1, 1); } + } } .header-button-right { - position: absolute; - top: 0px; - right: 0px; - [dir="rtl"] & { - left: 0px; - right: unset; - } - margin: 10px 0px; - font-weight: bold; - font-size: 12 * $chat-text-size; + position: absolute; + top: 0px; + right: 0px; + [dir="rtl"] & { + left: 0px; + right: unset; + } + margin: 10px 0px; + font-weight: bold; + font-size: 12 * $chat-text-size; } .profile { + background-color: white; + height: 100%; + .chat-header { + background-color: transparent; + border: none; + position: relative; + } + .v-card { background-color: white; - height: 100%; - .chat-header { - background-color: transparent; - border: none; - position: relative; - } - .v-card { - background-color: white; - border-radius: 20px; - } + border-radius: 20px; + } - .user-info { - display: flex; - flex-wrap: nowrap; - max-width: 80%; - } + .user-info { + display: flex; + flex-wrap: nowrap; + max-width: 80%; + } - .show-all { - color: black; - font-size: 14 * $chat-text-size; - font-weight: bold; - margin-left: 10px; - [dir="rtl"] & { - margin-left: initial; - margin-right: 10px; - } + .show-all { + color: black; + font-size: 14 * $chat-text-size; + font-weight: bold; + margin-left: 10px; + [dir="rtl"] & { + margin-left: initial; + margin-right: 10px; } + } } .action-row { - padding: 4px 20px; - cursor: pointer; - height: 55px; - font-family: "Inter", sans-serif; - font-size: 19px; - color: black; - position: relative; - .v-icon { - color: black !important; - } - &:not(:last-of-type):after { - /* divider */ - position: absolute; - content: " "; - display: block; - margin: 0px 10px; - bottom: 0px; - height: 1px; - background-color: #e1e1e1; - width: 100%; - } + padding: 4px 20px; + cursor: pointer; + height: 55px; + font-family: "Inter", sans-serif; + font-size: 19px; + color: black; + position: relative; + .v-icon { + color: black !important; + } + &:not(:last-of-type):after { + /* divider */ + position: absolute; + content: " "; + display: block; + margin: 0px 10px; + bottom: 0px; + height: 1px; + background-color: #e1e1e1; + width: 100%; + } } .mic-button { - z-index: 10; - background-color: transparent !important; - &.waiting-for-long-tap { - transition: background-color 0.5s; - background-color: black !important; - .v-icon { - color: white !important; - } + z-index: 10; + background-color: transparent !important; + &.waiting-for-long-tap { + transition: background-color 0.5s; + background-color: black !important; + .v-icon { + color: white !important; } + } } .voice-recorder { - position: relative; - margin-top: 14px !important; - &.ptt { - position: absolute; - left: 10px; - bottom: 0px; - right: 10px; - } - border-radius: 10px; - background-color: black; - overflow: hidden; + position: relative; + margin-top: 14px !important; + &.ptt { + position: absolute; + left: 10px; + bottom: 0px; + right: 10px; + } + border-radius: 10px; + background-color: black; + overflow: hidden; - .will-cancel, .locked, .error { - position: absolute !important; - top: 0 ; - left: 0; - right: 0; - bottom: 0 + .will-cancel, + .locked, + .error { + position: absolute !important; + top: 0; + left: 0; + right: 0; + bottom: 0; + } + .will-cancel { + background-color: #ff3300; + } + .recording-time { + color: white; + } + .swipe-info { + color: white; + } + .locked { + background-color: black; + } + .error { + background-color: orange; + } + .voice-recorder-lock { + position: relative; + margin-left: 10px; + margin-right: 10px; + width: 20px; + height: 100%; + border: 1px solid black; + border-radius: 10px; + background-color: rgba(white, 0.3); + &.locked { + background-color: rgba(white, 0.8); } - .will-cancel { - background-color: #ff3300; - } - .recording-time { - color: white; - } - .swipe-info { - color: white; - } - .locked { - background-color: black; - } - .error { - background-color: orange; - } - .voice-recorder-lock { - position: relative; - margin-left: 10px; - margin-right: 10px; - width: 20px; - height: 100%; - border: 1px solid black; - border-radius: 10px; - background-color: rgba(white, 0.3); - &.locked { - background-color: rgba(white, 0.8); - } - .thumb { - width: 16px; - height: 16px; - background-color: black; - border-radius: 8px; - position: absolute; - bottom: 1px; - left: 1px; - &.locked { - top: 1px; - bottom: unset; - } - } + .thumb { + width: 16px; + height: 16px; + background-color: black; + border-radius: 8px; + position: absolute; + bottom: 1px; + left: 1px; + &.locked { + top: 1px; + bottom: unset; + } } + } } .bottom-sheet .card { - z-index: 10; /* Above mic button etc. */ - background-color: white; - padding: 10px; + z-index: 10; /* Above mic button etc. */ + background-color: white; + padding: 10px; } .room-info-sheet { - background-color: white; + background-color: white; - .current-room { - padding: 25px; - background: linear-gradient(180deg, #ffffff 0%, rgba(255, 255, 255, 0) 100%), #f5f5f7; - box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.15); - border-radius: 18px; - } + .current-room { + padding: 25px; + background: linear-gradient(180deg, #ffffff 0%, rgba(255, 255, 255, 0) 100%), #f5f5f7; + box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.15); + border-radius: 18px; + } - .room-avatar { - background-color: #ededed; - width: 44px !important; - height: 44px !important; - margin-bottom: 20px; - .headline { - font-size: 70 * $chat-text-size !important; - } + .room-avatar { + background-color: #ededed; + width: 44px !important; + height: 44px !important; + margin-bottom: 20px; + .headline { + font-size: 70 * $chat-text-size !important; } + } } .create-room { - background-color: $background; + background-color: $background; - .v-avatar { - border: 1px solid #808080 !important; - } + .v-avatar { + border: 1px solid #808080 !important; + } - .section { - background-color: white; - border-radius: 20px; - padding: 20px; - border: 1px solid #808080 !important; - position: relative; - } + .section { + background-color: white; + border-radius: 20px; + padding: 20px; + border: 1px solid #808080 !important; + position: relative; + } } .room-link .v-input__slot::before { - /* Remove text underline */ - border-style: none !important; + /* Remove text underline */ + border-style: none !important; } .created-room-welcome-header { - background-color: #f5f5f5; - border-radius: 25px; - margin: 20px; - padding: 20px; + background-color: #f5f5f5; + border-radius: 25px; + margin: 20px; + padding: 20px; } .link-copied { - position: absolute; - bottom: 10px; - left: 20%; - right: 20%; - background-color: #888888; - height: 40px; - border-radius: 25px; - color: white; - text-align: center; - vertical-align: middle; - padding-top: 10px; + position: absolute; + bottom: 10px; + left: 20%; + right: 20%; + background-color: #888888; + height: 40px; + border-radius: 25px; + color: white; + text-align: center; + vertical-align: middle; + padding-top: 10px; } .avatar-22 { - font-size: 14 * $chat-text-size !important; + font-size: 14 * $chat-text-size !important; } .avatar-32 { - font-size: 18 * $chat-text-size !important; + font-size: 18 * $chat-text-size !important; } .avatar-48 { - font-size: 27 * $chat-text-size !important; + font-size: 27 * $chat-text-size !important; } .avatar-32.clickable, .avatar-48.clickable, .clickable { - cursor: pointer; - &:hover { - opacity: 0.7; - } + cursor: pointer; + &:hover { + opacity: 0.7; + } } .new-room { - font-family: "Inter", sans-serif; - font-size: 16px !important; - font-weight: 600 !important; - text-decoration: underline; - color: black; - &::after { - content: "\00a0\00a0>"; - display: inline-block; - text-decoration: none !important; - } + font-family: "Inter", sans-serif; + font-size: 16px !important; + font-weight: 600 !important; + text-decoration: underline; + color: black; + &::after { + content: "\00a0\00a0>"; + display: inline-block; + text-decoration: none !important; + } } .recent-emoji { - color: black; + color: black; } .current-image-input-path { - max-height: 50vh; - background-color: #e2e2e2 + max-height: 50vh; + background-color: #e2e2e2; } .loading-indicator { - position: absolute; - background-color: rgba(0, 0, 0, 0.2); + position: absolute; + background-color: rgba(0, 0, 0, 0.2); } .exporting-indicator { - position: absolute; - background-color: white; -} \ No newline at end of file + position: absolute; + background-color: white; +} + +.toast { + position: absolute; + bottom: 68px; + left: 8px; + right: 8px; + height: 48px; + background: rgba(0, 0, 0, 0.69); + border: 1px solid #000000; + border-radius: 5px; + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 20px; + text-align: center; + letter-spacing: 0.25px; + color: #ffffff; + opacity: 1; + transition: opacity 0.3s linear; +} diff --git a/src/assets/css/components/_poll.scss b/src/assets/css/components/_poll.scss index 948bb65..5b1ef54 100644 --- a/src/assets/css/components/_poll.scss +++ b/src/assets/css/components/_poll.scss @@ -1,5 +1,6 @@ .poll-bubble { width: 70%; + text-align: start; } .poll-bubble { @@ -36,6 +37,7 @@ border-radius: 4px; padding: 15px 14px; margin: 0px; + height: 48px; &.winner { font-weight: 700; } @@ -77,40 +79,189 @@ .poll-status { justify-content: space-between; + align-items: flex-start; font-size: 13px; line-height: 117%; - margin: 0px; + margin: 17px 0px 0px 0px; .poll-status-title { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 117%; + display: flex; + align-items: center; + letter-spacing: 0.4px; + color: #1d1d1d; + opacity: 0.8; + .from-admin & { + color: white; + } } .poll-status-close { - color: $poll-hilite-color; + background: transparent; + border: 1px solid #000000; + border-radius: 32px; + font-family: "Inter"; + font-style: normal; + font-weight: 700; + font-size: 10px; + line-height: 133%; + letter-spacing: 0.34px; + text-transform: uppercase; + color: #181719; + padding: 7px 14px; + text-align: center; + } + + .poll-status-closed { + background: white; + border-radius: 32px; + font-family: "Inter"; + font-style: normal; + font-weight: 700; + font-size: 10px; + line-height: 133%; + letter-spacing: 0.34px; + text-transform: uppercase; + color: #181719; + padding: 7px 14px; + display: flex; + align-items: center; + justify-content: center; + .icon { + width: 9px; + height: 8px; + margin-right: 3px; + } } } .poll-submit { - .v-btn { - font-family: "Inter", sans-serif; - font-weight: 700; - font-size: 11 * $chat-text-size; - color: white; - text-transform: uppercase; - background-color: $poll-hilite-color !important; - border: 1px solid black; - border-radius: 21px !important; - height: 42px !important; - margin-top: $chat-standard-padding-xs; - margin-bottom: $chat-standard-padding-xs; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(0deg, #6360f0, #6360f0), #536dfe; + border-radius: 32px; + font-family: "Inter"; + font-style: normal; + font-weight: 700; + font-size: 11.5411px; + line-height: 140%; + text-align: center; + letter-spacing: 0.34px; + text-transform: uppercase; + color: #ffffff; + padding: 14px 18px; + color: white; + text-transform: uppercase; + height: 42px; +} + +.poll-disclose { + height: 18px; + margin: 0; + padding: 0; + font-family: "Inter"; + font-style: normal; + font-weight: 500; + font-size: 12px; + line-height: 100%; + display: flex; + align-items: center; + letter-spacing: 0.4px; + color: #1d1d1d; + opacity: 0.8; + .poll-disclose-track { + position: relative; + width: 30px; + height: 18px; + background: #ededed; + border-radius: 16px; + transform: rotate(180deg); + margin-left: 8px; + transition: background-color 0.3s linear; + .poll-disclose-knob { + position: absolute; + background: #ffffff; + box-shadow: 0px 3px 7px rgba(0, 0, 0, 0.12); + border-radius: 16px; + transform: rotate(180deg); + width: 16px; + right: 1px; + top: 1px; + bottom: 1px; + transition: right 0.3s linear; + } + } + + &.selected .poll-disclose-track { + background: #1d1d1d; + .poll-disclose-knob { + right: 13px; + } } } // Creation dialog // -.poll-create-dialog-content { - max-height: 50vh; +.poll-create { overflow-x: hidden; overflow-y: auto; -} -.poll-create-status { - font-size: 0.7rem; + .poll-create-dialog-content { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-size: 16px; + line-height: 117%; + letter-spacing: 0.4px; + color: rgba(0, 0, 0, 0.7); + + .add-answer-button { + border-radius: 4px; + height: 48px; + width: 100%; + overflow: hidden; + border: 1px solid #242424; + display: flex; + align-items: center; + justify-content: center; + opacity: 1; + transition: opacity 1s linear, height 0.3s linear; + &.hidden { + opacity: 0; + height: 0; + transition: opacity 0s linear, height 0s linear; + } + img { + width: 14.88px; + height: 14.88px; + object-fit: contain; + } + } + } + .filled-button.publish-button { + background: linear-gradient(0deg, #6360f0, #6360f0), #536dfe !important; + padding-left: 30px; + padding-right: 30px; + height: 42px !important; + border-radius: 32px; + } + .tip { + font-family: "Inter"; + font-style: normal; + font-size: 13px; + line-height: 117%; + letter-spacing: 0.4px; + color: #1d1d1d; + opacity: 0.8; + text-align: left; + b { + margin-right: 4px; + } + } + .poll-create-status { + font-size: 0.7rem; + } } diff --git a/src/assets/icons/ic_add.svg b/src/assets/icons/ic_add.svg new file mode 100644 index 0000000..f7efc88 --- /dev/null +++ b/src/assets/icons/ic_add.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/ic_check_small.svg b/src/assets/icons/ic_check_small.svg new file mode 100644 index 0000000..36e9a13 --- /dev/null +++ b/src/assets/icons/ic_check_small.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/translations/bo.json b/src/assets/translations/bo.json index fdc284a..869bf1c 100644 --- a/src/assets/translations/bo.json +++ b/src/assets/translations/bo.json @@ -214,6 +214,9 @@ "text_public": "གལ་ཏེ་ཁྱེད་ཀྱིས་འབྲེལ་ཐག་དེ་ཧ་གོ་ཚེ། ག་དུས་ཡིན་ཡང་། ཁ་བརྡ་ཁང་དུ་འཛུལ་ཆོག", "title_public": "{user} ག་ལེེར་བཞུགས།" }, + "logout": { + "confirm_text": "" + }, "join": { "status_joining": "ཁ་བརྡ་ཁང་དུ་འཛུལ་བཞིན་པ།...", "status_logging_in": "ནང་འཛུལ་བྱེད་བཞིན་པ།...", diff --git a/src/assets/translations/de.json b/src/assets/translations/de.json index 4a6e776..9b9bfc5 100644 --- a/src/assets/translations/de.json +++ b/src/assets/translations/de.json @@ -165,6 +165,9 @@ "leave": "Verlassen", "title_invite": "Bist du sicher, dass du gehen willst?" }, + "logout": { + "confirm_text": "" + }, "purge_room": { "info": "Alle Mitglieder und Nachrichten werden entfernt. Diese Aktion kann nicht rückgängig gemacht werden.", "button": "Löschen", diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index 45a13bb..a8a29df 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -179,6 +179,9 @@ "go_back": "Go back", "leave": "Leave" }, + "logout": { + "confirm_text": "Are you sure you want to logout ?" + }, "purge_room": { "title": "Delete room?", "info": "All members and messages will be removed. This action cannot be undone.", @@ -238,26 +241,31 @@ "download_name": "Download" }, "poll_create": { - "title": "Create poll", - "intro": "Please fill in details below.", - "create": "Create", + "title": "New Poll", + "create": "Publish", "creating": "Creating poll", "poll_disclosed": "Open - current results are shown at all times.", "poll_undisclosed": "Closed - users will see the results when poll is closed.", "add_answer": "Add answer", "failed": "Failed to create poll, please try again later.", - "question_label": "Type your question here", + "question_label": "Ask your question*", "question_required": "You need to enter a question!", - "answer_label": "Answer no {index}", + "answer_label_1": "Answer*", + "answer_label_n": "Answer", + "please_complete": "Please complete", "answer_required": "Answer can't be empty. Please enter some text or remove this option.", + "tip_title": "PRO TIP", + "tip_text": "Members will see the poll results after they answer. Close the poll when you're done to show results to everyone in the room..", "create_poll_menu_option": "Create poll", "poll_status_closed": "Poll is closed", "poll_status_disclosed": "Results will be shown when poll is closed.", "poll_status_open": "Poll is open", "poll_status_open_not_voted": "Poll is open - vote to see the results", + "view_results": "View Results", "close_poll": "Close poll", "poll_submit": "Submit", - "num_answered": "{count} have answered" + "num_answered": "{count} answers", + "results_shared": "Results shared to the room." }, "export": { "exported_date": "Exported on {date}", diff --git a/src/assets/translations/es.json b/src/assets/translations/es.json index b4b178b..6fbbbc8 100644 --- a/src/assets/translations/es.json +++ b/src/assets/translations/es.json @@ -47,6 +47,9 @@ "text_public": "Siempre puedes volver a unirte a esta sala si conoces el enlace.", "title_public": "Adios, [user}" }, + "logout": { + "confirm_text": "" + }, "invite": { "status_error": "No se pudo invitar a uno o más amigos!", "status_inviting": "Invitando amigo {index} de {count}", diff --git a/src/assets/translations/fi.json b/src/assets/translations/fi.json index faa21ea..c33d955 100644 --- a/src/assets/translations/fi.json +++ b/src/assets/translations/fi.json @@ -84,6 +84,9 @@ "leave": "Poistu", "text_invite": "Tämä huone on lukittu. Et pääse takaisin ilman erillistä lupaa." }, + "logout": { + "confirm_text": "" + }, "message": { "you": "Sinä", "user_created_room": "{user} loi huoneen", diff --git a/src/assets/translations/fr.json b/src/assets/translations/fr.json index 79b2a50..ac102b0 100644 --- a/src/assets/translations/fr.json +++ b/src/assets/translations/fr.json @@ -165,6 +165,9 @@ "text_invite": "Ce salon est verrouillé. Vous ne pouvez pas le rejoindre sans une autorisation spéciale.", "go_back": "Retour" }, + "logout": { + "confirm_text": "" + }, "purge_room": { "title": "Supprimer le salon ?", "info": "Tous les membres et les messages seront supprimés. Cette action ne peut être annulée.", diff --git a/src/assets/translations/it.json b/src/assets/translations/it.json index ef969aa..d061c6c 100644 --- a/src/assets/translations/it.json +++ b/src/assets/translations/it.json @@ -164,6 +164,9 @@ "leave": "Lascia", "text_public_lastroom": "Se vuoi unirti di nuovo a questa stanza, puoi farlo con una nuova identità. Per mantenere {user}, {action}." }, + "logout": { + "confirm_text": "" + }, "purge_room": { "info": "Tutti i membri e i messaggi saranno rimossi. Questa azione non può essere annullata.", "button": "Elimina", diff --git a/src/assets/translations/nb_NO.json b/src/assets/translations/nb_NO.json index 9f14738..c7e9596 100644 --- a/src/assets/translations/nb_NO.json +++ b/src/assets/translations/nb_NO.json @@ -139,6 +139,9 @@ "create_account": "opprett en konto", "title_public": "Adjø, {user}" }, + "logout": { + "confirm_text": "" + }, "invite": { "status_inviting": "Inviterer venn {index} av {count}", "send_invites_to": "Send invitasjoner til", diff --git a/src/assets/translations/pt_BR.json b/src/assets/translations/pt_BR.json index c24a0d1..5ff1079 100644 --- a/src/assets/translations/pt_BR.json +++ b/src/assets/translations/pt_BR.json @@ -118,7 +118,7 @@ "status_creating": "Criando a sala", "status_avatar_total": "Enviando o avatar: {count} de {total}", "status_avatar": "Enviando avatar: {count}", - "room_name_limit_error_msg": "" + "room_name_limit_error_msg": "O máximo de 50 caracteres são permitidos" }, "device_list": { "title": "DISPOSITIVOS", @@ -173,7 +173,7 @@ "status_logging_in": "Fazendo login...", "status_joining": "Entrando na sala...", "join_failed": "Houve uma falha ao entrar na sala.", - "choose_name": "" + "choose_name": "Escolha um nome para usar" }, "leave": { "title_public": "Adeus, {user}", @@ -185,6 +185,9 @@ "go_back": "Retorna", "leave": "Sair" }, + "logout": { + "confirm_text": "" + }, "purge_room": { "title": "Exclui a sala?", "info": "Todos os membros e as mensagens serão excluídos. Essa ação não pode ser desfeita.", @@ -216,7 +219,8 @@ "show_all": "Mostre tudo >", "leave_room": "Sair", "version_info": "Desenvolvido por Guardian Project. Versão: {version}", - "scan_code": "Faça a varredura para entrar na sala" + "scan_code": "Faça a varredura para entrar na sala", + "export_room": "Exportar a conversa" }, "room_info_sheet": { "this_room": "Esta sala", @@ -235,5 +239,34 @@ "default": "padrão", "custom": "personalizado ({level})", "restricted": "restrito" + }, + "poll_create": { + "title": "Criar uma enquete", + "intro": "Preencha os detalhes abaixo.", + "create": "Criar", + "creating": "Criando a enquete", + "poll_disclosed": "Aberto - os resultados atuais são mostrados em todos os momentos.", + "add_answer": "Adicionar uma resposta", + "failed": "Houve uma falha ao criar a enquete. Tente novamente mais tarde.", + "question_label": "Digite a sua pergunta aqui", + "question_required": "Você precisa inserir uma pergunta!", + "answer_label": "Responda sem {index}", + "answer_required": "A resposta não pode estar vazia. Insira algum texto ou remova esta opção.", + "create_poll_menu_option": "Criar uma enquete", + "poll_status_closed": "A enquete foi encerrada", + "poll_status_disclosed": "Os resultados serão mostrados quando a enquete for encerrada.", + "poll_status_open": "A enquete está aberta", + "poll_status_open_not_voted": "A enquete está aberta - vote para ver os resultados", + "close_poll": "Fechar a enquete", + "poll_submit": "Enviar", + "num_answered": "{count} responderam", + "poll_undisclosed": "Fechado - os usuários verão os resultados quando a pesquisa for fechada." + }, + "export": { + "exported_date": "Foi exportado em {date}", + "fetched_n_events": "{count} eventos buscados", + "fetched_n_of_total_events": "Obteve {count} de {total} eventos", + "processed_n_of_total_events": "Mídia processada para {count} de {total} eventos", + "export_filename": "Bate-papo exportado {date}" } } diff --git a/src/assets/translations/ro.json b/src/assets/translations/ro.json index b4209f4..ad231fd 100644 --- a/src/assets/translations/ro.json +++ b/src/assets/translations/ro.json @@ -83,6 +83,9 @@ "text_public": "Puteți oricând să vă alăturați din nou acestei camere dacă știți link-ul.", "title_public": "La revedere, {user}" }, + "logout": { + "confirm_text": "" + }, "invite": { "status_error": "Nu ați reușit să invitați unul sau mai mulți prieteni!", "status_inviting": "Invitați prietenul {index} din {count}", diff --git a/src/assets/translations/si.json b/src/assets/translations/si.json index e7e08d8..24ce6f4 100644 --- a/src/assets/translations/si.json +++ b/src/assets/translations/si.json @@ -29,5 +29,8 @@ }, "login": { "invalid_message": "" + }, + "logout": { + "confirm_text": "" } } diff --git a/src/assets/translations/ug.json b/src/assets/translations/ug.json index b8e401e..9e3650d 100644 --- a/src/assets/translations/ug.json +++ b/src/assets/translations/ug.json @@ -106,6 +106,9 @@ "text_public": "ئۇلىنىشنى بىلسىڭىز ھەمىشە بۇ ئۆيگە قايتا كىرەلەيسىز.", "title_public": "خەير خوش ، {ئىشلەتكۈچى}" }, + "logout": { + "confirm_text": "" + }, "join": { "join_failed": "مۇنازىرە ئۆيىگە قوشۇلۇش مەغلۇب بولدى.", "status_joining": "مۇنازىرىگە كىرىش...", diff --git a/src/assets/translations/zh_Hans.json b/src/assets/translations/zh_Hans.json index 5b0a8ef..002e147 100644 --- a/src/assets/translations/zh_Hans.json +++ b/src/assets/translations/zh_Hans.json @@ -42,6 +42,9 @@ "text_public": "如果您知道链接,您可以随时再次加入此聊天室。", "title_public": "再见,{user}" }, + "logout": { + "confirm_text": "" + }, "login": { "login": "登录", "password": "输入密码", diff --git a/src/components/BottomSheet.vue b/src/components/BottomSheet.vue index 20e83ba..f622116 100644 --- a/src/components/BottomSheet.vue +++ b/src/components/BottomSheet.vue @@ -17,6 +17,16 @@ ref="pan" :style="{ top: `${isMove ? y : calcY()}px` }" > + + cancel +
@@ -203,6 +213,13 @@ export default { background-color: white; overflow: hidden; + .bottom-sheet-close { + position: absolute; + right: 0; + top: 0; + z-index: 1; + } + @media #{map-get($display-breakpoints, 'lg-and-up')} { margin: 0 auto; width: $dialog-desktop-width; diff --git a/src/components/Chat.vue b/src/components/Chat.vue index abdf012..bdf2759 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -26,7 +26,10 @@ v-on:edit="edit(selectedEvent)" v-on:redact="redact(selectedEvent)" v-on:download="download(selectedEvent)" - v-on:more="showMoreMessageOperations" + v-on:more=" + isEmojiQuickReaction= true + showMoreMessageOperations($event) + " :event="selectedEvent" />
@@ -72,13 +75,13 @@ :room="room" :event="event" :nextEvent="events[index + 1]" - :reactions="timelineSet.getRelationsForEvent(event.getId(), 'm.annotation', 'm.reaction')" :timelineSet="timelineSet" v-on:send-quick-reaction="sendQuickReaction" v-on:context-menu="showContextMenuForEvent($event)" v-on:own-avatar-clicked="viewProfile" v-on:other-avatar-clicked="showAvatarMenuForEvent($event)" v-on:download="download(event)" + v-on:poll-closed="pollWasClosed(event)" /> @@ -164,6 +167,32 @@ + + + + + + + + + + + + + + $vuetify.icons.addReaction + + + - - - - - - - - - - - - - - - {{ $t("poll_create.create_poll_menu_option") }} - - - container.clientHeight || (this.timelineWindow && this.timelineWindow.canPaginate(EventTimeline.FORWARDS)); + this.showScrollToEnd = + container.scrollHeight === container.clientHeight + ? false + : container.scrollHeight - container.scrollTop.toFixed(0) > container.clientHeight || + (this.timelineWindow && this.timelineWindow.canPaginate(EventTimeline.FORWARDS)); this.restartRRTimer(); }, @@ -1263,13 +1276,21 @@ export default { }, emojiSelected(e) { + if(this.isEmojiQuickReaction) { + // When quick emoji picker is clicked + if (this.selectedEvent) { + const event = this.selectedEvent; + this.selectedEvent = null; + this.sendQuickReaction({ reaction: e.data, event: event }); + } + } else { + // When text input emoji picker is clicked + this.currentInput = e.data; + this.$refs.messageInput.focus(); + } + this.showEmojiPicker = false; this.$refs.messageOperationsSheet.close(); - if (this.selectedEvent) { - const event = this.selectedEvent; - this.selectedEvent = null; - this.sendQuickReaction({ reaction: e.data, event: event }); - } }, sendQuickReaction(e) { @@ -1438,8 +1459,8 @@ export default { this.sendAttachment(text); this.showRecorder = false; - // Log event to Clean Insights - this.$ci.event("Audio", "Voice message sent"); + // Log event + this.$analytics.event("Audio", "Voice message sent"); }, closeCreateRoomWelcomeHeader() { @@ -1482,6 +1503,15 @@ export default { onInvitationsClick() { this.$navigation.push({ name: "Home" }, -1); }, + pollWasClosed(ignoredE) { + let div = document.createElement("div"); + div.classList.add("toast"); + div.innerText = this.$t("poll_create.results_shared"); + this.$refs.chatContainer.parentElement.appendChild(div); + setTimeout(() => { + this.$refs.chatContainer.parentElement.removeChild(div); + }, 3000); + } }, }; diff --git a/src/components/CreatePollDialog.vue b/src/components/CreatePollDialog.vue index 8decf7b..c5ff2aa 100644 --- a/src/components/CreatePollDialog.vue +++ b/src/components/CreatePollDialog.vue @@ -1,16 +1,18 @@ diff --git a/src/components/InputControl.vue b/src/components/InputControl.vue new file mode 100644 index 0000000..a0a077c --- /dev/null +++ b/src/components/InputControl.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/src/components/LogoutRoomDialog.vue b/src/components/LogoutRoomDialog.vue new file mode 100644 index 0000000..e869e1b --- /dev/null +++ b/src/components/LogoutRoomDialog.vue @@ -0,0 +1,54 @@ + + diff --git a/src/components/Profile.vue b/src/components/Profile.vue index 031e01e..daa30cf 100644 --- a/src/components/Profile.vue +++ b/src/components/Profile.vue @@ -53,9 +53,14 @@ - {{ - $t("menu.logout") - }} + + {{ $t("menu.logout") }} + + @@ -182,6 +187,7 @@ const sizeOf = require("image-size"); //const dataUriToBuffer = require("data-uri-to-buffer"); import util from "../plugins/utils"; import profileInfoMixin from "./profileInfoMixin"; +import LogoutRoomDialog from './LogoutRoomDialog.vue'; export default { name: "Profile", @@ -189,12 +195,14 @@ export default { components: { ActionRow, SelectLanguageDialog, + LogoutRoomDialog, }, data() { return { showEditPasswordDialog: false, showEditDisplaynameDialog: false, showSelectLanguageDialog: false, + showLogoutPopup: false, editValue: null, password: null, newPassword1: null, diff --git a/src/components/ProfileInfoPopup.vue b/src/components/ProfileInfoPopup.vue index b42bf96..136c344 100644 --- a/src/components/ProfileInfoPopup.vue +++ b/src/components/ProfileInfoPopup.vue @@ -60,10 +60,15 @@ :text="$t('profile_info_popup.edit_profile')" /> +
@@ -89,12 +94,14 @@ diff --git a/src/components/RoomExport.vue b/src/components/RoomExport.vue index 8ed0640..0010efb 100644 --- a/src/components/RoomExport.vue +++ b/src/components/RoomExport.vue @@ -33,7 +33,6 @@ :room="room" :event="event" :nextEvent="events[index + 1]" - :reactions="timelineSet.getRelationsForEvent(event.getId(), 'm.annotation', 'm.reaction')" :timelineSet="timelineSet" ref="exportedEvent" /> diff --git a/src/components/RoomInfo.vue b/src/components/RoomInfo.vue index ab1c4d6..c59f700 100644 --- a/src/components/RoomInfo.vue +++ b/src/components/RoomInfo.vue @@ -24,12 +24,7 @@
- - - {{ - roomName.substring(0, 1).toUpperCase() - }} - +
{{ roomName }}
{{ roomTopic }}
@@ -190,7 +185,7 @@ >{{ $t("room_info.purge") }}
- +
{{ $t("room_info.version_info", { version: buildVersion }) }}
@@ -218,6 +213,7 @@ import LeaveRoomDialog from "../components/LeaveRoomDialog"; import PurgeRoomDialog from "../components/PurgeRoomDialog"; import DeviceList from "../components/DeviceList"; import RoomExport from "../components/RoomExport"; +import RoomAvatarPicker from "../components/RoomAvatarPicker"; import QRCode from "qrcode"; import roomInfoMixin from "./roomInfoMixin"; import QRCodePopup from './QRCodePopup.vue'; @@ -232,6 +228,7 @@ export default { DeviceList, RoomExport, QRCodePopup, + RoomAvatarPicker }, data() { return { diff --git a/src/components/RoomInfoBottomSheet.vue b/src/components/RoomInfoBottomSheet.vue index 086749e..bd09691 100644 --- a/src/components/RoomInfoBottomSheet.vue +++ b/src/components/RoomInfoBottomSheet.vue @@ -1,34 +1,12 @@ diff --git a/src/components/messages/MessageIncomingPoll.vue b/src/components/messages/MessageIncomingPoll.vue index 2b956a3..8bb5166 100644 --- a/src/components/messages/MessageIncomingPoll.vue +++ b/src/components/messages/MessageIncomingPoll.vue @@ -21,6 +21,7 @@ />
+
{{ pollQuestion }}
{{ answer.percentage }}% -
+
- - + +
+ {{ $t("poll_create.poll_submit") }} +
+
+
+ + {{ $t("poll_create.num_answered", { count: pollNumAnswers }) }} - - {{ $t("poll_create.close_poll") }} - - - - - {{ $t("poll_create.poll_submit") }} - + +
+ {{ $t("poll_create.view_results") }} + +
+
+
+
+
+ {{ $t("poll_create.close_poll") }} +
+
+ + {{ $t("poll_create.poll_status_closed") }} +
diff --git a/src/components/messages/MessageOutgoing.vue b/src/components/messages/MessageOutgoing.vue index c14d2c9..11b4000 100644 --- a/src/components/messages/MessageOutgoing.vue +++ b/src/components/messages/MessageOutgoing.vue @@ -8,7 +8,7 @@
{{ event.status }}
- +
more_vert {{ answer.percentage }}% -
+
- - + +
+ {{ $t("poll_create.poll_submit") }} +
+
+
+ + {{ $t("poll_create.num_answered", { count: pollNumAnswers }) }} - - {{ $t("poll_create.close_poll") }} - - - - - {{ $t("poll_create.poll_submit") }} - + +
+ {{ $t("poll_create.view_results") }} + +
+
+
+
+
+ {{ $t("poll_create.close_poll") }} +
+
+ + {{ $t("poll_create.poll_status_closed") }} +
diff --git a/src/components/messages/QuickReactions.vue b/src/components/messages/QuickReactions.vue index 0e7c7b6..deb608b 100644 --- a/src/components/messages/QuickReactions.vue +++ b/src/components/messages/QuickReactions.vue @@ -15,24 +15,33 @@ export default { return {} } }, - reactions: { + timelineSet: { type: Object, default: function () { return null } - } + }, }, data() { return { - reactionMap: {} + reactionMap: {}, + reactions: null } }, + mounted() { + this.reactions = this.timelineSet.getRelationsForEvent(this.event.getId(), 'm.annotation', 'm.reaction'); + this.event.on("Event.relationsCreated", this.onRelationsCreated); + }, beforeDestroy() { + this.event.off("Event.relationsCreated", this.onRelationsCreated); if (this.reactions) { this.reactions.off('Relations.add', this.onAddRelation); } }, methods: { + onRelationsCreated() { + this.reactions = this.timelineSet.getRelationsForEvent(this.event.getId(), 'm.annotation', 'm.reaction'); + }, onClickEmoji(emoji) { this.$bubble('send-quick-reaction', {reaction:emoji, event:this.event}); }, diff --git a/src/components/messages/messageMixin.js b/src/components/messages/messageMixin.js index 4255022..e51e53c 100644 --- a/src/components/messages/messageMixin.js +++ b/src/components/messages/messageMixin.js @@ -27,12 +27,6 @@ export default { return null } }, - reactions: { - type: Object, - default: function () { - return null - } - }, timelineSet: { type: Object, default: function () { diff --git a/src/components/messages/pollMixin.js b/src/components/messages/pollMixin.js index 7544764..6bb073f 100644 --- a/src/components/messages/pollMixin.js +++ b/src/components/messages/pollMixin.js @@ -11,6 +11,7 @@ export default { pollEndTs: null, pollIsDisclosed: true, pollTentativeAnswer: null, + pollViewResults: false, }; }, mounted() { @@ -145,8 +146,13 @@ export default { this.pollTotalVotes = totalVotes; }, pollAnswer(id) { - if (!this.userHasVoted) { - this.pollTentativeAnswer = id; + // Only if not voted and not currently viewing poll results. + if (!this.userHasVoted && !this.pollViewResults) { + if (id == this.pollTentativeAnswer) { + this.pollTentativeAnswer = null; + } else { + this.pollTentativeAnswer = id; + } } }, pollAnswerSubmit() { @@ -163,7 +169,9 @@ export default { }); }, pollClose() { - util.closePoll(this.$matrix.matrixClient, this.room.roomId, this.event).catch((err) => { + util.closePoll(this.$matrix.matrixClient, this.room.roomId, this.event).then(() => { + this.$emit("poll-closed", this); + }).catch((err) => { console.log("Failed to send:", err); }); }, diff --git a/src/main.js b/src/main.js index 2019b78..07853c9 100644 --- a/src/main.js +++ b/src/main.js @@ -7,7 +7,7 @@ import router from './router' import matrix from './services/matrix.service' import navigation from './services/navigation.service' import config from './services/config.service' -import cleaninsights from './services/cleaninsights.service' +import analytics from './services/analytics.service' import 'roboto-fontface/css/roboto/roboto-fontface.css' import 'material-design-icons-iconfont/dist/material-design-icons.css' import VEmojiPicker from 'v-emoji-picker'; @@ -27,7 +27,7 @@ Vue.use(VueResize); Vue.use(VEmojiPicker); Vue.use(matrix, { store: store, i18n: i18n }); Vue.use(config); // Use this before cleaninsights below, it depends on config! -Vue.use(cleaninsights); +Vue.use(analytics); Vue.use(VueClipboard); // Add bubble functionality to custom events. @@ -159,6 +159,6 @@ new Vue({ router, matrix, config, - cleaninsights, + analytics, render: h => h(App) }).$mount('#app'); \ No newline at end of file diff --git a/src/plugins/utils.js b/src/plugins/utils.js index cb9b67f..1122cb8 100644 --- a/src/plugins/utils.js +++ b/src/plugins/utils.js @@ -389,8 +389,12 @@ class Util { } /** Generate a random user name */ - randomUser() { - return this.randomString( + randomUser(prefix) { + var pfx = prefix ? prefix.replace(/[^0-9a-zA-Z\-_]/gi, '') : null; + if (!pfx || pfx.length == 0) { + pfx = "weblite-"; + } + return pfx + this.randomString( 12, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ); diff --git a/src/services/analytics.service.js b/src/services/analytics.service.js new file mode 100644 index 0000000..ce7e58f --- /dev/null +++ b/src/services/analytics.service.js @@ -0,0 +1,65 @@ +import cleaninsights from './cleaninsights.service' +import matomo from './matomo.service' + +export default { + install(Vue) { + const analyticsService = new Vue({ + data() { + return { + engines: [], + cachedEvents: [], + initialized: false + } + }, + created() { + this.$config.promise.then((config) => { + var analytics = config.analytics || {}; + if (!Array.isArray(analytics)) { + analytics = [analytics]; + } + for (const engineConfig of analytics) { + if (engineConfig.enabled) { + let type = engineConfig.type || "ci"; + switch (type) { + case "ci": + { + let engine = cleaninsights.install(Vue, engineConfig.config); + this.engines.push(engine); + } + break; + case "matomo": + { + let engine = matomo.install(Vue, engineConfig.config); + this.engines.push(engine); + } + break; + } + } + } + + this.initialized = true; + + // Handle cached events + this.cachedEvents.forEach(([category, action]) => { + this.event(category, action); + }) + this.cachedEvents = []; + }); + }, + methods: { + event(category, action) { + if (!this.initialized) { + this.cachedEvents.push([category, action]); + return + } + + // Send the event to each configured analytics engine. + this.engines.forEach((engine) => { + engine.event(category, action); + }); + } + } + }); + Vue.prototype.$analytics = analyticsService; + } +} diff --git a/src/services/cleaninsights.service.js b/src/services/cleaninsights.service.js index accfb7b..ba0fe60 100644 --- a/src/services/cleaninsights.service.js +++ b/src/services/cleaninsights.service.js @@ -1,7 +1,7 @@ import { CleanInsights, ConsentRequestUi } from 'clean-insights-sdk'; export default { - install(Vue) { + install(Vue, config) { class RequestUi extends ConsentRequestUi { showForCampaign(campaignId, campaign, complete) { @@ -18,6 +18,7 @@ export default { } const cleanInsightsService = new Vue({ + config: config, data() { return { ci: null, @@ -26,17 +27,14 @@ export default { } }, created() { - const self = this; - this.$config.promise.then(function (config) { - const analytics = config.analytics || {}; - if (analytics.enabled && analytics.config) { - self.ci = new CleanInsights(analytics.config); + if (this.$options.config) { + const config = this.$options.config; + this.ci = new CleanInsights(config); - // Get name of first campaign in the config. - self.campaignId = Object.keys(analytics.config.campaigns || { invalid: {} })[0]; - } + // Get name of first campaign in the config. + this.campaignId = Object.keys(config.campaigns || { invalid: {} })[0]; - }); + } }, methods: { event(category, action) { @@ -55,6 +53,6 @@ export default { } } }); - Vue.prototype.$ci = cleanInsightsService; + return cleanInsightsService; } } diff --git a/src/services/matomo.service.js b/src/services/matomo.service.js new file mode 100644 index 0000000..70ded8b --- /dev/null +++ b/src/services/matomo.service.js @@ -0,0 +1,51 @@ + +export default { + install(Vue, config) { + + const matomoService = new Vue({ + config: config, + data() { + return { + initialized: false + } + }, + created() { + if (this.$options.config) { + const config = this.$options.config; + let server = config.server; + let siteId = config.siteId; + if (server && siteId) { + if (!server.endsWith("/")) { + server = server + "/"; + } + let script = ` + var _paq = window._paq = window._paq || []; + /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + (function() { + var u="${server}"; + _paq.push(['setTrackerUrl', u+'matomo.php']); + _paq.push(['setSiteId', '${siteId}']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); + })(); + `; + var s = document.createElement('script'); + s.innerHTML = script; + document.body.appendChild(s); + this.initialized = true; + } + } + }, + methods: { + event(category, action) { + if (this.initialized) { + window._paq.push(['trackEvent', category, action]); + } + } + } + }); + return matomoService; + } +} diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js index 1265a0c..ce0ac87 100644 --- a/src/services/matrix.service.js +++ b/src/services/matrix.service.js @@ -115,7 +115,7 @@ export default { // 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 user = util.randomUser(); + const user = util.randomUser(this.$config.userIdPrefix); const pass = util.randomPass(); promiseLogin = tempMatrixClient .register(user, pass, null, { @@ -854,7 +854,7 @@ export default { if (tempUser) { clientPromise = Promise.resolve(tempUser); } else { - const user = util.randomUser(); + const user = util.randomUser(this.$config.userIdPrefix); const pass = util.randomPass(); clientPromise = tempMatrixClient .register(user, pass, null, {