basic feed list view

This commit is contained in:
Nazar Kanaev 2020-07-03 23:47:26 +01:00
parent 9cea82005b
commit 9d5d8f4df2
6 changed files with 41 additions and 22 deletions

View File

@ -256,3 +256,14 @@ func FeedHandler(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusMethodNotAllowed) rw.WriteHeader(http.StatusMethodNotAllowed)
} }
} }
func FeedItemsHandler(rw http.ResponseWriter, req *http.Request) {
id, err := strconv.ParseInt(Vars(req)["id"], 10, 64)
if err != nil {
rw.WriteHeader(http.StatusBadRequest)
return
}
rw.WriteHeader(http.StatusOK)
items := db(req).ListFeedItems(id)
writeJSON(rw, items)
}

View File

@ -80,6 +80,7 @@ var routes []Route = []Route{
p("/api/folders/:id", FolderHandler), p("/api/folders/:id", FolderHandler),
p("/api/feeds", FeedListHandler), p("/api/feeds", FeedListHandler),
p("/api/feeds/:id", FeedHandler), p("/api/feeds/:id", FeedHandler),
p("/api/feeds/:id/items", FeedItemsHandler),
p("/api/feeds/find", FeedHandler), p("/api/feeds/find", FeedHandler),
} }

View File

@ -14,17 +14,17 @@ const (
) )
type Item struct { type Item struct {
Id string Id string `json:"id"`
FeedId int64 FeedId int64 `json:"feed_id"`
Title string Title string `json:"title"`
Link string Link string `json:"link"`
Description string Description string `json:"description"`
Content string Content string `json:"content"`
Author string Author string `json:"author"`
Date *time.Time Date *time.Time `json:"date"`
DateUpdated *time.Time DateUpdated *time.Time `json:"date_updated"`
Status ItemStatus Status ItemStatus `json:"status"`
Image string Image string `json:"image"`
} }
func (s *Storage) CreateItems(items []Item) bool { func (s *Storage) CreateItems(items []Item) bool {
@ -70,7 +70,6 @@ func itemQuery(s *Storage, cond string, v ...interface{}) []Item {
content, author, date, date_updated, status, image content, author, date, date_updated, status, image
from items from items
where %s`, cond) where %s`, cond)
s.log.Print(query)
rows, err := s.db.Query(query, v...) rows, err := s.db.Query(query, v...)
if err != nil { if err != nil {
s.log.Print(err) s.log.Print(err)

View File

@ -77,12 +77,12 @@
<input type="radio" name="item" :value="item.id" v-model="itemSelected"> <input type="radio" name="item" :value="item.id" v-model="itemSelected">
<div class="menu-item p-2"> <div class="menu-item p-2">
<div class="d-flex flex-column ml-4"> <div class="d-flex flex-column ml-4">
<div style="line-height: 1" class="d-flex"> <div style="line-height: 1" class="d-flex text-muted">
<img src="./static/images/circle-full.svg" class="nav-icon ml-n4 mr-2" v-if="item.status === 'unread'"> <img src="./static/images/circle-full.svg" class="nav-icon ml-n4 mr-2" v-if="item.status === 'unread'">
<img src="./static/images/circle.svg" class="nav-icon ml-n4 mr-2" v-if="item.status === 'read'"> <img src="./static/images/circle.svg" class="nav-icon ml-n4 mr-2" v-if="item.status === 'read'">
<img src="./static/images/star.svg" class="nav-icon ml-n4 mr-2" v-if="item.status === 'starred'"> <img src="./static/images/star.svg" class="nav-icon ml-n4 mr-2" v-if="item.status === 'starred'">
<small class="flex-fill text-truncate">{{feedsById[item.feed_id].title}}</small> <small class="flex-fill text-truncate mr-1">{{feedsById[item.feed_id].title}}</small>
<small class="">{{formatDate(item.date)}}</small> <small class="flex-shrink-0">{{formatDate(item.date)}}</small>
</div> </div>
<span>{{item.title}}</span> <span>{{item.title}}</span>
</div> </div>
@ -97,7 +97,7 @@
<img src="./static/images/settings.svg" alt="" style="width: 20px; height: 20px;"> <img src="./static/images/settings.svg" alt="" style="width: 20px; height: 20px;">
</button> </button>
</div> </div>
<div v-if="itemSelected" class="mx-3 my-2 overflow-auto"> <div v-if="itemSelected" class="px-3 mt-2 overflow-auto">
<h3>{{itemSelectedDetails.title}}</h3> <h3>{{itemSelectedDetails.title}}</h3>
<div class="text-muted"> <div class="text-muted">
<div>{{ feedsById[itemSelectedDetails.feed_id].title }}</div> <div>{{ feedsById[itemSelectedDetails.feed_id].title }}</div>
@ -105,7 +105,7 @@
</div> </div>
<hr> <hr>
<div> <div>
content goes here <div v-html="itemSelectedDetails.description" v-if="itemSelectedDetails.description"></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -26,7 +26,10 @@
}, },
delete: function(id) { delete: function(id) {
return api('delete', '/api/feeds/' + id) return api('delete', '/api/feeds/' + id)
} },
list_items: function(id) {
return api('get', '/api/feeds/' + id + '/items').then(json)
},
}, },
folders: { folders: {
list: function() { list: function() {
@ -41,6 +44,6 @@
delete: function(id) { delete: function(id) {
return api('delete', '/api/folders/' + id) return api('delete', '/api/folders/' + id)
}, },
} },
} }
})() })()

View File

@ -43,9 +43,15 @@ var vm = new Vue({
watch: { watch: {
'feedSelected': function(newVal, oldVal) { 'feedSelected': function(newVal, oldVal) {
if (newVal === null) return if (newVal === null) return
var vm = this
var parts = newVal.split(':', 2) var parts = newVal.split(':', 2)
var type = parts[0] var type = parts[0]
var guid = parts[1] var guid = parts[1]
if (type === 'feed') {
api.feeds.list_items(guid).then(function(items) {
vm.items = items
})
}
}, },
'itemSelected': function(newVal, oldVal) { 'itemSelected': function(newVal, oldVal) {
this.itemSelectedDetails = this.itemsById[newVal] this.itemSelectedDetails = this.itemsById[newVal]
@ -64,9 +70,8 @@ var vm = new Vue({
toggleFolderExpanded: function(folder) { toggleFolderExpanded: function(folder) {
folder.is_expanded = !folder.is_expanded folder.is_expanded = !folder.is_expanded
}, },
formatDate: function(timestamp_s) { formatDate: function(datestr) {
var d = new Date(timestamp_s * 1000) return new Date(datestr).toLocaleDateString(undefined, {year: "numeric", month: "long", day: "numeric"})
return d.getDate() + '/' + d.getMonth() + '/' + d.getFullYear()
}, },
moveFeed: function(feed, folder) { moveFeed: function(feed, folder) {
var folder_id = folder ? folder.id : null var folder_id = folder ? folder.id : null