From 294904321cb6de535237a6a156d5c4ec462bc117 Mon Sep 17 00:00:00 2001 From: SohnyBohny <sohny.bean@streber24.de> Date: Tue, 27 Nov 2018 16:18:26 +0100 Subject: [PATCH] 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 --- Makefile | 2 + modules/templates/dynamic.go | 12 +++++ modules/templates/static.go | 9 ++++ public/img/gitea-192.png | Bin 0 -> 8738 bytes public/img/gitea-512.png | Bin 0 -> 25737 bytes routers/routes/routes.go | 9 ++++ templates/base/head.tmpl | 17 +++++++ templates/pwa/manifest_json.tmpl | 31 ++++++++++++ templates/pwa/serviceworker_js.tmpl | 72 ++++++++++++++++++++++++++++ 9 files changed, 152 insertions(+) create mode 100644 public/img/gitea-192.png create mode 100644 public/img/gitea-512.png create mode 100644 templates/pwa/manifest_json.tmpl create mode 100644 templates/pwa/serviceworker_js.tmpl diff --git a/Makefile b/Makefile index 6f3779e30b..5e7e72df0b 100644 --- a/Makefile +++ b/Makefile @@ -347,6 +347,8 @@ update-translations: generate-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 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 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 diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go index d70a465c1c..dbd75221d2 100644 --- a/modules/templates/dynamic.go +++ b/modules/templates/dynamic.go @@ -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. func Mailer() *template.Template { for _, funcs := range NewFuncMap() { diff --git a/modules/templates/static.go b/modules/templates/static.go index 6fd4d245e1..e69e1cae48 100644 --- a/modules/templates/static.go +++ b/modules/templates/static.go @@ -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. func Mailer() *template.Template { for _, funcs := range NewFuncMap() { diff --git a/public/img/gitea-192.png b/public/img/gitea-192.png new file mode 100644 index 0000000000000000000000000000000000000000..63f963e846a9cdb153e8131179e7d347400c412e GIT binary patch literal 8738 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 S9-hu~01C3IGF8&BkpBS!?Tk49 literal 0 HcmV?d00001 diff --git a/public/img/gitea-512.png b/public/img/gitea-512.png new file mode 100644 index 0000000000000000000000000000000000000000..59d1fed7d976bfae5b710aa04d983329641e8898 GIT binary patch literal 25737 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 literal 0 HcmV?d00001 diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 06292557b3..1c1bcd8f95 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -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 if setting.Metrics.Enabled { c := metrics.NewCollector() diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index bb6a8a981b..47c0d6b473 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -5,6 +5,23 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <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="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}}" /> diff --git a/templates/pwa/manifest_json.tmpl b/templates/pwa/manifest_json.tmpl new file mode 100644 index 0000000000..557bee5d76 --- /dev/null +++ b/templates/pwa/manifest_json.tmpl @@ -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}}" + } \ No newline at end of file diff --git a/templates/pwa/serviceworker_js.tmpl b/templates/pwa/serviceworker_js.tmpl new file mode 100644 index 0000000000..5e5860ebb0 --- /dev/null +++ b/templates/pwa/serviceworker_js.tmpl @@ -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); + } + ) + ); +});