studio-engine 0.109.0.rc2 → 0.110.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/app/views/layouts/studio/_head.html.erb +3 -1
- data/app/views/studio/site_footer/_footer.html.erb +14 -2
- data/app/views/studio/site_footer/_lockup_assets.html.erb +30 -0
- data/docs/SITE_FOOTER.md +39 -1
- data/lib/studio/public_file_version.rb +55 -0
- data/lib/studio/site_footer.rb +39 -0
- data/lib/studio/version.rb +1 -1
- data/lib/studio.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: faad0b30d10e3cfbb58f3af463f47af004c790db2ef4945c7e8c914d533bcc5a
|
|
4
|
+
data.tar.gz: 567c93db53a89e63a192abf3ccd03b5dfddbadb03df8072783988cd7aed43482
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 014cccc62e8ac88d2c6bbf9d5758eaf1997c42ff654f84bbf889d8f0c20f5e3bd15cd3aa8fb7946775e29f91fceaa1f8916a15f57bb7c7340d6c13a21de4b8dd
|
|
7
|
+
data.tar.gz: d3523274d32ed61fcc806a32a73b17f92f857c7c471bb91bd28b8cfeff5c27ab1cd04100156aca35b46472222789fa6425288178b087142394fe7acc8ef1e217
|
data/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,34 @@ The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This pro
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.110.0 — 2026-10-15
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **The site footer can draw a brand lockup in place of its logo and
|
|
12
|
+
wordmark.** A new `lockup:` fact in `config.site_footer` names one file per
|
|
13
|
+
theme, plus the artwork's own size: `lockup: { light:
|
|
14
|
+
"/brand/stacked-light.svg", dark: "/brand/stacked-dark.svg", width: 942,
|
|
15
|
+
height: 885 }`. Both images render with the site name as `alt` and that
|
|
16
|
+
`width`/`height`, inside the home link; CSS shows the light file on a light
|
|
17
|
+
page and the dark file under `.dark`, so a theme toggle swaps them with no
|
|
18
|
+
script. It is drawn `7rem` tall (`--ftr-lockup-height` on `.ftr` changes it)
|
|
19
|
+
and never wider than its column. A lockup centres the brand block
|
|
20
|
+
(`.ftr-brand-lockup`: the lockup, tagline, email and social row), since a
|
|
21
|
+
stacked lockup is symmetric; the link columns keep their alignment. A footer that declares no lockup is byte-identical: the lockup's
|
|
22
|
+
styles render only with it (`studio/site_footer/_lockup_assets`), and an
|
|
23
|
+
older engine ignores the key. See `docs/SITE_FOOTER.md`, *A lockup*.
|
|
24
|
+
|
|
7
25
|
### Changed
|
|
8
26
|
|
|
27
|
+
- **The favicon link carries its content version.** The head writes
|
|
28
|
+
`<link rel="icon" href="/favicon.png?v=<8 hex>">`, the first 8 characters of
|
|
29
|
+
the file's SHA-256 (`Studio::PublicFileVersion.path`), so a redrawn favicon
|
|
30
|
+
is a new URL: browsers cache a favicon per origin and a hard reload does not
|
|
31
|
+
reliably clear it, on a reused localhost port or for a returning visitor.
|
|
32
|
+
The digest is read once per file contents (cached by path, size and mtime).
|
|
33
|
+
A host with no `public/favicon.png` keeps the bare link, byte for byte.
|
|
34
|
+
|
|
9
35
|
- **A held navbar eases its collapse again.** 0.108.0 held the header's
|
|
10
36
|
footprint so the page never moves, and with it let the header follow the
|
|
11
37
|
scroll position exactly. On a hard flick that crossed the whole ramp in a
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
includes Studio::ErrorHandling. See studio/_session_stamp. %>
|
|
32
32
|
<%= render "studio/session_stamp" %>
|
|
33
33
|
<%= render "layouts/studio/smooth_load" %>
|
|
34
|
-
|
|
34
|
+
<%# The favicon's URL carries its content version (Studio::PublicFileVersion),
|
|
35
|
+
so a redrawn favicon is a new URL no browser has cached. %>
|
|
36
|
+
<link rel="icon" type="image/png" href="<%= Studio::PublicFileVersion.path("/favicon.png") %>">
|
|
35
37
|
<%# Link-preview (og:/twitter:) tags: the page's link_preview override, else the
|
|
36
38
|
operator default from /admin/link_preview, else the static fallback. Gated by
|
|
37
39
|
Studio.link_preview_tags? — under the default :auto, only once this app has
|
|
@@ -15,8 +15,20 @@
|
|
|
15
15
|
<div class="ftr-wrap">
|
|
16
16
|
<% tracks = Studio::SiteFooter.tracks(columns) %>
|
|
17
17
|
<div class="ftr-cols<%= " ftr-cols-many" if columns.size > Studio::SiteFooter::MAX_ROW_COLUMNS %>"<% if tracks %> style="--ftr-tracks: <%= tracks %>"<% end %>>
|
|
18
|
-
<div class="ftr-brand">
|
|
19
|
-
<% if
|
|
18
|
+
<div class="ftr-brand<%= " ftr-brand-lockup" if facts[:lockup] %>">
|
|
19
|
+
<% if (lockup = facts[:lockup]) %>
|
|
20
|
+
<%# The lockup replaces the logo and the wordmark, and centres the
|
|
21
|
+
brand block (.ftr-brand-lockup). Both theme files render;
|
|
22
|
+
studio/site_footer/_lockup_assets shows the one that matches the
|
|
23
|
+
page, so a theme toggle swaps them with no script. %>
|
|
24
|
+
<%= render "studio/site_footer/lockup_assets" %>
|
|
25
|
+
<a href="<%= facts[:home_path] %>" class="ftr-home" aria-label="<%= facts[:name] %>">
|
|
26
|
+
<% [ [ :light, lockup[:light] ], [ :dark, lockup[:dark] ] ].each do |theme, src| %>
|
|
27
|
+
<%= image_tag src, class: "ftr-lockup ftr-lockup-#{theme}", alt: facts[:name].to_s,
|
|
28
|
+
width: lockup[:width], height: lockup[:height] %>
|
|
29
|
+
<% end %>
|
|
30
|
+
</a>
|
|
31
|
+
<% elsif facts[:logo] || facts[:wordmark] %>
|
|
20
32
|
<a href="<%= facts[:home_path] %>" class="ftr-home" aria-label="<%= facts[:name] %>">
|
|
21
33
|
<% if facts[:logo] %>
|
|
22
34
|
<%= image_tag facts[:logo], class: [ "ftr-logo", ("ftr-logo-invert" if facts[:logo_invert]) ].compact.join(" "), alt: "" %>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<%# The footer lockup's styles (the `lockup:` fact; docs/SITE_FOOTER.md). Only
|
|
2
|
+
a footer that declares a lockup renders this, so a footer without one is
|
|
3
|
+
byte for byte what it was before the fact existed.
|
|
4
|
+
|
|
5
|
+
HEIGHT-LED. The lockup is drawn at --ftr-lockup-height (default 7rem, about
|
|
6
|
+
the icon-and-name block's height plus the room a stacked logo's second line
|
|
7
|
+
needs) and its width follows the artwork, never wider than its column. The
|
|
8
|
+
width and height attributes give the box its shape before the file loads.
|
|
9
|
+
|
|
10
|
+
CENTRED. A lockup centres the brand block (.ftr-brand-lockup): the lockup,
|
|
11
|
+
the tagline, the email and the social row. A stacked lockup is symmetric
|
|
12
|
+
about its own centre, so it reads as the column's heading only when
|
|
13
|
+
centred under it. The link columns keep their alignment. The home link is
|
|
14
|
+
inline-flex, so it hugs the artwork (centred by the block's text-align)
|
|
15
|
+
and its focus ring, offset 4px, rings the lockup instead of running
|
|
16
|
+
across the column through the name.
|
|
17
|
+
|
|
18
|
+
THEME SWAP. Light shows on a light page, dark under the root's `dark`
|
|
19
|
+
class. The hide rule comes after the display rule, so it wins on order. %>
|
|
20
|
+
<style>
|
|
21
|
+
.ftr-lockup { display: block; width: auto; height: var(--ftr-lockup-height, 7rem); max-width: 100%;
|
|
22
|
+
object-fit: contain; object-position: center; }
|
|
23
|
+
.ftr-brand-lockup { text-align: center; }
|
|
24
|
+
.ftr-brand-lockup .ftr-home { display: inline-flex; justify-content: center; vertical-align: top; }
|
|
25
|
+
.ftr-brand-lockup .ftr-home:focus-visible { outline-offset: 4px; }
|
|
26
|
+
.ftr-brand-lockup .ftr-socials { justify-content: center; }
|
|
27
|
+
.ftr-lockup-dark { display: none; }
|
|
28
|
+
.dark .ftr-lockup-light { display: none; }
|
|
29
|
+
.dark .ftr-lockup-dark { display: block; }
|
|
30
|
+
</style>
|
data/docs/SITE_FOOTER.md
CHANGED
|
@@ -191,6 +191,7 @@ Every key is optional. A missing key removes its part of the footer.
|
|
|
191
191
|
| `wordmark` | Two parts, the second in the primary colour: `%w[Example Co]` | `name`, split before its last word |
|
|
192
192
|
| `logo` | An image beside the wordmark: an asset name or a path | The app's "Footer Logo" in `config.theme_logos`, else its navbar logo. `logo: false` shows none |
|
|
193
193
|
| `logo_invert` | `true` inverts a dark mark in light mode | Shown as drawn |
|
|
194
|
+
| `lockup` | One brand artwork in place of the logo AND the wordmark, one file per theme: `{ light: "/brand/stacked-light.svg", dark: "/brand/stacked-dark.svg", width: 942, height: 885 }`. See [A lockup](#a-lockup) | The logo and the wordmark |
|
|
194
195
|
| `home_path` | Where the logo and wordmark link | `/` |
|
|
195
196
|
| `tagline` | A line under the wordmark | No line |
|
|
196
197
|
| `email` | A `mailto:` link under the tagline | No line. (To list the email in a column instead, write it as a column link.) |
|
|
@@ -282,6 +283,40 @@ Propshaft app. The engine's copy of the stylesheet drops Leaflet's default marke
|
|
|
282
283
|
image and its layers-control image, which are not shipped: mark a point with
|
|
283
284
|
`L.divIcon`, as the footer does.
|
|
284
285
|
|
|
286
|
+
|
|
287
|
+
### A lockup
|
|
288
|
+
|
|
289
|
+
A kit's stacked logo, say, draws the icon and the name as one piece of
|
|
290
|
+
artwork. Declare it as `lockup:` and the footer draws it in place of the logo
|
|
291
|
+
and the wordmark; the tagline, email and social row stay below it.
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
config.site_footer = ->(view) {
|
|
295
|
+
{ name: "Example Co",
|
|
296
|
+
lockup: { light: "/brand/stacked-light.svg", dark: "/brand/stacked-dark.svg",
|
|
297
|
+
width: 942, height: 885 },
|
|
298
|
+
tagline: "Everything, by example" }
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
- `light` is drawn on a light page and `dark` under the root's `dark` class.
|
|
303
|
+
Both images render and CSS hides the one that does not match, so a theme
|
|
304
|
+
toggle swaps them with no script (as `Studio.navbar_wordmark` does). With no
|
|
305
|
+
`dark`, `light` serves both. With no `light`, there is no lockup.
|
|
306
|
+
- `width` and `height` are the artwork's own size, an SVG's `viewBox` rounded.
|
|
307
|
+
Both are written onto each image so the browser holds the box before the
|
|
308
|
+
file loads and nothing below it moves. Give both or neither.
|
|
309
|
+
- It is drawn `7rem` tall, its width following the artwork and never wider
|
|
310
|
+
than its column. Set `--ftr-lockup-height` on `.ftr` to change that.
|
|
311
|
+
- It centres the brand block (`.ftr-brand-lockup`): the lockup, the tagline,
|
|
312
|
+
the email and the social row, at every width. A stacked lockup is symmetric
|
|
313
|
+
about its centre, so it is centred rather than given an alignment option; the
|
|
314
|
+
link columns keep theirs.
|
|
315
|
+
- Both images carry the site name as `alt`, inside the home link.
|
|
316
|
+
- A footer that declares no lockup renders exactly as before: its styles ride
|
|
317
|
+
only with a lockup (`studio/site_footer/_lockup_assets`). An engine older
|
|
318
|
+
than the fact ignores the key, so a host can declare it before it upgrades.
|
|
319
|
+
|
|
285
320
|
## Where it shows
|
|
286
321
|
|
|
287
322
|
`studio_site_footer` asks `config.site_footer_visible`, one callable that
|
|
@@ -402,13 +437,14 @@ These class names are stable, and an app may style against them:
|
|
|
402
437
|
|-------|---------|
|
|
403
438
|
| `.ftr` | The footer |
|
|
404
439
|
| `.ftr-cols` | The grid of brand and link columns; `--ftr-tracks` is its link-column tracks. `.ftr-cols-many` with more than four |
|
|
405
|
-
| `.ftr-brand` | The brand block |
|
|
440
|
+
| `.ftr-brand` | The brand block; `.ftr-brand-lockup` when it holds a lockup (centred) |
|
|
406
441
|
| `.ftr-col` | One link column (a `nav`) |
|
|
407
442
|
| `.ftr-heading`, `.ftr-list` | A column's heading and its list |
|
|
408
443
|
| `.ftr-link`, `.ftr-link-solid`, `.ftr-link-disabled` | A link; an address kept on one line; a "coming soon" label. `--ftr-link-ink` on `.ftr` is the link colour |
|
|
409
444
|
| `.ftr-location`, `.ftr-location-title`, `.ftr-address` | The Location band |
|
|
410
445
|
| `.ftr-legal`, `.ftr-copyright` | The legal line and the © line |
|
|
411
446
|
| `.ftr-map` | The map |
|
|
447
|
+
| `.ftr-lockup`, `.ftr-lockup-light`, `.ftr-lockup-dark` | The lockup's images; `--ftr-lockup-height` on `.ftr` is its height |
|
|
412
448
|
|
|
413
449
|
The rest (`.ftr-wrap`, `.ftr-home`, the social and pin classes) may change.
|
|
414
450
|
|
|
@@ -435,6 +471,8 @@ link. Those rules are more specific than the engine's and still apply.
|
|
|
435
471
|
|
|
436
472
|
- `test/lib/studio/site_footer_test.rb`: the facts' rules, the default facts, the
|
|
437
473
|
address setting's precedence, and the visibility rule.
|
|
474
|
+
- `test/views/site_footer_lockup_css_test.rb`: the lockup's size, centring and theme swap,
|
|
475
|
+
and that the stylesheet every footer renders carries none of it.
|
|
438
476
|
- `test/lib/vendored_leaflet_test.rb`: Leaflet is vendored, precompiled, and
|
|
439
477
|
addressed through the asset pipeline.
|
|
440
478
|
- `test/integration/site_footer_test.rb`: what a host renders, with and without
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "digest"
|
|
4
|
+
|
|
5
|
+
module Studio
|
|
6
|
+
# A content version for a file in the host's public/ directory, so a link to
|
|
7
|
+
# it changes when the file does (task footer-stacked-logo). Browsers cache a
|
|
8
|
+
# favicon per origin and a hard reload does not reliably clear it: a redrawn
|
|
9
|
+
# /favicon.png kept showing the old picture, both on a localhost port reused
|
|
10
|
+
# by another desk and for returning production visitors. A versioned URL is
|
|
11
|
+
# a new resource, so nobody has to bump anything by hand.
|
|
12
|
+
#
|
|
13
|
+
# Studio::PublicFileVersion.path("/favicon.png")
|
|
14
|
+
# # => "/favicon.png?v=1a2b3c4d" (the first 8 hex of the file's SHA-256)
|
|
15
|
+
# # => "/favicon.png" when the host has no such file
|
|
16
|
+
#
|
|
17
|
+
# The digest is read once per file contents: it is cached by the file's
|
|
18
|
+
# path, size and mtime, so a process reads each file once and a file
|
|
19
|
+
# redrawn in development gets its new version on the next request.
|
|
20
|
+
module PublicFileVersion
|
|
21
|
+
LENGTH = 8
|
|
22
|
+
@versions = {}
|
|
23
|
+
@lock = Mutex.new
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
# The path with `?v=<digest>` when root/path is a file, else the path as given.
|
|
28
|
+
def path(path, root: default_root)
|
|
29
|
+
version = version(path, root: root)
|
|
30
|
+
version ? "#{path}?v=#{version}" : path
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The first LENGTH hex characters of the file's SHA-256, or nil when it is not a file.
|
|
34
|
+
def version(path, root: default_root)
|
|
35
|
+
return nil if root.nil?
|
|
36
|
+
|
|
37
|
+
file = File.join(root.to_s, path.to_s.delete_prefix("/"))
|
|
38
|
+
stat = File.stat(file)
|
|
39
|
+
return nil unless stat.file?
|
|
40
|
+
|
|
41
|
+
key = [file, stat.size, stat.mtime.to_r]
|
|
42
|
+
@lock.synchronize { @versions[key] ||= Digest::SHA256.file(file).hexdigest[0, LENGTH] }
|
|
43
|
+
rescue SystemCallError
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def default_root
|
|
48
|
+
::Rails.public_path if defined?(::Rails.public_path) && ::Rails.respond_to?(:public_path)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def reset!
|
|
52
|
+
@lock.synchronize { @versions.clear }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/studio/site_footer.rb
CHANGED
|
@@ -183,6 +183,7 @@ module Studio
|
|
|
183
183
|
wordmark: wordmark(facts[:wordmark], site_name),
|
|
184
184
|
logo: facts.key?(:logo) ? text(facts[:logo]) : text(logo),
|
|
185
185
|
logo_invert: facts[:logo_invert] ? true : false,
|
|
186
|
+
lockup: lockup(facts[:lockup]),
|
|
186
187
|
home_path: safe_href(facts[:home_path], "home_path") || "/",
|
|
187
188
|
tagline: text(facts[:tagline]),
|
|
188
189
|
email: text(facts[:email]),
|
|
@@ -253,6 +254,44 @@ module Studio
|
|
|
253
254
|
[words[0..-2].join(" "), words.last]
|
|
254
255
|
end
|
|
255
256
|
|
|
257
|
+
# THE LOCKUP: one piece of brand artwork (an icon and the name drawn
|
|
258
|
+
# together, such as a kit's stacked logo) that the footer draws in place of
|
|
259
|
+
# the logo and the wordmark. One file per theme, as Studio.navbar_wordmark
|
|
260
|
+
# takes them:
|
|
261
|
+
#
|
|
262
|
+
# lockup: { light: "/brand/stacked-light.svg", dark: "/brand/stacked-dark.svg",
|
|
263
|
+
# width: 942, height: 885 }
|
|
264
|
+
#
|
|
265
|
+
# `light` is drawn on a light page, `dark` on a dark one; a lockup with no
|
|
266
|
+
# `dark` uses its `light` file for both. `width` and `height` are the
|
|
267
|
+
# artwork's own size (an SVG's viewBox): written onto both images, they
|
|
268
|
+
# give the browser the shape before the file arrives, so nothing moves
|
|
269
|
+
# when it does. Either one missing or not a positive number, neither is
|
|
270
|
+
# written. No `light`: no lockup, and the logo and wordmark are drawn.
|
|
271
|
+
def lockup(declared)
|
|
272
|
+
return nil unless declared.respond_to?(:to_h) && !declared.is_a?(Array)
|
|
273
|
+
|
|
274
|
+
source = symbolize(declared)
|
|
275
|
+
light = text(source[:light])
|
|
276
|
+
return nil if light.nil?
|
|
277
|
+
|
|
278
|
+
width = dimension(source[:width])
|
|
279
|
+
height = dimension(source[:height])
|
|
280
|
+
sized = !width.nil? && !height.nil?
|
|
281
|
+
{ light: light, dark: text(source[:dark]) || light,
|
|
282
|
+
width: (width if sized), height: (height if sized) }
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# A positive, finite number, rounded to a whole pixel; anything else is nil.
|
|
286
|
+
def dimension(value)
|
|
287
|
+
return nil unless value.is_a?(Numeric) || value.to_s.match?(/\A\s*\d+(\.\d+)?\s*\z/)
|
|
288
|
+
|
|
289
|
+
number = Float(value)
|
|
290
|
+
number.finite? && number.positive? ? [number.round, 1].max : nil
|
|
291
|
+
rescue ArgumentError, TypeError, FloatDomainError
|
|
292
|
+
nil
|
|
293
|
+
end
|
|
294
|
+
|
|
256
295
|
# The address may be nested under :address or written flat (street:,
|
|
257
296
|
# city_line:, lat:, lng:, directions_url:). No street and no city line means
|
|
258
297
|
# no address at all: no Location band and no map.
|
data/lib/studio/version.rb
CHANGED
data/lib/studio.rb
CHANGED
|
@@ -13,6 +13,7 @@ require "active_support/core_ext/numeric/time"
|
|
|
13
13
|
require "active_support/core_ext/integer/time"
|
|
14
14
|
require "studio/version"
|
|
15
15
|
require "studio/local_path"
|
|
16
|
+
require "studio/public_file_version"
|
|
16
17
|
require "studio/component_gallery"
|
|
17
18
|
require "studio/log_rotation"
|
|
18
19
|
require "studio/ip_locations"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: studio-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.110.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex McRitchie
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -660,6 +660,7 @@ files:
|
|
|
660
660
|
- app/views/studio/site_footer/_assets.html.erb
|
|
661
661
|
- app/views/studio/site_footer/_footer.html.erb
|
|
662
662
|
- app/views/studio/site_footer/_link.html.erb
|
|
663
|
+
- app/views/studio/site_footer/_lockup_assets.html.erb
|
|
663
664
|
- app/views/studio/site_footer/_map.html.erb
|
|
664
665
|
- app/views/studio/site_footer/_map_assets.html.erb
|
|
665
666
|
- app/views/studio/site_footer/_social_icon.html.erb
|
|
@@ -768,6 +769,7 @@ files:
|
|
|
768
769
|
- lib/studio/partial_block.rb
|
|
769
770
|
- lib/studio/profile_image.rb
|
|
770
771
|
- lib/studio/profile_sections.rb
|
|
772
|
+
- lib/studio/public_file_version.rb
|
|
771
773
|
- lib/studio/public_user.rb
|
|
772
774
|
- lib/studio/redis.rb
|
|
773
775
|
- lib/studio/s3.rb
|