Skip to content

Commit

Permalink
Merge pull request #1 from IniongunIsaac/main
Browse files Browse the repository at this point in the history
add progress bar configuration for easy customisation
  • Loading branch information
swiftuiux authored Sep 20, 2024
2 parents f586ef3 + e48e621 commit a73260e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
17 changes: 7 additions & 10 deletions Sources/d3-stories-instagram/ProgressBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ import SwiftUI

/// Indicate time progress for ``StoriesView`` component
struct ProgressBar<Item: IStory>: View {
/// Indicators height
private let height: CGFloat = 2

/// Space between indicators
private let spacing: CGFloat = 5
/// ProgressBar configuration: height, spacing, active & inactive colors
let config: ProgressBarConfig

// MARK: - Config

Expand All @@ -29,22 +26,22 @@ struct ProgressBar<Item: IStory>: View {
// MARK: - Life circle

var body: some View {
HStack(spacing: spacing) {
HStack(spacing: config.spacing) {
ForEach(stories, id: \.self) { story in
GeometryReader { proxy in
let width = proxy.size.width
itemTpl(story, width)
}
}
}.frame(height: height)
}.frame(height: config.height)
}

// MARK: - private

/// Progress slot view
@ViewBuilder
private func itemTpl(_ item: Item, _ width: CGFloat) -> some View {
Color.primary.opacity(0.5)
config.inactiveColor
.overlay(progressTpl(item, width, current), alignment: .leading)
.clipShape(Capsule())
}
Expand All @@ -58,9 +55,9 @@ struct ProgressBar<Item: IStory>: View {
@ViewBuilder
private func progressTpl(_ item: Item, _ width: CGFloat, _ current: Item) -> some View {
if item.isBefore(current) { // has already passed
Color.primary
config.activeColor
} else if item == current {
Color.primary.frame(width: progress * width) // current progress
config.activeColor.frame(width: progress * width) // current progress
} else {
EmptyView()
}
Expand Down
9 changes: 8 additions & 1 deletion Sources/d3-stories-instagram/StoriesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ struct StoriesView<M: IStoriesManager>: View {

/// Shared var to control stories running process by external controls that are not inside StoriesWidget
private var pause: Binding<Bool>

/// ProgressBar configuration
private let progressBarConfig: ProgressBarConfig

// MARK: - Life circle

Expand All @@ -28,15 +31,18 @@ struct StoriesView<M: IStoriesManager>: View {
/// - strategy: `.once` or `.circle`
/// - leeway: Delay before start stories
/// - stories: Set of stories
/// - progressBarConfig: progressBar configuration: height, spacing, active & inactive colors
init(
manager: M.Type,
stories: [Item],
current: Item? = nil,
strategy: Strategy = .circle,
leeway: DispatchTimeInterval = .seconds(0),
pause: Binding<Bool>
pause: Binding<Bool>,
progressBarConfig: ProgressBarConfig = .init()
) {
self.pause = pause
self.progressBarConfig = progressBarConfig

_model = StateObject(wrappedValue:
manager.init(stories: stories, current: current, strategy: strategy, leeway: leeway)
Expand Down Expand Up @@ -138,6 +144,7 @@ struct StoriesView<M: IStoriesManager>: View {
@ViewBuilder
private var progressView: some View {
ProgressBar(
config: progressBarConfig,
stories: model.stories,
current: model.current,
progress: model.progress
Expand Down
9 changes: 8 additions & 1 deletion Sources/d3-stories-instagram/StoriesWidget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public struct StoriesWidget<M: IStoriesManager>: View {

/// Custom validator to check validity of stories data set
let validator: IStoriesValidater.Type?

/// ProgressBar configuration
private let progressBarConfig: ProgressBarConfig

// MARK: - Life circle

Expand All @@ -48,6 +51,7 @@ public struct StoriesWidget<M: IStoriesManager>: View {
/// - leeway: Delay before start stories
/// - pause: Pause and resume control from out side environment
/// - validator: Custom validator for stories input data set
/// - progressBarConfig: ProgressBar configuration
/// - onStoriesStateChanged: Closure to react on stories state change
public init(
manager: M.Type,
Expand All @@ -57,6 +61,7 @@ public struct StoriesWidget<M: IStoriesManager>: View {
leeway: DispatchTimeInterval = .seconds(0),
pause: Binding<Bool> = .constant(false),
validator: IStoriesValidater.Type? = nil,
progressBarConfig: ProgressBarConfig = .init(),
onStoriesStateChanged: ((StoriesState) -> Void)?
) {
self.manager = manager
Expand All @@ -66,6 +71,7 @@ public struct StoriesWidget<M: IStoriesManager>: View {
self.leeway = leeway
self.pause = pause
self.validator = validator
self.progressBarConfig = progressBarConfig
self.onStoriesStateChanged = onStoriesStateChanged
}

Expand All @@ -80,7 +86,8 @@ public struct StoriesWidget<M: IStoriesManager>: View {
current: current,
strategy: strategy,
leeway: leeway,
pause: pause
pause: pause,
progressBarConfig: progressBarConfig
)
.onPreferenceChange(StoriesStateKey.self) { state in
onStoriesStateChanged?(state)
Expand Down
27 changes: 27 additions & 0 deletions Sources/d3-stories-instagram/data/ProgressBarConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// ProgressBarConfig.swift
//
//
// Created by Isaac Iniongun on 01/03/2024.
//

import SwiftUI

public struct ProgressBarConfig {
let height: CGFloat
let spacing: CGFloat
let activeColor: Color
let inactiveColor: Color

public init(
height: CGFloat = 2,
spacing: CGFloat = 5,
activeColor: Color = .primary,
inactiveColor: Color = .primary.opacity(0.5)
) {
self.height = height
self.spacing = spacing
self.activeColor = activeColor
self.inactiveColor = inactiveColor
}
}

0 comments on commit a73260e

Please sign in to comment.