pageflow 0.11.4 → 12.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pageflow might be problematic. Click here for more details.

Files changed (416) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +224 -1207
  3. data/README.md +7 -3
  4. data/Rakefile +2 -0
  5. data/admins/pageflow/accounts.rb +27 -8
  6. data/admins/pageflow/entry.rb +130 -47
  7. data/admins/pageflow/folder.rb +28 -17
  8. data/admins/pageflow/membership.rb +58 -6
  9. data/admins/pageflow/user.rb +105 -98
  10. data/app/assets/fonts/pageflow/fontawesome-webfont.eot +0 -0
  11. data/app/assets/fonts/pageflow/fontawesome-webfont.svg +644 -463
  12. data/app/assets/fonts/pageflow/fontawesome-webfont.ttf +0 -0
  13. data/app/assets/fonts/pageflow/fontawesome-webfont.woff +0 -0
  14. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.eot +0 -0
  15. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.svg +2864 -696
  16. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.ttf +0 -0
  17. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.woff +0 -0
  18. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.eot +0 -0
  19. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.svg +2572 -613
  20. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.ttf +0 -0
  21. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.woff +0 -0
  22. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.eot +0 -0
  23. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.svg +2977 -779
  24. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.ttf +0 -0
  25. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.woff +0 -0
  26. data/app/assets/javascripts/pageflow/admin/entries.js +21 -3
  27. data/app/assets/javascripts/pageflow/audio.js +30 -15
  28. data/app/assets/javascripts/pageflow/audio/multi_player.js +12 -1
  29. data/app/assets/javascripts/pageflow/audio_player.js +15 -1
  30. data/app/assets/javascripts/pageflow/audio_player/rewind_method.js +3 -1
  31. data/app/assets/javascripts/pageflow/base.js +4 -1
  32. data/app/assets/javascripts/pageflow/browser.js +3 -0
  33. data/app/assets/javascripts/pageflow/browser/autoplay_support.js +3 -0
  34. data/app/assets/javascripts/pageflow/browser/facebook.js +1 -2
  35. data/app/assets/javascripts/pageflow/browser/ios_platform.js +5 -0
  36. data/app/assets/javascripts/pageflow/browser/video.js +4 -0
  37. data/app/assets/javascripts/pageflow/components.js +7 -0
  38. data/app/assets/javascripts/pageflow/cookies.js +1 -4
  39. data/app/assets/javascripts/pageflow/dist/react.js +4724 -5808
  40. data/app/assets/javascripts/pageflow/editor/api.js +201 -161
  41. data/app/assets/javascripts/pageflow/editor/api/errors.js +80 -0
  42. data/app/assets/javascripts/pageflow/editor/api/failure.js +9 -0
  43. data/app/assets/javascripts/pageflow/editor/api/failures.js +25 -2
  44. data/app/assets/javascripts/pageflow/editor/api/file_type.js +42 -3
  45. data/app/assets/javascripts/pageflow/editor/api/file_types.js +75 -46
  46. data/app/assets/javascripts/pageflow/editor/base.js +8 -0
  47. data/app/assets/javascripts/pageflow/editor/collections/file_types_collection.js +37 -0
  48. data/app/assets/javascripts/pageflow/editor/collections/files_collection.js +32 -1
  49. data/app/assets/javascripts/pageflow/editor/collections/mixins/ordered_collection.js +1 -1
  50. data/app/assets/javascripts/pageflow/editor/collections/multi_collection.js +4 -6
  51. data/app/assets/javascripts/pageflow/editor/collections/nested_files_collection.js +27 -0
  52. data/app/assets/javascripts/pageflow/editor/collections/pages_collection.js +21 -1
  53. data/app/assets/javascripts/pageflow/editor/collections/subset_collection.js +8 -2
  54. data/app/assets/javascripts/pageflow/editor/controllers/sidebar_controller.js +3 -2
  55. data/app/assets/javascripts/pageflow/editor/initializers/error_listener.js +10 -5
  56. data/app/assets/javascripts/pageflow/editor/initializers/routing.js +3 -1
  57. data/app/assets/javascripts/pageflow/editor/initializers/setup_collections.js +3 -0
  58. data/app/assets/javascripts/pageflow/editor/initializers/setup_file_types.js +136 -6
  59. data/app/assets/javascripts/pageflow/editor/initializers/setup_file_uploader.js +10 -0
  60. data/app/assets/javascripts/pageflow/editor/initializers/setup_hotkeys.js +5 -7
  61. data/app/assets/javascripts/pageflow/editor/initializers/stylesheet_reloading.js +1 -1
  62. data/app/assets/javascripts/pageflow/editor/models/configuration.js +1 -0
  63. data/app/assets/javascripts/pageflow/editor/models/entry.js +34 -26
  64. data/app/assets/javascripts/pageflow/editor/models/file_configuration.js +10 -0
  65. data/app/assets/javascripts/pageflow/editor/models/file_reuse.js +23 -0
  66. data/app/assets/javascripts/pageflow/editor/models/file_uploader.js +69 -0
  67. data/app/assets/javascripts/pageflow/editor/models/mixins/retryable.js +1 -1
  68. data/app/assets/javascripts/pageflow/editor/models/page.js +13 -0
  69. data/app/assets/javascripts/pageflow/editor/models/text_track_file.js +48 -0
  70. data/app/assets/javascripts/pageflow/editor/models/uploaded_file.js +62 -11
  71. data/app/assets/javascripts/pageflow/editor/routers/sidebar_router.js +1 -0
  72. data/app/assets/javascripts/pageflow/editor/templates/confirm_upload.jst.ejs +18 -0
  73. data/app/assets/javascripts/pageflow/editor/templates/delete_row_table_cell.jst.ejs +1 -0
  74. data/app/assets/javascripts/pageflow/editor/templates/drop_down_button.jst.ejs +0 -2
  75. data/app/assets/javascripts/pageflow/editor/templates/drop_down_button_item.jst.ejs +1 -0
  76. data/app/assets/javascripts/pageflow/editor/templates/edit_entry.jst.ejs +3 -1
  77. data/app/assets/javascripts/pageflow/editor/templates/edit_file.jst.ejs +0 -0
  78. data/app/assets/javascripts/pageflow/editor/templates/file_item.jst.ejs +1 -6
  79. data/app/assets/javascripts/pageflow/editor/templates/file_meta_data_item_value_view.jst.ejs +3 -0
  80. data/app/assets/javascripts/pageflow/editor/templates/file_settings_dialog.jst.ejs +10 -0
  81. data/app/assets/javascripts/pageflow/editor/templates/files_blank_slate.jst.ejs +1 -1
  82. data/app/assets/javascripts/pageflow/editor/templates/filtered_files.jst.ejs +10 -0
  83. data/app/assets/javascripts/pageflow/{ui → editor}/templates/inputs/file_input.jst.ejs +1 -1
  84. data/app/assets/javascripts/pageflow/editor/templates/inputs/reference.jst.ejs +2 -2
  85. data/app/assets/javascripts/pageflow/editor/templates/nested_files.jst.ejs +1 -0
  86. data/app/assets/javascripts/pageflow/editor/templates/table_cell.jst.ejs +0 -0
  87. data/app/assets/javascripts/pageflow/editor/templates/text_tracks.jst.ejs +13 -0
  88. data/app/assets/javascripts/pageflow/editor/templates/uploadable_files.jst.ejs +1 -0
  89. data/app/assets/javascripts/pageflow/editor/utils/form_data_utils.js +19 -0
  90. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/audio.js +5 -2
  91. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/background_image.js +3 -2
  92. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/background.js +35 -0
  93. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/options.js +7 -9
  94. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/video.js +6 -5
  95. data/app/assets/javascripts/pageflow/editor/views/confirm_upload_view.js +69 -0
  96. data/app/assets/javascripts/pageflow/editor/views/confirmable_file_item_view.js +1 -1
  97. data/app/assets/javascripts/pageflow/editor/views/drop_down_button_item_list_view.js +9 -0
  98. data/app/assets/javascripts/pageflow/editor/views/drop_down_button_item_view.js +14 -1
  99. data/app/assets/javascripts/pageflow/editor/views/drop_down_button_view.js +51 -20
  100. data/app/assets/javascripts/pageflow/editor/views/edit_entry_view.js +21 -2
  101. data/app/assets/javascripts/pageflow/editor/views/edit_file_view.js +52 -0
  102. data/app/assets/javascripts/pageflow/editor/views/edit_storyline_view.js +1 -1
  103. data/app/assets/javascripts/pageflow/editor/views/entry_preview_view.js +15 -7
  104. data/app/assets/javascripts/pageflow/editor/views/file_item_view.js +33 -22
  105. data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_value_view.js +49 -0
  106. data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_view.js +16 -5
  107. data/app/assets/javascripts/pageflow/editor/views/file_settings_dialog_view.js +31 -0
  108. data/app/assets/javascripts/pageflow/editor/views/files_explorer_view.js +6 -7
  109. data/app/assets/javascripts/pageflow/editor/views/files_view.js +13 -14
  110. data/app/assets/javascripts/pageflow/editor/views/filtered_files_view.js +75 -0
  111. data/app/assets/javascripts/pageflow/editor/views/help_view.js +3 -0
  112. data/app/assets/javascripts/pageflow/editor/views/inputs/file_input_view.js +217 -0
  113. data/app/assets/javascripts/pageflow/editor/views/inputs/page_link_input_view.js +6 -0
  114. data/app/assets/javascripts/pageflow/editor/views/inputs/reference_input_view.js +13 -2
  115. data/app/assets/javascripts/pageflow/editor/views/list_view.js +24 -14
  116. data/app/assets/javascripts/pageflow/editor/views/model_thumbnail_view.js +4 -1
  117. data/app/assets/javascripts/pageflow/editor/views/nested_files_view.js +94 -0
  118. data/app/assets/javascripts/pageflow/editor/views/page_preview_view.js +7 -2
  119. data/app/assets/javascripts/pageflow/editor/views/text_file_meta_data_item_value_view.js +25 -0
  120. data/app/assets/javascripts/pageflow/editor/views/text_tracks_file_meta_data_item_value_view.js +12 -0
  121. data/app/assets/javascripts/pageflow/editor/views/text_tracks_view.js +65 -0
  122. data/app/assets/javascripts/pageflow/editor/views/uploadable_files_view.js +56 -0
  123. data/app/assets/javascripts/pageflow/editor/views/uploader_view.js +13 -10
  124. data/app/assets/javascripts/pageflow/features.js +8 -12
  125. data/app/assets/javascripts/pageflow/focus_outline.js +2 -0
  126. data/app/assets/javascripts/pageflow/media_player/volume_binding.js +2 -0
  127. data/app/assets/javascripts/pageflow/media_player/volume_fading.js +6 -0
  128. data/app/assets/javascripts/pageflow/page_type.js +0 -1
  129. data/app/assets/javascripts/pageflow/phone_landscape_fullscreen.js +34 -0
  130. data/app/assets/javascripts/pageflow/react.js +4 -0
  131. data/app/assets/javascripts/pageflow/ready.js +3 -0
  132. data/app/assets/javascripts/pageflow/seed_entry_data.js +4 -1
  133. data/app/assets/javascripts/pageflow/slideshow.js +1 -0
  134. data/app/assets/javascripts/pageflow/slideshow/adjacent_preparer.js +7 -5
  135. data/app/assets/javascripts/pageflow/slideshow/atmo.js +3 -3
  136. data/app/assets/javascripts/pageflow/slideshow/hidden_text_indicator_widget.js +4 -2
  137. data/app/assets/javascripts/pageflow/slideshow/hide_text.js +8 -4
  138. data/app/assets/javascripts/pageflow/slideshow/lazy_page_widget.js +5 -0
  139. data/app/assets/javascripts/pageflow/slideshow/scroller_widget.js +11 -18
  140. data/app/assets/javascripts/pageflow/ui.js +6 -0
  141. data/app/assets/javascripts/pageflow/ui/templates/inputs/url_display.jst.ejs +7 -0
  142. data/app/assets/javascripts/pageflow/ui/templates/table.jst.ejs +7 -0
  143. data/app/assets/javascripts/pageflow/ui/templates/table_blank_slate.jst.ejs +3 -0
  144. data/app/assets/javascripts/pageflow/ui/utils/i18n_utils.js +97 -2
  145. data/app/assets/javascripts/pageflow/ui/views/collection_view.js +8 -1
  146. data/app/assets/javascripts/pageflow/ui/views/inputs/check_box_input_view.js +12 -1
  147. data/app/assets/javascripts/pageflow/ui/views/inputs/proxy_url_input_view.js +51 -5
  148. data/app/assets/javascripts/pageflow/ui/views/inputs/select_input_view.js +80 -2
  149. data/app/assets/javascripts/pageflow/ui/views/inputs/slider_input_view.js +8 -1
  150. data/app/assets/javascripts/pageflow/ui/views/inputs/text_area_input_view.js +17 -1
  151. data/app/assets/javascripts/pageflow/ui/views/inputs/text_input_view.js +47 -4
  152. data/app/assets/javascripts/pageflow/ui/views/inputs/url_display_view.js +42 -0
  153. data/app/assets/javascripts/pageflow/ui/views/inputs/url_input_view.js +20 -2
  154. data/app/assets/javascripts/pageflow/ui/views/mixins/input_view.js +74 -46
  155. data/app/assets/javascripts/pageflow/ui/views/table_cells/delete_row_table_cell_view.js +63 -0
  156. data/app/assets/javascripts/pageflow/ui/views/table_cells/enum_table_cell_view.js +26 -0
  157. data/app/assets/javascripts/pageflow/ui/views/table_cells/icon_table_cell_view.js +40 -0
  158. data/app/assets/javascripts/pageflow/ui/views/table_cells/presence_table_cell_view.js +31 -0
  159. data/app/assets/javascripts/pageflow/ui/views/table_cells/table_cell_view.js +101 -0
  160. data/app/assets/javascripts/pageflow/ui/views/table_cells/table_header_cell_view.js +10 -0
  161. data/app/assets/javascripts/pageflow/ui/views/table_cells/text_table_cell_view.js +46 -0
  162. data/app/assets/javascripts/pageflow/ui/views/table_row_view.js +47 -0
  163. data/app/assets/javascripts/pageflow/ui/views/table_view.js +47 -0
  164. data/app/assets/javascripts/pageflow/video_player.js +9 -5
  165. data/app/assets/javascripts/pageflow/video_player/buffer_underrun_waiting.js +15 -13
  166. data/app/assets/javascripts/pageflow/video_player/cue_settings_methods.js +33 -0
  167. data/app/assets/javascripts/pageflow/video_player/dash.js +3 -0
  168. data/app/assets/javascripts/pageflow/video_player/filter_sources.js +1 -1
  169. data/app/assets/javascripts/pageflow/video_player/lazy.js +3 -9
  170. data/app/assets/javascripts/pageflow/video_player/prebuffering.js +11 -2
  171. data/app/assets/javascripts/pageflow/video_player/use_slim_controls_during_phone_playback.js +16 -0
  172. data/app/assets/javascripts/pageflow/videojs.js +6 -0
  173. data/app/assets/javascripts/pageflow/widgets.js +41 -7
  174. data/app/assets/stylesheets/pageflow/admin.scss +7 -4
  175. data/app/assets/stylesheets/pageflow/admin/{entries/user_badge_list.scss → badge_list.scss} +6 -9
  176. data/app/assets/stylesheets/pageflow/admin/embed_code.scss +13 -0
  177. data/app/assets/stylesheets/pageflow/admin/entries.scss +1 -2
  178. data/app/assets/stylesheets/pageflow/admin/hint.scss +20 -0
  179. data/app/assets/stylesheets/pageflow/admin/tooltip_bubble.scss +34 -0
  180. data/app/assets/stylesheets/pageflow/editor/base.scss +4 -4
  181. data/app/assets/stylesheets/pageflow/editor/confirm_upload.scss +66 -0
  182. data/app/assets/stylesheets/pageflow/editor/dialogs.scss +9 -1
  183. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +56 -20
  184. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +26 -6
  185. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +32 -0
  186. data/app/assets/stylesheets/pageflow/editor/files.scss +5 -0
  187. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +25 -0
  188. data/app/assets/stylesheets/pageflow/editor/inputs.scss +2 -1
  189. data/app/assets/stylesheets/pageflow/editor/inputs/file_input.scss +65 -0
  190. data/app/assets/stylesheets/pageflow/editor/inputs/reference.scss +2 -2
  191. data/app/assets/stylesheets/pageflow/editor/text_tracks.scss +39 -0
  192. data/app/assets/stylesheets/pageflow/entries.scss +1 -0
  193. data/app/assets/stylesheets/pageflow/mixins/buttons.scss +77 -5
  194. data/app/assets/stylesheets/pageflow/mixins/icons/fontawesome.scss +3 -1
  195. data/app/assets/stylesheets/pageflow/page_types.scss +0 -4
  196. data/app/assets/stylesheets/pageflow/page_types/video.scss +5 -1
  197. data/app/assets/stylesheets/pageflow/page_types/video/content_hiding.scss +1 -0
  198. data/app/assets/stylesheets/pageflow/themes/default/base.scss +1 -0
  199. data/app/assets/stylesheets/pageflow/themes/default/built_in_page_types.scss +0 -2
  200. data/app/assets/stylesheets/pageflow/themes/default/definitions.scss +1 -0
  201. data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +31 -12
  202. data/app/assets/stylesheets/pageflow/themes/default/logo.scss +9 -1
  203. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/background_image.scss +8 -2
  204. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +21 -0
  205. data/app/assets/stylesheets/pageflow/themes/default/mixins/cue_margins.scss +43 -0
  206. data/app/assets/stylesheets/pageflow/themes/default/mixins/indicator_typography.scss +7 -3
  207. data/app/assets/stylesheets/pageflow/themes/default/page.scss +20 -2
  208. data/app/assets/stylesheets/pageflow/themes/default/player_controls.scss +4 -0
  209. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic.scss +4 -0
  210. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/container.scss +8 -6
  211. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/control_bar.scss +18 -3
  212. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/cue_margins.scss +1 -0
  213. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/icons/custom.scss +14 -0
  214. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/icons/icon_font.scss +4 -0
  215. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/icons/sprite.scss +4 -0
  216. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/info_box.scss +2 -2
  217. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/menu_bar.scss +5 -0
  218. data/app/assets/stylesheets/pageflow/themes/default/player_controls/shared/menu_bar.scss +121 -0
  219. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim.scss +2 -0
  220. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/container.scss +2 -0
  221. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/control_bar.scss +74 -12
  222. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/cue_margins.scss +3 -0
  223. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/info_box.scss +31 -5
  224. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/menu_bar.scss +13 -0
  225. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/quality_menu.scss +116 -0
  226. data/app/assets/stylesheets/pageflow/themes/default/player_controls/vjs_mapping.scss +13 -3
  227. data/app/assets/stylesheets/pageflow/themes/default/player_controls/widget_margins.scss +8 -3
  228. data/app/assets/stylesheets/pageflow/themes/default/text_track_cues.scss +25 -0
  229. data/app/assets/stylesheets/pageflow/themes/default/variables/widgets.scss +2 -2
  230. data/app/assets/stylesheets/pageflow/themes/default/video_player/vjs_base.scss +122 -79
  231. data/app/assets/stylesheets/pageflow/themes/default/video_wrapper.scss +16 -7
  232. data/app/assets/stylesheets/pageflow/ui.scss +5 -1
  233. data/app/assets/stylesheets/pageflow/ui/forms.scss +5 -58
  234. data/app/assets/stylesheets/pageflow/ui/table_cells/delete_row_table_cell.scss +7 -0
  235. data/app/assets/stylesheets/pageflow/ui/table_cells/icon_table_cell.scss +16 -0
  236. data/app/assets/stylesheets/pageflow/ui/table_cells/presence_table_cell.scss +8 -0
  237. data/app/assets/stylesheets/pageflow/ui/table_view.scss +33 -0
  238. data/app/assets/stylesheets/pageflow/ui/tooltip.scss +1 -1
  239. data/app/controllers/pageflow/editor/encoding_confirmations_controller.rb +3 -3
  240. data/app/controllers/pageflow/editor/entry_publications_controller.rb +3 -3
  241. data/app/controllers/pageflow/editor/files_controller.rb +72 -14
  242. data/app/controllers/pageflow/editor/widgets_controller.rb +1 -1
  243. data/app/controllers/pageflow/entries_controller.rb +12 -2
  244. data/app/controllers/pageflow/files_controller.rb +1 -1
  245. data/app/helpers/pageflow/admin/entries_helper.rb +17 -0
  246. data/app/helpers/pageflow/admin/form_helper.rb +1 -1
  247. data/app/helpers/pageflow/admin/memberships_helper.rb +117 -13
  248. data/app/helpers/pageflow/common_entry_seed_helper.rb +36 -5
  249. data/app/helpers/pageflow/embed_code_helper.rb +32 -0
  250. data/app/helpers/pageflow/entries_helper.rb +1 -1
  251. data/app/helpers/pageflow/entry_json_seed_helper.rb +6 -16
  252. data/app/helpers/pageflow/files_helper.rb +5 -2
  253. data/app/helpers/pageflow/folders_helper.rb +26 -2
  254. data/app/helpers/pageflow/page_background_asset_helper.rb +8 -0
  255. data/app/helpers/pageflow/quota_helper.rb +1 -1
  256. data/app/helpers/pageflow/video_files_helper.rb +0 -5
  257. data/app/jobs/pageflow/poll_zencoder_job.rb +1 -1
  258. data/app/jobs/pageflow/process_file_job.rb +18 -0
  259. data/app/mailers/pageflow/user_mailer.rb +4 -2
  260. data/app/models/concerns/pageflow/hosted_file.rb +9 -0
  261. data/app/models/concerns/pageflow/output_source.rb +60 -0
  262. data/app/models/concerns/pageflow/uploaded_file.rb +33 -5
  263. data/app/models/pageflow/account.rb +3 -1
  264. data/app/models/pageflow/audio_file_url_templates.rb +21 -0
  265. data/app/models/pageflow/draft_entry.rb +19 -9
  266. data/app/models/pageflow/entry.rb +2 -1
  267. data/app/models/pageflow/entry_duplicate.rb +2 -2
  268. data/app/models/pageflow/entry_role_query.rb +81 -0
  269. data/app/models/pageflow/file_reuse.rb +25 -0
  270. data/app/models/pageflow/file_usage.rb +7 -1
  271. data/app/models/pageflow/image_file.rb +7 -1
  272. data/app/models/pageflow/image_file_url_templates.rb +19 -0
  273. data/app/models/pageflow/invited_user.rb +2 -0
  274. data/app/models/pageflow/membership.rb +46 -3
  275. data/app/models/pageflow/published_entry.rb +2 -2
  276. data/app/models/pageflow/revision.rb +16 -5
  277. data/app/models/pageflow/roles.rb +36 -0
  278. data/app/models/pageflow/text_track_file.rb +45 -0
  279. data/app/models/pageflow/text_track_file_url_templates.rb +16 -0
  280. data/app/models/pageflow/thumbnail_file_resolver.rb +22 -2
  281. data/app/models/pageflow/url_template.rb +13 -0
  282. data/app/models/pageflow/used_file.rb +21 -0
  283. data/app/models/pageflow/video_file.rb +72 -27
  284. data/app/models/pageflow/video_file_url_templates.rb +34 -0
  285. data/app/policies/pageflow/account_policy.rb +145 -0
  286. data/app/policies/pageflow/admin/admin_only_tab_policy.rb +16 -0
  287. data/app/policies/pageflow/admin/entry_tab_policy.rb +25 -0
  288. data/app/policies/pageflow/application_policy.rb +11 -0
  289. data/app/policies/pageflow/entry_policy.rb +138 -0
  290. data/app/policies/pageflow/file_policy.rb +42 -0
  291. data/app/policies/pageflow/folder_policy.rb +54 -0
  292. data/app/policies/pageflow/membership_policy.rb +105 -0
  293. data/app/policies/pageflow/theming_policy.rb +57 -0
  294. data/app/policies/pageflow/user_policy.rb +69 -0
  295. data/app/state_machines/pageflow/encoded_file_state_machine.rb +4 -0
  296. data/app/state_machines/pageflow/image_file_state_machine.rb +5 -1
  297. data/app/views/admin/entries/_attributes_table.html.arb +21 -2
  298. data/app/views/admin/entries/_links.html.arb +1 -1
  299. data/app/views/admin/memberships/_entity_account_input.html.erb +5 -0
  300. data/app/views/admin/memberships/_entity_entry_input.html.erb +5 -0
  301. data/app/views/admin/memberships/_form.html.erb +16 -5
  302. data/app/views/admin/memberships/_role_hint.html.arb +2 -0
  303. data/app/views/admin/users/_form.html.erb +29 -20
  304. data/app/views/components/pageflow/admin/add_membership_button_if_needed.rb +62 -0
  305. data/app/views/components/pageflow/admin/embed_code_field.rb +15 -0
  306. data/app/views/components/pageflow/admin/entry_user_badge_list.rb +15 -7
  307. data/app/views/components/pageflow/admin/grouped_folder_list.rb +20 -16
  308. data/app/views/components/pageflow/admin/members_tab.rb +22 -11
  309. data/app/views/components/pageflow/admin/membership_role_with_tooltip.rb +21 -0
  310. data/app/views/components/pageflow/admin/tabs_view.rb +13 -13
  311. data/app/views/components/pageflow/admin/user_account_badge_list.rb +43 -0
  312. data/app/views/components/pageflow/admin/user_accounts_tab.rb +46 -0
  313. data/app/views/components/pageflow/admin/user_entries_tab.rb +50 -0
  314. data/app/views/components/pageflow/admin/users_tab.rb +32 -4
  315. data/app/views/layouts/pageflow/application.html.erb +3 -2
  316. data/app/views/pageflow/config/_editor_seeds.json.jbuilder +15 -2
  317. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +1 -0
  318. data/app/views/pageflow/editor/files/_file.json.jbuilder +10 -2
  319. data/app/views/pageflow/entries/show.css.erb +4 -11
  320. data/app/views/pageflow/entries/show.json.jbuilder +1 -1
  321. data/app/views/pageflow/entry_json_seed/_entry.json.jbuilder +19 -0
  322. data/app/views/pageflow/file_types/_thumbnails.css.erb +1 -1
  323. data/app/views/pageflow/files/_file.json.jbuilder +12 -0
  324. data/app/views/pageflow/page_background_asset/_element.html.erb +3 -0
  325. data/app/views/pageflow/page_types/_page_type.json.jbuilder +7 -0
  326. data/app/views/pageflow/react/_widget.html.erb +1 -0
  327. data/app/views/pageflow/react/page.html.erb +6 -0
  328. data/app/views/pageflow/video_files/_video_file.json.jbuilder +2 -0
  329. data/config/initializers/admin_resource_tabs.rb +8 -1
  330. data/config/initializers/features.rb +1 -4
  331. data/config/initializers/help_entries.rb +2 -1
  332. data/config/initializers/paperclip.rb +4 -0
  333. data/config/initializers/zencoder.rb +5 -2
  334. data/config/locales/de.yml +370 -108
  335. data/config/locales/en.yml +333 -83
  336. data/config/routes.rb +18 -10
  337. data/db/migrate/20150825133449_update_audio_loop_pages_to_use_atmo.rb +24 -0
  338. data/db/migrate/20160304072911_rename_membership_entry_and_make_polymorphic.rb +19 -0
  339. data/db/migrate/20160304151327_add_role_to_membership.rb +19 -0
  340. data/db/migrate/20160504093145_replace_role_and_account_on_user.rb +42 -0
  341. data/db/migrate/20160531152500_update_users_count.rb +27 -0
  342. data/db/migrate/20160707125400_add_output_presences_to_video_files.rb +5 -0
  343. data/db/migrate/20160824115000_add_parent_file_to_video_files.rb +8 -0
  344. data/db/migrate/20160824115100_add_parent_file_to_audio_files.rb +8 -0
  345. data/db/migrate/20160824115200_add_parent_file_to_image_files.rb +8 -0
  346. data/db/migrate/20160929102700_add_configuration_to_files.rb +7 -0
  347. data/db/migrate/20161007144500_add_text_track_files.rb +31 -0
  348. data/db/migrate/20161216175734_move_configuration_from_file_to_file_usage.rb +27 -0
  349. data/db/migrate/20161230144429_add_processed_attachment_to_text_track_files.rb +8 -0
  350. data/db/migrate/20170222124848_update_video_file_output_presences.rb +12 -0
  351. data/db/migrate/20170421112300_turn_background_video_pages_into_background_image_pages.rb +22 -0
  352. data/lib/generators/pageflow/assets/assets_generator.rb +2 -0
  353. data/lib/generators/pageflow/assets/templates/components.js +4 -0
  354. data/lib/generators/pageflow/initializer/templates/pageflow.rb +23 -20
  355. data/lib/generators/pageflow/seeds/templates/seeds.rb +81 -15
  356. data/lib/pageflow.rb +8 -0
  357. data/lib/pageflow/ability_mixin.rb +196 -62
  358. data/lib/pageflow/admin/tab.rb +21 -0
  359. data/lib/pageflow/admin/tabs.rb +31 -6
  360. data/lib/pageflow/built_in_file_type.rb +39 -0
  361. data/lib/pageflow/built_in_page_types_plugin.rb +80 -0
  362. data/lib/pageflow/configuration.rb +13 -1
  363. data/lib/pageflow/engine.rb +6 -1
  364. data/lib/pageflow/file_type.rb +60 -15
  365. data/lib/pageflow/file_types.rb +20 -2
  366. data/lib/pageflow/page_type.rb +53 -4
  367. data/lib/pageflow/page_types.rb +4 -0
  368. data/lib/pageflow/paperclip_processors/vtt.rb +35 -0
  369. data/lib/pageflow/react.rb +11 -0
  370. data/lib/pageflow/react/page_type.rb +26 -0
  371. data/lib/pageflow/react/widget_type.rb +20 -0
  372. data/lib/pageflow/seeds.rb +59 -15
  373. data/lib/pageflow/user_mixin.rb +18 -25
  374. data/lib/pageflow/version.rb +1 -1
  375. data/lib/pageflow/zencoder_api.rb +18 -4
  376. data/lib/pageflow/zencoder_video_output_definition.rb +375 -127
  377. data/lib/tasks/pageflow_tasks.rake +7 -0
  378. data/spec/factories/accounts.rb +36 -3
  379. data/spec/factories/entries.rb +22 -4
  380. data/spec/factories/invited_user.rb +3 -4
  381. data/spec/factories/memberships.rb +34 -2
  382. data/spec/factories/text_track_files.rb +40 -0
  383. data/spec/factories/users.rb +32 -7
  384. data/spec/factories/video_files.rb +7 -1
  385. data/spec/fixtures/sample.srt +12 -0
  386. data/spec/fixtures/sample.vtt +40 -0
  387. data/vendor/assets/javascripts/dash.all.min.js +14 -0
  388. data/vendor/assets/javascripts/polyfills/bind.js +17 -11
  389. data/vendor/assets/javascripts/videojs-dash.js +302 -0
  390. data/vendor/assets/javascripts/videojs.js +26804 -0
  391. metadata +187 -49
  392. data/app/assets/images/pageflow/themes/default/page_type_pictograms/audio_loop/sprite.png +0 -0
  393. data/app/assets/images/pageflow/themes/default/page_type_pictograms/audio_loop/wide.png +0 -0
  394. data/app/assets/javascripts/pageflow/editor/collections/file_usages_collection.js +0 -21
  395. data/app/assets/javascripts/pageflow/editor/models/file_usage.js +0 -8
  396. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/audio_loop.js +0 -20
  397. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/background_video.js +0 -24
  398. data/app/assets/javascripts/pageflow/page_types/audio.js +0 -135
  399. data/app/assets/javascripts/pageflow/page_types/audio_loop.js +0 -102
  400. data/app/assets/javascripts/pageflow/page_types/background_image.js +0 -44
  401. data/app/assets/javascripts/pageflow/page_types/background_video.js +0 -137
  402. data/app/assets/javascripts/pageflow/page_types/video.js +0 -277
  403. data/app/assets/javascripts/pageflow/ui/views/inputs/file_input_view.js +0 -79
  404. data/app/assets/javascripts/pageflow/video_player/play_button_patch.js +0 -39
  405. data/app/assets/javascripts/pageflow/video_player/player_buffered_patch.js +0 -47
  406. data/app/assets/javascripts/pageflow/video_player/src_from_options_method.js +0 -31
  407. data/app/assets/stylesheets/pageflow/page_types/audio_loop.scss +0 -18
  408. data/app/assets/stylesheets/pageflow/page_types/background-video.scss +0 -50
  409. data/app/controllers/pageflow/editor/file_usages_controller.rb +0 -37
  410. data/app/jobs/pageflow/process_image_file_job.rb +0 -18
  411. data/app/views/pageflow/pages/templates/_audio.html.erb +0 -69
  412. data/app/views/pageflow/pages/templates/_audio_loop.html.erb +0 -34
  413. data/app/views/pageflow/pages/templates/_background_image.html.erb +0 -24
  414. data/app/views/pageflow/pages/templates/_background_video.html.erb +0 -32
  415. data/app/views/pageflow/pages/templates/_video.html.erb +0 -42
  416. data/lib/pageflow/built_in_page_type.rb +0 -79
@@ -169,6 +169,11 @@ module Pageflow
169
169
  # end
170
170
  attr_accessor :public_entry_url_options
171
171
 
172
+ # Either a lambda or an object with a `call` method taking a
173
+ # {Theming} as paramater and returing a hash of options used to
174
+ # construct the embed url of a published entry.
175
+ attr_accessor :entry_embed_url_options
176
+
172
177
  # Submit video/audio encoding jobs only after the user has
173
178
  # explicitly confirmed in the editor. Defaults to false.
174
179
  attr_accessor :confirm_encoding_jobs
@@ -234,7 +239,7 @@ module Pageflow
234
239
  #
235
240
  # config.authorize_user_deletion =
236
241
  # lambda do |user_to_delete|
237
- # if user_to_delete.account.users.length > 1
242
+ # if user_to_delete.accounts.all? { |account| account.users.size > 1 }
238
243
  # true
239
244
  # else
240
245
  # 'Last user on account. Permission denied'
@@ -243,6 +248,10 @@ module Pageflow
243
248
  # @since 0.11
244
249
  attr_accessor :authorize_user_deletion
245
250
 
251
+ # Array of values that the `kind` attribute on text tracks can
252
+ # take. Defaults to `[:captions, :subtitles, :descriptions]`.
253
+ attr_reader :available_text_track_kinds
254
+
246
255
  def initialize
247
256
  @paperclip_filesystem_default_options = {validate_media_type: false}
248
257
  @paperclip_s3_default_options = {validate_media_type: false}
@@ -266,6 +275,7 @@ module Pageflow
266
275
  @theming_request_scope = CnameThemingRequestScope.new
267
276
  @public_entry_request_scope = lambda { |entries, request| entries }
268
277
  @public_entry_url_options = Pageflow::ThemingsHelper::DEFAULT_PUBLIC_ENTRY_OPTIONS
278
+ @entry_embed_url_options = {protocol: 'https'}
269
279
 
270
280
  @confirm_encoding_jobs = false
271
281
 
@@ -282,6 +292,8 @@ module Pageflow
282
292
  @default_publisher_meta_tag = 'Pageflow'
283
293
 
284
294
  @authorize_user_deletion = lambda { |_user| true }
295
+
296
+ @available_text_track_kinds = [:captions, :subtitles, :descriptions]
285
297
  end
286
298
 
287
299
  # Activate a plugin.
@@ -9,6 +9,7 @@ require 'cancan'
9
9
  require 'jbuilder'
10
10
  require 'htmlentities'
11
11
  require 'kramdown'
12
+ require 'react-rails'
12
13
 
13
14
  require 'resque_mailer'
14
15
  require 'resque_scheduler'
@@ -16,7 +17,6 @@ require 'resque_scheduler'
16
17
  require 'active_admin'
17
18
 
18
19
  require 'jquery-layout-rails'
19
- require 'videojs_rails'
20
20
  require 'backbone-rails'
21
21
  require 'marionette-rails'
22
22
  require 'jquery-fileupload-rails'
@@ -25,6 +25,11 @@ require 'i18n-js'
25
25
  require 'http_accept_language'
26
26
  require 'pageflow-public-i18n'
27
27
 
28
+ if Gem::Specification.find_all_by_name('pageflow-react', '>= 0.0').any?
29
+ fail('The pageflow-react gem has been merged into the pageflow gem. ' \
30
+ 'See the pageflow changelog for update instructions.')
31
+ end
32
+
28
33
  module Pageflow
29
34
  # Rails integration
30
35
  class Engine < ::Rails::Engine
@@ -5,18 +5,29 @@ module Pageflow
5
5
  class NotFoundError < RuntimeError
6
6
  end
7
7
 
8
- # ActiveRecord model that represents the files of this type.
9
- # @return {ActiveRecord::Model}
10
- attr_reader :model
8
+ # Path of a partial rendered in the json representation of the
9
+ # file in both the editor and published entries
10
+ # @return {String}
11
+ attr_reader :partial
11
12
 
12
- # Path of the partial used to render a json representation of the
13
- # file.
13
+ # Path of a partial rendered in the json representation of the
14
+ # file inside the editor.
14
15
  # @return {String}
15
16
  attr_reader :editor_partial
16
17
 
17
- # Underscored plural name for usage in routes.
18
- # @return {String}
19
- attr_reader :collection_name
18
+ # File types that are allowed to be nested inside the file
19
+ # @return {Array<FileType>}
20
+ attr_reader :nested_file_types
21
+
22
+ # Is this file type used in situations where it is not nested into
23
+ # another file type?
24
+ # @return {Boolean}
25
+ attr_reader :top_level_type
26
+
27
+ # Callable that returns a hash of url template strings indexed by
28
+ # their names.
29
+ # @return [#call]
30
+ attr_reader :url_templates
20
31
 
21
32
  # Create file type to be returned in {PageType#file_types}.
22
33
  #
@@ -26,17 +37,51 @@ module Pageflow
26
37
  # editor_partial: 'pageflow/rainbow/editor/files/file')
27
38
  #
28
39
  # @param [Hash] options
29
- # @option options [ActiveRecord::Base] :model Required. Model
30
- # representing the file.
31
- # @option options [String] :editor_partial Optional. Path of a
32
- # partial to include in json representations of the file.
40
+ # @option options [ActiveRecord::Base, String] :model
41
+ # Required. Model representing the file, or name of that model.
42
+ # @option options [String] :partial
43
+ # Optional. Path of a partial to include in json representations
44
+ # of the file both inside the editor and published entries.
45
+ # @option options [String] :editor_partial
46
+ # Optional. Path of a partial to include in json representations
47
+ # of the file inside the editor.
33
48
  # @option options [String] :collection_name Optional. String to
34
49
  # be used in routes. Defaults to `"pageflow_rainbow_file"` for
35
50
  # model `Pageflow::Rainbow::File`.
51
+ # @option options [Array<FileType>] :nested_file_types
52
+ # Optional. Array of FileTypes allowed for nested files. Defaults to [].
53
+ # @option options [#call] :url_templates
54
+ # Optional. Callable returning a hash of url template strings
55
+ # indexed by their names.
36
56
  def initialize(options)
37
- @model = options.fetch(:model)
38
- @editor_partial = options.fetch(:editor_partial, nil)
39
- @collection_name = options.fetch(:collection_name, model.model_name.plural)
57
+ @model_string_or_reference = options.fetch(:model)
58
+ @partial = options[:partial]
59
+ @editor_partial = options[:editor_partial]
60
+ @collection_name_or_blank = options[:collection_name]
61
+ @nested_file_types = options.fetch(:nested_file_types, [])
62
+ @top_level_type = options.fetch(:top_level_type, false)
63
+ @url_templates = options.fetch(:url_templates, ->() { {} })
64
+ end
65
+
66
+ # ActiveRecord model that represents the files of this type.
67
+ # @return {ActiveRecord::Model}
68
+ def model
69
+ @model ||=
70
+ if @model_string_or_reference.is_a?(String)
71
+ @model_string_or_reference.constantize
72
+ else
73
+ @model_string_or_reference
74
+ end
75
+ end
76
+
77
+ # Underscored plural name for usage in routes.
78
+ # @return {String}
79
+ def collection_name
80
+ if @collection_name_or_blank.blank?
81
+ model.model_name.plural
82
+ else
83
+ @collection_name_or_blank
84
+ end
40
85
  end
41
86
 
42
87
  # @api private
@@ -7,13 +7,22 @@ module Pageflow
7
7
  end
8
8
 
9
9
  def each(&block)
10
- @page_types.map(&:file_types).flatten.uniq(&:model).each(&block)
10
+ first_level_file_types = @page_types.map(&:file_types).flatten
11
+ lower_level_file_types = search_for_nested_file_types(first_level_file_types)
12
+ (first_level_file_types + lower_level_file_types).uniq(&:model).each(&block)
11
13
  end
12
14
 
13
15
  def find_by_collection_name!(collection_name)
14
16
  detect do |file_type|
15
17
  file_type.collection_name == collection_name
16
- end || raise(FileType::NotFoundError, "No file type found for collection name '#{collection_name}'.")
18
+ end || raise(FileType::NotFoundError,
19
+ "No file type found for collection name '#{collection_name}'.")
20
+ end
21
+
22
+ def find_by_model!(model)
23
+ detect do |file_type|
24
+ file_type.model == model
25
+ end || raise(FileType::NotFoundError, "No file type found for '#{model.name}'.")
17
26
  end
18
27
 
19
28
  def with_thumbnail_support
@@ -21,5 +30,14 @@ module Pageflow
21
30
  file_type.model.instance_methods.include?(:thumbnail_url)
22
31
  end
23
32
  end
33
+
34
+ private
35
+
36
+ def search_for_nested_file_types(higher_level_file_types)
37
+ higher_level_file_types.map { |file_type|
38
+ file_type.nested_file_types +
39
+ search_for_nested_file_types(file_type.nested_file_types)
40
+ }.flatten
41
+ end
24
42
  end
25
43
  end
@@ -104,18 +104,67 @@ module Pageflow
104
104
  # a registered {FileType}. The first file found is used as
105
105
  # thumbnail.
106
106
  #
107
- # @example Default return value
108
- #
109
107
  # [
110
108
  # {attribute: 'thumbnail_image_id', file_collection: 'image_files'},
111
109
  # {attribute: 'background_image_id', file_collection: 'image_files'}
112
110
  # ]
113
111
  #
112
+ # It is possible to specify further conditions under which the
113
+ # candidate may be used via `if` or `unless` keys:
114
+ #
115
+ # [
116
+ # {
117
+ # attribute: 'video_id',
118
+ # file_collection: 'video_files',
119
+ # if: {
120
+ # attribute: 'background_type',
121
+ # value: 'video',
122
+ # }
123
+ # },
124
+ # {
125
+ # attribute: 'image_id',
126
+ # file_collection: 'image_files',
127
+ # unless: {
128
+ # attribute: 'background_type',
129
+ # value: 'video',
130
+ # }
131
+ # }
132
+ # ]
133
+ #
134
+ # The candidate will only be used if the given attribute has the
135
+ # given value.
136
+ #
114
137
  # @returns {Array<Hash>}
115
138
  def thumbnail_candidates
116
139
  [
117
- {attribute: 'thumbnail_image_id', file_collection: 'image_files'},
118
- {attribute: 'background_image_id', file_collection: 'image_files'}
140
+ {
141
+ file_collection: 'image_files',
142
+ attribute: 'thumbnail_image_id'
143
+ },
144
+ {
145
+ file_collection: 'image_files',
146
+ attribute: 'background_image_id',
147
+ unless: {
148
+ attribute: 'background_type',
149
+ value: 'video'
150
+ }
151
+ },
152
+ {
153
+ file_collection: 'image_files',
154
+ attribute: 'poster_image_id',
155
+ if: {
156
+ attribute: 'background_type',
157
+ value: 'video'
158
+ }
159
+ },
160
+ {
161
+ file_collection: 'video_files',
162
+ attribute: 'video_file_id',
163
+ if: {
164
+ attribute: 'background_type',
165
+ value: 'video'
166
+ }
167
+ }
119
168
  ]
120
169
  end
121
170
 
@@ -3,6 +3,10 @@ module Pageflow
3
3
  include Enumerable
4
4
 
5
5
  def initialize
6
+ clear
7
+ end
8
+
9
+ def clear
6
10
  @page_types = []
7
11
  @page_types_by_name = {}
8
12
  end
@@ -0,0 +1,35 @@
1
+ require 'webvtt'
2
+ require 'fileutils'
3
+
4
+ module Pageflow
5
+ module PaperclipProcessors
6
+ class Vtt < Paperclip::Processor
7
+ def make
8
+ destination = make_tempfile_for(file.path)
9
+
10
+ if File.extname(file.path) =~ /\.srt$/
11
+ srt_to_vtt(file.path, destination.path)
12
+ else
13
+ FileUtils.cp(file.path, destination.path)
14
+ end
15
+
16
+ destination
17
+ end
18
+
19
+ private
20
+
21
+ def srt_to_vtt(source_path, destination_path)
22
+ WebVTT.convert_from_srt(source_path, destination_path)
23
+ end
24
+
25
+ def make_tempfile_for(path)
26
+ basename = File.basename(path, File.extname(path))
27
+
28
+ tempfile = Tempfile.new([basename, '.vtt'])
29
+ tempfile.binmode
30
+
31
+ tempfile
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ module Pageflow
2
+ module React
3
+ def self.create_page_type(name, options = {})
4
+ Pageflow::React::PageType.new(name, options)
5
+ end
6
+
7
+ def self.create_widget_type(name, role)
8
+ Pageflow::React::WidgetType.new(name, role)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module Pageflow
2
+ module React
3
+ class PageType < Pageflow::PageType
4
+ attr_reader :name, :component_name, :file_types
5
+
6
+ def initialize(name, options)
7
+ @name = name
8
+ @thumbnail_candidates = options[:thumbnail_candidates]
9
+ @translation_key_prefix = options[:translation_key_prefix]
10
+ @file_types = options.fetch(:file_types, [])
11
+ end
12
+
13
+ def template_path
14
+ 'pageflow/react/page'
15
+ end
16
+
17
+ def thumbnail_candidates
18
+ @thumbnail_candidates || super
19
+ end
20
+
21
+ def translation_key_prefix
22
+ @translation_key_prefix || super
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ module Pageflow
2
+ module React
3
+ class WidgetType < Pageflow::WidgetType
4
+ attr_reader :name, :role
5
+
6
+ def initialize(name, role)
7
+ @name = name
8
+ @role = role
9
+ end
10
+
11
+ def roles
12
+ [role]
13
+ end
14
+
15
+ def render(template, _)
16
+ template.render(File.join('pageflow', 'react', 'widget'), name: name)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -65,7 +65,7 @@ module Pageflow
65
65
  account.build_default_theming(default_attributes.merge(attributes), &block)
66
66
  end
67
67
 
68
- # Create a {User} if non with the given email exists yet.
68
+ # Create a {User} if none with the given email exists yet.
69
69
  #
70
70
  # @param [Hash] attributes attributes to override defaults
71
71
  # @option attributes [String] :email required
@@ -111,33 +111,55 @@ module Pageflow
111
111
  entry = Entry.where(attributes.slice(:account, :title)).first
112
112
 
113
113
  if entry.nil?
114
- entry = Entry.create!(attributes) do |entry|
115
- entry.theming = attributes.fetch(:account).default_theming
114
+ entry = Entry.create!(attributes) do |created_entry|
115
+ created_entry.theming = attributes.fetch(:account).default_theming
116
116
 
117
- say_creating_entry(entry)
118
- yield(entry) if block_given?
117
+ say_creating_entry(created_entry)
118
+ yield(created_entry) if block_given?
119
119
  end
120
120
 
121
121
  storyline = entry.draft.storylines.first
122
122
 
123
- chapter = storyline.chapters.create!(title: 'Chapter 1')
123
+ chapter = storyline.chapters.create!(title: 'Chapter 1', position: 0)
124
124
  chapter.pages.create!(template: 'background_image')
125
125
  chapter.pages.create!(template: 'background_image')
126
126
 
127
- chapter = storyline.chapters.create!(title: 'Chapter 2')
127
+ chapter = storyline.chapters.create!(title: 'Chapter 2', position: 1)
128
128
  chapter.pages.create!(template: 'video')
129
129
  end
130
130
 
131
131
  entry
132
132
  end
133
133
 
134
- # Create a {Membership} for the given user and entry.
134
+ # Create a {Membership} for the given user and entity.
135
+ # Create a {Membership} for the corresponding account first if a {Membership} on an entry is to
136
+ # be created and no {Membership} on the entry's account exists yet.
135
137
  #
136
138
  # @param [Hash] attributes attributes to override defaults
137
139
  # @option attributes [User] :user required
138
- # @option attributes [Entry] :entry required
140
+ # @option attributes [Entity] :entity required
141
+ # :entry and :account are lower-priority aliases for :entity
139
142
  # @return [Membership] newly created membership
140
143
  def membership(attributes)
144
+ if (attributes[:entry].present? && attributes[:entity].present?) ||
145
+ (attributes[:account].present? && attributes[:entity].present?)
146
+ say_attribute_precedence(':entity', ':entry and :account')
147
+ end
148
+ unless attributes[:entity].present?
149
+ entry_or_account_attributes_specified attributes
150
+ end
151
+
152
+ if attributes[:entity].is_a?(Entry) || attributes[:entry].present?
153
+ entry = attributes[:entity] || attributes[:entry]
154
+ unless attributes[:user].accounts.include?(entry.account)
155
+ Membership.find_or_create_by!(entity: entry.account,
156
+ user: attributes[:user],
157
+ role: :member) do |membership|
158
+ say_creating_membership(membership)
159
+ end
160
+ end
161
+ end
162
+
141
163
  Membership.find_or_create_by!(attributes) do |membership|
142
164
  say_creating_membership(membership)
143
165
  end
@@ -150,25 +172,47 @@ module Pageflow
150
172
  end
151
173
 
152
174
  def say_creating_user(user)
153
- say(<<-END)
154
- #{user.role} user:
175
+ say(<<-END)
176
+
177
+ user with login:
155
178
 
156
- email: #{user.email}
157
- password: #{user.password}
179
+ email: #{user.email}
180
+ password: #{user.password}
158
181
 
159
182
  END
160
183
  end
161
184
 
162
185
  def say_creating_entry(entry)
163
- say(" sample entry '#{entry.title}'")
186
+ say(" sample entry '#{entry.title}'\n")
164
187
  end
165
188
 
166
189
  def say_creating_membership(membership)
167
- say(" membership for user '#{membership.user.email}' and entry '#{membership.entry.title}'")
190
+ say(" -- '#{membership.role}' membership for user '#{membership.user.email}' on " +
191
+ "#{membership.entity_type == 'Pageflow::Entry' ? 'entry' : 'account'} " +
192
+ %|'#{if membership.entity_type == "Pageflow::Entry"
193
+ membership.entity.title
194
+ else
195
+ membership.entity.name
196
+ end}'\n|)
197
+ end
198
+
199
+ def say_attribute_precedence(subject, object)
200
+ say(" #{subject} attribute precedes #{object}")
168
201
  end
169
202
 
170
203
  def say(text)
171
204
  puts(text) unless Rails.env.test?
172
205
  end
206
+
207
+ def entry_or_account_attributes_specified(attributes)
208
+ if attributes[:entry].present? || attributes[:account].present?
209
+ attributes[:entity] = attributes[:entry]
210
+ if attributes[:account].present?
211
+ say_attribute_precedence(':entry', ':account')
212
+ end
213
+ else
214
+ attributes[:entity] = attributes[:account]
215
+ end
216
+ end
173
217
  end
174
218
  end