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

기록 수정 기능 구현 #36

Merged
merged 56 commits into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
98771d2
[Refactor] Modify 버튼 생성 및 버튼 상단이동 반영
minsangKang Aug 12, 2022
4e6abfb
[Feat] ModifyRecordVC 생성 및 navigation 추가 구현
minsangKang Aug 12, 2022
eee4f7e
[Feat] Log화면 네비게이션 컨트롤러 bottom bar None 처리
sujeong000 Aug 14, 2022
e4eb76e
[Feat] 그래프 스크롤뷰 및 페이지컨트롤 추가
sujeong000 Aug 14, 2022
e530597
[Feat] ModifyRecordVM 정의
sujeong000 Aug 14, 2022
2525d0c
[Feat] ModifyRecordVC에 뷰모델 추가
sujeong000 Aug 14, 2022
da9b252
[Feat] 타임라인그래프를 위한 HostingVC 구성
sujeong000 Aug 14, 2022
f315442
[Feat] 그래프 데이터 연결
sujeong000 Aug 14, 2022
a2acf9f
[Feat] HistoryCell 정의
sujeong000 Aug 14, 2022
c5fd405
[Feat] TaskInteractionView 정의
sujeong000 Aug 14, 2022
8962d37
[Feat] 커스텀 PaddingLabel 정의
sujeong000 Aug 14, 2022
a0f529b
[Feat] ModityRecord 화면에 InteractionView 추가
sujeong000 Aug 14, 2022
22cb1cf
[Feat] InteractionView에 Shadow, CornerRadius 적용
sujeong000 Aug 14, 2022
5c81f90
[Style] HistoryCell 디자인 수정
sujeong000 Aug 14, 2022
dc8431d
[Fix] InteractionView 사이즈 조정
sujeong000 Aug 14, 2022
0074e73
[Feat] TableViewDelegate, Datasource 연결
sujeong000 Aug 14, 2022
d1af8ec
[Feat] TableViewCell CustomSeparator 추가
sujeong000 Aug 14, 2022
2ab51cc
[Fix] Task명 길어지는 경우 뷰가 겹치는 현상 해결
sujeong000 Aug 15, 2022
d70a4a4
[Feat] TaskModityInteractionView 데이터 표시
sujeong000 Aug 15, 2022
7c7b626
[Feat] AddHistoryCell 추가
sujeong000 Aug 15, 2022
8d76c19
[Feat] ModifyInteractionView 내부 Button Delegate 설정
sujeong000 Aug 15, 2022
7a2d3b2
[Feat] 과목명 수정 기능 구현
sujeong000 Aug 15, 2022
06cf926
[Feat] 기록 추가 기능 구현
sujeong000 Aug 15, 2022
2dac1c1
[Feat] TaskHistory 수정 기능 구현
sujeong000 Aug 15, 2022
c38c48c
[Feat] OK 버튼 액션 구현
sujeong000 Aug 15, 2022
11e4fd0
[Feat] 선택 과목 테두리 처리 구현
sujeong000 Aug 15, 2022
fa8c60b
[Feat] ModifyRecordVC에 Daily 전달 및 BackButton 구현
sujeong000 Aug 15, 2022
c22b8ce
[Feat] InteractionView 유저컬러 반영
sujeong000 Aug 15, 2022
39f7c2c
[Fix] 기록 추가 시 날짜 오류 수정
sujeong000 Aug 15, 2022
8343839
[Feat] 컬렉션뷰 기록 추가 셀 구현
sujeong000 Aug 15, 2022
e137f15
[Feat] 과목추가 인터렉션뷰 구현
sujeong000 Aug 16, 2022
00c0934
[Refactor] 편집 모드(수정/추가) 구현 방식 변경
sujeong000 Aug 16, 2022
b16e8ed
[Refactor] 두가지 인터렉션뷰(수정/추가) 상속으로 구현
sujeong000 Aug 16, 2022
6891d95
[Feat] 기록추가 과목 입력창 구현
sujeong000 Aug 16, 2022
92c8870
[Refactor] alert 띄우는 코드 메소드로 분리
sujeong000 Aug 16, 2022
ff7812b
[Feat] ADD 버튼 구현
sujeong000 Aug 16, 2022
09a3564
[Fix] 오늘 날짜의 기록을 수정한 경우 예외 처리
sujeong000 Aug 16, 2022
952de9d
[Refactor] emptyView -> placeholder로 변경
sujeong000 Aug 16, 2022
6214493
[Comment] 주석 추가
sujeong000 Aug 16, 2022
4ff2ecf
[Refactor] 인터렉션 뷰 전환 방식 리팩토링
sujeong000 Aug 16, 2022
f381cd5
[Refactor] 리뷰 반영
minsangKang Aug 18, 2022
525342d
[Fix] 기록 추가 시 동일 과목명 설정 가능 버그 수정
sujeong000 Aug 18, 2022
2ecd286
[Feat] reverseColor 반영
sujeong000 Aug 22, 2022
a3351e9
[Fix] DatePicker로 시간 변경 시 초단위 00으로 처리
sujeong000 Aug 23, 2022
6c52747
[Fix] 새 기록 추가시 종료 시각 디폴트값 = 시작 시각으로 수정
sujeong000 Aug 23, 2022
bb6635e
[Fix] 기록 수정 후 Dailys 화면 데이터 최신화
sujeong000 Aug 23, 2022
a6634ba
[Feat] 동일 과목명 존재하는 경우 편집 불가 기능 구현
sujeong000 Aug 23, 2022
9a0ef80
[Refactor] EditHistoryVC configure 함수 추가
sujeong000 Aug 23, 2022
a1c8cb7
[Feat] 그래프와 동일하게 히스토리 정렬 기능 구현
sujeong000 Aug 23, 2022
c918a67
[Feat] 인터렉션뷰 전환시 alpha 애니메이션 추가
sujeong000 Aug 23, 2022
bcb5db6
[Refactor] StandardDailyTaskCell 하이라이트 cell 내부 로직으로 이동
sujeong000 Aug 23, 2022
a02f982
[Feat] 수정할 기록이 존재하지 않는 경우 alert 추가
sujeong000 Aug 23, 2022
e4e0b92
[Feat] localized 적용
sujeong000 Aug 23, 2022
67193ec
[Refactor] 기록수정 불가한 경우 alert 표시 로직 추가
minsangKang Aug 24, 2022
69c8b38
[Fix] 기록추가 cell 터치 action 터지는 현상 수정
minsangKang Aug 24, 2022
0699295
[Refactor] Date+Extension 으로 로직 이동 반영
minsangKang Aug 25, 2022
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
112 changes: 108 additions & 4 deletions Project_Timer.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

506 changes: 412 additions & 94 deletions Project_Timer/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions Project_Timer/Global/DailyManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ class DailyManager {
print("update daily!")
}
}

func modifyDaily(_ newDaily: Daily) {
guard let index = self.dailys.firstIndex(where: { $0.day == newDaily.day }) else { return }
self.dailys[index] = newDaily

self.saveDailys()
}
}
4 changes: 4 additions & 0 deletions Project_Timer/Global/DailyViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class DailyViewModel {
manager.loadDailys()
}

func modifyDaily(_ daily: Daily) {
manager.modifyDaily(daily)
}

func totalStudyTimeofMonth(month: Int, completion: @escaping (Int) -> ()) {
let monthData = dailys.filter { $0.day.month == month }
completion(monthData.reduce(0, { $0 + $1.totalTime }))
Expand Down
10 changes: 10 additions & 0 deletions Project_Timer/Global/Extension/Date+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ extension Date {
return dateFormatter.string(from: self)
}

var HHmmssStyleString: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
return dateFormatter.string(from: self)
}

func isSameDate(with date: Date) -> Bool {
return self.YYYYMMDDstyleString == date.YYYYMMDDstyleString
}
Expand Down Expand Up @@ -84,4 +90,8 @@ extension Date {
let timeComponents = Calendar.current.dateComponents([.hour, .minute, .second], from: from, to: to)
return (timeComponents.hour ?? 0)*3600 + (timeComponents.minute ?? 0)*60 + (timeComponents.second ?? 0)
}

var truncateSeconds: Date? {
return Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self))
}
}
13 changes: 13 additions & 0 deletions Project_Timer/Global/Extension/Int+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ extension Int {
}
}

var toHHmmss: String {
let time = self < 0 ? -self : self
let s = time % 60
let h = time / 3600
let m = (time / 60) - (h * 60)

if self < 0 {
return String(format: "-%d:%02d:%02d", h, m, s)
} else {
return String(format: "%d:%02d:%02d", h, m, s)
}
}

var toHM: String {
let h = self / 3600
let m = (self / 60) - (h * 60)
Expand Down
44 changes: 38 additions & 6 deletions Project_Timer/Global/Model/Daily.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@

import Foundation

struct TaskHistory: Codable {
let startDate: Date
let endDate: Date
struct TaskHistory: Codable, Equatable {
var startDate: Date
var endDate: Date
var interval: Int {
return Date.interval(from: startDate, to: endDate)
}

mutating func updateStartDate(to date: Date) {
self.startDate = date
}

mutating func updateEndDate(to date: Date) {
self.endDate = date
}

static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.startDate.YYYYMMDDHMSstyleString == rhs.startDate.YYYYMMDDHMSstyleString
&& lhs.endDate.YYYYMMDDHMSstyleString == rhs.endDate.YYYYMMDDHMSstyleString
}
}

struct Daily: Codable, CustomStringConvertible {
Expand Down Expand Up @@ -109,6 +122,8 @@ extension Daily {
taskHistorys[taskName] = [] // 빈 배열로 초기화
}
taskHistorys[taskName]?.append(TaskHistory(startDate: startDate, endDate: endDate))
// TODO: sort 로직 수정 필요 새벽 5시~새벽4시
taskHistorys[taskName]?.sort(by: { $0.startDate < $1.startDate })
self.taskHistorys = taskHistorys
} else {
assertionFailure("taskHistorys 값이 nil 입니다.")
Expand Down Expand Up @@ -161,12 +176,29 @@ extension Daily {
for i in 0...23 { timeline[i] = min(3600, timeline[i]) }
self.timeline = timeline
}
}

// MARK: ModifyRecordVM 내에서 불리는 메소드들
extension Daily {
mutating func changeTaskName(from oldName: String, to newName: String) {
// 같은 이름의 과목이 없다는 것이 보장된 상태

// tasks 업데이트
let totalTime = self.tasks[oldName]
self.tasks.removeValue(forKey: oldName)
self.tasks[newName] = totalTime

// taskHistorys 업데이트
let historys = self.taskHistorys?[oldName]
self.taskHistorys?.removeValue(forKey: oldName)
self.taskHistorys?[newName] = historys
}

mutating func modifyTaskHistorys(to taskHistorys: [String: [TaskHistory]]) {
self.taskHistorys = taskHistorys
mutating func updateTaskHistorys(of taskName: String, with historys: [TaskHistory]) {
self.taskHistorys?[taskName] = historys

self.updateTasks()
self.updateMaxTime()
self.updateTimeline()
self.save()
}
}
14 changes: 7 additions & 7 deletions Project_Timer/Global/Model/RecordTimes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ struct RecordTimes: Codable, CustomStringConvertible {
}
static let fileName: String = "recordTimes.json"

private(set) var recordTask: String = "none" // 측정중인 과목명
private(set) var recordTaskFromTime: Int = 0 // 측정중인 과목 기준시간값
private(set) var recordTask: String = "none" // 측정중인 과목명 ->?
private(set) var recordTaskFromTime: Int = 0 // 측정중인 과목 기준시간값 ->?

private(set) var recordStartAt = Date() // 기록측정 시작시각
private(set) var recording: Bool = false // 기록중인지 여부값, network 상 다른 기기에서도 표시 가능
Expand All @@ -24,12 +24,12 @@ struct RecordTimes: Codable, CustomStringConvertible {
private(set) var settedTimerTime: Int = 2400 // 사용자가 설정한 타이머 시간값

private var recordingMode: Int = 1 // 기록모드값, 1: timer, 2: stopwatch
private var savedSumTime: Int = 0 // sum 기준값 및 저장된 sum 값
private var savedTimerTime: Int = 2400 // timer 기준값 및 저장된 timer 값
private var savedStopwatchTime: Int = 0// stopwath 기준값 및 저장된 stopwatch 값
private var savedGoalTime: Int = 21600 // 저장된 goalTime 값
private var savedSumTime: Int = 0 // sum 기준값 및 저장된 sum 값 ->
private var savedTimerTime: Int = 2400 // timer 기준값 및 저장된 timer 값 ->
private var savedStopwatchTime: Int = 0// stopwath 기준값 및 저장된 stopwatch 값 ->
private var savedGoalTime: Int = 21600 // 저장된 goalTime 값 ->

private(set) var recordStartTimeline = Array(repeating: 0, count: 24) // 기록시작시 timeline 값
private(set) var recordStartTimeline = Array(repeating: 0, count: 24) // 기록시작시 timeline 값 ->

// task 를 변경할 경우 반영 (기록하기 전 반영)
mutating func updateTask(to taskName: String, fromTime: Int) {
Expand Down
42 changes: 42 additions & 0 deletions Project_Timer/Global/View/PaddingLabel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// PaddingLabel.swift
// Project_Timer
//
// Created by 최수정 on 2022/08/14.
// Copyright © 2022 FDEE. All rights reserved.
//

import UIKit

class PaddingLabel: UILabel {
private var padding = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)

convenience init(vertical: CGFloat, horizontal: CGFloat) {
self.init()
self.padding = UIEdgeInsets(top: vertical,
left: horizontal,
bottom: vertical,
right: horizontal)
}

convenience init(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) {
self.init()
self.padding = UIEdgeInsets(top: top,
left: left,
bottom: bottom,
right: right)
}

override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: padding))
}

override var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize

contentSize.height += padding.top + padding.bottom
contentSize.width += padding.left + padding.right

return contentSize
}
}
9 changes: 9 additions & 0 deletions Project_Timer/Logs/Dailys/Cell/StandardDailyTaskCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ final class StandardDailyTaskCell: UICollectionViewCell {
self.taskBackgroundView.backgroundColor = color
self.taskTimeLabel.textColor = color
}

func highlightBorder() {
self.layer.borderWidth = 2
self.layer.borderColor = UIColor.red.cgColor
}

func removeHighlight() {
self.layer.borderWidth = 0
}
}
32 changes: 30 additions & 2 deletions Project_Timer/Logs/Dailys/DailysVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import Combine
import SwiftUI
import FSCalendar

protocol ModifyRecordDelegate: AnyObject {
func showModifyRecordVC(daily: Daily)
}

final class DailysVC: UIViewController {
static let identifier = "DailysVC"
@IBOutlet var calendar: FSCalendar!
Expand All @@ -26,8 +30,9 @@ final class DailysVC: UIViewController {
UserDefaultsManager.set(to: isGraphChecked, forKey: .checks)
}
}
private weak var delegate: ModifyRecordDelegate?
private var previusColorIndex: Int?
private var isReversColor: Bool = false
var isReversColor: Bool = false
private var viewModel: DailysVM?
private var cancellables: Set<AnyCancellable> = []
enum GraphCollectionView: Int {
Expand All @@ -54,6 +59,7 @@ final class DailysVC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.post(name: LogVC.changePageIndex, object: nil, userInfo: ["pageIndex" : 1])
self.viewModel?.updateCurrentDaily()
}

override func viewWillLayoutSubviews() {
Expand Down Expand Up @@ -104,6 +110,28 @@ final class DailysVC: UIViewController {

self.present(activityViewController, animated: true)
}

@IBAction func modifyRecord(_ sender: Any) {
guard let viewModel = viewModel,
let targetDaily = viewModel.currentDaily else {
let alert = UIAlertController(title: "Unable to Modify Records".localized(),
message: "No record exists to modify.".localized(),
preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
alert.addAction(okAction)
present(alert, animated: true)

return
}

self.delegate?.showModifyRecordVC(daily: targetDaily)
}
}

extension DailysVC {
func configureDelegate(to delegate: ModifyRecordDelegate) {
self.delegate = delegate
}
}

extension DailysVC {
Expand All @@ -113,7 +141,7 @@ extension DailysVC {
self.calendar.appearance.headerDateFormat = "YYYY.MM"
self.calendar.appearance.headerTitleFont = TiTiFont.HGGGothicssiP80g(size: 25)
self.calendar.appearance.weekdayFont = TiTiFont.HGGGothicssiP80g(size: 13)
self.calendar.appearance.titleFont = TiTiFont.HGGGothicssiP60g(size: 20)
self.calendar.appearance.titleFont = TiTiFont.HGGGothicssiP60g(size: 18)
self.calendar.clipsToBounds = true
self.calendar.layer.cornerCurve = .continuous
self.calendar.layer.borderWidth = 2
Expand Down
5 changes: 5 additions & 0 deletions Project_Timer/Logs/Dailys/DailysVM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ final class DailysVM {
.map { TaskInfo(taskName: $0.key, taskTime: $0.value) }
}

func updateCurrentDaily() {
let newDaily = RecordController.shared.dailys.dailys.first(where: { $0.day == self.currentDaily?.day })
self.updateDaily(to: newDaily)
}

func updateColor(isReverseColor: Bool) {
self.timelineVM.updateColor(isReversColor: isReverseColor)
}
Expand Down
10 changes: 10 additions & 0 deletions Project_Timer/Logs/Dailys/Graph/StandardDailyGraphView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ final class StandardDailyGraphView: UIView {

private func configureCollectionView() {
let standardDailyTaskCellNib = UINib.init(nibName: StandardDailyTaskCell.identifier, bundle: nil)
let addNewTaskHistoryCellNib = UINib.init(nibName: AddNewTaskHistoryCell.identifier, bundle: nil)
self.tasksCollectionView.register(standardDailyTaskCellNib, forCellWithReuseIdentifier: StandardDailyTaskCell.identifier)
self.tasksCollectionView.register(addNewTaskHistoryCellNib, forCellWithReuseIdentifier: AddNewTaskHistoryCell.identifier)
}

private func configureProgressView() {
Expand Down Expand Up @@ -226,6 +228,14 @@ extension StandardDailyGraphView {
func reload() {
self.tasksCollectionView.reloadData()
}
/// 컬렉션뷰 테두리 하이라이트
func highlightCollectionView() {
self.tasksCollectionView.layer.borderColor = UIColor.red.cgColor
}
/// 컬렉션뷰 테두리 하이라이트 제거
func removeCollectionViewHighlight() {
self.tasksCollectionView.layer.borderColor = UIColor(named: "System_border")?.cgColor
}
}

// MARK: StandardDailyGraphView Private Actions
Expand Down
16 changes: 15 additions & 1 deletion Project_Timer/Logs/LogVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ final class LogVC: UIViewController {

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.tabBarController?.updateTabbarColor(backgroundColor: TiTiColor.tabbarBackground, tintColor: .label, normalColor: .lightGray)
}

override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.tabBarController?.updateTabbarColor(backgroundColor: TiTiColor.tabbarBackground, tintColor: .label, normalColor: .lightGray)
}

Expand Down Expand Up @@ -72,8 +74,10 @@ extension LogVC {

private func configureChildViewControllers() {
guard let logHomeVC = self.storyboard?.instantiateViewController(withIdentifier: LogHomeVC.identifier),
let dailysVC = self.storyboard?.instantiateViewController(withIdentifier: DailysVC.identifier),
let dailysVC = self.storyboard?.instantiateViewController(withIdentifier: DailysVC.identifier) as? DailysVC,
let weeksVC = self.storyboard?.instantiateViewController(withIdentifier: WeeksVC.identifier) else { return }
dailysVC.configureDelegate(to: self)

self.childVCs = [logHomeVC, dailysVC, weeksVC]
self.pageViewController.setViewControllers([logHomeVC], direction: .forward, animated: true)
}
Expand All @@ -96,3 +100,13 @@ extension LogVC: UIPageViewControllerDataSource {
return self.childVCs[index+1]
}
}

extension LogVC: ModifyRecordDelegate {
func showModifyRecordVC(daily: Daily) {
print(daily.day.YYYYMMDDstyleString)
guard let modifyRecordVC = self.storyboard?.instantiateViewController(withIdentifier: ModifyRecordVC.identifier) as? ModifyRecordVC,
let dailysVC = self.childVCs[1] as? DailysVC else { return }
modifyRecordVC.configureViewModel(with: daily, isReverseColor: dailysVC.isReversColor)
self.navigationController?.pushViewController(modifyRecordVC, animated: true)
}
}
Loading