Signed by hanna SSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
assets/base.css +13 −3 crates/web/src/activity.rs +20 −5 crates/web/src/pages.rs +4 −3 assets/base.css +13 −3 342 } 342 } 343 . label-list . entry-row-body { 343 . label-list . entry-row-body { 344 display : flex ; 344 display : flex ; 345 flex-direction : column ; 345 flex-direction : row ; 346 gap : 0.25rem ; 346 align-items : center ; 347 align-items : flex-start ; 347 gap : 0.6rem ; 348 flex-wrap : wrap ; 349 } 350 . label-list . entry-row-meta { 351 margin : 0 ; 348 } 352 } 349 . label-add { 353 . label-add { 350 display : flex ; 354 display : flex ; 606 margin : 0 0 1rem ; 610 margin : 0 0 1rem ; 607 } 611 } 608 . lang-bar-summary { 612 . lang-bar-summary { 613 614 615 display : block ; 609 list-style : none ; 616 list-style : none ; 610 cursor : pointer ; 617 cursor : pointer ; 611 } 618 } 612 . lang-bar-summary :: -webkit-details-marker { 619 . lang-bar-summary :: -webkit-details-marker { 613 display : none ; 620 display : none ; 614 } 621 } 622 . lang-bar-summary :: marker { 623 content : "" ; 624 } 615 . lang-bar { 625 . lang-bar { 616 display : flex ; 626 display : flex ; 617 height : 0.6rem ; 627 height : 0.6rem ;
crates/web/src/activity.rs +20 −5 25 const WEEKS : usize = 53 ; 25 const WEEKS : usize = 53 ; 26 26 27 const SCAN_PER_REPO : usize = 400 ; 27 const SCAN_PER_REPO : usize = 400 ; 28 28 29 const FEED_LIMIT : usize = 20 ; 29 const FEED_LIMIT : usize = 100 ; 30 30 31 31 32 pub struct FeedItem { 32 pub struct FeedItem { 219 } 219 } 220 } 220 } 221 221 222 222 223 pub fn feed_section ( & self , now_ms : i64 ) -> Markup { 223 224 225 pub fn feed_section ( 226 & self , 227 now_ms : i64 , 228 paging : crate :: repo:: Pagination , 229 path : & str , 230 query : Option < & str > , 231 ) -> Markup { 232 let start = paging. offset ( ) . min ( self . feed. len ( ) ) ; 233 let end = start. saturating_add ( paging. per_page) . min ( self . feed. len ( ) ) ; 234 let page = & self . feed[ start..end] ; 235 let has_next = end < self . feed. len ( ) ; 224 html ! { 236 html ! { 225 section class="listing" { 237 section class="listing" { 226 h2 { "Recent activity" } 238 h2 { "Recent activity" } 228 div class="card" { p class="muted" { "No recent activity." } } 240 div class="card" { p class="muted" { "No recent activity." } } 229 } @else { 241 } @else { 230 ul class="activity-feed card" { 242 ul class="activity-feed card" { 231 @for item in & self . feed { 243 @for item in page { 232 @let base = format ! ( "/{}/{}" , item. owner, item. repo) ; 244 @let base = format ! ( "/{}/{}" , item. owner, item. repo) ; 233 li class="activity-item" { 245 li class="activity-item" { 234 div class="activity-head muted" { 246 div class="activity-head muted" { 246 } 258 } 247 } 259 } 248 } 260 } 261 @if has_next || paging. page > 1 { 262 ( crate :: repo:: pagination_nav ( path, query, paging, has_next) ) 263 } 249 } 264 } 250 } 265 } 251 } 266 }
crates/web/src/pages.rs +4 −3 70 ) -> AppResult < Response > { 70 ) -> AppResult < Response > { 71 let ( jar, chrome) = build_chrome ( & state, jar, user. clone ( ) , uri. path ( ) . to_string ( ) ) ; 71 let ( jar, chrome) = build_chrome ( & state, jar, user. clone ( ) , uri. path ( ) . to_string ( ) ) ; 72 if let Some ( u) = user { 72 if let Some ( u) = user { 73 let body = dashboard_body ( & state, & u, & lq. q. unwrap_or_default ( ) ) . await ?; 73 let body = dashboard_body ( & state, & u, & lq. q. unwrap_or_default ( ) , & uri) . await ?; 74 Ok ( ( jar, page ( & chrome, "Dashboard" , body) ) . into_response ( ) ) 74 Ok ( ( jar, page ( & chrome, "Dashboard" , body) ) . into_response ( ) ) 75 } else { 75 } else { 76 let body = explore_repos_body ( & state, "" ) . await ?; 76 let body = explore_repos_body ( & state, "" ) . await ?; 217 217 218 218 219 219 220 async fn dashboard_body ( state : & AppState , user : & User , q : & str ) -> AppResult < Markup > { 220 async fn dashboard_body ( state : & AppState , user : & User , q : & str , uri : & Uri ) -> AppResult < Markup > { 221 let now = now_ms ( ) ; 221 let now = now_ms ( ) ; 222 let activity = crate :: activity:: compute ( state, user, now) . await ?; 222 let activity = crate :: activity:: compute ( state, user, now) . await ?; 223 let paging = repo:: Pagination :: from_query ( uri. query ( ) ) ; 223 224 224 let mine = state. store. repos_by_owner ( & user. id) . await ?; 225 let mine = state. store. repos_by_owner ( & user. id) . await ?; 225 let needle = q. trim ( ) . to_lowercase ( ) ; 226 let needle = q. trim ( ) . to_lowercase ( ) ; 233 div class="dashboard" { 234 div class="dashboard" { 234 div class="dashboard-main" { 235 div class="dashboard-main" { 235 ( activity. heatmap ( ) ) 236 ( activity. heatmap ( ) ) 236 ( activity. feed_section ( now) ) 237 ( activity. feed_section ( now, paging, uri. path ( ) , uri. query ( ) ) ) 237 } 238 } 238 aside class="dashboard-side" { 239 aside class="dashboard-side" { 239 form class="search-row" method="get" { 240 form class="search-row" method="get" {