updateLastConsumedMessageIndex зависает, не вызывая обновления в сообщениях - PullRequest
0 голосов
/ 06 мая 2020

Когда компонент монтируется, канал либо берется из существующего, либо создается новый. Этот канал позже сохраняется в состоянии для постоянства в компоненте. При щелчке по компоненту все сообщения канала обновляются до потребляемых.

Код принадлежит столбцу «Сегодняшний канал сдвига». Код правой стороны является отдельным.

Senario: Когда я нажимаю User, вызывается onTaskSelect, который запускает весь пользовательский чат справа после установки всех потребляемых сообщений. здесь возникает проблема 1 и 2 . Теперь я щелкаю другого пользователя и возвращаюсь к ранее выбранному пользователю возникает проблема 3

Проблемы:
1) Он не обновляет использованные сообщения и всегда возвращает ноль.
2 ) Он перестает получать новые сообщения от прослушивателя .on , вызванного в функции joinOrCreate.
3) при повторяющемся ответе на щелчок с ошибкой
SyncError: Доступ запрещен для идентификации (статус: 403, код: 54007) в mapTransportError (http://localhost: 3000 / static / js / 0.chunk. js: 162153: 12 ) в http://localhost: 3000 / static / js / 0.chunk . js: 162210: 20

ПРИМЕЧАНИЕ. Каналы устанавливаются один раз и никогда не уходят, если не обновляется страница.
ПРИМЕЧАНИЕ. Весь чат с правой стороны работает нормально и находится отдельно. module.
ПРИМЕЧАНИЕ. Клиент был инициализирован в начале приложения как контекст, который сохраняется на протяжении всего жизненного цикла приложения от открытия до закрытия.

const TaskCard = props => {

    const [lastMessage, setLastMessage] = useState({})
    const [open, setOpen] = useState(false)
    const [unread, setUnread] = useState(0)
    const [channel, setChannel] = useState({})

    const joinOrCreate = useCallback(async() => {
        try{
            const fetchedChannel = await props.client.getChannelByUniqueName(props.task.id.toString())
            let joined = fetchedChannel
            if(fetchedChannel.state.status !== "joined") {
                joined = await fetchedChannel.join()
            }
            console.log()
            joined.getMessages()
            .then(messages => {
                if(messages.items.length > 0) {
                    if(joined.lastConsumedMessageIndex < messages.items.length - 1) {
                        setUnread(true)
                    }
                    const recent_message = messages.items[messages.items.length - 1]
                    const limit_message = recent_message.body.slice(0,14)
                    setLastMessage({
                        body: limit_message.length === 14? (limit_message + '...') : limit_message,
                        time: recent_message.timestamp,
                        index: recent_message.index,
                    })
                }
            })
            joined.on('messageAdded', messageUpdated)
            setChannel(joined)
        }
        catch(ch) {
            console.log(ch)
            try{
                const newChannel = await props.client.createChannel({
                    uniqueName: props.task.id.toString(),
                    friendlyName: 'General Chat Channel'
                })

                let joined = newChannel
                if(newChannel.state.status !== "joined") {   
                    joined = await newChannel.join()                 
                }
                joined.getMessages()
                .then(messages => {
                    if(messages.items.length > 0) {
                        const recent_message = messages.items[messages.items.length - 1]
                        setLastMessage({
                            body: recent_message.body,
                            time: recent_message.timestamp,
                        })
                    }
                })
                joined.on('messageAdded', messageUpdated)
                setChannel(joined)
            }

            catch(e) {
                console.log(e)
            }
        }
    }, [props.client, props.task.id])

    const messageUpdated = message => {
        const limit_message = message.body.slice(0,14)
        setLastMessage({
            body: limit_message.length === 14? (limit_message + '...') : limit_message,
            time: message.timestamp,
            index: message.index
        })
    }

    const onTaskSelect = () => {
        // console.log(lastMessage.index)
        console.log(channel.uniqueName)
        if(lastMessage.body) {
            channel.updateLastConsumedMessageIndex(+lastMessage.index)
            .then(res => {
                console.log(res)
            })
            .catch(e => {
                // console.log(props.client)
                // console.log(channel)
                console.log(e)
            })
        }
        props.onTaskClick(props.task.id.toString())
    }

    useEffect(() => {
        if(props.channelId === props.task.id) {
            setOpen(true)
            setUnread(false)
        }
        else {
            setOpen(false)
        }
    }, [props.channelId, props.task.id])

    useEffect(() => {
        joinOrCreate()
    }, [joinOrCreate])

    useEffect(() => {
        if(channel.lastConsumedMessageIndex < lastMessage.index && !open) {
            setUnread(true)
        }
    }, [channel.lastConsumedMessageIndex, lastMessage, open])

return (
        <Row key={props.task.id} >
            <Col className='justify-center'>
                <Card className={'more-than-90 ' + (open? 'background-active' : null)}
                    onClick={e => onTaskSelect()}
                >
                    <Row>
                        <Col md={2} style={{alignSelf: 'center', paddingLeft:'15px'}}>
                            {
                                props.task.worker.pic_url === "" || props.task.worker.pic_url === null ?
                                <div className="name-image">
                                    {props.task.worker.first_name[0] + props.task.worker.last_name[0]}
                                </div>
                                :
                                <Image width={50} height={50} src={props.task.worker.pic_url} roundedCircle />                                                
                            }
                        </Col>
                        <Col md={10}>
                            <Row>
                                <Col md={8}>
                                    <p style={{fontSize:'.9rem'}}>{props.task.worker.name}</p>
                                </Col>
                                <Col>
                                    <p style={{fontSize:'.7rem'}} className='left-align-text'>{lastMessage.time? moment(lastMessage.time).format('hh:mm A') : null}</p>
                                </Col>
                            </Row>
                            <Row>
                                <Col md={8}>
                                    <p style={{fontSize:'.7rem'}}>{lastMessage.body? lastMessage.body : null}</p>
                                </Col>
                                <Col>
                                    {
                                        unread ?
                                        <FontAwesomeIcon 
                                            icon={faEnvelopeOpenText}
                                            size="lg"
                                            color={"#0064bb"}
                                        />
                                        :
                                        null
                                    }
                                </Col>
                            </Row>
                        </Col>
                    </Row>
                </Card>
            </Col>
        </Row>
    )
}

enter image description here

1 Ответ

1 голос
/ 07 мая 2020

Здесь проповедник разработчиков Twilio.

Я думаю, что Уилл Сэмс хорошо подметил в своем комментарии. Вам действительно необходимо установить индекс непрочитанных сообщений, чтобы канал мог иметь действительный индекс непрочитанных сообщений. Из документов:

Примечание: Chat не устанавливает автоматически горизонт потребления . Если вы не установите это явно в своем приложении, горизонт потребления не будет существовать для пользователя в канале. Без горизонта потребления горизонт потребления вашего пользователя (состояние чтения) не будет правильно синхронизироваться между клиентами. Если для пользователя не установлен горизонт потребления на канале, получение неизрасходованных сообщений всегда будет возвращать 0 . Если член канала не имеет статуса потребления, его последний использованный индекс и временная метка будут равны нулю или 0 в зависимости от платформы.

Итак, при создании канала я бы установил сообщения канала неизрасходованному , чтобы начать эту меру. Вы также можете использовать функцию setAllMessagesConsumed вместо того, чтобы читать индекс последнего сообщения.

Я также заметил, что когда вы устанавливаете последнее сообщение, вы пропускаете установку его индекса на единицу point:

                        const recent_message = messages.items[messages.items.length - 1]
                        setLastMessage({
                            body: recent_message.body,
                            time: recent_message.timestamp,
                        })

, что может вызвать проблемы.

Меня беспокоит способ настройки ваших обратных вызовов и эффектов. Когда вы запускаете onTaskSelect, это выглядит так, как будто вы отправляете идентификатор задачи обратно родителю.

props.onTaskClick(props.task.id.toString());

Предположительно это так, чтобы вы могли видеть все сообщения на главной панели.

Однако я также предполагаю, что это устанавливает задачу в родительском элементе, которая затем передается как props.tasks этому дочернему элементу. Обратный вызов joinOrCreate настроен на обновление при обновлении props.task.id, а useEffect основан на изменении joinOrCreate. Поэтому я предполагаю, что всякий раз, когда вы переходите между задачами, вы запускаете очистку и переоценку joinOrCreate. За исключением того, что здесь нет функции очистки, поэтому вы каждый раз перезагружаете канал для каждого из этих компонентов. Я бы предположил, что это как-то связано с нарушением событий и возможными ошибками, которые вы получаете при повторном щелчке. жизненный цикл объекта канала. Я бы загрузил и присоединил к списку каналов, которые вы собираетесь отображать в родительском компоненте, а затем передал бы объект канала в TaskCard. Это упростило бы компоненты, поскольку родительский элемент будет обрабатывать данные, а TaskCard может обрабатывать только рендеринг. Это также будет означать, что при изменении статуса карты (с показа на не показ) вы только повторно визуализируете данные. Таким образом, вы также можете поделиться объектом канала между TaskCard и представлением чата справа от скриншота (в противном случае я предполагаю, что вам нужно загрузить его и в этот компонент, и это, вероятно, тоже не поможет).

Это лишь некоторые идеи, основанные на том, что я вижу в вашем приложении. Надеюсь, они помогут!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...