From 877042b6afab2bfca38c0a50eb66986002709424 Mon Sep 17 00:00:00 2001 From: kean Date: Mon, 12 Jun 2023 13:43:38 -0400 Subject: [PATCH 1/4] Add SiteSettingsView --- .../Blog/Settings/SiteSettingsView.swift | 126 ++++++++++++++++++ .../Blog/Settings/SiteSettingsViewModel.swift | 41 ++++++ WordPress/WordPress.xcodeproj/project.pbxproj | 20 +++ 3 files changed, 187 insertions(+) create mode 100644 WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift create mode 100644 WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift new file mode 100644 index 000000000000..a8ede2d491bd --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift @@ -0,0 +1,126 @@ +import Foundation +import SwiftUI +import Combine +import SVProgressHUD + +struct SiteSettingsView: View { + @ObservedObject private var blog: Blog + @ObservedObject private var settings: BlogSettings + + @StateObject private var viewModel: SiteSettingsViewModel + + @SwiftUI.Environment(\.presentationMode) private var presentationMode + + init(blog: Blog) { + self.blog = blog + self.settings = blog.settings ?? BlogSettings(context: ContextManager.shared.mainContext) // Right-side should never happen + self._viewModel = StateObject(wrappedValue: SiteSettingsViewModel(blog: blog)) + } + + var body: some View { + List { + Section(header: Text(Strings.Sections.general), content: { + siteTitleRow + }) + } + .listStyle(.insetGrouped) + .navigationTitle(Strings.title) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + if presentationMode.wrappedValue.isPresented { + closeButton + } + } + } + .onReceive(viewModel.onDismissableError) { + SVProgressHUD.showDismissibleError(withStatus: $0) + } + } + + // MARK: - General + + private var siteTitleRow: some View { + withAdminNavigationLink(destination: { + SettingsTextEditView( + value: settings.name, + placeholder: Strings.General.siteTitlePlaceholder, + onCommit: viewModel.updateSiteTitle + ) + .navigationTitle(Strings.General.siteTitle) + }) { + SettingsCell(title: Strings.General.siteTitle, value: settings.name ?? Strings.General.siteTitlePlaceholder) + } + } + + // MARK: - Helpers + + @ViewBuilder + private func withAdminNavigationLink( + @ViewBuilder destination: () -> T, + @ViewBuilder content: () -> U + ) -> some View { + if blog.isAdmin { + NavigationLink(destination: destination(), label: content) + } else { + content() + } + } + + private var closeButton: some View { + Button(action: { presentationMode.wrappedValue.dismiss() }) { + Text(Strings.done) + .font(.body.weight(.medium)) + .foregroundColor(Color.primary) + } + } +} + +private struct SettingsCell: View { + let title: String + let value: String + + var body: some View { + HStack { + Text(title) + .layoutPriority(1) + Spacer() + Text(value) + .foregroundColor(.secondary) + } + .lineLimit(1) + } +} + +private struct SettingsTextEditView: UIViewControllerRepresentable { + let value: String? + let placeholder: String + var hint: String? + let onCommit: ((String)) -> Void + + func makeUIViewController(context: Context) -> SettingsTextViewController { + let viewController = SettingsTextViewController(text: value ?? "", placeholder: placeholder, hint: hint ?? "") + viewController.onValueChanged = onCommit + return viewController + } + + func updateUIViewController(_ uiViewController: SettingsTextViewController, context: Context) { + // Do nothing + } +} + +private extension SiteSettingsView { + enum Strings { + static let title = NSLocalizedString("Settings", comment: "Title for screen that allows configuration of your blog/site settings.") + static let done = NSLocalizedString("Done", comment: "Label for Done button") + + enum Sections { + static let general = NSLocalizedString("General", comment: "Title for the general section in site settings screen") + } + + enum General { + static let siteTitle = NSLocalizedString("Site Title", comment: "Label for site title blog setting") + static let siteTitlePlaceholder = NSLocalizedString("A title for the site", comment: "Placeholder text for the title of a site") + } + } +} diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift new file mode 100644 index 000000000000..a9d2a122a6bc --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift @@ -0,0 +1,41 @@ +import Foundation +import SwiftUI +import Combine + +final class SiteSettingsViewModel: ObservableObject { + private let blog: Blog + private let service: BlogService + + let onDismissableError = PassthroughSubject() + + init(blog: Blog) { + self.blog = blog + self.service = BlogService(coreDataStack: ContextManager.shared) + } + + func updateSiteTitle(_ value: String) { + guard value != blog.settings?.name else { return } + blog.settings?.name = value + save() + trackSettingsChange(fieldName: "site_title") + } + + private func save() { + service.updateSettings(for: blog, success: { + NotificationCenter.default.post(name: .WPBlogSettingsUpdated, object: nil) + }, failure: { [weak self] error in + self?.onDismissableError.send(Strings.saveFailed) + DDLogError("Error while trying to update BlogSettings: \(error)") + }) + } + + private func trackSettingsChange(fieldName: String, value: Any? = nil) { + WPAnalytics.trackSettingsChange("site_settings", fieldName: fieldName, value: value) + } +} + +private extension SiteSettingsViewModel { + enum Strings { + static let saveFailed = NSLocalizedString("Settings update failed", comment: "Message to show when setting save failed") + } +} diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index fc18f3e753eb..24f3468cc8f0 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -346,6 +346,10 @@ 0C391E612A3002950040EA91 /* DashboardBlazeCampaignStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C391E602A3002950040EA91 /* DashboardBlazeCampaignStatusView.swift */; }; 0C391E622A3002950040EA91 /* DashboardBlazeCampaignStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C391E602A3002950040EA91 /* DashboardBlazeCampaignStatusView.swift */; }; 0C391E642A312DB20040EA91 /* DashboardBlazeCampaignViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C391E632A312DB20040EA91 /* DashboardBlazeCampaignViewModelTests.swift */; }; + 0C60DF792A377C3800509C91 /* SiteSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C60DF782A377C3800509C91 /* SiteSettingsView.swift */; }; + 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 */; }; 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 */; }; @@ -6054,6 +6058,8 @@ 0C391E5D2A2FE5350040EA91 /* DashboardBlazeCampaignView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardBlazeCampaignView.swift; sourceTree = ""; }; 0C391E602A3002950040EA91 /* DashboardBlazeCampaignStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardBlazeCampaignStatusView.swift; sourceTree = ""; }; 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 = ""; }; 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 = ""; }; @@ -10025,6 +10031,15 @@ path = Mocks; sourceTree = ""; }; + 0C60DF7C2A37C8E800509C91 /* Settings */ = { + isa = PBXGroup; + children = ( + 0C60DF782A377C3800509C91 /* SiteSettingsView.swift */, + 0C60DF7D2A37C90200509C91 /* SiteSettingsViewModel.swift */, + ); + path = Settings; + sourceTree = ""; + }; 0CB4056F29C8DCD7008EED0A /* BlogPersonalization */ = { isa = PBXGroup; children = ( @@ -14755,6 +14770,7 @@ FA5C74091C596E69000B528C /* Site Management */, FA73D7E72798766300DF24B3 /* Site Picker */, 3F43603823F36A76001DEE70 /* Site Settings */, + 0C60DF7C2A37C8E800509C91 /* Settings */, BE6AB7FB1BC62E0B00D980FC /* Style */, ); path = Blog; @@ -21356,6 +21372,7 @@ E64384831C628FCC0052ADB5 /* WPStyleGuide+Sharing.swift in Sources */, F504D2B025D60C5900A2764C /* StoryPoster.swift in Sources */, 981C82B62193A7B900A06E84 /* Double+Stats.swift in Sources */, + 0C60DF792A377C3800509C91 /* SiteSettingsView.swift in Sources */, 175507B327A062980038ED28 /* PublicizeConnectionURLMatcher.swift in Sources */, 177074851FB209F100951A4A /* CircularProgressView.swift in Sources */, 3F8B45A9292C1F2C00730FA4 /* DashboardMigrationSuccessCell.swift in Sources */, @@ -21568,6 +21585,7 @@ C81CCD81243BF7A600A83E27 /* TenorService.swift in Sources */, 8B51844525893F140085488D /* FilterBarView.swift in Sources */, E105205B1F2B1CF400A948F6 /* BlogToBlogMigration_61_62.swift in Sources */, + 0C60DF7E2A37C90200509C91 /* SiteSettingsViewModel.swift in Sources */, FE3E83E526A58646008CE851 /* ListSimpleOverlayView.swift in Sources */, 98B88452261E4E09007ED7F8 /* LikeUserTableViewCell.swift in Sources */, E16FB7E31F8B61040004DD9F /* WebKitViewController.swift in Sources */, @@ -23776,6 +23794,7 @@ FABB20F02602FC2C00C8785C /* ReaderDetailToolbar.swift in Sources */, 80A2154429D1177A002FE8EB /* RemoteConfigDebugViewController.swift in Sources */, FAD1263D2A0CF2F50004E24C /* String+NonbreakingSpace.swift in Sources */, + 0C60DF7A2A377C3800509C91 /* SiteSettingsView.swift in Sources */, FABB20F12602FC2C00C8785C /* RecentSitesService.swift in Sources */, FA332AD129C1F97A00182FBB /* MovedToJetpackViewController.swift in Sources */, 8BD66ED52787530C00CCD95A /* PostsCardViewModel.swift in Sources */, @@ -24879,6 +24898,7 @@ FABB241A2602FC2C00C8785C /* PostToPost30To31.m in Sources */, FABB241B2602FC2C00C8785C /* GutenGhostView.swift in Sources */, FABB241C2602FC2C00C8785C /* ModelSettableCell.swift in Sources */, + 0C60DF7F2A37C90200509C91 /* SiteSettingsViewModel.swift in Sources */, FABB241D2602FC2C00C8785C /* FollowCommentsService.swift in Sources */, 4AA33F022999D11A005B6E23 /* ReaderSiteTopic+Lookup.swift in Sources */, FABB241E2602FC2C00C8785C /* ForcePopoverPresenter.swift in Sources */, From 8044c30c77b1159797c575c79ea25a64b070a1bc Mon Sep 17 00:00:00 2001 From: kean Date: Mon, 12 Jun 2023 18:34:08 -0400 Subject: [PATCH 2/4] Add Site Settings refresh --- .../Classes/Extensions/SwiftUI+Backport.swift | 20 ++++++++++++ .../Blog/Settings/SiteSettingsView.swift | 32 +++++++++++++------ .../Blog/Settings/SiteSettingsViewModel.swift | 11 +++++++ WordPress/WordPress.xcodeproj/project.pbxproj | 6 ++++ 4 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 WordPress/Classes/Extensions/SwiftUI+Backport.swift 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..7c380c6258b1 100644 --- a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift @@ -19,22 +19,34 @@ struct SiteSettingsView: View { var body: some View { List { - Section(header: Text(Strings.Sections.general), content: { - siteTitleRow - }) + sections } .listStyle(.insetGrouped) + .onReceive(viewModel.onDismissableError) { + SVProgressHUD.showDismissibleError(withStatus: $0) + } + .backport.refreshable { + await viewModel.refresh() + } + .onAppear { + Task { await viewModel.refresh() } + } .navigationTitle(Strings.title) .navigationBarTitleDisplayMode(.inline) - .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { - if presentationMode.wrappedValue.isPresented { - closeButton - } + .toolbar { toolbar } + } + + private var toolbar: some ToolbarContent { + ToolbarItem(placement: .navigationBarTrailing) { + if presentationMode.wrappedValue.isPresented { + closeButton } } - .onReceive(viewModel.onDismissableError) { - SVProgressHUD.showDismissibleError(withStatus: $0) + } + + private var sections: some View { + Section(header: Text(Strings.Sections.general)) { + siteTitleRow } } 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 24f3468cc8f0..f34afee9b744 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 */; }; @@ -6060,6 +6062,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 = ""; }; @@ -15241,6 +15244,7 @@ C7AFF873283C0ADC000E01DF /* UIApplication+Helpers.swift */, C3AB4878292F114A001F7AF8 /* UIApplication+AppAvailability.swift */, F49D7BEA29DF329500CB93A5 /* UIPopoverPresentationController+PopoverAnchor.swift */, + 0C60DF802A37CFED00509C91 /* SwiftUI+Backport.swift */, ); path = Extensions; sourceTree = ""; @@ -22333,6 +22337,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 */, @@ -24329,6 +24334,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 */, From b16704dbc6fc41516b9bc71a2b39c3ef6983ad41 Mon Sep 17 00:00:00 2001 From: kean Date: Wed, 14 Jun 2023 09:04:56 -0400 Subject: [PATCH 3/4] Update localizable strings on new Site Settings screen to use namespaces --- .../ViewRelated/Blog/Settings/SiteSettingsView.swift | 10 +++++----- .../Blog/Settings/SiteSettingsViewModel.swift | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift index 7c380c6258b1..16a354487749 100644 --- a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift @@ -123,16 +123,16 @@ private struct SettingsTextEditView: UIViewControllerRepresentable { private extension SiteSettingsView { enum Strings { - static let title = NSLocalizedString("Settings", comment: "Title for screen that allows configuration of your blog/site settings.") - static let done = NSLocalizedString("Done", comment: "Label for Done button") + static let title = NSLocalizedString("siteSettings.title", value: "Settings", comment: "Title for screen that allows configuration of your blog/site settings.") + static let done = NSLocalizedString("siteSettings.done", value: "Done", comment: "Label for Done button") enum Sections { - static let general = NSLocalizedString("General", comment: "Title for the general section in site settings screen") + static let general = NSLocalizedString("siteSettings.general.title", value: "General", comment: "Title for the general section in site settings screen") } enum General { - static let siteTitle = NSLocalizedString("Site Title", comment: "Label for site title blog setting") - static let siteTitlePlaceholder = NSLocalizedString("A title for the site", comment: "Placeholder text for the title of a site") + static let siteTitle = NSLocalizedString("siteSettings.general.siteTitle", value: "Site Title", comment: "Label for site title blog setting") + static let siteTitlePlaceholder = NSLocalizedString("siteSettings.general.siteTitlePlaceholder", value: "A title for the site", comment: "Placeholder text for the title of a site") } } } diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift index 9c45bf6fb623..299d62e8f881 100644 --- a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift @@ -47,6 +47,6 @@ final class SiteSettingsViewModel: ObservableObject { private extension SiteSettingsViewModel { enum Strings { - static let saveFailed = NSLocalizedString("Settings update failed", comment: "Message to show when setting save failed") + static let saveFailed = NSLocalizedString("siteSettings.updateFailedMessage", value: "Settings update failed", comment: "Message to show when setting save failed") } } From 71a7368ed17cde887761336a89eac4c5199074aa Mon Sep 17 00:00:00 2001 From: kean Date: Wed, 14 Jun 2023 12:17:40 -0400 Subject: [PATCH 4/4] Inject BlogService --- .../ViewRelated/Blog/Settings/SiteSettingsViewModel.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift index 299d62e8f881..849ccc9f3109 100644 --- a/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsViewModel.swift @@ -8,9 +8,10 @@ final class SiteSettingsViewModel: ObservableObject { let onDismissableError = PassthroughSubject() - init(blog: Blog) { + init(blog: Blog, + service: BlogService = BlogService(coreDataStack: ContextManager.shared)) { self.blog = blog - self.service = BlogService(coreDataStack: ContextManager.shared) + self.service = service } func refresh() async -> Void {