diff --git a/app/actions/local/channel.ts b/app/actions/local/channel.ts index 090441b51..729fddb29 100644 --- a/app/actions/local/channel.ts +++ b/app/actions/local/channel.ts @@ -189,7 +189,7 @@ export const markChannelAsViewed = async (serverUrl: string, channelId: string, } }; -export const markChannelAsUnread = async (serverUrl: string, channelId: string, messageCount: number, mentionsCount: number, manuallyUnread: boolean, lastViewed: number, prepareRecordsOnly = false) => { +export const markChannelAsUnread = async (serverUrl: string, channelId: string, messageCount: number, mentionsCount: number, lastViewed: number, prepareRecordsOnly = false) => { const operator = DatabaseManager.serverDatabases[serverUrl]?.operator; if (!operator) { return {error: `${serverUrl} database not found`}; @@ -201,11 +201,12 @@ export const markChannelAsUnread = async (serverUrl: string, channelId: string, } member.prepareUpdate((m) => { - m.viewedAt = lastViewed; + m.viewedAt = lastViewed - 1; m.lastViewedAt = lastViewed; m.messageCount = messageCount; m.mentionsCount = mentionsCount; - m.manuallyUnread = manuallyUnread; + m.manuallyUnread = true; + m.isUnread = true; }); try { diff --git a/app/actions/remote/post.ts b/app/actions/remote/post.ts index 26f3e299d..dd7f7cfd1 100644 --- a/app/actions/remote/post.ts +++ b/app/actions/remote/post.ts @@ -4,7 +4,7 @@ import {DeviceEventEmitter} from 'react-native'; -import {updateLastPostAt} from '@actions/local/channel'; +import {markChannelAsUnread, updateLastPostAt} from '@actions/local/channel'; import {processPostsFetched, removePost} from '@actions/local/post'; import {addRecentReaction} from '@actions/local/reactions'; import {ActionType, Events, General, ServerErrors} from '@constants'; @@ -575,3 +575,43 @@ export const deletePost = async (serverUrl: string, postId: string) => { return {error}; } }; + +export const markPostAsUnread = async (serverUrl: string, postId: string) => { + const database = DatabaseManager.serverDatabases[serverUrl]?.database; + if (!database) { + return {error: `${serverUrl} database not found`}; + } + let client; + try { + client = NetworkManager.getClient(serverUrl); + } catch (error) { + return {error}; + } + + try { + const [userId, post] = await Promise.all([queryCurrentUserId(database), queryPostById(database, postId)]); + if (post && userId) { + await client.markPostAsUnread(userId, postId); + const {channelId} = post; + + const [channel, channelMember] = await Promise.all([ + client.getChannel(channelId), + client.getChannelMember(channelId, userId), + ]); + if (channel && channelMember) { + const messageCount = channel.total_msg_count - channelMember.msg_count; + const mentionCount = channelMember.mention_count; + await markChannelAsUnread(serverUrl, channelId, messageCount, mentionCount, post.createAt); + return { + post, + }; + } + } + return { + post, + }; + } catch (error) { + forceLogoutIfNecessary(serverUrl, error as ClientErrorProps); + return {error}; + } +}; diff --git a/app/actions/websocket/posts.ts b/app/actions/websocket/posts.ts index 84cc9a34a..17b71d1ff 100644 --- a/app/actions/websocket/posts.ts +++ b/app/actions/websocket/posts.ts @@ -152,9 +152,7 @@ export async function handleNewPostEvent(serverUrl: string, msg: WebSocketMessag post.channel_id, myChannel.messageCount + 1, myChannel.mentionsCount + (hasMentions ? 1 : 0), - false, myChannel.lastViewedAt, - true, ); if (unreadAt) { models.push(unreadAt); @@ -217,5 +215,5 @@ export async function handlePostUnread(serverUrl: string, msg: WebSocketMessage) const channel = channels?.[0]; const postNumber = channel?.total_msg_count; const delta = postNumber ? postNumber - msg.data.msg_count : msg.data.msg_count; - markChannelAsUnread(serverUrl, msg.broadcast.channel_id, delta, msg.data.mention_count, true, msg.data.last_viewed_at); + markChannelAsUnread(serverUrl, msg.broadcast.channel_id, delta, msg.data.mention_count, msg.data.last_viewed_at); } diff --git a/app/screens/post_options/options/mark_unread_option.tsx b/app/screens/post_options/options/mark_unread_option.tsx index 745f4da57..14805ead1 100644 --- a/app/screens/post_options/options/mark_unread_option.tsx +++ b/app/screens/post_options/options/mark_unread_option.tsx @@ -1,24 +1,34 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {useCallback} from 'react'; +import {markPostAsUnread} from '@actions/remote/post'; +import Screens from '@constants/screens'; +import {useServerUrl} from '@context/server'; import {t} from '@i18n'; +import {dismissBottomSheet} from '@screens/navigation'; import BaseOption from './base_option'; -//fixme: wire up canMarkAsUnread -const MarkAsUnreadOption = () => { - const handleMarkUnread = () => { - //todo: - }; +type Props = { + postId: string; +} + +const MarkAsUnreadOption = ({postId}: Props) => { + const serverUrl = useServerUrl(); + + const onPress = useCallback(() => { + markPostAsUnread(serverUrl, postId); + dismissBottomSheet(Screens.POST_OPTIONS); + }, [serverUrl, postId]); return ( ); diff --git a/app/screens/post_options/post_options.tsx b/app/screens/post_options/post_options.tsx index e0076e115..eeecc936b 100644 --- a/app/screens/post_options/post_options.tsx +++ b/app/screens/post_options/post_options.tsx @@ -74,7 +74,9 @@ const PostOptions = ({ thread={thread} /> } - {canMarkAsUnread && !isSystemPost && ()} + {canMarkAsUnread && !isSystemPost && + + } {canCopyPermalink && } {!isSystemPost &&