mirror of
https://github.com/ajurna/cbwebreader.git
synced 2025-12-06 06:17:17 +00:00
New reader based on reveal.js. works well on mobile and desktop and gives a better expierance all around.
This commit is contained in:
@@ -131,13 +131,9 @@ class ComicBook(models.Model):
|
||||
out.prev_index = page - 1
|
||||
out.prev_path = out.cur_path
|
||||
|
||||
if self.is_last_page(page):
|
||||
out.next_path, out.next_index = self.nav_get_next_comic(user)
|
||||
if out.next_index == -1:
|
||||
out.q_next_to_directory = True
|
||||
else:
|
||||
out.next_index = page + 1
|
||||
out.next_path = out.cur_path
|
||||
out.next_path, out.next_index = self.nav_get_next_comic(user)
|
||||
if out.next_index == -1:
|
||||
out.q_next_to_directory = True
|
||||
return out
|
||||
|
||||
def nav_get_prev_comic(self, user):
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
<link href="{% static "css/base.css" %}" rel="stylesheet">
|
||||
<link href="{% static "font-awesome/css/all.css" %}" rel="stylesheet">
|
||||
|
||||
{# <link href="{% static "reveal.js/css/reveal.css" %}" rel="stylesheet">#}
|
||||
{# <link href="{% static "reveal.js/css/theme/white.css" %}" rel="stylesheet">#}
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
@@ -51,9 +54,9 @@
|
||||
|
||||
|
||||
<!-- /.container -->
|
||||
<footer class="footer">
|
||||
<div class="container centered">
|
||||
<center><a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons Licence" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/InteractiveResource" property="dct:title" rel="dct:type">CBReader</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Ajurna</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://github.com/ajurna/cbreader" rel="dct:source">https://github.com/ajurna/cbreader</a>.</center>
|
||||
<footer class="footer mt-auto py-3">
|
||||
<div class="container text-center">
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons Licence" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/InteractiveResource" property="dct:title" rel="dct:type">CBReader</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Ajurna</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://github.com/ajurna/cbreader" rel="dct:source">https://github.com/ajurna/cbreader</a>.
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -63,6 +66,9 @@
|
||||
{% bootstrap_javascript jquery='full' %}
|
||||
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.21/b-1.6.2/b-colvis-1.6.2/r-2.2.4/datatables.min.js"></script>
|
||||
<script type="text/javascript" src="{% static "js/js.cookie.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "reveal.js/js/reveal.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "js/hammer.min.js" %}"></script>
|
||||
|
||||
{% block script %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
||||
@@ -2,47 +2,99 @@
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container comic_box justify-content-center">
|
||||
<div class="row justify-content-center">
|
||||
{% if nav.q_next_to_directory %}
|
||||
<a href="/comic/{{ nav.next_path }}/">
|
||||
{% else %}
|
||||
<a href="/comic/read/{{ nav.next_path }}/{{ nav.next_index }}/">
|
||||
{% endif %}
|
||||
<img src="/comic/read/{{ nav.cur_path }}/{{ nav.cur_index }}/img" class="img-fluid">
|
||||
</a>
|
||||
</div>
|
||||
<div class="row justify-content-center mt-1 mb-1">
|
||||
<div class="btn-group" role="group" aria-label="Navigation">
|
||||
{% if nav.q_prev_to_directory %}
|
||||
{% if nav.prev_path %}
|
||||
<a href="/comic/{{ nav.prev_path }}/" class="btn btn-secondary">Prev</a>
|
||||
{% else %}
|
||||
<a href="/comic/" class="btn btn-secondary">Prev</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<a href="/comic/read/{{ nav.prev_path }}/{{ nav.prev_index }}/" class="btn btn-secondary">Prev</a>
|
||||
{% endif %}
|
||||
<div class="btn-group" role="group">
|
||||
<button id="page_list" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ orig_file_name }}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="page_list">
|
||||
{% for file in book.pages %}
|
||||
<a class="dropdown-item" href="/comic/read/{{ nav.cur_path }}/{{ file.index }}/">{{ file.page_file_name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% if nav.q_next_to_directory %}
|
||||
{% if nav.next_path %}
|
||||
<a href="/comic/{{ nav.next_path }}/" class="btn btn-secondary">Next</a>
|
||||
{% else %}
|
||||
<a href="/comic/" class="btn btn-secondary">Next</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<a href="/comic/read/{{ nav.next_path }}/{{ nav.next_index }}/" class="btn btn-secondary">Next</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="reveal" id="comic_box">
|
||||
<div class="slides">
|
||||
{% for page in pages %}
|
||||
<section><img data-src="{% url "get_image" nav.cur_path page.index %}" class=" w-100" onclick="Reveal.next()"></section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script>
|
||||
Reveal.initialize({
|
||||
controls: false,
|
||||
hash: true,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
margin: 0,
|
||||
minScale: 1,
|
||||
maxScale: 1,
|
||||
disableLayout: true,
|
||||
keyboard: false,
|
||||
touch: false,
|
||||
transition: 'slide',
|
||||
});
|
||||
Reveal.setState({indexh: {{ status.last_read_page }} });
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
// event.previousSlide, event.currentSlide, event.indexh, event.indexv
|
||||
document.getElementsByClassName('present')[0].scrollIntoView({behavior: 'smooth'})
|
||||
$.ajax({url: "/comic/set_page/{{nav.cur_path}}/" + event.indexh + "/"})
|
||||
} );
|
||||
$(document).keydown(function(e) {
|
||||
switch(e.which) {
|
||||
case 37: // left
|
||||
if (Reveal.isFirstSlide()){
|
||||
window.location = "{% url "read_comic" nav.prev_path %}"
|
||||
} else {
|
||||
Reveal.prev();
|
||||
}
|
||||
break;
|
||||
|
||||
case 38: // up
|
||||
window.scrollTo({
|
||||
top: window.scrollY-window.innerHeight*.7,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
break;
|
||||
|
||||
case 39: // right
|
||||
if (Reveal.isLastSlide()){
|
||||
window.location = "{% url "read_comic" nav.next_path %}"
|
||||
} else {
|
||||
Reveal.next()
|
||||
}
|
||||
break;
|
||||
|
||||
case 40: // down
|
||||
window.scrollTo({
|
||||
top: window.scrollY+window.innerHeight*.7,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
break;
|
||||
|
||||
default: return; // exit this handler for other keys
|
||||
}
|
||||
e.preventDefault(); // prevent the default action (scroll / move caret)
|
||||
});
|
||||
|
||||
var hammertime = new Hammer(document.getElementById('comic_box'), {});
|
||||
hammertime.on('swipeleft', function (ev) {
|
||||
if (Reveal.isLastSlide()){
|
||||
window.location = "{% url "read_comic" nav.next_path %}"
|
||||
} else {
|
||||
Reveal.next()
|
||||
}
|
||||
})
|
||||
hammertime.on('swiperight', function (ev) {
|
||||
if (Reveal.isFirstSlide()){
|
||||
window.location = "{% url "read_comic" nav.prev_path %}"
|
||||
} else {
|
||||
Reveal.prev();
|
||||
}
|
||||
})
|
||||
hammertime.on('tap', function (ev) {
|
||||
if (Reveal.isLastSlide()){
|
||||
window.location = "{% url "read_comic" nav.next_path %}"
|
||||
} else {
|
||||
Reveal.next()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.conf.urls import url
|
||||
from django.urls import path
|
||||
|
||||
from . import feeds, views
|
||||
|
||||
@@ -9,7 +10,8 @@ urlpatterns = [
|
||||
url(r"^settings/users/(?P<user_id>[0-9]+)/$", views.user_config_page, name="user_details"),
|
||||
url(r"^settings/users/add/$", views.user_add_page, name="add_users"),
|
||||
url(r"^account/$", views.account_page, name="account"),
|
||||
url(r"^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/$", views.read_comic, name="read_comic"),
|
||||
url(r"^read/(?P<comic_selector>[\w-]+)/$", views.read_comic, name="read_comic"),
|
||||
url(r"^set_page/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/$", views.set_read_page, name="set_read_page"),
|
||||
url(r"^read/(?P<comic_selector>[\w-]+)/(?P<page>[0-9]+)/img$", views.get_image, name="get_image"),
|
||||
url(r"^list_json/$", views.comic_list_json, name="comic_list_json1"),
|
||||
url(r"^list_json/(?P<directory_selector>[\w-]+)/$", views.comic_list_json, name="comic_list_json2"),
|
||||
|
||||
@@ -112,7 +112,7 @@ class DirFile:
|
||||
if created:
|
||||
status.save()
|
||||
self.selector = urlsafe_base64_encode(comic.selector.bytes)
|
||||
self.location = "/comic/read/{0}/{1}/".format(self.selector, status.last_read_page)
|
||||
self.location = "/comic/read/{0}/".format(self.selector)
|
||||
self.label = generate_label(comic, status)
|
||||
self.type = "book"
|
||||
|
||||
|
||||
@@ -140,9 +140,7 @@ def recent_comics_json(request):
|
||||
"name": book.file_name,
|
||||
"date": book.date_added.strftime("%d/%m/%y-%H:%M"),
|
||||
"label": generate_label(book, status),
|
||||
"url": "/comic/read/{0}/{1}/".format(
|
||||
urlsafe_base64_encode(book.selector.bytes), status.last_read_page
|
||||
),
|
||||
"url": "/comic/read/{0}/".format(urlsafe_base64_encode(book.selector.bytes)),
|
||||
}
|
||||
)
|
||||
return HttpResponse(json.dumps(response_data), content_type="application/json")
|
||||
@@ -293,13 +291,31 @@ def settings_page(request):
|
||||
|
||||
|
||||
@login_required
|
||||
def read_comic(request, comic_selector, page):
|
||||
def read_comic(request, comic_selector):
|
||||
selector = uuid.UUID(bytes=urlsafe_base64_decode(comic_selector))
|
||||
book = get_object_or_404(ComicBook, selector=selector)
|
||||
pages = ComicPage.objects.filter(Comic=book)
|
||||
|
||||
status, _ = ComicStatus.objects.get_or_create(comic=book, user=request.user)
|
||||
title = "CBWebReader - " + book.file_name
|
||||
context = {
|
||||
"book": book,
|
||||
"pages": pages,
|
||||
# "orig_file_name": book.page_name(page),
|
||||
"nav": book.nav(0, request.user),
|
||||
"status": status,
|
||||
"breadcrumbs": generate_breadcrumbs_from_path(book.directory, book),
|
||||
"menu": Menu(request.user),
|
||||
"title": title,
|
||||
}
|
||||
return render(request, "comic/read_comic.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
def set_read_page(request, comic_selector, page):
|
||||
page = int(page)
|
||||
selector = uuid.UUID(bytes=urlsafe_base64_decode(comic_selector))
|
||||
book = get_object_or_404(ComicBook, selector=selector)
|
||||
|
||||
breadcrumbs = generate_breadcrumbs_from_path(book.directory, book)
|
||||
|
||||
status, _ = ComicStatus.objects.get_or_create(comic=book, user=request.user)
|
||||
status.unread = False
|
||||
status.last_read_page = page
|
||||
@@ -308,16 +324,7 @@ def read_comic(request, comic_selector, page):
|
||||
else:
|
||||
status.finished = False
|
||||
status.save()
|
||||
title = "CBWebReader - " + book.file_name + " - Page: " + str(page)
|
||||
context = {
|
||||
"book": book,
|
||||
"orig_file_name": book.page_name(page),
|
||||
"nav": book.nav(page, request.user),
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"menu": Menu(request.user),
|
||||
"title": title,
|
||||
}
|
||||
return render(request, "comic/read_comic.html", context)
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
@login_required
|
||||
|
||||
Reference in New Issue
Block a user