diff --git a/src/app/shared/ui/manga-page/manga-page-even.component.scss b/src/app/shared/ui/manga-page/manga-page-even.component.scss
index 4089250..c9e361a 100644
--- a/src/app/shared/ui/manga-page/manga-page-even.component.scss
+++ b/src/app/shared/ui/manga-page/manga-page-even.component.scss
@@ -1,5 +1,5 @@
svg {
- aspect-ratio: 257/364;
+ aspect-ratio: var(--ratio);
border: 1px solid;
grid-area: 1/4;
width: 100%;
@@ -11,7 +11,7 @@ svg {
:host {
display: grid;
max-height: 100vh;
- aspect-ratio: 257/364;
+ aspect-ratio: var(--ratio);
--side-gap: 2rem;
background-color: #fff;
diff --git a/src/app/shared/ui/manga-page/manga-page.component.scss b/src/app/shared/ui/manga-page/manga-page.component.scss
index fd6d0d3..ede7aa8 100644
--- a/src/app/shared/ui/manga-page/manga-page.component.scss
+++ b/src/app/shared/ui/manga-page/manga-page.component.scss
@@ -2,7 +2,7 @@
--side-gap: 2rem;
display: grid;
max-height: 100vh;
- aspect-ratio: 257/364;
+ aspect-ratio: var(--ratio);
background-color: #fff;
color: #000;
gap: 2ch 1ch;
@@ -13,7 +13,7 @@
}
svg {
- aspect-ratio: 257/364;
+ aspect-ratio: var(--ratio);
border: 1px solid;
grid-area: 1/4;
width: 100%;
diff --git a/src/app/shared/ui/pages-indicator/pages-indicator.component.scss b/src/app/shared/ui/pages-indicator/pages-indicator.component.scss
index 4a2fa62..2c1b2ae 100644
--- a/src/app/shared/ui/pages-indicator/pages-indicator.component.scss
+++ b/src/app/shared/ui/pages-indicator/pages-indicator.component.scss
@@ -42,7 +42,7 @@ div {
:host.pages {
div {
border-radius: .5ch;
- box-shadow: var(--flat-shadow-medium);
+ box-shadow: var(--shadow-1);
}
diff --git a/src/app/shared/ui/text-embracer/text-embracer.component.scss b/src/app/shared/ui/text-embracer/text-embracer.component.scss
index f7ad1b4..d61ca07 100644
--- a/src/app/shared/ui/text-embracer/text-embracer.component.scss
+++ b/src/app/shared/ui/text-embracer/text-embracer.component.scss
@@ -1,9 +1,9 @@
:host {
- --border-color: currentColor;
+ --frame-color: currentColor;
--border-width: 1px;
--border-style: solid;
--back-color: transparent;
- --shc: var(--border-color);
+ --dot-color: red;
margin: 0;
text-transform: uppercase;
text-align: center;
@@ -14,22 +14,18 @@
&>span {
text-box: ex alphabetic;
- aspect-ratio: 2/3;
+ aspect-ratio: var(--ratio);
display: grid;
- border: var(--border-width) var(--border-style) var(--border-color);
+ border: var(--border-width) var(--border-style) var(--frame-color);
border-radius: .1ch;
height: 1.5lh;
place-content: center;
background-color: var(--back-color);
- --bg-1: var(--gl) 0px 0px / 4px 4px;
- --bg-2: var(--gl) 0px 0px / 3px 3px, var(--gl) 1.5px 1.5px / 3px 3px;
--gl: radial-gradient(circle 1px at 0px 0px, var(--dot-color) 1px, transparent 0);
+ --bg-1: var(--gl) 0px 0px / 8px 8px;
+ --bg-2: var(--gl) 0px 0px / 4px 4px, var(--gl) 1.5px 1.5px / 4px 4px;
background: var(--bg-1);
-
- text-shadow: 0.025ch .025ch var(--shc),
- 0.05ch .05ch var(--shc),
- 0.075ch .075ch var(--shc),
- 0.1ch .1ch var(--shc);
+ text-shadow: var(--text-shadow-1);
transition: all var(--t) ease-in-out;
&:hover {
diff --git a/src/app/shared/ui/view-mode-bar/view-mode-bar.component.scss b/src/app/shared/ui/view-mode-bar/view-mode-bar.component.scss
index b29bf43..2a6000d 100644
--- a/src/app/shared/ui/view-mode-bar/view-mode-bar.component.scss
+++ b/src/app/shared/ui/view-mode-bar/view-mode-bar.component.scss
@@ -43,10 +43,10 @@
padding: 0;
&:checked~label {
- background-color: #103651;
+ background-color: var(--surface-avarage);
color: var(--surface-1);
- transform: translateY(.25ch);
- // box-shadow: unset;
+ transform: translate(2px, 2px);
+ box-shadow: unset;
}
&:not(:checked):is(:focus-within, :hover)~label {
diff --git a/src/app/shared/ui/viewer/components/hint-page/hint-page.component.html b/src/app/shared/ui/viewer/components/hint-page/hint-page.component.html
index 6f69ae1..39755ae 100644
--- a/src/app/shared/ui/viewer/components/hint-page/hint-page.component.html
+++ b/src/app/shared/ui/viewer/components/hint-page/hint-page.component.html
@@ -34,7 +34,7 @@
-

+
@if (getPrevIndex() >=0 && playlist[getPrevIndex()]; as prev) {
diff --git a/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.html b/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.html
new file mode 100644
index 0000000..6949fa6
--- /dev/null
+++ b/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.html
@@ -0,0 +1,35 @@
+@let vm = viewer.viewModeOption();
+@let pub = episode?.publisher;
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @if(pub && pub.id) {
+
Робота від {{pub.name}}
+
+ }
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.scss b/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.scss
new file mode 100644
index 0000000..fa6ebb6
--- /dev/null
+++ b/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.scss
@@ -0,0 +1,60 @@
+app-manga-page-even.long,
+.last-hint-page.long {
+ height: unset;
+ width: 100%;
+}
+
+[frame="1"],
+[frame="2"],
+[frame="3"],
+[frame="4"],
+[frame="5"] {
+ padding: 1ch;
+ width: 100%;
+ display: grid;
+ place-items: center;
+}
+
+[frame="3"] {
+ height: 100%;
+}
+
+[frame="4"] {
+ text-align: center;
+}
+
+img {
+ display: block;
+ margin: auto;
+ max-width: 40%;
+}
+
+[frame="5"] img {
+ max-width: 100%;
+ max-height: 100%;
+}
+
+[frame] {
+ &::before {
+ --gc: #f0f4f8;
+ --gc2: #fff;
+ content: "";
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+ background: radial-gradient(circle at 50% 50%, var(--gc) 0 4vmin, transparent 50vmin 100%), repeating-conic-gradient(from 0deg at 50% 50%, transparent 0 6deg, var(--gc2) 0 12deg);
+ background-blend-mode: soft-light;
+}
+}
+
+.publisher-links {
+ display: flex;
+ justify-content: center;
+ flex-wrap: wrap;
+ gap: 1ch;
+ font-size: x-small;
+}
+
+.text-center {
+ text-align: center;
+}
\ No newline at end of file
diff --git a/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.ts b/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.ts
new file mode 100644
index 0000000..015045a
--- /dev/null
+++ b/src/app/shared/ui/viewer/components/thanks-page/thanks-page.component.ts
@@ -0,0 +1,54 @@
+import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core';
+import { Playlist, PlaylistItem } from '../../../../../playlist/data-access/playlist.service';
+import { ViewerService } from '../../../../data-access';
+import { LangService } from '../../../../data-access/lang.service';
+import { CompositionEpisode } from '../../../../../@site-modules/@common-read';
+
+@Component({
+ selector: 'app-thanks-page',
+ standalone: false,
+ templateUrl: './thanks-page.component.html',
+ styleUrl: './thanks-page.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class ThanksPageComponent {
+ viewer: ViewerService = inject(ViewerService)
+ lang: LangService = inject(LangService)
+ @Input() episode: CompositionEpisode | undefined = undefined;
+
+ @Input() playlist: Playlist = [];
+ @Input() currentPlaylistItem: PlaylistItem | undefined;
+ @Input() playlistLink: string = "";
+
+
+ getCyrrentIndex() {
+ for (let i = 0; i < this.playlist.length; i++) {
+ const item = this.playlist[i];
+ if (this.currentPlaylistItem?.id == item.id && this.currentPlaylistItem?.site == item.site)
+ return i;
+ }
+
+ return -1;
+ }
+
+ getNextIndex() {
+ const index = this.getCyrrentIndex();
+ if (index < 0) return -1;
+
+ return ((index + 1) < this.playlist.length) ? index + 1 : -1;
+ }
+
+ readonly logo = {
+ src: '/assets/icons/chtnk.svg',
+ alt: 'Chytanka logo'
+ }
+ readonly heart = {
+ src: '/assets/images/heart-hand-drawn-symbol-outline-svgrepo-com.svg',
+ alt: 'Heart icon'
+ }
+ readonly map = {
+ src: '/assets/images/web-comics-svgrepo-com.svg',
+ alt: 'Map hand-drawn'
+ }
+
+}
diff --git a/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.html b/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.html
index 18bdb0d..8824a70 100644
--- a/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.html
+++ b/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.html
@@ -10,7 +10,7 @@
}
-
{{episode?.title}}
+
{{episode().title}}
@@ -42,18 +42,18 @@
+ [title]="'📥 Download '+ episode().title">
- @if(episode) {
+ @if(episode()) {
@if(!dl.getFromQueue(genId())){
- {{episode.title}}
+ style="display: grid; grid-template-columns: 1fr auto; padding: 1.5ch 2ch; border-radius:.5ch; box-shadow: var(--shadow-1); gap: 1ch; align-items: center;">
+ {{episode().title}}
+ (click)="dl.addToQueue(episode(), genId())">▶️
- 📥 {{episode.images.length}} pages
+ 📥 {{episode().images.length}} pages
diff --git a/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.scss b/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.scss
index d3150d2..4e84f68 100644
--- a/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.scss
+++ b/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.scss
@@ -1,7 +1,7 @@
progress {
display: block;
border-radius: var(--radius-2);
- box-shadow: var(--flat-shadow-medium);
+ box-shadow: var(--shadow-1);
height: 1lh;
width: 100%;
position: relative;
@@ -51,7 +51,7 @@ textarea {
padding: 1ch;
border-top-left-radius: var(--radius-2);
border-bottom-left-radius: var(--radius-2);
- box-shadow: var(--flat-shadow-medium);
+ box-shadow: var(--shadow-1);
}
.open-chtnk-link {
diff --git a/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.ts b/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.ts
index 08366bf..07272c9 100644
--- a/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.ts
+++ b/src/app/shared/ui/viewer/components/viewer-header/viewer-header.component.ts
@@ -1,4 +1,4 @@
-import { Component, computed, EventEmitter, HostListener, inject, Input, Output, PLATFORM_ID, Signal, signal, ViewChild } from '@angular/core';
+import { AfterViewInit, ChangeDetectorRef, Component, computed, effect, EventEmitter, HostListener, inject, input, Input, Output, PLATFORM_ID, Signal, signal, ViewChild } from '@angular/core';
import { DomManipulationService, ViewerService } from '../../../../data-access';
import { CompositionEpisode } from '../../../../../@site-modules/@common-read';
import { Playlist, PlaylistItem } from '../../../../../playlist/data-access/playlist.service';
@@ -13,15 +13,54 @@ import { isPlatformBrowser } from '@angular/common';
// const L = window.location;
@Component({
- selector: 'app-viewer-header',
- templateUrl: './viewer-header.component.html',
- styleUrls: [
- './viewer-header.component.scss',
- '../../../../../shared/ui/@styles/input-group.scss'
- ],
- standalone: false
+ selector: 'app-viewer-header',
+ templateUrl: './viewer-header.component.html',
+ styleUrls: [
+ './viewer-header.component.scss',
+ '../../../../../shared/ui/@styles/input-group.scss'
+ ],
+ standalone: false
})
export class ViewerHeaderComponent {
+
+ parseTagsFromTitle(title: string): Set
{
+ const matchedTags = title.toLowerCase().match(/\b(rtl|ltr|ver|long|scroll|nsfw|sfw|color|bw|demo|extra)\b/g) ?? [];
+ const tags = new Set(matchedTags);
+ return tags;
+ }
+
+ applyEpisodeTitleTags(tags: Set): void {
+
+ const viewModeMap: Record = {
+ 'ver': '3',
+ 'long': '3',
+ 'scroll': '3',
+ 'rtl': '1',
+ 'ltr': '2',
+ };
+
+ for (const [tag, code] of Object.entries(viewModeMap)) {
+ if (tags.has(tag)) {
+ this.viewer.setViewModeOptionByCode(code);
+ break;
+ }
+ }
+
+ if (tags.has('nsfw')) {
+ this.episode().nsfw = true;
+ }
+ }
+
+
+ constructor() {
+ effect(() => {
+ const episode = this.episode();
+ if (!episode) return;
+ const tags = this.parseTagsFromTitle(episode.title);
+ this.applyEpisodeTitleTags(tags);
+ })
+ }
+
viewer: ViewerService = inject(ViewerService)
lang: LangService = inject(LangService)
embedHelper = inject(EmbedHalperService);
@@ -39,7 +78,11 @@ export class ViewerHeaderComponent {
@Input() currentPlaylistItem: PlaylistItem | undefined;
// @Input() playlist: Playlist = [];
- @Input() episode: CompositionEpisode | undefined = undefined;
+ // @Input() episode: CompositionEpisode | undefined = undefined;
+ episode = input({
+ title: '',
+ images: []
+ })
@Output() onToggle: EventEmitter = new EventEmitter();
@@ -63,11 +106,11 @@ export class ViewerHeaderComponent {
this.domMan.setHotkeys(event, this.hotKeys)
}
- isFileRoute = computed(() => {
+ isFileRoute = computed(() => {
const L = (isPlatformBrowser(this.platformId)) ? window.location : { pathname: '' }
return L.pathname.startsWith('/file/')
-})
+ })
link: Signal =
//decodeURIComponent
@@ -87,7 +130,7 @@ export class ViewerHeaderComponent {
shareWith() {
const shareData = {
- title: this.episode?.title,
+ title: this.episode().title,
url: this.link(),
};
navigator?.share(shareData)
diff --git a/src/app/shared/ui/viewer/viewer.component.html b/src/app/shared/ui/viewer/viewer.component.html
index 9183a8f..7d5c0e5 100644
--- a/src/app/shared/ui/viewer/viewer.component.html
+++ b/src/app/shared/ui/viewer/viewer.component.html
@@ -41,53 +41,11 @@
-
-
-

-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
+
+
+
+
@@ -100,9 +58,11 @@
@defer{
+@if (episode) {
}
+}
@defer{
+
+
+
+
+
\ No newline at end of file
diff --git a/src/favicon.ico b/src/favicon.ico
old mode 100644
new mode 100755
index bf63ddf..2d10844
Binary files a/src/favicon.ico and b/src/favicon.ico differ
diff --git a/src/styles.scss b/src/styles.scss
index d5b0946..52b0aff 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -9,6 +9,7 @@
--blur: 1ch;
--t: 133.333334ms; //266.666667ms; //calc(1s / 60 * 16);
--surface: hsl(203.44 8% 16%);
+ --surface-avarage: oklch(from var(--avarage-color, var(--surface)) 0.2 0.0256 h);
--text: hsl(200 5% 80%);
--dot-color: #000;
--bg-1: var(--gl) 0px 0px / 4px 4px;
@@ -20,6 +21,7 @@
font-size: 16px;
@media (prefers-color-scheme: light) {
+ --surface-avarage: oklch(from var(--avarage-color, #ffd60a) 1 0.016 h);
--surface: #f7fcff;
--text: #010102;
}
@@ -75,7 +77,7 @@ input {
transition: all var(--t);
text-wrap: balance;
-webkit-tap-highlight-color: transparent;
- box-shadow: var(--flat-shadow-medium);
+ box-shadow: var(--shadow-1);
}
&.small {
@@ -104,15 +106,17 @@ input {
color: white;
}
-
+ &.border {
+ border: var(--border-size) solid var(--border-color);
+ }
&:hover {
- background-color: #103651;
- color: #ffd60a;
+ color: #103651;
+ background-color: #ffd60a;
@media (prefers-color-scheme: light) {
- background-color: #f8d755;
- color: #103651;
+ color: #f8d755;
+ background-color: #166496;
}
}
@@ -171,29 +175,35 @@ a[target="_blank"]:after {
}
:root {
- --shc: #ffd60a; //rgb(0, 39, 65);
+ --ratio: 257/364;
+ --accent: #ffd60a;
+
--avarage-l: 0.48;
--avarage-l-2: 0.36;
@media (prefers-color-scheme: light) {
- --shc: #166496;
+ --accent: #166496;
}
& {
- --shadow-color: oklch(from var(--shc) var(--avarage-l-2) c h);
- --shadow-distance: .25rem;
- --shadow-distance-2: .5rem;
+ --avarage: oklch(from var(--avarage-color, #c3d3e3) var(--avarage-l) 0.0192 h);
+
+ --border-size: 0.2rem;
+ --border-color: oklch(from var(--avarage) var(--avarage-l) c h);
+
+ --shadow-color: oklch(from var(--avarage) var(--avarage-l-2) c h);
+ --shadow-distance: var(--border-size) var(--border-size);
+ --shadow-distance-2: calc(var(--border-size) * 2) calc(var(--border-size) * 2);
- // --flat-shadow-high: 1px 1px var(--shc),
- // 2px 2px var(--shc),
- // 3px 3px 0 -1px var(--shc),
- // 4px 4px 0 -1px var(--shc);
+ --shadow-1: 1px 1px var(--surface), var(--shadow-distance) var(--shadow-color);
+ --shadow-2: 2px 2px var(--surface), var(--shadow-distance-2) var(--shadow-color);
+
+ --text-shadow-1: 1px 1px var(--surface), var(--shadow-distance) var(--shadow-color);
+ --text-shadow-1: 2px 2px var(--surface), var(--shadow-distance-2) var(--shadow-color);
+
+ --filter-shadow-1: drop-shadow(1px 1px var(--surface)) drop-shadow(var(--shadow-distance) var(--shadow-color));
- // --flat-shadow-medium: 1px 1px var(--shc),
- // 2px 2px var(--shc);
- --flat-shadow-medium: 1px 1px var(--surface), var(--shadow-distance) var(--shadow-distance) var(--shadow-color);
- --flat-shadow-high: 1px 1px var(--surface), var(--shadow-distance-2) var(--shadow-distance-2) var(--shadow-color);
}
}
@@ -225,4 +235,9 @@ a[target="_blank"]:after {
filter: blur(var(--blur));
}
}
+}
+
+::selection {
+ background: var(--accent);
+ color: var(--surface);
}
\ No newline at end of file