Skip to content

Commit

Permalink
Async await implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-amisha-i authored Oct 2, 2024
1 parent b3de79b commit e9b8882
Show file tree
Hide file tree
Showing 92 changed files with 2,930 additions and 2,729 deletions.
14 changes: 11 additions & 3 deletions BaseStyle/BaseStyle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
2176204A2C521EDF00FED0D4 /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 217620492C521EDF00FED0D4 /* RadioButton.swift */; };
21BEF8A52C637E4900FBC9CF /* NavigationBarTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21BEF8A42C637E4900FBC9CF /* NavigationBarTopView.swift */; };
21BEF8A72C6399BA00FBC9CF /* BottomSheetHeightModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21BEF8A62C6399BA00FBC9CF /* BottomSheetHeightModifier.swift */; };
21D26E232CA199630090488B /* CapsuleButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21D26E222CA199610090488B /* CapsuleButton.swift */; };
21D614792CAD527D00779F1E /* NavigationTitleTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21D614782CAD527D00779F1E /* NavigationTitleTextView.swift */; };
5DAEE93D2D2208132D031984 /* Pods_BaseStyleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4AFAF996FB5C233D40D81D5 /* Pods_BaseStyleTests.framework */; };
A40018A9B957803B8105BEA5 /* Pods_BaseStyle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 174198EE4AF2FC82DADEB060 /* Pods_BaseStyle.framework */; };
D82174BE2BBAD86D00DB42C3 /* ProfileImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D82174BD2BBAD86D00DB42C3 /* ProfileImageView.swift */; };
Expand Down Expand Up @@ -71,6 +73,8 @@
217620492C521EDF00FED0D4 /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = "<group>"; };
21BEF8A42C637E4900FBC9CF /* NavigationBarTopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarTopView.swift; sourceTree = "<group>"; };
21BEF8A62C6399BA00FBC9CF /* BottomSheetHeightModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomSheetHeightModifier.swift; sourceTree = "<group>"; };
21D26E222CA199610090488B /* CapsuleButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleButton.swift; sourceTree = "<group>"; };
21D614782CAD527D00779F1E /* NavigationTitleTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationTitleTextView.swift; sourceTree = "<group>"; };
2CE85328C46B183FC3F074A3 /* Pods-BaseStyle.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BaseStyle.release.xcconfig"; path = "Target Support Files/Pods-BaseStyle/Pods-BaseStyle.release.xcconfig"; sourceTree = "<group>"; };
5BDB5B9B63CFD771230CD759 /* Pods-BaseStyleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BaseStyleTests.release.xcconfig"; path = "Target Support Files/Pods-BaseStyleTests/Pods-BaseStyleTests.release.xcconfig"; sourceTree = "<group>"; };
CC9EC1F1C0A5A0821118E6CA /* Pods-BaseStyleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BaseStyleTests.debug.xcconfig"; path = "Target Support Files/Pods-BaseStyleTests/Pods-BaseStyleTests.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -161,6 +165,7 @@
D8302D9A2B9EE1BF005ACA13 /* Buttons */ = {
isa = PBXGroup;
children = (
21D26E222CA199610090488B /* CapsuleButton.swift */,
D8D42AAD2B872B27009B345D /* DismissButton.swift */,
D8D42A7E2B85D07C009B345D /* PrimaryButton.swift */,
D8302D9B2B9EE1D2005ACA13 /* PrimaryFloatingButton.swift */,
Expand Down Expand Up @@ -260,6 +265,7 @@
D8D42A9C2B870A5D009B345D /* ToastPrompt.swift */,
D8E244B42B972AD200C6C82A /* EmptyRouteView.swift */,
21BEF8A42C637E4900FBC9CF /* NavigationBarTopView.swift */,
21D614782CAD527D00779F1E /* NavigationTitleTextView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -359,7 +365,7 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1520;
LastUpgradeCheck = 1520;
LastUpgradeCheck = 1600;
TargetAttributes = {
D8D42A3C2B85CC85009B345D = {
CreatedOnToolsVersion = 15.2;
Expand Down Expand Up @@ -486,6 +492,7 @@
files = (
D8D42AAE2B872B27009B345D /* DismissButton.swift in Sources */,
D8D42AB02B872E44009B345D /* LoaderView.swift in Sources */,
21D614792CAD527D00779F1E /* NavigationTitleTextView.swift in Sources */,
D8D42A9D2B870A5D009B345D /* ToastPrompt.swift in Sources */,
D82174BE2BBAD86D00DB42C3 /* ProfileImageView.swift in Sources */,
213F377E2C416C9C00972316 /* ScrollToTopButton.swift in Sources */,
Expand All @@ -502,6 +509,7 @@
D8D42AAC2B872A7C009B345D /* ToastView.swift in Sources */,
217620462C4F7CE700FED0D4 /* BackButton.swift in Sources */,
D8D42A952B85F8A2009B345D /* Bundle+Extension.swift in Sources */,
21D26E232CA199630090488B /* CapsuleButton.swift in Sources */,
D89C93462BC42DE500FACD16 /* MailComposeView.swift in Sources */,
213A1F2A2C52335D00BF9800 /* CheckmarkButton.swift in Sources */,
D86632962C2410BB009D3EF5 /* OtpTextInputView.swift in Sources */,
Expand Down Expand Up @@ -668,6 +676,7 @@
baseConfigurationReference = E0B1A6930B9FF35E9142463B /* Pods-BaseStyle.debug.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
Expand Down Expand Up @@ -706,6 +715,7 @@
baseConfigurationReference = 2CE85328C46B183FC3F074A3 /* Pods-BaseStyle.release.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
Expand Down Expand Up @@ -742,7 +752,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = CC9EC1F1C0A5A0821118E6CA /* Pods-BaseStyleTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = S985H2T7J8;
Expand All @@ -760,7 +769,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 5BDB5B9B63CFD771230CD759 /* Pods-BaseStyleTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = S985H2T7J8;
Expand Down
45 changes: 45 additions & 0 deletions BaseStyle/BaseStyle/CustomUI/Buttons/CapsuleButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// CapsuleButton.swift
// BaseStyle
//
// Created by Amisha Italiya on 23/09/24.
//

import SwiftUI

public struct CapsuleButton: View {

private let buttonName: String
private let paddingHr: CGFloat
private let paddingVr: CGFloat
private let isEnabled: Bool
private let onClick: (() -> Void)?

public init(buttonName: String, isEnabled: Bool = true, paddingHr: CGFloat = 73, paddingVr: CGFloat = 12, onClick: (() -> Void)?) {
self.buttonName = buttonName
self.paddingHr = paddingHr
self.paddingVr = paddingVr
self.isEnabled = isEnabled
self.onClick = onClick
}

public var body: some View {
Button {
if isEnabled {
onClick?()
}
} label: {
HStack(spacing: 5) {
Text(buttonName)
.font(.buttonText())
.foregroundColor(primaryLightText)
}
.padding(.horizontal, paddingHr)
.padding(.vertical, paddingVr)
.background(primaryColor)
.cornerRadius(12)
}
.buttonStyle(.scale)
.disabled(!isEnabled)
}
}
25 changes: 16 additions & 9 deletions BaseStyle/BaseStyle/CustomUI/Buttons/CheckmarkButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,32 @@ import SwiftUI

public struct CheckmarkButton: View {

private let showLoader: Bool
private let iconSize: (width: CGFloat, height: CGFloat)
private let padding: (edges: Edge.Set, value: CGFloat)

private let onClick: (() -> Void)?

public init(iconSize: (width: CGFloat, height: CGFloat) = (26, 34), padding: (edges: Edge.Set, value: CGFloat) = (.all, 2), onClick: (() -> Void)? = nil) {
public init(showLoader: Bool = false, iconSize: (width: CGFloat, height: CGFloat) = (26, 34),
padding: (edges: Edge.Set, value: CGFloat) = (.all, 2), onClick: (() -> Void)? = nil) {
self.showLoader = showLoader
self.iconSize = iconSize
self.padding = padding
self.onClick = onClick
}

public var body: some View {
Button(action: {
onClick?()
}, label: {
Image(.checkmarkIcon)
.resizable()
.frame(width: iconSize.width, height: iconSize.height)
.padding(padding.edges, padding.value)
})
if showLoader {
ImageLoaderView(tintColor: primaryColor)
} else {
Button(action: {
onClick?()
}, label: {
Image(.checkmarkIcon)
.resizable()
.frame(width: iconSize.width, height: iconSize.height)
.padding(padding.edges, padding.value)
})
}
}
}
1 change: 1 addition & 0 deletions BaseStyle/BaseStyle/CustomUI/Buttons/PrimaryButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,6 @@ public struct PrimaryButton: View {
.frame(minHeight: 50)
.buttonStyle(.scale)
.disabled(!isEnabled || showLoader)
.opacity(showLoader ? 0.8 : 1)
}
}
105 changes: 83 additions & 22 deletions BaseStyle/BaseStyle/CustomUI/LoaderView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,108 @@
import SwiftUI

public struct LoaderView: View {

@StateObject private var viewModel: LoaderViewModel = .init()

private let tintColor: Color
private let height: CGFloat

private let totalDots = 7
private let timer = Timer.publish(every: 0.20, on: .main, in: .common).autoconnect()

@State var current = 0

public init(tintColor: Color = primaryColor, height: CGFloat = 38) {
public init(tintColor: Color = primaryColor, height: CGFloat = 8) {
self.tintColor = tintColor
self.height = height
}

public var body: some View {
ZStack {
if viewModel.isStillLoading {
Color.clear.ignoresSafeArea()

ForEach(0..<totalDots, id: \.self) { index in
Circle()
.fill(tintColor)
.frame(height: height / 4)
.frame(height: height, alignment: .top)
.rotationEffect(Angle(degrees: 360 / Double(totalDots) * Double(index)))
.opacity(current == index ? 1.0 : current == index + 1 ? 0.5 :
current == (totalDots - 1) && index == (totalDots - 1) ? 0.5 : 0)
GeometryReader { geometry in
ZStack {
if viewModel.isStillLoading {
Color.clear.ignoresSafeArea()

DotsAnimation(color: tintColor, height: height)
.position(x: geometry.size.width / 2, y: geometry.size.height / 2) // Center the loader by using the size from GeometryReader
}
}
}
.onAppear(perform: viewModel.onViewAppear)
.onReceive(timer, perform: { _ in
withAnimation(Animation.easeInOut(duration: 0.5).repeatCount(1, autoreverses: true)) {
current = current == (totalDots - 1) ? 0 : current + 1
}
}

private struct DotsAnimation: View {

let color: Color
let height: CGFloat

static let DATA: [AnimationData] = [
AnimationData(delay: 0.0, ty: -20),
AnimationData(delay: 0.1, ty: -24),
AnimationData(delay: 0.2, ty: -28)
]

@State var transY: [CGFloat] = DATA.map { _ in return 0 }

var animation = Animation.easeInOut.speed(0.5)

var body: some View {
HStack(spacing: 5) {
DotView(transY: $transY[0], color: color, height: height)
DotView(transY: $transY[1], color: color, height: height)
DotView(transY: $transY[2], color: color, height: height)
}
.onAppear {
animateDots()
}
}

func animateDots() {
// Go through animation data and start each
// animation delayed as per data
for (index, data) in DotsAnimation.DATA.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + data.delay) {
animateDot(binding: $transY[index], animationData: data)
}
})
}

// Repeat main loop
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
animateDots()
}
}

func animateDot(binding: Binding<CGFloat>, animationData: AnimationData) {
withAnimation(animation) {
binding.wrappedValue = animationData.ty
}

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
withAnimation(animation) {
binding.wrappedValue = 0
}
}
}
}

private struct DotView: View {

@Binding var transY: CGFloat

let color: Color
let height: CGFloat

var body: some View {
Circle()
.fill(color)
.frame(width: height, height: height)
.offset(y: transY)
}
}

private struct AnimationData {
var delay: TimeInterval
var ty: CGFloat
}

public struct ImageLoaderView: View {

@StateObject var viewModel: LoaderViewModel = .init()

private let tintColor: Color
Expand Down
21 changes: 13 additions & 8 deletions BaseStyle/BaseStyle/CustomUI/ToastView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ struct ToastView: View {
var type: ToastStyle
var title: String
var message: String
let bottomPadding: CGFloat

var onCancelTapped: (() -> Void)

var body: some View {
Expand Down Expand Up @@ -49,12 +51,15 @@ struct ToastView: View {
.cornerRadius(8)
.shadow(color: primaryLightText.opacity(0.8), radius: 4, x: 0, y: 1)
.padding(.horizontal, 16)
.padding(.bottom, bottomPadding)
}
}

struct ToastModifier: ViewModifier {
@Binding var toast: ToastPrompt?

let bottomPadding: CGFloat

@State private var workItem: DispatchWorkItem?

func body(content: Content) -> some View {
Expand All @@ -75,11 +80,11 @@ struct ToastModifier: ViewModifier {
if let toast {
VStack(spacing: 0) {
Spacer()
ToastView(type: toast.type,
title: toast.title,
message: toast.message, onCancelTapped: {
dismissToast()
})
ToastView(type: toast.type, title: toast.title,
message: toast.message, bottomPadding: bottomPadding,
onCancelTapped: {
dismissToast()
})
}
.transition(.move(edge: .bottom))
}
Expand All @@ -95,7 +100,7 @@ struct ToastModifier: ViewModifier {
workItem?.cancel()

let task = DispatchWorkItem {
dismissToast()
dismissToast()
}

workItem = task
Expand All @@ -117,7 +122,7 @@ struct ToastModifier: ViewModifier {
}

public extension View {
func toastView(toast: Binding<ToastPrompt?>) -> some View {
self.modifier(ToastModifier(toast: toast))
func toastView(toast: Binding<ToastPrompt?>, bottomPadding: CGFloat = 0) -> some View {
self.modifier(ToastModifier(toast: toast, bottomPadding: bottomPadding))
}
}
Loading

0 comments on commit e9b8882

Please sign in to comment.