@@ -24,25 +24,26 @@ import Core
2424/// Variant B Builder: Custom structure with specific sections
2525final class BrowsingMenuVariantBBuilder : BrowsingMenuVariantBuilder {
2626 private weak var entryBuilder : BrowsingMenuEntryBuilding ?
27-
27+
2828 init ( entryBuilder: BrowsingMenuEntryBuilding ) {
2929 self . entryBuilder = entryBuilder
3030 }
31-
31+
3232 func buildMenu(
3333 context: BrowsingMenuContext ,
3434 bookmarksInterface: MenuBookmarksInteracting ,
3535 mobileCustomization: MobileCustomization ,
3636 clearTabsAndData: @escaping ( ) -> Void
3737 ) -> BrowsingMenuModel ? {
38-
38+
3939 switch context {
4040 case . newTabPage:
41- return buildNewTabPageMenu ( )
42-
41+ return buildNewTabPageMenu ( mobileCustomization: mobileCustomization,
42+ clearTabsAndData: clearTabsAndData)
43+
4344 case . aiChatTab:
4445 return buildAIChatMenu ( )
45-
46+
4647 case . website:
4748 return buildWebsiteMenu (
4849 bookmarksInterface: bookmarksInterface,
@@ -51,41 +52,51 @@ final class BrowsingMenuVariantBBuilder: BrowsingMenuVariantBuilder {
5152 )
5253 }
5354 }
54-
55- private func buildNewTabPageMenu( ) -> BrowsingMenuModel ? {
55+
56+ private func buildNewTabPageMenu( mobileCustomization: MobileCustomization ,
57+ clearTabsAndData: @escaping ( ) -> Void ) -> BrowsingMenuModel ? {
5658 guard let entryBuilder = entryBuilder else { return nil }
57-
59+
5860 var headerItems = [ BrowsingMenuModel . Entry] ( )
59-
61+
6062 let newTabEntry = entryBuilder. buildNewTabEntry ( )
6163 headerItems. append ( . init( newTabEntry) )
62-
63- var sectionItems = [ BrowsingMenuEntry] ( )
64-
64+
6565 if entryBuilder. shouldShowAIChatInMenu {
66- let chatEntry = entryBuilder. buildChatEntry ( withSmallIcon: true )
67- sectionItems . append ( chatEntry)
66+ let chatEntry = entryBuilder. buildChatEntry ( withSmallIcon: false )
67+ headerItems . append ( . init ( chatEntry) )
6868 }
69-
69+
70+ var shortcutsItems = [ BrowsingMenuModel . Entry] ( )
71+
7072 let bookmarksEntry = entryBuilder. buildOpenBookmarksEntry ( )
71- sectionItems . append ( bookmarksEntry)
72-
73+ shortcutsItems . append ( . init ( bookmarksEntry) )
74+
7375 if entryBuilder. featureFlagger. isFeatureOn ( . autofillAccessCredentialManagement) {
7476 let autofillEntry = entryBuilder. buildAutoFillEntry ( )
75- sectionItems . append ( autofillEntry)
77+ shortcutsItems . append ( . init ( autofillEntry) )
7678 }
77-
79+
7880 let downloadsEntry = entryBuilder. buildDownloadsEntry ( )
79- sectionItems. append ( downloadsEntry)
80-
81+ shortcutsItems. append ( . init( downloadsEntry) )
82+
83+ // Privacy section
84+ var privacyItems = [ BrowsingMenuModel . Entry] ( )
85+
8186 if entryBuilder. featureFlagger. isFeatureOn ( . vpnMenuItem) , AppDependencyProvider . shared. subscriptionAuthV1toV2Bridge. canPurchase {
8287 let vpnEntry = entryBuilder. buildVPNEntry ( )
83- sectionItems. append ( vpnEntry)
88+ privacyItems. append ( . init( vpnEntry) )
89+ }
90+
91+ if mobileCustomization. isEnabled && !mobileCustomization. hasFireButton {
92+ let clearDataEntry = entryBuilder. buildClearDataEntry ( clearTabsAndData: clearTabsAndData)
93+ privacyItems. append ( . init( clearDataEntry) )
8494 }
85-
86- let sections = [ BrowsingMenuModel . Section (
87- items: sectionItems. map { . init( $0) }
88- ) ]
95+
96+ let sections = [
97+ BrowsingMenuModel . Section ( items: shortcutsItems) ,
98+ BrowsingMenuModel . Section ( items: privacyItems)
99+ ]
89100
90101 var footerItems = [ BrowsingMenuModel . Entry] ( )
91102 let settingsEntry = entryBuilder. buildSettingsEntry ( useSmallIcon: false )
@@ -97,140 +108,140 @@ final class BrowsingMenuVariantBBuilder: BrowsingMenuVariantBuilder {
97108 footerItems: footerItems
98109 )
99110 }
100-
111+
101112 private func buildAIChatMenu( ) -> BrowsingMenuModel ? {
102113 guard let entryBuilder = entryBuilder else { return nil }
103-
114+
104115 let header = entryBuilder. buildAITabMenuHeaderContent ( )
105116 let menu = entryBuilder. buildAITabMenu ( )
106-
117+
107118 let headerItems : [ BrowsingMenuModel . Entry ] = header. map { . init( $0) }
108119 let sections : [ BrowsingMenuModel . Section ] = menu. split ( whereSeparator: \. isSeparator) . map {
109120 BrowsingMenuModel . Section ( items: $0. compactMap { . init( $0) } )
110121 }
111-
122+
112123 return BrowsingMenuModel (
113124 headerItems: headerItems,
114125 sections: sections,
115126 footerItems: [ ]
116127 )
117128 }
118-
129+
119130 private func buildWebsiteMenu(
120131 bookmarksInterface: MenuBookmarksInteracting ,
121132 mobileCustomization: MobileCustomization ,
122133 clearTabsAndData: @escaping ( ) -> Void
123134 ) -> BrowsingMenuModel ? {
124135 guard let entryBuilder = entryBuilder else { return nil }
125-
136+
126137 // Header: new tab, duck.ai (conditional), settings
127138 var headerItems = [ BrowsingMenuModel . Entry] ( )
128139 let newTabEntry = entryBuilder. buildNewTabEntry ( )
129140 headerItems. append ( . init( newTabEntry) )
130-
141+
131142 if entryBuilder. shouldShowAIChatInMenu {
132143 let aiChat = entryBuilder. buildChatEntry ( withSmallIcon: false )
133144 headerItems. append ( . init( aiChat) )
134145 }
135-
146+
136147 // Sections
137148 var sections = [ BrowsingMenuModel . Section] ( )
138-
149+
139150 // Link section
140151 if let link = entryBuilder. link, !entryBuilder. isError {
141152 var linkItems = [ BrowsingMenuModel . Entry] ( )
142-
153+
143154 let bookmarkEntries = entryBuilder. buildBookmarkEntries ( for: link, with: bookmarksInterface)
144155 linkItems. append ( . init( bookmarkEntries. bookmark) )
145156 linkItems. append ( . init( bookmarkEntries. favorite, tag: . favorite) )
146-
157+
147158 let shareEntry = entryBuilder. buildShareEntry ( useSmallIcon: true )
148159 linkItems. append ( . init( shareEntry) )
149-
160+
150161 if !linkItems. isEmpty {
151162 sections. append ( BrowsingMenuModel . Section ( items: linkItems) )
152163 }
153164 }
154-
165+
155166 // Tab actions section
156167 if let link = entryBuilder. link, !entryBuilder. isError {
157168 var tabActionItems = [ BrowsingMenuModel . Entry] ( )
158-
169+
159170 let findInPageEntry = entryBuilder. buildFindInPageEntry ( forLink: link)
160171 tabActionItems. append ( . init( findInPageEntry) )
161-
172+
162173 if let zoomEntry = entryBuilder. buildZoomEntry ( forLink: link) {
163174 tabActionItems. append ( . init( zoomEntry) )
164175 }
165-
176+
166177 let desktopSiteEntry = entryBuilder. buildDesktopSiteEntry ( forLink: link)
167178 tabActionItems. append ( . init( desktopSiteEntry) )
168-
179+
169180 if !tabActionItems. isEmpty {
170181 sections. append ( BrowsingMenuModel . Section ( items: tabActionItems) )
171182 }
172183 }
173-
184+
174185 // Shortcuts section
175186 var shortcutItems = [ BrowsingMenuModel . Entry] ( )
176-
187+
177188 let bookmarksEntry = entryBuilder. buildOpenBookmarksEntry ( )
178189 shortcutItems. append ( . init( bookmarksEntry) )
179-
190+
180191 if entryBuilder. featureFlagger. isFeatureOn ( . autofillAccessCredentialManagement) {
181192 let passwordsEntry = entryBuilder. buildAutoFillEntry ( )
182193 shortcutItems. append ( . init( passwordsEntry) )
183194 }
184-
195+
185196 let downloadsEntry = entryBuilder. buildDownloadsEntry ( )
186197 shortcutItems. append ( . init( downloadsEntry) )
187-
198+
188199 if !shortcutItems. isEmpty {
189200 sections. append ( BrowsingMenuModel . Section ( items: shortcutItems) )
190201 }
191-
202+
192203 // Privacy section
193204 var privacyItems = [ BrowsingMenuModel . Entry] ( )
194-
205+
195206 if entryBuilder. featureFlagger. isFeatureOn ( . vpnMenuItem) , AppDependencyProvider . shared. subscriptionAuthV1toV2Bridge. canPurchase {
196207 let vpnEntry = entryBuilder. buildVPNEntry ( )
197208 privacyItems. append ( . init( vpnEntry) )
198209 }
199-
210+
200211 if let link = entryBuilder. link, !entryBuilder. isError {
201212 if let duckAddressEntry = entryBuilder. buildUseNewDuckAddressEntry ( forLink: link) {
202213 privacyItems. append ( . init( duckAddressEntry) )
203214 }
204-
215+
205216 if let fireproofEntry = entryBuilder. buildKeepSignInEntry ( forLink: link) {
206217 privacyItems. append ( . init( fireproofEntry) )
207218 }
208219 }
209-
220+
210221 if mobileCustomization. isEnabled && !mobileCustomization. hasFireButton {
211222 let clearDataEntry = entryBuilder. buildClearDataEntry ( clearTabsAndData: clearTabsAndData)
212223 privacyItems. append ( . init( clearDataEntry) )
213224 }
214-
225+
215226 if !privacyItems. isEmpty {
216227 sections. append ( BrowsingMenuModel . Section ( items: privacyItems) )
217228 }
218-
229+
219230 // Other section
220231 if entryBuilder. link != nil , !entryBuilder. isError {
221232 var otherItems = [ BrowsingMenuModel . Entry] ( )
222-
233+
223234 let reportBrokenSiteEntry = entryBuilder. buildReportBrokenSiteEntry ( )
224235 otherItems. append ( . init( reportBrokenSiteEntry) )
225-
236+
226237 let printEntry = entryBuilder. buildPrintEntry ( withSmallIcon: true )
227238 otherItems. append ( . init( printEntry) )
228-
239+
229240 if !otherItems. isEmpty {
230241 sections. append ( BrowsingMenuModel . Section ( items: otherItems) )
231242 }
232243 }
233-
244+
234245 // Footer
235246 var footerItems = [ BrowsingMenuModel . Entry] ( )
236247 let settingsEntry = entryBuilder. buildSettingsEntry ( useSmallIcon: false )
@@ -252,4 +263,3 @@ private extension BrowsingMenuEntry {
252263 }
253264 }
254265}
255-
0 commit comments