Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

export const LANGUAGES = [
{locale: 'en', name: 'English'},
{locale: 'es', name: "Español"}
{locale: 'es', name: "Español"},
{locale: 'pt-BR', name: "Português (Brasil)"}

Check failure on line 6 in src/common/constants.js

View workflow job for this annotation

GitHub Actions / Eslint

You have a misspelled word: Brasil on String

Check failure on line 6 in src/common/constants.js

View workflow job for this annotation

GitHub Actions / Eslint

You have a misspelled word: Portugu on String
]


Expand Down
7 changes: 5 additions & 2 deletions src/components/common/Events.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ import Link from '../common/Link'
import UserIcon from '../users/UserIcon'

const EventDescription = ({ event, isFirst, isLast, isJoined }) => {
const { t } = useTranslation()
const { event_type, description, referenced_object} = event;
const getDescription = () => {
let eventDescription = description
if(isJoined)
eventDescription += ' ' + getSiteTitle()
let rel;
if(event_type && !isEmpty(referenced_object)) {
eventDescription = `${event_type} ${referenced_object.type} `
const translatedEventType = t(`common.event_types.${event_type.toLowerCase()}`, { defaultValue: event_type });
const translatedObjectType = referenced_object.type ? t(`common.event_object_types.${referenced_object.type}`, { defaultValue: referenced_object.type }) : '';
eventDescription = `${translatedEventType} ${translatedObjectType} `
if(['Source Version', 'Collection Version'].includes(referenced_object.type)) {
rel = `${referenced_object.short_code}/${referenced_object.id}`
} else
Expand Down Expand Up @@ -105,7 +108,7 @@ const Events = ({ user, events, onLoadMore, showAvatar, maxHeight, dashboard })
showAvatar &&
<UserIcon noTooltip user={user} sx={{width: '40px', height: '40px', marginRight: '16px'}} color='primary' />
}
{`${isSelf ? t('user.your') : (user.name + "'s")} ${t('user.recent_activity')}`}
{isSelf ? t('user.own_recent_activity') : t('user.recent_activity_of', {name: user.name})}
</Typography>
<Timeline
id="events-timeline"
Expand Down
14 changes: 7 additions & 7 deletions src/components/dashboard/DashboardEvents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ const EventCard = ({ event, highlight }) => {
const { t } = useTranslation()
const getTitle = (event, object, includeSubtitle) => {
let title = object?.id || object?.username || object?.name
let subTitle = event?.event_type?.toLowerCase()
if(event?.referenced_object?.type === 'Organization')
subTitle += ` ${t('common.an')} ${event.referenced_object?.type?.toLowerCase()}`
else if(event?.referenced_object?.type)
subTitle += ` ${t('common.a')} ${event.referenced_object?.type?.toLowerCase()}`
const eventType = event?.event_type?.toLowerCase()
const translatedEventType = t(`common.event_types.${eventType}`, { defaultValue: eventType });
let subTitle
if(event?.referenced_object?.type)
subTitle = t(`common.event_object_types.${event.referenced_object.type}`, { defaultValue: event.referenced_object.type.toLowerCase() })
else
subTitle += ` ${getSiteTitle()}`
subTitle = getSiteTitle()
return (
<span style={{display: 'flex', alignItems: 'center'}}>
<Typography component='span' sx={{fontWeight: 'bold'}}>
Expand All @@ -40,7 +40,7 @@ const EventCard = ({ event, highlight }) => {
{
includeSubtitle &&
<Typography component='span' sx={{marginLeft: '4px'}}>
{subTitle}
{translatedEventType} {subTitle}
</Typography>
}
</span>
Expand Down
3 changes: 1 addition & 2 deletions src/components/dashboard/EventsButtonGroup.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import { useTranslation } from 'react-i18next';
import startCase from 'lodash/startCase'
import DoneIcon from '@mui/icons-material/Done';
import ButtonGroup from '@mui/material/ButtonGroup'
import Button from '@mui/material/Button'
Expand Down Expand Up @@ -29,7 +28,7 @@ const EventsButtonGroup = ({ onClick, selected }) => {
<ButtonGroup size="small" aria-label="Small button group" color='secondary'>
<EventButton label={t('common.all')} selected={selected === 'all'} terminal onClick={() => onClick('all')} />
<EventButton label={t('common.following')} selected={selected === 'following'} onClick={() => onClick('following')} />
<EventButton label={startCase(t('org.my'))} selected={selected === 'orgs'} terminal onClick={() => onClick('orgs')} />
<EventButton label={t('org.my')} selected={selected === 'orgs'} terminal onClick={() => onClick('orgs')} />
</ButtonGroup>
)
}
Expand Down
32 changes: 30 additions & 2 deletions src/i18n/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,34 @@ import { initReactI18next } from 'react-i18next';
import en from './locales/en/translations.json'
import es from './locales/es/translations.json'
import zh from './locales/zh/translations.json'
import ptBR from './locales/pt-BR/translations.json'

const LANGUAGE_STORAGE_KEY = 'ocl.language'
const SUPPORTED_LANGUAGES = ['en', 'es', 'zh', 'pt-BR']

const getInitialLanguage = () => {
if(typeof window === 'undefined')
return 'en'

try {
const storedLanguage = window.localStorage.getItem(LANGUAGE_STORAGE_KEY)
return SUPPORTED_LANGUAGES.includes(storedLanguage) ? storedLanguage : 'en'
} catch(_) {
return 'en'
}
}

const persistLanguage = language => {
try {
window.localStorage.setItem(LANGUAGE_STORAGE_KEY, language)
} catch(_) {
// Keep i18n usable when browser storage is unavailable.
}
}

i18n.use(initReactI18next).init({
fallbackLng: 'en',
lng: 'en',
lng: getInitialLanguage(),
resources: {
en: {
translations: en
Expand All @@ -16,12 +40,16 @@ i18n.use(initReactI18next).init({
},
zh: {
translations: zh
},
'pt-BR': {
translations: ptBR
}
},
ns: ['translations'],
defaultNS: 'translations'
});

i18n.languages = ['en', 'es', 'zh'];
i18n.languages = SUPPORTED_LANGUAGES;
i18n.on('languageChanged', persistLanguage)

export default i18n;
34 changes: 33 additions & 1 deletion src/i18n/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,36 @@
"create_from_ocl_url": "Create from OCL URL",
"created_on": "Created On",
"created_by": "Created By",
"event_types": {
"created": "Created",
"updated": "Updated",
"released": "Released",
"deleted": "Deleted",
"followed": "Followed",
"unfollowed": "Unfollowed",
"joined": "Joined",
"source": "Source"
},
"object_types": {
"Source": "Source",
"Collection": "Collection",
"Source Version": "Source Version",
"Collection Version": "Collection Version",
"Organization": "Organization",
"Concept": "Concept",
"Mapping": "Mapping",
"Repository": "Repository"
},
"event_object_types": {
"Source": "a Source",
"Collection": "a Collection",
"Source Version": "a Source Version",
"Collection Version": "a Collection Version",
"Organization": "an Organization",
"Concept": "a Concept",
"Mapping": "a Mapping",
"Repository": "a Repository"
},
"version": "Version",
"versions": "Versions",
"summary": "Summary",
Expand Down Expand Up @@ -891,7 +921,9 @@
"about_me": "About me",
"about_me_description": "Create an introduction for visiting your profile (200 characters).",
"user_has_not_created_public_repos_suffix": "has not created any public repositories",
"recent_activity": "recent activity"
"recent_activity": "recent activity",
"own_recent_activity": "Your recent activity",
"recent_activity_of": "{{name}}'s recent activity"
},
"search": {
"filters": "Filters",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/es/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,9 @@
"location": "Ubicación",
"website": "Sitio web",
"last_login": "Último inicio de sesión",
"name_and_description": "Nombre y descripción"
"name_and_description": "Nombre y descripción",
"own_recent_activity": "Tu actividad reciente",
"recent_activity_of": "Actividad reciente de {{name}}"
},
"search": {
"filters": "Filtros",
Expand Down
Loading
Loading