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:
@@ -141,6 +141,7 @@
|
|||||||
4C75EFB728049D990006080F /* RelayPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFB628049D990006080F /* RelayPool.swift */; };
|
4C75EFB728049D990006080F /* RelayPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFB628049D990006080F /* RelayPool.swift */; };
|
||||||
4C75EFB92804A2740006080F /* EventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFB82804A2740006080F /* EventView.swift */; };
|
4C75EFB92804A2740006080F /* EventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFB82804A2740006080F /* EventView.swift */; };
|
||||||
4C75EFBB2804A34C0006080F /* ProofOfWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFBA2804A34C0006080F /* ProofOfWork.swift */; };
|
4C75EFBB2804A34C0006080F /* ProofOfWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFBA2804A34C0006080F /* ProofOfWork.swift */; };
|
||||||
|
4C7D09592A05BEAD00943473 /* KeyboardVisible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09582A05BEAD00943473 /* KeyboardVisible.swift */; };
|
||||||
4C7FF7D52823313F009601DB /* Mentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7FF7D42823313F009601DB /* Mentions.swift */; };
|
4C7FF7D52823313F009601DB /* Mentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7FF7D42823313F009601DB /* Mentions.swift */; };
|
||||||
4C8682872814DE470026224F /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8682862814DE470026224F /* ProfileView.swift */; };
|
4C8682872814DE470026224F /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8682862814DE470026224F /* ProfileView.swift */; };
|
||||||
4C8D00C829DF791C0036AF10 /* CompatibleAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00C729DF791C0036AF10 /* CompatibleAttribute.swift */; };
|
4C8D00C829DF791C0036AF10 /* CompatibleAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00C729DF791C0036AF10 /* CompatibleAttribute.swift */; };
|
||||||
@@ -559,6 +560,7 @@
|
|||||||
4C75EFB628049D990006080F /* RelayPool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayPool.swift; sourceTree = "<group>"; };
|
4C75EFB628049D990006080F /* RelayPool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayPool.swift; sourceTree = "<group>"; };
|
||||||
4C75EFB82804A2740006080F /* EventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventView.swift; sourceTree = "<group>"; };
|
4C75EFB82804A2740006080F /* EventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventView.swift; sourceTree = "<group>"; };
|
||||||
4C75EFBA2804A34C0006080F /* ProofOfWork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProofOfWork.swift; sourceTree = "<group>"; };
|
4C75EFBA2804A34C0006080F /* ProofOfWork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProofOfWork.swift; sourceTree = "<group>"; };
|
||||||
|
4C7D09582A05BEAD00943473 /* KeyboardVisible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardVisible.swift; sourceTree = "<group>"; };
|
||||||
4C7FF7D42823313F009601DB /* Mentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mentions.swift; sourceTree = "<group>"; };
|
4C7FF7D42823313F009601DB /* Mentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mentions.swift; sourceTree = "<group>"; };
|
||||||
4C8682862814DE470026224F /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
|
4C8682862814DE470026224F /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
|
||||||
4C8D00C729DF791C0036AF10 /* CompatibleAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompatibleAttribute.swift; sourceTree = "<group>"; };
|
4C8D00C729DF791C0036AF10 /* CompatibleAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompatibleAttribute.swift; sourceTree = "<group>"; };
|
||||||
@@ -1069,6 +1071,7 @@
|
|||||||
4CDA128B29EB19C40006FA5A /* LocalNotification.swift */,
|
4CDA128B29EB19C40006FA5A /* LocalNotification.swift */,
|
||||||
4CA5588229F33F5B00DC6A45 /* StringCodable.swift */,
|
4CA5588229F33F5B00DC6A45 /* StringCodable.swift */,
|
||||||
50B5685229F97CB400A23243 /* CredentialHandler.swift */,
|
50B5685229F97CB400A23243 /* CredentialHandler.swift */,
|
||||||
|
4C7D09582A05BEAD00943473 /* KeyboardVisible.swift */,
|
||||||
);
|
);
|
||||||
path = Util;
|
path = Util;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1654,6 +1657,7 @@
|
|||||||
4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */,
|
4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */,
|
||||||
4CB883A82975FC1800DC99E7 /* Zaps.swift in Sources */,
|
4CB883A82975FC1800DC99E7 /* Zaps.swift in Sources */,
|
||||||
4C75EFB128049D510006080F /* NostrResponse.swift in Sources */,
|
4C75EFB128049D510006080F /* NostrResponse.swift in Sources */,
|
||||||
|
4C7D09592A05BEAD00943473 /* KeyboardVisible.swift in Sources */,
|
||||||
4CEE2AF7280B2DEA00AB5EEF /* ProfileName.swift in Sources */,
|
4CEE2AF7280B2DEA00AB5EEF /* ProfileName.swift in Sources */,
|
||||||
4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */,
|
4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */,
|
||||||
31D2E847295218AF006D67F8 /* Shimmer.swift in Sources */,
|
31D2E847295218AF006D67F8 /* Shimmer.swift in Sources */,
|
||||||
|
|||||||
31
damus/Util/KeyboardVisible.swift
Normal file
31
damus/Util/KeyboardVisible.swift
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,8 +6,9 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import Combine
|
||||||
|
|
||||||
struct DMChatView: View {
|
struct DMChatView: View, KeyboardReadable {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@ObservedObject var dms: DirectMessageModel
|
@ObservedObject var dms: DirectMessageModel
|
||||||
@State var showPrivateKeyWarning: Bool = false
|
@State var showPrivateKeyWarning: Bool = false
|
||||||
@@ -24,17 +25,37 @@ struct DMChatView: View {
|
|||||||
DMView(event: dms.events[ind], damus_state: damus_state)
|
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)}
|
.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)
|
.padding(.horizontal)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.dismissKeyboardOnTap()
|
||||||
.onAppear {
|
.onAppear {
|
||||||
scroller.scrollTo("endblock")
|
scroll_to_end(scroller)
|
||||||
}.onChange(of: dms.events.count) { _ in
|
}.onChange(of: dms.events.count) { _ in
|
||||||
withAnimation {
|
scroll_to_end(scroller, animated: true)
|
||||||
scroller.scrollTo("endblock")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
var Footer: some View {
|
||||||
ZStack {
|
|
||||||
BackgroundColor()
|
HStack(spacing: 0) {
|
||||||
|
InputField
|
||||||
HStack(spacing: 0) {
|
|
||||||
InputField
|
|
||||||
|
|
||||||
if !dms.draft.isEmpty {
|
if !dms.draft.isEmpty {
|
||||||
Button(
|
Button(
|
||||||
role: .none,
|
role: .none,
|
||||||
action: {
|
action: {
|
||||||
showPrivateKeyWarning = contentContainsPrivateKey(dms.draft)
|
showPrivateKeyWarning = contentContainsPrivateKey(dms.draft)
|
||||||
|
|
||||||
if !showPrivateKeyWarning {
|
if !showPrivateKeyWarning {
|
||||||
send_message()
|
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)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
.frame(minHeight: 70, maxHeight: 150, alignment: .bottom)
|
.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() {
|
func send_message() {
|
||||||
@@ -143,13 +159,6 @@ struct DMChatView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
Messages
|
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.")
|
Text("Send a message to start the conversation...", comment: "Text prompt for user to send a message to the other user.")
|
||||||
.lineLimit(nil)
|
.lineLimit(nil)
|
||||||
@@ -238,3 +247,4 @@ extension View {
|
|||||||
.background(content())
|
.background(content())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user