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
})
}
+// 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() {
})
}
+// 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() {
}
})
+ // 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()
<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}}" />
--- /dev/null
+{
+ "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
--- /dev/null
+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);
+ }
+ )
+ );
+});