pageflow 15.7.0 → 15.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +103 -199
  3. data/README.md +1 -9
  4. data/Rakefile +4 -1
  5. data/admins/pageflow/entry.rb +32 -6
  6. data/admins/pageflow/membership.rb +5 -1
  7. data/admins/pageflow/user.rb +7 -0
  8. data/app/assets/javascripts/pageflow/admin/entries.js +40 -0
  9. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +65 -0
  10. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  11. data/app/assets/stylesheets/pageflow/editor/base.scss +2 -6
  12. data/app/assets/stylesheets/pageflow/editor/dialogs.scss +2 -0
  13. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +9 -0
  14. data/app/assets/stylesheets/pageflow/editor/info_box.scss +13 -3
  15. data/app/assets/stylesheets/pageflow/mixins/buttons.scss +1 -0
  16. data/app/assets/stylesheets/pageflow/page.scss +0 -2
  17. data/app/assets/stylesheets/pageflow/themes/default/page.scss +1 -1
  18. data/app/assets/stylesheets/pageflow/ui/forms.scss +4 -1
  19. data/app/controllers/pageflow/editor/file_import_controller.rb +32 -42
  20. data/app/controllers/pageflow/entries_controller.rb +25 -1
  21. data/app/helpers/pageflow/admin/permalinks_helper.rb +15 -0
  22. data/app/helpers/pageflow/entries_helper.rb +9 -1
  23. data/app/helpers/pageflow/themings_helper.rb +1 -1
  24. data/app/inputs/pageflow_permalink_input.rb +47 -0
  25. data/app/models/concerns/pageflow/permalinkable.rb +12 -0
  26. data/app/models/concerns/pageflow/reusable_file.rb +5 -0
  27. data/app/models/concerns/pageflow/uploadable_file.rb +4 -0
  28. data/app/models/pageflow/customized_theme.rb +4 -2
  29. data/app/models/pageflow/entry.rb +13 -0
  30. data/app/models/pageflow/entry_at_revision.rb +2 -1
  31. data/app/models/pageflow/entry_duplicate.rb +7 -0
  32. data/app/models/pageflow/image_file_url_templates.rb +2 -2
  33. data/app/models/pageflow/permalink.rb +39 -0
  34. data/app/models/pageflow/permalink_directory.rb +10 -0
  35. data/app/models/pageflow/published_entry.rb +17 -0
  36. data/app/models/pageflow/revision.rb +1 -1
  37. data/app/models/pageflow/theme_customization_file.rb +6 -1
  38. data/app/models/pageflow/theming.rb +1 -0
  39. data/app/views/admin/entries/_form.html.erb +9 -1
  40. data/app/views/admin/entries/_permalink_inputs.html.erb +6 -0
  41. data/app/views/admin/entries/permalink_inputs.html.erb +7 -0
  42. data/app/views/pageflow/editor/file_import/start_import_job.json.jbuilder +10 -0
  43. data/app/views/pageflow/files/_file.json.jbuilder +1 -0
  44. data/config/initializers/mime_types.rb +1 -0
  45. data/config/routes.rb +8 -5
  46. data/db/migrate/20221024100724_create_pageflow_permalink_directories.rb +10 -0
  47. data/db/migrate/20221025074049_add_permalink_attributes_to_entries.rb +5 -0
  48. data/db/migrate/20221027065022_create_pageflow_permalinks.rb +12 -0
  49. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +166 -169
  50. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +44 -2
  51. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +5 -5
  52. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +1 -1
  53. data/entry_types/paged/config/initializers/features.rb +2 -0
  54. data/entry_types/paged/config/locales/{new/help.de.yml → de.yml} +74 -65
  55. data/entry_types/paged/config/locales/{new/help.en.yml → en.yml} +66 -56
  56. data/entry_types/scrolled/app/helpers/pageflow_scrolled/favicon_helper.rb +39 -13
  57. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +55 -0
  58. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +6 -2
  59. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +2 -0
  60. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/_manifest.json.jbuilder +16 -0
  61. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +9 -3
  62. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +16 -10
  63. data/entry_types/scrolled/config/locales/de.yml +265 -76
  64. data/entry_types/scrolled/config/locales/en.yml +266 -77
  65. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +3 -3
  66. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +14 -0
  67. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +1 -1
  68. data/entry_types/scrolled/lib/pageflow_scrolled/web_app_manifest.rb +11 -0
  69. data/entry_types/scrolled/lib/pageflow_scrolled.rb +39 -1
  70. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +3 -2
  71. data/entry_types/scrolled/package/contentElements-editor.js +124 -38
  72. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  73. data/entry_types/scrolled/package/contentElements-frontend.js +321 -27
  74. data/entry_types/scrolled/package/editor.js +1345 -739
  75. data/entry_types/scrolled/package/frontend/EditableInlineText.module-c6672f27.js +5314 -0
  76. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9fb97827.js → PhonePlatformContext-22e65f92.js} +40 -4
  77. data/entry_types/scrolled/package/frontend/{Viewer-e2290ea0.js → Viewer-6b05522f.js} +6 -40
  78. data/entry_types/scrolled/package/frontend/arrowRight-7e3d9dd5.js +42 -0
  79. data/entry_types/scrolled/package/frontend/{components-6ab26015.js → components-487daafa.js} +546 -361
  80. data/entry_types/scrolled/package/frontend/index.css +1 -1
  81. data/entry_types/scrolled/package/frontend/index.js +197 -3674
  82. data/entry_types/scrolled/package/package.json +3 -2
  83. data/entry_types/scrolled/package/testHelpers.js +12 -2
  84. data/entry_types/scrolled/package/widgets/defaultNavigation.css +1 -1
  85. data/entry_types/scrolled/package/widgets/defaultNavigation.js +35 -32
  86. data/entry_types/scrolled/spec/fixtures/image.ico +0 -0
  87. data/lib/pageflow/entry_type.rb +6 -2
  88. data/lib/pageflow/user_mixin.rb +6 -0
  89. data/lib/pageflow/version.rb +1 -1
  90. data/package/editor.js +122 -149
  91. data/package/frontend.js +19 -2
  92. data/package/testHelpers.js +39 -6
  93. data/spec/factories/entries.rb +17 -0
  94. data/spec/factories/permalink_directory.rb +6 -0
  95. data/spec/factories/permalinks.rb +4 -0
  96. data/spec/factories/published_entries.rb +2 -0
  97. metadata +30 -47
  98. data/entry_types/paged/config/locales/new/video_contain.de.yml +0 -7
  99. data/entry_types/paged/config/locales/new/video_contain.en.yml +0 -7
  100. data/entry_types/scrolled/config/locales/new/before_after_slider.de.yml +0 -8
  101. data/entry_types/scrolled/config/locales/new/before_after_slider.en.yml +0 -8
  102. data/entry_types/scrolled/config/locales/new/center_ragged.de.yml +0 -8
  103. data/entry_types/scrolled/config/locales/new/center_ragged.en.yml +0 -9
  104. data/entry_types/scrolled/config/locales/new/consent.de.yml +0 -25
  105. data/entry_types/scrolled/config/locales/new/consent.en.yml +0 -24
  106. data/entry_types/scrolled/config/locales/new/content_element_categories.de.yml +0 -39
  107. data/entry_types/scrolled/config/locales/new/content_element_categories.en.yml +0 -39
  108. data/entry_types/scrolled/config/locales/new/default_transition.de.yml +0 -14
  109. data/entry_types/scrolled/config/locales/new/default_transition.en.yml +0 -14
  110. data/entry_types/scrolled/config/locales/new/header_line_breaks.de.yml +0 -28
  111. data/entry_types/scrolled/config/locales/new/header_line_breaks.en.yml +0 -27
  112. data/entry_types/scrolled/config/locales/new/header_size.de.yml +0 -17
  113. data/entry_types/scrolled/config/locales/new/header_size.en.yml +0 -17
  114. data/entry_types/scrolled/config/locales/new/iframe_embed.de.yml +0 -39
  115. data/entry_types/scrolled/config/locales/new/iframe_embed.en.yml +0 -39
  116. data/entry_types/scrolled/config/locales/new/inline_loops.de.yml +0 -26
  117. data/entry_types/scrolled/config/locales/new/inline_loops.en.yml +0 -26
  118. data/entry_types/scrolled/config/locales/new/portrait_inline_image.de.yml +0 -9
  119. data/entry_types/scrolled/config/locales/new/portrait_inline_image.en.yml +0 -9
  120. data/entry_types/scrolled/config/locales/new/section_width.de.yml +0 -10
  121. data/entry_types/scrolled/config/locales/new/section_width.en.yml +0 -10
  122. data/entry_types/scrolled/config/locales/new/typography_variants.de.yml +0 -7
  123. data/entry_types/scrolled/config/locales/new/typography_variants.en.yml +0 -7
  124. data/entry_types/scrolled/config/locales/new/video_embed_poster.de.yml +0 -8
  125. data/entry_types/scrolled/config/locales/new/video_embed_poster.en.yml +0 -8
  126. data/entry_types/scrolled/config/locales/new/waveform_styles.de.yml +0 -11
  127. data/entry_types/scrolled/config/locales/new/waveform_styles.en.yml +0 -12
  128. data/entry_types/scrolled/config/locales/new/widgets.de.yml +0 -6
  129. data/entry_types/scrolled/config/locales/new/widgets.en.yml +0 -6
  130. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/browserconfig.xml +0 -9
  131. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/mstile-150x150.png +0 -0
  132. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/safari-pinned-tab.svg +0 -46
  133. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/site.webmanifest +0 -19
  134. data/entry_types/scrolled/package/frontend/EditableInlineText.module-b9923660.js +0 -993
  135. data/entry_types/scrolled/package/frontend/usePhonePlatform-2857c22b.js +0 -34
@@ -1,5 +1,5 @@
1
- import { useContentElementConfigurationUpdate, useI18n, useIsStaticPreview, withShadowClassName, Text, EditableInlineText, frontend, useFile, useContentElementEditorState, FitViewport, ContentElementBox, Figure, useContentElementLifecycle, usePortraitOrientation, Image, usePlayerState, MediaInteractionTracking, useAudioFocus, VideoPlayerControls, VideoPlayer, AudioPlayerControls, AudioPlayer, useMediaMuted, EditableText, ThirdPartyOptOutInfo, ThirdPartyOptIn, useDarkBackground, textColorForBackgroundColor, Panorama, utils } from 'pageflow-scrolled/frontend';
2
- import React, { useState, useEffect, useRef, useCallback } from 'react';
1
+ import { useContentElementConfigurationUpdate, useI18n, withShadowClassName, Text, EditableInlineText, frontend, useFile, useContentElementEditorState, FitViewport, ContentElementBox, Figure, useContentElementLifecycle, usePortraitOrientation, Image, usePlayerState, MediaInteractionTracking, useAudioFocus, VideoPlayerControls, PlayerEventContextDataProvider, VideoPlayer, AudioPlayerControls, AudioPlayer, useMediaMuted, useDarkBackground, EditableText, ThirdPartyOptOutInfo, ThirdPartyOptIn, useAtmo, textColorForBackgroundColor, Panorama, utils, ThemeIcon } from 'pageflow-scrolled/frontend';
2
+ import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react';
3
3
  import classNames from 'classnames';
4
4
  import ReactCompareImage from 'react-compare-image';
5
5
  import Measure from 'react-measure';
@@ -21,7 +21,7 @@ function _defineProperty(obj, key, value) {
21
21
  return obj;
22
22
  }
23
23
 
24
- var styles = {"root":"Heading-module_root__33TFw","right":"Heading-module_right__1TJKF","centerRagged":"Heading-module_centerRagged__388sq","center":"Heading-module_center__38lDY","first":"Heading-module_first__1PMJX"};
24
+ var styles = {"root":"Heading-module_root__33TFw","right":"Heading-module_right__1TJKF","centerRagged":"Heading-module_centerRagged__388sq","center":"Heading-module_center__38lDY","forcePaddingTop":"Heading-module_forcePaddingTop__30Juh"};
25
25
 
26
26
  function Heading(_ref) {
27
27
  var configuration = _ref.configuration,
@@ -35,13 +35,11 @@ function Heading(_ref) {
35
35
  }),
36
36
  t = _useI18n.t;
37
37
 
38
- var isStaticPreview = useIsStaticPreview();
39
- var legacyValue = configuration.children; // Prevent collision with legacy editor rules for h2 elements. We do
40
- // not care about header structure in the static preview thumbnails.
41
-
42
- var Tag = firstSectionInEntry || isStaticPreview ? 'h1' : 'h2';
38
+ var legacyValue = configuration.children;
39
+ var Tag = firstSectionInEntry ? 'h1' : 'h2';
40
+ var forcePaddingTop = firstSectionInEntry && !('marginTop' in configuration);
43
41
  return /*#__PURE__*/React.createElement(Tag, {
44
- className: classNames(styles.root, configuration.typographyVariant && "typography-heading-".concat(configuration.typographyVariant), _defineProperty({}, styles.first, firstSectionInEntry), _defineProperty({}, styles[sectionProps.layout], configuration.position === 'wide' || sectionProps.layout === 'centerRagged'), _defineProperty({}, withShadowClassName, !sectionProps.invert))
42
+ className: classNames(styles.root, configuration.typographyVariant && "typography-heading-".concat(configuration.typographyVariant), _defineProperty({}, styles.forcePaddingTop, forcePaddingTop), _defineProperty({}, styles[sectionProps.layout], configuration.position === 'wide' || sectionProps.layout === 'centerRagged'), _defineProperty({}, withShadowClassName, !sectionProps.invert))
45
43
  }, /*#__PURE__*/React.createElement(Text, {
46
44
  scaleCategory: getScaleCategory(configuration, firstSectionInEntry),
47
45
  inline: true
@@ -327,7 +325,8 @@ function ImageWithCaption(_ref3) {
327
325
  imageFile: imageFile,
328
326
  load: shouldLoad,
329
327
  structuredData: true,
330
- variant: configuration.position === 'full' ? 'large' : 'medium'
328
+ variant: configuration.position === 'full' ? 'large' : 'medium',
329
+ preferSvg: true
331
330
  })))));
332
331
  }
333
332
 
@@ -540,6 +539,9 @@ function Player(_ref2) {
540
539
  configuration: configuration,
541
540
  sectionProps: sectionProps,
542
541
  onPlayerClick: onPlayerClick
542
+ }, /*#__PURE__*/React.createElement(PlayerEventContextDataProvider, {
543
+ playerDescription: "Inline Video",
544
+ playbackMode: configuration.playbackMode || (configuration.autoplay ? 'autoplay' : 'manual')
543
545
  }, /*#__PURE__*/React.createElement(VideoPlayer, {
544
546
  load: shouldPrepare ? 'auto' : shouldLoad ? 'poster' : 'none',
545
547
  loop: configuration.playbackMode === 'loop',
@@ -551,7 +553,7 @@ function Player(_ref2) {
551
553
  quality: 'high',
552
554
  playsInline: true,
553
555
  atmoDuringPlayback: configuration.atmoDuringPlayback
554
- }));
556
+ })));
555
557
  }
556
558
 
557
559
  var fallbackAspectRatio = 0.5625;
@@ -629,6 +631,9 @@ function InlineAudio(_ref) {
629
631
  configuration: configuration,
630
632
  sectionProps: sectionProps,
631
633
  onPlayerClick: onPlayerClick
634
+ }, /*#__PURE__*/React.createElement(PlayerEventContextDataProvider, {
635
+ playerDescription: "Inline Audio",
636
+ playbackMode: configuration.autoplay ? 'autoplay' : 'manual'
632
637
  }, /*#__PURE__*/React.createElement(AudioPlayer, {
633
638
  load: shouldPrepare ? 'auto' : shouldLoad ? 'poster' : 'none',
634
639
  controls: configuration.controls,
@@ -640,7 +645,7 @@ function InlineAudio(_ref) {
640
645
  quality: 'high',
641
646
  playsInline: true,
642
647
  atmoDuringPlayback: configuration.atmoDuringPlayback
643
- }))))));
648
+ })))))));
644
649
  }
645
650
 
646
651
  frontend.contentElementTypes.register('inlineAudio', {
@@ -788,28 +793,30 @@ frontend.contentElementTypes.register('soundDisclaimer', {
788
793
  component: SoundDisclaimer
789
794
  });
790
795
 
791
- var styles$4 = {"text":"TextBlock-module_text__21Hk4","layout-centerRagged":"TextBlock-module_layout-centerRagged__1tjoI"};
796
+ var styles$4 = {"breakpoint-sm":"(min-width: 640px)","text":"TextBlock-module_text__21Hk4","darkBackground":"TextBlock-module_darkBackground__22pEl","layout-centerRagged":"TextBlock-module_layout-centerRagged__1tjoI"};
792
797
 
793
798
  function TextBlock(props) {
794
799
  var updateConfiguration = useContentElementConfigurationUpdate();
800
+ var dark = useDarkBackground();
795
801
 
796
802
  var _useI18n = useI18n({
797
803
  locale: 'ui'
798
804
  }),
799
805
  t = _useI18n.t;
800
806
 
801
- return /*#__PURE__*/React.createElement("div", {
802
- className: classNames(styles$4.text, styles$4["layout-".concat(props.sectionProps.layout)])
803
- }, /*#__PURE__*/React.createElement(EditableText, {
807
+ var className = classNames(styles$4.text, _defineProperty({}, styles$4.darkBackground, dark), styles$4["layout-".concat(props.sectionProps.layout)]);
808
+ return /*#__PURE__*/React.createElement(EditableText, {
804
809
  value: props.configuration.value,
805
810
  contentElementId: props.contentElementId,
811
+ className: className,
812
+ selectionRect: true,
806
813
  placeholder: t('pageflow_scrolled.inline_editing.type_text'),
807
814
  onChange: function onChange(value) {
808
815
  return updateConfiguration({
809
816
  value: value
810
817
  });
811
818
  }
812
- }));
819
+ });
813
820
  }
814
821
 
815
822
  frontend.contentElementTypes.register('textBlock', {
@@ -892,6 +899,11 @@ function PreparedPlayer(_ref2) {
892
899
  setPlayerState('paused');
893
900
  }
894
901
  });
902
+ useContentElementLifecycle({
903
+ onInvisible: function onInvisible() {
904
+ setPlayerState('paused');
905
+ }
906
+ });
895
907
  var posterImageFile = useFile({
896
908
  collectionName: 'imageFiles',
897
909
  permaId: configuration.posterId
@@ -904,6 +916,18 @@ function PreparedPlayer(_ref2) {
904
916
  return [config.hideControls, config.hideInfo].join('');
905
917
  }
906
918
 
919
+ var atmoHooks = useAtmoHooks(configuration.atmoDuringPlayback);
920
+
921
+ function onPlay() {
922
+ setPlayerState('playing');
923
+ atmoHooks.before();
924
+ }
925
+
926
+ function onPauseOrEnd() {
927
+ setPlayerState('paused');
928
+ atmoHooks.after();
929
+ }
930
+
907
931
  return /*#__PURE__*/React.createElement(ThirdPartyOptIn, {
908
932
  providerName: providerName
909
933
  }, function (_ref3) {
@@ -913,20 +937,20 @@ function PreparedPlayer(_ref2) {
913
937
  key: keyFromConfiguration(configuration),
914
938
  url: configuration.videoSource,
915
939
  playing: playerState !== 'paused',
916
- onPlay: function onPlay() {
917
- return setPlayerState('playing');
918
- },
919
- onPause: function onPause() {
920
- return setPlayerState('paused');
921
- },
922
- onEnded: function onEnded() {
923
- return setPlayerState('paused');
924
- },
940
+ onPlay: onPlay,
941
+ onPause: onPauseOrEnd,
942
+ onEnded: onPauseOrEnd,
925
943
  light: !consentedHere && playerState === 'unplayed' ? posterUrl || true : false,
926
944
  width: "100%",
927
945
  height: "100%",
928
946
  controls: !configuration.hideControls,
929
947
  config: {
948
+ // ReactPlayer does not rerender when only
949
+ // event handler props change. Since event
950
+ // handlers depend on latest value of
951
+ // atmoDuringPlayback, we force a render by
952
+ // changing this unused config option.
953
+ _unused: configuration.atmoDuringPlayback,
930
954
  youtube: {
931
955
  playerVars: {
932
956
  showinfo: !configuration.hideInfo
@@ -942,6 +966,39 @@ function PreparedPlayer(_ref2) {
942
966
  });
943
967
  }
944
968
 
969
+ function useAtmoHooks(atmoDuringPlayback) {
970
+ var atmo = useAtmo();
971
+ return useMemo(function () {
972
+ var _ref4 = atmo.createMediaPlayerHooks(atmoDuringPlayback) || {
973
+ before: function before() {},
974
+ after: function after() {}
975
+ },
976
+ _before = _ref4.before,
977
+ _after = _ref4.after;
978
+
979
+ var timeout;
980
+ return {
981
+ before: function before() {
982
+ if (timeout) {
983
+ clearTimeout(timeout);
984
+ timeout = null;
985
+ } else {
986
+ _before();
987
+ }
988
+ },
989
+ after: function after() {
990
+ // When seeking in the video pause and play events
991
+ // fired. Prevent briefly fading the atmo back in.
992
+ timeout = setTimeout(function () {
993
+ _after();
994
+
995
+ timeout = null;
996
+ }, 1000);
997
+ }
998
+ };
999
+ }, [atmo, atmoDuringPlayback]);
1000
+ }
1001
+
945
1002
  frontend.contentElementTypes.register('videoEmbed', {
946
1003
  component: VideoEmbed,
947
1004
  lifecycle: true,
@@ -1064,7 +1121,7 @@ function ExternalLinkList(props) {
1064
1121
 
1065
1122
  var darkBackground = useDarkBackground();
1066
1123
  return /*#__PURE__*/React.createElement("div", {
1067
- className: styles$7.ext_links_container
1124
+ className: classNames(styles$7.ext_links_container, props.configuration.variant && "scope-externalLinkList-".concat(props.configuration.variant))
1068
1125
  }, linkList.map(function (link, index) {
1069
1126
  return /*#__PURE__*/React.createElement(ExternalLink, Object.assign({}, link, {
1070
1127
  key: link.id,
@@ -1357,3 +1414,240 @@ frontend.contentElementTypes.register('iframeEmbed', {
1357
1414
  component: IframeEmbed,
1358
1415
  lifecycle: true
1359
1416
  });
1417
+
1418
+ var styles$a = {"wrapper":"Placeholder-module_wrapper__jRFYE","row":"Placeholder-module_row__1SBRB","item":"Placeholder-module_item__RozmQ","load":"Placeholder-module_load__uFpxr","avatar":"Placeholder-module_avatar__2VeHz Placeholder-module_item__RozmQ","info":"Placeholder-module_info__37csK","name":"Placeholder-module_name__2T6as Placeholder-module_item__RozmQ","handle":"Placeholder-module_handle__2WwoF Placeholder-module_item__RozmQ","text":"Placeholder-module_text__DWLME Placeholder-module_item__RozmQ"};
1419
+
1420
+ function _extends$2() {
1421
+ _extends$2 = Object.assign || function (target) {
1422
+ for (var i = 1; i < arguments.length; i++) {
1423
+ var source = arguments[i];
1424
+
1425
+ for (var key in source) {
1426
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1427
+ target[key] = source[key];
1428
+ }
1429
+ }
1430
+ }
1431
+
1432
+ return target;
1433
+ };
1434
+
1435
+ return _extends$2.apply(this, arguments);
1436
+ }
1437
+ var Icon = (function (_ref) {
1438
+ var _ref$styles = _ref.styles,
1439
+ styles = _ref$styles === void 0 ? {} : _ref$styles,
1440
+ props = _objectWithoutProperties(_ref, ["styles"]);
1441
+
1442
+ return /*#__PURE__*/React.createElement("svg", _extends$2({
1443
+ viewBox: "0 0 24 24",
1444
+ "aria-hidden": "true",
1445
+ className: (styles["r-1cvl2hr"] || "r-1cvl2hr") + " " + (styles["r-4qtqp9"] || "r-4qtqp9") + " " + (styles["r-yyyyoo"] || "r-yyyyoo") + " " + (styles["r-6zzn7w"] || "r-6zzn7w") + " " + (styles["r-19fsva8"] || "r-19fsva8") + " " + (styles["r-dnmrzs"] || "r-dnmrzs") + " " + (styles["r-bnwqim"] || "r-bnwqim") + " " + (styles["r-1plcrui"] || "r-1plcrui") + " " + (styles["r-lrvibr"] || "r-lrvibr") + " " + (styles["r-q1j0wu"] || "r-q1j0wu")
1446
+ }, props), /*#__PURE__*/React.createElement("path", {
1447
+ d: "M23.643 4.937c-.835.37-1.732.62-2.675.733a4.67 4.67 0 002.048-2.578 9.3 9.3 0 01-2.958 1.13 4.66 4.66 0 00-7.938 4.25 13.229 13.229 0 01-9.602-4.868c-.4.69-.63 1.49-.63 2.342A4.66 4.66 0 003.96 9.824a4.647 4.647 0 01-2.11-.583v.06a4.66 4.66 0 003.737 4.568 4.692 4.692 0 01-2.104.08 4.661 4.661 0 004.352 3.234 9.348 9.348 0 01-5.786 1.995 9.5 9.5 0 01-1.112-.065 13.175 13.175 0 007.14 2.093c8.57 0 13.255-7.098 13.255-13.254 0-.2-.005-.402-.014-.602a9.47 9.47 0 002.323-2.41z"
1448
+ }));
1449
+ });
1450
+
1451
+ function Placeholder(_ref) {
1452
+ var children = _ref.children,
1453
+ minHeight = _ref.minHeight;
1454
+ return /*#__PURE__*/React.createElement("div", {
1455
+ className: styles$a.wrapper,
1456
+ style: {
1457
+ minHeight: minHeight
1458
+ }
1459
+ }, /*#__PURE__*/React.createElement("div", {
1460
+ className: styles$a.row
1461
+ }, /*#__PURE__*/React.createElement("div", {
1462
+ className: styles$a.avatar
1463
+ }), /*#__PURE__*/React.createElement("div", {
1464
+ className: styles$a.info
1465
+ }, /*#__PURE__*/React.createElement("div", {
1466
+ className: styles$a.name
1467
+ }), /*#__PURE__*/React.createElement("div", {
1468
+ className: styles$a.handle
1469
+ })), /*#__PURE__*/React.createElement(Icon, {
1470
+ width: 24,
1471
+ height: 24
1472
+ })), children || /*#__PURE__*/React.createElement("div", {
1473
+ className: styles$a.text
1474
+ }));
1475
+ }
1476
+
1477
+ var styles$b = {"loadingContainer":"TwitterEmbed-module_loadingContainer__3Ozs_","container":"TwitterEmbed-module_container__380cX"};
1478
+
1479
+ function TwitterEmbed(_ref) {
1480
+ var configuration = _ref.configuration;
1481
+ var url = configuration.url,
1482
+ hideConversation = configuration.hideConversation,
1483
+ hideMedia = configuration.hideMedia;
1484
+
1485
+ var _useContentElementEdi = useContentElementEditorState(),
1486
+ isEditable = _useContentElementEdi.isEditable,
1487
+ isSelected = _useContentElementEdi.isSelected;
1488
+
1489
+ var _useContentElementLif = useContentElementLifecycle(),
1490
+ shouldLoad = _useContentElementLif.shouldLoad;
1491
+
1492
+ var _useState = useState({}),
1493
+ _useState2 = _slicedToArray(_useState, 2),
1494
+ minHeight = _useState2[0],
1495
+ setMinHeight = _useState2[1];
1496
+
1497
+ var key = [url, hideConversation, hideMedia].join('-');
1498
+ var onLoad = useCallback(function (_ref2) {
1499
+ var height = _ref2.height;
1500
+ setMinHeight(_defineProperty({}, key, height));
1501
+ }, [key]);
1502
+ return /*#__PURE__*/React.createElement(ContentElementBox, null, /*#__PURE__*/React.createElement("div", {
1503
+ style: {
1504
+ pointerEvents: isEditable && !isSelected ? 'none' : undefined
1505
+ }
1506
+ }, shouldLoad ? /*#__PURE__*/React.createElement(ThirdPartyOptIn, {
1507
+ providerName: "twitter",
1508
+ icon: false,
1509
+ wrapper: function wrapper(children) {
1510
+ return /*#__PURE__*/React.createElement(Placeholder, null, children);
1511
+ }
1512
+ }, /*#__PURE__*/React.createElement(Tweet, {
1513
+ key: key,
1514
+ url: url,
1515
+ hideConversation: hideConversation,
1516
+ hideMedia: hideMedia,
1517
+ minHeight: minHeight[key],
1518
+ onLoad: onLoad
1519
+ })) : /*#__PURE__*/React.createElement(Placeholder, {
1520
+ minHeight: minHeight[key]
1521
+ }), /*#__PURE__*/React.createElement(ThirdPartyOptOutInfo, {
1522
+ providerName: "twitter",
1523
+ contentElementPosition: configuration.position
1524
+ })));
1525
+ }
1526
+
1527
+ function scriptLoaded() {
1528
+ var promise = new Promise(function (resolve) {
1529
+ var script = document.createElement("script");
1530
+ script.src = "https://platform.twitter.com/widgets.js";
1531
+ script.addEventListener('load', resolve);
1532
+ document.head.appendChild(script);
1533
+ });
1534
+ return promise;
1535
+ }
1536
+
1537
+ function Tweet(_ref3) {
1538
+ var url = _ref3.url,
1539
+ hideConversation = _ref3.hideConversation,
1540
+ hideMedia = _ref3.hideMedia,
1541
+ minHeight = _ref3.minHeight,
1542
+ onLoad = _ref3.onLoad;
1543
+ var ref = useRef(null);
1544
+ var tweetId = url ? url.split('/')[5] : undefined;
1545
+
1546
+ var _useState3 = useState(false),
1547
+ _useState4 = _slicedToArray(_useState3, 2),
1548
+ loaded = _useState4[0],
1549
+ setLoaded = _useState4[1];
1550
+
1551
+ useEffect(function () {
1552
+ var isComponentMounted = true;
1553
+ var options = {
1554
+ cards: hideMedia ? "hidden" : "",
1555
+ conversation: hideConversation ? "none" : ""
1556
+ };
1557
+ scriptLoaded().then(function () {
1558
+ if (window.twttr.widgets && tweetId) {
1559
+ if (isComponentMounted) {
1560
+ if (window.twttr.widgets['createTweetEmbed']) {
1561
+ window.twttr.widgets.createTweet(tweetId, ref.current, options).then(function () {
1562
+ var _ref$current;
1563
+
1564
+ setLoaded(true);
1565
+ onLoad({
1566
+ height: (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.clientHeight
1567
+ });
1568
+ });
1569
+ }
1570
+ }
1571
+ }
1572
+ });
1573
+ return function () {
1574
+ return isComponentMounted = false;
1575
+ };
1576
+ }, [hideMedia, hideConversation, tweetId, onLoad]);
1577
+ return /*#__PURE__*/React.createElement(React.Fragment, null, !loaded && /*#__PURE__*/React.createElement(Placeholder, {
1578
+ minHeight: minHeight
1579
+ }), /*#__PURE__*/React.createElement("div", {
1580
+ ref: ref,
1581
+ className: classNames(styles$b.container, _defineProperty({}, styles$b.loadingContainer, !loaded))
1582
+ }));
1583
+ }
1584
+
1585
+ frontend.contentElementTypes.register('twitterEmbed', {
1586
+ component: TwitterEmbed,
1587
+ lifecycle: true,
1588
+ consentVendors: function consentVendors(_ref) {
1589
+ var t = _ref.t;
1590
+ var prefix = 'pageflow_scrolled.public.twitter';
1591
+ return [{
1592
+ name: 'twitter',
1593
+ displayName: t("".concat(prefix, ".consent_vendor_name")),
1594
+ description: t("".concat(prefix, ".consent_vendor_description")),
1595
+ paradigm: 'lazy opt-in'
1596
+ }];
1597
+ }
1598
+ });
1599
+
1600
+ var styles$c = {"details":"Question-module_details__3FxH-","layout-centerRagged":"Question-module_layout-centerRagged__1hovs"};
1601
+
1602
+ function Question(_ref) {
1603
+ var configuration = _ref.configuration,
1604
+ contentElementId = _ref.contentElementId,
1605
+ sectionProps = _ref.sectionProps;
1606
+ var updateConfiguration = useContentElementConfigurationUpdate();
1607
+
1608
+ var _useI18n = useI18n({
1609
+ locale: 'ui'
1610
+ }),
1611
+ t = _useI18n.t;
1612
+
1613
+ var _useContentElementEdi = useContentElementEditorState(),
1614
+ isEditable = _useContentElementEdi.isEditable,
1615
+ isSelected = _useContentElementEdi.isSelected;
1616
+
1617
+ return /*#__PURE__*/React.createElement("details", {
1618
+ open: configuration.expandByDefault || isEditable && isSelected,
1619
+ className: classNames(styles$c.details, styles$c["layout-".concat(sectionProps.layout)])
1620
+ }, /*#__PURE__*/React.createElement("summary", {
1621
+ onClick: isEditable ? function (event) {
1622
+ return event.preventDefault();
1623
+ } : undefined
1624
+ }, /*#__PURE__*/React.createElement(ThemeIcon, {
1625
+ name: "expand"
1626
+ }), /*#__PURE__*/React.createElement(Text, {
1627
+ scaleCategory: "question"
1628
+ }, /*#__PURE__*/React.createElement(EditableInlineText, {
1629
+ value: configuration.question,
1630
+ onChange: function onChange(question) {
1631
+ return updateConfiguration({
1632
+ question: question
1633
+ });
1634
+ },
1635
+ hyphens: "none",
1636
+ placeholder: t('pageflow_scrolled.inline_editing.type_question')
1637
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(EditableText, {
1638
+ value: configuration.answer,
1639
+ contentElementId: contentElementId,
1640
+ onChange: function onChange(answer) {
1641
+ return updateConfiguration({
1642
+ answer: answer
1643
+ });
1644
+ },
1645
+ onlyParagraphs: true,
1646
+ hyphens: "none",
1647
+ placeholder: t('pageflow_scrolled.inline_editing.type_answer')
1648
+ })));
1649
+ }
1650
+
1651
+ frontend.contentElementTypes.register('question', {
1652
+ component: Question
1653
+ });