Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Modules/Sources/APIClient/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,12 @@ public struct APIClient: Sendable {
// Forum
public var getForumsList: @Sendable (_ policy: CachePolicy) async throws -> AsyncThrowingStream<[ForumInfo], any Error>
public var getForum: @Sendable (_ id: Int, _ page: Int, _ perPage: Int, _ policy: CachePolicy) async throws -> AsyncThrowingStream<Forum, any Error>
public var getForumStat: @Sendable (_ id: Int) async throws -> ForumStat
public var jumpForum: @Sendable (_ request: JumpForumRequest) async throws -> ForumJump
public var markRead: @Sendable (_ id: Int, _ isTopic: Bool) async throws -> Bool
public var getAnnouncement: @Sendable (_ id: Int) async throws -> Announcement
public var getTopic: @Sendable (_ id: Int, _ page: Int, _ perPage: Int, _ postsFilter: TopicPostsFilter) async throws -> Topic
public var getTopicViewers: @Sendable (_ id: Int) async throws -> TopicViewers
public var getTemplate: @Sendable (_ request: ForumTemplateRequest, _ isTopic: Bool) async throws -> [FormFieldType]
public var sendTemplate: @Sendable (_ id: Int, _ content: PDAPIDocument, _ isTopic: Bool) async throws -> TemplateSend
public var getHistory: @Sendable (_ offset: Int, _ perPage: Int) async throws -> History
Expand Down Expand Up @@ -306,6 +308,12 @@ extension APIClient: DependencyKey {
)
},

getForumStat: { id in
let command = ForumCommand.info(id: id)
let response = try await api.send(command)
return try await parser.parseForumStat(response)
},

jumpForum: { request in
let command = ForumCommand.jump(data: ForumJumpRequest(
type: request.transferType,
Expand Down Expand Up @@ -339,6 +347,14 @@ extension APIClient: DependencyKey {
let response = try await api.send(ForumCommand.Topic.view(data: request))
return try await parser.parseTopic(response)
},
getTopicViewers: { topicId in
let command = MemberCommand.sessions(
pageType: .topic,
pageId: topicId
)
let response = try await api.send(command)
return try await parser.parseTopicViewers(response)
},

getTemplate: { request, isTopic in
let command = ForumCommand.template(
Expand Down Expand Up @@ -627,6 +643,9 @@ extension APIClient: DependencyKey {
getForum: { _, _, _, _ in
return .finished()
},
getForumStat: { _ in
return .mock
},
jumpForum: { _ in
return .mock
},
Expand All @@ -639,6 +658,9 @@ extension APIClient: DependencyKey {
getTopic: { _, _, _, _ in
return .mock
},
getTopicViewers: { _ in
return .mock
},
getTemplate: { _, _ in
return [.mockTitle, .mockRequiredText, .mockRequiredEditor, .mockEditor, .mockUploadBox]
},
Expand Down
4 changes: 4 additions & 0 deletions Modules/Sources/AnalyticsClient/Events/ForumEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public enum ForumEvent: Event {
case menuOpen(Int)
case menuGoToEnd(Int)

case menuStat(Int, Bool)
case menuMarkRead(Int, Bool)
case menuCopyLink(Int, Bool)
case menuOpenInBrowser(Int, Bool)
Expand Down Expand Up @@ -59,6 +60,9 @@ public enum ForumEvent: Event {
case let .menuGoToEnd(id):
return ["id": String(id)]

case let .menuStat(id, isForum):
return ["id": String(id), "isForum": String(isForum)]

case let .menuMarkRead(id, isForum):
return ["id": String(id), "isForum": String(isForum)]

Expand Down
1 change: 1 addition & 0 deletions Modules/Sources/AnalyticsClient/Events/TopicEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum TopicEvent: Event {
case menuOpenInBrowser
case menuGoToEnd
case menuSetFavorite
case menuAboutTopic
case menuWritePost
case menuWritePostWithTemplate

Expand Down
3 changes: 3 additions & 0 deletions Modules/Sources/AppFeature/Navigation/StackTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ public struct StackTab: Reducer, Sendable {
case let .forum(.delegate(.openSearch(on, navigation))):
state.path.append(.search(.search(SearchFeature.State(on: on, navigation: navigation))))

case let .forum(.delegate(.openUser(id))):
state.path.append(.profile(.profile(ProfileFeature.State(userId: id))))

case let .forum(.delegate(.handleRedirect(url))):
return handleDeeplink(url: url, state: &state)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ extension ForumFeature {

case let .view(.contextCommonMenu(option, id, isForum)):
switch option {
case .stat:
analytics.log(ForumEvent.menuStat(id, isForum))
case .markRead:
analytics.log(ForumEvent.menuMarkRead(id, isForum))
case .copyLink:
Expand Down
16 changes: 13 additions & 3 deletions Modules/Sources/ForumFeature/ForumFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ import PersistenceKeys
import TCAExtensions
import ToastClient
import FormFeature
import ForumStatFeature

@Reducer
public struct ForumFeature: Reducer, Sendable {

public init() {}

// MARK: - Localizations
// MARK: - Localizations

public enum Localization {
static let linkCopied = LocalizedStringResource("Link copied", bundle: .module)
static let markAsReadSuccess = LocalizedStringResource("Marked as read", bundle: .module)
}

// MARK: - Enums

public struct SectionExpand: Equatable {
Expand All @@ -55,6 +56,7 @@ public struct ForumFeature: Reducer, Sendable {
@Reducer
public enum Destination {
case form(FormFeature)
case stat(ForumStatFeature)
}

// MARK: - State
Expand Down Expand Up @@ -120,7 +122,7 @@ public struct ForumFeature: Reducer, Sendable {
case contextTopicMenu(ForumTopicContextMenuAction, TopicInfo)
case contextCommonMenu(ForumCommonContextMenuAction, Int, Bool)
}

case `internal`(Internal)
public enum Internal {
case refresh
Expand All @@ -130,6 +132,7 @@ public struct ForumFeature: Reducer, Sendable {

case delegate(Delegate)
public enum Delegate {
case openUser(id: Int)
case openTopic(id: Int, name: String, goTo: GoTo)
case openForum(id: Int, name: String)
case openAnnouncement(id: Int, name: String)
Expand Down Expand Up @@ -161,6 +164,9 @@ public struct ForumFeature: Reducer, Sendable {
case let .destination(.presented(.form(.delegate(.formSent(.topic(id)))))):
return .send(.delegate(.openTopic(id: id, name: "", goTo: .first)))

case let .destination(.presented(.stat(.delegate(.userTapped(id))))):
return .send(.delegate(.openUser(id: id)))

case .destination, .pageNavigation:
return .none

Expand Down Expand Up @@ -260,6 +266,10 @@ public struct ForumFeature: Reducer, Sendable {
await send(.internal(.refresh))
}

case .stat:
state.destination = .stat(ForumStatFeature.State(type: .forum(id: state.forumId)))
return .none

case .setFavorite(let isFavorite):
return .run { [id = id, isFavorite = isFavorite, isForum = isForum] send in
let request = SetFavoriteRequest(
Expand Down
26 changes: 19 additions & 7 deletions Modules/Sources/ForumFeature/ForumScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SharedUI
import Models
import BBBuilder
import FormFeature
import ForumStatFeature

@ViewAction(for: ForumFeature.self)
public struct ForumScreen: View {
Expand Down Expand Up @@ -96,6 +97,11 @@ public struct ForumScreen: View {
.padding(.bottom, 8)
}
}
.sheet(item: $store.scope(state: \.destination?.stat, action: \.destination.stat)) { store in
NavigationStack {
ForumStatView(store: store)
}
}
.toolbar {
ToolbarItem {
Button {
Expand Down Expand Up @@ -323,14 +329,14 @@ public struct ForumScreen: View {
send(.contextCommonMenu(.openInBrowser, id, isForum))
}

if store.isUserAuthorized {
if isUnread {
ContextButton(text: LocalizedStringResource("Mark Read", bundle: .module), symbol: .checkmarkCircle) {
send(.contextCommonMenu(.markRead, id, isForum))
}
if store.isUserAuthorized, isUnread {
ContextButton(text: LocalizedStringResource("Mark Read", bundle: .module), symbol: .checkmarkCircle) {
send(.contextCommonMenu(.markRead, id, isForum))
}

Section {
}

Section {
if store.isUserAuthorized {
ContextButton(
text: isFavorite
? LocalizedStringResource("Remove from favorites", bundle: .module)
Expand All @@ -340,6 +346,12 @@ public struct ForumScreen: View {
send(.contextCommonMenu(.setFavorite(isFavorite), id, isForum))
}
}

if isForum {
ContextButton(text: LocalizedStringResource("About Forum", bundle: .module), symbol: .infoCircle) {
send(.contextCommonMenu(.stat, id, isForum))
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

public enum ForumCommonContextMenuAction {
case stat
case markRead
case copyLink
case openInBrowser
Expand Down
10 changes: 10 additions & 0 deletions Modules/Sources/ForumFeature/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
{
"sourceLanguage" : "en",
"strings" : {
"About Forum" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "О форуме"
}
}
}
},
"Add to favorites" : {
"localizations" : {
"ru" : {
Expand Down
Loading
Loading