Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/#316] 추천 보틀 웹뷰 액션 핸들링 #317

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public extension ModulePath {
// MARK: - FeatureModule
public extension ModulePath {
enum Feature: String, CaseIterable {
case GoodFeeling
case Guide
case TabBar
case Report
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public enum BottleWebViewAction: Equatable {
/// 회원가입 성공 콜백
case signUpDidComplted(accessToken: String, refreshToken: String)
/// 외부 링크 이동
case openLink(href: String)
case openLink(url: String)

// MARK: - LogIn

Expand Down Expand Up @@ -53,7 +53,7 @@ public enum BottleWebViewAction: Equatable {
message: String? = nil,
accessToken: String? = nil,
refreshToken: String? = nil,
href: String? = nil,
url: String? = nil,
isCompletedOnboardingIntroduction: Bool? = nil
) {
switch type {
Expand Down Expand Up @@ -94,14 +94,14 @@ public enum BottleWebViewAction: Equatable {
refreshToken: refreshToken
)
case "openLink":
guard let href
guard let url
else {
Log.assertion(
message: "openLink: \(String(describing: href))"
message: "openLink: \(String(describing: url))"
)
return nil
}
self = .openLink(href: href)
self = .openLink(url: url)



Expand Down
2 changes: 1 addition & 1 deletion Projects/Domain/WebView/Sources/WebViewClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extension WebViewClient: DependencyKey {
message: dict["message"] as? String ?? "",
accessToken: dict["accessToken"] as? String ?? "",
refreshToken: dict["refreshToken"] as? String ?? "",
href: dict["href"] as? String ?? "",
url: dict["url"] as? String ?? "",
isCompletedOnboardingIntroduction: dict["hasCompleteIntroduction"] as? Bool ?? false
)
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import DomainApplication
import CoreWebViewInterface
import CoreKeyChainStoreInterface
import CoreKeyChainStore
import CoreLoggerInterface

import Dependencies

Expand All @@ -24,8 +25,10 @@ public enum BottleWebViewType {
case createProfile
case signUp
case login
case bottles
case bottleArrival
case editProfile
case goodFeeling
case openURL(url: String)

var path: String {
switch self {
Expand All @@ -35,10 +38,14 @@ public enum BottleWebViewType {
return "signup"
case .login:
return "login"
case .bottles:
return "bottles"
case .bottleArrival:
return "bottles/recommendations"
case .editProfile:
return "profile/edit"
case .goodFeeling:
return "bottles/sents"
case .openURL:
return ""
}
}

Expand All @@ -53,11 +60,17 @@ public enum BottleWebViewType {
case .login:
return URL(string: baseURL + "/" + path)!

case .bottles:
case .bottleArrival:
return makeUrlWithToken(path)

case .editProfile:
return makeUrlWithToken(path)

case .goodFeeling:
return makeUrlWithToken(path)

case let .openURL(url):
return URL(string: url)!
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ extension BottleArrivalFeature {
state.isLoading = false
return .none

case .bottelDidAccepted:
return .send(.delegate(.bottelDidAccepted))
case let .arrivalBottleTapped(url):
return .send(.delegate(.arrivalBottleTapped(url: url)))

case .closeWebView:
return .send(.delegate(.closeWebView))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public struct BottleArrivalFeature {
// View Life Cycle
case onAppear
case webViewLoadingDidCompleted
case bottelDidAccepted
case arrivalBottleTapped(url: String)
case closeWebView
case presentToastDidRequired(message: String)
// Delegate
Expand All @@ -38,6 +38,7 @@ public struct BottleArrivalFeature {
public enum Delegate {
case bottelDidAccepted
case closeWebView
case arrivalBottleTapped(url: String)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ public struct BottleArrivalView: View {
public var body: some View {

WithPerceptionTracking {
BaseWebView(
type: .bottles) { action in
BaseWebView(type: .bottleArrival) { action in
switch action {
case .webViewLoadingDidCompleted:
store.send(.webViewLoadingDidCompleted)
case .bottelDidAccepted:
store.send(.bottelDidAccepted)
case let .openLink(url):
store.send(.arrivalBottleTapped(url: url))
case .closeWebView:
store.send(.closeWebView)
case let .showTaost(message):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// BottleArrivalDetailFeature.swift
// FeatureBottleArrival
//
// Created by JongHoon on 10/9/24.
//

import Foundation

import ComposableArchitecture

@Reducer
public struct BottleArrivalDetailFeature {
private let reducer: Reduce<State, Action>

public init(reducer: Reduce<State, Action>) {
self.reducer = reducer
}

@ObservableState
public struct State: Equatable {
let bottleArrivalURL: String

public init(bottleArrivalURL: String) {
self.bottleArrivalURL = bottleArrivalURL
}
}

public enum Action: BindableAction {
case backButtonDidTapped
case bottelDidAccepted
case showToast(message: String)

case delegate(Delegate)
public enum Delegate {
case backButtonDidTapped
}

case binding(BindingAction<State>)
}

public var body: some ReducerOf<Self> {
BindingReducer()

reducer
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// BottleArrivalDetailFeatureInterface.swift
// FeatureBottleArrival
//
// Created by JongHoon on 10/9/24.
//

import Foundation

import CoreToastInterface

import ComposableArchitecture

extension BottleArrivalDetailFeature {
public init() {
@Dependency(\.toastClient) var toastClient

let reducer = Reduce<State, Action> { state, action in
switch action {
case .backButtonDidTapped:
return .send(.delegate(.backButtonDidTapped))

case let .showToast(message):
toastClient.presentToast(message: message)
return .none

default:
return .none
}
}

self.init(reducer: reducer)
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// BottleArrivalDetailView.swift
// FeatureBottleArrival
//
// Created by JongHoon on 10/9/24.
//

import SwiftUI

import FeatureBaseWebViewInterface

import CoreLoggerInterface

import ComposableArchitecture

public struct BottleArrivalDetailView: View {
@Perception.Bindable private var store: StoreOf<BottleArrivalDetailFeature>

public init(store: StoreOf<BottleArrivalDetailFeature>) {
self.store = store
}

public var body: some View {
WithPerceptionTracking {
BaseWebView(
type: .openURL(url: store.bottleArrivalURL),
actionDidInputted: { action in
switch action {
case .webViewLoadingDidCompleted:
break

case .closeWebView:
store.send(.backButtonDidTapped)

case let .showTaost(message):
store.send(.showToast(message: message))

default:
Log.assertion(message: "not handled action: \(action)")
}
}
)
.navigationBarBackButtonHidden()
.ignoresSafeArea(.all, edges: .bottom)
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private extension MatchingView {
)

OutlinedStyleButton(
.small(contentType: .image(type: .local(bottleImageSystem: .icom(.share)))),
.small(contentType: .image(type: .local(bottleImageSystem: .icon(.share)))),
title: "복사하기",
buttonType: .throttle
) {
Expand Down
21 changes: 21 additions & 0 deletions Projects/Feature/GoodFeeling/Example/Sources/AppView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import SwiftUI

import FeatureGoodFeeling
import FeatureGoodFeelingInterface

import DomainAuth
import DomainAuthInterface

import ComposableArchitecture

@main
struct AppView: App {
var body: some Scene {
WindowGroup {
GoodFeelingRootView(store: Store(
initialState: GoodFeelingRootFeature.State(),
reducer: { GoodFeelingRootFeature() }
))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// GoodFeelingFeatureInterface.swift
// FeatureGoodFeelingInterface
//
// Created by JongHoon on 10/6/24.
//

import Foundation

import ComposableArchitecture

@Reducer
public struct GoodFeelingFeature {
private let reducer: Reduce<State, Action>

public init(reducer: Reduce<State, Action>) {
self.reducer = reducer
}

@ObservableState
public struct State: Equatable {
public init() {

}
}

public enum Action: BindableAction {
case sentBottleTapped(url: String)

case delegate(Delegate)
public enum Delegate {
case sentBottleTapped(url: String)
}

case binding(BindingAction<State>)
}

public var body: some ReducerOf<Self> {
BindingReducer()

reducer
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// GoodFeelingFeature.swift
// FeatureGoodFeelingInterface
//
// Created by JongHoon on 10/6/24.
//

import Foundation

import ComposableArchitecture

extension GoodFeelingFeature {
public init() {
let reducer = Reduce<State, Action> { state, action in
switch action {
case let .sentBottleTapped(url):
return .send(.delegate(.sentBottleTapped(url: url)))

default:
return .none
}
}

self.init(reducer: reducer)
}
}
Loading