mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 14:17:19 +00:00
Merge pull request #77
* added timestamp to comicstatus. * added timestamp to comicstatus.
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
<li><a class="dropdown-item" @click="updateComic('mark_unread')"><font-awesome-icon icon='book' /> Mark Un-read</a></li>
|
||||
<li><a class="dropdown-item" @click="updateComic('mark_read')"><font-awesome-icon icon='book-open' /> Mark read</a></li>
|
||||
<li><a class="dropdown-item" v-if="data.type === 'ComicBook'" @click="$emit('markPreviousRead', data.selector)"><font-awesome-icon icon='book' /><font-awesome-icon icon='turn-up' />Mark previous comics read</a></li>
|
||||
<li><a class="dropdown-item" v-if="data.type === 'Directory'" data-bs-toggle="modal" :data-bs-target="'#'+data.selector"><font-awesome-icon icon='edit' />Edit comic</a></li>
|
||||
<li><a class="dropdown-item" v-if="data.type === 'Directory'" data-bs-toggle="modal" :data-bs-target="'#id'+data.selector"><font-awesome-icon icon='edit' />Edit comic</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" :id="data.selector" tabindex="-1" :aria-labelledby="data.selector+'-label'" aria-hidden="true" >
|
||||
<div class="modal fade" :id="'id'+data.selector" tabindex="-1" :aria-labelledby="data.selector+'-label'" aria-hidden="true" >
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
||||
146
frontend/src/components/HistoryTable.vue
Normal file
146
frontend/src/components/HistoryTable.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center">
|
||||
<form class="form-inline ">
|
||||
<label class="my-1 px-1" for="selectChoices">Show</label>
|
||||
<select class="custom-select my-1 mr-sm-2 " id="selectChoices" v-model="this.page_size" @change="this.setPage(this.page)">
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<label class="my-1 px-1" for="selectChoices">entries</label>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col d-flex justify-content-end">
|
||||
<form class="form-inline">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" v-model="search_text" @keyup="this.debounceInput()">
|
||||
<label for="floatingInput">Search</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<caption>
|
||||
<h2>Reading History</h2>
|
||||
</caption>
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table table-striped table-bordered">
|
||||
<caption>Recent Comics</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Comic</th>
|
||||
<th scope="col">Date Read</th>
|
||||
<th scope="col">status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-for="item in comics" :key="item.id">
|
||||
<tr>
|
||||
<th scope="row"><font-awesome-icon icon='book' class="" /></th>
|
||||
<td><router-link :to="{name: 'read', params: { selector: item.selector }}" class="" >{{ item.file_name }}</router-link></td>
|
||||
<td>{{ timeago(item.last_read_time) }}</td>
|
||||
<td>{{ get_status(item) }}</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
Showing page {{ this.page }} of {{ this.page_count }} pages.
|
||||
</div>
|
||||
<div class="col d-flex justify-content-end">
|
||||
<paginate
|
||||
v-model="this.page"
|
||||
:page-count="this.page_count"
|
||||
:click-handler="this.setPage"
|
||||
:prev-text="'Prev'"
|
||||
:next-text="'Next'"
|
||||
:container-class="'pagination '"
|
||||
>
|
||||
</paginate>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Paginate from "vuejs-paginate-next";
|
||||
import api from "@/api";
|
||||
import * as timeago from "timeago.js";
|
||||
|
||||
export default {
|
||||
name: "HistoryTable",
|
||||
components: {
|
||||
Paginate
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
page_count: 2,
|
||||
search_text: '',
|
||||
comics: [],
|
||||
timeout: null,
|
||||
func_selected: 'choose',
|
||||
feed_id: ''
|
||||
}},
|
||||
methods: {
|
||||
updateComicList () {
|
||||
let comic_list_url = '/api/history/'
|
||||
let params = { params: { page: this.page, page_size: this.page_size } }
|
||||
|
||||
if (this.search_text) {
|
||||
params.params.search_text = this.search_text
|
||||
}
|
||||
|
||||
api.get(comic_list_url, params)
|
||||
.then(response => {
|
||||
this.comics = response.data.results
|
||||
this.page_count = Math.ceil(response.data.count / this.page_size)
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response.data.detail === 'Invalid page.') {
|
||||
this.setPage(1)
|
||||
} else {
|
||||
console.log(error)
|
||||
}
|
||||
})
|
||||
},
|
||||
timeago(input) {
|
||||
return timeago.format(input)
|
||||
},
|
||||
get_status(item) {
|
||||
if (item.unread || item.unread === null) {
|
||||
return "Unread"
|
||||
} else if (item.finished) {
|
||||
return "Finished"
|
||||
} else {
|
||||
return item.last_read_page + ' / ' + item.page_count
|
||||
}
|
||||
},
|
||||
setPage(page) {
|
||||
this.page = page
|
||||
this.updateComicList()
|
||||
},
|
||||
debounceInput() {
|
||||
clearTimeout(this.timeout)
|
||||
this.timeout = setTimeout(() => {
|
||||
this.setPage(this.page)
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.updateComicList()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="reveal" id="comic_box" ref="comic_box" >
|
||||
<div id="slides_div" class="slides" ref="slides">
|
||||
<section class="" v-for="page in pages" :key="page.index" :data-menu-title="page.page_file_name" hidden>
|
||||
<img :data-src="'/api/read/' + selector + '/image/' + page.index + '/'" class="w-100" :alt="page.page_file_name">
|
||||
<section class="" v-for="page in pages" :key="page" :data-menu-title="page" hidden>
|
||||
<img :data-src="'/api/read/' + selector + '/image/' + page + '/'" class="w-100" :alt="page">
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row navButtons pb-2">
|
||||
<comic-paginate
|
||||
v-model="paginate_page"
|
||||
:page_count="pages.length"
|
||||
:page_count="pages"
|
||||
@setPage="this.setPage"
|
||||
@prevComic="prevComic"
|
||||
@nextComic="nextComic"
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
title: '',
|
||||
prev_comic: {},
|
||||
next_comic: {},
|
||||
pages: [],
|
||||
pages: 1,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@@ -130,7 +130,8 @@ export default {
|
||||
plugins: [ ]
|
||||
}).then(() => {
|
||||
this.deck.slide(this.current_page)
|
||||
this.deck.on( 'slidechanged', () => {
|
||||
api.put(set_read_url, {page: this.current_page})
|
||||
this.deck.on( 'slidechanged', (event) => {
|
||||
this.$refs.comic_box.scrollIntoView({behavior: 'smooth'})
|
||||
api.put(set_read_url, {page: event.indexh})
|
||||
});
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
<li class="nav-item">
|
||||
<router-link :to="{name: 'recent'}" class="nav-link" >Recent</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link :to="{name: 'history'}" class="nav-link" >History</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link :to="{name: 'account'}" class="nav-link" >Account</router-link>
|
||||
</li>
|
||||
|
||||
@@ -131,7 +131,7 @@ export default {
|
||||
} else if (item.finished) {
|
||||
return "Finished"
|
||||
} else {
|
||||
return item.last_read_page + 1 + ' / ' + item.total_pages
|
||||
return item.last_read_page + ' / ' + item.page_count
|
||||
}
|
||||
},
|
||||
setPage(page) {
|
||||
|
||||
@@ -6,6 +6,7 @@ const AccountView = () => import('@/views/AccountView')
|
||||
const BrowseView = () => import('@/views/BrowseView')
|
||||
const UserView = () => import('@/views/UserView')
|
||||
const LoginView = () => import('@/views/LoginView')
|
||||
const HistoryView = () => import('@/views/HistoryView')
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@@ -37,6 +38,11 @@ const routes = [
|
||||
name: 'recent',
|
||||
component: RecentView
|
||||
},
|
||||
{
|
||||
path: '/history',
|
||||
name: 'history',
|
||||
component: HistoryView
|
||||
},
|
||||
{
|
||||
path: '/account',
|
||||
name: 'account',
|
||||
|
||||
24
frontend/src/views/HistoryView.vue
Normal file
24
frontend/src/views/HistoryView.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<the-breadcrumbs :manual_crumbs="this.crumbs" />
|
||||
<history-table />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TheBreadcrumbs from "@/components/TheBreadcrumbs";
|
||||
import HistoryTable from "@/components/HistoryTable";
|
||||
export default {
|
||||
name: "HistoryView",
|
||||
components: {HistoryTable, TheBreadcrumbs},
|
||||
data () {
|
||||
return {
|
||||
crumbs: [
|
||||
{id: 0, selector: '', name: 'Home'},
|
||||
{id: 1, selector: '', name: 'History'}
|
||||
]
|
||||
}},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user