diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml new file mode 100644 index 000000000..b80ae44fa --- /dev/null +++ b/.github/workflows/develop.yml @@ -0,0 +1,48 @@ +name: staging deployment v1 + +on: + push: + branches: + - develop + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [12.x] + python-version: [3.0] + env: + S3_BUCKET_PREFIX: hackingstudio-code4maus-projects + AWS_REGION: eu-central-1 + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + steps: + - name: Checkout app + uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: before install dep + run: | + sudo apt-get install -y python3-pip python3-setuptools libcups2-dev + pip3 install --user awscli + export PATH=$PATH:$HOME/.local/bin + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + - name: Install dependencies + run: | + yarn install + - name: build app + run: NODE_ENV=production yarn build + - name: serverless deploy + run: SLS_STAGE=staging BRANCH=develop yarn deploy diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml new file mode 100644 index 000000000..08a8c3b5c --- /dev/null +++ b/.github/workflows/production.yml @@ -0,0 +1,47 @@ +name: production deployment v1 + +on: + push: + branches: + - production +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [12.x] + python-version: [3.0] + env: + S3_BUCKET_PREFIX: hackingstudio-code4maus-projects + AWS_REGION: eu-central-1 + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + steps: + - name: Checkout app + uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: before install dep + run: | + sudo apt-get install -y python3-pip python3-setuptools libcups2-dev + pip3 install --user awscli + export PATH=$PATH:$HOME/.local/bin + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + - name: Install dependencies + run: | + yarn install + - name: build app + run: NODE_ENV=production yarn build + - name: serverless deploy + run: SLS_STAGE=prod BRANCH=production yarn deploy diff --git a/.gitignore b/.gitignore index 33632648b..736415084 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,6 @@ npm-* .env .env.backend -# External assets -/assets/ - # Cache /.cache/ .webpack/ @@ -43,4 +40,4 @@ yarn-error.log .vscode/ # Jupyter Checkpoints -.ipynb_checkpoints/ \ No newline at end of file +.ipynb_checkpoints/ diff --git a/assets/blocks-media/green-flag.svg b/assets/blocks-media/green-flag.svg new file mode 100644 index 000000000..c78bfa3d3 --- /dev/null +++ b/assets/blocks-media/green-flag.svg @@ -0,0 +1,88 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/assets/blocks-media/zoom-in.svg b/assets/blocks-media/zoom-in.svg new file mode 100644 index 000000000..480da8330 --- /dev/null +++ b/assets/blocks-media/zoom-in.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/blocks-media/zoom-out.svg b/assets/blocks-media/zoom-out.svg new file mode 100644 index 000000000..1a4a6ddd5 --- /dev/null +++ b/assets/blocks-media/zoom-out.svg @@ -0,0 +1 @@ +Verkleinern \ No newline at end of file diff --git a/assets/blocks-media/zoom-reset.svg b/assets/blocks-media/zoom-reset.svg new file mode 100644 index 000000000..db1a63af9 --- /dev/null +++ b/assets/blocks-media/zoom-reset.svg @@ -0,0 +1 @@ +Element 63 \ No newline at end of file diff --git a/assets/icons/header_menu.svg b/assets/icons/header_menu.svg new file mode 100644 index 000000000..36420cc7c --- /dev/null +++ b/assets/icons/header_menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/header_open.svg b/assets/icons/header_open.svg new file mode 100644 index 000000000..4397b8d95 --- /dev/null +++ b/assets/icons/header_open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/header_save.svg b/assets/icons/header_save.svg new file mode 100644 index 000000000..ecbb99161 --- /dev/null +++ b/assets/icons/header_save.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + Speichern + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/icon_aussehen.svg b/assets/icons/icon_aussehen.svg new file mode 100644 index 000000000..9bb83db7c --- /dev/null +++ b/assets/icons/icon_aussehen.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + Element 7 + + + + + + + diff --git a/assets/icons/icon_bewegung.svg b/assets/icons/icon_bewegung.svg new file mode 100644 index 000000000..f73e53f2d --- /dev/null +++ b/assets/icons/icon_bewegung.svg @@ -0,0 +1,89 @@ + + + + + + image/svg+xml + + + + + + Element 6 + + + + + + + + + + + diff --git a/assets/icons/icon_ereignisse.svg b/assets/icons/icon_ereignisse.svg new file mode 100644 index 000000000..e4a2e6413 --- /dev/null +++ b/assets/icons/icon_ereignisse.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + Element 9 + + + + + + + diff --git a/assets/icons/icon_film.svg b/assets/icons/icon_film.svg new file mode 100644 index 000000000..2207d7950 --- /dev/null +++ b/assets/icons/icon_film.svg @@ -0,0 +1,112 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/icon_film_schraeg.svg b/assets/icons/icon_film_schraeg.svg new file mode 100644 index 000000000..dfb5f7ddd --- /dev/null +++ b/assets/icons/icon_film_schraeg.svg @@ -0,0 +1,139 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/icon_fuehlen.svg b/assets/icons/icon_fuehlen.svg new file mode 100644 index 000000000..b700b434a --- /dev/null +++ b/assets/icons/icon_fuehlen.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + + + + Element 11 + + + + + + diff --git a/assets/icons/icon_gif.svg b/assets/icons/icon_gif.svg new file mode 100644 index 000000000..efc6bab54 --- /dev/null +++ b/assets/icons/icon_gif.svg @@ -0,0 +1,96 @@ + + + + + + image/svg+xml + + Button_Gif + + + + + + + + + + + Button_Gif + + + + + + diff --git a/assets/icons/icon_hilfe.svg b/assets/icons/icon_hilfe.svg new file mode 100644 index 000000000..3ef7b5459 --- /dev/null +++ b/assets/icons/icon_hilfe.svg @@ -0,0 +1 @@ +hilfe_1 \ No newline at end of file diff --git a/assets/icons/icon_klang.svg b/assets/icons/icon_klang.svg new file mode 100644 index 000000000..1e0fa05ef --- /dev/null +++ b/assets/icons/icon_klang.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + + + + Element 8 + + + + + + diff --git a/assets/icons/icon_music.svg b/assets/icons/icon_music.svg new file mode 100644 index 000000000..232c4ec02 --- /dev/null +++ b/assets/icons/icon_music.svg @@ -0,0 +1,35 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/assets/icons/icon_myblocks.svg b/assets/icons/icon_myblocks.svg new file mode 100644 index 000000000..0d90d9a6f --- /dev/null +++ b/assets/icons/icon_myblocks.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + + + + Element 14 + + + + + + diff --git a/assets/icons/icon_operatoren.svg b/assets/icons/icon_operatoren.svg new file mode 100644 index 000000000..13cb0e25a --- /dev/null +++ b/assets/icons/icon_operatoren.svg @@ -0,0 +1,81 @@ + + + + + + image/svg+xml + + + + + + Element 12 + + + + + + + + diff --git a/assets/icons/icon_print.svg b/assets/icons/icon_print.svg new file mode 100644 index 000000000..42431fa8a --- /dev/null +++ b/assets/icons/icon_print.svg @@ -0,0 +1,102 @@ + + + + + + image/svg+xml + + Button_Camera + + + + + + + + + + + Button_Camera + + + + + + + diff --git a/assets/icons/icon_steuerung.svg b/assets/icons/icon_steuerung.svg new file mode 100644 index 000000000..993eb9857 --- /dev/null +++ b/assets/icons/icon_steuerung.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + + + + Element 10 + + + + + + diff --git a/assets/icons/icon_variablen.svg b/assets/icons/icon_variablen.svg new file mode 100644 index 000000000..28420fb07 --- /dev/null +++ b/assets/icons/icon_variablen.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + Element 13 + + + + + + + diff --git a/assets/icons/menu_edugames.svg b/assets/icons/menu_edugames.svg new file mode 100644 index 000000000..58340759b --- /dev/null +++ b/assets/icons/menu_edugames.svg @@ -0,0 +1 @@ +lernen-icon \ No newline at end of file diff --git a/assets/icons/menu_eltern-info.svg b/assets/icons/menu_eltern-info.svg new file mode 100644 index 000000000..1857e024e --- /dev/null +++ b/assets/icons/menu_eltern-info.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/menu_examples.svg b/assets/icons/menu_examples.svg new file mode 100644 index 000000000..a2aae58ba --- /dev/null +++ b/assets/icons/menu_examples.svg @@ -0,0 +1 @@ +beispiele-icon \ No newline at end of file diff --git a/assets/icons/menu_impressum.svg b/assets/icons/menu_impressum.svg new file mode 100644 index 000000000..e1f8cd84f --- /dev/null +++ b/assets/icons/menu_impressum.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/icons/menu_lehrer.svg b/assets/icons/menu_lehrer.svg new file mode 100644 index 000000000..52237628f --- /dev/null +++ b/assets/icons/menu_lehrer.svg @@ -0,0 +1,144 @@ + + + +image/svg+xmlButton_Print + +Button_Print + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/icons/menu_mausseite.svg b/assets/icons/menu_mausseite.svg new file mode 100644 index 000000000..e899a92a3 --- /dev/null +++ b/assets/icons/menu_mausseite.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/menu_plus.svg b/assets/icons/menu_plus.svg new file mode 100644 index 000000000..8b6743c4e --- /dev/null +++ b/assets/icons/menu_plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/menu_projects.svg b/assets/icons/menu_projects.svg new file mode 100644 index 000000000..43b5333a4 --- /dev/null +++ b/assets/icons/menu_projects.svg @@ -0,0 +1 @@ +selber-machen-icon diff --git a/assets/icons/tab_sound.svg b/assets/icons/tab_sound.svg new file mode 100644 index 000000000..c2fb275f6 --- /dev/null +++ b/assets/icons/tab_sound.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/target_add.svg b/assets/icons/target_add.svg new file mode 100644 index 000000000..25a281ac1 --- /dev/null +++ b/assets/icons/target_add.svg @@ -0,0 +1,33 @@ + + + + + + image/svg+xml + + plus + + + + + plus + + diff --git a/assets/icons/target_bg.svg b/assets/icons/target_bg.svg new file mode 100644 index 000000000..9167cc52d --- /dev/null +++ b/assets/icons/target_bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/target_costume.svg b/assets/icons/target_costume.svg new file mode 100644 index 000000000..ea908da84 --- /dev/null +++ b/assets/icons/target_costume.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/target_exchange.svg b/assets/icons/target_exchange.svg new file mode 100644 index 000000000..171c79b37 --- /dev/null +++ b/assets/icons/target_exchange.svg @@ -0,0 +1 @@ +Hintergrund ändern \ No newline at end of file diff --git a/assets/img/beta_head_logo.png b/assets/img/beta_head_logo.png new file mode 100644 index 000000000..e69c9e13e Binary files /dev/null and b/assets/img/beta_head_logo.png differ diff --git a/assets/img/beta_header_sans.png b/assets/img/beta_header_sans.png new file mode 100644 index 000000000..9d01c58d8 Binary files /dev/null and b/assets/img/beta_header_sans.png differ diff --git a/assets/img/block1.png b/assets/img/block1.png new file mode 100644 index 000000000..de85521c1 Binary files /dev/null and b/assets/img/block1.png differ diff --git a/assets/img/block2.png b/assets/img/block2.png new file mode 100644 index 000000000..77aa335c8 Binary files /dev/null and b/assets/img/block2.png differ diff --git a/assets/img/block3.png b/assets/img/block3.png new file mode 100644 index 000000000..73aa14c64 Binary files /dev/null and b/assets/img/block3.png differ diff --git a/assets/img/button_print.png b/assets/img/button_print.png new file mode 100644 index 000000000..f8c84d203 Binary files /dev/null and b/assets/img/button_print.png differ diff --git a/assets/img/button_printnow.png b/assets/img/button_printnow.png new file mode 100644 index 000000000..b62b74f44 Binary files /dev/null and b/assets/img/button_printnow.png differ diff --git a/assets/img/button_share.png b/assets/img/button_share.png new file mode 100644 index 000000000..03ac41857 Binary files /dev/null and b/assets/img/button_share.png differ diff --git a/assets/img/code.gif b/assets/img/code.gif new file mode 100644 index 000000000..de84d8e80 Binary files /dev/null and b/assets/img/code.gif differ diff --git a/assets/img/fant.png b/assets/img/fant.png new file mode 100644 index 000000000..807a9c1c5 Binary files /dev/null and b/assets/img/fant.png differ diff --git a/assets/img/favicon.jpg b/assets/img/favicon.jpg new file mode 100644 index 000000000..8cfac0081 Binary files /dev/null and b/assets/img/favicon.jpg differ diff --git a/assets/img/favicon.png b/assets/img/favicon.png new file mode 100644 index 000000000..26502c35c Binary files /dev/null and b/assets/img/favicon.png differ diff --git a/assets/img/head_logo.png b/assets/img/head_logo.png new file mode 100644 index 000000000..8a9752ff8 Binary files /dev/null and b/assets/img/head_logo.png differ diff --git a/assets/img/head_logo_beta.png b/assets/img/head_logo_beta.png new file mode 100644 index 000000000..e69c9e13e Binary files /dev/null and b/assets/img/head_logo_beta.png differ diff --git a/assets/img/loader.svg b/assets/img/loader.svg new file mode 100644 index 000000000..ca43cbfde --- /dev/null +++ b/assets/img/loader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/logo_text.png b/assets/img/logo_text.png new file mode 100644 index 000000000..399be7754 Binary files /dev/null and b/assets/img/logo_text.png differ diff --git a/assets/img/logo_text.png.png b/assets/img/logo_text.png.png new file mode 100644 index 000000000..399be7754 Binary files /dev/null and b/assets/img/logo_text.png.png differ diff --git a/assets/img/logo_text_beta.png b/assets/img/logo_text_beta.png new file mode 100644 index 000000000..9d01c58d8 Binary files /dev/null and b/assets/img/logo_text_beta.png differ diff --git a/assets/img/maus1.png b/assets/img/maus1.png new file mode 100644 index 000000000..adcb33b68 Binary files /dev/null and b/assets/img/maus1.png differ diff --git a/assets/img/maus_question.svg b/assets/img/maus_question.svg new file mode 100644 index 000000000..8b4fb79d5 --- /dev/null +++ b/assets/img/maus_question.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/img/meine_sache.png b/assets/img/meine_sache.png new file mode 100644 index 000000000..aa41be5d4 Binary files /dev/null and b/assets/img/meine_sache.png differ diff --git a/assets/img/meine_sachen.png b/assets/img/meine_sachen.png new file mode 100644 index 000000000..aa41be5d4 Binary files /dev/null and b/assets/img/meine_sachen.png differ diff --git a/assets/img/planetschule_logo.jpg b/assets/img/planetschule_logo.jpg new file mode 100644 index 000000000..2284a2cbd Binary files /dev/null and b/assets/img/planetschule_logo.jpg differ diff --git a/assets/img/screenshot_editor.png b/assets/img/screenshot_editor.png new file mode 100644 index 000000000..29cb9cda6 Binary files /dev/null and b/assets/img/screenshot_editor.png differ diff --git a/assets/img/wdr_logo.svg b/assets/img/wdr_logo.svg new file mode 100644 index 000000000..d585b15a3 --- /dev/null +++ b/assets/img/wdr_logo.svg @@ -0,0 +1,55 @@ + + + + \ No newline at end of file diff --git a/assets/project-assets/282fb24fedf9ed8f6b7dd08366a0f83c.mp3 b/assets/project-assets/282fb24fedf9ed8f6b7dd08366a0f83c.mp3 new file mode 100644 index 000000000..c00fda49d Binary files /dev/null and b/assets/project-assets/282fb24fedf9ed8f6b7dd08366a0f83c.mp3 differ diff --git a/assets/project-assets/3a343d19f40be5196f5b1cad1c7d1e39.jpg b/assets/project-assets/3a343d19f40be5196f5b1cad1c7d1e39.jpg new file mode 100644 index 000000000..c8a722327 Binary files /dev/null and b/assets/project-assets/3a343d19f40be5196f5b1cad1c7d1e39.jpg differ diff --git a/assets/project-assets/7a0b6208f0ac9b50189eaa3a2fa68590.jpg b/assets/project-assets/7a0b6208f0ac9b50189eaa3a2fa68590.jpg new file mode 100644 index 000000000..1372e3cef Binary files /dev/null and b/assets/project-assets/7a0b6208f0ac9b50189eaa3a2fa68590.jpg differ diff --git a/assets/project-assets/a14c503a8981039b7ab3c70cbf355886.jpg b/assets/project-assets/a14c503a8981039b7ab3c70cbf355886.jpg new file mode 100644 index 000000000..a07944cbe Binary files /dev/null and b/assets/project-assets/a14c503a8981039b7ab3c70cbf355886.jpg differ diff --git a/assets/project-assets/a35419bc3c9a8888430c157960ef28b4.jpg b/assets/project-assets/a35419bc3c9a8888430c157960ef28b4.jpg new file mode 100644 index 000000000..d1d949221 Binary files /dev/null and b/assets/project-assets/a35419bc3c9a8888430c157960ef28b4.jpg differ diff --git a/assets/project-assets/b38904cb3103c903cd6be4b569b8db5c.mp3 b/assets/project-assets/b38904cb3103c903cd6be4b569b8db5c.mp3 new file mode 100644 index 000000000..63b7d3666 Binary files /dev/null and b/assets/project-assets/b38904cb3103c903cd6be4b569b8db5c.mp3 differ diff --git a/assets/project-assets/b533867ddb6e18b4d508f11be3b46095.jpg b/assets/project-assets/b533867ddb6e18b4d508f11be3b46095.jpg new file mode 100644 index 000000000..2c4560992 Binary files /dev/null and b/assets/project-assets/b533867ddb6e18b4d508f11be3b46095.jpg differ diff --git a/assets/project-assets/bea568d0b736f0a365cb41e7d05f8100.jpg b/assets/project-assets/bea568d0b736f0a365cb41e7d05f8100.jpg new file mode 100644 index 000000000..f98376a4f Binary files /dev/null and b/assets/project-assets/bea568d0b736f0a365cb41e7d05f8100.jpg differ diff --git a/assets/project-assets/c6824e69f8d1c3c8859666fcbe3e547c.svg b/assets/project-assets/c6824e69f8d1c3c8859666fcbe3e547c.svg new file mode 100644 index 000000000..b62bf1bd6 --- /dev/null +++ b/assets/project-assets/c6824e69f8d1c3c8859666fcbe3e547c.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/netlify.toml b/netlify.toml index 26683849d..0317fd9e6 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,4 +1,8 @@ [build] - Command = "NODE_ENV=production yarn build:netlify" + Command = "NODE_ENV=staging yarn build:netlify" Functions = "lambda" Publish = "build" +[[headers]] + for = "/*" + [headers.values] + Access-Control-Allow-Origin = "https://logs1414.xiti.com" diff --git a/package.json b/package.json index 3bcfe15d8..b0098a109 100644 --- a/package.json +++ b/package.json @@ -129,9 +129,9 @@ "rimraf": "^2.6.1", "scratch-paint": "0.2.0-prerelease.20181120191526", "scratch-render": "0.1.0-prerelease.20210325231800", + "scratch-render-fonts": "1.0.0-prerelease.20210401210003", "scratch-storage": "1.2.2", "scratch-svg-renderer": "0.2.0-prerelease.20210511195415", - "scratch-render-fonts": "1.0.0-prerelease.20210401210003", "selenium-webdriver": "4.0.0-alpha.1", "serverless": "^1.30.3", "serverless-domain-manager": "^3.1.0", @@ -183,6 +183,7 @@ "jspdf": "^1.5.3", "lodash.keyby": "^4.6.0", "multer": "^1.4.1", + "piano-analytics-js": "^6.8.3", "qrcode.react": "^0.9.3", "scratch-audio": "0.1.0-prerelease.20200528195344", "scratch-blocks": "0.1.0-prerelease.20210529032338", diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..88294b13f --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +awscli diff --git a/scripts/deploy-frontend.sh b/scripts/deploy-frontend.sh index 49c8e6f9e..538a46805 100755 --- a/scripts/deploy-frontend.sh +++ b/scripts/deploy-frontend.sh @@ -3,16 +3,19 @@ # todo: make dynamic via serverless BUCKET="hackingstudio-code4maus-app" -if [ "$TRAVIS_BRANCH" == "production" ]; then +if [ "$BRANCH" == "production" ]; then BUCKET="${BUCKET}-prod" -elif [ "$TRAVIS_BRANCH" == "develop" ]; then +elif [ "$BRANCH" == "develop" ]; then BUCKET="${BUCKET}-staging" else BUCKET="${BUCKET}-dev" fi +echo "Deploying to bucket: ${BUCKET}" aws s3 sync build s3://${BUCKET} --delete --acl public-read for FILE in $(find build -name index.html -printf '%P\n'); do aws s3 cp build/${FILE} s3://${BUCKET}/${FILE} --metadata-directive REPLACE --cache-control max-age=0,no-cache,no-store,must-revalidate --content-type text/html --acl public-read done + aws s3 cp build/service-worker.js s3://${BUCKET}/service-worker.js --metadata-directive REPLACE --cache-control max-age=0,no-cache,no-store,must-revalidate --content-type application/javascript --acl public-read + diff --git a/serverless.yml b/serverless.yml index 506a8e28c..19ffceaee 100644 --- a/serverless.yml +++ b/serverless.yml @@ -2,7 +2,7 @@ service: hackingstudio-code4maus provider: name: aws - runtime: nodejs12.x + runtime: nodejs18.x region: eu-central-1 role: 'arn:aws:iam::#{AWS::AccountId}:role/hackingstudio/code4maus/hackingstudio-code4maus-functions' stage: ${file(scripts/env.js):stage} diff --git a/src/components/edu-stage/edu-stage.jsx b/src/components/edu-stage/edu-stage.jsx index f1e4b97df..40a599705 100644 --- a/src/components/edu-stage/edu-stage.jsx +++ b/src/components/edu-stage/edu-stage.jsx @@ -17,6 +17,7 @@ import { eduUrl } from '../../lib/routing' import { gamesKeyed } from '../../lib/edu/' import VideoPlayer from '../video-player/video-player.jsx' import styles from './edu-stage.css' +import { guiTypePages, paEvent } from '../../lib/piano-analytics/main' const EduStageComponent = (props) => { const [isPreVideoModalOpen, setPreVideoModalOpen] = useState(false) @@ -58,7 +59,10 @@ const EduStageComponent = (props) => {
{props.caption}
@@ -97,7 +104,10 @@ const EduStageComponent = (props) => { arrowRight style="primary" wiggle={props.slideIndex === 0 && !props.finished} - onClick={props.nextSlide} + onClick={() => { + sendPaEvent(props, 'Weiter') + return props.nextSlide() + }} disabled={props.finished} > {!props.linkNextGame ? 'Weiter' : 'Nächstes Lernspiel'} @@ -108,6 +118,24 @@ const EduStageComponent = (props) => { ) } +const sendPaEvent = (props, clickName) => { + const pages = guiTypePages(props.gameId) + pages.push('Code') + + let target = `${props.slideIndex}/${props.slideCount}` + if (clickName == 'Weiter') { + target = !props.linkNextGame ? `${props.slideIndex + 2}/${props.slideCount}` : 'Nächstes Lernspiel' + } + + paEvent.clickAction({ + pages, + pageType: 'Spiele', + chapter1: 'Tutorial', + chapter2: clickName, + target + }) +} + EduStageComponent.propTypes = { caption: PropTypes.string, imageSrc: PropTypes.string, diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index e8ac7ae6d..2b99ae6e1 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -34,6 +34,7 @@ import costumesIcon from './icon--costumes.svg' import expandIcon from './expand_right@2x.svg' import styles from './gui.css' +import { buildGuiPage, paEvent } from '../../lib/piano-analytics/main.js' // Cache this value to only retreive it once the first time. // Assume that it doesn't change for a session. @@ -67,6 +68,7 @@ const GUIComponent = (props) => { closeSaveModal, saveProjectError, isSaving, + isNewProject, projectName, eduLayerActive, eduId, @@ -102,6 +104,17 @@ const GUIComponent = (props) => { isRendererSupported = Renderer.isSupported() } + const logClickEvent = (eventFn, eventName) => { + paEvent.clickAction({ + pages: buildGuiPage(props.eduId, props.isNewProject, props.activeTabIndex), + pageType: 'Spiele', + chapter1: 'Speichern', + chapter2: eventName, + target: eventName + }) + eventFn() + } + return (
{loading ? : null} @@ -125,7 +138,7 @@ const GUIComponent = (props) => {

{saveProjectError}

@@ -162,7 +175,7 @@ const GUIComponent = (props) => {
- +
diff --git a/src/components/menu/menu.jsx b/src/components/menu/menu.jsx index 6aaf13f27..8f19e1991 100644 --- a/src/components/menu/menu.jsx +++ b/src/components/menu/menu.jsx @@ -25,6 +25,16 @@ import buttonIconInfo from '!raw-loader!../../../assets/icons/menu_eltern-info.s import buttonIconMausseite from '!raw-loader!../../../assets/icons/menu_mausseite.svg' import buttonIconDatenschutz from '!raw-loader!../../../assets/icons/icon_hilfe.svg' import buttonIconImpressum from '!raw-loader!../../../assets/icons/menu_impressum.svg' +import { paEvent } from '../../lib/piano-analytics/main.js' +import { menuTabTitles } from '../../lib/piano-analytics/constants.js' + +// TODO: Use when updating react-intl (must use static values for now) +// const tabListData = { +// 0: { title: "Lernen", id: "gui.gui.eduGames", svg: tabIconEdugames }, +// 1: { title: "Meine Sachen", id: "gui.gui.games", svg: tabIconProjects }, +// 2: { title: "Beispiele", id: "gui.gui.examples", svg: tabIconExamples }, +// 3: { title: "Videos", id: "gui.gui.videos", svg: tabIconVideos }, +// } export const MenuComponent = (props) => { const tabClassNames = { @@ -39,6 +49,26 @@ export const MenuComponent = (props) => { tabSelected: classNames(tabStyles.reactTabsTabSelected, styles.isSelected), } + // TODO: Use when updating react-intl + // const menuTab = (index) => { + // const { title, id, svg } = tabListData[index] + + // return ( + // + //
+ // + // + //
+ //
+ // ) + // } + return (
@@ -72,7 +102,10 @@ export const MenuComponent = (props) => { selectedTabClassName={tabClassNames.tabSelected} selectedTabPanelClassName={tabClassNames.tabPanelSelected} selectedIndex={props.selectedTab} - onSelect={props.handleTabSelected} + onSelect={(index) => { + paEvent.pageDisplay({ pages: ["Menu", menuTabTitles[index]], pageType: "Hauptseite" }) + return props.handleTabSelected(index) + }} > @@ -152,6 +185,15 @@ export const MenuComponent = (props) => { iconSvg={buttonIconMausseite} external linkTo="https://www.wdrmaus.de/" + onClick={() => { + paEvent.clickExit({ + pages: ['Menu', menuTabTitles[props.selectedTab]], + pageType: 'Hauptseite', + chapter1: 'Exit', + chapter2: 'Zur Maus-Seite', + target: "https://www.wdrmaus.de/" + }) + }} > Zur Maus-Seite diff --git a/src/components/stage-header/stage-header.jsx b/src/components/stage-header/stage-header.jsx index 7770a157a..d9aa64668 100644 --- a/src/components/stage-header/stage-header.jsx +++ b/src/components/stage-header/stage-header.jsx @@ -7,6 +7,7 @@ import { Link } from 'redux-little-router' import Controls from '../../containers/controls.jsx' import Fullscreen from '../../containers/fullscreen.jsx' import MenuButton from '../menu-button/menu-button.jsx' +import { guiTypePages, paEvent } from '../../lib/piano-analytics/main.js' import styles from './stage-header.css' import saveIcon from '!raw-loader!../../../assets/icons/header_save.svg' @@ -14,7 +15,7 @@ import menuIcon from '!raw-loader!../../../assets/icons/header_menu.svg' import mailIcon from '!raw-loader!../../../assets/icons/menu_impressum.svg' const StageHeaderComponent = function (props) { - const { isFullScreen, onSaveProject, vm } = props + const { isFullScreen, onSaveProject, vm, logPageInfo } = props return (
{isFullScreen ? ( @@ -75,6 +77,7 @@ const StageHeaderComponent = function (props) { StageHeaderComponent.propTypes = { intl: intlShape, isFullScreen: PropTypes.bool.isRequired, + gameId: PropTypes.string, onSaveProject: PropTypes.func.isRequired, vm: PropTypes.instanceOf(VM).isRequired, } diff --git a/src/components/video-button-modal/video-button-modal.jsx b/src/components/video-button-modal/video-button-modal.jsx index 043a1d257..af00d5cea 100644 --- a/src/components/video-button-modal/video-button-modal.jsx +++ b/src/components/video-button-modal/video-button-modal.jsx @@ -1,11 +1,13 @@ import PropTypes from 'prop-types' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import Modal from '../modal/modal.jsx' import VideoPlayer from '../video-player/video-player.jsx' import defaultImage from '../../../assets/img/meine_sachen.png' import styles from './video-button-modal.css' +import { paEvent } from '../../lib/piano-analytics/main.js' +import { menuTabTitles } from '../../lib/piano-analytics/constants.js' const VideoButtonModal = ({ title, image, note, video }) => { const [showModal, setShowModal] = useState(false) @@ -14,6 +16,15 @@ const VideoButtonModal = ({ title, image, note, video }) => { // Add the '(' back to the 2nd line for correct display secondline = secondline ? `(${secondline}` : '' + useEffect(() => { + if (!showModal) return + + paEvent.pageDisplay({ + pages: ["Menu", menuTabTitles[3], `Video ${note}`], + pageType: 'Video' + }) + }, [showModal]) + return ( <>
( -
- WDR +const WelcomeScreenComponent = () => { -
-
- + useEffect(() => { + paEvent.pageDisplay({ + pages: ['Willkommensseite'], + pageType: 'Onboarding' + }) + }, []) -

- Willkommen zu Programmieren mit der Maus! -

-

- Hier lernst du Schritt für Schritt Bildergeschichten und Spiele mit - der Maus zu programmieren. Viel Spaß! -

+ return ( +
+ WDR - -
- Spielst du zum ersten Mal? -
- Fang am besten mit unserem ersten Lernspiel an. +
+
+ + +

+ Willkommen zu Programmieren mit der Maus! +

+

+ Hier lernst du Schritt für Schritt Bildergeschichten und Spiele mit + der Maus zu programmieren. Viel Spaß! +

+ + +
+ Spielst du zum ersten Mal? +
+ Fang am besten mit unserem ersten Lernspiel an. +
+
- -
- - + + - -
- Kennst du dich schon aus? -
- Gehe direkt zur Übersicht und klicke dein nächstes Lernspiel an. - Gespeicherte Spiele findest du unter „Meine Sachen“. + +
+ Kennst du dich schon aus? +
+ Gehe direkt zur Übersicht und klicke dein nächstes Lernspiel an. + Gespeicherte Spiele findest du unter „Meine Sachen“. +
+
- -
- - + + +
-
-) + ) +} export default WelcomeScreenComponent diff --git a/src/containers/content.jsx b/src/containers/content.jsx index 9e7860740..ca06cf16b 100644 --- a/src/containers/content.jsx +++ b/src/containers/content.jsx @@ -14,6 +14,7 @@ import Privacy, { attributes as privacyAttributes, } from '../lib/content/privacy.md' import Terms, { attributes as termsAttributes } from '../lib/content/terms.md' +import { paEvent } from '../lib/piano-analytics/main.js' const contentMap = { eltern: { @@ -43,6 +44,13 @@ class Content extends React.Component { ) } + componentDidMount() { + paEvent.pageDisplay({ + pages: [this.props.page], + pageType: 'Beitrag' + }) + } + render() { if (!(this.props.page in contentMap)) { return this.wrapContent('Inhalt nicht gefunden.') diff --git a/src/containers/controls.jsx b/src/containers/controls.jsx index cfbdcd92c..9b23bcb13 100644 --- a/src/containers/controls.jsx +++ b/src/containers/controls.jsx @@ -4,6 +4,7 @@ import React from 'react' import VM from 'scratch-vm' import ControlsComponent from '../components/controls/controls.jsx' +import { paEvent } from '../lib/piano-analytics/main.js' class Controls extends React.Component { constructor(props) { @@ -35,20 +36,45 @@ class Controls extends React.Component { } handleGreenFlagClick(e) { e.preventDefault() + + if (this.props.onGreenFlagClick) { + this.props.onGreenFlagClick() + } if (e.shiftKey) { this.setState({ turbo: !this.state.turbo }) this.props.vm.setTurboMode(!this.state.turbo) } else { this.props.vm.greenFlag() } + + paEvent.clickAction({ + pages: this.props.logPageInfo, + pageType: 'Spiele', + chapter1: 'Code', + chapter2: 'Los', + target: 'Code ausführen' + }) } handleStopAllClick(e) { e.preventDefault() + + if (this.props.onStopAllClick) { + this.props.onStopAllClick() + } this.props.vm.stopAll() + + paEvent.clickAction({ + pages: this.props.logPageInfo, + pageType: 'Spiele', + chapter1: 'Code', + chapter2: 'Stopp', + target: 'Code stoppen' + }) } render() { const { vm, // eslint-disable-line no-unused-vars + logPageInfo, ...props } = this.props return ( @@ -65,6 +91,8 @@ class Controls extends React.Component { Controls.propTypes = { vm: PropTypes.instanceOf(VM), + onGreenFlagClick: PropTypes.func, + onStopAllClick: PropTypes.func } export default Controls diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx index ea4825ae6..e7cb730da 100644 --- a/src/containers/gui.jsx +++ b/src/containers/gui.jsx @@ -9,6 +9,7 @@ import { activateTab, BLOCKS_TAB_INDEX, COSTUMES_TAB_INDEX, + editorTabNames, SOUNDS_TAB_INDEX, } from '../reducers/editor-tab' @@ -22,6 +23,8 @@ import { StageSizeProviderHOC } from '../lib/stage-size-provider.jsx' import GUIComponent from '../components/gui/gui.jsx' import { toggleLayoutMode } from '../reducers/layout-mode' import { setProjectUnchanged } from '../reducers/project-changed' +import { buildGuiPage, paEvent } from '../lib/piano-analytics/main' +import { menuTabTitles } from '../lib/piano-analytics/constants' class GUI extends React.Component { constructor(props) { @@ -45,6 +48,14 @@ class GUI extends React.Component { } } componentDidUpdate(prevProps) { + if (this.props.isNewProject && prevProps.fetchingProject) { + logPageDisplay(null, this.props.isNewProject) + } + + if (this.props.eduId && this.props.eduId !== prevProps.eduId) { + logPageDisplay(this.props.eduId, false) + } + if ( prevProps.projectData !== this.props.projectData || // force clearing workspace after fetching @@ -140,19 +151,42 @@ const mapStateToProps = (state) => ({ saveProjectVisible: state.scratchGui.modals.saveProject, eduLayerActive: state.scratchGui.eduLayer.enabled, eduId: state.scratchGui.eduLayer.gameId, + isNewProject: state.router.result && !!state.router.result.newProject }) +const logPageDisplay = (eduId, isNewProject, tab) => { + const pages = buildGuiPage(eduId, isNewProject, tab) + + paEvent.pageDisplay({ pages: pages, pageType: "Spiele" }) +} + +const onTabActivating = (eduId, isNewProject, tab) => { + logPageDisplay(eduId, isNewProject, tab) + return activateTab(tab) +} + const mapDispatchToProps = (dispatch) => ({ closeSaveModal: () => dispatch(closeSaveProject()), onExtensionButtonClick: () => dispatch(openExtensionLibrary()), - onActivateTab: (tab) => dispatch(activateTab(tab)), + onActivateTab: (eduId, isNewProject, tab) => dispatch(onTabActivating(eduId, isNewProject, tab)), onActivateCostumesTab: () => dispatch(activateTab(COSTUMES_TAB_INDEX)), onActivateSoundsTab: () => dispatch(activateTab(SOUNDS_TAB_INDEX)), onLayoutModeClick: () => dispatch(toggleLayoutMode()), onSetUnchanged: () => dispatch(setProjectUnchanged()), }) -const ConnectedGUI = connect(mapStateToProps, mapDispatchToProps)(GUI) +const mergeProps = (stateProps, dispatchProps, ownProps) => { + return { + ...ownProps, + ...stateProps, + ...dispatchProps, + onActivateTab: (tab) => dispatchProps.onActivateTab(stateProps.eduId, stateProps.isNewProject, tab), + onActivateCostumesTab: () => dispatchProps.onActivateCostumesTab(), + onActivateSoundsTab: () => dispatchProps.onActivateSoundsTab(), + } +} + +const ConnectedGUI = connect(mapStateToProps, mapDispatchToProps, mergeProps)(GUI) // eslint-disable-next-line new-cap const WrappedGui = flow([ diff --git a/src/containers/menu.jsx b/src/containers/menu.jsx index defac7240..4d7fc7cd2 100644 --- a/src/containers/menu.jsx +++ b/src/containers/menu.jsx @@ -6,6 +6,7 @@ import { push } from 'redux-little-router' import { MenuComponent } from '../components/menu/menu.jsx' import { MenuTabs } from '../lib/routing' import { games, examples, videos } from '../lib/edu' +import { paEvent } from '../lib/piano-analytics/main.js' const tabIdToTab = { 0: MenuTabs.edugames, @@ -45,6 +46,8 @@ class Menu extends React.Component { projects: [], videos: videos.map(Menu.mapVideoData), } + + paEvent.pageDisplay({ pages: ['Menu'], pageType: 'Hauptseite' }) } componentDidMount() { diff --git a/src/containers/stage-header.jsx b/src/containers/stage-header.jsx index 34009300a..e7388baf8 100644 --- a/src/containers/stage-header.jsx +++ b/src/containers/stage-header.jsx @@ -39,6 +39,7 @@ StageHeader.propTypes = { const mapStateToProps = (state) => ({ isFullScreen: state.scratchGui.mode.isFullScreen, + gameId: state.scratchGui.eduLayer.gameId }) const mapDispatchToProps = (dispatch) => ({ diff --git a/src/entrypoints/index.jsx b/src/entrypoints/index.jsx index c23a93c81..8563c71e5 100644 --- a/src/entrypoints/index.jsx +++ b/src/entrypoints/index.jsx @@ -5,6 +5,9 @@ import ReactDOM from 'react-dom' import App from '../containers/app.jsx' import '../css/defaults.css' +import { paSetConfig } from '../lib/piano-analytics/main.js' + +paSetConfig() const appTarget = document.getElementById('__mausapp') diff --git a/src/lib/piano-analytics/constants.js b/src/lib/piano-analytics/constants.js new file mode 100644 index 000000000..ec5290836 --- /dev/null +++ b/src/lib/piano-analytics/constants.js @@ -0,0 +1,39 @@ +export const EVENTS = { + pageDisplay: 'page.display', + clickNavigation: 'click.navigation', + clickExit: 'click.exit', + clickAction: 'click.action', +} + +export const PROPERTIES = { + siteLevel2: 'site_level2', + brand: 'brand', + redaction: 'editorial_department', + platform: 'platform', + siteTitle: 'page_title', + pageLevel1: 'page_chapter1', + pageLevel2: 'page_chapter2', + pageLevel3: 'page_chapter3', + siteType: 'content_type', + publicationTimeAt: 'publication_time', // date + reactionUpdatedAt: 'last_editorial_update', // date + daysSincePublication: 'days_since_publication', // integer + clickLabel: 'click', + clickTarget: 'click_target', + clickChapter1: 'click_chapter1', + clickChapter2: 'click_chapter2', +} + +export const DEFAULT_PROPERTY_VALUES = { + [PROPERTIES.siteLevel2]: 'Programmieren mit der Maus', + [PROPERTIES.brand]: 'Die Maus', + [PROPERTIES.redaction]: 'PG Kinder und Familie', + [PROPERTIES.platform]: 'Web', +} + +export const menuTabTitles = { + 0: 'Lernen', + 1: 'Meine Sachen', + 2: 'Beispiele', + 3: 'Videos', +} diff --git a/src/lib/piano-analytics/main.js b/src/lib/piano-analytics/main.js new file mode 100644 index 000000000..092d8acbd --- /dev/null +++ b/src/lib/piano-analytics/main.js @@ -0,0 +1,135 @@ +import { pianoAnalytics } from 'piano-analytics-js' +import { + EVENTS, + PROPERTIES, + DEFAULT_PROPERTY_VALUES, + menuTabTitles, +} from './constants' +import { editorTabNames } from '../../reducers/editor-tab' + +pianoAnalytics.setConfigurations({ + site: 621455, + collectDomain: 'https://logs1414.xiti.com/', +}) + +export const paSetConfig = () => { + let configurations + + if (process.env.BRANCH === 'production') { + configurations = { + site: 632700, + collectDomain: 'https://ama.wdr.de/', + } + } else { + configurations = { + site: 621455, + collectDomain: 'https://logs1414.xiti.com/', + } + } + pianoAnalytics.setConfigurations(configurations) +} + +export const guiTypePages = (gameId) => { + if (!gameId) { + return [menuTabTitles[1], 'New Project'] + } + + if (gameId.match(/beispiel(0|0\d{1})?$/gm)) { + return [menuTabTitles[2], `Beispiel ${gameId}`] + } else { + return [menuTabTitles[0], `Lernspiel ${gameId}`] + } +} + +const pageLevelKeys = [ + PROPERTIES.pageLevel1, + PROPERTIES.pageLevel2, + PROPERTIES.pageLevel3, +] + +const sendEvent = (eventKey, data) => { + let properties = { ...DEFAULT_PROPERTY_VALUES } + + switch (typeof data) { + case 'string': + properties[PROPERTIES.pageLevel1] = data + break + + case 'object': + properties = { ...properties, ...data } + break + } + + return pianoAnalytics.sendEvent(eventKey, { + ...getCustomProperties(properties), + ...properties, + }) +} + +const getCustomProperties = (data) => { + const pageList = pageLevelKeys + .filter((key) => key in data) + .map((key) => data[key]) + + return { + page: [data[PROPERTIES.siteLevel2], ...pageList].join('_'), + ...(pageList.length && { [PROPERTIES.siteTitle]: pageList.slice(-1)[0] }), + } +} + +export const paEvent = { + pageDisplay: ({ pages, pageType }) => { + let data = {} + + if (typeof pages === 'string') { + data[PROPERTIES.pageLevel1] = pages + } else { + const pagesList = [...pages].slice(0, 3) + pagesList.forEach((page, index) => { + data[PROPERTIES[`pageLevel${index + 1}`]] = page + }) + } + + if (pageType) data[PROPERTIES.siteType] = pageType + return sendEvent(EVENTS.pageDisplay, data) + }, + clickAction: (params) => clickEvent(EVENTS.clickAction, params), + clickExit: (params) => clickEvent(EVENTS.clickExit, params), +} + +export const buildGuiPage = (eduId, isNewProject, activeTab) => { + let pages = [] + if (isNewProject) { + pages = [menuTabTitles[1], 'New Project'] + } else if (eduId && eduId.match(/beispiel(0|0\d{1})?$/gm)) { + pages = [menuTabTitles[2], `Beispiel ${eduId}`] + } else if (eduId) { + pages = [menuTabTitles[0], `Lernspiel ${eduId}`] + } + return [...pages, editorTabNames[activeTab || 0]] +} + +const clickEvent = ( + eventName, + { pages, pageType, chapter1, chapter2, target } +) => { + let data = {} + + const pagesList = [...pages].slice(0, 3) + pagesList.forEach((page, index) => { + data[PROPERTIES[`pageLevel${index + 1}`]] = page + }) + data[PROPERTIES.siteType] = pageType + + const clickProperties = { + [PROPERTIES.clickChapter1]: chapter1, + [PROPERTIES.clickChapter2]: chapter2, + [PROPERTIES.clickTarget]: target, + [PROPERTIES.clickLabel]: chapter2, + } + + return sendEvent(eventName, { + ...data, + ...clickProperties, + }) +} diff --git a/src/reducers/editor-tab.js b/src/reducers/editor-tab.js index 142ea11f1..b91e1878e 100644 --- a/src/reducers/editor-tab.js +++ b/src/reducers/editor-tab.js @@ -9,6 +9,12 @@ const initialState = { activeTabIndex: BLOCKS_TAB_INDEX, } +const editorTabNames = { + [BLOCKS_TAB_INDEX]: 'Code', + [COSTUMES_TAB_INDEX]: 'Kostüme', + [SOUNDS_TAB_INDEX]: 'Töne', +} + const reducer = function (state, action) { if (typeof state === 'undefined') { state = initialState @@ -37,4 +43,5 @@ export { BLOCKS_TAB_INDEX, COSTUMES_TAB_INDEX, SOUNDS_TAB_INDEX, + editorTabNames, } diff --git a/yarn.lock b/yarn.lock index dff317dea..f583b5212 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8645,7 +8645,7 @@ intl-format-cache@^2.0.5: intl-messageformat-parser@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075" - integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU= + integrity sha512-/XkqFHKezO6UcF4Av2/Lzfrez18R0jyw7kRFhSeB/YRakdrgSc9QfFZUwNJI9swMwMoNPygK1ArC5wdFSjPw+A== intl-messageformat-parser@^1.2.0: version "1.8.1" @@ -8655,7 +8655,7 @@ intl-messageformat-parser@^1.2.0: intl-messageformat@^2.0.0, intl-messageformat@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc" - integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw= + integrity sha512-I+tSvHnXqJYjDfNmY95tpFMj30yoakC6OXAo+wu/wTMy6tA/4Fd4mvV7Uzs4cqK/Ap29sHhwjcY+78a8eifcXw== dependencies: intl-messageformat-parser "1.4.0" @@ -12152,6 +12152,11 @@ pez@2.x.x: hoek "4.x.x" nigel "2.x.x" +piano-analytics-js@^6.8.3: + version "6.8.3" + resolved "https://registry.yarnpkg.com/piano-analytics-js/-/piano-analytics-js-6.8.3.tgz#f13bfaafdc0a58b7045cfb02be20a918cf3231a7" + integrity sha512-2NI77WkB1I31ZYdHe9brUhrCpEeDWqdlY/KmUKgvF6npbTiONzMGJOKui6eqKJkoo8f0Wuy1ucmpGM7wXYVdGw== + picomatch@^2.0.5: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"