Skip to content

Commit bf2777e

Browse files
[iOS 26] Fix broken country select navigation (#16171)
2 parents 94221d2 + 328e4aa commit bf2777e

File tree

2 files changed

+121
-102
lines changed

2 files changed

+121
-102
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
23.4
55
-----
6-
6+
- [*] Order details: Fixes broken country selector navigation and "Non editable banner" width. [https://github.com/woocommerce/woocommerce-ios/pull/16171]
77

88
23.3
99
-----

WooCommerce/Classes/ViewRelated/Orders/Order Creation/OrderForm.swift

Lines changed: 120 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ struct OrderForm: View {
222222

223223
@State private var shouldShowGiftCardForm = false
224224

225+
@State private var bannerWidth: CGFloat = 0
226+
225227
@Environment(\.adaptiveModalContainerPresentationStyle) var presentationStyle
226228

227229
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@@ -239,6 +241,12 @@ struct OrderForm: View {
239241
viewModel.saveInFlightOrderNotes()
240242
viewModel.saveInflightCustomerDetails()
241243
}
244+
.background(
245+
GeometryReader { geometryProxy in
246+
Color.clear
247+
.preference(key: WidthPreferenceKey.self, value: geometryProxy.size.width)
248+
}
249+
)
242250
}
243251

244252
private func updateSelectionSyncApproach(for presentationStyle: AdaptiveModalContainerPresentationStyle?) {
@@ -251,137 +259,139 @@ struct OrderForm: View {
251259
}
252260

253261
@ViewBuilder private func orderFormSummary(_ presentProductSelector: (() -> Void)?) -> some View {
254-
GeometryReader { geometry in
255-
ScrollViewReader { scroll in
256-
ScrollView {
257-
Group {
258-
VStack(spacing: Layout.noSpacing) {
259-
Spacer(minLength: Layout.sectionSpacing)
262+
ScrollViewReader { scroll in
263+
ScrollView {
264+
Group {
265+
VStack(spacing: Layout.noSpacing) {
266+
Spacer(minLength: Layout.sectionSpacing)
260267

268+
if viewModel.shouldShowNonEditableIndicators {
261269
Group {
262270
Divider() // Needed because `NonEditableOrderBanner` does not have a top divider
263-
NonEditableOrderBanner(width: geometry.size.width)
271+
NonEditableOrderBanner(width: bannerWidth)
264272
}
265-
.renderedIf(viewModel.shouldShowNonEditableIndicators)
266-
267-
Group {
268-
OrderStatusSection(viewModel: viewModel, topDivider: !viewModel.shouldShowNonEditableIndicators)
269-
Spacer(minLength: Layout.sectionSpacing)
270-
}
271-
.renderedIf(flow == .editing)
272-
273-
ProductsSection(scroll: scroll,
274-
flow: flow,
275-
presentProductSelector: presentProductSelector,
276-
viewModel: viewModel,
277-
navigationButtonID: $navigationButtonID,
278-
isLoading: isLoading)
279-
.disabled(viewModel.shouldShowNonEditableIndicators)
273+
}
280274

281-
Group {
282-
Divider()
283-
Spacer(minLength: Layout.sectionSpacing)
284-
Divider()
285-
}
286-
.renderedIf(viewModel.shouldSplitProductsAndCustomAmountsSections)
275+
Group {
276+
OrderStatusSection(viewModel: viewModel, topDivider: !viewModel.shouldShowNonEditableIndicators)
277+
Spacer(minLength: Layout.sectionSpacing)
278+
}
279+
.renderedIf(flow == .editing)
287280

288-
OrderCustomAmountsSection(viewModel: viewModel, sectionViewModel: viewModel.customAmountsSectionViewModel)
289-
.disabled(viewModel.shouldShowNonEditableIndicators)
281+
ProductsSection(scroll: scroll,
282+
flow: flow,
283+
presentProductSelector: presentProductSelector,
284+
viewModel: viewModel,
285+
navigationButtonID: $navigationButtonID,
286+
isLoading: isLoading)
287+
.disabled(viewModel.shouldShowNonEditableIndicators)
290288

289+
Group {
291290
Divider()
292-
293291
Spacer(minLength: Layout.sectionSpacing)
292+
Divider()
293+
}
294+
.renderedIf(viewModel.shouldSplitProductsAndCustomAmountsSections)
294295

295-
Group {
296-
OrderShippingSection(viewModel: viewModel.shippingLineViewModel)
297-
.disabled(viewModel.shouldShowNonEditableIndicators)
298-
Spacer(minLength: Layout.sectionSpacing)
299-
}
300-
.renderedIf(viewModel.shippingLineViewModel.shippingLineRows.isNotEmpty)
301-
302-
Group {
303-
OrderCouponSectionView(viewModel: viewModel, couponViewModel: viewModel.couponLineViewModel)
304-
.disabled(viewModel.shouldShowNonEditableIndicators)
305-
Spacer(minLength: Layout.sectionSpacing)
306-
}
307-
.renderedIf(viewModel.couponLineViewModel.couponLineRows.isNotEmpty)
308-
309-
AddOrderComponentsSection(
310-
viewModel: viewModel.paymentDataViewModel,
311-
shippingLineViewModel: viewModel.shippingLineViewModel,
312-
couponLineViewModel: viewModel.couponLineViewModel,
313-
shouldShowCouponsInfoTooltip: $shouldShowInformationalCouponTooltip,
314-
shouldShowGiftCardForm: $shouldShowGiftCardForm)
315-
.addingTopAndBottomDividers()
296+
OrderCustomAmountsSection(viewModel: viewModel, sectionViewModel: viewModel.customAmountsSectionViewModel)
316297
.disabled(viewModel.shouldShowNonEditableIndicators)
317298

299+
Divider()
300+
301+
Spacer(minLength: Layout.sectionSpacing)
302+
303+
Group {
304+
OrderShippingSection(viewModel: viewModel.shippingLineViewModel)
305+
.disabled(viewModel.shouldShowNonEditableIndicators)
318306
Spacer(minLength: Layout.sectionSpacing)
319307
}
308+
.renderedIf(viewModel.shippingLineViewModel.shippingLineRows.isNotEmpty)
320309

321-
VStack(spacing: Layout.noSpacing) {
322-
Group {
323-
NewTaxRateSection(text: viewModel.taxRateRowText) {
324-
viewModel.onSetNewTaxRateTapped()
325-
switch viewModel.taxRateRowAction {
326-
case .storedTaxRateSheet:
327-
shouldShowStoredTaxRateSheet = true
328-
viewModel.onStoredTaxRateBottomSheetAppear()
329-
case .taxSelector:
330-
shouldShowNewTaxRateSelector = true
331-
}
310+
Group {
311+
OrderCouponSectionView(viewModel: viewModel, couponViewModel: viewModel.couponLineViewModel)
312+
.disabled(viewModel.shouldShowNonEditableIndicators)
313+
Spacer(minLength: Layout.sectionSpacing)
314+
}
315+
.renderedIf(viewModel.couponLineViewModel.couponLineRows.isNotEmpty)
316+
317+
AddOrderComponentsSection(
318+
viewModel: viewModel.paymentDataViewModel,
319+
shippingLineViewModel: viewModel.shippingLineViewModel,
320+
couponLineViewModel: viewModel.couponLineViewModel,
321+
shouldShowCouponsInfoTooltip: $shouldShowInformationalCouponTooltip,
322+
shouldShowGiftCardForm: $shouldShowGiftCardForm)
323+
.addingTopAndBottomDividers()
324+
.disabled(viewModel.shouldShowNonEditableIndicators)
325+
326+
Spacer(minLength: Layout.sectionSpacing)
327+
}
332328

333-
}
334-
.sheet(isPresented: $shouldShowNewTaxRateSelector) {
335-
NewTaxRateSelectorView(viewModel: NewTaxRateSelectorViewModel(siteID: viewModel.siteID,
336-
onTaxRateSelected: { taxRate in
337-
viewModel.onTaxRateSelected(taxRate)
338-
}),
339-
taxEducationalDialogViewModel: viewModel.paymentDataViewModel.taxEducationalDialogViewModel,
340-
onDismissWpAdminWebView: viewModel.paymentDataViewModel.onDismissWpAdminWebViewClosure,
341-
storeSelectedTaxRate: viewModel.shouldStoreTaxRateInSelectorByDefault)
342-
}
343-
.sheet(isPresented: $shouldShowStoredTaxRateSheet) {
344-
if #available(iOS 16.0, *) {
345-
storedTaxRateBottomSheetContent
346-
.presentationDetents([.medium])
347-
.presentationDragIndicator(.visible)
348-
} else {
349-
storedTaxRateBottomSheetContent
350-
}
329+
VStack(spacing: Layout.noSpacing) {
330+
Group {
331+
NewTaxRateSection(text: viewModel.taxRateRowText) {
332+
viewModel.onSetNewTaxRateTapped()
333+
switch viewModel.taxRateRowAction {
334+
case .storedTaxRateSheet:
335+
shouldShowStoredTaxRateSheet = true
336+
viewModel.onStoredTaxRateBottomSheetAppear()
337+
case .taxSelector:
338+
shouldShowNewTaxRateSelector = true
351339
}
352340

353-
Spacer(minLength: Layout.sectionSpacing)
354341
}
355-
.renderedIf(viewModel.shouldShowNewTaxRateSection)
356-
357-
Divider()
358-
359-
if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.subscriptionsInOrderCreationCustomers) {
360-
OrderCustomerSection(viewModel: viewModel.customerSectionViewModel)
361-
} else {
362-
LegacyOrderCustomerSection(viewModel: viewModel, addressFormViewModel: viewModel.addressFormViewModel)
342+
.sheet(isPresented: $shouldShowNewTaxRateSelector) {
343+
NewTaxRateSelectorView(viewModel: NewTaxRateSelectorViewModel(siteID: viewModel.siteID,
344+
onTaxRateSelected: { taxRate in
345+
viewModel.onTaxRateSelected(taxRate)
346+
}),
347+
taxEducationalDialogViewModel: viewModel.paymentDataViewModel.taxEducationalDialogViewModel,
348+
onDismissWpAdminWebView: viewModel.paymentDataViewModel.onDismissWpAdminWebViewClosure,
349+
storeSelectedTaxRate: viewModel.shouldStoreTaxRateInSelectorByDefault)
350+
}
351+
.sheet(isPresented: $shouldShowStoredTaxRateSheet) {
352+
if #available(iOS 16.0, *) {
353+
storedTaxRateBottomSheetContent
354+
.presentationDetents([.medium])
355+
.presentationDragIndicator(.visible)
356+
} else {
357+
storedTaxRateBottomSheetContent
358+
}
363359
}
364360

365-
Group {
366-
Divider()
361+
Spacer(minLength: Layout.sectionSpacing)
362+
}
363+
.renderedIf(viewModel.shouldShowNewTaxRateSection)
367364

368-
Spacer(minLength: Layout.sectionSpacing)
365+
Divider()
369366

370-
Divider()
371-
}
372-
.renderedIf(viewModel.shouldSplitCustomerAndNoteSections)
367+
if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.subscriptionsInOrderCreationCustomers) {
368+
OrderCustomerSection(viewModel: viewModel.customerSectionViewModel)
369+
} else {
370+
LegacyOrderCustomerSection(viewModel: viewModel, addressFormViewModel: viewModel.addressFormViewModel)
371+
}
372+
373+
Group {
374+
Divider()
373375

374-
CustomerNoteSection(viewModel: viewModel)
376+
Spacer(minLength: Layout.sectionSpacing)
375377

376378
Divider()
377379
}
380+
.renderedIf(viewModel.shouldSplitCustomerAndNoteSections)
381+
382+
CustomerNoteSection(viewModel: viewModel)
383+
384+
Divider()
378385
}
379-
.disabled(viewModel.disabled)
380386
}
381-
.accessibilityIdentifier(Accessibility.orderFormScrollViewIdentifier)
382-
.background(Color(.listBackground).ignoresSafeArea())
383-
.ignoresSafeArea(.container, edges: [.horizontal])
387+
.disabled(viewModel.disabled)
384388
}
389+
.accessibilityIdentifier(Accessibility.orderFormScrollViewIdentifier)
390+
.background(Color(.listBackground).ignoresSafeArea())
391+
.ignoresSafeArea(.container, edges: [.horizontal])
392+
}
393+
.onPreferenceChange(WidthPreferenceKey.self) { newWidth in
394+
bannerWidth = newWidth
385395
}
386396
.safeAreaInset(edge: .bottom) {
387397
VStack {
@@ -863,6 +873,15 @@ private extension OrderForm {
863873
}
864874
}
865875

876+
private extension OrderForm {
877+
struct WidthPreferenceKey: PreferenceKey {
878+
static var defaultValue: CGFloat = .zero
879+
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
880+
value = max(value, nextValue())
881+
}
882+
}
883+
}
884+
866885
struct OrderForm_Previews: PreviewProvider {
867886
static var previews: some View {
868887
let viewModel = EditableOrderViewModel(siteID: 123)

0 commit comments

Comments
 (0)