Compare commits

...

3 Commits

13 changed files with 182 additions and 100 deletions

View File

@ -42,6 +42,7 @@ struct AboutView: View {
} }
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
Section { Section {
Link("Website", destination: URL(string: "https://vaccor.space/tusker")!) Link("Website", destination: URL(string: "https://vaccor.space/tusker")!)
@ -67,7 +68,10 @@ struct AboutView: View {
Link("Source Code", destination: URL(string: "https://git.shadowfacts.net/shadowfacts/Tusker")!) Link("Source Code", destination: URL(string: "https://git.shadowfacts.net/shadowfacts/Tusker")!)
Link("Issue Tracker", destination: URL(string: "https://git.shadowfacts.net/shadowfacts/Tusker/issues")!) Link("Issue Tracker", destination: URL(string: "https://git.shadowfacts.net/shadowfacts/Tusker/issues")!)
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
.listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.sheet(isPresented: $isShowingMailSheet) { .sheet(isPresented: $isShowingMailSheet) {
MailSheet(logData: logData) MailSheet(logData: logData)
} }

View File

@ -14,6 +14,7 @@ struct AcknowledgementsView: View {
Text(text) Text(text)
.padding(.horizontal, 16) .padding(.horizontal, 16)
} }
.appGroupedScrollBackgroundIfAvailable()
.navigationTitle("Acknowledgements") .navigationTitle("Acknowledgements")
} }

View File

@ -23,7 +23,8 @@ struct AdvancedPrefsView : View {
errorReportingSection errorReportingSection
cachingSection cachingSection
} }
.listStyle(InsetGroupedListStyle()) .listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.navigationBarTitle(Text("Advanced")) .navigationBarTitle(Text("Advanced"))
} }
@ -50,6 +51,7 @@ struct AdvancedPrefsView : View {
// see FB6838291 // see FB6838291
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
var cloudKitSection: some View { var cloudKitSection: some View {
@ -74,7 +76,9 @@ struct AdvancedPrefsView : View {
Text(String(describing: cloudKitStatus!)) Text(String(describing: cloudKitStatus!))
} }
} }
}.task { }
.listRowBackground(Color.appGroupedCellBackground)
.task {
CKContainer.default().accountStatus { status, error in CKContainer.default().accountStatus { status, error in
if let error { if let error {
Logging.general.error("Unable to get CloudKit status: \(String(describing: error))") Logging.general.error("Unable to get CloudKit status: \(String(describing: error))")
@ -99,6 +103,7 @@ struct AdvancedPrefsView : View {
.lineLimit(nil) .lineLimit(nil)
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
var cachingSection: some View { var cachingSection: some View {
@ -120,7 +125,9 @@ struct AdvancedPrefsView : View {
s += AttributedString("\nMastodon cache size: \(ByteCountFormatter().string(fromByteCount: mastodonCacheSize))") s += AttributedString("\nMastodon cache size: \(ByteCountFormatter().string(fromByteCount: mastodonCacheSize))")
} }
return Text(s) return Text(s)
}.task { }
.listRowBackground(Color.appGroupedCellBackground)
.task {
imageCacheSize = [ imageCacheSize = [
ImageCache.avatars, ImageCache.avatars,
.headers, .headers,

View File

@ -33,7 +33,8 @@ struct AppearancePrefsView : View {
accountsSection accountsSection
postsSection postsSection
} }
.listStyle(InsetGroupedListStyle()) .listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.navigationBarTitle(Text("Appearance")) .navigationBarTitle(Text("Appearance"))
} }
@ -65,6 +66,7 @@ struct AppearancePrefsView : View {
.onReceive(appearanceChangePublisher) { _ in .onReceive(appearanceChangePublisher) { _ in
NotificationCenter.default.post(name: .themePreferenceChanged, object: nil) NotificationCenter.default.post(name: .themePreferenceChanged, object: nil)
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var accountsSection: some View { private var accountsSection: some View {
@ -76,6 +78,7 @@ struct AppearancePrefsView : View {
Text("Hide Custom Emoji in Usernames") Text("Hide Custom Emoji in Usernames")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var postsSection: some View { private var postsSection: some View {
@ -103,6 +106,7 @@ struct AppearancePrefsView : View {
.navigationTitle("Trailing Swipe Actions") .navigationTitle("Trailing Swipe Actions")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
} }

View File

@ -18,7 +18,8 @@ struct BehaviorPrefsView: View {
linksSection linksSection
contentWarningsSection contentWarningsSection
} }
.listStyle(InsetGroupedListStyle()) .listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.navigationBarTitle(Text("Behavior")) .navigationBarTitle(Text("Behavior"))
} }
@ -28,6 +29,7 @@ struct BehaviorPrefsView: View {
Text("Require Confirmation Before Reblogging") Text("Require Confirmation Before Reblogging")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var timelineSection: some View { private var timelineSection: some View {
@ -38,6 +40,7 @@ struct BehaviorPrefsView: View {
} header: { } header: {
Text("Timeline") Text("Timeline")
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var linksSection: some View { private var linksSection: some View {
@ -52,6 +55,7 @@ struct BehaviorPrefsView: View {
Text("Always Use Reader Mode in In-App Safari") Text("Always Use Reader Mode in In-App Safari")
}.disabled(!preferences.useInAppSafari) }.disabled(!preferences.useInAppSafari)
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var contentWarningsSection: some View { private var contentWarningsSection: some View {
@ -68,6 +72,7 @@ struct BehaviorPrefsView: View {
Text(preferences.expandAllContentWarnings ? "Collapse Posts with Keywords in CWs" : "Expand Posts with Keywords in CWs") Text(preferences.expandAllContentWarnings ? "Collapse Posts with Keywords in CWs" : "Expand Posts with Keywords in CWs")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
} }

View File

@ -19,7 +19,8 @@ struct ComposingPrefsView: View {
replyingSection replyingSection
writingSection writingSection
} }
.listStyle(InsetGroupedListStyle()) .listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.navigationBarTitle("Composing") .navigationBarTitle("Composing")
} }
@ -51,6 +52,7 @@ struct ComposingPrefsView: View {
} footer: { } footer: {
Text("When starting a reply, Tusker will use your preferred visibility or the visibility of the post to which you're replying, whichever is narrower.") Text("When starting a reply, Tusker will use your preferred visibility or the visibility of the post to which you're replying, whichever is narrower.")
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
var composingSection: some View { var composingSection: some View {
@ -62,6 +64,7 @@ struct ComposingPrefsView: View {
Text("Require Attachment Descriptions") Text("Require Attachment Descriptions")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
var replyingSection: some View { var replyingSection: some View {
@ -75,6 +78,7 @@ struct ComposingPrefsView: View {
Text("Mention Reblogger") Text("Mention Reblogger")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
var writingSection: some View { var writingSection: some View {
@ -83,6 +87,7 @@ struct ComposingPrefsView: View {
Text("Show @ and # on Keyboard") Text("Show @ and # on Keyboard")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
} }

View File

@ -15,7 +15,8 @@ struct MediaPrefsView: View {
List { List {
viewingSection viewingSection
} }
.listStyle(InsetGroupedListStyle()) .listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.navigationBarTitle("Media") .navigationBarTitle("Media")
} }
@ -42,6 +43,7 @@ struct MediaPrefsView: View {
Text("Show Uncropped Media Inline") Text("Show Uncropped Media Inline")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
} }

View File

@ -37,9 +37,11 @@ struct OppositeCollapseKeywordsView: View {
FocusableTextField(placeholder: "Add Keyword", text: $valueToAdd, becomeFirstResponder: $makeAddFieldFirstResponder, onCommit: self.addKeyword) FocusableTextField(placeholder: "Add Keyword", text: $valueToAdd, becomeFirstResponder: $makeAddFieldFirstResponder, onCommit: self.addKeyword)
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
.animation(.default, value: keywords.map(\.id)) .animation(.default, value: keywords.map(\.id))
.listStyle(GroupedListStyle()) .listStyle(.grouped)
.appGroupedScrollBackgroundIfAvailable()
} }
.onAppear(perform: updateAppearance) .onAppear(perform: updateAppearance)
.navigationBarTitle(preferences.expandAllContentWarnings ? "Collapse Post CW Keywords" : "Expand Post CW Keywords") .navigationBarTitle(preferences.expandAllContentWarnings ? "Collapse Post CW Keywords" : "Expand Post CW Keywords")

View File

@ -6,11 +6,11 @@
// //
import SwiftUI import SwiftUI
import TTTKit
struct PreferencesView: View { struct PreferencesView: View {
let mastodonController: MastodonController let mastodonController: MastodonController
@ObservedObject var localData = LocalData.shared
@ObservedObject private var localData = LocalData.shared
@State private var showingLogoutConfirmation = false @State private var showingLogoutConfirmation = false
init(mastodonController: MastodonController) { init(mastodonController: MastodonController) {
@ -18,101 +18,118 @@ struct PreferencesView: View {
} }
var body: some View { var body: some View {
// workaround: the navigation view is provided by MyProfileTableViewController so that it can inject the Done button List {
// NavigationView { accountsSection
List { preferencesSection
Section(header: Text("Accounts")) { aboutSection
ForEach(localData.accounts, id: \.accessToken) { (account) in }
Button(action: { .listStyle(.insetGrouped)
NotificationCenter.default.post(name: .activateAccount, object: nil, userInfo: ["account": account]) .appGroupedScrollBackgroundIfAvailable()
}) { .navigationBarTitle("Preferences")
HStack { .navigationBarTitleDisplayMode(.inline)
LocalAccountAvatarView(localAccountInfo: account) .onAppear {
VStack(alignment: .leading) { if #unavailable(iOS 16.0) {
Text(verbatim: account.username) UITableView.appearance(whenContainedInInstancesOf: [PreferencesNavigationController.self]).backgroundColor = .appGroupedBackground
.foregroundColor(.primary) }
Text(verbatim: account.instanceURL.host!) }
.font(.caption) }
.foregroundColor(.primary)
} private var accountsSection: some View {
Spacer() Section {
if account == mastodonController.accountInfo! { ForEach(localData.accounts, id: \.accessToken) { (account) in
Image(systemName: "checkmark") Button(action: {
.renderingMode(.template) NotificationCenter.default.post(name: .activateAccount, object: nil, userInfo: ["account": account])
.foregroundColor(.secondary) }) {
} HStack {
} LocalAccountAvatarView(localAccountInfo: account)
}.onDrag { VStack(alignment: .leading) {
let activity = UserActivityManager.mainSceneActivity(accountID: account.id) Text(verbatim: account.username)
return NSItemProvider(object: activity) .foregroundColor(.primary)
Text(verbatim: account.instanceURL.host!)
.font(.caption)
.foregroundColor(.primary)
} }
}.onDelete { (indices: IndexSet) in Spacer()
var indices = indices if account == mastodonController.accountInfo! {
var logoutFromCurrent = false Image(systemName: "checkmark")
if let index = indices.first(where: { localData.accounts[$0] == mastodonController.accountInfo! }) { .renderingMode(.template)
logoutFromCurrent = true .foregroundColor(.secondary)
indices.remove(index)
}
indices.forEach { LogoutService(accountInfo: localData.accounts[$0]).run() }
if logoutFromCurrent {
self.logoutPressed()
}
}
Button(action: {
NotificationCenter.default.post(name: .addAccount, object: nil)
}) {
Text("Add Account...")
}
if localData.getMostRecentAccount() != nil {
Button(action: {
self.showingLogoutConfirmation = true
}) {
Text("Logout from current")
}.alert(isPresented: $showingLogoutConfirmation) {
Alert(title: Text("Are you sure you want to logout?"), message: nil, primaryButton: .destructive(Text("Logout"), action: self.logoutPressed), secondaryButton: .cancel())
} }
} }
}.onDrag {
let activity = UserActivityManager.mainSceneActivity(accountID: account.id)
return NSItemProvider(object: activity)
}
}.onDelete { (indices: IndexSet) in
var indices = indices
var logoutFromCurrent = false
if let index = indices.first(where: { localData.accounts[$0] == mastodonController.accountInfo! }) {
logoutFromCurrent = true
indices.remove(index)
} }
Section { indices.forEach { LogoutService(accountInfo: localData.accounts[$0]).run() }
NavigationLink(destination: AppearancePrefsView()) {
Text("Appearance")
}
NavigationLink(destination: ComposingPrefsView()) {
Text("Composing")
}
NavigationLink(destination: MediaPrefsView()) {
Text("Media")
}
NavigationLink(destination: BehaviorPrefsView()) {
Text("Behavior")
}
NavigationLink(destination: WellnessPrefsView()) {
Text("Digital Wellness")
}
NavigationLink(destination: AdvancedPrefsView()) {
Text("Advanced")
}
}
Section { if logoutFromCurrent {
NavigationLink("About") { self.logoutPressed()
AboutView()
}
NavigationLink("Tip Jar") {
TipJarView()
}
NavigationLink("Acknowledgements") {
AcknowledgementsView()
}
} }
} }
.listStyle(InsetGroupedListStyle())
.navigationBarTitle(Text("Preferences"), displayMode: .inline) Button(action: {
// } NotificationCenter.default.post(name: .addAccount, object: nil)
}) {
Text("Add Account...")
}
Button(action: {
self.showingLogoutConfirmation = true
}) {
Text("Logout from current")
}.alert(isPresented: $showingLogoutConfirmation) {
Alert(title: Text("Are you sure you want to logout?"), message: nil, primaryButton: .destructive(Text("Logout"), action: self.logoutPressed), secondaryButton: .cancel())
}
} header: {
Text("Accounts")
}
.listRowBackground(Color.appGroupedCellBackground)
}
private var preferencesSection: some View {
Section {
NavigationLink(destination: AppearancePrefsView()) {
Text("Appearance")
}
NavigationLink(destination: ComposingPrefsView()) {
Text("Composing")
}
NavigationLink(destination: MediaPrefsView()) {
Text("Media")
}
NavigationLink(destination: BehaviorPrefsView()) {
Text("Behavior")
}
NavigationLink(destination: WellnessPrefsView()) {
Text("Digital Wellness")
}
NavigationLink(destination: AdvancedPrefsView()) {
Text("Advanced")
}
}
.listRowBackground(Color.appGroupedCellBackground)
}
private var aboutSection: some View {
Section {
NavigationLink("About") {
AboutView()
}
NavigationLink("Tip Jar") {
TipJarView()
}
NavigationLink("Acknowledgements") {
AcknowledgementsView()
}
}
.listRowBackground(Color.appGroupedCellBackground)
} }
func logoutPressed() { func logoutPressed() {
@ -120,6 +137,20 @@ struct PreferencesView: View {
} }
} }
extension View {
@available(iOS, obsoleted: 16.0)
@ViewBuilder
func appGroupedScrollBackgroundIfAvailable() -> some View {
if #available(iOS 16.0, *) {
self
.scrollContentBackground(.hidden)
.background(Color.appGroupedBackground)
} else {
self
}
}
}
//#if DEBUG //#if DEBUG
//struct PreferencesView_Previews : PreviewProvider { //struct PreferencesView_Previews : PreviewProvider {
// static var previews: some View { // static var previews: some View {

View File

@ -42,6 +42,7 @@ class SwipeActionsPrefsViewController: UIViewController, UICollectionViewDelegat
override func loadView() { override func loadView() {
let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, environment in let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, environment in
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped) var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
config.backgroundColor = .appGroupedBackground
if dataSource.sectionIdentifier(for: sectionIndex) == .selected { if dataSource.sectionIdentifier(for: sectionIndex) == .selected {
config.headerMode = .supplementary config.headerMode = .supplementary
} }
@ -59,6 +60,15 @@ class SwipeActionsPrefsViewController: UIViewController, UICollectionViewDelegat
config.image = UIImage(systemName: item.systemImageName) config.image = UIImage(systemName: item.systemImageName)
cell.contentConfiguration = config cell.contentConfiguration = config
cell.accessories = [.reorder(displayed: .always)] cell.accessories = [.reorder(displayed: .always)]
cell.configurationUpdateHandler = { cell, state in
var config = UIBackgroundConfiguration.listGroupedCell().updated(for: state)
if state.isHighlighted || state.isSelected {
config.backgroundColor = .appSelectedCellBackground
} else {
config.backgroundColor = .appGroupedCellBackground
}
cell.backgroundConfiguration = config
}
} }
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: itemIdentifier) return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: itemIdentifier)

View File

@ -26,8 +26,12 @@ struct TipJarView: View {
@StateObject private var observer = UbiquitousKeyValueStoreObserver() @StateObject private var observer = UbiquitousKeyValueStoreObserver()
var body: some View { var body: some View {
productsView ZStack {
.overlay { Color.appGroupedBackground
.edgesIgnoringSafeArea(.all)
productsView
if showConfetti { if showConfetti {
ConfettiView() ConfettiView()
.transition(.opacity.animation(.default)) .transition(.opacity.animation(.default))

View File

@ -19,7 +19,8 @@ struct WellnessPrefsView: View {
disableInfiniteScrolling disableInfiniteScrolling
hideDiscover hideDiscover
} }
.listStyle(InsetGroupedListStyle()) .listStyle(.insetGrouped)
.appGroupedScrollBackgroundIfAvailable()
.navigationBarTitle(Text("Digital Wellness")) .navigationBarTitle(Text("Digital Wellness"))
} }
@ -29,6 +30,7 @@ struct WellnessPrefsView: View {
Text("Favorite and Reblog Counts in Conversations") Text("Favorite and Reblog Counts in Conversations")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var notificationsMode: some View { private var notificationsMode: some View {
@ -39,6 +41,7 @@ struct WellnessPrefsView: View {
} }
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var grayscaleImages: some View { private var grayscaleImages: some View {
@ -47,6 +50,7 @@ struct WellnessPrefsView: View {
Text("Grayscale Images") Text("Grayscale Images")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var disableInfiniteScrolling: some View { private var disableInfiniteScrolling: some View {
@ -55,6 +59,7 @@ struct WellnessPrefsView: View {
Text("Disable Infinite Scrolling") Text("Disable Infinite Scrolling")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
private var hideDiscover: some View { private var hideDiscover: some View {
@ -63,6 +68,7 @@ struct WellnessPrefsView: View {
Text("Hide Discover Section") Text("Hide Discover Section")
} }
} }
.listRowBackground(Color.appGroupedCellBackground)
} }
} }

View File

@ -8,6 +8,7 @@
import UIKit import UIKit
import Pachyderm import Pachyderm
import SwiftUI
class MyProfileViewController: ProfileViewController { class MyProfileViewController: ProfileViewController {