2022-01-29 11:10:04 +00:00
|
|
|
//
|
|
|
|
// TerminalView.swift
|
|
|
|
// SimpleX
|
|
|
|
//
|
|
|
|
// Created by Evgeny Poberezkin on 27/01/2022.
|
|
|
|
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
|
2022-02-12 15:59:43 +00:00
|
|
|
private let terminalFont = Font.custom("Menlo", size: 16)
|
|
|
|
|
2022-04-08 19:58:02 +01:00
|
|
|
private let maxItemSize: Int = 50000
|
|
|
|
|
2022-01-29 11:10:04 +00:00
|
|
|
struct TerminalView: View {
|
|
|
|
@EnvironmentObject var chatModel: ChatModel
|
|
|
|
@State var inProgress: Bool = false
|
2022-03-25 22:26:05 +04:00
|
|
|
@State var message: String = ""
|
2022-02-11 07:42:00 +00:00
|
|
|
@FocusState private var keyboardVisible: Bool
|
2022-03-25 22:26:05 +04:00
|
|
|
@State var editing: Bool = false
|
2022-04-19 12:29:03 +04:00
|
|
|
@State var sendEnabled: Bool = false
|
2022-02-11 07:42:00 +00:00
|
|
|
|
2022-01-29 11:10:04 +00:00
|
|
|
var body: some View {
|
|
|
|
VStack {
|
2022-02-04 16:31:08 +00:00
|
|
|
ScrollViewReader { proxy in
|
|
|
|
ScrollView {
|
|
|
|
LazyVStack {
|
|
|
|
ForEach(chatModel.terminalItems) { item in
|
|
|
|
NavigationLink {
|
2022-04-08 19:58:02 +01:00
|
|
|
let s = item.details
|
2022-02-04 16:31:08 +00:00
|
|
|
ScrollView {
|
2022-04-08 19:58:02 +01:00
|
|
|
Text(s.prefix(maxItemSize))
|
2022-02-11 07:42:00 +00:00
|
|
|
.padding()
|
2022-02-04 16:31:08 +00:00
|
|
|
}
|
2022-04-08 19:58:02 +01:00
|
|
|
.toolbar {
|
|
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
|
|
Button { showShareSheet(items: [s]) } label: {
|
|
|
|
Image(systemName: "square.and.arrow.up")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-02-04 16:31:08 +00:00
|
|
|
} label: {
|
2022-02-11 07:42:00 +00:00
|
|
|
HStack {
|
|
|
|
Text(item.id.formatted(date: .omitted, time: .standard))
|
|
|
|
Text(item.label)
|
|
|
|
.frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
|
|
|
|
}
|
2022-02-12 15:59:43 +00:00
|
|
|
.font(terminalFont)
|
2022-02-11 07:42:00 +00:00
|
|
|
.padding(.horizontal)
|
2022-01-29 11:10:04 +00:00
|
|
|
}
|
|
|
|
}
|
2022-02-04 16:31:08 +00:00
|
|
|
.onAppear { scrollToBottom(proxy) }
|
|
|
|
.onChange(of: chatModel.terminalItems.count) { _ in scrollToBottom(proxy) }
|
2022-02-11 07:42:00 +00:00
|
|
|
.onChange(of: keyboardVisible) { _ in
|
|
|
|
if keyboardVisible {
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
|
|
|
|
scrollToBottom(proxy, animation: .easeInOut(duration: 1))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 11:10:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-04 16:31:08 +00:00
|
|
|
Spacer()
|
|
|
|
|
2022-02-11 07:42:00 +00:00
|
|
|
SendMessageView(
|
|
|
|
sendMessage: sendMessage,
|
|
|
|
inProgress: inProgress,
|
2022-03-25 22:26:05 +04:00
|
|
|
message: $message,
|
|
|
|
keyboardVisible: $keyboardVisible,
|
2022-04-19 12:29:03 +04:00
|
|
|
editing: $editing,
|
|
|
|
sendEnabled: $sendEnabled
|
2022-02-11 07:42:00 +00:00
|
|
|
)
|
2022-04-19 12:29:03 +04:00
|
|
|
.padding(.horizontal, 12)
|
2022-02-04 16:31:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
.navigationViewStyle(.stack)
|
|
|
|
.navigationTitle("Chat console")
|
2022-04-19 12:29:03 +04:00
|
|
|
.onChange(of: message) { _ in
|
|
|
|
sendEnabled = !message.isEmpty
|
|
|
|
}
|
2022-02-04 16:31:08 +00:00
|
|
|
}
|
2022-01-29 11:10:04 +00:00
|
|
|
|
2022-02-11 07:42:00 +00:00
|
|
|
func scrollToBottom(_ proxy: ScrollViewProxy, animation: Animation = .default) {
|
2022-02-04 16:31:08 +00:00
|
|
|
if let id = chatModel.terminalItems.last?.id {
|
2022-02-11 07:42:00 +00:00
|
|
|
withAnimation(animation) {
|
2022-02-04 16:31:08 +00:00
|
|
|
proxy.scrollTo(id, anchor: .bottom)
|
|
|
|
}
|
2022-01-29 11:10:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-29 23:37:02 +00:00
|
|
|
func sendMessage(_ cmdStr: String) {
|
|
|
|
let cmd = ChatCommand.string(cmdStr)
|
2022-01-29 11:10:04 +00:00
|
|
|
DispatchQueue.global().async {
|
2022-02-24 17:16:41 +00:00
|
|
|
Task {
|
|
|
|
inProgress = true
|
|
|
|
_ = await chatSendCmd(cmd)
|
|
|
|
inProgress = false
|
2022-01-29 23:37:02 +00:00
|
|
|
}
|
2022-01-29 11:10:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TerminalView_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
|
|
|
let chatModel = ChatModel()
|
2022-01-29 23:37:02 +00:00
|
|
|
chatModel.terminalItems = [
|
2022-02-04 22:13:52 +00:00
|
|
|
.resp(.now, ChatResponse.response(type: "contactSubscribed", json: "{}")),
|
|
|
|
.resp(.now, ChatResponse.response(type: "newChatItem", json: "{}"))
|
2022-01-29 11:10:04 +00:00
|
|
|
]
|
|
|
|
return NavigationView {
|
|
|
|
TerminalView()
|
|
|
|
.environmentObject(chatModel)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|