parent
17ead38524
commit
7c5b30335e
|
@ -17,6 +17,7 @@ struct AudioContentCommentItemView: View {
|
||||||
|
|
||||||
let modifyComment: (Int, String) -> Void
|
let modifyComment: (Int, String) -> Void
|
||||||
let onClickDelete: (Int) -> Void
|
let onClickDelete: (Int) -> Void
|
||||||
|
let onClickProfile: (Int) -> Void
|
||||||
|
|
||||||
@State var isShowPopupMenu: Bool = false
|
@State var isShowPopupMenu: Bool = false
|
||||||
@State var isModeModify: Bool = false
|
@State var isModeModify: Bool = false
|
||||||
|
@ -30,6 +31,11 @@ struct AudioContentCommentItemView: View {
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
|
.onTapGesture {
|
||||||
|
if UserDefaults.int(forKey: .userId) != commentItem.writerId {
|
||||||
|
onClickProfile(commentItem.writerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
HStack(spacing: 6.7) {
|
HStack(spacing: 6.7) {
|
||||||
|
@ -95,8 +101,8 @@ struct AudioContentCommentItemView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
.accentColor(Color(hex: "3bb9f1"))
|
.accentColor(Color.button)
|
||||||
.keyboardType(.default)
|
.keyboardType(.default)
|
||||||
.padding(.horizontal, 13.3)
|
.padding(.horizontal, 13.3)
|
||||||
|
|
||||||
|
@ -114,7 +120,7 @@ struct AudioContentCommentItemView: View {
|
||||||
isModeModify = false
|
isModeModify = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.background(Color(hex: "232323"))
|
.background(Color.gray23)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 10)
|
RoundedRectangle(cornerRadius: 10)
|
||||||
|
@ -151,7 +157,7 @@ struct AudioContentCommentItemView: View {
|
||||||
.padding(.leading, 46.7)
|
.padding(.leading, 46.7)
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.foregroundColor(Color(hex: "595959"))
|
.foregroundColor(Color.gray59)
|
||||||
.frame(height: 0.5)
|
.frame(height: 0.5)
|
||||||
.padding(.top, 16.7)
|
.padding(.top, 16.7)
|
||||||
}
|
}
|
||||||
|
@ -161,7 +167,7 @@ struct AudioContentCommentItemView: View {
|
||||||
if commentItem.writerId == UserDefaults.int(forKey: .userId) {
|
if commentItem.writerId == UserDefaults.int(forKey: .userId) {
|
||||||
Text("수정")
|
Text("수정")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14))
|
.font(.custom(Font.medium.rawValue, size: 14))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
isModeModify = true
|
isModeModify = true
|
||||||
isShowPopupMenu = false
|
isShowPopupMenu = false
|
||||||
|
@ -173,7 +179,7 @@ struct AudioContentCommentItemView: View {
|
||||||
{
|
{
|
||||||
Text("삭제")
|
Text("삭제")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14))
|
.font(.custom(Font.medium.rawValue, size: 14))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
onClickDelete(commentItem.id)
|
onClickDelete(commentItem.id)
|
||||||
isShowPopupMenu = false
|
isShowPopupMenu = false
|
||||||
|
@ -181,7 +187,7 @@ struct AudioContentCommentItemView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.background(Color(hex: "222222"))
|
.background(Color.gray22)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear { comment = commentItem.comment }
|
.onAppear { comment = commentItem.comment }
|
||||||
|
|
|
@ -21,6 +21,9 @@ struct AudioContentCommentListView: View {
|
||||||
@State private var commentId: Int = 0
|
@State private var commentId: Int = 0
|
||||||
@State private var isShowDeletePopup: Bool = false
|
@State private var isShowDeletePopup: Bool = false
|
||||||
|
|
||||||
|
@State private var memberId: Int = 0
|
||||||
|
@State private var isShowMemberProfilePopup: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
ZStack {
|
ZStack {
|
||||||
|
@ -137,6 +140,10 @@ struct AudioContentCommentListView: View {
|
||||||
onClickDelete: {
|
onClickDelete: {
|
||||||
commentId = $0
|
commentId = $0
|
||||||
isShowDeletePopup = true
|
isShowDeletePopup = true
|
||||||
|
},
|
||||||
|
onClickProfile: {
|
||||||
|
memberId = $0
|
||||||
|
isShowMemberProfilePopup = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 26.7)
|
.padding(.horizontal, 26.7)
|
||||||
|
@ -169,6 +176,10 @@ struct AudioContentCommentListView: View {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isShowMemberProfilePopup {
|
||||||
|
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||||
|
}
|
||||||
|
|
||||||
if viewModel.isLoading {
|
if viewModel.isLoading {
|
||||||
LoadingView()
|
LoadingView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ struct AudioContentListReplyView: View {
|
||||||
@State private var commentId: Int = 0
|
@State private var commentId: Int = 0
|
||||||
@State private var isShowDeletePopup: Bool = false
|
@State private var isShowDeletePopup: Bool = false
|
||||||
|
|
||||||
|
@State private var memberId: Int = 0
|
||||||
|
@State private var isShowMemberProfilePopup: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
@ -98,7 +101,11 @@ struct AudioContentListReplyView: View {
|
||||||
isReplyComment: true,
|
isReplyComment: true,
|
||||||
isShowPopupMenuButton: false,
|
isShowPopupMenuButton: false,
|
||||||
modifyComment: { _, _ in },
|
modifyComment: { _, _ in },
|
||||||
onClickDelete: { _ in }
|
onClickDelete: { _ in },
|
||||||
|
onClickProfile: {
|
||||||
|
memberId = $0
|
||||||
|
isShowMemberProfilePopup = true
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 26.7)
|
.padding(.horizontal, 26.7)
|
||||||
.padding(.bottom, 13.3)
|
.padding(.bottom, 13.3)
|
||||||
|
@ -120,6 +127,10 @@ struct AudioContentListReplyView: View {
|
||||||
onClickDelete: {
|
onClickDelete: {
|
||||||
commentId = $0
|
commentId = $0
|
||||||
isShowDeletePopup = true
|
isShowDeletePopup = true
|
||||||
|
},
|
||||||
|
onClickProfile: {
|
||||||
|
memberId = $0
|
||||||
|
isShowMemberProfilePopup = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 40)
|
.padding(.horizontal, 40)
|
||||||
|
@ -153,6 +164,10 @@ struct AudioContentListReplyView: View {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isShowMemberProfilePopup {
|
||||||
|
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||||
|
}
|
||||||
|
|
||||||
if viewModel.isLoading {
|
if viewModel.isLoading {
|
||||||
LoadingView()
|
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 modifyComment: (Int, String) -> Void
|
||||||
let onClickDelete: (Int) -> Void
|
let onClickDelete: (Int) -> Void
|
||||||
|
let onClickProfile: (Int) -> Void
|
||||||
|
|
||||||
@State var isShowPopupMenu: Bool = false
|
@State var isShowPopupMenu: Bool = false
|
||||||
@State var isModeModify: Bool = false
|
@State var isModeModify: Bool = false
|
||||||
|
@ -30,6 +31,11 @@ struct CreatorCommunityCommentItemView: View {
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
|
.onTapGesture {
|
||||||
|
if UserDefaults.int(forKey: .userId) != commentItem.writerId {
|
||||||
|
onClickProfile(commentItem.writerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
Text(commentItem.nickname)
|
Text(commentItem.nickname)
|
||||||
|
@ -38,7 +44,7 @@ struct CreatorCommunityCommentItemView: View {
|
||||||
|
|
||||||
Text(commentItem.date)
|
Text(commentItem.date)
|
||||||
.font(.custom(Font.medium.rawValue, size: 10.3))
|
.font(.custom(Font.medium.rawValue, size: 10.3))
|
||||||
.foregroundColor(Color(hex: "525252"))
|
.foregroundColor(Color.gray52)
|
||||||
.padding(.top, 4)
|
.padding(.top, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +63,8 @@ struct CreatorCommunityCommentItemView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
.accentColor(Color(hex: "3bb9f1"))
|
.accentColor(Color.button)
|
||||||
.keyboardType(.default)
|
.keyboardType(.default)
|
||||||
.padding(.horizontal, 13.3)
|
.padding(.horizontal, 13.3)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ struct CreatorCommunityCommentListView: View {
|
||||||
|
|
||||||
@State private var commentId: Int = 0
|
@State private var commentId: Int = 0
|
||||||
@State private var isShowDeletePopup: Bool = false
|
@State private var isShowDeletePopup: Bool = false
|
||||||
|
|
||||||
|
@State private var memberId: Int = 0
|
||||||
|
@State private var isShowMemberProfilePopup: Bool = false
|
||||||
|
|
||||||
@StateObject var viewModel = CreatorCommunityCommentListViewModel()
|
@StateObject var viewModel = CreatorCommunityCommentListViewModel()
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -115,6 +119,10 @@ struct CreatorCommunityCommentListView: View {
|
||||||
onClickDelete: {
|
onClickDelete: {
|
||||||
commentId = $0
|
commentId = $0
|
||||||
isShowDeletePopup = true
|
isShowDeletePopup = true
|
||||||
|
},
|
||||||
|
onClickProfile: {
|
||||||
|
memberId = $0
|
||||||
|
isShowMemberProfilePopup = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 26.7)
|
.padding(.horizontal, 26.7)
|
||||||
|
@ -147,6 +155,10 @@ struct CreatorCommunityCommentListView: View {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isShowMemberProfilePopup {
|
||||||
|
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||||
|
}
|
||||||
|
|
||||||
if viewModel.isLoading {
|
if viewModel.isLoading {
|
||||||
LoadingView()
|
LoadingView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ struct CreatorCommunityCommentReplyView: View {
|
||||||
@State private var commentId: Int = 0
|
@State private var commentId: Int = 0
|
||||||
@State private var isShowDeletePopup: Bool = false
|
@State private var isShowDeletePopup: Bool = false
|
||||||
|
|
||||||
|
@State private var memberId: Int = 0
|
||||||
|
@State private var isShowMemberProfilePopup: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
@ -98,7 +101,11 @@ struct CreatorCommunityCommentReplyView: View {
|
||||||
isReplyComment: true,
|
isReplyComment: true,
|
||||||
isShowPopupMenuButton: false,
|
isShowPopupMenuButton: false,
|
||||||
modifyComment: { _, _ in },
|
modifyComment: { _, _ in },
|
||||||
onClickDelete: { _ in }
|
onClickDelete: { _ in },
|
||||||
|
onClickProfile: {
|
||||||
|
memberId = $0
|
||||||
|
isShowMemberProfilePopup = true
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 26.7)
|
.padding(.horizontal, 26.7)
|
||||||
.padding(.bottom, 13.3)
|
.padding(.bottom, 13.3)
|
||||||
|
@ -120,6 +127,10 @@ struct CreatorCommunityCommentReplyView: View {
|
||||||
onClickDelete: {
|
onClickDelete: {
|
||||||
commentId = $0
|
commentId = $0
|
||||||
isShowDeletePopup = true
|
isShowDeletePopup = true
|
||||||
|
},
|
||||||
|
onClickProfile: {
|
||||||
|
memberId = $0
|
||||||
|
isShowMemberProfilePopup = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 26.7)
|
.padding(.horizontal, 26.7)
|
||||||
|
@ -154,6 +165,10 @@ struct CreatorCommunityCommentReplyView: View {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isShowMemberProfilePopup {
|
||||||
|
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||||
|
}
|
||||||
|
|
||||||
if viewModel.isLoading {
|
if viewModel.isLoading {
|
||||||
LoadingView()
|
LoadingView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ struct UserProfileFanTalkAllView: View {
|
||||||
@State private var cheersContent: String = ""
|
@State private var cheersContent: String = ""
|
||||||
@State private var cheersId: Int = 0
|
@State private var cheersId: Int = 0
|
||||||
|
|
||||||
|
@State private var memberId: Int = 0
|
||||||
|
@State private var isShowMemberProfilePopup: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { proxy in
|
GeometryReader { proxy in
|
||||||
BaseView(isLoading: $viewModel.isLoading) {
|
BaseView(isLoading: $viewModel.isLoading) {
|
||||||
|
@ -26,17 +29,17 @@ struct UserProfileFanTalkAllView: View {
|
||||||
HStack(spacing: 6.7) {
|
HStack(spacing: 6.7) {
|
||||||
Text("응원")
|
Text("응원")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
Text("\(viewModel.cheersTotalCount)")
|
Text("\(viewModel.cheersTotalCount)")
|
||||||
.font(.custom(Font.medium.rawValue, size: 12))
|
.font(.custom(Font.medium.rawValue, size: 12))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
.padding(.top, 20)
|
.padding(.top, 20)
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
.foregroundColor(Color.gray90.opacity(0.5))
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
|
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
|
@ -44,8 +47,8 @@ struct UserProfileFanTalkAllView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
.accentColor(Color(hex: "3bb9f1"))
|
.accentColor(Color.button)
|
||||||
.keyboardType(.default)
|
.keyboardType(.default)
|
||||||
.padding(.horizontal, 13.3)
|
.padding(.horizontal, 13.3)
|
||||||
|
|
||||||
|
@ -61,18 +64,18 @@ struct UserProfileFanTalkAllView: View {
|
||||||
cheersContent = ""
|
cheersContent = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.background(Color(hex: "232323"))
|
.background(Color.gray23)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 10)
|
RoundedRectangle(cornerRadius: 10)
|
||||||
.strokeBorder(lineWidth: 1)
|
.strokeBorder(lineWidth: 1)
|
||||||
.foregroundColor(Color(hex: "3bb9f1"))
|
.foregroundColor(Color.button)
|
||||||
)
|
)
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
.foregroundColor(Color.gray90.opacity(0.5))
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
|
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
|
@ -96,6 +99,10 @@ struct UserProfileFanTalkAllView: View {
|
||||||
onClickDelete: { cheersId in
|
onClickDelete: { cheersId in
|
||||||
self.cheersId = cheersId
|
self.cheersId = cheersId
|
||||||
viewModel.isShowCheersDeleteView = true
|
viewModel.isShowCheersDeleteView = true
|
||||||
|
},
|
||||||
|
onClickProfile: {
|
||||||
|
self.memberId = $0
|
||||||
|
self.isShowMemberProfilePopup = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
|
@ -110,7 +117,7 @@ struct UserProfileFanTalkAllView: View {
|
||||||
} else {
|
} else {
|
||||||
Text("응원이 없습니다.\n\n처음으로 응원을 해보세요!")
|
Text("응원이 없습니다.\n\n처음으로 응원을 해보세요!")
|
||||||
.font(.custom(Font.light.rawValue, size: 13.3))
|
.font(.custom(Font.light.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "bbbbbb"))
|
.foregroundColor(Color.graybb)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
.padding(.vertical, 60)
|
.padding(.vertical, 60)
|
||||||
|
@ -136,7 +143,7 @@ struct UserProfileFanTalkAllView: View {
|
||||||
.padding(.vertical, 13.3)
|
.padding(.vertical, 13.3)
|
||||||
.frame(width: screenSize().width - 66.7, alignment: .center)
|
.frame(width: screenSize().width - 66.7, alignment: .center)
|
||||||
.font(.custom(Font.medium.rawValue, size: 12))
|
.font(.custom(Font.medium.rawValue, size: 12))
|
||||||
.background(Color(hex: "9970ff"))
|
.background(Color.button)
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
.multilineTextAlignment(.leading)
|
.multilineTextAlignment(.leading)
|
||||||
.cornerRadius(20)
|
.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 modifyCheer: (Int, String) -> Void
|
||||||
let reportPopup: (Int) -> Void
|
let reportPopup: (Int) -> Void
|
||||||
let onClickDelete: (Int) -> Void
|
let onClickDelete: (Int) -> Void
|
||||||
|
let onClickProfile: (Int) -> Void
|
||||||
|
|
||||||
@State var replyContent: String = ""
|
@State var replyContent: String = ""
|
||||||
@State var isShowInputReply = false
|
@State var isShowInputReply = false
|
||||||
|
@ -34,6 +35,11 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 33.3, height: 33.3)
|
.frame(width: 33.3, height: 33.3)
|
||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
|
.onTapGesture {
|
||||||
|
if UserDefaults.int(forKey: .userId) != cheersItem.memberId {
|
||||||
|
onClickProfile(cheersItem.memberId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
Text("\(cheersItem.nickname)")
|
Text("\(cheersItem.nickname)")
|
||||||
|
@ -51,10 +57,10 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
.padding(13.3)
|
.padding(13.3)
|
||||||
.background(Color(hex: "232323"))
|
.background(Color.gray23)
|
||||||
.accentColor(Color(hex: "3bb9f1"))
|
.accentColor(Color.button)
|
||||||
.keyboardType(.default)
|
.keyboardType(.default)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.overlay(
|
.overlay(
|
||||||
|
@ -65,7 +71,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
|
|
||||||
Text("수정")
|
Text("수정")
|
||||||
.font(.custom(Font.bold.rawValue, size: 13.3))
|
.font(.custom(Font.bold.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "ffffff"))
|
.foregroundColor(Color.white)
|
||||||
.padding(13.3)
|
.padding(13.3)
|
||||||
.background(Color.button)
|
.background(Color.button)
|
||||||
.cornerRadius(6.7)
|
.cornerRadius(6.7)
|
||||||
|
@ -78,7 +84,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
.font(.custom(Font.bold.rawValue, size: 13.3))
|
.font(.custom(Font.bold.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color.button)
|
.foregroundColor(Color.button)
|
||||||
.padding(13.3)
|
.padding(13.3)
|
||||||
.background(Color(hex: "222222"))
|
.background(Color.gray22)
|
||||||
.cornerRadius(6.7)
|
.cornerRadius(6.7)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
isModeModify = false
|
isModeModify = false
|
||||||
|
@ -100,23 +106,23 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
.padding(13.3)
|
.padding(13.3)
|
||||||
.background(Color(hex: "232323"))
|
.background(Color.gray23)
|
||||||
.accentColor(Color(hex: "3bb9f1"))
|
.accentColor(Color.button)
|
||||||
.keyboardType(.default)
|
.keyboardType(.default)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 10)
|
RoundedRectangle(cornerRadius: 10)
|
||||||
.strokeBorder(lineWidth: 1)
|
.strokeBorder(lineWidth: 1)
|
||||||
.foregroundColor(Color(hex: "3bb9f1"))
|
.foregroundColor(Color.button)
|
||||||
)
|
)
|
||||||
|
|
||||||
Text("등록")
|
Text("등록")
|
||||||
.font(.custom(Font.bold.rawValue, size: 13.3))
|
.font(.custom(Font.bold.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "ffffff"))
|
.foregroundColor(Color.white)
|
||||||
.padding(13.3)
|
.padding(13.3)
|
||||||
.background(Color(hex: "3bb9f1"))
|
.background(Color.button)
|
||||||
.cornerRadius(6.7)
|
.cornerRadius(6.7)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
if cheersItem.replyList.count > 0 {
|
if cheersItem.replyList.count > 0 {
|
||||||
|
@ -182,7 +188,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
.foregroundColor(Color.gray90.opacity(0.5))
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
}
|
}
|
||||||
.frame(width: screenSize().width - 26.7)
|
.frame(width: screenSize().width - 26.7)
|
||||||
|
@ -192,7 +198,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
if cheersItem.memberId != UserDefaults.int(forKey: .userId) {
|
if cheersItem.memberId != UserDefaults.int(forKey: .userId) {
|
||||||
Text("신고하기")
|
Text("신고하기")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14))
|
.font(.custom(Font.medium.rawValue, size: 14))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
reportPopup(cheersItem.cheersId)
|
reportPopup(cheersItem.cheersId)
|
||||||
isShowPopupMenu = false
|
isShowPopupMenu = false
|
||||||
|
@ -202,7 +208,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
if cheersItem.memberId == UserDefaults.int(forKey: .userId) {
|
if cheersItem.memberId == UserDefaults.int(forKey: .userId) {
|
||||||
Text("수정")
|
Text("수정")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14))
|
.font(.custom(Font.medium.rawValue, size: 14))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
isModeModify = true
|
isModeModify = true
|
||||||
isShowPopupMenu = false
|
isShowPopupMenu = false
|
||||||
|
@ -215,7 +221,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
{
|
{
|
||||||
Text("삭제")
|
Text("삭제")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14))
|
.font(.custom(Font.medium.rawValue, size: 14))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
onClickDelete(cheersItem.cheersId)
|
onClickDelete(cheersItem.cheersId)
|
||||||
isShowPopupMenu = false
|
isShowPopupMenu = false
|
||||||
|
@ -223,7 +229,7 @@ struct UserProfileFanTalkCheersItemView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.background(Color(hex: "222222"))
|
.background(Color.gray22)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
|
|
|
@ -17,6 +17,7 @@ struct UserProfileFanTalkView: View {
|
||||||
let errorPopup: (String) -> Void
|
let errorPopup: (String) -> Void
|
||||||
let reportPopup: (Int) -> Void
|
let reportPopup: (Int) -> Void
|
||||||
let deletePopup: (Int) -> Void
|
let deletePopup: (Int) -> Void
|
||||||
|
let profilePopup: (Int) -> Void
|
||||||
|
|
||||||
@Binding var isLoading: Bool
|
@Binding var isLoading: Bool
|
||||||
@State private var cheersContent: String = ""
|
@State private var cheersContent: String = ""
|
||||||
|
@ -26,13 +27,13 @@ struct UserProfileFanTalkView: View {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
Text("팬 Talk")
|
Text("팬 Talk")
|
||||||
.font(.custom(Font.bold.rawValue, size: 16.7))
|
.font(.custom(Font.bold.rawValue, size: 16.7))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Text("전체보기")
|
Text("전체보기")
|
||||||
.font(.custom(Font.light.rawValue, size: 11.3))
|
.font(.custom(Font.light.rawValue, size: 11.3))
|
||||||
.foregroundColor(Color(hex: "bbbbbb"))
|
.foregroundColor(Color.graybb)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
AppState.shared.setAppStep(step: .userProfileFanTalkAll(userId: userId))
|
AppState.shared.setAppStep(step: .userProfileFanTalkAll(userId: userId))
|
||||||
}
|
}
|
||||||
|
@ -43,17 +44,17 @@ struct UserProfileFanTalkView: View {
|
||||||
HStack(spacing: 6.7) {
|
HStack(spacing: 6.7) {
|
||||||
Text("응원")
|
Text("응원")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
Text("\(cheers.totalCount)")
|
Text("\(cheers.totalCount)")
|
||||||
.font(.custom(Font.medium.rawValue, size: 12))
|
.font(.custom(Font.medium.rawValue, size: 12))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
.padding(.top, 20)
|
.padding(.top, 20)
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
.foregroundColor(Color.gray90.opacity(0.5))
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
|
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
|
@ -61,8 +62,8 @@ struct UserProfileFanTalkView: View {
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
.accentColor(Color(hex: "3bb9f1"))
|
.accentColor(Color.button)
|
||||||
.keyboardType(.default)
|
.keyboardType(.default)
|
||||||
.padding(.horizontal, 13.3)
|
.padding(.horizontal, 13.3)
|
||||||
|
|
||||||
|
@ -78,18 +79,18 @@ struct UserProfileFanTalkView: View {
|
||||||
cheersContent = ""
|
cheersContent = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.background(Color(hex: "232323"))
|
.background(Color.gray23)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 10)
|
RoundedRectangle(cornerRadius: 10)
|
||||||
.strokeBorder(lineWidth: 1)
|
.strokeBorder(lineWidth: 1)
|
||||||
.foregroundColor(Color(hex: "9970ff"))
|
.foregroundColor(Color.button)
|
||||||
)
|
)
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
.foregroundColor(Color(hex: "909090").opacity(0.5))
|
.foregroundColor(Color.gray90.opacity(0.5))
|
||||||
.padding(.top, 13.3)
|
.padding(.top, 13.3)
|
||||||
|
|
||||||
VStack(spacing: 20) {
|
VStack(spacing: 20) {
|
||||||
|
@ -110,6 +111,9 @@ struct UserProfileFanTalkView: View {
|
||||||
},
|
},
|
||||||
onClickDelete: { cheersId in
|
onClickDelete: { cheersId in
|
||||||
deletePopup(cheersId)
|
deletePopup(cheersId)
|
||||||
|
},
|
||||||
|
onClickProfile: {
|
||||||
|
profilePopup($0)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
|
@ -119,7 +123,7 @@ struct UserProfileFanTalkView: View {
|
||||||
} else {
|
} else {
|
||||||
Text("응원이 없습니다.\n\n처음으로 응원을 해보세요!")
|
Text("응원이 없습니다.\n\n처음으로 응원을 해보세요!")
|
||||||
.font(.custom(Font.light.rawValue, size: 13.3))
|
.font(.custom(Font.light.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "bbbbbb"))
|
.foregroundColor(Color.graybb)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
.padding(.vertical, 60)
|
.padding(.vertical, 60)
|
||||||
|
|
|
@ -12,6 +12,9 @@ struct UserProfileView: View {
|
||||||
let userId: Int
|
let userId: Int
|
||||||
@StateObject var viewModel = UserProfileViewModel()
|
@StateObject var viewModel = UserProfileViewModel()
|
||||||
|
|
||||||
|
@State private var memberId: Int = 0
|
||||||
|
@State private var isShowMemberProfilePopup: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { proxy in
|
GeometryReader { proxy in
|
||||||
BaseView(isLoading: $viewModel.isLoading) {
|
BaseView(isLoading: $viewModel.isLoading) {
|
||||||
|
@ -196,6 +199,10 @@ struct UserProfileView: View {
|
||||||
viewModel.cheersId = cheerId
|
viewModel.cheersId = cheerId
|
||||||
viewModel.isShowCheersDeleteView = true
|
viewModel.isShowCheersDeleteView = true
|
||||||
},
|
},
|
||||||
|
profilePopup: {
|
||||||
|
self.memberId = $0
|
||||||
|
self.isShowMemberProfilePopup = true
|
||||||
|
},
|
||||||
isLoading: $viewModel.isLoading
|
isLoading: $viewModel.isLoading
|
||||||
)
|
)
|
||||||
.padding(.top, 26.7)
|
.padding(.top, 26.7)
|
||||||
|
@ -311,6 +318,10 @@ struct UserProfileView: View {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isShowMemberProfilePopup {
|
||||||
|
MemberProfileDialog(isShowing: $isShowMemberProfilePopup, memberId: memberId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sheet(
|
.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 checkNickname(nickname: String)
|
||||||
case changeNickname(request: ProfileUpdateRequest)
|
case changeNickname(request: ProfileUpdateRequest)
|
||||||
case updateIdfa(request: IdfaUpdateRequest)
|
case updateIdfa(request: IdfaUpdateRequest)
|
||||||
|
case getMemberProfile(memberId: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UserApi: TargetType {
|
extension UserApi: TargetType {
|
||||||
|
@ -107,6 +108,9 @@ extension UserApi: TargetType {
|
||||||
|
|
||||||
case .updateIdfa:
|
case .updateIdfa:
|
||||||
return "/member/adid/update"
|
return "/member/adid/update"
|
||||||
|
|
||||||
|
case .getMemberProfile(let memberId):
|
||||||
|
return "/member/profile/\(memberId)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +120,7 @@ extension UserApi: TargetType {
|
||||||
.profileImageUpdate:
|
.profileImageUpdate:
|
||||||
return .post
|
return .post
|
||||||
|
|
||||||
case .searchUser, .getMypage, .getMemberInfo, .getMyProfile, .getChangeNicknamePrice, .checkNickname, .getBlockedMemberList, .getBlockedMemberIdList:
|
case .searchUser, .getMypage, .getMemberInfo, .getMyProfile, .getChangeNicknamePrice, .checkNickname, .getBlockedMemberList, .getBlockedMemberIdList, .getMemberProfile:
|
||||||
return .get
|
return .get
|
||||||
|
|
||||||
case .updatePushToken, .profileUpdate, .changeNickname, .updateIdfa:
|
case .updatePushToken, .profileUpdate, .changeNickname, .updateIdfa:
|
||||||
|
@ -141,7 +145,7 @@ extension UserApi: TargetType {
|
||||||
case .getMypage, .getMyProfile, .getMemberInfo:
|
case .getMypage, .getMyProfile, .getMemberInfo:
|
||||||
return .requestParameters(parameters: ["container" : "ios"], encoding: URLEncoding.queryString)
|
return .requestParameters(parameters: ["container" : "ios"], encoding: URLEncoding.queryString)
|
||||||
|
|
||||||
case .logout, .logoutAllDevice, .getChangeNicknamePrice, .getBlockedMemberIdList:
|
case .logout, .logoutAllDevice, .getChangeNicknamePrice, .getBlockedMemberIdList, .getMemberProfile:
|
||||||
return .requestPlain
|
return .requestPlain
|
||||||
|
|
||||||
case .notification(let request):
|
case .notification(let request):
|
||||||
|
|
|
@ -120,4 +120,8 @@ final class UserRepository {
|
||||||
func updateIdfa(request: IdfaUpdateRequest) -> AnyPublisher<Response, MoyaError> {
|
func updateIdfa(request: IdfaUpdateRequest) -> AnyPublisher<Response, MoyaError> {
|
||||||
return api.requestPublisher(.updateIdfa(request: request))
|
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