b8364df37d
App Store review for build 1.0 (2) flagged three guidelines; this covers the two that need binary changes: 3.1.1 Donate: external donation links are forbidden outside the US storefront's external-link API. Drop the Liberapay row from the Settings About section entirely. The donation pointer stays on the project README outside the bundle. 4 Design: bouncing the user out to Safari for sign-in or sign-up is rejected. Wrap SFSafariViewController in a SwiftUI helper (InAppBrowserView + InAppBrowserLink) and route the four external account-related links through it: vfile signup, GitHub PAT, Codeberg token page, and the Issue/PR link. The host and SSL chain stay visible to the user without leaving the app. 1.2 UGC (filter requirement): add a Muted words section in Settings. The user types one token per line; MuteFilter (in OrgSocialKit, pure Swift, 7 unit tests) does case-insensitive substring matching against post body + tags. Applied in TimelineViewModel.load and mergeOwnFeed plus ProfileView's posts list, so muted content disappears everywhere the timeline aggregates it. Persistence is immediate via onChange so muted words don't depend on the credentials Save gate. Lock the app to portrait via UISupportedInterfaceOrientations in project.yml so xcodegen stops rewriting the Info.plist back to the default landscape-too set. Block, report and EULA controls are the next pass for the same UGC guideline.
42 lines
1.4 KiB
Swift
42 lines
1.4 KiB
Swift
import SwiftUI
|
|
import SafariServices
|
|
|
|
/// `SFSafariViewController` wrapped for SwiftUI. Apple's review guideline 4
|
|
/// rejects apps that bounce the user out to Safari for sign-in or sign-up
|
|
/// flows; presenting the same URL inside SFSafariViewController keeps the
|
|
/// host + cert chain visible to the user without leaving the app.
|
|
struct InAppBrowserView: UIViewControllerRepresentable {
|
|
let url: URL
|
|
|
|
func makeUIViewController(context: Context) -> SFSafariViewController {
|
|
let config = SFSafariViewController.Configuration()
|
|
config.entersReaderIfAvailable = false
|
|
let vc = SFSafariViewController(url: url, configuration: config)
|
|
vc.dismissButtonStyle = .close
|
|
return vc
|
|
}
|
|
|
|
func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {}
|
|
}
|
|
|
|
/// Small convenience that turns a tappable label into a button that pops
|
|
/// the URL in the in-app browser. Use this anywhere we used to call
|
|
/// `Link(destination:)` for external pages.
|
|
struct InAppBrowserLink<Label: View>: View {
|
|
let url: URL
|
|
@ViewBuilder var label: () -> Label
|
|
@State private var presented = false
|
|
|
|
var body: some View {
|
|
Button {
|
|
presented = true
|
|
} label: {
|
|
label()
|
|
}
|
|
.sheet(isPresented: $presented) {
|
|
InAppBrowserView(url: url)
|
|
.ignoresSafeArea()
|
|
}
|
|
}
|
|
}
|