Skip to content

Commit

Permalink
feat(NewAnnouncement): Check has organization
Browse files Browse the repository at this point in the history
  • Loading branch information
dodo849 committed Aug 25, 2024
1 parent 919b4e7 commit 2bee2e9
Show file tree
Hide file tree
Showing 23 changed files with 156 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public struct ImageRepository: ImageRepositoryInterface {
body: .json(request)
)

let _ = try response.ok
let _ = try response.created

observer.onNext(())
observer.onCompleted()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public struct UploadImageUsecase {
.flatMap { output in
self.notifyImageUploadComplete(output: output)
}
.debug(":::")
}

// MARK: Private method
Expand All @@ -98,42 +99,53 @@ public struct UploadImageUsecase {
request.httpBody = imageData

return Observable.create { observer in
let task = URLSession.shared.dataTask(with: request) { data, response, error in
let task = URLSession.shared.dataTask(with: request) { _, response, error in
if let error = error {
observer.onError(error)
return
}

guard let httpResponse = response as? HTTPURLResponse else {
observer.onError(Error.imageMetaDataParseError)
return
}
guard 200..<300 ~= httpResponse.statusCode else {

guard 200 ..< 300 ~= httpResponse.statusCode else {
observer.onError(Error.imageMetaDataParseError)
return
}

observer.onNext(Output(url: uploadUrl))
observer.onCompleted()
}

task.resume()

return Disposables.create {
task.cancel()
}
}
}

private func notifyImageUploadComplete(output: Output) -> Observable<Output> {
// Extract URL without query string
guard let url = output.url,
let urlWithoutQuery = urlWithoutQuery(url: url)
else { return .error(Error.imageMetaDataParseError) }

return imageRepository.notifyImageUploadComplete(
.init(fileName: output.url?.absoluteString)
).map {
.init(fileName: urlWithoutQuery.absoluteString)
).map { _ in
output
}
}

private func urlWithoutQuery(url: URL) -> URL? {
var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
urlComponents?.query = nil
return urlComponents?.url
}

private func extractImageNameAndExtension(from url: URL) -> (name: String, extension: String)? {
let fileName = url.lastPathComponent
let fileExtension = url.pathExtension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public struct NewOrganizationEntity: Equatable {
public let categories: [Int]

/// URL of the image associated with the organization (optional).
public let imageURL: String?
public let imageURL: URL?

/// End date of the group's activities (optional).
public let endDate: Date?
Expand All @@ -29,7 +29,7 @@ public struct NewOrganizationEntity: Equatable {
public init(
name: String,
categories: [Int],
imageURL: String?,
imageURL: URL?,
endDate: Date?,
promotionCode: String?
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// OrganizationRole.swift
// OrganizationEntity
//
// Created by DOYEON LEE on 8/25/24.
//

public enum OrganizationRole: String, CaseIterable {
case leader
case member
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ public struct OrganizationSummaryEntity: Identifiable, Equatable {
/// Profile image url of the organization.
public let profileImageUrl: URL?

/// Role of the user in the organization
public let role: OrganizationRole

public init(
id: Int64,
name: String,
profileImageUrl: URL? = nil
profileImageUrl: URL?,
role: OrganizationRole
) {
self.id = id
self.name = name
self.profileImageUrl = profileImageUrl
self.role = role
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public struct CreateOrganizationUsecase {
body: .init(
name: newOrganization.name,
categoryList: newOrganization.categories.map { Int64($0) },
profileImage: newOrganization.imageURL,
profileImage: newOrganization.imageURL?.absoluteString,
endAt: newOrganization.endDate,
promotionCode: .init(promotionCode: newOrganization.promotionCode)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// GetMyOrganizationsUsecase.swift
// GetJoinedOrganizationsUsecase.swift
// OrganizationUsecase
//
// Created by DOYEON LEE on 7/22/24.
Expand All @@ -15,7 +15,7 @@ import UserDefaultsUtility
import Swinject
import RxSwift

public class GetMyOrganizationsUsecase {
public class GetJoinedOrganizationsUsecase {
// MARK: DTO
public struct Input {
public init() { }
Expand Down Expand Up @@ -56,7 +56,10 @@ public class GetMyOrganizationsUsecase {
OrganizationSummaryEntity(
id: $0.organizationId,
name: $0.organizationName,
profileImageUrl: URL(string: $0.profileImage)
profileImageUrl: URL(
string: $0.profileImage
),
role: $0.role == .LEADER ? .leader : .member
)
} ?? []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,12 @@ class AnnouncementPageReactor: Reactor {
enum Mutation {
case setOrganizations([AnnouncementOrganizationEntity])
case setMember(MemberEntity)
case toggleisOpenHasLeaderRoleOrganizationDialog
}

struct State {
// - Data
var organizations: [AnnouncementOrganizationEntity] = []
var member: MemberEntity?

// - View TODO: ㅠㅠ 어떻게하지 변수명 머선일
var isOpenHasLeaderRoleOrganizationDialog: Bool = false
}

// MARK: Dependency
Expand Down Expand Up @@ -70,9 +66,6 @@ class AnnouncementPageReactor: Reactor {

case let .setMember(member):
state.member = member

case .toggleisOpenHasLeaderRoleOrganizationDialog:
state.isOpenHasLeaderRoleOrganizationDialog
}
return state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,6 @@ class AnnouncementPageView: BaseView {
// MARK: UI Component
// - Announcement collection view
lazy var collectionView = CompositionalCollectionView()

// - Has leader role organization dialog
lazy var hasLeaderRoleOrganizationDialog = BaseDialog(
contentsBuilder: {
[
UILabel().then {
$0.text = "참여한 그룹이 없어요"
}
]
}
).then {
$0.styled()
}

// MARK: Setup
override func setupHierarchy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class AnnouncementPageViewController: BaseViewController<AnnouncementPageView> {
.init(
id: Int64(organization.id),
name: organization.name,
profileImageUrl: organization.profileImageUrl
profileImageUrl: organization.profileImageUrl,
role: .leader // FIXME: 롤 정보 필요
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ public class MypageView: BaseView {
[
BaseVStack(spacing: 18) {
let menus = [
("앱 버전", "1.0.0")
("앱 버전", "1.0.0"),
("문의하기", "do83430208@gmail.com"),
// TODO: v1.1.0 추가 예정
// ("문의하기", nil),
// ("공지사항", nil),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,43 @@

import Foundation

import Router
import AnnouncementUsecase
import AnnouncementEntity
import AnnouncementUsecase
import OrganizationUsecase
import Router

import ReactorKit
import ProgressHUD

class NewAnnouncementFunnelReactor: Reactor {
// MARK: Action
enum Action {
case viewDidLoad
case moveNextPage
case movePreviousPage
}

enum Mutation {
case setCurrentPage(NewAnnouncementFunnelPage)
case toggleisOpenHasLeaderRoleOrganizationDialog
}

// MARK: State
struct State {
var currentPage: NewAnnouncementFunnelPage = .selectOrganization

// - View TODO: ㅠㅠ 어떻게하지 변수명 머선일
var isOpenHasLeaderRoleOrganizationDialog: Bool = false
}

let initialState: State = State()

// MARK: Dependency
private let createAnnouncementUsecase = CreateAnnouncementUsecase()

// FIXME: 호출 최소화를 위한 고민 필요 (자식 리액토에서도 한번 호출함)
private let getJoinedOrganizationsUsecase = GetJoinedOrganizationsUsecase()

// MARK: Child Reactor
private let selectOrganizationReactor: SelectOrganizationPageReactor

Expand Down Expand Up @@ -73,10 +83,25 @@ class NewAnnouncementFunnelReactor: Reactor {
// MARK: Action operation
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .viewDidLoad:
ProgressHUD.animate(nil, .horizontalDotScaling, interaction: false)

// TODO: 리더롤인지 확인하고 넣어야함
let leaderRoleObservable = getJoinedOrganizationsUsecase
.execute(.init())
.compactMap {
$0.organizations.isEmpty ? nil : ()
}
.map {
return Mutation.toggleisOpenHasLeaderRoleOrganizationDialog
}

return leaderRoleObservable

case .moveNextPage:
let nextPage = nextPage(after: currentState.currentPage)
return Observable.just(.setCurrentPage(nextPage))

case .movePreviousPage:
let previousPage = previousPage(before: currentState.currentPage)
return Observable.just(.setCurrentPage(previousPage))
Expand All @@ -88,6 +113,9 @@ class NewAnnouncementFunnelReactor: Reactor {
switch mutation {
case .setCurrentPage(let page):
state.currentPage = page

case .toggleisOpenHasLeaderRoleOrganizationDialog:
state.isOpenHasLeaderRoleOrganizationDialog.toggle()
}
return state
}
Expand Down Expand Up @@ -128,9 +156,19 @@ class NewAnnouncementFunnelReactor: Reactor {
notifications: Array(editNotificationReactor.currentState.selectedTimeOptions)
)

ProgressHUD.animate(
nil,
.horizontalDotScaling,
interaction: false
)

return self.createAnnouncementUsecase
.execute(.init(newAnnouncement: newAnnouncement))
.map { _ in return Void() }
.map { _ in
ProgressHUD.dismiss()

return Void()
}

default:
return .empty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ public class NewAnnouncementFunnelView: BaseView {
$0.gestureScrollEnabled = false
}

// - Has leader role organization dialog
lazy var hasLeaderRoleOrganizationDialog = BaseDialog(
contentsBuilder: {
[
UILabel().then {
$0.text = "참여한 그룹이 없어요"
}
]
}
).then {
$0.styled()
}

// MARK: Setup
public override func setupHierarchy() {
addSubview(navigationBar)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ public class NewAnnouncementFunnelViewController: BaseViewController<NewAnnounce
owner.paginableView.currentPage = page
})
.disposed(by: self.disposeBag)

reactor.state.map { $0.isOpenHasLeaderRoleOrganizationDialog }
.withUnretained(self.baseView)
.subscribe(onNext: { owner, isOpen in
if isOpen {
owner.hasLeaderRoleOrganizationDialog.open()
} else {
owner.hasLeaderRoleOrganizationDialog.close()
}
})
.disposed(by: self.disposeBag)
}

public override func setupActionBind() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SelectOrganizationPageReactor: Reactor {
let initialState: State = State()

// MARK: Dependency
private let fetchMyOrganizations = GetMyOrganizationsUsecase()
private let fetchMyOrganizations = GetJoinedOrganizationsUsecase()

// MARK: DisposeBag
private let disposeBag = DisposeBag()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class NewOrganizationFunnelReactor: Reactor {
let newOrganization = NewOrganizationEntity(
name: self.nameReactor.currentState.name,
categories: self.categoryReactor.currentState.selectedCateogries.map { $0.id },
imageURL: "", // TODO: 추가 필요
imageURL: self.imageReactor.currentState.uploadedUrl,
endDate: self.endDateReactor.currentState.selectedDate,
promotionCode: self.promotionReactor.currentState.promotionCode
)
Expand Down
Loading

0 comments on commit 2bee2e9

Please sign in to comment.