Skip to content

Commit 27bca4e

Browse files
authored
[MOB-3199] Default Browser Settings Card (#889)
* [MOB-3199] Implement Settings Card and Detail Page Implemented by moving the NTPConfigurableNudgeCard into SwiftUI and leverage its details. * [MOB-3199] Update ConfigurableNudgeCard + Analytics - Modify the `AppSettingsTableViewController` so that implements the changes needed to display the custom card first and the classic one later - Replace the `Experiment`naming for a more convenient `Detail` one - Implemented Analytics to track all the click and dismissal event - Added animation and configured to play correctly * [MOB-3199] Update strings in #preview to match correct ones * [MOB-3199] Improved accessibility of nudge card + detail view * [MOB-3199] Replace Preview adding macro * [MOB-3199] Mark card as seen right after showing it * [MOB-3199] Add debug option to show/hide the card * [MOB-3199] Default Browser Card is now in in a HeaderFooter * [MOB-3199] Remove Ecosia's DefaultBrowserSetting Reset it's settings back to standard Firefox to reduce conflicts * [MOB-3199] Regenerate Settings section on reset Nudge Card * [MOB-3199] Optimize changes `AppSettingsTableViewController` * [MOB-3199] Move Analytics tap on the `onTap()` event * [MOB-3199] Further optimization to minimize code lines * [MOB-3199] Update string key to reuse in Setting item * [MOB-3199] Simplify DefaultBrowserCoordinator's detail show * [MOB-3199] Add `EcosiaDefaultBrowserSettings` to Search section * [MOB-3199] Add old Analytics's defaultBrowser action * [MOB-3199] Adds top padding to the Nudge Card Header * [MOB-3199] Play Lottie and stop at the end * [MOB-3199] Update Nudge Card's headerview background * [MOB-3199] Custom `EcosiaText` to facilitate localization * [MOB-3199] Improve nudge card shape * [MOB-3199] Add accesibilityTrait to the whole button * [MOB-3199] Loop lottie default browser detail animation * [MOB-3199] Fix CTA button background * [MOB-3199] Fix button CTA rounded corner * [MOB-3199] Update to remove `NavigationView` * [MOB-3199] Extra care to show the correct Done localization In both Settings and details * [MOB-3199] Better way to handle the topContentViewBackground * [MOB-3199] Review LottieView wrapper * [MOB-3199] Simplify Analytics functions. Add CTA click event * [MOB-3199] Swiftlint fix * [MOB-3199] Simplified nudge card name * [MOB-3199] Update typo in function (thanks GHCoPilot) * [MOB-3199] Apply safe unwrap as GHCoPilot suggestion * [MOB-3199] Introduce `ViewInspector`. Adds tests * [MOB-3199] Use of `DefaultBrowser` accessibility constant * [MOB-3199] Wire the showDetail analytics to `onAppear` event * [MOB-3199] Update tests * [MOB-3199] Use `EcosiaFloatDesignSystemFoundations`
1 parent a8e0d59 commit 27bca4e

28 files changed

+1061
-183
lines changed

Diff for: firefox-ios/Client.xcodeproj/project.pbxproj

+25
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@
293293
28E91E751B443AD5009DF274 /* SyncConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28E91E741B443AD5009DF274 /* SyncConstants.swift */; };
294294
28ECD9BF1BA1F19900D829DA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = E6231C001B90A44F005ABB0D /* libz.tbd */; };
295295
2C1298AF2BF602D3005AE4E4 /* DefaultSuggestedSites.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394CF6CE1BAA493C00906917 /* DefaultSuggestedSites.swift */; };
296+
2C2EA77F2DA3F2990085F5BC /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 2C2EA77E2DA3F2990085F5BC /* Lottie */; };
296297
2C2F31F52D46612F00977F55 /* TopSitesHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A5BD9582878871B000FE773 /* TopSitesHelperTests.swift */; };
297298
2C2F31F62D4663D800977F55 /* DependencyHelperMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A70EF18295E2E1600790249 /* DependencyHelperMock.swift */; };
298299
2C2F31F72D4664CB00977F55 /* MockThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA75A622A46272000533F8D /* MockThemeManager.swift */; };
@@ -323,6 +324,7 @@
323324
2C6C908F2C614A6C007D9B43 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 2C6C908E2C614A6C007D9B43 /* SnapshotTesting */; };
324325
2C7DC2402B1648BA00C049C8 /* LegacyTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9A179A20E69A7E00B12184 /* LegacyTheme.swift */; };
325326
2C7DC2462B16493C00C049C8 /* UIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2816EFFF1B33E05400522243 /* UIConstants.swift */; };
327+
2CC0C2AD2DA804EA006FE9B7 /* ViewInspector in Frameworks */ = {isa = PBXBuildFile; productRef = 2CC0C2AC2DA804EA006FE9B7 /* ViewInspector */; };
326328
2CC246602D520EF90098467A /* EcosiaLightTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC2465E2D520EF90098467A /* EcosiaLightTheme.swift */; };
327329
2CC246612D520EF90098467A /* EcosiaColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC2465C2D520EF90098467A /* EcosiaColor.swift */; };
328330
2CC246632D520EF90098467A /* EcosiaDarkTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC2465D2D520EF90098467A /* EcosiaDarkTheme.swift */; };
@@ -9705,6 +9707,7 @@
97059707
2CFE9FCE2D45363500B25CE0 /* BrazeUI in Frameworks */,
97069708
2CFE9FD22D45364600B25CE0 /* Common in Frameworks */,
97079709
2CFE9FEA2D45404800B25CE0 /* SwiftSoup in Frameworks */,
9710+
2C2EA77F2DA3F2990085F5BC /* Lottie in Frameworks */,
97089711
);
97099712
runOnlyForDeploymentPostprocessing = 0;
97109713
};
@@ -9714,6 +9717,7 @@
97149717
files = (
97159718
2CFE9FC02D45348700B25CE0 /* RustMozillaAppServices.framework in Frameworks */,
97169719
2CFE9FBF2D45348200B25CE0 /* SnowplowTracker in Frameworks */,
9720+
2CC0C2AD2DA804EA006FE9B7 /* ViewInspector in Frameworks */,
97179721
);
97189722
runOnlyForDeploymentPostprocessing = 0;
97199723
};
@@ -14893,6 +14897,7 @@
1489314897
2CFE9FCF2D45364100B25CE0 /* SnowplowTracker */,
1489414898
2CFE9FD12D45364600B25CE0 /* Common */,
1489514899
2CFE9FE92D45404800B25CE0 /* SwiftSoup */,
14900+
2C2EA77E2DA3F2990085F5BC /* Lottie */,
1489614901
);
1489714902
productName = Ecosia;
1489814903
productReference = 2CFE99662D45329200B25CE0 /* Ecosia.framework */;
@@ -14917,6 +14922,7 @@
1491714922
name = EcosiaTests;
1491814923
packageProductDependencies = (
1491914924
2CFE9FBE2D45348200B25CE0 /* SnowplowTracker */,
14925+
2CC0C2AC2DA804EA006FE9B7 /* ViewInspector */,
1492014926
);
1492114927
productName = EcosiaTests;
1492214928
productReference = 2CFE996F2D45329300B25CE0 /* EcosiaTests.xctest */;
@@ -15464,6 +15470,7 @@
1546415470
126509832CD925B30011BA36 /* XCRemoteSwiftPackageReference "braze-swift-sdk" */,
1546515471
12C25BEB2D27EBFF0048BADA /* XCRemoteSwiftPackageReference "snowplow-ios-tracker" */,
1546615472
2CFE9FE82D453F9600B25CE0 /* XCRemoteSwiftPackageReference "SwiftSoup" */,
15473+
2CC0C2A72DA802CD006FE9B7 /* XCRemoteSwiftPackageReference "ViewInspector" */,
1546715474
);
1546815475
productRefGroup = F84B21BF1A090F8100AAB793 /* Products */;
1546915476
projectDirPath = "";
@@ -27139,6 +27146,14 @@
2713927146
minimumVersion = 1.17.3;
2714027147
};
2714127148
};
27149+
2CC0C2A72DA802CD006FE9B7 /* XCRemoteSwiftPackageReference "ViewInspector" */ = {
27150+
isa = XCRemoteSwiftPackageReference;
27151+
repositoryURL = "https://github.com/nalexn/ViewInspector.git";
27152+
requirement = {
27153+
kind = upToNextMajorVersion;
27154+
minimumVersion = 0.10.1;
27155+
};
27156+
};
2714227157
2CCFB3D82C0FC4DC00BEDCA0 /* XCRemoteSwiftPackageReference "rust-components-swift" */ = {
2714327158
isa = XCRemoteSwiftPackageReference;
2714427159
repositoryURL = "https://github.com/ecosia/rust-components-swift/";
@@ -27270,6 +27285,11 @@
2727027285
isa = XCSwiftPackageProductDependency;
2727127286
productName = Redux;
2727227287
};
27288+
2C2EA77E2DA3F2990085F5BC /* Lottie */ = {
27289+
isa = XCSwiftPackageProductDependency;
27290+
package = 8AB30EC62B6C038600BD9A9B /* XCRemoteSwiftPackageReference "lottie-ios" */;
27291+
productName = Lottie;
27292+
};
2727327293
2C69DA7A2C6225C400D7F69F /* Common */ = {
2727427294
isa = XCSwiftPackageProductDependency;
2727527295
productName = Common;
@@ -27284,6 +27304,11 @@
2728427304
package = 2CCFB3D82C0FC4DC00BEDCA0 /* XCRemoteSwiftPackageReference "rust-components-swift" */;
2728527305
productName = MozillaAppServices;
2728627306
};
27307+
2CC0C2AC2DA804EA006FE9B7 /* ViewInspector */ = {
27308+
isa = XCSwiftPackageProductDependency;
27309+
package = 2CC0C2A72DA802CD006FE9B7 /* XCRemoteSwiftPackageReference "ViewInspector" */;
27310+
productName = ViewInspector;
27311+
};
2728727312
2CFE9FBE2D45348200B25CE0 /* SnowplowTracker */ = {
2728827313
isa = XCSwiftPackageProductDependency;
2728927314
package = 12C25BEB2D27EBFF0048BADA /* XCRemoteSwiftPackageReference "snowplow-ios-tracker" */;

Diff for: firefox-ios/Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+9
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@
225225
"version" : "2.0.0"
226226
}
227227
},
228+
{
229+
"identity" : "viewinspector",
230+
"kind" : "remoteSourceControl",
231+
"location" : "https://github.com/nalexn/ViewInspector.git",
232+
"state" : {
233+
"revision" : "788e7879d38a839c4e348ab0762dcc0364e646a2",
234+
"version" : "0.10.1"
235+
}
236+
},
228237
{
229238
"identity" : "xctest-dynamic-overlay",
230239
"kind" : "remoteSourceControl",

Diff for: firefox-ios/Client/Ecosia/Extensions/AppSettingsTableViewController+Ecosia.swift

+36-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ extension AppSettingsTableViewController {
1111

1212
func getEcosiaSettingsSectionsShowingDebug(_ isDebugSectionEnabled: Bool) -> [SettingSection] {
1313
var sections = [
14-
getEcosiaDefaultBrowserSection(),
1514
getSearchSection(),
1615
getCustomizationSection(),
1716
getEcosiaGeneralSection(),
@@ -20,6 +19,10 @@ extension AppSettingsTableViewController {
2019
getEcosiaAboutSection()
2120
]
2221

22+
if User.shared.shouldShowDefaultBrowserSettingNudgeCard {
23+
sections.insert(getEcosiaDefaultBrowserSection(), at: 0)
24+
}
25+
2326
if isDebugSectionEnabled {
2427
sections.append(getEcosiaDebugSupportSection())
2528
}
@@ -30,14 +33,15 @@ extension AppSettingsTableViewController {
3033

3134
extension AppSettingsTableViewController {
3235

36+
// We need this section as a placeholder for the default browser nudge card.
3337
private func getEcosiaDefaultBrowserSection() -> SettingSection {
34-
.init(footerTitle: .init(string: .localized(.linksFromWebsites)),
35-
children: [DefaultBrowserSetting(theme: themeManager.getCurrentTheme(for: windowUUID))])
38+
.init(children: [DefaultBrowserSetting(theme: themeManager.getCurrentTheme(for: windowUUID))])
3639
}
3740

3841
private func getSearchSection() -> SettingSection {
3942

40-
var settings: [Setting] = [
43+
let settings: [Setting] = [
44+
EcosiaDefaultBrowserSettings(),
4145
SearchAreaSetting(settings: self),
4246
SafeSearchSettings(settings: self),
4347
AutoCompleteSettings(prefs: profile.prefs, theme: themeManager.getCurrentTheme(for: windowUUID)),
@@ -149,6 +153,7 @@ extension AppSettingsTableViewController {
149153
AddClaim(settings: self),
150154
ChangeSearchCount(settings: self),
151155
ResetSearchCount(settings: self),
156+
ResetDefaultBrowserNudgeCard(settings: self),
152157
AnalyticsIdentifierSetting(settings: self),
153158
FasterInactiveTabs(settings: self, settingsDelegate: self),
154159
UnleashBrazeIntegrationSetting(settings: self),
@@ -170,3 +175,30 @@ extension AppSettingsTableViewController {
170175
return SettingSection(title: NSAttributedString(string: "Debug"), children: hiddenDebugSettings)
171176
}
172177
}
178+
179+
// MARK: - Default Browser Nudge Card helpers
180+
181+
extension AppSettingsTableViewController {
182+
183+
func isDefaultBrowserCell(_ section: Int) -> Bool {
184+
settings[section].children.first?.accessibilityIdentifier == AccessibilityIdentifiers.Settings.DefaultBrowser.defaultBrowser
185+
}
186+
187+
func shouldShowDefaultBrowserNudgeCardInSection(_ section: Int) -> Bool {
188+
isDefaultBrowserCell(section) &&
189+
User.shared.shouldShowDefaultBrowserSettingNudgeCard
190+
}
191+
192+
func hideDefaultBrowserNudgeCardInSection(_ section: Int) {
193+
guard section < settings.count else { return }
194+
self.settings.remove(at: section)
195+
self.tableView.deleteSections(IndexSet(integer: section), with: .automatic)
196+
}
197+
198+
func showDefaultBrowserDetailView() {
199+
DefaultBrowserCoordinator.makeDefaultCoordinatorAndShowDetailViewFrom(navigationController,
200+
analyticsLabel: .settingsNudgeCard,
201+
topViewContentBackground: EcosiaColor.DarkGreen50.color,
202+
with: themeManager.getCurrentTheme(for: windowUUID))
203+
}
204+
}

Diff for: firefox-ios/Client/Ecosia/Settings/EcosiaDebugSettings.swift

+19
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,25 @@ final class ChangeSearchCount: HiddenSetting {
200200
}
201201
}
202202

203+
final class ResetDefaultBrowserNudgeCard: HiddenSetting {
204+
override var title: NSAttributedString? {
205+
return NSAttributedString(string: "Debug: Makes the Default Browser nudge card visible again", attributes: [NSAttributedString.Key.foregroundColor: theme.colors.ecosia.tableViewRowText])
206+
}
207+
208+
override var status: NSAttributedString? {
209+
let status = "\(User.shared.shouldShowDefaultBrowserSettingNudgeCard)"
210+
let suggestion = User.shared.shouldShowDefaultBrowserSettingNudgeCard ? "" : " (Click to show)"
211+
return NSAttributedString(string: "Card visible: \(status)\(suggestion)", attributes: [NSAttributedString.Key.foregroundColor: theme.colors.ecosia.tableViewRowText])
212+
}
213+
214+
override func onClick(_ navigationController: UINavigationController?) {
215+
guard !User.shared.shouldShowDefaultBrowserSettingNudgeCard else { return }
216+
User.shared.showDefaultBrowserSettingNudgeCard()
217+
self.settings.settings = self.settings.generateSettings()
218+
self.settings.tableView.reloadData()
219+
}
220+
}
221+
203222
class UnleashVariantResetSetting: HiddenSetting {
204223
var titleName: String? { return nil }
205224
var variant: Unleash.Variant? { return nil }

Diff for: firefox-ios/Client/Ecosia/Settings/EcosiaSettings.swift

+16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ func ecosiaDisclosureIndicator(theme: Theme) -> UIImageView {
1616
return disclosureIndicator
1717
}
1818

19+
final class EcosiaDefaultBrowserSettings: Setting {
20+
21+
override var accessoryView: UIImageView? { ecosiaDisclosureIndicator(theme: theme) }
22+
23+
override var title: NSAttributedString? {
24+
NSAttributedString(string: .localized(.defaultBrowserSettingTitle), attributes: [NSAttributedString.Key.foregroundColor: theme.colors.ecosia.tableViewRowText])
25+
}
26+
27+
override func onClick(_ navigationController: UINavigationController?) {
28+
DefaultBrowserCoordinator.makeDefaultCoordinatorAndShowDetailViewFrom(navigationController,
29+
analyticsLabel: .settings,
30+
topViewContentBackground: EcosiaColor.DarkGreen50.color,
31+
with: theme)
32+
}
33+
}
34+
1935
final class SearchAreaSetting: Setting {
2036
override var title: NSAttributedString? {
2137
NSAttributedString(string: .localized(.searchRegion), attributes: [NSAttributedString.Key.foregroundColor: theme.colors.ecosia.tableViewRowText])
Binary file not shown.

0 commit comments

Comments
 (0)