This repository has no description
0

Configure Feed

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

add follows list

+116 -40
+1 -1
src/components/Verifier/Verifier.css
··· 519 519 .verifier-options { 520 520 margin-top: 10px; /* Space above the options */ 521 521 margin-bottom: 15px; /* Space below the options */ 522 - padding-left: 5px; /* Slight indent */ 523 522 } 524 523 525 524 .verifier-options label { ··· 533 532 534 533 .verifier-options input[type="checkbox"] { 535 534 cursor: pointer; 535 + margin: 0px; 536 536 }
+115 -39
src/components/Verifier/Verifier.js
··· 159 159 // Verification options 160 160 const [skipDuplicates, setSkipDuplicates] = useState(true); 161 161 162 + const followsListUri = 'special:follows'; // Constant for the special URI 163 + 162 164 useEffect(() => { 163 165 if (session) { 164 166 const agentInstance = new Agent(session); ··· 449 451 false // Not using direct fetch here 450 452 ); 451 453 console.log(`Fetched ${lists.length} lists for user ${session.handle}`); 452 - setUserLists(lists || []); 454 + 455 + // Prepend the special "Follows" list 456 + const followsPseudoList = { 457 + uri: 'special:follows', 458 + name: 'My Follows', 459 + // We don't fetch the count here for performance, handle display in component 460 + listItemCount: null // Indicate count is unknown/dynamic 461 + }; 462 + 463 + setUserLists([followsPseudoList, ...(lists || [])]); // Add follows list at the beginning 464 + 453 465 if (lists.length === 0) { 454 - setBulkVerifyStatus('You have not created any lists yet.'); 466 + // Adjust status message if only the pseudo-list exists 467 + setBulkVerifyStatus('You have not created any custom lists yet.'); 455 468 } else { 456 469 setBulkVerifyStatus(''); // Clear status on success if lists were found 457 470 } ··· 704 717 } 705 718 706 719 setIsVerifying(true); 707 - setBulkVerifyStatus(`Fetching members of list: ${selectedList.name}...`); 720 + setBulkVerifyStatus(`Fetching members of list: ${selectedList.name}...`); // Initial status 708 721 setBulkVerifyProgress(''); 709 722 setStatusMessage(''); // Clear single verify status 710 723 setRevokeStatusMessage(''); // Clear revoke status 711 724 725 + // Initialize counters 712 726 let successCount = 0; 713 727 let failureCount = 0; 714 728 let totalCount = 0; 715 - const errors = []; 729 + let errors = []; 716 730 let skippedCount = 0; // Track skipped users 717 731 718 732 try { 719 - // Fetch all items from the selected list 720 - const listItems = await fetchAllPaginated( 721 - agent.api.app.bsky.graph, // The context object 722 - 'getList', // The method name as a string 723 - { list: selectedListUri, limit: 100 }, 724 - false // Use agent method 725 - ); 733 + let fetchedItems = []; 734 + let sourceDescription = selectedList ? `list "${selectedList.name}"` : "the selected list"; 735 + if (selectedListUri === followsListUri) { 736 + sourceDescription = "follows list"; 737 + setBulkVerifyStatus(`Fetching your follows...`); 738 + fetchedItems = await fetchAllPaginated( 739 + agent.api.app.bsky.graph, 740 + 'getFollows', 741 + { actor: session.did, limit: 100 }, 742 + false 743 + ); 744 + // The items are directly in the result array for getFollows 745 + } else { 746 + // Fetch items from a regular list 747 + setBulkVerifyStatus(`Fetching members of list: ${selectedList.name}...`); 748 + fetchedItems = await fetchAllPaginated( 749 + agent.api.app.bsky.graph, 750 + 'getList', 751 + { list: selectedListUri, limit: 100 }, 752 + false 753 + ); 754 + // For getList, the users are within the 'subject' property of each item 755 + } 726 756 727 - totalCount = listItems.length; 728 - setBulkVerifyStatus(`Found ${totalCount} members in list "${selectedList.name}". Starting verification...`); 757 + totalCount = fetchedItems.length; 758 + setBulkVerifyStatus(`Found ${totalCount} members in ${sourceDescription}. Starting verification...`); 729 759 730 760 if (totalCount === 0) { 731 - setBulkVerifyStatus(`List "${selectedList.name}" is empty. No users to verify.`); 761 + setBulkVerifyStatus(`${sourceDescription} is empty. No users to verify.`); 732 762 setIsVerifying(false); 733 763 return; 734 764 } 735 765 736 766 // Iterate and verify each user 737 - for (let i = 0; i < listItems.length; i++) { 738 - const item = listItems[i]; 739 - const targetUser = item.subject; 740 - const targetHandle = targetUser.handle; 741 - const targetDid = targetUser.did; 742 - const targetDisplayName = targetUser.displayName || targetHandle; 767 + for (let i = 0; i < fetchedItems.length; i++) { 768 + const item = fetchedItems[i]; 769 + let targetUser, targetHandle, targetDid, targetDisplayName; 770 + 771 + // Extract user details based on source 772 + if (selectedListUri === followsListUri) { 773 + // item is the user profile directly from getFollows result 774 + targetUser = item; 775 + targetDid = targetUser.did; 776 + targetHandle = targetUser.handle; 777 + targetDisplayName = targetUser.displayName || targetHandle; 778 + } else { 779 + // item is from getList result, user is in item.subject 780 + targetUser = item.subject; 781 + targetDid = targetUser.did; 782 + targetHandle = targetUser.handle; 783 + targetDisplayName = targetUser.displayName || targetHandle; 784 + } 785 + 786 + // Check if essential details are present (safety check) 787 + if (!targetDid || !targetHandle) { 788 + console.warn(`Skipping item at index ${i} due to missing DID or handle`, item); 789 + failureCount++; 790 + errors.push(`Item ${i + 1}: Missing DID or handle`); 791 + continue; 792 + } 743 793 744 794 setBulkVerifyProgress(`Verifying ${i + 1} of ${totalCount}: @${targetHandle}`); 745 795 ··· 775 825 } 776 826 777 827 // Final status message 778 - let finalMessage = `Bulk verification complete for list "${selectedList.name}". \n`; 828 + let finalMessage = `Bulk verification complete for ${sourceDescription}. \n`; 779 829 finalMessage += `Successfully verified: ${successCount}. \n`; 780 830 if (failureCount > 0) { 781 831 finalMessage += `Failed: ${failureCount}. \n`; ··· 813 863 return; 814 864 } 815 865 866 + // Determine source description early for use in error messages 867 + let sourceDescription = selectedList ? `list "${selectedList.name}"` : "the selected list"; 868 + if (selectedListUriForRevoke === followsListUri) { 869 + sourceDescription = "follows list"; 870 + } 871 + 816 872 // Confirmation dialog 817 - if (!window.confirm(`Are you sure you want to revoke verifications for all users found in the list "${selectedList.name}"? This cannot be undone.`)) { 873 + if (!window.confirm(`Are you sure you want to revoke verifications for all users found in ${sourceDescription}? This cannot be undone.`)) { 818 874 return; 819 875 } 820 876 ··· 826 882 let successCount = 0; 827 883 let failureCount = 0; 828 884 let totalToRevoke = 0; 829 - const errors = []; 885 + let errors = []; 830 886 831 887 try { 832 - // Fetch all items from the selected list 833 - const listItems = await fetchAllPaginated( 834 - agent.api.app.bsky.graph, 835 - 'getList', 836 - { list: selectedListUriForRevoke, limit: 100 }, 837 - false 838 - ); 888 + let fetchedItems = []; 889 + let listMemberDids = new Set(); 890 + // sourceDescription is already set above 891 + 892 + // Check if it's the special Follows list 893 + if (selectedListUriForRevoke === followsListUri) { 894 + // sourceDescription = "follows list"; // Already set 895 + setBulkRevokeStatus(`Fetching your follows...`); 896 + fetchedItems = await fetchAllPaginated( 897 + agent.api.app.bsky.graph, 898 + 'getFollows', 899 + { actor: session.did, limit: 100 }, 900 + false 901 + ); 902 + // Extract DIDs directly from the follows list items 903 + listMemberDids = new Set(fetchedItems.map(item => item.did)); 904 + } else { 905 + // Fetch items from a regular list 906 + setBulkRevokeStatus(`Fetching members of list: ${selectedList.name}...`); 907 + fetchedItems = await fetchAllPaginated( 908 + agent.api.app.bsky.graph, 909 + 'getList', 910 + { list: selectedListUriForRevoke, limit: 100 }, 911 + false 912 + ); 913 + // Extract DIDs from the subject of list items 914 + listMemberDids = new Set(fetchedItems.map(item => item.subject.did)); 915 + } 839 916 840 - if (listItems.length === 0) { 917 + if (fetchedItems.length === 0 && selectedListUriForRevoke !== followsListUri) { 918 + // Only show empty message if it wasn't the follows list (or if follows *was* empty) 841 919 setBulkRevokeStatus(`List "${selectedList.name}" is empty. No users to check for revocation.`); 842 920 setIsRevoking(false); 843 921 return; 844 922 } 845 923 846 - const listMemberDids = new Set(listItems.map(item => item.subject.did)); 847 - 848 924 // Filter existing verifications to find those matching list members 849 925 const verificationsToRevoke = verifications.filter(verification => 850 926 listMemberDids.has(verification.subject) 851 927 ); 852 928 853 929 totalToRevoke = verificationsToRevoke.length; 854 - setBulkRevokeStatus(`Found ${totalToRevoke} existing verification(s) matching users in "${selectedList.name}". Starting revocation...`); 930 + setBulkRevokeStatus(`Found ${totalToRevoke} existing verification(s) matching users in ${sourceDescription}. Starting revocation...`); 855 931 856 932 if (totalToRevoke === 0) { 857 - setBulkRevokeStatus(`No existing verifications match users in the list "${selectedList.name}".`); 933 + setBulkRevokeStatus(`No existing verifications match users in the ${sourceDescription}.`); 858 934 setIsRevoking(false); 859 935 return; 860 936 } ··· 883 959 } 884 960 885 961 // Final status message 886 - let finalMessage = `Bulk revocation complete for list "${selectedList.name}". \n`; 962 + let finalMessage = `Bulk revocation complete for ${sourceDescription}. \n`; 887 963 finalMessage += `Successfully revoked: ${successCount}. \n`; 888 964 if (failureCount > 0) { 889 965 finalMessage += `Failed: ${failureCount}. \n`; ··· 895 971 setSelectedListUriForRevoke(''); // Reset selection 896 972 897 973 } catch (error) { 898 - console.error('Failed to fetch or process list items for revocation:', error); 899 - setBulkRevokeStatus(`Error during bulk revocation for "${selectedList.name}": ${error.message || 'Unknown error'}`); 974 + console.error('Failed to fetch or process items for revocation:', error); 975 + setBulkRevokeStatus(`Error during bulk revocation for ${sourceDescription}: ${error.message || 'Unknown error'}`); 900 976 } finally { 901 977 setIsRevoking(false); 902 978 setBulkRevokeProgress(''); ··· 987 1063 onChange={(e) => setSkipDuplicates(e.target.checked)} 988 1064 disabled={isVerifying} 989 1065 /> 990 - Skip Existing Verifications 1066 + Prevent Duplications 991 1067 </label> 992 1068 </div> 993 1069