Skip to content

Commit

Permalink
extract code into own files and tweakk UI
Browse files Browse the repository at this point in the history
  • Loading branch information
brindy committed Oct 25, 2024
1 parent a52dbf1 commit 6bee1ce
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 141 deletions.
2 changes: 2 additions & 0 deletions Core/UserDefaultsPropertyWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ public struct UserDefaultsWrapper<T> {
case duckPlayerPixelExperimentLastVideoIDRendered = "com.duckduckgo.ios.duckplayer.pixel.experiment.last.videoID.rendered.v2"
case duckPlayerPixelExperimentOverride = "com.duckduckgo.ios.duckplayer.pixel.experiment.override.v2"

// Domain specific text zoom
case domainTextZoomStorage = "com.duckduckgo.ios.domainTextZoomStorage"
}

private let key: Key
Expand Down
12 changes: 12 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@
851672D12BED1FC900592F24 /* AutocompleteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851672D02BED1FC900592F24 /* AutocompleteView.swift */; };
851672D32BED23FE00592F24 /* AutocompleteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851672D22BED23FE00592F24 /* AutocompleteViewModel.swift */; };
8517D98B221783A0006A8DD0 /* FindInPage.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8517D98A221783A0006A8DD0 /* FindInPage.xcassets */; };
851A373A2CCC437400CF190B /* TextZoomEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851A37392CCC437400CF190B /* TextZoomEditorModel.swift */; };
851A373C2CCC439E00CF190B /* TextZoomEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851A373B2CCC439E00CF190B /* TextZoomEditorView.swift */; };
851A373E2CCC476F00CF190B /* TabViewController+TextZoomEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851A373D2CCC476F00CF190B /* TabViewController+TextZoomEditor.swift */; };
851B1283221FE65E004781BC /* ImproveOnboardingExperiment1Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851B1281221FE64E004781BC /* ImproveOnboardingExperiment1Tests.swift */; };
851B128822200575004781BC /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851B128722200575004781BC /* Onboarding.swift */; };
851B12CC22369931004781BC /* AtbAndVariantCleanup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850250B220D803F4002199C7 /* AtbAndVariantCleanup.swift */; };
Expand Down Expand Up @@ -1718,6 +1721,9 @@
851672D02BED1FC900592F24 /* AutocompleteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteView.swift; sourceTree = "<group>"; };
851672D22BED23FE00592F24 /* AutocompleteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteViewModel.swift; sourceTree = "<group>"; };
8517D98A221783A0006A8DD0 /* FindInPage.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = FindInPage.xcassets; sourceTree = "<group>"; };
851A37392CCC437400CF190B /* TextZoomEditorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextZoomEditorModel.swift; sourceTree = "<group>"; };
851A373B2CCC439E00CF190B /* TextZoomEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextZoomEditorView.swift; sourceTree = "<group>"; };
851A373D2CCC476F00CF190B /* TabViewController+TextZoomEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TabViewController+TextZoomEditor.swift"; sourceTree = "<group>"; };
851B1281221FE64E004781BC /* ImproveOnboardingExperiment1Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImproveOnboardingExperiment1Tests.swift; sourceTree = "<group>"; };
851B128722200575004781BC /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = "<group>"; };
851B128B2220483A004781BC /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4567,7 +4573,10 @@
isa = PBXGroup;
children = (
85D3FF2A2CC941C100487724 /* DomainTextZoomStorage.swift */,
851A373D2CCC476F00CF190B /* TabViewController+TextZoomEditor.swift */,
859DA3312CCAC0A300C90694 /* TextZoomController.swift */,
851A37392CCC437400CF190B /* TextZoomEditorModel.swift */,
851A373B2CCC439E00CF190B /* TextZoomEditorView.swift */,
85147CB52CCA755300677835 /* TextZoomLevel.swift */,
);
name = TextZoom;
Expand Down Expand Up @@ -7759,6 +7768,7 @@
980891A32237146B00313A70 /* Feedback.swift in Sources */,
F1D796F01E7B07610019D451 /* BookmarksViewControllerCells.swift in Sources */,
9F9EE4D42C37BB1300D4118E /* OnboardingView+Landing.swift in Sources */,
851A373C2CCC439E00CF190B /* TextZoomEditorView.swift in Sources */,
85058369219F424500ED4EDB /* UIColorExtension.swift in Sources */,
BDE219E62C406D19005D5884 /* PrivacyProDataReporting.swift in Sources */,
D6E83C312B1EA309006C8AFB /* SettingsCell.swift in Sources */,
Expand Down Expand Up @@ -7820,6 +7830,7 @@
EE4BE0092A740BED00CD6AA8 /* ClearTextField.swift in Sources */,
56D060282C380D83003BAEB5 /* OnboardingSuggestedSearchesProvider.swift in Sources */,
F44D279C27F331BB0037F371 /* AutofillLoginPromptView.swift in Sources */,
851A373A2CCC437400CF190B /* TextZoomEditorModel.swift in Sources */,
C1EA86622C74CB8B00E8604D /* SyncPromoViewModel.swift in Sources */,
F1FDC9302BF4E0B3006B1435 /* SubscriptionEnvironment+Default.swift in Sources */,
CBD4F13E279EBFAB00B20FD7 /* HomeMessageView.swift in Sources */,
Expand All @@ -7840,6 +7851,7 @@
85864FBC24D31EF300E756FF /* SuggestionTrayViewController.swift in Sources */,
D64648AF2B5993890033090B /* SubscriptionEmailViewModel.swift in Sources */,
1EF24235273BB9D200DE3D02 /* IntervalSlider.swift in Sources */,
851A373E2CCC476F00CF190B /* TabViewController+TextZoomEditor.swift in Sources */,
F1D796EE1E7AF2EB0019D451 /* UIViewControllerExtension.swift in Sources */,
1EE411F12857C3640003FE64 /* TrackerAnimationImageProvider.swift in Sources */,
1E7A711C2934EEBC00B7EA19 /* OmniBarNotification.swift in Sources */,
Expand Down
17 changes: 11 additions & 6 deletions DuckDuckGo/DomainTextZoomStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
//

import Foundation
import Core
import Common

protocol DomainTextZoomStoring {
func textZoomLevelForDomain(_ domain: String) -> TextZoomLevel?
func set(textZoomLevel: TextZoomLevel, forDomain domain: String)
func resetTextZoomLevels(_ excludingDomains: [String])
func resetTextZoomLevels(excludingDomains: [String])
}

class DomainTextZoomStorage: DomainTextZoomStoring {

// TODO persist this
var textZoomLevels: [String: Int] = [:]
@UserDefaultsWrapper(key: .domainTextZoomStorage, defaultValue: [:])
var textZoomLevels: [String: Int]

func textZoomLevelForDomain(_ domain: String) -> TextZoomLevel? {
guard let zoomLevel = textZoomLevels[domain] else {
Expand All @@ -41,9 +43,12 @@ class DomainTextZoomStorage: DomainTextZoomStoring {
textZoomLevels[domain] = textZoomLevel.rawValue
}

func resetTextZoomLevels(_ excludingDomains: [String]) {
textZoomLevels = textZoomLevels.filter {
!excludingDomains.contains($0.key)
func resetTextZoomLevels(excludingDomains: [String]) {
let tld = TLD()
textZoomLevels = textZoomLevels.filter { level in
excludingDomains.contains(where: {
tld.eTLDplus1($0) == level.key
})
}
}

Expand Down
14 changes: 13 additions & 1 deletion DuckDuckGo/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ class MainViewController: UIViewController {
fatalError("Use init?(code:")
}

let preserveLogins: PreserveLogins
let domainTextZoomStorage: DomainTextZoomStoring

var historyManager: HistoryManaging
var viewCoordinator: MainViewCoordinator!

Expand All @@ -197,7 +200,8 @@ class MainViewController: UIViewController {
subscriptionFeatureAvailability: SubscriptionFeatureAvailability,
voiceSearchHelper: VoiceSearchHelperProtocol,
featureFlagger: FeatureFlagger,
domainTextZoomStorage: DomainTextZoomStoring = DomainTextZoomStorage()
domainTextZoomStorage: DomainTextZoomStoring = DomainTextZoomStorage(),
preserveLogins: PreserveLogins = .shared
) {
self.bookmarksDatabase = bookmarksDatabase
self.bookmarksDatabaseCleaner = bookmarksDatabaseCleaner
Expand Down Expand Up @@ -233,6 +237,8 @@ class MainViewController: UIViewController {
self.statisticsStore = statisticsStore
self.subscriptionFeatureAvailability = subscriptionFeatureAvailability
self.voiceSearchHelper = voiceSearchHelper
self.domainTextZoomStorage = domainTextZoomStorage
self.preserveLogins = preserveLogins

super.init(nibName: nil, bundle: nil)

Expand Down Expand Up @@ -2658,6 +2664,7 @@ extension MainViewController: AutoClearWorker {
fireButtonAnimator.animate {
self.tabManager.prepareCurrentTabForDataClearing()
self.stopAllOngoingDownloads()
self.forgetTextZoom()
self.forgetTabs()
await self.forgetData()
Instruments.shared.endTimedEvent(for: spid)
Expand Down Expand Up @@ -2714,6 +2721,11 @@ extension MainViewController: AutoClearWorker {
viewCoordinator.omniBar.dismissOnboardingPrivacyIconAnimation()
}

private func forgetTextZoom() {
let allowedDomains = preserveLogins.allowedDomains
domainTextZoomStorage.resetTextZoomLevels(excludingDomains: allowedDomains)
}

}

extension MainViewController {
Expand Down
43 changes: 43 additions & 0 deletions DuckDuckGo/TabViewController+TextZoomEditor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// TabViewController+TextZoomEditor.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import UIKit

extension TabViewController {

func showTextZoomAdjustment() {
guard let domain = webView.url?.host?.droppingWwwPrefix() else { return }
let controller = TextZoomController(
domain: domain,
storage: domainTextZoomStorage,
defaultTextZoom: appSettings.defaultTextZoomLevel
)

controller.modalPresentationStyle = .formSheet
if #available(iOS 16.0, *) {
controller.sheetPresentationController?.detents = [.custom(resolver: { _ in
return 152
})]
} else {
controller.sheetPresentationController?.detents = [.medium()]
}
present(controller, animated: true)
}

}
3 changes: 2 additions & 1 deletion DuckDuckGo/TabViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,9 @@ class TabViewController: UIViewController {
}

@objc func onTextSizeChange() {
let domain = TLD().eTLDplus1(webView.url?.host) ?? ""
// If the webview returns no host then there won't be a setting for a blank string anyway.
let level = domainTextZoomStorage.textZoomLevelForDomain(webView.url?.host?.droppingWwwPrefix() ?? "")
let level = domainTextZoomStorage.textZoomLevelForDomain(domain)
// And if there's no setting for whatever domain is passed in, use the app default
?? appSettings.defaultTextZoomLevel
webView.adjustTextSize(level.rawValue)
Expand Down
4 changes: 2 additions & 2 deletions DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ extension TabViewController {
}

private func buildZoomLevelEntry(forLink link: Link) -> BrowsingMenuEntry {
let domain = link.url.host?.droppingWwwPrefix() ?? ""
let domain = TLD().eTLDplus1(link.url.host) ?? ""
let percent = domainTextZoomStorage.textZoomLevelForDomain(domain)?.rawValue ?? appSettings.defaultTextZoomLevel.rawValue

return BrowsingMenuEntry.regular(name: UserText.pageZoomWithPercent(percent),
return BrowsingMenuEntry.regular(name: UserText.textZoomWithPercentMenuItem(percent),
image: UIImage(named: "Type-Size-16")!,
showNotificationDot: false) { [weak self] in
self?.showTextZoomAdjustment()
Expand Down
128 changes: 0 additions & 128 deletions DuckDuckGo/TextZoomController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,131 +36,3 @@ class TextZoomController: UIHostingController<TextZoomEditorView> {
}

}

class TextZoomEditorModel: ObservableObject {

let domain: String
let storage: DomainTextZoomStoring

var valueAsPercent: Int {
TextZoomLevel.allCases[value].rawValue
}

@Published var value: Int = 0 {
didSet {
title = UserText.pageZoomWithPercent(valueAsPercent)
storage.set(textZoomLevel: TextZoomLevel.allCases[value], forDomain: domain)
NotificationCenter.default.post(
name: AppUserDefaults.Notifications.textSizeChange,
object: nil)
}
}

@Published var title: String = ""

init(domain: String, storage: DomainTextZoomStoring, defaultTextZoom: TextZoomLevel) {
self.domain = domain
self.storage = storage
let percent = (storage.textZoomLevelForDomain(domain) ?? defaultTextZoom)
value = TextZoomLevel.allCases.firstIndex(of: percent) ?? 0
}

func increment() {
value = min(TextZoomLevel.allCases.count - 1, value + 1)
}

func decrement() {
value = max(0, value - 1)
}

}

struct TextZoomEditorView: View {

@ObservedObject var model: TextZoomEditorModel

@Environment(\.dismiss) var dismiss

@ViewBuilder
func header() -> some View {
ZStack(alignment: .center) {
Text(model.title)
.font(Font(uiFont: .daxHeadline()))
.frame(alignment: .center)

Button {
dismiss()
} label: {
Text(UserText.navigationTitleDone)
.font(Font(uiFont: .daxHeadline()))
}
.buttonStyle(.plain)
.padding(0)
.frame(maxWidth: .infinity, alignment: .trailing)
}
.padding(16)
}

func slider() -> some View {
HStack {
Button {
model.decrement()
} label: {
Image("Font-Smaller-24")
}
.foregroundColor(Color(designSystemColor: .textPrimary))
.padding(12)

IntervalSliderRepresentable(
value: $model.value,
steps: TextZoomLevel.allCases.map { $0.rawValue })
.padding(.vertical)

Button {
model.increment()
} label: {
Image("Font-Larger-24")
}
.foregroundColor(Color(designSystemColor: .textPrimary))
.padding(12)
}
.background(RoundedRectangle(cornerRadius: 8).foregroundColor(Color(designSystemColor: .surface)))
.padding(16)

}

var body: some View {
VStack {
header()
Spacer()
slider()
Spacer()
}
.frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, maxHeight: .infinity)
.background(Color(designSystemColor: .background))
}

}

extension TabViewController {

func showTextZoomAdjustment() {
guard let domain = webView.url?.host?.droppingWwwPrefix() else { return }
let controller = TextZoomController(
domain: domain,
storage: domainTextZoomStorage,
defaultTextZoom: appSettings.defaultTextZoomLevel
)

controller.modalPresentationStyle = .formSheet
if #available(iOS 16.0, *) {
controller.sheetPresentationController?.detents = [.custom(resolver: { _ in
return 180
})]
} else {
controller.sheetPresentationController?.detents = [.medium()]
}
present(controller, animated: true)
}

}
Loading

0 comments on commit 6bee1ce

Please sign in to comment.