-
Notifications
You must be signed in to change notification settings - Fork 19
feat(#607, #608): add support for labels with audio and video #611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
663cbd8
dccf43c
ca06c70
a03bfc8
e520893
aa1327c
9546081
998e545
1557429
39b9468
4aa0e11
839261e
839746e
4a54fe9
d9b53fc
e01b923
dce4610
cfea590
2df4e41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| '@getodk/web-forms': minor | ||
| '@getodk/common': minor | ||
| --- | ||
|
|
||
| Adds support for labels with audio and video |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,3 +3,5 @@ | |
| *.jpg -text | ||
|
|
||
| *.xlsx binary | ||
| *.mp3 binary | ||
| *.mp4 binary | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| <?xml version="1.0"?> | ||
| <h:html xmlns="http://www.w3.org/2002/xforms" | ||
| xmlns:h="http://www.w3.org/1999/xhtml" | ||
| xmlns:jr="http://openrosa.org/javarosa"> | ||
| <h:head> | ||
| <h:title>Media Label Test</h:title> | ||
| <model> | ||
| <itext> | ||
| <translation lang="en" default="true()"> | ||
| <text id="/data/audio_question:label"> | ||
| <value>Question with audio label</value> | ||
| <value form="audio">jr://audio/test-audio.mp3</value> | ||
| </text> | ||
| <text id="/data/video_question:label"> | ||
| <value>Question with video label</value> | ||
| <value form="video">jr://video/test-video.mp4</value> | ||
| </text> | ||
| <text id="/data/image_question:label"> | ||
| <value>Question with image label</value> | ||
| <value form="image">jr://images/test-image.jpg</value> | ||
| </text> | ||
| <text id="/data/combined_question:label"> | ||
| <value>Edge case: question with all media in label</value> | ||
| <value form="audio">jr://audio/test-audio.mp3</value> | ||
| <value form="video">jr://video/test-video.mp4</value> | ||
| <value form="image">jr://images/test-image.jpg</value> | ||
| </text> | ||
| <text id="/data/select_one_media:label"> | ||
| <value>Select one with media options (special style when it contains images)</value> | ||
| </text> | ||
| <text id="/data/select_multiple_media:label"> | ||
| <value>Select multiple with media options (special style when it contains images)</value> | ||
| </text> | ||
| <text id="/data/select_one_no_image:label"> | ||
| <value>Select one audio or video</value> | ||
| </text> | ||
| <text id="/data/select_multiple_no_image:label"> | ||
| <value>Select multiple audio or video</value> | ||
| </text> | ||
| <text id="choice_audio"> | ||
| <value>Option 1: Audio</value> | ||
| <value form="audio">jr://audio/test-audio.mp3</value> | ||
| </text> | ||
| <text id="choice_video"> | ||
| <value>Option 2: Video</value> | ||
| <value form="video">jr://video/test-video.mp4</value> | ||
| </text> | ||
| <text id="choice_image"> | ||
| <value>Option 3: Image</value> | ||
| <value form="image">jr://images/test-image.jpg</value> | ||
| </text> | ||
| <text id="choice_image_audio"> | ||
| <value>Option 4: Audio + Image</value> | ||
| <value form="image">jr://images/test-image.jpg</value> | ||
| <value form="audio">jr://audio/test-audio.mp3</value> | ||
| </text> | ||
| </translation> | ||
| </itext> | ||
| <instance> | ||
| <data id="media-test"> | ||
| <meta> | ||
| <instanceID/> | ||
| </meta> | ||
| <audio_question/> | ||
| <video_question/> | ||
| <image_question/> | ||
| <combined_question/> | ||
| <select_one_media/> | ||
| <select_multiple_media/> | ||
| <select_one_no_image/> | ||
| <select_multiple_no_image/> | ||
| </data> | ||
| </instance> | ||
| <bind nodeset="/data/meta/instanceID" type="string" readonly="true()" jr:preload="uid"/> | ||
| <bind nodeset="/data/audio_question" type="string"/> | ||
| <bind nodeset="/data/video_question" type="string"/> | ||
| <bind nodeset="/data/image_question" type="string"/> | ||
| <bind nodeset="/data/combined_question" type="string"/> | ||
| <bind nodeset="/data/select_one_media" type="select1"/> | ||
| <bind nodeset="/data/select_multiple_media" type="select"/> | ||
| <bind nodeset="/data/select_one_no_image" type="select1"/> | ||
| <bind nodeset="/data/select_multiple_no_image" type="select"/> | ||
| </model> | ||
| </h:head> | ||
| <h:body> | ||
| <input ref="/data/audio_question"> | ||
| <label ref="jr:itext('/data/audio_question:label')"/> | ||
| </input> | ||
| <input ref="/data/video_question"> | ||
| <label ref="jr:itext('/data/video_question:label')"/> | ||
| </input> | ||
| <input ref="/data/image_question"> | ||
| <label ref="jr:itext('/data/image_question:label')"/> | ||
| </input> | ||
| <input ref="/data/combined_question"> | ||
| <label ref="jr:itext('/data/combined_question:label')"/> | ||
| </input> | ||
| <select1 ref="/data/select_one_media"> | ||
| <label ref="jr:itext('/data/select_one_media:label')"/> | ||
| <item> | ||
| <label ref="jr:itext('choice_audio')"/> | ||
| <value>audio</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_video')"/> | ||
| <value>video</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_image')"/> | ||
| <value>image</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_image_audio')"/> | ||
| <value>image-audio</value> | ||
| </item> | ||
| </select1> | ||
| <select ref="/data/select_multiple_media"> | ||
| <label ref="jr:itext('/data/select_multiple_media:label')"/> | ||
| <item> | ||
| <label ref="jr:itext('choice_audio')"/> | ||
| <value>audio</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_video')"/> | ||
| <value>video</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_image')"/> | ||
| <value>image</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_image_audio')"/> | ||
| <value>image-audio</value> | ||
| </item> | ||
| </select> | ||
| <select1 ref="/data/select_one_no_image"> | ||
| <label ref="jr:itext('/data/select_one_no_image:label')"/> | ||
| <item> | ||
| <label ref="jr:itext('choice_audio')"/> | ||
| <value>audio</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_video')"/> | ||
| <value>video</value> | ||
| </item> | ||
| </select1> | ||
| <select ref="/data/select_multiple_no_image"> | ||
| <label ref="jr:itext('/data/select_multiple_no_image:label')"/> | ||
| <item> | ||
| <label ref="jr:itext('choice_audio')"/> | ||
| <value>audio</value> | ||
| </item> | ||
| <item> | ||
| <label ref="jr:itext('choice_video')"/> | ||
| <value>video</value> | ||
| </item> | ||
| </select> | ||
| </h:body> | ||
| </h:html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -102,7 +102,7 @@ export class XFormResource<Type extends XFormResourceType> { | |
| const service = new JRResourceService(); | ||
| const parentPath = localPath.replace(/\/[^/]+$/, ''); | ||
|
|
||
| service.activateFixtures(parentPath, ['file', 'file-csv', 'images']); | ||
| service.activateFixtures(parentPath, ['file', 'file-csv', 'images', 'audio', 'video']); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The changes in this file are to support audio and video in test forms (local dev and demo page on the website) |
||
|
|
||
| return service; | ||
| }, | ||
|
|
@@ -119,7 +119,7 @@ export class XFormResource<Type extends XFormResourceType> { | |
| const service = new JRResourceService(); | ||
| const parentPath = resourceURL.pathname.replace(/\/[^/]+$/, ''); | ||
|
|
||
| service.activateFixtures(parentPath, ['file', 'file-csv', 'images']); | ||
| service.activateFixtures(parentPath, ['file', 'file-csv', 'images', 'audio', 'video']); | ||
|
|
||
| return service; | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| @use 'primeflex/core/_variables.scss' as pf; | ||
|
|
||
| .value-option { | ||
| --text-content-margin: 15px; | ||
| } | ||
|
|
@@ -55,10 +57,12 @@ | |
| } | ||
|
|
||
| :deep(.media-content) { | ||
| background: var(--odk-base-background-color); | ||
| background: transparent; | ||
| height: calc(100% - (var(--odk-base-font-size) + (var(--text-content-margin) * 2))); | ||
| width: 100%; | ||
| justify-items: center; | ||
| min-height: 54px; | ||
| flex: 0 1 auto; | ||
| margin-left: auto; | ||
| align-content: center; | ||
| } | ||
|
|
||
| &:has(.media-content) { | ||
|
|
@@ -71,8 +75,11 @@ | |
| } | ||
|
|
||
| :deep(.text-content) { | ||
| width: fit-content; | ||
| min-width: unset; | ||
| max-width: calc(100% - 70px); | ||
| margin: var(--text-content-margin) 20px; | ||
| flex: 1 1 auto; | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -94,4 +101,27 @@ | |
| background: var(--odk-light-background-color); | ||
| align-content: flex-start; | ||
| flex-wrap: wrap; | ||
|
|
||
| :deep(.media-content) { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. align video and audio media |
||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| width: 100%; | ||
| justify-content: flex-start; | ||
| gap: 10px; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding space in case of more than one media (edge case) in the same option |
||
|
|
||
| .media-block { | ||
| border-radius: 0; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @media screen and (max-width: #{pf.$sm}) { | ||
| :not(.select-with-images) .value-option { | ||
| flex-wrap: wrap; | ||
|
|
||
| :deep(.media-content) { | ||
| margin-left: unset; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,7 @@ const selectValues = (values: readonly string[]) => { | |
| @update:model-value="selectValues" | ||
| @change="$emit('change')" | ||
| /> | ||
| <TextMedia :label="option.label" /> | ||
| <TextMedia :label="option.label" :audio-icons-only="question.currentState.isSelectWithImages" /> | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The engine detects if a select contains at least one image, and it displays differently from regular selects (each option is a card). Selects with images only show the play and stop buttons for audio, positioned next to the label, while videos are displayed in the default browser player. |
||
| </label> | ||
| </template> | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes in this file are to support mp3 and mp4 in test forms (local dev and demo page on the website)