This repository has no description
0

Configure Feed

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

fix

+15 -105
+9 -1
src/components/Verifier/Verifier.css
··· 108 108 flex-wrap: wrap; /* Allow wrapping */ 109 109 padding: 0px; 110 110 border: 0px; 111 - position: relative; /* Added for suggestion list positioning */ 111 + /* position: relative; */ /* Removed - no longer needed */ 112 112 } 113 113 114 114 .verifier-input-field { ··· 123 123 font-family: inherit; /* Use main font */ 124 124 min-width: 200px; /* Ensure minimum width */ 125 125 margin: 0px; 126 + text-align: left; 126 127 } 127 128 128 129 .verifier-input-field:hover, ··· 185 186 } 186 187 187 188 .verifier-list { 189 + list-style: none; 190 + padding: 0; 191 + margin: 0; /* Reset default ul margins */ 188 192 margin-top: 15px; 193 + width: 100%; /* Added */ 194 + box-sizing: border-box; /* Added */ 189 195 } 190 196 191 197 .verifier-list, ··· 205 211 margin-bottom: 10px; 206 212 flex-wrap: wrap; /* Allow actions to wrap */ 207 213 gap: 10px; 214 + width: 100%; /* Added */ 215 + box-sizing: border-box; /* Added */ 208 216 } 209 217 .verifier-list-item-content { 210 218 flex-grow: 1;
+6 -104
src/components/Verifier/Verifier.js
··· 1 - import React, { useState, useEffect, useRef, useCallback } from 'react'; 1 + import React, { useState, useEffect, useCallback } from 'react'; 2 2 import { useAuth } from '../../contexts/AuthContext'; 3 3 import { Agent } from '@atproto/api'; 4 4 import './Verifier.css'; ··· 108 108 } 109 109 } 110 110 111 - // --- Debounce Hook --- 112 - function useDebounce(value, delay) { 113 - const [debouncedValue, setDebouncedValue] = useState(value); 114 - 115 - useEffect(() => { 116 - const handler = setTimeout(() => { 117 - setDebouncedValue(value); 118 - }, delay); 119 - return () => { 120 - clearTimeout(handler); 121 - }; 122 - }, [value, delay]); 123 - 124 - return debouncedValue; 125 - } 126 - // --- End Debounce Hook --- 127 - 128 111 // Renamed component to Verifier 129 112 function Verifier() { 130 113 // Use the main app's AuthContext ··· 151 134 const [isCheckingValidity, setIsCheckingValidity] = useState(false); 152 135 const [networkStatusMessage, setNetworkStatusMessage] = useState(''); 153 136 const [officialVerifiersStatus, setOfficialVerifiersStatus] = useState({}); 154 - 155 - // --- Autocomplete State --- 156 - const [suggestions, setSuggestions] = useState([]); 157 - const [isFetchingSuggestions, setIsFetchingSuggestions] = useState(false); 158 - const [showSuggestions, setShowSuggestions] = useState(false); 159 - const debouncedSearchTerm = useDebounce(targetHandle, 300); 160 - const suggestionsRef = useRef(null); 161 - const inputRef = useRef(null); 162 - // --- End Autocomplete State --- 163 137 164 138 useEffect(() => { 165 139 if (session) { ··· 527 501 } 528 502 }, [session, checkOfficialVerification]); 529 503 530 - const fetchSuggestions = useCallback(async (query) => { 531 - if (!query || query.trim().length < 2) { 532 - setSuggestions([]); 533 - return; 534 - } 535 - setIsFetchingSuggestions(true); 536 - try { 537 - // *** Use direct fetch *** 538 - const url = new URL('https://public.api.bsky.app/xrpc/app.bsky.actor.searchActorsTypeahead'); 539 - url.searchParams.append('q', query); 540 - url.searchParams.append('limit', '5'); 541 - const response = await fetch(url.toString()); 542 - if (!response.ok) throw new Error(`Suggestions fetch failed: ${response.status}`); 543 - const data = await response.json(); 544 - setSuggestions(data.actors || []); 545 - } catch (error) { 546 - console.error('Failed to fetch suggestions:', error); 547 - setSuggestions([]); 548 - } finally { 549 - setIsFetchingSuggestions(false); 550 - } 551 - }, []); 552 - 553 - useEffect(() => { 554 - if (debouncedSearchTerm && showSuggestions) { 555 - fetchSuggestions(debouncedSearchTerm); 556 - } else if (!debouncedSearchTerm) { 557 - setSuggestions([]); 558 - } 559 - }, [debouncedSearchTerm, fetchSuggestions, showSuggestions]); 560 - 561 - useEffect(() => { 562 - function handleClickOutside(event) { 563 - if (suggestionsRef.current && !suggestionsRef.current.contains(event.target) && 564 - inputRef.current && !inputRef.current.contains(event.target)) { 565 - setShowSuggestions(false); 566 - } 567 - } 568 - document.addEventListener("mousedown", handleClickOutside); 569 - return () => document.removeEventListener("mousedown", handleClickOutside); 570 - }, [suggestionsRef, inputRef]); 571 - 572 504 const handleVerify = async (e) => { 573 505 e.preventDefault(); 574 506 if (!agent || !session) return; ··· 576 508 setIsVerifying(true); 577 509 setStatusMessage(`Verifying ${targetHandle}...`); 578 510 setRevokeStatusMessage(''); 579 - setShowSuggestions(false); 580 511 try { 581 512 const profileRes = await agent.api.app.bsky.actor.getProfile({ actor: targetHandle }); 582 513 const targetDid = profileRes.data.did; ··· 633 564 } 634 565 }; 635 566 636 - const handleSuggestionClick = (handle) => { 637 - setTargetHandle(handle); 638 - setSuggestions([]); 639 - setShowSuggestions(false); 640 - inputRef.current?.focus(); 641 - }; 642 - 643 567 // Handle loading and error states 644 568 if (isAuthLoading) return <p>Loading authentication...</p>; 645 569 if (authError) return <p>Authentication Error: {authError}. <a href="/login">Please login</a>.</p>; ··· 674 598 With Bluesky's new decentralized verification system, anyone can verify anyone else and any Bluesky client can choose which accounts to treat as "Trusted Verifiers". 675 599 </p> 676 600 <p className="verifier-intro-text"> 677 - Try verifying an account for yourself or check to see who has verified you! It's as simple as creating a verification record in your PDS that points to the account you want to verify. 601 + Try verifying an account for yourself or check to see who has verified you! It's as simple as creating a verification record in your PDS that points to the account you want to verify. The record looks like this: 602 + </p> 603 + <p> 604 + app.bsky.graph.verification 678 605 </p> 679 606 </div> 680 607 ··· 684 611 <p>Enter the handle of the user you want to verify (e.g., targetuser.bsky.social):</p> 685 612 <form onSubmit={handleVerify} className="verifier-form-container" style={{ marginBottom: 0 }}> 686 613 <input 687 - ref={inputRef} 688 614 type="text" 689 615 value={targetHandle} 690 - onChange={(e) => { 691 - const newValue = e.target.value; 692 - setTargetHandle(newValue); 693 - setShowSuggestions(newValue.length >= 2); 694 - if(newValue.length < 2) setSuggestions([]); 695 - }} 696 - onFocus={() => { if (targetHandle.length >= 2) setShowSuggestions(true); }} 616 + onChange={(e) => setTargetHandle(e.target.value)} 697 617 placeholder="targetuser.bsky.social" 698 618 disabled={isAnyOperationInProgress} 699 619 required ··· 704 624 {isVerifying ? 'Verifying...' : 'Verify Account'} 705 625 </button> 706 626 </form> 707 - {showSuggestions && (suggestions.length > 0 || isFetchingSuggestions) && ( 708 - <ul className="autocomplete-items" ref={suggestionsRef}> 709 - {isFetchingSuggestions && suggestions.length === 0 ? ( 710 - <li className="autocomplete-item">Loading...</li> 711 - ) : ( 712 - suggestions.map((actor) => ( 713 - <li key={actor.did} className="autocomplete-item" onMouseDown={(e) => { e.preventDefault(); handleSuggestionClick(actor.handle); }}> 714 - <img src={actor.avatar} alt="" /> 715 - <span className="verifier-suggestion-display-name">{actor.displayName || actor.handle}</span> 716 - <span className="verifier-suggestion-handle">@{actor.handle}</span> 717 - </li> 718 - )) 719 - )} 720 - {suggestions.length === 0 && !isFetchingSuggestions && targetHandle.length >= 2 && ( 721 - <li className="autocomplete-item">No users found matching "{targetHandle}"</li> 722 - )} 723 - </ul> 724 - )} 725 627 </div> 726 628 727 629 {statusMessage && (