From bf20181a323f8551f4e14739f8a2c9619c89033a Mon Sep 17 00:00:00 2001 From: Xialtal Date: Sun, 23 Feb 2025 13:56:31 +0300 Subject: [PATCH 1/4] Add auth check for context menu features --- .../FavoritesFeature/FavoritesFeature.swift | 5 +++ .../FavoritesFeature/FavoritesScreen.swift | 36 ++++++++++--------- .../Sources/ForumFeature/ForumFeature.swift | 5 +++ .../Sources/ForumFeature/ForumScreen.swift | 26 +++++++------- .../Sources/TopicFeature/TopicFeature.swift | 5 +++ .../Sources/TopicFeature/TopicScreen.swift | 2 +- 6 files changed, 49 insertions(+), 30 deletions(-) diff --git a/Modules/Sources/FavoritesFeature/FavoritesFeature.swift b/Modules/Sources/FavoritesFeature/FavoritesFeature.swift index 9654773a..c3aba0f3 100644 --- a/Modules/Sources/FavoritesFeature/FavoritesFeature.swift +++ b/Modules/Sources/FavoritesFeature/FavoritesFeature.swift @@ -24,6 +24,7 @@ public struct FavoritesFeature: Reducer, Sendable { @ObservableState public struct State: Equatable { @Shared(.appSettings) var appSettings: AppSettings + @Shared(.userSession) var userSession: UserSession? @Presents var sort: SortFeature.State? public var favorites: [FavoriteInfo] = [] @@ -35,6 +36,10 @@ public struct FavoritesFeature: Reducer, Sendable { public var pageNavigation = PageNavigationFeature.State(type: .forum) + public var isUserAuthorized: Bool { + return userSession != nil + } + public init( favorites: [FavoriteInfo] = [], favoritesImportant: [FavoriteInfo] = [] diff --git a/Modules/Sources/FavoritesFeature/FavoritesScreen.swift b/Modules/Sources/FavoritesFeature/FavoritesScreen.swift index a5b25273..c0bc7dd4 100644 --- a/Modules/Sources/FavoritesFeature/FavoritesScreen.swift +++ b/Modules/Sources/FavoritesFeature/FavoritesScreen.swift @@ -52,24 +52,26 @@ public struct FavoritesScreen: View { .toolbar { ToolbarItem(placement: .topBarTrailing) { HStack { - Menu { - ContextButton( - text: "Sort", - symbol: .line3HorizontalDecrease, - bundle: .module - ) { - store.send(.contextOptionMenu(.sort)) - } - - ContextButton( - text: "Read All", - symbol: .checkmarkCircle, - bundle: .module - ) { - store.send(.contextOptionMenu(.markAllAsRead)) + if store.isUserAuthorized { + Menu { + ContextButton( + text: "Sort", + symbol: .line3HorizontalDecrease, + bundle: .module + ) { + store.send(.contextOptionMenu(.sort)) + } + + ContextButton( + text: "Read All", + symbol: .checkmarkCircle, + bundle: .module + ) { + store.send(.contextOptionMenu(.markAllAsRead)) + } + } label: { + Image(systemSymbol: .ellipsisCircle) } - } label: { - Image(systemSymbol: .ellipsisCircle) } Button { diff --git a/Modules/Sources/ForumFeature/ForumFeature.swift b/Modules/Sources/ForumFeature/ForumFeature.swift index b7d7060a..9ce49dd0 100644 --- a/Modules/Sources/ForumFeature/ForumFeature.swift +++ b/Modules/Sources/ForumFeature/ForumFeature.swift @@ -24,6 +24,7 @@ public struct ForumFeature: Reducer, Sendable { @ObservableState public struct State: Equatable { @Shared(.appSettings) var appSettings: AppSettings + @Shared(.userSession) var userSession: UserSession? public var forumId: Int public var forumName: String? @@ -37,6 +38,10 @@ public struct ForumFeature: Reducer, Sendable { public var pageNavigation = PageNavigationFeature.State(type: .forum) + public var isUserAuthorized: Bool { + return userSession != nil + } + public init( forumId: Int, forumName: String? diff --git a/Modules/Sources/ForumFeature/ForumScreen.swift b/Modules/Sources/ForumFeature/ForumScreen.swift index 3bf74517..8e35b73e 100644 --- a/Modules/Sources/ForumFeature/ForumScreen.swift +++ b/Modules/Sources/ForumFeature/ForumScreen.swift @@ -206,19 +206,21 @@ public struct ForumScreen: View { store.send(.contextCommonMenu(.openInBrowser, id, isForum)) } - if isUnread { - ContextButton(text: "Mark Read", symbol: .checkmarkCircle, bundle: .module) { - store.send(.contextCommonMenu(.markRead, id, isForum)) + if store.isUserAuthorized { + if isUnread { + ContextButton(text: "Mark Read", symbol: .checkmarkCircle, bundle: .module) { + store.send(.contextCommonMenu(.markRead, id, isForum)) + } } - } - - Section { - ContextButton( - text: isFavorite ? "Remove from favorites" : "Add to favorites", - symbol: isFavorite ? .starFill : .star, - bundle: .module - ) { - store.send(.contextCommonMenu(.setFavorite(isFavorite), id, isForum)) + + Section { + ContextButton( + text: isFavorite ? "Remove from favorites" : "Add to favorites", + symbol: isFavorite ? .starFill : .star, + bundle: .module + ) { + store.send(.contextCommonMenu(.setFavorite(isFavorite), id, isForum)) + } } } } diff --git a/Modules/Sources/TopicFeature/TopicFeature.swift b/Modules/Sources/TopicFeature/TopicFeature.swift index 040d49ec..9cd1c448 100644 --- a/Modules/Sources/TopicFeature/TopicFeature.swift +++ b/Modules/Sources/TopicFeature/TopicFeature.swift @@ -26,6 +26,7 @@ public struct TopicFeature: Reducer, Sendable { @ObservableState public struct State: Equatable { @Shared(.appSettings) var appSettings: AppSettings + @Shared(.userSession) var userSession: UserSession? public let topicId: Int public let initialOffset: Int @@ -39,6 +40,10 @@ public struct TopicFeature: Reducer, Sendable { var pageNavigation = PageNavigationFeature.State(type: .topic) + public var isUserAuthorized: Bool { + return userSession != nil + } + public init( topicId: Int, initialOffset: Int = 0, diff --git a/Modules/Sources/TopicFeature/TopicScreen.swift b/Modules/Sources/TopicFeature/TopicScreen.swift index 4156af94..c94f182a 100644 --- a/Modules/Sources/TopicFeature/TopicScreen.swift +++ b/Modules/Sources/TopicFeature/TopicScreen.swift @@ -84,7 +84,7 @@ public struct TopicScreen: View { store.send(.contextMenu(.openInBrowser)) } - if let topic = store.topic { + if let topic = store.topic, store.isUserAuthorized { Section { ContextButton( text: topic.isFavorite ? "Remove from favorites" : "Add to favorites", From 6cd6a9469c7d1707527d5d3d74935627cd352faf Mon Sep 17 00:00:00 2001 From: Xialtal Date: Sun, 23 Feb 2025 19:57:35 +0300 Subject: [PATCH 2/4] Disable some context menu actions in articles --- .../Sources/ArticleFeature/ArticleScreen.swift | 6 +++--- .../ArticleFeature/Comments/CommentsView.swift | 6 +++--- .../Resources/Localizable.xcstrings | 2 ++ .../ArticleFeature/Views/ArticleMenu.swift | 6 +++--- .../Sources/SharedUI/Articles/MenuButtons.swift | 16 ++++++++-------- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Modules/Sources/ArticleFeature/ArticleScreen.swift b/Modules/Sources/ArticleFeature/ArticleScreen.swift index 0293faca..a04e5e16 100644 --- a/Modules/Sources/ArticleFeature/ArticleScreen.swift +++ b/Modules/Sources/ArticleFeature/ArticleScreen.swift @@ -85,9 +85,9 @@ public struct ArticleScreen: View { ToolbarItemGroup(placement: .topBarTrailing) { HStack(spacing: 8) { - ToolbarButton(placement: .topBarTrailing, symbol: .bookmark) { - store.send(.bookmarkButtonTapped) - } +// ToolbarButton(placement: .topBarTrailing, symbol: .bookmark) { +// store.send(.bookmarkButtonTapped) +// } ArticleMenu(store: store, isDark: navBarFullyVisible) } diff --git a/Modules/Sources/ArticleFeature/Comments/CommentsView.swift b/Modules/Sources/ArticleFeature/Comments/CommentsView.swift index 2a2764d6..0bb369e7 100644 --- a/Modules/Sources/ArticleFeature/Comments/CommentsView.swift +++ b/Modules/Sources/ArticleFeature/Comments/CommentsView.swift @@ -195,9 +195,9 @@ struct CommentView: View { @ViewBuilder private func MenuButton() -> some View { Menu { - ContextButton(text: "Report", symbol: .exclamationmarkTriangle, bundle: .module) { - store.send(.reportButtonTapped) - } +// ContextButton(text: "Report", symbol: .exclamationmarkTriangle, bundle: .module) { +// store.send(.reportButtonTapped) +// } ContextButton( text: store.comment.isHidden ? "Unhide comment" : "Hide comment", symbol: store.comment.isHidden ? .eyeSlash : .eye, diff --git a/Modules/Sources/ArticleFeature/Resources/Localizable.xcstrings b/Modules/Sources/ArticleFeature/Resources/Localizable.xcstrings index 82303a50..f032b483 100644 --- a/Modules/Sources/ArticleFeature/Resources/Localizable.xcstrings +++ b/Modules/Sources/ArticleFeature/Resources/Localizable.xcstrings @@ -142,6 +142,7 @@ } }, "Problems with article?" : { + "extractionState" : "stale", "localizations" : { "ru" : { "stringUnit" : { @@ -152,6 +153,7 @@ } }, "Report" : { + "extractionState" : "stale", "localizations" : { "ru" : { "stringUnit" : { diff --git a/Modules/Sources/ArticleFeature/Views/ArticleMenu.swift b/Modules/Sources/ArticleFeature/Views/ArticleMenu.swift index f4d4cd8c..81aa4b61 100644 --- a/Modules/Sources/ArticleFeature/Views/ArticleMenu.swift +++ b/Modules/Sources/ArticleFeature/Views/ArticleMenu.swift @@ -27,9 +27,9 @@ public struct ArticleMenu: View { ContextButton(text: "Share Link", symbol: .squareAndArrowUp, bundle: .module) { store.send(.menuActionTapped(.shareLink)) } - ContextButton(text: "Problems with article?", symbol: .questionmarkCircle, bundle: .module) { - store.send(.menuActionTapped(.report)) - } +// ContextButton(text: "Problems with article?", symbol: .questionmarkCircle, bundle: .module) { +// store.send(.menuActionTapped(.report)) +// } } label: { Image(systemSymbol: .ellipsis) .font(.body) diff --git a/Modules/Sources/SharedUI/Articles/MenuButtons.swift b/Modules/Sources/SharedUI/Articles/MenuButtons.swift index c0823dac..e79b95e1 100644 --- a/Modules/Sources/SharedUI/Articles/MenuButtons.swift +++ b/Modules/Sources/SharedUI/Articles/MenuButtons.swift @@ -42,16 +42,16 @@ public struct MenuButtons: View { ContextButton(text: "Open In Browser", symbol: .safari, bundle: .module) { contextMenuActions.openInBrowserAction() } - ContextButton(text: "Problems with article?", symbol: .exclamationmarkBubble, bundle: .module) { - contextMenuActions.reportAction() - } +// ContextButton(text: "Problems with article?", symbol: .exclamationmarkBubble, bundle: .module) { +// contextMenuActions.reportAction() +// } } - Section { - ContextButton(text: "Add To Bookmarks", symbol: .bookmark, bundle: .module) { - contextMenuActions.addToBookmarksAction() - } - } +// Section { +// ContextButton(text: "Add To Bookmarks", symbol: .bookmark, bundle: .module) { +// contextMenuActions.addToBookmarksAction() +// } +// } } } } From 5634265e0549e0f0ea7caf761b278b2f31ff7e9c Mon Sep 17 00:00:00 2001 From: Xialtal Date: Sun, 9 Mar 2025 15:02:16 +0300 Subject: [PATCH 3/4] Add download count stat for file in post --- Modules/Sources/Models/Forum/Post.swift | 8 ++++++-- Modules/Sources/ParsingClient/Parsers/TopicParser.swift | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Modules/Sources/Models/Forum/Post.swift b/Modules/Sources/Models/Forum/Post.swift index 7448f779..6e7aa04c 100644 --- a/Modules/Sources/Models/Forum/Post.swift +++ b/Modules/Sources/Models/Forum/Post.swift @@ -45,6 +45,7 @@ public struct Post: Sendable, Hashable, Identifiable, Codable { public let name: String public let size: Int public let metadata: Metadata? + public let downloadCount: Int? public enum AttachmentType: Sendable, Hashable, Codable { case file @@ -68,13 +69,15 @@ public struct Post: Sendable, Hashable, Identifiable, Codable { type: AttachmentType, name: String, size: Int, - metadata: Metadata? + metadata: Metadata?, + downloadCount: Int? ) { self.id = id self.type = type self.name = name self.size = size self.metadata = metadata + self.downloadCount = downloadCount } } @@ -146,7 +149,8 @@ extension Post { width: 281, height: 500, url: "https://cs2c9f.4pda.ws/14308454.png" - ) + ), + downloadCount: nil ) ], createdAt: Date(timeIntervalSince1970: 1725706321), diff --git a/Modules/Sources/ParsingClient/Parsers/TopicParser.swift b/Modules/Sources/ParsingClient/Parsers/TopicParser.swift index 10551e89..db7421c9 100644 --- a/Modules/Sources/ParsingClient/Parsers/TopicParser.swift +++ b/Modules/Sources/ParsingClient/Parsers/TopicParser.swift @@ -112,6 +112,8 @@ public struct TopicParser { ) } else { nil } + let downloadCount = attachment.count == 5 ? attachment[4] as? Int : nil + let type = if attachment[1] as! Int == 1 { Post.Attachment.AttachmentType.image } else { @@ -123,7 +125,8 @@ public struct TopicParser { type: type, name: attachment[2] as! String, size: attachment[3] as! Int, - metadata: metadata + metadata: metadata, + downloadCount: downloadCount ) } } From 7daf76252109ed32b29c523c4513efa104ce024b Mon Sep 17 00:00:00 2001 From: Xialtal Date: Sun, 9 Mar 2025 15:20:07 +0300 Subject: [PATCH 4/4] History feature improvements --- .../HistoryFeature/HistoryScreen.swift | 62 +++++++++++++++---- .../Resources/Localizable.xcstrings | 22 +++++++ 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/Modules/Sources/HistoryFeature/HistoryScreen.swift b/Modules/Sources/HistoryFeature/HistoryScreen.swift index d758e138..3afb025b 100644 --- a/Modules/Sources/HistoryFeature/HistoryScreen.swift +++ b/Modules/Sources/HistoryFeature/HistoryScreen.swift @@ -27,31 +27,46 @@ public struct HistoryScreen: View { Color(.Background.primary) .ignoresSafeArea() - if !store.isLoading { - VStack(spacing: 1) { - if store.pageNavigation.shouldShow { - PageNavigation(store: store.scope(state: \.pageNavigation, action: \.pageNavigation)) - .padding(.horizontal, 16) - } + if !store.history.isEmpty { + List { + Navigation() - List(store.history, id: \.hashValue) { history in + ForEach(store.history, id: \.hashValue) { history in HistorySection(history: history) } - .scrollContentBackground(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 24, bottom: 0, trailing: 24)) + + Navigation() } - } else { - PDALoader() - .frame(width: 24, height: 24) + .scrollContentBackground(.hidden) + } else if !store.isLoading { + EmptyHistory() } } .navigationTitle(Text("History", bundle: .module)) .navigationBarTitleDisplayMode(.large) + .overlay { + if store.isLoading { + PDALoader() + .frame(width: 24, height: 24) + } + } .task { store.send(.onTask) } } } + // MARK: - Page Navigation + + @ViewBuilder + private func Navigation() -> some View { + if store.pageNavigation.shouldShow { + PageNavigation(store: store.scope(state: \.pageNavigation, action: \.pageNavigation)) + //.listRowBackground(.primary) + } + } + // MARK: - History Section private func HistorySection(history: HistoryRow) -> some View { @@ -68,6 +83,31 @@ public struct HistoryScreen: View { .listRowBackground(Color(.Background.teritary)) } + // MARK: - Empty History + + @ViewBuilder + private func EmptyHistory() -> some View { + VStack(spacing: 0) { + Image(systemSymbol: .clockArrowCirclepath) + .font(.title) + .foregroundStyle(tintColor) + .frame(width: 48, height: 48) + .padding(.bottom, 6) + + Text("No history", bundle: .module) + .font(.title3) + .bold() + .foregroundColor(.primary) + .padding(.bottom, 6) + + Text("View any topic in forum and it displays here.", bundle: .module) + .font(.footnote) + .foregroundStyle(.tertiary) + .multilineTextAlignment(.center) + .frame(maxWidth: UIScreen.main.bounds.width * 0.7) + } + } + // MARK: - Row @ViewBuilder diff --git a/Modules/Sources/HistoryFeature/Resources/Localizable.xcstrings b/Modules/Sources/HistoryFeature/Resources/Localizable.xcstrings index 8fbd7910..b2365bbe 100644 --- a/Modules/Sources/HistoryFeature/Resources/Localizable.xcstrings +++ b/Modules/Sources/HistoryFeature/Resources/Localizable.xcstrings @@ -14,7 +14,18 @@ } } }, + "No history" : { + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Нет истории" + } + } + } + }, "Today" : { + "extractionState" : "stale", "localizations" : { "ru" : { "stringUnit" : { @@ -24,7 +35,18 @@ } } }, + "View any topic in forum and it displays here." : { + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Посмотрите любую тему на форуме и она появится тут." + } + } + } + }, "Yesterday" : { + "extractionState" : "stale", "localizations" : { "ru" : { "stringUnit" : {