Skip to content

Commit

Permalink
Merge pull request #49 from s-frostick/tagcloud
Browse files Browse the repository at this point in the history
Add tag cloud feature
  • Loading branch information
RadhiFadlillah committed Mar 10, 2018
2 parents 76fc01f + 21234f3 commit eee3dc7
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 19 deletions.
6 changes: 3 additions & 3 deletions assets/assets.go
100755 → 100644

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,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)
Expand Down Expand Up @@ -222,6 +223,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)
Expand Down
3 changes: 3 additions & 0 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 16 additions & 0 deletions database/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,3 +565,19 @@ func (db *SQLiteDatabase) DeleteAccounts(usernames ...string) error {
_, err := db.Exec(`DELETE FROM account `+whereClause, args...)
return err
}

// GetTags fetch list of tags and their frequency
func (db *SQLiteDatabase) GetTags() ([]model.Tag, error) {
tags := []model.Tag{}
query := `SELECT bt.tag_id id, t.name, COUNT(bt.tag_id) n_bookmarks
FROM bookmark_tag bt
LEFT JOIN tag t ON bt.tag_id = t.id
GROUP BY bt.tag_id ORDER BY t.name`

err := db.Select(&tags, query)
if err != nil && err != sql.ErrNoRows {
return nil, err
}

return tags, nil
}
7 changes: 4 additions & 3 deletions model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package model

// Tag is tag for the bookmark
type Tag struct {
ID int64 `db:"id" json:"id"`
Name string `db:"name" json:"name"`
Deleted bool `json:"-"`
ID int64 `db:"id" json:"id"`
Name string `db:"name" json:"name"`
NBookmarks int64 `db:"n_bookmarks" json:"nBookmarks"`
Deleted bool `json:"-"`
}

// Bookmark is record of a specified URL
Expand Down
2 changes: 1 addition & 1 deletion view/css/stylesheet.css

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions view/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
<i class="fas fa-cloud fa-fw"></i>
<span>Reload</span>
</a>
<a @click="showTagCloud">
<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>
<span>{{showImage ? 'Hide image' : 'Show image'}}</span>
Expand Down Expand Up @@ -147,6 +151,19 @@
</div>
</div>
</div>
<div v-if="tagCloud.visible" id="tag-cloud-overlay">
<div id="tag-cloud">
<div id="tag-cloud-title">
<p>Tag Cloud</p>
<a @click="tagCloud.visible = false" id="close-tag-cloud">
<i class="fas fa-fw fa-times"></i>
</a>
</div>
<div id="tag-cloud-content">
<a v-for="item in tagCloud.data" @click="selectTagCloud(item.name)" :style="{fontSize: item.fontSize+'em'}">#{{item.name}}</a>
</div>
</div>
</div>
</div>
<script>
var token = Cookies.get('token'),
Expand All @@ -161,7 +178,9 @@
windowWidth: 0,
error: "",
loading: false,
displayTags: false,
bookmarks: [],
tags: [],
checkedBookmarks: [],
showImage: true,
search: {
Expand Down Expand Up @@ -189,6 +208,10 @@
secondChoice: '',
mainAction: function () {},
secondAction: function () {}
},
tagCloud: {
visible: false,
data: []
}
},
methods: {
Expand Down Expand Up @@ -471,6 +494,53 @@
bookmarkItem[0].scrollIntoView();
})
},
showTagCloud: function () {
if (this.loading) return;

// Fetch data
this.error = '';
this.loading = true;
instance.get('/api/tags')
.then(function (response) {
app.loading = false;
app.tagCloud.data = response.data;

if (app.tagCloud.data.length === 0) {
app.tagCloud.visible = false;
app.showDialogError("Error Creating Tag Cloud", "There are no saved tags");
return;
}

app.tagCloud.visible = true;

// Find largest tags frequency
var minFont = 1,
maxFont = 5,
maxCount = 0;
for (var i = 0; i < app.tagCloud.data.length; i++) {
if (app.tagCloud.data[i].nBookmarks > maxCount) {
maxCount = app.tagCloud.data[i].nBookmarks;
}
}

// Set font size for tags
for (var i = 0; i < app.tagCloud.data.length; i++) {
var size = (Math.log(app.tagCloud.data[i].nBookmarks) / Math.log(maxCount)) *
(maxFont - minFont) + minFont;
app.tagCloud.data[i].fontSize = size;
}
})
.catch(function (error) {
var errorMsg = error.response ? error.response.data : error.message;
app.loading = false;
app.tagCloud.visible = false;
app.showDialogError("Error Creating Tag Cloud", errorMsg.trim());
});
},
selectTagCloud: function (tag) {
this.tagCloud.visible = false;
this.searchTag(tag);
},
bookmarkTime: function (book) {
// Define read time
var readTime = "";
Expand Down Expand Up @@ -543,6 +613,9 @@
}
},
computed: {
overlayVisible: function () {
return this.dialog.visible || this.tagCloud.visible;
},
gridColumns: function () {
var nColumn = Math.round(this.windowWidth / 500),
finalContent = [],
Expand Down Expand Up @@ -571,6 +644,10 @@
}
},
watch: {
overlayVisible: function (isVisible) {
if (isVisible) document.body.className = "noscroll";
else document.body.removeAttribute("class");
},
'inputBookmark.url': function (newURL) {
if (newURL === "") this.clearInputBookmark();
else this.$nextTick(function () {
Expand Down
65 changes: 53 additions & 12 deletions view/less/stylesheet.less
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
flex: 1 0;
}

.noscroll {
overflow: hidden;
}

#login-page {
display: flex;
flex-flow: column nowrap;
Expand Down Expand Up @@ -437,18 +441,7 @@
}

#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;
.full-overlay();
#dialog {
display: flex;
background-color: @contentBg;
Expand Down Expand Up @@ -491,6 +484,54 @@
}
}

#tag-cloud-overlay {
.full-overlay();
#tag-cloud {
display: flex;
background-color: @contentBg;
flex-flow: column nowrap;
border: 1px solid @border;
max-height: 100%;
#tag-cloud-title {
display: flex;
flex-flow: row nowrap;
padding: 16px;
border-bottom: 1px solid @border;
align-items: center;
p {
color: @fontColor;
font-weight: 600;
text-transform: uppercase;
font-size: 1em;
flex: 1 0;
}
a {
color: @fontLightColor;
cursor: pointer;
&:hover {
color: @main;
}
}
}
#tag-cloud-content {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
overflow-y: auto;
padding: 12px;
a {
color: @fontLightColor;
cursor: pointer;
margin: 4px;
&:hover {
color: @main;
}
}
}
}
}

.error-message {
color: @main !important;
font-size: 0.9em;
Expand Down
15 changes: 15 additions & 0 deletions view/less/variable.less
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,19 @@
&:hover {
color: @main;
}
}

.full-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;
}

0 comments on commit eee3dc7

Please sign in to comment.