lato_cms 3.2.4 → 3.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4512bf98553bdc298352f97641aeef70356dcc448862a84816ed64ec4df3d3b
4
- data.tar.gz: 7d7e190cf8997e7c9d6fcd94f7dc1570d9d939312b71a5caaa6cc2eadba697a3
3
+ metadata.gz: 29cb78070d1a03bb67b5c2ad9c06b212303ae2c390e3b3a2f17b07bbae26f949
4
+ data.tar.gz: 82dd11dac19e77c935a037561d668be95b6d4cc0a6cb08d53ce1e4eec81445b4
5
5
  SHA512:
6
- metadata.gz: e4bbfabdce312042bba9014b34a8ff1423a1dccd84e0798700f334d2836f7cda389a8ce15c04faca2188229271e30e74b1b6044222e1a0735960e875c5c68206
7
- data.tar.gz: 0f8191d661b29ce420e8ab5657511fe5c3d0af82ce0c60bd6ee11d695b86c2c27735c5d6b4ad806b9df149b46f1423e63512996e0eb99655c51da31fdac8a39f
6
+ metadata.gz: e07ea70a61268187c94a66ad273339bed785d0cc3e6f5562624b4924b6e721ff6f01d039e47a1ca9f18de58681b051ac50bbc03bc1ceeefa79dd351f94ff8250
7
+ data.tar.gz: b39a29416a88c3cace9b780a4a0582b721b5d038df0c0e7b14d6814b48612db14530c8e6bc8259a7fdca30febd8a70e8a290a3fb9ad33b6e4289333c4556e8ad
@@ -123,8 +123,12 @@ export default class extends Controller {
123
123
  }
124
124
 
125
125
  previewMarkup (item) {
126
+ // Mirrors the server-rendered tile: with a poster nothing but that image is
127
+ // fetched until the admin hits play (a freshly uploaded video has none yet,
128
+ // its poster job runs in the background).
126
129
  if (this.kindValue === 'video') {
127
- return `<video controls preload="metadata" class="lato-cms-media-field__player" src="${item.url}"></video>`
130
+ const poster = item.posterUrl || ''
131
+ return `<video controls preload="${poster ? 'none' : 'metadata'}" poster="${poster}" class="lato-cms-media-field__player" src="${item.url}"></video>`
128
132
  }
129
133
  if (item.thumbnailUrl || item.url) {
130
134
  return `<img src="${item.thumbnailUrl || item.url}" class="lato-cms-media-field__thumb">`
@@ -10,6 +10,7 @@ module LatoCms
10
10
  # "Unused" = no page field references it at all: the only media that can
11
11
  # be deleted, so it's worth being able to list just those.
12
12
  media = media.where.missing(:page_field_media) if params[:usage] == 'unused'
13
+ media = media.missing_translation(params[:missing]) if LatoCms::Media::TRANSLATABLE_ATTRIBUTES.include?(params[:missing])
13
14
 
14
15
  @media = lato_index_collection(
15
16
  media.order(created_at: :desc),
@@ -45,6 +45,26 @@ module LatoCms
45
45
 
46
46
  scope :of_type, ->(type) { where(media_type: type) if type.present? }
47
47
 
48
+ # Media missing `attribute` (alt_text or title) in at least one configured
49
+ # locale — the ones worth going back to fill in. Alt text exists only for
50
+ # images, so that filter is scoped to them; a title is editable on every
51
+ # media type.
52
+ #
53
+ # Filtered in Ruby rather than SQL: the translations live as a JSON blob in
54
+ # a text column, and "blank in one locale" is not a predicate any adapter
55
+ # can express without guessing at that serialization (a stored empty string
56
+ # counts as missing too). Only the id and the one column are loaded.
57
+ scope :missing_translation, ->(attribute) {
58
+ attribute = attribute.to_s
59
+ next none unless TRANSLATABLE_ATTRIBUTES.include?(attribute)
60
+
61
+ candidates = attribute == "alt_text" ? where(media_type: "image") : all
62
+ locales = LatoCms.config.locales
63
+ incomplete = candidates.select(:id, attribute).reject { |media| locales.all? { |locale| media.public_send(attribute, locale).present? } }
64
+
65
+ candidates.where(id: incomplete.map(&:id))
66
+ }
67
+
48
68
  # Hook picked up by lato's `lato_index_collection` in place of its generic
49
69
  # search, whose SQL leaves column names unqualified. The Spaces association
50
70
  # joins lato_spaces_groups, which also has a `name` column, so that generic
@@ -7,7 +7,9 @@
7
7
  <%= image_tag media.preview_url, class: 'd-block mx-auto', style: 'max-width: 100%; max-height: 420px;', alt: media.alt_text %>
8
8
  <% end %>
9
9
  <% elsif media.video? %>
10
- <video controls preload="metadata" class="d-block w-100 rounded bg-black" style="max-height: 420px;" src="<%= media.url %>"></video>
10
+ <%# Poster first, video bytes only on play (see the media field tile). %>
11
+ <video controls preload="<%= media.poster_url ? 'none' : 'metadata' %>" poster="<%= media.poster_url %>"
12
+ class="d-block w-100 rounded bg-black" style="max-height: 420px;" src="<%= media.url %>"></video>
11
13
  <% end %>
12
14
 
13
15
  <div class="d-flex align-items-center gap-2 mt-2">
@@ -1,12 +1,21 @@
1
1
  <%= lato_page_head t('lato_cms.media_index_title'), [{ label: t('lato_cms.media_index_title') }] %>
2
2
 
3
3
  <div class="card">
4
- <div class="card-header d-flex gap-2">
5
- <%= link_to lato_cms.media_path, class: "btn btn-sm #{params[:usage].blank? ? 'btn-primary' : 'btn-outline-secondary'}" do %>
6
- <i class="bi bi-images me-1"></i><%= t('lato_cms.media_filter_all') %>
7
- <% end %>
8
- <%= link_to lato_cms.media_path(usage: 'unused'), class: "btn btn-sm #{params[:usage] == 'unused' ? 'btn-primary' : 'btn-outline-secondary'}" do %>
9
- <i class="bi bi-unlink me-1"></i><%= t('lato_cms.media_filter_unused') %>
4
+ <%# Mutually exclusive shortcuts to the media worth acting on: the ones that
5
+ can be deleted, and the ones still missing a translation. %>
6
+ <% filters = [
7
+ { label: t('lato_cms.media_filter_all'), icon: 'bi-images', params: {} },
8
+ { label: t('lato_cms.media_filter_unused'), icon: 'bi-unlink', params: { usage: 'unused' } }
9
+ ] + LatoCms::Media::TRANSLATABLE_ATTRIBUTES.map do |attribute|
10
+ { label: t("lato_cms.media_filter_missing_#{attribute}"), icon: 'bi-translate', params: { missing: attribute } }
11
+ end %>
12
+ <% current = { usage: params[:usage].presence, missing: params[:missing].presence }.compact %>
13
+
14
+ <div class="card-header d-flex flex-wrap gap-2">
15
+ <% filters.each do |filter| %>
16
+ <%= link_to lato_cms.media_path(filter[:params]), class: "btn btn-sm #{filter[:params] == current ? 'btn-primary' : 'btn-outline-secondary'}" do %>
17
+ <i class="bi <%= filter[:icon] %> me-1"></i><%= filter[:label] %>
18
+ <% end %>
10
19
  <% end %>
11
20
  </div>
12
21
  <div class="card-body">
@@ -11,34 +11,39 @@
11
11
  <%# Two columns from lg up (preview left, data right), stacked below: the
12
12
  preview is the thing you look at first, the metadata the thing you read
13
13
  next to it. %>
14
- <div class="card-body row g-4">
15
- <div class="col-lg-5">
16
- <%= render 'lato_cms/media/preview', media: @media %>
17
- </div>
14
+ <div class="card-body">
15
+ <%# The row stays inside the card body: `row` carries a negative top margin
16
+ for its gutters, which on the body itself ate the card's own padding
17
+ and pushed the preview against the header. %>
18
+ <div class="row g-4">
19
+ <div class="col-lg-5">
20
+ <%= render 'lato_cms/media/preview', media: @media %>
21
+ </div>
18
22
 
19
- <dl class="col-lg-7 row mb-0">
20
- <dt class="col-sm-3"><%= LatoCms::Media.human_attribute_name(:name) %></dt>
21
- <dd class="col-sm-9"><%= @media.name %></dd>
23
+ <dl class="col-lg-7 row mb-0">
24
+ <dt class="col-sm-3"><%= LatoCms::Media.human_attribute_name(:name) %></dt>
25
+ <dd class="col-sm-9"><%= @media.name %></dd>
22
26
 
23
- <dt class="col-sm-3"><%= t('lato_cms.media_type_label') %></dt>
24
- <dd class="col-sm-9"><%= lato_cms_media_media_type(@media) %></dd>
27
+ <dt class="col-sm-3"><%= t('lato_cms.media_type_label') %></dt>
28
+ <dd class="col-sm-9"><%= lato_cms_media_media_type(@media) %></dd>
25
29
 
26
- <%# Alt text is image-only, mirroring the edit form. Both are translatable:
30
+ <%# Alt text is image-only, mirroring the edit form. Both are translatable:
27
31
  one row per configured locale, blanks included, so a missing
28
32
  translation is visible instead of just absent. %>
29
- <% attributes = @media.image? ? LatoCms::Media::TRANSLATABLE_ATTRIBUTES : %w[title] %>
30
- <% attributes.each do |attribute| %>
31
- <dt class="col-sm-3"><%= t("lato_cms.media_#{attribute}") %></dt>
32
- <dd class="col-sm-9">
33
- <% LatoCms.config.locales.each do |locale| %>
34
- <div class="d-flex gap-2">
35
- <span class="badge bg-secondary align-self-start"><%= locale.to_s.upcase %></span>
36
- <span><%= @media.public_send(attribute, locale).presence || content_tag(:span, '—', class: 'text-muted') %></span>
37
- </div>
38
- <% end %>
39
- </dd>
40
- <% end %>
41
- </dl>
33
+ <% attributes = @media.image? ? LatoCms::Media::TRANSLATABLE_ATTRIBUTES : %w[title] %>
34
+ <% attributes.each do |attribute| %>
35
+ <dt class="col-sm-3"><%= t("lato_cms.media_#{attribute}") %></dt>
36
+ <dd class="col-sm-9">
37
+ <% LatoCms.config.locales.each do |locale| %>
38
+ <div class="d-flex gap-2">
39
+ <span class="badge bg-secondary align-self-start"><%= locale.to_s.upcase %></span>
40
+ <span><%= @media.public_send(attribute, locale).presence || content_tag(:span, '—', class: 'text-muted') %></span>
41
+ </div>
42
+ <% end %>
43
+ </dd>
44
+ <% end %>
45
+ </dl>
46
+ </div>
42
47
  </div>
43
48
  </div>
44
49
 
@@ -8,7 +8,13 @@
8
8
  data-action="dragstart->lato-cms-media-reorder#onDragStart dragend->lato-cms-media-reorder#onDragEnd"
9
9
  <% end %>>
10
10
  <% if kind == 'video' %>
11
- <video controls preload="metadata" class="lato-cms-media-field__player" src="<%= media.url %>"></video>
11
+ <%# With a poster the browser fetches nothing but that image until the admin
12
+ hits play: a page can hold many video fields, and preloading metadata
13
+ for each one meant every video file was requested just to open the
14
+ editor (enough of them and the players stall before they ever start).
15
+ Without a poster there's nothing else to show, so metadata it is. %>
16
+ <video controls preload="<%= media.poster_url ? 'none' : 'metadata' %>" poster="<%= media.poster_url %>"
17
+ class="lato-cms-media-field__player" src="<%= media.url %>"></video>
12
18
  <% elsif media.thumbnail_url %>
13
19
  <img src="<%= media.thumbnail_url %>" class="lato-cms-media-field__thumb" alt="<%= media.alt_text %>">
14
20
  <% else %>
@@ -127,6 +127,8 @@ en:
127
127
  media_usages_title: Used in
128
128
  media_filter_all: All
129
129
  media_filter_unused: Unused
130
+ media_filter_missing_alt_text: Missing alt text
131
+ media_filter_missing_title: Missing title
130
132
  media_summary_title: Media details
131
133
  media_type_label: Type
132
134
  media_update_tab_details: Details
@@ -127,6 +127,8 @@ it:
127
127
  media_usages_title: Utilizzato in
128
128
  media_filter_all: Tutti
129
129
  media_filter_unused: Senza utilizzi
130
+ media_filter_missing_alt_text: Senza alt text
131
+ media_filter_missing_title: Senza title
130
132
  media_summary_title: Dettagli media
131
133
  media_type_label: Tipo
132
134
  media_update_tab_details: Dettagli
@@ -1,3 +1,3 @@
1
1
  module LatoCms
2
- VERSION = "3.2.4"
2
+ VERSION = "3.2.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lato_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.4
4
+ version: 3.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregorio Galante