diff --git a/README_TOONTJEHOGER.md b/README_TOONTJEHOGER.md index 8f643f480..8d162ee54 100644 --- a/README_TOONTJEHOGER.md +++ b/README_TOONTJEHOGER.md @@ -1,38 +1,4 @@ -# ToontjeHoger - -This repository contains the experiments for ToontjeHoger (2022), a website that shows music related research to a wider audience. - -## Homepage - -The ToontjeHoger homepage backend code can be found in: - -``` -backend/experiment/rules/toontjehoger_home.py -``` - -- To add/remove change experiments, update the contents of EXPERIMENT_DATA -- Note that the ToontjeHoger experiment slugs are hard coded here -- This file contains all textual content that is shown on the home/about page - -It uses a custom experiment view which contains both the home and about page: - -``` -backend/experiment/rules/views/toontjehoger.py -``` - -With corresponding frontend view: - -``` -frontend/src/components/ToontjeHoger/ToontjeHoger.js -``` - -Styling for the home and about page, as well as the general ToontjeHoger experiments styling (e.g. background image) can be found in: - -``` -frontend/src/components/ToontjeHoger/ToontjeHoger.scss -``` - -### Experiment config +### Experiment config of ToontjeHoger experiments Set the following experiment values in the admin: @@ -89,22 +55,6 @@ backend/templates/info/toontjehoger/experiment5.html backend/templates/info/toontjehoger/experiment6.html ``` -## Environment - -Use the following .env variables to configure your ToontjeHoger instance: - -``` -FRONTEND_EXPERIMENT_SLUG=toontjehoger -FRONTEND_AML_HOME=/toontjehoger -FRONTEND_LOGO_URL=/images/experiments/toontjehoger/logo-white.svg -FRONTEND_HTML_PAGE_TITLE=ToontjeHoger -FRONTEND_HTML_OG_DESCRIPTION=ToontjeHoger is een website met spelletjes die de luisteraar laat inzien dat zij muzikaler is dan je zou denken. -FRONTEND_HTML_OG_IMAGE=https://toontjehoger.changeme.example.com/images/og-hooked.jpg -FRONTEND_HTML_OG_TITLE=ToontjeHoger -FRONTEND_HTML_OG_URL=https://toontjehoger.changeme.example.com/ -FRONTEND_HTML_BODY_CLASS=toontjehoger -``` - ## Playlists Each experiment uses a playlist with additional information in the tag/group field. diff --git a/backend/experiment/actions/__init__.py b/backend/experiment/actions/__init__.py index 907198157..52cd741e0 100644 --- a/backend/experiment/actions/__init__.py +++ b/backend/experiment/actions/__init__.py @@ -9,5 +9,4 @@ from .playlist import Playlist from .redirect import Redirect from .score import Score -from .toontjehoger import ToontjeHoger from .trial import Trial diff --git a/backend/experiment/actions/tests/test_action_utils.py b/backend/experiment/actions/tests/test_action_utils.py index 60b111361..18d84c89d 100644 --- a/backend/experiment/actions/tests/test_action_utils.py +++ b/backend/experiment/actions/tests/test_action_utils.py @@ -1,10 +1,28 @@ from django.test import TestCase -from experiment.actions.utils import randomize_playhead +from experiment.actions.utils import COLLECTION_KEY, get_current_collection_url, randomize_playhead +from experiment.models import Block +from participant.models import Participant +from section.models import Playlist +from session.models import Session class TestActions(TestCase): + def setUp(self) -> None: + self.playlist = Playlist.objects.create(name='TestPlaylist') + self.participant = Participant.objects.create() + self.block = Block.objects.create(name='TestBlock') + self.session = Session.objects.create( + block=self.block, participant=self.participant, playlist=self.playlist) + + def test_collection_url(self): + self.assertEqual(get_current_collection_url(self.session), None) + self.session.save_json_data({COLLECTION_KEY: 'superdupercollection'}) + self.assertEqual(get_current_collection_url(self.session), '/collection/superdupercollection') + self.participant.participant_id_url = 'participant42' + self.assertEqual(get_current_collection_url(self.session), '/collection/superdupercollection?participant_id=participant42') + def test_randomize_playhead(self): min_jitter = 5 max_jitter = 10 diff --git a/backend/experiment/actions/toontjehoger.py b/backend/experiment/actions/toontjehoger.py deleted file mode 100644 index 9e733a0d9..000000000 --- a/backend/experiment/actions/toontjehoger.py +++ /dev/null @@ -1,27 +0,0 @@ -from .base_action import BaseAction - - -class ToontjeHoger(BaseAction): # pylint: disable=too-few-public-methods - """ - Provide data for a view that shows the ToontjeHoger homepage - - Relates to client component: ToontjeHoger.js - """ - - ID = "TOONTJEHOGER" - - def __init__(self, config, blocks=[]): - """ - ToontjeHoger shows the ToontjeHoger homepage - - config: Object containing texts and other configuration - - payoff - - intro - - main_button_label - - main_button_url - - score_label - - supporters_intro - blocks: A list of ExperimentData objects - """ - self.config = config - self.blocks = [vars(i) for i in self.blocks] diff --git a/backend/experiment/actions/utils.py b/backend/experiment/actions/utils.py index 5a82c6921..652b50272 100644 --- a/backend/experiment/actions/utils.py +++ b/backend/experiment/actions/utils.py @@ -6,23 +6,30 @@ from django.template.loader import render_to_string from experiment.actions import Final +from session.models import Session COLLECTION_KEY = 'experiment_collection' -def final_action_with_optional_button(session, final_text='', title=_('End'), button_text=_('Continue')): - """ given a session, a score message and an optional session dictionary from an experiment collection, - return a Final.action, which has a button to continue to the next block if series is defined - """ +def get_current_collection_url(session: Session) -> str: collection_slug = session.load_json_data().get(COLLECTION_KEY) + if not collection_slug: + return None if session.participant.participant_id_url: participant_id_url = session.participant.participant_id_url - redirect_url = f'/collection/{collection_slug}?participant_id_url={participant_id_url}' + return f'/collection/{collection_slug}?participant_id={participant_id_url}' else: - redirect_url = f'/collection/{collection_slug}' + return f'/collection/{collection_slug}' + + +def final_action_with_optional_button(session, final_text='', title=_('End'), button_text=_('Continue')): + """ given a session, a score message and an optional session dictionary from an experiment collection, + return a Final.action, which has a button to continue to the next block if series is defined + """ + redirect_url = get_current_collection_url(session) - if collection_slug: + if redirect_url: return Final( title=title, session=session, diff --git a/backend/experiment/rules/__init__.py b/backend/experiment/rules/__init__.py index cf1e72c60..b53df3ac1 100644 --- a/backend/experiment/rules/__init__.py +++ b/backend/experiment/rules/__init__.py @@ -35,7 +35,6 @@ from .toontjehogerkids_4_absolute import ToontjeHogerKids4Absolute from .toontjehogerkids_5_tempo import ToontjeHogerKids5Tempo from .toontjehogerkids_6_relative import ToontjeHogerKids6Relative -from .toontjehoger_home import ToontjeHogerHome from .visual_matching_pairs import VisualMatchingPairsGame # Rules available to this application @@ -74,7 +73,6 @@ ToontjeHoger4Absolute.ID: ToontjeHoger4Absolute, ToontjeHoger5Tempo.ID: ToontjeHoger5Tempo, ToontjeHoger6Relative.ID: ToontjeHoger6Relative, - ToontjeHogerHome.ID: ToontjeHogerHome, ToontjeHogerKids1Mozart.ID: ToontjeHogerKids1Mozart, ToontjeHogerKids2Preverbal.ID: ToontjeHogerKids2Preverbal, ToontjeHogerKids3Plink.ID: ToontjeHogerKids3Plink, diff --git a/backend/experiment/rules/toontjehoger_1_mozart.py b/backend/experiment/rules/toontjehoger_1_mozart.py index e7117f113..33afe115a 100644 --- a/backend/experiment/rules/toontjehoger_1_mozart.py +++ b/backend/experiment/rules/toontjehoger_1_mozart.py @@ -8,6 +8,7 @@ from experiment.actions.styles import STYLE_TOONTJEHOGER from .base import Base from experiment.utils import non_breaking_spaces +from experiment.actions.utils import get_current_collection_url from result.utils import prepare_result @@ -232,7 +233,7 @@ def get_final_round(self, session): body=body, heading="Het Mozart effect", button_label="Terug naar ToontjeHoger", - button_link="/collection/toontjehoger" + button_link=get_current_collection_url(session) ) return [*answer_explainer, *score, final, info] diff --git a/backend/experiment/rules/toontjehoger_2_preverbal.py b/backend/experiment/rules/toontjehoger_2_preverbal.py index 82cb4d18a..ece306921 100644 --- a/backend/experiment/rules/toontjehoger_2_preverbal.py +++ b/backend/experiment/rules/toontjehoger_2_preverbal.py @@ -9,6 +9,7 @@ from experiment.actions.playback import ImagePlayer from experiment.actions.styles import STYLE_NEUTRAL_INVERTED from experiment.actions.frontend_style import FrontendStyle, EFrontendStyle +from experiment.actions.utils import get_current_collection_url from experiment.utils import create_player_labels from .base import Base from result.utils import prepare_result @@ -290,7 +291,7 @@ def get_final_round(self, session): body=body, heading="Het eerste luisteren", button_label="Terug naar ToontjeHoger", - button_link="/collection/toontjehoger" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehoger_3_plink.py b/backend/experiment/rules/toontjehoger_3_plink.py index 0373c5880..5d2df7570 100644 --- a/backend/experiment/rules/toontjehoger_3_plink.py +++ b/backend/experiment/rules/toontjehoger_3_plink.py @@ -8,6 +8,7 @@ from experiment.actions import Explainer, Step, Score, Final, Playlist, Info, Trial from experiment.actions.playback import PlayButton from experiment.actions.form import AutoCompleteQuestion, RadiosQuestion, Form +from experiment.actions.utils import get_current_collection_url from .base import Base from experiment.utils import non_breaking_spaces from result.utils import prepare_result @@ -311,7 +312,7 @@ def get_final_round(self, session): body=body, heading="Muziekherkenning", button_label="Terug naar ToontjeHoger", - button_link="/collection/toontjehoger" + button_link=get_current_collection_url(session) ) return [score, final, info] diff --git a/backend/experiment/rules/toontjehoger_4_absolute.py b/backend/experiment/rules/toontjehoger_4_absolute.py index fc9689341..d5d3736cb 100644 --- a/backend/experiment/rules/toontjehoger_4_absolute.py +++ b/backend/experiment/rules/toontjehoger_4_absolute.py @@ -11,6 +11,7 @@ from experiment.actions.frontend_style import FrontendStyle, EFrontendStyle from experiment.actions.playback import Multiplayer from experiment.actions.styles import STYLE_NEUTRAL_INVERTED +from experiment.actions.utils import get_current_collection_url from experiment.utils import create_player_labels from .base import Base from result.utils import prepare_result @@ -182,7 +183,7 @@ def get_final_round(self, session): body=body, heading="Absoluut gehoor", button_label="Terug naar ToontjeHoger", - button_link="/collection/toontjehoger" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehoger_5_tempo.py b/backend/experiment/rules/toontjehoger_5_tempo.py index 89bbe7438..d22b7779d 100644 --- a/backend/experiment/rules/toontjehoger_5_tempo.py +++ b/backend/experiment/rules/toontjehoger_5_tempo.py @@ -9,6 +9,7 @@ from experiment.actions.frontend_style import FrontendStyle, EFrontendStyle from experiment.actions.playback import Multiplayer from experiment.actions.styles import STYLE_NEUTRAL_INVERTED +from experiment.actions.utils import get_current_collection_url from section.models import Playlist from .base import Base from experiment.utils import create_player_labels, non_breaking_spaces @@ -251,7 +252,7 @@ def get_final_round(self, session): body=body, heading="Timing en tempo", button_label="Terug naar ToontjeHoger", - button_link="/collection/toontjehoger" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehoger_6_relative.py b/backend/experiment/rules/toontjehoger_6_relative.py index f4b734e94..d49c52d4e 100644 --- a/backend/experiment/rules/toontjehoger_6_relative.py +++ b/backend/experiment/rules/toontjehoger_6_relative.py @@ -7,6 +7,7 @@ from experiment.actions.playback import Multiplayer from experiment.actions.frontend_style import FrontendStyle, EFrontendStyle from experiment.actions.styles import STYLE_BOOLEAN +from experiment.actions.utils import get_current_collection_url from section.models import Playlist from .base import Base from .toontjehoger_1_mozart import toontjehoger_ranks @@ -180,7 +181,7 @@ def get_final_round(self, session): body=body, heading="Relatief gehoor", button_label="Terug naar ToontjeHoger", - button_link="/collection/toontjehoger" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehoger_home.py b/backend/experiment/rules/toontjehoger_home.py deleted file mode 100644 index c655b8d40..000000000 --- a/backend/experiment/rules/toontjehoger_home.py +++ /dev/null @@ -1,167 +0,0 @@ -import logging -import random -from experiment.actions import ToontjeHoger -from .base import Base -from experiment.utils import external_url - -logger = logging.getLogger(__name__) - - -class ExperimentData: - # Colors - # $teal: #39d7b8; - # $yellow: #ffb14c; - # $pink: #d843e2; - # $red: #fa5577; - # $blue: #0cc7f1; - # $green: #00b612; - # $indigo: #2b2bee; - # $gray: #bdbebf; - # $gray-900: #212529; - - def __init__(self, slug, title, description, image, color): - self.slug = slug - self.title = title - self.description = description - self.image = image - self.color = color - - -class ToontjeHogerHome(Base): - ID = 'TOONTJE_HOGER_HOME' - TITLE = "" - - EXPERIMENT_DATA = [ - ExperimentData(slug='toontjehoger_1_mozart', - title="Het Mozart effect", - description="Helpt muziek jou met het oplossen van een korte puzzel?", - image="/images/experiments/toontjehoger/experiment_1.webp", - color="#ffb14c" - ), - ExperimentData(slug='toontjehoger_3_plink', - title="Muziekherkenning", - description="Ken je dit korte muziekfragment? Noem de titel en artiest.", - image="/images/experiments/toontjehoger/experiment_3.webp", - color="#fa5577" - ), - ExperimentData(slug='toontjehoger_6_relative', - title="Relatief gehoor", - description="Wanneer zijn twee getransponeerde melodieën hetzelfde?", - image="/images/experiments/toontjehoger/experiment_6.webp", - color="#39d7b8" - ), - ExperimentData(slug='toontjehoger_2_preverbal', - title="Het eerste luisteren", - description="Huilen Franse en Duitse baby's hetzelfde?", - image="/images/experiments/toontjehoger/experiment_2.webp", - color="#d843e2" - ), - ExperimentData(slug='toontjehoger_4_absolute', - title="Absoluut gehoor", - description="Welke versie van de televisieprogramma-intro heeft de juiste toonhoogte?", - image="/images/experiments/toontjehoger/experiment_4.webp", - color="#0cc7f1" - ), - ExperimentData(slug='toontjehoger_5_tempo', - title="Timing en tempo", - description="Kan jij aan de timing van de musicus horen welk fragment het origineel is?", - image="/images/experiments/toontjehoger/experiment_5.webp", - color="#2b2bee" - ), - ] - - def first_round(self, block): - """Create data for the first block round""" - - # Session history - sessions = self.get_sessions(participant) # To be fixed in the future - next_block_slug = self.get_next_block_slug(sessions) - - # Score - score = self.get_score(sessions) - score_label = "punten" if len(sessions) > 0 and score > 0 else "Nog geen punten!" - score_class = "" - if score < 100: - score_class = "plastic" - elif score < 200: - score_class = "bronze" - elif score < 300: - score_class = "silver" - elif score < 600: - score_class = "gold" - elif score < 1000: - score_class = "platinum" - else: - score_class = "diamond" - - # Main button shows - # - 'next experiment' when user does not have completed all blocks yet - # - 'random experiment' when user has completed all blocks - main_button_label = "Volgende experiment" if next_block_slug else "Willekeurig experiment" - main_button_url = "/{}".format(next_block_slug) if next_block_slug else random.choice([ - experiment.slug for experiment in self.EXPERIMENT_DATA]) - - # Home - home = ToontjeHoger( - config={ - # Home - 'payoff': "Je bent muzikaler dan je denkt!", - 'intro': "Hoe snel herken jij een liedje? Heb je gevoel voor ritme en timing? Hoe goed is jouw absoluut gehoor? Doe de minigames op ToontjeHoger en ontdek meer over je eigen muzikaliteit én wat de wetenschap daarover weet.", - 'intro_read_more': "Over ons", - 'main_button_label': main_button_label, - 'main_button_url': main_button_url, - 'score_label': score_label, - 'score': int(score), - 'score_class': score_class, - 'share_label': "Deel je score!", - 'share_message': "Ha! Ik ben muzikaler dan ik dacht - heb maar liefst {:d} punten! Speel mee met #ToontjeHoger".format(int(score)) if score > 0 else "Ha! Speel mee met #ToontjeHoger en laat je verrassen: je bent muzikaler dat je denkt!", - 'supporters_intro': "ToontjeHoger werd gemaakt door leden van muziekcognitiegroep ({}) en werd gesteund door {} en de Faculteit Geesteswetenschappen van de Universiteit van Amsterdam.".format(external_url("MCG", "https://www.mcg.uva.nl/"), external_url("KNAW Gewaardeerd!", "https://verrijkinggewaardeerd.nl/")), - # About - 'about_title': "De ToontjeHoger website heeft als doel te laten zien dat luisteraars muzikaler zijn dan ze zelf denken én wat de wetenschap daar inmiddels over weet.", - 'about_intro': "Wil je ontdekken hoe het zit met je absoluut en relatief gehoor, je gevoel voor ritme en timing en je geheugen voor muziek? Dan zijn de ToontjeHoger mini-games vast iets voor jou!", - 'about_description': "Muziek speelt op een intrigerende manier met ons gehoor, ons geheugen, onze emoties en onze verwachtingen. Maar als luisteraar zijn we ons vaak niet bewust dat we zelf een actieve rol hebben in wat muziek zo spannend, troostend of opwindend maakt. De wetenschap heeft ontdekt dat dat luisteren zich niet afspeelt in de buitenwereld van de klinkende muziek, maar in de binnenwereld van ons hoofd en onze hersenen. Kortom: iedereen is muzikaal!", - 'about_streamer': "Luisteraars zijn vaak muzikaler dan ze zelf denken!", - 'about_more_title': "Meer weten?", - 'about_more_description': "Bezoek {}, {} of onze blog {}. Of lees meer over muziekcognitie in het publieksboek {}.".format(external_url("AML", "https://www.amsterdammusiclab.nl"), external_url("MCG", "https://www.mcg.uva.nl/"), external_url("Music Matters", "https://musiccognition.blogspot.com/"), external_url("Iedereen is muzikaal", "https://henkjanhoning.nl/x/iedereen-is-muzikaal.html")), - 'about_colofon_title': "Colofon", - 'about_colofon_description': "Organisatie:Zwanet Young, Henkjan HoningCuratoren:Mariëlle Baelemans, Fleur Bouwer, Ashley Burgoyne, Atser Damsma en Henkjan HoningAdvies:Makiko Sadakata, Berit Janssen, en de leden van MCGRealisatie:Werner Helmich ({}), Berit Janssen (MUSCLE team)Foto:Bob Bronshoff".format(external_url("SUDOX", "https://www.sudox.nl?utm_source=toontjehoger")), - 'portrait_description': "Het ToontjeHoger team (v.l.n.r.): Atser Damsma, Henkjan Honing, Zwanet Young, Mariëlle Baelemans, Fleur Bouwer, Ashley Burgoyne, Berit Janssen* en Makiko Sadakata*. (foto: Bob Bronshoff)
*Niet op de foto", - 'privacy_description': "Deze website verwerkt uitsluitend geanomiseerde gegevens. Voor aanvullende informatie zie {}.".format(external_url("UvA Privacy Statement", "https://www.uva.nl/home/disclaimers/privacy.html")) - }, - experiments=self.EXPERIMENT_DATA - ) - - return [ - home, - ] - - def get_score(self, sessions): - score = 0 - for session in sessions: - score += session.final_score - return score - - def get_sessions(self, participant): - from session.models import Session - from experiment.models import Block - - block_slugs = [ - block.slug for block in self.EXPERIMENT_DATA] - - block_ids = Block.objects.filter(slug__in=block_slugs) - - sessions = Session.objects.filter(participant=participant, - block_id__in=block_ids) - return sessions - - def get_next_block_slug(self, sessions): - block_slugs = [ - block.slug for block in self.EXPERIMENT_DATA] - for session in sessions: - if session.block.slug in block_slugs: - block_slugs.remove(session.block.slug) - - if len(block_slugs) > 0: - return block_slugs[0] - - return '' diff --git a/backend/experiment/rules/toontjehogerkids_1_mozart.py b/backend/experiment/rules/toontjehogerkids_1_mozart.py index 0131bbd62..5fe0e5bd7 100644 --- a/backend/experiment/rules/toontjehogerkids_1_mozart.py +++ b/backend/experiment/rules/toontjehogerkids_1_mozart.py @@ -2,6 +2,7 @@ from django.template.loader import render_to_string from os.path import join from experiment.actions import Explainer, Step, Final, Info +from experiment.actions.utils import get_current_collection_url from .toontjehoger_1_mozart import toontjehoger_ranks, ToontjeHoger1Mozart logger = logging.getLogger(__name__) @@ -71,7 +72,7 @@ def get_final_round(self, session): body=body, heading="Het Mozart effect", button_label="Terug naar ToontjeHogerKids", - button_link="/collection/thkids" + button_link=get_current_collection_url(session) ) return [*answer_explainer, *score, final, info] diff --git a/backend/experiment/rules/toontjehogerkids_2_preverbal.py b/backend/experiment/rules/toontjehogerkids_2_preverbal.py index 044fe0b5a..f5bf49440 100644 --- a/backend/experiment/rules/toontjehogerkids_2_preverbal.py +++ b/backend/experiment/rules/toontjehogerkids_2_preverbal.py @@ -3,6 +3,7 @@ from .toontjehoger_1_mozart import toontjehoger_ranks from experiment.actions import Explainer, Step, Score, Final, Info +from experiment.actions.utils import get_current_collection_url from .toontjehoger_2_preverbal import ToontjeHoger2Preverbal from os.path import join @@ -113,7 +114,7 @@ def get_final_round(self, session): body=body, heading="Het eerste luisteren", button_label="Terug naar ToontjeHogerKids", - button_link="/collection/thkids" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehogerkids_3_plink.py b/backend/experiment/rules/toontjehogerkids_3_plink.py index 655ada16b..c9125b14a 100644 --- a/backend/experiment/rules/toontjehogerkids_3_plink.py +++ b/backend/experiment/rules/toontjehogerkids_3_plink.py @@ -6,6 +6,7 @@ from experiment.actions import Explainer, Step, Score, Final, Info, Trial from experiment.actions.playback import PlayButton from experiment.actions.form import AutoCompleteQuestion, Form +from experiment.actions.utils import get_current_collection_url from .toontjehoger_3_plink import ToontjeHoger3Plink from experiment.utils import non_breaking_spaces @@ -153,7 +154,7 @@ def get_final_round(self, session): body=body, heading="Muziekherkenning", button_label="Terug naar ToontjeHogerKids", - button_link="/collection/thkids" + button_link=get_current_collection_url(session) ) return [score, final, info] diff --git a/backend/experiment/rules/toontjehogerkids_4_absolute.py b/backend/experiment/rules/toontjehogerkids_4_absolute.py index ae1df8d5f..9265a4c2c 100644 --- a/backend/experiment/rules/toontjehogerkids_4_absolute.py +++ b/backend/experiment/rules/toontjehogerkids_4_absolute.py @@ -2,6 +2,7 @@ from django.template.loader import render_to_string from .toontjehoger_1_mozart import toontjehoger_ranks from experiment.actions import Explainer, Step, Final, Info +from experiment.actions.utils import get_current_collection_url from .toontjehoger_4_absolute import ToontjeHoger4Absolute @@ -66,7 +67,7 @@ def get_final_round(self, session): body=body, heading="Absoluut gehoor", button_label="Terug naar ToontjeHogerKids", - button_link="/collection/thkids" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehogerkids_5_tempo.py b/backend/experiment/rules/toontjehogerkids_5_tempo.py index 090ad71a5..63e6175f9 100644 --- a/backend/experiment/rules/toontjehogerkids_5_tempo.py +++ b/backend/experiment/rules/toontjehogerkids_5_tempo.py @@ -5,7 +5,7 @@ from .toontjehoger_1_mozart import toontjehoger_ranks from .toontjehoger_5_tempo import ToontjeHoger5Tempo from experiment.actions import Explainer, Step, Score, Final, Info -from experiment.utils import non_breaking_spaces +from experiment.actions.utils import get_current_collection_url logger = logging.getLogger(__name__) @@ -126,7 +126,7 @@ def get_final_round(self, session): body=body, heading="Timing en tempo", button_label="Terug naar ToontjeHogerKids", - button_link="/collection/thkids" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/backend/experiment/rules/toontjehogerkids_6_relative.py b/backend/experiment/rules/toontjehogerkids_6_relative.py index 35a1e0d8a..a656d61c7 100644 --- a/backend/experiment/rules/toontjehogerkids_6_relative.py +++ b/backend/experiment/rules/toontjehogerkids_6_relative.py @@ -4,6 +4,7 @@ from .toontjehoger_1_mozart import toontjehoger_ranks from .toontjehoger_6_relative import ToontjeHoger6Relative from experiment.actions import Explainer, Step, Score, Final, Info +from experiment.actions.utils import get_current_collection_url logger = logging.getLogger(__name__) @@ -82,7 +83,7 @@ def get_final_round(self, session): body=body, heading="Relatief gehoor", button_label="Terug naar ToontjeHogerKids", - button_link="/collection/thkids" + button_link=get_current_collection_url(session) ) return [*score, final, info] diff --git a/frontend/src/components/Block/Block.jsx b/frontend/src/components/Block/Block.jsx index 0e61109a1..514ca5ff9 100644 --- a/frontend/src/components/Block/Block.jsx +++ b/frontend/src/components/Block/Block.jsx @@ -7,7 +7,6 @@ import useBoundStore from "@/util/stores"; import { createSession, getNextRound, useBlock } from "@/API"; import Consent from "@/components/Consent/Consent"; import DefaultPage from "@/components/Page/DefaultPage"; -import ToontjeHoger from "@/components/ToontjeHoger/ToontjeHoger"; import Explainer from "@/components/Explainer/Explainer"; import Final from "@/components/Final/Final"; import Loading from "@/components/Loading/Loading"; @@ -206,11 +205,6 @@ const Block = ({ match }) => { case "REDIRECT": return window.location.replace(state.url); - // Specials - // ------------------------- - case "TOONTJEHOGER": - return ; - default: return (
diff --git a/frontend/src/components/ExperimentCollection/ExperimentCollection.scss b/frontend/src/components/ExperimentCollection/ExperimentCollection.scss index efd4894d5..e4e15f7d4 100644 --- a/frontend/src/components/ExperimentCollection/ExperimentCollection.scss +++ b/frontend/src/components/ExperimentCollection/ExperimentCollection.scss @@ -252,7 +252,7 @@ } } } - + } } } @@ -385,31 +385,3 @@ } } } - -// Global styling tweaks -// ========================= - -.aha__experiment.experiment-toontjehoger { - // Hide app bar - .aha__app-bar { - display: none; - } - // Fix page width - @media (min-width: 800px) { - .aha__page .container { - max-width: calc(100% - 50px) !important; - padding-top: 0; - } - } -} - -body.toontjehoger .aha__experiment:not(.experiment-toontjehoger) .aha__toontjehoger { - display: none; -} - -body.toontjehoger, -body.toontjehoger .aha__page { - background-image: url("/public/images/background-blur.webp"); - background-color: #202e30; - background-position: top center; -} diff --git a/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx b/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx deleted file mode 100644 index 673fd2ab6..000000000 --- a/frontend/src/components/ToontjeHoger/ToontjeHoger.jsx +++ /dev/null @@ -1,323 +0,0 @@ -import React, { useEffect, useState, useRef } from "react"; -import { LOGO_TITLE } from "@/config"; -import { Switch, Route, Link } from "react-router-dom"; -import Cup from "../Cup/Cup"; - -const LOGO_URL = "/images/experiments/toontjehoger/logo.svg"; - -const Logo = ({ homeUrl }) => ( - - {LOGO_TITLE} - -); - -const Share = ({ score, label, message }) => { - const getLink = (url) => - url - .replace("%URL%", encodeURIComponent(window.location)) - .replace( - "%TEXT%", - encodeURIComponent( - message.replace("%SCORE%", score).replace("%URL%", window.location) - ) - ); - - return ( -
-
{label}
-
- - twitter - - - facebook - - - Whatsapp - -
-
- ); -}; - -const Supporters = ({ intro }) => ( -
-

-

- - KNAW - - - UvA - - - Music Cognition Group - - - Amsterdam Music Lab - -
-
-); - -const useAnimatedScore = (targetScore) => { - const [score, setScore] = useState(0); - - const scoreValue = useRef(0); - - useEffect(() => { - if (targetScore === 0) { - return; - } - - let id = -1; - - const nextStep = () => { - // Score step - const scoreStep = Math.max( - 1, - Math.min(10, Math.ceil(Math.abs(scoreValue.current - targetScore) / 10)) - ); - - // Scores are equal, stop - if (targetScore === scoreValue.current) { - return; - } - - // Add / subtract score - scoreValue.current += Math.sign(targetScore - scoreValue.current) * scoreStep; - setScore(scoreValue.current); - - id = setTimeout(nextStep, 50); - }; - id = setTimeout(nextStep, 50); - - return () => { - window.clearTimeout(id); - }; - }, [targetScore]); - - return score; -}; - -const Score = ({ score, label, scoreClass }) => { - const currentScore = useAnimatedScore(score); - - return ( -
- -

- {currentScore ? currentScore + " " : ""} - {label} -

-
- ); -}; - -const Privacy = ({ description }) => ( -
-

-

-); - -/** ToontjeHoger is an block view that shows the ToontjeHoger home */ -const ToontjeHogerHome = ({ block, config, experiments }) => { - return ( -
- - - {/* Hero */} -
-
-

{config.payoff}

-

{config.intro}

-
- {config.main_button_label && ( - - {config.main_button_label} - - )} - {config.intro_read_more && ( - - {config.intro_read_more} - - )} -
-
- -
- - - -
-
- - {/* Blocks */} -
-
    - {experiments.map((experiment) => ( -
  • - -
    -

    {experiment.title}

    -

    {experiment.description}

    - -
  • - ))} -
-
- - {/* Supporters */} - - - {/* Privacy */} - -
- ); -}; - -/** ToontjeHoger is an block view that shows the ToontjeHoger home */ -const ToontjeHogerAbout = ({ block, config }) => { - return ( -
- - {/* Project */} -
-

{config.intro_read_more}

-
{config.about_title}
-

{config.about_intro}

-

-

- {/* Streamer */} -
-

- {config.about_streamer} -

-
- - {/* More */} -
-

{config.about_more_title}

-

-

- - {/* Colofon */} -
-

{config.about_colofon_title}

-

-

- - {/* Portrait */} -
- Music Cognition Group -

-

- - {/* Supporters */} - - - {/* Privacy */} - -
- ); -}; - -const ToontjeHoger = (props) => { - return props.block ? ( - <> - - - - - - - - - - ) : null; -}; - -export default ToontjeHoger; diff --git a/frontend/src/components/ToontjeHoger/ToontjeHoger.scss b/frontend/src/components/ToontjeHoger/ToontjeHoger.scss deleted file mode 100644 index 550b0bfa4..000000000 --- a/frontend/src/components/ToontjeHoger/ToontjeHoger.scss +++ /dev/null @@ -1,381 +0,0 @@ -.aha__toontjehoger { - .logo { - height: 90px; - width: 100%; - max-width: 300px; - font-size: 0; - margin: 0 auto 15px; - background-size: contain; - background-position: center center; - background-repeat: no-repeat; - display: block; - - @media (max-width: 720px) { - margin-bottom: 15px; - } - } - - .hero { - display: flex; - justify-content: center; - align-items: center; - padding-bottom: 30px; - position: relative; - - @media (max-width: 720px) { - flex-wrap: wrap; - padding-bottom: 30px; - border-top: 2px solid rgba(white, 0.2); - } - - @media (min-width: 1024px) { - min-height: 430px; - } - - .intro { - @media (min-width: 720px) { - width: 50%; - max-width: 650px; - } - - @media (max-width: 720px) { - padding: 30px 15px 40px; - } - - .actions { - display: flex; - flex-wrap: wrap; - row-gap: 15px; - column-gap: 15px; - } - } - - .results { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - - @media (min-width: 720px) { - width: 50%; - max-width: 380px; - } - - .score { - background: radial-gradient( - circle at center, - rgba(white, 0.6), - rgba(white, 0.2), - rgba(white, 0), - rgba(white, 0) - ); - width: 270px; - height: 240px; - text-align: center; - border-radius: 135px; - - .aha__rank { - margin-top: 35px; - margin-bottom: 15px; - } - - h1 { - line-height: 200px; - } - } - - .share { - h5 { - opacity: 0.7; - text-align: center; - font-size: 1.1em; - } - .social { - display: flex; - a { - $shareSize: 50px; - color: white; - display: inline-block; - width: $shareSize; - height: $shareSize; - border: 2px solid rgba(white, 0.1); - background-color: rgba(white, 0.1); - text-align: center; - line-height: $shareSize - 2; - border-radius: $shareSize; - margin: 0 5px; - text-decoration: none; - transition: background-color 0.3s ease-out; - font-size: 0; - - &::before { - font-size: 1.3rem; - } - - &:hover { - background-color: rgba(white, 0.3); - } - - &.whatsapp { - background-image: url("/public/images/experiments/toontjehoger/icon-whatsapp.svg"); - background-position: center; - background-size: 23px; - background-repeat: no-repeat; - display: none; - - @media (max-width: 720px) and (hover: none) and (pointer: coarse) { - display: block; - } - } - } - } - } - } - } - - .experiments { - border-top: 12px solid rgba(white, 0.2); - border-bottom: 12px solid rgba(white, 0.2); - border-radius: 12px; - padding-top: 50px; - padding-bottom: 50px; - background-color: rgba(white, 0.2); - max-width: 1200px; - margin: 0 auto; - - @media (max-width: 720px) { - padding: 15px 15px; - } - - ul { - display: flex; - justify-content: center; - align-items: stretch; - flex-wrap: wrap; - column-gap: 25px; - row-gap: 25px; - list-style: none; - margin: 0; - padding: 0; - - @media (max-width: 420px) { - column-gap: 15px; - row-gap: 15px; - } - - &:hover { - li { - opacity: 0.8; - } - } - - li { - border-radius: 5px; - border: 1px solid rgba(black, 0.5); - transition: opacity 0.3s ease-out, box-shadow 0.3s ease-out; - background-color: rgba($black, 0.5); - box-shadow: 0 0 0 rgba(black, 0.5); - - @media (max-width: 350px) { - width: 100%; - } - - &:hover { - opacity: 1; - box-shadow: 0 2px 15px rgba(black, 0.3); - } - - a { - display: block; - text-decoration: none; - color: white; - width: 300px; - max-width: 100%; - min-height: 300px; - - @media (max-width: 420px) { - width: 100%; - } - - .image { - height: 200px; - background-color: $gray; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - background-size: cover; - background-repeat: no-repeat; - background-position: center center; - position: relative; - background-blend-mode: multiply; - } - - h3 { - padding: 15px 15px 10px; - margin: 0; - } - p { - margin: 0; - padding: 0 15px 15px; - opacity: 0.8; - } - } - } - } - } - - .supporters { - margin-top: 30px; - padding-top: 20px; - padding-bottom: 30px; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - text-align: center; - - p { - max-width: 700px; - } - - .organizations { - padding-top: 30px; - padding-bottom: 30px; - display: flex; - column-gap: 45px; - row-gap: 45px; - flex-wrap: wrap; - align-items: center; - justify-content: center; - - a { - max-width: 80%; - width: 330px; - display: block; - position: relative; - transition: opacity 0.3s ease-out; - opacity: 0.8; - padding: 15px; - - &:hover { - opacity: 1; - } - - img { - width: 100%; - } - - &.aml { - width: 140px; - } - &.uva { - width: 250px; - } - - &.mcg { - width: 200px; - } - } - } - } - - .privacy { - border-top: 2px solid rgba(white, 0.2); - width: 100%; - padding: 20px; - text-align: center; - font-size: 0.9em; - } - - // About - // ========================= - - &.about { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - - h3 { - margin-bottom: 25px; - } - } - - .project { - max-width: 700px; - } - - .streamer { - margin: 50px 30px; - color: $pink; - text-shadow: 0 0 30px $pink; - - @media (max-width: 720px) { - margin: 30px 20px; - } - } - - .colofon { - max-width: 700px; - - span { - display: block; - padding-left: 150px; - padding-bottom: 10px; - } - - b { - display: inline-block; - margin-left: -150px; - min-width: 150px; - } - } - - .group-portrait { - display: block; - margin: 20px auto 0; - width: 951px; - max-width: 100%; - border-bottom: 2px solid rgba(white, 0.2); - - img { - width: 100%; - border-radius: 3px; - } - p { - font-size: 0.9em; - font-style: italic; - margin: 0 auto; - max-width: 700px; - padding: 10px; - opacity: 0.7; - } - } -} - -// Global styling tweaks -// ========================= - -.aha__experiment.experiment-toontjehoger { - // Hide app bar - .aha__app-bar { - display: none; - } - // Fix page width - @media (min-width: 800px) { - .aha__page .container { - max-width: calc(100% - 50px) !important; - padding-top: 0; - } - } -} - -body.toontjehoger .aha__experiment:not(.experiment-toontjehoger) .aha__toontjehoger { - display: none; -} - -body.toontjehoger, -body.toontjehoger .aha__page { - background-image: url("/public/images/background-blur.webp"); - background-color: #202e30; - background-position: top center; -} diff --git a/frontend/src/components/components.scss b/frontend/src/components/components.scss index 01fe63c1e..ea5a1f608 100644 --- a/frontend/src/components/components.scss +++ b/frontend/src/components/components.scss @@ -42,7 +42,6 @@ @import "./Score/Score"; @import "./Trial/Trial"; @import "./FeedbackForm/FeedbackForm"; -@import "./ToontjeHoger/ToontjeHoger"; @import "./UserFeedback/UserFeedback"; // ExperimentCollection