Skip to content

Commit

Permalink
[Feat] #375 첫박에 화면 Blink 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
l1004ga committed Jan 31, 2025
1 parent 4cd9b23 commit 4e1454b
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 26 deletions.
2 changes: 2 additions & 0 deletions Macro/Domain/UseCase/Interface/MetronomeOnOffUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ protocol MetronomeOnOffUseCase {
var isPlayingPublisher: AnyPublisher<Bool, Never> { get }
var isSobakOnPublisher: AnyPublisher<Bool, Never> { get }
var tickPublisher: AnyPublisher<(Int,Int,Int), Never> { get }
var firstTickPublisher: AnyPublisher<Void, Never> { get }

func changeSobak()
func changeBlink()
func play()
func stop()
func setSoundType()
Expand Down
61 changes: 37 additions & 24 deletions Macro/Domain/UseCase/MetronomeOnOffImplement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class MetronomeOnOffImplement {
private var bpm: Double
private var currentBeatIndex: Int
private var isSobakOn: Bool
private var isBlinkOn: Bool

// 현재 진행중인 박 위치 관련 변수
private var currentSobak: Int = 0
Expand All @@ -31,6 +32,7 @@ class MetronomeOnOffImplement {
private var isPlayingSubject: PassthroughSubject<Bool, Never> = .init()
private var isSobakOnSubject: PassthroughSubject<Bool, Never> = .init()
private var tickSubject: PassthroughSubject<(Int,Int,Int), Never> = .init()
private var firstTickSubject: PassthroughSubject<Void, Never> = .init()
private var cancelBag: Set<AnyCancellable> = []

// timer
Expand All @@ -48,6 +50,7 @@ class MetronomeOnOffImplement {
self.bpm = 60.0
self.currentBeatIndex = 0
self.isSobakOn = false
self.isBlinkOn = false
self.lastPlayTime = .now
self.jangdanRepository = jangdanRepository
self.soundManager = soundManager
Expand All @@ -72,30 +75,6 @@ class MetronomeOnOffImplement {
}
.store(in: &self.cancelBag)
}

private func updateStatePerBak() {
var nextSobak: Int = self.currentSobak
var nextDaebak: Int = self.currentDaebak
var nextRow: Int = self.currentRow

nextSobak += 1
if nextSobak == self.jangdan[nextRow][nextDaebak].count {
nextDaebak += 1
if nextDaebak == self.jangdan[nextRow].count {
nextRow += 1
if nextRow == self.jangdan.count {
nextRow = 0
}
nextDaebak = 0
}
nextSobak = 0
}

self.currentSobak = nextSobak
self.currentDaebak = nextDaebak
self.currentRow = nextRow
}

}

// Play / Stop
Expand All @@ -112,11 +91,19 @@ extension MetronomeOnOffImplement: MetronomeOnOffUseCase {
self.tickSubject.eraseToAnyPublisher()
}

var firstTickPublisher: AnyPublisher<Void, Never> {
self.firstTickSubject.eraseToAnyPublisher()
}

func changeSobak() {
self.isSobakOn.toggle()
self.isSobakOnSubject.send(self.isSobakOn)
}

func changeBlink() {
self.isBlinkOn.toggle()
}

func play() {
// AudioEngine start()
self.soundManager.audioEngineStart()
Expand Down Expand Up @@ -155,12 +142,38 @@ extension MetronomeOnOffImplement: MetronomeOnOffUseCase {
// timer 카운트를 해주고, 틱마다 publish
self.updateStatePerBak()
self.tickSubject.send((currentSobak, currentDaebak, currentRow))
if self.currentSobak == 0 {
self.firstTickSubject.send()
}

let accent: Accent = jangdanAccentList[self.currentBeatIndex % jangdanAccentList.count]
self.soundManager.beep(accent)
self.currentBeatIndex += 1
}

private func updateStatePerBak() {
var nextSobak: Int = self.currentSobak
var nextDaebak: Int = self.currentDaebak
var nextRow: Int = self.currentRow

nextSobak += 1
if nextSobak == self.jangdan[nextRow][nextDaebak].count {
nextDaebak += 1
if nextDaebak == self.jangdan[nextRow].count {
nextRow += 1
if nextRow == self.jangdan.count {
nextRow = 0
}
nextDaebak = 0
}
nextSobak = 0
}

self.currentSobak = nextSobak
self.currentDaebak = nextDaebak
self.currentRow = nextRow
}

func initialDaeSoBakIndex() {
self.currentRow = self.jangdan.count - 1
self.currentDaebak = self.jangdan[self.currentRow].count - 1
Expand Down
4 changes: 2 additions & 2 deletions Macro/Screen/HomeScreen/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import StoreKit
struct HomeView: View {
@Environment(\.requestReview) private var requestReview
@State private var viewModel: HomeViewModel
@State private var metronomeViewModel: MetronomeViewModel = DIContainer.shared.metronomeViewModel
@State private var scrollOffset: CGFloat = 0

private var router: Router
Expand Down Expand Up @@ -131,9 +130,10 @@ struct HomeView: View {
}
}

if self.metronomeViewModel.state.isBlinkOn {
if self.viewModel.state.isBlinkOn {
Color.white
.ignoresSafeArea()
.animation(.linear(duration: 0.3), value: self.viewModel.state.isBlinkOn)
}
}
} else {
Expand Down
18 changes: 18 additions & 0 deletions Macro/Screen/HomeScreen/ViewModel/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,34 @@
//

import SwiftUI
import Combine

@Observable
class HomeViewModel {

private var metronomeOnOffUseCase: MetronomeOnOffUseCase
private var dynamicIconUseCase: DynamicIconUseCase

private var cancelBag: Set<AnyCancellable> = []

init(metronomeOnOffUseCase: MetronomeOnOffUseCase, dynamicIconUseCase: DynamicIconUseCase) {
self.metronomeOnOffUseCase = metronomeOnOffUseCase
self.dynamicIconUseCase = dynamicIconUseCase

self.metronomeOnOffUseCase.firstTickPublisher.sink { [weak self] _ in
guard let self else { return }
self.state.isBlinkOn = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.state.isBlinkOn = false
}
}
.store(in: &cancelBag)
}

private(set) var state: State = .init()

struct State {
var isBlinkOn: Bool = false
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ extension MetronomeViewModel {
self.taptapUseCase.finishTapping()
case .changeBlinkOnOff:
self.state.isBlinkOn.toggle()
self.metronomeOnOffUseCase.changeBlink()
}
}
}

0 comments on commit 4e1454b

Please sign in to comment.