mirror of
https://github.com/go-shiori/shiori.git
synced 2024-09-20 23:16:12 +08:00
Implement delete in web interface
This commit is contained in:
parent
093b398b2f
commit
7ab6c533a3
|
@ -36,6 +36,7 @@ export default {
|
||||||
imageURL: String,
|
imageURL: String,
|
||||||
showId: Boolean,
|
showId: Boolean,
|
||||||
listMode: Boolean,
|
listMode: Boolean,
|
||||||
|
index: Number,
|
||||||
tags: {
|
tags: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default () {
|
default () {
|
||||||
|
@ -62,13 +63,16 @@ export default {
|
||||||
this.$emit("tagClicked", name);
|
this.$emit("tagClicked", name);
|
||||||
},
|
},
|
||||||
editBookmark() {
|
editBookmark() {
|
||||||
this.$emit("edit", this.id);
|
this.$emit("edit", this.id, this.index);
|
||||||
},
|
},
|
||||||
deleteBookmark() {
|
deleteBookmark() {
|
||||||
this.$emit("delete", this.id);
|
this.$emit("delete", {
|
||||||
|
id: this.id,
|
||||||
|
index: this.index
|
||||||
|
});
|
||||||
},
|
},
|
||||||
updateBookmark() {
|
updateBookmark() {
|
||||||
this.$emit("update", this.id);
|
this.$emit("update", this.id, this.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,12 +16,14 @@ var template = `
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="bookmarks-grid" ref="bookmarksGrid" :class="{list: displayOptions.listMode}">
|
<div id="bookmarks-grid" ref="bookmarksGrid" :class="{list: displayOptions.listMode}">
|
||||||
<bookmark-item v-for="book in bookmarks"
|
<bookmark-item v-for="(book, index) in bookmarks"
|
||||||
v-bind="book"
|
v-bind="book"
|
||||||
:key="book.id"
|
:index="index"
|
||||||
:showId="displayOptions.showId"
|
:key="book.id"
|
||||||
:listMode="displayOptions.listMode"
|
:showId="displayOptions.showId"
|
||||||
@tagClicked="filterTag">
|
:listMode="displayOptions.listMode"
|
||||||
|
@tagClicked="filterTag"
|
||||||
|
@delete="showDialogDelete">
|
||||||
</bookmark-item>
|
</bookmark-item>
|
||||||
<div class="pagination-box" v-if="maxPage > 0">
|
<div class="pagination-box" v-if="maxPage > 0">
|
||||||
<p>Page</p>
|
<p>Page</p>
|
||||||
|
@ -284,6 +286,70 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
showDialogDelete(items) {
|
||||||
|
// Check and filter items
|
||||||
|
if (typeof items !== "object") return;
|
||||||
|
if (!Array.isArray(items)) items = [items];
|
||||||
|
|
||||||
|
items = items.filter(item => {
|
||||||
|
var id = (typeof item.id === "number") ? item.id : 0,
|
||||||
|
index = (typeof item.index === "number") ? item.index : -1;
|
||||||
|
|
||||||
|
return id > 0 && index > -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (items.length === 0) return;
|
||||||
|
|
||||||
|
// Split ids and indices
|
||||||
|
var ids = items.map(item => item.id),
|
||||||
|
indices = items.map(item => item.index).sort((a, b) => b - a);
|
||||||
|
|
||||||
|
// Create title and content
|
||||||
|
var title = "Delete Bookmarks",
|
||||||
|
content = "Delete the selected bookmarks ? This action is irreversible.";
|
||||||
|
|
||||||
|
if (items.length === 1) {
|
||||||
|
title = "Delete Bookmark";
|
||||||
|
content = "Are you sure ? This action is irreversible.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show dialog
|
||||||
|
this.showDialog({
|
||||||
|
title: title,
|
||||||
|
content: content,
|
||||||
|
mainText: 'Yes',
|
||||||
|
secondText: 'No',
|
||||||
|
mainClick: () => {
|
||||||
|
this.dialog.loading = true;
|
||||||
|
fetch("/api/bookmarks", {
|
||||||
|
method: "delete",
|
||||||
|
body: JSON.stringify(ids),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) throw response;
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.dialog.loading = false;
|
||||||
|
this.dialog.visible = false;
|
||||||
|
indices.forEach(index => this.bookmarks.splice(index, 1))
|
||||||
|
|
||||||
|
if (this.bookmarks.length < 20) {
|
||||||
|
this.loadData(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.dialog.loading = false;
|
||||||
|
err.text().then(msg => {
|
||||||
|
this.showErrorDialog(`${msg} (${err.status})`);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
var stateWatcher = (e) => {
|
var stateWatcher = (e) => {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
nurl "net/url"
|
nurl "net/url"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
fp "path/filepath"
|
fp "path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -277,3 +278,28 @@ func (h *handler) apiInsertBookmark(w http.ResponseWriter, r *http.Request, ps h
|
||||||
err = json.NewEncoder(w).Encode(&book)
|
err = json.NewEncoder(w).Encode(&book)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apiDeleteBookmarks is handler for DELETE /api/bookmark
|
||||||
|
func (h *handler) apiDeleteBookmark(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
|
// Make sure session still valid
|
||||||
|
err := h.validateSession(r)
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
// Decode request
|
||||||
|
ids := []int{}
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&ids)
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
// Delete bookmarks
|
||||||
|
err = h.DB.DeleteBookmarks(ids...)
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
// Delete thumbnail image from local disk
|
||||||
|
for _, id := range ids {
|
||||||
|
strID := strconv.Itoa(id)
|
||||||
|
imgPath := fp.Join(h.DataDir, "thumb", strID)
|
||||||
|
os.Remove(imgPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, 1)
|
||||||
|
}
|
||||||
|
|
|
@ -40,10 +40,10 @@ func ServeApp(DB database.DB, dataDir string, port int) error {
|
||||||
router.GET("/api/bookmarks", hdl.apiGetBookmarks)
|
router.GET("/api/bookmarks", hdl.apiGetBookmarks)
|
||||||
router.GET("/api/tags", hdl.apiGetTags)
|
router.GET("/api/tags", hdl.apiGetTags)
|
||||||
router.POST("/api/bookmarks", hdl.apiInsertBookmark)
|
router.POST("/api/bookmarks", hdl.apiInsertBookmark)
|
||||||
|
router.DELETE("/api/bookmarks", hdl.apiDeleteBookmark)
|
||||||
// router.PUT("/api/cache", hdl.apiUpdateCache)
|
// router.PUT("/api/cache", hdl.apiUpdateCache)
|
||||||
// router.PUT("/api/bookmarks", hdl.apiUpdateBookmark)
|
// router.PUT("/api/bookmarks", hdl.apiUpdateBookmark)
|
||||||
// router.PUT("/api/bookmarks/tags", hdl.apiUpdateBookmarkTags)
|
// router.PUT("/api/bookmarks/tags", hdl.apiUpdateBookmarkTags)
|
||||||
// router.DELETE("/api/bookmarks", hdl.apiDeleteBookmark)
|
|
||||||
|
|
||||||
// Route for panic
|
// Route for panic
|
||||||
router.PanicHandler = func(w http.ResponseWriter, r *http.Request, arg interface{}) {
|
router.PanicHandler = func(w http.ResponseWriter, r *http.Request, arg interface{}) {
|
||||||
|
|
Loading…
Reference in a new issue