Skip to content

Commit

Permalink
Implement PrimaryButton in SwiftUI and integrate it
Browse files Browse the repository at this point in the history
  • Loading branch information
ealymbaev committed Sep 8, 2023
1 parent 0829a4a commit ab44345
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 83 deletions.
24 changes: 18 additions & 6 deletions UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class BalanceErrorViewController: ThemeActionSheetController {

private func openBtc(blockchain: Blockchain) {
dismiss(animated: true) { [weak self] in
self?.sourceViewController?.present(BtcBlockchainSettingsModule.viewController(blockchain: blockchain), animated: true)
self?.sourceViewController?.present(BtcBlockchainSettingsModule.view(blockchain: blockchain).toNavigationViewController(), animated: true)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import SwiftUI
import UIKit
import MarketKit

struct BtcBlockchainSettingsModule {

static func viewController(blockchain: Blockchain) -> UIViewController {
static func view(blockchain: Blockchain) -> some View {
let service = BtcBlockchainSettingsService(blockchain: blockchain, btcBlockchainManager: App.shared.btcBlockchainManager)
let viewModel = BtcBlockchainSettingsViewModel(service: service)
let view = BtcBlockchainSettingsView(viewModel: viewModel)

return UIHostingController(rootView: view)
return BtcBlockchainSettingsView(viewModel: viewModel)
}

}
Original file line number Diff line number Diff line change
@@ -1,76 +1,72 @@
import SwiftUI
import SDWebImageSwiftUI
import SwiftUI

struct BtcBlockchainSettingsView: View {
@ObservedObject var viewModel: BtcBlockchainSettingsViewModel

@Environment(\.presentationMode) var presentationMode
@State var infoPresented = false
@Environment(\.presentationMode) private var presentationMode
@State private var infoPresented = false

var body: some View {
ThemeNavigationView {
ThemeView {
VStack(spacing: 0) {
ScrollView {
VStack(spacing: .margin24) {
HighlightedTextView(text: "btc_blockchain_settings.restore_source.alert".localized(viewModel.title))
ThemeView {
BottomGradientWrapper {
VStack(spacing: .margin24) {
HighlightedTextView(text: "btc_blockchain_settings.restore_source.alert".localized(viewModel.title))

VStack(spacing: 0) {
ListSectionInfoHeader(text: "btc_blockchain_settings.restore_source".localized) {
infoPresented = true
}
.sheet(isPresented: $infoPresented) {
InfoModule.restoreSourceInfo
}
VStack(spacing: 0) {
ListSectionInfoHeader(text: "btc_blockchain_settings.restore_source".localized) {
infoPresented = true
}
.sheet(isPresented: $infoPresented) {
InfoModule.restoreSourceInfo
}

ListSection {
ForEach(viewModel.restoreModes) { restoreMode in
ClickableRow(action: {
viewModel.selectedRestoreMode = restoreMode
}) {
VStack(spacing: 1) {
Text(restoreMode.title).themeBody()
Text(restoreMode.description).themeSubhead2()
}
ListSection {
ForEach(viewModel.restoreModes) { restoreMode in
ClickableRow(action: {
viewModel.selectedRestoreMode = restoreMode
}) {
VStack(spacing: 1) {
Text(restoreMode.title).themeBody()
Text(restoreMode.description).themeSubhead2()
}

if restoreMode == viewModel.selectedRestoreMode {
Image("check_1_20").themeIcon(color: .themeJacob)
}
}
if restoreMode == viewModel.selectedRestoreMode {
Image("check_1_20").themeIcon(color: .themeJacob)
}
}

ListSectionFooter(text: "btc_blockchain_settings.restore_source.description".localized)
}
}
.padding(EdgeInsets(top: .margin12, leading: .margin16, bottom: .margin32, trailing: .margin16))
}

Button(action: {
viewModel.onTapSave()
presentationMode.wrappedValue.dismiss()
}) {
Text("Save")
ListSectionFooter(text: "btc_blockchain_settings.restore_source.description".localized)
}
.disabled(!viewModel.saveEnabled)
}
.padding(EdgeInsets(top: .margin12, leading: .margin16, bottom: .margin32, trailing: .margin16))
} bottomContent: {
Button(action: {
viewModel.onTapSave()
presentationMode.wrappedValue.dismiss()
}) {
Text("button.save".localized)
}
.buttonStyle(PrimaryButtonStyle(style: .yellow))
.disabled(!viewModel.saveEnabled)
}
}
.navigationBarTitle(viewModel.title)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
WebImage(url: URL(string: viewModel.iconUrl))
.resizable()
.scaledToFit()
.frame(width: .iconSize24, height: .iconSize24)
}
.navigationBarTitle(viewModel.title)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
WebImage(url: URL(string: viewModel.iconUrl))
.resizable()
.scaledToFit()
.frame(width: .iconSize24, height: .iconSize24)
}

ToolbarItem(placement: .navigationBarTrailing) {
Button("button.cancel".localized) {
presentationMode.wrappedValue.dismiss()
}
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("button.cancel".localized) {
presentationMode.wrappedValue.dismiss()
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class BlockchainSettingsViewController: ThemeViewController {
}

private func openBtc(blockchain: Blockchain) {
present(BtcBlockchainSettingsModule.viewController(blockchain: blockchain), animated: true)
present(BtcBlockchainSettingsModule.view(blockchain: blockchain).toNavigationViewController(), animated: true)
}

private func openEvm(blockchain: Blockchain) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ class MainSettingsViewController: ThemeViewController {
isFirst: true,
isLast: true,
action: { [weak self] in
self?.navigationController?.pushViewController(ExperimentalFeaturesModule.viewController(), animated: true)
let viewController = ExperimentalFeaturesView().toViewController(title: "settings.experimental_features.title".localized)
self?.navigationController?.pushViewController(viewController, animated: true)
}
)
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import SwiftUI

struct BottomGradientWrapper<Content: View, BottomContent: View>: View {
@ViewBuilder let content: Content
@ViewBuilder let bottomContent: BottomContent

var body: some View {
VStack(spacing: 0) {
ZStack {
ScrollView {
content
}

VStack {
Spacer()
LinearGradient(colors: [.themeTyler, .clear], startPoint: .bottom, endPoint: .top)
.frame(maxWidth: .infinity)
.frame(height: .margin16)
}
}

bottomContent
.padding(EdgeInsets(top: .margin8, leading: .margin24, bottom: .margin12, trailing: .margin24))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import SwiftUI
import UIKit

extension View {
func toViewController(title: String? = nil) -> UIViewController {
let viewController = UIHostingController(rootView: self)

if let title {
viewController.title = title
}

return viewController
}

func toNavigationViewController() -> UIViewController {
UIHostingController(rootView: ThemeNavigationView { self })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import SwiftUI

struct PrimaryButtonStyle: ButtonStyle {
let style: Style

@Environment(\.isEnabled) var isEnabled

func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)
.padding(EdgeInsets(top: 15, leading: .margin32, bottom: 15, trailing: .margin32))
.font(.themeHeadline2)
.foregroundColor(style.foregroundColor(isEnabled: isEnabled, isPressed: configuration.isPressed))
.background(style.backgroundColor(isEnabled: isEnabled, isPressed: configuration.isPressed))
.clipShape(Capsule(style: .continuous))
.animation(.easeOut(duration: 0.2), value: configuration.isPressed)
}

enum Style {
case yellow
case red
case gray
case transparent

func foregroundColor(isEnabled: Bool, isPressed: Bool) -> Color {
switch self {
case .yellow: return isEnabled ? .themeDark : .themeGray50
case .red, .gray: return isEnabled ? .themeClaude : .themeGray50
case .transparent: return isEnabled ? (isPressed ? .themeGray : .themeLeah) : .themeGray50
}
}

func backgroundColor(isEnabled: Bool, isPressed: Bool) -> Color {
switch self {
case .yellow: return isEnabled ? (isPressed ? .themeYellow50 : .themeYellow) : .themeSteel20
case .red: return isEnabled ? (isPressed ? .themeRed50 : .themeLucian) : .themeSteel20
case .gray: return isEnabled ? (isPressed ? .themeNina : .themeLeah) : .themeSteel20
case .transparent: return .clear
}
}
}
}

0 comments on commit ab44345

Please sign in to comment.