view who was fronting when a record was made

refactor: improve how the fronter links look in query output

ptr.pet c68dca70 2da508cc

verified
Changed files
+60 -25
src
entrypoints
popup
+60 -25
src/entrypoints/popup/App.svelte
··· 6 6 import FronterList from "@/components/FronterList.svelte"; 7 7 8 8 let recordAtUri = $state(""); 9 - let queryResult = $state(""); 9 + let queryResult = $state<{ 10 + handle: string; 11 + fronters: { name: string; uri?: string }[]; 12 + } | null>(null); 13 + let queryError = $state(""); 10 14 let isQuerying = $state(false); 11 15 let fronters = $state<string[]>([]); 12 16 let pkFronters = $state<string[]>([]); ··· 14 18 let isFromCurrentTab = $state(false); 15 19 16 20 const makeOutput = (record: any) => { 17 - const fronters = record.members 18 - .map((f: any) => { 19 - if (!f.uri) return f.name; 20 - const publicUri = getMemberPublicUri(f.uri); 21 - if (!publicUri) return f.name; 22 - return `<a href="${publicUri}">${f.name}</a>`; 23 - }) 24 - .join(", "); 25 - return [ 26 - `HANDLE: ${record.handle ?? `handle.invalid (${record.did})`}`, 27 - `FRONTER(S): ${fronters}`, 28 - ].join("<br>"); 21 + const fronters = record.members.map((f: any) => ({ 22 + name: f.name, 23 + uri: f.uri ? getMemberPublicUri(f.uri) : undefined, 24 + })); 25 + return { 26 + handle: record.handle ?? `handle.invalid (${record.did})`, 27 + fronters, 28 + }; 29 29 }; 30 30 31 31 const queryRecord = async (recordUri: ResourceUri) => { 32 32 if (!recordAtUri.trim()) return; 33 33 34 34 isQuerying = true; 35 - queryResult = ""; 35 + queryResult = null; 36 36 37 37 try { 38 38 if (!isResourceUri(recordUri)) throw "INVALID_RESOURCE_URI"; 39 39 const result = expect(await getFronter(recordUri)); 40 - queryResult = makeOutput(result) || "NO_FRONTER_FOUND"; 40 + queryResult = makeOutput(result); 41 41 } catch (error) { 42 - queryResult = `ERROR: ${error}`; 42 + queryResult = null; 43 + queryError = `ERROR: ${error}`; 43 44 } finally { 44 45 isQuerying = false; 45 46 } ··· 67 68 }; 68 69 69 70 const clearResult = () => { 70 - queryResult = ""; 71 + queryResult = null; 72 + queryError = ""; 71 73 recordAtUri = ""; 72 74 isFromCurrentTab = false; 73 75 }; ··· 151 153 {/if} 152 154 </div> 153 155 <div class="clear-button-container"> 154 - {#if queryResult && !isQuerying} 156 + {#if (queryResult || queryError) && !isQuerying} 155 157 <button 156 158 class="clear-button" 157 159 onclick={clearResult} ··· 170 172 > 171 173 <div class="loading-bar"></div> 172 174 </div> 175 + {:else if queryError} 176 + <div class="result-text error"> 177 + {queryError} 178 + </div> 173 179 {:else if queryResult} 174 - <div 175 - class="result-text" 176 - class:error={queryResult.startsWith( 177 - "ERROR:", 178 - )} 179 - > 180 - {@html queryResult} 180 + <div class="result-text"> 181 + <div>HANDLE: {queryResult.handle}</div> 182 + <div> 183 + FRONTER(S): 184 + {#each queryResult.fronters as fronter, i} 185 + {#if fronter.uri} 186 + <a 187 + href={fronter.uri} 188 + class="fronter-link" 189 + >{fronter.name}</a 190 + > 191 + {:else} 192 + {fronter.name} 193 + {/if} 194 + {#if i < queryResult.fronters.length - 1}, 195 + {/if} 196 + {/each} 197 + </div> 181 198 </div> 182 199 {:else} 183 200 <div class="placeholder-text"> ··· 571 588 572 589 .result-text.error { 573 590 color: #ff4444; 591 + } 592 + 593 + .fronter-link { 594 + color: #00ff41; 595 + text-decoration: none; 596 + font-weight: 700; 597 + transition: all 0.2s ease; 598 + position: relative; 599 + border-bottom: 1px solid transparent; 600 + } 601 + 602 + .fronter-link:hover { 603 + color: #33ff66; 604 + border-bottom-color: #00ff41; 605 + } 606 + 607 + .fronter-link:active { 608 + color: #ffffff; 574 609 } 575 610 576 611 .placeholder-text {