diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/QuestsRepository.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/QuestsRepository.swift index f63b2a65..b7ef2bdd 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/QuestsRepository.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/QuestsRepository.swift @@ -8,6 +8,7 @@ import Foundation struct DefaultQuestRepository: QuestsInterface { + private let network: NetworkService private let userDefaultsService: UserDefaultService @@ -118,6 +119,10 @@ struct DefaultQuestRepository: QuestsInterface { try await editQuest(questID: questID, answer: answer, imageKey: imageKey) } + func fetchCommoncQuest(date: String) async throws -> CommonQuestAnswersEntity { + .stub() + } + // MARK: private function private func makeSignedURL(imageKey: String) async throws -> String { @@ -223,4 +228,8 @@ final class MockQuestsRepository: QuestsInterface { func editActiveQuest(questID: Int, answer: String, image: Data?, imageKey: String, isImageChanged: Bool) async throws { self.editActiveQuestCalled = true } + + func fetchCommoncQuest(date: String) async throws -> CommonQuestAnswersEntity { + .stub() + } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift index 31fb6cdc..058335a9 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift @@ -135,6 +135,10 @@ struct DomainDependencyAssembler: DependencyAssembler { DIContainer.shared.register(type: FetchCompletedQuestsUseCase.self) { _ in return DefaultFetchCompletedQuestsUseCase(repository: questRepository) } + + DIContainer.shared.register(type: FetchCommonQuestByDateUseCase.self) { _ in + return DefaultFetchCommonQuestByDateUseCase(repository: questRepository) + } DIContainer.shared.register(type: AutoLoginUseCase.self) { _ in return DefaultAutoLoginUseCase(repository: authRepository) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift new file mode 100644 index 00000000..af32f885 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift @@ -0,0 +1,46 @@ +// +// CommonQuestAnswersEntity.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import Foundation + +struct CommonQuestAnswersEntity { + let question: String + let answerCount: Int + let isAnswered: Bool + let answers: [CommonQuestAnswerEntity] +} + +struct CommonQuestAnswerEntity { + let answerID: Int + let writer: String + let profileIcon: String + let writtenAt: Date + let content: String +} + +extension CommonQuestAnswersEntity { + static func stub() -> Self { + .init( + question: "연애에서 반복된 문제 패턴 3가지를 생각해보아요", + answerCount: 0, + isAnswered: false, + answers: [] + ) + } +} + +extension CommonQuestAnswerEntity { + static func stub() -> Self { + .init( + answerID: 1, + writer: "장원영", + profileIcon: "SO_SO", + writtenAt: Date.now, + content: "헤어진 지 벌써 일주일이 지났습니다. 처음에는 실감이 안 나서 눈물조차 나오지 않았어요. 그저 멍하니 천장만 바라보며 시간을 보냈습니다. 그런데 오늘 아침, 습관적으로 휴대폰을 확인하다가 더 이상 '굿모닝' 인사를 보낼 사람이 없다는 사실을 깨닫고 그제야 무너져 내렸습니다. 밥알이 모래알 같아서 잘 넘어가지도 않네요. 친구들은 시간이 약이라고, 더 좋은 사람 만날 거라고 위로하지만 지금 당장은 그 어떤 말도 귀에 들어오지 않습니다." + ) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/QuestsInterface.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/QuestsInterface.swift index ce531b63..8478ab5d 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/QuestsInterface.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/Interface/QuestsInterface.swift @@ -30,4 +30,5 @@ protocol QuestsInterface { image: Data?, imageKey: String, isImageChanged: Bool) async throws + func fetchCommoncQuest(date: String) async throws -> CommonQuestAnswersEntity } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/FetchCommonQuestByDateUseCase.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/FetchCommonQuestByDateUseCase.swift new file mode 100644 index 00000000..67ad27b1 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/UseCase/FetchCommonQuestByDateUseCase.swift @@ -0,0 +1,30 @@ +// +// FetchCommonQuestByDateUseCase.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +protocol FetchCommonQuestByDateUseCase { + func execute(date: String) async throws -> CommonQuestAnswersEntity +} + +struct DefaultFetchCommonQuestByDateUseCase: FetchCommonQuestByDateUseCase { + + private let repository: QuestsInterface + + init(repository: QuestsInterface) { + self.repository = repository + } + + func execute(date: String) async throws -> CommonQuestAnswersEntity { + try await repository.fetchCommoncQuest(date: date) + } +} + +struct MockFetchCommonQuestByDateUseCase: FetchCommonQuestByDateUseCase { + + func execute(date: String) async throws -> CommonQuestAnswersEntity { + .stub() + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/QuestModalView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/QuestModalView.swift index e5e1a9e5..bb91edc3 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/QuestModalView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/QuestModalView.swift @@ -18,7 +18,7 @@ final class QuestModalView: BaseView, ModalProtocol { private let imageView = UIImageView() private let questLabel = UILabel() private let titleLabel = UILabel() - let tipButton = ByeBooTipTag() + let tipButton = ByeBooTipTag(text: "작성 TIP") private var questNumber: Int private var quest: String diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Tag/ByeBooTipTag.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Tag/ByeBooTipTag.swift index 24463e38..0edab116 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Tag/ByeBooTipTag.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Tag/ByeBooTipTag.swift @@ -11,8 +11,11 @@ import SnapKit import Then final class ByeBooTipTag: UIButton { - override init(frame: CGRect) { - super.init(frame: frame) + + init(text: String) { + super.init(frame: .zero) + + setTitle(text, for: .normal) setStyle() setLayout() } @@ -25,7 +28,6 @@ final class ByeBooTipTag: UIButton { self.do { $0.applyByeBooFont( style: .cap1M12, - text: "작성 TIP", color: .primary200 ) $0.backgroundColor = .white5 @@ -37,7 +39,7 @@ final class ByeBooTipTag: UIButton { private func setLayout() { self.snp.makeConstraints { - $0.width.equalTo(76.adjustedW) + $0.width.greaterThanOrEqualTo(76.adjustedW) $0.height.equalTo(24.adjustedH) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UIButton+.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UIButton+.swift index f3a570e7..0c3ecacf 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UIButton+.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UIButton+.swift @@ -27,20 +27,18 @@ extension UIButton { text: String? = nil, color: UIColor, for state: UIControl.State = .normal) { - titleLabel?.font = style.font - titleLabel?.textColor = color let targetText = text ?? title(for: state) - guard let targetText else { return } + guard let targetText = targetText else { return } - var attributes: [NSAttributedString.Key: Any] = [ + let attributes: [NSAttributedString.Key: Any] = [ .font: style.font, - .kern: style.kern + .kern: style.kern, + .foregroundColor: color ] - if let titleColor = titleColor(for: state) { - attributes[.foregroundColor] = titleColor - } - - setAttributedTitle(NSAttributedString(string: targetText, attributes: attributes), for: state) + setAttributedTitle( + NSAttributedString(string: targetText, attributes: attributes), + for: state + ) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableView+.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableView+.swift new file mode 100644 index 00000000..39099b9d --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableView+.swift @@ -0,0 +1,22 @@ +// +// UITableView+.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/22/26. +// + +import UIKit + +extension UITableView { + + func dequeueReusableCell(for indexPath: IndexPath) -> T { + guard let cell = self.dequeueReusableCell( + withIdentifier: T.identifier, + for: indexPath + ) as? T else { + return T() + } + + return cell + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableViewCell+.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableViewCell+.swift new file mode 100644 index 00000000..8d6df180 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableViewCell+.swift @@ -0,0 +1,14 @@ +// +// UITableViewCell+.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import UIKit + +extension UITableViewCell { + static var identifier: String { + String(describing: self) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableViewHeaderFooterView+.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableViewHeaderFooterView+.swift new file mode 100644 index 00000000..18c09eb2 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Extension/UITableViewHeaderFooterView+.swift @@ -0,0 +1,14 @@ +// +// UITableViewHeaderFooterView+.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/22/26. +// + +import UIKit + +extension UITableViewHeaderFooterView { + static var identifier: String { + String(describing: self) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/CommonQuestAnswersCell.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/CommonQuestAnswersCell.swift new file mode 100644 index 00000000..fc78df10 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/CommonQuestAnswersCell.swift @@ -0,0 +1,115 @@ +// +// CommonQuestAnswersCell.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import UIKit + +final class CommonQuestAnswersCell: UITableViewCell { + + private let containerView = UIView() + private let userIconView = UIImageView() + private let userNicknameLabel = UILabel() + private let answerContentLabel = UILabel() + private let writtenDateLabel = UILabel() + + override init( + style: UITableViewCell.CellStyle, + reuseIdentifier: String? + ) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + setStyle() + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setStyle() { + self.do { + $0.backgroundColor = .clear + $0.selectionStyle = .none + } + containerView.do { + $0.layer.cornerRadius = 12 + $0.backgroundColor = .white5 + } + userNicknameLabel.applyByeBooFont( + style: .body6R14, + color: .grayscale200 + ) + answerContentLabel.applyByeBooFont( + style: .body3R16, + color: .grayscale100, + numberOfLines: 0 + ) + writtenDateLabel.applyByeBooFont( + style: .body6R14, + color: .grayscale400 + ) + } + + private func setUI() { + addSubview(containerView) + containerView.addSubviews( + userIconView, + userNicknameLabel, + answerContentLabel, + writtenDateLabel + ) + } + + private func setLayout() { + containerView.snp.makeConstraints { + $0.top.equalToSuperview().inset(24.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.bottom.equalToSuperview() + } + userIconView.snp.makeConstraints { + $0.top.equalToSuperview().inset(16.adjustedH) + $0.leading.equalToSuperview().inset(24.adjustedW) + $0.size.equalTo(20.adjustedW) + } + userNicknameLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(16.adjustedH) + $0.leading.equalTo(userIconView.snp.trailing).offset(4.adjustedW) + $0.centerY.equalTo(userIconView.snp.centerY) + } + answerContentLabel.snp.makeConstraints { + $0.top.equalTo(userIconView.snp.bottom).offset(12.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.height.equalTo(47.adjustedH) + } + writtenDateLabel.snp.makeConstraints { + $0.top.equalTo(answerContentLabel.snp.bottom).offset(20.adjustedH) + $0.leading.equalToSuperview().inset(24.adjustedW) + $0.bottom.equalToSuperview().inset(16.adjustedH) + } + } +} + +extension CommonQuestAnswersCell { + + func bind( + profileIcon: UIImage?, + answer: CommonQuestAnswerEntity, + writtenAt: String + ) { + if let profileIcon { + userIconView.image = profileIcon + } else { + userIconView.do { + $0.backgroundColor = .grayscale600 + $0.layer.cornerRadius = 10 + } + } + userNicknameLabel.text = answer.writer + answerContentLabel.text = answer.content + writtenDateLabel.text = writtenAt + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/CommonQuestContentCell.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/CommonQuestContentCell.swift new file mode 100644 index 00000000..a36db95b --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/CommonQuestContentCell.swift @@ -0,0 +1,124 @@ +// +// CommonQuestContentCell.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/21/26. +// + +import UIKit + +final class CommonQuestContentCell: UITableViewCell { + + private let questionView = UIView() + private let questionMarkLabel = UILabel() + private let questionContentLabel = UILabel() + private let guideTimeLabel = UILabel() + private(set) var moveWriteAnswerButton = UIButton() + private let answersCountLabel = UILabel() + + override init( + style: UITableViewCell.CellStyle, + reuseIdentifier: String? + ) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + setStyle() + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setStyle() { + self.do { + $0.backgroundColor = .grayscale900 + $0.selectionStyle = .none + } + questionMarkLabel.applyByeBooFont( + style: .body1Sb16, + text: "Q.", + color: .primary200 + ) + questionContentLabel.do { + $0.applyByeBooFont( + style: .sub3M18, + color: .grayscale50, + numberOfLines: 0 + ) + $0.lineBreakStrategy = [] + } + guideTimeLabel.applyByeBooFont( + style: .cap2R12, + text: "23:59까지 답변 가능해요", + color: .grayscale400, + textAlignment: .left + ) + moveWriteAnswerButton.do { + $0.applyByeBooFont( + style: .body2M16, + text: "답변 작성하기", + color: .primary500 + ) + $0.layer.cornerRadius = 12 + $0.backgroundColor = .primary100 + } + answersCountLabel.applyByeBooFont( + style: .cap2R12, + color: .grayscale400, + textAlignment: .left + ) + } + + private func setUI() { + addSubviews( + questionView, + guideTimeLabel, + moveWriteAnswerButton, + answersCountLabel + ) + questionView.addSubviews( + questionMarkLabel, + questionContentLabel + ) + } + + private func setLayout() { + questionView.snp.makeConstraints { + $0.top.equalToSuperview() + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + } + questionMarkLabel.snp.makeConstraints { + $0.top.equalToSuperview() + $0.leading.equalToSuperview() + $0.width.equalTo(17.adjustedW) + } + questionContentLabel.snp.makeConstraints { + $0.verticalEdges.equalToSuperview() + $0.leading.equalTo(questionMarkLabel.snp.trailing).offset(4.adjustedW) + $0.trailing.equalToSuperview() + } + guideTimeLabel.snp.makeConstraints { + $0.top.equalTo(questionView.snp.bottom).offset(12.adjustedH) + $0.leading.equalToSuperview().inset(24.adjustedW) + } + moveWriteAnswerButton.snp.makeConstraints { + $0.top.equalTo(guideTimeLabel.snp.bottom).offset(16.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.height.equalTo(53.adjustedH) + } + answersCountLabel.snp.makeConstraints { + $0.top.equalTo(moveWriteAnswerButton.snp.bottom).offset(24.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + } + } +} + +extension CommonQuestContentCell { + + func bind(question: String, answersCount: Int) { + questionContentLabel.text = question + guideTimeLabel.text = "\(answersCount)개의 답변" + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/NoAnswerCell.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/NoAnswerCell.swift new file mode 100644 index 00000000..c97c76a9 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/Cells/NoAnswerCell.swift @@ -0,0 +1,53 @@ +// +// NoAnswerView.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/19/26. +// + +import UIKit + +final class NoAnswerCell: UITableViewCell { + + private let noAnswerLabel = UILabel() + + override init( + style: UITableViewCell.CellStyle, + reuseIdentifier: String? + ) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + setStyle() + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setStyle() { + self.do { + $0.backgroundColor = .grayscale900 + $0.selectionStyle = .none + } + noAnswerLabel.applyByeBooFont( + style: .body6R14, + text: "아직 작성된 답변이 없어요!", + color: .grayscale400, + textAlignment: .center + ) + } + + private func setUI() { + addSubview(noAnswerLabel) + } + + private func setLayout() { + noAnswerLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(70.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(80.adjustedW) + $0.bottom.equalToSuperview().inset(51.adjustedH) + } + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/CommonQuestHeaderView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/CommonQuestHeaderView.swift new file mode 100644 index 00000000..1765f4e8 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/CommonQuestHeaderView.swift @@ -0,0 +1,69 @@ +// +// CommonQuestHeaderView.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import UIKit + +final class CommonQuestHeaderView: BaseView { + + private let titleLabel = UILabel() + private let subtitleLabel = UILabel() + private(set) var historyButton = ByeBooTipTag(text: "나의 답변 모아보기") + private let underline = UILabel() + + override func setStyle() { + titleLabel.applyByeBooFont( + style: .head2M22, + text: "함께 이별을 극복하는 공간이에요", + color: .grayscale50, + textAlignment: .left, + numberOfLines: 1 + ) + subtitleLabel.applyByeBooFont( + style: .body6R14, + text: "공통 퀘스트를 통해 나의 이야기를 솔직히 털어놓고,\n타인의 답변도 확인해 보세요", + color: .grayscale300, + textAlignment: .left, + numberOfLines: 2 + ) + underline.do { + $0.backgroundColor = .grayscale800 + $0.layer.borderColor = UIColor.grayscale800.cgColor + $0.layer.borderWidth = 1 + } + } + + override func setUI() { + addSubviews( + titleLabel, + subtitleLabel, + historyButton, + underline + ) + } + + override func setLayout() { + titleLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(16.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + } + subtitleLabel.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(12.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + } + historyButton.snp.makeConstraints { + $0.top.equalTo(subtitleLabel.snp.bottom).offset(16.adjustedH) + $0.leading.equalToSuperview().inset(24.adjustedW) + $0.width.equalTo(123.adjustedW) + $0.height.equalTo(24.adjustedH) + } + underline.snp.makeConstraints { + $0.top.equalTo(historyButton.snp.bottom).offset(16.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.height.equalTo(1.adjustedH) + } + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/CommonQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/CommonQuestView.swift new file mode 100644 index 00000000..c2ca5221 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/CommonQuestView.swift @@ -0,0 +1,40 @@ +// +// CommonQuestView.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import UIKit + +import SnapKit + +final class CommonQuestView: BaseView { + + private(set) var commonQuestTableView = UITableView() + private(set) var headerView = CommonQuestHeaderView() + + override func setStyle() { + commonQuestTableView.do { + $0.backgroundColor = .grayscale900 + headerView.frame = CGRect( + x: 0, + y: 0, + width: UIScreen.main.bounds.width, + height: 152.adjustedH + ) + $0.tableHeaderView = headerView + $0.sectionHeaderTopPadding = 0 + } + } + + override func setUI() { + addSubview(commonQuestTableView) + } + + override func setLayout() { + commonQuestTableView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/DateNavigator.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/DateNavigator.swift new file mode 100644 index 00000000..c923a586 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/CommonQuest/DateNavigator.swift @@ -0,0 +1,151 @@ +// +// DateNavigator.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import UIKit + +protocol DateNavigatorDelegate: AnyObject { + func dateDidChanged(to date: String) +} + +final class DateNavigator: UITableViewHeaderFooterView { + + weak var delegate: DateNavigatorDelegate? + + private let calendar = Calendar.current + private let yesterday: Int = -1 + private let tommorw: Int = 1 + private let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "M월 dd일" + return formatter + }() + + private(set) var currentDate: Date = .now + private let navigatorStackView = UIStackView() + private(set) var previousButton = UIButton() + private let dateLabel = UILabel() + private(set) var nextButton = UIButton() + + override init(reuseIdentifier: String?) { + super.init(reuseIdentifier: reuseIdentifier) + + setStyle() + setUI() + setLayout() + setAction() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setStyle() { + self.do { + $0.backgroundView = UIView() + $0.backgroundColor = .grayscale900 + $0.contentView.backgroundColor = .grayscale900 + } + navigatorStackView.do { + $0.axis = .horizontal + $0.spacing = 20 + $0.distribution = .fill + } + previousButton.do { + $0.setImage(.previousOn, for: .normal) + $0.backgroundColor = .white5 + $0.layer.cornerRadius = 16 + } + dateLabel.applyByeBooFont( + style: .body2M16, + text: dateFormatter.string(from: currentDate), + color: .grayscale50 + ) + nextButton.do { + $0.setImage(.nextOff, for: .normal) + $0.backgroundColor = .white5 + $0.layer.cornerRadius = 16 + $0.isEnabled = true + } + } + + private func setUI() { + addSubview(navigatorStackView) + navigatorStackView.addArrangedSubviews( + previousButton, + dateLabel, + nextButton + ) + } + + private func setLayout() { + navigatorStackView.snp.makeConstraints { + $0.top.equalToSuperview().inset(20.adjustedH) + $0.centerX.equalToSuperview() + $0.bottom.equalToSuperview().inset(24.adjustedH) + } + previousButton.snp.makeConstraints { + $0.size.equalTo(32.adjustedW) + $0.centerY.equalToSuperview() + } + dateLabel.snp.makeConstraints { + $0.centerY.equalToSuperview() + } + nextButton.snp.makeConstraints { + $0.size.equalTo(32.adjustedW) + $0.centerY.equalToSuperview() + } + } + + private func setAction() { + previousButton.addTarget( + self, + action: #selector(moveYesterday), + for: .touchUpInside + ) + nextButton.addTarget( + self, + action: #selector(moveTomorrow), + for: .touchUpInside + ) + } +} + +extension DateNavigator { + + @objc + private func moveYesterday() { + currentDate = getDate(by: yesterday) ?? .now + dateLabel.text = dateFormatter.string(from: currentDate) + updateNextButton() + + // TO-DO : 실제 날짜 형식으로 수정 + delegate?.dateDidChanged(to: currentDate.toString()) + } + + @objc + private func moveTomorrow() { + currentDate = getDate(by: tommorw) ?? .now + dateLabel.text = dateFormatter.string(from: currentDate) + updateNextButton() + + delegate?.dateDidChanged(to: currentDate.toString()) + } + + private func getDate(by value: Int) -> Date? { + calendar.date(byAdding: .day, value: value, to: currentDate) + } + + private func updateNextButton() { + let image: UIImage = isToday ? .nextOff : .nextOn + nextButton.setImage(image, for: .normal) + nextButton.isEnabled = !isToday + } + + private var isToday: Bool { + calendar.isDateInToday(currentDate) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift index 2fefe288..54bae52b 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift @@ -5,15 +5,188 @@ // Created by APPLE on 2/12/26. // +import UIKit + final class CommonQuestViewController: BaseViewController { + private let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy.MM.dd." + return formatter + }() + private let rootView = CommonQuestView() + private let viewModel: CommonQuestViewModel + + init(viewModel: CommonQuestViewModel) { + self.viewModel = viewModel + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + view = rootView + } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(true, animated: false) } + override func viewDidLoad() { + super.viewDidLoad() + + let _ = viewModel.action(.viewDidLoad) + } + override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.navigationController?.setNavigationBarHidden(false, animated: false) } + + override func setAddTarget() { + rootView.headerView.historyButton.addTarget( + self, + action: #selector(myAnswerHistoryButtonDidTap), + for: .touchUpInside + ) + } + + override func setDelegate() { + rootView.commonQuestTableView.do { + $0.delegate = self + $0.dataSource = self + $0.register( + CommonQuestAnswersCell.self, + forCellReuseIdentifier: CommonQuestAnswersCell.identifier + ) + $0.register( + CommonQuestContentCell.self, + forCellReuseIdentifier: CommonQuestContentCell.identifier + ) + $0.register( + NoAnswerCell.self, + forCellReuseIdentifier: NoAnswerCell.identifier + ) + $0.register( + DateNavigator.self, + forHeaderFooterViewReuseIdentifier: DateNavigator.identifier + ) + } + } +} + +extension CommonQuestViewController: DateNavigatorDelegate { + + @objc + private func myAnswerHistoryButtonDidTap() {} + + @objc + private func moveWriteAnswerButtonDidTap() {} + + func dateDidChanged(to date: String) { + let _ = viewModel.action( + .moveDateButtonDidTap(selectedDate: date) + ).commonQuestAnswers + rootView.commonQuestTableView.reloadData() + } +} + +extension CommonQuestViewController: UITableViewDelegate { + + func tableView( + _ tableView: UITableView, + heightForRowAt indexPath: IndexPath + ) -> CGFloat { + indexPath.row == 0 ? 141.adjustedH : 171.adjustedH + } + + func tableView( + _ tableView: UITableView, + viewForHeaderInSection section: Int + ) -> UIView? { + guard let navigator = tableView.dequeueReusableHeaderFooterView( + withIdentifier: DateNavigator.identifier + ) as? DateNavigator else { + return nil + } + + return navigator + } + + func tableView( + _ tableView: UITableView, + heightForHeaderInSection section: Int + ) -> CGFloat { + 76.adjustedH + } +} + +extension CommonQuestViewController: UITableViewDataSource { + + func tableView( + _ tableView: UITableView, + numberOfRowsInSection section: Int + ) -> Int { + if viewModel.isExistAnswer { + return 1 + viewModel.answersCount + } + return 2 + } + + func tableView( + _ tableView: UITableView, + cellForRowAt indexPath: IndexPath + ) -> UITableViewCell { + if indexPath.row == .zero { + return dequeueQuestContentCell(from: tableView, indexPath: indexPath) + } + if viewModel.isExistAnswer { + return dequeueQuestAnswersCell(from: tableView, indexPath: indexPath) + } + return dequeueNoAnswerCell(from: tableView, indexPath: indexPath) + } + + private func dequeueQuestContentCell( + from tableView: UITableView, + indexPath: IndexPath + ) -> UITableViewCell { + let cell: CommonQuestContentCell = tableView.dequeueReusableCell(for: indexPath) + + cell.bind( + question: viewModel.question, + answersCount: viewModel.answersCount + ) + cell.moveWriteAnswerButton.addTarget( + self, + action: #selector(moveWriteAnswerButtonDidTap), + for: .touchUpInside + ) + + return cell + } + + private func dequeueQuestAnswersCell( + from tableView: UITableView, + indexPath: IndexPath + ) -> UITableViewCell { + let cell: CommonQuestAnswersCell = tableView.dequeueReusableCell(for: indexPath) + + let answer = viewModel.getAnswer(at: indexPath.row - 1) + let profileIcon = viewModel.getProfileIcon(at: indexPath.row - 1) + let writtenAt = dateFormatter.string(from: viewModel.getWrittenAt(at: indexPath.row - 1)) + cell.bind(profileIcon: profileIcon, answer: answer, writtenAt: writtenAt) + + return cell + } + + private func dequeueNoAnswerCell( + from tableView: UITableView, + indexPath: IndexPath + ) -> UITableViewCell { + let cell: NoAnswerCell = tableView.dequeueReusableCell(for: indexPath) + return cell + } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewModel/CommonQuestViewModel.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewModel/CommonQuestViewModel.swift new file mode 100644 index 00000000..ad6b8b5e --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewModel/CommonQuestViewModel.swift @@ -0,0 +1,84 @@ +// +// CommonQuestViewModel.swift +// ByeBoo-iOS +// +// Created by APPLE on 2/17/26. +// + +import UIKit + +final class CommonQuestViewModel { + + private var commonQuest: CommonQuestAnswersEntity? + private let fetchCommonQuestByDateUseCase: FetchCommonQuestByDateUseCase + + init(fetchCommonQuestByDateUseCase: FetchCommonQuestByDateUseCase) { + self.fetchCommonQuestByDateUseCase = fetchCommonQuestByDateUseCase + } + + enum Input { + case viewDidLoad + case moveDateButtonDidTap(selectedDate: String) + } + + struct Output { + let commonQuestAnswers: CommonQuestAnswersEntity + } + + func action(_ trigger: Input) -> Output { + let result: CommonQuestAnswersEntity = .stub() + commonQuest = result + return .init(commonQuestAnswers: result) + } +} + +extension CommonQuestViewModel { + + private enum ProfileIcon: String, CaseIterable { + case sad = "SAD" + 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 + } + } + } + + var question: String { + commonQuest?.question ?? "" + } + + var answersCount: Int { + commonQuest?.answerCount ?? 0 + } + + var isExistAnswer: Bool { + commonQuest?.answerCount != 0 + } + + func getAnswer(at index: Int) -> CommonQuestAnswerEntity { + commonQuest?.answers[index] ?? .stub() + } + + func getProfileIcon(at index: Int) -> UIImage? { + let iconString = commonQuest?.answers[index].profileIcon + let profileIcon = ProfileIcon.allCases + .first { $0.rawValue == iconString }? + .image + return profileIcon + } + + func getWrittenAt(at index: Int) -> Date { + commonQuest?.answers[index].writtenAt ?? .now + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/Common/WriteQuestTitleView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/Common/WriteQuestTitleView.swift index b7bb5aa3..f3307d20 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/Common/WriteQuestTitleView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/Common/WriteQuestTitleView.swift @@ -19,7 +19,7 @@ final class WriteQuestTitleView: BaseView { private let questNumLabel = UILabel() private let titleLabel = UILabel() - let tipTag = ByeBooTipTag() + let tipTag = ByeBooTipTag(text: "작성 TIP") init(stepNum: String, stepTitle: String, questNum: Int, title: String) { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift index 641d3ed8..52e94048 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/PresentationDependencyAssembler.swift @@ -258,5 +258,14 @@ struct PresentationDependencyAssembler: DependencyAssembler { getLastJourneyUseCase: getLastJourneyUseCase ) } + + DIContainer.shared.register(type: CommonQuestViewModel.self) { container in + guard let fetchCommonQuestByDateUseCase = container.resolve(type: FetchCommonQuestByDateUseCase.self) else { + ByeBooLogger.error(ByeBooError.DIFailedError) + return + } + + return CommonQuestViewModel(fetchCommonQuestByDateUseCase: fetchCommonQuestByDateUseCase) + } } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/ViewControllerFactory.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/ViewControllerFactory.swift index 2b1e6d38..d1e54e42 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/ViewControllerFactory.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/ViewControllerFactory.swift @@ -195,7 +195,12 @@ final class ViewControllerFactory: ViewControllerFactoryProtocol { } func makeCommonQuestViewController() -> CommonQuestViewController { - return .init() + guard let viewModel = DIContainer.shared.resolve(type: CommonQuestViewModel.self) else { + DIErrorHandle() + fatalError() + } + + return .init(viewModel: viewModel) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_off.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_off.imageset/Contents.json new file mode 100644 index 00000000..785bb348 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_off.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "next_off.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_off.imageset/next_off.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_off.imageset/next_off.svg new file mode 100644 index 00000000..d2d44bec --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_off.imageset/next_off.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_on.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_on.imageset/Contents.json new file mode 100644 index 00000000..0569b10d --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_on.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "next_on.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_on.imageset/next_on.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_on.imageset/next_on.svg new file mode 100644 index 00000000..d33bd381 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/next_on.imageset/next_on.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/previous_on.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/previous_on.imageset/Contents.json new file mode 100644 index 00000000..121c9c29 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/previous_on.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "previous_on.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/previous_on.imageset/previous_on.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/previous_on.imageset/previous_on.svg new file mode 100644 index 00000000..cd76ce50 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/IconSystem/previous_on.imageset/previous_on.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/relieved_badge.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/relieved_badge.imageset/Contents.json new file mode 100644 index 00000000..ff36ecee --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/relieved_badge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "relieved.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/relieved_badge.imageset/relieved.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/relieved_badge.imageset/relieved.svg new file mode 100644 index 00000000..4d706f26 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/relieved_badge.imageset/relieved.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/sadness_badge.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/sadness_badge.imageset/Contents.json new file mode 100644 index 00000000..76d3cdc3 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/sadness_badge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "sadness.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/sadness_badge.imageset/sadness.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/sadness_badge.imageset/sadness.svg new file mode 100644 index 00000000..3c9547bb --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/sadness_badge.imageset/sadness.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/self_understanding_badge.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/self_understanding_badge.imageset/Contents.json new file mode 100644 index 00000000..7bb22db9 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/self_understanding_badge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "self_understanding.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/self_understanding_badge.imageset/self_understanding.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/self_understanding_badge.imageset/self_understanding.svg new file mode 100644 index 00000000..f5279adc --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/self_understanding_badge.imageset/self_understanding.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/soso_badge.imageset/Contents.json b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/soso_badge.imageset/Contents.json new file mode 100644 index 00000000..89f6e5f4 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/soso_badge.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "soso.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/soso_badge.imageset/soso.svg b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/soso_badge.imageset/soso.svg new file mode 100644 index 00000000..83965cbf --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Resource/Assets.xcassets/Profile/soso_badge.imageset/soso.svg @@ -0,0 +1,5 @@ + + + + +