Implement delete in web view

This commit is contained in:
Radhi Fadlillah 2018-02-14 11:41:43 +07:00
parent 5a2fed1888
commit be95bdf227
5 changed files with 198 additions and 68 deletions

View file

@ -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

View file

@ -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 = "",

View file

@ -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;
@ -298,4 +252,105 @@
color: white;
}
}
}
#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;
}
}
}
}
}
}

View file

@ -2,7 +2,7 @@
@appBg: #F5F5F5;
@border: #E5E5E5;
@borderDark: #9E9E9E;
@headerBg: #FFF;
@contentBg: #FFF;
@headerInputBg: #FFF;
@fontColor: #000;
@linkColor: #535A60;