From d2ce9b638d93b96cfc2ae4152929ef8fd6aa8f9b Mon Sep 17 00:00:00 2001 From: Sam Symons Date: Tue, 2 Apr 2024 06:35:36 -0700 Subject: [PATCH] Add LazyView to help with FAQ view allocation (#2660) Task/Issue URL: https://app.asana.com/0/414235014887631/1206765939311868/f Tech Design URL: CC: Description: This PR updates the VPN FAQ row to load the web view lazily. Before this, the web view was being recreated every time the UI updated. --- DuckDuckGo.xcodeproj/project.pbxproj | 4 +++ DuckDuckGo/LazyView.swift | 32 ++++++++++++++++++++ DuckDuckGo/NetworkProtectionStatusView.swift | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 DuckDuckGo/LazyView.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index fcc93ce1c0..2240414f03 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -263,6 +263,7 @@ 4B0F3F502B9BFF2100392892 /* NetworkProtectionFAQView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F3F4F2B9BFF2100392892 /* NetworkProtectionFAQView.swift */; }; 4B274F602AFEAECC003F0745 /* NetworkProtectionWidgetRefreshModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B274F5F2AFEAECC003F0745 /* NetworkProtectionWidgetRefreshModel.swift */; }; 4B37E0502B928CA6009E81CA /* vpn-light-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B37E04F2B928CA6009E81CA /* vpn-light-mode.json */; }; + 4B412ACC2BBB3D0900A39F5E /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B412ACB2BBB3D0900A39F5E /* LazyView.swift */; }; 4B470ED6299C49800086EBDC /* AppTrackingProtectionDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B470ED5299C49800086EBDC /* AppTrackingProtectionDatabase.swift */; }; 4B470ED9299C4AED0086EBDC /* AppTrackingProtectionModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4B470ED7299C4AED0086EBDC /* AppTrackingProtectionModel.xcdatamodeld */; }; 4B470EDB299C4FB20086EBDC /* AppTrackingProtectionListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B470EDA299C4FB20086EBDC /* AppTrackingProtectionListViewModel.swift */; }; @@ -1390,6 +1391,7 @@ 4B0F3F4F2B9BFF2100392892 /* NetworkProtectionFAQView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionFAQView.swift; sourceTree = ""; }; 4B274F5F2AFEAECC003F0745 /* NetworkProtectionWidgetRefreshModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionWidgetRefreshModel.swift; sourceTree = ""; }; 4B37E04F2B928CA6009E81CA /* vpn-light-mode.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "vpn-light-mode.json"; sourceTree = ""; }; + 4B412ACB2BBB3D0900A39F5E /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = ""; }; 4B470ED5299C49800086EBDC /* AppTrackingProtectionDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTrackingProtectionDatabase.swift; sourceTree = ""; }; 4B470ED8299C4AED0086EBDC /* AppTrackingProtectionModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = AppTrackingProtectionModel.xcdatamodel; sourceTree = ""; }; 4B470EDA299C4FB20086EBDC /* AppTrackingProtectionListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTrackingProtectionListViewModel.swift; sourceTree = ""; }; @@ -5546,6 +5548,7 @@ 4BBBBA912B03291700D965DA /* VPNWaitlistUserText.swift */, 986DA94924884B18004A7E39 /* WebViewTransition.swift */, EE9D68D72AE15AD600B55EF4 /* UIApplicationExtension.swift */, + 4B412ACB2BBB3D0900A39F5E /* LazyView.swift */, ); name = UserInterface; sourceTree = ""; @@ -6794,6 +6797,7 @@ 1E4FAA6427D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift in Sources */, 8C4724502217A14B004C9B2D /* TabViewControllerLongPressBookmarkExtension.swift in Sources */, 1EDE39D22705D4A200C99C72 /* FileSizeDebugViewController.swift in Sources */, + 4B412ACC2BBB3D0900A39F5E /* LazyView.swift in Sources */, 85047C772A0D5D3D00D2FF3F /* SyncSettingsViewController+SyncDelegate.swift in Sources */, 85DDE0402AC6FF65006ABCA2 /* MainView.swift in Sources */, 980891A72237D5D800313A70 /* FeedbackPresenter.swift in Sources */, diff --git a/DuckDuckGo/LazyView.swift b/DuckDuckGo/LazyView.swift new file mode 100644 index 0000000000..7605f98e3d --- /dev/null +++ b/DuckDuckGo/LazyView.swift @@ -0,0 +1,32 @@ +// +// LazyView.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 Foundation +import SwiftUI + +// https://gist.github.com/chriseidhof/d2fcafb53843df343fe07f3c0dac41d5 +struct LazyView: View { + let build: () -> Content + init(_ build: @autoclosure @escaping () -> Content) { + self.build = build + } + var body: Content { + build() + } +} diff --git a/DuckDuckGo/NetworkProtectionStatusView.swift b/DuckDuckGo/NetworkProtectionStatusView.swift index 2705b9fdc6..953881fd00 100644 --- a/DuckDuckGo/NetworkProtectionStatusView.swift +++ b/DuckDuckGo/NetworkProtectionStatusView.swift @@ -199,7 +199,7 @@ struct NetworkProtectionStatusView: View { private func about() -> some View { Section { if statusModel.shouldShowFAQ { - NavigationLink(UserText.netPVPNSettingsFAQ, destination: NetworkProtectionFAQView()) + NavigationLink(UserText.netPVPNSettingsFAQ, destination: LazyView(NetworkProtectionFAQView())) .daxBodyRegular() .foregroundColor(.init(designSystemColor: .textPrimary)) }