From 5d6f3d98d27bfd13d3a177ff15d5fcee21f920a1 Mon Sep 17 00:00:00 2001 From: str Date: Sat, 29 Dec 2018 13:32:37 +0100 Subject: [PATCH] refactor: Extract PagerRenderer from renderer. --- src/electronApp/State.ts | 7 ++ src/electronApp/renderer.ts | 70 +---------------- src/electronApp/rendering/HtmlGrid.ts | 4 - src/electronApp/rendering/PagerRenderer.ts | 87 ++++++++++++++++++++++ 4 files changed, 98 insertions(+), 70 deletions(-) create mode 100644 src/electronApp/State.ts create mode 100644 src/electronApp/rendering/PagerRenderer.ts diff --git a/src/electronApp/State.ts b/src/electronApp/State.ts new file mode 100644 index 0000000..f76d7a6 --- /dev/null +++ b/src/electronApp/State.ts @@ -0,0 +1,7 @@ +export type State = { + currentPage: number; + imageInputDir: string; + // Each 'browse to directory' or 'select page' is a new epoch, + // so can igore stale async responses. Alt could be to cancel promises but seems complicated. + epoch: number; +}; diff --git a/src/electronApp/renderer.ts b/src/electronApp/renderer.ts index 8dbe222..3f43b66 100644 --- a/src/electronApp/renderer.ts +++ b/src/electronApp/renderer.ts @@ -1,9 +1,7 @@ import * as jquery from "jquery"; import { ChocolateBars } from "../bars/ChocolateBars"; -import { ImageFinder } from "../bars/files/ImageFinder"; import { ImageDetail } from "../bars/model/ImageDetail"; -import { PagingModel } from "../bars/model/PagingModel"; import { JQueryUtils } from "../utils/JQueryUtils"; import { ConsoleOutputter } from "../utils/outputter/ConsoleOutputter"; import { Verbosity } from "../utils/outputter/Verbosity"; @@ -12,7 +10,9 @@ import { DetailPaneRenderer } from "./rendering/DetailPaneRenderer"; import { ExpandedImageRenderer } from "./rendering/ExpandedImageRenderer"; import { HtmlGrid } from "./rendering/HtmlGrid"; import { LoaderRenderer } from "./rendering/LoaderRenderer"; +import { PagerRenderer } from "./rendering/PagerRenderer"; import { SelectDirectoryRenderer } from "./rendering/SelectDirectoryRenderer"; +import { State } from "./State"; const remote = require("electron").remote; @@ -26,11 +26,9 @@ const grid = new HtmlGrid(); const HIDE_LOADING_AFTER_N_IMAGES = 9; -const state = { +const state: State = { currentPage: 0, imageInputDir: "", - // Each 'browse to directory' or 'select page' is a new epoch, - // so can igore stale async responses. Alt could be to cancel promises but seems complicated. epoch: 0 }; @@ -70,7 +68,7 @@ async function renderContainerAndDetailWithImages(imageInputDir: string) { } async function renderImagesAndPager() { - renderPagerButtons(); + PagerRenderer.renderPagerButtons(state, outputter, renderImagesAndPager); await renderImages(); } @@ -82,29 +80,6 @@ async function renderImagesAndPagerForDirectory(imageInputDir: string) { renderImagesAndPager(); } -// xxx PagerRenderer -async function renderPagerButtons() { - let pageCount = 0; - let imageCountThisPage = 0; - grid.clearPagerContainer(); - - // Always have a 1st page: - renderPager(pageCount); - pageCount++; - - const allImages = await ImageFinder.findImagesInDirectory(state.imageInputDir, outputter); - allImages.forEach(() => { - imageCountThisPage++; - - if (imageCountThisPage > PagingModel.IMAGES_PER_PAGE) { - renderPager(pageCount); - - pageCount++; - imageCountThisPage = 1; - } - }); -} - // xxx ImagesRenderer async function renderImages() { grid.clearImagesContainer(); @@ -155,43 +130,6 @@ async function renderImages() { LoaderRenderer.hideImagesLoading(); } -// xxx PagerRenderer -function renderPager(pageId: number) { - const isCurrent = pageId === state.currentPage; - const disabled = isCurrent ? " disabled" : ""; - const currentClass = isCurrent ? " image-pager-button-current" : ""; - - const pagerHtml = ``; - jquery(".image-pager").append(pagerHtml); - - addPagerClickListener(pageId); -} - -function addPagerClickListener(pageId: number) { - const pageDiv = document.getElementById(`button-pager-${pageId}}`); - if (!pageDiv) { - outputter.error(`could not find page button div for '${pageId}'`); - return; - } - - pageDiv.addEventListener("click", () => onClickPager(pageId)); -} - -function onClickPager(pageId: number) { - state.epoch++; - - state.currentPage = pageId; - - LoaderRenderer.showImagesLoading(); - - // use setTimeout to ensure loader appears - setTimeout(() => { - // a new pager button may become disabled - so also need to render the pager buttons. - renderImagesAndPager(); - }, 250); -} - function addImageClickListener(image: ImageDetail) { const imageDivId = HtmlGrid.getImageDivId(image); diff --git a/src/electronApp/rendering/HtmlGrid.ts b/src/electronApp/rendering/HtmlGrid.ts index e035a79..3004e26 100644 --- a/src/electronApp/rendering/HtmlGrid.ts +++ b/src/electronApp/rendering/HtmlGrid.ts @@ -32,10 +32,6 @@ export class HtmlGrid { JQueryUtils.clearHtmlDivById(IMAGE_CONTAINER_ID); } - clearPagerContainer() { - JQueryUtils.clearHtmlDivByClass("image-pager"); - } - setTitleForDir(imageInputDir: string) { jquery(".grid-header").html(`Images at '${imageInputDir}'`); } diff --git a/src/electronApp/rendering/PagerRenderer.ts b/src/electronApp/rendering/PagerRenderer.ts new file mode 100644 index 0000000..6c07559 --- /dev/null +++ b/src/electronApp/rendering/PagerRenderer.ts @@ -0,0 +1,87 @@ +import * as jquery from "jquery"; + +import { ImageFinder } from "../../bars/files/ImageFinder"; +import { PagingModel } from "../../bars/model/PagingModel"; +import { JQueryUtils } from "../../utils/JQueryUtils"; +import { IOutputter } from "../../utils/outputter/IOutputter"; +import { State } from "../State"; +import { LoaderRenderer } from "./LoaderRenderer"; + +export namespace PagerRenderer { + export async function renderPagerButtons( + state: State, + outputter: IOutputter, + renderImagesAndPager: () => void + ) { + let pageCount = 0; + let imageCountThisPage = 0; + + clearPagerContainer(); + + // Always have a 1st page: + renderPager(pageCount, state, outputter, renderImagesAndPager); + pageCount++; + + const allImages = await ImageFinder.findImagesInDirectory(state.imageInputDir, outputter); + allImages.forEach(() => { + imageCountThisPage++; + + if (imageCountThisPage > PagingModel.IMAGES_PER_PAGE) { + renderPager(pageCount, state, outputter, renderImagesAndPager); + + pageCount++; + imageCountThisPage = 1; + } + }); + } + + function renderPager( + pageId: number, + state: State, + outputter: IOutputter, + renderImagesAndPager: () => void + ) { + const isCurrent = pageId === state.currentPage; + const disabled = isCurrent ? " disabled" : ""; + const currentClass = isCurrent ? " image-pager-button-current" : ""; + + const pagerHtml = ``; + jquery(".image-pager").append(pagerHtml); + + addPagerClickListener(pageId, state, outputter, renderImagesAndPager); + } + + function clearPagerContainer() { + JQueryUtils.clearHtmlDivByClass("image-pager"); + } + + export function addPagerClickListener( + pageId: number, + state: State, + outputter: IOutputter, + renderImagesAndPager: () => void + ) { + const pageDiv = document.getElementById(`button-pager-${pageId}}`); + if (!pageDiv) { + outputter.error(`could not find page button div for '${pageId}'`); + return; + } + + pageDiv.addEventListener("click", () => onClickPager(pageId, state, renderImagesAndPager)); + } + + function onClickPager(pageId: number, state: State, renderImagesAndPager: () => void) { + state.epoch++; + + state.currentPage = pageId; + + LoaderRenderer.showImagesLoading(); + + // use setTimeout to ensure loader appears + setTimeout(() => { + // a new pager button may become disabled - so also need to render the pager buttons. + renderImagesAndPager(); + }, 250); + } +}