mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at thread-bug 2.6 kB view raw
1import {useCallback, useMemo} from 'react' 2import Graphemer from 'graphemer' 3 4export function enforceLen( 5 str: string, 6 len: number, 7 ellipsis = false, 8 mode: 'end' | 'middle' = 'end', 9): string { 10 str = str || '' 11 if (str.length > len) { 12 if (ellipsis) { 13 if (mode === 'end') { 14 return str.slice(0, len) + '…' 15 } else if (mode === 'middle') { 16 const half = Math.floor(len / 2) 17 return str.slice(0, half) + '…' + str.slice(-half) 18 } else { 19 // fallback 20 return str.slice(0, len) 21 } 22 } else { 23 return str.slice(0, len) 24 } 25 } 26 return str 27} 28 29export function useEnforceMaxGraphemeCount() { 30 const splitter = useMemo(() => new Graphemer(), []) 31 32 return useCallback( 33 (text: string, maxCount: number) => { 34 if (splitter.countGraphemes(text) > maxCount) { 35 return splitter.splitGraphemes(text).slice(0, maxCount).join('') 36 } else { 37 return text 38 } 39 }, 40 [splitter], 41 ) 42} 43 44export function useWarnMaxGraphemeCount({ 45 text, 46 maxCount, 47}: { 48 text: string 49 maxCount: number 50}) { 51 const splitter = useMemo(() => new Graphemer(), []) 52 53 return useMemo(() => { 54 return splitter.countGraphemes(text) > maxCount 55 }, [splitter, maxCount, text]) 56} 57 58// https://stackoverflow.com/a/52171480 59export function toHashCode(str: string, seed = 0): number { 60 let h1 = 0xdeadbeef ^ seed, 61 h2 = 0x41c6ce57 ^ seed 62 for (let i = 0, ch; i < str.length; i++) { 63 ch = str.charCodeAt(i) 64 h1 = Math.imul(h1 ^ ch, 2654435761) 65 h2 = Math.imul(h2 ^ ch, 1597334677) 66 } 67 h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) 68 h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909) 69 h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) 70 h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909) 71 72 return 4294967296 * (2097151 & h2) + (h1 >>> 0) 73} 74 75export function countLines(str: string | undefined): number { 76 if (!str) return 0 77 return str.match(/\n/g)?.length ?? 0 78} 79 80// Augments search query with additional syntax like `from:me` 81export function augmentSearchQuery(query: string, {did}: {did?: string}) { 82 // Don't do anything if there's no DID 83 if (!did) { 84 return query 85 } 86 87 // We don't want to replace substrings that are being "quoted" because those 88 // are exact string matches, so what we'll do here is to split them apart 89 90 // Even-indexed strings are unquoted, odd-indexed strings are quoted 91 const splits = query.split(/("(?:[^"\\]|\\.)*")/g) 92 93 return splits 94 .map((str, idx) => { 95 if (idx % 2 === 0) { 96 return str.replaceAll(/(^|\s)from:me(\s|$)/g, `$1${did}$2`) 97 } 98 99 return str 100 }) 101 .join('') 102}