Files
SodaLive
Preview Content
Resources
Sources
Agora
App
Audition
Common
Content
CustomView
Debug
Dialog
Explorer
Extensions
Follow
Font
FortuneWheel
IAP
ImagePicker
Keyboard
Live
Main
Message
Text
Voice
Write
GetVoiceMessageResponse.swift
SoundManager.swift
VoiceMessageItemView.swift
VoiceMessageView.swift
VoiceMessageViewModel.swift
KeepMessageRequest.swift
MessageApi.swift
MessageFilterTab.swift
MessageFilterTabView.swift
MessageRepository.swift
MessageView.swift
MessageViewModel.swift
SendMessageRequest.swift
MyPage
NavigationBar
Onboarding
Report
Settings
Shape
Splash
UI
User
Utils
ContentView.swift
SodaLive.entitlements
SodaLive.xcworkspace
generated
.gitignore
Podfile
Podfile.lock
SodaLive-dev.entitlements
model-SodaLive-dev.json
model-SodaLive.json
sodalive-ios/SodaLive/Sources/Message/Voice/VoiceMessageView.swift

209 lines
9.7 KiB
Swift

//
// VoiceMessageView.swift
// SodaLive
//
// Created by klaus on 2023/08/10.
//
import SwiftUI
struct VoiceMessageView: View {
@StateObject var viewModel = VoiceMessageViewModel()
@StateObject var soundManager = SoundManager()
var body: some View {
ZStack {
Color.black.ignoresSafeArea()
ZStack(alignment: .bottomTrailing) {
VStack(spacing: 13.3) {
MessageFilterTabView(currentFilterTab: $viewModel.currentFilter)
.padding(.top, 20)
ScrollView(.vertical, showsIndicators: false) {
if viewModel.items.count > 0 {
VStack(spacing: 26.7) {
ForEach(0..<viewModel.items.count, id: \.self) { index in
let item = viewModel.items[index]
VoiceMessageItemView(
index: index,
item: item,
currentFilter: viewModel.currentFilter,
soundManager: soundManager,
openPlayerItemIndex: $viewModel.openPlayerItemIndex,
onClickSave: {
viewModel.selectedMessageId = item.messageId
soundManager.stopAudio()
if item.isKept {
viewModel.errorMessage = "이미 보관된 메시지 입니다"
viewModel.isShowPopup = true
return
} else {
viewModel.keepVoiceMessage()
}
},
onClickReply: {
viewModel.selectedMessageId = item.messageId
soundManager.stopAudio()
AppState.shared.setAppStep(
step: .writeVoiceMessage(
userId: item.senderId,
nickname: item.senderNickname,
onRefresh: {
viewModel.refresh()
}
)
)
},
onClickDelete: {
viewModel.selectedMessageId = item.messageId
soundManager.stopAudio()
viewModel.deleteMessage()
}
)
.onAppear {
if index == viewModel.items.count - 1 {
viewModel.loadMessage()
}
}
}
}
} else {
VStack(spacing: 6.7) {
Image("ic_no_item")
.resizable()
.frame(width: 60, height: 60)
Text("메시지가 없습니다.\n친구들과 소통해보세요!")
.multilineTextAlignment(.center)
.font(.custom(Font.medium.rawValue, size: 10.7))
.foregroundColor(Color(hex: "bbbbbb"))
}
.frame(width: screenSize().width - 26.7, height: screenSize().height / 2)
.background(Color(hex: "13181b"))
.cornerRadius(4.7)
}
}
}
Image("ic_make_voice")
.resizable()
.padding(13.3)
.frame(width: 53.3, height: 53.3)
.background(Color(hex: "3bb9f1"))
.cornerRadius(26.7)
.padding(.bottom, 33.3)
.onTapGesture {
AppState.shared.setAppStep(
step: .writeVoiceMessage(
userId: nil,
nickname: nil,
onRefresh: {
viewModel.refresh()
}
)
)
}
}
if viewModel.isShowSavePopup {
ZStack {
Color.black.opacity(0.7)
.ignoresSafeArea()
VStack(spacing: 0) {
Text("메시지 보관")
.font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "bbbbbb"))
.padding(.top, 40)
Text("메시지를 보관하는데\n\(viewModel.saveMessagePrice)캔이 필요합니다.\n메시지를 보관하시겠습니까?")
.font(.custom(Font.medium.rawValue, size: 15))
.foregroundColor(Color(hex: "bbbbbb"))
.padding(.top, 13.3)
.multilineTextAlignment(.center)
Text("※ 메시지 보관시, 본인이 삭제하기 전까지 영구보관됩니다.")
.font(.custom(Font.medium.rawValue, size: 12))
.foregroundColor(Color(hex: "bbbbbb"))
.padding(.top, 13.3)
.padding(.horizontal, 13.3)
.multilineTextAlignment(.center)
HStack(spacing: 13.3) {
Text("취소")
.font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "3bb9f1"))
.padding(.vertical, 16)
.frame(width: (screenSize().width - 66.7) / 3)
.background(Color(hex: "13181b"))
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(
Color(hex: "3bb9f1"),
lineWidth: 1
)
)
.onTapGesture {
viewModel.isShowSavePopup = false
}
Text("확인")
.font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(.white)
.padding(.vertical, 16)
.frame(width: (screenSize().width - 66.7) * 2 / 3)
.background(Color(hex: "3bb9f1"))
.cornerRadius(10)
.onTapGesture {
viewModel.isShowSavePopup = false
viewModel.keepTextMessage()
}
}
.padding(.vertical, 20)
.padding(.horizontal, 16.7)
}
.frame(width: screenSize().width - 26.7)
.background(Color(hex: "222222"))
.cornerRadius(10)
}
}
if viewModel.isLoading || soundManager.isLoading {
LoadingView()
}
}
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) {
GeometryReader { geo in
HStack {
Spacer()
Text(viewModel.errorMessage)
.padding(.vertical, 13.3)
.padding(.horizontal, 6.7)
.frame(width: geo.size.width - 66.7, alignment: .center)
.font(.custom(Font.medium.rawValue, size: 12))
.background(Color(hex: "3bb9f1"))
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.cornerRadius(20)
.padding(.top, 66.7)
Spacer()
}
}
}
.onAppear {
viewModel.refresh()
}
}
}
struct VoiceMessageView_Previews: PreviewProvider {
static var previews: some View {
VoiceMessageView()
}
}