Skip to content

Commit 3b3430f

Browse files
committed
make message bubble text selectable
1 parent 4dce938 commit 3b3430f

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

Diff for: LlamaChat.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
82F14EA329E45C5D001E9C1E /* AvatarPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F14EA229E45C5D001E9C1E /* AvatarPickerView.swift */; };
9393
82F14EA629E46454001E9C1E /* llama in Frameworks */ = {isa = PBXBuildFile; productRef = 82F14EA529E46454001E9C1E /* llama */; };
9494
82F14EA829E4D2DD001E9C1E /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 82F14EA729E4D2DD001E9C1E /* Credits.rtf */; };
95+
82F76A0529E6B6E0007B8A2D /* Text+TextSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F76A0429E6B6E0007B8A2D /* Text+TextSelection.swift */; };
9596
/* End PBXBuildFile section */
9697

9798
/* Begin PBXFileReference section */
@@ -181,6 +182,7 @@
181182
82E7FFE829DE5B7100BF0251 /* ConfigureLocalModelSizePickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigureLocalModelSizePickerViewModel.swift; sourceTree = "<group>"; };
182183
82F14EA229E45C5D001E9C1E /* AvatarPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarPickerView.swift; sourceTree = "<group>"; };
183184
82F14EA729E4D2DD001E9C1E /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
185+
82F76A0429E6B6E0007B8A2D /* Text+TextSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Text+TextSelection.swift"; sourceTree = "<group>"; };
184186
/* End PBXFileReference section */
185187

186188
/* Begin PBXFrameworksBuildPhase section */
@@ -201,6 +203,7 @@
201203
children = (
202204
821B253829DFA39600CF1001 /* NSApplication+Settings.swift */,
203205
821B255629E1F05000CF1001 /* NSScrollView+Bottom.swift */,
206+
82F76A0429E6B6E0007B8A2D /* Text+TextSelection.swift */,
204207
);
205208
path = extensions;
206209
sourceTree = "<group>";
@@ -700,6 +703,7 @@
700703
82718D0429D368EA00545C32 /* MessagesView.swift in Sources */,
701704
82914CC529D6E69C00858B2C /* BorderlessTextField.swift in Sources */,
702705
82A7B4EB29DE484600BCBB6B /* ConfigureLocalGgmlModelSettingsViewModel.swift in Sources */,
706+
82F76A0529E6B6E0007B8A2D /* Text+TextSelection.swift in Sources */,
703707
82E7FFE729DE5B1F00BF0251 /* ConfigureLocalModelSizePickerView.swift in Sources */,
704708
82E3F1DC29DF37DA003F0368 /* AddSourceViewModel.swift in Sources */,
705709
82914CCA29D76A2F00858B2C /* Sender.swift in Sources */,

Diff for: LlamaChat/extensions/Text+TextSelection.swift

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Text+TextSelection.swift
3+
// LlamaChat
4+
//
5+
// Created by Alex Rozanski on 12/04/2023.
6+
//
7+
8+
import SwiftUI
9+
10+
struct EnabledTextSelection: ViewModifier {
11+
func body(content: Content) -> some View {
12+
content
13+
.textSelection(.enabled)
14+
}
15+
}
16+
17+
struct DisabledTextSelection: ViewModifier {
18+
func body(content: Content) -> some View {
19+
content
20+
.textSelection(.disabled)
21+
}
22+
}
23+
24+
extension View {
25+
@ViewBuilder func textSelectionEnabled(_ flag: Bool) -> some View {
26+
if flag {
27+
modifier(EnabledTextSelection())
28+
} else {
29+
modifier(DisabledTextSelection())
30+
}
31+
}
32+
}

Diff for: LlamaChat/ui/chat/messages/GeneratedMessageView.swift

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct GeneratedMessageView: View {
3434
TypingBubbleContentView()
3535
case .generating, .finished, .cancelled, .error:
3636
Text(viewModel.content)
37+
.textSelectionEnabled(viewModel.canCopyContents.value)
3738
}
3839
}
3940
}

Diff for: LlamaChat/ui/chat/messages/MessagesView.swift

+2-12
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ struct MessageView: View {
1111
@ObservedObject var viewModel: ObservableMessageViewModel
1212
let availableWidth: Double
1313

14-
@ViewBuilder var messageView: some View {
14+
var body: some View {
1515
if let staticMessageViewModel: StaticMessageViewModel = viewModel.get() {
1616
MessageBubbleView(sender: staticMessageViewModel.sender, style: .regular, isError: staticMessageViewModel.isError, availableWidth: availableWidth * 0.8) {
1717
Text(staticMessageViewModel.content)
18+
.textSelectionEnabled(viewModel.canCopyContents)
1819
}
1920
} else if let generatedMessageViewModel: GeneratedMessageViewModel = viewModel.get() {
2021
GeneratedMessageView(viewModel: generatedMessageViewModel, availableWidth: availableWidth * 0.8)
@@ -29,17 +30,6 @@ struct MessageView: View {
2930
#endif
3031
}
3132
}
32-
33-
var body: some View {
34-
messageView
35-
.contextMenu {
36-
if viewModel.canCopyContents {
37-
Button("Copy") {
38-
viewModel.copyContents()
39-
}
40-
}
41-
}
42-
}
4333
}
4434

4535
struct MessagesView: View {

0 commit comments

Comments
 (0)