@@ -30,74 +30,21 @@ struct SuggestionPanelView: View {
3030 @State var codeHeight : Double = 0
3131
3232 var body : some View {
33- // weird, if the if statement is at the top level, the view may not update sometimes.
3433 VStack {
3534 ZStack ( alignment: . topLeading) {
3635 VStack ( spacing: 0 ) {
3736 ScrollView {
38- LazyVGrid ( columns: [
39- GridItem ( . fixed( 30 ) , alignment: . top) ,
40- GridItem ( . flexible( ) ) ,
41- ] , spacing: 4 ) {
42- ForEach ( 0 ..< viewModel. suggestion. count, id: \. self) { index in
43- Text ( " \( index + viewModel. startLineIndex + 1 ) " )
44- . foregroundColor ( Color . white. opacity ( 0.6 ) )
45- Text ( viewModel. suggestion [ index] )
46- . frame ( maxWidth: . infinity, alignment: . leading)
47- . multilineTextAlignment ( . leading)
48- . lineSpacing ( 4 )
49- }
50- }
51- . foregroundColor ( . white)
52- . font ( . system( size: 12 , design: . monospaced) )
53- . padding ( )
54- . background (
55- GeometryReader { proxy -> Color in
56- Task {
57- codeHeight = proxy. size. height
58- }
59- return Color . clear
60- }
61- )
62-
63- Spacer ( )
37+ CodeBlock ( viewModel: viewModel)
6438 }
65- . frame ( maxHeight: max ( codeHeight, 300 ) )
66- . fixedSize ( horizontal: false , vertical: true )
67-
68- HStack {
69- Text ( " \( viewModel. currentSuggestionIndex) / \( viewModel. suggestionCount) " )
70-
71- Spacer ( )
72-
73- Button ( action: {
74- Task {
75- try await Environment . triggerAction ( " Accept Suggestion " )
76- }
77- } ) {
78- Text ( " Accept " )
79- } . buttonStyle ( CommandButtonStyle ( color: . green) )
80- Button ( action: {
81- Task {
82- try await Environment . triggerAction ( " Reject Suggestion " )
83- }
84- } ) {
85- Text ( " Reject " )
86- } . buttonStyle ( CommandButtonStyle ( color: . red) )
87- }
88- . padding ( )
89- . foregroundColor ( . white)
90- . background ( Color . white. opacity ( 0.1 ) )
39+
40+ ToolBar ( viewModel: viewModel)
9141 }
9242 }
43+ . frame ( maxWidth: . infinity, maxHeight: Style . panelHeight)
44+ . fixedSize ( horizontal: false , vertical: true )
9345 . background ( Color ( red: 31 / 255 , green: 31 / 255 , blue: 36 / 255 ) )
9446 . clipShape ( RoundedRectangle ( cornerRadius: 8 , style: . continuous) )
95- . opacity ( {
96- guard viewModel. isPanelDisplayed else { return 0 }
97- guard !viewModel. suggestion. isEmpty else { return 0 }
98- return 1
99- } ( ) )
100- . frame ( maxWidth: . infinity)
47+
10148 . onHover { yes in
10249 withAnimation ( . easeInOut( duration: 0.2 ) ) {
10350 isHovering = yes
@@ -109,6 +56,79 @@ struct SuggestionPanelView: View {
10956 . frame ( minHeight: 0 , maxHeight: . infinity)
11057 . allowsHitTesting ( false )
11158 }
59+ . overlay (
60+ RoundedRectangle ( cornerRadius: 8 , style: . continuous)
61+ . stroke ( Color . black. opacity ( 0.3 ) , style: . init( lineWidth: 1 ) )
62+ )
63+ . opacity ( {
64+ guard viewModel. isPanelDisplayed else { return 0 }
65+ guard !viewModel. suggestion. isEmpty else { return 0 }
66+ return 1
67+ } ( ) )
68+ }
69+ }
70+
71+ struct CodeBlock : View {
72+ struct SizePreferenceKey : PreferenceKey {
73+ public static var defaultValue : CGSize = . zero
74+ public static func reduce( value: inout CGSize , nextValue: ( ) -> CGSize ) {
75+ value = value. width + value. height > nextValue ( ) . width + nextValue( )
76+ . height ? value : nextValue ( )
77+ }
78+ }
79+
80+ @ObservedObject var viewModel : SuggestionPanelViewModel
81+
82+ var body : some View {
83+ LazyVGrid ( columns: [
84+ GridItem ( . fixed( 30 ) , alignment: . top) ,
85+ GridItem ( . flexible( ) ) ,
86+ ] , spacing: 4 ) {
87+ ForEach ( 0 ..< viewModel. suggestion. count, id: \. self) { index in
88+ Text ( " \( index + viewModel. startLineIndex + 1 ) " )
89+ . foregroundColor ( Color . white. opacity ( 0.6 ) )
90+ Text ( viewModel. suggestion [ index] )
91+ . frame ( maxWidth: . infinity, alignment: . leading)
92+ . multilineTextAlignment ( . leading)
93+ . lineSpacing ( 4 )
94+ }
95+ }
96+ . foregroundColor ( . white)
97+ . font ( . system( size: 12 , design: . monospaced) )
98+ . padding ( )
99+ . background ( GeometryReader ( content: { proxy in
100+ Color . clear. preference ( key: SizePreferenceKey . self, value: proxy. size)
101+ } ) )
102+ }
103+ }
104+
105+ struct ToolBar : View {
106+ @ObservedObject var viewModel : SuggestionPanelViewModel
107+
108+ var body : some View {
109+ HStack {
110+ Text ( " \( viewModel. currentSuggestionIndex) / \( viewModel. suggestionCount) " )
111+
112+ Spacer ( )
113+
114+ Button ( action: {
115+ Task {
116+ try await Environment . triggerAction ( " Accept Suggestion " )
117+ }
118+ } ) {
119+ Text ( " Accept " )
120+ } . buttonStyle ( CommandButtonStyle ( color: . green) )
121+ Button ( action: {
122+ Task {
123+ try await Environment . triggerAction ( " Reject Suggestion " )
124+ }
125+ } ) {
126+ Text ( " Reject " )
127+ } . buttonStyle ( CommandButtonStyle ( color: . red) )
128+ }
129+ . padding ( )
130+ . foregroundColor ( . white)
131+ . background ( Color . white. opacity ( 0.1 ) )
112132 }
113133}
114134
0 commit comments