|
"source": "import Foundation\n\npublic extension NotificationFeed {\n public struct MappedNotificationItem: Hashable, Sendable {\n public let rantId: Rant.ID\n public let commentId: Comment.ID?\n public let userId: Int\n public let userAvatar: User.Avatar\n public let userName: String\n public let notificationKind: Notification.Kind\n public let created: Date\n public let isRead: Bool\n \n public init(rantId: Rant.ID, commentId: Comment.ID?, userId: Int, userAvatar: User.Avatar, userName: String, notificationKind: Notification.Kind, created: Date, isRead: Bool) {\n self.rantId = rantId\n self.commentId = commentId\n self.userId = userId\n self.userAvatar = userAvatar\n self.userName = userName\n self.notificationKind = notificationKind\n self.created = created\n self.isRead = isRead\n }\n }\n \n public var mappedItems: [MappedNotificationItem] {\n notifications.map { notification in\n let rantId = notification.rantId\n let commentId = notification.commentId\n let userId = notification.userId\n let userInfo = userInfos.first { $0.userId == userId }\n let userAvatar = userInfo?.avatar ?? .init(colorHex: \"cccccc\", imageUrlPath: nil)\n let userName = userInfo?.username ?? \"\"\n \n return MappedNotificationItem(\n rantId: rantId,\n commentId: commentId,\n userId: userId,\n userAvatar: userAvatar,\n userName: userName,\n notificationKind: notification.kind,\n created: notification.created,\n isRead: notification.read\n )\n }\n }\n \n public var unreadByCategory: [NotificationFeed.Category: Int] {\n [\n .all: unreadNumbers.all,\n .upvotes: unreadNumbers.upvotes,\n .mentions: unreadNumbers.mentions,\n .comments: unreadNumbers.comments,\n .subscriptions: unreadNumbers.subscriptions,\n ]\n }\n}\n",
|
|
"review": "8\n\n### Bugs\n- `public` keyword is redundant in the extension as `NotificationFeed` is already marked `public`, making its contents inherently public.\n\n### Optimizations\n- Consider caching `userInfos.first { $0.userId == userId }` if this operation is performed frequently, to minimize searching through the userInfos array repeatedly.\n- Consider using guard or if-let statements to handle optional values more safely and improve code readability.\n\n### Good points\n- The code makes good use of Swift's strong typing with specific types for each property.\n- Use of collections like arrays and dictionaries is appropriate and idiomatic.\n- Adopting `Hashable` and `Sendable` protocols for the `MappedNotificationItem` adds future-proofing, considering Swift concurrency.\n\n### Summary\nThe provided Swift code is clean and follows Swift's best practices in handling data mapping and optional unwrapping fairly well. The encapsulation through extensions and struct initializers is well handled. However, some redundant `public` access specifiers could be removed for conciseness, and a bit more optimization in handling optional values could improve readability and efficiency.\n\n### Open source alternatives\n- [Rocket.Chat](https://github.com/RocketChat/Rocket.Chat) provides a framework for managing notifications.\n- [OneSignal](https://github.com/OneSignal/OneSignal-iOS-SDK) offers implementation options for handling notification feeds with diverse functionalities.",
|