aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorGravatar Frédéric Guillot <fred@miniflux.net>2017-11-21 14:44:47 -0800
committerGravatar Frédéric Guillot <fred@miniflux.net>2017-11-21 14:44:47 -0800
commit5983db1a770e458c4ecbbe9a4a2df70f0ebc0d9a (patch)
tree454cea39e4aa6017381ab5334f50ea00b8689501 /server
parent25a5250eb9c6410fcd2876a941f9128ebd3d9bc4 (diff)
Ask for confirmation before removing something
Diffstat (limited to 'server')
-rw-r--r--server/routes.go8
-rw-r--r--server/static/bin.go2
-rw-r--r--server/static/css.go6
-rw-r--r--server/static/css/common.css23
-rw-r--r--server/static/js.go8
-rw-r--r--server/static/js/app.js56
-rw-r--r--server/template/common.go2
-rw-r--r--server/template/html/categories.html8
-rw-r--r--server/template/html/feeds.html8
-rw-r--r--server/template/html/sessions.html10
-rw-r--r--server/template/html/users.html8
-rw-r--r--server/template/views.go44
12 files changed, 148 insertions, 35 deletions
diff --git a/server/routes.go b/server/routes.go
index 4f6b1d4..239f5fa 100644
--- a/server/routes.go
+++ b/server/routes.go
@@ -74,7 +74,7 @@ func getRoutes(store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
router.Handle("/feed/{feedID}/refresh", uiHandler.Use(uiController.RefreshFeed)).Name("refreshFeed").Methods("GET")
router.Handle("/feed/{feedID}/edit", uiHandler.Use(uiController.EditFeed)).Name("editFeed").Methods("GET")
- router.Handle("/feed/{feedID}/remove", uiHandler.Use(uiController.RemoveFeed)).Name("removeFeed").Methods("GET")
+ router.Handle("/feed/{feedID}/remove", uiHandler.Use(uiController.RemoveFeed)).Name("removeFeed").Methods("POST")
router.Handle("/feed/{feedID}/update", uiHandler.Use(uiController.UpdateFeed)).Name("updateFeed").Methods("POST")
router.Handle("/feed/{feedID}/entries", uiHandler.Use(uiController.ShowFeedEntries)).Name("feedEntries").Methods("GET")
router.Handle("/feeds", uiHandler.Use(uiController.ShowFeedsPage)).Name("feeds").Methods("GET")
@@ -92,7 +92,7 @@ func getRoutes(store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
router.Handle("/category/{categoryID}/entries", uiHandler.Use(uiController.ShowCategoryEntries)).Name("categoryEntries").Methods("GET")
router.Handle("/category/{categoryID}/edit", uiHandler.Use(uiController.EditCategory)).Name("editCategory").Methods("GET")
router.Handle("/category/{categoryID}/update", uiHandler.Use(uiController.UpdateCategory)).Name("updateCategory").Methods("POST")
- router.Handle("/category/{categoryID}/remove", uiHandler.Use(uiController.RemoveCategory)).Name("removeCategory").Methods("GET")
+ router.Handle("/category/{categoryID}/remove", uiHandler.Use(uiController.RemoveCategory)).Name("removeCategory").Methods("POST")
router.Handle("/icon/{iconID}", uiHandler.Use(uiController.ShowIcon)).Name("icon").Methods("GET")
router.Handle("/proxy/{encodedURL}", uiHandler.Use(uiController.ImageProxy)).Name("proxy").Methods("GET")
@@ -102,7 +102,7 @@ func getRoutes(store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
router.Handle("/user/save", uiHandler.Use(uiController.SaveUser)).Name("saveUser").Methods("POST")
router.Handle("/users/{userID}/edit", uiHandler.Use(uiController.EditUser)).Name("editUser").Methods("GET")
router.Handle("/users/{userID}/update", uiHandler.Use(uiController.UpdateUser)).Name("updateUser").Methods("POST")
- router.Handle("/users/{userID}/remove", uiHandler.Use(uiController.RemoveUser)).Name("removeUser").Methods("GET")
+ router.Handle("/users/{userID}/remove", uiHandler.Use(uiController.RemoveUser)).Name("removeUser").Methods("POST")
router.Handle("/about", uiHandler.Use(uiController.AboutPage)).Name("about").Methods("GET")
@@ -110,7 +110,7 @@ func getRoutes(store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
router.Handle("/settings", uiHandler.Use(uiController.UpdateSettings)).Name("updateSettings").Methods("POST")
router.Handle("/sessions", uiHandler.Use(uiController.ShowSessions)).Name("sessions").Methods("GET")
- router.Handle("/sessions/{sessionID}/remove", uiHandler.Use(uiController.RemoveSession)).Name("removeSession").Methods("GET")
+ router.Handle("/sessions/{sessionID}/remove", uiHandler.Use(uiController.RemoveSession)).Name("removeSession").Methods("POST")
router.Handle("/export", uiHandler.Use(uiController.Export)).Name("export").Methods("GET")
router.Handle("/import", uiHandler.Use(uiController.Import)).Name("import").Methods("GET")
diff --git a/server/static/bin.go b/server/static/bin.go
index 0fef1c4..af1c085 100644
--- a/server/static/bin.go
+++ b/server/static/bin.go
@@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
-// 2017-11-20 18:31:16.964945842 -0800 PST m=+0.004093224
+// 2017-11-21 14:38:46.651098874 -0800 PST m=+0.002920446
package static
diff --git a/server/static/css.go b/server/static/css.go
index d9d5126..e632be5 100644
--- a/server/static/css.go
+++ b/server/static/css.go
@@ -1,14 +1,14 @@
// Code generated by go generate; DO NOT EDIT.
-// 2017-11-20 18:31:16.967667594 -0800 PST m=+0.006814976
+// 2017-11-21 14:38:46.651532115 -0800 PST m=+0.003353687
package static
var Stylesheets = map[string]string{
"black": `body{background:#222;color:#efefef}h1,h2,h3{color:#aaa}a{color:#aaa}a:focus,a:hover{color:#ddd}.header li{border-color:#333}.header a{color:#ddd;font-weight:400}.header .active a{font-weight:400;color:#9b9494}.header a:focus,.header a:hover{color:rgba(82,168,236,.85)}.page-header h1{border-color:#333}.logo a:hover span{color:#555}table,th,td{border:1px solid #555}th{background:#333;color:#aaa;font-weight:400}tr:hover{background-color:#333;color:#aaa}input[type=url],input[type=password],input[type=text]{border:1px solid #555;background:#333;color:#ccc}input[type=url]:focus,input[type=password]:focus,input[type=text]:focus{color:#efefef;border-color:rgba(82,168,236,.8);box-shadow:0 0 8px rgba(82,168,236,.6)}.button-primary{border-color:#444;background:#333;color:#efefef}.button-primary:hover,.button-primary:focus{border-color:#888;background:#555}.alert,.alert-success,.alert-error,.alert-info,.alert-normal{color:#efefef;background-color:#333;border-color:#444}.panel{background:#333;border-color:#555}.unread-counter{color:#bbb}.category{color:#efefef;background-color:#333;border-color:#444}.category a{color:#999}.category a:hover,.category a:focus{color:#aaa}.pagination a{color:#aaa}.pagination-bottom{border-color:#333}.item{border-color:#666;padding:4px}.item.current-item{border-width:2px;border-color:rgba(82,168,236,.8);box-shadow:0 0 8px rgba(82,168,236,.6)}.item-title a{font-weight:400}.item-status-read .item-title a{color:#666}.item-status-read .item-title a:focus,.item-status-read .item-title a:hover{color:rgba(82,168,236,.6)}.item-meta a:hover,.item-meta a:focus{color:#aaa}.item-meta li:after{color:#ddd}.entry header{border-color:#333}.entry header h1 a{color:#bbb}.entry-content,.entry-content p,ul{color:#999}.entry-content pre,.entry-content code{color:#fff;background:#555;border-color:#888}.entry-enclosure{border-color:#333}`,
- "common": `*{margin:0;padding:0;box-sizing:border-box}body{font-family:helvetica neue,Helvetica,Arial,sans-serif;text-rendering:optimizeLegibility}.main{padding-left:3px;padding-right:3px}a{color:#36c}a:focus{outline:0;color:red;text-decoration:none;border:1px dotted #aaa}a:hover{color:#333;text-decoration:none}.header{margin-top:10px;margin-bottom:20px}.header nav ul{display:none}.header li{cursor:pointer;padding-left:10px;line-height:2.1em;font-size:1.2em;border-bottom:1px dotted #ddd}.header li:hover a{color:#888}.header a{font-size:.9em;color:#444;text-decoration:none;border:0}.header .active a{font-weight:600}.header a:hover,.header a:focus{color:#888}.page-header{margin-bottom:25px}.page-header h1{font-weight:500;border-bottom:1px dotted #ddd}.page-header ul{margin-left:25px;font-size:.9em}.page-header li{list-style-type:circle;line-height:1.4em}.logo{cursor:pointer;text-align:center}.logo a{color:#000;letter-spacing:1px}.logo a:hover{color:#396}.logo a span{color:#396}.logo a:hover span{color:#000}@media(min-width:600px){body{margin:auto;max-width:750px}.logo{text-align:left;float:left;margin-right:15px}.header nav ul{display:block}.header li{display:inline;padding:0;padding-right:15px;line-height:normal;font-size:1em;border:0}.page-header ul{margin-left:0}.page-header li{display:inline;padding-right:15px}}table{width:100%;border-collapse:collapse}table,th,td{border:1px solid #ddd}th,td{padding:5px;text-align:left}td{vertical-align:top}th{background:#fcfcfc}.table-overflow td{max-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}tr:hover{background-color:#f9f9f9}.column-40{width:40%}.column-25{width:25%}.column-20{width:20%}label{cursor:pointer;display:block}.radio-group{line-height:1.9em}div.radio-group label{display:inline-block}select{margin-bottom:15px}input[type=url],input[type=password],input[type=text]{border:1px solid #ccc;padding:3px;line-height:15px;width:250px;font-size:99%;margin-bottom:10px;margin-top:5px;-webkit-appearance:none}input[type=url]:focus,input[type=password]:focus,input[type=text]:focus{color:#000;border-color:rgba(82,168,236,.8);outline:0;box-shadow:0 0 8px rgba(82,168,236,.6)}::-moz-placeholder,::-ms-input-placeholder,::-webkit-input-placeholder{color:#ddd;padding-top:2px}.form-help{font-size:.9em;color:brown;margin-bottom:15px}a.button{text-decoration:none}.button{display:inline-block;-webkit-appearance:none;-moz-appearance:none;font-size:1.1em;cursor:pointer;padding:3px 10px;border:1px solid;border-radius:unset}.button-primary{border-color:#3079ed;background:#4d90fe;color:#fff}.button-primary:hover,.button-primary:focus{border-color:#2f5bb7;background:#357ae8}.button-danger{border-color:#b0281a;background:#d14836;color:#fff}.button-danger:hover,.button-danger:focus{color:#fff;background:#c53727}.button:disabled{color:#ccc;background:#f7f7f7;border-color:#ccc}.buttons{margin-top:10px;margin-bottom:20px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;background-color:#fcf8e3;border:1px solid #fbeed5;border-radius:4px;overflow:auto}.alert h3{margin-top:0;margin-bottom:15px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-error a{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel{color:#333;background-color:#f0f0f0;border:1px solid #ddd;border-radius:5px;padding:10px;margin-bottom:15px}.panel h3{font-weight:500;margin-top:0;margin-bottom:20px}.panel ul{margin-left:30px}.login-form{margin:auto;margin-top:50px;width:350px}.unread-counter{font-size:.8em;font-weight:300;color:#666}.category{font-size:.75em;background-color:#fffcd7;border:1px solid #d5d458;border-radius:5px;margin-left:.25em;padding:1px .4em;white-space:nowrap}.category a{color:#555;text-decoration:none}.category a:hover,.category a:focus{color:#000}.pagination{font-size:1.1em;display:flex;align-items:center;padding-top:8px}.pagination-bottom{border-top:1px dotted #ddd;margin-bottom:15px;margin-top:50px}.pagination>div{flex:1}.pagination-next{text-align:right}.pagination-prev:before{content:"« "}.pagination-next:after{content:" »"}.pagination a{color:#333}.pagination a:hover,.pagination a:focus{text-decoration:none}.item{border:1px dotted #ddd;margin-bottom:20px;padding:5px;overflow:hidden}.item.current-item{border:3px solid #bce;padding:3px}.item-title a{text-decoration:none;font-weight:600}.item-status-read .item-title a{color:#777}.item-meta{color:#777;font-size:.8em}.item-meta a{color:#777;text-decoration:none}.item-meta a:hover,.item-meta a:focus{color:#333}.item-meta ul{margin-top:5px}.item-meta li{display:inline}.item-meta li:after{content:"|";color:#aaa}.item-meta li:last-child:after{content:""}.hide-read-items .item-status-read{display:none}.entry header{padding-bottom:5px;border-bottom:1px dotted #ddd}.entry header h1{font-size:2em;line-height:1.25em;margin:30px 0}.entry header h1 a{text-decoration:none;color:#333}.entry header h1 a:hover,.entry header h1 a:focus{color:#666}.entry-meta{font-size:.95em;margin:0 0 20px;color:#666}.entry-website img{vertical-align:top}.entry-website a{color:#666;vertical-align:top;text-decoration:none}.entry-website a:hover,.entry-website a:focus{text-decoration:underline}.entry-date{font-size:.65em;font-style:italic;color:#555}.entry-content{padding-top:15px;font-size:1.1em;font-weight:300;color:#444}.entry-content h1,h2,h3,h4,h5,h6{margin-top:15px}.entry-content iframe,.entry-content video,.entry-content img{max-width:100%}.entry-content figure img{border:1px solid #000}.entry-content figcaption{font-size:.75em;text-transform:uppercase;color:#777}.entry-content p{margin-top:15px;margin-bottom:15px;text-align:justify}.entry-content a:visited{color:purple}.entry-content dt{font-weight:500;margin-top:15px;color:#555}.entry-content dd{margin-left:15px;margin-top:5px;padding-left:20px;border-left:3px solid #ddd;color:#777;font-weight:300;line-height:1.4em}.entry-content blockquote{border-left:4px solid #ddd;padding-left:25px;margin-left:20px;margin-top:20px;margin-bottom:20px;color:#888;line-height:1.4em;font-family:Georgia,serif}.entry-content blockquote+p{color:#555;font-style:italic;font-weight:200}.entry-content q{color:purple;font-family:Georgia,serif;font-style:italic}.entry-content q:before{content:"“"}.entry-content q:after{content:"”"}.entry-content pre{padding:5px;background:#f0f0f0;border:1px solid #ddd;overflow:scroll}.entry-content ul,.entry-content ol{margin-left:30px}.entry-content ul{list-style-type:square}.entry-enclosures h3{font-weight:500}.entry-enclosure{border:1px dotted #ddd;padding:5px;margin-top:10px;max-width:100%}.entry-enclosure-download{font-size:.85em}.enclosure-video video,.enclosure-image img{max-width:100%}`,
+ "common": `*{margin:0;padding:0;box-sizing:border-box}body{font-family:helvetica neue,Helvetica,Arial,sans-serif;text-rendering:optimizeLegibility}.main{padding-left:3px;padding-right:3px}a{color:#36c}a:focus{outline:0;color:red;text-decoration:none;border:1px dotted #aaa}a:hover{color:#333;text-decoration:none}.header{margin-top:10px;margin-bottom:20px}.header nav ul{display:none}.header li{cursor:pointer;padding-left:10px;line-height:2.1em;font-size:1.2em;border-bottom:1px dotted #ddd}.header li:hover a{color:#888}.header a{font-size:.9em;color:#444;text-decoration:none;border:0}.header .active a{font-weight:600}.header a:hover,.header a:focus{color:#888}.page-header{margin-bottom:25px}.page-header h1{font-weight:500;border-bottom:1px dotted #ddd}.page-header ul{margin-left:25px;font-size:.9em}.page-header li{list-style-type:circle;line-height:1.4em}.logo{cursor:pointer;text-align:center}.logo a{color:#000;letter-spacing:1px}.logo a:hover{color:#396}.logo a span{color:#396}.logo a:hover span{color:#000}@media(min-width:600px){body{margin:auto;max-width:750px}.logo{text-align:left;float:left;margin-right:15px}.header nav ul{display:block}.header li{display:inline;padding:0;padding-right:15px;line-height:normal;font-size:1em;border:0}.page-header ul{margin-left:0}.page-header li{display:inline;padding-right:15px}}table{width:100%;border-collapse:collapse}table,th,td{border:1px solid #ddd}th,td{padding:5px;text-align:left}td{vertical-align:top}th{background:#fcfcfc}tr:hover{background-color:#f9f9f9}.column-40{width:40%}.column-25{width:25%}.column-20{width:20%}label{cursor:pointer;display:block}.radio-group{line-height:1.9em}div.radio-group label{display:inline-block}select{margin-bottom:15px}input[type=url],input[type=password],input[type=text]{border:1px solid #ccc;padding:3px;line-height:20px;width:250px;font-size:99%;margin-bottom:10px;margin-top:5px;-webkit-appearance:none}input[type=url]:focus,input[type=password]:focus,input[type=text]:focus{color:#000;border-color:rgba(82,168,236,.8);outline:0;box-shadow:0 0 8px rgba(82,168,236,.6)}::-moz-placeholder,::-ms-input-placeholder,::-webkit-input-placeholder{color:#ddd;padding-top:2px}.form-help{font-size:.9em;color:brown;margin-bottom:15px}a.button{text-decoration:none}.button{display:inline-block;-webkit-appearance:none;-moz-appearance:none;font-size:1.1em;cursor:pointer;padding:3px 10px;border:1px solid;border-radius:unset}.button-primary{border-color:#3079ed;background:#4d90fe;color:#fff}.button-primary:hover,.button-primary:focus{border-color:#2f5bb7;background:#357ae8}.button-danger{border-color:#b0281a;background:#d14836;color:#fff}.button-danger:hover,.button-danger:focus{color:#fff;background:#c53727}.button:disabled{color:#ccc;background:#f7f7f7;border-color:#ccc}.buttons{margin-top:10px;margin-bottom:20px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;background-color:#fcf8e3;border:1px solid #fbeed5;border-radius:4px;overflow:auto}.alert h3{margin-top:0;margin-bottom:15px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-error a{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel{color:#333;background-color:#f0f0f0;border:1px solid #ddd;border-radius:5px;padding:10px;margin-bottom:15px}.panel h3{font-weight:500;margin-top:0;margin-bottom:20px}.panel ul{margin-left:30px}.login-form{margin:auto;margin-top:50px;width:350px}.unread-counter{font-size:.8em;font-weight:300;color:#666}.category{font-size:.75em;background-color:#fffcd7;border:1px solid #d5d458;border-radius:5px;margin-left:.25em;padding:1px .4em;white-space:nowrap}.category a{color:#555;text-decoration:none}.category a:hover,.category a:focus{color:#000}.pagination{font-size:1.1em;display:flex;align-items:center;padding-top:8px}.pagination-bottom{border-top:1px dotted #ddd;margin-bottom:15px;margin-top:50px}.pagination>div{flex:1}.pagination-next{text-align:right}.pagination-prev:before{content:"« "}.pagination-next:after{content:" »"}.pagination a{color:#333}.pagination a:hover,.pagination a:focus{text-decoration:none}.item{border:1px dotted #ddd;margin-bottom:20px;padding:5px;overflow:hidden}.item.current-item{border:3px solid #bce;padding:3px}.item-title a{text-decoration:none;font-weight:600}.item-status-read .item-title a{color:#777}.item-meta{color:#777;font-size:.8em}.item-meta a{color:#777;text-decoration:none}.item-meta a:hover,.item-meta a:focus{color:#333}.item-meta ul{margin-top:5px}.item-meta li{display:inline}.item-meta li:after{content:"|";color:#aaa}.item-meta li:last-child:after{content:""}.hide-read-items .item-status-read{display:none}.entry header{padding-bottom:5px;border-bottom:1px dotted #ddd}.entry header h1{font-size:2em;line-height:1.25em;margin:30px 0}.entry header h1 a{text-decoration:none;color:#333}.entry header h1 a:hover,.entry header h1 a:focus{color:#666}.entry-meta{font-size:.95em;margin:0 0 20px;color:#666}.entry-website img{vertical-align:top}.entry-website a{color:#666;vertical-align:top;text-decoration:none}.entry-website a:hover,.entry-website a:focus{text-decoration:underline}.entry-date{font-size:.65em;font-style:italic;color:#555}.entry-content{padding-top:15px;font-size:1.1em;font-weight:300;color:#444}.entry-content h1,h2,h3,h4,h5,h6{margin-top:15px}.entry-content iframe,.entry-content video,.entry-content img{max-width:100%}.entry-content figure img{border:1px solid #000}.entry-content figcaption{font-size:.75em;text-transform:uppercase;color:#777}.entry-content p{margin-top:15px;margin-bottom:15px;text-align:justify}.entry-content a:visited{color:purple}.entry-content dt{font-weight:500;margin-top:15px;color:#555}.entry-content dd{margin-left:15px;margin-top:5px;padding-left:20px;border-left:3px solid #ddd;color:#777;font-weight:300;line-height:1.4em}.entry-content blockquote{border-left:4px solid #ddd;padding-left:25px;margin-left:20px;margin-top:20px;margin-bottom:20px;color:#888;line-height:1.4em;font-family:Georgia,serif}.entry-content blockquote+p{color:#555;font-style:italic;font-weight:200}.entry-content q{color:purple;font-family:Georgia,serif;font-style:italic}.entry-content q:before{content:"“"}.entry-content q:after{content:"”"}.entry-content pre{padding:5px;background:#f0f0f0;border:1px solid #ddd;overflow:scroll}.entry-content ul,.entry-content ol{margin-left:30px}.entry-content ul{list-style-type:square}.entry-enclosures h3{font-weight:500}.entry-enclosure{border:1px dotted #ddd;padding:5px;margin-top:10px;max-width:100%}.entry-enclosure-download{font-size:.85em}.enclosure-video video,.enclosure-image img{max-width:100%}.confirm{font-weight:500;color:#ed2d04}.confirm a{color:#ed2d04}.loading{font-style:italic}`,
}
var StylesheetsChecksums = map[string]string{
"black": "38e7fee92187a036ce37f3c15fde2deff59a55c5ab693c7b8578af79d6a117d2",
- "common": "0f4de90d16570a37392ff64dd85b336372477afee298c47b6a3d98d3fb4bd4b3",
+ "common": "66deebc05acbfd97a2c0b04ebe0bd0205c1e99c92599df1c311b4085c39171ba",
}
diff --git a/server/static/css/common.css b/server/static/css/common.css
index bfbc43e..0c0fe22 100644
--- a/server/static/css/common.css
+++ b/server/static/css/common.css
@@ -167,13 +167,6 @@ th {
background: #fcfcfc;
}
-.table-overflow td {
- max-width: 0;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
-}
-
tr:hover {
background-color: #f9f9f9;
}
@@ -213,7 +206,7 @@ input[type="password"],
input[type="text"] {
border: 1px solid #ccc;
padding: 3px;
- line-height: 15px;
+ line-height: 20px;
width: 250px;
font-size: 99%;
margin-bottom: 10px;
@@ -652,3 +645,17 @@ a.button {
.enclosure-image img {
max-width: 100%;
}
+
+/* Confirmation */
+.confirm {
+ font-weight: 500;
+ color: #ed2d04;
+}
+
+.confirm a {
+ color: #ed2d04;
+}
+
+.loading {
+ font-style: italic;
+}
diff --git a/server/static/js.go b/server/static/js.go
index df65da9..2a9ed37 100644
--- a/server/static/js.go
+++ b/server/static/js.go
@@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
-// 2017-11-20 18:31:16.972315949 -0800 PST m=+0.011463331
+// 2017-11-21 14:38:46.652422004 -0800 PST m=+0.004243576
package static
@@ -15,7 +15,9 @@ getKey(event){const mapping={'Esc':'Escape','Up':'ArrowUp','Down':'ArrowDown','L
return event.key;}}
class FormHandler{static handleSubmitButtons(){let elements=document.querySelectorAll("form");elements.forEach(function(element){element.onsubmit=function(){let button=document.querySelector("button");if(button){button.innerHTML=button.dataset.labelLoading;button.disabled=true;}};});}}
class MouseHandler{onClick(selector,callback){let elements=document.querySelectorAll(selector);elements.forEach((element)=>{element.onclick=(event)=>{event.preventDefault();callback(event);};});}}
-class App{run(){FormHandler.handleSubmitButtons();let keyboardHandler=new KeyboardHandler();keyboardHandler.on("g u",()=>this.goToPage("unread"));keyboardHandler.on("g h",()=>this.goToPage("history"));keyboardHandler.on("g f",()=>this.goToPage("feeds"));keyboardHandler.on("g c",()=>this.goToPage("categories"));keyboardHandler.on("g s",()=>this.goToPage("settings"));keyboardHandler.on("ArrowLeft",()=>this.goToPrevious());keyboardHandler.on("ArrowRight",()=>this.goToNext());keyboardHandler.on("j",()=>this.goToPrevious());keyboardHandler.on("p",()=>this.goToPrevious());keyboardHandler.on("k",()=>this.goToNext());keyboardHandler.on("n",()=>this.goToNext());keyboardHandler.on("h",()=>this.goToPage("previous"));keyboardHandler.on("l",()=>this.goToPage("next"));keyboardHandler.on("o",()=>this.openSelectedItem());keyboardHandler.on("v",()=>this.openOriginalLink());keyboardHandler.on("m",()=>this.toggleEntryStatus());keyboardHandler.on("A",()=>this.markPageAsRead());keyboardHandler.listen();let mouseHandler=new MouseHandler();mouseHandler.onClick("a[data-on-click=markPageAsRead]",()=>this.markPageAsRead());if(document.documentElement.clientWidth<600){mouseHandler.onClick(".logo",()=>this.toggleMainMenu());mouseHandler.onClick(".header nav li",(event)=>this.clickMenuListItem(event));}}
+class App{run(){FormHandler.handleSubmitButtons();let keyboardHandler=new KeyboardHandler();keyboardHandler.on("g u",()=>this.goToPage("unread"));keyboardHandler.on("g h",()=>this.goToPage("history"));keyboardHandler.on("g f",()=>this.goToPage("feeds"));keyboardHandler.on("g c",()=>this.goToPage("categories"));keyboardHandler.on("g s",()=>this.goToPage("settings"));keyboardHandler.on("ArrowLeft",()=>this.goToPrevious());keyboardHandler.on("ArrowRight",()=>this.goToNext());keyboardHandler.on("j",()=>this.goToPrevious());keyboardHandler.on("p",()=>this.goToPrevious());keyboardHandler.on("k",()=>this.goToNext());keyboardHandler.on("n",()=>this.goToNext());keyboardHandler.on("h",()=>this.goToPage("previous"));keyboardHandler.on("l",()=>this.goToPage("next"));keyboardHandler.on("o",()=>this.openSelectedItem());keyboardHandler.on("v",()=>this.openOriginalLink());keyboardHandler.on("m",()=>this.toggleEntryStatus());keyboardHandler.on("A",()=>this.markPageAsRead());keyboardHandler.listen();let mouseHandler=new MouseHandler();mouseHandler.onClick("a[data-on-click=markPageAsRead]",()=>this.markPageAsRead());mouseHandler.onClick("a[data-confirm]",(event)=>this.confirm(event));if(document.documentElement.clientWidth<600){mouseHandler.onClick(".logo",()=>this.toggleMainMenu());mouseHandler.onClick(".header nav li",(event)=>this.clickMenuListItem(event));}}
+remove(url){let request=new Request(url,{method:"POST",cache:"no-cache",credentials:"include",headers:new Headers({"X-Csrf-Token":this.getCsrfToken()})});fetch(request).then(()=>{window.location.reload();});}
+confirm(event){let questionElement=document.createElement("span");let linkElement=event.target;let containerElement=linkElement.parentNode;linkElement.style.display="none";let yesElement=document.createElement("a");yesElement.href="#";yesElement.appendChild(document.createTextNode(linkElement.dataset.labelYes));yesElement.onclick=(event)=>{event.preventDefault();let loadingElement=document.createElement("span");loadingElement.className="loading";loadingElement.appendChild(document.createTextNode(linkElement.dataset.labelLoading));questionElement.remove();containerElement.appendChild(loadingElement);this.remove(linkElement.dataset.url);};let noElement=document.createElement("a");noElement.href="#";noElement.appendChild(document.createTextNode(linkElement.dataset.labelNo));noElement.onclick=(event)=>{event.preventDefault();linkElement.style.display="inline";questionElement.remove();};questionElement.className="confirm";questionElement.appendChild(document.createTextNode(linkElement.dataset.labelQuestion+" "));questionElement.appendChild(yesElement);questionElement.appendChild(document.createTextNode(", "));questionElement.appendChild(noElement);containerElement.appendChild(questionElement);}
clickMenuListItem(event){let element=event.target;console.log(element);if(element.tagName==="A"){window.location.href=element.getAttribute("href");}else{window.location.href=element.querySelector("a").getAttribute("href");}}
toggleMainMenu(){let menu=document.querySelector(".header nav ul");if(this.isVisible(menu)){menu.style.display="none";}else{menu.style.display="block";}}
updateEntriesStatus(entryIDs,status){let url=document.body.dataset.entriesStatusUrl;let request=new Request(url,{method:"POST",cache:"no-cache",credentials:"include",body:JSON.stringify({entry_ids:entryIDs,status:status}),headers:new Headers({"Content-Type":"application/json","X-Csrf-Token":this.getCsrfToken()})});fetch(request);}
@@ -48,5 +50,5 @@ document.addEventListener("DOMContentLoaded",function(){(new App()).run();});})(
}
var JavascriptChecksums = map[string]string{
- "app": "e250c2af19dea14fd75681a81080cf183919a7a589b0886a093586ee894c8282",
+ "app": "cc5edd35e9e10e45cd84487bd11bed357f4e759917da1c83137f3c37006edd6f",
}
diff --git a/server/static/js/app.js b/server/static/js/app.js
index 46a8f72..e54a238 100644
--- a/server/static/js/app.js
+++ b/server/static/js/app.js
@@ -120,6 +120,7 @@ class App {
let mouseHandler = new MouseHandler();
mouseHandler.onClick("a[data-on-click=markPageAsRead]", () => this.markPageAsRead());
+ mouseHandler.onClick("a[data-confirm]", (event) => this.confirm(event));
if (document.documentElement.clientWidth < 600) {
mouseHandler.onClick(".logo", () => this.toggleMainMenu());
@@ -127,6 +128,61 @@ class App {
}
}
+ remove(url) {
+ let request = new Request(url, {
+ method: "POST",
+ cache: "no-cache",
+ credentials: "include",
+ headers: new Headers({
+ "X-Csrf-Token": this.getCsrfToken()
+ })
+ });
+
+ fetch(request).then(() => {
+ window.location.reload();
+ });
+ }
+
+ confirm(event) {
+ let questionElement = document.createElement("span");
+ let linkElement = event.target;
+ let containerElement = linkElement.parentNode;
+ linkElement.style.display = "none";
+
+ let yesElement = document.createElement("a");
+ yesElement.href = "#";
+ yesElement.appendChild(document.createTextNode(linkElement.dataset.labelYes));
+ yesElement.onclick = (event) => {
+ event.preventDefault();
+
+ let loadingElement = document.createElement("span");
+ loadingElement.className = "loading";
+ loadingElement.appendChild(document.createTextNode(linkElement.dataset.labelLoading));
+
+ questionElement.remove();
+ containerElement.appendChild(loadingElement);
+
+ this.remove(linkElement.dataset.url);
+ };
+
+ let noElement = document.createElement("a");
+ noElement.href = "#";
+ noElement.appendChild(document.createTextNode(linkElement.dataset.labelNo));
+ noElement.onclick = (event) => {
+ event.preventDefault();
+ linkElement.style.display = "inline";
+ questionElement.remove();
+ };
+
+ questionElement.className = "confirm";
+ questionElement.appendChild(document.createTextNode(linkElement.dataset.labelQuestion + " "));
+ questionElement.appendChild(yesElement);
+ questionElement.appendChild(document.createTextNode(", "));
+ questionElement.appendChild(noElement);
+
+ containerElement.appendChild(questionElement);
+ }
+
clickMenuListItem(event) {
let element = event.target;console.log(element);
diff --git a/server/template/common.go b/server/template/common.go
index d2258db..24e2a97 100644
--- a/server/template/common.go
+++ b/server/template/common.go
@@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
-// 2017-11-20 18:31:16.991583598 -0800 PST m=+0.030730980
+// 2017-11-21 14:38:46.654164863 -0800 PST m=+0.005986435
package template
diff --git a/server/template/html/categories.html b/server/template/html/categories.html
index 88b0ebe..c2d7850 100644
--- a/server/template/html/categories.html
+++ b/server/template/html/categories.html
@@ -37,7 +37,13 @@
</li>
{{ if eq .FeedCount 0 }}
<li>
- <a href="{{ route "removeCategory" "categoryID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeCategory" "categoryID" .ID }}">{{ t "Remove" }}</a>
</li>
{{ end }}
</ul>
diff --git a/server/template/html/feeds.html b/server/template/html/feeds.html
index d753754..778f64f 100644
--- a/server/template/html/feeds.html
+++ b/server/template/html/feeds.html
@@ -53,7 +53,13 @@
<a href="{{ route "editFeed" "feedID" .ID }}">{{ t "Edit" }}</a>
</li>
<li>
- <a href="{{ route "removeFeed" "feedID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeFeed" "feedID" .ID }}">{{ t "Remove" }}</a>
</li>
</ul>
</div>
diff --git a/server/template/html/sessions.html b/server/template/html/sessions.html
index 048719e..2e01d17 100644
--- a/server/template/html/sessions.html
+++ b/server/template/html/sessions.html
@@ -16,7 +16,7 @@
</ul>
</section>
-<table class="table-overflow">
+<table>
<tr>
<th>{{ t "Date" }}</th>
<th>{{ t "IP Address" }}</th>
@@ -32,7 +32,13 @@
{{ if eq .Token $.currentSessionToken }}
{{ t "Current session" }}
{{ else }}
- <a href="{{ route "removeSession" "sessionID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeSession" "sessionID" .ID }}">{{ t "Remove" }}</a>
{{ end }}
</td>
</tr>
diff --git a/server/template/html/users.html b/server/template/html/users.html
index 69acd00..be67d4b 100644
--- a/server/template/html/users.html
+++ b/server/template/html/users.html
@@ -40,7 +40,13 @@
</td>
<td>
<a href="{{ route "editUser" "userID" .ID }}">{{ t "Edit" }}</a>,
- <a href="{{ route "removeUser" "userID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeUser" "userID" .ID }}">{{ t "Remove" }}</a>
</td>
</tr>
{{ end }}
diff --git a/server/template/views.go b/server/template/views.go
index f224646..c9d845e 100644
--- a/server/template/views.go
+++ b/server/template/views.go
@@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
-// 2017-11-20 18:31:16.974386894 -0800 PST m=+0.013534276
+// 2017-11-21 14:38:46.652925155 -0800 PST m=+0.004746727
package template
@@ -127,7 +127,13 @@ var templateViewsMap = map[string]string{
</li>
{{ if eq .FeedCount 0 }}
<li>
- <a href="{{ route "removeCategory" "categoryID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeCategory" "categoryID" .ID }}">{{ t "Remove" }}</a>
</li>
{{ end }}
</ul>
@@ -621,7 +627,13 @@ var templateViewsMap = map[string]string{
<a href="{{ route "editFeed" "feedID" .ID }}">{{ t "Edit" }}</a>
</li>
<li>
- <a href="{{ route "removeFeed" "feedID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeFeed" "feedID" .ID }}">{{ t "Remove" }}</a>
</li>
</ul>
</div>
@@ -752,7 +764,7 @@ var templateViewsMap = map[string]string{
</ul>
</section>
-<table class="table-overflow">
+<table>
<tr>
<th>{{ t "Date" }}</th>
<th>{{ t "IP Address" }}</th>
@@ -768,7 +780,13 @@ var templateViewsMap = map[string]string{
{{ if eq .Token $.currentSessionToken }}
{{ t "Current session" }}
{{ else }}
- <a href="{{ route "removeSession" "sessionID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeSession" "sessionID" .ID }}">{{ t "Remove" }}</a>
{{ end }}
</td>
</tr>
@@ -930,7 +948,13 @@ var templateViewsMap = map[string]string{
</td>
<td>
<a href="{{ route "editUser" "userID" .ID }}">{{ t "Edit" }}</a>,
- <a href="{{ route "removeUser" "userID" .ID }}">{{ t "Remove" }}</a>
+ <a href="#"
+ data-confirm="true"
+ data-label-question="{{ t "Are you sure?" }}"
+ data-label-yes="{{ t "yes" }}"
+ data-label-no="{{ t "no" }}"
+ data-label-loading="{{ t "Work in progress..." }}"
+ data-url="{{ route "removeUser" "userID" .ID }}">{{ t "Remove" }}</a>
</td>
</tr>
{{ end }}
@@ -945,7 +969,7 @@ var templateViewsMap = map[string]string{
var templateViewsMapChecksums = map[string]string{
"about": "56f1d45d8b9944306c66be0712320527e739a0ce4fccbd97a4c414c8f9cfab04",
"add_subscription": "098ea9e492e18242bd414b22c4d8638006d113f728e5ae78c9186663f60ae3f1",
- "categories": "721b6bae6aa6461f4e020d667707fabe53c94b399f7d74febef2de5eb9f15071",
+ "categories": "ca1280cd157bb527d4fc907da67b05a8347378f6dce965b9389d4bcdf3600a11",
"category_entries": "0bdcf28ef29b976b78d1add431896a8c56791476abd7a4240998d52c3efe1f35",
"choose_subscription": "d37682743d8bbd84738a964e238103db2651f95fa340c6e285ffe2e12548d673",
"create_category": "2b82af5d2dcd67898dc5daa57a6461e6ff8121a6089b2a2a1be909f35e4a2275",
@@ -955,12 +979,12 @@ var templateViewsMapChecksums = map[string]string{
"edit_user": "f0f79704983de3ca7858bd8cda7a372c3999f5e4e0cf951fba5fa2c1752f9111",
"entry": "32e605edd6d43773ac31329d247ebd81d38d974cd43689d91de79fffec7fe04b",
"feed_entries": "9aff923b6c7452dec1514feada7e0d2bbc1ec21c6f5e9f48b2de41d1b731ffe4",
- "feeds": "ddcf12a47c850e6a1f3b85c9ab6566b4e45adfcd7a3546381a0c3a7a54f2b7d4",
+ "feeds": "94e43404a4044490c065c888a49bebd3ff51b588b9fb47d03c2598003aa40dca",
"history": "439000d0be8fd716f3b89860af4d721e05baef0c2ccd2325ba020c940d6aa847",
"import": "73b5112e20bfd232bf73334544186ea419505936bc237d481517a8622901878f",
"login": "568f2f69f248048f3e55e9bbc719077a74ae23fe18f237aa40e3de37e97b7a41",
- "sessions": "7fcd3bb794d4ad01eb9fa515660f04c8e79e1568970fd541cc7b2de8a76e1542",
+ "sessions": "5ac3793f0ee74d0807bab6a173a1aa6508e98add5c022fa54c8fdf5c6b4a0e75",
"settings": "9c89bfd70ff288b4256e5205be78a7645450b364db1df51d10fee3cb915b2c6b",
"unread": "b6f9be1a72188947c75a6fdcac6ff7878db7745f9efa46318e0433102892a722",
- "users": "5bd535de3e46d9b14667d8159a5ec1478d6e028a77bf306c89d7b55813eeb625",
+ "users": "c6b1fa81cf229dde88e69c353114b542c67794a2cd513eddaf600828ab14aa18",
}