diff --git a/WordPress/Classes/Extensions/SwiftUI+Backport.swift b/WordPress/Classes/Extensions/SwiftUI+Backport.swift new file mode 100644 index 000000000000..17a9802f91ab --- /dev/null +++ b/WordPress/Classes/Extensions/SwiftUI+Backport.swift @@ -0,0 +1,20 @@ +import SwiftUI + +struct Backport { + let view: T +} + +extension View { + var backport: Backport { Backport(view: self) } +} + +extension Backport { + @ViewBuilder + func refreshable(action: @Sendable @escaping () async -> Void) -> some View { + if #available(iOS 15, *) { + view.refreshable(action: action) + } else { + view + } + } +} diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift index a8ede2d491bd..ee3e208d5756 100644 --- a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift @@ -19,11 +19,12 @@ struct SiteSettingsView: View { var body: some View { List { - Section(header: Text(Strings.Sections.general), content: { - siteTitleRow - }) + sections } .listStyle(.insetGrouped) + .backport.refreshable { + await viewModel.refresh() + } .navigationTitle(Strings.title) .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -36,6 +37,16 @@ struct SiteSettingsView: View { .onReceive(viewModel.onDismissableError) { SVProgressHUD.showDismissibleError(withStatus: $0) } + .onAppear { + Task { await viewModel.refresh() } + } + } + + @ViewBuilder + private var sections: some View { + Section(header: Text(Strings.Sections.general)) { + siteTitleRow + } } // MARK: - General diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift index a9d2a122a6bc..9c45bf6fb623 100644 --- a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift @@ -13,6 +13,17 @@ final class SiteSettingsViewModel: ObservableObject { self.service = BlogService(coreDataStack: ContextManager.shared) } + func refresh() async -> Void { + await withUnsafeContinuation { continuation in + service.syncSettings(for: blog, success: { + continuation.resume() + }, failure: { error in + continuation.resume() + DDLogError("Error while refreshing blog settings: \(error)") + }) + } + } + func updateSiteTitle(_ value: String) { guard value != blog.settings?.name else { return } blog.settings?.name = value diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 9e5a316206bc..9b12f7e42eb0 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -350,6 +350,8 @@ 0C60DF7A2A377C3800509C91 /* SiteSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C60DF782A377C3800509C91 /* SiteSettingsView.swift */; }; 0C60DF7E2A37C90200509C91 /* SiteSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C60DF7D2A37C90200509C91 /* SiteSettingsViewModel.swift */; }; 0C60DF7F2A37C90200509C91 /* SiteSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C60DF7D2A37C90200509C91 /* SiteSettingsViewModel.swift */; }; + 0C60DF812A37CFED00509C91 /* SwiftUI+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C60DF802A37CFED00509C91 /* SwiftUI+Backport.swift */; }; + 0C60DF822A37CFED00509C91 /* SwiftUI+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C60DF802A37CFED00509C91 /* SwiftUI+Backport.swift */; }; 0CB4056B29C78F06008EED0A /* BlogDashboardPersonalizationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB4056A29C78F06008EED0A /* BlogDashboardPersonalizationService.swift */; }; 0CB4056C29C78F06008EED0A /* BlogDashboardPersonalizationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB4056A29C78F06008EED0A /* BlogDashboardPersonalizationService.swift */; }; 0CB4056E29C7BA63008EED0A /* BlogDashboardPersonalizationServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB4056D29C7BA63008EED0A /* BlogDashboardPersonalizationServiceTests.swift */; }; @@ -6059,6 +6061,7 @@ 0C391E632A312DB20040EA91 /* DashboardBlazeCampaignViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardBlazeCampaignViewModelTests.swift; sourceTree = ""; }; 0C60DF782A377C3800509C91 /* SiteSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteSettingsView.swift; sourceTree = ""; }; 0C60DF7D2A37C90200509C91 /* SiteSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteSettingsViewModel.swift; sourceTree = ""; }; + 0C60DF802A37CFED00509C91 /* SwiftUI+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftUI+Backport.swift"; sourceTree = ""; }; 0CB4056A29C78F06008EED0A /* BlogDashboardPersonalizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDashboardPersonalizationService.swift; sourceTree = ""; }; 0CB4056D29C7BA63008EED0A /* BlogDashboardPersonalizationServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDashboardPersonalizationServiceTests.swift; sourceTree = ""; }; 0CB4057029C8DCF4008EED0A /* BlogDashboardPersonalizationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDashboardPersonalizationViewModel.swift; sourceTree = ""; }; @@ -15238,6 +15241,7 @@ C7AFF873283C0ADC000E01DF /* UIApplication+Helpers.swift */, C3AB4878292F114A001F7AF8 /* UIApplication+AppAvailability.swift */, F49D7BEA29DF329500CB93A5 /* UIPopoverPresentationController+PopoverAnchor.swift */, + 0C60DF802A37CFED00509C91 /* SwiftUI+Backport.swift */, ); path = Extensions; sourceTree = ""; @@ -22330,6 +22334,7 @@ 176CE91627FB44C100F1E32B /* StatsBaseCell.swift in Sources */, E1C2260723901AAD0021D03C /* WordPressOrgRestApi+WordPress.swift in Sources */, B53B02B31CAC3AAC003190A0 /* GravatarPickerViewController.swift in Sources */, + 0C60DF812A37CFED00509C91 /* SwiftUI+Backport.swift in Sources */, D81879D920ABC647000CFA95 /* ReaderTableConfiguration.swift in Sources */, 3F758FD524F6FB4900BBA2FC /* AnnouncementsStore.swift in Sources */, E6D2E1691B8AAD9B0000ED14 /* ReaderListStreamHeader.swift in Sources */, @@ -24325,6 +24330,7 @@ FABB226C2602FC2C00C8785C /* ParentPageSettingsViewController.swift in Sources */, FABB226D2602FC2C00C8785C /* Queue.swift in Sources */, FABB226E2602FC2C00C8785C /* SwitchTableViewCell.swift in Sources */, + 0C60DF822A37CFED00509C91 /* SwiftUI+Backport.swift in Sources */, 3FBB2D2C27FB6CB200C57BBF /* SiteNameViewController.swift in Sources */, 17171375265FAA8A00F3A022 /* BloggingRemindersNavigationController.swift in Sources */, FABB226F2602FC2C00C8785C /* ReaderTopicToReaderSiteTopic37to38.swift in Sources */,