interface: added the ability to make and redirect to a new DM from the ProfileOverlay

This commit is contained in:
Logan Allen 2020-10-05 17:28:16 -05:00
parent 4a469fc393
commit 826248021a
5 changed files with 72 additions and 16 deletions

View File

@ -113,6 +113,7 @@ export function ChatResource(props: ChatResourceProps) {
group={group} group={group}
ship={owner} ship={owner}
station={station} station={station}
allStations={Object.keys(props.inbox)}
api={props.api} api={props.api}
hideNicknames={props.hideNicknames} hideNicknames={props.hideNicknames}
hideAvatars={props.hideAvatars} hideAvatars={props.hideAvatars}

View File

@ -46,9 +46,12 @@ interface ChatMessageProps {
className?: string; className?: string;
isPending: boolean; isPending: boolean;
style?: any; style?: any;
allStations: any;
scrollWindow: HTMLDivElement; scrollWindow: HTMLDivElement;
isLastMessage?: boolean; isLastMessage?: boolean;
unreadMarkerRef: React.RefObject<HTMLDivElement>; unreadMarkerRef: React.RefObject<HTMLDivElement>;
history: any;
api: any;
} }
export default class ChatMessage extends Component<ChatMessageProps> { export default class ChatMessage extends Component<ChatMessageProps> {
@ -83,7 +86,10 @@ export default class ChatMessage extends Component<ChatMessageProps> {
measure, measure,
scrollWindow, scrollWindow,
isLastMessage, isLastMessage,
unreadMarkerRef unreadMarkerRef,
allStations,
history,
api
} = this.props; } = this.props;
const renderSigil = Boolean((nextMsg && msg.author !== nextMsg.author) || !nextMsg || msg.number === 1); const renderSigil = Boolean((nextMsg && msg.author !== nextMsg.author) || !nextMsg || msg.number === 1);
@ -112,6 +118,9 @@ export default class ChatMessage extends Component<ChatMessageProps> {
style, style,
containerClass, containerClass,
isPending, isPending,
allStations,
history,
api,
scrollWindow scrollWindow
}; };
@ -145,6 +154,7 @@ interface MessageProps {
containerClass: string; containerClass: string;
isPending: boolean; isPending: boolean;
style: any; style: any;
allStations: any;
measure(element): void; measure(element): void;
scrollWindow: HTMLDivElement; scrollWindow: HTMLDivElement;
}; };
@ -161,6 +171,9 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
hideAvatars, hideAvatars,
remoteContentPolicy, remoteContentPolicy,
measure, measure,
allStations,
history,
api,
scrollWindow scrollWindow
} = this.props; } = this.props;
@ -194,6 +207,9 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
hideAvatars={hideAvatars} hideAvatars={hideAvatars}
hideNicknames={hideNicknames} hideNicknames={hideNicknames}
scrollWindow={scrollWindow} scrollWindow={scrollWindow}
allStations={allStations}
history={history}
api={api}
className="fl pr3 v-top bg-white bg-gray0-d" className="fl pr3 v-top bg-white bg-gray0-d"
/> />
<div className="fr f8 clamp-message white-d" style={{ flexGrow: 1, marginTop: -12 }}> <div className="fr f8 clamp-message white-d" style={{ flexGrow: 1, marginTop: -12 }}>

View File

@ -39,6 +39,7 @@ type ChatWindowProps = RouteComponentProps<{
group: Group; group: Group;
ship: Patp; ship: Patp;
station: any; station: any;
allStations: any;
api: GlobalApi; api: GlobalApi;
hideNicknames: boolean; hideNicknames: boolean;
hideAvatars: boolean; hideAvatars: boolean;
@ -127,7 +128,6 @@ export default class ChatWindow extends Component<ChatWindowProps, ChatWindowSta
const { isChatMissing, history, envelopes, mailboxSize, stationPendingMessages, unreadCount } = this.props; const { isChatMissing, history, envelopes, mailboxSize, stationPendingMessages, unreadCount } = this.props;
if (isChatMissing) { if (isChatMissing) {
// TODO: fix this and push a different route
history.push("/~404"); history.push("/~404");
} else if (envelopes.length !== prevProps.envelopes.length && this.state.fetchPending) { } else if (envelopes.length !== prevProps.envelopes.length && this.state.fetchPending) {
this.setState({ fetchPending: false }); this.setState({ fetchPending: false });
@ -241,6 +241,8 @@ export default class ChatWindow extends Component<ChatWindowProps, ChatWindowSta
hideAvatars, hideAvatars,
hideNicknames, hideNicknames,
remoteContentPolicy, remoteContentPolicy,
allStations,
history
} = this.props; } = this.props;
const unreadMarkerRef = this.unreadMarkerRef; const unreadMarkerRef = this.unreadMarkerRef;
@ -263,7 +265,7 @@ export default class ChatWindow extends Component<ChatWindowProps, ChatWindowSta
lastMessage = mailboxSize + index; lastMessage = mailboxSize + index;
}); });
const messageProps = { association, group, contacts, hideAvatars, hideNicknames, remoteContentPolicy, unreadMarkerRef }; const messageProps = { association, group, contacts, hideAvatars, hideNicknames, remoteContentPolicy, unreadMarkerRef, allStations, history, api };
return ( return (
<> <>

View File

@ -55,7 +55,7 @@ export class OverlaySigil extends PureComponent {
render() { render() {
const { props, state } = this; const { props, state } = this;
const { hideAvatars } = props; const { hideAvatars, allStations } = props;
const img = (props.contact && (props.contact.avatar !== null) && !hideAvatars) const img = (props.contact && (props.contact.avatar !== null) && !hideAvatars)
? <img src={props.contact.avatar} height={16} width={16} className="dib" /> ? <img src={props.contact.avatar} height={16} width={16} className="dib" />
@ -83,8 +83,11 @@ export class OverlaySigil extends PureComponent {
association={props.association} association={props.association}
group={props.group} group={props.group}
onDismiss={this.profileHide} onDismiss={this.profileHide}
allStations={allStations}
hideAvatars={hideAvatars} hideAvatars={hideAvatars}
hideNicknames={props.hideNicknames} hideNicknames={props.hideNicknames}
history={props.history}
api={props.api}
/> />
)} )}
{img} {img}

View File

@ -3,6 +3,8 @@ import { Link } from 'react-router-dom';
import { cite } from '~/logic/lib/util'; import { cite } from '~/logic/lib/util';
import { Sigil } from '~/logic/lib/sigil'; import { Sigil } from '~/logic/lib/sigil';
import { Center, Button } from "@tlon/indigo-react";
export const OVERLAY_HEIGHT = 250; export const OVERLAY_HEIGHT = 250;
export class ProfileOverlay extends PureComponent { export class ProfileOverlay extends PureComponent {
@ -11,6 +13,7 @@ export class ProfileOverlay extends PureComponent {
this.popoverRef = React.createRef(); this.popoverRef = React.createRef();
this.onDocumentClick = this.onDocumentClick.bind(this); this.onDocumentClick = this.onDocumentClick.bind(this);
this.createAndRedirectToDM = this.createAndRedirectToDM.bind(this);
} }
componentDidMount() { componentDidMount() {
@ -23,6 +26,42 @@ export class ProfileOverlay extends PureComponent {
document.removeEventListener('touchstart', this.onDocumentClick); document.removeEventListener('touchstart', this.onDocumentClick);
} }
createAndRedirectToDM() {
const { api, ship, history, allStations } = this.props;
const station = `/~${window.ship}/dm--${ship}`;
const theirStation = `/~${ship}/dm--${window.ship}`;
if (allStations.indexOf(station) !== -1) {
history.push(`/~groups/home/resource/chat${station}`);
return;
}
if (allStations.indexOf(theirStation) !== -1) {
history.push(`/~groups/home/resource/chat${theirStation}`);
return;
}
const groupPath = `/ship/~${window.ship}/dm--${ship}`;
const aud = ship !== window.ship ? [`~${ship}`] : [];
const title = `${cite(window.ship)} <-> ${cite(ship)}`;
api.chat.create(
title,
'',
station,
groupPath,
{ invite: { pending: aud } },
aud,
true,
false
);
// TODO: make a pretty loading state
setTimeout(() => {
history.push(`/~groups/home/resource/chat${station}`);
}, 5000);
}
onDocumentClick(event) { onDocumentClick(event) {
const { popoverRef } = this; const { popoverRef } = this;
// Do nothing if clicking ref's element or descendent elements // Do nothing if clicking ref's element or descendent elements
@ -65,11 +104,9 @@ export class ProfileOverlay extends PureComponent {
/>; />;
const showNickname = contact?.nickname && !hideNicknames; const showNickname = contact?.nickname && !hideNicknames;
if (!group.hidden) { if (!group.hidden) {
img = <Link to={`/~groups/view${association['group-path']}/${ship}`}>{img}</Link>; img = <Link to={`/~groups/view${association['group-path']}/${ship}`}>{img}</Link>;
} }
// TODO: create a chat DM
return ( return (
<div <div
@ -78,20 +115,17 @@ export class ProfileOverlay extends PureComponent {
className="flex-col shadow-6 br2 bg-white bg-gray0-d inter absolute z-1 f9 lh-solid" className="flex-col shadow-6 br2 bg-white bg-gray0-d inter absolute z-1 f9 lh-solid"
> >
<div style={{ height: '160px', width: '160px' }}> <div style={{ height: '160px', width: '160px' }}>
{img} {img}
</div> </div>
<div className="pv3 pl3 pr2"> <div className="pv3 pl3 pr3">
{showNickname && ( {showNickname && (
<div className="b white-d truncate">{contact.nickname}</div> <div className="b white-d truncate">{contact.nickname}</div>
)} )}
<div className="mono gray2">{cite(`~${ship}`)}</div> <div className="mono gray2">{cite(`~${ship}`)}</div>
{!isOwn && ( {!isOwn && (
<Link <Button mt={2} width="100%" onClick={this.createAndRedirectToDM}>
to={`/~todo/~${ship}`}
className="b--green0 b--green2-d b--solid ba green2 mt3 tc pa2 pointer db"
>
Send Message Send Message
</Link> </Button>
)} )}
{isOwn && ( {isOwn && (
<Link <Link