1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-01-20 18:28:25 +02:00

Moving gallery loading/listening to the Gallery component instead to each card

This commit is contained in:
Jesús Espino 2021-03-31 12:17:52 +02:00
parent 41a91fb7b5
commit 6adc1cb756
4 changed files with 52 additions and 45 deletions

View File

@ -28,7 +28,7 @@ const CardDialog = (props: Props) => {
const [syncComplete, setSyncComplete] = useState(false) const [syncComplete, setSyncComplete] = useState(false)
const [cardTree, setCardTree] = useState<CardTree>() const [cardTree, setCardTree] = useState<CardTree>()
useCardListener( useCardListener(
props.cardId, [props.cardId],
async (blocks) => { async (blocks) => {
Utils.log(`cardListener.onChanged: ${blocks.length}`) Utils.log(`cardListener.onChanged: ${blocks.length}`)
const newCardTree = cardTree ? MutableCardTree.incrementalUpdate(cardTree, blocks) : await MutableCardTree.sync(props.cardId) const newCardTree = cardTree ? MutableCardTree.incrementalUpdate(cardTree, blocks) : await MutableCardTree.sync(props.cardId)

View File

@ -1,9 +1,11 @@
// 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, {useState, useEffect} from 'react'
import {FormattedMessage} from 'react-intl' import {FormattedMessage} from 'react-intl'
import {BoardTree} from '../../viewModel/boardTree' import {BoardTree} from '../../viewModel/boardTree'
import {CardTree, MutableCardTree} from '../../viewModel/cardTree'
import useCardListener from '../../hooks/cardListener'
import './gallery.scss' import './gallery.scss'
import GalleryCard from './galleryCard' import GalleryCard from './galleryCard'
@ -18,18 +20,45 @@ type Props = {
const Gallery = (props: Props): JSX.Element => { const Gallery = (props: Props): JSX.Element => {
const {boardTree} = props const {boardTree} = props
const {cards} = boardTree const {cards} = boardTree
const [cardTrees, setCardTrees] = useState<{[key: string]: CardTree | undefined}>({})
useCardListener(
cards.map((c) => c.id),
async (blocks) => {
cards.forEach(async (c) => {
const cardTree = cardTrees[c.id]
const newCardTree = cardTree ? MutableCardTree.incrementalUpdate(cardTree, blocks) : await MutableCardTree.sync(c.id)
setCardTrees((oldTree) => ({...oldTree, [c.id]: newCardTree}))
})
},
async () => {
cards.forEach(async (c) => {
const newCardTree = await MutableCardTree.sync(c.id)
setCardTrees((oldTree) => ({...oldTree, [c.id]: newCardTree}))
})
},
)
useEffect(() => {
cards.forEach(async (c) => {
const newCardTree = await MutableCardTree.sync(c.id)
setCardTrees((oldTree) => ({...oldTree, [c.id]: newCardTree}))
})
}, [cards])
return ( return (
<div className='octo-table-body Gallery'> <div className='octo-table-body Gallery'>
{cards.map((card) => { {cards.map((card) => {
const tableRow = ( if (cardTrees[card.id]) {
<GalleryCard return (
key={card.id + card.updateAt} <GalleryCard
card={card} key={card.id + card.updateAt}
showCard={props.showCard} cardTree={cardTrees[card.id]}
/>) showCard={props.showCard}
/>
return tableRow )
}
return null
})} })}
{/* Add New row */} {/* Add New row */}

View File

@ -1,53 +1,31 @@
// 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, {useState, useEffect} from 'react' import React from 'react'
import {FormattedMessage} from 'react-intl' import {FormattedMessage} from 'react-intl'
import {Card} from '../../blocks/card' import {CardTree} from '../../viewModel/cardTree'
import {CardTree, MutableCardTree} from '../../viewModel/cardTree'
import {IContentBlock} from '../../blocks/contentBlock' import {IContentBlock} from '../../blocks/contentBlock'
import useCardListener from '../../hooks/cardListener'
import ImageElement from '../content/imageElement' import ImageElement from '../content/imageElement'
import ContentElement from '../content/contentElement' import ContentElement from '../content/contentElement'
import './galleryCard.scss' import './galleryCard.scss'
type Props = { type Props = {
card: Card cardTree: CardTree
showCard: (cardId: string) => void showCard: (cardId: string) => void
} }
const GalleryCard = React.memo((props: Props) => { const GalleryCard = React.memo((props: Props) => {
const {card} = props const {cardTree} = props
const [cardTree, setCardTree] = useState<CardTree>()
useCardListener(
card.id,
async (blocks) => {
const newCardTree = cardTree ? MutableCardTree.incrementalUpdate(cardTree, blocks) : await MutableCardTree.sync(card.id)
setCardTree(newCardTree)
},
async () => {
const newCardTree = await MutableCardTree.sync(card.id)
setCardTree(newCardTree)
},
)
useEffect(() => {
const f = async () => setCardTree(await MutableCardTree.sync(card.id))
f()
}, [])
let images: IContentBlock[] = [] let images: IContentBlock[] = []
if (cardTree) { images = cardTree.contents.filter((content) => content.type === 'image')
images = cardTree.contents.filter((content) => content.type === 'image')
}
return ( return (
<div <div
className='GalleryCard' className='GalleryCard'
onClick={() => props.showCard(props.card.id)} onClick={() => props.showCard(cardTree.card.id)}
> >
{images?.length > 0 && {images?.length > 0 &&
<div className='gallery-image'> <div className='gallery-image'>
@ -64,9 +42,9 @@ const GalleryCard = React.memo((props: Props) => {
))} ))}
</div>} </div>}
<div className='gallery-title'> <div className='gallery-title'>
{ card.icon ? <div className='octo-icon'>{card.icon}</div> : undefined } { cardTree.card.icon ? <div className='octo-icon'>{cardTree.card.icon}</div> : undefined }
<div key='__title'> <div key='__title'>
{card.title || {cardTree.card.title ||
<FormattedMessage <FormattedMessage
id='KanbanCard.untitled' id='KanbanCard.untitled'
defaultMessage='Untitled' defaultMessage='Untitled'

View File

@ -7,7 +7,7 @@ import octoClient from '../octoClient'
import {OctoListener} from '../octoListener' import {OctoListener} from '../octoListener'
import {Utils} from '../utils' import {Utils} from '../utils'
export default function useCardListener(cardId:string, onChange: (blocks: IBlock[]) => void, onReconnect: () => void): void { export default function useCardListener(cardIds: string[], onChange: (blocks: IBlock[]) => void, onReconnect: () => void): void {
let cardListener: OctoListener | null = null let cardListener: OctoListener | null = null
const deleteListener = () => { const deleteListener = () => {
@ -21,7 +21,7 @@ export default function useCardListener(cardId:string, onChange: (blocks: IBlock
cardListener = new OctoListener() cardListener = new OctoListener()
cardListener.open( cardListener.open(
octoClient.workspaceId, octoClient.workspaceId,
[cardId], cardIds,
onChange, onChange,
onReconnect, onReconnect,
) )
@ -33,11 +33,11 @@ export default function useCardListener(cardId:string, onChange: (blocks: IBlock
} }
useEffect(() => { useEffect(() => {
Utils.log(`useCardListener.connect: ${cardId}`) Utils.log(`useCardListener.connect: ${cardIds}`)
createCardTreeAndSync() createCardTreeAndSync()
return () => { return () => {
Utils.log(`useCardListener.disconnect: ${cardId}`) Utils.log(`useCardListener.disconnect: ${cardIds}`)
deleteListener() deleteListener()
} }
}, [cardId]) }, [cardIds.join('-')])
} }