diff --git a/README.es.md b/README.es.md new file mode 100644 index 0000000..2275b94 --- /dev/null +++ b/README.es.md @@ -0,0 +1,47 @@ +# Media Portal + +> [⬇️ Descargar la aplicación](https://github.com/desko27/mediaportal/releases/latest) + +Media Portal es una aplicación para ordenador gratuita y de código abierto, que funciona tanto en sistemas Windows como en Mac. + +Si necesitas exponer diferentes imágenes o vídeos durante una videoconferencia y utilizas la función de compartir pantalla, Media Portal te ayuda a preparar una lista de archivos desde la cual mandarás contenido en un solo click. + +## Manual de uso + +Al ejecutar Media Portal se abren dos ventanas: una es la ventana de gestión de la lista de archivos, la otra es el portal donde veremos el contenido. + +![Boot Media Portal](https://user-images.githubusercontent.com/4168389/80231414-9f39e300-8653-11ea-9453-74fbc6f83ac9.png) + +A continuación, solo tenemos que seleccionar y arrastrar nuestra lista de archivos de imagen o vídeo hacia la ventana de gestión. + +![Dragging Media Files](https://user-images.githubusercontent.com/4168389/80231433-a52fc400-8653-11ea-9d38-6ea11f9d19f3.png) + +Entonces, hacemos click en cualquiera de ellos e inmediatamente veremos el contenido en el portal. + +Se trate de una imagen... + +![Sending Content Image](https://user-images.githubusercontent.com/4168389/80231438-a82ab480-8653-11ea-959f-f2322055848f.png) + +... o de vídeo + +![Sending Content Video](https://user-images.githubusercontent.com/4168389/80231445-aa8d0e80-8653-11ea-81dd-a4bf6bc1e576.png) + + +Es así de sencillo, ¡ya puedes empezar a usar Media Portal! + +## Preguntas frecuentes + +### ¿Puedo usarlo con varias pantallas? +Si tienes dos o más pantallas, puedes mover el portal a cualquiera de ellas, e incluso ampliarlo a pantalla completa haciendo doble click sobre él. Esto te puede venir bien si deseas compartir directamente una de tus pantallas secundarias en tu aplicación de videoconferencias. + +### ¿Qué son los checks verdes de la izquierda? +Para llevar control de lo que ya has compartido durante la reunión, Media Portal marcará automáticamente cada archivo al seleccionarlo; de este modo siempre sabrás cuál es el siguiente. También puedes añadir o retirar estas marcas manualmente haciendo click sobre ellas. + +### ¿Hay atajos de teclado? +Efectivamente, para los más exigentes, Media Portal ofrece la posibilidad de controlar el envío de contenido mediante atajos de teclado, algo muy conveniente considerando que lo normal es que estemos más pendientes de la aplicación de videoconferencias y que quizá no haya tanto tiempo para ir cambiando entre ventanas. + +| Atajo de teclado | Acción | +| --- | --- | +| SHIFT + ALT + A | Envía el contenido siguiente | +| SHIFT + ALT + 0 | Deja de enviar el contenido actual | +| SHIFT + ALT + [1-9] | Envía el contenido de la posición deseada | diff --git a/package.json b/package.json index 7c81fb1..61e3e13 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "mediaportal", "description": "Portal for media", "author": "desko27", - "version": "2.2.0", + "version": "2.3.0", "private": true, "scripts": { "react-start": "react-scripts start", @@ -47,6 +47,7 @@ "react": "^16.8.6", "react-dom": "^16.8.6", "react-dropzone": "^10.2.2", + "react-intl": "^4.5.0", "react-router-dom": "^5.1.2" }, "devDependencies": { diff --git a/src/App.js b/src/App.js index c787b14..125f8b6 100644 --- a/src/App.js +++ b/src/App.js @@ -1,21 +1,39 @@ import React from 'react' import { HashRouter as Router, Switch, Route } from 'react-router-dom' +import { IntlProvider } from 'react-intl' import MainRoute from './routes/MainRoute' import PortalRoute from './routes/PortalRoute' +import en from './translations/en.json' +import es from './translations/es.json' + +const translations = { en, es } +const availableLanguages = Object.keys(translations) + +// get language without region code from browser +const [rawBrowserLanguage] = navigator.language.split(/[-_]/) +const originalLang = rawBrowserLanguage && rawBrowserLanguage.toLowerCase() + +// take decisions like fallback to english if browser's not available +const DEFAULT_LANGUAGE = 'en' +const browserLanguage = originalLang === 'ca' ? 'es' : originalLang // catalan -> spanish +const language = availableLanguages.includes(browserLanguage) ? browserLanguage : DEFAULT_LANGUAGE + const App = () => { return ( - - - - - - - - - - + + + + + + + + + + + + ) } diff --git a/src/components/Header/UpdateButton/index.js b/src/components/Header/UpdateButton/index.js index 73e9e47..2694a5e 100644 --- a/src/components/Header/UpdateButton/index.js +++ b/src/components/Header/UpdateButton/index.js @@ -1,11 +1,12 @@ import React from 'react' +import { FormattedMessage } from 'react-intl' import styles from './index.module.css' const UpdateButton = ({ onClick }) => { return ( ) } diff --git a/src/components/Header/index.js b/src/components/Header/index.js index a432e06..2d851cc 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -1,5 +1,6 @@ import React from 'react' import cx from 'classnames' +import { FormattedMessage } from 'react-intl' import { ReactComponent as XCircleIcon } from './icons/x-circle.svg' import { ReactComponent as MenuIcon } from './icons/menu.svg' @@ -34,7 +35,7 @@ const Header = ({ {!!filesNumber && `${Math.round(progressRatio * 100)}% | `} - {filesNumber || '--'} files + {filesNumber || '--'} {FLEX_SPACER} {isUpdateAvailable && } diff --git a/src/components/MediaControls/index.js b/src/components/MediaControls/index.js index d4e9908..ce02efa 100644 --- a/src/components/MediaControls/index.js +++ b/src/components/MediaControls/index.js @@ -1,5 +1,6 @@ import React from 'react' import cx from 'classnames' +import { FormattedMessage } from 'react-intl' import ElapsedTimeBar from './ElapsedTimeBar' import { ReactComponent as PlayIcon } from './icons/play.svg' @@ -19,7 +20,7 @@ const MediaControls = ({ className, sendAction, video }) => { if (!video) { return (
- No video selected +
) } diff --git a/src/components/Menu/MenuItem/index.module.css b/src/components/Menu/MenuItem/index.module.css index 645907a..9253d64 100644 --- a/src/components/Menu/MenuItem/index.module.css +++ b/src/components/Menu/MenuItem/index.module.css @@ -29,6 +29,7 @@ } .notificationBall { + flex-shrink: 0; height: 10px; width: 10px; border-radius: 5px; diff --git a/src/components/Menu/index.js b/src/components/Menu/index.js index fefbb88..b9282df 100644 --- a/src/components/Menu/index.js +++ b/src/components/Menu/index.js @@ -1,7 +1,8 @@ import React from 'react' import cx from 'classnames' - +import { FormattedMessage, useIntl } from 'react-intl' import { version } from '../../../package.json' + import MenuItem from './MenuItem' import styles from './index.module.css' @@ -10,7 +11,10 @@ const openUrl = url => shell.openExternal(url) const FLEX_SPACER =
const LINKS = { - USER_MANUAL: 'https://github.com/desko27/mediaportal/blob/master/README.md', + USER_MANUAL: locale => { + const localizedExtension = locale === 'en' ? '' : `.${locale}` + return `https://github.com/desko27/mediaportal/blob/master/README${localizedExtension}.md` + }, SOURCE_CODE: 'https://github.com/desko27/mediaportal', REPORT_ISSUE: 'https://github.com/desko27/mediaportal/issues/new', SEND_COMMENTS: 'mailto:desko27@gmail.com' @@ -19,20 +23,32 @@ const LINKS = { const Menu = ({ isOpen, isUpdateAvailable, + lang, performUpdate, setIsOpen }) => { + const { locale } = useIntl() return (
setIsOpen(false)} />
{isUpdateAvailable && ( - Download update + + + )} - openUrl(LINKS.USER_MANUAL)}>See user manual - openUrl(LINKS.SOURCE_CODE)}>Source code - openUrl(LINKS.REPORT_ISSUE)}>Report an issue - openUrl(LINKS.SEND_COMMENTS)}>Send comments + openUrl(LINKS.USER_MANUAL(locale))}> + + + openUrl(LINKS.SOURCE_CODE)}> + + + openUrl(LINKS.REPORT_ISSUE)}> + + + openUrl(LINKS.SEND_COMMENTS)}> + + {FLEX_SPACER} v{version}
diff --git a/src/components/Menu/index.module.css b/src/components/Menu/index.module.css index 5e5402f..66730c2 100644 --- a/src/components/Menu/index.module.css +++ b/src/components/Menu/index.module.css @@ -12,7 +12,7 @@ top: var(--h-menu-spacing); bottom: 0; right: 0; - width: 200px; + width: 210px; background-color: var(--c-gray); box-shadow: calc(-1 * var(--bxsh-width)) 0px 0px 0px rgba(var(--c-black-rgb), 0.15); transform: translateX(calc(100% + var(--bxsh-width))); diff --git a/src/translations/en.json b/src/translations/en.json new file mode 100644 index 0000000..c5eda2d --- /dev/null +++ b/src/translations/en.json @@ -0,0 +1,10 @@ +{ + "header.files": "files", + "header.update": "update!", + "menu.download-update": "Download update", + "menu.see-user-manual": "See user manual", + "menu.source-code": "Source code", + "menu.report-issue": "Report an issue", + "menu.send-comments": "Send comments", + "media-controls.no-video-selected": "No video selected" +} diff --git a/src/translations/es.json b/src/translations/es.json new file mode 100644 index 0000000..ddcc170 --- /dev/null +++ b/src/translations/es.json @@ -0,0 +1,10 @@ +{ + "header.files": "archivos", + "header.update": "¡novedades!", + "menu.download-update": "Descargar actualización", + "menu.see-user-manual": "Ver instrucciones", + "menu.source-code": "Código fuente", + "menu.report-issue": "Reportar error", + "menu.send-comments": "Enviar comentarios", + "media-controls.no-video-selected": "Sin vídeo seleccionado" +}