Skip to content

Commit

Permalink
Merge pull request #21 from jaesung-0o0/feature/jaesung/line-limit-op…
Browse files Browse the repository at this point in the history
…tion

[ADD] Added `MessageRow/lineLimit` and `MessageField/characterLimit`
  • Loading branch information
x-0o0 authored Mar 15, 2023
2 parents dbea0c4 + 904bc28 commit c2d9538
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 22 deletions.
5 changes: 4 additions & 1 deletion Sources/ChatUI/ChatInChannel/MessageField/MessageField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public struct MessageField: View {

let options: [MessageOption]
let showsSendButtonAlways: Bool
let characterLimit: Int?
let onSend: (_ messageStyle: MessageStyle) -> ()

private var leftSideOptions: [MessageOption] {
Expand Down Expand Up @@ -146,7 +147,7 @@ public struct MessageField: View {

// TextField
HStack(alignment: .bottom) {
MessageTextField(text: $text, height: $textFieldHeight)
MessageTextField(text: $text, height: $textFieldHeight, characterLimit: characterLimit)
.frame(height: textFieldHeight < 90 ? textFieldHeight : 90)
.padding(.leading, 9)
.padding(.trailing, 4)
Expand Down Expand Up @@ -206,11 +207,13 @@ public struct MessageField: View {
public init(
options: [MessageOption] = MessageOption.all,
showsSendButtonAlways: Bool = false,
characterLimit: Int? = nil,
isMenuItemPresented: Binding<Bool> = .constant(false),
onSend: @escaping (_ messageStyle: MessageStyle) -> ()
) {
self.options = options
self.showsSendButtonAlways = showsSendButtonAlways
self.characterLimit = characterLimit
self._isMenuItemPresented = isMenuItemPresented
self.onSend = onSend
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct MessageTextField: UIViewRepresentable {

@State private var isEditing: Bool = false
let placeholder: String = String.MessageField.placeholder
let characterLimit: Int?

func makeUIView(context: UIViewRepresentableContext<MessageTextField>) -> UITextView {
let view = UITextView()
Expand Down Expand Up @@ -67,7 +68,7 @@ struct MessageTextField: UIViewRepresentable {
}

func textViewDidChange(_ textView: UITextView) {
if textView.text.count > 300 {
if let characterLimit = parent.characterLimit, textView.text.count > characterLimit {
let start = textView.text.index(textView.text.startIndex, offsetBy: 0)
let end = textView.text.index(textView.text.startIndex, offsetBy: 300)
textView.text = String(textView.text[start..<end])
Expand Down
7 changes: 5 additions & 2 deletions Sources/ChatUI/ChatInChannel/MessageRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public struct MessageRow<M: MessageProtocol>: View {
let showsDate: Bool
let showsProfileImage: Bool
let showsReadReceiptStatus: Bool
let lineLimit: Int?

@State private var isSelected: Bool = false

Expand Down Expand Up @@ -80,7 +81,7 @@ public struct MessageRow<M: MessageProtocol>: View {
}

// MARK: Message bubble
MessageView(style: message.style, isMyMessage: isMyMessage)
MessageView(style: message.style, isMyMessage: isMyMessage, lineLimit: lineLimit)
.zIndex(0)
.onLongPressGesture {
withAnimation(.easeInOut) {
Expand Down Expand Up @@ -147,13 +148,15 @@ public struct MessageRow<M: MessageProtocol>: View {
showsUsername: Bool = true,
showsDate: Bool = true,
showsProfileImage: Bool = true,
showsReadReceiptStatus: Bool = true
showsReadReceiptStatus: Bool = true,
lineLimit: Int? = nil
) {
self.message = message
self.showsUsername = showsUsername
self.showsDate = showsDate
self.showsProfileImage = showsProfileImage
self.showsReadReceiptStatus = showsReadReceiptStatus
self.lineLimit = lineLimit
}

var formatter: DateFormatter {
Expand Down
13 changes: 7 additions & 6 deletions Sources/ChatUI/ChatInChannel/MessageViews/MessageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,39 @@ struct MessageView: View {

let style: MessageStyle
let isMyMessage: Bool
let lineLimit: Int?

var body: some View {
switch style {
case .text(let text):
let markdown = LocalizedStringKey(text)
Text(markdown)
.tint(isMyMessage ? appearance.prominentLink : appearance.link)
.messageStyle(isMyMessage ? .localBody : .remoteBody)
.messageStyle(isMyMessage ? .localBody(lineLimit) : .remoteBody(lineLimit))
case .media(let mediaType):
switch mediaType {
case .emoji(let key):
Text(key)
.messageStyle(isMyMessage ? .localBody : .remoteBody)
.messageStyle(isMyMessage ? .localBody(lineLimit) : .remoteBody(lineLimit))
case .gif(let key):
GiphyStyleView(id: key)
case .photo(let data):
PhotoStyleView(data: data)
case .video(let data):
Text("\(data)")
.lineLimit(5)
.messageStyle(isMyMessage ? .localBody : .remoteBody)
.messageStyle(isMyMessage ? .localBody(lineLimit) : .remoteBody(lineLimit))
case .document(let data):
Text("\(data)")
.lineLimit(5)
.messageStyle(isMyMessage ? .localBody : .remoteBody)
.messageStyle(isMyMessage ? .localBody(lineLimit) : .remoteBody(lineLimit))
case .contact(let contact):
let markdown = """
Name: **\(contact.givenName) \(contact.familyName)**
Phone: \(contact.phoneNumbers)
"""
Text(.init(markdown))
.messageStyle(isMyMessage ? .localBody : .remoteBody)
.messageStyle(isMyMessage ? .localBody(lineLimit) : .remoteBody(lineLimit))
case .location(let latitude, let longitude):
LocationStyleView(
latitude: latitude,
Expand All @@ -52,7 +53,7 @@ struct MessageView: View {
}
case .voice(let data):
VoiceStyleView(data: data)
.messageStyle(isMyMessage ? .localBody : .remoteBody)
.messageStyle(isMyMessage ? .localBody(lineLimit) : .remoteBody(lineLimit))
}
}
}
30 changes: 18 additions & 12 deletions Sources/ChatUI/ViewModifiers/MessageModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ import SwiftUI

public class MessageModifier {
public enum Style {
case remoteBody
case localBody
case remoteBody(_ lineLimit: Int?)
case localBody(_ lineLimit: Int?)
case date
case receipt
case senderName
case senderProfile
}

public static var remoteBodyStyle = RemoteBody()
public static func remoteBodyStyle(_ lineLimit: Int?) -> RemoteBody {
RemoteBody(lineLimit: lineLimit)
}

public static var localBodyStyle = LocalBody()
public static func localBodyStyle(_ lineLimit: Int?) -> LocalBody {
LocalBody(lineLimit: lineLimit)
}

public static var dateStyle = Date()

Expand All @@ -32,9 +36,11 @@ public class MessageModifier {
public struct RemoteBody: ViewModifier {
@Environment(\.appearance) var appearance

let lineLimit: Int?

public func body(content: Content) -> some View {
content
.lineLimit(10)
.lineLimit(lineLimit)
.font(appearance.messageBody)
.frame(minWidth: 18) /// To make the bubble to be a circle shape, when the text is too short
.padding(12)
Expand All @@ -47,9 +53,11 @@ public class MessageModifier {
public struct LocalBody: ViewModifier {
@Environment(\.appearance) var appearance

let lineLimit: Int?

public func body(content: Content) -> some View {
content
.lineLimit(10)
.lineLimit(lineLimit)
.font(appearance.messageBody)
.frame(minWidth: 18) /// To make the bubble to be a circle shape, when the text is too short
.padding(12)
Expand Down Expand Up @@ -107,10 +115,10 @@ public class MessageModifier {
extension View {
public func messageStyle(_ style: MessageModifier.Style) -> some View {
switch style {
case .remoteBody:
return AnyView(modifier(MessageModifier.remoteBodyStyle))
case .localBody:
return AnyView(modifier(MessageModifier.localBodyStyle))
case .remoteBody(let lineLimit):
return AnyView(modifier(MessageModifier.remoteBodyStyle(lineLimit)))
case .localBody(let lineLimit):
return AnyView(modifier(MessageModifier.localBodyStyle(lineLimit)))
case .date:
return AnyView(modifier(MessageModifier.dateStyle))
case .receipt:
Expand All @@ -122,5 +130,3 @@ extension View {
}
}
}


0 comments on commit c2d9538

Please sign in to comment.