mirror of
https://github.com/hkalexling/Mango.git
synced 2026-04-25 00:00:52 -04:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a6c2799521 | |||
| 2370e4d2c6 | |||
| 32b0384ea0 | |||
| 50d4ffdb7b | |||
| 96463641f9 | |||
| ddbba5d596 | |||
| 2a04f4531e | |||
| a5b6fb781f | |||
| 8dfdab9d73 | |||
| 3a95270dfb | |||
| 2960ca54df | |||
| f5fe3c6b1c |
+1
-1
@@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y wget git make llvm-8 llvm-8-dev g++ lib
|
|||||||
RUN git clone https://github.com/crystal-lang/crystal && cd crystal && git checkout 0.34.0 && make deps && cd ..
|
RUN git clone https://github.com/crystal-lang/crystal && cd crystal && git checkout 0.34.0 && make deps && cd ..
|
||||||
RUN git clone https://github.com/kostya/myhtml && cd myhtml/src/ext && git checkout v1.5.0 && make && cd ..
|
RUN git clone https://github.com/kostya/myhtml && cd myhtml/src/ext && git checkout v1.5.0 && make && cd ..
|
||||||
RUN git clone https://github.com/jessedoyle/duktape.cr && cd duktape.cr/ext && git checkout v0.20.0 && make && cd ..
|
RUN git clone https://github.com/jessedoyle/duktape.cr && cd duktape.cr/ext && git checkout v0.20.0 && make && cd ..
|
||||||
RUN git clone https://github.com/hkalexling/image_size.cr && cd image_size.cr/ext/libwebp && git checkout v0.1.1 && make && cd ../stbi && make
|
RUN git clone https://github.com/hkalexling/image_size.cr && cd image_size.cr && git checkout v0.2.0 && make && cd ..
|
||||||
|
|
||||||
COPY mango-arm32v7.o .
|
COPY mango-arm32v7.o .
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y wget git make llvm-8 llvm-8-dev g++ lib
|
|||||||
RUN git clone https://github.com/crystal-lang/crystal && cd crystal && git checkout 0.34.0 && make deps && cd ..
|
RUN git clone https://github.com/crystal-lang/crystal && cd crystal && git checkout 0.34.0 && make deps && cd ..
|
||||||
RUN git clone https://github.com/kostya/myhtml && cd myhtml/src/ext && git checkout v1.5.0 && make && cd ..
|
RUN git clone https://github.com/kostya/myhtml && cd myhtml/src/ext && git checkout v1.5.0 && make && cd ..
|
||||||
RUN git clone https://github.com/jessedoyle/duktape.cr && cd duktape.cr/ext && git checkout v0.20.0 && make && cd ..
|
RUN git clone https://github.com/jessedoyle/duktape.cr && cd duktape.cr/ext && git checkout v0.20.0 && make && cd ..
|
||||||
RUN git clone https://github.com/hkalexling/image_size.cr && cd image_size.cr/ext/libwebp && git checkout v0.1.1 && make && cd ../stbi && make
|
RUN git clone https://github.com/hkalexling/image_size.cr && cd image_size.cr && git checkout v0.2.0 && make && cd ..
|
||||||
|
|
||||||
COPY mango-arm64v8.o .
|
COPY mango-arm64v8.o .
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ The official docker images are available on [Dockerhub](https://hub.docker.com/r
|
|||||||
### CLI
|
### CLI
|
||||||
|
|
||||||
```
|
```
|
||||||
Mango - Manga Server and Web Reader. Version 0.12.0
|
Mango - Manga Server and Web Reader. Version 0.12.3
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
@@ -142,6 +142,7 @@ Mobile UI:
|
|||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
<a href="https://casinoshunter.com/online-casinos/"><img src="https://i.imgur.com/EJb3wBo.png" width="150" height="auto"></a>
|
<a href="https://casinoshunter.com/online-casinos/"><img src="https://i.imgur.com/EJb3wBo.png" width="150" height="auto"></a>
|
||||||
|
<a href="https://www.browserstack.com/open-source"><img src="https://i.imgur.com/hGJUJXD.png" width="150" height="auto"></a>
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
|
|||||||
+45
-31
@@ -1,15 +1,43 @@
|
|||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
const minify = require("gulp-babel-minify");
|
const babel = require('gulp-babel');
|
||||||
|
const minify = require('gulp-babel-minify');
|
||||||
const minifyCss = require('gulp-minify-css');
|
const minifyCss = require('gulp-minify-css');
|
||||||
const less = require('gulp-less');
|
const less = require('gulp-less');
|
||||||
|
|
||||||
gulp.task('copy-uikit-js', () => {
|
// Copy libraries from node_moduels to public/js
|
||||||
return gulp.src('node_modules/uikit/dist/js/*.min.js')
|
gulp.task('copy-js', () => {
|
||||||
|
return gulp.src([
|
||||||
|
'node_modules/@fortawesome/fontawesome-free/js/fontawesome.min.js',
|
||||||
|
'node_modules/@fortawesome/fontawesome-free/js/solid.min.js',
|
||||||
|
'node_modules/uikit/dist/js/uikit.min.js',
|
||||||
|
'node_modules/uikit/dist/js/uikit-icons.min.js'
|
||||||
|
])
|
||||||
.pipe(gulp.dest('public/js'));
|
.pipe(gulp.dest('public/js'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('minify-js', () => {
|
// Copy UIKit SVG icons to public/img
|
||||||
return gulp.src('public/js/*.js')
|
gulp.task('copy-uikit-icons', () => {
|
||||||
|
return gulp.src('node_modules/uikit/src/images/backgrounds/*.svg')
|
||||||
|
.pipe(gulp.dest('public/img'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compile less
|
||||||
|
gulp.task('less', () => {
|
||||||
|
return gulp.src('public/css/*.less')
|
||||||
|
.pipe(less())
|
||||||
|
.pipe(gulp.dest('public/css'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Transpile and minify JS files and output to dist
|
||||||
|
gulp.task('babel', () => {
|
||||||
|
return gulp.src(['public/js/*.js', '!public/js/*.min.js'])
|
||||||
|
.pipe(babel({
|
||||||
|
presets: [
|
||||||
|
['@babel/preset-env', {
|
||||||
|
targets: '>0.25%, not dead, ios>=9'
|
||||||
|
}]
|
||||||
|
],
|
||||||
|
}))
|
||||||
.pipe(minify({
|
.pipe(minify({
|
||||||
removeConsole: true,
|
removeConsole: true,
|
||||||
builtIns: false
|
builtIns: false
|
||||||
@@ -17,40 +45,26 @@ gulp.task('minify-js', () => {
|
|||||||
.pipe(gulp.dest('dist/js'));
|
.pipe(gulp.dest('dist/js'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('less', () => {
|
// Minify CSS and output to dist
|
||||||
return gulp.src('public/css/*.less')
|
|
||||||
.pipe(less())
|
|
||||||
.pipe(gulp.dest('public/css'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('minify-css', () => {
|
gulp.task('minify-css', () => {
|
||||||
return gulp.src('public/css/*.css')
|
return gulp.src('public/css/*.css')
|
||||||
.pipe(minifyCss())
|
.pipe(minifyCss())
|
||||||
.pipe(gulp.dest('dist/css'));
|
.pipe(gulp.dest('dist/css'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('copy-uikit-icons', () => {
|
// Copy static files (includeing images) to dist
|
||||||
return gulp.src('node_modules/uikit/src/images/backgrounds/*.svg')
|
|
||||||
.pipe(gulp.dest('public/img'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('img', () => {
|
|
||||||
return gulp.src('public/img/*')
|
|
||||||
.pipe(gulp.dest('dist/img'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('copy-files', () => {
|
gulp.task('copy-files', () => {
|
||||||
return gulp.src('public/*.*')
|
return gulp.src(['public/img/*', 'public/*.*', 'public/js/*.min.js'], {
|
||||||
|
base: 'public'
|
||||||
|
})
|
||||||
.pipe(gulp.dest('dist'));
|
.pipe(gulp.dest('dist'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('default', gulp.parallel(
|
// Set up the public folder for development
|
||||||
gulp.series('copy-uikit-js', 'minify-js'),
|
gulp.task('dev', gulp.parallel('copy-js', 'copy-uikit-icons', 'less'));
|
||||||
gulp.series('less', 'minify-css'),
|
|
||||||
gulp.series('copy-uikit-icons', 'img'),
|
|
||||||
'copy-files'
|
|
||||||
));
|
|
||||||
|
|
||||||
gulp.task('dev', gulp.parallel(
|
// Set up the dist folder for deployment
|
||||||
'copy-uikit-js', 'less', 'copy-uikit-icons'
|
gulp.task('deploy', gulp.parallel('babel', 'minify-css', 'copy-files'));
|
||||||
));
|
|
||||||
|
// Default task
|
||||||
|
gulp.task('default', gulp.series('dev', 'deploy'));
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
"author": "Alex Ling <hkalexling@gmail.com>",
|
"author": "Alex Ling <hkalexling@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/preset-env": "^7.11.5",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
|
"gulp-babel": "^8.0.0",
|
||||||
"gulp-babel-minify": "^0.5.1",
|
"gulp-babel-minify": "^0.5.1",
|
||||||
"gulp-less": "^4.0.1",
|
"gulp-less": "^4.0.1",
|
||||||
"gulp-minify-css": "^1.2.4",
|
"gulp-minify-css": "^1.2.4",
|
||||||
@@ -16,6 +18,7 @@
|
|||||||
"uglify": "gulp"
|
"uglify": "gulp"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||||
"uikit": "^3.5.4"
|
"uikit": "^3.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-5
File diff suppressed because one or more lines are too long
+41
-7
@@ -1,3 +1,7 @@
|
|||||||
|
let lastSavedPage = page;
|
||||||
|
let items = [];
|
||||||
|
let longPages = false;
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
getPages();
|
getPages();
|
||||||
|
|
||||||
@@ -28,7 +32,7 @@ const getPages = () => {
|
|||||||
throw new Error(resp.error);
|
throw new Error(resp.error);
|
||||||
const dimensions = data.dimensions;
|
const dimensions = data.dimensions;
|
||||||
|
|
||||||
const items = dimensions.map((d, i) => {
|
items = dimensions.map((d, i) => {
|
||||||
return {
|
return {
|
||||||
id: i + 1,
|
id: i + 1,
|
||||||
url: `${base_url}api/page/${tid}/${eid}/${i+1}`,
|
url: `${base_url}api/page/${tid}/${eid}/${i+1}`,
|
||||||
@@ -37,6 +41,13 @@ const getPages = () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const avgRatio = items.reduce((acc, cur) => {
|
||||||
|
return acc + cur.height / cur.width
|
||||||
|
}, 0) / items.length;
|
||||||
|
|
||||||
|
console.log(avgRatio);
|
||||||
|
longPages = avgRatio > 2;
|
||||||
|
|
||||||
setProp('items', items);
|
setProp('items', items);
|
||||||
setProp('loading', false);
|
setProp('loading', false);
|
||||||
|
|
||||||
@@ -136,26 +147,49 @@ const setupScroller = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let lastSavedPage = page;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the backend reading progress if the current page is more than
|
* Update the backend reading progress if:
|
||||||
* five pages away from the last saved page
|
* 1) the current page is more than five pages away from the last
|
||||||
|
* saved page, or
|
||||||
|
* 2) the average height/width ratio of the pages is over 2, or
|
||||||
|
* 3) the current page is the first page, or
|
||||||
|
* 4) the current page is the last page
|
||||||
*
|
*
|
||||||
* @function saveProgress
|
* @function saveProgress
|
||||||
* @param {number} idx - One-based index of the page
|
* @param {number} idx - One-based index of the page
|
||||||
|
* @param {function} cb - Callback
|
||||||
*/
|
*/
|
||||||
const saveProgress = (idx) => {
|
const saveProgress = (idx, cb) => {
|
||||||
if (Math.abs(idx - lastSavedPage) < 5) return;
|
idx = parseInt(idx);
|
||||||
|
if (Math.abs(idx - lastSavedPage) >= 5 ||
|
||||||
|
longPages ||
|
||||||
|
idx === 1 || idx === items.length
|
||||||
|
) {
|
||||||
lastSavedPage = idx;
|
lastSavedPage = idx;
|
||||||
|
console.log('saving progress', idx);
|
||||||
|
|
||||||
const url = `${base_url}api/progress/${tid}/${idx}?${$.param({entry: eid})}`;
|
const url = `${base_url}api/progress/${tid}/${idx}?${$.param({entry: eid})}`;
|
||||||
$.post(url)
|
$.post(url)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.error) throw new Error(data.error);
|
if (data.error) throw new Error(data.error);
|
||||||
|
if (cb) cb();
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
alert('danger', e);
|
alert('danger', e);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark progress to 100% and redirect to the next entry
|
||||||
|
* Used as the onclick handler for the "Next Entry" button
|
||||||
|
*
|
||||||
|
* @function nextEntry
|
||||||
|
* @param {string} nextUrl - URL of the next entry
|
||||||
|
*/
|
||||||
|
const nextEntry = (nextUrl) => {
|
||||||
|
saveProgress(items.length, () => {
|
||||||
|
redirect(nextUrl);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
-5
File diff suppressed because one or more lines are too long
+1
-1
@@ -55,7 +55,7 @@ function showModal(encodedPath, pages, percentage, encodedeTitle, encodedEntryTi
|
|||||||
|
|
||||||
$('#modal-edit-btn').attr('onclick', `edit("${entryID}")`);
|
$('#modal-edit-btn').attr('onclick', `edit("${entryID}")`);
|
||||||
|
|
||||||
$('#modal-download-btn').attr('href', `/opds/download/${titleID}/${entryID}`);
|
$('#modal-download-btn').attr('href', `${base_url}opds/download/${titleID}/${entryID}`);
|
||||||
|
|
||||||
UIkit.modal($('#modal')).show();
|
UIkit.modal($('#modal')).show();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ shards:
|
|||||||
|
|
||||||
image_size:
|
image_size:
|
||||||
github: hkalexling/image_size.cr
|
github: hkalexling/image_size.cr
|
||||||
version: 0.1.1
|
version: 0.2.0
|
||||||
|
|
||||||
kemal:
|
kemal:
|
||||||
github: kemalcr/kemal
|
github: kemalcr/kemal
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: mango
|
name: mango
|
||||||
version: 0.12.0
|
version: 0.12.3
|
||||||
|
|
||||||
authors:
|
authors:
|
||||||
- Alex Ling <hkalexling@gmail.com>
|
- Alex Ling <hkalexling@gmail.com>
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ require "option_parser"
|
|||||||
require "clim"
|
require "clim"
|
||||||
require "./plugin/*"
|
require "./plugin/*"
|
||||||
|
|
||||||
MANGO_VERSION = "0.12.0"
|
MANGO_VERSION = "0.12.3"
|
||||||
|
|
||||||
# From http://www.network-science.de/ascii/
|
# From http://www.network-science.de/ascii/
|
||||||
BANNER = %{
|
BANNER = %{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class ReaderRouter < Router
|
|||||||
next layout "reader-error" if entry.err_msg
|
next layout "reader-error" if entry.err_msg
|
||||||
|
|
||||||
# load progress
|
# load progress
|
||||||
page = entry.load_progress username
|
page = [1, entry.load_progress username].max
|
||||||
|
|
||||||
# start from page 1 if the user has finished reading the entry
|
# start from page 1 if the user has finished reading the entry
|
||||||
page = 1 if entry.finished? username
|
page = 1 if entry.finished? username
|
||||||
|
|||||||
@@ -7,9 +7,12 @@
|
|||||||
<link rel="stylesheet" href="<%= base_url %>css/uikit.css" />
|
<link rel="stylesheet" href="<%= base_url %>css/uikit.css" />
|
||||||
<link rel="stylesheet" href="<%= base_url %>css/mango.css" />
|
<link rel="stylesheet" href="<%= base_url %>css/mango.css" />
|
||||||
<link rel="icon" href="<%= base_url %>favicon.ico">
|
<link rel="icon" href="<%= base_url %>favicon.ico">
|
||||||
|
|
||||||
|
<script src="https://polyfill.io/v3/polyfill.min.js?features=matchMedia%2Cdefault&flags=gated"></script>
|
||||||
<script defer src="<%= base_url %>js/fontawesome.min.js"></script>
|
<script defer src="<%= base_url %>js/fontawesome.min.js"></script>
|
||||||
<script defer src="<%= base_url %>js/solid.min.js"></script>
|
<script defer src="<%= base_url %>js/solid.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.5.0/dist/alpine.min.js" defer></script>
|
<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.5.0/dist/alpine.min.js"></script>
|
||||||
|
<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.5.0/dist/alpine-ie11.min.js" defer></script>
|
||||||
<script src="<%= base_url %>js/theme.js"></script>
|
<script src="<%= base_url %>js/theme.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<%- if next_entry_url -%>
|
<%- if next_entry_url -%>
|
||||||
<button id="next-btn" class="uk-align-center uk-button uk-button-primary" @click="redirect('<%= next_entry_url %>')">Next Entry</button>
|
<button id="next-btn" class="uk-align-center uk-button uk-button-primary" @click="nextEntry('<%= next_entry_url %>')">Next Entry</button>
|
||||||
<%- else -%>
|
<%- else -%>
|
||||||
<button id="next-btn" class="uk-align-center uk-button uk-button-primary" @click="redirect('<%= exit_url %>')">Exit Reader</button>
|
<button id="next-btn" class="uk-align-center uk-button uk-button-primary" @click="redirect('<%= exit_url %>')">Exit Reader</button>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
|||||||
Reference in New Issue
Block a user