Coffee journaling on ATProto (alpha) alpha.arabica.social
coffee
17
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: fix popular sort fetch limit

authored by

Patrick Dewey and committed by tangled.org b448aeac 32166a27

+111 -2
+8 -2
internal/firehose/index.go
··· 455 455 collectionFilter = nsid 456 456 } 457 457 458 - items, err := idx.getFeedItems(ctx, collectionFilter, q.Limit+1, q.Cursor) 458 + // For popular sort, fetch more candidates to re-rank by score 459 + fetchLimit := q.Limit + 1 460 + if q.Sort == FeedSortPopular { 461 + fetchLimit = q.Limit * 5 462 + } 463 + 464 + items, err := idx.getFeedItems(ctx, collectionFilter, fetchLimit, q.Cursor) 459 465 if err != nil { 460 466 return nil, err 461 467 } 462 468 463 - // Sort based on query 469 + 464 470 if q.Sort == FeedSortPopular { 465 471 sort.Slice(items, func(i, j int) bool { 466 472 scoreI := items[i].LikeCount*3 + items[i].CommentCount*2
+103
internal/web/pages/feed.templ
··· 3 3 import ( 4 4 "arabica/internal/feed" 5 5 "arabica/internal/lexicons" 6 + "arabica/internal/web/bff" 6 7 "arabica/internal/web/components" 7 8 "fmt" 8 9 ) ··· 311 312 > 312 313 @components.BrewContent(item.Brew) 313 314 </a> 315 + } 316 + } 317 + 318 + // FeedBrewContent renders brew content in a feed card 319 + templ FeedBrewContent(item *feed.FeedItem) { 320 + if item.Brew != nil { 321 + <div class="feed-content-box"> 322 + <!-- Bean info with rating --> 323 + <div class="flex items-start justify-between gap-3 mb-3"> 324 + <div class="flex-1 min-w-0"> 325 + if item.Brew.Bean != nil { 326 + <div class="font-bold text-brown-900 text-base"> 327 + if item.Brew.Bean.Name != "" { 328 + { item.Brew.Bean.Name } 329 + } else { 330 + { item.Brew.Bean.Origin } 331 + } 332 + </div> 333 + if item.Brew.Bean.Roaster != nil && item.Brew.Bean.Roaster.Name != "" { 334 + <div class="text-sm text-brown-700 mt-0.5"> 335 + <span class="font-medium">🏭 { item.Brew.Bean.Roaster.Name }</span> 336 + </div> 337 + } 338 + <div class="text-xs text-brown-600 mt-1 flex flex-wrap gap-x-2 gap-y-0.5"> 339 + if item.Brew.Bean.Origin != "" { 340 + <span class="inline-flex items-center gap-0.5">📍 { item.Brew.Bean.Origin }</span> 341 + } 342 + if item.Brew.Bean.RoastLevel != "" { 343 + <span class="inline-flex items-center gap-0.5">🔥 { item.Brew.Bean.RoastLevel }</span> 344 + } 345 + if item.Brew.Bean.Process != "" { 346 + <span class="inline-flex items-center gap-0.5">🌱 { item.Brew.Bean.Process }</span> 347 + } 348 + if item.Brew.CoffeeAmount > 0 { 349 + <span class="inline-flex items-center gap-0.5">⚖️ { fmt.Sprintf("%dg", item.Brew.CoffeeAmount) }</span> 350 + } 351 + </div> 352 + } 353 + </div> 354 + if item.Brew.Rating > 0 { 355 + <span class="badge-rating"> 356 + ⭐ { fmt.Sprintf("%d/10", item.Brew.Rating) } 357 + </span> 358 + } 359 + </div> 360 + <!-- Brewer --> 361 + if item.Brew.BrewerObj != nil || item.Brew.Method != "" { 362 + <div class="mb-2"> 363 + <span class="text-meta">Brewer:</span> 364 + <span class="text-sm font-semibold text-brown-900"> 365 + if item.Brew.BrewerObj != nil { 366 + { item.Brew.BrewerObj.Name } 367 + } else if item.Brew.Method != "" { 368 + { item.Brew.Method } 369 + } 370 + </span> 371 + </div> 372 + } 373 + <!-- Brew parameters in compact grid --> 374 + <div class="grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-brown-700"> 375 + if item.Brew.GrinderObj != nil { 376 + <div> 377 + <span class="text-label">Grinder:</span> 378 + { " " }{ item.Brew.GrinderObj.Name } 379 + if item.Brew.GrindSize != "" { 380 + ({ item.Brew.GrindSize }) 381 + } 382 + </div> 383 + } else if item.Brew.GrindSize != "" { 384 + <div> 385 + <span class="text-label">Grind:</span> { item.Brew.GrindSize } 386 + </div> 387 + } 388 + if len(item.Brew.Pours) > 0 { 389 + <div class="col-span-2"> 390 + <span class="text-label">Pours:</span> 391 + for _, pour := range item.Brew.Pours { 392 + <div class="pl-2 text-brown-600">• { fmt.Sprintf("%dg @ %s", pour.WaterAmount, bff.FormatTime(pour.TimeSeconds)) }</div> 393 + } 394 + </div> 395 + } else if item.Brew.WaterAmount > 0 { 396 + <div> 397 + <span class="text-label">Water:</span> { fmt.Sprintf("%dg", item.Brew.WaterAmount) } 398 + </div> 399 + } 400 + if bff.HasTemp(item.Brew.Temperature) { 401 + <div> 402 + <span class="text-label">Temp:</span> { bff.FormatTemp(item.Brew.Temperature) } 403 + </div> 404 + } 405 + if item.Brew.TimeSeconds > 0 { 406 + <div> 407 + <span class="text-label">Time:</span> { bff.FormatTime(item.Brew.TimeSeconds) } 408 + </div> 409 + } 410 + </div> 411 + if item.Brew.TastingNotes != "" { 412 + <div class="mt-3 text-sm text-brown-800 italic border-t border-brown-200 pt-2"> 413 + "{ item.Brew.TastingNotes }" 414 + </div> 415 + } 416 + </div> 314 417 } 315 418 } 316 419