parent
17ead38524
commit
7c5b30335e
|
@ -17,6 +17,7 @@ struct AudioContentCommentItemView: View {
|
|||
|
||||
let modifyComment: (Int, String) -> Void
|
||||
let onClickDelete: (Int) -> Void
|
||||
let onClickProfile: (Int) -> Void
|
||||
|
||||
@State var isShowPopupMenu: Bool = false
|
||||
@State var isModeModify: Bool = false
|
||||
|
@ -30,6 +31,11 @@ struct AudioContentCommentItemView: View {
|
|||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
.onTapGesture {
|
||||
if UserDefaults.int(forKey: .userId) != commentItem.writerId {
|
||||
onClickProfile(commentItem.writerId)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
HStack(spacing: 6.7) {
|
||||
|
@ -95,8 +101,8 @@ struct AudioContentCommentItemView: View {
|
|||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.foregroundColor(Color.grayee)
|
||||
.accentColor(Color.button)
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
|
@ -114,7 +120,7 @@ struct AudioContentCommentItemView: View {
|
|||
isModeModify = false
|
||||
}
|
||||
}
|
||||
.background(Color(hex: "232323"))
|
||||
.background(Color.gray23)
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
|
@ -151,7 +157,7 @@ struct AudioContentCommentItemView: View {
|
|||
.padding(.leading, 46.7)
|
||||
|
||||
Rectangle()
|
||||
.foregroundColor(Color(hex: "595959"))
|
||||
.foregroundColor(Color.gray59)
|
||||
.frame(height: 0.5)
|
||||
.padding(.top, 16.7)
|
||||
}
|
||||
|
@ -161,7 +167,7 @@ struct AudioContentCommentItemView: View {
|
|||
if commentItem.writerId == UserDefaults.int(forKey: .userId) {
|
||||
Text("수정")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
.onTapGesture {
|
||||
isModeModify = true
|
||||
isShowPopupMenu = false
|
||||
|
@ -173,7 +179,7 @@ struct AudioContentCommentItemView: View {
|
|||
{
|
||||
Text("삭제")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
.onTapGesture {
|
||||
onClickDelete(commentItem.id)
|
||||
isShowPopupMenu = false
|
||||
|
@ -181,7 +187,7 @@ struct AudioContentCommentItemView: View {
|
|||
}
|
||||
}
|
||||
.padding(10)
|
||||
.background(Color(hex: "222222"))
|
||||
.background(Color.gray22)
|
||||
}
|
||||
}
|
||||
.onAppear { comment = commentItem.comment }
|
||||
|
|
|
@ -21,6 +21,9 @@ struct AudioContentCommentListView: View {
|
|||
@State private var commentId: Int = 0
|
||||
@State private var isShowDeletePopup: Bool = false
|
||||
|
||||
@State private var memberId: Int = 0
|
||||
@State private var isShowMemberProfilePopup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
|
@ -137,6 +140,10 @@ struct AudioContentCommentListView: View {
|
|||
onClickDelete: {
|
||||
commentId = $0
|
||||
isShowDeletePopup = true
|
||||
},
|
||||
onClickProfile: {
|
||||
memberId = $0
|
||||
isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
|
@ -169,6 +176,10 @@ struct AudioContentCommentListView: View {
|
|||
)
|
||||
}
|
||||
|
||||
if isShowMemberProfilePopup {
|
||||
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ struct AudioContentListReplyView: View {
|
|||
@State private var commentId: Int = 0
|
||||
@State private var isShowDeletePopup: Bool = false
|
||||
|
||||
@State private var memberId: Int = 0
|
||||
@State private var isShowMemberProfilePopup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
|
@ -98,7 +101,11 @@ struct AudioContentListReplyView: View {
|
|||
isReplyComment: true,
|
||||
isShowPopupMenuButton: false,
|
||||
modifyComment: { _, _ in },
|
||||
onClickDelete: { _ in }
|
||||
onClickDelete: { _ in },
|
||||
onClickProfile: {
|
||||
memberId = $0
|
||||
isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
.padding(.bottom, 13.3)
|
||||
|
@ -120,6 +127,10 @@ struct AudioContentListReplyView: View {
|
|||
onClickDelete: {
|
||||
commentId = $0
|
||||
isShowDeletePopup = true
|
||||
},
|
||||
onClickProfile: {
|
||||
memberId = $0
|
||||
isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 40)
|
||||
|
@ -153,6 +164,10 @@ struct AudioContentListReplyView: View {
|
|||
)
|
||||
}
|
||||
|
||||
if isShowMemberProfilePopup {
|
||||
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
//
|
||||
// MemberProfileDialog.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 9/7/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct MemberProfileDialog: View {
|
||||
|
||||
@StateObject var viewModel = UserViewModel()
|
||||
|
||||
@Binding var isShowing: Bool
|
||||
let memberId: Int
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Color.black.opacity(0.7).ignoresSafeArea()
|
||||
.onTapGesture {
|
||||
isShowing = false
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 21) {
|
||||
HStack(spacing: 0) {
|
||||
Text("프로필")
|
||||
.font(.custom(Font.bold.rawValue, size: 15))
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("ic_close_white")
|
||||
.onTapGesture {
|
||||
isShowing = false
|
||||
}
|
||||
}
|
||||
|
||||
if let profile = viewModel.memberProfile {
|
||||
Text(profile.nickname)
|
||||
.font(.custom(Font.bold.rawValue, size: 18.3))
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
KFImage(URL(string: profile.profileImageUrl))
|
||||
.resizable()
|
||||
.frame(maxWidth: screenSize().width - 66.7, maxHeight: screenSize().width - 66.7)
|
||||
.aspectRatio(CGSize(width: 1, height: 1), contentMode: .fit)
|
||||
.cornerRadius(8)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
Text(profile.isBlocked ? "차단 해제" : "차단")
|
||||
.font(.custom(Font.bold.rawValue, size: 15))
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 13)
|
||||
.cornerRadius(8)
|
||||
.contentShape(Rectangle())
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color.button)
|
||||
)
|
||||
.onTapGesture {
|
||||
if profile.isBlocked {
|
||||
viewModel.memberUnBlock()
|
||||
} else {
|
||||
viewModel.isShowUesrBlockConfirm = true
|
||||
}
|
||||
}
|
||||
|
||||
Text("사용자 신고")
|
||||
.font(.custom(Font.bold.rawValue, size: 15))
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 13)
|
||||
.cornerRadius(8)
|
||||
.contentShape(Rectangle())
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color.button)
|
||||
)
|
||||
.onTapGesture { viewModel.isShowUesrReportView = true }
|
||||
|
||||
Text("프로필 신고")
|
||||
.font(.custom(Font.bold.rawValue, size: 15))
|
||||
.foregroundColor(Color.button)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 13)
|
||||
.cornerRadius(8)
|
||||
.contentShape(Rectangle())
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color.button)
|
||||
)
|
||||
.onTapGesture { viewModel.isShowProfileReportConfirm = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 13.3)
|
||||
.padding(.top, 13.3)
|
||||
.padding(.bottom, 20)
|
||||
.background(Color.gray22)
|
||||
.cornerRadius(8)
|
||||
.padding(.horizontal, 13.3)
|
||||
.frame(maxWidth: screenSize().width - 33.3)
|
||||
.onAppear {
|
||||
if memberId <= 1 {
|
||||
viewModel.errorMessage = "잘못된 요청입니다."
|
||||
viewModel.isShowPopup = true
|
||||
} else {
|
||||
viewModel.getMemberProfile(memberId: memberId)
|
||||
}
|
||||
}
|
||||
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) {
|
||||
HStack {
|
||||
Spacer()
|
||||
Text(viewModel.errorMessage)
|
||||
.padding(.vertical, 13.3)
|
||||
.frame(width: screenSize().width - 66.7, alignment: .center)
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.background(Color.button)
|
||||
.foregroundColor(Color.white)
|
||||
.multilineTextAlignment(.leading)
|
||||
.cornerRadius(20)
|
||||
.padding(.bottom, 66.7)
|
||||
Spacer()
|
||||
}
|
||||
.onDisappear {
|
||||
if viewModel.dismissDialog {
|
||||
isShowing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.isShowUesrBlockConfirm {
|
||||
UserBlockConfirmDialogView(
|
||||
isShowing: $viewModel.isShowUesrBlockConfirm,
|
||||
nickname: viewModel.nickname,
|
||||
confirmAction: {
|
||||
viewModel.memberBlock()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if viewModel.isShowUesrReportView {
|
||||
UserReportDialogView(
|
||||
isShowing: $viewModel.isShowUesrReportView,
|
||||
confirmAction: { reason in
|
||||
viewModel.report(type: .USER, reason: reason)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if viewModel.isShowProfileReportConfirm {
|
||||
ProfileReportDialogView(
|
||||
isShowing: $viewModel.isShowProfileReportConfirm,
|
||||
confirmAction: {
|
||||
viewModel.report(type: .PROFILE)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
MemberProfileDialog(isShowing: .constant(true), memberId: 1)
|
||||
}
|
|
@ -17,6 +17,7 @@ struct CreatorCommunityCommentItemView: View {
|
|||
|
||||
let modifyComment: (Int, String) -> Void
|
||||
let onClickDelete: (Int) -> Void
|
||||
let onClickProfile: (Int) -> Void
|
||||
|
||||
@State var isShowPopupMenu: Bool = false
|
||||
@State var isModeModify: Bool = false
|
||||
|
@ -30,6 +31,11 @@ struct CreatorCommunityCommentItemView: View {
|
|||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
.onTapGesture {
|
||||
if UserDefaults.int(forKey: .userId) != commentItem.writerId {
|
||||
onClickProfile(commentItem.writerId)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(commentItem.nickname)
|
||||
|
@ -38,7 +44,7 @@ struct CreatorCommunityCommentItemView: View {
|
|||
|
||||
Text(commentItem.date)
|
||||
.font(.custom(Font.medium.rawValue, size: 10.3))
|
||||
.foregroundColor(Color(hex: "525252"))
|
||||
.foregroundColor(Color.gray52)
|
||||
.padding(.top, 4)
|
||||
}
|
||||
|
||||
|
@ -57,8 +63,8 @@ struct CreatorCommunityCommentItemView: View {
|
|||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.foregroundColor(Color.grayee)
|
||||
.accentColor(Color.button)
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@ struct CreatorCommunityCommentListView: View {
|
|||
|
||||
@State private var commentId: Int = 0
|
||||
@State private var isShowDeletePopup: Bool = false
|
||||
|
||||
@State private var memberId: Int = 0
|
||||
@State private var isShowMemberProfilePopup: Bool = false
|
||||
|
||||
@StateObject var viewModel = CreatorCommunityCommentListViewModel()
|
||||
|
||||
var body: some View {
|
||||
|
@ -115,6 +119,10 @@ struct CreatorCommunityCommentListView: View {
|
|||
onClickDelete: {
|
||||
commentId = $0
|
||||
isShowDeletePopup = true
|
||||
},
|
||||
onClickProfile: {
|
||||
memberId = $0
|
||||
isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
|
@ -147,6 +155,10 @@ struct CreatorCommunityCommentListView: View {
|
|||
)
|
||||
}
|
||||
|
||||
if isShowMemberProfilePopup {
|
||||
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ struct CreatorCommunityCommentReplyView: View {
|
|||
@State private var commentId: Int = 0
|
||||
@State private var isShowDeletePopup: Bool = false
|
||||
|
||||
@State private var memberId: Int = 0
|
||||
@State private var isShowMemberProfilePopup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
|
@ -98,7 +101,11 @@ struct CreatorCommunityCommentReplyView: View {
|
|||
isReplyComment: true,
|
||||
isShowPopupMenuButton: false,
|
||||
modifyComment: { _, _ in },
|
||||
onClickDelete: { _ in }
|
||||
onClickDelete: { _ in },
|
||||
onClickProfile: {
|
||||
memberId = $0
|
||||
isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
.padding(.bottom, 13.3)
|
||||
|
@ -120,6 +127,10 @@ struct CreatorCommunityCommentReplyView: View {
|
|||
onClickDelete: {
|
||||
commentId = $0
|
||||
isShowDeletePopup = true
|
||||
},
|
||||
onClickProfile: {
|
||||
memberId = $0
|
||||
isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
|
@ -154,6 +165,10 @@ struct CreatorCommunityCommentReplyView: View {
|
|||
)
|
||||
}
|
||||
|
||||
if isShowMemberProfilePopup {
|
||||
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ struct UserProfileFanTalkAllView: View {
|
|||
@State private var cheersContent: String = ""
|
||||
@State private var cheersId: Int = 0
|
||||
|
||||
@State private var memberId: Int = 0
|
||||
@State private var isShowMemberProfilePopup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { proxy in
|
||||
BaseView(isLoading: $viewModel.isLoading) {
|
||||
|
@ -26,17 +29,17 @@ struct UserProfileFanTalkAllView: View {
|
|||
HStack(spacing: 6.7) {
|
||||
Text("응원")
|
||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Text("\(viewModel.cheersTotalCount)")
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
}
|
||||
.padding(.top, 20)
|
||||
|
||||
Rectangle()
|
||||
.frame(height: 1)
|
||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
||||
.foregroundColor(Color.gray90.opacity(0.5))
|
||||
.padding(.top, 13.3)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
|
@ -44,8 +47,8 @@ struct UserProfileFanTalkAllView: View {
|
|||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.foregroundColor(Color.grayee)
|
||||
.accentColor(Color.button)
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
|
@ -61,18 +64,18 @@ struct UserProfileFanTalkAllView: View {
|
|||
cheersContent = ""
|
||||
}
|
||||
}
|
||||
.background(Color(hex: "232323"))
|
||||
.background(Color.gray23)
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color(hex: "3bb9f1"))
|
||||
.foregroundColor(Color.button)
|
||||
)
|
||||
.padding(.top, 13.3)
|
||||
|
||||
Rectangle()
|
||||
.frame(height: 1)
|
||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
||||
.foregroundColor(Color.gray90.opacity(0.5))
|
||||
.padding(.top, 13.3)
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
|
@ -96,6 +99,10 @@ struct UserProfileFanTalkAllView: View {
|
|||
onClickDelete: { cheersId in
|
||||
self.cheersId = cheersId
|
||||
viewModel.isShowCheersDeleteView = true
|
||||
},
|
||||
onClickProfile: {
|
||||
self.memberId = $0
|
||||
self.isShowMemberProfilePopup = true
|
||||
}
|
||||
)
|
||||
.onAppear {
|
||||
|
@ -110,7 +117,7 @@ struct UserProfileFanTalkAllView: View {
|
|||
} else {
|
||||
Text("응원이 없습니다.\n\n처음으로 응원을 해보세요!")
|
||||
.font(.custom(Font.light.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "bbbbbb"))
|
||||
.foregroundColor(Color.graybb)
|
||||
.multilineTextAlignment(.center)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding(.vertical, 60)
|
||||
|
@ -136,7 +143,7 @@ struct UserProfileFanTalkAllView: View {
|
|||
.padding(.vertical, 13.3)
|
||||
.frame(width: screenSize().width - 66.7, alignment: .center)
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.background(Color(hex: "9970ff"))
|
||||
.background(Color.button)
|
||||
.foregroundColor(Color.white)
|
||||
.multilineTextAlignment(.leading)
|
||||
.cornerRadius(20)
|
||||
|
@ -171,6 +178,10 @@ struct UserProfileFanTalkAllView: View {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
if isShowMemberProfilePopup {
|
||||
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
let modifyCheer: (Int, String) -> Void
|
||||
let reportPopup: (Int) -> Void
|
||||
let onClickDelete: (Int) -> Void
|
||||
let onClickProfile: (Int) -> Void
|
||||
|
||||
@State var replyContent: String = ""
|
||||
@State var isShowInputReply = false
|
||||
|
@ -34,6 +35,11 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
.resizable()
|
||||
.frame(width: 33.3, height: 33.3)
|
||||
.clipShape(Circle())
|
||||
.onTapGesture {
|
||||
if UserDefaults.int(forKey: .userId) != cheersItem.memberId {
|
||||
onClickProfile(cheersItem.memberId)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text("\(cheersItem.nickname)")
|
||||
|
@ -51,10 +57,10 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.foregroundColor(Color.grayee)
|
||||
.padding(13.3)
|
||||
.background(Color(hex: "232323"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.background(Color.gray23)
|
||||
.accentColor(Color.button)
|
||||
.keyboardType(.default)
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
|
@ -65,7 +71,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
|
||||
Text("수정")
|
||||
.font(.custom(Font.bold.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "ffffff"))
|
||||
.foregroundColor(Color.white)
|
||||
.padding(13.3)
|
||||
.background(Color.button)
|
||||
.cornerRadius(6.7)
|
||||
|
@ -78,7 +84,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
.font(.custom(Font.bold.rawValue, size: 13.3))
|
||||
.foregroundColor(Color.button)
|
||||
.padding(13.3)
|
||||
.background(Color(hex: "222222"))
|
||||
.background(Color.gray22)
|
||||
.cornerRadius(6.7)
|
||||
.onTapGesture {
|
||||
isModeModify = false
|
||||
|
@ -100,23 +106,23 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.foregroundColor(Color.grayee)
|
||||
.padding(13.3)
|
||||
.background(Color(hex: "232323"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.background(Color.gray23)
|
||||
.accentColor(Color.button)
|
||||
.keyboardType(.default)
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color(hex: "3bb9f1"))
|
||||
.foregroundColor(Color.button)
|
||||
)
|
||||
|
||||
Text("등록")
|
||||
.font(.custom(Font.bold.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "ffffff"))
|
||||
.foregroundColor(Color.white)
|
||||
.padding(13.3)
|
||||
.background(Color(hex: "3bb9f1"))
|
||||
.background(Color.button)
|
||||
.cornerRadius(6.7)
|
||||
.onTapGesture {
|
||||
if cheersItem.replyList.count > 0 {
|
||||
|
@ -182,7 +188,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
|
||||
Rectangle()
|
||||
.frame(height: 1)
|
||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
||||
.foregroundColor(Color.gray90.opacity(0.5))
|
||||
.padding(.top, 13.3)
|
||||
}
|
||||
.frame(width: screenSize().width - 26.7)
|
||||
|
@ -192,7 +198,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
if cheersItem.memberId != UserDefaults.int(forKey: .userId) {
|
||||
Text("신고하기")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
.onTapGesture {
|
||||
reportPopup(cheersItem.cheersId)
|
||||
isShowPopupMenu = false
|
||||
|
@ -202,7 +208,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
if cheersItem.memberId == UserDefaults.int(forKey: .userId) {
|
||||
Text("수정")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
.onTapGesture {
|
||||
isModeModify = true
|
||||
isShowPopupMenu = false
|
||||
|
@ -215,7 +221,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
{
|
||||
Text("삭제")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
.onTapGesture {
|
||||
onClickDelete(cheersItem.cheersId)
|
||||
isShowPopupMenu = false
|
||||
|
@ -223,7 +229,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
|||
}
|
||||
}
|
||||
.padding(10)
|
||||
.background(Color(hex: "222222"))
|
||||
.background(Color.gray22)
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
|
|
|
@ -17,6 +17,7 @@ struct UserProfileFanTalkView: View {
|
|||
let errorPopup: (String) -> Void
|
||||
let reportPopup: (Int) -> Void
|
||||
let deletePopup: (Int) -> Void
|
||||
let profilePopup: (Int) -> Void
|
||||
|
||||
@Binding var isLoading: Bool
|
||||
@State private var cheersContent: String = ""
|
||||
|
@ -26,13 +27,13 @@ struct UserProfileFanTalkView: View {
|
|||
HStack(spacing: 0) {
|
||||
Text("팬 Talk")
|
||||
.font(.custom(Font.bold.rawValue, size: 16.7))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("전체보기")
|
||||
.font(.custom(Font.light.rawValue, size: 11.3))
|
||||
.foregroundColor(Color(hex: "bbbbbb"))
|
||||
.foregroundColor(Color.graybb)
|
||||
.onTapGesture {
|
||||
AppState.shared.setAppStep(step: .userProfileFanTalkAll(userId: userId))
|
||||
}
|
||||
|
@ -43,17 +44,17 @@ struct UserProfileFanTalkView: View {
|
|||
HStack(spacing: 6.7) {
|
||||
Text("응원")
|
||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Text("\(cheers.totalCount)")
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.foregroundColor(Color.gray77)
|
||||
}
|
||||
.padding(.top, 20)
|
||||
|
||||
Rectangle()
|
||||
.frame(height: 1)
|
||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
||||
.foregroundColor(Color.gray90.opacity(0.5))
|
||||
.padding(.top, 13.3)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
|
@ -61,8 +62,8 @@ struct UserProfileFanTalkView: View {
|
|||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.foregroundColor(Color.grayee)
|
||||
.accentColor(Color.button)
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
|
@ -78,18 +79,18 @@ struct UserProfileFanTalkView: View {
|
|||
cheersContent = ""
|
||||
}
|
||||
}
|
||||
.background(Color(hex: "232323"))
|
||||
.background(Color.gray23)
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color(hex: "9970ff"))
|
||||
.foregroundColor(Color.button)
|
||||
)
|
||||
.padding(.top, 13.3)
|
||||
|
||||
Rectangle()
|
||||
.frame(height: 1)
|
||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
||||
.foregroundColor(Color.gray90.opacity(0.5))
|
||||
.padding(.top, 13.3)
|
||||
|
||||
VStack(spacing: 20) {
|
||||
|
@ -110,6 +111,9 @@ struct UserProfileFanTalkView: View {
|
|||
},
|
||||
onClickDelete: { cheersId in
|
||||
deletePopup(cheersId)
|
||||
},
|
||||
onClickProfile: {
|
||||
profilePopup($0)
|
||||
}
|
||||
)
|
||||
.onTapGesture {
|
||||
|
@ -119,7 +123,7 @@ struct UserProfileFanTalkView: View {
|
|||
} else {
|
||||
Text("응원이 없습니다.\n\n처음으로 응원을 해보세요!")
|
||||
.font(.custom(Font.light.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "bbbbbb"))
|
||||
.foregroundColor(Color.graybb)
|
||||
.multilineTextAlignment(.center)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding(.vertical, 60)
|
||||
|
|
|
@ -12,6 +12,9 @@ struct UserProfileView: View {
|
|||
let userId: Int
|
||||
@StateObject var viewModel = UserProfileViewModel()
|
||||
|
||||
@State private var memberId: Int = 0
|
||||
@State private var isShowMemberProfilePopup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { proxy in
|
||||
BaseView(isLoading: $viewModel.isLoading) {
|
||||
|
@ -196,6 +199,10 @@ struct UserProfileView: View {
|
|||
viewModel.cheersId = cheerId
|
||||
viewModel.isShowCheersDeleteView = true
|
||||
},
|
||||
profilePopup: {
|
||||
self.memberId = $0
|
||||
self.isShowMemberProfilePopup = true
|
||||
},
|
||||
isLoading: $viewModel.isLoading
|
||||
)
|
||||
.padding(.top, 26.7)
|
||||
|
@ -311,6 +318,10 @@ struct UserProfileView: View {
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
if isShowMemberProfilePopup {
|
||||
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||
}
|
||||
}
|
||||
}
|
||||
.sheet(
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// GetMemberProfileResponse.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 9/7/24.
|
||||
//
|
||||
|
||||
struct GetMemberProfileResponse: Decodable {
|
||||
let memberId: Int
|
||||
let nickname: String
|
||||
let profileImageUrl: String
|
||||
let isBlocked: Bool
|
||||
}
|
|
@ -33,6 +33,7 @@ enum UserApi {
|
|||
case checkNickname(nickname: String)
|
||||
case changeNickname(request: ProfileUpdateRequest)
|
||||
case updateIdfa(request: IdfaUpdateRequest)
|
||||
case getMemberProfile(memberId: Int)
|
||||
}
|
||||
|
||||
extension UserApi: TargetType {
|
||||
|
@ -80,10 +81,10 @@ extension UserApi: TargetType {
|
|||
|
||||
case .creatorUnFollow:
|
||||
return "/member/creator/unfollow"
|
||||
|
||||
|
||||
case .getBlockedMemberIdList:
|
||||
return "/member/block/id"
|
||||
|
||||
|
||||
case .getBlockedMemberList, .memberBlock:
|
||||
return "/member/block"
|
||||
|
||||
|
@ -107,6 +108,9 @@ extension UserApi: TargetType {
|
|||
|
||||
case .updateIdfa:
|
||||
return "/member/adid/update"
|
||||
|
||||
case .getMemberProfile(let memberId):
|
||||
return "/member/profile/\(memberId)"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +120,7 @@ extension UserApi: TargetType {
|
|||
.profileImageUpdate:
|
||||
return .post
|
||||
|
||||
case .searchUser, .getMypage, .getMemberInfo, .getMyProfile, .getChangeNicknamePrice, .checkNickname, .getBlockedMemberList, .getBlockedMemberIdList:
|
||||
case .searchUser, .getMypage, .getMemberInfo, .getMyProfile, .getChangeNicknamePrice, .checkNickname, .getBlockedMemberList, .getBlockedMemberIdList, .getMemberProfile:
|
||||
return .get
|
||||
|
||||
case .updatePushToken, .profileUpdate, .changeNickname, .updateIdfa:
|
||||
|
@ -141,7 +145,7 @@ extension UserApi: TargetType {
|
|||
case .getMypage, .getMyProfile, .getMemberInfo:
|
||||
return .requestParameters(parameters: ["container" : "ios"], encoding: URLEncoding.queryString)
|
||||
|
||||
case .logout, .logoutAllDevice, .getChangeNicknamePrice, .getBlockedMemberIdList:
|
||||
case .logout, .logoutAllDevice, .getChangeNicknamePrice, .getBlockedMemberIdList, .getMemberProfile:
|
||||
return .requestPlain
|
||||
|
||||
case .notification(let request):
|
||||
|
|
|
@ -120,4 +120,8 @@ final class UserRepository {
|
|||
func updateIdfa(request: IdfaUpdateRequest) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.updateIdfa(request: request))
|
||||
}
|
||||
|
||||
func getMemberProfile(memberId: Int) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getMemberProfile(memberId: memberId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
//
|
||||
// UserViewModel.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 9/7/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Moya
|
||||
import Combine
|
||||
|
||||
final class UserViewModel: ObservableObject {
|
||||
private let repository = UserRepository()
|
||||
private let reportRepository = ReportRepository()
|
||||
private var subscription = Set<AnyCancellable>()
|
||||
|
||||
@Published var isLoading = false
|
||||
@Published var errorMessage = ""
|
||||
@Published var isShowPopup = false
|
||||
|
||||
@Published var memberId = 0
|
||||
@Published var nickname = ""
|
||||
@Published var dismissDialog = false
|
||||
|
||||
@Published var isShowUesrBlockConfirm = false
|
||||
@Published var isShowUesrReportView = false
|
||||
@Published var isShowProfileReportConfirm = false
|
||||
|
||||
@Published var memberProfile: GetMemberProfileResponse?
|
||||
|
||||
func getMemberProfile(memberId: Int) {
|
||||
isLoading = true
|
||||
|
||||
repository.getMemberProfile(memberId: memberId)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
}
|
||||
} receiveValue: { [unowned self] response in
|
||||
let responseData = response.data
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponse<GetMemberProfileResponse>.self, from: responseData)
|
||||
|
||||
if let data = decoded.data, decoded.success {
|
||||
self.memberProfile = data
|
||||
self.memberId = data.memberId
|
||||
self.nickname = data.nickname
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
|
||||
self.isLoading = false
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
func memberBlock() {
|
||||
isLoading = true
|
||||
repository.memberBlock(userId: memberId)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
}
|
||||
} receiveValue: { [unowned self] response in
|
||||
self.isLoading = false
|
||||
let responseData = response.data
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
self.errorMessage = "차단하였습니다."
|
||||
self.dismissDialog = true
|
||||
|
||||
self.memberId = 0
|
||||
self.nickname = ""
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
func memberUnBlock() {
|
||||
isLoading = true
|
||||
repository.memberUnBlock(userId: memberId)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
}
|
||||
} receiveValue: { [unowned self] response in
|
||||
self.isLoading = false
|
||||
let responseData = response.data
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
self.errorMessage = "차단이 해제 되었습니다."
|
||||
self.dismissDialog = true
|
||||
|
||||
self.memberId = 0
|
||||
self.nickname = ""
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
func report(type: ReportType, reason: String = "프로필 신고") {
|
||||
isLoading = true
|
||||
|
||||
let request = ReportRequest(type: type, reason: reason, reportedMemberId: memberId, cheersId: nil, audioContentId: nil)
|
||||
reportRepository.report(request: request)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
}
|
||||
} receiveValue: { [unowned self] response in
|
||||
self.isLoading = false
|
||||
let responseData = response.data
|
||||
|
||||
self.memberId = 0
|
||||
self.nickname = ""
|
||||
self.dismissDialog = true
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue