support edits pagination in a ScrollPanel

This commit is contained in:
Bruno Windels 2019-06-25 14:50:56 +02:00
parent 0fe28cba43
commit 8c9a6ddf96
2 changed files with 56 additions and 15 deletions

View file

@ -15,6 +15,17 @@ limitations under the License.
*/ */
.mx_MessageEditHistoryDialog ul { .mx_MessageEditHistoryDialog ul {
.mx_MessageEditHistoryDialog {
display: flex;
flex-direction: column;
max-height: 60vh;
}
.mx_MessageEditHistoryDialog_scrollPanel {
flex: 1 1 auto;
}
.mx_MessageEditHistoryDialog_edits {
list-style-type: none; list-style-type: none;
font-size: 14px; font-size: 14px;

View file

@ -28,21 +28,41 @@ export default class MessageEditHistoryDialog extends React.Component {
}; };
componentWillMount() { componentWillMount() {
this.loadMoreEdits = this.loadMoreEdits.bind(this);
this.setState({ this.setState({
edits: [this.props.mxEvent], events: [],
nextBatch: null,
isLoading: true, isLoading: true,
isTwelveHour: SettingsStore.getValue("showTwelveHourTimestamps"), isTwelveHour: SettingsStore.getValue("showTwelveHourTimestamps"),
}); });
} }
async componentDidMount() { async loadMoreEdits(backwards) {
if (backwards || (!this.state.nextBatch && !this.state.isLoading)) {
// bail out on backwards as we only paginate in one direction
return false;
}
const opts = {token: this.state.nextBatch};
const roomId = this.props.mxEvent.getRoomId(); const roomId = this.props.mxEvent.getRoomId();
const eventId = this.props.mxEvent.getId(); const eventId = this.props.mxEvent.getId();
let edits = await MatrixClientPeg.get(). const result = await MatrixClientPeg.get().relations(
relations(roomId, eventId, "m.replace", "m.room.message"); roomId, eventId, "m.replace", "m.room.message", opts);
edits = edits.slice().reverse(); //console.log(`loadMoreEdits: got ${result.}`)
edits.unshift(this.props.mxEvent); let resolve;
this.setState({edits, isLoading: false}); const promise = new Promise(r => resolve = r);
this.setState({
events: this.state.events.concat(result.events),
nextBatch: result.nextBatch,
isLoading: false,
}, () => {
const hasMoreResults = !!this.state.nextBatch;
resolve(hasMoreResults);
});
return promise;
}
componentDidMount() {
this.loadMoreEdits();
} }
_renderEdits() { _renderEdits() {
@ -50,7 +70,7 @@ export default class MessageEditHistoryDialog extends React.Component {
const DateSeparator = sdk.getComponent('messages.DateSeparator'); const DateSeparator = sdk.getComponent('messages.DateSeparator');
const nodes = []; const nodes = [];
let lastEvent; let lastEvent;
this.state.edits.forEach(e => { this.state.events.forEach(e => {
if (!lastEvent || wantsDateSeparator(lastEvent.getDate(), e.getDate())) { if (!lastEvent || wantsDateSeparator(lastEvent.getDate(), e.getDate())) {
nodes.push(<li key={e.getTs() + "~"}><DateSeparator ts={e.getTs()} /></li>); nodes.push(<li key={e.getTs() + "~"}><DateSeparator ts={e.getTs()} /></li>);
} }
@ -61,18 +81,28 @@ export default class MessageEditHistoryDialog extends React.Component {
} }
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); let content;
let spinner; if (this.state.error) {
const edits = this._renderEdits(); content = this.state.error;
if (this.state.isLoading) { } else if (this.state.isLoading) {
const Spinner = sdk.getComponent("elements.Spinner"); const Spinner = sdk.getComponent("elements.Spinner");
spinner = <Spinner />; content = <Spinner />;
} else {
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
content = (<ScrollPanel
className="mx_MessageEditHistoryDialog_scrollPanel"
onFillRequest={ this.loadMoreEdits }
stickyBottom={false}
startAtBottom={false}
>
<ul className="mx_MessageEditHistoryDialog_edits">{this._renderEdits()}</ul>
</ScrollPanel>);
} }
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return ( return (
<BaseDialog className='mx_MessageEditHistoryDialog' hasCancel={true} <BaseDialog className='mx_MessageEditHistoryDialog' hasCancel={true}
onFinished={this.props.onFinished} title={_t("Message edits")}> onFinished={this.props.onFinished} title={_t("Message edits")}>
<ul>{edits}</ul> {content}
{spinner}
</BaseDialog> </BaseDialog>
); );
} }