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