mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

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

at samuel/patch-onpaste 127 lines 3.6 kB view raw
1import {useEffect, useState} from 'react' 2import {View} from 'react-native' 3import {msg, Trans} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5import lande from 'lande' 6 7import {code3ToCode2Strict, codeToLanguageName} from '#/locale/helpers' 8import { 9 toPostLanguages, 10 useLanguagePrefs, 11 useLanguagePrefsApi, 12} from '#/state/preferences/languages' 13import {atoms as a, useTheme} from '#/alf' 14import {Button, ButtonText} from '#/components/Button' 15import {Earth_Stroke2_Corner2_Rounded as EarthIcon} from '#/components/icons/Globe' 16import {Text} from '#/components/Typography' 17 18// fallbacks for safari 19const onIdle = globalThis.requestIdleCallback || (cb => setTimeout(cb, 1)) 20const cancelIdle = globalThis.cancelIdleCallback || clearTimeout 21 22export function SuggestedLanguage({ 23 text, 24 replyToLanguage, 25}: { 26 text: string 27 replyToLanguage?: string 28}) { 29 const [suggestedLanguage, setSuggestedLanguage] = useState< 30 string | undefined 31 >(text.length === 0 ? replyToLanguage : undefined) 32 const langPrefs = useLanguagePrefs() 33 const setLangPrefs = useLanguagePrefsApi() 34 const t = useTheme() 35 const {_} = useLingui() 36 37 useEffect(() => { 38 // For replies, suggest the language of the post being replied to if no text 39 // has been typed yet 40 if (replyToLanguage && text.length === 0) { 41 setSuggestedLanguage(replyToLanguage) 42 return 43 } 44 45 const textTrimmed = text.trim() 46 47 // Don't run the language model on small posts, the results are likely 48 // to be inaccurate anyway. 49 if (textTrimmed.length < 40) { 50 setSuggestedLanguage(undefined) 51 return 52 } 53 54 const idle = onIdle(() => { 55 setSuggestedLanguage(guessLanguage(textTrimmed)) 56 }) 57 58 return () => cancelIdle(idle) 59 }, [text, replyToLanguage]) 60 61 if ( 62 suggestedLanguage && 63 !toPostLanguages(langPrefs.postLanguage).includes(suggestedLanguage) 64 ) { 65 const suggestedLanguageName = codeToLanguageName( 66 suggestedLanguage, 67 langPrefs.appLanguage, 68 ) 69 70 return ( 71 <View 72 style={[ 73 t.atoms.border_contrast_low, 74 a.gap_sm, 75 a.border, 76 a.flex_row, 77 a.align_center, 78 a.rounded_sm, 79 a.px_lg, 80 a.py_md, 81 a.mx_md, 82 a.my_sm, 83 t.atoms.bg, 84 ]}> 85 <EarthIcon /> 86 <Text style={[a.flex_1]}> 87 <Trans> 88 Are you writing in{' '} 89 <Text style={[a.font_bold]}>{suggestedLanguageName}</Text>? 90 </Trans> 91 </Text> 92 93 <Button 94 color="secondary" 95 size="small" 96 variant="solid" 97 onPress={() => setLangPrefs.setPostLanguage(suggestedLanguage)} 98 label={_(msg`Change post language to ${suggestedLanguageName}`)}> 99 <ButtonText> 100 <Trans>Yes</Trans> 101 </ButtonText> 102 </Button> 103 </View> 104 ) 105 } else { 106 return null 107 } 108} 109 110/** 111 * This function is using the lande language model to attempt to detect the language 112 * We want to only make suggestions when we feel a high degree of certainty 113 * The magic numbers are based on debugging sessions against some test strings 114 */ 115function guessLanguage(text: string): string | undefined { 116 const scores = lande(text).filter(([_lang, value]) => value >= 0.0002) 117 // if the model has multiple items with a score higher than 0.0002, it isn't certain enough 118 if (scores.length !== 1) { 119 return undefined 120 } 121 const [lang, value] = scores[0] 122 // if the model doesn't give a score of 0.97 or above, it isn't certain enough 123 if (value < 0.97) { 124 return undefined 125 } 126 return code3ToCode2Strict(lang) 127}