Create Progressive Web App (#4730)
* Create manifest and serviceworker * Create templates and add AppSubUrl * Add JSRenderer * fix ctx type * Add JSRenderer to static.go * Complete adding {{AppSubUrl}} * Add more fonts to urlsToCache * Add 512px and 192px icons * Hardcode font MD5 * Default theme doesn't have a specific CSS file
This commit is contained in:
parent
e09fe48773
commit
294904321c
9 changed files with 152 additions and 0 deletions
2
Makefile
2
Makefile
|
@ -347,6 +347,8 @@ update-translations:
|
||||||
generate-images:
|
generate-images:
|
||||||
mkdir -p $(TMPDIR)/images
|
mkdir -p $(TMPDIR)/images
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 880 -h 880 -e $(PWD)/public/img/gitea-lg.png
|
inkscape -f $(PWD)/assets/logo.svg -w 880 -h 880 -e $(PWD)/public/img/gitea-lg.png
|
||||||
|
inkscape -f $(PWD)/assets/logo.svg -w 512 -h 512 -e $(PWD)/public/img/gitea-512.png
|
||||||
|
inkscape -f $(PWD)/assets/logo.svg -w 192 -h 192 -e $(PWD)/public/img/gitea-192.png
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer1 -e $(TMPDIR)/images/sm-1.png
|
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer1 -e $(TMPDIR)/images/sm-1.png
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer2 -e $(TMPDIR)/images/sm-2.png
|
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer2 -e $(TMPDIR)/images/sm-2.png
|
||||||
composite -compose atop $(TMPDIR)/images/sm-2.png $(TMPDIR)/images/sm-1.png $(PWD)/public/img/gitea-sm.png
|
composite -compose atop $(TMPDIR)/images/sm-2.png $(TMPDIR)/images/sm-1.png $(PWD)/public/img/gitea-sm.png
|
||||||
|
|
|
@ -45,6 +45,18 @@ func JSONRenderer() macaron.Handler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSRenderer implements the macaron handler for serving JS templates.
|
||||||
|
func JSRenderer() macaron.Handler {
|
||||||
|
return macaron.Renderer(macaron.RenderOptions{
|
||||||
|
Funcs: NewFuncMap(),
|
||||||
|
Directory: path.Join(setting.StaticRootPath, "templates"),
|
||||||
|
AppendDirectories: []string{
|
||||||
|
path.Join(setting.CustomPath, "templates"),
|
||||||
|
},
|
||||||
|
HTMLContentType: "application/javascript",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Mailer provides the templates required for sending notification mails.
|
// Mailer provides the templates required for sending notification mails.
|
||||||
func Mailer() *template.Template {
|
func Mailer() *template.Template {
|
||||||
for _, funcs := range NewFuncMap() {
|
for _, funcs := range NewFuncMap() {
|
||||||
|
|
|
@ -129,6 +129,15 @@ func JSONRenderer() macaron.Handler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSRenderer implements the macaron handler for serving JS templates.
|
||||||
|
func JSRenderer() macaron.Handler {
|
||||||
|
return macaron.Renderer(macaron.RenderOptions{
|
||||||
|
Funcs: NewFuncMap(),
|
||||||
|
TemplateFileSystem: NewTemplateFileSystem(),
|
||||||
|
HTMLContentType: "application/javascript",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Mailer provides the templates required for sending notification mails.
|
// Mailer provides the templates required for sending notification mails.
|
||||||
func Mailer() *template.Template {
|
func Mailer() *template.Template {
|
||||||
for _, funcs := range NewFuncMap() {
|
for _, funcs := range NewFuncMap() {
|
||||||
|
|
BIN
public/img/gitea-192.png
Normal file
BIN
public/img/gitea-192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
BIN
public/img/gitea-512.png
Normal file
BIN
public/img/gitea-512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -791,6 +791,15 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Progressive Web App
|
||||||
|
m.Get("/manifest.json", templates.JSONRenderer(), func(ctx *context.Context) {
|
||||||
|
ctx.HTML(200, "pwa/manifest_json")
|
||||||
|
})
|
||||||
|
|
||||||
|
m.Get("/serviceworker.js", templates.JSRenderer(), func(ctx *context.Context) {
|
||||||
|
ctx.HTML(200, "pwa/serviceworker_js")
|
||||||
|
})
|
||||||
|
|
||||||
// prometheus metrics endpoint
|
// prometheus metrics endpoint
|
||||||
if setting.Metrics.Enabled {
|
if setting.Metrics.Enabled {
|
||||||
c := metrics.NewCollector()
|
c := metrics.NewCollector()
|
||||||
|
|
|
@ -5,6 +5,23 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
|
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
|
||||||
|
<link rel="manifest" href="{{AppSubUrl}}/manifest.json">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js').then(function(registration) {
|
||||||
|
// Registration was successful
|
||||||
|
console.log('ServiceWorker registration successful with scope: ', registration.scope);
|
||||||
|
}, function(err) {
|
||||||
|
// registration failed :(
|
||||||
|
console.log('ServiceWorker registration failed: ', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
<meta name="theme-color" content="{{ThemeColorMetaTag}}">
|
<meta name="theme-color" content="{{ThemeColorMetaTag}}">
|
||||||
<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}" />
|
<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}" />
|
||||||
<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}" />
|
<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}" />
|
||||||
|
|
31
templates/pwa/manifest_json.tmpl
Normal file
31
templates/pwa/manifest_json.tmpl
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"short_name": "Gitea",
|
||||||
|
"name": "Gitea - Git with a cup of tea",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "{{AppSubUrl}}/img/gitea-lg.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "880x880"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "{{AppSubUrl}}/img/gitea-sm.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "120x120"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "{{AppSubUrl}}/img/gitea-512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "{{AppSubUrl}}/img/gitea-192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "{{AppSubUrl}}/",
|
||||||
|
"scope": "{{AppSubUrl}}/",
|
||||||
|
"background_color": "#FAFAFA",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "{{ThemeColorMetaTag}}"
|
||||||
|
}
|
72
templates/pwa/serviceworker_js.tmpl
Normal file
72
templates/pwa/serviceworker_js.tmpl
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
var STATIC_CACHE = 'static-cache-v1';
|
||||||
|
var urlsToCache = [
|
||||||
|
// js
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js',
|
||||||
|
'{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}',
|
||||||
|
'{{AppSubUrl}}/js/draw.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/clipboard/clipboard.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/vue/vue.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/emojify/emojify.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/highlight/highlight.pack.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/codemirror/addon/mode/loadmode.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/codemirror/mode/meta.js',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.js',
|
||||||
|
|
||||||
|
// css
|
||||||
|
'{{AppSubUrl}}/vendor/assets/font-awesome/css/font-awesome.min.css',
|
||||||
|
'{{AppSubUrl}}/vendor/assets/octicons/octicons.min.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/tribute/tribute.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.css',
|
||||||
|
'{{AppSubUrl}}/css/index.css?v={{MD5 AppVer}}',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/highlight/github.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.css',
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.css',
|
||||||
|
{{if ne DefaultTheme "gitea"}}
|
||||||
|
'{{AppSubUrl}}/css/theme-{{DefaultTheme}}.css',
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
// img
|
||||||
|
'{{AppSubUrl}}/img/gitea-sm.png',
|
||||||
|
'{{AppSubUrl}}/img/gitea-lg.png',
|
||||||
|
|
||||||
|
// fonts
|
||||||
|
'{{AppSubUrl}}/vendor/plugins/semantic/themes/default/assets/fonts/icons.woff2',
|
||||||
|
'{{AppSubUrl}}/vendor/assets/octicons/octicons.woff2?ef21c39f0ca9b1b5116e5eb7ac5eabe6',
|
||||||
|
'{{AppSubUrl}}/vendor/assets/lato-fonts/lato-v14-latin-regular.woff2',
|
||||||
|
'{{AppSubUrl}}/vendor/assets/lato-fonts/lato-v14-latin-700.woff2'
|
||||||
|
];
|
||||||
|
|
||||||
|
self.addEventListener('install', function (event) {
|
||||||
|
// Perform install steps
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open(STATIC_CACHE)
|
||||||
|
.then(function (cache) {
|
||||||
|
return cache.addAll(urlsToCache);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', function (event) {
|
||||||
|
event.respondWith(
|
||||||
|
caches.match(event.request)
|
||||||
|
.then(function (response) {
|
||||||
|
// Cache hit - return response
|
||||||
|
if (response) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
return fetch(event.request);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in a new issue