diff options
Diffstat (limited to 'src/locale')
-rw-r--r-- | src/locale/helpers.ts | 81 | ||||
-rw-r--r-- | src/locale/languages.ts | 4 |
2 files changed, 85 insertions, 0 deletions
diff --git a/src/locale/helpers.ts b/src/locale/helpers.ts new file mode 100644 index 000000000..4b9002586 --- /dev/null +++ b/src/locale/helpers.ts @@ -0,0 +1,81 @@ +import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api' +import lande from 'lande' +import {hasProp} from 'lib/type-guards' +import * as bcp47Match from 'bcp-47-match' +import {LANGUAGES_MAP_CODE2, LANGUAGES_MAP_CODE3} from './languages' + +export function code2ToCode3(lang: string): string { + if (lang.length === 2) { + return LANGUAGES_MAP_CODE2[lang]?.code3 || lang + } + return lang +} + +export function code3ToCode2(lang: string): string { + if (lang.length === 3) { + return LANGUAGES_MAP_CODE3[lang]?.code2 || lang + } + return lang +} + +export function getPostLanguage( + post: AppBskyFeedDefs.PostView, +): string | undefined { + let candidates: string[] = [] + let postText: string = '' + if (hasProp(post.record, 'text') && typeof post.record.text === 'string') { + postText = post.record.text + } + + if ( + AppBskyFeedPost.isRecord(post.record) && + hasProp(post.record, 'langs') && + Array.isArray(post.record.langs) + ) { + candidates = post.record.langs + } + + // if there's only one declared language, use that + if (candidates?.length === 1) { + return candidates[0] + } + + // no text? can't determine + if (postText.trim().length === 0) { + return undefined + } + + // run the language model + let langsProbabilityMap = lande(postText) + + // filter down using declared languages + if (candidates?.length) { + langsProbabilityMap = langsProbabilityMap.filter( + ([lang, _probability]: [string, number]) => { + return candidates.includes(code3ToCode2(lang)) + }, + ) + } + + if (langsProbabilityMap[0]) { + return code3ToCode2(langsProbabilityMap[0][0]) + } +} + +export function isPostInLanguage( + post: AppBskyFeedDefs.PostView, + targetLangs: string[], +): boolean { + const lang = getPostLanguage(post) + if (!lang) { + // the post has no text, so we just say "yes" for now + return true + } + return bcp47Match.basicFilter(lang, targetLangs).length > 0 +} + +export function getTranslatorLink(lang: string, text: string): string { + return encodeURI( + `https://translate.google.com/?sl=auto&tl=${lang}&text=${text}`, + ) +} diff --git a/src/locale/languages.ts b/src/locale/languages.ts index 269e2fa9a..3983c213f 100644 --- a/src/locale/languages.ts +++ b/src/locale/languages.ts @@ -555,3 +555,7 @@ export const LANGUAGES_MAP_CODE2 = Object.fromEntries( export const LANGUAGES_MAP_CODE3 = Object.fromEntries( LANGUAGES.map(lang => [lang.code3, lang]), ) +// some additional manual mappings (not clear if these should be in the "official" mappings) +if (LANGUAGES_MAP_CODE2.fa) { + LANGUAGES_MAP_CODE3.pes = LANGUAGES_MAP_CODE2.fa +} |