multi downloads progress bars

This commit is contained in:
Daniel Bulant 2021-05-25 18:03:43 +02:00
parent ff730c8916
commit e1d90cc5f5
4 changed files with 34 additions and 12 deletions

View file

@ -6,9 +6,12 @@
export var chapter; export var chapter;
export var selected; export var selected;
export var disabledDownload = false; export var disabledDownload = false;
export var progress = 0;
$: if(progress !== 0) console.log("chapter", chapter.data.attributes.chapter, progress * 100);
</script> </script>
<tr on:click={() => dispatch("select")} class:selected={selected}> <tr on:click={() => dispatch("select")} class:selected={selected} style="background-image: linear-gradient(to right, rgba(0, 255, 0, 0.247) {progress * 100}%, transparent {progress * 100}%)">
<td class="no-wrap">{chapter.data.attributes.volume ? "Vol " + chapter.data.attributes.volume : ""}</td> <td class="no-wrap">{chapter.data.attributes.volume ? "Vol " + chapter.data.attributes.volume : ""}</td>
<td class="no-wrap">Chapter {chapter.data.attributes.chapter}</td> <td class="no-wrap">Chapter {chapter.data.attributes.chapter}</td>
<td>{chapter.data.attributes.title}</td> <td>{chapter.data.attributes.title}</td>
@ -19,6 +22,8 @@
<style> <style>
tr { tr {
border: 1px solid black; border: 1px solid black;
position: relative;
transition: background-image 0.3s;
} }
tr.selected { tr.selected {

View file

@ -3,9 +3,8 @@
import Chapter from "../../components/chapter.svelte"; import Chapter from "../../components/chapter.svelte";
import { EpubGenerator } from "../../util/generateEpub"; import { EpubGenerator } from "../../util/generateEpub";
import { CBZGenerator } from "../../util/generateCbz"; import { CBZGenerator } from "../../util/generateCbz";
// import * as streamSaver from "streamsaver";
import request from "../../util/request"; import request from "../../util/request";
import { BaseGenerator } from "../../util/baseGenerator";
export var scoped; export var scoped;
@ -17,7 +16,7 @@
$: relationships = scoped.mangaRelationships; $: relationships = scoped.mangaRelationships;
async function getMangaChapters(id) { async function getMangaChapters(id) {
const data = await request("manga/" + id + "/feed?translatedLanguage[]=en"); const data = await request("manga/" + id + "/feed?limit=500&translatedLanguage[]=en");
data.results.sort((a, b) => a.data.attributes.chapter - b.data.attributes.chapter); data.results.sort((a, b) => a.data.attributes.chapter - b.data.attributes.chapter);
return data; return data;
} }
@ -39,19 +38,37 @@
$: if(totalPages) text = `Saving page ${pagesDone + 1} of ${totalPages}`; $: if(totalPages) text = `Saving page ${pagesDone + 1} of ${totalPages}`;
/** /**
* @type {EpubGenerator[]} * @type {BaseGenerator[]}
*/ */
var queue = []; var queue = [];
/**
* @type {BaseGenerator}
*/
var processing = null; var processing = null;
/**
* @type {Map<string, number>}
*/
var progressMap = new Map();
async function processQueue() { async function processQueue() {
if(processing) return; if(processing) return;
processing = queue.shift(); processing = queue.shift();
if(!processing) return processing = null; if(!processing) return processing = null;
processing.opts.callback = (chapter, link, finished) => { state = "active";
processing.opts.callback = async (chapter, link, finished) => {
console.log(chapter, link, finished); console.log(chapter, link, finished);
var cs = await chapters;
var related = cs.results.filter(t => processing.opts.chapters.find(c => t.data.id === c.id));
var done = processing.opts.chapters.filter(t => t.number < chapter);
var linkCount = related.map(t => t.data.attributes[quality].length).reduce((a, b) => a + b);
progress = (done.reduce((a, b) => (a.links || []).length + (b.links || []).length, 0) + link + 1) / linkCount;
progressMap.set(processing.opts.chapters[chapter].number, link + 1);
progressMap = progressMap;
}; };
await processing.generate(); await processing.generate();
processing = null; processing = null;
progressMap = new Map();
progress = 0;
state = "idle";
processQueue(); processQueue();
} }
@ -184,7 +201,7 @@
<option value="cbz"><b>.cbz</b> Comic Book Zip</option> <option value="cbz"><b>.cbz</b> Comic Book Zip</option>
<option value="epub"><b>.epub</b> Electronic publication</option> <option value="epub"><b>.epub</b> Electronic publication</option>
</select> </select>
<button disabled={!!progress && selected.length} on:click={downloadMulti}>Download</button> <button disabled={!selected.length} on:click={downloadMulti}>Download</button>
</div> </div>
<p> <p>
@ -196,13 +213,13 @@
{#await chapters} {#await chapters}
Loading chapters... Loading chapters...
{:then chapters} {:then chapters}
{#if chapters.results.filter(c => c.data.attributes.translatedLanguage === "en").length === 0} {#if chapters.results.length === 0}
<p>No chapters found.</p> <p>No chapters found.</p>
{/if} {/if}
<table> <table>
<tbody> <tbody>
{#each chapters.results.filter(c => c.data.attributes.translatedLanguage === "en") as chapter} {#each chapters.results as chapter, i}
<Chapter {chapter} disabledDownload={!!progress} selected={selected.includes(chapter)} on:select={() => select(chapter)} on:download={() => downloadSingle(chapter)} /> <Chapter progress={(progressMap.get(chapter.data.attributes.chapter) || 0) / chapter.data.attributes[quality].length} {chapter} disabledDownload={!!progress} selected={selected.includes(chapter)} on:select={() => select(chapter)} on:download={() => downloadSingle(chapter)} />
{/each} {/each}
</tbody> </tbody>
</table> </table>

View file

@ -67,7 +67,7 @@ export class BaseGenerator {
*/ */
callback(chapter = -1, link = -1, finished = false) { callback(chapter = -1, link = -1, finished = false) {
if(this.opts.callback) { if(this.opts.callback) {
this.opts.callback(chapter, link, finished); this.opts.callback(chapter, parseInt(link), finished);
} }
} }
} }

View file

@ -22,7 +22,7 @@ export class CBZGenerator extends BaseGenerator {
this.hashes = this.opts.chapters.map(t => t.links).flat(); this.hashes = this.opts.chapters.map(t => t.links).flat();
const chapterCountLength = this.opts.chapters.reduce((a, b) => Math.max(a.number, b.number)).number.toString().length; const chapterCountLength = this.opts.chapters.reduce((a, b) => Math.max(a.number, b.number), 0).toString().length;
for(const chapterI in this.opts.chapters) { for(const chapterI in this.opts.chapters) {
const chapter = this.opts.chapters[chapterI]; const chapter = this.opts.chapters[chapterI];
const baseUrl = await this.getBaseURL(chapter.id); const baseUrl = await this.getBaseURL(chapter.id);