pageflow 17.1.0 → 17.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +319 -345
- data/README.md +3 -4
- data/admins/pageflow/accounts.rb +6 -6
- data/admins/pageflow/entry.rb +10 -8
- data/admins/pageflow/membership.rb +11 -11
- data/admins/pageflow/translations.rb +5 -5
- data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
- data/app/assets/javascripts/pageflow/dist/ui.js +1350 -630
- data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
- data/app/assets/javascripts/pageflow/ui.js +0 -1
- data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
- data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -1
- data/app/assets/stylesheets/pageflow/admin.scss +1 -0
- data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
- data/app/assets/stylesheets/pageflow/animations.scss +1 -0
- data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +21 -5
- data/app/assets/stylesheets/pageflow/editor/base.scss +9 -1
- data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +13 -1
- data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
- data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
- data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +0 -1
- data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
- data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
- data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
- data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
- data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
- data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
- data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
- data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
- data/app/assets/stylesheets/pageflow/editor/files.scss +230 -50
- data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +142 -14
- data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
- data/app/assets/stylesheets/pageflow/editor/info_box.scss +12 -0
- data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
- data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
- data/app/assets/stylesheets/pageflow/editor/list.scss +88 -38
- data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
- data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
- data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
- data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
- data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
- data/app/assets/stylesheets/pageflow/ui/forms.scss +34 -4
- data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
- data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -16
- data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
- data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
- data/app/assets/stylesheets/pageflow/ui/properties.scss +29 -0
- data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
- data/app/assets/stylesheets/pageflow/ui.scss +4 -2
- data/app/controllers/pageflow/editor/entries_controller.rb +1 -0
- data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
- data/app/controllers/pageflow/editor/file_import_controller.rb +1 -0
- data/app/controllers/pageflow/editor/files_controller.rb +15 -6
- data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
- data/app/controllers/pageflow/entries_controller.rb +17 -13
- data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
- data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
- data/app/controllers/pageflow/review/comments_controller.rb +53 -0
- data/app/controllers/pageflow/revisions_controller.rb +4 -1
- data/app/helpers/pageflow/admin/entries_helper.rb +40 -0
- data/app/helpers/pageflow/admin/widgets_helper.rb +2 -2
- data/app/helpers/pageflow/common_entry_seed_helper.rb +5 -3
- data/app/helpers/pageflow/editor/config_helper.rb +3 -1
- data/app/helpers/pageflow/entries_helper.rb +24 -42
- data/app/helpers/pageflow/entry_json_seed_helper.rb +4 -4
- data/app/helpers/pageflow/public_i18n_helper.rb +9 -8
- data/app/helpers/pageflow/structured_data_helper.rb +4 -1
- data/app/helpers/pageflow/themes_helper.rb +1 -3
- data/app/helpers/pageflow/widgets_helper.rb +2 -1
- data/app/inputs/pageflow_permalink_input.rb +6 -2
- data/app/models/concerns/pageflow/auto_generated_perma_id.rb +11 -4
- data/app/models/concerns/pageflow/reusable_file.rb +1 -1
- data/app/models/concerns/pageflow/serialization_blacklist.rb +2 -4
- data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
- data/app/models/concerns/pageflow/uploadable_file.rb +1 -1
- data/app/models/pageflow/comment.rb +30 -0
- data/app/models/pageflow/comment_thread.rb +65 -0
- data/app/models/pageflow/comment_thread_read.rb +22 -0
- data/app/models/pageflow/customized_theme.rb +3 -2
- data/app/models/pageflow/draft_entry.rb +20 -8
- data/app/models/pageflow/entry.rb +2 -0
- data/app/models/pageflow/entry_at_revision.rb +9 -1
- data/app/models/pageflow/entry_comment_summary.rb +114 -0
- data/app/models/pageflow/file_folder.rb +74 -0
- data/app/models/pageflow/file_reuse.rb +3 -2
- data/app/models/pageflow/file_usage.rb +8 -0
- data/app/models/pageflow/image_file.rb +24 -20
- data/app/models/pageflow/image_file_url_templates.rb +3 -3
- data/app/models/pageflow/legal_info.rb +38 -0
- data/app/models/pageflow/nested_revision_component_copy.rb +1 -1
- data/app/models/pageflow/permalink.rb +1 -0
- data/app/models/pageflow/revision.rb +6 -2
- data/app/models/pageflow/site.rb +10 -0
- data/app/models/pageflow/used_file.rb +8 -2
- data/app/models/pageflow/widget.rb +2 -2
- data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
- data/app/views/pageflow/editor/config/_seeds.json.jbuilder +4 -2
- data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
- data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
- data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
- data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
- data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
- data/app/views/pageflow/editor/files/_file.json.jbuilder +2 -1
- data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
- data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +3 -0
- data/app/views/pageflow/files/_file.json.jbuilder +2 -0
- data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
- data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
- data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
- data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
- data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
- data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
- data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
- data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
- data/config/locales/de.yml +152 -14
- data/config/locales/en.yml +150 -14
- data/config/routes.rb +14 -0
- data/db/migrate/20140418225525_setup_schema.rb +2 -2
- data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
- data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
- data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
- data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
- data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
- data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
- data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
- data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
- data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
- data/db/migrate/20260728000000_create_file_folders.rb +17 -0
- data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
- data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
- data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
- data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
- data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +8665 -3890
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +979 -3571
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20199 -28120
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18652 -26584
- data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +33 -3
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -3
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +21 -1
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +7 -5
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +5 -2
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +13 -5
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +26 -11
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +2 -2
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +174 -3
- data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +49 -7
- data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
- data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
- data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +1 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +13 -12
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +30 -10
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +9 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
- data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
- data/entry_types/scrolled/config/locales/de.yml +512 -65
- data/entry_types/scrolled/config/locales/en.yml +518 -52
- data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
- data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +51 -6
- data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
- data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +205 -22
- data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
- data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +56 -36
- data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
- data/entry_types/scrolled/lib/pageflow_scrolled.rb +13 -0
- data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +19 -1
- data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
- data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
- data/entry_types/scrolled/package/config/webpack.js +72 -0
- data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -1
- data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1181 -915
- data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
- data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
- data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
- data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +71 -21
- data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
- data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
- data/entry_types/scrolled/package/contentElements-editor.js +1915 -1097
- data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
- data/entry_types/scrolled/package/contentElements-frontend.js +3093 -1679
- data/entry_types/scrolled/package/editor.css +1 -0
- data/entry_types/scrolled/package/editor.js +8667 -4077
- data/entry_types/scrolled/package/entryState.js +1600 -0
- data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
- data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
- data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9f76033e.js → PhonePlatformContext-035a99fa.js} +7 -12
- data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
- data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
- data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
- data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
- data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
- data/entry_types/scrolled/package/frontend/{ToggleFullscreenCornerButton-788e9cdb.js → ToggleFullscreenCornerButton-30fd1124.js} +6 -6
- data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
- data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
- data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
- data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
- data/entry_types/scrolled/package/frontend/{Viewer-0345ce57.js → Viewer-cc8d4072.js} +84 -92
- data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
- data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
- data/entry_types/scrolled/package/frontend/commenting.css +1 -0
- data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
- data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
- data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
- data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
- data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
- data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
- data/entry_types/scrolled/package/frontend/{index-eb670c2f.js → index-2e5546f7.js} +36 -44
- data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
- data/entry_types/scrolled/package/frontend/index.css +1 -1
- data/entry_types/scrolled/package/frontend/index.js +1870 -875
- data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
- data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
- data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
- data/entry_types/scrolled/package/frontend/{usePhonePlatform-c2ba875d.js → usePhonePlatform-4ecb96d4.js} +1 -1
- data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
- data/entry_types/scrolled/package/frontend-server.js +20 -209
- data/entry_types/scrolled/package/package.json +5 -3
- data/entry_types/scrolled/package/review.css +1 -0
- data/entry_types/scrolled/package/review.js +3306 -0
- data/entry_types/scrolled/package/testHelpers.js +836 -359
- data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
- data/entry_types/scrolled/package/widgets/consentBar.js +269 -290
- data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
- data/entry_types/scrolled/package/widgets/defaultNavigation.js +911 -352
- data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -1
- data/entry_types/scrolled/package/widgets/excursionSheet.js +87 -124
- data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
- data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -29
- data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +32 -13
- data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -1
- data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +56 -100
- data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
- data/entry_types/scrolled/package/widgets/textInlineFileRights.js +33 -28
- data/entry_types/scrolled/package/widgets-server.js +1 -0
- data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
- data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
- data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
- data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
- data/lib/generators/pageflow/resque/resque_generator.rb +0 -2
- data/lib/pageflow/configuration.rb +49 -7
- data/lib/pageflow/deprecation.rb +19 -0
- data/lib/pageflow/engine.rb +1 -1
- data/lib/pageflow/entries_controller_env_helper.rb +32 -2
- data/lib/pageflow/entry_export_import/entry_serialization.rb +4 -4
- data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
- data/lib/pageflow/entry_export_import/revision_serialization/import.rb +10 -0
- data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
- data/lib/pageflow/entry_structured_data_types.rb +43 -0
- data/lib/pageflow/entry_type_configuration.rb +1 -0
- data/lib/pageflow/file_type.rb +2 -2
- data/lib/pageflow/file_types.rb +1 -1
- data/lib/pageflow/oembed_providers.rb +42 -0
- data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
- data/lib/pageflow/rails_version.rb +13 -2
- data/lib/pageflow/themes.rb +41 -0
- data/lib/pageflow/user_mixin.rb +12 -0
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow.rb +1 -0
- data/package/config/eslint-rules/documented-in-toc.js +125 -0
- data/package/config/jest/index.js +0 -1
- data/package/config/webpack.js +0 -1
- data/package/config/webpack5.js +0 -1
- data/package/editor.js +4378 -1897
- data/package/frontend.js +647 -886
- data/package/package.json +2 -1
- data/package/review.js +384 -0
- data/package/testHelpers.js +248 -188
- data/package/ui.js +1346 -630
- data/package/vendor/stubs/wysihtml5.js +2 -0
- data/spec/factories/comment_thread_reads.rb +10 -0
- data/spec/factories/comment_threads.rb +10 -0
- data/spec/factories/comments.rb +9 -0
- data/spec/factories/file_folders.rb +8 -0
- data/spec/factories/published_entries.rb +2 -0
- metadata +188 -67
- data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
- data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-51914be7.js +0 -5439
- data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +0 -1932
- data/entry_types/scrolled/package/frontend/Viewer-cdc549cc.js +0 -147
- data/entry_types/scrolled/package/frontend/Wavesurfer-1cdc3925.js +0 -313
- data/entry_types/scrolled/package/frontend/components-96660ffd.js +0 -3803
- data/entry_types/scrolled/package/frontend/inherits-539844a6.js +0 -99
- data/entry_types/scrolled/package/frontend/useContentElementEditorState-77fe6c79.js +0 -51
- data/entry_types/scrolled/package/widgets/excursionDialog.css +0 -1
- data/entry_types/scrolled/package/widgets/excursionDialog.js +0 -109
- data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
- data/package/vendor/jquery.minicolors.js +0 -1108
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import 'pageflow/frontend';
|
|
2
2
|
import React, { useMemo, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import ReactDOM from 'react-dom';
|
|
4
|
-
import { b as _defineProperty, T as ThemeIcon, e as _objectWithoutProperties, _ as _slicedToArray } from './ThemeIcon-81f2f066.js';
|
|
5
4
|
import classNames from 'classnames';
|
|
6
|
-
import '
|
|
7
|
-
import 'reselect';
|
|
8
|
-
import 'slugify';
|
|
5
|
+
import 'pageflow-scrolled/entryState';
|
|
9
6
|
import 'i18n-js';
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import './i18n-493cd2a6.js';
|
|
8
|
+
import { u as useBrowserFeature } from './PhonePlatformContext-035a99fa.js';
|
|
9
|
+
import { T as ThemeIcon } from './ThemeIcon-ab834849.js';
|
|
10
|
+
import { T as ToggleFullscreenCornerButton } from './ToggleFullscreenCornerButton-30fd1124.js';
|
|
11
|
+
import { u as usePhonePlatform } from './usePhonePlatform-ce9ff08d.js';
|
|
13
12
|
import { PanoViewer } from '@egjs/view360';
|
|
14
13
|
import screenfull from 'screenfull';
|
|
15
14
|
|
|
16
15
|
var styles = {"wrapper":"Fullscreen-module_wrapper__300hJ"};
|
|
17
16
|
|
|
18
|
-
function Fullscreen(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
useEffect(function () {
|
|
17
|
+
function Fullscreen({
|
|
18
|
+
isFullscreen,
|
|
19
|
+
children
|
|
20
|
+
}) {
|
|
21
|
+
const root = useMemo(() => document.getElementById('fullscreenRoot'), []);
|
|
22
|
+
useEffect(() => {
|
|
25
23
|
if (isFullscreen) {
|
|
26
24
|
document.body.style.overflow = 'hidden';
|
|
27
25
|
} else {
|
|
@@ -39,10 +37,13 @@ function Fullscreen(_ref) {
|
|
|
39
37
|
|
|
40
38
|
var styles$1 = {"indicator":"PanoramaIndicator-module_indicator__3A90v","visible":"PanoramaIndicator-module_visible__3LOgm","arrow":"PanoramaIndicator-module_arrow__QV1Pd","arrowLeft":"PanoramaIndicator-module_arrowLeft__Jh7GC PanoramaIndicator-module_arrow__QV1Pd","arrowRight":"PanoramaIndicator-module_arrowRight__ZZBtO PanoramaIndicator-module_arrow__QV1Pd","nudgeLeft":"PanoramaIndicator-module_nudgeLeft__IU_Iy","nudgeRight":"PanoramaIndicator-module_nudgeRight__3XzNu","text":"PanoramaIndicator-module_text__2FzUy"};
|
|
41
39
|
|
|
42
|
-
function PanoramaIndicator(
|
|
43
|
-
|
|
40
|
+
function PanoramaIndicator({
|
|
41
|
+
visible
|
|
42
|
+
}) {
|
|
44
43
|
return /*#__PURE__*/React.createElement("div", {
|
|
45
|
-
className: classNames(styles$1.indicator,
|
|
44
|
+
className: classNames(styles$1.indicator, {
|
|
45
|
+
[styles$1.visible]: visible
|
|
46
|
+
})
|
|
46
47
|
}, /*#__PURE__*/React.createElement("div", {
|
|
47
48
|
className: styles$1.arrowLeft
|
|
48
49
|
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ThemeIcon, {
|
|
@@ -58,11 +59,14 @@ function PanoramaIndicator(_ref) {
|
|
|
58
59
|
|
|
59
60
|
var styles$2 = {"indicator":"FullscreenIndicator-module_indicator__2Jl_-","visible":"FullscreenIndicator-module_visible__2ywsZ","icon":"FullscreenIndicator-module_icon__2Ddof","icons":"FullscreenIndicator-module_icons__3-Xm6","text":"FullscreenIndicator-module_text__3wCW3","pulse":"FullscreenIndicator-module_pulse__1qujU","iconTopLeft":"FullscreenIndicator-module_iconTopLeft__2u7-j FullscreenIndicator-module_icon__2Ddof","iconTopRight":"FullscreenIndicator-module_iconTopRight__14nUk FullscreenIndicator-module_icon__2Ddof","iconBottomRight":"FullscreenIndicator-module_iconBottomRight__lEtN6 FullscreenIndicator-module_icon__2Ddof","iconBottomLeft":"FullscreenIndicator-module_iconBottomLeft__voLm_ FullscreenIndicator-module_icon__2Ddof"};
|
|
60
61
|
|
|
61
|
-
function FullscreenIndicator(
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
function FullscreenIndicator({
|
|
63
|
+
visible,
|
|
64
|
+
onClick
|
|
65
|
+
}) {
|
|
64
66
|
return /*#__PURE__*/React.createElement("div", {
|
|
65
|
-
className: classNames(styles$2.indicator,
|
|
67
|
+
className: classNames(styles$2.indicator, {
|
|
68
|
+
[styles$2.visible]: visible
|
|
69
|
+
})
|
|
66
70
|
}, /*#__PURE__*/React.createElement("div", {
|
|
67
71
|
className: styles$2.icons
|
|
68
72
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -88,7 +92,6 @@ function FullscreenIndicator(_ref) {
|
|
|
88
92
|
|
|
89
93
|
var styles$3 = {"full":"Viewer-module_full__1q18y","container":"Viewer-module_container__3eJ34 Viewer-module_full__1q18y","spinner":"Viewer-module_spinner__2oRve","spin":"Viewer-module_spin__3jBR2","isLoading":"Viewer-module_isLoading__sQuGw"};
|
|
90
94
|
|
|
91
|
-
var _excluded = ["styles"];
|
|
92
95
|
function _extends() {
|
|
93
96
|
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
94
97
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -103,48 +106,42 @@ function _extends() {
|
|
|
103
106
|
};
|
|
104
107
|
return _extends.apply(this, arguments);
|
|
105
108
|
}
|
|
106
|
-
var SpinnerIcon = (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
109
|
+
var SpinnerIcon = (({
|
|
110
|
+
styles = {},
|
|
111
|
+
...props
|
|
112
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends({
|
|
113
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
114
|
+
fill: "none",
|
|
115
|
+
viewBox: "0 0 24 24"
|
|
116
|
+
}, props), /*#__PURE__*/React.createElement("circle", {
|
|
117
|
+
cx: "12",
|
|
118
|
+
cy: "12",
|
|
119
|
+
r: "10",
|
|
120
|
+
stroke: "currentColor",
|
|
121
|
+
strokeWidth: "4",
|
|
122
|
+
opacity: ".23"
|
|
123
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
124
|
+
fill: "currentColor",
|
|
125
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z",
|
|
126
|
+
opacity: ".75"
|
|
127
|
+
})));
|
|
126
128
|
|
|
127
|
-
function Viewer(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
var _useState3 = useState(false),
|
|
144
|
-
_useState4 = _slicedToArray(_useState3, 2),
|
|
145
|
-
isFullscreen = _useState4[0],
|
|
146
|
-
setIsFullscreen = _useState4[1];
|
|
147
|
-
var isPhonePlatform = usePhonePlatform();
|
|
129
|
+
function Viewer({
|
|
130
|
+
imageFile,
|
|
131
|
+
viewerRef,
|
|
132
|
+
initialYaw,
|
|
133
|
+
initialPitch,
|
|
134
|
+
hidePanoramaIndicator,
|
|
135
|
+
onReady,
|
|
136
|
+
onFullscreen
|
|
137
|
+
}) {
|
|
138
|
+
const elRef = useRef();
|
|
139
|
+
const initialYawRef = useRef(initialYaw);
|
|
140
|
+
const initialPitchRef = useRef(initialPitch);
|
|
141
|
+
const touchSupport = useBrowserFeature('touch support');
|
|
142
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
143
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
144
|
+
const isPhonePlatform = usePhonePlatform();
|
|
148
145
|
|
|
149
146
|
// When toggling to fullscreen mode, this component renders to a
|
|
150
147
|
// portal div in the body of the document. We do not want to recreate
|
|
@@ -167,7 +164,7 @@ function Viewer(_ref) {
|
|
|
167
164
|
yaw: initialYawRef.current,
|
|
168
165
|
pitch: initialPitchRef.current
|
|
169
166
|
});
|
|
170
|
-
viewerRef.current.on(PanoViewer.EVENTS.READY,
|
|
167
|
+
viewerRef.current.on(PanoViewer.EVENTS.READY, () => {
|
|
171
168
|
viewerRef.current.updateViewportDimensions();
|
|
172
169
|
setIsLoading(false);
|
|
173
170
|
if (onReady) {
|
|
@@ -178,8 +175,8 @@ function Viewer(_ref) {
|
|
|
178
175
|
parentNode.appendChild(elRef.current);
|
|
179
176
|
viewerRef.current.updateViewportDimensions();
|
|
180
177
|
}
|
|
181
|
-
useEffect(
|
|
182
|
-
return
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
return () => {
|
|
183
180
|
if (elRef.current) {
|
|
184
181
|
viewerRef.current.destroy();
|
|
185
182
|
viewerRef.current = null;
|
|
@@ -187,7 +184,7 @@ function Viewer(_ref) {
|
|
|
187
184
|
}
|
|
188
185
|
};
|
|
189
186
|
}, [viewerRef]);
|
|
190
|
-
useEffect(
|
|
187
|
+
useEffect(() => {
|
|
191
188
|
if (initialYawRef.current !== initialYaw) {
|
|
192
189
|
initialYawRef.current = initialYaw;
|
|
193
190
|
viewerRef.current.lookAt({
|
|
@@ -195,7 +192,7 @@ function Viewer(_ref) {
|
|
|
195
192
|
}, 200);
|
|
196
193
|
}
|
|
197
194
|
}, [initialYaw, viewerRef]);
|
|
198
|
-
useEffect(
|
|
195
|
+
useEffect(() => {
|
|
199
196
|
if (initialPitchRef.current !== initialPitch) {
|
|
200
197
|
initialPitchRef.current = initialPitch;
|
|
201
198
|
viewerRef.current.lookAt({
|
|
@@ -203,7 +200,7 @@ function Viewer(_ref) {
|
|
|
203
200
|
}, 200);
|
|
204
201
|
}
|
|
205
202
|
}, [initialPitch, viewerRef]);
|
|
206
|
-
useEffect(
|
|
203
|
+
useEffect(() => {
|
|
207
204
|
function onChange() {
|
|
208
205
|
if (!screenfull.isFullscreen) {
|
|
209
206
|
setIsFullscreen(false);
|
|
@@ -211,21 +208,17 @@ function Viewer(_ref) {
|
|
|
211
208
|
}
|
|
212
209
|
if (screenfull.isEnabled) {
|
|
213
210
|
screenfull.on('change', onChange);
|
|
214
|
-
return
|
|
215
|
-
return screenfull.off('change', onChange);
|
|
216
|
-
};
|
|
211
|
+
return () => screenfull.off('change', onChange);
|
|
217
212
|
}
|
|
218
213
|
}, []);
|
|
219
|
-
useEffect(
|
|
214
|
+
useEffect(() => {
|
|
220
215
|
function onChange() {
|
|
221
216
|
viewerRef.current.updateViewportDimensions();
|
|
222
217
|
}
|
|
223
218
|
window.addEventListener('resize', onChange);
|
|
224
|
-
return
|
|
225
|
-
return window.removeEventListener('resize', onChange);
|
|
226
|
-
};
|
|
219
|
+
return () => window.removeEventListener('resize', onChange);
|
|
227
220
|
}, [viewerRef]);
|
|
228
|
-
useEffect(
|
|
221
|
+
useEffect(() => {
|
|
229
222
|
if (isFullscreen) {
|
|
230
223
|
viewerRef.current.setTouchDirection(PanoViewer.TOUCH_DIRECTION.ALL);
|
|
231
224
|
viewerRef.current.setGyroMode(PanoViewer.GYRO_MODE.YAWPITCH);
|
|
@@ -272,16 +265,16 @@ function Viewer(_ref) {
|
|
|
272
265
|
}, /*#__PURE__*/React.createElement("div", {
|
|
273
266
|
className: styles$3.container,
|
|
274
267
|
onKeyDown: preventDefaultForArrowUpDown,
|
|
275
|
-
onClick:
|
|
268
|
+
onClick: () => {
|
|
276
269
|
isPhonePlatform && enterFullscreen();
|
|
277
270
|
}
|
|
278
271
|
}, /*#__PURE__*/React.createElement(DOMNodeContainer, {
|
|
279
272
|
className: styles$3.full,
|
|
280
|
-
onUpdate:
|
|
281
|
-
return appendViewerTo(el);
|
|
282
|
-
}
|
|
273
|
+
onUpdate: el => appendViewerTo(el)
|
|
283
274
|
})), /*#__PURE__*/React.createElement(SpinnerIcon, {
|
|
284
|
-
className: classNames(styles$3.spinner,
|
|
275
|
+
className: classNames(styles$3.spinner, {
|
|
276
|
+
[styles$3.isLoading]: isLoading
|
|
277
|
+
})
|
|
285
278
|
}), (!isPhonePlatform || isFullscreen) && /*#__PURE__*/React.createElement(ToggleFullscreenCornerButton, {
|
|
286
279
|
isFullscreen: isFullscreen,
|
|
287
280
|
onEnter: enterFullscreen,
|
|
@@ -292,14 +285,15 @@ function Viewer(_ref) {
|
|
|
292
285
|
visible: !isLoading && isPhonePlatform && !isFullscreen
|
|
293
286
|
}));
|
|
294
287
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
288
|
+
const DOMNodeContainer = React.memo(function ({
|
|
289
|
+
className,
|
|
290
|
+
onUpdate
|
|
291
|
+
}) {
|
|
292
|
+
const ref = useRef();
|
|
293
|
+
useEffect(() => {
|
|
294
|
+
const current = ref.current;
|
|
301
295
|
onUpdate(current);
|
|
302
|
-
return
|
|
296
|
+
return () => {
|
|
303
297
|
current.removeChild(current.firstChild);
|
|
304
298
|
};
|
|
305
299
|
});
|
|
@@ -307,8 +301,6 @@ var DOMNodeContainer = React.memo(function (_ref2) {
|
|
|
307
301
|
ref: ref,
|
|
308
302
|
className: className
|
|
309
303
|
});
|
|
310
|
-
},
|
|
311
|
-
return true;
|
|
312
|
-
});
|
|
304
|
+
}, () => true);
|
|
313
305
|
|
|
314
306
|
export default Viewer;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import Measure from 'react-measure';
|
|
3
|
+
import assign from 'deep-assign';
|
|
4
|
+
import WaveSurfer from 'wavesurfer.js';
|
|
5
|
+
|
|
6
|
+
const EVENTS = ['audioprocess', 'error', 'finish', 'loading', 'mouseup', 'pause', 'play', 'ready', 'scroll', 'seek', 'zoom'];
|
|
7
|
+
function capitaliseFirstLetter(string) {
|
|
8
|
+
return string.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('');
|
|
9
|
+
}
|
|
10
|
+
class Wavesurfer extends Component {
|
|
11
|
+
constructor(props) {
|
|
12
|
+
super(props);
|
|
13
|
+
this.state = {
|
|
14
|
+
isReady: false
|
|
15
|
+
};
|
|
16
|
+
if (typeof WaveSurfer === undefined) {
|
|
17
|
+
throw new Error('WaveSurfer is undefined!');
|
|
18
|
+
}
|
|
19
|
+
this._loadMediaElt = this._loadMediaElt.bind(this);
|
|
20
|
+
this._loadAudio = this._loadAudio.bind(this);
|
|
21
|
+
this._seekTo = this._seekTo.bind(this);
|
|
22
|
+
this._handleResize = () => {
|
|
23
|
+
if (this.state.isReady) {
|
|
24
|
+
// Force redraw
|
|
25
|
+
this._wavesurfer.zoom(false);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
componentDidMount() {
|
|
30
|
+
const options = assign({}, this.props.options, {
|
|
31
|
+
container: this.wavesurferEl
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// media element loading is only supported by MediaElement backend
|
|
35
|
+
if (this.props.mediaElt) {
|
|
36
|
+
options.backend = 'MediaElement';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Do not draw waveform behind translucent progress waveform.
|
|
40
|
+
|
|
41
|
+
this._wavesurfer = WaveSurfer.create(options);
|
|
42
|
+
this._wavesurfer.drawer.updateProgress = function (position) {
|
|
43
|
+
this.style(this.progressWave, {
|
|
44
|
+
width: position + 'px'
|
|
45
|
+
});
|
|
46
|
+
this.style(this.wrapper.lastChild, {
|
|
47
|
+
clipPath: 'rect(auto auto auto ' + position + 'px)'
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Prevent Wavesurfer from calling load on media element when peak
|
|
52
|
+
// data is present. Otherwise play progress is reset lazy loading
|
|
53
|
+
// re-initializes the player after having moved off-screen.
|
|
54
|
+
// Wavesurfer already skips that if preload is"none". We can thus
|
|
55
|
+
// use this to suppress the unwanted load. If media is already
|
|
56
|
+
// playing, we need to fire play event to make Wavesurfer start
|
|
57
|
+
// the timer that updates waveform progress.
|
|
58
|
+
|
|
59
|
+
const origLoad = this._wavesurfer.backends.MediaElement.prototype._load;
|
|
60
|
+
this._wavesurfer.backends.MediaElement.prototype._load = function (media, peaks) {
|
|
61
|
+
origLoad.call(this, media, peaks, 'none');
|
|
62
|
+
if (!media.paused) {
|
|
63
|
+
this.fireEvent('play');
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// file was loaded, wave was drawn
|
|
68
|
+
this._wavesurfer.on('ready', () => {
|
|
69
|
+
this.setState({
|
|
70
|
+
isReady: true,
|
|
71
|
+
pos: this.props.pos
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// set initial position
|
|
75
|
+
if (this.props.pos) {
|
|
76
|
+
this._seekTo(this.props.pos);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// set initial volume
|
|
80
|
+
if (this.props.volume != null) {
|
|
81
|
+
this._wavesurfer.setVolume(this.props.volume);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// set initial playing state
|
|
85
|
+
if (this.props.playing) {
|
|
86
|
+
this._wavesurfer.play();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// set initial zoom
|
|
90
|
+
if (this.props.zoom) {
|
|
91
|
+
this._wavesurfer.zoom(this.props.zoom);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
this._wavesurfer.on('audioprocess', pos => {
|
|
95
|
+
this.setState({
|
|
96
|
+
pos
|
|
97
|
+
});
|
|
98
|
+
this.props.onPosChange({
|
|
99
|
+
wavesurfer: this._wavesurfer,
|
|
100
|
+
originalArgs: [pos]
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// `audioprocess` is not fired when seeking, so we have to plug into the
|
|
105
|
+
// `seek` event and calculate the equivalent in seconds (seek event
|
|
106
|
+
// receives a position float 0-1) – See the README.md for explanation why we
|
|
107
|
+
// need this
|
|
108
|
+
this._wavesurfer.on('seek', pos => {
|
|
109
|
+
const formattedPos = this._posToSec(pos);
|
|
110
|
+
this.setState({
|
|
111
|
+
formattedPos
|
|
112
|
+
});
|
|
113
|
+
this.props.onPosChange({
|
|
114
|
+
wavesurfer: this._wavesurfer,
|
|
115
|
+
originalArgs: [formattedPos]
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// hook up events to callback handlers passed in as props
|
|
120
|
+
EVENTS.forEach(e => {
|
|
121
|
+
const propCallback = this.props[`on${capitaliseFirstLetter(e)}`];
|
|
122
|
+
const wavesurfer = this._wavesurfer;
|
|
123
|
+
if (propCallback) {
|
|
124
|
+
this._wavesurfer.on(e, (...originalArgs) => {
|
|
125
|
+
propCallback({
|
|
126
|
+
wavesurfer,
|
|
127
|
+
originalArgs
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// if audioFile prop, load file
|
|
134
|
+
if (this.props.audioFile) {
|
|
135
|
+
this._loadAudio(this.props.audioFile, this.props.audioPeaks);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// if mediaElt prop, load media Element
|
|
139
|
+
if (this.props.mediaElt) {
|
|
140
|
+
this._loadMediaElt(this.props.mediaElt, this.props.audioPeaks);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// update wavesurfer rendering manually
|
|
145
|
+
componentDidUpdate(prevProps) {
|
|
146
|
+
// update audioFile
|
|
147
|
+
if (prevProps.audioFile !== this.props.audioFile) {
|
|
148
|
+
this._loadAudio(this.props.audioFile, this.props.audioPeaks);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// update mediaElt
|
|
152
|
+
if (prevProps.mediaElt !== this.props.mediaElt) {
|
|
153
|
+
this._loadMediaElt(this.props.mediaElt, this.props.audioPeaks);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// update peaks
|
|
157
|
+
if (prevProps.audioPeaks !== this.props.audioPeaks) {
|
|
158
|
+
if (this.props.mediaElt) {
|
|
159
|
+
this._loadMediaElt(prevProps.mediaElt, this.props.audioPeaks);
|
|
160
|
+
} else {
|
|
161
|
+
this._loadAudio(this.props.audioFile, this.props.audioPeaks);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// update position
|
|
166
|
+
if (this.props.pos && this.state.isReady && prevProps.pos !== this.props.pos && this.props.pos !== this.state.pos) {
|
|
167
|
+
this._seekTo(this.props.pos);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// update playing state
|
|
171
|
+
if (this.props.playing !== prevProps.playing) {
|
|
172
|
+
if (this.props.playing) {
|
|
173
|
+
this._wavesurfer.play();
|
|
174
|
+
} else {
|
|
175
|
+
this._wavesurfer.pause();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// update volume
|
|
180
|
+
if (this.props.volume !== prevProps.volume) {
|
|
181
|
+
this._wavesurfer.setVolume(this.props.volume);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// update volume
|
|
185
|
+
if (this.props.zoom !== prevProps.zoom) {
|
|
186
|
+
this._wavesurfer.zoom(this.props.zoom);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// update audioRate
|
|
190
|
+
if (this.props.options.audioRate !== prevProps.options.audioRate) {
|
|
191
|
+
this._wavesurfer.setPlaybackRate(this.props.options.audioRate);
|
|
192
|
+
}
|
|
193
|
+
if (prevProps.options.waveColor !== this.props.options.waveColor) {
|
|
194
|
+
this._wavesurfer.setWaveColor(this.props.options.waveColor);
|
|
195
|
+
}
|
|
196
|
+
if (prevProps.options.progressColor !== this.props.options.progressColor) {
|
|
197
|
+
this._wavesurfer.setProgressColor(this.props.options.progressColor);
|
|
198
|
+
}
|
|
199
|
+
if (prevProps.options.cursorColor !== this.props.options.cursorColor) {
|
|
200
|
+
this._wavesurfer.setCursorColor(this.props.options.cursorColor);
|
|
201
|
+
}
|
|
202
|
+
if (prevProps.options.height !== this.props.options.height) {
|
|
203
|
+
this._wavesurfer.setHeight(this.props.options.height);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
componentWillUnmount() {
|
|
207
|
+
// remove listeners
|
|
208
|
+
EVENTS.forEach(e => {
|
|
209
|
+
this._wavesurfer.un(e);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// destroy wavesurfer instance
|
|
213
|
+
this._wavesurfer.destroy();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// receives seconds and transforms this to the position as a float 0-1
|
|
217
|
+
_secToPos(sec) {
|
|
218
|
+
return 1 / this._wavesurfer.getDuration() * sec;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// receives position as a float 0-1 and transforms this to seconds
|
|
222
|
+
_posToSec(pos) {
|
|
223
|
+
return pos * this._wavesurfer.getDuration();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// pos is in seconds, the 0-1 proportional position we calculate here …
|
|
227
|
+
_seekTo(sec) {
|
|
228
|
+
const pos = this._secToPos(sec);
|
|
229
|
+
if (this.props.options.autoCenter) {
|
|
230
|
+
this._wavesurfer.seekAndCenter(pos);
|
|
231
|
+
} else {
|
|
232
|
+
this._wavesurfer.seekTo(pos);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// load a media element selector or HTML element
|
|
237
|
+
// if selector, get the HTML element for it
|
|
238
|
+
// and pass to _loadAudio
|
|
239
|
+
_loadMediaElt(selectorOrElt, audioPeaks) {
|
|
240
|
+
if (selectorOrElt instanceof global.HTMLElement) {
|
|
241
|
+
this._loadAudio(selectorOrElt, audioPeaks);
|
|
242
|
+
} else {
|
|
243
|
+
// Ignore if media element cannot be found. There are edge cases
|
|
244
|
+
// where React already unmounted the corresponding media element,
|
|
245
|
+
// but the parent Waveform component still holds the old media
|
|
246
|
+
// element id.
|
|
247
|
+
if (global.document.querySelector(selectorOrElt)) {
|
|
248
|
+
this._loadAudio(global.document.querySelector(selectorOrElt), audioPeaks);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// pass audio data to wavesurfer
|
|
254
|
+
_loadAudio(audioFileOrElt, audioPeaks) {
|
|
255
|
+
if (audioFileOrElt instanceof global.HTMLElement) {
|
|
256
|
+
// media element
|
|
257
|
+
this._wavesurfer.loadMediaElement(audioFileOrElt, audioPeaks);
|
|
258
|
+
} else if (typeof audioFileOrElt === 'string') {
|
|
259
|
+
// bog-standard string is handled by load method and ajax call
|
|
260
|
+
this._wavesurfer.load(audioFileOrElt, audioPeaks);
|
|
261
|
+
} else if (audioFileOrElt instanceof global.Blob || audioFileOrElt instanceof global.File) {
|
|
262
|
+
// blob or file is loaded with loadBlob method
|
|
263
|
+
this._wavesurfer.loadBlob(audioFileOrElt, audioPeaks);
|
|
264
|
+
} else {
|
|
265
|
+
throw new Error(`Wavesurfer._loadAudio expects prop audioFile
|
|
266
|
+
to be either HTMLElement, string or file/blob`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
_measureIfResponsive(children) {
|
|
270
|
+
if (this.props.responsive) {
|
|
271
|
+
return /*#__PURE__*/React.createElement(Measure, {
|
|
272
|
+
client: true,
|
|
273
|
+
onResize: this._handleResize
|
|
274
|
+
}, ({
|
|
275
|
+
measureRef
|
|
276
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
277
|
+
ref: measureRef
|
|
278
|
+
}, children));
|
|
279
|
+
}
|
|
280
|
+
return children;
|
|
281
|
+
}
|
|
282
|
+
render() {
|
|
283
|
+
const childrenWithProps = this.props.children ? React.Children.map(this.props.children, child => React.cloneElement(child, {
|
|
284
|
+
wavesurfer: this._wavesurfer,
|
|
285
|
+
isReady: this.state.isReady
|
|
286
|
+
})) : false;
|
|
287
|
+
return this._measureIfResponsive( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
|
288
|
+
ref: c => {
|
|
289
|
+
this.wavesurferEl = c;
|
|
290
|
+
}
|
|
291
|
+
}), childrenWithProps));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
Wavesurfer.defaultProps = {
|
|
295
|
+
playing: false,
|
|
296
|
+
pos: 0,
|
|
297
|
+
options: WaveSurfer.defaultParams,
|
|
298
|
+
responsive: true,
|
|
299
|
+
onPosChange: () => {}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
export default Wavesurfer;
|