Skip to content

Commit

Permalink
Makes the conversation view work on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
cbothner committed Nov 27, 2017
1 parent f20f998 commit e2ac13d
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 50 deletions.
3 changes: 3 additions & 0 deletions app/assets/stylesheets/CaseOverview.sass
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

.CaseOverviewRight
+flex($fg: 0, $fs: 1, $fb: 20em)
@media screen and (max-width: $mobileCutoff)
+flex($fg: 1, $fs: 1, $fb: 20em)

min-width: 15em
& > *
margin: 1em
Expand Down
43 changes: 23 additions & 20 deletions app/javascript/conversation/CommentThreadItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ const CommentThreadItem = ({
)
export default withRouter(connect(mapStateToProps)(CommentThreadItem))

const ConversationMetadata = styled.div`
display: flex;
justify-content: space-between;
margin: 14px 0 0.5em;
`
const Indenticons = styled.div`
display: flex;
justify-content: flex-start;
& .Identicon {
margin-right: 5px;
}
`
const CommentCount = styled.div`
color: #5c7080;
font-size: 13px;
`

const CommentThreadLink = styled(Link)`
display: block;
color: inherit;
Expand All @@ -110,9 +128,12 @@ const CommentThreadLink = styled(Link)`
}
&:focus {
border: 3px solid #373565;
padding: 11px 15px 12px;
outline: none;
& ${CommentCount} {
border: 3px rgb(210, 201, 239) solid;
margin: -5px -10px;
padding: 2px 7px;
}
}
.pt-focus-disabled & {
Expand Down Expand Up @@ -147,24 +168,6 @@ const MostRecentComment = styled.blockquote`
}
`

const ConversationMetadata = styled.div`
display: flex;
justify-content: space-between;
margin: 14px 0 0.5em;
`
const Indenticons = styled.div`
display: flex;
justify-content: flex-start;
& .Identicon {
margin-right: 5px;
}
`
const CommentCount = styled.div`
color: #5c7080;
font-size: 13px;
`

// eslint-disable-next-line react/prefer-stateless-function
class PureTruncate extends React.PureComponent<{
lines: number,
Expand Down
1 change: 0 additions & 1 deletion app/javascript/conversation/LeadComment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ const LeadComment = ({
{originalHighlightText}
</Link>
</HighlightedText>
{/* http://localhost:3000/en/cases/ethiopia-napa/4/cards/77/comments/53 */}
</CommentThreadLocation>,

<LeadCommentContents key="3">
Expand Down
57 changes: 37 additions & 20 deletions app/javascript/conversation/NewCommentForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,34 @@ function mapStateToProps ({ caseData, ui }: State, { threadId }: OwnProps) {

function mapDispatchToProps (dispatch: Dispatch, { threadId }: OwnProps) {
return {
handleChange: (editorState: EditorState) =>
onSaveChanges: (editorState: EditorState) =>
dispatch(changeCommentInProgress(threadId, editorState)) && void 0,
handleSubmit: () => dispatch(createComment(threadId)),
onSubmitComment: () => dispatch(createComment(threadId)),
}
}

type StateProps = ExtractReturn<typeof mapStateToProps>
type DispatchProps = ExtractReturn<typeof mapDispatchToProps>
type Props = { ...OwnProps, ...StateProps, ...DispatchProps }

class NewCommentForm extends React.Component<Props> {
class NewCommentForm extends React.Component<
Props,
{ editorState: EditorState }
> {
state = { editorState: this.props.editorState }

container: ?HTMLDivElement

componentDidUpdate (prevProps) {
if (this.props.editorState === prevProps.editorState) return
const height = this.container && this.container.offsetHeight
height && this.props.onResize(height)
componentDidUpdate (prevProps: Props) {
if (prevProps.threadId !== this.props.threadId) {
this.setState({ editorState: this.props.editorState })
}
this._updateHeight()
}

render () {
const {
editorHasFocus,
editorState,
handleChange,
handleSubmit,
intl,
reader,
} = this.props
const { editorHasFocus, onSubmitComment, intl, reader } = this.props
const { editorState } = this.state
if (reader == null) return null
return (
<Container innerRef={(el: HTMLDivElement) => (this.container = el)}>
Expand All @@ -73,7 +73,8 @@ class NewCommentForm extends React.Component<Props> {
id: 'comments.write',
defaultMessage: 'Write a reply...',
})}
onChange={handleChange}
onChange={this.handleChange}
onBlur={this.handleBlur}
/>
</Input>
<SendButton
Expand All @@ -83,27 +84,43 @@ class NewCommentForm extends React.Component<Props> {
})}
className="pt-button pt-small pt-minimal pt-intent-primary pt-icon-upload"
editorHasFocus={editorHasFocus}
onClick={handleSubmit}
onClick={onSubmitComment}
/>
</Container>
)
}

handleChange = editorState => this.setState({ editorState })
handleBlur = () => this.props.onSaveChanges(this.state.editorState)

_updateHeight = () => {
console.log('_updateHeight')
const height = this.container && this.container.offsetHeight
height && this.props.onResize(height)
}
}
export default injectIntl(
connect(mapStateToProps, mapDispatchToProps)(NewCommentForm)
)

const Container = styled.div`
display: flex;
align-items: flex-end;
flex-shrink: 0;
background-color: #ebeae4;
border-top: 1px solid #bfbdac;
border-radius: 0 0 2px 2px;
display: flex;
align-items: flex-end;
padding: 11px;
position: relative;
& .Identicon {
margin-bottom: 1px;
}
@media (max-width: 700px) {
margin: 0 6px;
bottom: 0;
width: calc(100vw - 12px);
`

const Input = styled.div`
Expand All @@ -119,7 +136,7 @@ const Input = styled.div`
line-height: 1.3;
& .public-DraftEditorPlaceholder-root {
position: absolute;
margin-bottom: -18px;
pointer-events: none;
opacity: 0.6;
&.public-DraftEditorPlaceholder-hasFocus {
Expand Down
11 changes: 11 additions & 0 deletions app/javascript/conversation/RecentCommentThreads.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ const Container = styled.div`
background-color: #ebeae4;
border-radius: 2px;
margin-top: 30px;
@media (max-width: 1000px) {
width: calc(30vw - 16px);
}
@media (max-width: 700px) {
margin-top: 18px;
& .BillboardTitle {
padding-top: 18px;
}
}
`

const Shadow = styled.div`
Expand Down
11 changes: 7 additions & 4 deletions app/javascript/conversation/Responses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import type { Comment } from 'redux/state'

const ms = x => new Date(x).getTime()

const ONE_MINUTE = 6000
const closeEnoughTimestamps = (a, b) =>
Math.abs(ms(a.timestamp) - ms(b.timestamp)) < ONE_MINUTE
const TWO_MINUTES = 2 * 60 * 1000 // milliseconds
const closeEnoughTimestamps = (a, b) => {
return Math.abs(ms(a.timestamp) - ms(b.timestamp)) < TWO_MINUTES
}
const sameReader = (a, b) => a.reader.hashKey === b.reader.hashKey

const groupComments = comments =>
Expand All @@ -35,7 +36,9 @@ const Responses = ({ responses }: Props) => {
<ConversationTimestamp value={firstTimestamp} />
</Timestamp>,
readerGroups.map(comments => (
<ResponseGroup key={`${comments[0].timestamp}-group`}>
<ResponseGroup
key={`${comments[0].reader.name} ${comments[0].timestamp}`}
>
<SmallGreyText>{comments[0].reader.name}</SmallGreyText>
{comments.map(comment => (
<Response key={comment.id}>{comment.content}</Response>
Expand Down
42 changes: 41 additions & 1 deletion app/javascript/conversation/SelectedCommentThread.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import * as React from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'

import { Link } from 'react-router-dom'
import { FormattedMessage } from 'react-intl'

import LeadComment from 'conversation/LeadComment'
import Responses from 'conversation/Responses'
import NewCommentForm from 'conversation/NewCommentForm'
Expand Down Expand Up @@ -71,6 +74,12 @@ class SelectedCommentThread extends React.Component<
<Container>
<ScrollView maxHeightOffset={`108px + ${formHeight}px`}>
<CommentsContainer>
<AllCommentsButton to="/conversation">
<FormattedMessage
id="conversation.allComments"
defaultMessage="All comments"
/>
</AllCommentsButton>
<LeadComment
cardPosition={cardPosition}
inSituPath={inSituPath}
Expand All @@ -93,8 +102,10 @@ export default connect(mapStateToProps)(SelectedCommentThread)
const Container = styled.div`
flex: 1;
max-width: 633px;
margin-left: 36px;
margin-left: 16px;
position: relative;
display: flex;
flex-direction: column;
&::before {
position: absolute;
Expand All @@ -105,11 +116,40 @@ const Container = styled.div`
content: '';
z-index: 100;
}
@media (max-width: 700px) {
max-width: 700px;
background-color: #35536f;
position: fixed;
width: 100vw;
height: 100%;
margin: 0;
left: 0;
top: 0;
& .ScrollView {
max-height: none;
}
}
`

const CommentsContainer = styled.div`
margin-top: 30px;
padding: 30px;
background-color: #ebeae4;
border-radius: 2px 2px 0 0;
@media (max-width: 700px) {
margin: 6px 6px 0 6px;
min-height: 100%;
}
`

const AllCommentsButton = styled(Link).attrs({
className: 'pt-button pt-minimal pt-icon-arrow-left',
})`
margin: -10px 0 15px -32px;
@media (min-width: 699px) {
display: none;
}
`
12 changes: 10 additions & 2 deletions app/javascript/conversation/shared.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const CommentThreadBreadcrumbs = styled.ul.attrs({
className: 'pt-breadcrumbs',
})`
display: flex;
align-items: baseline;
white-space: nowrap;
`

Expand Down Expand Up @@ -52,6 +53,7 @@ const StyledBreadcrumbLink = styled.a.attrs({ className: 'pt-breadcrumb' })`
color: black;
font-family: 'freight-text-pro';
font-size: 15px;
display: block;
&::before {
content: '“';
Expand Down Expand Up @@ -79,10 +81,12 @@ const OptionalUnderline = styled.span.attrs({
`};
`

export const ScrollView = styled.div`
export const ScrollView = styled.div.attrs({ className: 'ScrollView' })`
max-height: ${({ maxHeightOffset }) =>
`calc(100vh - (${maxHeightOffset}))` || '100vh'};
overflow: scroll;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
`

export const SmallGreyText = styled.span`
Expand Down Expand Up @@ -112,4 +116,8 @@ export const NoSelectedCommentThread = styled.div`
padding: 30px;
background-color: #415e77;
border-radius: 2px;
@media (max-width: 700px) {
display: none;
}
`
4 changes: 2 additions & 2 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class Comment < ApplicationRecord
include Authority::Abilities

belongs_to :reader
belongs_to :comment_thread, counter_cache: true, touch: true

Expand All @@ -20,7 +20,7 @@ class Comment < ApplicationRecord
delegate :forum, to: :comment_thread

def timestamp
I18n.l created_at.in_time_zone('America/Detroit'), format: :long
created_at
end

private
Expand Down
6 changes: 6 additions & 0 deletions flow-typed/npm/lodash.throttle_vx.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare module 'lodash.throttle' {
declare module.exports: <Args, Returns>(
callback: (Args) => Returns,
maximumFrequency: number
) => Args => Returns
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"js-yaml": "^3.8.3",
"json-loader": "^0.5.4",
"loader-utils": "1.1.0",
"lodash.throttle": "^4.1.1",
"node-sass": "^4.5.2",
"path-complete-extname": "^0.1.0",
"path-to-regexp": "^1.7.0",
Expand Down
Loading

0 comments on commit e2ac13d

Please sign in to comment.