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,
|
||||
showId: Boolean,
|
||||
listMode: Boolean,
|
||||
index: Number,
|
||||
tags: {
|
||||
type: Array,
|
||||
default () {
|
||||
|
@ -62,13 +63,16 @@ export default {
|
|||
this.$emit("tagClicked", name);
|
||||
},
|
||||
editBookmark() {
|
||||
this.$emit("edit", this.id);
|
||||
this.$emit("edit", this.id, this.index);
|
||||
},
|
||||
deleteBookmark() {
|
||||
this.$emit("delete", this.id);
|
||||
this.$emit("delete", {
|
||||
id: this.id,
|
||||
index: this.index
|
||||
});
|
||||
},
|
||||
updateBookmark() {
|
||||
this.$emit("update", this.id);
|
||||
this.$emit("update", this.id, this.index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,12 +16,14 @@ var template = `
|
|||
</a>
|
||||
</div>
|
||||
<div id="bookmarks-grid" ref="bookmarksGrid" :class="{list: displayOptions.listMode}">
|
||||
<bookmark-item v-for="book in bookmarks"
|
||||
v-bind="book"
|
||||
:key="book.id"
|
||||
:showId="displayOptions.showId"
|
||||
:listMode="displayOptions.listMode"
|
||||
@tagClicked="filterTag">
|
||||
<bookmark-item v-for="(book, index) in bookmarks"
|
||||
v-bind="book"
|
||||
:index="index"
|
||||
:key="book.id"
|
||||
:showId="displayOptions.showId"
|
||||
:listMode="displayOptions.listMode"
|
||||
@tagClicked="filterTag"
|
||||
@delete="showDialogDelete">
|
||||
</bookmark-item>
|
||||
<div class="pagination-box" v-if="maxPage > 0">
|
||||
<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() {
|
||||
var stateWatcher = (e) => {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,7 @@ import (
|
|||
"math"
|
||||
"net/http"
|
||||
nurl "net/url"
|
||||
"os"
|
||||
"path"
|
||||
fp "path/filepath"
|
||||
"strconv"
|
||||
|
@ -277,3 +278,28 @@ func (h *handler) apiInsertBookmark(w http.ResponseWriter, r *http.Request, ps h
|
|||
err = json.NewEncoder(w).Encode(&book)
|
||||
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/tags", hdl.apiGetTags)
|
||||
router.POST("/api/bookmarks", hdl.apiInsertBookmark)
|
||||
router.DELETE("/api/bookmarks", hdl.apiDeleteBookmark)
|
||||
// router.PUT("/api/cache", hdl.apiUpdateCache)
|
||||
// router.PUT("/api/bookmarks", hdl.apiUpdateBookmark)
|
||||
// router.PUT("/api/bookmarks/tags", hdl.apiUpdateBookmarkTags)
|
||||
// router.DELETE("/api/bookmarks", hdl.apiDeleteBookmark)
|
||||
|
||||
// Route for panic
|
||||
router.PanicHandler = func(w http.ResponseWriter, r *http.Request, arg interface{}) {
|
||||
|
|
Loading…
Reference in a new issue