Skip to content

Commit

Permalink
Small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmitrevski committed Dec 6, 2023
1 parent e5c2223 commit 75f3997
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 33 deletions.
10 changes: 10 additions & 0 deletions Sources/StreamChatSwiftUI/ChatChannel/ChatChannelDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ protocol ChannelDataSource: AnyObject {

/// Determines whether all new messages have been fetched.
var hasLoadedAllNextMessages: Bool { get }

var firstUnreadMessageId: String? { get }

/// Loads the previous messages.
/// - Parameters:
Expand Down Expand Up @@ -89,6 +91,10 @@ class ChatChannelDataSource: ChannelDataSource, ChatChannelControllerDelegate {
var hasLoadedAllNextMessages: Bool {
controller.hasLoadedAllNextMessages
}

var firstUnreadMessageId: String? {
controller.firstUnreadMessageId
}

init(controller: ChatChannelController) {
self.controller = controller
Expand Down Expand Up @@ -160,6 +166,10 @@ class MessageThreadDataSource: ChannelDataSource, ChatMessageControllerDelegate
var hasLoadedAllNextMessages: Bool {
messageController.hasLoadedAllNextReplies
}

var firstUnreadMessageId: String? {
channelController.firstUnreadMessageId
}

init(
channelController: ChatChannelController,
Expand Down
34 changes: 20 additions & 14 deletions Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {

channelName = channel?.name ?? ""
checkHeaderType()
if channelController.channel?.unreadCount.messages ?? 0 > 0 {
if channelController.firstUnreadMessageId != nil {
firstUnreadMessageId = channelController.firstUnreadMessageId
canMarkRead = false
} else if channelController.lastReadMessageId != nil {
lastReadMessageId = channelController.lastReadMessageId
canMarkRead = false
}
}
checkUnreadCount()
}

@objc
Expand All @@ -216,7 +208,9 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
@objc
private func applicationWillEnterForeground() {
guard let first = messages.first else { return }
maybeSendReadEvent(for: first)
if canMarkRead {
maybeSendReadEvent(for: first)
}
}

public func scrollToLastMessage() {
Expand All @@ -237,8 +231,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
log.error("Error loading messages around message \(messageId)")
return
}
//TODO: change to data source.
if let firstUnread = self?.channelController.firstUnreadMessageId,
if let firstUnread = self?.channelDataSource.firstUnreadMessageId,
let message = self?.channelController.dataStore.message(id: firstUnread) {
self?.firstUnreadMessageId = message.messageId
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
Expand Down Expand Up @@ -404,8 +397,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
}

if lastMessageRead != nil && firstUnreadMessageId == nil {
//TODO: data source
self.firstUnreadMessageId = channelController.firstUnreadMessageId
self.firstUnreadMessageId = channelDataSource.firstUnreadMessageId
}
}

Expand Down Expand Up @@ -434,6 +426,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
public func onViewAppear() {
setActive()
messages = channelDataSource.messages
firstUnreadMessageId = channelDataSource.firstUnreadMessageId
checkNameChange()
}

Expand Down Expand Up @@ -607,6 +600,19 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
}
}

private func checkUnreadCount() {
guard !isMessageThread else { return }
if channelController.channel?.unreadCount.messages ?? 0 > 0 {
if channelController.firstUnreadMessageId != nil {
firstUnreadMessageId = channelController.firstUnreadMessageId
canMarkRead = false
} else if channelController.lastReadMessageId != nil {
lastReadMessageId = channelController.lastReadMessageId
canMarkRead = false
}
}
}

private func handleDateChange() {
guard showScrollToLatestButton == true, let currentDate = currentDate else {
currentDateString = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import StreamChat
import SwiftUI

//TODO: improve this
struct JumpToUnreadButton: View {

@Injected(\.colors) var colors

var unreadCount: Int
var onTap: () -> ()
var onClose: () -> ()
Expand All @@ -17,18 +18,19 @@ struct JumpToUnreadButton: View {
Button {
onTap()
} label: {
Text("\(unreadCount) unread ")
Text(L10n.Message.Unread.count(unreadCount))
.font(.caption)
}
Button {
onClose()
} label: {
Image(systemName: "xmark")
.font(.caption.weight(.bold))
}
}
.padding()
.padding(.all, 10)
.foregroundColor(.white)
.background(Color.gray)
.background(Color(colors.textLowEmphasis))
.cornerRadius(16)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,16 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
}
})
.overlay(
(channel.unreadCount.messages > 0 && !unreadMessagesBannerShown) ? VStack {
JumpToUnreadButton(unreadCount: channel.unreadCount.messages) {
(channel.unreadCount.messages > 0 && !unreadMessagesBannerShown) ?
factory.makeJumpToUnreadButton(
channel: channel,
onJumpToMessage: {
_ = onJumpToMessage?(firstUnreadMessageId ?? "unknown")
} onClose: {
},
onClose: {
firstUnreadMessageId = nil
}

Spacer()
} : nil
) : nil
)
.modifier(factory.makeMessageListContainerModifier())
.modifier(HideKeyboardOnTapGesture(shouldAdd: keyboardShown))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,17 @@ extension MessageAction {

messageActions.append(deleteAction)
} else {
let markUnreadAction = markAsUnreadAction(
for: message,
channel: channel,
chatClient: chatClient,
onFinish: onFinish,
onError: onError
)

messageActions.append(markUnreadAction)
if !message.isPartOfThread {
let markUnreadAction = markAsUnreadAction(
for: message,
channel: channel,
chatClient: chatClient,
onFinish: onFinish,
onError: onError
)

messageActions.append(markUnreadAction)
}

let flagAction = flagMessageAction(
for: message,
Expand Down
17 changes: 17 additions & 0 deletions Sources/StreamChatSwiftUI/DefaultViewFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,23 @@ extension ViewFactory {
count: count
)
}

public func makeJumpToUnreadButton(
channel: ChatChannel,
onJumpToMessage: @escaping () -> (),
onClose: @escaping () -> ()
) -> some View {
VStack {
JumpToUnreadButton(
unreadCount: channel.unreadCount.messages,
onTap: onJumpToMessage,
onClose: onClose
)
.padding(.all, 8)

Spacer()
}
}
}

/// Default class conforming to `ViewFactory`, used throughout the SDK.
Expand Down
6 changes: 6 additions & 0 deletions Sources/StreamChatSwiftUI/Generated/L10n.swift
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ internal enum L10n {
/// Online
internal static var online: String { L10n.tr("Localizable", "message.title.online") }
}
internal enum Unread {
/// Plural format key: "%#@unread@"
internal static func count(_ p1: Int) -> String {
return L10n.tr("Localizable", "message.unread.count", p1)
}
}
}

internal enum MessageList {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@
<string>%d Message Reactions</string>
</dict>
</dict>
<key>message.unread.count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@unread@</string>
<key>unread</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>zero</key>
<string>%d unread</string>
<key>one</key>
<string>%d unread</string>
<key>other</key>
<string>%d unread</string>
</dict>
</dict>
<key>message.search.number-of-results</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
Expand Down
13 changes: 13 additions & 0 deletions Sources/StreamChatSwiftUI/ViewFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -870,4 +870,17 @@ public protocol ViewFactory: AnyObject {
newMessagesStartId: Binding<String?>,
count: Int
) -> NewMessagesIndicatorViewType

associatedtype JumpToUnreadButtonType: View
/// Creates a jump to unread button.
/// - Parameters:
/// - channel: the current channel.
/// - onJumpToMessage: called when jump to message is tapped.
/// - onClose: called when the jump to unread should be dismissed.
/// - Returns: view shown in the jump to unread slot.
func makeJumpToUnreadButton(
channel: ChatChannel,
onJumpToMessage: @escaping () -> (),
onClose: @escaping () -> ()
) -> JumpToUnreadButtonType
}

0 comments on commit 75f3997

Please sign in to comment.