New room list and chat header design
This commit is contained in:
parent
f41abd66ba
commit
4ad60ec44b
23 changed files with 651 additions and 287 deletions
|
|
@ -45,15 +45,28 @@ body {
|
|||
border-bottom: 1px solid var(--v-divider-color);
|
||||
.chat-header-row {
|
||||
margin: 0;
|
||||
padding: 4px 10px;
|
||||
padding: 4px 10px 4px 28px;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
button {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
.v-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.room-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.chat-header-members,
|
||||
.chat-header-name {
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
.chat-header-members {
|
||||
overflow: hidden;
|
||||
}
|
||||
.num-members {
|
||||
font-family: "Inter", sans-serif;
|
||||
font-weight: 400;
|
||||
|
|
@ -73,44 +86,72 @@ body {
|
|||
margin-bottom: $chat-standard-padding-xs;
|
||||
}
|
||||
|
||||
@media #{map-get($display-breakpoints, 'sm-and-down')} {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.icon-dropdown {
|
||||
margin: 0px 8px;
|
||||
}
|
||||
|
||||
.notification-alert {
|
||||
display: inline-block;
|
||||
background-color: #ff3300;
|
||||
background-color: $alert-bg-color;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
&.popup-open::after {
|
||||
top: 5px;
|
||||
color: #246bfd;
|
||||
}
|
||||
.missed-items-popup {
|
||||
position: absolute;
|
||||
bottom: -17px;
|
||||
left: -20px;
|
||||
transform: translateY(100%);
|
||||
background: #246bfd;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 22px 18px 23px 18px;
|
||||
z-index: 300;
|
||||
user-select: none;
|
||||
.text {
|
||||
white-space: nowrap;
|
||||
font-family: "Inter", sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.button {
|
||||
margin-left: 50px;
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 11.5411px;
|
||||
line-height: 140%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
letter-spacing: 0.34px;
|
||||
text-transform: uppercase;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.missed-items-popup-background {
|
||||
content: " ";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
z-index: 250;
|
||||
backdrop-filter: blur(2px);
|
||||
-webkit-backdrop-filter: blur(2px);
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-root {
|
||||
|
|
@ -128,11 +169,6 @@ body {
|
|||
background-color: $chat-background;
|
||||
overflow: hidden;
|
||||
|
||||
.chat-room-invitations {
|
||||
padding: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.chat-content {
|
||||
margin: 0;
|
||||
padding-top: $chat-standard-padding-s;
|
||||
|
|
@ -224,7 +260,7 @@ body {
|
|||
padding: 0;
|
||||
min-width: 48px;
|
||||
|
||||
&.input-more-icon {
|
||||
&.input-more-icon {
|
||||
svg {
|
||||
fill: black;
|
||||
}
|
||||
|
|
@ -709,7 +745,7 @@ body {
|
|||
.room-name-inline {
|
||||
font-family: "Poppins", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 18 * $chat-text-size;
|
||||
font-size: 16 * $chat-text-size;
|
||||
text-transform: uppercase;
|
||||
color: var(--v-foreground-color);
|
||||
text-align: center;
|
||||
|
|
@ -787,6 +823,50 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.room-list {
|
||||
.room-list-room {
|
||||
color: white; // Used as selected item background
|
||||
.v-avatar:not(.round) {
|
||||
// Make avatars rounded squares!
|
||||
border-radius: 8px;
|
||||
}
|
||||
.room-list-name,
|
||||
.room-list-new-room {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 117%;
|
||||
letter-spacing: 0.4px;
|
||||
color: #0e252d;
|
||||
}
|
||||
.room-list-new-room {
|
||||
font-weight: 400;
|
||||
}
|
||||
.room-list-new-messages {
|
||||
font-family: "Inter", sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 117%;
|
||||
letter-spacing: 0.4px;
|
||||
color: #1d1d1d;
|
||||
padding-left: 13px;
|
||||
position: relative;
|
||||
&::before {
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
background: $alert-bg-color;
|
||||
border-radius: 3px;
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.room-info {
|
||||
background-color: #e8e8e8;
|
||||
height: 100%;
|
||||
|
|
@ -1275,11 +1355,11 @@ body {
|
|||
background-color: var(--v-background-color);
|
||||
color: var(--v-foreground-color);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
.load-earlier {
|
||||
flex: 1 0 auto;
|
||||
padding: 20px;
|
||||
|
|
@ -1297,7 +1377,8 @@ body {
|
|||
height: 32px !important;
|
||||
margin-left: -8px !important;
|
||||
}
|
||||
.list-enter-active, .list-leave-active {
|
||||
.list-enter-active,
|
||||
.list-leave-active {
|
||||
transition: all 1s;
|
||||
}
|
||||
.list-enter, .list-leave-to /* .list-leave-active below version 2.1.8 */ {
|
||||
|
|
@ -1310,7 +1391,7 @@ body {
|
|||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items:center;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -1372,7 +1453,8 @@ body {
|
|||
height: 103px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
#btn-play, #btn-pause {
|
||||
#btn-play,
|
||||
#btn-pause {
|
||||
margin: 26px;
|
||||
}
|
||||
.mic-button {
|
||||
|
|
@ -1385,4 +1467,4 @@ body {
|
|||
right: 20px;
|
||||
bottom: 20px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
src/assets/icons/ic_circle.vue
Normal file
5
src/assets/icons/ic_circle.vue
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="8" r="7.5" stroke="#242424" stroke-opacity="0.3" />
|
||||
</svg>
|
||||
</template>
|
||||
6
src/assets/icons/ic_circle_filled.vue
Normal file
6
src/assets/icons/ic_circle_filled.vue
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="8" r="7.5" stroke="#242424" />
|
||||
<circle cx="8" cy="8" r="4.5" fill="#242424" stroke="#242424" />
|
||||
</svg>
|
||||
</template>
|
||||
15
src/assets/icons/ic_download.vue
Normal file
15
src/assets/icons/ic_download.vue
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<svg width="15" height="16" viewBox="0 0 15 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M14.1487 15.7001H0.822597C0.376044 15.7001 0 15.3241 0 14.8775C0 14.431 0.376044 14.0549 0.822597 14.0549H14.1487C14.5952 14.0549 14.9713 14.431 14.9713 14.8775C14.9713 15.3241 14.5952 15.7001 14.1487 15.7001Z"
|
||||
fill="#161616" />
|
||||
<path
|
||||
d="M7.4974 12.1509C7.05085 12.1509 6.6748 11.7749 6.6748 11.3283V0.822597C6.6748 0.376044 7.05085 0 7.4974 0C7.94395 0 8.32 0.376044 8.32 0.822597V11.3283C8.32 11.7749 7.94395 12.1509 7.4974 12.1509Z"
|
||||
fill="#161616" />
|
||||
<path
|
||||
d="M7.49734 12.151C7.28581 12.151 7.07429 12.0805 6.90977 11.916L3.05531 8.03806C2.72627 7.70902 2.72627 7.19196 3.05531 6.88643C3.38435 6.55739 3.90141 6.55739 4.20695 6.88643L8.0614 10.7409C8.39044 11.0699 8.39044 11.587 8.0614 11.8925C7.92039 12.0805 7.70886 12.151 7.49734 12.151Z"
|
||||
fill="#161616" />
|
||||
<path
|
||||
d="M7.49739 12.151C7.28586 12.151 7.07434 12.0805 6.90982 11.916C6.58078 11.587 6.58078 11.0699 6.90982 10.7644L10.7878 6.88643C11.1168 6.55739 11.6339 6.55739 11.9394 6.88643C12.2685 7.21547 12.2685 7.73253 11.9394 8.03806L8.08496 11.916C7.92044 12.0805 7.70891 12.151 7.49739 12.151Z"
|
||||
fill="#161616" />
|
||||
</svg></template>
|
||||
12
src/assets/icons/ic_info.vue
Normal file
12
src/assets/icons/ic_info.vue
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<template>
|
||||
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M8.49142 7.29595V7.29595C8.6693 7.29366 8.84063 7.36327 8.96659 7.48895L8.9666 7.48896C9.09283 7.61492 9.16273 7.78654 9.1605 7.96481M8.49142 7.29595L9.0355 7.96399M8.49142 7.29595L8.49009 7.29597M8.49142 7.29595L8.49009 7.29597M9.1605 7.96481C9.1605 7.96512 9.16049 7.96542 9.16049 7.96573L9.0355 7.96399M9.1605 7.96481V7.96399H9.0355M9.1605 7.96481V11.7131M9.0355 7.96399V11.714M9.1605 11.7131C9.1605 11.7128 9.16049 11.7125 9.16049 11.7122L9.0355 11.714M9.1605 11.7131C9.1628 11.8897 9.09425 12.0598 8.97033 12.1855C8.84616 12.3115 8.67664 12.3824 8.49979 12.3824C8.32293 12.3824 8.15349 12.3115 8.02932 12.1855M9.1605 11.7131V11.714H9.0355M9.0355 11.714L8.02932 12.1855M8.02932 12.1855L8.11832 12.0978L8.0293 12.1855C8.02931 12.1855 8.02932 12.1855 8.02932 12.1855ZM8.02932 12.1855C7.90529 12.0598 7.83685 11.8897 7.83907 11.7132M8.02932 12.1855L7.83907 7.96481M8.49009 7.29597C8.48989 7.29597 8.4897 7.29598 8.4895 7.29598C8.31454 7.29866 8.14772 7.37071 8.02581 7.49631L8.49009 7.29597ZM7.83907 7.96481C7.83692 7.79012 7.90404 7.62168 8.02577 7.49636L7.83907 7.96481ZM7.83907 7.96481V11.7132M7.83907 11.7132V11.714H7.96407L7.83908 11.7122C7.83908 11.7126 7.83908 11.7129 7.83907 11.7132Z"
|
||||
fill="#161616" stroke="black" stroke-width="0.25" />
|
||||
<path
|
||||
d="M8.49998 5.94643C8.86489 5.94643 9.16069 5.65062 9.16069 5.28571C9.16069 4.92081 8.86489 4.625 8.49998 4.625C8.13507 4.625 7.83926 4.92081 7.83926 5.28571C7.83926 5.65062 8.13507 5.94643 8.49998 5.94643Z"
|
||||
fill="#161616" stroke="black" stroke-width="0.25" />
|
||||
<path
|
||||
d="M8.5 0.875C4.29525 0.875 0.875 4.29525 0.875 8.5C0.875 12.7048 4.29525 16.125 8.5 16.125C12.7048 16.125 16.125 12.7048 16.125 8.5C16.125 4.29525 12.7048 0.875 8.5 0.875ZM8.5 2.19643C11.9877 2.19643 14.8036 5.01232 14.8036 8.5C14.8036 11.9877 11.9877 14.8036 8.5 14.8036C5.01232 14.8036 2.19643 11.9877 2.19643 8.5C2.19643 5.01232 5.01232 2.19643 8.5 2.19643Z"
|
||||
fill="#161616" stroke="black" stroke-width="0.25" />
|
||||
</svg></template>
|
||||
7
src/assets/icons/ic_link.vue
Normal file
7
src/assets/icons/ic_link.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg width="17" height="9" viewBox="0 0 17 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M1.615 4.5C1.615 2.961 2.7965 1.71 4.25 1.71H7.65V0H4.25C1.904 0 0 2.016 0 4.5C0 6.984 1.904 9 4.25 9H7.65V7.29H4.25C2.7965 7.29 1.615 6.039 1.615 4.5ZM5.1 5.4H11.9V3.6H5.1V5.4ZM12.75 0H9.35V1.71H12.75C14.2035 1.71 15.385 2.961 15.385 4.5C15.385 6.039 14.2035 7.29 12.75 7.29H9.35V9H12.75C15.096 9 17 6.984 17 4.5C17 2.016 15.096 0 12.75 0Z"
|
||||
fill="#161616" />
|
||||
</svg>
|
||||
</template>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5714 14.1903C10.7619 14.357 10.9762 14.4284 11.1904 14.4284C11.4523 14.4284 11.7142 14.3093 11.9047 14.095L14.9047 10.6189C15.2142 10.2617 15.2142 9.7379 14.9047 9.38076L11.9047 5.90457C11.5714 5.49981 10.9523 5.45219 10.5714 5.80933C10.1666 6.14267 10.119 6.76171 10.4762 7.14267L12.119 9.04743H6.0952C5.57139 9.04743 5.14282 9.476 5.14282 9.99981C5.14282 10.5236 5.57139 10.9522 6.0952 10.9522H12.119L10.4762 12.857C10.119 13.2617 10.1666 13.857 10.5714 14.1903Z" fill="white"/>
|
||||
<path d="M17.5 6.92857C17.6905 7.40476 18.2619 7.64286 18.7381 7.45238C19.2143 7.2619 19.4524 6.69048 19.2619 6.21429C17.7143 2.42857 14.0714 0 10 0C4.47619 0 0 4.47619 0 10C0 15.5238 4.47619 20 10 20C14.0714 20 17.7143 17.5714 19.2619 13.7857C19.4524 13.3095 19.2381 12.7381 18.7381 12.5476C18.2619 12.3571 17.6905 12.5714 17.5 13.0714C16.2381 16.119 13.3095 18.0952 10 18.0952C5.54762 18.0952 1.90476 14.4524 1.90476 10C1.90476 5.54762 5.54762 1.90476 10 1.90476C13.3095 1.90476 16.2381 3.88095 17.5 6.92857Z" fill="white"/>
|
||||
<path d="M10.5714 14.1903C10.7619 14.357 10.9762 14.4284 11.1904 14.4284C11.4523 14.4284 11.7142 14.3093 11.9047 14.095L14.9047 10.6189C15.2142 10.2617 15.2142 9.7379 14.9047 9.38076L11.9047 5.90457C11.5714 5.49981 10.9523 5.45219 10.5714 5.80933C10.1666 6.14267 10.119 6.76171 10.4762 7.14267L12.119 9.04743H6.0952C5.57139 9.04743 5.14282 9.476 5.14282 9.99981C5.14282 10.5236 5.57139 10.9522 6.0952 10.9522H12.119L10.4762 12.857C10.119 13.2617 10.1666 13.857 10.5714 14.1903Z" fill="currentColor"/>
|
||||
<path d="M17.5 6.92857C17.6905 7.40476 18.2619 7.64286 18.7381 7.45238C19.2143 7.2619 19.4524 6.69048 19.2619 6.21429C17.7143 2.42857 14.0714 0 10 0C4.47619 0 0 4.47619 0 10C0 15.5238 4.47619 20 10 20C14.0714 20 17.7143 17.5714 19.2619 13.7857C19.4524 13.3095 19.2381 12.7381 18.7381 12.5476C18.2619 12.3571 17.6905 12.5714 17.5 13.0714C16.2381 16.119 13.3095 18.0952 10 18.0952C5.54762 18.0952 1.90476 14.4524 1.90476 10C1.90476 5.54762 5.54762 1.90476 10 1.90476C13.3095 1.90476 16.2381 3.88095 17.5 6.92857Z" fill="currentColor"/>
|
||||
</svg>
|
||||
</template>
|
||||
7
src/assets/icons/ic_more.vue
Normal file
7
src/assets/icons/ic_more.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg width="3" height="15" viewBox="0 0 3 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M0.000170402 1.49991C0.00017042 1.10212 0.158154 0.720548 0.439485 0.439314C0.720719 0.157973 1.10229 4.81825e-08 1.50009 6.55708e-08C1.89788 8.29591e-08 2.27945 0.157984 2.56069 0.439314C2.84203 0.720549 3 1.10212 3 1.49991C3 1.89771 2.84202 2.27928 2.56069 2.56052C2.27945 2.84186 1.89788 2.99983 1.50009 2.99983C1.10229 2.99983 0.720718 2.84185 0.439485 2.56052C0.158143 2.27928 0.000170385 1.89771 0.000170402 1.49991ZM0.00017014 7.49957C0.000170157 7.10178 0.158154 6.72021 0.439484 6.43897C0.720718 6.15763 1.10229 5.99966 1.50008 5.99966C1.89788 5.99966 2.27945 6.15764 2.56069 6.43897C2.84203 6.72021 3 7.10178 3 7.49957C3 7.89737 2.84202 8.27894 2.56069 8.56017C2.27945 8.84152 1.89788 8.99949 1.50008 8.99949C1.10052 8.99949 0.717478 8.84014 0.435949 8.55661C0.154394 8.27318 -0.00242794 7.8891 0.00017014 7.48953L0.00017014 7.49957ZM0.000169878 13.4992C0.000169895 13.1014 0.158154 12.7199 0.439484 12.4386C0.720718 12.1573 1.10229 11.9993 1.50008 11.9993C1.89788 11.9993 2.27945 12.1573 2.56068 12.4386C2.84203 12.7199 3 13.1014 3 13.4992C3 13.897 2.84202 14.2786 2.56068 14.5598C2.27945 14.8412 1.89788 14.9991 1.50008 14.9991C1.09832 14.9991 0.713406 14.8381 0.431449 14.5519C0.149492 14.2657 -0.00588337 13.8784 0.000169879 13.4767L0.000169878 13.4992Z"
|
||||
fill="#242424" />
|
||||
</svg>
|
||||
</template>
|
||||
7
src/assets/icons/ic_new_room.vue
Normal file
7
src/assets/icons/ic_new_room.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.7445 5.16411H6.83749V1.25713C6.83749 0.782712 6.4747 0.419922 6.00028 0.419922C5.52586 0.419922 5.16307 0.782712 5.16307 1.25713V5.16411H1.25609C0.781675 5.16411 0.418884 5.5269 0.418884 6.00132C0.418884 6.47573 0.781675 6.83853 1.25609 6.83853H5.16307V10.7455C5.16307 11.2199 5.52586 11.5827 6.00028 11.5827C6.4747 11.5827 6.83749 11.2199 6.83749 10.7455V6.83853H10.7445C11.2189 6.83853 11.5817 6.47573 11.5817 6.00132C11.5817 5.5269 11.2189 5.16411 10.7445 5.16411Z"
|
||||
fill="#242424" />
|
||||
</svg>
|
||||
</template>
|
||||
7
src/assets/icons/ic_public.vue
Normal file
7
src/assets/icons/ic_public.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M9.59107 0.0357724L5.39388 2.30685C5.36127 2.31538 5.31109 2.32819 5.27848 2.33459H0.667336C0.298545 2.33459 0 2.5886 0 2.90236V6.30471C0 6.61847 0.298545 6.87248 0.667336 6.87248H1.13648C1.25439 6.87248 1.35725 6.93864 1.39237 7.03256L2.36933 9.83565C2.40195 9.93383 2.50732 10 2.62523 10H4.73762C4.91575 10 5.04369 9.85486 4.99352 9.71185L4.10687 7.16703C4.05419 7.02189 4.18214 6.87461 4.36277 6.87461H5.26593C5.3136 6.88742 5.35876 6.89809 5.40642 6.90876L9.59107 9.1713C9.76919 9.26735 10 9.15849 10 8.9792V0.22574C10 0.0485792 9.76668 -0.0602787 9.59107 0.0357724Z"
|
||||
fill="#242424" />
|
||||
</svg>
|
||||
</template>
|
||||
|
|
@ -86,6 +86,7 @@
|
|||
},
|
||||
"room": {
|
||||
"invitations": "You have no invitations | You have 1 invitation | You have {count} invitations",
|
||||
"unseen_messages": "You have no unseen messages | You have 1 unseen message | You have {count} unseen messages",
|
||||
"members": "no members | 1 member | {count} members",
|
||||
"leave": "Leave",
|
||||
"purge_set_room_state": "Setting room state",
|
||||
|
|
@ -93,6 +94,7 @@
|
|||
"purge_removing_members": "Removing members ({count} of {total})",
|
||||
"purge_failed": "Failed to purge room!",
|
||||
"room_list_invites": "Invites",
|
||||
"room_list_new_messages": "{count} new messages",
|
||||
"room_list_rooms": "Rooms",
|
||||
"room_name_required": "Room name is required",
|
||||
"room_topic_required": "Room description is required"
|
||||
|
|
@ -172,7 +174,7 @@
|
|||
"logout": "Logout",
|
||||
"want_more": "Want more?",
|
||||
"powered_by": "This room is powered by {product}. Learn more at {productLink} or go ahead and create another room!",
|
||||
"new_room": "+ New room"
|
||||
"new_room": "New room"
|
||||
},
|
||||
"join": {
|
||||
"title": "Welcome you have been invited to join",
|
||||
|
|
@ -246,7 +248,8 @@
|
|||
"user_moderator": "Moderator",
|
||||
"experimental_features": "Experimental Features",
|
||||
"voice_mode": "Voice mode",
|
||||
"voice_mode_info": "Switches the chat interface to a 'listen and record' mode"
|
||||
"voice_mode_info": "Switches the chat interface to a 'listen and record' mode",
|
||||
"download_chat": "Download chat"
|
||||
},
|
||||
"room_info_sheet": {
|
||||
"this_room": "This room",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
v-on="$listeners"
|
||||
>
|
||||
<v-col cols="auto" class="me-2">
|
||||
<v-icon size="22">{{ icon }}</v-icon>
|
||||
<v-icon :size="iconSize">{{ icon }}</v-icon>
|
||||
</v-col>
|
||||
<v-col>{{ text }}</v-col>
|
||||
</v-row>
|
||||
|
|
@ -22,6 +22,12 @@ export default {
|
|||
return null;
|
||||
},
|
||||
},
|
||||
iconSize: {
|
||||
type: Number,
|
||||
default: function() {
|
||||
return 22;
|
||||
}
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: function () {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
color="black"
|
||||
@click.stop="onBackgroundClick"
|
||||
class="bottom-sheet-close"
|
||||
v-if="showCloseButton"
|
||||
>
|
||||
<v-icon color="white" >cancel</v-icon>
|
||||
</v-btn>
|
||||
|
|
@ -40,6 +41,10 @@ import Hammer from "hammerjs";
|
|||
|
||||
export default {
|
||||
props: {
|
||||
showCloseButton: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
openY: {
|
||||
type: Number,
|
||||
default: 0.1,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<div class="chat-root fill-height d-flex flex-column">
|
||||
<div class="chat-room-invitations clickable" v-if="invitationCount > 0" @click.stop="onInvitationsClick">
|
||||
{{ $tc("room.invitations", invitationCount) }}
|
||||
</div>
|
||||
<ChatHeader class="chat-header flex-grow-0 flex-shrink-0" v-on:header-click="onHeaderClick" />
|
||||
<ChatHeader class="chat-header flex-grow-0 flex-shrink-0" v-on:header-click="onHeaderClick" v-on:view-room-details="viewRoomDetails" />
|
||||
<AudioLayout ref="chatContainer" class="auto-audio-player-root" v-if="useVoiceMode" :room="room"
|
||||
:events="events" :autoplay="!showRecorder"
|
||||
:timelineSet="timelineSet"
|
||||
|
|
@ -513,9 +510,6 @@ export default {
|
|||
debugging() {
|
||||
return false; //(window.location.host || "").startsWith("localhost");
|
||||
},
|
||||
invitationCount() {
|
||||
return this.$matrix.invites.length;
|
||||
},
|
||||
canCreatePoll() {
|
||||
// We say that if you can redact events, you are allowed to create polls.
|
||||
const me = this.room && this.room.getMember(this.$matrix.currentUserId);
|
||||
|
|
@ -1436,16 +1430,17 @@ export default {
|
|||
},
|
||||
|
||||
onHeaderClick() {
|
||||
const invitations = this.$matrix.invites.length;
|
||||
const joinedRooms = this.$matrix.joinedRooms;
|
||||
if (joinedRooms && joinedRooms.length == 1 && joinedRooms[0].roomId == this.room.roomId) {
|
||||
if (invitations == 0 && joinedRooms && joinedRooms.length == 1 && joinedRooms[0].roomId == this.room.roomId) {
|
||||
// Only joined to this room, go directly to room details!
|
||||
this.$navigation.push({ name: "RoomInfo" });
|
||||
return;
|
||||
}
|
||||
this.$refs.roomInfoSheet.open();
|
||||
},
|
||||
onInvitationsClick() {
|
||||
this.$navigation.push({ name: "Home" }, -1);
|
||||
viewRoomDetails() {
|
||||
this.$navigation.push({ name: "RoomInfo" });
|
||||
},
|
||||
pollWasClosed(ignoredE) {
|
||||
let div = document.createElement("div");
|
||||
|
|
|
|||
|
|
@ -1,92 +1,73 @@
|
|||
<template>
|
||||
<v-container fluid v-if="room">
|
||||
<v-row class="chat-header-row flex-nowrap">
|
||||
<v-col
|
||||
cols="auto"
|
||||
class="chat-header-members text-start ma-0 pa-0"
|
||||
@click.stop="onHeaderClicked"
|
||||
>
|
||||
<v-avatar size="40" class="me-2">
|
||||
<v-img v-if="room.avatar || memberAvatar" :src="room.avatar || memberAvatar" />
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="chat-header-name ma-0 pa-0 flex-shrink-1 flex-nowrap"
|
||||
@click.stop="onHeaderClicked"
|
||||
>
|
||||
<div class="room-name-inline text-truncate" :title="room.name">
|
||||
{{ room.name }}<v-icon class="icon-dropdown" size="11">$vuetify.icons.ic_dropdown</v-icon><div class="notification-alert" v-if="notifications"></div>
|
||||
|
||||
<!--<v-icon>expand_more</v-icon>-->
|
||||
<v-col class="chat-header-name ma-0 pa-0 flex-shrink-1 flex-nowrap" @click.stop="onHeaderClicked">
|
||||
<div class="room-title-row">
|
||||
<div class="room-name-inline text-truncate" :title="room.name">
|
||||
{{ room.name }}
|
||||
</div>
|
||||
<v-icon class="icon-dropdown" size="11">$vuetify.icons.ic_dropdown</v-icon>
|
||||
<div :class="{ 'notification-alert': true, 'popup-open': showMissedItemsInfo }" v-if="notifications">
|
||||
<!-- MISSED ITEMS POPUP -->
|
||||
<div class="missed-items-popup-background" v-if="showMissedItemsInfo" @click.stop=""></div>
|
||||
<div class="missed-items-popup" v-if="showMissedItemsInfo">
|
||||
<div class="text">{{ notificationsText }}</div>
|
||||
<div class="button clickable" @click.stop="$store.commit('setHasShownMissedItemsHint', true)">{{$t('menu.ok')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="num-members">{{ $tc("room.members", memberCount) }}</div>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0">
|
||||
<v-btn
|
||||
id="btn-purge-room"
|
||||
v-if="userCanPurgeRoom"
|
||||
class="mx-2 box-shadow-none"
|
||||
fab
|
||||
dark
|
||||
small
|
||||
color="red"
|
||||
@click.stop="showPurgeConfirmation = true"
|
||||
>
|
||||
<v-icon light>$vuetify.icons.ic_moderator-delete</v-icon>
|
||||
</v-btn>
|
||||
<v-btn
|
||||
id="btn-leave-room"
|
||||
class="mx-2 box-shadow-none"
|
||||
fab
|
||||
dark
|
||||
small
|
||||
color="red"
|
||||
@click.stop="leaveRoom"
|
||||
v-else
|
||||
>
|
||||
<v-icon>$vuetify.icons.ic_member-leave</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-2">
|
||||
<v-avatar
|
||||
class="avatar-32 clickable"
|
||||
size="40"
|
||||
color="#e0e0e0"
|
||||
@click.stop="showProfileInfo = true"
|
||||
>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1">
|
||||
<v-avatar :class="{ 'avatar-32': true, 'clickable': true, 'popup-open': showProfileInfo }" size="26"
|
||||
color="#e0e0e0" @click.stop="showProfileInfo = true">
|
||||
<img v-if="userAvatar" :src="userAvatar" />
|
||||
<span v-else class="white--text">{{ userAvatarLetter }}</span>
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1">
|
||||
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red"
|
||||
@click.stop="showPurgeConfirmation = true">
|
||||
<v-icon light>$vuetify.icons.ic_moderator-delete</v-icon>
|
||||
</v-btn>
|
||||
<v-btn id="btn-leave-room" class="mx-2 box-shadow-none" fab dark small color="red" @click.stop="leaveRoom" v-else>
|
||||
<v-icon color="white">$vuetify.icons.ic_member-leave</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1 clickable">
|
||||
<div :class="{ 'popup-open': showMoreMenu }">
|
||||
<v-btn class="mx-2 box-shadow-none" fab dark small color="transparent" @click.stop="showMoreMenu = true">
|
||||
<v-icon size="15" color="black">$vuetify.icons.ic_more</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- "REALLY LEAVE?" dialog -->
|
||||
<LeaveRoomDialog
|
||||
:show="showLeaveConfirmation"
|
||||
:room="room"
|
||||
@close="showLeaveConfirmation = false"
|
||||
/>
|
||||
<LeaveRoomDialog :show="showLeaveConfirmation" :room="room" @close="showLeaveConfirmation = false" />
|
||||
|
||||
<!-- PROFILE INFO POPUP -->
|
||||
<ProfileInfoPopup
|
||||
:show="showProfileInfo"
|
||||
@close="showProfileInfo = false"
|
||||
/>
|
||||
<ProfileInfoPopup :show="showProfileInfo" @close="showProfileInfo = false" />
|
||||
|
||||
<!-- MORE MENU POPUP -->
|
||||
<MoreMenuPopup :show="showMoreMenu" :menuItems="moreMenuItems" @close="showMoreMenu = false"
|
||||
v-on:leave="showLeaveConfirmation = true" />
|
||||
|
||||
<!-- PURGE ROOM POPUP -->
|
||||
<PurgeRoomDialog
|
||||
:show="showPurgeConfirmation"
|
||||
:room="room"
|
||||
@close="showPurgeConfirmation = false"
|
||||
/>
|
||||
<PurgeRoomDialog :show="showPurgeConfirmation" :room="room" @close="showPurgeConfirmation = false" />
|
||||
|
||||
<RoomExport :room="room" v-if="downloadingChat" v-on:close="downloadingChat = false" />
|
||||
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LeaveRoomDialog from "../components/LeaveRoomDialog";
|
||||
import ProfileInfoPopup from "../components/ProfileInfoPopup";
|
||||
import MoreMenuPopup from "../components/MoreMenuPopup";
|
||||
import profileInfoMixin from "../components/profileInfoMixin";
|
||||
import PurgeRoomDialog from "../components/PurgeRoomDialog";
|
||||
import RoomExport from "../components/RoomExport";
|
||||
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
|
||||
|
|
@ -96,14 +77,18 @@ export default {
|
|||
components: {
|
||||
LeaveRoomDialog,
|
||||
ProfileInfoPopup,
|
||||
PurgeRoomDialog
|
||||
MoreMenuPopup,
|
||||
PurgeRoomDialog,
|
||||
RoomExport
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
memberCount: null,
|
||||
showLeaveConfirmation: false,
|
||||
showProfileInfo: false,
|
||||
showPurgeConfirmation: false
|
||||
showPurgeConfirmation: false,
|
||||
showMoreMenu: false,
|
||||
downloadingChat: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -123,8 +108,8 @@ export default {
|
|||
let roomMember;
|
||||
if (this.room) {
|
||||
this.room.getMembers().forEach(member => {
|
||||
if(this.room.name === member.name) {
|
||||
roomMember = member;
|
||||
if (this.room.name === member.name) {
|
||||
roomMember = member;
|
||||
}
|
||||
});
|
||||
if (roomMember) {
|
||||
|
|
@ -140,8 +125,57 @@ export default {
|
|||
return null;
|
||||
},
|
||||
notifications() {
|
||||
return this.$matrix.joinedRooms.some(room => room.roomId !== this.$matrix.currentRoomId && room.getUnreadNotificationCount("total") > 0);
|
||||
}
|
||||
return this.$matrix.joinedRooms.some(room => room.roomId !== this.$matrix.currentRoomId && room.getUnreadNotificationCount("total") > 0) ||
|
||||
this.$matrix.invites.length > 0;
|
||||
},
|
||||
notificationsText() {
|
||||
const invitationCount = this.$matrix.invites.length
|
||||
if (invitationCount > 0) {
|
||||
return this.$tc('room.invitations', invitationCount);
|
||||
}
|
||||
const missedMessagesCount = this.$matrix.joinedRooms.reduce((value, room) => (room.roomId !== this.$matrix.currentRoomId ? (value + room.getUnreadNotificationCount("total")) : value), 0);
|
||||
if (missedMessagesCount > 0) {
|
||||
return this.$tc('room.unseen_messages', missedMessagesCount);
|
||||
}
|
||||
return "";
|
||||
},
|
||||
moreMenuItems() {
|
||||
let items = [];
|
||||
const roomLink = this.publicRoomLink;
|
||||
if (roomLink) {
|
||||
items.push({
|
||||
icon: '$vuetify.icons.ic_link', text: this.$t('room_info.copy_link'), handler: () => {
|
||||
this.$copyText(this.publicRoomLink);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (this.userCanExportChat) {
|
||||
items.push({
|
||||
icon: '$vuetify.icons.ic_download', text: this.$t('room_info.download_chat'), handler: () => {
|
||||
this.downloadingChat = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
icon: '$vuetify.icons.ic_info', text: this.$t('room_info.title'), handler: () => {
|
||||
this.$emit("view-room-details", { event: this.event });
|
||||
}
|
||||
});
|
||||
items.push({
|
||||
icon: '$vuetify.icons.ic_member-leave', text: this.$t('leave.leave'), handler: () => {
|
||||
this.leaveRoom();
|
||||
}
|
||||
});
|
||||
return items;
|
||||
},
|
||||
showMissedItemsInfo: {
|
||||
get() {
|
||||
return this.notifications && (this.$store.state.hasShownMissedItemsHint !== true);
|
||||
},
|
||||
set(newValue) {
|
||||
console.log("Ignore", newValue);
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
room: {
|
||||
|
|
@ -186,4 +220,36 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
|
||||
.popup-open {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.popup-open::after {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
content: "▲";
|
||||
top: 30px;
|
||||
margin-left: -10px;
|
||||
font-size: 20px;
|
||||
color: #ffffff;
|
||||
z-index: 400;
|
||||
pointer-events: none;
|
||||
animation-duration: 0.3s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: both;
|
||||
animation-name: fadein;
|
||||
animation-iteration-count: 1;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -15,8 +15,6 @@
|
|||
<RoomList
|
||||
showInvites
|
||||
showCreate
|
||||
title=""
|
||||
:invitesTitle="$t('room.room_list_invites')"
|
||||
v-on:newroom="createRoom"
|
||||
/>
|
||||
</v-card-text>
|
||||
|
|
|
|||
169
src/components/MoreMenuPopup.vue
Normal file
169
src/components/MoreMenuPopup.vue
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
<template>
|
||||
<v-dialog v-model="showDialog" content-class="more-menu-popup" class="ma-0 pa-0">
|
||||
<div class="popup-wrapper">
|
||||
<v-card flat>
|
||||
<v-card-text>
|
||||
|
||||
<v-container class="mt-0 pa-0 action-row-container-no-dividers">
|
||||
<ActionRow v-for="item in menuItems" :key="item.name" :icon="item.icon" :iconSize="16" :text="item.text" @click="$emit('close');item.handler()" />
|
||||
|
||||
<v-row class="profile-row clickable" @click="viewProfile" no-gutters align-content="center">
|
||||
<v-col cols="auto" class="me-2">
|
||||
<v-avatar class="avatar-32" size="32" color="#e0e0e0" @click.stop="viewProfile">
|
||||
<img v-if="userAvatar" :src="userAvatar" />
|
||||
<span v-else class="white--text">{{ userAvatarLetter }}</span>
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<div class="profile-label">{{ $t('profile.title') }}</div>
|
||||
<div class="display-name">{{ displayName }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import profileInfoMixin from "./profileInfoMixin";
|
||||
import ActionRow from "./ActionRow.vue";
|
||||
|
||||
export default {
|
||||
name: "MoreMenuPopup",
|
||||
mixins: [profileInfoMixin],
|
||||
components: { ActionRow },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
menuItems: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
immediate: true,
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog() {
|
||||
if (!this.showDialog) {
|
||||
this.$emit("close");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
viewProfile() {
|
||||
this.showDialog = false;
|
||||
this.$navigation.push({ name: "Profile" }, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
@import '~vuetify/src/styles/settings/_variables.scss';
|
||||
|
||||
.popup-wrapper {
|
||||
width: fit-content;
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 18px;
|
||||
pointer-events: initial;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.more-menu-popup {
|
||||
font-family: "Inter", sans-serif !important;
|
||||
font-size: 16px;
|
||||
line-height: 117%;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.4px;
|
||||
position: fixed;
|
||||
margin: 0px;
|
||||
top: 70px;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
box-shadow: none;
|
||||
pointer-events: none;
|
||||
.v-card__text {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
height: 40px;
|
||||
padding: 4px 20px !important;
|
||||
font-size: 16px;
|
||||
color: #000B16;
|
||||
}
|
||||
|
||||
.profile-row {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding: 20px 20px !important;
|
||||
}
|
||||
|
||||
.action-row:after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.profile-label {
|
||||
letter-spacing: 0.4px;
|
||||
color: #000B16;
|
||||
}
|
||||
|
||||
.display-name {
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.4px;
|
||||
color: #000B16;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
//border-radius: 40px;
|
||||
width: 95%;
|
||||
|
||||
@media #{map-get($display-breakpoints, 'sm-and-up')} {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
@media #{map-get($display-breakpoints, 'lg-and-up')} {
|
||||
overflow: unset;
|
||||
width: $main-desktop-width;
|
||||
;
|
||||
position: absolute;
|
||||
top: 70px;
|
||||
right: unset;
|
||||
width: $dialog-desktop-width;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
// .v-card {
|
||||
// border-radius: 20px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,51 +1,38 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
v-model="showDialog"
|
||||
content-class="profile-info-popup"
|
||||
class="ma-0 pa-0"
|
||||
>
|
||||
<v-dialog v-model="showDialog" content-class="profile-info-popup" class="ma-0 pa-0">
|
||||
<v-card flat>
|
||||
<v-card-text>
|
||||
<div class="you-are">{{ $t("profile_info_popup.you_are") }}</div>
|
||||
<v-container fluid>
|
||||
<v-row>
|
||||
<v-col :class="['username',{'editable': editDisplayName }]" cols="pa-2" ref="username">
|
||||
<v-col :class="['username', { 'editable': editDisplayName }]" cols="pa-2" ref="username">
|
||||
<div v-if="$matrix.currentUser.is_guest">
|
||||
<i18n path="profile_info_popup.identity_temporary" tag="span">
|
||||
<template v-slot:displayName>
|
||||
<input
|
||||
v-model="displayName"
|
||||
@blur="
|
||||
updateDisplayName($event.target.value);
|
||||
editDisplayName = !editDisplayName;
|
||||
"
|
||||
@focus="editDisplayName = !editDisplayName"
|
||||
/>
|
||||
<input v-model="displayName"
|
||||
@keyup.enter="$event => $event.target.blur()"
|
||||
@blur="
|
||||
updateDisplayName($event.target.value);
|
||||
editDisplayName = !editDisplayName;
|
||||
" @focus="editDisplayName = !editDisplayName" />
|
||||
</template>
|
||||
</i18n>
|
||||
</div>
|
||||
<div v-else>
|
||||
<i18n path="profile_info_popup.identity" tag="span">
|
||||
<template v-slot:displayName>
|
||||
<input
|
||||
<input
|
||||
v-model="displayName"
|
||||
@blur="
|
||||
updateDisplayName($event.target.value);
|
||||
editDisplayName = !editDisplayName;
|
||||
"
|
||||
@focus="editDisplayName = !editDisplayName"
|
||||
/>
|
||||
@keyup.enter="$event => $event.target.blur()"
|
||||
@blur="updateDisplayName($event.target.value);editDisplayName = !editDisplayName;"
|
||||
@focus="editDisplayName = !editDisplayName"
|
||||
/>
|
||||
</template>
|
||||
</i18n>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="pa-2">
|
||||
<v-avatar
|
||||
class="avatar-32"
|
||||
size="32"
|
||||
color="#e0e0e0"
|
||||
@click.stop="viewProfile"
|
||||
>
|
||||
<v-avatar class="avatar-32" size="32" color="#e0e0e0" @click.stop="viewProfile">
|
||||
<img v-if="userAvatar" :src="userAvatar" />
|
||||
<span v-else class="white--text">{{ userAvatarLetter }}</span>
|
||||
</v-avatar>
|
||||
|
|
@ -53,24 +40,6 @@
|
|||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<v-container class="mt-4 pa-0">
|
||||
<ActionRow
|
||||
@click="viewProfile"
|
||||
:icon="'account_circle'"
|
||||
:text="$t('profile_info_popup.edit_profile')"
|
||||
/>
|
||||
<ActionRow
|
||||
@click.stop="showLogoutPopup=true"
|
||||
:icon="'logout'"
|
||||
:text="$t('profile_info_popup.logout')"
|
||||
/>
|
||||
<LogoutRoomDialog
|
||||
:showLogoutPopup="showLogoutPopup"
|
||||
@onOutsideLogoutPopupClicked="showLogoutPopup=false"
|
||||
@onCancelLogoutClicked="showLogoutPopup=false"
|
||||
/>
|
||||
</v-container>
|
||||
|
||||
<div class="more-container">
|
||||
<div class="want_more">
|
||||
🙌 {{ $t("profile_info_popup.want_more") }}
|
||||
|
|
@ -78,7 +47,7 @@
|
|||
<i18n path="profile_info_popup.powered_by" tag="div">
|
||||
<template v-slot:product>{{ product }}</template>
|
||||
<template v-slot:productLink>
|
||||
<a :href="'//'+productLink">{{ productLink }}</a>
|
||||
<a :href="'//' + productLink">{{ productLink }}</a>
|
||||
</template>
|
||||
</i18n>
|
||||
<div class="text-end">
|
||||
|
|
@ -93,16 +62,10 @@
|
|||
</template>
|
||||
<script>
|
||||
import profileInfoMixin from "./profileInfoMixin";
|
||||
import ActionRow from "./ActionRow.vue";
|
||||
import LogoutRoomDialog from './LogoutRoomDialog.vue';
|
||||
|
||||
export default {
|
||||
name: "ProfileInfoPopup",
|
||||
mixins: [profileInfoMixin],
|
||||
components: {
|
||||
ActionRow,
|
||||
LogoutRoomDialog
|
||||
},
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
|
|
@ -115,7 +78,6 @@ export default {
|
|||
return {
|
||||
showDialog: false,
|
||||
editDisplayName: false,
|
||||
showLogoutPopup: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -163,28 +125,20 @@ export default {
|
|||
margin: 0px;
|
||||
top: 70px;
|
||||
right: 10px;
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
border-radius: 40px;
|
||||
width: 95%;
|
||||
|
||||
&::before {
|
||||
content: "▲";
|
||||
position: fixed;
|
||||
top: 57px;
|
||||
right: 22px;
|
||||
[dir="rtl"] & {
|
||||
left: 22px;
|
||||
right: inherit;
|
||||
}
|
||||
color: white;
|
||||
}
|
||||
.you-are {
|
||||
padding-top: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.username {
|
||||
border-radius: 4px;
|
||||
background-color: #f5f5f5;
|
||||
|
|
@ -202,19 +156,45 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.more-container {
|
||||
border-radius: 10px;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 14 * $chat-text-size;
|
||||
line-height: 117%;
|
||||
letter-spacing: 0.4px;
|
||||
color: #000B16;
|
||||
margin-top: 18px;
|
||||
a {
|
||||
color: #000B16 !important;
|
||||
}
|
||||
.want_more {
|
||||
font-family: "Poppins", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 13 * $chat-text-size;
|
||||
color: #0e252d;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.new_room {
|
||||
margin-top: 16px;
|
||||
height: 27px;
|
||||
border-radius: 13.5px;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
.new_room .v-btn__content {
|
||||
font-family: "Poppins", sans-serif !important;
|
||||
font-weight: 700 !important;
|
||||
font-size: 13 * $chat-text-size !important;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 10 * $chat-text-size !important;
|
||||
line-height: 133%;
|
||||
letter-spacing: 0.34px;
|
||||
text-transform: uppercase;
|
||||
color: #181719;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +204,8 @@ export default {
|
|||
|
||||
@media #{map-get($display-breakpoints, 'lg-and-up')} {
|
||||
overflow: unset;
|
||||
width: $main-desktop-width;;
|
||||
width: $main-desktop-width;
|
||||
;
|
||||
position: absolute;
|
||||
top: 70px;
|
||||
right: unset;
|
||||
|
|
|
|||
|
|
@ -4,12 +4,6 @@
|
|||
<!-- Header-->
|
||||
<v-container fluid class="chat-header flex-grow-0 flex-shrink-0">
|
||||
<v-row class="chat-header-row flex-nowrap">
|
||||
<v-col cols="auto" class="chat-header-members text-start ma-0 pa-0" @click.stop="onHeaderClicked">
|
||||
<v-avatar size="40" class="me-2">
|
||||
<v-img v-if="room.avatar" :src="room.avatar" />
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
|
||||
<v-col class="chat-header-name ma-0 pa-0 flex-shrink-1 flex-nowrap">
|
||||
<div class="room-name-inline text-truncate" :title="room.name">
|
||||
{{ room.name }}
|
||||
|
|
|
|||
|
|
@ -3,52 +3,16 @@
|
|||
class="room-info-bottom-sheet"
|
||||
:halfY="0.12"
|
||||
ref="sheet"
|
||||
:showCloseButton="false"
|
||||
>
|
||||
<div class="room-info-sheet" ref="roomInfoSheetContent">
|
||||
<div class="text-center current-room">
|
||||
<room-avatar-picker />
|
||||
<div class="h4">{{$t('room_info_sheet.this_room')}}</div>
|
||||
<div
|
||||
class="h2"
|
||||
v-if="!isRoomNameEditMode"
|
||||
@click="onRoomNameClicked()"
|
||||
>
|
||||
{{ roomName }}
|
||||
</div>
|
||||
<v-text-field
|
||||
v-model="editedRoomName"
|
||||
ref="editedRoomName"
|
||||
:rules="[(v) => !!v || $t('room.room_name_required')]"
|
||||
:error="roomNameErrorMessage != null"
|
||||
:error-messages="roomNameErrorMessage"
|
||||
required
|
||||
color="black"
|
||||
counter="50"
|
||||
background-color="white"
|
||||
autofocus
|
||||
v-if="isRoomNameEditMode"
|
||||
maxlength="50"
|
||||
@blur="updateRoomName()"
|
||||
@keyup.enter="updateRoomName()"
|
||||
solo
|
||||
></v-text-field>
|
||||
<v-btn
|
||||
id="btn-room-details"
|
||||
height="20px"
|
||||
color="black"
|
||||
class="filled-button"
|
||||
@click.stop="showDetails"
|
||||
>{{$t('room_info_sheet.view_details')}}</v-btn
|
||||
>
|
||||
</div>
|
||||
<room-list :title="'Other rooms'" v-on:close="close" v-on:newroom="createRoom" :showCreate="true" />
|
||||
<room-list v-on:close="close" v-on:newroom="createRoom" :showCreate="true" />
|
||||
</div>
|
||||
</BottomSheet>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BottomSheet from "./BottomSheet";
|
||||
import RoomAvatarPicker from "./RoomAvatarPicker";
|
||||
import RoomList from "./RoomList";
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
|
||||
|
|
@ -58,7 +22,6 @@ export default {
|
|||
components: {
|
||||
BottomSheet,
|
||||
RoomList,
|
||||
RoomAvatarPicker,
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
|
|
|
|||
|
|
@ -1,70 +1,59 @@
|
|||
<template>
|
||||
<v-list dense class="room-list">
|
||||
<div class="h4">{{ title }}</div>
|
||||
<v-list-item-group v-model="currentRoomId" color="primary">
|
||||
<v-list-item v-if="showCreate" @click.stop="$emit('newroom')">
|
||||
|
||||
<v-list-item v-if="showCreate" @click.stop="$emit('newroom')" class="room-list-room">
|
||||
<v-list-item-avatar class="round" size="42" color="#d9d9d9">
|
||||
<v-icon size="11">$vuetify.icons.ic_new_room</v-icon>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="new-room">{{
|
||||
<v-list-item-title class="room-list-new-room">{{
|
||||
$t("menu.new_room")
|
||||
}}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<!-- invites -->
|
||||
<v-list-item
|
||||
:disabled="roomsProcessing[room.roomId]"
|
||||
v-for="room in invitedRooms"
|
||||
:key="room.roomId"
|
||||
:value="room.roomId"
|
||||
>
|
||||
<v-list-item-avatar size="40" color="#e0e0e0">
|
||||
<v-img v-if="room.avatar" :src="room.avatar" />
|
||||
<v-list-item :disabled="roomsProcessing[room.roomId]" v-for="room in invitedRooms" :key="room.roomId"
|
||||
:value="room.roomId" class="room-list-room">
|
||||
<v-list-item-avatar size="42" color="#d9d9d9">
|
||||
<v-img v-if="roomAvatar(room)" :src="roomAvatar(room)" />
|
||||
<span v-else class="white--text headline">{{
|
||||
room.name.substring(0, 1).toUpperCase()
|
||||
}}</span>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ room.name }}</v-list-item-title>
|
||||
<v-list-item-title class="room-list-name">{{ room.name }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ room.topic }}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn
|
||||
id="btn-accept"
|
||||
class="filled-button"
|
||||
depressed
|
||||
color="black"
|
||||
@click.stop="acceptInvitation(room)"
|
||||
>{{ $t("menu.join") }}</v-btn
|
||||
>
|
||||
<v-btn
|
||||
id="btn-reject"
|
||||
class="filled-button"
|
||||
color="black"
|
||||
@click.stop="rejectInvitation(room)"
|
||||
text
|
||||
>{{ $t("menu.ignore") }}</v-btn
|
||||
>
|
||||
<v-btn id="btn-accept" class="filled-button" depressed color="black" @click.stop="acceptInvitation(room)">{{
|
||||
$t("menu.join") }}</v-btn>
|
||||
<v-btn id="btn-reject" class="filled-button" color="black" @click.stop="rejectInvitation(room)" text>{{
|
||||
$t("menu.ignore") }}</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-for="room in joinedRooms"
|
||||
:key="room.roomId"
|
||||
:value="room.roomId"
|
||||
>
|
||||
<v-list-item-avatar size="40" color="#e0e0e0">
|
||||
<v-img v-if="room.avatar" :src="room.avatar" />
|
||||
<v-list-item v-for="room in joinedRooms" :key="room.roomId" :value="room.roomId" class="room-list-room"
|
||||
#default="{ active }">
|
||||
<v-list-item-avatar size="42" color="#d9d9d9">
|
||||
<v-img v-if="roomAvatar(room)" :src="roomAvatar(room)" />
|
||||
<span v-else class="white--text headline">{{
|
||||
room.name.substring(0, 1).toUpperCase()
|
||||
}}</span>
|
||||
</v-list-item-avatar>
|
||||
<div class="room-list-notification-count" v-if="notificationCount(room) > 0">
|
||||
{{ notificationCount(room) }}
|
||||
</div>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ room.name }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ room.topic }}</v-list-item-subtitle>
|
||||
<v-list-item-title class="room-list-name">{{ room.name }}
|
||||
<v-icon class="ml-2 mb-1" size="10" v-if="isPublic(room)">$vuetify.icons.ic_public</v-icon>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="room-list-new-messages" v-if="notificationCount(room) > 0">
|
||||
{{ $t("room.room_list_new_messages", { count: notificationCount(room) }) }}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-icon size="16" v-if="active">$vuetify.icons.ic_circle_filled</v-icon>
|
||||
<v-icon size="16" v-else>$vuetify.icons.ic_circle</v-icon>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
|
|
@ -108,6 +97,26 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
roomAvatar(room) {
|
||||
if (this.isDirect(room)) {
|
||||
if (room.avatar) {
|
||||
return room.avatar;
|
||||
}
|
||||
const membersNotMe = room.getMembers().filter(m => m.userId != this.$matrix.currentUserId);
|
||||
if (membersNotMe && membersNotMe.length == 1) {
|
||||
return membersNotMe[0].getAvatarUrl(
|
||||
this.$matrix.matrixClient.getHomeserverUrl(),
|
||||
42,
|
||||
42,
|
||||
"scale",
|
||||
true
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return room.avatar;
|
||||
}
|
||||
},
|
||||
|
||||
sortItemsOnName(items) {
|
||||
if (items == null) {
|
||||
return [];
|
||||
|
|
@ -166,6 +175,14 @@ export default {
|
|||
Vue.delete(this.roomsProcessing, room.roomId);
|
||||
});
|
||||
},
|
||||
|
||||
isPublic(room) {
|
||||
return this.$matrix.getRoomJoinRule(room) === "public"
|
||||
},
|
||||
|
||||
isDirect(room) {
|
||||
return this.$matrix.isDirectRoom(room);
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
|
|
|||
|
|
@ -799,6 +799,20 @@ export default {
|
|||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return true if this room is a direct room with one other user. NOTE: this currently
|
||||
* only checks number of members, not any is_direct flag.
|
||||
* @param { } room
|
||||
*/
|
||||
isDirectRoom(room) {
|
||||
// TODO - Use the is_direct accountData flag (m.direct). WE (as the client)
|
||||
// apprently need to set this...
|
||||
if (room.getJoinRule() == "invite" && room.getMembers().length == 2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
on(event, handler) {
|
||||
if (this.matrixClient) {
|
||||
this.matrixClient.on(event, handler);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ const vuexPersistLocalStorage = new VuexPersist({
|
|||
return {
|
||||
language: state.language,
|
||||
currentRoomId: state.currentRoomId,
|
||||
hasShownMissedItemsHint: state.hasShownMissedItemsHint,
|
||||
};
|
||||
} else {
|
||||
return {};
|
||||
|
|
@ -55,6 +56,7 @@ const vuexPersistSessionStorage = new VuexPersist({
|
|||
return {
|
||||
language: state.language,
|
||||
currentRoomId: state.currentRoomId,
|
||||
hasShownMissedItemsHint: state.hasShownMissedItemsHint,
|
||||
};
|
||||
} else {
|
||||
return {};
|
||||
|
|
@ -93,6 +95,9 @@ export default new Vuex.Store({
|
|||
},
|
||||
setUseLocalStorage(state, useLocalStorage) {
|
||||
state.useLocalStorage = useLocalStorage;
|
||||
},
|
||||
setHasShownMissedItemsHint(state) {
|
||||
state.hasShownMissedItemsHint = true;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue