1import * as Kb from '../../../common-adapters' 2import * as React from 'react' 3import * as Styles from '../../../styles' 4import Banner from '../bottom-banner/container' 5import InputArea from '../input-area/container' 6import InvitationToBlock from '../../blocking/invitation-to-block' 7import ListArea from '../list-area/container' 8import PinnedMessage from '../pinned-message/container' 9import ThreadLoadStatus from '../load-status/container' 10import ThreadSearch from '../search/container' 11import {Props} from '.' 12import {readImageFromClipboard} from '../../../util/clipboard.desktop' 13import '../conversation.css' 14 15const Offline = () => ( 16 <Kb.Banner color="grey" small={true} style={styles.offline}> 17 Couldn't load all chat messages due to network connectivity. Retrying... 18 </Kb.Banner> 19) 20 21class Conversation extends React.PureComponent<Props> { 22 private onPaste = (e: React.SyntheticEvent) => { 23 readImageFromClipboard(e, () => {}).then(clipboardData => { 24 if (clipboardData) { 25 this.props.onPaste(clipboardData) 26 } 27 }) 28 } 29 30 private hotKeys = ['mod+f'] 31 private onHotKey = () => { 32 this.props.onToggleThreadSearch() 33 } 34 35 render() { 36 return ( 37 <Kb.Box className="conversation" style={styles.container} onPaste={this.onPaste}> 38 <Kb.HotKey hotKeys={this.hotKeys} onHotKey={this.onHotKey} /> 39 <Kb.DragAndDrop 40 onAttach={this.props.onAttach} 41 fullHeight={true} 42 fullWidth={true} 43 rejectReason={this.props.dragAndDropRejectReason} 44 > 45 {this.props.threadLoadedOffline && <Offline />} 46 <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} style={styles.innerContainer}> 47 <ListArea 48 onFocusInput={this.props.onFocusInput} 49 scrollListDownCounter={this.props.scrollListDownCounter} 50 scrollListToBottomCounter={this.props.scrollListToBottomCounter} 51 scrollListUpCounter={this.props.scrollListUpCounter} 52 conversationIDKey={this.props.conversationIDKey} 53 /> 54 <Kb.Box2 direction="vertical" fullWidth={true} style={{left: 0, position: 'absolute', top: 0}}> 55 <ThreadLoadStatus conversationIDKey={this.props.conversationIDKey} /> 56 {!this.props.showThreadSearch && ( 57 <PinnedMessage conversationIDKey={this.props.conversationIDKey} /> 58 )} 59 </Kb.Box2> 60 {this.props.showThreadSearch && ( 61 <ThreadSearch 62 style={styles.threadSearchStyle} 63 conversationIDKey={this.props.conversationIDKey} 64 /> 65 )} 66 {this.props.showLoader && <Kb.LoadingLine />} 67 </Kb.Box2> 68 <InvitationToBlock conversationID={this.props.conversationIDKey} /> 69 <Banner conversationIDKey={this.props.conversationIDKey} /> 70 <InputArea 71 focusInputCounter={this.props.focusInputCounter} 72 jumpToRecent={this.props.jumpToRecent} 73 onRequestScrollDown={this.props.onRequestScrollDown} 74 onRequestScrollToBottom={this.props.onRequestScrollToBottom} 75 onRequestScrollUp={this.props.onRequestScrollUp} 76 conversationIDKey={this.props.conversationIDKey} 77 /> 78 </Kb.DragAndDrop> 79 </Kb.Box> 80 ) 81 } 82} 83 84const styles = Styles.styleSheetCreate( 85 () => 86 ({ 87 container: { 88 ...Styles.globalStyles.flexBoxColumn, 89 flex: 1, 90 position: 'relative', 91 }, 92 innerContainer: { 93 flex: 1, 94 position: 'relative', 95 }, 96 offline: { 97 padding: Styles.globalMargins.xxtiny, 98 }, 99 threadSearchStyle: { 100 position: 'absolute' as const, 101 top: 0, 102 }, 103 } as const) 104) 105 106export default Conversation 107