Revert buggy timeline layout refactor
This commit is contained in:
parent
81e991af80
commit
3226156a45
6 changed files with 64 additions and 23 deletions
|
@ -5448,7 +5448,6 @@ button.module-image__border-overlay:focus {
|
||||||
|
|
||||||
.module-timeline {
|
.module-timeline {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
@ -5463,7 +5462,6 @@ button.module-image__border-overlay:focus {
|
||||||
overflow-y: overlay;
|
overflow-y: overlay;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-timeline__messages {
|
.module-timeline__messages {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
left: 0;
|
left: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: sticky;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
transition: opacity 0.25s ease-out;
|
transition: opacity 0.25s ease-out;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -2,7 +2,12 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
.module-TimelineWarnings {
|
.module-TimelineWarnings {
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: $z-index-above-above-base;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,7 @@ export type PropsType = PropsDataType &
|
||||||
type StateType = {
|
type StateType = {
|
||||||
hasDismissedDirectContactSpoofingWarning: boolean;
|
hasDismissedDirectContactSpoofingWarning: boolean;
|
||||||
hasRecentlyScrolled: boolean;
|
hasRecentlyScrolled: boolean;
|
||||||
|
lastMeasuredWarningHeight: number;
|
||||||
newestBottomVisibleMessageId?: string;
|
newestBottomVisibleMessageId?: string;
|
||||||
oldestPartiallyVisibleMessageId?: string;
|
oldestPartiallyVisibleMessageId?: string;
|
||||||
widthBreakpoint: WidthBreakpoint;
|
widthBreakpoint: WidthBreakpoint;
|
||||||
|
@ -276,7 +277,8 @@ export class Timeline extends React.Component<
|
||||||
hasRecentlyScrolled: true,
|
hasRecentlyScrolled: true,
|
||||||
hasDismissedDirectContactSpoofingWarning: false,
|
hasDismissedDirectContactSpoofingWarning: false,
|
||||||
|
|
||||||
// This may be swiftly overridden.
|
// These may be swiftly overridden.
|
||||||
|
lastMeasuredWarningHeight: 0,
|
||||||
widthBreakpoint: WidthBreakpoint.Wide,
|
widthBreakpoint: WidthBreakpoint.Wide,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -792,6 +794,7 @@ export class Timeline extends React.Component<
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {
|
const {
|
||||||
hasRecentlyScrolled,
|
hasRecentlyScrolled,
|
||||||
|
lastMeasuredWarningHeight,
|
||||||
newestBottomVisibleMessageId,
|
newestBottomVisibleMessageId,
|
||||||
oldestPartiallyVisibleMessageId,
|
oldestPartiallyVisibleMessageId,
|
||||||
widthBreakpoint,
|
widthBreakpoint,
|
||||||
|
@ -845,6 +848,11 @@ export class Timeline extends React.Component<
|
||||||
<TimelineFloatingHeader
|
<TimelineFloatingHeader
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
isLoading={isLoadingMessages}
|
isLoading={isLoadingMessages}
|
||||||
|
style={
|
||||||
|
lastMeasuredWarningHeight
|
||||||
|
? { marginTop: lastMeasuredWarningHeight }
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
timestamp={oldestPartiallyVisibleMessageTimestamp}
|
timestamp={oldestPartiallyVisibleMessageTimestamp}
|
||||||
visible={
|
visible={
|
||||||
(hasRecentlyScrolled || isLoadingMessages) &&
|
(hasRecentlyScrolled || isLoadingMessages) &&
|
||||||
|
@ -976,14 +984,27 @@ export class Timeline extends React.Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
timelineWarning = (
|
timelineWarning = (
|
||||||
<TimelineWarnings>
|
<Measure
|
||||||
<TimelineWarning i18n={i18n} onClose={onClose}>
|
bounds
|
||||||
<TimelineWarning.IconContainer>
|
onResize={({ bounds }) => {
|
||||||
<TimelineWarning.GenericIcon />
|
if (!bounds) {
|
||||||
</TimelineWarning.IconContainer>
|
assert(false, 'We should be measuring the bounds');
|
||||||
<TimelineWarning.Text>{text}</TimelineWarning.Text>
|
return;
|
||||||
</TimelineWarning>
|
}
|
||||||
</TimelineWarnings>
|
this.setState({ lastMeasuredWarningHeight: bounds.height });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ measureRef }) => (
|
||||||
|
<TimelineWarnings ref={measureRef}>
|
||||||
|
<TimelineWarning i18n={i18n} onClose={onClose}>
|
||||||
|
<TimelineWarning.IconContainer>
|
||||||
|
<TimelineWarning.GenericIcon />
|
||||||
|
</TimelineWarning.IconContainer>
|
||||||
|
<TimelineWarning.Text>{text}</TimelineWarning.Text>
|
||||||
|
</TimelineWarning>
|
||||||
|
</TimelineWarnings>
|
||||||
|
)}
|
||||||
|
</Measure>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,13 +1087,13 @@ export class Timeline extends React.Component<
|
||||||
>
|
>
|
||||||
{timelineWarning}
|
{timelineWarning}
|
||||||
|
|
||||||
|
{floatingHeader}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="module-timeline__messages__container"
|
className="module-timeline__messages__container"
|
||||||
onScroll={this.onScroll}
|
onScroll={this.onScroll}
|
||||||
ref={this.containerRef}
|
ref={this.containerRef}
|
||||||
>
|
>
|
||||||
{floatingHeader}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-timeline__messages',
|
'module-timeline__messages',
|
||||||
|
@ -1080,8 +1101,14 @@ export class Timeline extends React.Component<
|
||||||
)}
|
)}
|
||||||
ref={this.messagesRef}
|
ref={this.messagesRef}
|
||||||
>
|
>
|
||||||
{haveOldest &&
|
{haveOldest && (
|
||||||
renderHeroRow(id, unblurAvatar, updateSharedGroups)}
|
<>
|
||||||
|
{Timeline.getWarning(this.props, this.state) && (
|
||||||
|
<div style={{ height: lastMeasuredWarningHeight }} />
|
||||||
|
)}
|
||||||
|
{renderHeroRow(id, unblurAvatar, updateSharedGroups)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{messageNodes}
|
{messageNodes}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { ReactElement } from 'react';
|
import type { CSSProperties, ReactElement } from 'react';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import type { LocalizerType } from '../../types/Util';
|
import type { LocalizerType } from '../../types/Util';
|
||||||
import { TimelineDateHeader } from './TimelineDateHeader';
|
import { TimelineDateHeader } from './TimelineDateHeader';
|
||||||
|
@ -11,11 +11,13 @@ import { Spinner } from '../Spinner';
|
||||||
export const TimelineFloatingHeader = ({
|
export const TimelineFloatingHeader = ({
|
||||||
i18n,
|
i18n,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
style,
|
||||||
timestamp,
|
timestamp,
|
||||||
visible,
|
visible,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
style?: CSSProperties;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
}>): ReactElement => {
|
}>): ReactElement => {
|
||||||
|
@ -33,6 +35,7 @@ export const TimelineFloatingHeader = ({
|
||||||
visible && hasRendered ? 'visible' : 'hidden'
|
visible && hasRendered ? 'visible' : 'hidden'
|
||||||
}`
|
}`
|
||||||
)}
|
)}
|
||||||
|
style={style}
|
||||||
>
|
>
|
||||||
<TimelineDateHeader floating i18n={i18n} timestamp={timestamp} />
|
<TimelineDateHeader floating i18n={i18n} timestamp={timestamp} />
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
// Copyright 2021-2022 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { FunctionComponent } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import React from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
|
|
||||||
const CLASS_NAME = 'module-TimelineWarnings';
|
const CLASS_NAME = 'module-TimelineWarnings';
|
||||||
|
|
||||||
export const TimelineWarnings: FunctionComponent = ({ children }) => (
|
type PropsType = {
|
||||||
<div className={CLASS_NAME}>{children}</div>
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TimelineWarnings = forwardRef<HTMLDivElement, PropsType>(
|
||||||
|
({ children }, ref) => (
|
||||||
|
<div className={CLASS_NAME} ref={ref}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue