TSPurchaseVideoTimesAlertView.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //
  2. // TSPurchaseVideoTimesAlertView.swift
  3. // AIEmoji
  4. //
  5. // Created by 100Years on 2025/8/6.
  6. //
  7. import SwiftUI
  8. import SwiftUIX
  9. struct TSPurchaseVideoTimesAlertView :View {
  10. @ObservedObject var viewModel: TSPurchaseVideoTimesVM
  11. @State var isExpand: Bool = false
  12. var body: some View {
  13. VStack {
  14. let limit = "No effect uses left. Get more to keep creating.".localized
  15. Spacer()
  16. ZStack(alignment: .topTrailing) {
  17. VStack {
  18. Spacer().frame(height: 24)
  19. Text("Limit Reached".localized)
  20. .font(.font(size: 22,weight: .medium))
  21. .foregroundColor(.white)
  22. .padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
  23. Spacer().frame(height: 16)
  24. Text(limit)
  25. .foregroundColor(.white.opacity(0.7))
  26. .padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
  27. Spacer().frame(height: 15)
  28. VStack(alignment: .leading, spacing: 20, content: {
  29. TSPurchaseVideoTimesCellView(type: .purchase(.videoNum1), selectedType: $viewModel.selectedType)
  30. .onTapGesture {
  31. viewModel.selectedType = .purchase(.videoNum1)
  32. }
  33. ZStack(alignment: .topTrailing) {
  34. TSPurchaseVideoTimesCellView(type: .purchase(.videoNum2), selectedType: $viewModel.selectedType)
  35. .onTapGesture {
  36. viewModel.selectedType = .purchase(.videoNum2)
  37. }
  38. TSPurchaseVideoTimesRecView()
  39. .offset(x:-30,y:-14)
  40. }
  41. TSPurchaseVideoTimesCellView(type: .purchase(.videoNum3), selectedType: $viewModel.selectedType)
  42. .onTapGesture {
  43. viewModel.selectedType = .purchase(.videoNum3)
  44. }
  45. }).multilineTextAlignment(.center).font(.font(size: 16,weight:.regular)).foregroundColor(.white)
  46. Spacer().frame(height: 44)
  47. Button {
  48. viewModel.buyPublisher.send(true)
  49. } label: {
  50. ZStack {
  51. Image(.purchaseVideoTimesBtnbg)
  52. Text("Purchase".localized)
  53. .font(.font(size: 16,weight: .medium))
  54. .foregroundColor(.white)
  55. }.frame(maxWidth: .infinity ,minHeight: 48.0,maxHeight: 48.0)
  56. }
  57. VStack{
  58. Spacer().frame(height: 15)
  59. Button {
  60. withAnimation(.easeInOut(duration: 0.3)) {
  61. isExpand.toggle()
  62. }
  63. } label: {
  64. HStack(spacing: 4) {
  65. Text("View Usage Rules".localized)
  66. .font(.font(size: 12,weight: .regular))
  67. .foregroundColor(.white.opacity(0.7))
  68. Image(isExpand ? .chatUpArrow : .chatDownArrow)
  69. }
  70. }
  71. }
  72. if isExpand {
  73. Spacer().frame(height: 10)
  74. VStack(alignment: .leading, spacing: 8, content: {
  75. TSPurchaseVideoTextLineView(image: .purchaseVideoTimesCheck, text: "Only VIP can purchase video effect uses".localized)
  76. TSPurchaseVideoTextLineView(image: .purchaseVideoTimesCheck, text: "Uses can be applied to all video generations".localized)
  77. TSPurchaseVideoTextLineView(image: .purchaseVideoTimesCheck, text: "Uses never expire and can be purchased repeatedly".localized)
  78. TSPurchaseVideoTextLineView(image: .purchaseVideoTimesCheck, text: "All unused uses will be lost if the app is uninstalled".localized)
  79. })
  80. .padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
  81. Spacer().frame(height: 24 + k_Height_safeAreaInsetsBottom())
  82. }else{
  83. Spacer().frame(height: k_Height_safeAreaInsetsBottom())
  84. }
  85. }
  86. .padding(.horizontal,16)
  87. .background(
  88. // Image(.purchaseVideoTimesAlertBj)
  89. // .resizable() // 允许调整大小
  90. // .scaledToFill()
  91. Color.hex("#261840").cornerRadius([.topLeading,.topTrailing], 20)
  92. )
  93. Button {
  94. viewModel.closePagePublisher.send(true)
  95. } label: {
  96. Image(.closeClear).resizable().frame(width: 24, height: 24)
  97. }.offset(x:-8,y:8)
  98. }
  99. }
  100. .ignoresSafeArea()
  101. }
  102. }