From 2bf7c91fe4784b6c3a261d22ca48c390d357d499 Mon Sep 17 00:00:00 2001 From: chrisgarrity <chrisg@media.mit.edu> Date: Mon, 15 Oct 2018 15:08:05 -0400 Subject: [PATCH] Add video translation * Look up video id based on locale. * add japanese video ids * add test --- src/components/cards/cards.jsx | 8 +- src/containers/cards.jsx | 1 + src/lib/libraries/decks/index.jsx | 28 +++---- src/lib/libraries/decks/translate-video.js | 97 ++++++++++++++++++++++ test/unit/util/translate-video.test.js | 19 +++++ 5 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 src/lib/libraries/decks/translate-video.js create mode 100644 test/unit/util/translate-video.test.js diff --git a/src/components/cards/cards.jsx b/src/components/cards/cards.jsx index 335849e9e..1ca7672f1 100644 --- a/src/components/cards/cards.jsx +++ b/src/components/cards/cards.jsx @@ -11,6 +11,8 @@ import leftArrow from './icon--prev.svg'; import helpIcon from '../../lib/assets/icon--tutorials.svg'; import closeIcon from '../close-button/icon--close.svg'; +import {translateVideo} from '../../lib/libraries/decks/translate-video.js'; + const CardHeader = ({onCloseCards, onShowAll, totalSteps, step}) => ( <div className={styles.headerButtons}> <div @@ -213,6 +215,7 @@ const Cards = props => { content, dragging, isRtl, + locale, onActivateDeckFactory, onCloseCards, onDrag, @@ -264,7 +267,7 @@ const Cards = props => { steps[step].video ? ( <VideoStep dragging={dragging} - video={steps[step].video} + video={translateVideo(steps[step].video, locale)} /> ) : ( <ImageStep @@ -300,7 +303,8 @@ Cards.propTypes = { }) }), dragging: PropTypes.bool.isRequired, - isRtl: PropTypes.bool, + isRtl: PropTypes.bool.isRequired, + locale: PropTypes.string.isRequired, onActivateDeckFactory: PropTypes.func.isRequired, onCloseCards: PropTypes.func.isRequired, onDrag: PropTypes.func, diff --git a/src/containers/cards.jsx b/src/containers/cards.jsx index 2e4b92e5a..0cc39f5c5 100644 --- a/src/containers/cards.jsx +++ b/src/containers/cards.jsx @@ -24,6 +24,7 @@ const mapStateToProps = state => ({ x: state.scratchGui.cards.x, y: state.scratchGui.cards.y, isRtl: state.locales.isRtl, + locale: state.locales.locale, dragging: state.scratchGui.cards.dragging }); diff --git a/src/lib/libraries/decks/index.jsx b/src/lib/libraries/decks/index.jsx index bf714af93..179666ff4 100644 --- a/src/lib/libraries/decks/index.jsx +++ b/src/lib/libraries/decks/index.jsx @@ -74,7 +74,7 @@ export default { img: libraryIntro, steps: [{ - video: 'rpjvs3v9gj' + video: 'intro-move-sayhello' }, { title: ( <FormattedMessage @@ -112,7 +112,7 @@ export default { ), img: libraryAnimate, steps: [{ - video: 'pyur30ho05' + video: 'animate-a-name' }, { title: ( <FormattedMessage @@ -186,7 +186,7 @@ export default { ), img: libraryMakeMusic, steps: [{ - video: 'ir0j8ljsgm' + video: 'Make-Music' }, { title: ( @@ -254,7 +254,7 @@ export default { ), img: libraryMakeAGame, steps: [{ - video: '5rp47ys13g' + video: 'Make-A-Game' }, { title: ( @@ -340,7 +340,7 @@ export default { ), img: libraryChaseGame, steps: [{ - video: 'kusyx9thl5' + video: 'Chase-Game' }, { title: ( @@ -471,7 +471,7 @@ export default { ), img: addBackdropThumb, steps: [{ - video: 'nict6zdzlx' + video: 'add-a-backdrop' }, { deckIds: [ 'change-size', @@ -490,7 +490,7 @@ export default { ), img: changeSizeThumb, steps: [{ - video: 'p8va85hh61' + video: 'change-size' }, { deckIds: [ 'glide-around', @@ -509,7 +509,7 @@ export default { ), img: glideAroundThumb, steps: [{ - video: 'sh9j978rg8' + video: 'glide-around' }, { deckIds: [ 'add-a-backdrop', @@ -529,7 +529,7 @@ export default { ), img: recordASound, steps: [{ - video: 'ulzl1fbzny' + video: 'record-a-sound' }, { deckIds: [ 'Make-Music', @@ -548,7 +548,7 @@ export default { ), img: spinThumb, steps: [{ - video: '07fed5hhpv' + video: 'spin-video' }, { deckIds: [ 'add-a-backdrop', @@ -567,7 +567,7 @@ export default { ), img: hideAndShowThumb, steps: [{ - video: 'g479ahobo9' + video: 'hide-and-show' }, { deckIds: [ 'add-a-backdrop', @@ -587,7 +587,7 @@ export default { ), img: switchCostumeThumb, steps: [{ - video: '1ocp6a1ejn' + video: 'switch-costume' }, { deckIds: [ 'add-a-backdrop', @@ -607,7 +607,7 @@ export default { ), img: moveArrowKeysThumb, steps: [{ - video: 'yetrmk4iuu' + video: 'move-around-with-arrow-keys' }, { deckIds: [ 'add-a-backdrop', @@ -626,7 +626,7 @@ export default { ), img: addEffectsThumb, steps: [{ - video: '3jvl8zgjo2' + video: 'add-effects' }, { deckIds: [ 'add-a-backdrop', diff --git a/src/lib/libraries/decks/translate-video.js b/src/lib/libraries/decks/translate-video.js new file mode 100644 index 000000000..6f34771b0 --- /dev/null +++ b/src/lib/libraries/decks/translate-video.js @@ -0,0 +1,97 @@ +/** + * @fileoverview + * Utility function to look up whether a translated video exists for a locale. + */ + +// TODO: ja-Hira are copies of ja, replace with real ja-Hira when available. +const videos = { + 'intro-move-sayhello': { + 'en': 'rpjvs3v9gj', + 'ja': 'v2c2f3y2sc', + 'ja-Hira': 'v2c2f3y2sc' + }, + 'animate-a-name': { + 'en': 'pyur30ho05', + 'ja': 'xrmgno02th', + 'ja-Hira': 'xrmgno02th' + }, + 'Make-Music': { + 'en': 'ir0j8ljsgm', + 'ja': 'iybhyobckr', + 'ja-Hira': 'iybhyobckr' + }, + 'Make-A-Game': { + 'en': '5rp47ys13g', + 'ja': 'h4q2ea3ojw', + 'ja-Hira': 'h4q2ea3ojw' + }, + 'Chase-Game': { + 'en': 'kusyx9thl5', + 'ja': 'wr6ysk8s6d', + 'ja-Hira': 'wr6ysk8s6d' + }, + 'add-a-backdrop': { + 'en': 'nict6zdzlx', + 'ja': 'j382ohngg7', + 'ja-Hira': 'j382ohngg7' + }, + 'change-size': { + 'en': 'p8va85hh61', + 'ja': 'uzkfi9uai0', + 'ja-Hira': 'uzkfi9uai0' + }, + 'glide-around': { + 'en': 'sh9j978rg8', + 'ja': 'jsat4vhu48', + 'ja-Hira': 'jsat4vhu48' + }, + 'record-a-sound': { + 'en': 'ulzl1fbzny', + 'ja': '5zmy6u614k', + 'ja-Hira': '5zmy6u614k' + }, + 'spin-video': { + 'en': '07fed5hhpv', + 'ja': 'hjhc0a8r7j', + 'ja-Hira': 'hjhc0a8r7j' + }, + 'hide-and-show': { + 'en': 'g479ahobo9', + 'ja': 'ruynguvag5', + 'ja-Hira': 'ruynguvag5' + }, + 'switch-costume': { + 'en': '1ocp6a1ejn', + 'ja': 'g3vluv0ms8', + 'ja-Hira': 'g3vluv0ms8' + }, + 'move-around-with-arrow-keys': { + 'en': 'yetrmk4iuu', + 'ja': 'fk34dcg5oz', + 'ja-Hira': 'fk34dcg5oz' + }, + 'add-effects': { + 'en': '3jvl8zgjo2', + 'ja': 'q7zq9vu0wb', + 'ja-Hira': 'q7zq9vu0wb' + } +}; + +/** + * Return a video identifier (on our video hosting service) + * @param {string} videoId key in the videos object, or id string. + * @param {string} locale locale to look up. If locale is not defined return the id for 'en' by default + * @return {string} identifier for the video on our video hosting service. + */ +const translateVideo = (videoId, locale) => { + // if the videoId is not recognized in the videos object, assume it's already a video id on wistia + if (!videos.hasOwnProperty(videoId)) return videoId; + if (videos[videoId].hasOwnProperty(locale)) { + return videos[videoId][locale]; + } + return videos[videoId].en; +}; + +export { + translateVideo +}; diff --git a/test/unit/util/translate-video.test.js b/test/unit/util/translate-video.test.js new file mode 100644 index 000000000..b63769b03 --- /dev/null +++ b/test/unit/util/translate-video.test.js @@ -0,0 +1,19 @@ +import {translateVideo} from '../../../src/lib/libraries/decks/translate-video.js'; + +describe('translateVideo', () => { + test('returns the id if it is not found', () => { + expect(translateVideo('not-a-key', 'en')).toEqual('not-a-key'); + }); + + test('returns the expected id for Japanese', () => { + expect(translateVideo('intro-move-sayhello', 'ja')).toEqual('v2c2f3y2sc'); + }); + + test('returns the expected id for English', () => { + expect(translateVideo('intro-move-sayhello', 'en')).toEqual('rpjvs3v9gj'); + }); + + test('returns the English id for non-existent locales', () => { + expect(translateVideo('intro-move-sayhello', 'yum')).toEqual('rpjvs3v9gj'); + }); +}); -- GitLab