Skip to content

Commit 5af018c

Browse files
committed
Merge remote-tracking branch 'origin/develop' into feature/image-gallery
# Conflicts: # ForPDA.xcodeproj/project.pbxproj
2 parents 308616a + bbc7db3 commit 5af018c

File tree

61 files changed

+2426
-513
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2426
-513
lines changed

.github/workflows/main.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Github Telegram Notifier
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
- "develop"
8+
pull_request:
9+
create:
10+
delete:
11+
issues:
12+
issue_comment:
13+
pull_request_review:
14+
pull_request_review_comment:
15+
fork:
16+
watch:
17+
release:
18+
19+
jobs:
20+
notify:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Send Telegram Notification
24+
uses: EverythingSuckz/[email protected]
25+
with:
26+
bot_token: ${{ secrets.TG_BOT_TOKEN }}
27+
chat_id: ${{ secrets.TG_CHAT_ID }}

Configs/App.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#include "Secrets.xcconfig"
22
MARKETING_VERSION = 0.8.0
3-
CURRENT_PROJECT_VERSION = 629
3+
CURRENT_PROJECT_VERSION = 663

ForPDA.xcodeproj/project.pbxproj

Lines changed: 719 additions & 48 deletions
Large diffs are not rendered by default.

Gemfile.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ GEM
99
public_suffix (>= 2.0.2, < 7.0)
1010
artifactory (3.0.17)
1111
atomos (0.1.3)
12-
aws-eventstream (1.3.1)
13-
aws-partitions (1.1054.0)
14-
aws-sdk-core (3.219.0)
12+
aws-eventstream (1.3.2)
13+
aws-partitions (1.1070.0)
14+
aws-sdk-core (3.220.1)
1515
aws-eventstream (~> 1, >= 1.3.0)
1616
aws-partitions (~> 1, >= 1.992.0)
1717
aws-sigv4 (~> 1.9)
@@ -69,7 +69,7 @@ GEM
6969
faraday_middleware (1.2.1)
7070
faraday (~> 1.0)
7171
fastimage (2.4.0)
72-
fastlane (2.226.0)
72+
fastlane (2.227.0)
7373
CFPropertyList (>= 2.3, < 4.0.0)
7474
addressable (>= 2.8, < 3.0.0)
7575
artifactory (~> 3.0)
@@ -111,7 +111,7 @@ GEM
111111
xcodeproj (>= 1.13.0, < 2.0.0)
112112
xcpretty (~> 0.4.0)
113113
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
114-
fastlane-plugin-sentry (1.28.0)
114+
fastlane-plugin-sentry (1.28.1)
115115
os (~> 1.1, >= 1.1.4)
116116
fastlane-plugin-telegram (0.1.4)
117117
fastlane-plugin-xcconfig (2.1.0)
@@ -134,12 +134,12 @@ GEM
134134
google-apis-core (>= 0.11.0, < 2.a)
135135
google-apis-storage_v1 (0.31.0)
136136
google-apis-core (>= 0.11.0, < 2.a)
137-
google-cloud-core (1.7.1)
137+
google-cloud-core (1.8.0)
138138
google-cloud-env (>= 1.0, < 3.a)
139139
google-cloud-errors (~> 1.0)
140140
google-cloud-env (1.6.0)
141141
faraday (>= 0.17.3, < 3.0)
142-
google-cloud-errors (1.4.0)
142+
google-cloud-errors (1.5.0)
143143
google-cloud-storage (1.47.0)
144144
addressable (~> 2.8)
145145
digest-crc (~> 0.4)
@@ -160,7 +160,7 @@ GEM
160160
httpclient (2.9.0)
161161
mutex_m
162162
jmespath (1.6.2)
163-
json (2.10.1)
163+
json (2.10.2)
164164
jwt (2.10.1)
165165
base64
166166
mini_magick (4.13.2)

Modules/Sources/APIClient/APIClient.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public struct APIClient: Sendable {
5050
public var getHistory: @Sendable (_ offset: Int, _ perPage: Int) async throws -> History
5151

5252
// Favorites
53-
public var getFavorites: @Sendable (_ request: FavoritesRequest, _ policy: CachePolicy) async throws -> AsyncThrowingStream<[FavoriteInfo], any Error>
53+
public var getFavorites: @Sendable (_ request: FavoritesRequest, _ policy: CachePolicy) async throws -> AsyncThrowingStream<Favorite, any Error>
5454
public var setFavorite: @Sendable (_ request: SetFavoriteRequest) async throws -> Bool
5555
public var notifyFavorite: @Sendable (_ request: NotifyFavoriteRequest) async throws -> Bool
5656
public var readAllFavorites: @Sendable () async throws -> Bool
@@ -244,8 +244,8 @@ extension APIClient: DependencyKey {
244244
)
245245
let response = try await api.get(command)
246246
let favorites = try await parser.parseFavorites(response)
247-
await cache.setFavorites(favorites.favorites)
248-
return favorites.favorites
247+
await cache.setFavorites(favorites)
248+
return favorites
249249
},
250250
policy: policy
251251
)

Modules/Sources/AnalyticsClient/AnalyticsClient.swift

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public struct AnalyticsClient: Sendable {
2323
public var logout: @Sendable () -> Void
2424
public var log: @Sendable (any Event) -> Void
2525
public var capture: @Sendable (any Error) -> Void
26+
public var reportFullyDisplayed: @Sendable () -> Void
2627
}
2728

2829
// MARK: - Dependency Keys
@@ -63,6 +64,10 @@ extension AnalyticsClient: DependencyKey {
6364
capture: { error in
6465
logger.error("Captured error via Sentry: \(error)")
6566
SentrySDK.capture(error: error)
67+
},
68+
reportFullyDisplayed: {
69+
logger.info("Did report fully displayed")
70+
SentrySDK.reportFullyDisplayed()
6671
}
6772
)
6873
}
@@ -80,15 +85,17 @@ extension AnalyticsClient: DependencyKey {
8085
},
8186
capture: { error in
8287
print("[Sentry] \(error)")
83-
}
88+
},
89+
reportFullyDisplayed: { }
8490
)
8591

8692
public static let testValue = Self(
8793
configure: { _ in },
8894
identify: { _ in },
8995
logout: { },
9096
log: { _ in },
91-
capture: { _ in }
97+
capture: { _ in },
98+
reportFullyDisplayed: { }
9299
)
93100
}
94101

@@ -112,7 +119,7 @@ extension AnalyticsClient {
112119

113120
private static func configureAnalytics(id: String, isEnabled: Bool, isDebugEnabled: Bool) {
114121
let config = PostHogConfig(apiKey: Secrets.get(.POSTHOG_TOKEN), host: "https://eu.i.posthog.com")
115-
config.debug = true
122+
config.debug = isDebugEnabled
116123
config.getAnonymousId = { _ in UUID(uuidString: id) ?? UUID.v7() }
117124
config.optOut = !isEnabled
118125
config.captureScreenViews = false // Track manually
@@ -151,12 +158,21 @@ extension AnalyticsClient {
151158
options.dsn = Secrets.get(.SENTRY_DSN)
152159
options.debug = isDebugEnabled
153160
options.enabled = isEnabled
161+
options.enableAppLaunchProfiling = true
162+
options.enableMetricKit = true
163+
options.enableAppHangTrackingV2 = true
164+
options.enableReportNonFullyBlockingAppHangs = false // False positives
165+
options.enablePerformanceV2 = true
166+
options.enablePreWarmedAppStartTracing = true
167+
options.enableCoreDataTracing = false // I don't have CoreData
168+
options.enableUserInteractionTracing = false // Doesn't work with SwiftUI
169+
options.enableUIViewControllerTracing = false // I don't have UIViewControllers
170+
options.enableTimeToFullDisplayTracing = true
171+
options.tracePropagationTargets = ["4pda"] // Dismiss analytics requests
172+
options.swiftAsyncStacktraces = true
173+
options.attachScreenshot = true
154174
options.tracesSampleRate = 1.0
155-
options.profilesSampleRate = 1.0
156175
options.diagnosticLevel = .warning
157-
options.attachScreenshot = true
158-
options.attachViewHierarchy = true
159-
options.swiftAsyncStacktraces = true
160176
}
161177
SentrySDK.setUser(User(userId: id))
162178

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// FavoritesEvent.swift
3+
// AnalyticsClient
4+
//
5+
// Created by Ilia Lubianoi on 20.03.2025.
6+
//
7+
8+
import Foundation
9+
10+
public enum FavoritesEvent: Event {
11+
case onRefresh
12+
case onSceneBecomeActive
13+
case favoriteTapped(Int, String, Int?, Bool)
14+
case unreadTapped(Int)
15+
16+
case sortButtonTapped
17+
case readAllButtonTapped
18+
19+
case setImportant(Int, Bool)
20+
case linkCopied(Int, Bool)
21+
case delete(Int)
22+
23+
case goToEnd(Int)
24+
case notify(Int, Int, String)
25+
case notifyHatUpdate(Int)
26+
27+
case sortDismissed
28+
case sortSaveButtonTapped
29+
case sortCancelButtonTapped
30+
case sortTypeSelected(String)
31+
32+
case loadingStart(Int)
33+
case loadingSuccess
34+
case loadingFailure(any Error)
35+
case startUnreadLoadingIndicator(Int)
36+
case jumpRequestFailed
37+
38+
public var name: String {
39+
return "Favorites " + eventName(for: self).inProperCase
40+
}
41+
42+
public var properties: [String: String]? {
43+
switch self {
44+
case let .favoriteTapped(id, name, postId, isForum):
45+
return [
46+
"id": String(id),
47+
"name": name,
48+
"postId": postId.map { String($0) } ?? "nil",
49+
"isForum": isForum.description
50+
]
51+
52+
case let .unreadTapped(id):
53+
return ["id": String(id)]
54+
55+
case let .setImportant(id, isForum):
56+
return ["id": String(id), "isForum": isForum.description]
57+
58+
case let .linkCopied(id, isForum):
59+
return ["id": String(id), "isForum": isForum.description]
60+
61+
case let .delete(id):
62+
return ["id": String(id)]
63+
64+
case let .goToEnd(id):
65+
return ["id": String(id)]
66+
67+
case let .notify(id, flag, type):
68+
return ["id": String(id), "flag": String(flag), "type": type]
69+
70+
case let .notifyHatUpdate(id):
71+
return ["id": String(id)]
72+
73+
case let .sortTypeSelected(type):
74+
return ["type": type]
75+
76+
case let .loadingStart(offset):
77+
return ["offset": String(offset)]
78+
79+
case let .loadingFailure(error):
80+
return ["error": error.localizedDescription]
81+
82+
case let .startUnreadLoadingIndicator(id):
83+
return ["id": String(id)]
84+
85+
default:
86+
return nil
87+
}
88+
}
89+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// FavoritesRootEvent.swift
3+
// AnalyticsClient
4+
//
5+
// Created by Ilia Lubianoi on 20.03.2025.
6+
//
7+
8+
import Foundation
9+
10+
public enum FavoritesRootEvent: Event {
11+
case settingsButtonTapped
12+
case tabChanged(Int)
13+
14+
public var name: String {
15+
return "Favorites Root " + eventName(for: self).inProperCase
16+
}
17+
18+
public var properties: [String: String]? {
19+
switch self {
20+
case let .tabChanged(tab):
21+
return ["tab": String(tab)]
22+
default:
23+
return nil
24+
}
25+
}
26+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//
2+
// ForumEvent.swift
3+
// AnalyticsClient
4+
//
5+
// Created by Ilia Lubianoi on 20.03.2025.
6+
//
7+
8+
import Foundation
9+
10+
public enum ForumEvent: Event {
11+
case onRefresh
12+
case settingsButtonTapped
13+
case topicTapped(Int, Int)
14+
case subforumRedirectTapped(URL)
15+
case subforumTapped(Int, String)
16+
case announcementTapped(Int, String)
17+
18+
// case menuSort
19+
// case menuBookmarks
20+
21+
case menuOpen(Int)
22+
case menuGoToEnd(Int)
23+
24+
case menuMarkRead(Int, Bool)
25+
case menuCopyLink(Int, Bool)
26+
case menuOpenInBrowser(Int, Bool)
27+
case menuSetFavorite(Int, Bool, Bool)
28+
29+
case loadingStart(Int)
30+
case loadingSuccess
31+
case loadingFailure(any Error)
32+
33+
public var name: String {
34+
return "Forum " + eventName(for: self).inProperCase
35+
}
36+
37+
public var properties: [String: String]? {
38+
switch self {
39+
case let .topicTapped(id, offset):
40+
return ["id": String(id), "offset": String(offset)]
41+
42+
case let .subforumRedirectTapped(url):
43+
return ["url": url.absoluteString]
44+
45+
case let .subforumTapped(id, name):
46+
return ["id": String(id), "name": name]
47+
48+
case let .announcementTapped(id, name):
49+
return ["id": String(id), "name": name]
50+
51+
case let .menuOpen(id):
52+
return ["id": String(id)]
53+
54+
case let .menuGoToEnd(id):
55+
return ["id": String(id)]
56+
57+
case let .menuMarkRead(id, isForum):
58+
return ["id": String(id), "isForum": String(isForum)]
59+
60+
case let .menuCopyLink(id, isForum):
61+
return ["id": String(id), "isForum": String(isForum)]
62+
63+
case let .menuOpenInBrowser(id, isForum):
64+
return ["id": String(id), "isForum": String(isForum)]
65+
66+
case let .menuSetFavorite(id, isForum, state):
67+
return ["id": String(id), "isForum": String(isForum), "state": state.description]
68+
69+
case let .loadingStart(offset):
70+
return ["offset": String(offset)]
71+
72+
case let .loadingFailure(error):
73+
return ["error": error.localizedDescription]
74+
75+
default:
76+
return nil
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)