media_component_helper.rb 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. # frozen_string_literal: true
  2. module MediaComponentHelper
  3. def render_video_component(status, **options)
  4. video = status.ordered_media_attachments.first
  5. meta = video.file.meta || {}
  6. component_params = {
  7. sensitive: sensitive_viewer?(status, current_account),
  8. src: full_asset_url(video.file.url(:original)),
  9. preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)),
  10. alt: video.description,
  11. blurhash: video.blurhash,
  12. frameRate: meta.dig('original', 'frame_rate'),
  13. inline: true,
  14. media: [
  15. serialize_media_attachment(video),
  16. ].as_json,
  17. }.merge(**options)
  18. react_component :video, component_params do
  19. render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
  20. end
  21. end
  22. def render_audio_component(status, **options)
  23. audio = status.ordered_media_attachments.first
  24. meta = audio.file.meta || {}
  25. component_params = {
  26. src: full_asset_url(audio.file.url(:original)),
  27. poster: full_asset_url(audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url),
  28. alt: audio.description,
  29. backgroundColor: meta.dig('colors', 'background'),
  30. foregroundColor: meta.dig('colors', 'foreground'),
  31. accentColor: meta.dig('colors', 'accent'),
  32. duration: meta.dig('original', 'duration'),
  33. }.merge(**options)
  34. react_component :audio, component_params do
  35. render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
  36. end
  37. end
  38. def render_media_gallery_component(status, **options)
  39. component_params = {
  40. sensitive: sensitive_viewer?(status, current_account),
  41. autoplay: prefers_autoplay?,
  42. media: status.ordered_media_attachments.map { |a| serialize_media_attachment(a).as_json },
  43. }.merge(**options)
  44. react_component :media_gallery, component_params do
  45. render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
  46. end
  47. end
  48. def render_card_component(status, **options)
  49. component_params = {
  50. sensitive: sensitive_viewer?(status, current_account),
  51. card: serialize_status_card(status).as_json,
  52. }.merge(**options)
  53. react_component :card, component_params
  54. end
  55. def render_poll_component(status, **options)
  56. component_params = {
  57. disabled: true,
  58. poll: serialize_status_poll(status).as_json,
  59. }.merge(**options)
  60. react_component :poll, component_params do
  61. render partial: 'statuses/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: prefers_autoplay? }
  62. end
  63. end
  64. private
  65. def serialize_media_attachment(attachment)
  66. ActiveModelSerializers::SerializableResource.new(
  67. attachment,
  68. serializer: REST::MediaAttachmentSerializer
  69. )
  70. end
  71. def serialize_status_card(status)
  72. ActiveModelSerializers::SerializableResource.new(
  73. status.preview_card,
  74. serializer: REST::PreviewCardSerializer
  75. )
  76. end
  77. def serialize_status_poll(status)
  78. ActiveModelSerializers::SerializableResource.new(
  79. status.preloadable_poll,
  80. serializer: REST::PollSerializer,
  81. scope: current_user,
  82. scope_name: :current_user
  83. )
  84. end
  85. def sensitive_viewer?(status, account)
  86. if !account.nil? && account.id == status.account_id
  87. status.sensitive
  88. else
  89. status.account.sensitized? || status.sensitive
  90. end
  91. end
  92. end