Add author's userId to comment

This commit is contained in:
Chen-I Lim 2021-01-19 14:48:20 -08:00
parent b22d34057e
commit dcba640427
10 changed files with 59 additions and 38 deletions

View file

@ -44,7 +44,7 @@ interface Board extends IBlock {
duplicate(): MutableBoard duplicate(): MutableBoard
} }
class MutableBoard extends MutableBlock { class MutableBoard extends MutableBlock implements Board {
get icon(): string { get icon(): string {
return this.fields.icon as string return this.fields.icon as string
} }

View file

@ -14,7 +14,7 @@ interface Card extends IBlock {
duplicate(): MutableCard duplicate(): MutableCard
} }
class MutableCard extends MutableBlock { class MutableCard extends MutableBlock implements Card {
get icon(): string { get icon(): string {
return this.fields.icon as string return this.fields.icon as string
} }

View file

@ -4,12 +4,23 @@ import {IBlock} from '../blocks/block'
import {MutableBlock} from './block' import {MutableBlock} from './block'
type CommentBlock = IBlock interface CommentBlock extends IBlock {
readonly userId: string
}
class MutableCommentBlock extends MutableBlock implements CommentBlock {
get userId(): string {
return this.fields.userId as string
}
set userId(value: string) {
this.fields.userId = value
}
class MutableCommentBlock extends MutableBlock {
constructor(block: any = {}) { constructor(block: any = {}) {
super(block) super(block)
this.type = 'comment' this.type = 'comment'
this.userId = block.fields?.userId || ''
} }
} }

View file

@ -4,7 +4,7 @@ import {IContentBlock, MutableContentBlock} from './contentBlock'
type DividerBlock = IContentBlock type DividerBlock = IContentBlock
class MutableDividerBlock extends MutableContentBlock { class MutableDividerBlock extends MutableContentBlock implements DividerBlock {
constructor(block: any = {}) { constructor(block: any = {}) {
super(block) super(block)
this.type = 'divider' this.type = 'divider'

View file

@ -6,7 +6,7 @@ interface ImageBlock extends IContentBlock {
readonly url: string readonly url: string
} }
class MutableImageBlock extends MutableContentBlock implements IContentBlock { class MutableImageBlock extends MutableContentBlock implements ImageBlock {
get url(): string { get url(): string {
return this.fields.url as string return this.fields.url as string
} }

View file

@ -4,7 +4,7 @@ import {IContentBlock, MutableContentBlock} from './contentBlock'
type TextBlock = IContentBlock type TextBlock = IContentBlock
class MutableTextBlock extends MutableContentBlock { class MutableTextBlock extends MutableContentBlock implements TextBlock {
constructor(block: any = {}) { constructor(block: any = {}) {
super(block) super(block)
this.type = 'text' this.type = 'text'

View file

@ -1,30 +1,29 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react' import React from 'react'
import {FormattedMessage, IntlShape, injectIntl} from 'react-intl' import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'
import {BlockIcons} from '../blockIcons' import {BlockIcons} from '../blockIcons'
import {MutableTextBlock} from '../blocks/textBlock'
import {BoardTree} from '../viewModel/boardTree'
import {PropertyType} from '../blocks/board' import {PropertyType} from '../blocks/board'
import {CardTree} from '../viewModel/cardTree' import {MutableTextBlock} from '../blocks/textBlock'
import mutator from '../mutator' import mutator from '../mutator'
import {UserContext} from '../user'
import {Utils} from '../utils' import {Utils} from '../utils'
import {BoardTree} from '../viewModel/boardTree'
import MenuWrapper from '../widgets/menuWrapper' import {CardTree} from '../viewModel/cardTree'
import Menu from '../widgets/menu'
import PropertyMenu from '../widgets/propertyMenu'
import Editable from '../widgets/editable'
import Button from '../widgets/buttons/button' import Button from '../widgets/buttons/button'
import Editable from '../widgets/editable'
import EmojiIcon from '../widgets/icons/emoji' import EmojiIcon from '../widgets/icons/emoji'
import Menu from '../widgets/menu'
import MenuWrapper from '../widgets/menuWrapper'
import PropertyMenu from '../widgets/propertyMenu'
import {MarkdownEditor} from './markdownEditor'
import ContentBlock from './contentBlock'
import CommentsList from './commentsList'
import BlockIconSelector from './blockIconSelector' import BlockIconSelector from './blockIconSelector'
import PropertyValueElement from './propertyValueElement'
import './cardDetail.scss' import './cardDetail.scss'
import CommentsList from './commentsList'
import ContentBlock from './contentBlock'
import {MarkdownEditor} from './markdownEditor'
import PropertyValueElement from './propertyValueElement'
type Props = { type Props = {
boardTree: BoardTree boardTree: BoardTree
@ -196,11 +195,16 @@ class CardDetail extends React.Component<Props, State> {
{!this.props.readonly && {!this.props.readonly &&
<> <>
<hr/> <hr/>
<CommentsList <UserContext.Consumer>
comments={comments} {(user) => (user &&
rootId={card.rootId} <CommentsList
cardId={card.id} comments={comments}
/> userId={user.id}
rootId={card.rootId}
cardId={card.id}
/>
)}
</UserContext.Consumer>
<hr/> <hr/>
</> </>
} }

View file

@ -3,8 +3,7 @@
import React from 'react' import React from 'react'
import {FormattedMessage, injectIntl, IntlShape} from 'react-intl' import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'
import {IBlock} from '../blocks/block' import {CommentBlock, MutableCommentBlock} from '../blocks/commentBlock'
import {MutableCommentBlock} from '../blocks/commentBlock'
import mutator from '../mutator' import mutator from '../mutator'
import {Utils} from '../utils' import {Utils} from '../utils'
import Button from '../widgets/buttons/button' import Button from '../widgets/buttons/button'
@ -14,7 +13,8 @@ import './commentsList.scss'
import {MarkdownEditor} from './markdownEditor' import {MarkdownEditor} from './markdownEditor'
type Props = { type Props = {
comments: readonly IBlock[] comments: readonly CommentBlock[]
userId: string
rootId: string rootId: string
cardId: string cardId: string
intl: IntlShape intl: IntlShape
@ -39,12 +39,16 @@ class CommentsList extends React.Component<Props, State> {
} }
private sendComment = () => { private sendComment = () => {
const {rootId, cardId} = this.props const {userId, rootId, cardId} = this.props
Utils.assertValue(cardId) Utils.assertValue(cardId)
const block = new MutableCommentBlock({rootId, parentId: cardId, title: this.state.newComment}) const comment = new MutableCommentBlock()
mutator.insertBlock(block, 'add comment') comment.parentId = cardId
comment.rootId = rootId
comment.userId = userId
comment.title = this.state.newComment
mutator.insertBlock(comment, 'add comment')
this.setState({newComment: ''}) this.setState({newComment: ''})
} }
@ -52,7 +56,6 @@ class CommentsList extends React.Component<Props, State> {
const {comments, intl} = this.props const {comments, intl} = this.props
// TODO: Replace this placeholder // TODO: Replace this placeholder
const username = 'John Smith'
const userImageUrl = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" style="fill: rgb(192, 192, 192);"><rect width="100" height="100" /></svg>' const userImageUrl = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" style="fill: rgb(192, 192, 192);"><rect width="100" height="100" /></svg>'
return ( return (
@ -62,7 +65,9 @@ class CommentsList extends React.Component<Props, State> {
key={comment.id} key={comment.id}
comment={comment} comment={comment}
userImageUrl={userImageUrl} userImageUrl={userImageUrl}
username={username}
// TODO: Look up user name from userId
username={comment.userId}
/> />
))} ))}

View file

@ -2,20 +2,21 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import {IBlock} from '../blocks/block' import {IBlock} from '../blocks/block'
import {Card, MutableCard} from '../blocks/card' import {Card, MutableCard} from '../blocks/card'
import {CommentBlock} from '../blocks/commentBlock'
import {IContentBlock} from '../blocks/contentBlock' import {IContentBlock} from '../blocks/contentBlock'
import octoClient from '../octoClient' import octoClient from '../octoClient'
import {OctoUtils} from '../octoUtils' import {OctoUtils} from '../octoUtils'
interface CardTree { interface CardTree {
readonly card: Card readonly card: Card
readonly comments: readonly IBlock[] readonly comments: readonly CommentBlock[]
readonly contents: readonly IContentBlock[] readonly contents: readonly IContentBlock[]
readonly allBlocks: readonly IBlock[] readonly allBlocks: readonly IBlock[]
} }
class MutableCardTree implements CardTree { class MutableCardTree implements CardTree {
card: MutableCard card: MutableCard
comments: IBlock[] = [] comments: CommentBlock[] = []
contents: IContentBlock[] = [] contents: IContentBlock[] = []
get allBlocks(): IBlock[] { get allBlocks(): IBlock[] {
@ -53,7 +54,7 @@ class MutableCardTree implements CardTree {
const cardTree = new MutableCardTree(card) const cardTree = new MutableCardTree(card)
cardTree.comments = blocks. cardTree.comments = blocks.
filter((block) => block.type === 'comment'). filter((block) => block.type === 'comment').
sort((a, b) => a.createAt - b.createAt) sort((a, b) => a.createAt - b.createAt) as CommentBlock[]
const contentBlocks = blocks.filter((block) => block.type === 'text' || block.type === 'image' || block.type === 'divider') as IContentBlock[] const contentBlocks = blocks.filter((block) => block.type === 'text' || block.type === 'image' || block.type === 'divider') as IContentBlock[]
cardTree.contents = OctoUtils.getBlockOrder(card.contentOrder, contentBlocks) cardTree.contents = OctoUtils.getBlockOrder(card.contentOrder, contentBlocks)

View file

@ -13,7 +13,7 @@ interface WorkspaceTree {
readonly allBlocks: readonly IBlock[] readonly allBlocks: readonly IBlock[]
} }
class MutableWorkspaceTree { class MutableWorkspaceTree implements WorkspaceTree {
boards: Board[] = [] boards: Board[] = []
boardTemplates: Board[] = [] boardTemplates: Board[] = []
views: BoardView[] = [] views: BoardView[] = []