Skip to content

Commit b48f4fc

Browse files
Merge pull request #205 from YAPP-Github/style/#204-adjust-profile-image
[Style] 프로필 사진 변경 기능 사용성 확보
2 parents 1e2c72b + c75da04 commit b48f4fc

8 files changed

Lines changed: 72 additions & 57 deletions

File tree

Neki-iOS/APP/Sources/Application/AppCoordinator.swift

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,8 @@ struct AppCoordinator {
193193

194194
switch newStatus {
195195
case let .signedIn(user):
196-
if case var .mainTab(mainTabState) = state.route {
197-
mainTabState.user = user
198-
state.route = .mainTab(.init(user: user))
199-
return .none
200-
}
201-
state.route = .mainTab(.init(user: user))
196+
if case .mainTab = state.route { return .none }
197+
state.route = .mainTab(.init())
202198
return .none
203199

204200
case .signedOut:
@@ -221,24 +217,17 @@ struct AppCoordinator {
221217

222218
case let .route(.auth(.delegate(.moveToMainTab(user)))):
223219
state.$userSessionStatus.withLock { $0 = .signedIn(user) }
224-
state.route = .mainTab(.init(user: user))
220+
state.route = .mainTab(.init())
225221
return .send(.executePendingShareExtensionIfNeeded)
226222

227-
case .route(.mainTab(.delegate(.signedOut))):
228-
state.$userSessionStatus.withLock { $0 = .signedOut }
229-
state.route = .auth(.init())
230-
return .none
231-
232-
case .route(.mainTab(.delegate(.withdraw))):
223+
case .route(.mainTab(.delegate(.signedOut))), .route(.mainTab(.delegate(.withdraw))):
233224
state.$userSessionStatus.withLock { $0 = .signedOut }
234-
state.initializeUserDefaults()
225+
if case .route(.mainTab(.delegate(.withdraw))) = action {
226+
state.initializeUserDefaults()
227+
}
235228
state.route = .auth(.init())
236229
return .none
237230

238-
case let .route(.mainTab(.delegate(.profileUpdated(user)))):
239-
state.$userSessionStatus.withLock { $0 = .signedIn(user) }
240-
return .none
241-
242231
case .binding(\.isAlertPresented):
243232
guard state.isAlertPresented == false else { return .none }
244233
guard let pendingSessionStatus = state.pendingSessionStatus else { return .none }
@@ -253,8 +242,8 @@ struct AppCoordinator {
253242

254243
private func navigateToNextScreen(state: inout State, sessionStatus: UserSessionStatus) -> Effect<Action> {
255244
switch sessionStatus {
256-
case .signedIn(let user):
257-
state.route = .mainTab(.init(user: user))
245+
case .signedIn:
246+
state.route = .mainTab(.init())
258247
return .send(.executePendingShareExtensionIfNeeded)
259248

260249
case .signedOut, .expired:

Neki-iOS/APP/Sources/MainTab/MainTabCoordinator.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ struct MainTabCoordinator {
1616

1717
@ObservableState
1818
struct State {
19-
var user: User
19+
@Shared(.appStorage(AppStorageKey.userSessionStatus)) var userSessionStatus: UserSessionStatus = .signedOut
2020
var selectedTab: NekiTab = .archive
2121

2222
// 하위 코디네이터들의 State를 보유
2323
var pose = PoseCoordinator.State()
2424
var archive = ArchiveCoordinator.State()
2525
var map = MapCoordinator.State()
26-
var myPage: MyPageCoordinator.State
26+
var myPage = MyPageCoordinator.State()
2727

2828
var imagePicker = ImagePickerFeature.State(mediaType: .photoBooth, autoUpload: false)
2929

@@ -37,9 +37,15 @@ struct MainTabCoordinator {
3737
var toast: NekiToastItem? = nil
3838
var isPermissionAlertPresented: Bool = false
3939

40-
init(user: User) {
41-
self.user = user
42-
myPage = MyPageCoordinator.State(user: user)
40+
var user: User {
41+
get {
42+
guard case let .signedIn(user) = userSessionStatus else { return .dummy }
43+
return user
44+
}
45+
46+
set {
47+
$userSessionStatus.withLock { $0 = .signedIn(newValue) }
48+
}
4349
}
4450
}
4551

@@ -72,7 +78,6 @@ struct MainTabCoordinator {
7278
enum Delegate {
7379
case signedOut
7480
case withdraw
75-
case profileUpdated(User)
7681
}
7782
}
7883

@@ -170,9 +175,6 @@ struct MainTabCoordinator {
170175
await send(.delegate(.withdraw))
171176
}
172177

173-
case let .myPage(.delegate(.profileUpdated(user))):
174-
return .send(.delegate(.profileUpdated(user)))
175-
176178
case let .imagePicker(.delegate(.imagesConverted(entities))):
177179
state.isPhotoPickerPresented = false
178180
state.isLoading = false

Neki-iOS/Core/Sources/Auth/Sources/Domain/Sources/Entities/User.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ public struct User: Sendable, Equatable, Codable {
1616
let providerType: ProviderType
1717
var allRequiredTermsAgreed: Bool
1818
}
19+
20+
extension User {
21+
static var dummy: Self { User(id: -1, nickname: "-", email: nil, profileImageURL: nil, providerType: .local, allRequiredTermsAgreed: true) }
22+
}

Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Coordinator/MyPageCoordinator.swift

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ import ComposableArchitecture
1212
struct MyPageCoordinator {
1313
@ObservableState
1414
struct State {
15-
var root: MyPageFeature.State
16-
var path = StackState<Path.State>()
15+
@Shared(.appStorage(AppStorageKey.userSessionStatus)) var userSessionStatus: UserSessionStatus = .signedOut
1716

18-
init(user: User) {
19-
root = MyPageFeature.State(user: user)
20-
}
17+
var root = MyPageFeature.State()
18+
var path = StackState<Path.State>()
2119
}
2220

2321
enum Action {
@@ -28,7 +26,6 @@ struct MyPageCoordinator {
2826
enum Delegate {
2927
case didLogout
3028
case didWithdraw
31-
case profileUpdated(User)
3229
}
3330
}
3431

@@ -43,11 +40,12 @@ struct MyPageCoordinator {
4340
return routeMyPageCellTapped(state: &state, cellItem)
4441

4542
case .root(.profileTapped):
46-
state.path.append(.accountPreference(.init(user: state.root.user)))
43+
state.path.append(.accountPreference(.init()))
4744
return .none
4845

4946
case .path(.element(id: _, action: .accountPreference(.editProfileButtonTapped))):
50-
state.path.append(.profileEdit(.init(user: state.root.user)))
47+
guard case let .signedIn(user) = state.userSessionStatus else { return .none }
48+
state.path.append(.profileEdit(.init(user: user)))
5149
return .none
5250

5351
case .path(.element(id: _, action: .accountPreference(.didSignOut))):
@@ -56,9 +54,6 @@ struct MyPageCoordinator {
5654
case .path(.element(id: _, action: .accountPreference(.didWithdraw))):
5755
return .send(.delegate(.didWithdraw))
5856

59-
case let .path(.element(id: _, action: .profileEdit(.profileUpdated(user)))):
60-
return .send(.delegate(.profileUpdated(user)))
61-
6257
default:
6358
return .none
6459
}

Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/AccountPreferenceFeature.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ import os
1313
struct AccountPreferenceFeature {
1414
@ObservableState
1515
struct State {
16-
var user: User
16+
@Shared(.appStorage(AppStorageKey.userSessionStatus)) var userSessionStatus: UserSessionStatus = .signedOut
1717

1818
var isLogoutAlertPresented: Bool = false
1919
var isUnregisterAlertPresented: Bool = false
2020
var isLoading: Bool = false
21+
22+
var user: User {
23+
guard case let .signedIn(user) = userSessionStatus else { return .dummy }
24+
return user
25+
}
2126
}
2227

2328
enum Action: BindableAction {
@@ -71,9 +76,9 @@ struct AccountPreferenceFeature {
7176
state.isUnregisterAlertPresented = false
7277
state.isLoading = true
7378

74-
return .run { [userId = state.user.id] send in
79+
return .run { [userID = state.user.id] send in
7580
try await authClient.withdraw()
76-
UserDefaults.standard.removeObject(forKey: "TermsAgreed_\(userId)")
81+
UserDefaults.standard.removeObject(forKey: "TermsAgreed_\(userID)")
7782
await send(.didWithdraw)
7883
} catch: { error, send in
7984
Logger.presentation.error("회원탈퇴 과정 중 에러 발생: \(error)")

Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/MyPageFeature.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@ import ComposableArchitecture
1212
struct MyPageFeature {
1313
@ObservableState
1414
struct State {
15-
var user: User
15+
@Shared(.appStorage(AppStorageKey.userSessionStatus)) var userSessionStatus: UserSessionStatus = .signedOut
1616
var appVersion: AppVersion = AppVersion(major: 0, minor: 0, revision: 0)
17+
18+
var user: User {
19+
guard case let .signedIn(user) = userSessionStatus else { return .dummy }
20+
return user
21+
}
1722
}
1823

1924
enum Action {

Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/ProfileEditFeature.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import os
1414
struct ProfileEditFeature {
1515
@ObservableState
1616
struct State {
17-
@ObservationStateIgnored let user: User
17+
@Shared(.appStorage(AppStorageKey.userSessionStatus)) var userSessionStatus: UserSessionStatus = .signedOut
1818
var nickname: String
1919
var currentProfileImageURL: URL?
2020
var selectedProfileImage: UIImage?
@@ -29,8 +29,18 @@ struct ProfileEditFeature {
2929

3030
var isProfileSelectionAlertPresented: Bool = false
3131

32+
var user: User {
33+
get {
34+
guard case let .signedIn(user) = userSessionStatus else { return .dummy }
35+
return user
36+
}
37+
38+
set {
39+
$userSessionStatus.withLock { $0 = .signedIn(newValue) }
40+
}
41+
}
42+
3243
init(user: User) {
33-
self.user = user
3444
nickname = user.nickname
3545
currentProfileImageURL = user.profileImageURL
3646
}
@@ -50,9 +60,6 @@ struct ProfileEditFeature {
5060

5161
// Binding Actions
5262
case binding(BindingAction<State>)
53-
54-
// Delegate Actions
55-
case profileUpdated(User)
5663
}
5764

5865
private enum CancelID { case imageLoad }
@@ -134,8 +141,8 @@ struct ProfileEditFeature {
134141

135142
case let .updateProfileResponse(.success(user)):
136143
state.isLoading = false
137-
return .run { send in
138-
await send(.profileUpdated(user))
144+
state.user = user
145+
return .run { _ in
139146
await dismiss()
140147
}
141148

Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,20 @@ private extension AccountPreferenceView {
6969

7070
var profileArea: some View {
7171
VStack(spacing: 16) {
72-
KFImage(store.user.profileImageURL)
73-
.resizable()
74-
.onFailureImage(.iconDefaultProfile)
75-
.scaledToFill()
76-
.frame(width: 142, height: 142)
77-
.clipShape(.circle)
72+
ZStack(alignment: .bottomTrailing) {
73+
KFImage(store.user.profileImageURL)
74+
.resizable()
75+
.onFailureImage(.iconDefaultProfile)
76+
.scaledToFill()
77+
.frame(width: 142, height: 142)
78+
.clipShape(.circle)
79+
80+
Button {
81+
store.send(.editProfileButtonTapped)
82+
} label: {
83+
Image(.iconProfileCamera)
84+
}
85+
}
7886

7987
HStack(spacing: 9) {
8088
Text(store.user.nickname)

0 commit comments

Comments
 (0)