From 9cd7001c5917c6d26a2bcd9c6ddd528804ad1cb2 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 11:38:52 -0800 Subject: [PATCH 01/14] Add edit notices strings. --- WMF Framework/CommonStrings.swift | 1 + Wikipedia.xcodeproj/project.pbxproj | 40 ++++++++++++++++++ .../en.lproj/Localizable.strings | 3 ++ .../qqq.lproj/Localizable.strings | 3 ++ .../en.lproj/Localizable.strings | Bin 406604 -> 407262 bytes 5 files changed, 47 insertions(+) diff --git a/WMF Framework/CommonStrings.swift b/WMF Framework/CommonStrings.swift index 83e84b1c7df..79cc12f53a6 100644 --- a/WMF Framework/CommonStrings.swift +++ b/WMF Framework/CommonStrings.swift @@ -146,6 +146,7 @@ public class CommonStrings: NSObject { @objc public static let okTitle = WMFLocalizedString("button-ok", value: "OK", comment: "Button text for ok button used in various places {{Identical|OK}}") @objc public static let doneTitle = WMFLocalizedString("description-published-button-title", value: "Done", comment: "Title for description panel done button.") + @objc public static let editNotices = WMFLocalizedString("edit-notices", value: "Edit notices", comment: "Title text and accessibility label for edit notices button.") @objc public static let undo = WMFLocalizedString("action-undo", value: "Undo", comment: "Title text and accessibility label for undo action on buttons or info sheets.") @objc public static let redo = WMFLocalizedString("action-redo", value: "Redo", comment: "Title text and accessibility label for redo action on buttons or info sheets.") @objc public static let findInPage = WMFLocalizedString("action-find-in-page", value: "Find in page", comment: "Title text and accessibility label for find in page action on buttons or info sheets.") diff --git a/Wikipedia.xcodeproj/project.pbxproj b/Wikipedia.xcodeproj/project.pbxproj index b90faec089a..3956637cedd 100644 --- a/Wikipedia.xcodeproj/project.pbxproj +++ b/Wikipedia.xcodeproj/project.pbxproj @@ -37,6 +37,10 @@ 0033D79E24F8193900CAB5B3 /* CGPoint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0033D79C24F8193900CAB5B3 /* CGPoint+Extensions.swift */; }; 0033D7A124F8199300CAB5B3 /* Sparkline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0033D7A024F8199300CAB5B3 /* Sparkline.swift */; }; 0036C8B3282C2AAA00EADB35 /* Notification+NotificationsCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0036C8B2282C2AAA00EADB35 /* Notification+NotificationsCenter.swift */; }; + 003AD72E2979C512005BDB90 /* EditNoticesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003AD72D2979C512005BDB90 /* EditNoticesViewModel.swift */; }; + 003AD72F2979C512005BDB90 /* EditNoticesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003AD72D2979C512005BDB90 /* EditNoticesViewModel.swift */; }; + 003AD7302979C512005BDB90 /* EditNoticesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003AD72D2979C512005BDB90 /* EditNoticesViewModel.swift */; }; + 003AD7312979C512005BDB90 /* EditNoticesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003AD72D2979C512005BDB90 /* EditNoticesViewModel.swift */; }; 003CD3E928EF7C77000158E4 /* TalkPageFindInPageSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003CD3E828EF7C77000158E4 /* TalkPageFindInPageSearchController.swift */; }; 003CD3EA28EF7C77000158E4 /* TalkPageFindInPageSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003CD3E828EF7C77000158E4 /* TalkPageFindInPageSearchController.swift */; }; 003CD3EB28EF7C77000158E4 /* TalkPageFindInPageSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003CD3E828EF7C77000158E4 /* TalkPageFindInPageSearchController.swift */; }; @@ -222,6 +226,14 @@ 007F5C70275AA74200E4B02C /* StackedImageLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007F5C6C275AA74200E4B02C /* StackedImageLabelView.swift */; }; 00841DE524477805003CF74A /* AppTabBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE891452445150B0058B642 /* AppTabBarDelegate.swift */; }; 00841DE724477806003CF74A /* AppTabBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE891452445150B0058B642 /* AppTabBarDelegate.swift */; }; + 009B8358298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B8357298091BC00AABEA3 /* EditNoticesViewController.swift */; }; + 009B8359298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B8357298091BC00AABEA3 /* EditNoticesViewController.swift */; }; + 009B835A298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B8357298091BC00AABEA3 /* EditNoticesViewController.swift */; }; + 009B835B298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B8357298091BC00AABEA3 /* EditNoticesViewController.swift */; }; + 009B835D298091CD00AABEA3 /* EditNoticesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B835C298091CD00AABEA3 /* EditNoticesView.swift */; }; + 009B835E298091CD00AABEA3 /* EditNoticesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B835C298091CD00AABEA3 /* EditNoticesView.swift */; }; + 009B835F298091CD00AABEA3 /* EditNoticesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B835C298091CD00AABEA3 /* EditNoticesView.swift */; }; + 009B8360298091CD00AABEA3 /* EditNoticesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009B835C298091CD00AABEA3 /* EditNoticesView.swift */; }; 009C8EC229071E720056A3AC /* NSString+Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009C8EC129071E720056A3AC /* NSString+Range.swift */; }; 009C8EC329071E720056A3AC /* NSString+Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009C8EC129071E720056A3AC /* NSString+Range.swift */; }; 009C8EC429071E720056A3AC /* NSString+Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009C8EC129071E720056A3AC /* NSString+Range.swift */; }; @@ -243,6 +255,10 @@ 00AA5AAE276BF2AE005295B0 /* TextBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00AA5AAB276BF2AE005295B0 /* TextBarButtonItem.swift */; }; 00AA5AAF276BF2AE005295B0 /* TextBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00AA5AAB276BF2AE005295B0 /* TextBarButtonItem.swift */; }; 00AB75BD24D4E8FB0041056A /* WMF.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D844D96C1D6CB2600042D692 /* WMF.framework */; }; + 00B0B3D02978745400DD7893 /* EditNoticesFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B0B3CF2978745400DD7893 /* EditNoticesFetcher.swift */; }; + 00B0B3D12978745400DD7893 /* EditNoticesFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B0B3CF2978745400DD7893 /* EditNoticesFetcher.swift */; }; + 00B0B3D22978745400DD7893 /* EditNoticesFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B0B3CF2978745400DD7893 /* EditNoticesFetcher.swift */; }; + 00B0B3D32978745400DD7893 /* EditNoticesFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B0B3CF2978745400DD7893 /* EditNoticesFetcher.swift */; }; 00B16E8E293AACC200EF847F /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B16E8D293AACC200EF847F /* UIImage+Extensions.swift */; }; 00BCB71826DEE04D002C3F72 /* InsetLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00BCB71726DEE04D002C3F72 /* InsetLabelView.swift */; }; 00BCB71926DEE11B002C3F72 /* InsetLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00BCB71726DEE04D002C3F72 /* InsetLabelView.swift */; }; @@ -3850,6 +3866,7 @@ 0033D79C24F8193900CAB5B3 /* CGPoint+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGPoint+Extensions.swift"; sourceTree = ""; }; 0033D7A024F8199300CAB5B3 /* Sparkline.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sparkline.swift; sourceTree = ""; }; 0036C8B2282C2AAA00EADB35 /* Notification+NotificationsCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+NotificationsCenter.swift"; sourceTree = ""; }; + 003AD72D2979C512005BDB90 /* EditNoticesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditNoticesViewModel.swift; sourceTree = ""; }; 003CD3E828EF7C77000158E4 /* TalkPageFindInPageSearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TalkPageFindInPageSearchController.swift; sourceTree = ""; }; 0042804025E6E395004945B3 /* FLAnimatedImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImage.m; sourceTree = ""; }; 0042804125E6E395004945B3 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = ""; }; @@ -4000,12 +4017,15 @@ 007CCF0B26D5A5E400D5EA7C /* NotificationsCenterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsCenterViewModel.swift; sourceTree = ""; }; 007CCF1026D5BF1300D5EA7C /* NotificationsCenterPresentationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsCenterPresentationDelegate.swift; sourceTree = ""; }; 007F5C6C275AA74200E4B02C /* StackedImageLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedImageLabelView.swift; sourceTree = ""; usesTabs = 0; }; + 009B8357298091BC00AABEA3 /* EditNoticesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditNoticesViewController.swift; sourceTree = ""; }; + 009B835C298091CD00AABEA3 /* EditNoticesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditNoticesView.swift; sourceTree = ""; }; 009C8EC129071E720056A3AC /* NSString+Range.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSString+Range.swift"; sourceTree = ""; }; 00A7946A245CA4E60063BA18 /* ArticleSurveyTimerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSurveyTimerController.swift; sourceTree = ""; usesTabs = 0; }; 00A8F58526BDD5E700175B8E /* WidgetSampleContentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSampleContentTests.swift; sourceTree = ""; }; 00A988072829D92B006D800B /* PushNotificationContentIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationContentIdentifier.swift; sourceTree = ""; }; 00AA5AA6276BF29E005295B0 /* StatusTextBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTextBarButtonItem.swift; sourceTree = ""; }; 00AA5AAB276BF2AE005295B0 /* TextBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBarButtonItem.swift; sourceTree = ""; }; + 00B0B3CF2978745400DD7893 /* EditNoticesFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditNoticesFetcher.swift; sourceTree = ""; }; 00B16E8D293AACC200EF847F /* UIImage+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extensions.swift"; sourceTree = ""; }; 00BCB71726DEE04D002C3F72 /* InsetLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsetLabelView.swift; sourceTree = ""; }; 00BCB71C26DEE1C7002C3F72 /* VerticalSpacerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalSpacerView.swift; sourceTree = ""; }; @@ -6362,6 +6382,9 @@ 7A196F5921BF199500D9E4B5 /* SectionEditorWebView.swift */, 7A32078721E40193009E1677 /* SectionEditorMenuItemsController.swift */, 83F26B29220B62EC002D87A4 /* SectionEditorButton.swift */, + 003AD72D2979C512005BDB90 /* EditNoticesViewModel.swift */, + 009B8357298091BC00AABEA3 /* EditNoticesViewController.swift */, + 009B835C298091CD00AABEA3 /* EditNoticesView.swift */, ); name = SectionEditor; sourceTree = ""; @@ -6408,6 +6431,7 @@ B09B03F11CE0FB6300009083 /* PageHistoryFetcher.swift */, 67E8B0A7226A654D00537BC9 /* OldTalkPageFetcher.swift */, 838790B22858009000067B1D /* TalkPageFetcher.swift */, + 00B0B3CF2978745400DD7893 /* EditNoticesFetcher.swift */, ); name = Fetchers; path = Wikipedia/Code; @@ -11494,6 +11518,7 @@ B0E803441C0CD7980065EBC0 /* WMFSearchFetcher.m in Sources */, 83B01F7C23DB0BA2001185F4 /* ArticleViewController+Editing.swift in Sources */, BCA15AE51C0E213300D0A3EA /* LoggingDefaults.swift in Sources */, + 003AD72E2979C512005BDB90 /* EditNoticesViewModel.swift in Sources */, 005E004128DE1F2800721584 /* TalkPageCoffeeRollViewModel.swift in Sources */, 67B5334128416C0D00C33E13 /* UserDataExportCache.swift in Sources */, 7A741DCA207FB9CC00CBAAE2 /* SearchBarExtendedViewController.swift in Sources */, @@ -11505,6 +11530,7 @@ 67B64D5C2507E9FD00FA27F3 /* ArticleAsLivingDocSmallEventCollectionViewCell.swift in Sources */, B0E803911C0CDABE0065EBC0 /* UIView+WMFSnapshotting.m in Sources */, D818D3811ED7254D0076110D /* ColumnarCollectionViewController.swift in Sources */, + 009B835D298091CD00AABEA3 /* EditNoticesView.swift in Sources */, 672428972362113400490629 /* DiffFetcher.swift in Sources */, 83E776A320FFA4D700E26A47 /* DetailTransition.swift in Sources */, 832BD3BC28996B68002623CA /* VanishAccountContentView.swift in Sources */, @@ -11615,6 +11641,7 @@ B0E802B81C0CD2140065EBC0 /* UIBarButtonItem+WMFButtonConvenience.m in Sources */, B08E7E9B1C1FA57A00EC3C99 /* UIViewController+WMFEmptyView.m in Sources */, FFD7B85624B3B384005C2471 /* ReferenceBackLinksViewControllerDelegate.swift in Sources */, + 009B8358298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */, 003CD3E928EF7C77000158E4 /* TalkPageFindInPageSearchController.swift in Sources */, B0524B1F214854E900D8FD8D /* DescriptionWelcomeInitialViewController.swift in Sources */, D80BF0A32347735E00B3B522 /* AppSearchButton.swift in Sources */, @@ -11791,6 +11818,7 @@ 6798332922C3F28A0073CE6F /* UITextView+Extensions.swift in Sources */, B031032D1F677BEC00E2FCF6 /* WMFWelcomeExplorationViewController.swift in Sources */, 7AE99B2E21CC53AB0092BE7F /* TextFontFormattingTableViewController.swift in Sources */, + 00B0B3D02978745400DD7893 /* EditNoticesFetcher.swift in Sources */, 00E5B39F28EB8E2100D2C51A /* TalkPageTopicReplyOnboardingView.swift in Sources */, 6782DBC12343FDCA003FA21B /* DiffListChangeCell.swift in Sources */, 7A32078821E40193009E1677 /* SectionEditorMenuItemsController.swift in Sources */, @@ -12466,6 +12494,7 @@ 8351CE7B20D4424100E32FC1 /* CollectionViewHeader.swift in Sources */, 6734EE7922976AED00F00B05 /* ActionButton.swift in Sources */, 7A0CD24321DFA34100066F68 /* TextFormattingToolbarView.swift in Sources */, + 003AD7312979C512005BDB90 /* EditNoticesViewModel.swift in Sources */, 005E004428DE1F2800721584 /* TalkPageCoffeeRollViewModel.swift in Sources */, 67B5334428416C0F00C33E13 /* UserDataExportCache.swift in Sources */, 83B01F7F23DB0BA2001185F4 /* ArticleViewController+Editing.swift in Sources */, @@ -12477,6 +12506,7 @@ 6782DBFF234537D0003FA21B /* DiffHeaderExtendedView.swift in Sources */, D8A42A971E815A9C00D8E281 /* MWKTitleLanguageController.m in Sources */, D8A42A981E815A9C00D8E281 /* UIView+WMFSnapshotting.m in Sources */, + 009B8360298091CD00AABEA3 /* EditNoticesView.swift in Sources */, 6724289A2362113A00490629 /* DiffFetcher.swift in Sources */, 6747118B25072D1500287951 /* IconTitleBadge.swift in Sources */, 832BD3BF28996B68002623CA /* VanishAccountContentView.swift in Sources */, @@ -12587,6 +12617,7 @@ 83E52BB71F681F940045E776 /* ShareAFactViewController.swift in Sources */, D8A42AD51E815A9C00D8E281 /* UIViewController+WMFEmptyView.m in Sources */, BAA0D91F1F4F165A00091284 /* PageIssuesTableViewController.swift in Sources */, + 009B835B298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */, 003CD3EC28EF7C77000158E4 /* TalkPageFindInPageSearchController.swift in Sources */, B0524B22214854E900D8FD8D /* DescriptionWelcomeInitialViewController.swift in Sources */, D8A42ADD1E815A9C00D8E281 /* NSUserDefaults+WMFApplicationDefaults.swift in Sources */, @@ -12763,6 +12794,7 @@ BA7683C71F30D87D00A487AA /* ProminentSwitch.swift in Sources */, 6782DBAC2343B7FC003FA21B /* DiffHeaderEditorView.swift in Sources */, D8A42B4B1E815A9C00D8E281 /* WMFLanguageCell.m in Sources */, + 00B0B3D32978745400DD7893 /* EditNoticesFetcher.swift in Sources */, 00E5B3A228EB8E2100D2C51A /* TalkPageTopicReplyOnboardingView.swift in Sources */, 7A1469C0220BBE44000A20F1 /* EditHintViewController.swift in Sources */, 6798332C22C3F2950073CE6F /* UITextView+Extensions.swift in Sources */, @@ -13041,6 +13073,7 @@ 83A171D82819B6A70029FB89 /* UNAuthorizationStatus+String.swift in Sources */, 67DC5BEA23A03FE700B03A84 /* ArticleToolbarController.swift in Sources */, D8CE25121E698E2400DAE2E0 /* WMFEmptyView.m in Sources */, + 009B835A298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */, 7AE1FE3221B4A9790068BE9F /* TextFormattingButtonView.swift in Sources */, D8CE25151E698E2400DAE2E0 /* WMFSettingsTableViewCell.m in Sources */, 7A35CB881FD82B6300AAF3B7 /* ReadingListDetailViewController.swift in Sources */, @@ -13198,6 +13231,7 @@ 67B5334328416C0E00C33E13 /* UserDataExportCache.swift in Sources */, 8361474C24223689003E49D3 /* ArticleViewController+Announcements.swift in Sources */, 83023C2020E6584F00EC7592 /* SearchTransition.swift in Sources */, + 003AD7302979C512005BDB90 /* EditNoticesViewModel.swift in Sources */, 677129A224FFF43000E89CA5 /* ArticleAsLivingDocHorizontallyScrollingCell.swift in Sources */, 676F392A2745FB2000F4D33D /* NotificationsCenterFiltersViewModel.swift in Sources */, 0042813725E6E841004945B3 /* NYTPhotoDismissalInteractionController.m in Sources */, @@ -13206,6 +13240,7 @@ 67861A18223C13940044F69D /* FocusNavigationView.swift in Sources */, 6734EE7322976AE300F00B05 /* InfoBannerView.swift in Sources */, 00FCB2C526D839A500F5A47A /* NotificationsCenterCellViewModel.swift in Sources */, + 00B0B3D22978745400DD7893 /* EditNoticesFetcher.swift in Sources */, D8BDA8BE1E71B8C90031F4BF /* WMFDeleteBackwardReportingTextField.swift in Sources */, 83023C0720E51DDF00EC7592 /* SearchLanguagesBarViewController.swift in Sources */, D8CE25771E698E2400DAE2E0 /* MWKLanguageLinkFetcher.m in Sources */, @@ -13246,6 +13281,7 @@ BA4524251F32500C00439C42 /* TextSizeChangeExampleViewController.swift in Sources */, D8CE25891E698E2400DAE2E0 /* UIImageView+WMFFaceDetectionBasedOnUIApplicationSharedApplication.m in Sources */, D8CE258E1E698E2400DAE2E0 /* UIView+WMFFrameUtils.m in Sources */, + 009B835F298091CD00AABEA3 /* EditNoticesView.swift in Sources */, D8E6FF6D24056AC300686272 /* ArticleViewController+ContextMenu.swift in Sources */, 8386BDFC2386D754007EE89D /* SinglePageWebViewController.swift in Sources */, D8CE258F1E698E2400DAE2E0 /* WMFWelcomeAnimationViewControllers.swift in Sources */, @@ -13639,6 +13675,7 @@ 83A171D72819B6A60029FB89 /* UNAuthorizationStatus+String.swift in Sources */, 67DC5BEB23A03FE700B03A84 /* ArticleToolbarController.swift in Sources */, D8EC3DFE1E9BDA35006712EB /* PlaceSearch.swift in Sources */, + 009B8359298091BC00AABEA3 /* EditNoticesViewController.swift in Sources */, 7AE1FE3321B4A9790068BE9F /* TextFormattingButtonView.swift in Sources */, D8EC3E001E9BDA35006712EB /* PlaceSearchSuggestionController.swift in Sources */, B0B423631EF9D6A300D3DC4C /* OnThisDayViewController.swift in Sources */, @@ -13796,6 +13833,7 @@ 67B5334228416C0E00C33E13 /* UserDataExportCache.swift in Sources */, 7AFC79FA21B0367700BB0C50 /* TextFormattingTableViewController.swift in Sources */, 6782DBC32343FDCA003FA21B /* DiffListChangeCell.swift in Sources */, + 003AD72F2979C512005BDB90 /* EditNoticesViewModel.swift in Sources */, D8EC3E631E9BDA35006712EB /* WMFWelcomeContainerViewController.swift in Sources */, 676F39292745FB2000F4D33D /* NotificationsCenterFiltersViewModel.swift in Sources */, 0042813625E6E841004945B3 /* NYTPhotoDismissalInteractionController.m in Sources */, @@ -13804,6 +13842,7 @@ D8EC3E641E9BDA35006712EB /* WMFAccountCreator.swift in Sources */, D8EC3E651E9BDA35006712EB /* UIViewController+WMFHideKeyboard.swift in Sources */, 00FCB2C426D839A500F5A47A /* NotificationsCenterCellViewModel.swift in Sources */, + 00B0B3D12978745400DD7893 /* EditNoticesFetcher.swift in Sources */, 674711842507253500287951 /* ArticleAsLivingDocSnippetCollectionViewCell.swift in Sources */, D8EC3E671E9BDA35006712EB /* WeakScriptMessageDelegate.swift in Sources */, D8EC3E6D1E9BDA35006712EB /* UIView+Animations.swift in Sources */, @@ -13844,6 +13883,7 @@ D8EC3E8A1E9BDA35006712EB /* UIView+WMFFrameUtils.m in Sources */, D8E6FF6E24056AC300686272 /* ArticleViewController+ContextMenu.swift in Sources */, 8386BDFD2386D754007EE89D /* SinglePageWebViewController.swift in Sources */, + 009B835E298091CD00AABEA3 /* EditNoticesView.swift in Sources */, D8EC3E8B1E9BDA35006712EB /* WMFWelcomeAnimationViewControllers.swift in Sources */, D8EC3E8C1E9BDA35006712EB /* TableOfContentsCell.swift in Sources */, FFD7B85724B3B39A005C2471 /* ReferenceBackLinksViewControllerDelegate.swift in Sources */, diff --git a/Wikipedia/Localizations/en.lproj/Localizable.strings b/Wikipedia/Localizations/en.lproj/Localizable.strings index 9047ec32fc2..5a51eb78c57 100644 --- a/Wikipedia/Localizations/en.lproj/Localizable.strings +++ b/Wikipedia/Localizations/en.lproj/Localizable.strings @@ -256,6 +256,9 @@ "edit-menu-item-could-not-find-selection-alert-title" = "The text that you selected could not be located"; "edit-minor-learn-more-text" = "Learn more about minor edits"; "edit-minor-text" = "This is a minor edit"; +"edit-notices" = "Edit notices"; +"edit-notices-always-display" = "Always display edit notices"; +"edit-notices-please-read" = "Please read before editing"; "edit-ordered-list-accessibility-label" = "Make current line ordered list"; "edit-ordered-list-remove-accessibility-label" = "Remove ordered list from current line"; "edit-published" = "Edit published"; diff --git a/Wikipedia/Localizations/qqq.lproj/Localizable.strings b/Wikipedia/Localizations/qqq.lproj/Localizable.strings index 50b90a20a91..c629b343102 100644 --- a/Wikipedia/Localizations/qqq.lproj/Localizable.strings +++ b/Wikipedia/Localizations/qqq.lproj/Localizable.strings @@ -256,6 +256,9 @@ "edit-menu-item-could-not-find-selection-alert-title" = "Title for alert informing user their text selection could not be located in the article wikitext."; "edit-minor-learn-more-text" = "Text for minor edits learn more button"; "edit-minor-text" = "Text for minor edit label"; +"edit-notices" = "Title text and accessibility label for edit notices button."; +"edit-notices-always-display" = "Title for toggle switch label in edit notices view."; +"edit-notices-please-read" = "Subtitle displayed in edit notices view."; "edit-ordered-list-accessibility-label" = "Accessibility label for ordered list button"; "edit-ordered-list-remove-accessibility-label" = "Accessibility label for remove ordered list button"; "edit-published" = "Title edit published panel letting user know their edit was saved."; diff --git a/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings b/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings index 822516739a84268e6eee8fb225ac030af4925f80..5de5eb1a80a915b0f732f8ca506fa6286064bfa4 100644 GIT binary patch delta 389 zcmX@}LgL51h($ delta 38 pcmccjR^rSHiH0qVlkBE{&}1}d4{>A!VkRJF24a@&A&#tFUjaX;4&VR) From 37a61f0eb3b5738a3fc37cbc43125efbe0853d21 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 11:41:25 -0800 Subject: [PATCH 02/14] Add UserDefault for automatically displaying edit notices. This defaults to being on unless the user takes action to disable automatically displaying the edit notices modal when editing a page. --- Wikipedia/Code/NSUserDefaults+WMFExtensions.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Wikipedia/Code/NSUserDefaults+WMFExtensions.swift b/Wikipedia/Code/NSUserDefaults+WMFExtensions.swift index 9a4f3c2b4bd..32ef7dd4f14 100644 --- a/Wikipedia/Code/NSUserDefaults+WMFExtensions.swift +++ b/Wikipedia/Code/NSUserDefaults+WMFExtensions.swift @@ -31,6 +31,7 @@ let WMFUserHasOnboardedToContributingToTalkPages = "WMFUserHasOnboardedToContrib let WMFDidShowNotificationsCenterPushOptInPanel = "WMFDidShowNotificationsCenterPushOptInPanel" let WMFSubscribedToEchoNotifications = "WMFSubscribedToEchoNotifications" let WMFTappedToImportSharedReadingListSurvey = "WMFTappedToImportSharedReadingListSurvey" +public let WMFAlwaysDisplayEditNotices = "WMFAlwaysDisplayEditNotices" @objc public enum WMFAppDefaultTabType: Int { case explore @@ -522,6 +523,19 @@ let WMFTappedToImportSharedReadingListSurvey = "WMFTappedToImportSharedReadingLi } } + @objc var wmf_alwaysDisplayEditNotices: Bool { + get { + if object(forKey: WMFAlwaysDisplayEditNotices) == nil { + return true + } + return bool(forKey: WMFAlwaysDisplayEditNotices) + } + set { + set(newValue, forKey: WMFAlwaysDisplayEditNotices) + } + } + + #if UI_TEST @objc func wmf_isFastlaneSnapshotInProgress() -> Bool { return bool(forKey: "FASTLANE_SNAPSHOT") From c658966be7e7d6eb566bfa0fa91c1f9f1a770e8a Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 11:44:38 -0800 Subject: [PATCH 03/14] Add `EditNoticesFetcher`. We filter the notices by those containing the key "editnotice" as Android does in order to not display notices that will be displayed elsewhere. --- Wikipedia/Code/EditNoticesFetcher.swift | 56 +++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Wikipedia/Code/EditNoticesFetcher.swift diff --git a/Wikipedia/Code/EditNoticesFetcher.swift b/Wikipedia/Code/EditNoticesFetcher.swift new file mode 100644 index 00000000000..7a05284af67 --- /dev/null +++ b/Wikipedia/Code/EditNoticesFetcher.swift @@ -0,0 +1,56 @@ +class EditNoticesFetcher: Fetcher { + + // MARK: - Nested Types + + struct Notice: Codable { + let name: String + let description: String + } + + private struct Response: Codable { + struct VisualEditor: Codable { + let notices: [String: String]? + } + + enum CodingKeys: String, CodingKey { + case visualEditor = "visualeditor" + } + + let visualEditor: VisualEditor? + } + + // MARK: - Public + + func fetchNotices(for articleURL: URL, completion: @escaping (Result<[Notice], Error>) -> Void) { + guard let title = articleURL.wmf_title else { + completion(.failure(RequestError.invalidParameters)) + return + } + + let parameters: [String: Any] = [ + "action": "visualeditor", + "paction": "metadata", + "page": title, + "errorsuselocal": "1", + "formatversion" : "2", + "format": "json" + ] + + performDecodableMediaWikiAPIGET(for: articleURL, with: parameters) { (result: Result) in + switch result { + case .failure(let error): + completion(.failure(error)) + case .success(let response): + var notices: [Notice] = [] + if let rawNotices = response.visualEditor?.notices?.filter({ $0.key.contains("editnotice")}) { + for rawNotice in rawNotices { + notices.append(Notice(name: rawNotice.key, description: rawNotice.value)) + } + } + + completion(.success(notices)) + } + } + } + +} From 4cb97f73ecd9fe34545a63a64da0e860e2cff246 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 12:01:21 -0800 Subject: [PATCH 04/14] Add edit notices modal view. --- Wikipedia/Code/EditNoticesView.swift | 245 ++++++++++++++++++ .../Code/EditNoticesViewController.swift | 77 ++++++ 2 files changed, 322 insertions(+) create mode 100644 Wikipedia/Code/EditNoticesView.swift create mode 100644 Wikipedia/Code/EditNoticesViewController.swift diff --git a/Wikipedia/Code/EditNoticesView.swift b/Wikipedia/Code/EditNoticesView.swift new file mode 100644 index 00000000000..bb7a691234a --- /dev/null +++ b/Wikipedia/Code/EditNoticesView.swift @@ -0,0 +1,245 @@ +import UIKit + +final class EditNoticesView: SetupView { + + // MARK: - UI Elements + + lazy var scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.showsVerticalScrollIndicator = false + return scrollView + }() + + lazy var stackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.spacing = 0 + stackView.isUserInteractionEnabled = true + return stackView + }() + + lazy var editNoticesImageContainer: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(editNoticesImageView) + NSLayoutConstraint.activate([ + editNoticesImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 10), + editNoticesImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10), + editNoticesImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + editNoticesImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor) + ]) + return view + }() + + lazy var editNoticesImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(systemName: "exclamationmark.circle.fill")) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFill + + let imageWidthConstraint = imageView.widthAnchor.constraint(equalToConstant: 50) + imageWidthConstraint.priority = .required + let imageHeightConstraint = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor) + imageHeightConstraint.priority = .required + + NSLayoutConstraint.activate([ + imageWidthConstraint, + imageHeightConstraint + ]) + + return imageView + }() + + lazy var editNoticesTitle: UILabel = { + let label = UILabel() + label.text = CommonStrings.editNotices + label.textAlignment = .center + label.numberOfLines = 0 + label.font = UIFont.wmf_scaledSystemFont(forTextStyle: .title1, weight: .semibold, size: 20) + label.adjustsFontForContentSizeCategory = true + return label + }() + + lazy var editNoticesSubtitle: UILabel = { + let label = UILabel() + label.text = WMFLocalizedString("edit-notices-please-read", value: "Please read before editing", comment: "Subtitle displayed in edit notices view.") + label.textAlignment = .center + label.numberOfLines = 0 + label.font = UIFont.wmf_scaledSystemFont(forTextStyle: .title2, weight: .semibold, size: 15) + label.adjustsFontForContentSizeCategory = true + return label + }() + + lazy var contentContainer: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + lazy var doneContainer: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + lazy var doneButton: UIButton = { + let button = UIButton(type: .system) + button.titleLabel?.font = UIFont.wmf_scaledSystemFont(forTextStyle: .body, weight: .medium, size: 17) + button.titleLabel?.adjustsFontForContentSizeCategory = true + button.setTitle(CommonStrings.doneTitle, for: .normal) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + lazy var footerContainer: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + lazy var footerStack: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.distribution = .fill + stackView.spacing = 20 + return stackView + }() + + lazy var footerSwitchLabel: UILabel = { + let label = UILabel() + label.text = WMFLocalizedString("edit-notices-always-display", value: "Always display edit notices", comment: "Title for toggle switch label in edit notices view.") + label.numberOfLines = 0 + label.font = UIFont.wmf_scaledSystemFont(forTextStyle: .body, weight: .regular, size: 15) + label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false + + label.setContentCompressionResistancePriority(.required, for: .vertical) + label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + + return label + }() + + lazy var switchContainer: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + + view.addSubview(toggleSwitch) + NSLayoutConstraint.activate([ + toggleSwitch.centerYAnchor.constraint(equalTo: view.centerYAnchor), + toggleSwitch.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor), + toggleSwitch.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor), + toggleSwitch.leadingAnchor.constraint(equalTo: view.leadingAnchor), + toggleSwitch.trailingAnchor.constraint(equalTo: view.trailingAnchor) + ]) + + return view + }() + + lazy var toggleSwitch: UISwitch = { + let toggle = UISwitch() + toggle.translatesAutoresizingMaskIntoConstraints = false + toggle.setContentHuggingPriority(.required, for: .vertical) + toggle.setContentCompressionResistancePriority(.required, for: .vertical) + return toggle + }() + + lazy var textView: UITextView = { + let textView = UITextView() + textView.translatesAutoresizingMaskIntoConstraints = false + textView.isScrollEnabled = false + textView.isEditable = false + textView.adjustsFontForContentSizeCategory = true + textView.textContainerInset = .zero + textView.textContainer.lineFragmentPadding = 0 + return textView + }() + + // MARK: - Override + + override func setup() { + // Top "navigation" bar + + addSubview(doneContainer) + doneContainer.addSubview(doneButton) + + // Primary content container, scrollable + + addSubview(contentContainer) + contentContainer.addSubview(scrollView) + scrollView.addSubview(stackView) + + stackView.addArrangedSubview(editNoticesImageContainer) + stackView.addArrangedSubview(VerticalSpacerView.spacerWith(space: 10)) + stackView.addArrangedSubview(editNoticesTitle) + stackView.addArrangedSubview(VerticalSpacerView.spacerWith(space: 6)) + stackView.addArrangedSubview(editNoticesSubtitle) + stackView.addArrangedSubview(VerticalSpacerView.spacerWith(space: 32)) + stackView.addArrangedSubview(textView) + + // Footer label/switch + + addSubview(footerContainer) + footerContainer.addSubview(footerStack) + + footerStack.addArrangedSubview(footerSwitchLabel) + footerStack.addArrangedSubview(switchContainer) + + NSLayoutConstraint.activate([ + doneContainer.topAnchor.constraint(equalTo: topAnchor), + doneContainer.leadingAnchor.constraint(equalTo: leadingAnchor), + doneContainer.trailingAnchor.constraint(equalTo: trailingAnchor), + doneContainer.bottomAnchor.constraint(equalTo: contentContainer.topAnchor), + + doneButton.trailingAnchor.constraint(equalTo: doneContainer.trailingAnchor, constant: -16), + doneButton.topAnchor.constraint(equalTo: doneContainer.topAnchor, constant: 16), + doneButton.bottomAnchor.constraint(equalTo: doneContainer.bottomAnchor, constant: -5), + + contentContainer.leadingAnchor.constraint(equalTo: leadingAnchor), + contentContainer.trailingAnchor.constraint(equalTo: trailingAnchor), + + scrollView.topAnchor.constraint(equalTo: contentContainer.topAnchor), + scrollView.bottomAnchor.constraint(equalTo: contentContainer.bottomAnchor), + scrollView.leadingAnchor.constraint(equalTo: contentContainer.readableContentGuide.leadingAnchor, constant: 24), + scrollView.trailingAnchor.constraint(equalTo: contentContainer.readableContentGuide.trailingAnchor, constant: -24), + + stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor), + stackView.topAnchor.constraint(equalTo: scrollView.topAnchor), + stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), + stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), + + footerContainer.topAnchor.constraint(equalTo: contentContainer.bottomAnchor), + footerContainer.leadingAnchor.constraint(equalTo: leadingAnchor), + footerContainer.trailingAnchor.constraint(equalTo: trailingAnchor), + footerContainer.bottomAnchor.constraint(equalTo: bottomAnchor), + + footerStack.leadingAnchor.constraint(equalTo: footerContainer.readableContentGuide.leadingAnchor, constant: 20), + footerStack.trailingAnchor.constraint(equalTo: footerContainer.readableContentGuide.trailingAnchor, constant: -20), + footerStack.topAnchor.constraint(equalTo: footerContainer.topAnchor, constant: 20), + footerStack.bottomAnchor.constraint(equalTo: footerContainer.readableContentGuide.bottomAnchor) + ]) + } + + func configure(viewModel: EditNoticesViewModel, theme: Theme) { + let attributedNoticeString = NSMutableAttributedString() + for notice in viewModel.notices { + let noticeString = notice.description.byAttributingHTML(with: .callout, matching: traitCollection, color: theme.colors.primaryText, handlingLinks: true) + attributedNoticeString.append(noticeString) + } + + textView.attributedText = attributedNoticeString.removingInitialNewlineCharacters().removingRepetitiveNewlineCharacters() + + // Update colors + backgroundColor = theme.colors.paperBackground + doneButton.setTitleColor(theme.colors.link, for: .normal) + editNoticesImageView.tintColor = theme.colors.primaryText + editNoticesTitle.textColor = theme.colors.primaryText + editNoticesSubtitle.textColor = theme.colors.primaryText + textView.backgroundColor = theme.colors.paperBackground + textView.linkTextAttributes = [.foregroundColor: theme.colors.link] + footerSwitchLabel.textColor = theme.colors.primaryText + } + +} diff --git a/Wikipedia/Code/EditNoticesViewController.swift b/Wikipedia/Code/EditNoticesViewController.swift new file mode 100644 index 00000000000..c3ad48ae171 --- /dev/null +++ b/Wikipedia/Code/EditNoticesViewController.swift @@ -0,0 +1,77 @@ +import UIKit + +protocol EditNoticesViewControllerDelegate: AnyObject { + func editNoticesControllerUserTapped(url: URL) +} + +class EditNoticesViewController: ViewController { + + // MARK: - Properties + + let viewModel: EditNoticesViewModel + + weak var delegate: EditNoticesViewControllerDelegate? + + var editNoticesView: EditNoticesView { + return view as! EditNoticesView + } + + // MARK: - Lifecycle + + init(theme: Theme, viewModel: EditNoticesViewModel) { + self.viewModel = viewModel + super.init(theme: theme) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + let editNoticesView = EditNoticesView(frame: UIScreen.main.bounds) + view = editNoticesView + scrollView = editNoticesView.scrollView + scrollView?.automaticallyAdjustsScrollIndicatorInsets = false + + editNoticesView.configure(viewModel: viewModel, theme: theme) + + editNoticesView.doneButton.addTarget(self, action: #selector(dismissView), for: .primaryActionTriggered) + editNoticesView.toggleSwitch.addTarget(self, action: #selector(didToggleSwitch(_:)), for: .valueChanged) + editNoticesView.toggleSwitch.isOn = UserDefaults.standard.wmf_alwaysDisplayEditNotices + editNoticesView.textView.delegate = self + } + + // MARK: - Actions + + @objc private func dismissView() { + dismiss(animated: true) + } + + @objc private func didToggleSwitch(_ sender: UISwitch) { + UserDefaults.standard.wmf_alwaysDisplayEditNotices = sender.isOn + } + + // MARK: - Themeable + + override func apply(theme: Theme) { + super.apply(theme: theme) + editNoticesView.configure(viewModel: viewModel, theme: theme) + } + +} + +extension EditNoticesViewController: UITextViewDelegate { + + func textView(_ textView: UITextView, shouldInteractWith url: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { + guard let url = URL(string: url.absoluteString, relativeTo: viewModel.siteURL) else { + return false + } + + dismiss(animated: true) { + self.delegate?.editNoticesControllerUserTapped(url: url) + } + + return false + } + +} From 7264419e08e70dd80b5ee9736d034d1ab229fdce Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 12:11:49 -0800 Subject: [PATCH 05/14] Add `EditNoticesViewModel`. --- Wikipedia/Code/EditNoticesViewModel.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Wikipedia/Code/EditNoticesViewModel.swift diff --git a/Wikipedia/Code/EditNoticesViewModel.swift b/Wikipedia/Code/EditNoticesViewModel.swift new file mode 100644 index 00000000000..555c8b0cc1c --- /dev/null +++ b/Wikipedia/Code/EditNoticesViewModel.swift @@ -0,0 +1,17 @@ +import Foundation + +final class EditNoticesViewModel { + + // MARK: - Properties + + var siteURL: URL + var notices: [EditNoticesFetcher.Notice] + + // MARK: - Public + + init(siteURL: URL, notices: [EditNoticesFetcher.Notice]) { + self.siteURL = siteURL + self.notices = notices + } + +} From fa0f87c028cb51a7529281f40f2c0960a95812a1 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 12:18:09 -0800 Subject: [PATCH 06/14] Update editor bar with edit notices button. --- .../SectionEditorNavigationItemController.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Wikipedia/Code/SectionEditorNavigationItemController.swift b/Wikipedia/Code/SectionEditorNavigationItemController.swift index eacfc9b733a..dd9933ef700 100644 --- a/Wikipedia/Code/SectionEditorNavigationItemController.swift +++ b/Wikipedia/Code/SectionEditorNavigationItemController.swift @@ -4,6 +4,7 @@ protocol SectionEditorNavigationItemControllerDelegate: AnyObject { func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapUndoButton undoButton: UIBarButtonItem) func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapRedoButton redoButton: UIBarButtonItem) func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapReadingThemesControlsButton readingThemesControlsButton: UIBarButtonItem) + func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapEditNoticesButton: UIBarButtonItem) } class SectionEditorNavigationItemController: NSObject, Themeable { @@ -73,6 +74,10 @@ class SectionEditorNavigationItemController: NSObject, Themeable { private lazy var undoButton: BarButtonItem = { return BarButtonItem(image: #imageLiteral(resourceName: "undo"), style: .plain, target: self, action: #selector(undo(_ :)), tintColorKeyPath: \Theme.colors.inputAccessoryButtonTint, accessibilityLabel: CommonStrings.undo) }() + + private lazy var editNoticesButton: BarButtonItem = { + return BarButtonItem(image: UIImage(systemName: "exclamationmark.circle.fill") , style: .plain, target: self, action: #selector(editNotices(_ :)), tintColorKeyPath: \Theme.colors.inputAccessoryButtonTint, accessibilityLabel: CommonStrings.editNotices) + }() private lazy var readingThemesControlsButton: BarButtonItem = { return BarButtonItem(image: #imageLiteral(resourceName: "settings-appearance"), style: .plain, target: self, action: #selector(showReadingThemesControls(_ :)), tintColorKeyPath: \Theme.colors.inputAccessoryButtonTint, accessibilityLabel: CommonStrings.readingThemesControls) @@ -100,11 +105,22 @@ class SectionEditorNavigationItemController: NSObject, Themeable { @objc private func redo(_ sender: UIBarButtonItem) { delegate?.sectionEditorNavigationItemController(self, didTapRedoButton: sender) } + + @objc private func editNotices(_ sender: UIBarButtonItem) { + delegate?.sectionEditorNavigationItemController(self, didTapEditNoticesButton: sender) + } @objc private func showReadingThemesControls(_ sender: UIBarButtonItem) { delegate?.sectionEditorNavigationItemController(self, didTapReadingThemesControlsButton: sender) } + func addEditNoticesButton() { + navigationItem?.rightBarButtonItems?.append(contentsOf: [ + UIBarButtonItem.wmf_barButtonItem(ofFixedWidth: 20), + editNoticesButton + ]) + } + private func configureNavigationButtonItems() { let closeButton = BarButtonItem(image: #imageLiteral(resourceName: "close"), style: .plain, target: self, action: #selector(close(_ :)), tintColorKeyPath: \Theme.colors.chromeText) closeButton.accessibilityLabel = CommonStrings.closeButtonAccessibilityLabel From a051d98f9a2dda6d1136a9939ea315811f98ba5e Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 13:13:57 -0800 Subject: [PATCH 07/14] Refactor onboarding to present before presenting section editor. --- .../Code/ArticleViewController+Editing.swift | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/Wikipedia/Code/ArticleViewController+Editing.swift b/Wikipedia/Code/ArticleViewController+Editing.swift index 1f281ee0f23..bf02de1e9a8 100644 --- a/Wikipedia/Code/ArticleViewController+Editing.swift +++ b/Wikipedia/Code/ArticleViewController+Editing.swift @@ -18,27 +18,20 @@ extension ArticleViewController { sectionEditVC.editFunnel = editFunnel let navigationController = WMFThemeableNavigationController(rootViewController: sectionEditVC, theme: theme) navigationController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext + let needsIntro = !UserDefaults.standard.didShowEditingOnboarding if needsIntro { - navigationController.view.alpha = 0 - } - - sectionEditVC.shouldFocusWebView = !needsIntro - let showIntro: (() -> Void)? = { - self.editFunnel.logOnboardingPresentation(initiatedBy: funnelSource, language: self.articleLanguageCode) - let editingWelcomeViewController = EditingWelcomeViewController(theme: self.theme) { - sectionEditVC.shouldFocusWebView = true + editFunnel.logOnboardingPresentation(initiatedBy: funnelSource, language: articleLanguageCode) + let editingWelcomeViewController = EditingWelcomeViewController(theme: theme) { + self.present(navigationController, animated: true) } - editingWelcomeViewController.apply(theme: self.theme) - navigationController.present(editingWelcomeViewController, animated: true) { + editingWelcomeViewController.apply(theme: theme) + present(editingWelcomeViewController, animated: true) { UserDefaults.standard.didShowEditingOnboarding = true - navigationController.view.alpha = 1 - } - } - present(navigationController, animated: !needsIntro) { - if needsIntro { - showIntro?() } + + } else { + present(navigationController, animated: true) } } From b169a0d560a3f54576680fe2ca8c6aa0337add56 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Mon, 6 Feb 2023 13:27:22 -0800 Subject: [PATCH 08/14] Present edit notices modal on initial fetch task completion. --- .../Code/SectionEditorViewController.swift | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/Wikipedia/Code/SectionEditorViewController.swift b/Wikipedia/Code/SectionEditorViewController.swift index 54c3477c09a..ac02801aabe 100644 --- a/Wikipedia/Code/SectionEditorViewController.swift +++ b/Wikipedia/Code/SectionEditorViewController.swift @@ -20,7 +20,11 @@ class SectionEditorViewController: ViewController { private var dataStore: MWKDataStore private var webView: SectionEditorWebView! + + private let initialFetchGroup: WMFTaskGroup = WMFTaskGroup() private let sectionFetcher: SectionFetcher + private let editNoticesFetcher: EditNoticesFetcher + private var editNoticesViewModel: EditNoticesViewModel? = nil private var inputViewsController: SectionEditorInputViewsController! private var messagingController: SectionEditorWebViewMessagingController! @@ -76,6 +80,7 @@ class SectionEditorViewController: ViewController { self.messagingController = messagingController ?? SectionEditorWebViewMessagingController() languageCode = articleURL.wmf_languageCode ?? NSLocale.current.languageCode ?? "en" self.sectionFetcher = SectionFetcher(session: dataStore.session, configuration: dataStore.configuration) + self.editNoticesFetcher = EditNoticesFetcher(session: dataStore.session, configuration: dataStore.configuration) super.init(theme: theme) } @@ -84,6 +89,7 @@ class SectionEditorViewController: ViewController { } override func viewDidLoad() { + loadEditNotices() loadWikitext() navigationItemController = SectionEditorNavigationItemController(navigationItem: navigationItem) @@ -102,7 +108,13 @@ class SectionEditorViewController: ViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - selectLastSelectionIfNeeded() + + initialFetchGroup.waitInBackground { + self.presentEditNoticesIfNecessary() + self.selectLastSelectionIfNeeded() + + } + } override func viewWillDisappear(_ animated: Bool) { @@ -117,6 +129,24 @@ class SectionEditorViewController: ViewController { @objc func keyboardDidHide() { inputViewsController.resetFormattingAndStyleSubmenus() } + + private func presentEditNoticesIfNecessary() { + guard UserDefaults.standard.wmf_alwaysDisplayEditNotices else { + return + } + + presentEditNoticesIfAvailable() + } + + private func presentEditNoticesIfAvailable() { + guard let editNoticesViewModel = self.editNoticesViewModel else { + return + } + + let editNoticesViewController = EditNoticesViewController(theme: self.theme, viewModel: editNoticesViewModel) + editNoticesViewController.delegate = self + present(editNoticesViewController, animated: true) + } private func setupFocusNavigationView() { @@ -327,7 +357,24 @@ class SectionEditorViewController: ViewController { messagingController.setWikitext(wikitext, completionHandler: completionHandler) } + private func loadEditNotices() { + initialFetchGroup.enter() + editNoticesFetcher.fetchNotices(for: articleURL) { (result) in + if case let .success(notices) = result, !notices.isEmpty, let siteURL = self.articleURL.wmf_site { + self.editNoticesViewModel = EditNoticesViewModel(siteURL: siteURL, notices: notices) + + DispatchQueue.main.async { + self.navigationItemController.addEditNoticesButton() + self.navigationItemController.apply(theme: self.theme) + } + } + + self.initialFetchGroup.leave() + } + } + private func loadWikitext() { + initialFetchGroup.enter() let isShowingStatusMessage = shouldFocusWebView if isShowingStatusMessage { let message = WMFLocalizedString("wikitext-downloading", value: "Loading content...", comment: "Alert text shown when obtaining latest revision of the section being edited") @@ -342,15 +389,17 @@ class SectionEditorViewController: ViewController { case .failure(let error): self.didFocusWebViewCompletion = { WMFAlertManager.sharedInstance.showErrorAlert(error as NSError, sticky: true, dismissPreviousAlerts: true) + self.initialFetchGroup.leave() } case .success(let response): self.wikitext = response.wikitext self.handle(protection: response.protection) + self.initialFetchGroup.leave() } } } } - + private func handle(protection: [SectionFetcher.Protection]) { let allowedGroups = protection.map { $0.level } guard !allowedGroups.isEmpty else { @@ -471,6 +520,10 @@ extension SectionEditorViewController: SectionEditorNavigationItemControllerDele func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapRedoButton redoButton: UIBarButtonItem) { messagingController.redo() } + + func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapEditNoticesButton: UIBarButtonItem) { + presentEditNoticesIfAvailable() + } func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapReadingThemesControlsButton readingThemesControlsButton: UIBarButtonItem) { @@ -752,6 +805,16 @@ extension SectionEditorViewController: EditingFlowViewController { } +extension SectionEditorViewController: EditNoticesViewControllerDelegate { + + func editNoticesControllerUserTapped(url: URL) { + dismiss(animated: true) { [weak self] in + self?.navigate(to: url) + } + } + +} + #if (TEST) // MARK: Helpers for testing extension SectionEditorViewController { From fca14e4e8ee888ae94eea33bda245d766668621a Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Thu, 9 Feb 2023 12:20:28 -0800 Subject: [PATCH 09/14] Update localized strings. --- .../en.lproj/Localizable.strings | Bin 0 -> 407522 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings b/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c8059f2387df273ded48ec0d55706902fc0be1e5 100644 GIT binary patch literal 407522 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�Pfhb{aHcq*Jv8~&UoQaT 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 Date: Thu, 9 Feb 2023 12:30:41 -0800 Subject: [PATCH 10/14] Move initial fetch group `leave()` out of completion block. --- Wikipedia/Code/SectionEditorViewController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Wikipedia/Code/SectionEditorViewController.swift b/Wikipedia/Code/SectionEditorViewController.swift index 06d23d1c52e..17daffa35d3 100644 --- a/Wikipedia/Code/SectionEditorViewController.swift +++ b/Wikipedia/Code/SectionEditorViewController.swift @@ -389,8 +389,8 @@ class SectionEditorViewController: ViewController { case .failure(let error): self.didFocusWebViewCompletion = { WMFAlertManager.sharedInstance.showErrorAlert(error as NSError, sticky: true, dismissPreviousAlerts: true) - self.initialFetchGroup.leave() } + self.initialFetchGroup.leave() case .success(let response): self.wikitext = response.wikitext self.handle(protection: response.protection) @@ -826,6 +826,9 @@ extension SectionEditorViewController: EditingFlowViewController { extension SectionEditorViewController: EditNoticesViewControllerDelegate { func editNoticesControllerUserTapped(url: URL) { + showAlert() + + dismiss(animated: true) { [weak self] in self?.navigate(to: url) } From 3d5fc60c06dbd2c22505c1ce9b5accb4978663d1 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Thu, 9 Feb 2023 13:26:27 -0800 Subject: [PATCH 11/14] Update done button to use readable content guide. --- Wikipedia/Code/EditNoticesView.swift | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Wikipedia/Code/EditNoticesView.swift b/Wikipedia/Code/EditNoticesView.swift index bb7a691234a..f72ae26e96b 100644 --- a/Wikipedia/Code/EditNoticesView.swift +++ b/Wikipedia/Code/EditNoticesView.swift @@ -156,6 +156,14 @@ final class EditNoticesView: SetupView { return textView }() + // MARK: - Private Properties + + private var doneButtonTrailingConstraint: NSLayoutConstraint! + + private var doneButtonTrailingMargin: CGFloat { + return traitCollection.verticalSizeClass == .compact ? -20 : -8 + } + // MARK: - Override override func setup() { @@ -163,6 +171,7 @@ final class EditNoticesView: SetupView { addSubview(doneContainer) doneContainer.addSubview(doneButton) + doneButtonTrailingConstraint = doneButton.trailingAnchor.constraint(equalTo: doneContainer.readableContentGuide.trailingAnchor, constant: doneButtonTrailingMargin) // Primary content container, scrollable @@ -192,7 +201,7 @@ final class EditNoticesView: SetupView { doneContainer.trailingAnchor.constraint(equalTo: trailingAnchor), doneContainer.bottomAnchor.constraint(equalTo: contentContainer.topAnchor), - doneButton.trailingAnchor.constraint(equalTo: doneContainer.trailingAnchor, constant: -16), + doneButtonTrailingConstraint, doneButton.topAnchor.constraint(equalTo: doneContainer.topAnchor, constant: 16), doneButton.bottomAnchor.constraint(equalTo: doneContainer.bottomAnchor, constant: -5), @@ -222,6 +231,15 @@ final class EditNoticesView: SetupView { ]) } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + doneButtonTrailingConstraint.constant = doneButtonTrailingMargin + doneContainer.setNeedsLayout() + } + + // MARK: - Public + func configure(viewModel: EditNoticesViewModel, theme: Theme) { let attributedNoticeString = NSMutableAttributedString() for notice in viewModel.notices { From 8b06555b11ed27d075834e0f5ed6457988705cff Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Thu, 9 Feb 2023 13:45:14 -0800 Subject: [PATCH 12/14] Perform edit notices modal URL navigation after presenting destructive alert. --- .../Code/ArticleViewController+Editing.swift | 6 ++++-- .../Code/SectionEditorViewController.swift | 21 +++++++------------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Wikipedia/Code/ArticleViewController+Editing.swift b/Wikipedia/Code/ArticleViewController+Editing.swift index bf02de1e9a8..f52665c7e26 100644 --- a/Wikipedia/Code/ArticleViewController+Editing.swift +++ b/Wikipedia/Code/ArticleViewController+Editing.swift @@ -195,8 +195,10 @@ extension ArticleViewController: SectionEditorViewControllerDelegate { } } - func sectionEditorDidCancelEditing(_ sectionEditor: SectionEditorViewController) { - dismiss(animated: true) + func sectionEditorDidCancelEditing(_ sectionEditor: SectionEditorViewController, navigateToURL url: URL?) { + dismiss(animated: true) { + self.navigate(to: url) + } } func sectionEditorDidFinishLoadingWikitext(_ sectionEditor: SectionEditorViewController) { diff --git a/Wikipedia/Code/SectionEditorViewController.swift b/Wikipedia/Code/SectionEditorViewController.swift index 17daffa35d3..b44a41e3a26 100644 --- a/Wikipedia/Code/SectionEditorViewController.swift +++ b/Wikipedia/Code/SectionEditorViewController.swift @@ -1,7 +1,7 @@ import CocoaLumberjackSwift protocol SectionEditorViewControllerDelegate: AnyObject { - func sectionEditorDidCancelEditing(_ sectionEditor: SectionEditorViewController) + func sectionEditorDidCancelEditing(_ sectionEditor: SectionEditorViewController, navigateToURL: URL?) func sectionEditorDidFinishEditing(_ sectionEditor: SectionEditorViewController, result: Result) func sectionEditorDidFinishLoadingWikitext(_ sectionEditor: SectionEditorViewController) } @@ -421,7 +421,7 @@ class SectionEditorViewController: ViewController { // MARK: - Accessibility override func accessibilityPerformEscape() -> Bool { - delegate?.sectionEditorDidCancelEditing(self) + delegate?.sectionEditorDidCancelEditing(self, navigateToURL: nil) return true } @@ -476,10 +476,10 @@ class SectionEditorViewController: ViewController { messagingController.setAdjustedContentInset(newInset: newContentInset) } - fileprivate func showAlert() { + fileprivate func showDestructiveDismissAlert(navigateToURLOnCompletion url: URL? = nil) { let alert = UIAlertController(title: CommonStrings.editorExitConfirmationTitle, message: CommonStrings.editorExitConfirmationBody, preferredStyle: .alert) let confirmClose = UIAlertAction(title: CommonStrings.discardEditsActionTitle, style: .destructive) { _ in - self.closeEditor() + self.closeEditor(navigateToURL: url) } alert.addAction(confirmClose) let cancel = UIAlertAction(title: CommonStrings.cancelActionTitle, style: .default) @@ -487,8 +487,8 @@ class SectionEditorViewController: ViewController { present(alert, animated: true) } - fileprivate func closeEditor() { - delegate?.sectionEditorDidCancelEditing(self) + fileprivate func closeEditor(navigateToURL url: URL? = nil) { + delegate?.sectionEditorDidCancelEditing(self, navigateToURL: url) } } @@ -525,7 +525,7 @@ extension SectionEditorViewController: SectionEditorNavigationItemControllerDele func sectionEditorNavigationItemController(_ sectionEditorNavigationItemController: SectionEditorNavigationItemController, didTapCloseButton closeButton: UIBarButtonItem) { if navigationItemController.progressButton.isEnabled && navigationItemController.undoButton.isEnabled { - showAlert() + showDestructiveDismissAlert() } else { closeEditor() } @@ -826,12 +826,7 @@ extension SectionEditorViewController: EditingFlowViewController { extension SectionEditorViewController: EditNoticesViewControllerDelegate { func editNoticesControllerUserTapped(url: URL) { - showAlert() - - - dismiss(animated: true) { [weak self] in - self?.navigate(to: url) - } + showDestructiveDismissAlert(navigateToURLOnCompletion: url) } } From 525771bf3b56dbfcc7b5a156ce60c753bccabe5a Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Thu, 9 Feb 2023 13:54:47 -0800 Subject: [PATCH 13/14] Update `SectionEditorFindAndReplaceTests` delegate parameter conformance. --- WikipediaUnitTests/Code/SectionEditorFindAndReplaceTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WikipediaUnitTests/Code/SectionEditorFindAndReplaceTests.swift b/WikipediaUnitTests/Code/SectionEditorFindAndReplaceTests.swift index 8ebe54f9d21..29102a9e12a 100644 --- a/WikipediaUnitTests/Code/SectionEditorFindAndReplaceTests.swift +++ b/WikipediaUnitTests/Code/SectionEditorFindAndReplaceTests.swift @@ -397,7 +397,7 @@ class SectionEditorFindAndReplaceTests: XCTestCase { } extension SectionEditorFindAndReplaceTests: SectionEditorViewControllerDelegate { - func sectionEditorDidCancelEditing(_ sectionEditor: SectionEditorViewController) { + func sectionEditorDidCancelEditing(_ sectionEditor: SectionEditorViewController, navigateToURL: URL?) { // no-op } From 0da7a9f13fb0c04d6ca2ce6ad4a82cc6769f11b5 Mon Sep 17 00:00:00 2001 From: Deepak Mantena Date: Thu, 9 Feb 2023 15:16:39 -0800 Subject: [PATCH 14/14] Update `EditNoticesViewController` to conform to `ThemeableViewController`. --- Wikipedia/Code/EditNoticesViewController.swift | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Wikipedia/Code/EditNoticesViewController.swift b/Wikipedia/Code/EditNoticesViewController.swift index c3ad48ae171..934a3549d38 100644 --- a/Wikipedia/Code/EditNoticesViewController.swift +++ b/Wikipedia/Code/EditNoticesViewController.swift @@ -4,7 +4,7 @@ protocol EditNoticesViewControllerDelegate: AnyObject { func editNoticesControllerUserTapped(url: URL) } -class EditNoticesViewController: ViewController { +class EditNoticesViewController: ThemeableViewController { // MARK: - Properties @@ -20,7 +20,8 @@ class EditNoticesViewController: ViewController { init(theme: Theme, viewModel: EditNoticesViewModel) { self.viewModel = viewModel - super.init(theme: theme) + super.init(nibName: nil, bundle: nil) + self.theme = theme } required init?(coder aDecoder: NSCoder) { @@ -30,9 +31,6 @@ class EditNoticesViewController: ViewController { override func loadView() { let editNoticesView = EditNoticesView(frame: UIScreen.main.bounds) view = editNoticesView - scrollView = editNoticesView.scrollView - scrollView?.automaticallyAdjustsScrollIndicatorInsets = false - editNoticesView.configure(viewModel: viewModel, theme: theme) editNoticesView.doneButton.addTarget(self, action: #selector(dismissView), for: .primaryActionTriggered)