1
1
use crate :: {
2
- app_style:: { get_font_size, NotedeckTextStyle } ,
3
- fonts:: NamedFontFamily ,
2
+ app_style:: NotedeckTextStyle ,
3
+ column:: Columns ,
4
+ imgcache:: ImageCache ,
4
5
nav:: RenderNavAction ,
5
6
route:: Route ,
6
- ui:: anim:: { AnimationHelper , ICON_EXPANSION_MULTIPLE } ,
7
+ timeline:: { TimelineId , TimelineRoute } ,
8
+ ui:: {
9
+ self ,
10
+ anim:: { AnimationHelper , ICON_EXPANSION_MULTIPLE } ,
11
+ } ,
7
12
} ;
8
13
9
- use egui:: { pos2, Color32 , Stroke } ;
14
+ use egui:: { pos2, RichText , Stroke } ;
15
+ use enostr:: Pubkey ;
16
+ use nostrdb:: { Ndb , Transaction } ;
10
17
11
18
pub struct NavTitle < ' a > {
19
+ ndb : & ' a Ndb ,
20
+ img_cache : & ' a mut ImageCache ,
21
+ columns : & ' a Columns ,
22
+ deck_author : Option < & ' a Pubkey > ,
12
23
routes : & ' a [ Route ] ,
13
24
}
14
25
15
26
impl < ' a > NavTitle < ' a > {
16
- pub fn new ( routes : & ' a [ Route ] ) -> Self {
17
- NavTitle { routes }
27
+ pub fn new (
28
+ ndb : & ' a Ndb ,
29
+ img_cache : & ' a mut ImageCache ,
30
+ columns : & ' a Columns ,
31
+ deck_author : Option < & ' a Pubkey > ,
32
+ routes : & ' a [ Route ] ,
33
+ ) -> Self {
34
+ NavTitle {
35
+ ndb,
36
+ img_cache,
37
+ columns,
38
+ deck_author,
39
+ routes,
40
+ }
18
41
}
19
42
20
43
pub fn show ( & mut self , ui : & mut egui:: Ui ) -> Option < RenderNavAction > {
@@ -32,7 +55,6 @@ impl<'a> NavTitle<'a> {
32
55
) -> Option < RenderNavAction > {
33
56
let icon_width = 32.0 ;
34
57
let padding_external = 16.0 ;
35
- let padding_internal = 8.0 ;
36
58
let has_back = prev ( self . routes ) . is_some ( ) ;
37
59
38
60
let ( spacing_rect, titlebar_rect) = allocated_response
@@ -41,7 +63,8 @@ impl<'a> NavTitle<'a> {
41
63
42
64
ui. advance_cursor_after_rect ( spacing_rect) ;
43
65
44
- let ( titlebar_resp, back_button_resp) = if has_back {
66
+ // TODO: what are we doing with titlebar_response ?
67
+ let ( _titlebar_resp, back_button_resp) = if has_back {
45
68
let ( button_rect, titlebar_rect) = titlebar_rect. split_left_right_at_x (
46
69
allocated_response. rect . left ( ) + icon_width + padding_external,
47
70
) ;
@@ -53,20 +76,7 @@ impl<'a> NavTitle<'a> {
53
76
( allocated_response, None )
54
77
} ;
55
78
56
- self . title (
57
- ui,
58
- self . routes . last ( ) . unwrap ( ) ,
59
- titlebar_resp. rect ,
60
- icon_width,
61
- if has_back {
62
- padding_internal
63
- } else {
64
- padding_external
65
- } ,
66
- ) ;
67
-
68
- let delete_button_resp =
69
- self . delete_column_button ( ui, titlebar_resp, icon_width, padding_external) ;
79
+ let delete_button_resp = self . title ( ui, self . routes . last ( ) . unwrap ( ) ) ;
70
80
71
81
if delete_button_resp. clicked ( ) {
72
82
Some ( RenderNavAction :: RemoveColumn )
@@ -116,13 +126,7 @@ impl<'a> NavTitle<'a> {
116
126
helper. take_animation_response ( )
117
127
}
118
128
119
- fn delete_column_button (
120
- & self ,
121
- ui : & mut egui:: Ui ,
122
- allocation_response : egui:: Response ,
123
- icon_width : f32 ,
124
- padding : f32 ,
125
- ) -> egui:: Response {
129
+ fn delete_column_button ( & self , ui : & mut egui:: Ui , icon_width : f32 ) -> egui:: Response {
126
130
let img_size = 16.0 ;
127
131
let max_size = icon_width * ICON_EXPANSION_MULTIPLE ;
128
132
@@ -133,20 +137,8 @@ impl<'a> NavTitle<'a> {
133
137
} ;
134
138
let img = egui:: Image :: new ( img_data) . max_width ( img_size) ;
135
139
136
- let button_rect = {
137
- let titlebar_rect = allocation_response. rect ;
138
- let titlebar_width = titlebar_rect. width ( ) ;
139
- let titlebar_center = titlebar_rect. center ( ) ;
140
- let button_center_y = titlebar_center. y ;
141
- let button_center_x =
142
- titlebar_center. x + ( titlebar_width / 2.0 ) - ( max_size / 2.0 ) - padding;
143
- egui:: Rect :: from_center_size (
144
- pos2 ( button_center_x, button_center_y) ,
145
- egui:: vec2 ( max_size, max_size) ,
146
- )
147
- } ;
148
-
149
- let helper = AnimationHelper :: new_from_rect ( ui, "delete-column-button" , button_rect) ;
140
+ let helper =
141
+ AnimationHelper :: new ( ui, "delete-column-button" , egui:: vec2 ( max_size, max_size) ) ;
150
142
151
143
let cur_img_size = helper. scale_1d_pos_min_max ( 0.0 , img_size) ;
152
144
@@ -158,42 +150,89 @@ impl<'a> NavTitle<'a> {
158
150
animation_resp
159
151
}
160
152
161
- fn title (
162
- & mut self ,
163
- ui : & mut egui :: Ui ,
164
- top : & Route ,
165
- titlebar_rect : egui :: Rect ,
166
- icon_width : f32 ,
167
- padding : f32 ,
168
- ) {
169
- let painter = ui . painter_at ( titlebar_rect ) ;
170
-
171
- let font = egui :: FontId :: new (
172
- get_font_size ( ui. ctx ( ) , & NotedeckTextStyle :: Body ) ,
173
- egui :: FontFamily :: Name ( NamedFontFamily :: Bold . as_str ( ) . into ( ) ) ,
174
- ) ;
153
+ fn pubkey_pfp < ' txn , ' me > (
154
+ & ' me mut self ,
155
+ txn : & ' txn Transaction ,
156
+ pubkey : & [ u8 ; 32 ] ,
157
+ pfp_size : f32 ,
158
+ ) -> Option < ui :: ProfilePic < ' me , ' txn > > {
159
+ self . ndb
160
+ . get_profile_by_pubkey ( txn , pubkey )
161
+ . as_ref ( )
162
+ . ok ( )
163
+ . and_then ( move |p| {
164
+ Some ( ui:: ProfilePic :: from_profile ( self . img_cache , p ) ? . size ( pfp_size ) )
165
+ } )
166
+ }
175
167
176
- let max_title_width = titlebar_rect. width ( ) - icon_width - padding * 2. ;
168
+ fn timeline_pfp ( & mut self , ui : & mut egui:: Ui , id : TimelineId , pfp_size : f32 ) {
169
+ let txn = Transaction :: new ( self . ndb ) . unwrap ( ) ;
170
+
171
+ if let Some ( pfp) = self
172
+ . columns
173
+ . find_timeline ( id)
174
+ . and_then ( |tl| tl. kind . pubkey_source ( ) )
175
+ . and_then ( |pksrc| self . deck_author . map ( |da| pksrc. to_pubkey ( da) ) )
176
+ . and_then ( |pk| self . pubkey_pfp ( & txn, pk. bytes ( ) , pfp_size) )
177
+ {
178
+ ui. add ( pfp) ;
179
+ } else {
180
+ ui. add (
181
+ ui:: ProfilePic :: new ( self . img_cache , ui:: ProfilePic :: no_pfp_url ( ) ) . size ( pfp_size) ,
182
+ ) ;
183
+ }
184
+ }
177
185
178
- let title_galley = ui. fonts ( |f| {
179
- f. layout (
180
- top. to_string ( ) ,
181
- font,
182
- ui. visuals ( ) . text_color ( ) ,
183
- max_title_width,
184
- )
185
- } ) ;
186
+ fn title_pfp ( & mut self , ui : & mut egui:: Ui , top : & Route ) {
187
+ let pfp_size = 32.0 ;
188
+ match top {
189
+ Route :: Timeline ( tlr) => match tlr {
190
+ TimelineRoute :: Timeline ( tlid) => {
191
+ self . timeline_pfp ( ui, * tlid, pfp_size) ;
192
+ }
193
+
194
+ TimelineRoute :: Thread ( _note_id) => { }
195
+ TimelineRoute :: Reply ( _note_id) => { }
196
+ TimelineRoute :: Quote ( _note_id) => { }
197
+
198
+ TimelineRoute :: Profile ( pubkey) => {
199
+ let txn = Transaction :: new ( self . ndb ) . unwrap ( ) ;
200
+ if let Some ( pfp) = self . pubkey_pfp ( & txn, pubkey. bytes ( ) , pfp_size) {
201
+ ui. add ( pfp) ;
202
+ } else {
203
+ ui. add (
204
+ ui:: ProfilePic :: new ( self . img_cache , ui:: ProfilePic :: no_pfp_url ( ) )
205
+ . size ( pfp_size) ,
206
+ ) ;
207
+ }
208
+ }
209
+ } ,
186
210
187
- let pos = {
188
- let titlebar_center = titlebar_rect. center ( ) ;
189
- let text_height = title_galley. rect . height ( ) ;
211
+ Route :: Accounts ( _as) => { }
212
+ Route :: ComposeNote => { }
213
+ Route :: AddColumn ( _add_col_route) => { }
214
+ Route :: Support => { }
215
+ Route :: Relays => { }
216
+ }
217
+ }
190
218
191
- let galley_pos_x = titlebar_rect. left ( ) + padding;
192
- let galley_pos_y = titlebar_center. y - ( text_height / 2. ) ;
193
- pos2 ( galley_pos_x, galley_pos_y)
194
- } ;
219
+ fn title ( & mut self , ui : & mut egui:: Ui , top : & Route ) -> egui:: Response {
220
+ ui. horizontal ( |ui| {
221
+ ui. spacing_mut ( ) . item_spacing . x = 10.0 ;
222
+
223
+ self . title_pfp ( ui, top) ;
224
+
225
+ ui. label (
226
+ RichText :: new ( top. title ( self . columns ) )
227
+ . text_style ( NotedeckTextStyle :: Body . text_style ( ) ) ,
228
+ ) ;
195
229
196
- painter. galley ( pos, title_galley, Color32 :: WHITE ) ;
230
+ ui. with_layout ( egui:: Layout :: right_to_left ( egui:: Align :: Center ) , |ui| {
231
+ self . delete_column_button ( ui, 32.0 )
232
+ } )
233
+ . inner
234
+ } )
235
+ . inner
197
236
}
198
237
}
199
238
0 commit comments