diff --git a/Modules/Sources/WordPressUI/Views/Settings/SecureTextField.swift b/Modules/Sources/WordPressUI/Views/Settings/SecureTextField.swift new file mode 100644 index 000000000000..3317cab43e61 --- /dev/null +++ b/Modules/Sources/WordPressUI/Views/Settings/SecureTextField.swift @@ -0,0 +1,65 @@ +import SwiftUI +import UIKit + +/// - note: The SwiftUI version of the secure text field does not allow you to +/// change to the "view password" mode while preserving the focus – you have +/// to create a separate (regular) text field for that, and it loses focus. +public struct SecureTextField: UIViewRepresentable { + @Binding var text: String + var isSecure: Bool + let placeholder: String + + public init(text: Binding, isSecure: Bool, placeholder: String) { + self._text = text + self.isSecure = isSecure + self.placeholder = placeholder + } + + public func makeUIView(context: Context) -> UITextField { + let textField = UITextField() + textField.placeholder = placeholder + textField.isSecureTextEntry = isSecure + textField.borderStyle = .none + textField.isSecureTextEntry = true + textField.textContentType = .password + textField.autocorrectionType = .no + textField.autocapitalizationType = .none + textField.spellCheckingType = .no + textField.adjustsFontForContentSizeCategory = true + textField.addTarget(context.coordinator, action: #selector(Coordinator.textFieldDidChange), for: .editingChanged) + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { + textField.becomeFirstResponder() + } + return textField + } + + public func updateUIView(_ textView: UITextField, context: Context) { + textView.text = text + textView.isSecureTextEntry = isSecure + textView.font = { + if isSecure { + return UIFont.preferredFont(forTextStyle: .body) + } + guard let font = UIFont(name: "Menlo", size: 17) else { + return UIFont.preferredFont(forTextStyle: .body) + } + return UIFontMetrics(forTextStyle: .body).scaledFont(for: font) + }() + } + + public func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + public class Coordinator: NSObject { + let parent: SecureTextField + + init(_ parent: SecureTextField) { + self.parent = parent + } + + @objc func textFieldDidChange(_ textField: UITextField) { + parent.text = textField.text ?? "" + } + } +} diff --git a/Modules/Sources/WordPressUI/Views/Settings/SettingsCheckmark.swift b/Modules/Sources/WordPressUI/Views/Settings/SettingsCheckmark.swift new file mode 100644 index 000000000000..99d383895c9c --- /dev/null +++ b/Modules/Sources/WordPressUI/Views/Settings/SettingsCheckmark.swift @@ -0,0 +1,18 @@ +import SwiftUI +import DesignSystem + +public struct SettingsCheckmark: View { + let isSelected: Bool + + public init(isSelected: Bool) { + self.isSelected = isSelected + } + + public var body: some View { + Image(systemName: "checkmark") + .font(.headline) + .opacity(isSelected ? 1 : 0) + .foregroundStyle(AppColor.primary) + .symbolEffect(.bounce.up, value: isSelected) + } +} diff --git a/Modules/Sources/WordPressUI/Views/Settings/SettingsRow.swift b/Modules/Sources/WordPressUI/Views/Settings/SettingsRow.swift new file mode 100644 index 000000000000..f1904965af25 --- /dev/null +++ b/Modules/Sources/WordPressUI/Views/Settings/SettingsRow.swift @@ -0,0 +1,32 @@ +import SwiftUI + +public struct SettingsRow: View { + let title: String + let content: Content + + public init(_ title: String, @ViewBuilder content: () -> Content) { + self.title = title + self.content = content() + } + + public var body: some View { + HStack { + Text(title) + .layoutPriority(1) + Spacer() + content + .font(.callout) + .foregroundColor(.secondary) + .textSelection(.enabled) + } + .lineLimit(1) + } +} + +public extension SettingsRow where Content == Text { + init(_ title: String, value: String) { + self.init(title) { + Text(value) + } + } +} diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 5b3672489631..20d9d2fca552 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,6 +1,9 @@ 26.5 ----- +* [**] Add "Status" field to the "Post Settings" screen to make it easier to move posts from one state to another [#24939] +* [*] Add "Publish Date" back to "Post Settings" for draft and pending posts [#24939] +* [*] Use "Menlo" font for the password field to make it easier to distinguish between characters like `0` and `0` [#24939] 26.4 ----- diff --git a/WordPress/Classes/Services/PostCoordinator.swift b/WordPress/Classes/Services/PostCoordinator.swift index a3e0bacf6b9c..5afd0b748efd 100644 --- a/WordPress/Classes/Services/PostCoordinator.swift +++ b/WordPress/Classes/Services/PostCoordinator.swift @@ -82,32 +82,11 @@ class PostCoordinator: NSObject { /// with the publishing options. @MainActor func publish(_ post: AbstractPost, parameters: RemotePostUpdateParameters = .init()) async throws { - wpAssert(post.isOriginal()) - wpAssert(post.isStatus(in: [.draft, .pending])) - - await pauseSyncing(for: post) - defer { resumeSyncing(for: post) } - var parameters = parameters if parameters.status == nil { parameters.status = Post.Status.publish.rawValue } - if parameters.date == nil { - // If the post was previously scheduled for a different date, - // the app has to send a new value to override it. - parameters.date = post.shouldPublishImmediately() ? nil : Date() - } - - do { - let repository = PostRepository(coreDataStack: coreDataStack) - try await repository.save(post, changes: parameters) - didPublish(post) - show(PostCoordinator.makeUploadSuccessNotice(for: post)) - } catch { - trackError(error, operation: "post-publish", post: post) - handleError(error, for: post) - throw error - } + try await save(post, changes: parameters) } @MainActor @@ -129,9 +108,32 @@ class PostCoordinator: NSObject { await pauseSyncing(for: post) defer { resumeSyncing(for: post) } + let previousStatus = post.status + + var changes = changes ?? .init() + + // If the post was previously scheduled and the user wants to publish + // it without specifying a new publish date, we have to send `.now` + // to ensure it gets published immediatelly. + if (changes.status == Post.Status.publish.rawValue || + changes.status == Post.Status.publishPrivate.rawValue) && + previousStatus == .scheduled && + changes.date == nil { + changes.date = .now + } + do { - let previousStatus = post.status try await PostRepository().save(post, changes: changes) + + if previousStatus != post.status && post.isStatus(in: [.scheduled, .publish]) { + if post.status == .scheduled { + notifyNewPostScheduled() + } else if post.status == .publish { + notifyNewPostPublished() + } + SearchManager.shared.indexItem(post) + AppRatingUtility.shared.incrementSignificantEvent() + } show(PostCoordinator.makeUploadSuccessNotice(for: post, previousStatus: previousStatus)) return post } catch { diff --git a/WordPress/Classes/ViewRelated/Post/PostSettings/Extensions/PostStatus+Extensions.swift b/WordPress/Classes/ViewRelated/Post/PostSettings/Extensions/PostStatus+Extensions.swift new file mode 100644 index 000000000000..9f401149a3f7 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Post/PostSettings/Extensions/PostStatus+Extensions.swift @@ -0,0 +1,42 @@ +import SwiftUI +import WordPressData +import WordPressShared + +extension BasePost.Status: @retroactive Identifiable { + public var id: Self { self } + + var title: String { + switch self { + case .draft: NSLocalizedString("postStatus.draft.title", value: "Draft", comment: "Post status title") + case .pending: NSLocalizedString("postStatus.pending.title", value: "Pending", comment: "Post status title") + case .publishPrivate: NSLocalizedString("postStatus.private.title", value: "Private", comment: "Post status title") + case .scheduled: NSLocalizedString("postStatus.scheduled.title", value: "Scheduled", comment: "Post status title") + case .publish: NSLocalizedString("postStatus.published.title", value: "Published", comment: "Post status title") + case .trash: NSLocalizedString("postStatus.trash.title", value: "Trashed", comment: "Post status title") + case .deleted: NSLocalizedString("postStatus.deleted.title", value: "Deleted", comment: "Post status title") + } + } + + var details: String { + switch self { + case .draft: NSLocalizedString("postStatus.draft.details", value: "Not ready to publish", comment: "Post status details") + case .pending: NSLocalizedString("postStatus.pending.details", value: "Waiting for review before publishing", comment: "Post status details") + case .publishPrivate: NSLocalizedString("postStatus.private.details", value: "Only visible to site admins and editors", comment: "Post status details") + case .scheduled: NSLocalizedString("postStatus.scheduled.details", value: "Publish automatically on a chosen date", comment: "Post status details") + case .publish: NSLocalizedString("postStatus.published.details", value: "Visible to everyone", comment: "Post status details") + case .trash: NSLocalizedString("postStatus.trash.details", value: "Trashed but not deleted yet", comment: "Post status title") + case .deleted: NSLocalizedString("postStatus.deleted.details", value: "Permanently deleted", comment: "Post status title") + } + } + + var image: String { + switch self { + case .draft: "post-status-draft" + case .pending: "post-status-pending" + case .publishPrivate: "post-status-private" + case .scheduled: "post-status-scheduled" + case .publish: "post-status-published" + case .trash, .deleted: "" // We don't show these anywhere in the UI + } + } +} diff --git a/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift b/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift index 5b2600bb0c0b..b08be4faad2f 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift +++ b/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift @@ -240,11 +240,11 @@ struct PostSettingsFormContentView: View { @ViewBuilder private var generalSection: some View { Section { - authorRow - if !viewModel.isDraftOrPending || viewModel.context == .publishing { - publishDateRow - visibilityRow + if viewModel.context != .publishing { + statusRow } + authorRow + publishDateRow slugRow } header: { SectionHeader(Strings.generalHeader) @@ -264,6 +264,21 @@ struct PostSettingsFormContentView: View { } } + private var statusRow: some View { + NavigationLink { + PostStatusView(settings: $viewModel.settings, timeZone: viewModel.timeZone) + } label: { + SettingsRow(Strings.status) { + HStack(alignment: .center, spacing: 2) { + ScaledImage(viewModel.settings.status.image, height: 23) + VStack(alignment: .leading, spacing: 2) { + Text(viewModel.settings.status.title) + } + } + } + } + } + private var pendingReviewRow: some View { Toggle(isOn: $viewModel.settings.isPendingReview) { Text(Strings.pendingReviewLabel) @@ -410,29 +425,6 @@ private struct PostSettingsAuthorRow: View { } } -@MainActor -private struct SettingsRow: View { - let title: String - let value: String - - init(_ title: String, value: String) { - self.title = title - self.value = value - } - - var body: some View { - HStack { - Text(title) - .layoutPriority(1) - Spacer() - Text(value) - .foregroundColor(.secondary) - .textSelection(.enabled) - } - .lineLimit(1) - } -} - @MainActor private struct SettingsTextFieldView: View { let title: String @@ -638,4 +630,10 @@ private enum Strings { value: "Ready to Publish?", comment: "The title of the top section that shows the site your are publishing to. Default is 'Ready to Publish?'" ) + + static let status = NSLocalizedString( + "postSettings.status.label", + value: "Status", + comment: "Label for the status field in Post Settings" + ) } diff --git a/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsViewModel.swift b/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsViewModel.swift index d6c7faaaf75d..849d82ca6485 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsViewModel.swift @@ -53,6 +53,10 @@ final class PostSettingsViewModel: NSObject, ObservableObject { guard let date = settings.publishDate else { return nil } + return Self.formattedDate(date, in: timeZone) + } + + static func formattedDate(_ date: Date, in timeZone: TimeZone) -> String { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short @@ -264,7 +268,7 @@ final class PostSettingsViewModel: NSObject, ObservableObject { do { let settings = getSettingsToSave(for: self.settings) let coordinator = PostCoordinator.shared - if coordinator.isSyncAllowed(for: post) { + if coordinator.isSyncAllowed(for: post) && post.status == settings.status { let revision = post.createRevision() settings.apply(to: revision) coordinator.setNeedsSync(for: revision) diff --git a/WordPress/Classes/ViewRelated/Post/PostSettings/Views/PostSettingsPasswordEntryView.swift b/WordPress/Classes/ViewRelated/Post/PostSettings/Views/PostSettingsPasswordEntryView.swift new file mode 100644 index 000000000000..bf7513b9d123 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Post/PostSettings/Views/PostSettingsPasswordEntryView.swift @@ -0,0 +1,67 @@ +import SwiftUI +import WordPressUI + +struct PostSettingsPasswordEntryView: View { + let password: String + + @State private var input = "" + @State private var isSecure = true + + @Environment(\.dismiss) private var dismiss + + var onSave: (String) -> Void + var onCancel: () -> Void + + var body: some View { + NavigationStack { + Form { + Section { + HStack { + SecureTextField(text: $input, isSecure: isSecure, placeholder: Strings.placeholder) + .fixedSize(horizontal: false, vertical: true) + + Button { + isSecure.toggle() + } label: { + Image(systemName: isSecure ? "eye" : "eye.slash") + .foregroundStyle(.secondary) + } + .buttonStyle(.plain) + .accessibilityLabel(isSecure ? Strings.showPassword : Strings.hidePassword) + } + } footer: { + Text(Strings.instructions) + } + } + .navigationTitle(Strings.title) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button.make(role: .cancel) { + onCancel() + dismiss() + } + } + + ToolbarItem(placement: .navigationBarTrailing) { + Button.make(role: .confirm) { + onSave(input) + dismiss() + } + .disabled(input.isEmpty) + } + } + } + .onAppear { + input = password + } + } +} + +private enum Strings { + static let title = NSLocalizedString("postSettings.passwordEntry.navigationTitle", value: "Enter Password", comment: "Navigation title for password entry screen") + static let placeholder = NSLocalizedString("postSettings.passwordEntry.placeholder", value: "Enter password", comment: "Placeholder for password field") + static let instructions = NSLocalizedString("postSettings.passwordEntry.instructions", value: "Enter a password to protect this post. Only users with the password will be able to view it.", comment: "Instructions for password entry") + static let showPassword = NSLocalizedString("postSettings.passwordEntry.showPassword", value: "Show password", comment: "Accessibility label for show password button") + static let hidePassword = NSLocalizedString("postSettings.passwordEntry.hidePassword", value: "Hide password", comment: "Accessibility label for hide password button") +} diff --git a/WordPress/Classes/ViewRelated/Post/PostSettings/Views/PostStatusView.swift b/WordPress/Classes/ViewRelated/Post/PostSettings/Views/PostStatusView.swift new file mode 100644 index 000000000000..00f319fd03d9 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Post/PostSettings/Views/PostStatusView.swift @@ -0,0 +1,238 @@ +import SwiftUI +import WordPressUI +import WordPressData + +struct PostStatusView: View { + @Binding var settings: PostSettings + let timeZone: TimeZone + + @State private var isShowingPublishDatePicker = false + @State private var isShowingPasswordEntry = false + @State private var publishDate = Date() + @State private var password = "" + + @ScaledMetric + private var statusRowLeadingInset: CGFloat = PostStatusRow.leadingInset + + private let statuses = [BasePost.Status.draft, .pending, .publishPrivate, .scheduled, .publish] + + var body: some View { + Form { + statusSection + if settings.status != .publishPrivate { + passwordSection + } + stickySection + } + .dynamicTypeSize(...DynamicTypeSize.accessibility1) + .animation(.default, value: settings) + .navigationTitle(Strings.title) + .navigationBarTitleDisplayMode(.inline) + .sheet(isPresented: $isShowingPublishDatePicker) { + NavigationStack { + PostStatusPublishDatePicker(selection: settings.publishDate, timeZone: timeZone) { + settings.status = .scheduled + settings.publishDate = $0 + } + } + .presentationDetents([.large]) + } + .sheet(isPresented: $isShowingPasswordEntry) { + passwordEntryView + } + } + + @ViewBuilder + private var statusSection: some View { + Section { + ForEach(statuses) { status in + Button { + switch status { + case .draft, .pending, .publishPrivate, .publish: + if settings.status == .scheduled { + settings.publishDate = nil + } + settings.status = status + case .scheduled: + isShowingPublishDatePicker = true + default: + wpAssertionFailure("unsupported case") + } + } label: { + VStack { + PostStatusRow(status: status, isSelected: settings.status == status) + if status == .scheduled && settings.status == .scheduled, let date = settings.publishDate { + HStack { + SettingsRow(Strings.scheduleDate, value: PostSettingsViewModel.formattedDate(date, in: timeZone)) + Image(systemName: "chevron.forward") + .font(.footnote.weight(.semibold)) + .foregroundColor(Color(.tertiaryLabel)) + } + .padding(.leading, statusRowLeadingInset) + .padding(.top, 8) + } + } + } + .buttonStyle(.plain) + .accessibilityLabel(status.title) + } + } + } + + @ViewBuilder + private var passwordSection: some View { + Section { + VStack(alignment: .leading, spacing: 0) { + Toggle(isOn: Binding( + get: { !(settings.password ?? "").isEmpty }, + set: { newValue in + if newValue { + isShowingPasswordEntry = true + } else { + settings.password = nil + } + } + )) { + VStack(alignment: .leading, spacing: 2) { + Text(Strings.passwordProtected) + Text(Strings.passwordProtectedSubtitle) + .font(.footnote) + .foregroundStyle(.secondary) + } + } + } + if !(settings.password ?? "").isEmpty { + Button { + isShowingPasswordEntry = true + } label: { + HStack { + Text(Strings.passwordLabel) + Spacer() + Text("••••••••••••") + .font(.footnote.monospaced()) + .foregroundStyle(.secondary) + Image(systemName: "chevron.forward") + .font(.subheadline.weight(.medium)) + .foregroundStyle(.secondary.opacity(0.5)) + } + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } + } + } + + @ViewBuilder + private var stickySection: some View { + Section { + Toggle(isOn: $settings.isStickyPost) { + VStack(alignment: .leading, spacing: 2) { + Text(Strings.sticky) + Text(Strings.stickySubtitle) + .font(.footnote) + .foregroundStyle(.secondary) + } + } + } + } + + private var passwordEntryView: some View { + PostSettingsPasswordEntryView( + password: password, + onSave: { + settings.password = $0 + }, + onCancel: { + // Do nothing + } + ) + .presentationDetents([.large]) + } +} + +private struct PostStatusPublishDatePicker: View { + let selection: Date? + let timeZone: TimeZone + let onSubmit: (Date) -> Void + + @State private var newSelection: Date? + + @Environment(\.dismiss) var dismiss + + var body: some View { + PublishDatePickerView(configuration: PublishDatePickerConfiguration( + date: selection, + isRequired: true, + timeZone: timeZone, + range: Date.now...Date.distantFuture, + updated: { date in + newSelection = date + } + )) + .onAppear { + newSelection = selection + } + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button.make(role: .cancel) { + dismiss() + } + } + ToolbarItem(placement: .topBarTrailing) { + Button.make(role: .confirm) { + if let newSelection { + onSubmit(newSelection) + } + dismiss() + } + .disabled(newSelection == nil) + } + } + } +} + +private struct PostStatusRow: View { + let status: BasePost.Status + let isSelected: Bool + + @ScaledMetric + private var leadingInset: CGFloat = Self.leadingInset + + static let leadingInset: CGFloat = 28 + + var body: some View { + HStack(alignment: .center, spacing: 0) { + HStack(alignment: .top, spacing: 0) { + ScaledImage(status.image, height: 23) + .foregroundStyle(isSelected ? Color.primary : .secondary.opacity(0.66)) + .frame(width: leadingInset, alignment: .leading) + .offset(y: -1) + VStack(alignment: .leading, spacing: 2) { + Text(status.title) + .font(isSelected ? .body.weight(.medium) : .body) + .foregroundStyle(.primary) + Text(status.details) + .font(.footnote) + .foregroundStyle(.secondary) + } + } + Spacer(minLength: 0) + SettingsCheckmark(isSelected: isSelected) + } + .contentShape(Rectangle()) + } +} + +private enum Strings { + static let title = NSLocalizedString("postSettings.statusPicker.navigationTitle", value: "Status & Visibility", comment: "Navigation title for status picker") + + static let passwordProtected = NSLocalizedString("postSettings.statusPicker.passwordProtected", value: "Password Protected", comment: "Toggle label for password protection") + static let passwordProtectedSubtitle = NSLocalizedString("postSettings.statusPicker.passwordProtectedSubtitle", value: "Only visible to those who know the password", comment: "Subtitle for password protected toggle") + + static let sticky = NSLocalizedString("postSettings.statusPicker.sticky", value: "Sticky", comment: "Toggle label for sticky posts") + static let stickySubtitle = NSLocalizedString("postSettings.statusPicker.stickySubtitle", value: "Pin this post to the top of the blog", comment: "Subtitle for sticky toggle") + + static let passwordLabel = NSLocalizedString("postSettings.statusPicker.passwordLabel", value: "Password", comment: "Label showing the current password") + + static let scheduleDate = NSLocalizedString("postSettings.statusPicker.scheduleDate", value: "Date", comment: "Label for schedule date row") +} diff --git a/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift b/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift index 133e82f18507..f9ea122d78a9 100644 --- a/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift +++ b/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift @@ -11,6 +11,7 @@ struct PublishDatePickerConfiguration { /// If set to `true`, the user will no longer be able to remove the selection. var isRequired = false var timeZone: TimeZone + var range = Date.distantPast...Date.distantFuture var updated: (Date?) -> Void } @@ -90,7 +91,7 @@ struct PublishDatePickerView: View { configuration.date ?? Date() }, set: { configuration.date = $0 - }), displayedComponents: [.date, .hourAndMinute]) + }), in: configuration.range, displayedComponents: [.date, .hourAndMinute]) .environment(\.timeZone, configuration.timeZone) .datePickerStyle(.graphical) .labelsHidden() diff --git a/WordPress/Resources/AppImages.xcassets/post-status/Contents.json b/WordPress/Resources/AppImages.xcassets/post-status/Contents.json new file mode 100644 index 000000000000..73c00596a7fc --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-draft.imageset/Contents.json b/WordPress/Resources/AppImages.xcassets/post-status/post-status-draft.imageset/Contents.json new file mode 100644 index 000000000000..cf2c7a3491d8 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-draft.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "post-status-draft.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-draft.imageset/post-status-draft.svg b/WordPress/Resources/AppImages.xcassets/post-status/post-status-draft.imageset/post-status-draft.svg new file mode 100644 index 000000000000..e5533413fda3 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-draft.imageset/post-status-draft.svg @@ -0,0 +1,3 @@ + + + diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-pending.imageset/Contents.json b/WordPress/Resources/AppImages.xcassets/post-status/post-status-pending.imageset/Contents.json new file mode 100644 index 000000000000..dc306c93b44c --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-pending.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "post-status-pending.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-pending.imageset/post-status-pending.svg b/WordPress/Resources/AppImages.xcassets/post-status/post-status-pending.imageset/post-status-pending.svg new file mode 100644 index 000000000000..fb66b339cac9 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-pending.imageset/post-status-pending.svg @@ -0,0 +1,3 @@ + + + diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-private.imageset/Contents.json b/WordPress/Resources/AppImages.xcassets/post-status/post-status-private.imageset/Contents.json new file mode 100644 index 000000000000..1077c0c91524 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-private.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "post-status-private.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-private.imageset/post-status-private.svg b/WordPress/Resources/AppImages.xcassets/post-status/post-status-private.imageset/post-status-private.svg new file mode 100644 index 000000000000..f4c213af7820 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-private.imageset/post-status-private.svg @@ -0,0 +1,3 @@ + + + diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-published.imageset/Contents.json b/WordPress/Resources/AppImages.xcassets/post-status/post-status-published.imageset/Contents.json new file mode 100644 index 000000000000..cef277eb056d --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-published.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "post-status-published.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-published.imageset/post-status-published.svg b/WordPress/Resources/AppImages.xcassets/post-status/post-status-published.imageset/post-status-published.svg new file mode 100644 index 000000000000..3dc6a10efe54 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-published.imageset/post-status-published.svg @@ -0,0 +1,3 @@ + + + diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-scheduled.imageset/Contents.json b/WordPress/Resources/AppImages.xcassets/post-status/post-status-scheduled.imageset/Contents.json new file mode 100644 index 000000000000..97e5cba87b31 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-scheduled.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "post-status-scheduled.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/WordPress/Resources/AppImages.xcassets/post-status/post-status-scheduled.imageset/post-status-scheduled.svg b/WordPress/Resources/AppImages.xcassets/post-status/post-status-scheduled.imageset/post-status-scheduled.svg new file mode 100644 index 000000000000..fd5b47ec7a89 --- /dev/null +++ b/WordPress/Resources/AppImages.xcassets/post-status/post-status-scheduled.imageset/post-status-scheduled.svg @@ -0,0 +1,3 @@ + + +