mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 18:30:26 -06:00
FIX: limits max height to viewport on channel only (#21539)
Before this commit chat was applying a fixed height on everything under the `/chat` route. It's only really needed on the channel page with the composer at the bottom of the page. This commits makes the following changes: - moves height limitation from `#main-outlet-wrapper` to `.chat-channel` - makes browse channel page and members list page full height and rely on main document scrollbar - adds height computation for draft header and direct message creator block to ensure the height is correct when creating a draft channel - makes chat index full height to rely on the browser scrollbar. As a result the <kbd> + </kbd> button used on mobile to create a direct message as been moved out of `<ChannelsList>` into the chat index template - sidebar height was relying on chat setting a max height, as a result the height computation of sidebar has been changed to work correctly, especially with an opened keyboard on mobile or ipad
This commit is contained in:
parent
9a2780397f
commit
5ce0697348
@ -31,18 +31,21 @@
|
|||||||
|
|
||||||
@include unselectable;
|
@include unselectable;
|
||||||
|
|
||||||
// 100dvh with fallback for old browsers
|
// 1dvh with fallback for old browsers
|
||||||
--100dvh: 100vh;
|
--1dvh: 1vh;
|
||||||
@supports (height: 100dvh) {
|
@supports (height: 1dvh) {
|
||||||
--100dvh: 100dvh;
|
--1dvh: 1dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
height: calc(var(--100dvh) - var(--header-offset, 0px));
|
height: calc(
|
||||||
|
var(--composer-vh, var(--1dvh)) * 100 - var(--header-offset, 0px)
|
||||||
|
);
|
||||||
|
|
||||||
.footer-nav-ipad & {
|
.footer-nav-ipad & {
|
||||||
top: calc(var(--header-offset) + var(--footer-nav-height));
|
top: calc(var(--header-offset) + var(--footer-nav-height));
|
||||||
height: calc(
|
height: calc(
|
||||||
var(--100dvh) - var(--header-offset, 0px) - var(--footer-nav-height, 0px)
|
var(--composer-vh, var(--1dvh)) * 100 - var(--header-offset, 0px) -
|
||||||
|
var(--footer-nav-height, 0px)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
{{#if
|
{{#if this.showMobileDirectMessageButton}}
|
||||||
(and this.showMobileDirectMessageButton this.canCreateDirectMessageChannel)
|
|
||||||
}}
|
|
||||||
<LinkTo
|
<LinkTo
|
||||||
@route="chat.draft-channel"
|
@route="chat.draft-channel"
|
||||||
class="btn-flat open-draft-channel-page-btn keep-mobile-sidebar-open btn-floating"
|
class="btn-flat open-draft-channel-page-btn keep-mobile-sidebar-open btn-floating"
|
||||||
title={{i18n this.createDirectMessageChannelLabel}}
|
title={{i18n "chat.direct_messages.new"}}
|
||||||
>
|
>
|
||||||
{{d-icon "plus"}}
|
{{d-icon "plus"}}
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
@ -62,6 +60,7 @@
|
|||||||
/>
|
/>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ export default class ChannelsList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get showMobileDirectMessageButton() {
|
get showMobileDirectMessageButton() {
|
||||||
return this.site.mobileView && this.showDirectMessageChannels;
|
return this.site.mobileView && this.canCreateDirectMessageChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
get inSidebar() {
|
get inSidebar() {
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
{{#if this.chatProgressBarContainer}}
|
|
||||||
{{#in-element this.chatProgressBarContainer}}
|
|
||||||
<DProgressBar
|
|
||||||
@key="browse-list"
|
|
||||||
@isLoading={{this.channelsCollection.loading}}
|
|
||||||
/>
|
|
||||||
{{/in-element}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="chat-browse-view__header chat-full-page-header">
|
<div class="chat-browse-view__header chat-full-page-header">
|
||||||
{{#if this.site.mobileView}}
|
{{#if this.site.mobileView}}
|
||||||
<LinkTo
|
<LinkTo
|
||||||
@ -75,18 +66,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else if this.channelsCollection.length}}
|
{{else if this.channelsCollection.length}}
|
||||||
<div class="chat-browse-view__content_wrapper">
|
<LoadMore
|
||||||
<div class="chat-browse-view__content">
|
@selector=".chat-channel-card"
|
||||||
<div class="chat-browse-view__cards">
|
@action={{this.channelsCollection.loadMore}}
|
||||||
{{#each this.channelsCollection as |channel|}}
|
>
|
||||||
<ChatChannelCard @channel={{channel}} />
|
<div class="chat-browse-view__content_wrapper">
|
||||||
{{/each}}
|
<div class="chat-browse-view__content">
|
||||||
|
<div class="chat-browse-view__cards">
|
||||||
|
{{#each this.channelsCollection as |channel|}}
|
||||||
|
<ChatChannelCard @channel={{channel}} />
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#unless this.channelsCollection.loading}}
|
|
||||||
<OnVisibilityAction @action={{action "onScroll"}} />
|
|
||||||
{{/unless}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<ConditionalLoadingSpinner
|
||||||
|
@condition={{this.channelsCollection.loading}}
|
||||||
|
/>
|
||||||
|
</LoadMore>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
@ -1,45 +1,41 @@
|
|||||||
{{#if this.chatProgressBarContainer}}
|
|
||||||
{{#in-element this.chatProgressBarContainer}}
|
|
||||||
<DProgressBar @key="members-view" @isLoading={{this.members.loading}} />
|
|
||||||
{{/in-element}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if (gt this.channel.membershipsCount 0)}}
|
{{#if (gt this.channel.membershipsCount 0)}}
|
||||||
<div class="channel-members-view-wrapper">
|
<LoadMore
|
||||||
<div
|
@selector=".channel-members-view__list-item"
|
||||||
class={{concat
|
@action={{this.loadMore}}
|
||||||
"channel-members-view__search-input-container"
|
>
|
||||||
(if this.isSearchFocused " is-focused")
|
<div class="channel-members-view-wrapper">
|
||||||
}}
|
<div
|
||||||
>
|
class={{concat
|
||||||
<Input
|
"channel-members-view__search-input-container"
|
||||||
class={{this.inputSelector}}
|
(if this.isSearchFocused " is-focused")
|
||||||
placeholder={{i18n "chat.members_view.filter_placeholder"}}
|
}}
|
||||||
{{on "input" (action "onFilterMembers" value="target.value")}}
|
>
|
||||||
{{on "focusin" (action (mut this.isSearchFocused) true)}}
|
<Input
|
||||||
{{on "focusout" (action (mut this.isSearchFocused) false)}}
|
class={{this.inputSelector}}
|
||||||
/>
|
placeholder={{i18n "chat.members_view.filter_placeholder"}}
|
||||||
{{d-icon "search"}}
|
{{on "input" (action "onFilterMembers" value="target.value")}}
|
||||||
</div>
|
{{on "focusin" (action (mut this.isSearchFocused) true)}}
|
||||||
|
{{on "focusout" (action (mut this.isSearchFocused) false)}}
|
||||||
|
/>
|
||||||
|
{{d-icon "search"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="channel-members-view__list-container">
|
||||||
class="channel-members-view__list-container"
|
<div role="list" class="channel-members-view__list">
|
||||||
{{on "scroll" (action "loadMore")}}
|
{{#each this.members as |membership|}}
|
||||||
>
|
<div class="channel-members-view__list-item">
|
||||||
|
<ChatUserInfo @user={{membership.user}} />
|
||||||
<div role="list" class="channel-members-view__list">
|
</div>
|
||||||
{{#each this.members as |membership|}}
|
{{else}}
|
||||||
<div class="channel-members-view__list-item">
|
{{#unless this.isFetchingMembers}}
|
||||||
<ChatUserInfo @user={{membership.user}} />
|
{{i18n "chat.channel.no_memberships_found"}}
|
||||||
</div>
|
{{/unless}}
|
||||||
{{else}}
|
{{/each}}
|
||||||
{{#unless this.isFetchingMembers}}
|
</div>
|
||||||
{{i18n "chat.channel.no_memberships_found"}}
|
|
||||||
{{/unless}}
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<ConditionalLoadingSpinner @condition={{this.members.loading}} />
|
||||||
|
</LoadMore>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="channel-members-view-wrapper">
|
<div class="channel-members-view-wrapper">
|
||||||
{{i18n "chat.channel.no_memberships"}}
|
{{i18n "chat.channel.no_memberships"}}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
<div class="chat-draft">
|
<div class="chat-draft">
|
||||||
{{#if this.site.mobileView}}
|
{{#if this.site.mobileView}}
|
||||||
<header class="chat-draft-header">
|
<header
|
||||||
|
class="chat-draft-header"
|
||||||
|
{{did-insert this.setChatDraftHeaderHeight}}
|
||||||
|
{{will-destroy this.unsetChatDraftHeaderHeight}}
|
||||||
|
>
|
||||||
<FlatButton
|
<FlatButton
|
||||||
@class="chat-draft-header__btn btn"
|
@class="chat-draft-header__btn btn"
|
||||||
@icon="chevron-left"
|
@icon="chevron-left"
|
||||||
|
@ -14,6 +14,22 @@ export default class ChatDraftChannelScreen extends Component {
|
|||||||
return this.router.transitionTo("chat.index");
|
return this.router.transitionTo("chat.index");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
setChatDraftHeaderHeight(element) {
|
||||||
|
document.documentElement.style.setProperty(
|
||||||
|
"--chat-draft-header-height",
|
||||||
|
`${element.clientHeight}px`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
unsetChatDraftHeaderHeight() {
|
||||||
|
document.documentElement.style.setProperty(
|
||||||
|
"--chat-draft-header-height",
|
||||||
|
"0px"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onChangeSelectedUsers(users) {
|
onChangeSelectedUsers(users) {
|
||||||
this._fetchPreviewedChannel(users);
|
this._fetchPreviewedChannel(users);
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (and this.channel.isDraft (not this.isLoading))}}
|
{{#if (and this.channel.isDraft (not this.isLoading))}}
|
||||||
<div class="direct-message-creator">
|
<div
|
||||||
|
class="direct-message-creator"
|
||||||
|
{{did-insert this.setDirectMessageCreatorHeight}}
|
||||||
|
{{will-destroy this.unsetDirectMessageCreatorHeight}}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="filter-area {{if this.isFilterFocused 'is-focused'}}"
|
class="filter-area {{if this.isFilterFocused 'is-focused'}}"
|
||||||
role="button"
|
role="button"
|
||||||
|
@ -126,6 +126,22 @@ export default Component.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
setDirectMessageCreatorHeight(element) {
|
||||||
|
document.documentElement.style.setProperty(
|
||||||
|
"--chat-direct-message-creator-height",
|
||||||
|
`${element.clientHeight}px`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
unsetDirectMessageCreatorHeight() {
|
||||||
|
document.documentElement.style.setProperty(
|
||||||
|
"--chat-direct-message-creator-height",
|
||||||
|
"0px"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onFilterInput(term) {
|
onFilterInput(term) {
|
||||||
this.set("term", term);
|
this.set("term", term);
|
||||||
|
@ -428,8 +428,7 @@ body.has-full-page-chat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-messages-scroll,
|
.chat-messages-scroll {
|
||||||
.chat-channel {
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -574,30 +573,13 @@ html.has-full-page-chat {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&.keyboard-visible body #main-outlet .full-page-chat {
|
|
||||||
padding-bottom: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&.footer-nav-ipad {
|
|
||||||
#main-outlet-wrapper {
|
|
||||||
grid-template-rows: calc(
|
|
||||||
var(--chat-vh, 1vh) * 100 - var(--header-offset, 0px) -
|
|
||||||
var(--footer-nav-height, 0px)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-outlet {
|
#main-outlet {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-height: calc(
|
|
||||||
var(--chat-vh, 1vh) * 100 - var(--header-offset, 0px) -
|
|
||||||
var(--composer-height, 0px)
|
|
||||||
);
|
|
||||||
|
|
||||||
.full-page-chat {
|
.full-page-chat {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -620,32 +602,12 @@ html.has-full-page-chat {
|
|||||||
|
|
||||||
// these need to apply to desktop too, because iPads
|
// these need to apply to desktop too, because iPads
|
||||||
&.discourse-touch {
|
&.discourse-touch {
|
||||||
// iPad web
|
|
||||||
#main-outlet-wrapper {
|
|
||||||
// restrict the row height, including when virtual keyboard is open
|
|
||||||
grid-template-rows: calc(
|
|
||||||
var(--chat-vh, 1vh) * 100 - var(--header-offset, 0px)
|
|
||||||
);
|
|
||||||
|
|
||||||
.sidebar-wrapper {
|
|
||||||
// prevents sidebar from overflowing behind the virtual keyboard
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-page-chat,
|
.full-page-chat,
|
||||||
.chat-channel,
|
.chat-channel,
|
||||||
#main-outlet {
|
#main-outlet {
|
||||||
// allows containers to shrink to fit
|
// allows containers to shrink to fit
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-outlet {
|
|
||||||
// limits height for iPad
|
|
||||||
max-height: calc(
|
|
||||||
100vh - calc(var(--header-offset) + var(--composer-ipad-padding))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[data-popper-reference-hidden] {
|
[data-popper-reference-hidden] {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
@ -1,16 +1,7 @@
|
|||||||
.chat-browse-view {
|
.chat-browse-view {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100vh - var(--header-offset) - var(--chat-header-offset));
|
|
||||||
padding-top: 1em;
|
|
||||||
padding-bottom: 41px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: scroll;
|
padding: 1rem;
|
||||||
|
|
||||||
@include chat-scrollbar();
|
|
||||||
|
|
||||||
@include breakpoint(mobile-large) {
|
|
||||||
padding-right: 1rem; //fix for different scroll behaviour on mobile where overflow-y:scroll acts like auto
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -28,18 +19,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__content_wrapper {
|
&__content_wrapper {
|
||||||
margin: 2rem 0 0 1rem;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
margin-top: 1rem;
|
||||||
@include breakpoint(tablet) {
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__cards {
|
&__cards {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
grid-gap: 2.5rem;
|
grid-gap: 2rem;
|
||||||
|
|
||||||
@include breakpoint(tablet) {
|
@include breakpoint(tablet) {
|
||||||
grid-template-columns: repeat(1, 1fr);
|
grid-template-columns: repeat(1, 1fr);
|
||||||
@ -51,7 +38,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
margin: 0 0 0 1rem;
|
|
||||||
|
|
||||||
@include breakpoint(tablet) {
|
@include breakpoint(tablet) {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -101,10 +101,6 @@ input.channel-members-view__search-input {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-height: 1px;
|
|
||||||
overflow-y: auto;
|
|
||||||
height: 100%;
|
|
||||||
@include chat-scrollbar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-members-view__list-item {
|
.channel-members-view__list-item {
|
||||||
|
@ -7,6 +7,19 @@
|
|||||||
grid-area: main;
|
grid-area: main;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
|
height: calc(
|
||||||
|
var(--chat-vh, 1vh) * 100 - var(--header-offset, 0px) -
|
||||||
|
var(--composer-height, 0px) - var(--chat-draft-header-height, 0px) -
|
||||||
|
var(--chat-direct-message-creator-height, 0px)
|
||||||
|
);
|
||||||
|
|
||||||
|
.footer-nav-ipad & {
|
||||||
|
height: calc(
|
||||||
|
var(--chat-vh, 1vh) * 100 - var(--header-offset, 0px) -
|
||||||
|
var(--footer-nav-height, 0px) - var(--chat-draft-header-height, 0px) -
|
||||||
|
var(--chat-direct-message-creator-height, 0px)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.open-drawer-btn,
|
.open-drawer-btn,
|
||||||
.open-thread-list-btn {
|
.open-thread-list-btn {
|
||||||
|
@ -251,4 +251,5 @@ a.chat-drawer-header__title {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 1px;
|
min-height: 1px;
|
||||||
padding-bottom: 0.25em;
|
padding-bottom: 0.25em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,31 @@
|
|||||||
|
.btn-floating.open-draft-channel-page-btn {
|
||||||
|
position: fixed;
|
||||||
|
background: var(--tertiary);
|
||||||
|
bottom: 2rem;
|
||||||
|
right: 2rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: var(--font-up-4);
|
||||||
|
padding: 1rem;
|
||||||
|
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
||||||
|
z-index: z("usercard");
|
||||||
|
box-shadow: 0px 5px 5px -1px rgba(0, 0, 0, 0.25);
|
||||||
|
|
||||||
|
.d-icon {
|
||||||
|
color: var(--primary-very-low);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
box-shadow: 0px 0px 5px -1px rgba(0, 0, 0, 0.25);
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
@include default-focus;
|
||||||
|
border-color: var(--quaternary);
|
||||||
|
outline-color: var(--quaternary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.channels-list {
|
.channels-list {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
|
@ -76,32 +76,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-floating.open-draft-channel-page-btn {
|
|
||||||
position: absolute;
|
|
||||||
background: var(--tertiary);
|
|
||||||
bottom: 2.5rem;
|
|
||||||
right: 2.5rem;
|
|
||||||
border-radius: 50%;
|
|
||||||
font-size: var(--font-up-4);
|
|
||||||
padding: 1rem;
|
|
||||||
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
|
||||||
z-index: z("usercard");
|
|
||||||
box-shadow: 0px 5px 5px -1px rgba(0, 0, 0, 0.25);
|
|
||||||
|
|
||||||
.d-icon {
|
|
||||||
color: var(--primary-very-low);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
box-shadow: 0px 0px 5px -1px rgba(0, 0, 0, 0.25);
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
@include default-focus;
|
|
||||||
border-color: var(--quaternary);
|
|
||||||
outline-color: var(--quaternary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user