Skip to content

Commit f5be5a3

Browse files
authored
Merge branch 'trunk' into issue/handle-variation-ids-in-dotcom-errors
2 parents 96d9ab1 + 6abd2f2 commit f5be5a3

25 files changed

+369
-365
lines changed

.buildkite/pipeline.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,20 @@ steps:
3131
- github_commit_status:
3232
context: Prototype Build
3333

34+
- group: ":rocket: Prototype Build"
35+
if: build.branch == "trunk"
36+
steps:
37+
- input: Deploy Prototype Build?
38+
prompt: Share a Prototype Build via Firebase App Distribution?
39+
key: prototype_triggered
40+
- label: Prototype Build
41+
depends_on: prototype_triggered
42+
command: .buildkite/commands/prototype-build.sh
43+
plugins: [$CI_TOOLKIT]
44+
notify:
45+
- github_commit_status:
46+
context: Prototype Build From Trunk
47+
3448
#################
3549
# Run Unit Tests
3650
#################

Modules/Sources/PointOfSale/Presentation/Orders/POSOrderDetailsView.swift

Lines changed: 91 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct POSOrderDetailsView: View {
1414
@Environment(\.siteTimezone) private var siteTimezone
1515
@Environment(POSOrderListModel.self) private var orderListModel
1616
@Environment(\.posAnalytics) private var analytics
17+
@Environment(\.posFeatureFlags) private var featureFlags
1718
@State private var isShowingEmailReceiptView: Bool = false
1819

1920
private var shouldShowBackButton: Bool {
@@ -32,9 +33,7 @@ struct POSOrderDetailsView: View {
3233
title: POSOrderListView.Localization.orderTitle(order.number),
3334
backButtonConfiguration: shouldShowBackButton ? .init(state: .enabled, action: onBack) : nil,
3435
trailingContent: {
35-
if actions.isNotEmpty {
36-
actionsSection(actions)
37-
}
36+
actionsSection(setup: availableActionsSetup)
3837
},
3938
bottomContent: {
4039
headerBottomContent(for: order)
@@ -377,59 +376,102 @@ private extension POSOrderDetailsView {
377376

378377
// MARK: - Actions
379378
private extension POSOrderDetailsView {
380-
enum POSOrderDetailsAction: Identifiable, CaseIterable {
379+
enum OrderDetailsAction: Identifiable, CaseIterable {
380+
case issueRefund
381381
case emailReceipt
382382

383383
var id: String { title }
384384

385385
var title: String {
386386
switch self {
387-
case .emailReceipt:
388-
Localization.emailReceiptActionTitle
387+
case .issueRefund: Localization.issueRefundActionTitle
388+
case .emailReceipt: Localization.emailReceiptActionTitle
389389
}
390390
}
391391

392-
func available(for order: POSOrder) -> Bool {
392+
var accessibilityHint: String {
393393
switch self {
394+
case .issueRefund: Localization.issueRefundAccessibilityHint
395+
case .emailReceipt: Localization.emailReceiptAccessibilityHint
396+
}
397+
}
398+
399+
var priority: Int {
400+
switch self {
401+
case .issueRefund: 100
402+
case .emailReceipt: 50
403+
}
404+
}
405+
406+
func isAvailable(for order: POSOrder, flags: POSFeatureFlagProviding) -> Bool {
407+
guard order.status == .completed else { return false }
408+
switch self {
409+
case .issueRefund:
410+
return flags.isFeatureFlagEnabled(.pointOfSaleRefundsi1)
394411
case .emailReceipt:
395-
order.status == .completed
412+
return true
413+
}
414+
}
415+
}
416+
417+
func handler(for action: OrderDetailsAction) -> @MainActor () -> Void {
418+
switch action {
419+
case .emailReceipt:
420+
return {
421+
analytics.track(event: WooAnalyticsEvent.PointOfSale.orderDetailsEmailReceiptTapped())
422+
isShowingEmailReceiptView = true
396423
}
424+
case .issueRefund:
425+
return { }
397426
}
398427
}
399428

400-
var actions: [POSOrderDetailsAction] {
401-
POSOrderDetailsAction.allCases.filter { $0.available(for: order) }
429+
struct OrderDetailsActionsSetup {
430+
let primary: OrderDetailsAction?
431+
let secondary: [OrderDetailsAction]
432+
}
433+
434+
var availableActionsSetup: OrderDetailsActionsSetup {
435+
let available = OrderDetailsAction.allCases
436+
.filter { $0.isAvailable(for: order, flags: featureFlags) }
437+
.sorted { $0.priority > $1.priority }
438+
439+
let primary = available.first
440+
let secondary = Array(available.dropFirst())
441+
442+
return OrderDetailsActionsSetup(primary: primary, secondary: secondary)
402443
}
403444

404445
@ViewBuilder
405-
func actionsSection(_ actions: [POSOrderDetailsAction]) -> some View {
406-
VStack {
407-
HStack {
408-
ForEach(actions) { action in
409-
Button(action: {
410-
switch action {
411-
case .emailReceipt:
412-
analytics.track(event: WooAnalyticsEvent.PointOfSale.orderDetailsEmailReceiptTapped())
413-
isShowingEmailReceiptView = true
446+
func actionsSection(setup: OrderDetailsActionsSetup) -> some View {
447+
if let primary = setup.primary {
448+
HStack(spacing: POSSpacing.large) {
449+
Button(primary.title, action: handler(for: primary))
450+
.buttonStyle(POSFilledButtonStyle(size: .extraSmall))
451+
.accessibilityHint(primary.accessibilityHint)
452+
453+
if !setup.secondary.isEmpty {
454+
Menu {
455+
ForEach(setup.secondary) { action in
456+
Button(action.title, action: handler(for: action))
457+
.accessibilityHint(action.accessibilityHint)
414458
}
415-
}) {
416-
Text(Localization.emailReceiptActionTitle)
417-
.lineLimit(1)
418-
.minimumScaleFactor(0.5)
459+
} label: {
460+
Image(systemName: "ellipsis")
461+
.font(.posBodyLargeBold)
462+
.dynamicTypeSize(...DynamicTypeSize.accessibility2)
463+
.foregroundColor(.posOnSurface)
464+
.padding(POSPadding.small)
419465
}
420-
.buttonStyle(POSFilledButtonStyle(size: .extraSmall))
421-
.accessibilityHint(accessibilityHint(for: action))
466+
.menuIndicator(.hidden)
422467
}
423468
}
424-
Spacer()
425469
}
426470
}
427471

428-
private func accessibilityHint(for action: POSOrderDetailsAction) -> String {
429-
switch action {
430-
case .emailReceipt:
431-
return Localization.emailReceiptAccessibilityHint
432-
}
472+
func emailReceiptAction() {
473+
analytics.track(event: WooAnalyticsEvent.PointOfSale.orderDetailsEmailReceiptTapped())
474+
isShowingEmailReceiptView = true
433475
}
434476
}
435477

@@ -529,6 +571,24 @@ private enum Localization {
529571
comment: "Accessibility hint for email receipt button on order details view"
530572
)
531573

574+
static let issueRefundActionTitle = NSLocalizedString(
575+
"pos.orderDetailsView.issueRefundAction.title",
576+
value: "Issue refund",
577+
comment: "Primary action button to start issuing a refund on the order details view"
578+
)
579+
580+
static let issueRefundAccessibilityHint = NSLocalizedString(
581+
"pos.orderDetailsView.issueRefundAction.accessibilityHint",
582+
value: "Start refund flow for this order",
583+
comment: "Accessibility hint for issue refund button"
584+
)
585+
586+
static let moreActionsA11yLabel = NSLocalizedString(
587+
"pos.orderDetailsView.moreActions.label",
588+
value: "More actions",
589+
comment: "Accessibility label for the overflow actions menu button (three dots)"
590+
)
591+
532592
static func headerBottomContentAccessibilityLabel(date: String, email: String?, status: String) -> String {
533593
let baseFormat = NSLocalizedString(
534594
"pos.orderDetailsView.headerBottomContent.accessibilityLabel",

Modules/Sources/WPMediaPicker/WPImageExporter.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
@import MobileCoreServices;
44
@import ImageIO;
5+
@import UniformTypeIdentifiers;
56

67
@implementation WPImageExporter
78

@@ -33,7 +34,7 @@ + (BOOL)writeImage:(UIImage *)image withMetadata:(NSDictionary *)metadata toURL:
3334
adjustedMetadata[(NSString *)kCGImagePropertyIPTCDictionary] = adjustedIPTC;
3435
}
3536

36-
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((CFURLRef)fileURL, kUTTypeJPEG, 1, nil);
37+
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((CFURLRef)fileURL, (CFStringRef)UTTypeJPEG.identifier, 1, nil);
3738
if (destination == NULL) {
3839
return NO;
3940
}

Modules/Sources/WPMediaPicker/WPInputMediaPickerViewController.m

Lines changed: 0 additions & 134 deletions
This file was deleted.

Modules/Sources/WPMediaPicker/WPMediaCapturePresenter.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
@import MobileCoreServices;
55
@import AVFoundation;
6+
@import UniformTypeIdentifiers;
67

78
@interface WPMediaCapturePresenter () <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
89
@property (nonatomic, strong, nullable) UIViewController *presentingViewController;
@@ -79,11 +80,10 @@ - (void)presentCaptureViewController
7980
UIImagePickerControllerSourceTypeCamera]];
8081
NSMutableSet *mediaDesired = [NSMutableSet new];
8182
if (self.mediaType & WPMediaTypeImage) {
82-
[mediaDesired addObject:(__bridge NSString *)kUTTypeImage];
83+
[mediaDesired addObject:UTTypeImage.identifier];
8384
}
8485
if (self.mediaType & WPMediaTypeVideo) {
85-
[mediaDesired addObject:(__bridge NSString *)kUTTypeMovie];
86-
86+
[mediaDesired addObject:UTTypeMovie.identifier];
8787
}
8888
if (mediaDesired.count > 0){
8989
[mediaTypes intersectSet:mediaDesired];

0 commit comments

Comments
 (0)