Ferrite: Fix iOS 14 onAppear bug
onAppear does not fire properly on iOS 14 due to a longstanding bug in SwiftUI. Add a UIKit onAppear hook for listening to these events and implement inside the backport namespace. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
4512318e8f
commit
9ff7f5a7d5
23 changed files with 126 additions and 32 deletions
|
|
@ -46,8 +46,8 @@
|
||||||
0C50055B2992BA6A0064606A /* PluginTag+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C5005592992BA6A0064606A /* PluginTag+CoreDataProperties.swift */; };
|
0C50055B2992BA6A0064606A /* PluginTag+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C5005592992BA6A0064606A /* PluginTag+CoreDataProperties.swift */; };
|
||||||
0C54D36328C5086E00BFEEE2 /* History+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C54D36128C5086E00BFEEE2 /* History+CoreDataClass.swift */; };
|
0C54D36328C5086E00BFEEE2 /* History+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C54D36128C5086E00BFEEE2 /* History+CoreDataClass.swift */; };
|
||||||
0C54D36428C5086E00BFEEE2 /* History+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C54D36228C5086E00BFEEE2 /* History+CoreDataProperties.swift */; };
|
0C54D36428C5086E00BFEEE2 /* History+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C54D36228C5086E00BFEEE2 /* History+CoreDataProperties.swift */; };
|
||||||
0C572D4C2993FC2A003EEC05 /* OnAppearHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C572D4B2993FC2A003EEC05 /* OnAppearHandler.swift */; };
|
0C572D4C2993FC2A003EEC05 /* ViewDidAppearHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C572D4B2993FC2A003EEC05 /* ViewDidAppearHandler.swift */; };
|
||||||
0C572D4E299403B7003EEC05 /* DidAppearModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C572D4D299403B7003EEC05 /* DidAppearModifier.swift */; };
|
0C572D4E299403B7003EEC05 /* ViewDidAppearModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C572D4D299403B7003EEC05 /* ViewDidAppearModifier.swift */; };
|
||||||
0C57D4CC289032ED008534E8 /* SearchResultInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C57D4CB289032ED008534E8 /* SearchResultInfoView.swift */; };
|
0C57D4CC289032ED008534E8 /* SearchResultInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C57D4CB289032ED008534E8 /* SearchResultInfoView.swift */; };
|
||||||
0C5FCB05296744F300849E87 /* AllDebridCloudView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C5FCB04296744F300849E87 /* AllDebridCloudView.swift */; };
|
0C5FCB05296744F300849E87 /* AllDebridCloudView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C5FCB04296744F300849E87 /* AllDebridCloudView.swift */; };
|
||||||
0C64A4B4288903680079976D /* Base32 in Frameworks */ = {isa = PBXBuildFile; productRef = 0C64A4B3288903680079976D /* Base32 */; };
|
0C64A4B4288903680079976D /* Base32 in Frameworks */ = {isa = PBXBuildFile; productRef = 0C64A4B3288903680079976D /* Base32 */; };
|
||||||
|
|
@ -169,8 +169,8 @@
|
||||||
0C5005592992BA6A0064606A /* PluginTag+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PluginTag+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
0C5005592992BA6A0064606A /* PluginTag+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PluginTag+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
0C54D36128C5086E00BFEEE2 /* History+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "History+CoreDataClass.swift"; sourceTree = "<group>"; };
|
0C54D36128C5086E00BFEEE2 /* History+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "History+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
0C54D36228C5086E00BFEEE2 /* History+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "History+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
0C54D36228C5086E00BFEEE2 /* History+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "History+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
0C572D4B2993FC2A003EEC05 /* OnAppearHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnAppearHandler.swift; sourceTree = "<group>"; };
|
0C572D4B2993FC2A003EEC05 /* ViewDidAppearHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewDidAppearHandler.swift; sourceTree = "<group>"; };
|
||||||
0C572D4D299403B7003EEC05 /* DidAppearModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DidAppearModifier.swift; sourceTree = "<group>"; };
|
0C572D4D299403B7003EEC05 /* ViewDidAppearModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewDidAppearModifier.swift; sourceTree = "<group>"; };
|
||||||
0C57D4CB289032ED008534E8 /* SearchResultInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultInfoView.swift; sourceTree = "<group>"; };
|
0C57D4CB289032ED008534E8 /* SearchResultInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultInfoView.swift; sourceTree = "<group>"; };
|
||||||
0C5FCB04296744F300849E87 /* AllDebridCloudView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllDebridCloudView.swift; sourceTree = "<group>"; };
|
0C5FCB04296744F300849E87 /* AllDebridCloudView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllDebridCloudView.swift; sourceTree = "<group>"; };
|
||||||
0C68134F28BC1A2D00FAD890 /* GithubWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GithubWrapper.swift; sourceTree = "<group>"; };
|
0C68134F28BC1A2D00FAD890 /* GithubWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GithubWrapper.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -380,7 +380,7 @@
|
||||||
0CD5E78828CD932B001BF684 /* DisabledAppearance.swift */,
|
0CD5E78828CD932B001BF684 /* DisabledAppearance.swift */,
|
||||||
0CBAB83528D12ED500AC903E /* DisableInteraction.swift */,
|
0CBAB83528D12ED500AC903E /* DisableInteraction.swift */,
|
||||||
0CB6516428C5A5D700DCA721 /* InlinedList.swift */,
|
0CB6516428C5A5D700DCA721 /* InlinedList.swift */,
|
||||||
0C572D4D299403B7003EEC05 /* DidAppearModifier.swift */,
|
0C572D4D299403B7003EEC05 /* ViewDidAppearModifier.swift */,
|
||||||
);
|
);
|
||||||
path = Modifiers;
|
path = Modifiers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -531,7 +531,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0CA148CE288903F000DE2211 /* WebView.swift */,
|
0CA148CE288903F000DE2211 /* WebView.swift */,
|
||||||
0C572D4B2993FC2A003EEC05 /* OnAppearHandler.swift */,
|
0C572D4B2993FC2A003EEC05 /* ViewDidAppearHandler.swift */,
|
||||||
);
|
);
|
||||||
path = RepresentableViews;
|
path = RepresentableViews;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -745,7 +745,7 @@
|
||||||
0CA148EC288903F000DE2211 /* ContentView.swift in Sources */,
|
0CA148EC288903F000DE2211 /* ContentView.swift in Sources */,
|
||||||
0CC389532970AD900066D06F /* Action+CoreDataClass.swift in Sources */,
|
0CC389532970AD900066D06F /* Action+CoreDataClass.swift in Sources */,
|
||||||
0C03EB72296F619900162E9A /* PluginList+CoreDataProperties.swift in Sources */,
|
0C03EB72296F619900162E9A /* PluginList+CoreDataProperties.swift in Sources */,
|
||||||
0C572D4C2993FC2A003EEC05 /* OnAppearHandler.swift in Sources */,
|
0C572D4C2993FC2A003EEC05 /* ViewDidAppearHandler.swift in Sources */,
|
||||||
0C95D8D828A55B03005E22B3 /* DefaultActionsPickerViews.swift in Sources */,
|
0C95D8D828A55B03005E22B3 /* DefaultActionsPickerViews.swift in Sources */,
|
||||||
0C44E2AF28D52E8A007711AE /* BackupsView.swift in Sources */,
|
0C44E2AF28D52E8A007711AE /* BackupsView.swift in Sources */,
|
||||||
0CA148E1288903F000DE2211 /* Collection.swift in Sources */,
|
0CA148E1288903F000DE2211 /* Collection.swift in Sources */,
|
||||||
|
|
@ -795,7 +795,7 @@
|
||||||
0C4CFC4D28970C8B00AD9FAD /* SourceComplexQuery+CoreDataClass.swift in Sources */,
|
0C4CFC4D28970C8B00AD9FAD /* SourceComplexQuery+CoreDataClass.swift in Sources */,
|
||||||
0CA148E8288903F000DE2211 /* RealDebridWrapper.swift in Sources */,
|
0CA148E8288903F000DE2211 /* RealDebridWrapper.swift in Sources */,
|
||||||
0CA148D6288903F000DE2211 /* SettingsView.swift in Sources */,
|
0CA148D6288903F000DE2211 /* SettingsView.swift in Sources */,
|
||||||
0C572D4E299403B7003EEC05 /* DidAppearModifier.swift in Sources */,
|
0C572D4E299403B7003EEC05 /* ViewDidAppearModifier.swift in Sources */,
|
||||||
0CA148E5288903F000DE2211 /* DebridManager.swift in Sources */,
|
0CA148E5288903F000DE2211 /* DebridManager.swift in Sources */,
|
||||||
0C54D36328C5086E00BFEEE2 /* History+CoreDataClass.swift in Sources */,
|
0C54D36328C5086E00BFEEE2 /* History+CoreDataClass.swift in Sources */,
|
||||||
0CBAB83628D12ED500AC903E /* DisableInteraction.swift in Sources */,
|
0CBAB83628D12ED500AC903E /* DisableInteraction.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,8 @@ extension View {
|
||||||
func inlinedList() -> some View {
|
func inlinedList() -> some View {
|
||||||
modifier(InlinedList())
|
modifier(InlinedList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func viewDidAppear(_ callback: @escaping () -> Void) -> some View {
|
||||||
|
modifier(ViewDidAppearModifier(callback: callback))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ struct FerriteApp: App {
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
MainView()
|
MainView()
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
scrapingModel.toastModel = toastModel
|
scrapingModel.toastModel = toastModel
|
||||||
debridManager.toastModel = toastModel
|
debridManager.toastModel = toastModel
|
||||||
pluginManager.toastModel = toastModel
|
pluginManager.toastModel = toastModel
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
// Version is optional until v1 is phased out
|
||||||
public struct Backup: Codable {
|
public struct Backup: Codable {
|
||||||
let version: Int
|
let version: Int?
|
||||||
var bookmarks: [BookmarkJson]?
|
var bookmarks: [BookmarkJson]?
|
||||||
var history: [HistoryJson]?
|
var history: [HistoryJson]?
|
||||||
var sourceNames: [String]?
|
var sourceNames: [String]?
|
||||||
|
|
|
||||||
|
|
@ -161,8 +161,10 @@ public class BackupManager: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let storedLists = backup.sourceLists, (backup.version == 1) {
|
let version = backup.version ?? -1
|
||||||
// Only present in v1 backups
|
|
||||||
|
if let storedLists = backup.sourceLists, version < 2 {
|
||||||
|
// Only present in v1 or no version backups
|
||||||
for list in storedLists {
|
for list in storedLists {
|
||||||
try await pluginManager.addPluginList(list.urlString, existingPluginList: nil)
|
try await pluginManager.addPluginList(list.urlString, existingPluginList: nil)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,11 @@ public class PluginManager: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
toastModel?.updateToastDescription("Plugin fetch error: \(error)")
|
let error = error as NSError
|
||||||
|
if error.code != -999 {
|
||||||
|
toastModel?.updateToastDescription("Plugin fetch error: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
print("Plugin fetch error: \(error)")
|
print("Plugin fetch error: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,12 @@ extension View {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Backport where Content: View {
|
extension Backport where Content: View {
|
||||||
@ViewBuilder func alert(isPresented: Binding<Bool>, title: String, message: String?, buttons: [AlertButton] = []) -> some View {
|
@ViewBuilder func alert(
|
||||||
|
isPresented: Binding<Bool>,
|
||||||
|
title: String,
|
||||||
|
message: String?,
|
||||||
|
buttons: [AlertButton] = []
|
||||||
|
) -> some View {
|
||||||
if #available(iOS 15, *) {
|
if #available(iOS 15, *) {
|
||||||
content
|
content
|
||||||
.alert(
|
.alert(
|
||||||
|
|
@ -63,7 +68,11 @@ extension Backport where Content: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder func confirmationDialog(isPresented: Binding<Bool>, title: String, message: String?, buttons: [AlertButton]) -> some View {
|
@ViewBuilder func confirmationDialog(
|
||||||
|
isPresented: Binding<Bool>,
|
||||||
|
title: String, message: String?,
|
||||||
|
buttons: [AlertButton]
|
||||||
|
) -> some View {
|
||||||
if #available(iOS 15, *) {
|
if #available(iOS 15, *) {
|
||||||
content
|
content
|
||||||
.confirmationDialog(
|
.confirmationDialog(
|
||||||
|
|
@ -100,4 +109,18 @@ extension Backport where Content: View {
|
||||||
.accentColor(color)
|
.accentColor(color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder func onAppear(callback: @escaping () -> Void) -> some View {
|
||||||
|
if #available(iOS 15, *) {
|
||||||
|
content
|
||||||
|
.onAppear {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
.viewDidAppear {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ struct IndeterminateProgressView: View {
|
||||||
.offset(x: -reader.size.width * 0.6, y: 0)
|
.offset(x: -reader.size.width * 0.6, y: 0)
|
||||||
.offset(x: reader.size.width * 1.2 * self.offset, y: 0)
|
.offset(x: reader.size.width * 1.2 * self.offset, y: 0)
|
||||||
.animation(.default.repeatForever().speed(0.5), value: self.offset)
|
.animation(.default.repeatForever().speed(0.5), value: self.offset)
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
self.offset = 1
|
self.offset = 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
//
|
||||||
|
// ViewDidAppearModifier.swift
|
||||||
|
// Ferrite
|
||||||
|
//
|
||||||
|
// Created by Brian Dashore on 2/8/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ViewDidAppearModifier: ViewModifier {
|
||||||
|
let callback: () -> Void
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.background(ViewDidAppearHandler(callback: callback))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ struct BookmarksView: View {
|
||||||
}
|
}
|
||||||
.inlinedList()
|
.inlinedList()
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
if debridManager.enabledDebrids.count > 0 {
|
if debridManager.enabledDebrids.count > 0 {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
let magnets = bookmarks.compactMap {
|
let magnets = bookmarks.compactMap {
|
||||||
|
|
@ -72,7 +72,7 @@ struct BookmarksView: View {
|
||||||
viewTask?.cancel()
|
viewTask?.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
applyPredicate()
|
applyPredicate()
|
||||||
}
|
}
|
||||||
.onChange(of: searchText) { _ in
|
.onChange(of: searchText) { _ in
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ struct AllDebridCloudView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
await debridManager.fetchAdCloud()
|
await debridManager.fetchAdCloud()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ struct PremiumizeCloudView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
await debridManager.fetchPmCloud()
|
await debridManager.fetchPmCloud()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ struct RealDebridCloudView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
await debridManager.fetchRdCloud()
|
await debridManager.fetchRdCloud()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ struct HistoryView: View {
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
applyPredicate()
|
applyPredicate()
|
||||||
}
|
}
|
||||||
.onChange(of: searchText) { _ in
|
.onChange(of: searchText) { _ in
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ struct PluginListView<P: Plugin, PJ: PluginJson>: View {
|
||||||
.environmentObject(navModel)
|
.environmentObject(navModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
filteredAvailablePlugins = pluginManager.fetchFilteredPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
filteredAvailablePlugins = pluginManager.fetchFilteredPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||||
filteredUpdatedPlugins = pluginManager.fetchUpdatedPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
filteredUpdatedPlugins = pluginManager.fetchUpdatedPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ struct SourceSettingsBaseUrlView: View {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.keyboardType(.URL)
|
.keyboardType(.URL)
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
tempBaseUrl = selectedSource.baseUrl ?? ""
|
tempBaseUrl = selectedSource.baseUrl ?? ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ struct SourceSettingsApiView: View {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
tempClientId = clientId.value ?? ""
|
tempClientId = clientId.value ?? ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +140,7 @@ struct SourceSettingsApiView: View {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
tempClientSecret = clientSecret.value ?? ""
|
tempClientSecret = clientSecret.value ?? ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ struct SearchResultButtonView: View {
|
||||||
existingBookmark = nil
|
existingBookmark = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
// Only run a exists request if a bookmark isn't passed to the view
|
// Only run a exists request if a bookmark isn't passed to the view
|
||||||
if existingBookmark == nil, !runOnce {
|
if existingBookmark == nil, !runOnce {
|
||||||
let bookmarkRequest = Bookmark.fetchRequest()
|
let bookmarkRequest = Bookmark.fetchRequest()
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ struct BackupsView: View {
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
backupManager.backupUrls = FileManager.default.appDirectory
|
backupManager.backupUrls = FileManager.default.appDirectory
|
||||||
.appendingPathComponent("Backups", isDirectory: true).contentsByDateAdded
|
.appendingPathComponent("Backups", isDirectory: true).contentsByDateAdded
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ struct PluginListEditorView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.conditionalId(sourceUrlSet)
|
.conditionalId(sourceUrlSet)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
pluginListUrl = selectedPluginList?.urlString ?? ""
|
pluginListUrl = selectedPluginList?.urlString ?? ""
|
||||||
sourceUrlSet = true
|
sourceUrlSet = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ struct SettingsAppVersionView: View {
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
do {
|
do {
|
||||||
if let fetchedReleases = try await Github().fetchReleases() {
|
if let fetchedReleases = try await Github().fetchReleases() {
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ struct MainView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
if autoUpdateNotifs {
|
if autoUpdateNotifs {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
do {
|
do {
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ struct PluginsView: View {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.backport.onAppear {
|
||||||
viewTask = Task {
|
viewTask = Task {
|
||||||
await pluginManager.fetchPluginsFromUrl()
|
await pluginManager.fetchPluginsFromUrl()
|
||||||
checkedForPlugins = true
|
checkedForPlugins = true
|
||||||
|
|
|
||||||
43
Ferrite/Views/RepresentableViews/ViewDidAppearHandler.swift
Normal file
43
Ferrite/Views/RepresentableViews/ViewDidAppearHandler.swift
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// ViewDidAppearHandler.swift
|
||||||
|
// Ferrite
|
||||||
|
//
|
||||||
|
// Created by Brian Dashore on 2/8/23.
|
||||||
|
//
|
||||||
|
// UIKit onAppear hook to fix onAppear behavior in iOS 14
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ViewDidAppearHandler: UIViewControllerRepresentable {
|
||||||
|
let callback: () -> Void
|
||||||
|
|
||||||
|
class Coordinator: UIViewController {
|
||||||
|
let callback: () -> Void
|
||||||
|
|
||||||
|
init(callback: @escaping () -> Void) {
|
||||||
|
self.callback = callback
|
||||||
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable)
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(callback: callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> UIViewController {
|
||||||
|
context.coordinator
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue