1/// Utility functions for community handle formatting and resolution. 2/// 3/// Coves communities use atProto handles in the format: 4/// - DNS format: `gaming.community.coves.social` 5/// - Display format: `!gaming@coves.social` 6class CommunityHandleUtils { 7 /// Converts a DNS-style community handle to display format 8 /// 9 /// Transforms `gaming.community.coves.social` → `!gaming@coves.social` 10 /// by removing the `.community.` segment 11 /// 12 /// Returns null if the handle is null or doesn't contain `.community.` 13 static String? formatHandleForDisplay(String? handle) { 14 if (handle == null || handle.isEmpty) { 15 return null; 16 } 17 18 // Expected format: name.community.instance.domain 19 // e.g., gaming.community.coves.social 20 final parts = handle.split('.'); 21 22 // Must have at least 4 parts: [name, community, instance, domain] 23 if (parts.length < 4 || parts[1] != 'community') { 24 return null; 25 } 26 27 // Extract community name (first part) 28 final communityName = parts[0]; 29 30 // Extract instance domain (everything after .community.) 31 final instanceDomain = parts.sublist(2).join('.'); 32 33 // Format as !name@instance 34 return '!$communityName@$instanceDomain'; 35 } 36 37 /// Converts a display-style community handle to DNS format 38 /// 39 /// Transforms `!gaming@coves.social` → `gaming.community.coves.social` 40 /// by inserting `.community.` between the name and instance 41 /// 42 /// Returns null if the handle is null or doesn't match expected format 43 static String? formatHandleForDNS(String? displayHandle) { 44 if (displayHandle == null || displayHandle.isEmpty) { 45 return null; 46 } 47 48 // Remove leading ! if present 49 final cleaned = 50 displayHandle.startsWith('!') 51 ? displayHandle.substring(1) 52 : displayHandle; 53 54 // Expected format: name@instance.domain 55 if (!cleaned.contains('@')) { 56 return null; 57 } 58 59 final parts = cleaned.split('@'); 60 if (parts.length != 2) { 61 return null; 62 } 63 64 final communityName = parts[0]; 65 final instanceDomain = parts[1]; 66 67 // Format as name.community.instance.domain 68 return '$communityName.community.$instanceDomain'; 69 } 70}