Merge pull request #1635 from urbit/chat-pending

Chat: Display pending messages
This commit is contained in:
Jared Tobin 2019-08-23 15:55:35 -02:30 committed by GitHub
commit 164bba60fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 11 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,8 @@ import React from 'react';
import ReactDOM from 'react-dom';
import _ from 'lodash';
import { uuid } from '/lib/util';
import { store } from '/store';
class UrbitApi {
setAuthTokens(authTokens) {
@ -34,6 +36,18 @@ class UrbitApi {
hall(data) {
this.action("hall", "hall-action", data);
}
addPendingMessage(data) {
let pendingMap = store.state.pendingMessages;
if (pendingMap.has(data.aud[0])) {
pendingMap.get(data.aud[0]).push(data)
} else {
pendingMap.set(data.aud[0], [data])
}
store.setState({
pendingMessages: pendingMap
});
}
chat(lis) {
this.action("chat", "chat-action", {

View File

@ -20,6 +20,8 @@ export class ChatScreen extends Component {
scrollLocked: false,
};
this.pendingQueue = props.pendingMessages;
this.hasAskedForMessages = false;
this.onScroll = this.onScroll.bind(this);
@ -182,6 +184,18 @@ export class ChatScreen extends Component {
let config = props.configs[state.station] || {};
let messages = props.messages.slice(0);
// Pending messages get pinned to the bottom of the messages queue.
let pendingInRoom =
(this.pendingQueue.has(this.state.station))
? this.pendingQueue.get(this.state.station) : [];
pendingInRoom.map(function(value) {
return value.pending = true;
})
messages = messages.concat(pendingInRoom);
let lastMsgNum = (messages.length > 0) ?
messages[messages.length - 1].num : 0;
@ -194,23 +208,39 @@ export class ChatScreen extends Component {
let reversedMessages = messages.reverse();
let chatMessages = reversedMessages.map((msg, i) => {
// Render sigil if previous message is not by the same sender
let gamAut = ['gam', 'aut'];
let gamAut = ['gam', 'aut'];
// Local messages don't have a 'gam' prop, so look for the top level if it doesn't exist.
let aut = msg.aut ? msg.aut : null;
// No gamAut? Return top level author for the same sender check.
let renderSigil =
_.get(reversedMessages[i + 1], gamAut) !== _.get(msg, gamAut);
_.get(reversedMessages[i + 1], gamAut) !== _.get(msg, gamAut, aut);
// More padding top if previous message is not by the same sender
let paddingTop = renderSigil;
// More padding bot if next message is not by the same sender
let paddingBot =
_.get(reversedMessages[i - 1], gamAut) !== _.get(msg, gamAut);
_.get(reversedMessages[i - 1], gamAut) !== _.get(msg, gamAut, aut);
// Non-local ships don't have pending props.
if (!msg.pending) {
var pending = false;
}
// Non-local ships don't have pending props.
if (!pending) {
var pending = false;
}
return (
<Message
key={msg.gam.uid}
msg={msg.gam}
key={msg.gam ? msg.gam.uid : msg.uid}
msg={msg.gam ? msg.gam : msg}
renderSigil={renderSigil}
paddingTop={paddingTop}
paddingBot={paddingBot} />
paddingBot={paddingBot}
pending={!!pending}/>
);
});

View File

@ -263,6 +263,8 @@ export class ChatInput extends Component {
)
};
props.api.addPendingMessage(message);
props.api.hall(
{
convey: [message]

View File

@ -171,7 +171,7 @@ export class Message extends Component {
render() {
const { props } = this;
let pending = !!props.msg.pending ? ' o-80' : '';
let pending = !!props.msg.pending ? ' o-40' : '';
let datestamp = moment.unix(props.msg.wen / 1000).format('LL');
let paddingTop = props.paddingTop ? 'pt3' : '';

View File

@ -158,6 +158,7 @@ export class Root extends Component {
api={api}
configs={configs}
messages={messages}
pendingMessages={state.pendingMessages}
peers={state.peers}
subscription={subscription}
{...props}

View File

@ -61,4 +61,3 @@ export function dateToDa(d, mil) {
export function deSig(ship) {
return ship.replace('~', '');
}

View File

@ -6,6 +6,7 @@ export class UpdateReducer {
let data = _.get(json, 'update', false);
if (data) {
this.reduceInbox(_.get(data, 'inbox', false), state);
this.reducePending(_.get(data, 'message', false), state);
this.reduceMessage(_.get(data, 'message', false), state);
this.reduceMessages(_.get(data, 'messages', false), state);
this.reduceConfig(_.get(data, 'config', false), state);
@ -29,6 +30,23 @@ export class UpdateReducer {
}
}
reducePending(message, state) {
if (message && (state.pendingMessages.has(message.envelope.gam.aud[0]))) {
for (let pendingMessage of state.pendingMessages.get(message.envelope.gam.aud[0])) {
// Does the incoming message match a pending one?
if (message.envelope.gam.uid === pendingMessage.uid) {
// Mutating the pendingMessages array.
let pendingMessageMap = state.pendingMessages;
let matchedMessage = pendingMessageMap.get(pendingMessage.aud[0]).indexOf(pendingMessage);
pendingMessageMap.get(pendingMessage.aud[0]).splice(matchedMessage, 1);
state.pendingMessages = pendingMessageMap;
}
}
}
}
reduceMessages(msgs, state) {
if (msgs) {

View File

@ -11,7 +11,8 @@ class Store {
configs: {},
circles: [],
peers: {},
spinner: false
spinner: false,
pendingMessages: new Map([])
};
this.initialReducer = new InitialReducer();