@@ -14,53 +14,68 @@ struct CommentRow: View {
1414 let state : CommentState
1515 let likeComment : ( CommentState ) -> Void
1616 let toggleComment : ( ) -> Void
17+
18+ @State private var isPressed = false
1719
1820 var body : some View {
19- VStack ( alignment: . leading) {
21+ VStack ( alignment: . leading, spacing : 0 ) {
2022 // first row
2123 HStack {
22- // author
23- Text ( " @ \( state. user) " )
24- . font ( . ibmPlexMono( . bold, size: 12 ) )
25- // time
26- HStack ( alignment: . center, spacing: 4.0 ) {
27- Image ( systemName: " clock " )
24+ Group {
25+ // author
26+ Text ( " @ \( state. user) " )
27+ . font ( . ibmPlexMono( . bold, size: 12 ) )
28+ // time
29+ HStack ( alignment: . center, spacing: 4.0 ) {
30+ Image ( systemName: " clock " )
31+ . font ( . system( size: 12 ) )
32+ Text ( state. age)
33+ . font ( . ibmPlexSans( . medium, size: 12 ) )
34+ }
35+ . font ( . caption)
36+ // collapse/expand
37+ Image ( systemName: " chevron.up.chevron.down " )
2838 . font ( . system( size: 12 ) )
29- Text ( state. age)
30- . font ( . ibmPlexSans( . medium, size: 12 ) )
39+ . rotationEffect ( . degrees( state. hidden ? 180 : 0 ) )
40+ // space between
41+ Spacer ( )
42+ // upvote
43+ Button ( action: {
44+ likeComment ( state)
45+ } ) {
46+ Image ( systemName: " arrow.up " )
47+ . font ( . system( size: 12 ) )
48+ . padding ( . horizontal, 8 )
49+ . padding ( . vertical, 4 )
50+ }
51+ . background ( state. upvoted ? . green. opacity ( 0.2 ) : . white. opacity ( 0.2 ) )
52+ . foregroundStyle ( state. upvoted ? . green : . onBackground)
53+ . clipShape ( Capsule ( ) )
3154 }
32- . font ( . caption)
33- // collapse/expand
34- Image ( systemName: " chevron.up.chevron.down " )
35- . font ( . system( size: 12 ) )
36- // space between
37- Spacer ( )
38- // upvote
39- Button ( action: {
40- likeComment ( state)
41- } ) {
42- Image ( systemName: " arrow.up " )
43- . font ( . system( size: 12 ) )
44- . padding ( . horizontal, 8 )
45- . padding ( . vertical, 4 )
46- }
47- . background ( state. upvoted ? . green. opacity ( 0.2 ) : . white. opacity ( 0.2 ) )
48- . foregroundStyle ( state. upvoted ? . green : . onBackground)
49- . clipShape ( Capsule ( ) )
5055 }
56+ . padding ( 8 )
57+ . background ( isPressed ? . surface. opacity ( 0.85 ) : . surface)
58+ . zIndex ( 1 ) // Ensure header stays on top
5159
5260 // Comment Body
5361 if !state. hidden {
54- Text ( state. text. strippingHTML ( ) )
55- . font ( . ibmPlexMono( . regular, size: 12 ) )
62+ VStack ( alignment: . leading) {
63+ Text ( state. text. strippingHTML ( ) )
64+ . font ( . ibmPlexMono( . regular, size: 12 ) )
65+ }
66+ . padding ( EdgeInsets ( top: - 3 , leading: 8 , bottom: 8 , trailing: 8 ) )
67+ . transition (
68+ . asymmetric(
69+ insertion: . move( edge: . top) . combined ( with: . opacity) ,
70+ removal: . move( edge: . top) . combined ( with: . opacity)
71+ )
72+ )
5673 }
5774 }
58- . padding ( 8.0 )
59- . background ( . surface)
75+ . background ( isPressed ? . surface. opacity ( 0.85 ) : . surface)
6076 . clipShape ( RoundedRectangle ( cornerRadius: 16.0 ) )
61- . onTapGesture {
62- toggleComment ( )
63- }
77+ . animation ( . spring( duration: 0.3 ) , value: state. hidden)
78+ . simultaneousGesture ( makeCommentGesture ( ) )
6479 . padding (
6580 EdgeInsets (
6681 top: 0 ,
@@ -71,6 +86,27 @@ struct CommentRow: View {
7186 }
7287}
7388
89+ extension CommentRow {
90+ fileprivate func makeCommentGesture( ) -> some Gesture {
91+ DragGesture ( minimumDistance: 0 )
92+ . onChanged { value in
93+ // Only show press effect if we haven't moved far
94+ if abs ( value. translation. height) < 2 && abs ( value. translation. width) < 2 {
95+ isPressed = true
96+ } else {
97+ isPressed = false
98+ }
99+ }
100+ . onEnded { value in
101+ isPressed = false
102+ // Trigger tap if it was a small movement (effectively a tap)
103+ if abs ( value. translation. height) < 2 && abs ( value. translation. width) < 2 {
104+ toggleComment ( )
105+ }
106+ }
107+ }
108+ }
109+
74110struct CommentView_Preview : PreviewProvider {
75111 static var previews : some View {
76112 PreviewVariants {
0 commit comments