chat: fixed indentation

logging for scrollback
This commit is contained in:
Logan Allen 2020-03-24 18:49:04 -04:00
parent 16b4e2e8e4
commit 8d64d9d253
5 changed files with 299 additions and 287 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

@ -14,288 +14,297 @@ import { deSig } from '/lib/util';
export class ChatScreen extends Component {
constructor(props) {
super(props);
constructor(props) {
super(props);
this.state = {
numPages: 1,
scrollLocked: false
};
this.hasAskedForMessages = false;
this.onScroll = this.onScroll.bind(this);
this.updateReadInterval = setInterval(
this.updateReadNumber.bind(this),
1000
);
}
componentDidMount() {
this.updateReadNumber();
}
componentWillUnmount() {
if (this.updateReadInterval) {
clearInterval(this.updateReadInterval);
this.updateReadInterval = null;
}
}
componentDidUpdate(prevProps, prevState) {
const { props, state } = this;
if (
prevProps.match.params.station !== props.match.params.station ||
prevProps.match.params.ship !== props.match.params.ship
) {
this.hasAskedForMessages = false;
clearInterval(this.updateReadInterval);
this.setState(
{ scrollLocked: false },
() => {
this.scrollToBottom();
this.updateReadInterval = setInterval(
this.updateReadNumber.bind(this),
1000
);
this.updateReadNumber();
}
);
} else if (props.chatInitialized && !(props.station in props.inbox)) {
props.history.push("/~chat");
} else if (
props.envelopes.length - prevProps.envelopes.length >=
200
) {
this.hasAskedForMessages = false;
}
}
updateReadNumber() {
const { props, state } = this;
if (props.read < props.length) {
props.api.chat.read(props.station);
}
}
askForMessages() {
const { props, state } = this;
this.state = {
numPages: 1,
scrollLocked: false
};
console.log('askForMessages');
if (
state.numPages * 100 < props.length - 400 ||
this.hasAskedForMessages
) {
console.log('condition 1: ', state.numPages * 100 < props.length - 400);
console.log('condition 2: ', this.hasAskedForMessages);
return;
}
this.hasAskedForMessages = false;
this.onScroll = this.onScroll.bind(this);
this.updateReadInterval = setInterval(
this.updateReadNumber.bind(this),
1000
);
}
componentDidMount() {
this.updateReadNumber();
}
componentWillUnmount() {
if (this.updateReadInterval) {
clearInterval(this.updateReadInterval);
this.updateReadInterval = null;
}
}
componentDidUpdate(prevProps, prevState) {
const { props, state } = this;
if (
prevProps.match.params.station !== props.match.params.station ||
prevProps.match.params.ship !== props.match.params.ship
) {
this.hasAskedForMessages = false;
clearInterval(this.updateReadInterval);
this.setState(
{ scrollLocked: false },
() => {
this.scrollToBottom();
this.updateReadInterval = setInterval(
this.updateReadNumber.bind(this),
1000
);
this.updateReadNumber();
}
);
} else if (props.chatInitialized && !(props.station in props.inbox)) {
props.history.push("/~chat");
} else if (
props.envelopes.length - prevProps.envelopes.length >=
200
) {
this.hasAskedForMessages = false;
}
}
updateReadNumber() {
const { props, state } = this;
if (props.read < props.length) {
props.api.chat.read(props.station);
}
}
askForMessages() {
const { props, state } = this;
if (
state.numPages * 100 < props.length - 400 ||
this.hasAskedForMessages
) {
return;
}
if (props.length > 0) {
let end = props.envelopes[0].number;
if (end > 0) {
let start = end - 400 > 0 ? end - 400 : 0;
if (start === 0 && end === 1) {
return;
}
this.hasAskedForMessages = true;
props.subscription.fetchMessages(start, end - 1, props.station);
}
}
}
scrollToBottom() {
if (!this.state.scrollLocked && this.scrollElement) {
this.scrollElement.scrollIntoView({ behavior: "smooth" });
}
}
onScroll(e) {
if (
navigator.userAgent.includes("Safari") &&
navigator.userAgent.includes("Chrome")
) {
// Google Chrome
if (e.target.scrollTop === 0) {
this.setState(
{
numPages: this.state.numPages + 1,
scrollLocked: true
},
() => {
this.askForMessages();
}
);
} else if (
e.target.scrollHeight - Math.round(e.target.scrollTop) ===
e.target.clientHeight
) {
this.setState({
numPages: 1,
scrollLocked: false
});
}
} else if (navigator.userAgent.includes("Safari")) {
// Safari
if (e.target.scrollTop === 0) {
this.setState({
numPages: 1,
scrollLocked: false
});
} else if (
e.target.scrollHeight + Math.round(e.target.scrollTop) <=
e.target.clientHeight + 10
) {
this.setState(
{
numPages: this.state.numPages + 1,
scrollLocked: true
},
() => {
this.askForMessages();
}
);
}
} else {
console.log("Your browser is not supported.");
}
}
render() {
const { props, state } = this;
let messages = props.envelopes.slice(0);
let lastMsgNum = messages.length > 0 ? messages.length : 0;
if (messages.length > 100 * state.numPages) {
messages = messages.slice(
messages.length - 100 * state.numPages,
messages.length
);
}
let pendingMessages = props.pendingMessages.has(props.station)
? props.pendingMessages.get(props.station)
: [];
pendingMessages.map(function(value) {
return (value.pending = true);
});
let reversedMessages = messages.concat(pendingMessages);
reversedMessages = reversedMessages.reverse();
reversedMessages = reversedMessages.map((msg, i) => {
// Render sigil if previous message is not by the same sender
let aut = ["author"];
let renderSigil =
_.get(reversedMessages[i + 1], aut) !==
_.get(msg, aut, msg.author);
let paddingTop = renderSigil;
let paddingBot =
_.get(reversedMessages[i - 1], aut) !==
_.get(msg, aut, msg.author);
return (
<Message
key={msg.uid}
msg={msg}
contacts={props.contacts}
renderSigil={renderSigil}
paddingTop={paddingTop}
paddingBot={paddingBot}
pending={!!msg.pending}
/>
);
});
let group = Array.from(props.group.values());
const isinPopout = props.popout ? "popout/" : "";
let ownerContact = (window.ship in props.contacts)
? props.contacts[window.ship] : false;
let title = props.station.substr(1);
if (props.association && "metadata" in props.association) {
title =
props.association.metadata.title !== ""
? props.association.metadata.title
: props.station.substr(1);
}
return (
<div
key={props.station}
className="h-100 w-100 overflow-hidden flex flex-column">
<div
className="w-100 dn-m dn-l dn-xl inter pt4 pb6 pl3 f8"
style={{ height: "1rem" }}>
<Link to="/~chat/">{"⟵ All Chats"}</Link>
</div>
<div
className={"pl4 pt2 bb b--gray4 b--gray1-d bg-gray0-d flex relative" +
"overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"}
style={{ height: 48 }}>
<SidebarSwitcher
sidebarShown={this.props.sidebarShown}
popout={this.props.popout}
/>
<Link to={`/~chat/` + isinPopout + `room` + props.station}
className="pt2 white-d">
<h2
className={"dib f9 fw4 lh-solid v-top " +
((title === props.station.substr(1)) ? "mono" : "")}
style={{ width: "max-content" }}>
{title}
</h2>
</Link>
<ChatTabBar
{...props}
station={props.station}
numPeers={group.length}
isOwner={deSig(props.match.params.ship) === window.ship}
popout={this.props.popout}
api={props.api}
/>
</div>
<div
className="overflow-y-scroll bg-white bg-gray0-d pt3 pb2 flex flex-column-reverse"
style={{ height: "100%", resize: "vertical" }}
onScroll={this.onScroll}>
<div
ref={el => {
this.scrollElement = el;
}}></div>
{ (
!(props.station in props.chatSynced) &&
(reversedMessages.length > 0)
) ? (
<ResubscribeElement
api={props.api}
host={props.match.params.ship}
station={props.station} />
) : (<div/>)
}
{reversedMessages}
</div>
<ChatInput
api={props.api}
numMsgs={lastMsgNum}
station={props.station}
owner={deSig(props.match.params.ship)}
ownerContact={ownerContact}
permissions={props.permissions}
envelopes={props.envelopes}
contacts={props.contacts}
placeholder="Message..."
/>
</div>
);
}
console.log('length: ', props.length);
if (props.length > 0) {
let end = props.envelopes[0].number;
console.log('end: ', end);
if (end > 0) {
let start = end - 400 > 0 ? end - 400 : 0;
console.log('start: ', start);
if (start === 0 && end === 1) {
return;
}
this.hasAskedForMessages = true;
props.subscription.fetchMessages(start, end - 1, props.station);
}
}
}
scrollToBottom() {
if (!this.state.scrollLocked && this.scrollElement) {
this.scrollElement.scrollIntoView({ behavior: "smooth" });
}
}
onScroll(e) {
if (
navigator.userAgent.includes("Safari") &&
navigator.userAgent.includes("Chrome")
) {
// Google Chrome
console.log('scrollTop: ', e.target.scrollTop);
if (e.target.scrollTop === 0) {
console.log('google chrome');
this.setState(
{
numPages: this.state.numPages + 1,
scrollLocked: true
},
() => {
this.askForMessages();
}
);
} else if (
e.target.scrollHeight - Math.round(e.target.scrollTop) ===
e.target.clientHeight
) {
this.setState({
numPages: 1,
scrollLocked: false
});
}
} else if (navigator.userAgent.includes("Safari")) {
// Safari
console.log('safari');
if (e.target.scrollTop === 0) {
this.setState({
numPages: 1,
scrollLocked: false
});
} else if (
e.target.scrollHeight + Math.round(e.target.scrollTop) <=
e.target.clientHeight + 10
) {
this.setState(
{
numPages: this.state.numPages + 1,
scrollLocked: true
},
() => {
this.askForMessages();
}
);
}
} else {
console.log("Your browser is not supported.");
}
}
render() {
const { props, state } = this;
let messages = props.envelopes.slice(0);
let lastMsgNum = messages.length > 0 ? messages.length : 0;
if (messages.length > 100 * state.numPages) {
messages = messages.slice(
messages.length - 100 * state.numPages,
messages.length
);
}
let pendingMessages = props.pendingMessages.has(props.station)
? props.pendingMessages.get(props.station)
: [];
pendingMessages.map(function(value) {
return (value.pending = true);
});
let reversedMessages = messages.concat(pendingMessages);
reversedMessages = reversedMessages.reverse();
reversedMessages = reversedMessages.map((msg, i) => {
// Render sigil if previous message is not by the same sender
let aut = ["author"];
let renderSigil =
_.get(reversedMessages[i + 1], aut) !==
_.get(msg, aut, msg.author);
let paddingTop = renderSigil;
let paddingBot =
_.get(reversedMessages[i - 1], aut) !==
_.get(msg, aut, msg.author);
return (
<Message
key={msg.uid}
msg={msg}
contacts={props.contacts}
renderSigil={renderSigil}
paddingTop={paddingTop}
paddingBot={paddingBot}
pending={!!msg.pending}
/>
);
});
let group = Array.from(props.group.values());
const isinPopout = props.popout ? "popout/" : "";
let ownerContact = (window.ship in props.contacts)
? props.contacts[window.ship] : false;
let title = props.station.substr(1);
if (props.association && "metadata" in props.association) {
title =
props.association.metadata.title !== ""
? props.association.metadata.title
: props.station.substr(1);
}
return (
<div
key={props.station}
className="h-100 w-100 overflow-hidden flex flex-column">
<div
className="w-100 dn-m dn-l dn-xl inter pt4 pb6 pl3 f8"
style={{ height: "1rem" }}>
<Link to="/~chat/">{"⟵ All Chats"}</Link>
</div>
<div
className={"pl4 pt2 bb b--gray4 b--gray1-d bg-gray0-d flex relative" +
"overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"}
style={{ height: 48 }}>
<SidebarSwitcher
sidebarShown={this.props.sidebarShown}
popout={this.props.popout}
/>
<Link to={`/~chat/` + isinPopout + `room` + props.station}
className="pt2 white-d">
<h2
className={"dib f9 fw4 lh-solid v-top " +
((title === props.station.substr(1)) ? "mono" : "")}
style={{ width: "max-content" }}>
{title}
</h2>
</Link>
<ChatTabBar
{...props}
station={props.station}
numPeers={group.length}
isOwner={deSig(props.match.params.ship) === window.ship}
popout={this.props.popout}
api={props.api}
/>
</div>
<div
className="overflow-y-scroll bg-white bg-gray0-d pt3 pb2 flex flex-column-reverse"
style={{ height: "100%", resize: "vertical" }}
onScroll={this.onScroll}>
<div
ref={el => {
this.scrollElement = el;
}}></div>
{ (
!(props.station in props.chatSynced) &&
(reversedMessages.length > 0)
) ? (
<ResubscribeElement
api={props.api}
host={props.match.params.ship}
station={props.station} />
) : (<div/>)
}
{reversedMessages}
</div>
<ChatInput
api={props.api}
numMsgs={lastMsgNum}
station={props.station}
owner={deSig(props.match.params.ship)}
ownerContact={ownerContact}
permissions={props.permissions}
envelopes={props.envelopes}
contacts={props.contacts}
placeholder="Message..."
/>
</div>
);
}
}

View File

@ -125,7 +125,7 @@ export class ChatInput extends Component {
this.textareaInput = _.debounce(this.textareaInput.bind(this), 16);
// perf testing:
/*let closure = () => {
let closure = () => {
let x = 0;
for (var i = 0; i < 30; i++) {
x++;
@ -140,7 +140,7 @@ export class ChatInput extends Component {
}
setTimeout(closure, 1000);
};
this.closure = closure.bind(this);*/
this.closure = closure.bind(this);
moment.updateLocale('en', {
relativeTime : {
@ -400,6 +400,7 @@ export class ChatInput extends Component {
}
})
if (message.length > 0) {
message = message.join(" ");
message = this.getLetterType(message);
@ -412,7 +413,8 @@ export class ChatInput extends Component {
message = [];
}
// perf: setTimeout(this.closure, 2000);
// perf:
setTimeout(this.closure, 2000);
this.setState({
message: '',

View File

@ -69,6 +69,7 @@ export class Subscription {
fetch(`/~chat/paginate/${start}/${end}${path}`)
.then((response) => response.json())
.then((json) => {
console.log(json);
store.handleEvent({
data: json
});