From 294904321cb6de535237a6a156d5c4ec462bc117 Mon Sep 17 00:00:00 2001 From: SohnyBohny 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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

iRIRtht!NLOL!odOfQgxezV=w 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 YlAWYk4rk^E0001G1r7NcIe7U000QldIRF3v 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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%0AZMs2$Q4T^h2M#@Oo!syOG;Ju{5 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 {{if .Title}}{{.Title}} - {{end}}{{AppName}} + + + + 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); + } + ) + ); +});