mirror of
https://github.com/go-shiori/shiori.git
synced 2024-11-15 05:34:45 +08:00
additions for tag cloud
This commit is contained in:
parent
d167379546
commit
0c39393a92
7 changed files with 431 additions and 328 deletions
664
assets/assets.go
Executable file → Normal file
664
assets/assets.go
Executable file → Normal file
File diff suppressed because one or more lines are too long
15
cmd/serve.go
15
cmd/serve.go
|
@ -62,6 +62,7 @@ var (
|
|||
|
||||
router.POST("/api/login", apiLogin)
|
||||
router.GET("/api/bookmarks", apiGetBookmarks)
|
||||
router.GET("/api/tags", apiGetTags)
|
||||
router.POST("/api/bookmarks", apiInsertBookmarks)
|
||||
router.PUT("/api/bookmarks", apiUpdateBookmarks)
|
||||
router.DELETE("/api/bookmarks", apiDeleteBookmarks)
|
||||
|
@ -210,6 +211,20 @@ func apiGetBookmarks(w http.ResponseWriter, r *http.Request, ps httprouter.Param
|
|||
checkError(err)
|
||||
}
|
||||
|
||||
func apiGetTags(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
// Check token
|
||||
err := checkAPIToken(r)
|
||||
checkError(err)
|
||||
|
||||
// Fetch all tags
|
||||
tags, err := DB.GetTags()
|
||||
checkError(err)
|
||||
|
||||
err = json.NewEncoder(w).Encode(&tags)
|
||||
checkError(err)
|
||||
}
|
||||
|
||||
func apiInsertBookmarks(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
// Check token
|
||||
err := checkAPIToken(r)
|
||||
|
|
|
@ -14,6 +14,9 @@ type Database interface {
|
|||
// GetBookmarks fetch list of bookmarks based on submitted indices.
|
||||
GetBookmarks(withContent bool, indices ...string) ([]model.Bookmark, error)
|
||||
|
||||
//GetTags fetch list of tags and their frequency
|
||||
GetTags() ([]model.Tag, error)
|
||||
|
||||
// DeleteBookmarks removes all record with matching indices from database.
|
||||
DeleteBookmarks(indices ...string) error
|
||||
|
||||
|
|
|
@ -564,3 +564,15 @@ func (db *SQLiteDatabase) DeleteAccounts(usernames ...string) error {
|
|||
_, err := db.Exec(`DELETE FROM account `+whereClause, args...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *SQLiteDatabase) GetTags() ([]model.Tag, error) {
|
||||
tags := []model.Tag{}
|
||||
|
||||
query := `select T.id, T.name, C.count from tag T inner join (select tag_id, count(tag_id) as count from bookmark_tag group by tag_id) C on T.id = C.tag_id`
|
||||
|
||||
err := db.Select(&tags, query)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ type Tag struct {
|
|||
ID int64 `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Deleted bool `json:"-"`
|
||||
Count int64 `db:"count" json:"count"`
|
||||
}
|
||||
|
||||
// Bookmark is record of a specified URL
|
||||
|
|
10
view/css/cloud.css
Normal file
10
view/css/cloud.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
.cloud {
|
||||
margin: auto;
|
||||
width: 75%;
|
||||
padding: 10px;
|
||||
}
|
||||
.cloud li {
|
||||
list-style: none;
|
||||
padding: 5px;
|
||||
display: inline;
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
<link rel="stylesheet" href="/css/stylesheet.css">
|
||||
<link rel="stylesheet" href="/css/fontawesome.css">
|
||||
<link rel="stylesheet" href="/css/source-sans-pro.css">
|
||||
<link rel="stylesheet" href="/css/cloud.css">
|
||||
<script src="/js/vue.js"></script>
|
||||
<script src="/js/axios.js"></script>
|
||||
<script src="/js/js-cookie.js"></script>
|
||||
|
@ -34,6 +35,10 @@
|
|||
<a @click="reloadData">
|
||||
<i class="fas fa-cloud fa-fw"></i>
|
||||
<span>Reload</span>
|
||||
</a>
|
||||
<a @click="showTags">
|
||||
<i class="fas fa-hashtag fa-fw"></i>
|
||||
<span>Tags</span>
|
||||
</a>
|
||||
<a @click="toggleImage">
|
||||
<i class="fas fa-fw" :class="showImage ? 'fa-eye-slash' : 'fa-eye'"></i>
|
||||
|
@ -89,7 +94,8 @@
|
|||
<a v-if="search.keyword !== ''" @click="removeSearchParam(search.keyword)">{{search.keyword}}</a>
|
||||
<a v-for="tag in search.tags" @click="removeSearchParam('#'+tag)">#{{tag}}</a>
|
||||
</div>
|
||||
<div id="grid">
|
||||
<template v-if="!displayTags">
|
||||
<div id="grid">
|
||||
<div v-for="column in gridColumns" class="column">
|
||||
<div v-for="item in column" class="bookmark" :class="{checked: isBookmarkChecked(item.index)}" :ref="'bookmark-'+item.index">
|
||||
<a class="checkbox" @click="toggleBookmarkCheck(item.index)">
|
||||
|
@ -125,6 +131,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="displayTags">
|
||||
<div id="tagcloud">
|
||||
<ul class="cloud">
|
||||
<li v-for="item in this.tagCloud">
|
||||
<a href="javascript: void(0);" @click="selectTag(item.name)" v-bind:style="'font-size:' + item.count +'em;'">#{{item.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<div v-if="loading || error !== ''" id="message-bar">
|
||||
<i v-if="loading" class="fas fa-fw fa-spinner fa-spin"></i>
|
||||
|
@ -161,7 +177,9 @@
|
|||
windowWidth: 0,
|
||||
error: "",
|
||||
loading: false,
|
||||
displayTags: false,
|
||||
bookmarks: [],
|
||||
tags: [],
|
||||
checkedBookmarks: [],
|
||||
showImage: true,
|
||||
search: {
|
||||
|
@ -454,6 +472,38 @@
|
|||
bookmarkItem[0].scrollIntoView();
|
||||
})
|
||||
},
|
||||
showTags: function(){
|
||||
instance.get('/api/tags')
|
||||
.then(function (response){
|
||||
app.displayTags = true
|
||||
app.loading = false;
|
||||
app.tagCloud = response.data;
|
||||
var minFont = 1;
|
||||
var maxFont = 8;
|
||||
var maxCount = 0;
|
||||
//find largest count value
|
||||
for (var i = 0; i < app.tagCloud.length; i++){
|
||||
if (app.tagCloud[i].count > maxCount) {
|
||||
maxCount = app.tagCloud[i].count;
|
||||
}
|
||||
}
|
||||
//update tag count value to be fontsize we want to display
|
||||
for (var i = 0; i < app.tagCloud.length; i++){
|
||||
var size = (Math.log(app.tagCloud[i].count)/Math.log(maxCount)) * (maxFont - minFont) + minFont;
|
||||
app.tagCloud[i].count = size;
|
||||
}
|
||||
|
||||
})
|
||||
.catch(function (error){
|
||||
var errorMsg = error.response ? error.response.data : error.message;
|
||||
app.loading = false;
|
||||
app.error = errorMsg.trim();
|
||||
});
|
||||
},
|
||||
selectTag: function(tag){
|
||||
app.displayTags = false;
|
||||
app.searchTag(tag);
|
||||
},
|
||||
bookmarkTime: function (book) {
|
||||
var time = book.modified,
|
||||
readTime = "",
|
||||
|
@ -558,4 +608,4 @@
|
|||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue