mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Fix: Voice recording tooltip location (#1961)
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
This commit is contained in:
@@ -28,7 +28,7 @@ import SwiftUI
|
|||||||
/// ```
|
/// ```
|
||||||
struct ViewFrameReader: View {
|
struct ViewFrameReader: View {
|
||||||
@Binding var frame: CGRect
|
@Binding var frame: CGRect
|
||||||
let coordinateSpace: CoordinateSpace = .local
|
var coordinateSpace: CoordinateSpace = .local
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { geometry in
|
GeometryReader { geometry in
|
||||||
|
|||||||
@@ -32,12 +32,13 @@ struct ComposerToolbar: View {
|
|||||||
@State private var voiceMessageRecordingStartTime: Date?
|
@State private var voiceMessageRecordingStartTime: Date?
|
||||||
@State private var showVoiceMessageRecordingTooltip = false
|
@State private var showVoiceMessageRecordingTooltip = false
|
||||||
@ScaledMetric private var voiceMessageTooltipPointerHeight = 6
|
@ScaledMetric private var voiceMessageTooltipPointerHeight = 6
|
||||||
|
@State private var voiceMessageRecordingButtonFrame: CGRect = .zero
|
||||||
|
|
||||||
private let voiceMessageMinimumRecordingDuration = 1.0
|
private let voiceMessageMinimumRecordingDuration = 1.0
|
||||||
private let voiceMessageTooltipDuration = 1.0
|
private let voiceMessageTooltipDuration = 1.0
|
||||||
|
|
||||||
@State private var frame: CGRect = .zero
|
@State private var frame: CGRect = .zero
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 8) {
|
VStack(spacing: 8) {
|
||||||
topBar
|
topBar
|
||||||
@@ -86,6 +87,9 @@ struct ComposerToolbar: View {
|
|||||||
.padding(.leading, 3)
|
.padding(.leading, 3)
|
||||||
} else if context.viewState.enableVoiceMessageComposer {
|
} else if context.viewState.enableVoiceMessageComposer {
|
||||||
voiceMessageRecordingButton
|
voiceMessageRecordingButton
|
||||||
|
.background {
|
||||||
|
ViewFrameReader(frame: $voiceMessageRecordingButtonFrame, coordinateSpace: .global)
|
||||||
|
}
|
||||||
.padding(.leading, 4)
|
.padding(.leading, 4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,7 +294,10 @@ struct ComposerToolbar: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var voiceMessageRecordingButtonTooltipView: some View {
|
private var voiceMessageRecordingButtonTooltipView: some View {
|
||||||
VoiceMessageRecordingButtonTooltipView(text: L10n.screenRoomVoiceMessageTooltip, pointerHeight: voiceMessageTooltipPointerHeight)
|
VoiceMessageRecordingButtonTooltipView(text: L10n.screenRoomVoiceMessageTooltip,
|
||||||
|
pointerHeight: voiceMessageTooltipPointerHeight,
|
||||||
|
pointerLocation: voiceMessageRecordingButtonFrame.midX,
|
||||||
|
pointerLocationCoordinateSpace: .global)
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + voiceMessageTooltipDuration) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + voiceMessageTooltipDuration) {
|
||||||
@@ -299,6 +306,7 @@ struct ComposerToolbar: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func voiceMessagePreviewComposer(audioPlayerState: AudioPlayerState, waveform: WaveformSource) -> some View {
|
private func voiceMessagePreviewComposer(audioPlayerState: AudioPlayerState, waveform: WaveformSource) -> some View {
|
||||||
|
|||||||
+26
-17
@@ -24,7 +24,8 @@ struct VoiceMessageRecordingButtonTooltipView: View {
|
|||||||
var corners: UIRectCorner = .allCorners
|
var corners: UIRectCorner = .allCorners
|
||||||
@ScaledMetric var pointerHeight: CGFloat = 6
|
@ScaledMetric var pointerHeight: CGFloat = 6
|
||||||
@ScaledMetric var pointerWidth: CGFloat = 10
|
@ScaledMetric var pointerWidth: CGFloat = 10
|
||||||
@ScaledMetric var pointerOffset: CGFloat = 8
|
var pointerLocation: CGFloat = 10
|
||||||
|
var pointerLocationCoordinateSpace: CoordinateSpace = .local
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Text(text)
|
Text(text)
|
||||||
@@ -32,27 +33,35 @@ struct VoiceMessageRecordingButtonTooltipView: View {
|
|||||||
.foregroundColor(.compound.textOnSolidPrimary)
|
.foregroundColor(.compound.textOnSolidPrimary)
|
||||||
.padding(6)
|
.padding(6)
|
||||||
.background(
|
.background(
|
||||||
TooltipShape(radius: radius,
|
GeometryReader { geometry in
|
||||||
corners: corners,
|
TooltipShape(radius: radius,
|
||||||
pointerHeight: pointerHeight,
|
corners: corners,
|
||||||
pointerWidth: pointerWidth,
|
pointerHeight: pointerHeight,
|
||||||
pointerOffset: pointerOffset)
|
pointerWidth: pointerWidth,
|
||||||
.fill(.compound.bgActionPrimaryRest)
|
pointerLocation: localPointerLocation(using: geometry))
|
||||||
|
.fill(.compound.bgActionPrimaryRest)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.padding(.trailing, 8)
|
}
|
||||||
|
|
||||||
|
private func localPointerLocation(using geometry: GeometryProxy) -> CGFloat {
|
||||||
|
let frame = geometry.frame(in: pointerLocationCoordinateSpace)
|
||||||
|
let minX = radius + pointerWidth / 2
|
||||||
|
let maxX = geometry.size.width - radius - pointerWidth / 2
|
||||||
|
return min(max(minX, pointerLocation - frame.minX), maxX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct TooltipShape: Shape {
|
private struct TooltipShape: Shape {
|
||||||
var radius: CGFloat = 4
|
var radius: CGFloat
|
||||||
var corners: UIRectCorner = .allCorners
|
var corners: UIRectCorner
|
||||||
var pointerHeight: CGFloat = 6
|
var pointerHeight: CGFloat
|
||||||
var pointerWidth: CGFloat = 10
|
var pointerWidth: CGFloat
|
||||||
var pointerOffset: CGFloat = 8
|
var pointerLocation: CGFloat
|
||||||
|
|
||||||
func path(in rect: CGRect) -> Path {
|
func path(in rect: CGRect) -> Path {
|
||||||
var path = Path()
|
var path = Path()
|
||||||
|
|
||||||
let width = rect.size.width
|
let width = rect.size.width
|
||||||
let height = rect.size.height
|
let height = rect.size.height
|
||||||
|
|
||||||
@@ -76,9 +85,9 @@ private struct TooltipShape: Shape {
|
|||||||
path.addArc(center: CGPoint(x: width - bottomRight, y: height - bottomRight), radius: bottomRight,
|
path.addArc(center: CGPoint(x: width - bottomRight, y: height - bottomRight), radius: bottomRight,
|
||||||
startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false)
|
startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false)
|
||||||
|
|
||||||
path.addLine(to: CGPoint(x: width - pointerOffset, y: height))
|
path.addLine(to: CGPoint(x: pointerLocation + (pointerWidth / 2.0), y: height))
|
||||||
path.addLine(to: CGPoint(x: width - pointerOffset - (pointerWidth / 2.0), y: height + pointerHeight))
|
path.addLine(to: CGPoint(x: pointerLocation, y: height + pointerHeight))
|
||||||
path.addLine(to: CGPoint(x: width - pointerOffset - pointerWidth, y: height))
|
path.addLine(to: CGPoint(x: pointerLocation - (pointerWidth / 2.0), y: height))
|
||||||
|
|
||||||
path.addLine(to: CGPoint(x: bottomLeft, y: height))
|
path.addLine(to: CGPoint(x: bottomLeft, y: height))
|
||||||
path.addArc(center: CGPoint(x: bottomLeft, y: height - bottomLeft), radius: bottomLeft,
|
path.addArc(center: CGPoint(x: bottomLeft, y: height - bottomLeft), radius: bottomLeft,
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b82dbb24ecf09d3fa08a0308181b83106f7e62935ee5f1201ef8ae1533e33ded
|
oid sha256:ffcce0a3fe8e27798377372f73090b72a27c986d36f4936701317d60571f5b92
|
||||||
size 60029
|
size 60040
|
||||||
|
|||||||
Reference in New Issue
Block a user