mirror of
https://github.com/go-shiori/shiori.git
synced 2025-12-10 22:17:50 +08:00
Implement delete in web view
This commit is contained in:
parent
5a2fed1888
commit
be95bdf227
5 changed files with 198 additions and 68 deletions
12
cmd/serve.go
12
cmd/serve.go
|
|
@ -29,6 +29,7 @@ var (
|
|||
router.GET("/api/bookmarks", apiGetBookmarks)
|
||||
router.POST("/api/bookmarks", apiInsertBookmarks)
|
||||
router.PUT("/api/bookmarks", apiUpdateBookmarks)
|
||||
router.DELETE("/api/bookmarks/:id", apiDeleteBookmarks)
|
||||
|
||||
// Route for panic
|
||||
router.PanicHandler = func(w http.ResponseWriter, r *http.Request, arg interface{}) {
|
||||
|
|
@ -103,3 +104,14 @@ func apiUpdateBookmarks(w http.ResponseWriter, r *http.Request, ps httprouter.Pa
|
|||
err = json.NewEncoder(w).Encode(&bookmarks[0])
|
||||
checkError(err)
|
||||
}
|
||||
|
||||
func apiDeleteBookmarks(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
// Decode request
|
||||
id := ps.ByName("id")
|
||||
|
||||
// Delete bookmarks
|
||||
_, _, err := DB.DeleteBookmarks(id)
|
||||
checkError(err)
|
||||
|
||||
fmt.Fprint(w, id)
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -64,7 +64,7 @@
|
|||
<a href="#" @click="editBookmark(item.index)">
|
||||
<i class="fas fa-pencil-alt"></i>
|
||||
</a>
|
||||
<a href="#">
|
||||
<a href="#" @click="deleteBookmark(item.index)">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</a>
|
||||
<a href="#">
|
||||
|
|
@ -79,6 +79,22 @@
|
|||
<a href="#">Load more bookmarks</a>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="dialog.visible" id="dialog-overlay">
|
||||
<div id="dialog">
|
||||
<p id="dialog-title">{{dialog.title}}</p>
|
||||
<p v-html="dialog.content" id="dialog-content"></p>
|
||||
<div id="dialog-button">
|
||||
<div class="spacer"></div>
|
||||
<a v-if="dialog.loading">
|
||||
<i class="fas fa-fw fa-spinner fa-spin"></i>
|
||||
</a>
|
||||
<template v-else>
|
||||
<a class="button" @click="dialog.secondAction">{{dialog.secondChoice}}</a>
|
||||
<a class="button" @click="dialog.mainAction">{{dialog.mainChoice}}</a>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var instance = axios.create();
|
||||
|
|
@ -98,6 +114,16 @@
|
|||
tags: "",
|
||||
excerpt: "",
|
||||
loading: false
|
||||
},
|
||||
dialog: {
|
||||
visible: false,
|
||||
loading: false,
|
||||
title: '',
|
||||
content: '',
|
||||
mainChoice: '',
|
||||
secondChoice: '',
|
||||
mainAction: function () {},
|
||||
secondAction: function () {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -153,22 +179,6 @@
|
|||
console.log(error);
|
||||
});
|
||||
},
|
||||
clearInputBookmark: function () {
|
||||
var idx = this.inputBookmark.index;
|
||||
|
||||
this.inputBookmark.index = -1;
|
||||
this.inputBookmark.id = -1;
|
||||
this.inputBookmark.url = "";
|
||||
this.inputBookmark.title = "";
|
||||
this.inputBookmark.tags = "";
|
||||
this.inputBookmark.excerpt = "";
|
||||
this.inputBookmark.loading = false;
|
||||
|
||||
if (idx !== -1) app.$nextTick(function () {
|
||||
var bookmarkItem = app.$refs['bookmark-' + idx];
|
||||
bookmarkItem[0].scrollIntoView();
|
||||
})
|
||||
},
|
||||
editBookmark: function (idx) {
|
||||
var bookmark = this.bookmarks[idx],
|
||||
tags = [];
|
||||
|
|
@ -188,6 +198,59 @@
|
|||
app.$refs.inputURL.focus();
|
||||
});
|
||||
},
|
||||
deleteBookmark: function (idx) {
|
||||
var bookmark = this.bookmarks[idx];
|
||||
|
||||
this.dialog.visible = true;
|
||||
this.dialog.loading = false;
|
||||
this.dialog.title = "Delete Bookmark";
|
||||
this.dialog.content = "Delete <b>\"" + bookmark.title.trim() + "\"</b> from bookmarks ? This action is irreversible.";
|
||||
this.dialog.mainChoice = "Yes";
|
||||
this.dialog.secondChoice = "No";
|
||||
this.dialog.mainAction = function () {
|
||||
app.dialog.loading = true;
|
||||
|
||||
instance.delete('/api/bookmarks/' + bookmark.id)
|
||||
.then(function (response) {
|
||||
app.dialog.loading = false;
|
||||
app.dialog.visible = false;
|
||||
app.bookmarks.splice(idx, 1);
|
||||
|
||||
var scrollIdx = idx === 1 ? 1 : idx - 1;
|
||||
app.$nextTick(function () {
|
||||
app.$refs['bookmark-' + scrollIdx][0].scrollIntoView();
|
||||
});
|
||||
})
|
||||
.catch(function (error) {
|
||||
app.dialog.loading = false;
|
||||
app.dialog.visible = false;
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
this.dialog.secondAction = function () {
|
||||
app.dialog.visible = false;
|
||||
app.$nextTick(function () {
|
||||
app.$refs['bookmark-' + idx][0].scrollIntoView();
|
||||
});
|
||||
};
|
||||
|
||||
},
|
||||
clearInputBookmark: function () {
|
||||
var idx = this.inputBookmark.index;
|
||||
|
||||
this.inputBookmark.index = -1;
|
||||
this.inputBookmark.id = -1;
|
||||
this.inputBookmark.url = "";
|
||||
this.inputBookmark.title = "";
|
||||
this.inputBookmark.tags = "";
|
||||
this.inputBookmark.excerpt = "";
|
||||
this.inputBookmark.loading = false;
|
||||
|
||||
if (idx !== -1) app.$nextTick(function () {
|
||||
var bookmarkItem = app.$refs['bookmark-' + idx];
|
||||
bookmarkItem[0].scrollIntoView();
|
||||
})
|
||||
},
|
||||
bookmarkTime: function (book) {
|
||||
var time = book.modified,
|
||||
readTime = "",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
height: auto;
|
||||
min-height: 100vh;
|
||||
#header {
|
||||
background-color: @headerBg;
|
||||
background-color: @contentBg;
|
||||
box-shadow: 0 0 3px @headerShadow;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
|
|
@ -80,52 +80,6 @@
|
|||
margin-top: @headerHeight;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
#input-bookmark {
|
||||
align-self: center;
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin: 32px 8px 20px;
|
||||
background-color: @headerInputBg;
|
||||
outline: 1px solid @border;
|
||||
>p {
|
||||
color: @fontColor;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
padding: 16px;
|
||||
}
|
||||
input[type=text],
|
||||
textarea {
|
||||
outline: 1px solid @border;
|
||||
color: @fontColor;
|
||||
font-size: 0.9em;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
textarea {
|
||||
resize: vertical;
|
||||
min-height: 4em;
|
||||
max-height: 10em;
|
||||
}
|
||||
.button-area {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
padding: 8px;
|
||||
a {
|
||||
color: @linkColor;
|
||||
text-transform: uppercase;
|
||||
padding: 8px;
|
||||
background-color: @headerInputBg;
|
||||
&.button {
|
||||
font-size: 0.9em;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: @accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#grid {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
|
|
@ -159,7 +113,7 @@
|
|||
}
|
||||
|
||||
.bookmark {
|
||||
background-color: @headerBg;
|
||||
background-color: @contentBg;
|
||||
border: 1px solid @border;
|
||||
position: relative;
|
||||
.checkbox {
|
||||
|
|
@ -169,7 +123,7 @@
|
|||
position: absolute;
|
||||
outline: 1px solid @border;
|
||||
color: @linkColor;
|
||||
background-color: @headerBg;
|
||||
background-color: @contentBg;
|
||||
width: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
|
|
@ -299,3 +253,104 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#input-bookmark {
|
||||
align-self: center;
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin: 32px 8px 20px;
|
||||
background-color: @headerInputBg;
|
||||
outline: 1px solid @border;
|
||||
>p {
|
||||
color: @fontColor;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
padding: 16px;
|
||||
}
|
||||
input[type=text],
|
||||
textarea {
|
||||
outline: 1px solid @border;
|
||||
color: @fontColor;
|
||||
font-size: 0.9em;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
textarea {
|
||||
resize: vertical;
|
||||
min-height: 4em;
|
||||
max-height: 10em;
|
||||
}
|
||||
.button-area {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
padding: 8px;
|
||||
a {
|
||||
color: @linkColor;
|
||||
text-transform: uppercase;
|
||||
padding: 8px;
|
||||
background-color: @headerInputBg;
|
||||
font-size: 0.9em;
|
||||
&.button {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: @accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#dialog-overlay {
|
||||
position: fixed;
|
||||
z-index: 101;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
padding: 32px;
|
||||
#dialog {
|
||||
display: flex;
|
||||
background-color: @contentBg;
|
||||
align-self: center;
|
||||
flex-flow: column;
|
||||
border: 1px solid @border;
|
||||
max-width: 500px;
|
||||
#dialog-title {
|
||||
color: @fontColor;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid @border;
|
||||
}
|
||||
#dialog-content {
|
||||
padding: 16px;
|
||||
}
|
||||
#dialog-button {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
padding: 8px;
|
||||
border-top: 1px solid @border;
|
||||
a {
|
||||
color: @linkColor;
|
||||
text-transform: uppercase;
|
||||
padding: 8px;
|
||||
background-color: @headerInputBg;
|
||||
&.button {
|
||||
cursor: pointer;
|
||||
&:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
&:hover {
|
||||
color: @accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
@appBg: #F5F5F5;
|
||||
@border: #E5E5E5;
|
||||
@borderDark: #9E9E9E;
|
||||
@headerBg: #FFF;
|
||||
@contentBg: #FFF;
|
||||
@headerInputBg: #FFF;
|
||||
@fontColor: #000;
|
||||
@linkColor: #535A60;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue