Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1ae504e
add: #428 댓글, 좋아요 이미지 추가
y-eonee Apr 29, 2026
25d3085
style: #428 퀘스트 content, 댓글 컴포넌트 분리
y-eonee Apr 29, 2026
33d1a93
feat: #428 좋아요 누르기 구현
y-eonee Apr 29, 2026
23b5086
style: #428 나의여정에서도 프로필아이콘이 뜨도록 수정
y-eonee Apr 29, 2026
8eaeb44
refactor: #428 extension 적용
y-eonee May 4, 2026
1a38631
setting: #428 리퀴드글래스 미적용
y-eonee May 4, 2026
e695a05
feat: #428 댓글 입력 컴포넌트 구현
y-eonee May 4, 2026
a94efc5
chore: #428 주석 삭제
y-eonee May 4, 2026
349d4ab
refactor: #428 변경된 DTO 수정
y-eonee May 7, 2026
5cb40bf
feat: #428 재사용을 위해 answer entity 수정 및 comment entity 작성
y-eonee May 7, 2026
840d3b0
refactor: #428 profile Icon String -> Image 전역으로 분리
y-eonee May 7, 2026
809f5dc
feat: #428 Textview line 수 계산 익스텐션
y-eonee May 7, 2026
55b01b1
style: #428 댓글 UI 구현
y-eonee May 7, 2026
70c5108
refactor: #428 entity 수정에 따른 configure 함수 내부 수정
y-eonee May 7, 2026
cac5977
refactor: #428 profileIcon 로직 뷰모델 내부에서 삭제
y-eonee May 7, 2026
ba83a40
feat: #428 comment Table View VC에 연결
y-eonee May 7, 2026
5755451
fix: #428 컴포넌트 재사용에 따른 UI 로직 수정
y-eonee May 7, 2026
4e56be0
style: #428 History View UI
y-eonee May 7, 2026
5a5b38f
feat: #428 scrollView, tableView 중첩을 위한 익스텐션
y-eonee May 7, 2026
5997863
feat: #428 댓글 더보기 구현
y-eonee May 8, 2026
c4dbe52
add: #428 답글 아이콘 추가
y-eonee May 10, 2026
2da80d8
chore: #428 comment entity stub 추가
y-eonee May 10, 2026
0d248ec
feat: #428 댓글, 답글 레이아웃 분기처리 수정
y-eonee May 10, 2026
a3e1ea0
style: #428 답글 바텀시트 UI 구현
y-eonee May 10, 2026
34610bf
feat: #428 답글 뷰 모델 생성
y-eonee May 10, 2026
cd2ae9b
refactor: #428 키보드 로직 분리
y-eonee May 10, 2026
d2f185f
feat: #428 답글 기능 구현
y-eonee May 10, 2026
ee5f919
style: #428 separator 설정
y-eonee May 10, 2026
fdca78c
fix: #428 stub id 수정
y-eonee May 10, 2026
d8fa920
refactor: #428 불필요한 분기처리 삭제
y-eonee May 10, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// CommonQuestAnswerDetailResponseDTO.swift
// ByeBoo-iOS
//
// Created by 이나연 on 5/5/26.
//

import Foundation

struct CommonQuestAnswerDetailResponseDTO: Decodable {
let question: String
let answer: CommonQuestAnswerResponseDTO
let comments: [CommonQuestCommentResponseDTO]
}

struct CommonQuestCommentResponseDTO: Decodable {
let commentId: Int
let replyCount: Int
let writerId: Int
let writer: String
let profileIcon: String
let writtenAt: String
let content: String
}

extension CommonQuestAnswerDetailResponseDTO {
func toEntity() -> [CommonQuestCommentEntity] {
comments.map {
$0.toEntity()
}
}
}

extension CommonQuestCommentResponseDTO {
func toEntity() -> CommonQuestCommentEntity {
.init(
commentID: commentId,
replyCount: replyCount,
writerID: writerId,
writer: writer,
profileIcon: profileIcon,
writtenAt: writtenAt,
content: content
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// CommonQuestAnswerRepliesResponseDTO.swift
// ByeBoo-iOS
//
// Created by 이나연 on 5/5/26.
//

import Foundation

struct CommonQuestAnswerRepliesResponseDTO: Decodable {
let totalCount: Int
let comment: CommonQuestAnswerCommentResponseDTO
let replies: [CommonQuestAnswerReplyResponseDTO]
}

struct CommonQuestAnswerCommentResponseDTO: Decodable {
let content: String
let writer: String
let createdAt: String
let profileIcon: String
let commentId: Int
let writerId: Int
}

struct CommonQuestAnswerReplyResponseDTO: Decodable {
let content: String
let writer: String
let createdAt: String
let profileIcon: String
let commentId: Int
let writerId: Int
}

extension CommonQuestAnswerRepliesResponseDTO {
func toEntity() -> [CommonQuestCommentEntity] {
replies.map {
$0.toEntity()
}
}
}

extension CommonQuestAnswerReplyResponseDTO {
func toEntity() -> CommonQuestCommentEntity {
.init(
commentID: commentId,
replyCount: nil,
writerID: writerId,
writer: writer,
profileIcon: profileIcon,
writtenAt: createdAt,
content: content
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ struct CommonQuestAnswersResponseDTO: Decodable {
}

struct CommonQuestAnswerResponseDTO: Decodable {
// let likeCount: Int
// let commentCount: Int
// let isLiked: Bool
let answerId: Int
// let userId: Int
// let writerId: String
let writer: String
let writerId: Int
let profileIcon: String
let writtenAt: String
let content: String
let writerId: Int
}

extension CommonQuestAnswersResponseDTO {
Expand All @@ -41,13 +46,26 @@ extension CommonQuestAnswersResponseDTO {
extension CommonQuestAnswerResponseDTO {
func toEntity(userName: String) -> CommonQuestAnswerEntity {
.init(
// isMyAnswer: userName == writerId ? true : false,
// answerID: answerId,
// writerID: writerId,
// profileIcon: profileIcon,
// writtenAt: writtenAt,
// content: content,
// userID: userId,
// likeCount: likeCount,
// commentCount: commentCount,
// isLiked: isLiked
isMyAnswer: userName == writer ? true : false,
answerID: answerId,
writer: writer,
writerID: writer,
profileIcon: profileIcon,
writtenAt: writtenAt,
content: content,
writerID: writerId
userID: writerId,
likeCount: 3,
commentCount: 4,
isLiked: false,
)
}
}
21 changes: 15 additions & 6 deletions ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ struct CommonQuestAnswersEntity {
struct CommonQuestAnswerEntity {
let isMyAnswer: Bool
let answerID: Int
let writer: String
let writerID: String
let profileIcon: String
let writtenAt: String
let content: String
let writerID: Int
let userID: Int
let likeCount: Int
let commentCount: Int
let isLiked: Bool
}

extension CommonQuestAnswersEntity {
Expand All @@ -35,11 +38,14 @@ extension CommonQuestAnswersEntity {
CommonQuestAnswerEntity(
isMyAnswer: false,
answerID: $0,
writer: "유저\($0)",
writerID: "유저\($0)",
profileIcon: profileIcons[$0 % 4],
writtenAt: Date.now.toString(),
content: "\($0)번째 테스트 답변",
writerID: 1
userID: $0,
likeCount: 1,
commentCount: 1,
isLiked: false
)
}

Expand All @@ -61,11 +67,14 @@ extension CommonQuestAnswerEntity {
.init(
isMyAnswer: false,
answerID: 1,
writer: "장원영",
writerID: "장원영",
profileIcon: "SO_SO",
writtenAt: "2025-10-12",
content: "헤어진 지 벌써 일주일이 지났습니다. 처음에는 실감이 안 나서 눈물조차 나오지 않았어요. 그저 멍하니 천장만 바라보며 시간을 보냈습니다. 그런데 오늘 아침, 습관적으로 휴대폰을 확인하다가 더 이상 '굿모닝' 인사를 보낼 사람이 없다는 사실을 깨닫고 그제야 무너져 내렸습니다. 밥알이 모래알 같아서 잘 넘어가지도 않네요. 친구들은 시간이 약이라고, 더 좋은 사람 만날 거라고 위로하지만 지금 당장은 그 어떤 말도 귀에 들어오지 않습니다.",
writerID: 1
userID: 12,
likeCount: 3,
commentCount: 4,
isLiked: false
)
}
}
73 changes: 73 additions & 0 deletions ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestCommentEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// CommonQuestCommentEntity.swift
// ByeBoo-iOS
//
// Created by 이나연 on 5/5/26.
//

import Foundation

struct CommonQuestCommentEntity: Hashable {
let commentID: Int
let replyCount: Int?
let writerID: Int
let writer: String
let profileIcon: String
let writtenAt: String
let content: String
}

extension CommonQuestCommentEntity {
static func toCommentListStub() -> [Self] {
return (1...5).map {
.init(
commentID: $0,
replyCount: $0 - 1,
writerID: 2,
writer: "장원영",
profileIcon: "SADNESS",
writtenAt: "2026-02-19T02:09:43.735730",
content: "나도여ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ냐냐냐냐냐냐냐냐냐"
)
}
}

static func toCommentStub() -> Self {
.init(
commentID: 1,
replyCount: 2,
writerID: 2,
writer: "가을이",
profileIcon: "SELF_UNDERSTANDING",
writtenAt: "2026-02-19T02:09:43.735730",
content: "나도여ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ냐냐냐냐냐냐냐냐냐"
)
}

static func toReplyListStub() -> [Self] {
return (6...10).map {
.init(
commentID: $0,
replyCount: nil,
writerID: 2,
writer: "안유진",
profileIcon: "SADNESS",
writtenAt: "2026-02-19T02:09:43.735730",
content: "헤어짐ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ"
)
}
}


static func toReplyStub() -> Self {
.init(
commentID: 1,
replyCount: nil,
writerID: 2,
writer: "가을이",
profileIcon: "SELF_UNDERSTANDING",
writtenAt: "2026-02-19T02:09:43.735730",
content: "헤어짐"
)
}
}
32 changes: 32 additions & 0 deletions ByeBoo-iOS/ByeBoo-iOS/Presentation/Enum/ProfileIcon.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// ProfileIcon.swift
// ByeBoo-iOS
//
// Created by 이나연 on 5/5/26.
//

import UIKit

enum ProfileIcon: String, CaseIterable {
case sad = "SADNESS"
case selfUnderstanding = "SELF_UNDERSTANDING"
case soso = "SO_SO"
case relieved = "RELIEVED"

var image: UIImage {
switch self {
case .sad:
return .sadnessBadge
case .selfUnderstanding:
return .selfUnderstandingBadge
case .soso:
return .sosoBadge
case .relieved:
return .relievedBadge
}
}

static func image(for iconString: String) -> UIImage? {
ProfileIcon(rawValue: iconString)?.image
}
}
16 changes: 15 additions & 1 deletion ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableView+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,22 @@

import UIKit

final class SelfSizingTableView: UITableView {
override var contentSize: CGSize {
didSet {
if oldValue != contentSize {
invalidateIntrinsicContentSize()
}
}
}

override var intrinsicContentSize: CGSize {
return contentSize
}
}

extension UITableView {

func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T {
guard let cell = self.dequeueReusableCell(
withIdentifier: T.identifier,
Expand Down
27 changes: 27 additions & 0 deletions ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITextView+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,31 @@ extension UITextView {
attributedText = NSAttributedString(string: targetText, attributes: attributes)
typingAttributes = attributes
}

func applyTextViewStyle(style: FontManager, text: String, color: UIColor) {
self.applyByeBooFont(
style: style,
text: text,
color: color
)
}

func numberOfLine() -> Int {
guard !text.isEmpty else { return 0 }
let size = CGSize(width: frame.width, height: .infinity)
let estimatedSize = sizeThatFits(size)

let lineHeight: CGFloat
if let paragraphStyle = attributedText?.attribute(.paragraphStyle, at: 0, effectiveRange: nil) as? NSParagraphStyle,
paragraphStyle.minimumLineHeight > 0 {
lineHeight = paragraphStyle.minimumLineHeight
} else if let font = attributedText?.attribute(.font, at: 0, effectiveRange: nil) as? UIFont {
lineHeight = font.lineHeight
} else {
lineHeight = self.font?.lineHeight ?? 0
}

guard lineHeight > 0 else { return 0 }
return Int(estimatedSize.height / lineHeight)
}
}
Loading
Loading