diff --git a/server/middleware/user_session.go b/server/middleware/user_session.go
index e9bad82d..3d1dae61 100644
--- a/server/middleware/user_session.go
+++ b/server/middleware/user_session.go
@@ -50,7 +50,7 @@ func (s *UserSessionMiddleware) Handler(next http.Handler) http.Handler {
func (s *UserSessionMiddleware) isPublicRoute(r *http.Request) bool {
route := mux.CurrentRoute(r)
switch route.GetName() {
- case "login", "checkLogin", "stylesheet", "javascript", "oauth2Redirect", "oauth2Callback", "appIcon", "favicon":
+ case "login", "checkLogin", "stylesheet", "javascript", "oauth2Redirect", "oauth2Callback", "appIcon", "favicon", "webManifest":
return true
default:
return false
diff --git a/server/routes.go b/server/routes.go
index 06af5818..ffcdc940 100644
--- a/server/routes.go
+++ b/server/routes.go
@@ -80,6 +80,7 @@ func getRoutes(cfg *config.Config, store *storage.Storage, feedHandler *feed.Han
router.Handle("/js", uiHandler.Use(uiController.Javascript)).Name("javascript").Methods("GET")
router.Handle("/favicon.ico", uiHandler.Use(uiController.Favicon)).Name("favicon").Methods("GET")
router.Handle("/icon/{filename}", uiHandler.Use(uiController.AppIcon)).Name("appIcon").Methods("GET")
+ router.Handle("/manifest.json", uiHandler.Use(uiController.WebManifest)).Name("webManifest").Methods("GET")
router.Handle("/subscribe", uiHandler.Use(uiController.AddSubscription)).Name("addSubscription").Methods("GET")
router.Handle("/subscribe", uiHandler.Use(uiController.SubmitSubscription)).Name("submitSubscription").Methods("POST")
diff --git a/server/template/common.go b/server/template/common.go
index ca38f7da..a7202c67 100644
--- a/server/template/common.go
+++ b/server/template/common.go
@@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
-// 2017-12-22 11:25:01.981502305 -0800 PST m=+0.046470067
+// 2017-12-22 20:01:12.434799064 -0800 PST m=+0.047000060
package template
@@ -33,6 +33,7 @@ var templateCommonMap = map[string]string{
+
@@ -127,6 +128,6 @@ var templateCommonMap = map[string]string{
var templateCommonMapChecksums = map[string]string{
"entry_pagination": "f1465fa70f585ae8043b200ec9de5bf437ffbb0c19fb7aefc015c3555614ee27",
- "layout": "ade38fbe1058c8dac86b973c289a716e3f97289735e7ad8e8d1731dc6807e38c",
+ "layout": "778c5cd419c3bd0e35141b1c17bc6775c58b36c650b7566c27ccfd51a6f1417d",
"pagination": "6ff462c2b2a53bc5448b651da017f40a39f1d4f16cef4b2f09784f0797286924",
}
diff --git a/server/template/html/common/layout.html b/server/template/html/common/layout.html
index 91d7a895..746ef8be 100644
--- a/server/template/html/common/layout.html
+++ b/server/template/html/common/layout.html
@@ -8,6 +8,7 @@
+
diff --git a/server/ui/controller/static.go b/server/ui/controller/static.go
index c37fae50..7cf7a35d 100644
--- a/server/ui/controller/static.go
+++ b/server/ui/controller/static.go
@@ -63,3 +63,35 @@ func (c *Controller) AppIcon(ctx *core.Context, request *core.Request, response
response.Cache("image/png", static.BinariesChecksums[filename], blob, 48*time.Hour)
}
+
+// WebManifest renders web manifest file.
+func (c *Controller) WebManifest(ctx *core.Context, request *core.Request, response *core.Response) {
+ type webManifestIcon struct {
+ Source string `json:"src"`
+ Sizes string `json:"sizes"`
+ Type string `json:"type"`
+ }
+
+ type webManifest struct {
+ Name string `json:"name"`
+ Description string `json:"description"`
+ ShortName string `json:"short_name"`
+ StartURL string `json:"start_url"`
+ Icons []webManifestIcon `json:"icons"`
+ Display string `json:"display"`
+ }
+
+ manifest := &webManifest{
+ Name: "Miniflux",
+ ShortName: "Miniflux",
+ Description: "Minimalist Feed Reader",
+ Display: "minimal-ui",
+ StartURL: ctx.Route("unread"),
+ Icons: []webManifestIcon{
+ webManifestIcon{Source: ctx.Route("appIcon", "filename", "touch-icon-ipad-retina.png"), Sizes: "144x144", Type: "image/png"},
+ webManifestIcon{Source: ctx.Route("appIcon", "filename", "touch-icon-iphone-retina.png"), Sizes: "114x114", Type: "image/png"},
+ },
+ }
+
+ response.JSON().Standard(manifest)
+}