add full screen button on message info screen

pull/874/head
Ryan Zhao 2 years ago
parent 8e1e74b9c0
commit 3ccf5995f2

@ -13,93 +13,189 @@ struct MessageInfoView: View {
} }
var body: some View { var body: some View {
ZStack (alignment: .topLeading) { NavigationView {
if #available(iOS 14.0, *) { ZStack (alignment: .topLeading) {
Color.black.ignoresSafeArea() if #available(iOS 14.0, *) {
} else { Color.black.ignoresSafeArea()
Color.black } else {
} Color.black
}
ScrollView(.vertical, showsIndicators: false) {
VStack( ScrollView(.vertical, showsIndicators: false) {
alignment: .leading, VStack(
spacing: 10 alignment: .leading,
) { spacing: 10
// Message bubble snapshot ) {
if let body: String = messageViewModel.body { // Message bubble snapshot
let (bubbleBackgroundColor, bubbleTextColor): (ThemeValue, ThemeValue) = ( if let body: String = messageViewModel.body {
messageViewModel.variant == .standardIncoming || let (bubbleBackgroundColor, bubbleTextColor): (ThemeValue, ThemeValue) = (
messageViewModel.variant == .standardIncomingDeleted messageViewModel.variant == .standardIncoming ||
) ? messageViewModel.variant == .standardIncomingDeleted
(.messageBubble_incomingBackground, .messageBubble_incomingText) : ) ?
(.messageBubble_outgoingBackground, .messageBubble_outgoingText) (.messageBubble_incomingBackground, .messageBubble_incomingText) :
(.messageBubble_outgoingBackground, .messageBubble_outgoingText)
ZStack {
RoundedRectangle(cornerRadius: 18)
.fill(themeColor: bubbleBackgroundColor)
Text(body) ZStack {
.foregroundColor(themeColor: bubbleTextColor) RoundedRectangle(cornerRadius: 18)
.padding( .fill(themeColor: bubbleBackgroundColor)
EdgeInsets(
top: 8, Text(body)
leading: 16, .foregroundColor(themeColor: bubbleTextColor)
bottom: 8, .padding(
trailing: 16 EdgeInsets(
top: 8,
leading: 16,
bottom: 8,
trailing: 16
)
) )
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
.fixedSize(horizontal: true, vertical: true)
.padding(
EdgeInsets(
top: 8,
leading: 30,
bottom: 4,
trailing: 30
) )
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
.fixedSize(horizontal: true, vertical: true)
.padding(
EdgeInsets(
top: 8,
leading: 30,
bottom: 4,
trailing: 30
) )
) }
}
if isMessageFailed {
let (image, statusText, tintColor) = messageViewModel.state.statusIconInfo(
variant: messageViewModel.variant,
hasAtLeastOneReadReceipt: messageViewModel.hasAtLeastOneReadReceipt
)
HStack(spacing: 6) { if isMessageFailed {
if let image: UIImage = image?.withRenderingMode(.alwaysTemplate) { let (image, statusText, tintColor) = messageViewModel.state.statusIconInfo(
Image(uiImage: image) variant: messageViewModel.variant,
.resizable() hasAtLeastOneReadReceipt: messageViewModel.hasAtLeastOneReadReceipt
.scaledToFit() )
.foregroundColor(themeColor: tintColor)
.frame(width: 13, height: 12)
}
if let statusText: String = statusText { HStack(spacing: 6) {
Text(statusText) if let image: UIImage = image?.withRenderingMode(.alwaysTemplate) {
.font(.system(size: 11)) Image(uiImage: image)
.foregroundColor(themeColor: tintColor) .resizable()
.scaledToFit()
.foregroundColor(themeColor: tintColor)
.frame(width: 13, height: 12)
}
if let statusText: String = statusText {
Text(statusText)
.font(.system(size: 11))
.foregroundColor(themeColor: tintColor)
}
} }
.padding(
EdgeInsets(
top: -8,
leading: 30,
bottom: 4,
trailing: 30
)
)
} }
.padding(
EdgeInsets( if let attachments = messageViewModel.attachments {
top: -8, ZStack(alignment: .bottomTrailing) {
leading: 30, if attachments.count > 1 {
bottom: 4, // Attachment carousel view
trailing: 30 SessionCarouselView_SwiftUI(index: $index, contentInfos: [.orange, .gray, .blue, .yellow])
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
} else {
// TODO: one attachment
}
Button {
// TODO: full screen function
} label: {
ZStack {
Circle()
.foregroundColor(.init(white: 0, opacity: 0.4))
Image(systemName: "arrow.up.left.and.arrow.down.right")
.font(.system(size: 13))
.foregroundColor(.white)
}
.frame(width: 26, height: 26)
}
.padding(
EdgeInsets(
top: 0,
leading: 0,
bottom: 8,
trailing: 38
)
)
}
.padding(
EdgeInsets(
top: 4,
leading: 0,
bottom: 4,
trailing: 0
)
) )
)
} // Attachment Info
ZStack {
if let attachments = messageViewModel.attachments { RoundedRectangle(cornerRadius: 17)
if attachments.count > 1 { .fill(Color(red: 27.0/255, green: 27.0/255, blue: 27.0/255))
// Attachment carousel view
SessionCarouselView_SwiftUI(index: $index, contentInfos: [.orange, .gray, .blue, .yellow]) VStack(
alignment: .leading,
spacing: 16
) {
InfoBlock(title: "ATTACHMENT_INFO_FILE_ID".localized() + ":") {
Text("12378965485235985214")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
HStack(
alignment: .center
) {
InfoBlock(title: "ATTACHMENT_INFO_FILE_TYPE".localized() + ":") {
Text(".PNG")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
Spacer()
InfoBlock(title: "ATTACHMENT_INFO_FILE_SIZE".localized() + ":") {
Text("6mb")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
Spacer()
}
HStack(
alignment: .center
) {
InfoBlock(title: "ATTACHMENT_INFO_RESOLUTION".localized() + ":") {
Text("550×550")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
Spacer()
InfoBlock(title: "ATTACHMENT_INFO_DURATION".localized() + ":") {
Text("N/A")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
Spacer()
}
}
.frame( .frame(
maxWidth: .infinity, maxWidth: .infinity,
maxHeight: .infinity, maxHeight: .infinity,
@ -107,69 +203,84 @@ struct MessageInfoView: View {
) )
.padding( .padding(
EdgeInsets( EdgeInsets(
top: 4, top: 24,
leading: 0, leading: 24,
bottom: 4, bottom: 24,
trailing: 0 trailing: 24
) )
) )
} else { }
// TODO: one attachment .frame(maxHeight: .infinity)
.fixedSize(horizontal: false, vertical: true)
.padding(
EdgeInsets(
top: 4,
leading: 30,
bottom: 4,
trailing: 30
)
)
} }
// Attachment Info // Message Info
ZStack { ZStack {
RoundedRectangle(cornerRadius: 17) RoundedRectangle(cornerRadius: 17)
.fill(Color(red: 27.0/255, green: 27.0/255, blue: 27.0/255)) .fill(themeColor: .backgroundSecondary)
VStack( VStack(
alignment: .leading, alignment: .leading,
spacing: 16 spacing: 16
) { ) {
InfoBlock(title: "ATTACHMENT_INFO_FILE_ID".localized() + ":") { InfoBlock(title: "MESSAGE_INFO_SENT".localized() + ":") {
Text("12378965485235985214") Text(messageViewModel.dateForUI.fromattedForMessageInfo)
.font(.system(size: 16)) .font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary) .foregroundColor(themeColor: .textPrimary)
} }
HStack( InfoBlock(title: "MESSAGE_INFO_RECEIVED".localized() + ":") {
alignment: .center Text(messageViewModel.receivedDateForUI.fromattedForMessageInfo)
) { .font(.system(size: 16))
InfoBlock(title: "ATTACHMENT_INFO_FILE_TYPE".localized() + ":") { .foregroundColor(themeColor: .textPrimary)
Text(".PNG")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
Spacer()
InfoBlock(title: "ATTACHMENT_INFO_FILE_SIZE".localized() + ":") {
Text("6mb")
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
Spacer()
} }
HStack( if isMessageFailed {
alignment: .center let failureText: String = messageViewModel.mostRecentFailureText ?? "Message failed to send"
) { InfoBlock(title: "ALERT_ERROR_TITLE".localized() + ":") {
InfoBlock(title: "ATTACHMENT_INFO_RESOLUTION".localized() + ":") { Text(failureText)
Text("550×550")
.font(.system(size: 16)) .font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary) .foregroundColor(themeColor: .danger)
} }
}
Spacer()
InfoBlock(title: "MESSAGE_INFO_FROM".localized() + ":") {
InfoBlock(title: "ATTACHMENT_INFO_DURATION".localized() + ":") { HStack(
Text("N/A") spacing: 10
.font(.system(size: 16)) ) {
.foregroundColor(themeColor: .textPrimary) Circle()
.frame(
width: 46,
height: 46,
alignment: .topLeading
)
.foregroundColor(themeColor: .primary)
// ProfilePictureSwiftUI(size: .message)
VStack(
alignment: .leading,
spacing: 4
) {
if !messageViewModel.authorName.isEmpty {
Text(messageViewModel.authorName)
.bold()
.font(.system(size: 18))
.foregroundColor(themeColor: .textPrimary)
}
Text(messageViewModel.authorId)
.font(.spaceMono(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
} }
Spacer()
} }
} }
.frame( .frame(
@ -196,158 +307,76 @@ struct MessageInfoView: View {
trailing: 30 trailing: 30
) )
) )
}
// Message Info // Actions
ZStack { if !actions.isEmpty {
RoundedRectangle(cornerRadius: 17) ZStack {
.fill(themeColor: .backgroundSecondary) RoundedRectangle(cornerRadius: 17)
.fill(themeColor: .backgroundSecondary)
VStack(
alignment: .leading, VStack(
spacing: 16 alignment: .leading,
) { spacing: 0
InfoBlock(title: "MESSAGE_INFO_SENT".localized() + ":") {
Text(messageViewModel.dateForUI.fromattedForMessageInfo)
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
InfoBlock(title: "MESSAGE_INFO_RECEIVED".localized() + ":") {
Text(messageViewModel.receivedDateForUI.fromattedForMessageInfo)
.font(.system(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
if isMessageFailed {
let failureText: String = messageViewModel.mostRecentFailureText ?? "Message failed to send"
InfoBlock(title: "ALERT_ERROR_TITLE".localized() + ":") {
Text(failureText)
.font(.system(size: 16))
.foregroundColor(themeColor: .danger)
}
}
InfoBlock(title: "MESSAGE_INFO_FROM".localized() + ":") {
HStack(
spacing: 10
) { ) {
Circle() ForEach(
.frame( 0...(actions.count - 1),
width: 46, id: \.self
height: 46, ) { index in
alignment: .topLeading let tintColor: ThemeValue = actions[index].isDestructive ? .danger : .textPrimary
) HStack(spacing: 24) {
.foregroundColor(themeColor: .primary) Image(uiImage: actions[index].icon!.withRenderingMode(.alwaysTemplate))
// ProfilePictureSwiftUI(size: .message) .resizable()
.scaledToFit()
.foregroundColor(themeColor: tintColor)
VStack( .frame(width: 26, height: 26)
alignment: .leading, Text(actions[index].title)
spacing: 4
) {
if !messageViewModel.authorName.isEmpty {
Text(messageViewModel.authorName)
.bold() .bold()
.font(.system(size: 18)) .font(.system(size: 18))
.foregroundColor(themeColor: .textPrimary) .foregroundColor(themeColor: tintColor)
}
.frame(width: .infinity, height: 60)
.onTapGesture {
actions[index].work()
}
if index < (actions.count - 1) {
Divider()
.foregroundColor(themeColor: .borderSeparator)
} }
Text(messageViewModel.authorId)
.font(.spaceMono(size: 16))
.foregroundColor(themeColor: .textPrimary)
}
}
}
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
.padding(
EdgeInsets(
top: 24,
leading: 24,
bottom: 24,
trailing: 24
)
)
}
.frame(maxHeight: .infinity)
.fixedSize(horizontal: false, vertical: true)
.padding(
EdgeInsets(
top: 4,
leading: 30,
bottom: 4,
trailing: 30
)
)
// Actions
if !actions.isEmpty {
ZStack {
RoundedRectangle(cornerRadius: 17)
.fill(themeColor: .backgroundSecondary)
VStack(
alignment: .leading,
spacing: 0
) {
ForEach(
0...(actions.count - 1),
id: \.self
) { index in
let tintColor: ThemeValue = actions[index].isDestructive ? .danger : .textPrimary
HStack(spacing: 24) {
Image(uiImage: actions[index].icon!.withRenderingMode(.alwaysTemplate))
.resizable()
.scaledToFit()
.foregroundColor(themeColor: tintColor)
.frame(width: 26, height: 26)
Text(actions[index].title)
.bold()
.font(.system(size: 18))
.foregroundColor(themeColor: tintColor)
}
.frame(width: .infinity, height: 60)
.onTapGesture {
actions[index].work()
}
if index < (actions.count - 1) {
Divider()
.foregroundColor(themeColor: .borderSeparator)
} }
} }
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
.padding(
EdgeInsets(
top: 0,
leading: 24,
bottom: 0,
trailing: 24
)
)
} }
.frame( .frame(maxHeight: .infinity)
maxWidth: .infinity, .fixedSize(horizontal: false, vertical: true)
maxHeight: .infinity,
alignment: .topLeading
)
.padding( .padding(
EdgeInsets( EdgeInsets(
top: 0, top: 4,
leading: 24, leading: 30,
bottom: 0, bottom: 4,
trailing: 24 trailing: 30
) )
) )
} }
.frame(maxHeight: .infinity)
.fixedSize(horizontal: false, vertical: true)
.padding(
EdgeInsets(
top: 4,
leading: 30,
bottom: 4,
trailing: 30
)
)
} }
} }
} }
.navigationBarTitle(
"Message Info",
displayMode: .inline
)
} }
} }
} }

@ -58,7 +58,6 @@ struct ArrowView: View {
var body: some View { var body: some View {
let imageName = self.type == .decrement ? "chevron.left" : "chevron.right" let imageName = self.type == .decrement ? "chevron.left" : "chevron.right"
Button { Button {
print("Tap")
if self.type == .decrement { if self.type == .decrement {
decrement() decrement()
} else { } else {

Loading…
Cancel
Save