2024-06-19 15:15:27 +00:00
import Combine
import Foundation
import Martin
import SwiftUI
2024-06-21 10:42:50 +00:00
struct ConversationScreen : View {
@ EnvironmentObject var store : AppStore
2024-06-19 15:15:27 +00:00
var body : some View {
2024-06-24 13:28:26 +00:00
ZStack {
// B a c k g r o u n d c o l o r
Color . Main . backgroundLight
. ignoresSafeArea ( )
2024-06-19 15:15:27 +00:00
2024-06-24 13:28:26 +00:00
// C o n t e n t
VStack ( spacing : 0 ) {
// H e a d e r
ConversationScreenHeader ( )
// M s g l i s t
let messages = store . state . conversationsState . currentMessages
if ! messages . isEmpty {
List {
ForEach ( messages ) { message in
ConversationMessageRow ( message : message )
}
}
. listStyle ( . plain )
. background ( Color . Main . backgroundLight )
} else {
Spacer ( )
}
}
2024-06-19 15:15:27 +00:00
}
2024-06-25 11:13:59 +00:00
. safeAreaInset ( edge : . bottom , spacing : 0 ) {
ConversationScreenTextInput ( )
}
}
}
struct ConversationScreenTextInput : View {
@ EnvironmentObject var store : AppStore
@ State private var messageStr = " "
var body : some View {
HStack {
Image ( systemName : " paperclip " )
. font ( . title2 )
. foregroundColor ( . Tango . blueLight )
. padding ( . leading , 8 )
. tappablePadding ( . symmetric ( 8 ) ) {
print ( " Attach file " )
}
TextField ( L10n . Chat . textfieldPrompt , text : $ messageStr )
. font ( . body1 )
. padding ( . horizontal , 8 )
. padding ( . vertical , 4 )
. background ( Color . Main . white )
. clipShape ( RoundedRectangle ( cornerRadius : 8 ) )
. padding ( . vertical , 4 )
let img = messageStr . isEmpty ? " paperplane " : " paperplane.fill "
Image ( systemName : img )
. font ( . title2 )
. foregroundColor ( messageStr . isEmpty ? . Main . separator : . Tango . blueLight )
. padding ( . trailing , 8 )
. tappablePadding ( . symmetric ( 8 ) ) {
if ! messageStr . isEmpty {
messageStr = " "
UIApplication . shared . sendAction ( #selector ( UIResponder . resignFirstResponder ) , to : nil , from : nil , for : nil )
}
}
}
. padding ( . vertical , 8 )
. background ( Color . Main . backgroundDark )
2024-06-19 15:15:27 +00:00
}
}
2024-06-21 10:42:50 +00:00
private struct ConversationScreenHeader : View {
2024-06-19 15:15:27 +00:00
// @ E n v i r o n m e n t O b j e c t v a r s t a t e : A p p S t a t e
var body : some View {
ZStack {
// b g
Color . Main . backgroundDark
. ignoresSafeArea ( )
// t i t l e
// l e t n a m e = (
// s t a t e . a c t i v e C o n v e r s a t i o n ? . p a r t i c i p a n t ? . n a m e ? ?
// s t a t e . a c t i v e C o n v e r s a t i o n . p a r t i c i p a n t ? . c o n t a c t B a r e J i d
// ) ? ? L 1 0 n . C h a t . t i t l e
Text ( L10n . Chat . title )
. font ( . head2 )
. foregroundColor ( Color . Main . black )
HStack {
Image ( systemName : " chevron.left " )
. foregroundColor ( Color . Tango . orangeMedium )
. tappablePadding ( . symmetric ( 12 ) ) {
2024-06-21 10:42:50 +00:00
store . dispatch ( . changeFlow ( store . state . previousFlow ) )
2024-06-19 15:15:27 +00:00
}
Spacer ( )
// I m a g e ( s y s t e m N a m e : " p l u s . v i e w f i n d e r " )
// . f o r e g r o u n d C o l o r ( C o l o r . T a n g o . o r a n g e M e d i u m )
// . t a p p a b l e P a d d i n g ( . s y m m e t r i c ( 1 2 ) ) {
// p r i n t ( " S c a n Q R - c o d e " )
// }
}
. padding ( . horizontal , 16 )
}
. frame ( height : 44 )
}
}
2024-06-24 13:28:26 +00:00
private struct ConversationMessageRow : View {
@ EnvironmentObject var store : AppStore
2024-06-19 15:15:27 +00:00
let message : Message
var body : some View {
2024-06-25 11:13:59 +00:00
VStack ( spacing : 0 ) {
HStack ( spacing : 0 ) {
if isOutgoing ( ) {
2024-06-24 13:28:26 +00:00
Spacer ( )
2024-06-25 11:13:59 +00:00
VStack ( spacing : 0 ) {
MessageTime ( message : message )
Spacer ( )
}
. padding ( . trailing , 4 )
2024-06-24 13:28:26 +00:00
}
2024-06-25 11:13:59 +00:00
MessageContainer ( message : message , isOutgoing : isOutgoing ( ) )
. background ( isOutgoing ( ) ? Color . Material . greenDark100 : Color . Main . white )
. clipShape ( MessageBubble ( isOutgoing : isOutgoing ( ) ) )
if ! isOutgoing ( ) {
VStack ( spacing : 0 ) {
MessageTime ( message : message )
Spacer ( )
}
. padding ( . leading , 4 )
2024-06-24 13:28:26 +00:00
Spacer ( )
}
}
2024-06-25 11:13:59 +00:00
. padding ( . vertical , 10 )
. padding ( . horizontal , 16 )
2024-06-19 15:15:27 +00:00
}
2024-06-24 13:28:26 +00:00
. sharedListRow ( )
2024-06-19 15:15:27 +00:00
}
2024-06-25 11:13:59 +00:00
private func isOutgoing ( ) -> Bool {
message . from = = store . state . conversationsState . currentChat ? . account
}
}
struct MessageContainer : View {
let message : Message
let isOutgoing : Bool
var body : some View {
Text ( message . body ? ? " ... " )
. font ( . body2 )
. foregroundColor ( Color . Main . black )
. multilineTextAlignment ( . leading )
. padding ( 10 )
}
}
struct MessageBubble : Shape {
let isOutgoing : Bool
func path ( in rect : CGRect ) -> Path {
let path = UIBezierPath (
roundedRect : rect ,
byRoundingCorners : isOutgoing ? [ . topLeft , . bottomLeft , . bottomRight ] : [ . topRight , . bottomLeft , . bottomRight ] ,
cornerRadii : CGSize ( width : 8 , height : 10 )
)
return Path ( path . cgPath )
2024-06-24 13:28:26 +00:00
}
2024-06-19 15:15:27 +00:00
}
2024-06-25 11:13:59 +00:00
struct MessageTime : View {
let message : Message
var body : some View {
Text ( message . date , style : . time )
. font ( . sub2 )
. foregroundColor ( Color . Main . gray )
}
}
// P r e v i e w
#if DEBUG
struct ConversationScreen_Previews : PreviewProvider {
static var previews : some View {
ConversationScreen ( )
. environmentObject ( pStore )
}
static var pStore : AppStore {
let state = pState
return AppStore ( initialState : state , reducer : AppState . reducer , middlewares : [ ] )
}
static var pState : AppState {
var state = AppState ( )
let acc = " user@test.com "
let contact = " some@test.com "
state . conversationsState . currentChat = Chat ( id : " 1 " , account : acc , participant : contact , type : . chat )
state . conversationsState . currentMessages = [
Message (
id : " 1 " ,
type : . chat ,
contentType : . text ,
from : contact ,
to : acc ,
body : " this is for test sdgdsfg dsfg dsfgdg dsfgdfgsdgsdfgdfg sdfgdsfgdfsg dsfgdsfgsdfg dsfgdfgsdg fgf fgfg sdfsdf sdfsdf sdf sdfsdf sdf sdfsdf sdfsdfsdf sdfsdf " ,
subject : nil ,
thread : nil ,
oobUrl : nil ,
date : Date ( )
) ,
Message ( id : " 2 " , type : . chat , contentType : . text , from : contact , to : acc , body : " this is for testsdfsdf sdfsdf sdfs sdf sdffsdf sdf sdf sdf sdf sdf sdff sdfffwwe " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 3 " , type : . chat , contentType : . text , from : contact , to : acc , body : " this is for test " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 4 " , type : . chat , contentType : . text , from : acc , to : contact , body : " this is for test sdfkjwek jwkjfh jwerf jdfhskjdhf jsdhfjhwefh sjdhfh fsdjhfh sd " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 5 " , type : . chat , contentType : . text , from : contact , to : acc , body : " this is for test sdfjkkeke kekkddjw;; w;edkdjfj l kjwekrjfk wef " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 6 " , type : . chat , contentType : . text , from : acc , to : contact , body : " this is for testsdf dsdkkekkddn wejkjfj " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message (
id : " 7 " ,
type : . chat ,
contentType : . text ,
from : acc ,
to : contact ,
body : " this is for test sdgdsfg dsfg dsfgdg dsfgdfgsdgsdfgdfg sdfgdsfgdfsg dsfgdsfgsdfg dsfgdfgsdg fgf fgfg sdfsdf sdfsdf sdf sdfsdf sdf sdfsdf sdfsdfsdf sdfsdf " ,
subject : nil ,
thread : nil ,
oobUrl : nil ,
date : Date ( )
) ,
Message ( id : " 8 " , type : . chat , contentType : . text , from : acc , to : contact , body : " so test " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 9 " , type : . chat , contentType : . text , from : contact , to : acc , body : " so test " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 10 " , type : . chat , contentType : . text , from : acc , to : contact , body : " so test so test so test " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) ) ,
Message ( id : " 11 " , type : . chat , contentType : . text , from : contact , to : acc , body : " xD " , subject : nil , thread : nil , oobUrl : nil , date : Date ( ) )
]
return state
}
}
#endif