mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-22 07:06:40 +00:00
Swift format
This commit is contained in:
parent
5871d13eee
commit
16636b12a9
26 changed files with 191 additions and 187 deletions
|
@ -12,9 +12,9 @@ import Timeline
|
|||
@main
|
||||
struct IceCubesApp: App {
|
||||
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
|
||||
|
||||
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
|
||||
|
||||
@StateObject private var appAccountsManager = AppAccountsManager.shared
|
||||
@StateObject private var currentInstance = CurrentInstance.shared
|
||||
@StateObject private var currentAccount = CurrentAccount.shared
|
||||
|
@ -23,18 +23,18 @@ struct IceCubesApp: App {
|
|||
@StateObject private var quickLook = QuickLook()
|
||||
@StateObject private var theme = Theme.shared
|
||||
@StateObject private var sidebarRouterPath = RouterPath()
|
||||
|
||||
|
||||
@State private var selectedTab: Tab = .timeline
|
||||
@State private var selectSidebarItem: Tab? = .timeline
|
||||
@State private var popToRootTab: Tab = .other
|
||||
@State private var sideBarLoadedTabs: Set<Tab> = Set()
|
||||
|
||||
|
||||
private let feedbackGenerator = UISelectionFeedbackGenerator()
|
||||
|
||||
|
||||
private var availableTabs: [Tab] {
|
||||
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
|
||||
}
|
||||
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
appView
|
||||
|
@ -72,7 +72,7 @@ struct IceCubesApp: App {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var appView: some View {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||
|
@ -81,14 +81,14 @@ struct IceCubesApp: App {
|
|||
tabBarView
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func badgeFor(tab: Tab) -> Int {
|
||||
if tab == .notifications && selectedTab != tab {
|
||||
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
private var sidebarView: some View {
|
||||
SideBarView(selectedTab: $selectedTab,
|
||||
popToRootTab: $popToRootTab,
|
||||
|
@ -116,7 +116,8 @@ struct IceCubesApp: App {
|
|||
}
|
||||
}
|
||||
if proxy.frame(in: .global).width > (.maxColumnWidth + .secondaryColumnWidth),
|
||||
currentAccount.account?.id != nil {
|
||||
currentAccount.account?.id != nil
|
||||
{
|
||||
Divider().edgesIgnoringSafeArea(.all)
|
||||
NotificationsTab(popToRootTab: $popToRootTab, lockedType: nil)
|
||||
.environment(\.isSecondaryColumn, true)
|
||||
|
@ -128,7 +129,7 @@ struct IceCubesApp: App {
|
|||
sideBarLoadedTabs.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var tabBarView: some View {
|
||||
TabView(selection: .init(get: {
|
||||
selectedTab
|
||||
|
@ -154,14 +155,14 @@ struct IceCubesApp: App {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func setNewClientsInEnv(client: Client) {
|
||||
currentAccount.setClient(client: client)
|
||||
currentInstance.setClient(client: client)
|
||||
userPreferences.setClient(client: client)
|
||||
watcher.setClient(client: client)
|
||||
}
|
||||
|
||||
|
||||
private func handleScenePhase(scenePhase: ScenePhase) {
|
||||
switch scenePhase {
|
||||
case .background:
|
||||
|
@ -178,16 +179,16 @@ struct IceCubesApp: App {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func setupRevenueCat() {
|
||||
Purchases.logLevel = .error
|
||||
Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi")
|
||||
}
|
||||
|
||||
|
||||
private func refreshPushSubs() {
|
||||
PushNotificationsService.shared.requestPushNotifications()
|
||||
}
|
||||
|
||||
|
||||
@CommandsBuilder
|
||||
private var appMenu: some Commands {
|
||||
CommandGroup(replacing: .newItem) {
|
||||
|
@ -214,14 +215,14 @@ struct IceCubesApp: App {
|
|||
|
||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
||||
let themeObserver = ThemeObserverViewController(nibName: nil, bundle: nil)
|
||||
|
||||
|
||||
func application(_: UIApplication,
|
||||
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
||||
{
|
||||
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func application(_: UIApplication,
|
||||
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
|
||||
{
|
||||
|
@ -231,9 +232,9 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||
await PushNotificationsService.shared.updateSubscriptions(forceCreate: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
||||
|
||||
|
||||
func application(_: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options _: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
|
||||
if connectingSceneSession.role == .windowApplication {
|
||||
|
@ -246,7 +247,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||
class ThemeObserverViewController: UIViewController {
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
|
||||
print(traitCollection.userInterfaceStyle.rawValue)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ struct QuickLookPreview: UIViewControllerRepresentable {
|
|||
let selectedURL: URL
|
||||
let urls: [URL]
|
||||
|
||||
func makeUIViewController(context: Context) -> UIViewController {
|
||||
func makeUIViewController(context _: Context) -> UIViewController {
|
||||
return AppQLPreviewController(selectedURL: selectedURL, urls: urls)
|
||||
}
|
||||
|
||||
|
@ -24,65 +24,65 @@ struct QuickLookPreview: UIViewControllerRepresentable {
|
|||
class AppQLPreviewController: UIViewController {
|
||||
let selectedURL: URL
|
||||
let urls: [URL]
|
||||
|
||||
var qlController : QLPreviewController?
|
||||
|
||||
|
||||
var qlController: QLPreviewController?
|
||||
|
||||
init(selectedURL: URL, urls: [URL]) {
|
||||
self.selectedURL = selectedURL
|
||||
self.urls = urls
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
if self.qlController == nil {
|
||||
self.qlController = QLPreviewController()
|
||||
self.qlController?.dataSource = self
|
||||
self.qlController?.delegate = self
|
||||
self.qlController?.currentPreviewItemIndex = urls.firstIndex(of: selectedURL) ?? 0
|
||||
self.present(self.qlController!, animated: true)
|
||||
if qlController == nil {
|
||||
qlController = QLPreviewController()
|
||||
qlController?.dataSource = self
|
||||
qlController?.delegate = self
|
||||
qlController?.currentPreviewItemIndex = urls.firstIndex(of: selectedURL) ?? 0
|
||||
present(qlController!, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AppQLPreviewController : QLPreviewControllerDataSource {
|
||||
extension AppQLPreviewController: QLPreviewControllerDataSource {
|
||||
func numberOfPreviewItems(in _: QLPreviewController) -> Int {
|
||||
return self.urls.count
|
||||
return urls.count
|
||||
}
|
||||
|
||||
func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
||||
return self.urls[index] as QLPreviewItem
|
||||
return urls[index] as QLPreviewItem
|
||||
}
|
||||
}
|
||||
|
||||
extension AppQLPreviewController : QLPreviewControllerDelegate {
|
||||
extension AppQLPreviewController: QLPreviewControllerDelegate {
|
||||
func previewController(_: QLPreviewController, editingModeFor _: QLPreviewItem) -> QLPreviewItemEditingMode {
|
||||
.createCopy
|
||||
}
|
||||
|
||||
func previewControllerWillDismiss(_ controller: QLPreviewController) {
|
||||
self.dismiss(animated: true)
|
||||
func previewControllerWillDismiss(_: QLPreviewController) {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
struct TransparentBackground: UIViewControllerRepresentable {
|
||||
public func makeUIViewController(context: Context) -> UIViewController {
|
||||
public func makeUIViewController(context _: Context) -> UIViewController {
|
||||
return TransparentController()
|
||||
}
|
||||
|
||||
public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
|
||||
}
|
||||
|
||||
|
||||
public func updateUIViewController(_: UIViewController, context _: Context) {}
|
||||
|
||||
class TransparentController: UIViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = .clear
|
||||
}
|
||||
|
||||
|
||||
override func willMove(toParent parent: UIViewController?) {
|
||||
super.willMove(toParent: parent)
|
||||
parent?.view?.backgroundColor = .clear
|
||||
|
|
|
@ -9,7 +9,7 @@ import Timeline
|
|||
|
||||
struct NotificationsTab: View {
|
||||
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
||||
|
||||
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var client: Client
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
|
|
|
@ -5,13 +5,13 @@ import Status
|
|||
import SwiftUI
|
||||
|
||||
struct DisplaySettingsView: View {
|
||||
typealias FontState = Theme.FontState
|
||||
|
||||
typealias FontState = Theme.FontState
|
||||
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var userPreferences: UserPreferences
|
||||
|
||||
@State private var isFontSelectorPresented = false
|
||||
|
||||
@State private var isFontSelectorPresented = false
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
@ -35,21 +35,21 @@ struct DisplaySettingsView: View {
|
|||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
|
||||
Section("settings.display.section.display") {
|
||||
Picker("settings.display.font", selection: .init(get: {
|
||||
userPreferences.chosenFontData != nil ? FontState.custom : FontState.system
|
||||
}, set: { newValue in
|
||||
switch newValue {
|
||||
case .system:
|
||||
userPreferences.chosenFont = nil
|
||||
case .custom:
|
||||
isFontSelectorPresented = true
|
||||
}
|
||||
})) {
|
||||
ForEach(FontState.allCases, id: \.rawValue) { fontState in
|
||||
Text(fontState.title).tag(fontState)
|
||||
}
|
||||
Picker("settings.display.font", selection: .init(get: {
|
||||
userPreferences.chosenFontData != nil ? FontState.custom : FontState.system
|
||||
}, set: { newValue in
|
||||
switch newValue {
|
||||
case .system:
|
||||
userPreferences.chosenFont = nil
|
||||
case .custom:
|
||||
isFontSelectorPresented = true
|
||||
}
|
||||
.navigationDestination(isPresented: $isFontSelectorPresented, destination: { FontPicker() })
|
||||
})) {
|
||||
ForEach(FontState.allCases, id: \.rawValue) { fontState in
|
||||
Text(fontState.title).tag(fontState)
|
||||
}
|
||||
}
|
||||
.navigationDestination(isPresented: $isFontSelectorPresented, destination: { FontPicker() })
|
||||
Picker("settings.display.avatar.position", selection: $theme.avatarPosition) {
|
||||
ForEach(Theme.AvatarPosition.allCases, id: \.rawValue) { position in
|
||||
Text(position.description).tag(position)
|
||||
|
|
|
@ -20,13 +20,13 @@ struct IconSelectorView: View {
|
|||
case alt9, alt10, alt11, alt12, alt13, alt14
|
||||
case alt15, alt16, alt17, alt18, alt19, alt20, alt21
|
||||
case alt22, alt23, alt24
|
||||
|
||||
|
||||
static var officialIcons: [Icon] {
|
||||
[.primary, .alt1, .alt2, .alt3, .alt4, .alt5, .alt6, .alt7, .alt8,
|
||||
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14,
|
||||
.alt15, .alt16, .alt17, .alt18, .alt19]
|
||||
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14,
|
||||
.alt15, .alt16, .alt17, .alt18, .alt19]
|
||||
}
|
||||
|
||||
|
||||
static var albertKinngIcons: [Icon] {
|
||||
[.alt20, .alt21, .alt22, .alt23, .alt24]
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ struct IconSelectorView: View {
|
|||
Text("Official icons")
|
||||
.font(.scaledHeadline)
|
||||
}
|
||||
|
||||
|
||||
Section {
|
||||
makeIconGridView(icons: Icon.albertKinngIcons)
|
||||
} header: {
|
||||
|
@ -72,7 +72,7 @@ struct IconSelectorView: View {
|
|||
}
|
||||
.background(theme.primaryBackgroundColor)
|
||||
}
|
||||
|
||||
|
||||
private func makeIconGridView(icons: [Icon]) -> some View {
|
||||
LazyVGrid(columns: columns, spacing: 6) {
|
||||
ForEach(icons) { icon in
|
||||
|
|
|
@ -37,14 +37,14 @@ class ShareViewController: UIViewController {
|
|||
childView.view.frame = self.view.bounds
|
||||
self.view.addSubview(childView.view)
|
||||
childView.didMove(toParent: self)
|
||||
|
||||
|
||||
childView.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
childView.view.topAnchor.constraint(equalTo: self.view.topAnchor),
|
||||
childView.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
|
||||
childView.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
|
||||
childView.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
|
||||
childView.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ struct AccountDetailHeaderView: View {
|
|||
Rectangle()
|
||||
.frame(height: 200)
|
||||
.overlay {
|
||||
headerImageView
|
||||
headerImageView
|
||||
}
|
||||
accountInfoView
|
||||
}
|
||||
|
|
|
@ -10,18 +10,18 @@ public struct ConversationsListView: View {
|
|||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@EnvironmentObject private var client: Client
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
|
||||
@StateObject private var viewModel = ConversationsListViewModel()
|
||||
|
||||
|
||||
public init() {}
|
||||
|
||||
|
||||
private var conversations: [Conversation] {
|
||||
if viewModel.isLoadingFirstPage {
|
||||
return Conversation.placeholders()
|
||||
}
|
||||
return viewModel.conversations
|
||||
}
|
||||
|
||||
|
||||
public var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack {
|
||||
|
@ -52,7 +52,7 @@ public struct ConversationsListView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if viewModel.nextPage != nil {
|
||||
HStack {
|
||||
Spacer()
|
||||
|
|
|
@ -13,59 +13,59 @@ public extension Font {
|
|||
private static let footnote = onMac ? 15.0 : 13.0
|
||||
private static let caption = onMac ? 14.0 : 12.0
|
||||
private static let onMac = ProcessInfo.processInfo.isiOSAppOnMac
|
||||
|
||||
|
||||
private static func customFont(size: CGFloat, relativeTo textStyle: TextStyle) -> Font {
|
||||
if let chosenFont = UserPreferences.shared.chosenFont {
|
||||
return .custom(chosenFont.fontName, size: size, relativeTo: textStyle)
|
||||
}
|
||||
|
||||
|
||||
return onMac ? .system(size: size) : .system(textStyle)
|
||||
}
|
||||
|
||||
|
||||
private static func customUIFont(size: CGFloat) -> UIFont {
|
||||
if let chosenFont = UserPreferences.shared.chosenFont {
|
||||
return chosenFont.withSize(size)
|
||||
}
|
||||
|
||||
|
||||
return .systemFont(ofSize: size)
|
||||
}
|
||||
|
||||
|
||||
private static func userScaledFontSize(baseSize: CGFloat) -> CGFloat {
|
||||
if onMac {
|
||||
return UIFontMetrics.default.scaledValue(for: baseSize * UserPreferences.shared.fontSizeScale)
|
||||
}
|
||||
|
||||
|
||||
return baseSize
|
||||
}
|
||||
|
||||
|
||||
static var scaledTitle: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: title), relativeTo: .title)
|
||||
}
|
||||
|
||||
|
||||
static var scaledHeadline: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: headline), relativeTo: .headline).weight(.semibold)
|
||||
}
|
||||
|
||||
|
||||
static var scaledBody: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: body), relativeTo: .body)
|
||||
}
|
||||
|
||||
|
||||
static var scaledBodyUIFont: UIFont {
|
||||
customUIFont(size: userScaledFontSize(baseSize: body))
|
||||
}
|
||||
|
||||
|
||||
static var scaledCallout: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: callout), relativeTo: .callout)
|
||||
}
|
||||
|
||||
|
||||
static var scaledSubheadline: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: subheadline), relativeTo: .subheadline)
|
||||
}
|
||||
|
||||
|
||||
static var scaledFootnote: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: footnote), relativeTo: .footnote)
|
||||
}
|
||||
|
||||
|
||||
static var scaledCaption: Font {
|
||||
customFont(size: userScaledFontSize(baseSize: caption), relativeTo: .caption)
|
||||
}
|
||||
|
|
|
@ -2,36 +2,36 @@ import Env
|
|||
import SwiftUI
|
||||
|
||||
public struct FontPicker: UIViewControllerRepresentable {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
|
||||
public class Coordinator: NSObject, UIFontPickerViewControllerDelegate {
|
||||
private let dismiss: DismissAction
|
||||
|
||||
public init(dismiss: DismissAction) {
|
||||
self.dismiss = dismiss
|
||||
}
|
||||
|
||||
public func fontPickerViewControllerDidCancel(_ viewController: UIFontPickerViewController) {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
public func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
|
||||
UserPreferences.shared.chosenFont = UIFont(descriptor: viewController.selectedFontDescriptor!, size: 0)
|
||||
dismiss()
|
||||
}
|
||||
@Environment(\.dismiss) var dismiss
|
||||
|
||||
public class Coordinator: NSObject, UIFontPickerViewControllerDelegate {
|
||||
private let dismiss: DismissAction
|
||||
|
||||
public init(dismiss: DismissAction) {
|
||||
self.dismiss = dismiss
|
||||
}
|
||||
|
||||
public init() {}
|
||||
|
||||
public func makeCoordinator() -> Coordinator {
|
||||
Coordinator(dismiss: dismiss)
|
||||
|
||||
public func fontPickerViewControllerDidCancel(_: UIFontPickerViewController) {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
public func makeUIViewController(context: Context) -> UIFontPickerViewController {
|
||||
let controller = UIFontPickerViewController()
|
||||
controller.delegate = context.coordinator
|
||||
return controller
|
||||
|
||||
public func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
|
||||
UserPreferences.shared.chosenFont = UIFont(descriptor: viewController.selectedFontDescriptor!, size: 0)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
public func updateUIViewController(_ viewController: UIFontPickerViewController, context: Context) {}
|
||||
}
|
||||
|
||||
public init() {}
|
||||
|
||||
public func makeCoordinator() -> Coordinator {
|
||||
Coordinator(dismiss: dismiss)
|
||||
}
|
||||
|
||||
public func makeUIViewController(context: Context) -> UIFontPickerViewController {
|
||||
let controller = UIFontPickerViewController()
|
||||
controller.delegate = context.coordinator
|
||||
return controller
|
||||
}
|
||||
|
||||
public func updateUIViewController(_: UIFontPickerViewController, context _: Context) {}
|
||||
}
|
||||
|
|
|
@ -8,21 +8,21 @@ public class Theme: ObservableObject {
|
|||
case selectedSet, selectedScheme
|
||||
case followSystemColorSchme
|
||||
}
|
||||
|
||||
public enum FontState: Int, CaseIterable {
|
||||
case system
|
||||
case custom
|
||||
|
||||
@MainActor
|
||||
public var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .system:
|
||||
return "settings.display.font.system"
|
||||
case .custom:
|
||||
return "settings.display.font.custom"
|
||||
}
|
||||
}
|
||||
|
||||
public enum FontState: Int, CaseIterable {
|
||||
case system
|
||||
case custom
|
||||
|
||||
@MainActor
|
||||
public var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .system:
|
||||
return "settings.display.font.system"
|
||||
case .custom:
|
||||
return "settings.display.font.custom"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum AvatarPosition: String, CaseIterable {
|
||||
case leading, top
|
||||
|
|
|
@ -48,7 +48,7 @@ struct ThemeApplier: ViewModifier {
|
|||
setBarsColor(newValue)
|
||||
}
|
||||
.onChange(of: theme.selectedScheme) { newValue in
|
||||
setWindowUserInterfaceStyle(from: newValue)
|
||||
setWindowUserInterfaceStyle(from: newValue)
|
||||
}
|
||||
.onChange(of: colorScheme) { newColorScheme in
|
||||
if theme.followSystemColorScheme,
|
||||
|
@ -64,8 +64,8 @@ struct ThemeApplier: ViewModifier {
|
|||
#if canImport(UIKit)
|
||||
private func setWindowUserInterfaceStyle(from colorScheme: ColorScheme) {
|
||||
guard !theme.followSystemColorScheme else {
|
||||
setWindowUserInterfaceStyle(.unspecified)
|
||||
return
|
||||
setWindowUserInterfaceStyle(.unspecified)
|
||||
return
|
||||
}
|
||||
switch colorScheme {
|
||||
case .dark:
|
||||
|
@ -74,14 +74,14 @@ struct ThemeApplier: ViewModifier {
|
|||
setWindowUserInterfaceStyle(.light)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func setWindowUserInterfaceStyle(_ userInterfaceStyle: UIUserInterfaceStyle) {
|
||||
allWindows()
|
||||
.forEach {
|
||||
$0.overrideUserInterfaceStyle = userInterfaceStyle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func setWindowTint(_ color: Color) {
|
||||
allWindows()
|
||||
.forEach {
|
||||
|
|
|
@ -5,8 +5,8 @@ private struct SecondaryColumnKey: EnvironmentKey {
|
|||
static let defaultValue = false
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
public var isSecondaryColumn: Bool {
|
||||
public extension EnvironmentValues {
|
||||
var isSecondaryColumn: Bool {
|
||||
get { self[SecondaryColumnKey.self] }
|
||||
set { self[SecondaryColumnKey.self] = newValue }
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class QuickLook: ObservableObject {
|
|||
paths.append(path)
|
||||
}
|
||||
return paths.sorted { url1, url2 in
|
||||
return pathOrderMap[url1.lastPathComponent] ?? 0 < pathOrderMap[url2.lastPathComponent] ?? 0
|
||||
pathOrderMap[url1.lastPathComponent] ?? 0 < pathOrderMap[url2.lastPathComponent] ?? 0
|
||||
}
|
||||
})
|
||||
withTransaction(transaction) {
|
||||
|
|
|
@ -26,7 +26,7 @@ public class UserPreferences: ObservableObject {
|
|||
@AppStorage("app_default_post_visibility") public var appDefaultPostVisibility: Models.Visibility = .pub
|
||||
@AppStorage("app_default_posts_sensitive") public var appDefaultPostsSensitive = false
|
||||
@AppStorage("autoplay_video") public var autoPlayVideo = true
|
||||
@AppStorage("chosen_font") public private(set) var chosenFontData: Data?
|
||||
@AppStorage("chosen_font") public private(set) var chosenFontData: Data?
|
||||
|
||||
public var postVisibility: Models.Visibility {
|
||||
if useInstanceContentSettings {
|
||||
|
@ -68,23 +68,24 @@ public class UserPreferences: ObservableObject {
|
|||
Self.sharedDefault?.set(newValue, forKey: "push_notifications_count")
|
||||
}
|
||||
}
|
||||
|
||||
public var chosenFont: UIFont? {
|
||||
get {
|
||||
guard let chosenFontData,
|
||||
let font = try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIFont.self, from: chosenFontData) else { return nil }
|
||||
|
||||
return font
|
||||
}
|
||||
set {
|
||||
if let font = newValue,
|
||||
let data = try? NSKeyedArchiver.archivedData(withRootObject: font, requiringSecureCoding: false) {
|
||||
chosenFontData = data
|
||||
} else {
|
||||
chosenFontData = nil
|
||||
}
|
||||
}
|
||||
|
||||
public var chosenFont: UIFont? {
|
||||
get {
|
||||
guard let chosenFontData,
|
||||
let font = try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIFont.self, from: chosenFontData) else { return nil }
|
||||
|
||||
return font
|
||||
}
|
||||
set {
|
||||
if let font = newValue,
|
||||
let data = try? NSKeyedArchiver.archivedData(withRootObject: font, requiringSecureCoding: false)
|
||||
{
|
||||
chosenFontData = data
|
||||
} else {
|
||||
chosenFontData = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Published public var serverPreferences: ServerPreferences?
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ public struct HTMLString: Decodable, Equatable, Hashable {
|
|||
// other characters the markdown parser used picks up
|
||||
// when it renders to attributed text
|
||||
if let regex = try? NSRegularExpression(pattern: "([\\_\\`\\[\\\\])", options: .caseInsensitive) {
|
||||
htmlValue = regex.stringByReplacingMatches(in: htmlValue, options: [], range: NSRange(location: 0, length: htmlValue.count), withTemplate: "\\\\$1")
|
||||
htmlValue = regex.stringByReplacingMatches(in: htmlValue, options: [], range: NSRange(location: 0, length: htmlValue.count), withTemplate: "\\\\$1")
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
asMarkdown = try HTMLParser().parse(html: htmlValue)
|
||||
.toMarkdown()
|
||||
|
|
|
@ -32,8 +32,8 @@ struct NotificationRowView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.alignmentGuide(.listRowSeparatorLeading) { viewDimensions in
|
||||
return -100
|
||||
.alignmentGuide(.listRowSeparatorLeading) { _ in
|
||||
-100
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import DesignSystem
|
||||
import Models
|
||||
import SwiftUI
|
||||
import DesignSystem
|
||||
|
||||
extension Models.Notification.NotificationType {
|
||||
func label(count: Int) -> LocalizedStringKey {
|
||||
|
@ -42,7 +42,7 @@ extension Models.Notification.NotificationType {
|
|||
return "pencil.line"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func tintColor() -> Color {
|
||||
switch self {
|
||||
case .status, .mention, .update, .poll:
|
||||
|
|
|
@ -103,7 +103,7 @@ public struct NotificationsListView: View {
|
|||
bottom: 12,
|
||||
trailing: .layoutPadding))
|
||||
.listRowBackground(notification.type == .mention && lockedType != .mention ?
|
||||
theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
|
||||
theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,9 +144,9 @@ public struct NotificationsListView: View {
|
|||
trailing: .layoutPadding))
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
}
|
||||
|
||||
|
||||
private var topPaddingView: some View {
|
||||
HStack { }
|
||||
HStack {}
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowInsets(.init())
|
||||
|
|
|
@ -14,15 +14,15 @@ public struct StatusDetailView: View {
|
|||
@Environment(\.openURL) private var openURL
|
||||
@StateObject private var viewModel: StatusDetailViewModel
|
||||
@State private var isLoaded: Bool = false
|
||||
|
||||
|
||||
public init(statusId: String) {
|
||||
_viewModel = StateObject(wrappedValue: .init(statusId: statusId))
|
||||
}
|
||||
|
||||
|
||||
public init(remoteStatusURL: URL) {
|
||||
_viewModel = StateObject(wrappedValue: .init(remoteStatusURL: remoteStatusURL))
|
||||
}
|
||||
|
||||
|
||||
public var body: some View {
|
||||
ScrollViewReader { proxy in
|
||||
ZStack {
|
||||
|
@ -51,8 +51,8 @@ public struct StatusDetailView: View {
|
|||
StatusRowView(viewModel: .init(status: status,
|
||||
isCompact: false,
|
||||
isFocused: true))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.id(status.id)
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.id(status.id)
|
||||
Divider()
|
||||
.padding(.bottom, .dividerPadding * 2)
|
||||
if !context.descendants.isEmpty {
|
||||
|
@ -63,7 +63,7 @@ public struct StatusDetailView: View {
|
|||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case .error:
|
||||
ErrorView(title: "status.error.title",
|
||||
message: "status.error.message",
|
||||
|
|
|
@ -78,7 +78,7 @@ struct StatusEditorAccessoryView: View {
|
|||
Image(systemName: "globe")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if preferences.isOpenAIEnabled {
|
||||
AIMenu.disabled(!viewModel.canPost)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ struct StatusEditorAccessoryView: View {
|
|||
Text(isoCode.uppercased())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var AIMenu: some View {
|
||||
Menu {
|
||||
ForEach(StatusEditorAIPrompts.allCases, id: \.self) { prompt in
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import AVKit
|
||||
import SwiftUI
|
||||
import Env
|
||||
import SwiftUI
|
||||
|
||||
class VideoPlayerViewModel: ObservableObject {
|
||||
@Published var player: AVPlayer?
|
||||
|
@ -41,7 +41,7 @@ class VideoPlayerViewModel: ObservableObject {
|
|||
struct VideoPlayerView: View {
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
|
||||
|
||||
@StateObject var viewModel: VideoPlayerViewModel
|
||||
|
||||
var body: some View {
|
||||
|
|
|
@ -87,7 +87,7 @@ struct StatusActionsView: View {
|
|||
}
|
||||
.buttonStyle(.borderless)
|
||||
.disabled(action == .boost &&
|
||||
(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv))
|
||||
(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv))
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,8 @@ struct StatusRowContextMenu: View {
|
|||
}
|
||||
} label: {
|
||||
if let statusLanguage = viewModel.status.language,
|
||||
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage) {
|
||||
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage)
|
||||
{
|
||||
Label("status.action.translate-from-\(lanugageName)", systemImage: "captions.bubble")
|
||||
} else {
|
||||
Label("status.action.translate", systemImage: "captions.bubble")
|
||||
|
|
|
@ -317,7 +317,8 @@ public struct StatusRowView: View {
|
|||
ProgressView()
|
||||
} else {
|
||||
if let statusLanguage = status.language,
|
||||
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage) {
|
||||
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage)
|
||||
{
|
||||
Text("status.action.translate-from-\(lanugageName)")
|
||||
} else {
|
||||
Text("status.action.translate")
|
||||
|
@ -389,7 +390,7 @@ public struct StatusRowView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var remoteContentLoadingView: some View {
|
||||
ZStack(alignment: .center) {
|
||||
VStack {
|
||||
|
|
|
@ -71,7 +71,7 @@ public class StatusRowViewModel: ObservableObject {
|
|||
routerPath.navigate(to: .statusDetail(id: status.reblog?.id ?? status.id))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func navigateToAccountDetail(account: Account, routerPath: RouterPath) {
|
||||
if isRemote, let url = account.url {
|
||||
withAnimation {
|
||||
|
@ -85,7 +85,7 @@ public class StatusRowViewModel: ObservableObject {
|
|||
routerPath.navigate(to: .accountDetailWithAccount(account: account))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func navigateToMention(mention: Mention, routerPath: RouterPath) {
|
||||
if isRemote {
|
||||
withAnimation {
|
||||
|
|
Loading…
Reference in a new issue