Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions Projects/App/Sources/Navigation/Class/ClassCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import TCAFlow

@FlowCoordinator(screen: "ClassScreen", navigation: true)
public struct ClassCoordinator {
@Dependency(\.classMemberUseCase) private var classMemberUseCase
@Dependency(\.classUseCase) private var classUseCase
@Dependency(\.uuid) private var uuid
@Dependency(\.date) private var date
Expand Down Expand Up @@ -365,9 +364,9 @@ private extension ClassCoordinator {
id: routeID,
action: .members(.loadingStarted(requestID))
)))
let fetch: Effect<Action> = .run { [classMemberUseCase] send in
let fetch: Effect<Action> = .run { [classUseCase] send in
do {
let memberList = try await classMemberUseCase.fetchMembers(classID: roomID)
let memberList = try await classUseCase.fetchMembers(classID: roomID)
await send(.inner(.membersLoaded(
routeID: routeID,
roomID: roomID,
Expand Down Expand Up @@ -835,10 +834,10 @@ private extension ClassCoordinator {
guard memberID != currentMemberID else {
return .send(.inner(.memberMutationFailed(roomID, "본인은 내보낼 수 없어요.")))
}
return .run { [classMemberUseCase, classUseCase] send in
return .run { [classUseCase] send in
do {
try await classMemberUseCase.removeMember(classID: roomID, memberID: memberID)
let memberList = try await classMemberUseCase.fetchMembers(classID: roomID)
try await classUseCase.removeMember(classID: roomID, memberID: memberID)
let memberList = try await classUseCase.fetchMembers(classID: roomID)
let room = try await classUseCase.fetchClass(id: roomID)
await send(.inner(.memberMutationCompleted(room, memberList.members)))
} catch {
Expand All @@ -858,10 +857,10 @@ private extension ClassCoordinator {
guard memberID == currentMemberID else {
return .send(.inner(.memberMutationFailed(roomID, "본인 이름만 바꿀 수 있어요.")))
}
return .run { [classMemberUseCase, classUseCase] send in
return .run { [classUseCase] send in
do {
_ = try await classMemberUseCase.updateMyDisplayName(classID: roomID, name: name)
let memberList = try await classMemberUseCase.fetchMembers(classID: roomID)
_ = try await classUseCase.updateMyDisplayName(classID: roomID, name: name)
let memberList = try await classUseCase.fetchMembers(classID: roomID)
let room = try await classUseCase.fetchClass(id: roomID)
await send(.inner(.memberMutationCompleted(room, memberList.members)))
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ public struct ClassCoordinatorView: View {
}
}
}
.toolbar(.hidden, for: .tabBar)
}
}

Expand Down
69 changes: 0 additions & 69 deletions Projects/App/Sources/Navigation/MainTab/MainTabBar.swift

This file was deleted.

17 changes: 2 additions & 15 deletions Projects/App/Sources/Navigation/MainTab/MainTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import TCAFlow

public struct MainTabView: View {
@Bindable private var store: StoreOf<MainTabCoordinator>
@State private var hasMeasuredKeyboard = false

public init(store: StoreOf<MainTabCoordinator>) {
PickeTabBarAppearance.configure()
Expand All @@ -24,29 +23,18 @@ public struct MainTabView: View {

public var body: some View {
ZStack {
tabLayout()
tabRouter

MainTabKeyboardObserver { isVisible in
if store.isKeyboardVisible != isVisible {
store.send(.keyboardVisibilityChanged(isVisible))
}
hasMeasuredKeyboard = true
}
}
}
}

private extension MainTabView {
@ViewBuilder
func tabLayout() -> some View {
VStack(spacing: 0) {
tabRouter
if hasMeasuredKeyboard, !store.shouldHideTabBar {
MainTabBar(store: store)
}
}
}

var tabRouter: some View {
TCAFlowTabRouter(
selectedTab: $store.selectedTab.sending(\.selectTab),
Expand All @@ -65,10 +53,9 @@ private extension MainTabView {
}
) {
tabContent(for: $0)
.toolbar(.hidden, for: .tabBar)
.toolbar(store.shouldHideTabBar ? .hidden : .visible, for: .tabBar)
}
.tint(.neutral900)
.toolbar(.hidden, for: .tabBar)
}

@ViewBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ public struct ClassCreation: Equatable, Sendable {
public var allowsAnonymousOpinion: Bool
public var requiresComment: Bool
public var ownerParticipates: Bool
public var ownerDisplayName: String?

public init(
name: String,
deadline: Date,
battleId: Int,
allowsAnonymousOpinion: Bool,
requiresComment: Bool,
ownerParticipates: Bool = false
ownerParticipates: Bool = false,
ownerDisplayName: String? = nil
) {
self.name = name
self.deadline = deadline
Expand All @@ -31,6 +33,7 @@ public struct ClassCreation: Equatable, Sendable {
self.allowsAnonymousOpinion = allowsAnonymousOpinion
self.requiresComment = requiresComment
self.ownerParticipates = ownerParticipates
self.ownerDisplayName = ownerDisplayName
}

public init(
Expand All @@ -39,7 +42,8 @@ public struct ClassCreation: Equatable, Sendable {
topicVersionId: Int,
allowsAnonymousOpinion: Bool,
requiresComment: Bool,
ownerParticipates: Bool = false
ownerParticipates: Bool = false,
ownerDisplayName: String? = nil
) {
self.name = name
self.deadline = deadline
Expand All @@ -48,5 +52,6 @@ public struct ClassCreation: Equatable, Sendable {
self.allowsAnonymousOpinion = allowsAnonymousOpinion
self.requiresComment = requiresComment
self.ownerParticipates = ownerParticipates
self.ownerDisplayName = ownerDisplayName
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
//
// ClassBattleInterface.swift
// ClassDomainInterface
//
// Created by Picke on 10/26/26.
//

import ComposableArchitecture
import Foundation

public protocol ClassBattleInterface: Sendable {
func fetchBattle(classID: Int) async throws -> ClassBattleSession
func submitPreVote(
classID: Int,
optionID: Int
) async throws -> ClassVoteReceipt
func submitPreVote(classID: Int, optionID: Int) async throws -> ClassVoteReceipt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [P4] Readability

함수 인자 라벨이 한 줄로 정리되어 Swift API Design Guideline에 부합하게 변경되었습니다. 잘하셨습니다.

func completeTTS(classID: Int) async throws
func submitPostVote(
classID: Int,
optionID: Int
) async throws -> ClassVoteReceipt
func submitPostVote(classID: Int, optionID: Int) async throws -> ClassVoteReceipt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [P4] Readability

함수 인자 라벨이 한 줄로 정리되어 Swift API Design Guideline에 부합하게 변경되었습니다. 잘하셨습니다.

func fetchMyVotes(classID: Int) async throws -> ClassVoteHistory
func fetchVoteStats(classID: Int) async throws -> ClassVoteStats
func publishPerspective(
classID: Int,
content: String
) async throws -> ClassPerspectiveReceipt
func publishPerspective(classID: Int, content: String) async throws -> ClassPerspectiveReceipt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [P4] Readability

함수 인자 라벨이 한 줄로 정리되어 Swift API Design Guideline에 부합하게 변경되었습니다. 잘하셨습니다.

func fetchPerspectives(
classID: Int,
cursor: String?,
Expand All @@ -29,11 +27,15 @@ public protocol ClassBattleInterface: Sendable {
}

public enum ClassBattleRepositoryDependency: TestDependencyKey {
public static var testValue: any ClassBattleInterface { UnavailableClassBattleRepository() }
public static var testValue: any ClassBattleInterface {
MockClassRepository()
}
}

public enum ClassBattleUseCaseDependency: TestDependencyKey {
public static var testValue: any ClassBattleInterface { UnavailableClassBattleRepository() }
public static var testValue: any ClassBattleInterface {
MockClassRepository()
}
}

public extension DependencyValues {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,18 @@
//

import ComposableArchitecture
import Foundation

public protocol ClassInterface: Sendable {
func fetchMyClasses() async throws -> [ClassRoom]
func fetchRecommendedBattles(filter: ClassTopicFilter) async throws -> [ClassBattleSummary]
func createClass(_ creation: ClassCreation) async throws -> ClassRoom
func fetchClass(id: Int) async throws -> ClassRoom
func fetchClass(joinCode: String) async throws -> ClassRoom
func fetchClassPreview(joinCode: String) async throws -> ClassJoinPreview
func joinClass(joinCode: String, nickname: String) async throws -> ClassRoom
func updateDeadline(id: Int, deadline: Date) async throws -> ClassRoom
func deleteClass(id: Int) async throws
func leaveClass(id: Int) async throws
func fetchReport(roomID: Int) async throws -> ClassReport?
func fetchOwnerDashboard(roomID: Int) async throws -> ClassOwnerDashboardData?
}

public extension ClassInterface {
func fetchClassPreview(joinCode: String) async throws -> ClassJoinPreview {
let room = try await fetchClass(joinCode: joinCode)
return ClassJoinPreview(room: room)
}
}
public protocol ClassInterface:
ClassRoomInterface,
ClassRecommendationInterface,
ClassBattleInterface,
ClassMemberInterface,
ClassDebateInterface,
ClassTicketInterface,
ClassResultInterface,
ClassTopicDraftInterface,
ClassReportInterface,
ClassLocalAIInterface {}

public enum ClassRepositoryDependency: TestDependencyKey {
public static var testValue: any ClassInterface {
Expand Down
Loading
Loading