From fe4a0858b7698aa29cbcf3dfb17a8492827e0042 Mon Sep 17 00:00:00 2001 From: otoolz Date: Fri, 12 Jan 2024 16:40:23 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat=20#384:=20=EC=97=A0=ED=8B=B0?= =?UTF-8?q?=EB=B7=B0=20=EA=B4=80=EB=A0=A8=20=EC=9D=B4=EB=AF=B8=EC=A7=80=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/empty.imageset/Contents.json | 23 ++++++++++++++++++ .../empty.imageset/Glyph_ undefined 1.png | Bin 0 -> 2605 bytes .../empty.imageset/Glyph_ undefined 2.png | Bin 0 -> 4198 bytes .../empty.imageset/Glyph_ undefined.png | Bin 0 -> 1431 bytes .../Sources/DesignSystem/View/EmptyView.swift | 21 ++++++++++++++++ 5 files changed, 44 insertions(+) create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Contents.json create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined 1.png create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined 2.png create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined.png create mode 100644 iOS/traveline/Sources/DesignSystem/View/EmptyView.swift diff --git a/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Contents.json b/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Contents.json new file mode 100644 index 0000000..b2a331d --- /dev/null +++ b/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "Glyph_ undefined.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Glyph_ undefined 1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Glyph_ undefined 2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined 1.png b/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined 1.png new file mode 100644 index 0000000000000000000000000000000000000000..75d5ea89540522ec64a92b129d62a00911c1dc9b GIT binary patch literal 2605 zcmV+|3exq7P)>$^b~n`Z0t4I` zSG}VYJb{EsUEtt`5RUEtK*A&~@Jzuw2#gxQ86-?EjI7USEaB87TV;B3x}y*9Dc!$w zK|yY(K=eZ`@!PG-%1otb{2pm~)$nxT|EEO(hua_35w!U}I9>Y*%km%gE`2c0Iu)3# zU^JADt5X~l>)`hf>JVB$pMx(X5D7L}wPImgg;%89E@Uz}7KwiCwa5ZW(fJ8;Y#yB9-}kM}M`$Ni?DfJQo*W!I)WwDh;E= z;EdO%4q}QNMPM>stV=QDyuZ+J0*QexO|D^R+^g203r=t&%Zf`am(}g!SoUuFgG$mp zSUY7~4*9vCp@n?~0SPK_D{-+~#?_lwSl|gH43>FwfK$IE%ah9pE^;t|+pP59d~q@> z#m!+2FlE(T6EdDZOJ)!CWw*MLfpf36_>!W9Z(q= zZ#6BRd<5Vb?*iKiedcZ<=#)A=e4p(HVyNj3FYmeq_ z4CWeD4^7-E%rV)k(dDfLQ{WqjxQ*DdyVkHrw893S@X~^9>-`GNce>g-Q5ztTopR}l z0{v+KkAL;hihZ@s3G{IDy=G(9w=&ICaa1VIo4K@g&n z+y-!36n|8}9(sbtHts36AwP${yk#-&5sRb*c7y_X344igkC;4yme>trdr$_jPtmV- z{`{kQ4-s&L0%dlY?HTm^9$Y?+^`r+Bg(XXav{@`fz*rTm_)X6HhBH>EYG?Q0Kn#0s?})1Z#B#AGVbrv>5l`FubmRfGAL)O=DsU{K&OwY#26Q#%#!2AH^wWC{_LD(IEH0IG%rSVM)^81X9G48=)==csZezXT)VAcGg zp*K+xjiD}OSkS$#+Zgw7;j)xnT2x^RY?GGMT!i4_5;oL@D){7w2vq3+hxm6dp{6nJ z!6a|EmI0GC^WfTXK}E<{HOE%)7y=UG9xkv!<+^T%VpC&VfZs(oY==xeSy&%gO#5{E zBKWtWp{WHc_#1>?;zi)br%hOuyy02~Oj6HPDL4>;*BlXe&1oZWUUxyYFxv$-S;IB< zv{YJfPr*j>bHn8z0ylkV27+&zrlmPBY2&KQ>#k`n0{cem#%U?rvDC(s)il@5K=4h| z>Rk>@_$^pBf9U7PSya~dzt3;Iae(TEl4z`^p0-X|SgZwEDywRfF z`k;DUhbg!!o5!27yS%)3smI_6+Tp-DUm}6CB~lQWb9`N<6&#}xczmA&FGyI*LRWCp zAt!LQL=w9T&v*3~X7+T08M6vF!TF-|6f|QY&(MGxz*eh6rV~lc*m`$i7f={0b~Tq= zk&RFasGFsS<7$3};oOI7S8C|Y!cBY-sP$7<&!-&sqwFxeFUjl=HWsbsiyRCqZmc=@ zeMxSIKU&pC__7BbkmC6g$u0QfwB$9-52ISJu}@O?6Tp=r`ne88S)a#~bHSH?S5{%H6U zzaOoHO=5P#j(i}r*znlLL*_+bM)H#6(hr4%b26MgdF9?quwJa_Yj=!L=JO-UT)RV-y(1@D;DS$YfM<#SOLm*o!0HL&a5fh0Vx&%nBeVBPD~S zX9~8OWQ{I*D&6xr8&?%73^gY6c&--W26X@hT`sg?wmgyPm~*U{l)G%xB{So>D&hv) zFhB%f4{j;48JB&Zf*k{TFgd568zPBIL|O3v5irkOq^JDTkQfCwGhS&>ZNw0lh!)ZD zBL^f;`=kBPSj&?#X2VtP`-r5A*d*~om(-2##Jrd z$VQ|PP`*g5o3;|q)kP#`r!iS}zBu2O39Fu;Yl7Foe8v=C^WRn+-zZDL_cELMl(xgR zZEfZ(V7Rd#Y}ikyr=RyC=*~u9n3$xtPx(Sj(+xP@DY%K;Sj;g}$?cWhiTJRr;xDh9 zZISoEag%IRC2{&vj|VDjAVKVKBi|&Q2yHlkEeMPW;Gu;KBPB}8p^`4{!#&Pv8 z2u}_PleEA%K9aQ^Zt78n&msV;5_)LE+Dhh zpph#*4dD# P00000NkvXXu0mjfMxV>? literal 0 HcmV?d00001 diff --git a/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined 2.png b/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined 2.png new file mode 100644 index 0000000000000000000000000000000000000000..fe4d797e9265a936623c179cccfc0e2fdf7bb112 GIT binary patch literal 4198 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 R=HEww&dS`z3=ctI{s-7P;{pHx literal 0 HcmV?d00001 diff --git a/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined.png b/iOS/traveline/Resources/Images.xcassets/Common/empty.imageset/Glyph_ undefined.png new file mode 100644 index 0000000000000000000000000000000000000000..5f36c0db6dea278b7cc0d4d641bd1cee57a601a9 GIT binary patch literal 1431 zcmV;I1!($-P)1FgQ*(#<_z z3t9?655>=ZzsAz8YKL0DPD}d!RKCxMX1E++W))^S^o}}-gvK>U& zMHaGkadIV&Fw!YS0@sZ;UZSnCj?knj0N#XIX6Y%}`Q%!BpuYsPHFJ^Hee;5s(ptQg z)1II&<}*!pMti{GRL(F{AI)db-sjNXpX z^ca19sOqy*OW(iAJB-m@usIoOucG7ct^1KaB35;DXp&VO%P81_!#6+B=P&GKL7gLK z8P`LM?%23Z$lQnjQRo3pihGbAyUIBUV+kHwk5UQ%oN*UceZ0h$Rpt4e@_rb=px2s- z7E-ItLsuauVJS;9nuc!ZEPLqiOI*(J|E^Ac8C-_TiXNTg|0q;`bsy8>-r}%9l>=ZS zvqFT;uF-*%a<@##H<%!zU8ohs8Zs^>5kglJCqzeN?{%}B{-I@?5UA6qS99U6HS zuoRU)VM|dZZ8^bX!alcGDch=T>8JH5p?@EVdE?-q;M|t558l91$<0Hd_TfsS!G;ly zSfQRt$hQo(n6!6v;OnQ-NKOAWb8r=M&TwHkupt1i!Vv|a2)*E!Xghr9`>jcq@1^BS z+Xm&Cfj5Q+dE3FG_2VHT0>8+za<;{t7%YDWSW%g6s9?s}A5ATyb;9;68Az4AoY7Cw z&z)~NKz;~$n?5PeeyTi_5+o9Jh~fZHq$Mp#HdJ=GvvATjSw<8~i#w{ln^zPFtb&^u zGrOtZr;v`%@_~G%6+%j$;Db1p_!O6CRNV{C^WYqhdB`bAr&O@`Bz1b?v8nn>Ib!(R z_+rVyGim@P-{<6(ESFadUP?NlrHM}&abwOONs4>a_oA*IU&36md1P!HkZub`RzMC< zjqVqD=#?XO9FXP)X-{}UmeeHFE@y_9(gJC=c1ms=Zg3x@U1T{%eeCHx2-=olRQw<- z)xlR;v;jw6Nw7`{BCO<@Bkp#72NX}J_6}^9wef-~QY}IhUeG>V*sE5Ul2L3AQLrtq zBviWxXYuF;j<6-LT$>K}gyNxOcCyS)u9~G~E?u7=6!8e$i+nfkR znX30$p)lFL#*uNCypmRIY3{IVX_=OgZY>q2@0fIE?W4_|YM->LE;V4g2EC(24;goF z Date: Fri, 12 Jan 2024 20:04:42 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat=20#384:=20TLEmptyView=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/DesignSystem/Common/TLImage.swift | 1 + .../Sources/DesignSystem/View/EmptyView.swift | 21 ---- .../DesignSystem/View/TLEmptyView.swift | 101 ++++++++++++++++++ 3 files changed, 102 insertions(+), 21 deletions(-) delete mode 100644 iOS/traveline/Sources/DesignSystem/View/EmptyView.swift create mode 100644 iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift diff --git a/iOS/traveline/Sources/DesignSystem/Common/TLImage.swift b/iOS/traveline/Sources/DesignSystem/Common/TLImage.swift index 5b52c10..8c7a0de 100644 --- a/iOS/traveline/Sources/DesignSystem/Common/TLImage.swift +++ b/iOS/traveline/Sources/DesignSystem/Common/TLImage.swift @@ -33,6 +33,7 @@ enum TLImage { static let close = TravelineAsset.Images.closeMedium.image static let logo = TravelineAsset.Images.travelineLogo.image static let`default` = TravelineAsset.Images.default.image + static let empty = TravelineAsset.Images.empty.image } enum Travel { diff --git a/iOS/traveline/Sources/DesignSystem/View/EmptyView.swift b/iOS/traveline/Sources/DesignSystem/View/EmptyView.swift deleted file mode 100644 index 89a3873..0000000 --- a/iOS/traveline/Sources/DesignSystem/View/EmptyView.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// EmptyView.swift -// traveline -// -// Created by KiWoong Hong on 2024/01/12. -// Copyright © 2024 traveline. All rights reserved. -// - -import UIKit - -class EmptyView: UIView { - - /* - // Only override draw() if you perform custom drawing. - // An empty implementation adversely affects performance during animation. - override func draw(_ rect: CGRect) { - // Drawing code - } - */ - -} diff --git a/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift b/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift new file mode 100644 index 0000000..9c5e316 --- /dev/null +++ b/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift @@ -0,0 +1,101 @@ +// +// TLEmptyView.swift +// traveline +// +// Created by KiWoong Hong on 2024/01/12. +// Copyright © 2024 traveline. All rights reserved. +// + +import UIKit + +class TLEmptyView: UIView { + + private enum Constants { + static let emptyText: String = "아직 작성된 글이 없어요!" + static let shareText: String = "나만의 여행 경험을 공유해보세요 :)" + } + + private enum Metric { + static let imageToLabelSpacing: CGFloat = 16 + static let labelToLabelSpacing: CGFloat = 12 + static let bottomConstants: CGFloat = UIScreen.main.bounds.width / 3 * 2 + } + + // MARK: - UI Components + + private let stackView: UIStackView = { + let view = UIStackView() + view.translatesAutoresizingMaskIntoConstraints = false + view.axis = .vertical + view.alignment = .center + view.distribution = .fill + + return view + }() + + private let imageView: UIImageView = { + let view = UIImageView(image: TLImage.Common.empty) + view.translatesAutoresizingMaskIntoConstraints = false + + return view + }() + + private let emptyLabel: TLLabel = { + let label = TLLabel(font: .subtitle2, color: TLColor.white) + label.setText(to: Constants.emptyText) + label.translatesAutoresizingMaskIntoConstraints = false + + return label + }() + + private let shareLabel: TLLabel = { + let label = TLLabel(font: .body2, color: TLColor.white) + label.setText(to: Constants.shareText) + label.translatesAutoresizingMaskIntoConstraints = false + + return label + }() + + // MARK: - initialize + + init() { + super.init(frame: .zero) + + setupAttributes() + setupLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +// MARK: - Setup Functions + +private extension TLEmptyView { + + func setupAttributes() { + backgroundColor = TLColor.black + } + + func setupLayout() { + addSubview(stackView) + stackView.addArrangedSubviews( + imageView, + emptyLabel, + shareLabel + ) + + NSLayoutConstraint.activate([ + stackView.topAnchor.constraint(equalTo: imageView.topAnchor), + stackView.leadingAnchor.constraint(equalTo: leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -Metric.bottomConstants) + ]) + + stackView.setCustomSpacing(Metric.imageToLabelSpacing, after: imageView) + stackView.setCustomSpacing(Metric.labelToLabelSpacing, after: emptyLabel) + } + +} From ea6c4cb9e94974685113845bc3628a3f4cb13da4 Mon Sep 17 00:00:00 2001 From: otoolz Date: Fri, 12 Jan 2024 20:13:13 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat=20#384:=20EmptyView=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift index b77df95..e25ed06 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift @@ -52,6 +52,8 @@ final class TimelineVC: UIViewController { return collectionView }() + private let emptyView: TLEmptyView = .init() + private let createPostingButton: TLFloatingButton = .init(style: .create) // MARK: - Properties @@ -145,6 +147,7 @@ final class TimelineVC: UIViewController { private extension TimelineVC { func setupAttributes() { view.backgroundColor = TLColor.black + timelineCollectionView.backgroundView = emptyView } func setupLayout() { @@ -199,6 +202,7 @@ private extension TimelineVC { .withUnretained(self) .sink { owner, cardlist in owner.setupData(list: cardlist) + owner.timelineCollectionView.backgroundView?.isHidden = !cardlist.isEmpty } .store(in: &cancellables) From 0e42acc7cf66abe35f5c0a0098ad52617db2a13d Mon Sep 17 00:00:00 2001 From: kth1210 Date: Sun, 14 Jan 2024 11:36:55 +0900 Subject: [PATCH 04/15] =?UTF-8?q?fix=20#383:=20=EC=88=98=EC=A0=95=20->=20?= =?UTF-8?q?=EC=B7=A8=EC=86=8C=20=EC=8B=9C=20=EB=8B=A4=EC=8B=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 화면 이동 시 isEdit을 초기화하는 코드 추가 --- .../TimelineDetailScene/VC/TimelineDetailVC.swift | 2 +- .../ViewModel/TimelineDetailViewModel.swift | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/VC/TimelineDetailVC.swift b/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/VC/TimelineDetailVC.swift index 15edcb0..990ddeb 100644 --- a/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/VC/TimelineDetailVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/VC/TimelineDetailVC.swift @@ -235,7 +235,6 @@ private extension TimelineDetailVC { viewModel.state .map(\.isEdit) .filter { $0 } - .removeDuplicates() .withUnretained(self) .sink { owner, _ in let timelineDetailInfo = owner.viewModel.currentState.timelineDetailInfo @@ -246,6 +245,7 @@ private extension TimelineDetailVC { timelineDetailInfo: timelineDetailInfo ) owner.navigationController?.pushViewController(timelineEditVC, animated: true) + owner.viewModel.sendAction(.movedToEdit) } .store(in: &cancellables) diff --git a/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/ViewModel/TimelineDetailViewModel.swift b/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/ViewModel/TimelineDetailViewModel.swift index 9f1902f..13ce77d 100644 --- a/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/ViewModel/TimelineDetailViewModel.swift +++ b/iOS/traveline/Sources/Feature/TimelineDetailFeature/TimelineDetailScene/ViewModel/TimelineDetailViewModel.swift @@ -14,6 +14,7 @@ enum TimelineDetailAction: BaseAction { case editTimeline case deleteTimeline case translateTimeline + case movedToEdit } enum TimelineDetailSideEffect: BaseSideEffect { @@ -34,6 +35,7 @@ enum TimelineDetailSideEffect: BaseSideEffect { case popToTimeline(Bool) case showTimelineDetailEditing case loadTimelineTranslatedInfo(TimelineTranslatedInfo) + case resetIsEditStatus } struct TimelineDetailState: BaseState { @@ -68,6 +70,9 @@ final class TimelineDetailViewModel: BaseViewModel Date: Sun, 14 Jan 2024 12:18:08 +0900 Subject: [PATCH 05/15] =?UTF-8?q?fix=20#383:=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EA=B0=80=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SelectImageButton에서 hasImage 프로퍼티의 업데이트 타이밍과 updateView 함수 호출의 타이밍이 맞지 않아 발생한 문제였음 --- .../VC/TimelineWritingVC.swift | 2 +- .../View/SelectImageButton.swift | 23 +++++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift index 8ee8ad6..a918176 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift @@ -165,7 +165,6 @@ final class TimelineWritingVC: UIViewController { @objc private func imageButtonCancelTapped() { selectImageButton.setImage(nil) viewModel.sendAction(.imageDidChange(nil)) - selectImageButton.updateView() } @objc private func locationButtonCancelTapped() { @@ -336,6 +335,7 @@ private extension TimelineWritingVC { viewModel.state .map(\.imageURLString) + .removeDuplicates() .withUnretained(self) .sink { owner, imageURLString in owner.selectImageButton.setImage(urlString: imageURLString) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/View/SelectImageButton.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/View/SelectImageButton.swift index 5b44f1d..547ade5 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/View/SelectImageButton.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/View/SelectImageButton.swift @@ -21,7 +21,7 @@ final class SelectImageButton: UIView { // MARK: - UI Components - let view: UIView = { + private let view: UIView = { let view = UIView() view.layer.cornerRadius = Metric.cornerRadius view.clipsToBounds = true @@ -41,7 +41,7 @@ final class SelectImageButton: UIView { let imageView: UIImageView = .init() - let selectView: UIStackView = { + private let selectView: UIStackView = { let view = UIStackView() view.axis = .vertical view.alignment = .center @@ -51,26 +51,19 @@ final class SelectImageButton: UIView { return view }() - let selectViewIcon: UIImageView = { + private let selectViewIcon: UIImageView = { let view = UIImageView(image: TLImage.Common.album) view.contentMode = .scaleAspectFit return view }() - let selectViewLabel: TLLabel = { + private let selectViewLabel: TLLabel = { let label = TLLabel(font: TLFont.body2, color: TLColor.white) label.textAlignment = .center return label }() - // MARK: - Properties - - private var hasImage: Bool { - imageView.image != nil - } - let width = Metric.viewWidth + Metric.buttonOffset - // MARK: - initialize init() { @@ -86,7 +79,7 @@ final class SelectImageButton: UIView { // MARK: - Functions - func updateView() { + private func updateView(hasImage: Bool) { selectView.isHidden = hasImage imageView.isHidden = !hasImage cancelButton.isHidden = !hasImage @@ -94,12 +87,12 @@ final class SelectImageButton: UIView { func setImage(_ image: UIImage?) { imageView.image = image - updateView() + updateView(hasImage: image != nil) } func setImage(urlString: String?, imagePath: String? = nil) { imageView.setImage(from: urlString, imagePath: imagePath) - updateView() + updateView(hasImage: urlString != nil) } } @@ -111,7 +104,7 @@ private extension SelectImageButton { func setupAttributes() { selectViewLabel.setText(to: "선택") view.backgroundColor = TLColor.backgroundGray - updateView() + updateView(hasImage: false) } func setupLayout() { From f8503c22f34edd71813cccc3847a3210f01402d4 Mon Sep 17 00:00:00 2001 From: kth1210 Date: Sun, 14 Jan 2024 13:41:27 +0900 Subject: [PATCH 06/15] =?UTF-8?q?fix=20#383:=20=EC=A7=80=EC=86=8D=EC=A0=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EC=83=98=ED=94=8C=EB=A7=81=EC=9D=B4=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=A0=81=EC=9A=A9=EB=90=98=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존의 이미지인지 확인하는 state 프로퍼티 추가 --- .../TimelineWritingScene/VC/TimelineWritingVC.swift | 5 ++++- .../ViewModel/TimelineWritingViewModel.swift | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift index a918176..18049a3 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift @@ -465,7 +465,10 @@ extension TimelineWritingVC: LocationSearchDelegate { extension TimelineWritingVC: TLNavigationBarDelegate { func rightButtonDidTapped() { if let selectedImage = selectImageButton.imageView.image { - let image = selectedImage.downSampling() + var image: UIImage? = selectedImage + if !viewModel.currentState.isOriginImage { + image = image?.downSampling() + } let imageData = image?.jpegData(compressionQuality: 1) viewModel.sendAction(.tapCompleteButton(imageData)) } else { diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift index d8184db..039474a 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift @@ -55,6 +55,7 @@ enum TimelineWritingSideEffect: BaseSideEffect { } struct TimelineWritingState: BaseState { + var isOriginImage: Bool = false var isCompletable: Bool = false var timelineDetailRequest: TimelineDetailRequest = .empty var popToTimeline: Bool = false @@ -190,6 +191,7 @@ final class TimelineWritingViewModel: BaseViewModel Date: Sun, 14 Jan 2024 13:55:17 +0900 Subject: [PATCH 07/15] =?UTF-8?q?fix=20#383:=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EB=B3=80=EA=B2=BD=ED=96=88=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EB=8B=A4=EC=9A=B4=EC=83=98=ED=94=8C=EB=A7=81=EC=9D=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이미지가 변경되었음을 알리는 action 추가 --- .../TimelineWritingScene/VC/TimelineWritingVC.swift | 10 +++++++--- .../ViewModel/TimelineWritingViewModel.swift | 12 ++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift index 18049a3..eb359fb 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift @@ -163,8 +163,7 @@ final class TimelineWritingVC: UIViewController { } @objc private func imageButtonCancelTapped() { - selectImageButton.setImage(nil) - viewModel.sendAction(.imageDidChange(nil)) + changeImage(to: nil) } @objc private func locationButtonCancelTapped() { @@ -172,6 +171,11 @@ final class TimelineWritingVC: UIViewController { viewModel.sendAction(.placeDidChange(.emtpy)) } + private func changeImage(to image: UIImage?) { + selectImageButton.setImage(image) + viewModel.sendAction(.imageDidChange) + } + private func actionKeyboardWillShow(_ keyboardFrame: CGRect) { self.scrollView.contentInset.bottom = keyboardFrame.size.height scrollView.scrollRectToVisible(textView.frame, animated: true) @@ -439,7 +443,7 @@ extension TimelineWritingVC: PHPickerViewControllerDelegate { guard let self = self else { return } DispatchQueue.main.async { guard let selectedImage = image as? UIImage else { return } - self.selectImageButton.setImage(selectedImage) + self.changeImage(to: selectedImage) } } diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift index 039474a..b15661a 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift @@ -17,7 +17,7 @@ enum TimelineWritingAction: BaseAction { case metaDataTime(String) case searchPlace(String) case placeDidChange(TimelinePlace) - case imageDidChange(Data?) + case imageDidChange case placeDidScrollToBottom case tapCompleteButton(Data?) case configTimelineDetailInfo(TimelineDetailInfo) @@ -43,7 +43,7 @@ enum TimelineWritingSideEffect: BaseSideEffect { case updateTitleState(String) case updateContentState(String) case updateTimeState(String) - case updateImageState(Data?) + case updateImageState case updatePlaceState(TimelinePlace) case updatePlaceKeyword(String) case fetchPlaceList(TimelinePlaceList) @@ -114,8 +114,8 @@ final class TimelineWritingViewModel: BaseViewModel Date: Sun, 14 Jan 2024 14:17:46 +0900 Subject: [PATCH 08/15] =?UTF-8?q?fix=20#383:=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EB=A7=8C=20=EB=B3=80=EA=B2=BD=EB=90=90=EC=9D=84=20=EC=8B=9C=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EB=B2=84=ED=8A=BC=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=98=84?= =?UTF-8?q?=EC=83=81=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/TimelineWritingViewModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift index b15661a..35815dc 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/ViewModel/TimelineWritingViewModel.swift @@ -188,6 +188,7 @@ final class TimelineWritingViewModel: BaseViewModel Date: Sun, 14 Jan 2024 22:58:34 +0900 Subject: [PATCH 09/15] =?UTF-8?q?add=20#384:=20=EA=B2=80=EC=83=89=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EC=9A=A9=20=EC=97=A0=ED=8B=B0=EB=B7=B0=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/errorCircle.imageset/Contents.json | 23 ++++++++++++++++++ .../Glyph_ undefined 1.png | Bin 0 -> 2696 bytes .../Glyph_ undefined 2.png | Bin 0 -> 4223 bytes .../errorCircle.imageset/Glyph_ undefined.png | Bin 0 -> 1509 bytes .../Sources/DesignSystem/Common/TLImage.swift | 1 + 5 files changed, 24 insertions(+) create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Contents.json create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Glyph_ undefined 1.png create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Glyph_ undefined 2.png create mode 100644 iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Glyph_ undefined.png diff --git a/iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Contents.json b/iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Contents.json new file mode 100644 index 0000000..b2a331d --- /dev/null +++ b/iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "Glyph_ undefined.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Glyph_ undefined 1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Glyph_ undefined 2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Glyph_ undefined 1.png b/iOS/traveline/Resources/Images.xcassets/Common/errorCircle.imageset/Glyph_ undefined 1.png new file mode 100644 index 0000000000000000000000000000000000000000..c63e2fcd26d82f3ba0e7d6d51e92f695c8b17793 GIT binary patch literal 2696 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 Date: Sun, 14 Jan 2024 23:07:34 +0900 Subject: [PATCH 10/15] =?UTF-8?q?chore=20#384:=20EmptyView=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DesignSystem/View/TLEmptyView.swift | 57 +++++++++++++++---- .../TimelineScene/VC/TimelineVC.swift | 2 +- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift b/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift index 9c5e316..bc73405 100644 --- a/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift +++ b/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift @@ -10,9 +10,36 @@ import UIKit class TLEmptyView: UIView { - private enum Constants { - static let emptyText: String = "아직 작성된 글이 없어요!" - static let shareText: String = "나만의 여행 경험을 공유해보세요 :)" + enum EmptyViewType { + case search + case timeline + + var image: UIImage { + switch self { + case .search: + return TLImage.Common.errorCircle + case .timeline: + return TLImage.Common.empty + } + } + + var firstText: String { + switch self { + case .search: + return "검색 결과가 없어요!" + case .timeline: + return "아직 작성된 글이 없어요!" + } + } + + var secondText: String { + switch self { + case .search: + return "다른 키워드로 검색해보세요 :)" + case .timeline: + return "나만의 여행 경험을 공유해보세요 :)" + } + } } private enum Metric { @@ -34,31 +61,34 @@ class TLEmptyView: UIView { }() private let imageView: UIImageView = { - let view = UIImageView(image: TLImage.Common.empty) + let view = UIImageView() view.translatesAutoresizingMaskIntoConstraints = false return view }() - private let emptyLabel: TLLabel = { + private let firstLabel: TLLabel = { let label = TLLabel(font: .subtitle2, color: TLColor.white) - label.setText(to: Constants.emptyText) label.translatesAutoresizingMaskIntoConstraints = false return label }() - private let shareLabel: TLLabel = { + private let secondLabel: TLLabel = { let label = TLLabel(font: .body2, color: TLColor.white) - label.setText(to: Constants.shareText) label.translatesAutoresizingMaskIntoConstraints = false return label }() + // MARK: - properties + + private let emptyViewType: EmptyViewType + // MARK: - initialize - init() { + init(type: EmptyViewType) { + self.emptyViewType = type super.init(frame: .zero) setupAttributes() @@ -77,14 +107,17 @@ private extension TLEmptyView { func setupAttributes() { backgroundColor = TLColor.black + imageView.image = emptyViewType.image + firstLabel.setText(to: emptyViewType.firstText) + secondLabel.setText(to: emptyViewType.secondText) } func setupLayout() { addSubview(stackView) stackView.addArrangedSubviews( imageView, - emptyLabel, - shareLabel + firstLabel, + secondLabel ) NSLayoutConstraint.activate([ @@ -95,7 +128,7 @@ private extension TLEmptyView { ]) stackView.setCustomSpacing(Metric.imageToLabelSpacing, after: imageView) - stackView.setCustomSpacing(Metric.labelToLabelSpacing, after: emptyLabel) + stackView.setCustomSpacing(Metric.labelToLabelSpacing, after: firstLabel) } } diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift index e25ed06..85b3590 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift @@ -52,7 +52,7 @@ final class TimelineVC: UIViewController { return collectionView }() - private let emptyView: TLEmptyView = .init() + private let emptyView: TLEmptyView = .init(type: .timeline) private let createPostingButton: TLFloatingButton = .init(style: .create) From e08014b79136fae1fb6681c152a400bee05113e3 Mon Sep 17 00:00:00 2001 From: otoolz Date: Mon, 15 Jan 2024 06:03:43 +0900 Subject: [PATCH 11/15] =?UTF-8?q?feat=20#384:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=97=A0=ED=8B=B0=EB=B7=B0=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomeFeature/HomeScene/VC/HomeVC.swift | 5 +++++ .../HomeScene/View/HomeListView.swift | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift index 6e9dcf9..b8527c3 100644 --- a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift +++ b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift @@ -161,6 +161,11 @@ private extension HomeVC { .withUnretained(self) .sink { owner, list in owner.homeListView.setupData(list: list) + if list.isEmpty { + owner.homeListView.showEmptyView() + } else { + owner.homeListView.hideEmptyView() + } } .store(in: &cancellables) diff --git a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/View/HomeListView.swift b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/View/HomeListView.swift index 0cd7e35..849462f 100644 --- a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/View/HomeListView.swift +++ b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/View/HomeListView.swift @@ -66,6 +66,8 @@ final class HomeListView: UIView { return refresh }() + private let emptyView: TLEmptyView = .init(type: .search) + // MARK: - Properties private typealias DataSource = UICollectionViewDiffableDataSource @@ -94,6 +96,7 @@ final class HomeListView: UIView { setupLayout() setupDataSource() + setupAttributes() setupSnapshot() } @@ -224,6 +227,14 @@ final class HomeListView: UIView { } } + func hideEmptyView() { + homeCollectionView.backgroundView?.isHidden = true + } + + func showEmptyView() { + homeCollectionView.backgroundView?.isHidden = false + } + @objc private func refreshList() { didRefreshHomeList.send(Void()) } @@ -232,6 +243,11 @@ final class HomeListView: UIView { // MARK: - Setup Functions extension HomeListView { + private func setupAttributes() { + homeCollectionView.backgroundView = emptyView + homeCollectionView.backgroundView?.isHidden = true + } + private func setupLayout() { addSubviews(homeCollectionView) From 8c4bfc56a97f6ddff2baaa69973f038ac34da368 Mon Sep 17 00:00:00 2001 From: otoolz Date: Tue, 16 Jan 2024 00:35:40 +0900 Subject: [PATCH 12/15] =?UTF-8?q?chore=20#384:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=8B=9C=20=EC=97=A0=ED=8B=B0=EB=B7=B0=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/DesignSystem/View/TLEmptyView.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift b/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift index bc73405..65dac97 100644 --- a/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift +++ b/iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift @@ -40,12 +40,20 @@ class TLEmptyView: UIView { return "나만의 여행 경험을 공유해보세요 :)" } } + + var bottomConstants: CGFloat { + switch self { + case .search: + return UIScreen.main.bounds.width + case .timeline: + return UIScreen.main.bounds.width / 3 * 2 + } + } } private enum Metric { static let imageToLabelSpacing: CGFloat = 16 static let labelToLabelSpacing: CGFloat = 12 - static let bottomConstants: CGFloat = UIScreen.main.bounds.width / 3 * 2 } // MARK: - UI Components @@ -124,7 +132,7 @@ private extension TLEmptyView { stackView.topAnchor.constraint(equalTo: imageView.topAnchor), stackView.leadingAnchor.constraint(equalTo: leadingAnchor), stackView.trailingAnchor.constraint(equalTo: trailingAnchor), - stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -Metric.bottomConstants) + stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -emptyViewType.bottomConstants) ]) stackView.setCustomSpacing(Metric.imageToLabelSpacing, after: imageView) From d82b7fd7ca21878660c8965be16224059b00fe3e Mon Sep 17 00:00:00 2001 From: kth1210 Date: Tue, 16 Jan 2024 01:14:01 +0900 Subject: [PATCH 13/15] =?UTF-8?q?chore=20#383:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20-=20=EC=82=BC=ED=95=AD=20=EC=97=B0?= =?UTF-8?q?=EC=82=B0=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TimelineWritingScene/VC/TimelineWritingVC.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift index eb359fb..0d56b06 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineWritingScene/VC/TimelineWritingVC.swift @@ -469,10 +469,7 @@ extension TimelineWritingVC: LocationSearchDelegate { extension TimelineWritingVC: TLNavigationBarDelegate { func rightButtonDidTapped() { if let selectedImage = selectImageButton.imageView.image { - var image: UIImage? = selectedImage - if !viewModel.currentState.isOriginImage { - image = image?.downSampling() - } + let image = viewModel.currentState.isOriginImage ? selectedImage : selectedImage.downSampling() let imageData = image?.jpegData(compressionQuality: 1) viewModel.sendAction(.tapCompleteButton(imageData)) } else { From afec52015aef35f23880b940519ad4000438de1f Mon Sep 17 00:00:00 2001 From: otoolz Date: Tue, 16 Jan 2024 02:09:44 +0900 Subject: [PATCH 14/15] =?UTF-8?q?chore=20#384:=20loading=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20=ED=9B=84=20=EC=97=A0=ED=8B=B0=20=EB=B7=B0=20?= =?UTF-8?q?=EB=9C=A8=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 --- .../TimelineFeature/TimelineScene/VC/TimelineVC.swift | 10 +++++++++- .../TimelineScene/ViewModel/TimelineViewModel.swift | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift index 85b3590..49a258c 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/VC/TimelineVC.swift @@ -148,6 +148,7 @@ private extension TimelineVC { func setupAttributes() { view.backgroundColor = TLColor.black timelineCollectionView.backgroundView = emptyView + timelineCollectionView.backgroundView?.isHidden = true } func setupLayout() { @@ -202,7 +203,6 @@ private extension TimelineVC { .withUnretained(self) .sink { owner, cardlist in owner.setupData(list: cardlist) - owner.timelineCollectionView.backgroundView?.isHidden = !cardlist.isEmpty } .store(in: &cancellables) @@ -249,6 +249,14 @@ private extension TimelineVC { owner.navigationController?.popViewController(animated: true) } .store(in: &cancellables) + + viewModel.state + .map(\.isEmptyList) + .withUnretained(self) + .sink { owner, isEmptyList in + owner.timelineCollectionView.backgroundView?.isHidden = !isEmptyList + } + .store(in: &cancellables) } } diff --git a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/ViewModel/TimelineViewModel.swift b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/ViewModel/TimelineViewModel.swift index 1bab99b..bc7bf70 100644 --- a/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/ViewModel/TimelineViewModel.swift +++ b/iOS/traveline/Sources/Feature/TimelineFeature/TimelineScene/ViewModel/TimelineViewModel.swift @@ -68,6 +68,7 @@ struct TimelineState: BaseState { var isEdit: Bool = false var deleteCompleted: Bool = false var errorMsg: String? + var isEmptyList: Bool = false } final class TimelineViewModel: BaseViewModel { @@ -141,6 +142,7 @@ final class TimelineViewModel: BaseViewModel Date: Tue, 16 Jan 2024 02:36:15 +0900 Subject: [PATCH 15/15] =?UTF-8?q?chore=20#384:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=97=A0=ED=8B=B0=EB=B7=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=A3=BC=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomeFeature/HomeScene/VC/HomeVC.swift | 19 +++++++++++++------ .../HomeScene/ViewModel/HomeState.swift | 1 + .../HomeScene/ViewModel/HomeViewModel.swift | 3 +++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift index b8527c3..2cb3895 100644 --- a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift +++ b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/VC/HomeVC.swift @@ -113,6 +113,7 @@ private extension HomeVC { self.navigationItem.backBarButtonItem = backBarButtonItem homeSearchView.isHidden = true + homeListView.hideEmptyView() } func setupLayout() { @@ -156,16 +157,10 @@ private extension HomeVC { viewModel.state .map(\.travelList) - .dropFirst() .removeDuplicates() .withUnretained(self) .sink { owner, list in owner.homeListView.setupData(list: list) - if list.isEmpty { - owner.homeListView.showEmptyView() - } else { - owner.homeListView.hideEmptyView() - } } .store(in: &cancellables) @@ -254,6 +249,18 @@ private extension HomeVC { owner.navigationController?.pushViewController(travelVC, animated: true) } .store(in: &cancellables) + + viewModel.state + .map(\.isEmptyResult) + .withUnretained(self) + .sink { owner, isEmpty in + if isEmpty { + owner.homeListView.showEmptyView() + } else { + owner.homeListView.hideEmptyView() + } + } + .store(in: &cancellables) } func bindListView() { diff --git a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeState.swift b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeState.swift index f890b40..7f46da4 100644 --- a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeState.swift +++ b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeState.swift @@ -27,6 +27,7 @@ struct HomeState: BaseState { var resultFilters: FilterDictionary = .make() var curFilter: Filter? = .emtpy var moveToTravelWriting: Bool = false + var isEmptyResult: Bool = false var isSearching: Bool { homeViewType == .recent || homeViewType == .related diff --git a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeViewModel.swift b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeViewModel.swift index 6851543..853f57d 100644 --- a/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeViewModel.swift +++ b/iOS/traveline/Sources/Feature/HomeFeature/HomeScene/ViewModel/HomeViewModel.swift @@ -90,6 +90,7 @@ final class HomeViewModel: BaseViewModel newState.travelList = searchResult.travelList newState.homeViewType = .result newState.resultFilters = .make() + newState.isEmptyResult = searchResult.travelList.isEmpty newState.searchQuery = .init( keyword: searchResult.keyword, offset: 2 @@ -99,10 +100,12 @@ final class HomeViewModel: BaseViewModel newState.travelList = travelList newState.searchQuery.offset = 2 newState.searchQuery.keyword = nil + newState.isEmptyResult = travelList.isEmpty case let .showNewList(travelList): newState.travelList = travelList newState.searchQuery.offset = 2 + newState.isEmptyResult = travelList.isEmpty case let .showFilter(type): newState.curFilter = (state.homeViewType == .home) ? state.homeFilters[type] : state.resultFilters[type]