mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-21 12:30:11 +00:00
ios: add CF page (#7369)
* ios: add cf page * add cf images * reduce image count * different design * button * simplify * texts * layout * update texts * zoom * add to settings * update text * more text * settings * remove translation * only US * update * update link * update * padding * update * update * safe area --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
co-authored by
Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
parent
bdaa36e847
commit
a0c72200e8
@@ -42,7 +42,7 @@ private struct FeatureView {
|
||||
let view: () -> any View
|
||||
}
|
||||
|
||||
private let isInUS = SKStorefront().countryCode == "USA"
|
||||
let isInUS = true // SKStorefront().countryCode == "USA"
|
||||
|
||||
private let versionDescriptions: [VersionDescription] = [
|
||||
VersionDescription(
|
||||
@@ -668,12 +668,12 @@ private let versionDescriptions: [VersionDescription] = [
|
||||
]
|
||||
),
|
||||
VersionDescription(
|
||||
version: "v7.0",
|
||||
version: "v7.0 ",
|
||||
post: nil,
|
||||
features: (isInUS ? [
|
||||
.view(FeatureView(
|
||||
icon: nil,
|
||||
title: "Invest in SimpleX Chat",
|
||||
title: "You can now invest in SimpleX Chat",
|
||||
view: { InvestInSimpleXChat() }
|
||||
))
|
||||
] : []) + [
|
||||
@@ -772,38 +772,130 @@ fileprivate struct CreateUpdateAddressShortLink: View {
|
||||
}
|
||||
|
||||
fileprivate struct InvestInSimpleXChat: View {
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@State private var showGetStakeSheet = false
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: 8) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
Image(systemName: "dollarsign.circle")
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(minWidth: 30, alignment: .center)
|
||||
Text(verbatim: "Invest in SimpleX Chat").font(.title3).bold()
|
||||
}
|
||||
Text(verbatim: "Equity crowdfunding launched!")
|
||||
.multilineTextAlignment(.leading)
|
||||
.lineLimit(2)
|
||||
if let url = URL("https://wefunder.com/simplexchat") {
|
||||
ExternalLink(destination: url) {
|
||||
HStack {
|
||||
Text(verbatim: "Learn more on Wefunder")
|
||||
Image(systemName: "arrow.up.right.circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Image(colorScheme == .light ? "own-stake" : "own-stake-light")
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("You can now invest in SimpleX Chat! 🚀").font(.title3).bold()
|
||||
(Text("Crowdfunding on Wefunder.") + Text(verbatim: " ") + Text("Learn more").foregroundColor(theme.colors.primary))
|
||||
.multilineTextAlignment(.leading)
|
||||
.onTapGesture { showGetStakeSheet = true }
|
||||
#if SIMPLEX_ASSETS
|
||||
Image("crowdfunding_1")
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: UIScreen.main.bounds.width / 5)
|
||||
.scaledToFit()
|
||||
.cornerRadius(12)
|
||||
.padding(.vertical, 4)
|
||||
.onTapGesture { showGetStakeSheet = true }
|
||||
#endif
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.sheet(isPresented: $showGetStakeSheet) {
|
||||
GetStakeView(fromSettings: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate let getStakeSlides: [(image: String, heading: String, info: String?, text: String)] = [
|
||||
(
|
||||
"crowdfunding_1",
|
||||
"The first and the only messaging network without any user IDs",
|
||||
nil,
|
||||
"By investing, you can benefit from the company growth, and help us build the future of private and secure communications."
|
||||
),
|
||||
(
|
||||
"crowdfunding_2",
|
||||
"480,000+ users joined on their own",
|
||||
nil,
|
||||
"SimpleX users have been more than doubling every year without any paid marketing, and donated over $650,000."
|
||||
),
|
||||
(
|
||||
"crowdfunding_3",
|
||||
"Developers already bet on SimpleX success",
|
||||
"Independent developers created moderation and AI bots, Telegram bridges, and a public server registry.",
|
||||
"Every service developers build on SimpleX Network may increase its value, and bring new users to SimpleX Chat."
|
||||
),
|
||||
(
|
||||
"crowdfunding_4",
|
||||
"Revenue plan: free for users, channels & businesses pay",
|
||||
"SimpleX Chat plans to earn from the infrastructure and services that creators, businesses and large communities need as they grow.",
|
||||
"Read about how we plan to make SimpleX Chat and network profitable, and about all the investment terms on Wefunder."
|
||||
),
|
||||
]
|
||||
|
||||
private let wefunderURL = URL(string: "https://wefunder.com/simplex.chat?utm_source=app")!
|
||||
|
||||
private let simplexCrowdfundingURL = URL(string: "simplex:/a#JxGcOA1_QhlmVFzYYabloMbvMZk5Y9d9iS3ITDnhzYo?h=smp11.simplex.im")!
|
||||
|
||||
struct GetStakeView: View {
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
var fromSettings: Bool
|
||||
|
||||
var body: some View {
|
||||
ZoomablePageView {
|
||||
VStack(alignment: .leading, spacing: 18) {
|
||||
Text(verbatim: "Get a stake in\nSimpleX Chat")
|
||||
.font(.largeTitle)
|
||||
.bold()
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.if(!fromSettings) { $0.padding(.top) }
|
||||
if fromSettings {
|
||||
slideImage(getStakeSlides[0])
|
||||
}
|
||||
(Text(verbatim: getStakeSlides[0].text) + Text(verbatim: " Learn more and invest on Wefunder.").bold().foregroundColor(.accentColor))
|
||||
.multilineTextAlignment(.leading)
|
||||
.onTapGesture {
|
||||
UIApplication.shared.open(wefunderURL)
|
||||
}
|
||||
.padding(.bottom)
|
||||
ForEach(getStakeSlides[1...3], id: \.image) { slide in
|
||||
VStack(alignment: .leading) {
|
||||
slideImage(slide)
|
||||
Text(slide.text)
|
||||
}
|
||||
.padding(.bottom)
|
||||
}
|
||||
|
||||
Button {
|
||||
UIApplication.shared.open(wefunderURL)
|
||||
} label: {
|
||||
Text(verbatim: "Learn more on Wefunder")
|
||||
}
|
||||
.buttonStyle(OnboardingButtonStyle())
|
||||
|
||||
Button {
|
||||
dismiss()
|
||||
DispatchQueue.main.async {
|
||||
ChatModel.shared.appOpenUrl = simplexCrowdfundingURL
|
||||
}
|
||||
} label: {
|
||||
Text(verbatim: "or ask SimpleX team")
|
||||
.font(.callout)
|
||||
}
|
||||
.disabled(chatModel.chatRunning != true)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.ignoresSafeArea(edges: .bottom)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func slideImage(_ slide: (image: String, heading: String, info: String?, text: String?)) -> some View {
|
||||
#if SIMPLEX_ASSETS
|
||||
Image(slide.image)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.cornerRadius(12)
|
||||
#else
|
||||
Text(slide.heading).font(.title3).bold()
|
||||
if let info = slide.info {
|
||||
Text(info)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,17 @@ struct SettingsView: View {
|
||||
Text(verbatim: "v\(appVersion ?? "?")")
|
||||
}
|
||||
}
|
||||
|
||||
if isInUS {
|
||||
Section(header: Text("You can now invest in SimpleX Chat").foregroundColor(theme.colors.secondary)) {
|
||||
NavigationLink {
|
||||
GetStakeView(fromSettings: true)
|
||||
.navigationBarTitle("", displayMode: .inline)
|
||||
} label: {
|
||||
settingsRow("dollarsign.circle", color: theme.colors.secondary) { Text("Crowdfunding on Wefunder") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("Your settings")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
|
||||
@@ -58,3 +58,54 @@ struct ZoomableScrollView<Content: View>: UIViewRepresentable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ZoomablePageView<Content: View>: UIViewRepresentable {
|
||||
private var content: Content
|
||||
|
||||
init(@ViewBuilder content: () -> Content) {
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
func makeUIView(context: Context) -> UIScrollView {
|
||||
let scrollView = UIScrollView()
|
||||
scrollView.delegate = context.coordinator
|
||||
scrollView.maximumZoomScale = 5
|
||||
scrollView.minimumZoomScale = 1
|
||||
scrollView.bouncesZoom = true
|
||||
scrollView.backgroundColor = .clear
|
||||
|
||||
let hostedView = context.coordinator.hostingController.view!
|
||||
hostedView.backgroundColor = .clear
|
||||
hostedView.translatesAutoresizingMaskIntoConstraints = false
|
||||
scrollView.addSubview(hostedView)
|
||||
NSLayoutConstraint.activate([
|
||||
hostedView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
|
||||
hostedView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
|
||||
hostedView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
|
||||
hostedView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
|
||||
hostedView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor)
|
||||
])
|
||||
|
||||
return scrollView
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(hostingController: UIHostingController(rootView: self.content))
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UIScrollView, context: Context) {
|
||||
context.coordinator.hostingController.rootView = self.content
|
||||
}
|
||||
|
||||
class Coordinator: NSObject, UIScrollViewDelegate {
|
||||
var hostingController: UIHostingController<Content>
|
||||
|
||||
init(hostingController: UIHostingController<Content>) {
|
||||
self.hostingController = hostingController
|
||||
}
|
||||
|
||||
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
||||
hostingController.view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user