Files
purchases-ios/RevenueCatUI/Templates/V2/Components/Tabs/TabControlButtonComponentView.swift
T
Facundo Menzella 3d8461686f ONC-34: Fix tab-button discount package context (#8187)
* Fix tab button discount context

* Fix tab discount tests in hostless CI

* Test shared discount comparison updates for empty tabs

* test: remove diagnostic output from tab discount tests
2026-11-09 15:24:00 +00:00

119 lines
3.8 KiB
Swift

//
// Copyright RevenueCat Inc. All Rights Reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/MIT
//
// TabsComponentView.swift
//
// Created by Josh Holtz on 1/9/25.
import Foundation
@_spi(Internal) import RevenueCat
import SwiftUI
#if !os(tvOS) // For Paywalls V2
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
struct TabControlButtonComponentView: View {
@EnvironmentObject
private var introOfferEligibilityContext: IntroOfferEligibilityContext
@EnvironmentObject
private var packageContext: PackageContext
@Environment(\.componentViewState)
private var componentViewState
@Environment(\.screenCondition)
private var screenCondition
@EnvironmentObject
private var tabControlContext: TabControlContext
@Environment(\.componentInteractionLogger)
private var componentInteractionLogger
@Environment(\.selectionHapticFeedback)
private var hapticFeedback
private let viewModel: TabControlButtonComponentViewModel
private let onDismiss: () -> Void
private var selectedState: ComponentViewState {
return self.tabControlContext.selectedTabId == self.viewModel.component.tabId ? .selected : .default
}
private var hapticFeedbackEnabled: Bool {
self.viewModel.component.hapticFeedbackEnabled ?? true
}
init(viewModel: TabControlButtonComponentViewModel, onDismiss: @escaping () -> Void) {
self.viewModel = viewModel
self.onDismiss = onDismiss
}
var body: some View {
Button {
let originTabId = self.tabControlContext.selectedTabId
let destinationTabId = self.viewModel.component.tabId
self.tabControlContext.selectedTabId = destinationTabId
self.trackTabcomponentInteraction(originTabId: originTabId, destinationTabId: destinationTabId)
if Self.shouldTriggerHapticFeedback(
originTabId: originTabId,
destinationTabId: destinationTabId,
hapticFeedbackEnabled: self.hapticFeedbackEnabled
) {
self.hapticFeedback()
}
} label: {
StackComponentView(
viewModel: self.viewModel.stackViewModel,
onDismiss: self.onDismiss
)
.environmentObject(
self.tabControlContext.textPackageContextsByTabId[self.viewModel.component.tabId] ?? self.packageContext
)
.environment(\.componentViewState, self.selectedState)
}
.onAppear {
if self.hapticFeedbackEnabled {
self.hapticFeedback.prepare()
}
}
}
private func trackTabcomponentInteraction(originTabId: String, destinationTabId: String) {
let destinationContextName = self.tabControlContext.contextName(for: destinationTabId)
_ = self.componentInteractionLogger(.paywallTabControlButtonSelection(
componentName: self.tabControlContext.name,
destinationTabId: destinationTabId,
metadata: .init(
originIndex: self.tabControlContext.index(for: originTabId),
destinationIndex: self.tabControlContext.index(for: destinationTabId),
originContextName: self.tabControlContext.contextName(for: originTabId),
destinationContextName: destinationContextName,
defaultIndex: self.tabControlContext.defaultTabIndex
)
))
}
static func shouldTriggerHapticFeedback(
originTabId: String,
destinationTabId: String,
hapticFeedbackEnabled: Bool
) -> Bool {
return hapticFeedbackEnabled && originTabId != destinationTabId
}
}
#endif