Skip to content

Commit c72c0cd

Browse files
committed
Add Write Form Feature
1 parent bbc7db3 commit c72c0cd

29 files changed

+2066
-79
lines changed

ForPDA.xcodeproj/project.pbxproj

Lines changed: 429 additions & 72 deletions
Large diffs are not rendered by default.

Modules/Sources/APIClient/APIClient.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ public struct APIClient: Sendable {
4747
public var markReadForum: @Sendable (_ id: Int, _ isTopic: Bool) async throws -> Bool
4848
public var getAnnouncement: @Sendable (_ id: Int) async throws -> Announcement
4949
public var getTopic: @Sendable (_ id: Int, _ page: Int, _ perPage: Int) async throws -> Topic
50+
public var getTemplate: @Sendable (_ request: ForumTemplateRequest, _ isTopic: Bool) async throws -> [WriteFormFieldType]
5051
public var getHistory: @Sendable (_ offset: Int, _ perPage: Int) async throws -> History
52+
public var previewPost: @Sendable (_ request: PostPreviewRequest) async throws -> PostPreview
53+
public var sendPost: @Sendable (_ request: PostRequest) async throws -> PostSend
5154

5255
// Favorites
5356
public var getFavorites: @Sendable (_ request: FavoritesRequest, _ policy: CachePolicy) async throws -> AsyncThrowingStream<Favorite, any Error>
@@ -224,11 +227,39 @@ extension APIClient: DependencyKey {
224227
let request = TopicRequest(id: id, offset: offset, itemsPerPage: perPage, showPostMode: 1)
225228
let response = try await api.get(ForumCommand.Topic.view(data: request))
226229
return try await parser.parseTopic(response)
230+
},
231+
getTemplate: { request, isTopic in
232+
let command = ForumCommand.template(
233+
type: isTopic ? .topic(forumId: request.id) : .post(topicId: request.id),
234+
action: request.action.transferType
235+
)
236+
let response = try await api.get(command)
237+
return try await parser.parseWriteForm(response)
227238
},
228239
getHistory: { offset, perPage in
229240
let response = try await api.get(MemberCommand.history(page: offset, perPage: perPage))
230241
return try await parser.parseHistory(response)
231242
},
243+
previewPost: { request in
244+
let command = ForumCommand.Post.preview(data: PostSendRequest(
245+
topicId: request.post.topicId,
246+
content: request.post.content,
247+
attaches: request.post.attachments,
248+
flag: request.post.flag
249+
), postId: request.id)
250+
let response = try await api.get(command)
251+
return try await parser.parsePostPreview(response)
252+
},
253+
sendPost: { request in
254+
let command = ForumCommand.Post.send(data: PostSendRequest(
255+
topicId: request.topicId,
256+
content: request.content,
257+
attaches: request.attachments,
258+
flag: request.flag
259+
))
260+
let response = try await api.get(command)
261+
return try await parser.parsePostSend(response)
262+
},
232263

233264
// MARK: - Favorites
234265

@@ -368,10 +399,19 @@ extension APIClient: DependencyKey {
368399
},
369400
getTopic: { _, _, _ in
370401
return .mock
402+
},
403+
getTemplate: { _, _ in
404+
return [.mockTitle, .mockText, .mockEditor]
371405
},
372406
getHistory: { _, _ in
373407
return .mock
374408
},
409+
previewPost: { _ in
410+
return PostPreview(content: "Post Content...", attachmentIds: [])
411+
},
412+
sendPost: { _ in
413+
return PostSend(id: 0, topicId: 1, offset: 2)
414+
},
375415
getFavorites: { _, _ in
376416
.finished()
377417
},
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// ForumTemplateRequest.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 15.03.25.
6+
//
7+
8+
import PDAPI
9+
10+
public struct ForumTemplateRequest {
11+
public let id: Int
12+
public let action: TemplateAction
13+
14+
public enum TemplateAction {
15+
case get
16+
case send([Any])
17+
case preview([Any])
18+
}
19+
20+
public init(id: Int, action: TemplateAction) {
21+
self.id = id
22+
self.action = action
23+
}
24+
}
25+
26+
extension ForumTemplateRequest.TemplateAction {
27+
var transferType: ForumCommand.TemplateAction {
28+
switch self {
29+
case .get: return .get
30+
case .preview(let data): return .preview(data)
31+
case .send(let data): return .send(data)
32+
}
33+
}
34+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// PostPreviewRequest.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 15.03.25.
6+
//
7+
8+
import PDAPI
9+
10+
public struct PostPreviewRequest: Sendable {
11+
public let id: Int
12+
public let post: PostRequest
13+
14+
public init(
15+
id: Int,
16+
post: PostRequest
17+
) {
18+
self.id = id
19+
self.post = post
20+
}
21+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// PostRequest.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 18.03.25.
6+
//
7+
8+
public struct PostRequest: Sendable {
9+
public let topicId: Int
10+
public let content: String
11+
public let flag: Int
12+
public let attachments: [Int]
13+
14+
public init(
15+
topicId: Int,
16+
content: String,
17+
flag: Int,
18+
attachments: [Int]
19+
) {
20+
self.topicId = topicId
21+
self.content = content
22+
self.flag = flag
23+
self.attachments = attachments
24+
}
25+
}

Modules/Sources/AnalyticsClient/Events/TopicEvent.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public enum TopicEvent: Event {
1616
case menuOpenInBrowser
1717
case menuGoToEnd
1818
case menuSetFavorite
19+
case menuWritePost
20+
21+
case menuPostReply(Int)
1922

2023
case loadingStart(Int)
2124
case loadingSuccess
@@ -28,7 +31,8 @@ public enum TopicEvent: Event {
2831

2932
public var properties: [String: String]? {
3033
switch self {
31-
case let .userAvatarTapped(id):
34+
case let .userAvatarTapped(id),
35+
let .menuPostReply(id):
3236
return ["userId": String(id)]
3337

3438
case let .urlTapped(url):
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// WriteFormFieldType.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 14.03.25.
6+
//
7+
8+
public enum WriteFormFieldType: Sendable, Equatable, Hashable {
9+
case title(String)
10+
case text(FormField)
11+
case editor(FormField)
12+
case dropdown(FormField, _ options: [String])
13+
case uploadbox(FormField, _ extens: [String])
14+
case checkboxList(FormField, _ options: [String])
15+
16+
public struct FormField: Sendable, Equatable, Hashable {
17+
public let name: String
18+
public let description: String
19+
public let example: String
20+
public let flag: Int
21+
public let defaultValue: String
22+
23+
public var isRequired: Bool {
24+
return flag & 1 != 0
25+
}
26+
27+
public var isVisible: Bool {
28+
return flag & 2 != 0
29+
}
30+
31+
public init(
32+
name: String,
33+
description: String,
34+
example: String,
35+
flag: Int,
36+
defaultValue: String
37+
) {
38+
self.name = name
39+
self.description = description
40+
self.example = example
41+
self.flag = flag
42+
self.defaultValue = defaultValue
43+
}
44+
}
45+
}
46+
47+
public extension WriteFormFieldType {
48+
static let mockTitle: WriteFormFieldType =
49+
.title("[b]This is absolute simple title[/b]")
50+
51+
static let mockText: WriteFormFieldType = .text(
52+
FormField(
53+
name: "Topic name",
54+
description: "Enter topic name.",
55+
example: "Starting from For, ends with PDA",
56+
flag: 1,
57+
defaultValue: ""
58+
)
59+
)
60+
61+
static let mockEditor: WriteFormFieldType = .editor(
62+
FormField(
63+
name: "Topic content",
64+
description: "This field contains topic [color=red]hat[/color] content.",
65+
example: "ForPDA Forever!",
66+
flag: 1,
67+
defaultValue: ""
68+
)
69+
)
70+
71+
static let mockEditorSimple: WriteFormFieldType = .editor(
72+
FormField(
73+
name: "",
74+
description: "",
75+
example: "Post text...",
76+
flag: 0,
77+
defaultValue: ""
78+
)
79+
)
80+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// WriteFormForType.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 14.03.25.
6+
//
7+
8+
import Foundation
9+
10+
public enum WriteFormForType: Sendable, Equatable {
11+
case topic(forumId: Int, content: [String])
12+
case post(topicId: Int, content: PostContentType)
13+
case report(id: Int, content: String, type: ReportType)
14+
15+
public enum PostContentType: Sendable, Equatable {
16+
case template([String])
17+
case simple(String, [Int])
18+
}
19+
20+
public enum ReportType: Sendable, Equatable {
21+
case post
22+
case comment
23+
case reputation
24+
}
25+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//
2+
// WriteFormSend.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 18.03.25.
6+
//
7+
8+
public enum WriteFormSend: Sendable {
9+
case post(PostSend)
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// PostPreview.swift
3+
// ForPDA
4+
//
5+
// Created by Xialtal on 15.03.25.
6+
//
7+
8+
public struct PostPreview: Sendable {
9+
public let content: String
10+
public let attachmentIds: [Int]
11+
12+
public init(
13+
content: String,
14+
attachmentIds: [Int]
15+
) {
16+
self.content = content
17+
self.attachmentIds = attachmentIds
18+
}
19+
}

0 commit comments

Comments
 (0)