Files
andros b8364df37d In-app browser, muted words and remove donation link
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.
2026-05-02 08:31:50 +02:00

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()
}
}
}