diff options
-rw-r--r-- | backend.php | 17 | ||||
-rw-r--r-- | index.php | 68 | ||||
-rw-r--r-- | js/index.js | 13 | ||||
-rw-r--r-- | js/offline.js | 23 | ||||
-rw-r--r-- | js/read.js | 15 | ||||
-rw-r--r-- | offline.html | 77 | ||||
-rw-r--r-- | read.html | 49 | ||||
-rw-r--r-- | worker.js | 72 |
8 files changed, 310 insertions, 24 deletions
diff --git a/backend.php b/backend.php index d14c92f..5d30f9d 100644 --- a/backend.php +++ b/backend.php @@ -43,6 +43,23 @@ break; + case "getinfo": + $id = (int) $_REQUEST["id"]; + + $db = new SQLite3(CALIBRE_DB, SQLITE3_OPEN_READONLY); + + $result = $db->query("SELECT books.*, s.name AS series_name, + (SELECT id FROM data WHERE book = books.id AND format = 'EPUB' LIMIT 1) AS epub_id FROM books + LEFT JOIN books_series_link AS bsl ON (bsl.book = books.id) + LEFT JOIN series AS s ON (bsl.series = s.id) + WHERE books.id = " . $id); + + if ($line = $result->fetchArray(SQLITE3_ASSOC)) { + print json_encode($line); + } + + break; + case "download": $id = (int) $_REQUEST["id"]; @@ -28,6 +28,7 @@ <link rel="shortcut icon" sizes="192x192" href="img/favicon_hires.png"> <link rel="manifest" href="manifest.json"> <meta name="mobile-web-app-capable" content="yes"> + <script src="js/index.js"></script> </head> <body> @@ -65,6 +66,23 @@ </div> </div> +<script type="text/javascript"> + $(document).ready(function() { + + if ('serviceWorker' in navigator) { + navigator.serviceWorker + .register('worker.js') + .then(function() { + console.log("service worker registered"); + }); + + $(window).on('offline', function() { + window.location.reload(); + }); + } + + }); +</script> <div class="container"> @@ -176,17 +194,51 @@ $data_result = $db->query("SELECT * FROM data WHERE book = " . $line["id"] . " LIMIT 3"); - while ($data_line = $data_result->fetchArray(SQLITE3_ASSOC)) { - if ($data_line["format"] != "ORIGINAL_EPUB") { - $label_class = $data_line["format"] == "EPUB" ? "label-success" : "label-primary"; + /*print "<span class=\"label label-default\"> + <span class=\"glyphicon glyphicon-download-alt\"> + </span>";*/ - $download_link = "backend.php?op=download&id=" . $data_line["id"]; - print "<a target=\"_blank\" href=\"$download_link\"><span class=\"label $label_class\">" . $data_line["format"] . "</span></a> "; - } - } + print "</div>"; + ?> + <div class="dropdown" style="white-space : nowrap"> + <a href="#" data-toggle="dropdown" role="button"> + More... + <span class="caret"></span> + </a> + + <ul class="dropdown-menu" aria-labelledby="dLabel"> + + <!-- <?php if ($line["series_name"]) { + $series_link = "?" . http_build_query(["query" => $line["series_name"]]); + $series_full = $line["series_name"] . " [" . $line["series_index"] . "]"; + + print "<li><a title=\"".htmlspecialchars($series_full)."\" + href=\"$series_link\">$series_full</a></li>"; + } + ?> --> + + <?php if ($line["epub_id"]) { ?> + <li><a href="#" onclick="return offline_cache(this)" + data-book-id="<?php echo $line["id"] ?>" class="offline" title="">Make available offline</a></li> + <li class="divider"></li> + <?php } ?> + + <?php while ($data_line = $data_result->fetchArray(SQLITE3_ASSOC)) { + if ($data_line["format"] != "ORIGINAL_EPUB") { + $label_class = $data_line["format"] == "EPUB" ? "label-success" : "label-primary"; + + $download_link = "backend.php?op=download&id=" . $data_line["id"]; + + print "<li><a target=\"_blank\" href=\"$download_link\">Download: <span class=\"label $label_class\">" . + $data_line["format"] . "</span></a></li>"; + } + } ?> + </ul> + </div> + + <?php - print "</div>"; print "</div>"; print "</div>"; diff --git a/js/index.js b/js/index.js new file mode 100644 index 0000000..e76be90 --- /dev/null +++ b/js/index.js @@ -0,0 +1,13 @@ +function offline_cache(elem) { + try { + var bookId = elem.getAttribute("data-book-id"); + + console.log(bookId); + + + return false; + + } catch (e) { + console.warn(e); + } +} diff --git a/js/offline.js b/js/offline.js new file mode 100644 index 0000000..d9bed0b --- /dev/null +++ b/js/offline.js @@ -0,0 +1,23 @@ +var CACHE_NAME = "epube-test"; + +function populate_list() { + + var books = $("#books_container"); + + window.caches.open(CACHE_NAME).then(function(cache) { + cache.keys().then(function(items) { + + $.each(items, function(i, req) { + + if (req.url.match(/\.epub/)) { + console.log(req.url); + + + } + + }); + + }); + }); + +} @@ -110,13 +110,16 @@ function mark_as_read() { } function save_and_close() { + if (navigator.onLine) { + var curPage = book.pagination.pageFromCfi(book.getCurrentLocationCfi()); - var curPage = book.pagination.pageFromCfi(book.getCurrentLocationCfi()); - - $.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: curPage, - cfi: book.getCurrentLocationCfi() }, function(data) { - window.location = "index.php"; - }); + $.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: curPage, + cfi: book.getCurrentLocationCfi() }, function(data) { + window.location = "index.php"; + }); + } else { + window.location = "index.php"; + } } function invert() { diff --git a/offline.html b/offline.html new file mode 100644 index 0000000..72d678b --- /dev/null +++ b/offline.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<html> +<head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link href="lib/bootstrap/v3/css/bootstrap.min.css" rel="stylesheet" media="screen"> + <link href="lib/bootstrap/v3/css/bootstrap-theme.min.css" rel="stylesheet" media="screen"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <script src="lib/bootstrap/v3/js/jquery.js"></script> + <script src="lib/bootstrap/v3/js/bootstrap.min.js"></script> + <script src="lib/holder.min.js"></script> + <title>The Epube</title> + <link type="text/css" rel="stylesheet" media="screen" href="css/index.css" /> + <link rel="shortcut icon" type="image/png" href="img/favicon.png" /> + <link rel="shortcut icon" sizes="192x192" href="img/favicon_hires.png"> + <link rel="manifest" href="manifest.json"> + <meta name="mobile-web-app-capable" content="yes"> + <script src="js/offline.js"></script> +</head> +<body> + +<div class="navbar navbar-default navbar-static-top"> +<div class="container"> + <div class="navbar-header"> + <span class="navbar-brand"><a href="offline.html">The Epube</a> (offline)</span> + + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-collapse" aria-expanded="false"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + + </div> + + <div class="collapse navbar-collapse" id="nav-collapse"> + + <ul class="nav navbar-nav"> + </ul> + + <form class="navbar-form navbar-right"> + <input type="text" name="query" class="form-control" + value=""> + <button type="submit" class="btn btn-default">Search</button> + </form> + + </div> + +</div> +</div> + +<script type="text/javascript"> + $(document).ready(function() { + + if ('serviceWorker' in navigator) { + navigator.serviceWorker + .register('worker.js') + .then(function() { + console.log("service worker registered"); + }); + + } + + populate_list(); + + }); +</script> + +<div class="container"> + + <div class="row" id="books_container"> + + + </div> + +</div> +</body> +</html> @@ -164,6 +164,15 @@ } $(document).ready(function() { + + if ('serviceWorker' in navigator) { + navigator.serviceWorker + .register('worker.js') + .then(function() { + console.log("service worker registered"); + }); + } + var book_url = "getbook/" + $.urlParam("id") + ".epub"; console.log("init: " + book_url); @@ -199,11 +208,8 @@ $("select.font_family").val(font); $.get("backend.php", { op: "getlastread", id: $.urlParam("id") }, function(data) { - $(".lastread_input").val(data.page); - }); - }) @@ -264,9 +270,21 @@ payload: JSON.stringify(pageList), total: book.pagination.totalPages }); } - $.get("backend.php", { op: "getlastread", id: $.urlParam("id") }, function(data) { - if (data.cfi) book.gotoCfi(data.cfi); - }); + var localCfi = localStorage["cfipoint." + $.urlParam("id")]; + + if (localCfi) { + + window.setTimeout(function() { + book.gotoCfi(localCfi); + }, 250); + + } else { + + $.get("backend.php", { op: "getlastread", id: $.urlParam("id") }, function(data) { + if (data.cfi) book.gotoCfi(data.cfi); + }); + + } $("#total_pages").html(book.pagination.totalPages); $("#cur_page").html(book.pagination.pageFromCfi(book.getCurrentLocationCfi())); @@ -296,11 +314,22 @@ if (_store_position && new Date().getTime()/1000 - _last_position_sync > 60) { console.log("storing lastread"); + + var currentCfi = book.getCurrentLocationCfi(); - $.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: location.anchorPage, - cfi: book.getCurrentLocationCfi() }); - _store_position = 0; - _last_position_sync = new Date().getTime()/1000; + if (navigator.onLine) { + + $.post("backend.php", { op: "storelastread", id: $.urlParam("id"), page: location.anchorPage, + cfi: currentCfi }); + _store_position = 0; + _last_position_sync = new Date().getTime()/1000; + + localStorage.removeItem("cfipoint." + $.urlParam("id")); + } else { + localStorage["cfipoint." + $.urlParam("id")] = currentCfi; + _last_position_sync = 0; + } + } }); diff --git a/worker.js b/worker.js new file mode 100644 index 0000000..2ef4b9c --- /dev/null +++ b/worker.js @@ -0,0 +1,72 @@ +var CACHE_NAME = 'epube-test'; + +self.addEventListener('activate', function(event) { + event.waitUntil( + caches.open(CACHE_NAME).then(function(cache) { + var urls = [ + 'read.html', + 'js/read.js', + 'js/offline.js', + 'css/read.css', + 'offline.html', + 'lib/zip.min.js', + 'lib/epub.js', + 'lib/localforage.min.js', + 'lib/holder.min.js', + 'lib/smartimages.js', + 'lib/bootstrap/v3/css/bootstrap-theme.min.css', + 'lib/bootstrap/v3/css/bootstrap.min.css', + 'lib/bootstrap/v3/js/jquery.js', + 'lib/bootstrap/v3/js/bootstrap.min.js', + 'lib/bootstrap/v3/fonts/glyphicons-halflings-regular.woff2', + ]; + + return cache.addAll(urls.map(url => new Request(url, {credentials: 'same-origin'}))); + }) + ); +}); + +this.addEventListener('fetch', function(event) { + var req = event.request.clone(); + + event.respondWith( + caches.match(req).then(function(resp) { + if (!navigator.onLine) { + + if (resp) return resp; + + console.log(req.url); + + if (req.url.match("read.html")) { + return caches.match("read.html"); + } + + if (req.url.match("index.php")) { + return caches.match("offline.html"); + } + } + + return fetch(req) + .then(function(resp) { + + if (req.url.match(/(getlastread|getpagination|\.epub)/)) { + caches.open(CACHE_NAME).then(function(cache) { + cache.put(event.request, resp.clone()); + }); + } /*else { + caches.match(req.url).then(function(cached) { + if (cached) { + console.log('refreshing ' + req.url); + + caches.open(CACHE_NAME).then(function(cache) { + cache.put(event.request, resp.clone()); + }); + } + }); + } */ + + return resp.clone(); + }); + }) + ); +}); |