Properly scroll DM view when keyboard is open

Less DM jank!

Changelog-Fixed: Properly scroll DM view when keyboard is open
This commit is contained in:
William Casarin
2023-05-05 16:12:03 -07:00
parent a5cb10ddaa
commit 0f5e1dfb81
3 changed files with 81 additions and 36 deletions

View File

@@ -0,0 +1,31 @@
//
// KeyboardVisible.swift
// damus
//
// Created by William Casarin on 2023-05-05.
//
import Foundation
import Combine
import UIKit
/// Publisher to read keyboard changes.
protocol KeyboardReadable {
var keyboardPublisher: AnyPublisher<Bool, Never> { get }
}
extension KeyboardReadable {
var keyboardPublisher: AnyPublisher<Bool, Never> {
Publishers.Merge(
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { _ in true },
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in false }
)
.eraseToAnyPublisher()
}
}

View File

@@ -6,8 +6,9 @@
//
import SwiftUI
import Combine
struct DMChatView: View {
struct DMChatView: View, KeyboardReadable {
let damus_state: DamusState
@ObservedObject var dms: DirectMessageModel
@State var showPrivateKeyWarning: Bool = false
@@ -24,17 +25,37 @@ struct DMChatView: View {
DMView(event: dms.events[ind], damus_state: damus_state)
.contextMenu{MenuItems(event: ev, keypair: damus_state.keypair, target_pubkey: ev.pubkey, bookmarks: damus_state.bookmarks, muted_threads: damus_state.muted_threads)}
}
EndBlock(height: 80)
EndBlock(height: 1)
}
.padding(.horizontal)
}
.dismissKeyboardOnTap()
.onAppear {
scroller.scrollTo("endblock")
scroll_to_end(scroller)
}.onChange(of: dms.events.count) { _ in
withAnimation {
scroller.scrollTo("endblock")
}
scroll_to_end(scroller, animated: true)
}
Footer
.onReceive(keyboardPublisher) { visible in
guard visible else {
return
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
scroll_to_end(scroller, animated: true)
}
}
}
}
func scroll_to_end(_ scroller: ScrollViewProxy, animated: Bool = false) {
if animated {
withAnimation {
scroller.scrollTo("endblock")
}
} else {
scroller.scrollTo("endblock")
}
}
@@ -87,37 +108,32 @@ struct DMChatView: View {
}
var Footer: some View {
ZStack {
BackgroundColor()
HStack(spacing: 0) {
InputField
HStack(spacing: 0) {
InputField
if !dms.draft.isEmpty {
Button(
role: .none,
action: {
showPrivateKeyWarning = contentContainsPrivateKey(dms.draft)
if !dms.draft.isEmpty {
Button(
role: .none,
action: {
showPrivateKeyWarning = contentContainsPrivateKey(dms.draft)
if !showPrivateKeyWarning {
send_message()
}
if !showPrivateKeyWarning {
send_message()
}
) {
Label("", systemImage: "arrow.right.circle")
.font(.title)
}
) {
Label("", systemImage: "arrow.right.circle")
.font(.title)
}
}
}
/*
Text(dms.draft).opacity(0).padding(.all, 8)
.fixedSize(horizontal: false, vertical: true)
.frame(minHeight: 70, maxHeight: 150, alignment: .bottom)
Text(dms.draft).opacity(0).padding(.all, 8)
.fixedSize(horizontal: false, vertical: true)
.frame(minHeight: 70, maxHeight: 150, alignment: .bottom)
}
.fixedSize(horizontal: false, vertical: true)
.frame(minHeight: 70, maxHeight: 150, alignment: .bottom)
*/
}
func send_message() {
@@ -143,13 +159,6 @@ struct DMChatView: View {
var body: some View {
ZStack {
Messages
.dismissKeyboardOnTap()
VStack {
Spacer()
Footer
}
Text("Send a message to start the conversation...", comment: "Text prompt for user to send a message to the other user.")
.lineLimit(nil)
@@ -238,3 +247,4 @@ extension View {
.background(content())
}
}