From 4d576b00fa926efc1165bc16b8e76d43e980d703 Mon Sep 17 00:00:00 2001 From: Arnas Udovic Date: Thu, 25 Jan 2024 15:13:15 +0200 Subject: [PATCH] possibility to set language for post --- bin/svgs.js | 3 +- src/intl/en-US.js | 14 ++- src/routes/_actions/addLanguage.js | 16 +++ src/routes/_actions/compose.js | 4 +- src/routes/_actions/language.js | 5 + src/routes/_api/statuses.js | 11 ++- .../_components/compose/ComposeBox.html | 10 +- .../_components/compose/ComposeToolbar.html | 15 +++ .../importShowSetLanguageDialog.js | 3 + .../dialog/components/SetLanguageDialog.html | 50 ++++++++++ .../dialog/creators/showSetLanguageDialog.js | 10 ++ .../_components/settings/SettingsNav.html | 2 + .../_components/status/StatusDetails.html | 10 ++ src/routes/_pages/settings/index.html | 3 + src/routes/_pages/settings/languages/add.html | 99 +++++++++++++++++++ .../_pages/settings/languages/index.html | 40 ++++++++ src/routes/_store/store.js | 4 +- src/routes/settings/languages/add.html | 21 ++++ src/routes/settings/languages/index.html | 21 ++++ 19 files changed, 327 insertions(+), 14 deletions(-) create mode 100644 src/routes/_actions/addLanguage.js create mode 100644 src/routes/_actions/language.js create mode 100644 src/routes/_components/dialog/asyncDialogs/importShowSetLanguageDialog.js create mode 100644 src/routes/_components/dialog/components/SetLanguageDialog.html create mode 100644 src/routes/_components/dialog/creators/showSetLanguageDialog.js create mode 100644 src/routes/_pages/settings/languages/add.html create mode 100644 src/routes/_pages/settings/languages/index.html create mode 100644 src/routes/settings/languages/add.html create mode 100644 src/routes/settings/languages/index.html diff --git a/bin/svgs.js b/bin/svgs.js index 7c5ef9f5a..d193bdd4f 100644 --- a/bin/svgs.js +++ b/bin/svgs.js @@ -60,5 +60,6 @@ export default [ { id: 'fa-crosshairs', src: 'src/thirdparty/font-awesome-svg-png/white/svg/crosshairs.svg' }, { id: 'fa-magic', src: 'src/thirdparty/font-awesome-svg-png/white/svg/magic.svg' }, { id: 'fa-hashtag', src: 'src/thirdparty/font-awesome-svg-png/white/svg/hashtag.svg' }, - { id: 'fa-bookmark', src: 'src/thirdparty/font-awesome-svg-png/white/svg/bookmark.svg' } + { id: 'fa-bookmark', src: 'src/thirdparty/font-awesome-svg-png/white/svg/bookmark.svg' }, + { id: 'fa-language', src: 'src/thirdparty/font-awesome-svg-png/white/svg/language.svg' } ] diff --git a/src/intl/en-US.js b/src/intl/en-US.js index e952f4eea..5960bb3dc 100644 --- a/src/intl/en-US.js +++ b/src/intl/en-US.js @@ -330,7 +330,7 @@ export default { aboutAppDescription: `

Semaphore is - free and open-source software + free and open-source software maintained by Nick Colley and distributed under the Languages + languages: 'Languages', + addLanguage: 'Add language', + add: 'Add', + languageCode: 'Language code', + enterLanguageCode: 'Enter language code', + getLanguageCode: 'Language should be code from ISO-639 base. To check the right code for the language visti IANA language sub-tag registry.', + ianaLanguageRegistry: 'IANA registry', + setLanguageLabel: 'Set language (current {label})', + setLanguage: 'Set language' } diff --git a/src/routes/_actions/addLanguage.js b/src/routes/_actions/addLanguage.js new file mode 100644 index 000000000..fa4042e1f --- /dev/null +++ b/src/routes/_actions/addLanguage.js @@ -0,0 +1,16 @@ +import { store } from '../_store/store.js' +import { goto } from '../../../__sapper__/client.js' + +export function addLanguage () { + const { languages, newLanguage } = store.get() + languages.push(newLanguage.toLowerCase().trim()) + store.set({ languages }) + store.save() + goto('/settings/languages') +} + +export function resetNewLanguage() { + const newLanguage = '' + store.set({ newLanguage }) + store.save() +} diff --git a/src/routes/_actions/compose.js b/src/routes/_actions/compose.js index d24515558..d559f9f8e 100644 --- a/src/routes/_actions/compose.js +++ b/src/routes/_actions/compose.js @@ -27,7 +27,7 @@ export async function insertHandleForReply (statusId) { export async function postStatus (realm, text, inReplyToId, mediaIds, sensitive, spoilerText, visibility, - mediaDescriptions, inReplyToUuid, poll, mediaFocalPoints) { + mediaDescriptions, inReplyToUuid, poll, mediaFocalPoints, language) { const { currentInstance, accessToken, online } = store.get() if (!online) { @@ -56,7 +56,7 @@ export async function postStatus (realm, text, inReplyToId, mediaIds, } })) const status = await postStatusToServer(currentInstance, accessToken, text, - inReplyToId, mediaIds, sensitive, spoilerText, visibility, poll, mediaFocalPoints) + inReplyToId, mediaIds, sensitive, spoilerText, visibility, poll, language, mediaFocalPoints) addStatusOrNotification(currentInstance, 'home', status) store.clearComposeData(realm) emit('postedStatus', realm, inReplyToUuid) diff --git a/src/routes/_actions/language.js b/src/routes/_actions/language.js new file mode 100644 index 000000000..f8d42fa68 --- /dev/null +++ b/src/routes/_actions/language.js @@ -0,0 +1,5 @@ +import { store } from '../_store/store.js' + +export function setLanguage (realm, language) { + store.setComposeData(realm, { language }) +} diff --git a/src/routes/_api/statuses.js b/src/routes/_api/statuses.js index 2ab1a5db3..c4941ebe7 100644 --- a/src/routes/_api/statuses.js +++ b/src/routes/_api/statuses.js @@ -3,13 +3,14 @@ import { DEFAULT_TIMEOUT, get, post, put, WRITE_TIMEOUT } from '../_utils/ajax.j // post is create, put is edit async function postOrPutStatus (url, accessToken, method, text, inReplyToId, mediaIds, - sensitive, spoilerText, visibility, poll) { + sensitive, spoilerText, visibility, poll, language) { const body = { status: text, media_ids: mediaIds, sensitive, spoiler_text: spoilerText, poll, + language, ...(method === 'post' && { // you can't change these properties when editing in_reply_to_id: inReplyToId, @@ -31,17 +32,17 @@ async function postOrPutStatus (url, accessToken, method, text, inReplyToId, med } export async function postStatus (instanceName, accessToken, text, inReplyToId, mediaIds, - sensitive, spoilerText, visibility, poll) { + sensitive, spoilerText, visibility, poll, language) { const url = `${basename(instanceName)}/api/v1/statuses` return postOrPutStatus(url, accessToken, 'post', text, inReplyToId, mediaIds, - sensitive, spoilerText, visibility, poll) + sensitive, spoilerText, visibility, poll, language) } export async function putStatus (instanceName, accessToken, id, text, inReplyToId, mediaIds, - sensitive, spoilerText, visibility, poll) { + sensitive, spoilerText, visibility, poll, language) { const url = `${basename(instanceName)}/api/v1/statuses/${id}` return postOrPutStatus(url, accessToken, 'put', text, inReplyToId, mediaIds, - sensitive, spoilerText, visibility, poll) + sensitive, spoilerText, visibility, poll, language) } export async function getStatusContext (instanceName, accessToken, statusId) { diff --git a/src/routes/_components/compose/ComposeBox.html b/src/routes/_components/compose/ComposeBox.html index 4f416c693..805e04927 100644 --- a/src/routes/_components/compose/ComposeBox.html +++ b/src/routes/_components/compose/ComposeBox.html @@ -19,7 +19,7 @@

{intl.composeStatus}

{/if} - + @@ -173,6 +173,9 @@

{intl.composeStatus}

poll: ({ composeData }) => composeData.poll, inReplyToId: ({ composeData }) => composeData.inReplyToId, postPrivacy: ({ postPrivacyKey }) => POST_PRIVACY_OPTIONS.find(_ => _.key === postPrivacyKey), + language: ({ composeData, $languages }) => { + return composeData.language ? composeData.language : ($languages.length ? $languages[0] : 'en') + }, defaultPostPrivacyKey: ({ $currentVerifyCredentials }) => ( ($currentVerifyCredentials && $currentVerifyCredentials.source.privacy) || 'public' ), @@ -219,7 +222,8 @@

{intl.composeStatus}

inReplyToUuid, // typical replies, using Semaphore-specific uuid inReplyToId, // delete-and-redraft replies, using standard id poll, - sensitive + sensitive, + language } = this.get() const mediaIds = media.map(_ => _.data.id) const mediaDescriptions = media.map(_ => _.description) @@ -248,7 +252,7 @@

{intl.composeStatus}

/* no await */ postStatus(realm, text, inReplyTo, mediaIds, sensitive, contentWarning, postPrivacyKey, mediaDescriptions, inReplyToUuid, pollToPost, - mediaFocalPoints) + mediaFocalPoints, language) } } } diff --git a/src/routes/_components/compose/ComposeToolbar.html b/src/routes/_components/compose/ComposeToolbar.html index 88605303b..89ebdde79 100644 --- a/src/routes/_components/compose/ComposeToolbar.html +++ b/src/routes/_components/compose/ComposeToolbar.html @@ -38,6 +38,12 @@ pressable={true} pressed={contentWarningShown} /> + ( formatIntl('intl.postPrivacyLabel', { label: postPrivacy.label }) + ), + setLanguageLabel: ({ language }) => ( + formatIntl('intl.setLanguageLabel', { label: language }) ) }, store: () => store, @@ -119,6 +129,11 @@ const showPostPrivacyDialog = await importShowPostPrivacyDialog() showPostPrivacyDialog(realm) }, + async onSetLanguageClick () { + const { realm } = this.get() + const showSetLanguageDialog = await importShowSetLanguageDialog() + showSetLanguageDialog(realm) + }, onContentWarningClick () { const { realm } = this.get() toggleContentWarningShown(realm) diff --git a/src/routes/_components/dialog/asyncDialogs/importShowSetLanguageDialog.js b/src/routes/_components/dialog/asyncDialogs/importShowSetLanguageDialog.js new file mode 100644 index 000000000..12fe397fc --- /dev/null +++ b/src/routes/_components/dialog/asyncDialogs/importShowSetLanguageDialog.js @@ -0,0 +1,3 @@ +export const importShowSetLanguageDialog = () => import( + '../creators/showSetLanguageDialog.js' +).then(mod => mod.default) diff --git a/src/routes/_components/dialog/components/SetLanguageDialog.html b/src/routes/_components/dialog/components/SetLanguageDialog.html new file mode 100644 index 000000000..a3aff9099 --- /dev/null +++ b/src/routes/_components/dialog/components/SetLanguageDialog.html @@ -0,0 +1,50 @@ + + + + diff --git a/src/routes/_components/dialog/creators/showSetLanguageDialog.js b/src/routes/_components/dialog/creators/showSetLanguageDialog.js new file mode 100644 index 000000000..09a26caa9 --- /dev/null +++ b/src/routes/_components/dialog/creators/showSetLanguageDialog.js @@ -0,0 +1,10 @@ +import SetLanguageDialog from '../components/SetLanguageDialog.html' +import { showDialog } from './showDialog.js' + +export default function showSetLanguageDialog (realm) { + return showDialog(SetLanguageDialog, { + label: 'intl.setLanguage', + title: 'intl.setLanguage', + realm + }) +} diff --git a/src/routes/_components/settings/SettingsNav.html b/src/routes/_components/settings/SettingsNav.html index 79ba5d598..362194122 100644 --- a/src/routes/_components/settings/SettingsNav.html +++ b/src/routes/_components/settings/SettingsNav.html @@ -51,6 +51,8 @@ settings: 'intl.settings', 'settings/about': 'intl.aboutApp', 'settings/general': 'intl.general', + 'settings/languages': 'intl.languages', + 'settings/languages/add': 'intl.addLanguage', 'settings/instances': 'intl.instances', 'settings/instances/add': $isUserLoggedIn ? 'intl.addInstance' : 'intl.logIn' }), diff --git a/src/routes/_components/status/StatusDetails.html b/src/routes/_components/status/StatusDetails.html index 8b6eadb23..1ab55778d 100644 --- a/src/routes/_components/status/StatusDetails.html +++ b/src/routes/_components/status/StatusDetails.html @@ -27,6 +27,11 @@ {/if} {/if} + {#if language} + + {language} + + {/if}
diff --git a/src/routes/_pages/settings/languages/index.html b/src/routes/_pages/settings/languages/index.html new file mode 100644 index 000000000..f3ae24889 --- /dev/null +++ b/src/routes/_pages/settings/languages/index.html @@ -0,0 +1,40 @@ + +

{intl.languages}

+ + + {#each $languages as language} + + + {language} + + + {/each} + + +

+ {intl.addLanguage} +

+ + + diff --git a/src/routes/_store/store.js b/src/routes/_store/store.js index 2e3ebf733..d296552e9 100644 --- a/src/routes/_store/store.js +++ b/src/routes/_store/store.js @@ -44,7 +44,9 @@ const persistedState = { reduceMotion: !process.browser || matchMedia('(prefers-reduced-motion: reduce)').matches, - underlineLinks: false + underlineLinks: false, + languages: ['en'], + newLanguage: '' } const nonPersistedState = { diff --git a/src/routes/settings/languages/add.html b/src/routes/settings/languages/add.html new file mode 100644 index 000000000..e4c4c63e6 --- /dev/null +++ b/src/routes/settings/languages/add.html @@ -0,0 +1,21 @@ + + + <LazyPage {pageComponent} {params} /> + +<script> + import Title from '../../_components/Title.html' + import LazyPage from '../../_components/LazyPage.html' + import pageComponent from '../../_pages/settings/languages/add.html' + + export default { + components: { + + Title, + LazyPage + }, + data: () => ({ + pageComponent + }) + } +</script> + diff --git a/src/routes/settings/languages/index.html b/src/routes/settings/languages/index.html new file mode 100644 index 000000000..6752106ea --- /dev/null +++ b/src/routes/settings/languages/index.html @@ -0,0 +1,21 @@ +<Title name="{intl.languages}" settingsPage={true} /> + + <LazyPage {pageComponent} {params} /> + +<script> + import Title from '../../_components/Title.html' + import LazyPage from '../../_components/LazyPage.html' + import pageComponent from '../../_pages/settings/languages/index.html' + + export default { + components: { + + Title, + LazyPage + }, + data: () => ({ + pageComponent + }) + } +</script> +