[fix] login PWA styling, [add] login local link, [add] home local link
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
5880d3beb6
commit
aacf5a7195
12
README.md
12
README.md
@ -44,12 +44,22 @@ In additional to the compatible KOSync API's, we add:
|
|||||||
- Book metadata scraping (Thanks [OpenLibrary](https://openlibrary.org/) & [Google Books API](https://developers.google.com/books/docs/v1/getting_started))
|
- Book metadata scraping (Thanks [OpenLibrary](https://openlibrary.org/) & [Google Books API](https://developers.google.com/books/docs/v1/getting_started))
|
||||||
- Limited JavaScript use. Server-Side Rendering is used wherever possible. The main app is fully operational without any JS. JS is only required for:
|
- Limited JavaScript use. Server-Side Rendering is used wherever possible. The main app is fully operational without any JS. JS is only required for:
|
||||||
- EPUB Reader
|
- EPUB Reader
|
||||||
- Offline Mode / Service Worker
|
- Local / Offline Mode
|
||||||
|
- Service Worker
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
|
|
||||||
Docker Image: `docker pull gitea.va.reichard.io/evan/bookmanager:latest`
|
Docker Image: `docker pull gitea.va.reichard.io/evan/bookmanager:latest`
|
||||||
|
|
||||||
|
## Local / Offline Reader
|
||||||
|
|
||||||
|
The Local / Offline reader allows you to use any BookManager server as a standalone offline accessible reading app! Some features:
|
||||||
|
|
||||||
|
- Add local EPUB documents
|
||||||
|
- Read both local and any cached server documents
|
||||||
|
- Maintains progress for all types of documents (server / local)
|
||||||
|
- Uploads any progress or activity for cached server documents once the internet is accessible
|
||||||
|
|
||||||
## KOSync API
|
## KOSync API
|
||||||
|
|
||||||
The KOSync compatible API endpoint is located at: `http(s)://<SERVER>/api/ko`
|
The KOSync compatible API endpoint is located at: `http(s)://<SERVER>/api/ko`
|
||||||
|
@ -93,8 +93,8 @@ func (api *API) registerWebAppRoutes() {
|
|||||||
api.Router.GET("/manifest.json", api.webManifest)
|
api.Router.GET("/manifest.json", api.webManifest)
|
||||||
api.Router.GET("/sw.js", api.serviceWorker)
|
api.Router.GET("/sw.js", api.serviceWorker)
|
||||||
|
|
||||||
// Offline Static Pages (No Template)
|
// Local / Offline Static Pages (No Template)
|
||||||
api.Router.GET("/offline", api.offlineDocuments)
|
api.Router.GET("/local", api.localDocuments)
|
||||||
api.Router.GET("/reader", api.documentReader)
|
api.Router.GET("/reader", api.documentReader)
|
||||||
|
|
||||||
// Template App
|
// Template App
|
||||||
|
@ -76,8 +76,8 @@ func (api *API) serviceWorker(c *gin.Context) {
|
|||||||
c.File("./assets/sw.js")
|
c.File("./assets/sw.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) offlineDocuments(c *gin.Context) {
|
func (api *API) localDocuments(c *gin.Context) {
|
||||||
c.File("./assets/offline/index.html")
|
c.File("./assets/local/index.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) documentReader(c *gin.Context) {
|
func (api *API) documentReader(c *gin.Context) {
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
media="(prefers-color-scheme: dark)"
|
media="(prefers-color-scheme: dark)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<title>Book Manager - Offline</title>
|
<title>Book Manager - Local</title>
|
||||||
|
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<link rel="stylesheet" href="/assets/style.css" />
|
<link rel="stylesheet" href="/assets/style.css" />
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<script src="/assets/lib/idb-keyval.js"></script>
|
<script src="/assets/lib/idb-keyval.js"></script>
|
||||||
<script src="/assets/lib/sw-helper.js"></script>
|
<script src="/assets/lib/sw-helper.js"></script>
|
||||||
<script src="/assets/index.js"></script>
|
<script src="/assets/index.js"></script>
|
||||||
<script src="/assets/offline/index.js"></script>
|
<script src="/assets/local/index.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* ----------------------------- */
|
/* ----------------------------- */
|
||||||
@ -87,7 +87,7 @@
|
|||||||
<body class="bg-gray-100 dark:bg-gray-800">
|
<body class="bg-gray-100 dark:bg-gray-800">
|
||||||
<div class="flex items-center justify-between w-full h-16">
|
<div class="flex items-center justify-between w-full h-16">
|
||||||
<h1 class="text-xl font-bold dark:text-white px-6 lg:ml-48">
|
<h1 class="text-xl font-bold dark:text-white px-6 lg:ml-48">
|
||||||
Offline Documents
|
Local Documents
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -12,8 +12,8 @@ async function handleLoad() {
|
|||||||
handleOnlineChange();
|
handleOnlineChange();
|
||||||
|
|
||||||
// If SW Redirected
|
// If SW Redirected
|
||||||
if (document.location.pathname !== "/offline")
|
if (document.location.pathname !== "/local")
|
||||||
window.history.replaceState(null, null, "/offline");
|
window.history.replaceState(null, null, "/local");
|
||||||
|
|
||||||
// Create Upload Listener
|
// Create Upload Listener
|
||||||
let uploadButton = document.querySelector("button");
|
let uploadButton = document.querySelector("button");
|
@ -49,7 +49,7 @@ async function initReader() {
|
|||||||
**/
|
**/
|
||||||
function populateMetadata(data) {
|
function populateMetadata(data) {
|
||||||
let documentLocation =
|
let documentLocation =
|
||||||
data.type == "LOCAL" ? "/offline" : "/documents/" + data.id;
|
data.type == "LOCAL" ? "/local" : "/documents/" + data.id;
|
||||||
|
|
||||||
let documentCoverLocation =
|
let documentCoverLocation =
|
||||||
data.type == "LOCAL"
|
data.type == "LOCAL"
|
||||||
|
@ -769,6 +769,10 @@ video {
|
|||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-4 {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.mt-6 {
|
.mt-6 {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
10
assets/sw.js
10
assets/sw.js
@ -35,7 +35,7 @@ const CACHE_UPDATE_ASYNC = "CACHE_UPDATE_ASYNC";
|
|||||||
* Return cache if exists & update cache in background.
|
* Return cache if exists & update cache in background.
|
||||||
**/
|
**/
|
||||||
const ROUTES = [
|
const ROUTES = [
|
||||||
{ route: "/offline", type: CACHE_UPDATE_ASYNC },
|
{ route: "/local", type: CACHE_UPDATE_ASYNC },
|
||||||
{ route: "/reader", type: CACHE_UPDATE_ASYNC },
|
{ route: "/reader", type: CACHE_UPDATE_ASYNC },
|
||||||
{ route: "/manifest.json", type: CACHE_UPDATE_ASYNC },
|
{ route: "/manifest.json", type: CACHE_UPDATE_ASYNC },
|
||||||
{ route: /^\/assets\//, type: CACHE_UPDATE_ASYNC },
|
{ route: /^\/assets\//, type: CACHE_UPDATE_ASYNC },
|
||||||
@ -50,7 +50,7 @@ const ROUTES = [
|
|||||||
{
|
{
|
||||||
route: /.*/,
|
route: /.*/,
|
||||||
type: CACHE_NEVER,
|
type: CACHE_NEVER,
|
||||||
fallback: (event) => caches.match("/offline"),
|
fallback: (event) => caches.match("/local"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -58,10 +58,10 @@ const ROUTES = [
|
|||||||
* These are assets that are cached on initial service worker installation.
|
* These are assets that are cached on initial service worker installation.
|
||||||
**/
|
**/
|
||||||
const PRECACHE_ASSETS = [
|
const PRECACHE_ASSETS = [
|
||||||
// Offline & Reqder Assets
|
// Offline & Reader Assets
|
||||||
"/offline",
|
"/local",
|
||||||
"/reader",
|
"/reader",
|
||||||
"/assets/offline/index.js",
|
"/assets/local/index.js",
|
||||||
"/assets/reader/index.js",
|
"/assets/reader/index.js",
|
||||||
"/assets/images/no-cover.jpg",
|
"/assets/images/no-cover.jpg",
|
||||||
"/assets/reader/readerThemes.css",
|
"/assets/reader/readerThemes.css",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
"./templates/**/*.html",
|
"./templates/**/*.html",
|
||||||
"./assets/offline/*.{html,js}",
|
"./assets/local/*.{html,js}",
|
||||||
"./assets/reader/*.{html,js}",
|
"./assets/reader/*.{html,js}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
|
@ -172,6 +172,24 @@
|
|||||||
</span>
|
</span>
|
||||||
<span class="mx-4 text-sm font-normal">Documents</span>
|
<span class="mx-4 text-sm font-normal">Documents</span>
|
||||||
</a>
|
</a>
|
||||||
|
<a
|
||||||
|
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100"
|
||||||
|
href="/local"
|
||||||
|
>
|
||||||
|
<span class="text-left">
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.27103 2.11151C5.46135 2.21816 5.03258 2.41324 4.72718 2.71244C4.42179 3.01165 4.22268 3.43172 4.11382 4.225C4.00176 5.04159 4 6.12387 4 7.67568V16.2442C4.38867 15.9781 4.82674 15.7756 5.29899 15.6517C5.82716 15.513 6.44305 15.5132 7.34563 15.5135L20 15.5135V7.67568C20 6.12387 19.9982 5.04159 19.8862 4.22499C19.7773 3.43172 19.5782 3.01165 19.2728 2.71244C18.9674 2.41324 18.5387 2.21816 17.729 2.11151C16.8955 2.00172 15.7908 2 14.2069 2H9.7931C8.2092 2 7.10452 2.00172 6.27103 2.11151ZM6.75862 6.59459C6.75862 6.1468 7.12914 5.78378 7.58621 5.78378H16.4138C16.8709 5.78378 17.2414 6.1468 17.2414 6.59459C17.2414 7.04239 16.8709 7.40541 16.4138 7.40541H7.58621C7.12914 7.40541 6.75862 7.04239 6.75862 6.59459ZM7.58621 9.56757C7.12914 9.56757 6.75862 9.93058 6.75862 10.3784C6.75862 10.8262 7.12914 11.1892 7.58621 11.1892H13.1034C13.5605 11.1892 13.931 10.8262 13.931 10.3784C13.931 9.93058 13.5605 9.56757 13.1034 9.56757H7.58621Z" />
|
||||||
|
<path d="M7.47341 17.1351H8.68965H13.1034H19.9991C19.9956 18.2657 19.9776 19.1088 19.8862 19.775C19.7773 20.5683 19.5782 20.9884 19.2728 21.2876C18.9674 21.5868 18.5387 21.7818 17.729 21.8885C16.8955 21.9983 15.7908 22 14.2069 22H9.7931C8.2092 22 7.10452 21.9983 6.27103 21.8885C5.46135 21.7818 5.03258 21.5868 4.72718 21.2876C4.42179 20.9884 4.22268 20.5683 4.11382 19.775C4.07259 19.4746 4.0463 19.1382 4.02952 18.7558C4.30088 18.0044 4.93365 17.4264 5.72738 17.218C6.01657 17.1421 6.39395 17.1351 7.47341 17.1351Z" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span class="mx-4 text-sm font-normal">Local</span>
|
||||||
|
</a>
|
||||||
<a
|
<a
|
||||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "activity"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "activity"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||||
href="/activity"
|
href="/activity"
|
||||||
|
@ -31,6 +31,34 @@
|
|||||||
<script src="/assets/lib/idb-keyval.js"></script>
|
<script src="/assets/lib/idb-keyval.js"></script>
|
||||||
<script src="/assets/lib/sw-helper.js"></script>
|
<script src="/assets/lib/sw-helper.js"></script>
|
||||||
<script src="/assets/index.js"></script>
|
<script src="/assets/index.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* ----------------------------- */
|
||||||
|
/* -------- PWA Styling -------- */
|
||||||
|
/* ----------------------------- */
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
overscroll-behavior-y: none;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
height: calc(100% + env(safe-area-inset-bottom));
|
||||||
|
padding: env(safe-area-inset-top) env(safe-area-inset-right) 0
|
||||||
|
env(safe-area-inset-left);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No Scrollbar - IE, Edge, Firefox */
|
||||||
|
* {
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No Scrollbar - WebKit */
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-100 dark:bg-gray-800 dark:text-white">
|
<body class="bg-gray-100 dark:bg-gray-800 dark:text-white">
|
||||||
<div class="flex flex-wrap w-full">
|
<div class="flex flex-wrap w-full">
|
||||||
@ -113,9 +141,8 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{{ if .RegistrationEnabled }}
|
|
||||||
<div class="pt-12 pb-12 text-center">
|
<div class="pt-12 pb-12 text-center">
|
||||||
{{ if .Register }}
|
{{ if .RegistrationEnabled }} {{ if .Register }}
|
||||||
<p>
|
<p>
|
||||||
Trying to login?
|
Trying to login?
|
||||||
<a href="./login" class="font-semibold underline">
|
<a href="./login" class="font-semibold underline">
|
||||||
@ -129,9 +156,13 @@
|
|||||||
Register here.
|
Register here.
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
{{end}}
|
{{end}} {{ end }}
|
||||||
|
<p class="mt-4">
|
||||||
|
<a href="./local" class="font-semibold underline">
|
||||||
|
Offline / Local Mode
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
Loading…
Reference in New Issue
Block a user