Skip to content

Commit

Permalink
Improve documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
philippzagar committed Dec 18, 2023
1 parent 0446310 commit f85e9b2
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 31 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ These entries are mandatory for apps that utilize microphone and speech recognit
### Chat View

The [`ChatView`](https://swiftpackageindex.com/stanfordspezi/spezichat/documentation/spezichat/chatview) provides a basic reusable chat view which includes a message input field. The input can be either typed out via the iOS keyboard or provided as voice input and transcribed into written text.
In addition, the [`ChatView`](https://swiftpackageindex.com/stanfordspezi/spezichat/documentation/spezichat/chatview) provides functionality to export the visualized [`Chat`](https://swiftpackageindex.com/stanfordspezi/spezichat/0.1.1/documentation/spezichat/chat) as a PDF document, JSON representation, or textual UTF-8 file (see `ChatView/ChatExportFormat`) via a Share Sheet (or Activity View).

```swift
struct ChatTestView: View {
Expand All @@ -66,7 +67,7 @@ struct ChatTestView: View {


var body: some View {
ChatView($chat)
ChatView($chat, exportFormat: .pdf)
.navigationTitle("SpeziChat")
}
}
Expand Down
7 changes: 3 additions & 4 deletions Sources/SpeziChat/ChatView+Export.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import SwiftUI


extension ChatView {
/// Output format of the exported ``Chat`` via a share button in the ``ChatView``.
/// Output format of the to-be exported ``Chat``.
public enum ChatExportFormat {
/// JSON representation of the ``Chat``
case json
Expand All @@ -31,7 +31,7 @@ extension ChatView {


var body: some View {
VStack(spacing: 8) { // Sadly, the SwiftUI `ImageRenderer` doesn't support SwiftUI `List`s
VStack(spacing: 8) { // The SwiftUI `ImageRenderer` doesn't support SwiftUI `List`s
ForEach(chat, id: \.self) { chatEntity in
HStack {
if chatEntity.alignment == .trailing {
Expand All @@ -50,7 +50,6 @@ extension ChatView {
Spacer(minLength: 32)
}
}

}

Spacer()
Expand Down Expand Up @@ -120,7 +119,7 @@ extension ChatView {
// Width from US Letter, height requested by the view
// Reason: Splitting a view in multiple PDF pages is complex!
let size = CGSize(
width: 72 * 8.5,
width: 72 * 8.5, // US Letter width
height: proposedHeight
)

Expand Down
5 changes: 4 additions & 1 deletion Sources/SpeziChat/ChatView+ShareSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ import SwiftUI


extension ChatView {
/// Provides an iOS-typical Share Sheet (also called Activity View: https://developer.apple.com/design/human-interface-guidelines/activity-views) SwiftUI wrapper
/// for exporting the ``Chat`` content of the ``ChatView`` without the downsides of the SwiftUI `ShareLink` such as unnecessary reevaluations of the to-be shared content.
struct ShareSheet: UIViewControllerRepresentable {
let sharedItem: Data
let sharedItemType: ChatExportFormat


func makeUIViewController(context: Context) -> UIActivityViewController {
/// Note: Need to write down the data to storage as in-memory PDFs are not recognized properly
// Note: Need to write down the data to storage as in-memory shared content is not recognized properly (e.g., PDFs)
var temporaryPath = FileManager.default.temporaryDirectory.appendingPathComponent("Exported Chat")

switch sharedItemType {
case .json: temporaryPath = temporaryPath.appendingPathExtension("json")
case .text: temporaryPath = temporaryPath.appendingPathExtension("txt")
case .pdf: temporaryPath = temporaryPath.appendingPathExtension("pdf")
}

try? sharedItem.write(to: temporaryPath)

let controller = UIActivityViewController(
Expand Down
3 changes: 2 additions & 1 deletion Sources/SpeziChat/ChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public struct ChatView: View {
let messagePlaceholder: String?

@State var messageInputHeight: CGFloat = 0
@State private var showShareSheet: Bool = false
@State private var showShareSheet = false


public var body: some View {
Expand Down Expand Up @@ -108,6 +108,7 @@ public struct ChatView: View {
} else {
ProgressView()
.padding()
.presentationDetents([.medium])
}
}
}
Expand Down
21 changes: 19 additions & 2 deletions Sources/SpeziChat/MessageStyleViewModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import SwiftUI


/// Provides styling for the visualization of a textual ``ChatEntity`` within the ``ChatView``.
struct MessageStyleModifier: ViewModifier {
let chatAlignment: ChatEntity.Alignment

Expand Down Expand Up @@ -41,7 +41,6 @@ struct MessageStyleModifier: ViewModifier {
func body(content: Content) -> some View {
content
.multilineTextAlignment(multilineTextAlignment)
//.frame(maxWidth: .infinity)
.padding(.horizontal, 10)
.padding(.vertical, 8)
.foregroundColor(foregroundColor)
Expand All @@ -61,6 +60,24 @@ struct MessageStyleModifier: ViewModifier {


extension View {
/// Attach this modifier to `Text`-based content in SwiftUI to format it as a typical chat bubble within a chat view.
/// The modifier handles text alignment, paddings, colourings, background, as well as the typical chat bubble visualization.
///
/// ### Usage
///
/// A minimal example can be found below.
/// See the ``MessageView`` for a more complete example.
///
/// ```swift
/// struct ChatMessageView: View {
/// let chatEntity: ChatEntity
///
/// var body: some View {
/// Text(chatEntity.content)
/// .chatMessageStyle(alignment: chatEntity.alignment)
/// }
/// }
/// ```
func chatMessageStyle(alignment: ChatEntity.Alignment) -> some View {
self.modifier(MessageStyleModifier(chatAlignment: alignment))
}
Expand Down
20 changes: 0 additions & 20 deletions Sources/SpeziChat/MessageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,7 @@ public struct MessageView: View {

private let chat: ChatEntity
private let hideMessagesWithRoles: Set<ChatEntity.Role>


private var foregroundColor: Color {
chat.alignment == .leading ? .primary : .white
}

private var backgroundColor: Color {
chat.alignment == .leading ? Color(.secondarySystemBackground) : .accentColor
}

private var multilineTextAllignment: TextAlignment {
chat.alignment == .leading ? .leading : .trailing
}

private var arrowRotation: Angle {
.degrees(chat.alignment == .leading ? -50 : -130)
}

private var arrowAllignment: CGFloat {
chat.alignment == .leading ? -7 : 7
}

public var body: some View {
if !hideMessagesWithRoles.contains(chat.role) {
Expand Down
3 changes: 2 additions & 1 deletion Sources/SpeziChat/SpeziChat.docc/SpeziChat.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ These entries are mandatory for apps that utilize microphone and speech recognit
### Chat View

The ``ChatView`` provides a basic reusable chat view which includes a message input field. The input can be either typed out via the iOS keyboard or provided as voice input and transcribed into written text.
In addition, the ``ChatView`` provides functionality to export the visualized ``Chat`` as a PDF document, JSON representation, or textual UTF-8 file (see ``ChatView/ChatExportFormat``) via a Share Sheet (or Activity View).

```swift
struct ChatTestView: View {
Expand All @@ -69,7 +70,7 @@ struct ChatTestView: View {


var body: some View {
ChatView($chat)
ChatView($chat, exportFormat: .pdf)
.navigationTitle("SpeziChat")
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/UITests/TestApp/ChatTestView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct ChatTestView: View {


var body: some View {
ChatView($chat, exportFormat: .text)
ChatView($chat, exportFormat: .pdf)
.navigationTitle("SpeziChat")
.padding(.top, 16)
.onChange(of: chat) { _, newValue in
Expand Down

0 comments on commit f85e9b2

Please sign in to comment.