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.

feat: use waow.tech alternate typeahead provider

authored by

Patrick Dewey and committed by tangled.org 571d3ab1 3d3b3437

+49 -7
+12 -1
internal/handlers/auth.go
··· 13 13 "github.com/rs/zerolog/log" 14 14 ) 15 15 16 + const ( 17 + // Public Bluesky API 18 + typeaheadProviderBluesky = "public.api.bsky.app" 19 + // waow.tech https://tangled.org/zzstoatzz.io/typeahead 20 + typeaheadProviderWaow = "typeahead.waow.tech" 21 + ) 22 + 16 23 // defaultHTTPClient is a shared HTTP client with connection pooling. 17 24 // Reusing http.Client is recommended by the Go documentation as it 18 25 // manages connection pooling and is safe for concurrent use. ··· 366 373 367 374 // Try using the public API endpoint with typeahead parameter 368 375 // Some PDS instances support public search 369 - searchURL := fmt.Sprintf("https://public.api.bsky.app/xrpc/app.bsky.actor.searchActorsTypeahead?q=%s&limit=5", query) 376 + searchURL := fmt.Sprintf( 377 + "https://%s/xrpc/app.bsky.actor.searchActorsTypeahead?q=%s&limit=5", 378 + typeaheadProviderWaow, 379 + query, 380 + ) 370 381 resp, err := apiClient.Get(searchURL) 371 382 if err != nil { 372 383 log.Warn().Err(err).Str("query", query).Msg("Failed to search actors")
+1 -1
internal/web/components/shared.templ
··· 271 271 required 272 272 class="w-full px-4 py-3 border border-brown-300 rounded-lg focus:ring-2 focus:ring-brown-600 focus:border-brown-600 bg-white" 273 273 /> 274 - <div id="autocomplete-results" class="hidden absolute z-10 w-full mt-1 bg-brown-50 border border-brown-300 rounded-lg shadow-lg max-h-60 overflow-y-auto"></div> 274 + <div id="autocomplete-results" class="hidden handle-dropdown"></div> 275 275 </div> 276 276 <button 277 277 type="submit"
+32
static/css/app.css
··· 677 677 box-shadow: var(--shadow-lg); 678 678 } 679 679 680 + /* Handle autocomplete typeahead dropdown */ 681 + .handle-dropdown { 682 + @apply absolute z-10 w-full mt-1 rounded-lg max-h-60 overflow-y-auto; 683 + background: var(--card-bg); 684 + border: 1px solid var(--card-border); 685 + box-shadow: var(--shadow-lg); 686 + } 687 + 688 + .handle-result { 689 + @apply px-3 py-2 cursor-pointer flex items-center gap-2 transition-colors; 690 + color: var(--text-primary); 691 + } 692 + 693 + .handle-result:hover { 694 + background: var(--surface-bg); 695 + } 696 + 697 + .handle-result .handle-name { 698 + @apply font-medium text-sm truncate; 699 + color: var(--text-primary); 700 + } 701 + 702 + .handle-result .handle-at { 703 + @apply text-xs truncate; 704 + color: var(--text-muted); 705 + } 706 + 707 + .handle-no-results { 708 + @apply px-4 py-3 text-sm; 709 + color: var(--text-muted); 710 + } 711 + 680 712 /* Entity suggestion typeahead dropdown */ 681 713 .suggestions-dropdown { 682 714 @apply absolute z-50 left-0 right-0 mt-1 rounded-lg max-h-48 overflow-y-auto;
+4 -5
static/js/handle-autocomplete.js
··· 55 55 56 56 if (!data.actors || data.actors.length === 0) { 57 57 results.innerHTML = 58 - '<div class="px-4 py-3 text-sm text-gray-500">No accounts found</div>'; 58 + '<div class="handle-no-results">No accounts found</div>'; 59 59 results.classList.remove("hidden"); 60 60 return; 61 61 } ··· 70 70 71 71 // Create container div 72 72 const resultDiv = document.createElement("div"); 73 - resultDiv.className = 74 - "handle-result px-3 py-2 hover:bg-gray-100 cursor-pointer flex items-center gap-2"; 73 + resultDiv.className = "handle-result"; 75 74 resultDiv.setAttribute("data-handle", actor.handle); 76 75 77 76 // Create avatar image ··· 99 98 100 99 // Create display name element 101 100 const nameDiv = document.createElement("div"); 102 - nameDiv.className = "font-medium text-sm text-gray-900 truncate"; 101 + nameDiv.className = "handle-name"; 103 102 nameDiv.textContent = displayName; // textContent auto-escapes 104 103 105 104 // Create handle element 106 105 const handleDiv = document.createElement("div"); 107 - handleDiv.className = "text-xs text-gray-500 truncate"; 106 + handleDiv.className = "handle-at"; 108 107 handleDiv.textContent = "@" + actor.handle; // textContent auto-escapes 109 108 110 109 // Assemble the elements