From 6cb89c1d19910734c090f242cf45d641f30f30db Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Wed, 22 Oct 2025 15:43:01 +0300 Subject: [PATCH] Add Identifiable conformances to models --- .../Models/Attachments/ChatMessageAttachment.swift | 2 +- Sources/StreamChat/Models/Channel.swift | 4 ++++ Sources/StreamChat/Models/ChatMessage.swift | 2 +- Sources/StreamChat/Models/Device.swift | 2 +- Sources/StreamChat/Models/DraftMessage.swift | 2 +- Sources/StreamChat/Models/MessageReaction.swift | 4 ++-- Sources/StreamChat/Models/MessageReminder.swift | 2 +- Sources/StreamChat/Models/Poll.swift | 2 +- Sources/StreamChat/Models/PollOption.swift | 2 +- Sources/StreamChat/Models/PollVote.swift | 2 +- Sources/StreamChat/Models/Thread.swift | 3 ++- Sources/StreamChat/Models/ThreadParticipant.swift | 6 ++++++ Sources/StreamChat/Models/User+SwiftUI.swift | 8 -------- Sources/StreamChat/Models/User.swift | 2 +- Sources/StreamChat/Models/UserInfo.swift | 2 +- StreamChat.xcodeproj/project.pbxproj | 6 ------ 16 files changed, 24 insertions(+), 27 deletions(-) delete mode 100644 Sources/StreamChat/Models/User+SwiftUI.swift diff --git a/Sources/StreamChat/Models/Attachments/ChatMessageAttachment.swift b/Sources/StreamChat/Models/Attachments/ChatMessageAttachment.swift index a991ef19df5..21f5ef26d9a 100644 --- a/Sources/StreamChat/Models/Attachments/ChatMessageAttachment.swift +++ b/Sources/StreamChat/Models/Attachments/ChatMessageAttachment.swift @@ -40,7 +40,7 @@ public struct StreamAttachment { /// A type representing a chat message attachment. /// `ChatMessageAttachment` is an immutable snapshot of message attachment at the given time. @dynamicMemberLookup -public struct ChatMessageAttachment { +public struct ChatMessageAttachment: Identifiable { /// The attachment identifier. public let id: AttachmentId diff --git a/Sources/StreamChat/Models/Channel.swift b/Sources/StreamChat/Models/Channel.swift index c8e1517d555..9778547f4c0 100644 --- a/Sources/StreamChat/Models/Channel.swift +++ b/Sources/StreamChat/Models/Channel.swift @@ -369,6 +369,10 @@ public struct ChatChannel: Sendable { } } +extension ChatChannel: Identifiable { + public var id: String { cid.rawValue } +} + extension ChatChannel { /// The type of the channel. public var type: ChannelType { cid.type } diff --git a/Sources/StreamChat/Models/ChatMessage.swift b/Sources/StreamChat/Models/ChatMessage.swift index d250ab838aa..cc8b7d7fc39 100644 --- a/Sources/StreamChat/Models/ChatMessage.swift +++ b/Sources/StreamChat/Models/ChatMessage.swift @@ -9,7 +9,7 @@ import Foundation public typealias MessageId = String /// A type representing a chat message. `ChatMessage` is an immutable snapshot of a chat message entity at the given time. -public struct ChatMessage: Sendable { +public struct ChatMessage: Identifiable, Sendable { /// A unique identifier of the message. public let id: MessageId diff --git a/Sources/StreamChat/Models/Device.swift b/Sources/StreamChat/Models/Device.swift index 3ca388f30aa..bc09afee1d9 100644 --- a/Sources/StreamChat/Models/Device.swift +++ b/Sources/StreamChat/Models/Device.swift @@ -13,7 +13,7 @@ extension Data { } /// An object representing a device which can receive push notifications. -public struct Device: Codable, Equatable, Sendable { +public struct Device: Codable, Equatable, Identifiable, Sendable { private enum CodingKeys: String, CodingKey { case id case createdAt = "created_at" diff --git a/Sources/StreamChat/Models/DraftMessage.swift b/Sources/StreamChat/Models/DraftMessage.swift index 852f1dfb42f..1e9a058d465 100644 --- a/Sources/StreamChat/Models/DraftMessage.swift +++ b/Sources/StreamChat/Models/DraftMessage.swift @@ -4,7 +4,7 @@ import Foundation -public struct DraftMessage: Sendable { +public struct DraftMessage: Sendable, Identifiable { /// A unique identifier of the message. public let id: MessageId diff --git a/Sources/StreamChat/Models/MessageReaction.swift b/Sources/StreamChat/Models/MessageReaction.swift index efa433ccaa3..55c80e419bc 100644 --- a/Sources/StreamChat/Models/MessageReaction.swift +++ b/Sources/StreamChat/Models/MessageReaction.swift @@ -6,9 +6,9 @@ import Foundation /// A type representing a message reaction. `ChatMessageReaction` is an immutable snapshot /// of a message reaction entity at the given time. -public struct ChatMessageReaction: Hashable, Sendable { +public struct ChatMessageReaction: Hashable, Identifiable, Sendable { /// The id of the reaction. - let id: String + public let id: String /// The reaction type. public let type: MessageReactionType diff --git a/Sources/StreamChat/Models/MessageReminder.swift b/Sources/StreamChat/Models/MessageReminder.swift index 18d5c17350b..ca387150aa0 100644 --- a/Sources/StreamChat/Models/MessageReminder.swift +++ b/Sources/StreamChat/Models/MessageReminder.swift @@ -5,7 +5,7 @@ import Foundation /// A type representing a message reminder. -public struct MessageReminder: Sendable { +public struct MessageReminder: Identifiable, Sendable { /// A unique identifier of the reminder, based on the message ID. public let id: String diff --git a/Sources/StreamChat/Models/Poll.swift b/Sources/StreamChat/Models/Poll.swift index 970f9cd13bc..2b2958a5779 100644 --- a/Sources/StreamChat/Models/Poll.swift +++ b/Sources/StreamChat/Models/Poll.swift @@ -5,7 +5,7 @@ import Foundation /// The model for a Poll. -public struct Poll: Equatable, Sendable { +public struct Poll: Equatable, Identifiable, Sendable { /// A boolean indicating whether the poll allows answers/comments. public let allowAnswers: Bool diff --git a/Sources/StreamChat/Models/PollOption.swift b/Sources/StreamChat/Models/PollOption.swift index 70d3d23fb16..47eebed115b 100644 --- a/Sources/StreamChat/Models/PollOption.swift +++ b/Sources/StreamChat/Models/PollOption.swift @@ -5,7 +5,7 @@ import Foundation /// The model for an option in a poll. -public struct PollOption: Hashable, Equatable, Sendable { +public struct PollOption: Hashable, Equatable, Identifiable, Sendable { /// The unique identifier of the poll option. public let id: String diff --git a/Sources/StreamChat/Models/PollVote.swift b/Sources/StreamChat/Models/PollVote.swift index 6cdee431e8d..0eda62fdc59 100644 --- a/Sources/StreamChat/Models/PollVote.swift +++ b/Sources/StreamChat/Models/PollVote.swift @@ -5,7 +5,7 @@ import Foundation /// A structure representing a vote in a poll. -public struct PollVote: Hashable, Equatable, Sendable { +public struct PollVote: Hashable, Equatable, Identifiable, Sendable { /// The unique identifier of the poll vote. public let id: String diff --git a/Sources/StreamChat/Models/Thread.swift b/Sources/StreamChat/Models/Thread.swift index 2e55c74c71d..2338051e0b2 100644 --- a/Sources/StreamChat/Models/Thread.swift +++ b/Sources/StreamChat/Models/Thread.swift @@ -5,7 +5,8 @@ import Foundation /// A type representing a thread. -public struct ChatThread: Sendable { +public struct ChatThread: Identifiable, Sendable { + public var id: MessageId { parentMessageId } /// The id of the message which created the thread. It is also the id of the thread. public let parentMessageId: MessageId /// The parent message which is the root of this thread. diff --git a/Sources/StreamChat/Models/ThreadParticipant.swift b/Sources/StreamChat/Models/ThreadParticipant.swift index 4516edaf11e..751f3e74fda 100644 --- a/Sources/StreamChat/Models/ThreadParticipant.swift +++ b/Sources/StreamChat/Models/ThreadParticipant.swift @@ -15,3 +15,9 @@ public struct ThreadParticipant: Equatable, Sendable { /// The date when the participant last read the thread. public let lastReadAt: Date? } + +extension ThreadParticipant: Identifiable { + public var id: String { + "\(threadId)-\(user.id)" + } +} diff --git a/Sources/StreamChat/Models/User+SwiftUI.swift b/Sources/StreamChat/Models/User+SwiftUI.swift deleted file mode 100644 index 9a50f402420..00000000000 --- a/Sources/StreamChat/Models/User+SwiftUI.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Foundation - -/// Protocol conformance needed for ActionSheet presenting. -extension ChatUser: Identifiable {} diff --git a/Sources/StreamChat/Models/User.swift b/Sources/StreamChat/Models/User.swift index f65987d0f3c..298ecfae052 100644 --- a/Sources/StreamChat/Models/User.swift +++ b/Sources/StreamChat/Models/User.swift @@ -12,7 +12,7 @@ public typealias TeamId = String /// A type representing a chat user. `ChatUser` is an immutable snapshot of a chat user entity at the given time. /// -public class ChatUser: @unchecked Sendable { +public class ChatUser: Identifiable, @unchecked Sendable { /// The unique identifier of the user. public let id: UserId diff --git a/Sources/StreamChat/Models/UserInfo.swift b/Sources/StreamChat/Models/UserInfo.swift index 8de44179af5..721eac84898 100644 --- a/Sources/StreamChat/Models/UserInfo.swift +++ b/Sources/StreamChat/Models/UserInfo.swift @@ -5,7 +5,7 @@ import Foundation /// The user information used to connect the user to chat. -public struct UserInfo: Sendable { +public struct UserInfo: Identifiable, Sendable { /// The id of the user. public let id: UserId /// The name of the user. diff --git a/StreamChat.xcodeproj/project.pbxproj b/StreamChat.xcodeproj/project.pbxproj index 0ec134c8f92..c90d65f318f 100644 --- a/StreamChat.xcodeproj/project.pbxproj +++ b/StreamChat.xcodeproj/project.pbxproj @@ -488,7 +488,6 @@ 7865705825FB6DF300974045 /* UIViewController+Extensions_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7865705725FB6DF300974045 /* UIViewController+Extensions_Tests.swift */; }; 78C8473825FA0EF000A5D1D0 /* ChatChannelUnreadCountView+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C8473725FA0EF000A5D1D0 /* ChatChannelUnreadCountView+SwiftUI.swift */; }; 78C8474125FA0F2900A5D1D0 /* ChatChannelUnreadCountView+SwiftUI_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C8474025FA0F2900A5D1D0 /* ChatChannelUnreadCountView+SwiftUI_Tests.swift */; }; - 7900452625374CA20096ECA1 /* User+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7900452525374CA20096ECA1 /* User+SwiftUI.swift */; }; 7908820625432B7200896F03 /* StreamChatUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 790881FD25432B7200896F03 /* StreamChatUI.framework */; }; 7908823325432C6400896F03 /* StreamChatUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 7908823125432C6400896F03 /* StreamChatUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7908824A25432CC600896F03 /* StreamChatStressTestPlan.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 7908824725432CC600896F03 /* StreamChatStressTestPlan.xctestplan */; }; @@ -2217,7 +2216,6 @@ C121E894274544B000023E4C /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799C9431247D2FB9001F1104 /* ChatMessage.swift */; }; C121E895274544B000023E4C /* MessagePinning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD7AC98B260A94C6004AADA5 /* MessagePinning.swift */; }; C121E896274544B000023E4C /* UnreadCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AAB1C6524CB39F2009B783F /* UnreadCount.swift */; }; - C121E897274544B000023E4C /* User+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7900452525374CA20096ECA1 /* User+SwiftUI.swift */; }; C121E898274544B000023E4C /* MessageReaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8899BC52254318CC003CB98B /* MessageReaction.swift */; }; C121E899274544B000023E4C /* MessageReactionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EA9AED254721C0007EE76B /* MessageReactionType.swift */; }; C121E89A274544B000023E4C /* MuteDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88DA57632631CF1F00FA8C53 /* MuteDetails.swift */; }; @@ -3470,7 +3468,6 @@ 7865705725FB6DF300974045 /* UIViewController+Extensions_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions_Tests.swift"; sourceTree = ""; }; 78C8473725FA0EF000A5D1D0 /* ChatChannelUnreadCountView+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatChannelUnreadCountView+SwiftUI.swift"; sourceTree = ""; }; 78C8474025FA0F2900A5D1D0 /* ChatChannelUnreadCountView+SwiftUI_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatChannelUnreadCountView+SwiftUI_Tests.swift"; sourceTree = ""; }; - 7900452525374CA20096ECA1 /* User+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "User+SwiftUI.swift"; sourceTree = ""; }; 790881FD25432B7200896F03 /* StreamChatUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StreamChatUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7908820525432B7200896F03 /* StreamChatUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StreamChatUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7908823125432C6400896F03 /* StreamChatUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamChatUI.h; sourceTree = ""; }; @@ -6295,7 +6292,6 @@ AD37D7D22BC9938E00800D8C /* ThreadRead.swift */, 8AAB1C6524CB39F2009B783F /* UnreadCount.swift */, 79877A012498E4BB00015F8B /* User.swift */, - 7900452525374CA20096ECA1 /* User+SwiftUI.swift */, 64C8C86D26934C6100329F82 /* UserInfo.swift */, ); path = Models; @@ -11944,7 +11940,6 @@ ADB8B90F2D8C7B2500549C95 /* ReminderUpdaterMiddleware.swift in Sources */, 882C5759252C794900E60C44 /* MemberEndpoints.swift in Sources */, DA640FC12535CFA100D32944 /* ChannelMemberListSortingKey.swift in Sources */, - 7900452625374CA20096ECA1 /* User+SwiftUI.swift in Sources */, 82C18FDC2C10C8E600C5283C /* BlockedUserPayload.swift in Sources */, 404296DA2A0112D00089126D /* AudioQueuePlayer.swift in Sources */, 4F51519C2BC66FBE001B7152 /* Task+Extensions.swift in Sources */, @@ -12940,7 +12935,6 @@ C121E896274544B000023E4C /* UnreadCount.swift in Sources */, ADFCA5B42D121EB8000F515F /* LocationInfo.swift in Sources */, 842F9746277A09B10060A489 /* PinnedMessagesQuery.swift in Sources */, - C121E897274544B000023E4C /* User+SwiftUI.swift in Sources */, C121E898274544B000023E4C /* MessageReaction.swift in Sources */, C121E899274544B000023E4C /* MessageReactionType.swift in Sources */, 84B7383E2BE8C13A00EC66EC /* PollController+SwiftUI.swift in Sources */,