sodalive-ios/SodaLive/Sources/Message/Voice/VoiceMessageItemView.swift

188 lines
6.9 KiB
Swift

//
// VoiceMessageItemView.swift
// SodaLive
//
// Created by klaus on 2023/08/10.
//
import SwiftUI
import Kingfisher
struct VoiceMessageItemView: View {
let index: Int
let item: VoiceMessageItem
let currentFilter: MessageFilterTab
let soundManager: SoundManager
@Binding var openPlayerItemIndex: Int
let onClickSave: () -> Void
let onClickReply: () -> Void
let onClickDelete: () -> Void
@State var progress: TimeInterval = 0
@State var timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
var body: some View {
let nickname = item.recipientNickname == UserDefaults.string(forKey: .nickname) ? item.senderNickname : item.recipientNickname
let profileUrl = item.recipientNickname == UserDefaults.string(forKey: .nickname) ? item.senderProfileImageUrl : item.recipientProfileImageUrl
VStack(spacing: 10) {
HStack(spacing: 0) {
KFImage(URL(string: profileUrl))
.resizable()
.scaledToFill()
.frame(width: 46.7, height: 46.7, alignment: .top)
.clipped()
.cornerRadius(23.4)
Text(nickname)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color(hex: "eeeeee"))
.padding(.leading, 13.3)
Spacer()
Text(item.date)
.font(.custom(Font.light.rawValue, size: 12))
.foregroundColor(Color(hex: "525252"))
}
.contentShape(Rectangle())
.onTapGesture {
openPlayerItemIndex = openPlayerItemIndex == index ? -1 : index
}
if openPlayerItemIndex == index {
VStack(spacing: 0) {
ProgressView(value: progress, total: soundManager.duration)
.progressViewStyle(LinearProgressViewStyle(tint: Color(hex: "9970ff")))
.padding(.horizontal, 13.3)
HStack(spacing: 0) {
Text("00:00")
.font(.custom(Font.medium.rawValue, size: 10.7))
.foregroundColor(Color(hex: "bbbbbb"))
Spacer()
Text("\(secondsToMinutesSeconds(seconds: Int(soundManager.duration)))")
.font(.custom(Font.medium.rawValue, size: 10.7))
.foregroundColor(Color(hex: "bbbbbb"))
}
.padding(.horizontal, 13.3)
.padding(.top, 6.7)
HStack(spacing: 0) {
Image("ic_save")
.resizable()
.frame(
width: currentFilter == .receive ? 27 : 22,
height: currentFilter == .receive ? 27 : 22
)
.opacity(currentFilter == .receive ? 1 : 0)
.onTapGesture {
if currentFilter == .receive {
onClickSave()
}
}
Spacer()
Image(soundManager.isPlaying ? "btn_bar_stop": "btn_bar_play")
.resizable()
.frame(width: 40, height: 40)
.onTapGesture {
if soundManager.isPlaying {
soundManager.stopAudio()
} else {
soundManager.playAudio()
}
}
Spacer()
if currentFilter == .receive {
Image("ic_mic_paint")
.resizable()
.frame(width: 27, height: 27)
.onTapGesture { onClickReply() }
}
if currentFilter == .sent || currentFilter == .keep {
Image(systemName: "trash.fill")
.resizable()
.frame(width: 22, height: 22)
.onTapGesture { onClickDelete() }
}
}
.padding(.top, 24.3)
.padding(.horizontal, 13.3)
}
.padding(.vertical, 20)
.background(Color(hex: "9970ff").opacity(0.2))
.cornerRadius(6.7)
.onAppear {
soundManager.startTimer = startTimer
soundManager.stopTimer = stopTimer
soundManager.prepareForPlay(URL(string: item.voiceMessageUrl)!)
}
.onDisappear {
soundManager.stopAudio()
}
}
}
.frame(width: screenSize().width - 26.7)
.background(Color.black)
.onAppear {
stopTimer()
}
.onReceive(timer) { _ in
self.progress = soundManager.getPlayerCurrentTime()
}
}
private func secondsToMinutesSeconds(seconds: Int) -> String {
let minute = String(format: "%02d", seconds / 60)
let second = String(format: "%02d", seconds % 60)
return "\(minute):\(second)"
}
private func startTimer() {
timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
}
private func stopTimer() {
timer.upstream.connect().cancel()
}
}
struct VoiceMessageItemView_Previews: PreviewProvider {
static var previews: some View {
VoiceMessageItemView(
index: 0,
item: VoiceMessageItem(
messageId: 24,
senderId: 13,
senderNickname: "user5",
senderProfileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
recipientNickname: "user8",
recipientProfileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
voiceMessageUrl: "",
date: "2022-07-02 01:42:43",
isKept: false
),
currentFilter: .keep,
soundManager: SoundManager(),
openPlayerItemIndex: .constant(0),
onClickSave: {},
onClickReply: {},
onClickDelete: {}
)
}
}