Allow the user to customize the thread indentation (#1737)

* Allow the user to customize the thread indentation

The user can now select if they want to indent threads/replies, and how much
the replies should be indented.

* Make the wording clearer

The wording is now clearer since "thread" is replaced by "reply".

* Fix localizations

---------

Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
Paul Schuetz 2023-12-14 07:17:09 +01:00 committed by GitHub
parent e4df8a8b69
commit d8a686be51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 288 additions and 5 deletions

View file

@ -205,6 +205,16 @@ struct DisplaySettingsView: View {
Toggle("settings.display.translate-button", isOn: $userPreferences.showTranslateButton)
Toggle("settings.display.pending-at-bottom", isOn: $userPreferences.pendingShownAtBottom)
Toggle("settings.display.pending-left", isOn: $userPreferences.pendingShownLeft)
Toggle("settings.display.show-reply-indentation", isOn: $userPreferences.showReplyIndentation)
if userPreferences.showReplyIndentation {
Slider(value: .init(get: {
Double(userPreferences.maxReplyIndentation)
}, set: { newVal in
userPreferences.maxReplyIndentation = UInt(newVal)
}), in: 1...20, step: 1)
Text("settings.display.max-reply-indentation-\(String(userPreferences.maxReplyIndentation))")
.font(.scaledBody)
}
}
.listRowBackground(theme.primaryBackgroundColor)
}

View file

@ -43068,6 +43068,125 @@
}
}
},
"settings.display.max-reply-indentation-%@" : {
"extractionState" : "manual",
"localizations" : {
"be" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"ca" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Max. Einrückung von Antworten: %@"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Max reply indentation: %@"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"es" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"eu" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Max reply indentation: %@"
}
},
"it" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"nb" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"nl" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"pl" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"tr" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"uk" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
}
}
},
"settings.display.navigation-title" : {
"localizations" : {
"be" : {
@ -44131,6 +44250,125 @@
}
}
},
"settings.display.show-reply-indentation" : {
"extractionState" : "manual",
"localizations" : {
"be" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"ca" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rücke Antworten ein"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Show reply indentation"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"es" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"eu" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"fr" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Max reply indentation: %@"
}
},
"it" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"nb" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"nl" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"pl" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"tr" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"uk" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Show reply indentation"
}
}
}
},
"settings.display.show-tab-label" : {
"localizations" : {
"be" : {
@ -51805,7 +52043,7 @@
"localizations" : {
"be" : {
"stringUnit" : {
"state" : "translated",
"state" : "needs_review",
"value" : " Become a supporter!"
}
},

View file

@ -56,6 +56,9 @@ import SwiftUI
@AppStorage("fast_refresh") public var fastRefreshEnabled: Bool = false
@AppStorage("max_reply_indentation") public var maxReplyIndentation: UInt = 7
@AppStorage("show_reply_indentation") public var showReplyIndentation: Bool = true
init() {}
}
@ -298,6 +301,22 @@ import SwiftUI
}
}
public var maxReplyIndentation: UInt {
didSet {
storage.maxReplyIndentation = maxReplyIndentation
}
}
public var showReplyIndentation: Bool {
didSet {
storage.showReplyIndentation = showReplyIndentation
}
}
public func getRealMaxIndent() -> UInt {
showReplyIndentation ? maxReplyIndentation : 0
}
public enum SwipeActionsIconStyle: String, CaseIterable {
case iconWithText, iconOnly
@ -464,5 +483,21 @@ import SwiftUI
pendingShownAtBottom = storage.pendingShownAtBottom
pendingShownLeft = storage.pendingShownLeft
fastRefreshEnabled = storage.fastRefreshEnabled
maxReplyIndentation = storage.maxReplyIndentation
showReplyIndentation = storage.showReplyIndentation
}
}
extension UInt: RawRepresentable {
public var rawValue: Int {
Int(self)
}
public init?(rawValue: Int) {
if rawValue >= 0 {
self.init(rawValue)
} else {
return nil
}
}
}

View file

@ -13,6 +13,7 @@ public struct StatusDetailView: View {
@Environment(Client.self) private var client
@Environment(RouterPath.self) private var routerPath
@Environment(\.isCompact) private var isCompact: Bool
@Environment(UserPreferences.self) private var userPreferences: UserPreferences
@State private var viewModel: StatusDetailViewModel
@ -109,7 +110,7 @@ public struct StatusDetailView: View {
private func makeStatusesListView(statuses: [Status]) -> some View {
ForEach(statuses) { status in
let (indentationLevel, extraInsets) = viewModel.getIndentationLevel(id: status.id)
let (indentationLevel, extraInsets) = viewModel.getIndentationLevel(id: status.id, maxIndent: userPreferences.getRealMaxIndent())
let viewModel: StatusRowViewModel = .init(status: status,
client: client,
routerPath: routerPath,

View file

@ -19,7 +19,6 @@ import SwiftUI
var state: State = .loading
var title: LocalizedStringKey = ""
var scrollToId: String?
static var maxIndent = UInt(7)
@ObservationIgnored
var indentationLevelPreviousCache: [String: UInt] = [:]
@ -139,8 +138,8 @@ import SwiftUI
}
}
func getIndentationLevel(id: String) -> (indentationLevel: UInt, extraInset: Double) {
let level = min(indentationLevelPreviousCache[id] ?? 0, Self.maxIndent)
func getIndentationLevel(id: String, maxIndent: UInt) -> (indentationLevel: UInt, extraInset: Double) {
let level = min(indentationLevelPreviousCache[id] ?? 0, maxIndent)
let barSize = Double(level) * 2
let spaceBetween = (Double(level) - 1) * 3