Skip to content

Commit

Permalink
merge #393: emptyView μž‘μ„±
Browse files Browse the repository at this point in the history
[feat] emptyView μž‘μ„±
  • Loading branch information
otoolz authored Jan 16, 2024
2 parents 94b9b7a + 7480120 commit 7d57f44
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions iOS/traveline/Sources/DesignSystem/Common/TLImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ 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
static let errorCircle = TravelineAsset.Images.errorCircle.image
}

enum Travel {
Expand Down
142 changes: 142 additions & 0 deletions iOS/traveline/Sources/DesignSystem/View/TLEmptyView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// TLEmptyView.swift
// traveline
//
// Created by KiWoong Hong on 2024/01/12.
// Copyright Β© 2024 traveline. All rights reserved.
//

import UIKit

class TLEmptyView: UIView {

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 "λ‚˜λ§Œμ˜ μ—¬ν–‰ κ²½ν—˜μ„ κ³΅μœ ν•΄λ³΄μ„Έμš” :)"
}
}

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
}

// 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()
view.translatesAutoresizingMaskIntoConstraints = false

return view
}()

private let firstLabel: TLLabel = {
let label = TLLabel(font: .subtitle2, color: TLColor.white)
label.translatesAutoresizingMaskIntoConstraints = false

return label
}()

private let secondLabel: TLLabel = {
let label = TLLabel(font: .body2, color: TLColor.white)
label.translatesAutoresizingMaskIntoConstraints = false

return label
}()

// MARK: - properties

private let emptyViewType: EmptyViewType

// MARK: - initialize

init(type: EmptyViewType) {
self.emptyViewType = type
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
imageView.image = emptyViewType.image
firstLabel.setText(to: emptyViewType.firstText)
secondLabel.setText(to: emptyViewType.secondText)
}

func setupLayout() {
addSubview(stackView)
stackView.addArrangedSubviews(
imageView,
firstLabel,
secondLabel
)

NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: imageView.topAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -emptyViewType.bottomConstants)
])

stackView.setCustomSpacing(Metric.imageToLabelSpacing, after: imageView)
stackView.setCustomSpacing(Metric.labelToLabelSpacing, after: firstLabel)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ private extension HomeVC {
self.navigationItem.backBarButtonItem = backBarButtonItem

homeSearchView.isHidden = true
homeListView.hideEmptyView()
}

func setupLayout() {
Expand Down Expand Up @@ -156,7 +157,6 @@ private extension HomeVC {

viewModel.state
.map(\.travelList)
.dropFirst()
.removeDuplicates()
.withUnretained(self)
.sink { owner, list in
Expand Down Expand Up @@ -249,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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ final class HomeListView: UIView {
return refresh
}()

private let emptyView: TLEmptyView = .init(type: .search)

// MARK: - Properties

private typealias DataSource = UICollectionViewDiffableDataSource<HomeSection, HomeItem>
Expand Down Expand Up @@ -94,6 +96,7 @@ final class HomeListView: UIView {

setupLayout()
setupDataSource()
setupAttributes()
setupSnapshot()
}

Expand Down Expand Up @@ -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())
}
Expand All @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ final class HomeViewModel: BaseViewModel<HomeAction, HomeSideEffect, HomeState>
newState.travelList = searchResult.travelList
newState.homeViewType = .result
newState.resultFilters = .make()
newState.isEmptyResult = searchResult.travelList.isEmpty
newState.searchQuery = .init(
keyword: searchResult.keyword,
offset: 2
Expand All @@ -99,10 +100,12 @@ final class HomeViewModel: BaseViewModel<HomeAction, HomeSideEffect, HomeState>
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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ final class TimelineVC: UIViewController {
return collectionView
}()

private let emptyView: TLEmptyView = .init(type: .timeline)

private let createPostingButton: TLFloatingButton = .init(style: .create)

// MARK: - Properties
Expand Down Expand Up @@ -145,6 +147,8 @@ final class TimelineVC: UIViewController {
private extension TimelineVC {
func setupAttributes() {
view.backgroundColor = TLColor.black
timelineCollectionView.backgroundView = emptyView
timelineCollectionView.backgroundView?.isHidden = true
}

func setupLayout() {
Expand Down Expand Up @@ -245,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)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TimelineAction, TimelineSideEffect, TimelineState> {
Expand Down Expand Up @@ -141,6 +142,7 @@ final class TimelineViewModel: BaseViewModel<TimelineAction, TimelineSideEffect,

case let .loadTimelineCardList(timelineCardList):
newState.timelineCardList = timelineCardList
newState.isEmptyList = timelineCardList.isEmpty

case let .removeRegacyCards(day):
newState.day = day
Expand Down

0 comments on commit 7d57f44

Please sign in to comment.