From f96f83f04e8b9efce32c578696a71f9438d74d72 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 8 Jun 2022 14:10:13 +0000 Subject: [PATCH 01/15] Translations update from Hosted Weblate --- src/assets/translations/pt_BR.json | 42 ++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/assets/translations/pt_BR.json b/src/assets/translations/pt_BR.json index 63e6914..270016a 100644 --- a/src/assets/translations/pt_BR.json +++ b/src/assets/translations/pt_BR.json @@ -75,7 +75,8 @@ "user_changed_guest_access_open": "{user} permitiu que convidados entrassem na sala", "reply_image": "Imagem", "reply_audio_message": "Mensagem de áudio", - "reply_video": "Vídeo" + "reply_video": "Vídeo", + "time_ago": "Hoje | Ontem | {count} dias atrás" }, "room": { "members": "sem membros | 1 membro | {count} membros", @@ -85,7 +86,8 @@ "purge_removing_members": "Removendo os membros", "purge_failed": "Houve uma falha ao eliminar a sala!", "room_list_invites": "Convites", - "room_list_rooms": "Salas" + "room_list_rooms": "Salas", + "invitations": "Você não tem convites | Você tem 1 convite | Você tem {count} convites" }, "room_welcome": { "info": "Bem-vindo! Aqui estão algumas coisas que você deve saber sobre a sua sala:", @@ -116,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", @@ -171,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}", @@ -214,7 +216,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", @@ -233,5 +236,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}" } } From 139792c3027795a18ad7c8ab3c47a1adf1bfe1b1 Mon Sep 17 00:00:00 2001 From: 10G Meow <10gmeow@gmail.com> Date: Wed, 8 Jun 2022 14:11:44 +0000 Subject: [PATCH 02/15] Room avatar picker added to room details page --- src/components/RoomAvatarPicker.vue | 68 ++++++++++++++++++++++++++ src/components/RoomInfo.vue | 11 ++--- src/components/RoomInfoBottomSheet.vue | 66 ++----------------------- 3 files changed, 77 insertions(+), 68 deletions(-) create mode 100644 src/components/RoomAvatarPicker.vue diff --git a/src/components/RoomAvatarPicker.vue b/src/components/RoomAvatarPicker.vue new file mode 100644 index 0000000..4b6bdb7 --- /dev/null +++ b/src/components/RoomAvatarPicker.vue @@ -0,0 +1,68 @@ + + + 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..20adc80 100644 --- a/src/components/RoomInfoBottomSheet.vue +++ b/src/components/RoomInfoBottomSheet.vue @@ -5,30 +5,7 @@ >
- - - {{ - roomName.substring(0, 1).toUpperCase() - }} - - - - {{ loadValue }} - +
{{$t('room_info_sheet.this_room')}}
{{ roomName }}
From 6951340081e45c8fda026c9e181fb992c860b8cf Mon Sep 17 00:00:00 2001 From: 10G Meow <10gmeow@gmail.com> Date: Wed, 8 Jun 2022 14:13:40 +0000 Subject: [PATCH 03/15] Emojis update realtime --- src/components/Chat.vue | 1 - src/components/RoomExport.vue | 1 - src/components/messages/MessageIncoming.vue | 2 +- src/components/messages/MessageOutgoing.vue | 2 +- src/components/messages/QuickReactions.vue | 15 ++++++++++++--- src/components/messages/messageMixin.js | 6 ------ 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/Chat.vue b/src/components/Chat.vue index abdf012..fc0f065 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -72,7 +72,6 @@ :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)" 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/messages/MessageIncoming.vue b/src/components/messages/MessageIncoming.vue index 3f11f2b..a345132 100644 --- a/src/components/messages/MessageIncoming.vue +++ b/src/components/messages/MessageIncoming.vue @@ -20,7 +20,7 @@ >more_vert
- +
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 Date: Wed, 8 Jun 2022 18:53:50 +0000 Subject: [PATCH 04/15] Resolve "Polling: Updated poll admin UX" --- src/assets/css/chat.scss | 1880 +++++++++-------- src/assets/css/components/_poll.scss | 194 +- src/assets/icons/ic_add.svg | 4 + src/assets/icons/ic_check_small.svg | 3 + src/assets/translations/en.json | 17 +- src/components/Chat.vue | 81 +- src/components/CreatePollDialog.vue | 145 +- src/components/InputControl.vue | 163 ++ .../messages/MessageIncomingPoll.vue | 71 +- .../messages/MessageOutgoingPoll.vue | 70 +- src/components/messages/pollMixin.js | 14 +- 11 files changed, 1531 insertions(+), 1111 deletions(-) create mode 100644 src/assets/icons/ic_add.svg create mode 100644 src/assets/icons/ic_check_small.svg create mode 100644 src/components/InputControl.vue diff --git a/src/assets/css/chat.scss b/src/assets/css/chat.scss index ef7a386..23a947f 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,1170 @@ $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; + } - @media #{map-get($display-breakpoints, 'sm-and-down')} { - margin-top: 72px; - margin-bottom: 70px; - z-index: 9; - } + .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; + } } - .input-area { - background-color: #e2e2e2; - margin: 0; - padding-left: $chat-standard-padding-s; - padding-right: $chat-standard-padding-s; + .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; + } } - .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-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; - } + @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; - } + .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..7b53aac 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,190 @@ .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; - overflow-x: hidden; - overflow-y: auto; -} -.poll-create-status { - font-size: 0.7rem; +.poll-create { + .poll-create-dialog-content { + overflow-x: hidden; + overflow-y: auto; + + 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/en.json b/src/assets/translations/en.json index a07f961..a84bab8 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -238,26 +238,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/components/Chat.vue b/src/components/Chat.vue index fc0f065..e67dad1 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -78,6 +78,7 @@ v-on:own-avatar-clicked="viewProfile" v-on:other-avatar-clicked="showAvatarMenuForEvent($event)" v-on:download="download(event)" + v-on:poll-closed="pollWasClosed(event)" /> @@ -163,6 +164,32 @@ + + + + + + + + + + + - - - - - - - - - - - - - - - {{ $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(); }, @@ -1481,6 +1473,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..14fc973 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/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/MessageOutgoingPoll.vue b/src/components/messages/MessageOutgoingPoll.vue index 01b4acc..d3aaaf6 100644 --- a/src/components/messages/MessageOutgoingPoll.vue +++ b/src/components/messages/MessageOutgoingPoll.vue @@ -31,8 +31,8 @@ :class="{ 'poll-answer': true, selected: !userHasVoted && answer.id == pollTentativeAnswer, - result: userHasVoted || pollIsClosed, - winner: answer.winner, + result: userHasVoted || pollIsClosed || pollViewResults, + winner: answer.winner && (userHasVoted || pollIsClosed || pollViewResults), }" ma-0 pa-0 @@ -42,41 +42,55 @@ >
{{ 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/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); }); }, From 9f2e543d07d90133167aa19ed9990c0be1c9ee2f Mon Sep 17 00:00:00 2001 From: 10G Meow <10gmeow@gmail.com> Date: Sat, 11 Jun 2022 09:31:14 +0300 Subject: [PATCH 05/15] logout confirmation popup --- src/assets/translations/bo.json | 3 ++ src/assets/translations/de.json | 3 ++ src/assets/translations/en.json | 3 ++ src/assets/translations/es.json | 3 ++ src/assets/translations/fi.json | 3 ++ src/assets/translations/fr.json | 3 ++ src/assets/translations/it.json | 3 ++ src/assets/translations/nb_NO.json | 3 ++ src/assets/translations/pt_BR.json | 3 ++ src/assets/translations/ro.json | 3 ++ src/assets/translations/si.json | 3 ++ src/assets/translations/ug.json | 3 ++ src/assets/translations/zh_Hans.json | 3 ++ src/components/LogoutRoomDialog.vue | 54 ++++++++++++++++++++++++++++ src/components/Profile.vue | 14 ++++++-- src/components/ProfileInfoPopup.vue | 12 +++++-- 16 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 src/components/LogoutRoomDialog.vue 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 a07f961..d72636b 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.", 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 63e6914..0f0abb7 100644 --- a/src/assets/translations/pt_BR.json +++ b/src/assets/translations/pt_BR.json @@ -183,6 +183,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.", 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 98e4e89..33e42f9 100644 --- a/src/assets/translations/si.json +++ b/src/assets/translations/si.json @@ -29,5 +29,8 @@ }, "login": { "invalid_message": "" + }, + "logout": { + "confirm_text": "" } } \ No newline at end of file diff --git a/src/assets/translations/ug.json b/src/assets/translations/ug.json index 64d2d37..c3aaa79 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/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 @@ From 64a31e31f9de055bcd7456a4317c341d28aacdaf Mon Sep 17 00:00:00 2001 From: N Pex Date: Thu, 30 Jun 2022 08:38:58 +0000 Subject: [PATCH 10/15] Implement support for multiple analytics engines --- src/components/Chat.vue | 4 +- src/main.js | 6 +-- src/services/analytics.service.js | 65 +++++++++++++++++++++++++++ src/services/cleaninsights.service.js | 20 ++++----- src/services/matomo.service.js | 51 +++++++++++++++++++++ 5 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 src/services/analytics.service.js create mode 100644 src/services/matomo.service.js diff --git a/src/components/Chat.vue b/src/components/Chat.vue index e67dad1..74cc531 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -1429,8 +1429,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() { 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/services/analytics.service.js b/src/services/analytics.service.js new file mode 100644 index 0000000..3fd7cd1 --- /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; + } +} From 03094e0137bcb83e516ad6d9527069304365317d Mon Sep 17 00:00:00 2001 From: John Hess Date: Thu, 30 Jun 2022 18:57:58 -0500 Subject: [PATCH 11/15] add matomo config --- src/assets/config.json | 45 +++++++++++++++++++------------ src/services/analytics.service.js | 10 +++---- 2 files changed, 33 insertions(+), 22 deletions(-) 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/services/analytics.service.js b/src/services/analytics.service.js index 3fd7cd1..ce7e58f 100644 --- a/src/services/analytics.service.js +++ b/src/services/analytics.service.js @@ -28,11 +28,11 @@ export default { } break; case "matomo": - { - let engine = matomo.install(Vue, engineConfig.config); - this.engines.push(engine); - } - break; + { + let engine = matomo.install(Vue, engineConfig.config); + this.engines.push(engine); + } + break; } } } From 6cf4971b2249c5cb92f73370a29c31bb3228d890 Mon Sep 17 00:00:00 2001 From: N Pex Date: Fri, 1 Jul 2022 08:34:59 +0000 Subject: [PATCH 12/15] Prefix random usernames with "weblite" --- src/plugins/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/utils.js b/src/plugins/utils.js index cb9b67f..652ae68 100644 --- a/src/plugins/utils.js +++ b/src/plugins/utils.js @@ -390,7 +390,7 @@ class Util { /** Generate a random user name */ randomUser() { - return this.randomString( + return "weblite-" + this.randomString( 12, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ); From 6bd0d8ad7e82a15f123ae2103f2acd890679a365 Mon Sep 17 00:00:00 2001 From: N Pex Date: Fri, 1 Jul 2022 08:55:26 +0000 Subject: [PATCH 13/15] Prefix random usernames with "weblite" --- src/plugins/utils.js | 8 ++++++-- src/services/matrix.service.js | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/utils.js b/src/plugins/utils.js index 652ae68..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 "weblite-" + 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/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, { From b1f68e59d9ed8bee75a1cd60d1b16200845fe07f Mon Sep 17 00:00:00 2001 From: N-Pex Date: Fri, 1 Jul 2022 11:09:30 +0200 Subject: [PATCH 14/15] Validate before enabling "publish" button on poll creation. --- src/components/CreatePollDialog.vue | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/CreatePollDialog.vue b/src/components/CreatePollDialog.vue index 14fc973..c5ff2aa 100644 --- a/src/components/CreatePollDialog.vue +++ b/src/components/CreatePollDialog.vue @@ -44,7 +44,7 @@ :class="{ deletable: pollAnswers.length > 1 }" ref="answerInput" > - delete + delete @@ -72,7 +72,7 @@ block class="filled-button publish-button" @click.stop="onCreatePoll()" - :disabled="isCreating" + :disabled="isCreating || !publishButtonEnabled" >{{ $t("poll_create.create") }} @@ -197,6 +197,11 @@ export default { } }, }, + computed: { + publishButtonEnabled() { + return this.pollQuestion && this.pollAnswers.length > 0 && this.pollAnswers.every(a => a.text); + } + }, components: { InputControl }, }; From 49e7028c312e081b11c8b3d8dfbc39836b08e0a5 Mon Sep 17 00:00:00 2001 From: N-Pex Date: Fri, 1 Jul 2022 11:20:05 +0200 Subject: [PATCH 15/15] Make create poll dialog scrollable --- src/assets/css/components/_poll.scss | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/assets/css/components/_poll.scss b/src/assets/css/components/_poll.scss index 7b53aac..5b1ef54 100644 --- a/src/assets/css/components/_poll.scss +++ b/src/assets/css/components/_poll.scss @@ -207,10 +207,9 @@ // Creation dialog // .poll-create { + overflow-x: hidden; + overflow-y: auto; .poll-create-dialog-content { - overflow-x: hidden; - overflow-y: auto; - font-family: "Inter"; font-style: normal; font-weight: 400;