252 lines
13 KiB
Swift
252 lines
13 KiB
Swift
import SwiftUI
|
||
|
||
struct JoinModal: View {
|
||
@Binding var isPresented: Bool
|
||
|
||
var body: some View {
|
||
ZStack(alignment: .bottom) {
|
||
// Semi-transparent background
|
||
if isPresented {
|
||
Color.black.opacity(0.4)
|
||
.edgesIgnoringSafeArea(.all)
|
||
.onTapGesture {
|
||
withAnimation {
|
||
isPresented = false
|
||
}
|
||
}
|
||
}
|
||
|
||
// Modal content
|
||
if isPresented {
|
||
VStack(spacing: 0) {
|
||
// 顶部装饰图已移除(按需求)
|
||
VStack(spacing: 0) {
|
||
// Close button on the right
|
||
HStack {
|
||
Spacer()
|
||
Button(action: {
|
||
withAnimation {
|
||
Router.shared.navigate(to: .blindBox(mediaType: .all))
|
||
}
|
||
}) {
|
||
Image(systemName: "xmark")
|
||
.font(.system(size: 20, weight: .medium))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
.padding(12)
|
||
}
|
||
.padding(.trailing, 16)
|
||
}
|
||
|
||
// 文本
|
||
VStack(spacing: 8) {
|
||
Text("Join us!")
|
||
.font(Typography.font(for: .headline1, family: .quicksandBold))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
Text("Join us to get more exclusive benefits.")
|
||
.font(.system(size: 14, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
.padding(.vertical, 12)
|
||
// List content
|
||
VStack (alignment: .leading) {
|
||
HStack {
|
||
JoinListMark()
|
||
.frame(width: 32, height: 32)
|
||
HStack (alignment: .top){
|
||
Text("Unlimited")
|
||
.font(.system(size: 16, weight: .bold))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
Text(" blind box purchases.")
|
||
.font(.system(size: 16, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
}
|
||
.padding(.vertical, 12)
|
||
.padding(.leading,12)
|
||
HStack (alignment: .center) {
|
||
JoinListMark()
|
||
.frame(width: 32, height: 32)
|
||
VStack (alignment: .leading,spacing: 4) {
|
||
HStack {
|
||
Text("Freely")
|
||
.font(.system(size: 16, weight: .bold))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
Text(" upload image and video")
|
||
.font(.system(size: 16, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
Text(" materials.")
|
||
.font(.system(size: 16, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
}
|
||
.padding(.vertical, 12)
|
||
.padding(.leading,12)
|
||
|
||
HStack(alignment: .top) {
|
||
JoinListMark()
|
||
.frame(width: 32, height: 32)
|
||
VStack (alignment: .leading,spacing: 4) {
|
||
HStack {
|
||
Text("500")
|
||
.font(.system(size: 16, weight: .bold))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
Text(" credits daily,")
|
||
.font(.system(size: 16, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
HStack(alignment: .top) {
|
||
VStack (alignment: .leading, spacing: 4) {
|
||
HStack {
|
||
Text("5000")
|
||
.font(.system(size: 16, weight: .bold))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
Text(" permanent credits on your first")
|
||
.font(.system(size: 16, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
Text(" purchase!")
|
||
.font(.system(size: 16, weight: .regular))
|
||
.foregroundColor(.themeTextMessageMain)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.padding(.top, 12)
|
||
.padding(.leading,12)
|
||
HStack {
|
||
Spacer() // This will push the button to the right
|
||
Button(action: {
|
||
// 点击跳转到会员页面
|
||
Router.shared.navigate(to: .subscribe)
|
||
}) {
|
||
HStack {
|
||
Text("See More")
|
||
.font(.system(size: 16))
|
||
Image(systemName: "chevron.right")
|
||
.font(.system(size: 14))
|
||
}
|
||
.foregroundColor(.themeTextMessageMain)
|
||
.padding(.vertical, 12)
|
||
.padding(.horizontal, 24)
|
||
.cornerRadius(20)
|
||
}
|
||
}
|
||
.padding(.trailing, 16) // Add some right padding to match the design
|
||
Button(action: {
|
||
// 点击跳转到会员页面
|
||
Router.shared.navigate(to: .subscribe)
|
||
}) {
|
||
HStack {
|
||
Text("Subscribe")
|
||
.font(Typography.font(for: .body, family: .quicksandBold))
|
||
Spacer()
|
||
Text("$1.00/Mon")
|
||
.font(Typography.font(for: .body, family: .quicksandBold))
|
||
}
|
||
.foregroundColor(.themeTextMessageMain)
|
||
.padding(.vertical, 12)
|
||
.padding(.horizontal, 30)
|
||
.background(Color.themePrimary)
|
||
.cornerRadius(20)
|
||
}
|
||
.padding(.top, 16)
|
||
// 协议条款
|
||
HStack(alignment: .center) {
|
||
Button(action: {
|
||
// Action for Terms of Service
|
||
if let url = URL(string: "https://memorywake.com/privacy-policy") {
|
||
UIApplication.shared.open(url)
|
||
}
|
||
}) {
|
||
Text("Terms of Service")
|
||
.font(.system(size: 12, weight: .regular))
|
||
.foregroundColor(.themeTextMessage)
|
||
.underline() // Add underline
|
||
}
|
||
Rectangle()
|
||
.fill(Color.gray.opacity(0.5))
|
||
.frame(width: 1, height: 16)
|
||
.padding(.vertical, 4)
|
||
Button(action: {
|
||
// 打开网页
|
||
if let url = URL(string: "https://memorywake.com/privacy-policy") {
|
||
UIApplication.shared.open(url)
|
||
}
|
||
}) {
|
||
Text("Privacy Policy")
|
||
.font(.system(size: 12, weight: .regular))
|
||
.foregroundColor(.themeTextMessage)
|
||
.underline() // Add underline
|
||
}
|
||
Rectangle()
|
||
.fill(Color.gray.opacity(0.5))
|
||
.frame(width: 1, height: 16)
|
||
.padding(.vertical, 4)
|
||
Button(action: {
|
||
// Action for Restore Purchase
|
||
if let url = URL(string: "https://memorywake.com/privacy-policy") {
|
||
UIApplication.shared.open(url)
|
||
}
|
||
}) {
|
||
Text("AI Usage Guidelines")
|
||
.font(.system(size: 12, weight: .regular))
|
||
.foregroundColor(.themeTextMessage)
|
||
.underline() // Add underline
|
||
}
|
||
}
|
||
.padding(.bottom, 24)
|
||
.frame(maxWidth: .infinity, alignment: .center)
|
||
}
|
||
.padding(.horizontal, 16)
|
||
}
|
||
.background(Color.white)
|
||
.cornerRadius(20, corners: [.topLeft, .topRight])
|
||
}
|
||
.frame(height: nil)
|
||
.transition(.move(edge: .bottom))
|
||
}
|
||
}
|
||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
|
||
.edgesIgnoringSafeArea(.all)
|
||
.animation(.easeInOut, value: isPresented)
|
||
}
|
||
}
|
||
|
||
// MARK: - SwiftUI JoinList 图标重绘
|
||
private struct JoinListMark: View {
|
||
var body: some View {
|
||
ZStack {
|
||
// 背景圆
|
||
Circle()
|
||
.fill(
|
||
LinearGradient(colors: [Color.themePrimary.opacity(0.9), Color.orange.opacity(0.8)],
|
||
startPoint: .topLeading,
|
||
endPoint: .bottomTrailing)
|
||
)
|
||
.shadow(color: Color.black.opacity(0.12), radius: 4, x: 0, y: 2)
|
||
|
||
// 右指三角(白色)
|
||
GeometryReader { geo in
|
||
Path { path in
|
||
let w = geo.size.width
|
||
let h = geo.size.height
|
||
path.move(to: CGPoint(x: w*0.42, y: h*0.30))
|
||
path.addLine(to: CGPoint(x: w*0.70, y: h*0.50))
|
||
path.addLine(to: CGPoint(x: w*0.42, y: h*0.70))
|
||
path.closeSubpath()
|
||
}
|
||
.fill(Color.white)
|
||
.opacity(0.95)
|
||
}
|
||
.padding(8)
|
||
}
|
||
}
|
||
}
|
||
|
||
struct JoinModal_Previews: PreviewProvider {
|
||
static var previews: some View {
|
||
JoinModal(isPresented: .constant(true))
|
||
}
|
||
}
|