diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 00d4766a23..73cbacc30b 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -283,9 +283,7 @@ processChatCommand = \case setActive ActiveNone atomically . writeTVar u $ Just user pure $ CRActiveUser user - ListUsers -> do - users <- withStore' getUsers - pure $ CRUsersList users + ListUsers -> CRUsersList <$> withStore' getUsersInfo APISetActiveUser userId -> do u <- asks currentUser user <- withStore $ \db -> getSetActiveUser db userId diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 76fe7310e5..65931173da 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -315,7 +315,7 @@ data ChatCommand data ChatResponse = CRActiveUser {user :: User} - | CRUsersList {users :: [User]} + | CRUsersList {users :: [UserInfo]} | CRChatStarted | CRChatRunning | CRChatStopped diff --git a/src/Simplex/Chat/Store.hs b/src/Simplex/Chat/Store.hs index 056a2071f6..78de28f5cf 100644 --- a/src/Simplex/Chat/Store.hs +++ b/src/Simplex/Chat/Store.hs @@ -26,6 +26,7 @@ module Simplex.Chat.Store chatStoreFile, agentStoreFile, createUserRecord, + getUsersInfo, getUsers, setActiveUser, getSetActiveUser, @@ -450,6 +451,19 @@ createUserRecord db (AgentUserId auId) Profile {displayName, fullName, image, pr DB.execute db "UPDATE users SET contact_id = ? WHERE user_id = ?" (contactId, userId) pure $ toUser (userId, auId, contactId, profileId, activeUser, displayName, fullName, image, userPreferences) +getUsersInfo :: DB.Connection -> IO [UserInfo] +getUsersInfo db = getUsers db >>= mapM getUserInfo + where + getUserInfo :: User -> IO UserInfo + getUserInfo user@User {userId} = do + count_ <- + maybeFirstRow fromOnly $ + DB.query + db + "SELECT COUNT(1) FROM chat_items WHERE user_id = ? AND item_status = ? GROUP BY user_id" + (userId, CISRcvNew) + pure UserInfo {user, unreadCount = fromMaybe 0 count_} + getUsers :: DB.Connection -> IO [User] getUsers db = map toUser <$> DB.query_ db userQuery diff --git a/src/Simplex/Chat/Types.hs b/src/Simplex/Chat/Types.hs index ef4bda562d..2776ae7f3b 100644 --- a/src/Simplex/Chat/Types.hs +++ b/src/Simplex/Chat/Types.hs @@ -115,6 +115,16 @@ data User = User instance ToJSON User where toEncoding = J.genericToEncoding J.defaultOptions +data UserInfo = UserInfo + { user :: User, + unreadCount :: Int + } + deriving (Show, Generic, FromJSON) + +instance ToJSON UserInfo where + toJSON = J.genericToJSON J.defaultOptions + toEncoding = J.genericToEncoding J.defaultOptions + type UserId = Int64 type ContactId = Int64 diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 53f5c94d0b..2d1fc9443f 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -267,12 +267,15 @@ responseToView user_ ChatConfig {logLevel, testView} liveItems ts = \case | muted chat chatItem = [] | otherwise = s -viewUsersList :: [User] -> [StyledString] -viewUsersList = - let ldn = T.toLower . (localDisplayName :: User -> ContactName) - in map (\user@User {profile = LocalProfile {displayName, fullName}} -> ttyFullName displayName fullName <> active user) . sortOn ldn +viewUsersList :: [UserInfo] -> [StyledString] +viewUsersList = map userInfo . sortOn ldn where - active User {activeUser} = if activeUser then highlight' " (active)" else "" + ldn (UserInfo User {localDisplayName = n} _) = T.toLower n + userInfo (UserInfo User {localDisplayName = n, profile = LocalProfile {fullName}, activeUser} count) = + ttyFullName n fullName <> active <> unread + where + active = if activeUser then highlight' " (active)" else "" + unread = if count /= 0 then plain $ " (unread: " <> show count <> ")" else "" muted :: ChatInfo c -> ChatItem c d -> Bool muted chat ChatItem {chatDir} = case (chat, chatDir) of diff --git a/tests/ChatTests.hs b/tests/ChatTests.hs index aba627a458..2716bd90fb 100644 --- a/tests/ChatTests.hs +++ b/tests/ChatTests.hs @@ -4425,7 +4425,7 @@ testCreateSecondUser = showActiveUser alice "alice (Alice)" alice ##> "/users" - alice <## "alice (Alice) (active)" + alice <## "alice (Alice) (active) (unread: 1)" alice <## "alisa" alice <##> bob