From ab20600fe4f864d6ca0435fc7ec3cfb3e7004f26 Mon Sep 17 00:00:00 2001 From: opficdev Date: Wed, 25 Mar 2026 22:45:43 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20row=EC=97=90=20=EC=83=81=EC=8B=9C?= =?UTF-8?q?=20=EC=B5=9C=EA=B7=BC=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=EC=9D=84=20=EB=9C=A8=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Component/RelativeTimeText.swift | 39 +++++++++++++++++++ DevLog/UI/Common/Component/TodoItemRow.swift | 3 +- DevLog/UI/Home/HomeView.swift | 23 +---------- 3 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 DevLog/UI/Common/Component/RelativeTimeText.swift diff --git a/DevLog/UI/Common/Component/RelativeTimeText.swift b/DevLog/UI/Common/Component/RelativeTimeText.swift new file mode 100644 index 00000000..4f182462 --- /dev/null +++ b/DevLog/UI/Common/Component/RelativeTimeText.swift @@ -0,0 +1,39 @@ +// +// RelativeTimeText.swift +// DevLog +// +// Created by opfic on 3/25/26. +// + +import SwiftUI + +struct RelativeTimeText: View { + let date: Date + var bodyFont: Font = .caption2 + var bodyColor: Color = .gray + + var body: some View { + TimelineView(.periodic(from: .now, by: 1.0)) { context in + Text(relativeTimeText(from: date, now: context.date) + " 업데이트") + .font(bodyFont) + .foregroundStyle(bodyColor) + } + } + + private func relativeTimeText(from date: Date, now: Date) -> String { + let seconds = Int(now.timeIntervalSince(date)) + + if seconds < 60 { + return "\(max(0, seconds))초 전" + } else if seconds < 3600 { + let minutes = seconds / 60 + return "\(minutes)분 전" + } else if seconds < 86400 { + let hours = seconds / 3600 + return "\(hours)시간 전" + } else { + let days = seconds / 86400 + return "\(days)일 전" + } + } +} diff --git a/DevLog/UI/Common/Component/TodoItemRow.swift b/DevLog/UI/Common/Component/TodoItemRow.swift index 7f1d8db3..c2f4b320 100644 --- a/DevLog/UI/Common/Component/TodoItemRow.swift +++ b/DevLog/UI/Common/Component/TodoItemRow.swift @@ -39,6 +39,7 @@ struct TodoItemRow: View { .fixedSize(horizontal: true, vertical: false) } } + RelativeTimeText(date: item.updatedAt) if !item.tags.isEmpty { TagList(item.tags, lineLimit: 1) } @@ -48,6 +49,6 @@ struct TodoItemRow: View { .font(.caption2.bold()) .foregroundStyle(.gray) } - .padding(.vertical, item.tags.isEmpty ? 20 : 4) + .padding(.vertical, 8) } } diff --git a/DevLog/UI/Home/HomeView.swift b/DevLog/UI/Home/HomeView.swift index f4107d24..696fd5e2 100644 --- a/DevLog/UI/Home/HomeView.swift +++ b/DevLog/UI/Home/HomeView.swift @@ -408,11 +408,7 @@ private struct RecentTodoRow: View { .font(.caption.weight(.semibold)) .foregroundStyle(todo.kind.color) - TimelineView(.periodic(from: .now, by: 1.0)) { context in - Text(timeAgoText(from: todo.updatedAt, now: context.date)) - .font(.caption2) - .foregroundStyle(Color.gray) - } + RelativeTimeText(date: todo.updatedAt) } if !todo.tags.isEmpty { @@ -421,21 +417,4 @@ private struct RecentTodoRow: View { } } } - - private func timeAgoText(from date: Date, now: Date) -> String { - let seconds = Int(now.timeIntervalSince(date)) - - if seconds < 60 { - return "\(max(0, seconds))초 전" - } else if seconds < 3600 { - let minutes = seconds / 60 - return "\(minutes)분 전" - } else if seconds < 86400 { - let hours = seconds / 3600 - return "\(hours)시간 전" - } else { - let days = seconds / 86400 - return "\(days)일 전" - } - } } From 51d6543f2dc4e8c503a2d38aa4afdc03d48e523b Mon Sep 17 00:00:00 2001 From: opficdev Date: Wed, 25 Mar 2026 23:02:53 +0900 Subject: [PATCH 2/3] =?UTF-8?q?ui:=20=EC=99=84=EB=A3=8C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20ui=EB=A5=BC=20=EC=83=81=EC=8B=9C=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A3=BC=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Common/Component/TodoItemRow.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DevLog/UI/Common/Component/TodoItemRow.swift b/DevLog/UI/Common/Component/TodoItemRow.swift index c2f4b320..8190b498 100644 --- a/DevLog/UI/Common/Component/TodoItemRow.swift +++ b/DevLog/UI/Common/Component/TodoItemRow.swift @@ -8,6 +8,7 @@ import SwiftUI struct TodoItemRow: View { + @Environment(\.sceneWidth) private var sceneWidth private let item: TodoListItem init(_ item: TodoListItem) { @@ -16,6 +17,10 @@ struct TodoItemRow: View { var body: some View { HStack { + Image(systemName: "checkmark.circle") + .resizable() + .frame(width: sceneWidth * 0.08, height: sceneWidth * 0.08) + .foregroundStyle(item.isCompleted ? .green : .secondary) VStack(alignment: .leading, spacing: 5) { HStack { if item.isPinned { @@ -23,11 +28,6 @@ struct TodoItemRow: View { .font(.headline) .foregroundStyle(.orange) } - if item.isCompleted { - Image(systemName: "checkmark.circle.fill") - .font(.headline) - .foregroundStyle(.green) - } Text(item.title) .font(.headline) .foregroundStyle(Color(.label)) @@ -49,6 +49,6 @@ struct TodoItemRow: View { .font(.caption2.bold()) .foregroundStyle(.gray) } - .padding(.vertical, 8) + .padding(.vertical, 12) } } From 85fdba4a78b97e91ed32084e3ef5f01605f601a8 Mon Sep 17 00:00:00 2001 From: opficdev Date: Wed, 25 Mar 2026 23:28:46 +0900 Subject: [PATCH 3/3] =?UTF-8?q?ui:=20=EC=A4=91=EC=9A=94=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20UI=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Common/Component/TodoItemRow.swift | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/DevLog/UI/Common/Component/TodoItemRow.swift b/DevLog/UI/Common/Component/TodoItemRow.swift index 8190b498..a341b9d8 100644 --- a/DevLog/UI/Common/Component/TodoItemRow.swift +++ b/DevLog/UI/Common/Component/TodoItemRow.swift @@ -21,13 +21,8 @@ struct TodoItemRow: View { .resizable() .frame(width: sceneWidth * 0.08, height: sceneWidth * 0.08) .foregroundStyle(item.isCompleted ? .green : .secondary) - VStack(alignment: .leading, spacing: 5) { + VStack(alignment: .leading, spacing: 0) { HStack { - if item.isPinned { - Image(systemName: "star.fill") - .font(.headline) - .foregroundStyle(.orange) - } Text(item.title) .font(.headline) .foregroundStyle(Color(.label)) @@ -39,7 +34,15 @@ struct TodoItemRow: View { .fixedSize(horizontal: true, vertical: false) } } - RelativeTimeText(date: item.updatedAt) + HStack(spacing: 4) { + if item.isPinned { + Image(systemName: "star.fill") + .font(.headline) + .foregroundStyle(.orange) + } + RelativeTimeText(date: item.updatedAt) + } + .frame(height: UIFont.preferredFont(forTextStyle: .headline).lineHeight) if !item.tags.isEmpty { TagList(item.tags, lineLimit: 1) }