Skip to content

Commit

Permalink
Add SiteSettingsView
Browse files Browse the repository at this point in the history
  • Loading branch information
kean committed Jun 12, 2023
1 parent b9a9ee8 commit 0dee1bb
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 0 deletions.
126 changes: 126 additions & 0 deletions WordPress/Classes/ViewRelated/Blog/Settings/SiteSettingsView.swift
Original file line number Diff line number Diff line change
@@ -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<T: View, U: View>(
@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")
}
}
}
Original file line number Diff line number Diff line change
@@ -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<String, Never>()

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")
}
}
20 changes: 20 additions & 0 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -6053,6 +6057,8 @@
0C391E5D2A2FE5350040EA91 /* DashboardBlazeCampaignView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardBlazeCampaignView.swift; sourceTree = "<group>"; };
0C391E602A3002950040EA91 /* DashboardBlazeCampaignStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardBlazeCampaignStatusView.swift; sourceTree = "<group>"; };
0C391E632A312DB20040EA91 /* DashboardBlazeCampaignViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardBlazeCampaignViewModelTests.swift; sourceTree = "<group>"; };
0C60DF782A377C3800509C91 /* SiteSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteSettingsView.swift; sourceTree = "<group>"; };
0C60DF7D2A37C90200509C91 /* SiteSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteSettingsViewModel.swift; sourceTree = "<group>"; };
0CB4056A29C78F06008EED0A /* BlogDashboardPersonalizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDashboardPersonalizationService.swift; sourceTree = "<group>"; };
0CB4056D29C7BA63008EED0A /* BlogDashboardPersonalizationServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDashboardPersonalizationServiceTests.swift; sourceTree = "<group>"; };
0CB4057029C8DCF4008EED0A /* BlogDashboardPersonalizationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDashboardPersonalizationViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -10023,6 +10029,15 @@
path = Mocks;
sourceTree = "<group>";
};
0C60DF7C2A37C8E800509C91 /* Settings */ = {
isa = PBXGroup;
children = (
0C60DF782A377C3800509C91 /* SiteSettingsView.swift */,
0C60DF7D2A37C90200509C91 /* SiteSettingsViewModel.swift */,
);
path = Settings;
sourceTree = "<group>";
};
0CB4056F29C8DCD7008EED0A /* BlogPersonalization */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -14752,6 +14767,7 @@
FA5C74091C596E69000B528C /* Site Management */,
FA73D7E72798766300DF24B3 /* Site Picker */,
3F43603823F36A76001DEE70 /* Site Settings */,
0C60DF7C2A37C8E800509C91 /* Settings */,
BE6AB7FB1BC62E0B00D980FC /* Style */,
);
path = Blog;
Expand Down Expand Up @@ -21353,6 +21369,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 */,
Expand Down Expand Up @@ -21565,6 +21582,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 */,
Expand Down Expand Up @@ -23772,6 +23790,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 */,
Expand Down Expand Up @@ -24875,6 +24894,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 */,
Expand Down

0 comments on commit 0dee1bb

Please sign in to comment.