Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify를 통일해 ContextMenu의 가짓수를 줄였어요 #121

Merged
merged 3 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Daily/Domain/Entities/Enums/SectionType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ enum SectionType {
case date
case time
case content
case count
case goalCount
case symbol
case count

var title: String {
switch self {
Expand All @@ -22,10 +23,12 @@ enum SectionType {
return "시간"
case .content:
return "목표"
case .count:
case .goalCount:
return "횟수"
case .symbol:
return "심볼"
case .count:
return "(기록 / 목표) 횟수"
}
}
var isNew: Bool {
Expand Down
7 changes: 3 additions & 4 deletions Daily/Domain/Entities/Model/ModifyDataModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import Foundation
struct ModifyDataModel: Hashable {
let date: Date
var modifyRecord: DailyRecordModel
var modifyType: ModifyTypes
var isAll: Bool = false
let modifyType: ModifyTypes
}

enum ModifyTypes {
case record
case date
case goal
case single
case all
}
30 changes: 18 additions & 12 deletions Daily/Presentation/Core/Component/DailyCycleTypePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,32 @@ import SwiftUI

struct DailyCycleTypePicker: View {
@Binding var cycleType: CycleTypes
let isModify: Bool

var body: some View {
Menu {
ForEach(CycleTypes.allCases, id: \.self) { cycleType in
Button {
withAnimation {
self.cycleType = cycleType
if isModify {
Text(cycleType.text)
.font(.system(size: CGFloat.fontSize * 2.5))
} else {
Menu {
ForEach(CycleTypes.allCases, id: \.self) { cycleType in
Button {
withAnimation {
self.cycleType = cycleType
}
} label: {
Text(cycleType.text)
}
} label: {
Text(cycleType.text)
}
} label: {
Text(cycleType.text)
.font(.system(size: CGFloat.fontSize * 2.5))
.foregroundStyle(Colors.daily)
}
} label: {
Text(cycleType.text)
.font(.system(size: CGFloat.fontSize * 2.5))
.foregroundStyle(Colors.daily)
}
}
}

#Preview {
DailyCycleTypePicker(cycleType: .constant(.date))
DailyCycleTypePicker(cycleType: .constant(.date), isModify: false)
}
3 changes: 2 additions & 1 deletion Daily/Presentation/Core/Component/DailySection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct DailySection<Content: View>: View {
var type: SectionType
var essentialConditions: Bool = false
@State var isShowEssentialConditions: Bool = false
var isModify: Bool = false
var content: () -> Content

var body: some View {
Expand All @@ -26,7 +27,7 @@ struct DailySection<Content: View>: View {
if type.isEssential && !essentialConditions {
essentialButton
}
if type.isNew {
if type.isNew && !isModify {
Text("new")
.foregroundStyle(Colors.daily)
}
Expand Down
110 changes: 77 additions & 33 deletions Daily/Presentation/Goal/DailyGoalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct DailyGoalView: View {

var body: some View {
VStack {
DailyNavigationBar(title: dailyGoalViewModel.getNavigationBarTitle())
DailyNavigationBar(title: "목표추가")
VStack(spacing: .zero) {
Spacer()
DailySection(type: .date) {
Expand All @@ -30,11 +30,10 @@ struct DailyGoalView: View {
ContentSection(content: $dailyGoalViewModel.content, goalType: $dailyGoalViewModel.goalType)
}
HStack {
DailySection(type: .count) {
CountSection(
DailySection(type: .goalCount) {
GoalCountSection(
goalType: $dailyGoalViewModel.goalType,
goalCount: $dailyGoalViewModel.goalCount,
goalTime: .constant(300) // TODO: 추후 수정
goalCount: $dailyGoalViewModel.goalCount
)
}
DailySection(type: .symbol) {
Expand All @@ -57,36 +56,45 @@ struct DailyGoalView: View {
// MARK: - DateSection
struct DateSection: View {
@ObservedObject var dailyGoalViewModel: DailyGoalViewModel
private let isModify: Bool
@Namespace var ns
@State var opacity: [Double] = Array(repeating: 0, count: 7)

init(dailyGoalViewModel: DailyGoalViewModel, isModify: Bool = false) {
self.dailyGoalViewModel = dailyGoalViewModel
self.isModify = isModify
}

var body: some View {
VStack {
HStack {
DailyCycleTypePicker(cycleType: $dailyGoalViewModel.cycleType)
Spacer()
if dailyGoalViewModel.cycleType == .date {
DailyDatePicker(currentDate: $dailyGoalViewModel.startDate)
.matchedGeometryEffect(id: "start_date", in: ns)
.matchedGeometryEffect(id: "end_date", in: ns)
} else if dailyGoalViewModel.cycleType == .rept {
DailyWeekIndicator(mode: .select, opacity: $opacity)
}
}
if dailyGoalViewModel.cycleType == .rept {
if let modifyType = dailyGoalViewModel.modifyType, modifyType == .all { EmptyView() }
else {
VStack {
HStack {
DailyDatePicker(currentDate: $dailyGoalViewModel.startDate)
.matchedGeometryEffect(id: "start_date", in: ns)
DailyCycleTypePicker(cycleType: $dailyGoalViewModel.cycleType, isModify: isModify)
Spacer()
Text("~")
Spacer()
DailyDatePicker(currentDate: $dailyGoalViewModel.endDate)
.matchedGeometryEffect(id: "end_date", in: ns)
if dailyGoalViewModel.cycleType == .date {
DailyDatePicker(currentDate: $dailyGoalViewModel.startDate)
.matchedGeometryEffect(id: "start_date", in: ns)
.matchedGeometryEffect(id: "end_date", in: ns)
} else if dailyGoalViewModel.cycleType == .rept {
DailyWeekIndicator(mode: .select, opacity: $opacity)
}
}
if dailyGoalViewModel.cycleType == .rept {
HStack {
DailyDatePicker(currentDate: $dailyGoalViewModel.startDate)
.matchedGeometryEffect(id: "start_date", in: ns)
Spacer()
Text("~")
Spacer()
DailyDatePicker(currentDate: $dailyGoalViewModel.endDate)
.matchedGeometryEffect(id: "end_date", in: ns)
}
}
}
}
.onChange(of: opacity) { _, opacity in
dailyGoalViewModel.selectedWeekday = opacity.enumerated().compactMap { $1 == 0.8 ? $0 + 1 : nil }
.onChange(of: opacity) { _, opacity in
dailyGoalViewModel.selectedWeekday = opacity.enumerated().compactMap { $1 == 0.8 ? $0 + 1 : nil }
}
}
}
}
Expand Down Expand Up @@ -140,12 +148,11 @@ struct ContentSection: View {
}
}

// MARK: - CountSection
struct CountSection: View {
// MARK: - GoalCountSection
struct GoalCountSection: View {
@EnvironmentObject var alertEnvironment: AlertEnvironment
@Binding var goalType: GoalTypes
@Binding var goalCount: Int
@Binding var goalTime: Int
@State var isShowAlert: Bool = false

var body: some View {
Expand Down Expand Up @@ -180,6 +187,46 @@ struct CountSection: View {
}
}

// MARK: - CountSection
struct CountSection: View {
@Binding var recordCount: Int
@Binding var goalCount: Int

var body: some View {
HStack {
Menu {
ForEach(0 ... goalCount, id: \.self) { count in
Button {
recordCount = count
} label: {
Text("\(count)")
}
}
} label: {
Text("\(recordCount)")
.frame(maxWidth: .infinity)
}
Text("/")
Menu {
ForEach(1 ... 10, id: \.self) { count in
Button {
goalCount = count
if recordCount > goalCount {
recordCount = count
}
} label: {
Text("\(count)")
}
}
} label: {
Text("\(goalCount)")
.frame(maxWidth: .infinity)
}
}
.foregroundStyle(Colors.reverse)
}
}

// MARK: - SymbolSection
struct SymbolSection: View {
@Binding var symbol: Symbols
Expand Down Expand Up @@ -217,9 +264,6 @@ struct ButtonSection: View {

var body: some View {
HStack {
if buttonType == .modify && dailyGoalViewModel.modifyType == .date {
Text("\(CalendarServices.shared.formatDateString(date: dailyGoalViewModel.modifyDate, joiner: .korean, hasSpacing: true, hasLastJoiner: true))")
}
Spacer()
DailyButton(action: {
dailyGoalViewModel.reset()
Expand Down
80 changes: 35 additions & 45 deletions Daily/Presentation/Goal/DailyGoalViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ class DailyGoalViewModel: ObservableObject {

@Published var content: String = ""
@Published var goalType: GoalTypes = .check
@Published var recordCount: Int = 0
@Published var goalCount: Int = 1
@Published var symbol: Symbols = .check

@Published var modifyRecord: DailyRecordModel? = nil
@Published var modifyType: ModifyTypes? = nil
@Published var modifyIsAll: Bool? = nil
@Published var modifyDate: Date = Date()
@Published var modifyRecordCount: Int = 0

private var beforeDate: Date = Date()
private var beforeRecord: Int = 0

// TODO: 추후 DailyGoalView로 이동시 Data에 날짜 데이터 추가, Date 변수들 조정
init() {
Expand All @@ -65,23 +64,11 @@ class DailyGoalViewModel: ObservableObject {
self.setRecord(record: modifyData.modifyRecord)
self.modifyRecord = modifyData.modifyRecord
self.modifyType = modifyData.modifyType
self.modifyIsAll = modifyData.isAll
self.cycleType = modifyData.modifyType == .all ? .rept : .date
self.beforeDate = modifyData.date
self.modifyDate = self.beforeDate
self.modifyRecordCount = modifyData.modifyRecord.count
}

// MARK: - get
func getNavigationBarTitle() -> String {
guard let modifyType = self.modifyType else { return "목표추가" }
switch modifyType {
case .record:
return "기록수정"
case .date:
return "날짜변경"
case .goal:
return "목표수정"
}
self.startDate = self.beforeDate
self.beforeRecord = modifyData.modifyRecord.count
self.recordCount = self.beforeRecord
}

// MARK: - set
Expand All @@ -100,7 +87,8 @@ class DailyGoalViewModel: ObservableObject {
func reset() {
if let modifyRecord {
self.setRecord(record: modifyRecord)
modifyDate = beforeDate
startDate = beforeDate
recordCount = beforeRecord
} else {
content = ""
symbol = .check
Expand Down Expand Up @@ -143,31 +131,21 @@ class DailyGoalViewModel: ObservableObject {

func modify(modelContext: ModelContext, successAction: @escaping (Date?) -> Void, validateAction: @escaping (DailyAlert) -> Void) {
if let validate = validate(validateType: .modify) { validateAction(validate); return }
var newDate: Date? = nil
if let record = modifyRecord,
let goal = record.goal,
let type = modifyType,
let isAll = modifyIsAll {
switch type {
if let record = modifyRecord, let goal = record.goal, let modifyType {
switch modifyType {
case .record:
record.count = modifyRecordCount
record.isSuccess = goal.count == modifyRecordCount
try? modelContext.save()
case .date:
record.date = modifyDate
newDate = modifyDate
goal.content = content
goal.symbol = symbol
goal.type = goalType
goal.count = goalCount
goal.isSetTime = isSetTime
goal.setTime = setTime.toStringOfSetTime()
record.date = startDate
record.count = recordCount
record.isSuccess = goalCount <= recordCount
try? modelContext.save()
case .goal:
if isAll {
goal.content = content
goal.symbol = symbol
goal.type = goalType
goal.count = goalCount
goal.isSetTime = isSetTime
goal.setTime = setTime.toStringOfSetTime()
record.isSuccess = goal.count <= modifyRecordCount
try? modelContext.save()
} else {
case .single:
if goal.content != content || goal.symbol != symbol || goal.type != goalType || goal.count != goalCount || goal.isSetTime != isSetTime || goal.setTime != setTime.toStringOfSetTime() {
let newGoal = DailyGoalModel(
type: goalType,
cycleType: cycleType,
Expand All @@ -185,11 +163,23 @@ class DailyGoalViewModel: ObservableObject {
try? modelContext.save()
goal.childGoals.append(newGoal)
record.goal = newGoal
try? modelContext.save()
}
record.date = startDate
record.count = recordCount
record.isSuccess = goalCount <= recordCount
try? modelContext.save()
case .all:
goal.content = content
goal.symbol = symbol
goal.type = goalType
goal.count = goalCount
goal.isSetTime = isSetTime
goal.setTime = setTime.toStringOfSetTime()
record.isSuccess = goalCount <= recordCount
try? modelContext.save()
}
successAction(startDate)
}
successAction(newDate)
}

// MARK: - validate func
Expand Down
Loading