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 verify-code 176 lines 4.6 kB view raw
1import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api' 2import * as bcp47Match from 'bcp-47-match' 3import lande from 'lande' 4 5import {hasProp} from 'lib/type-guards' 6import { 7 AppLanguage, 8 LANGUAGES_MAP_CODE2, 9 LANGUAGES_MAP_CODE3, 10} from './languages' 11 12export function code2ToCode3(lang: string): string { 13 if (lang.length === 2) { 14 return LANGUAGES_MAP_CODE2[lang]?.code3 || lang 15 } 16 return lang 17} 18 19export function code3ToCode2(lang: string): string { 20 if (lang.length === 3) { 21 return LANGUAGES_MAP_CODE3[lang]?.code2 || lang 22 } 23 return lang 24} 25 26export function code3ToCode2Strict(lang: string): string | undefined { 27 if (lang.length === 3) { 28 return LANGUAGES_MAP_CODE3[lang]?.code2 29 } 30 31 return undefined 32} 33 34export function codeToLanguageName(lang: string): string { 35 const lang2 = code3ToCode2(lang) 36 return LANGUAGES_MAP_CODE2[lang2]?.name || lang 37} 38 39export function getPostLanguage( 40 post: AppBskyFeedDefs.PostView, 41): string | undefined { 42 let candidates: string[] = [] 43 let postText: string = '' 44 if (hasProp(post.record, 'text') && typeof post.record.text === 'string') { 45 postText = post.record.text 46 } 47 48 if ( 49 AppBskyFeedPost.isRecord(post.record) && 50 hasProp(post.record, 'langs') && 51 Array.isArray(post.record.langs) 52 ) { 53 candidates = post.record.langs 54 } 55 56 // if there's only one declared language, use that 57 if (candidates?.length === 1) { 58 return candidates[0] 59 } 60 61 // no text? can't determine 62 if (postText.trim().length === 0) { 63 return undefined 64 } 65 66 // run the language model 67 let langsProbabilityMap = lande(postText) 68 69 // filter down using declared languages 70 if (candidates?.length) { 71 langsProbabilityMap = langsProbabilityMap.filter( 72 ([lang, _probability]: [string, number]) => { 73 return candidates.includes(code3ToCode2(lang)) 74 }, 75 ) 76 } 77 78 if (langsProbabilityMap[0]) { 79 return code3ToCode2(langsProbabilityMap[0][0]) 80 } 81} 82 83export function isPostInLanguage( 84 post: AppBskyFeedDefs.PostView, 85 targetLangs: string[], 86): boolean { 87 const lang = getPostLanguage(post) 88 if (!lang) { 89 // the post has no text, so we just say "yes" for now 90 return true 91 } 92 return bcp47Match.basicFilter(lang, targetLangs).length > 0 93} 94 95export function getTranslatorLink(text: string, lang: string): string { 96 return `https://translate.google.com/?sl=auto&tl=${lang}&text=${encodeURIComponent( 97 text, 98 )}` 99} 100 101/** 102 * Returns a valid `appLanguage` value from an arbitrary string. 103 * 104 * Contenxt: post-refactor, we populated some user's `appLanguage` setting with 105 * `postLanguage`, which can be a comma-separated list of values. This breaks 106 * `appLanguage` handling in the app, so we introduced this util to parse out a 107 * valid `appLanguage` from the pre-populated `postLanguage` values. 108 * 109 * The `appLanguage` will continue to be incorrect until the user returns to 110 * language settings and selects a new option, at which point we'll re-save 111 * their choice, which should then be a valid option. Since we don't know when 112 * this will happen, we should leave this here until we feel it's safe to 113 * remove, or we re-migrate their storage. 114 */ 115export function sanitizeAppLanguageSetting(appLanguage: string): AppLanguage { 116 const langs = appLanguage.split(',').filter(Boolean) 117 118 for (const lang of langs) { 119 switch (fixLegacyLanguageCode(lang)) { 120 case 'en': 121 return AppLanguage.en 122 case 'ca': 123 return AppLanguage.ca 124 case 'de': 125 return AppLanguage.de 126 case 'es': 127 return AppLanguage.es 128 case 'fi': 129 return AppLanguage.fi 130 case 'fr': 131 return AppLanguage.fr 132 case 'ga': 133 return AppLanguage.ga 134 case 'hi': 135 return AppLanguage.hi 136 case 'id': 137 return AppLanguage.id 138 case 'it': 139 return AppLanguage.it 140 case 'ja': 141 return AppLanguage.ja 142 case 'ko': 143 return AppLanguage.ko 144 case 'pt-BR': 145 return AppLanguage.pt_BR 146 case 'tr': 147 return AppLanguage.tr 148 case 'uk': 149 return AppLanguage.uk 150 case 'zh-CN': 151 return AppLanguage.zh_CN 152 case 'zh-TW': 153 return AppLanguage.zh_TW 154 default: 155 continue 156 } 157 } 158 return AppLanguage.en 159} 160 161export function fixLegacyLanguageCode(code: string | null): string | null { 162 // handle some legacy code conversions, see https://xml.coverpages.org/iso639a.html 163 if (code === 'in') { 164 // indonesian 165 return 'id' 166 } 167 if (code === 'iw') { 168 // hebrew 169 return 'he' 170 } 171 if (code === 'ji') { 172 // yiddish 173 return 'yi' 174 } 175 return code 176}