lato 0.2.1 → 0.3.1
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/README.md +13 -3
- data/app/assets/javascripts/lato/application.js +14 -4
- data/app/assets/javascripts/lato/controllers/lato_network_controller.js +53 -0
- data/app/views/layouts/lato/_head_content.html.erb +12 -0
- data/app/views/layouts/lato/_network.html.erb +4 -0
- data/app/views/layouts/lato/application.html.erb +3 -3
- data/config/locales/it.yml +1 -1
- data/lib/lato/config.rb +2 -1
- data/lib/lato/version.rb +1 -1
- data/lib/tasks/lato_tasks.rake +140 -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: 288d8c5087ad55acbc2bd7e40a3a4dbbea45592d89b1bab4ca04fcbb367876eb
|
4
|
+
data.tar.gz: b64204ee59d0ff500f26bd37605a0d903f713dba4e4c9fb9aa6ff25395733f43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b12c8cdbd45308fd565669c44b160f99fcbdf02dab34f554b9bc6b278e000d674111b67ea6d802627cef73d341a8fbd44937e0babdd29f985f1f1b35e40975c5
|
7
|
+
data.tar.gz: 453e2ec441176eddaa105606ddf68aed5ae116cbd8b0cfb162bf6029f1eca5fbdd1cc6a29e1349ca6b42dd8b3d9da5a7feea49a9fdb4c4bfc499442e0b78687f
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ Add required dependencies to your application's Gemfile:
|
|
9
9
|
gem "importmap-rails" # NOTE: Probably already installed in default rails 7 project
|
10
10
|
|
11
11
|
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
|
12
|
-
gem "turbo-rails"
|
12
|
+
gem "turbo-rails" # NOTE: Probably already installed in default rails 7 project
|
13
13
|
|
14
14
|
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
|
15
15
|
gem "stimulus-rails" # NOTE: Probably already installed in default rails 7 project
|
@@ -69,9 +69,19 @@ end
|
|
69
69
|
|
70
70
|
```
|
71
71
|
|
72
|
-
|
72
|
+
### Extra tasks
|
73
|
+
Lato integrates by default a basic PWAs manifest and service worker. To re-generate them with all required assets follow these steps:
|
74
|
+
|
75
|
+
1. Complete the configuration of lato on a custom initializer (see [configuration](https://github.com/lato-gam/lato/blob/main/lib/lato/config.rb) options for more details)
|
76
|
+
2. Add an icon.png file on **public/icon.png** with minimum size of 512x512px
|
77
|
+
3. Run the following commands:
|
78
|
+
|
79
|
+
```bash
|
80
|
+
$ rails lato:generate:favicon
|
81
|
+
$ rails lato:generate:pwa
|
82
|
+
```
|
73
83
|
|
74
|
-
|
84
|
+
## Development
|
75
85
|
|
76
86
|
Clone repository, install dependencies, run migrations and start:
|
77
87
|
|
@@ -5,6 +5,20 @@ import "bootstrap"
|
|
5
5
|
// Import controllers (stimulus rails)
|
6
6
|
import "controllers"
|
7
7
|
|
8
|
+
/**
|
9
|
+
* Include service worker
|
10
|
+
*/
|
11
|
+
|
12
|
+
if (navigator.serviceWorker) {
|
13
|
+
navigator.serviceWorker.register("/service-worker.js", { scope: "/" })
|
14
|
+
.then(() => navigator.serviceWorker.ready)
|
15
|
+
.then((registration) => {
|
16
|
+
const event = new CustomEvent("service-worker:ready", { detail: registration })
|
17
|
+
document.dispatchEvent(event)
|
18
|
+
})
|
19
|
+
.then(() => console.log("[App]", "Service worker registered! -> listen to 'service-worker:ready' document event to get the registration object"))
|
20
|
+
}
|
21
|
+
|
8
22
|
/**
|
9
23
|
* Fix form inside turbo-frame tag with redirect
|
10
24
|
* https://github.com/hotwired/turbo-rails/issues/440
|
@@ -22,15 +36,11 @@ document.addEventListener("turbo:frame-missing", event => {
|
|
22
36
|
const PAGE_TRANSITION_TIME = 50
|
23
37
|
|
24
38
|
document.addEventListener('DOMContentLoaded', () => {
|
25
|
-
console.log('DOMContentLoaded')
|
26
|
-
|
27
39
|
// add is-loaded class
|
28
40
|
document.body.classList.add('is-loaded')
|
29
41
|
})
|
30
42
|
|
31
43
|
document.addEventListener('turbo:load', () => {
|
32
|
-
console.log('turbo:load')
|
33
|
-
|
34
44
|
setTimeout(() => {
|
35
45
|
// add is-loaded class
|
36
46
|
document.body.classList.add('is-loaded')
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = [
|
5
|
+
'online',
|
6
|
+
'offline'
|
7
|
+
]
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Stimulus
|
11
|
+
*/
|
12
|
+
|
13
|
+
connect() {
|
14
|
+
window.addEventListener('online', this.onNetworkOnline.bind(this))
|
15
|
+
window.addEventListener('offline', this.onNetworkOffline.bind(this))
|
16
|
+
|
17
|
+
if (!navigator.onLine) {
|
18
|
+
this.onNetworkOffline()
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
disconnect() {
|
23
|
+
window.removeEventListener('online', this.onNetworkOnline.bind(this))
|
24
|
+
window.removeEventListener('offline', this.onNetworkOffline.bind(this))
|
25
|
+
if (this.timeout) clearTimeout(this.timeout)
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Events
|
30
|
+
*/
|
31
|
+
|
32
|
+
onNetworkOnline() {
|
33
|
+
this.element.classList.remove('d-none')
|
34
|
+
this.onlineTarget.classList.remove('d-none')
|
35
|
+
this.offlineTarget.classList.add('d-none')
|
36
|
+
|
37
|
+
if (this.timeout) clearTimeout(this.timeout)
|
38
|
+
this.timeout = setTimeout(() => {
|
39
|
+
this.element.classList.add('d-none')
|
40
|
+
}, 5000)
|
41
|
+
}
|
42
|
+
|
43
|
+
onNetworkOffline() {
|
44
|
+
this.element.classList.remove('d-none')
|
45
|
+
this.onlineTarget.classList.add('d-none')
|
46
|
+
this.offlineTarget.classList.remove('d-none')
|
47
|
+
|
48
|
+
if (this.timeout) clearTimeout(this.timeout)
|
49
|
+
this.timeout = setTimeout(() => {
|
50
|
+
this.element.classList.add('d-none')
|
51
|
+
}, 5000)
|
52
|
+
}
|
53
|
+
}
|
@@ -1 +1,13 @@
|
|
1
|
+
<meta name="application-name" content="<%= Lato.config.application_title %>">
|
2
|
+
<meta name="theme-color" content="<%= Lato.config.application_brand_color %>">
|
3
|
+
<meta name="full-screen" content="yes">
|
4
|
+
<meta name="browsermode" content="application">
|
5
|
+
<meta name="screen-orientation" content="portrait">
|
6
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
7
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
8
|
+
<meta name="apple-mobile-web-app-title" content="<%= Lato.config.application_title %>">
|
9
|
+
|
10
|
+
<link rel="icon" href="/favicon.ico">
|
11
|
+
<link rel="manifest" href="/manifest.json">
|
12
|
+
|
1
13
|
<!-- Free for head tags -->
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<div class="fixed-bottom p-3 d-none" data-controller="lato-network">
|
2
|
+
<span class="badge rounded-pill text-bg-danger fs-6 d-none" data-lato-network-target="offline">You are offline</span>
|
3
|
+
<span class="badge rounded-pill text-bg-success fs-6 d-none" data-lato-network-target="online">You are online</span>
|
4
|
+
</div>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<%= csrf_meta_tags %>
|
8
8
|
<%= csp_meta_tag %>
|
9
9
|
|
10
|
-
|
10
|
+
<% # TEMPORARY FIX: Popper js not working using bootstrap-gem %>
|
11
11
|
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
|
12
12
|
|
13
13
|
<%= render 'layouts/lato/head_content' %>
|
@@ -36,8 +36,6 @@
|
|
36
36
|
</main>
|
37
37
|
</div>
|
38
38
|
|
39
|
-
|
40
|
-
|
41
39
|
<footer>
|
42
40
|
<%= render 'layouts/lato/footer' %>
|
43
41
|
</footer>
|
@@ -45,8 +43,10 @@
|
|
45
43
|
<% if @layout_sidebar %>
|
46
44
|
<%= render 'layouts/lato/aside-opener' %>
|
47
45
|
<% end %>
|
46
|
+
|
48
47
|
<%= render 'layouts/lato/feedbacks' %>
|
49
48
|
<%= render 'layouts/lato/action' %>
|
49
|
+
<%= render 'layouts/lato/network' %>
|
50
50
|
|
51
51
|
<%= render 'layouts/lato/foot_content' %>
|
52
52
|
</body>
|
data/config/locales/it.yml
CHANGED
data/lib/lato/config.rb
CHANGED
@@ -4,7 +4,7 @@ module Lato
|
|
4
4
|
##
|
5
5
|
class Config
|
6
6
|
# Applicaction configs
|
7
|
-
attr_accessor :application_title, :application_version, :application_company_name, :application_company_url
|
7
|
+
attr_accessor :application_title, :application_version, :application_company_name, :application_company_url, :application_brand_color
|
8
8
|
|
9
9
|
# Session configs
|
10
10
|
attr_accessor :session_lifetime, :session_root_path
|
@@ -26,6 +26,7 @@ module Lato
|
|
26
26
|
@application_version = '1.0.0'
|
27
27
|
@application_company_name = 'Lato Team'
|
28
28
|
@application_company_url = 'https://github.com/Lato-GAM'
|
29
|
+
@application_brand_color = '#03256c'
|
29
30
|
|
30
31
|
@auth_disable_signup = false
|
31
32
|
@auth_disable_recover_password = false
|
data/lib/lato/version.rb
CHANGED
data/lib/tasks/lato_tasks.rake
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
namespace :lato do
|
4
5
|
namespace :install do
|
@@ -33,6 +34,145 @@ namespace :lato do
|
|
33
34
|
gem_concern_path = Lato::Engine.root.join('app', 'models', 'concerns', 'lato_user_application.rb').to_s
|
34
35
|
app_concern_path = Rails.root.join('app', 'models', 'concerns', 'lato_user_application.rb').to_s
|
35
36
|
FileUtils.copy(gem_concern_path, app_concern_path) unless File.exist? app_concern_path
|
37
|
+
|
38
|
+
# Generate sample manifest.json file in public folder
|
39
|
+
##
|
40
|
+
|
41
|
+
manifest_path = Rails.root.join('public', 'manifest.json')
|
42
|
+
unless File.exist? manifest_path
|
43
|
+
manifest = {
|
44
|
+
name: "Application",
|
45
|
+
short_name: "Application",
|
46
|
+
start_url: "/",
|
47
|
+
scope: "/",
|
48
|
+
display: "standalone",
|
49
|
+
orientation: "portrait",
|
50
|
+
theme_color: "#000000",
|
51
|
+
background_color: "#000000",
|
52
|
+
icons: []
|
53
|
+
}
|
54
|
+
File.open(manifest_path, 'w') { |f| f.write(JSON.pretty_generate(manifest)) }
|
55
|
+
end
|
56
|
+
|
57
|
+
# Generate sample service-worker.js file in public folder
|
58
|
+
##
|
59
|
+
|
60
|
+
service_worker_path = Rails.root.join('public', 'service-worker.js')
|
61
|
+
unless File.exist? service_worker_path
|
62
|
+
service_worker = <<-JS
|
63
|
+
function onInstall(event) {
|
64
|
+
console.log('[Serviceworker]', "Installing!", event);
|
65
|
+
}
|
66
|
+
function onActivate(event) {
|
67
|
+
console.log('[Serviceworker]', "Activating!", event);
|
68
|
+
}
|
69
|
+
function onFetch(event) {
|
70
|
+
console.log('[Serviceworker]', "Fetching!", event);
|
71
|
+
}
|
72
|
+
self.addEventListener('install', onInstall);
|
73
|
+
self.addEventListener('activate', onActivate);
|
74
|
+
self.addEventListener('fetch', onFetch);
|
75
|
+
JS
|
76
|
+
File.open(service_worker_path, 'w') { |f| f.write(service_worker) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
namespace :generate do
|
82
|
+
desc "Generate PWA icons from a single icon.png file (512x512) that should be placed inside 'public' folder"
|
83
|
+
# Usage: rails lato:generate:pwa
|
84
|
+
task :pwa do
|
85
|
+
# check if icon.png exists
|
86
|
+
icon_path = Rails.root.join('public', 'icon.png')
|
87
|
+
unless File.exist? icon_path
|
88
|
+
puts 'ERROR: icon.png file not found inside public folder'
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
# check MiniMagick is installed
|
93
|
+
begin
|
94
|
+
require 'mini_magick'
|
95
|
+
rescue LoadError
|
96
|
+
puts 'ERROR: mini_magick gem not found, please add it to your Gemfile'
|
97
|
+
return
|
98
|
+
end
|
99
|
+
|
100
|
+
# be sure icon.png is min 512x512
|
101
|
+
image = MiniMagick::Image.open(icon_path)
|
102
|
+
if image.width < 512 || image.height < 512 || image.width != image.height
|
103
|
+
puts 'ERROR: icon.png image size is not valid, it should be square and min 512x512'
|
104
|
+
return
|
105
|
+
end
|
106
|
+
|
107
|
+
# create icons folder if not exists
|
108
|
+
icons_path = Rails.root.join('public', 'icons')
|
109
|
+
FileUtils.mkdir_p(icons_path) unless File.exist? icons_path
|
110
|
+
|
111
|
+
# create icons
|
112
|
+
sizes = [16, 32, 48, 72, 96, 144, 152, 192, 384, 512]
|
113
|
+
sizes.each do |size|
|
114
|
+
file_path = "#{icons_path}/icon_#{size}x#{size}.png"
|
115
|
+
file_image = MiniMagick::Image.open(icon_path)
|
116
|
+
FileUtils.rm(file_path) if File.exist? file_path
|
117
|
+
file_image.resize "#{size}x#{size}"
|
118
|
+
file_image.write file_path
|
119
|
+
end
|
120
|
+
|
121
|
+
# create manifest.json
|
122
|
+
manifest_path = Rails.root.join('public', 'manifest.json')
|
123
|
+
manifest = {
|
124
|
+
name: Lato.config.application_title,
|
125
|
+
short_name: Lato.config.application_title,
|
126
|
+
start_url: '/',
|
127
|
+
scope: '/',
|
128
|
+
display: 'standalone',
|
129
|
+
orientation: 'portrait',
|
130
|
+
theme_color: Lato.config.application_brand_color,
|
131
|
+
background_color: Lato.config.application_brand_color,
|
132
|
+
icons: []
|
133
|
+
}
|
134
|
+
sizes.each do |size|
|
135
|
+
manifest[:icons] << {
|
136
|
+
src: "/icons/icon_#{size}x#{size}.png",
|
137
|
+
sizes: "#{size}x#{size}",
|
138
|
+
type: 'image/png'
|
139
|
+
}
|
140
|
+
end
|
141
|
+
FileUtils.rm(manifest_path) if File.exist? manifest_path
|
142
|
+
File.open(manifest_path, 'w') { |f| f.write(JSON.pretty_generate(manifest)) }
|
143
|
+
end
|
144
|
+
|
145
|
+
desc "Generate favicon.ico from a single icon.png file (512x512) that should be placed inside 'public' folder"
|
146
|
+
# Usage: rails lato:generate:favicon
|
147
|
+
task :favicon do
|
148
|
+
# check if icon.png exists
|
149
|
+
icon_path = Rails.root.join('public', 'icon.png')
|
150
|
+
unless File.exist? icon_path
|
151
|
+
puts 'ERROR: icon.png file not found inside public folder'
|
152
|
+
return
|
153
|
+
end
|
154
|
+
|
155
|
+
# check MiniMagick is installed
|
156
|
+
begin
|
157
|
+
require 'mini_magick'
|
158
|
+
rescue LoadError
|
159
|
+
puts 'ERROR: mini_magick gem not found, please add it to your Gemfile'
|
160
|
+
return
|
161
|
+
end
|
162
|
+
|
163
|
+
# be sure icon.png is min 512x512
|
164
|
+
image = MiniMagick::Image.open(icon_path)
|
165
|
+
if image.width < 512 || image.height < 512 || image.width != image.height
|
166
|
+
puts 'ERROR: icon.png image size is not valid, it should be square and min 512x512'
|
167
|
+
return
|
168
|
+
end
|
169
|
+
|
170
|
+
# create favicon.ico
|
171
|
+
file_path = Rails.root.join('public', 'favicon.ico')
|
172
|
+
file_image = MiniMagick::Image.open(icon_path)
|
173
|
+
FileUtils.rm(file_path) if File.exist? file_path
|
174
|
+
file_image.resize '48x48'
|
175
|
+
file_image.write file_path
|
36
176
|
end
|
37
177
|
end
|
38
178
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lato
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregorio Galante
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- app/assets/javascripts/lato/controllers/lato_form_controller.js
|
119
119
|
- app/assets/javascripts/lato/controllers/lato_hello_controller.js
|
120
120
|
- app/assets/javascripts/lato/controllers/lato_input_autocomplete_controller.js
|
121
|
+
- app/assets/javascripts/lato/controllers/lato_network_controller.js
|
121
122
|
- app/assets/javascripts/lato/controllers/lato_operation_controller.js
|
122
123
|
- app/assets/stylesheets/lato/application.scss
|
123
124
|
- app/controllers/concerns/lato/componentable.rb
|
@@ -186,6 +187,7 @@ files:
|
|
186
187
|
- app/views/layouts/lato/_navbar-brand_content.html.erb
|
187
188
|
- app/views/layouts/lato/_navbar-nav_content.html.erb
|
188
189
|
- app/views/layouts/lato/_navbar.html.erb
|
190
|
+
- app/views/layouts/lato/_network.html.erb
|
189
191
|
- app/views/layouts/lato/_sidebar-nav_content.html.erb
|
190
192
|
- app/views/layouts/lato/_sidebar.html.erb
|
191
193
|
- app/views/layouts/lato/application.html.erb
|