크리에이터 채널 - 팔로우와 알림설정

- 팔로잉 상태에서 알림 켜기/끄기 상태 추가
This commit is contained in:
Yu Sung 2024-09-23 15:19:15 +09:00
parent f444f0bfb0
commit d3ab1507a4
17 changed files with 228 additions and 11 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_following_no_alarm_big.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_avatar_unfollow.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_notify_all.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_notify_none.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,107 @@
//
// CreatorFollowNotifyDialog.swift
// SodaLive
//
// Created by klaus on 9/23/24.
//
import SwiftUI
struct CreatorFollowNotifyDialog: View {
@Binding var isShowing: Bool
let onClickNotifyAll: () -> Void
let onClickNotifyNone: () -> Void
let onClickUnFollow: () -> Void
@State private var isShow: Bool = false
var body: some View {
ZStack {
Color.black.opacity(0.7).ignoresSafeArea()
.onTapGesture {
isShowing = false
}
VStack(spacing: 0) {
Spacer()
if isShow {
VStack(alignment: .leading, spacing: 24) {
Text("알림")
.font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color.grayee)
CreatorFollowNotifyItem(
image: "ic_notify_all",
title: "전체",
onTapGesture: {
isShowing = false
onClickNotifyAll()
}
)
CreatorFollowNotifyItem(
image: "ic_notify_none",
title: "없음",
onTapGesture: {
isShowing = false
onClickNotifyNone()
}
)
CreatorFollowNotifyItem(
image: "ic_avatar_unfollow",
title: "팔로우 취소",
onTapGesture: {
isShowing = false
onClickUnFollow()
}
)
}
.frame(maxWidth:.infinity)
.padding(.horizontal, 16)
.padding(.top, 16)
.padding(.bottom, 32)
.background(Color.gray22)
.cornerRadius(10, corners: [.topLeft, .topRight])
.transition(.move(edge: .bottom))
.animation(.easeInOut(duration: 0.5), value: isShow)
}
}
.ignoresSafeArea()
}
.onAppear {
withAnimation {
isShow = true
}
}
}
}
struct CreatorFollowNotifyItem: View {
let image: String
let title: String
let onTapGesture: () -> Void
var body: some View {
HStack(spacing: 16) {
Image(image)
Text(title)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
Spacer()
}
.onTapGesture(perform: onTapGesture)
}
}
#Preview {
CreatorFollowNotifyDialog(
isShowing: .constant(true),
onClickNotifyAll: {},
onClickNotifyNone: {},
onClickUnFollow: {}
)
}

View File

@ -31,6 +31,8 @@ struct CreatorResponse: Decodable {
let youtubeUrl: String? let youtubeUrl: String?
let websiteUrl: String? let websiteUrl: String?
let blogUrl: String? let blogUrl: String?
let isFollow: Bool
let isNotify: Bool
let isNotification: Bool let isNotification: Bool
let notificationRecipientCount: Int let notificationRecipientCount: Int
} }

View File

@ -13,7 +13,7 @@ struct UserProfileCreatorView: View {
let creator: CreatorResponse let creator: CreatorResponse
let creatorFollow: () -> Void let creatorFollow: () -> Void
let creatorUnFollow: () -> Void let showCreatorFollowNotifyDialog: () -> Void
let shareChannel: () -> Void let shareChannel: () -> Void
var body: some View { var body: some View {
@ -57,12 +57,16 @@ struct UserProfileCreatorView: View {
} }
} else { } else {
VStack(alignment: .leading, spacing: 9.3) { VStack(alignment: .leading, spacing: 9.3) {
Image(creator.isNotification ? "btn_following_big" : "btn_follow_big") Image(
creator.isFollow ?
creator.isNotify ? "btn_following_big": "btn_following_no_alarm_big"
: "btn_follow_big"
)
.resizable() .resizable()
.frame(width: 83.3, height: 26.7) .frame(width: 83.3, height: 26.7)
.onTapGesture { .onTapGesture {
if creator.isNotification { if creator.isFollow {
creatorUnFollow() showCreatorFollowNotifyDialog()
} else { } else {
creatorFollow() creatorFollow()
} }
@ -143,11 +147,13 @@ struct UserProfileCreatorView_Previews: PreviewProvider {
youtubeUrl: Optional("https://www.youtube.com/watch?v=3x2tfZnfLRo"), youtubeUrl: Optional("https://www.youtube.com/watch?v=3x2tfZnfLRo"),
websiteUrl: Optional("https://instagram.com/dear.zia"), websiteUrl: Optional("https://instagram.com/dear.zia"),
blogUrl: Optional("dear.zia"), blogUrl: Optional("dear.zia"),
isFollow: false,
isNotify: false,
isNotification: false, isNotification: false,
notificationRecipientCount: 2 notificationRecipientCount: 2
) )
) { ) {
} creatorUnFollow: { } showCreatorFollowNotifyDialog: {
} shareChannel: { } shareChannel: {
} }
} }

View File

@ -14,6 +14,7 @@ struct UserProfileView: View {
@State private var memberId: Int = 0 @State private var memberId: Int = 0
@State private var isShowMemberProfilePopup: Bool = false @State private var isShowMemberProfilePopup: Bool = false
@State private var isShowFollowNotifyDialog: Bool = false
var body: some View { var body: some View {
GeometryReader { proxy in GeometryReader { proxy in
@ -52,8 +53,8 @@ struct UserProfileView: View {
UserProfileCreatorView( UserProfileCreatorView(
creator: creatorProfile.creator) { creator: creatorProfile.creator) {
viewModel.creatorFollow() viewModel.creatorFollow()
} creatorUnFollow: { } showCreatorFollowNotifyDialog: {
viewModel.creatorUnFollow() isShowFollowNotifyDialog = true
} shareChannel: { } shareChannel: {
viewModel.shareChannel(userId: userId) viewModel.shareChannel(userId: userId)
} }
@ -323,6 +324,21 @@ struct UserProfileView: View {
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId) MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
} }
} }
if isShowFollowNotifyDialog {
CreatorFollowNotifyDialog(
isShowing: $isShowFollowNotifyDialog,
onClickNotifyAll: {
viewModel.creatorFollow(follow: true, notify: true)
},
onClickNotifyNone: {
viewModel.creatorFollow(follow: true, notify: false)
},
onClickUnFollow: {
viewModel.creatorFollow(follow: false, notify: false)
}
)
}
} }
.sheet( .sheet(
isPresented: $viewModel.isShowShareView, isPresented: $viewModel.isShowShareView,

View File

@ -282,11 +282,11 @@ final class UserProfileViewModel: ObservableObject {
.store(in: &subscription) .store(in: &subscription)
} }
func creatorFollow() { func creatorFollow(follow: Bool = true, notify: Bool = true) {
if let creator = creatorProfile { if let creator = creatorProfile {
isLoading = true isLoading = true
userRepository.creatorFollow(creatorId: creator.creator.creatorId) userRepository.creatorFollow(creatorId: creator.creator.creatorId, follow: follow, notify: notify)
.sink { result in .sink { result in
switch result { switch result {
case .finished: case .finished:

View File

@ -9,4 +9,6 @@ import Foundation
struct CreatorFollowRequest: Encodable { struct CreatorFollowRequest: Encodable {
let creatorId: Int let creatorId: Int
var isNotify: Bool = true
var isActive: Bool = true
} }

View File

@ -69,8 +69,8 @@ final class UserRepository {
return api.requestPublisher(.updatePushToken(request: PushTokenUpdateRequest(pushToken: pushToken))) return api.requestPublisher(.updatePushToken(request: PushTokenUpdateRequest(pushToken: pushToken)))
} }
func creatorFollow(creatorId: Int) -> AnyPublisher<Response, MoyaError> { func creatorFollow(creatorId: Int, follow: Bool = true, notify: Bool = true) -> AnyPublisher<Response, MoyaError> {
return api.requestPublisher(.creatorFollow(request: CreatorFollowRequest(creatorId: creatorId))) return api.requestPublisher(.creatorFollow(request: CreatorFollowRequest(creatorId: creatorId, isNotify: notify, isActive: follow)))
} }
func creatorUnFollow(creatorId: Int) -> AnyPublisher<Response, MoyaError> { func creatorUnFollow(creatorId: Int) -> AnyPublisher<Response, MoyaError> {