Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/manga scroll width changer #2980

Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

<div infinite-scroll [infiniteScrollDistance]="1" [infiniteScrollThrottle]="50">
<ng-container *ngFor="let item of webtoonImages | async; let index = index;">
<img src="{{item.src}}" style="display: block"
<img src="{{item.src}}" style="display: block; width: {{widthOverride$ | async}}"
[style.filter]="(darkness$ | async) ?? '' | safeStyle"
class="mx-auto {{pageNum === item.page && showDebugOutline() ? 'active': ''}} {{areImagesWiderThanWindow ? 'full-width' : ''}}"
rel="nofollow" alt="image" (load)="onImageLoad($event)" id="page-{{item.page}}" [attr.page]="item.page" ondragstart="return false;" onselectstart="return false;">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import { WebtoonImage } from '../../_models/webtoon-image';
import { ManagaReaderService } from '../../_service/managa-reader.service';
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {TranslocoDirective} from "@ngneat/transloco";
import {MangaReaderComponent} from "../manga-reader/manga-reader.component";
import {InfiniteScrollModule} from "ngx-infinite-scroll";
import {ReaderSetting} from "../../_models/reader-setting";
import {SafeStylePipe} from "../../../_pipes/safe-style.pipe";
Expand Down Expand Up @@ -174,6 +173,14 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy,
*/
debugLogFilter: Array<string> = ['[PREFETCH]', '[Intersection]', '[Visibility]', '[Image Load]'];

/**
* Width overwrite for maunal width control
* 2 observables needed to avoid flickering, probably due to data races, when changing the width
* this allows to precicely define execution order
*/
widthOverride$ : Observable<string> = new Observable<string>();
widthSliderValue$ : Observable<string> = new Observable<string>();

get minPageLoaded() {
return Math.min(...Object.values(this.imagesLoaded));
}
Expand Down Expand Up @@ -232,6 +239,31 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy,
takeUntilDestroyed(this.destroyRef)
);


this.widthSliderValue$ = this.readerSettings$.pipe(
map(values => (parseInt(values.widthSlider) <= 0) ? '' : values.widthSlider + '%'),
takeUntilDestroyed(this.destroyRef)
);

this.widthOverride$ = this.widthSliderValue$;

//perfom jump so the page stays in view
this.widthSliderValue$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(val => {
this.currentPageElem = this.document.querySelector('img#page-' + this.pageNum);
if(!this.currentPageElem)
return;

let images = Array.from(document.querySelectorAll('img[id^="page-"]')) as HTMLImageElement[];
images.forEach((img) => {
this.renderer.setStyle(img, "width", val);
});

this.widthOverride$ = this.widthSliderValue$;
this.prevScrollPosition = this.currentPageElem.getBoundingClientRect().top;
this.currentPageElem.scrollIntoView();
majora2007 marked this conversation as resolved.
Show resolved Hide resolved
this.cdRef.markForCheck();
});

if (this.goToPage) {
this.goToPage.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(page => {
const isSamePage = this.pageNum === page;
Expand Down Expand Up @@ -369,6 +401,7 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy,
}

checkIfShouldTriggerContinuousReader() {
this.widthOverride$ = this.widthSliderValue$;
if (this.isScrolling) return;

if (this.scrollingDirection === PAGING_DIRECTION.FORWARD) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,13 @@
min="10" max="100" step="1" formControlName="darkness">
</div>

<div class="col-md-6 col-sm-12">
<label for="page-fitting-slider" class="form-label">{{t('width_override')}}:
{{ (widthOverrideLabel$ | async) ? (widthOverrideLabel$ | async) : t('width_override_off') }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably re-write this completely as:
@if (widthOverrideLabel$ | async; as widthOverrideLabel) {
{{ widthOverrideLabel ? widthOverrideLabel : t('off') }}
}

</label>
<input id="page-fitting-slider" type="range" min="0" max="100" class="form-range" formControlName="widthSlider">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's rename these ids to be width-override-slider instead

</div>


<div class="col-md-6 col-sm-12">
<button class="btn btn-primary" (click)="savePref()">{{t('save-globally')}}</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,10 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
* Show and log debug information
*/
debugMode: boolean = false;
/**
* Width overwrite label for maunal width control
*/
widthOverrideLabel$ : Observable<string> = new Observable<string>();

// Renderer interaction
readerSettings$!: Observable<ReaderSetting>;
Expand Down Expand Up @@ -513,6 +517,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
autoCloseMenu: new FormControl(this.autoCloseMenu),
pageSplitOption: new FormControl(this.pageSplitOption),
fittingOption: new FormControl(this.mangaReaderService.translateScalingOption(this.scalingOption)),
widthSlider: new FormControl('none'),
layoutMode: new FormControl(this.layoutMode),
darkness: new FormControl(100),
emulateBook: new FormControl(this.user.preferences.emulateBook),
Expand Down Expand Up @@ -549,9 +554,33 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
takeUntilDestroyed(this.destroyRef)
).subscribe(() => {});

this.generalSettingsForm.get('pageSplitOption')?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(val => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move the subscribe into a tap so that subscribe can be empty.

In addition, move each pipe into a new line, like you see elsewhere.

I would also get the control in a variable then re-use in the code, so:
const widthOverrideControl = this.generalSettingsForm.get('widthSlider')!;

let fitting = this.generalSettingsForm.get('fittingOption')?.value;
if(PageSplitOption.FitSplit == val && FITTING_OPTION.WIDTH == fitting) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after if. If ( and also newline above if statements please

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a bit of documentation about our decisions about when this should work. It will likely help me in the future when there is a bug.

this.generalSettingsForm.get('widthSlider')?.enable();
} else {
this.generalSettingsForm.get('widthSlider')?.setValue(0);
majora2007 marked this conversation as resolved.
Show resolved Hide resolved
this.generalSettingsForm.get('widthSlider')?.disable();
}
});

this.generalSettingsForm.get('fittingOption')?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(val => {
let splitting = this.generalSettingsForm.get('pageSplitOption')?.value;
if(PageSplitOption.FitSplit == splitting && FITTING_OPTION.WIDTH == val){
this.generalSettingsForm.get('widthSlider')?.enable();
} else {
this.generalSettingsForm.get('widthSlider')?.setValue(0);
this.generalSettingsForm.get('widthSlider')?.disable();
}

this.widthOverrideLabel$ = this.readerSettings$?.pipe(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation

map(values => (parseInt(values.widthSlider) <= 0) ? '' : values.widthSlider + '%'),
takeUntilDestroyed(this.destroyRef)
);


});

this.generalSettingsForm.get('layoutMode')?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(val => {

const changeOccurred = parseInt(val, 10) !== this.layoutMode;
Expand All @@ -560,11 +589,13 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
if (this.layoutMode === LayoutMode.Single) {
this.generalSettingsForm.get('pageSplitOption')?.setValue(this.user.preferences.pageSplitOption);
this.generalSettingsForm.get('pageSplitOption')?.enable();
this.generalSettingsForm.get('widthSlider')?.enable();
this.generalSettingsForm.get('fittingOption')?.enable();
this.generalSettingsForm.get('emulateBook')?.enable();
} else {
this.generalSettingsForm.get('pageSplitOption')?.setValue(PageSplitOption.NoSplit);
this.generalSettingsForm.get('pageSplitOption')?.disable();
this.generalSettingsForm.get('widthSlider')?.disable();
this.generalSettingsForm.get('fittingOption')?.setValue(this.mangaReaderService.translateScalingOption(ScalingOption.FitToHeight));
this.generalSettingsForm.get('fittingOption')?.disable();
this.generalSettingsForm.get('emulateBook')?.enable();
Expand Down Expand Up @@ -696,6 +727,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
return {
pageSplit: parseInt(this.generalSettingsForm.get('pageSplitOption')?.value, 10),
fitting: (this.generalSettingsForm.get('fittingOption')?.value as FITTING_OPTION),
widthSlider: this.generalSettingsForm.get('widthSlider')?.value,
layoutMode: this.layoutMode,
darkness: parseInt(this.generalSettingsForm.get('darkness')?.value + '', 10) || 100,
pagingDirection: this.pagingDirection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[style.filter]="(darkness$ | async) ?? '' | safeStyle" [style.height]="(imageContainerHeight$ | async) ?? '' | safeStyle">
@if(currentImage) {
<img alt=" "
style="width: {{widthOverride$ | async}}"
#image
[src]="currentImage.src"
id="image-1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export class SingleRendererComponent implements OnInit, ImageRenderer {
pageNum: number = 0;
maxPages: number = 1;

/**
* Width overwrite for maunal width control
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Width override*

*/
widthOverride$ : Observable<string> = new Observable<string>();

get ReaderMode() {return ReaderMode;}
get LayoutMode() {return LayoutMode;}

Expand All @@ -67,6 +72,13 @@ export class SingleRendererComponent implements OnInit, ImageRenderer {
takeUntilDestroyed(this.destroyRef)
);

//handle manual width
this.widthOverride$ = this.readerSettings$.pipe(
map(values => (parseInt(values.widthSlider) <= 0) ? '' : values.widthSlider + '%'),
takeUntilDestroyed(this.destroyRef)
);


this.emulateBookClass$ = this.readerSettings$.pipe(
map(data => data.emulateBook),
map(enabled => enabled ? 'book-shadow' : ''),
Expand Down
6 changes: 3 additions & 3 deletions UI/Web/src/app/manga-reader/_models/reader-enums.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export enum FITTING_OPTION {
HEIGHT = 'full-height',
WIDTH = 'full-width',
ORIGINAL = 'original'
ORIGINAL = 'original',
}

/**
Expand All @@ -12,9 +12,9 @@ export enum SPLIT_PAGE_PART {
LEFT_PART = 'left',
RIGHT_PART = 'right'
}

export enum PAGING_DIRECTION {
FORWARD = 1,
BACKWARDS = -1,
}

3 changes: 2 additions & 1 deletion UI/Web/src/app/manga-reader/_models/reader-setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { FITTING_OPTION, PAGING_DIRECTION } from "./reader-enums";
export interface ReaderSetting {
pageSplit: PageSplitOption;
fitting: FITTING_OPTION;
widthSlider: string;
layoutMode: LayoutMode;
darkness: number;
pagingDirection: PAGING_DIRECTION;
readerMode: ReaderMode;
emulateBook: boolean;
}
}
2 changes: 2 additions & 0 deletions UI/Web/src/assets/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,8 @@
"image-scaling-label": "Image Scaling",
"height": "Height",
"width": "Width",
"width_override": "Width Override",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to match the naming scheme of the other localization keys. override-width-label and off should be the keys.

"width_override_off": "Off",
"original": "Original",
"auto-close-menu-label": "{{user-preferences.auto-close-menu-label}}",
"swipe-enabled-label": "Swipe Enabled",
Expand Down