Skip to content

Commit

Permalink
Select language of the chapter while reading (xgi#324)
Browse files Browse the repository at this point in the history
* feat: change language while reading

* fix: delete volume comparison, they're too much inconsistent on sites

* fix: mark all translations of the same chapter as read for continue button to work as it should

* feat: only preferred language is displayed in chapter table list, if it is missing, second preferred selected and so on. Made because now you can change language in reader, and it makes table less cluttered
  • Loading branch information
rootBrz authored Feb 14, 2024
1 parent bb99984 commit 42546a4
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 8 deletions.
75 changes: 73 additions & 2 deletions src/components/reader/ReaderHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable react/button-has-type */
import React from 'react';
import { Chapter } from '@tiyo/common';
import { Chapter, Languages } from '@tiyo/common';
import { useRecoilState, useRecoilValue } from 'recoil';
import flags from '../../img/flags.png';
import {
IconArrowAutofitHeight,
IconArrowAutofitWidth,
Expand Down Expand Up @@ -41,6 +42,7 @@ import {
relevantChapterListState,
showingSettingsModalState,
pageGroupListState,
languageChapterListState,
} from '../../state/readerStates';
import {
fitContainToHeightState,
Expand Down Expand Up @@ -92,7 +94,7 @@ const ICONS_OFFSET_PAGES = {

type Props = {
changePage: (left: boolean, toBound?: boolean) => void;
setChapter: (id: string) => void;
setChapter: (id: string, page?: number) => void;
changeChapter: (direction: 'left' | 'right' | 'next' | 'previous') => void;
getAdjacentChapterId: (previous: boolean) => string | null;
exitPage: () => void;
Expand All @@ -106,6 +108,7 @@ const ReaderHeader: React.FC<Props> = (props: Props) => {
const pageGroupList = useRecoilValue(pageGroupListState);
const chapter = useRecoilValue(chapterState);
const relevantChapterList = useRecoilValue(relevantChapterListState);
const languageChapterList = useRecoilValue(languageChapterListState);
const [pageStyle, setPageStyle] = useRecoilState(pageStyleState);
const [fitContainToWidth, setFitContainToWidth] = useRecoilState(fitContainToWidthState);
const [fitContainToHeight, setFitContainToHeight] = useRecoilState(fitContainToHeightState);
Expand Down Expand Up @@ -390,6 +393,74 @@ const ReaderHeader: React.FC<Props> = (props: Props) => {
{TEXT_READING_DIRECTION[readingDirection]}
</Button>

<Menu shadow="md" width={320} trigger="hover">
<Menu.Target>
<Button
leftIcon={
chapter && chapter.languageKey ? (
<div className="flag-container">
<img
src={flags}
title={Languages[chapter.languageKey].name}
alt={Languages[chapter.languageKey].name}
className={`flag flag-${Languages[chapter.languageKey].flagCode
}`}
/>
</div>
) : (
<></>
)
}
compact
styles={buttonStyles}
radius={0}
>
<div>
{chapter && chapter.languageKey
? `${Languages[chapter.languageKey].name}`
: 'Unknown Language'}
</div>
</Button>
</Menu.Target>

<Menu.Dropdown>
<ScrollArea.Autosize maxHeight={220} style={{ width: 310 }}>
{languageChapterList.map((languageChapter: Chapter) => (
<Menu.Item
key={languageChapter.id}
onClick={() => {
if (languageChapter.id)
props.setChapter(languageChapter.id, pageNumber);
}}
>
{Languages[languageChapter.languageKey] === undefined ? (
<></>
) : (
<div style={{ display: 'flex' }}>
<div
style={{ marginRight: '5px' }}
className="flag-container"
>
<img
src={flags}
title={Languages[languageChapter.languageKey].name}
alt={Languages[languageChapter.languageKey].name}
className={`flag flag-${Languages[languageChapter.languageKey].flagCode
}`}
/>
</div>
{`${Languages[languageChapter.languageKey].name} ${languageChapter.volumeNumber
? 'Vol. ' + languageChapter.volumeNumber
: ''
} by ${languageChapter.groupName}`}
</div>
)}
</Menu.Item>
))}
</ScrollArea.Autosize>
</Menu.Dropdown>
</Menu>

<Button
compact
styles={buttonStyles}
Expand Down
47 changes: 42 additions & 5 deletions src/components/reader/ReaderPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
const [relevantChapterList, setRelevantChapterList] = useRecoilState(
readerStates.relevantChapterListState
);
const [languageChapterList, setLanguageChapterList] = useRecoilState(
readerStates.languageChapterListState
);
const [showingSettingsModal, setShowingSettingsModal] = useRecoilState(
readerStates.showingSettingsModalState
);
Expand Down Expand Up @@ -137,6 +140,39 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
setRelevantChapterList(newRelevantChapterList);
};

const createLanguageChapterList = (series: Series, chapter: Chapter) => {
if (series.id === undefined) return;

const newLanguageChapterList: Chapter[] = [];
const chapters: Chapter[] = library.fetchChapters(series.id);

const chapterLangsSet: Set<string> = new Set();
chapters.forEach((c: Chapter) => {
if (chapter.chapterNumber === c.chapterNumber) {
chapterLangsSet.add(c.chapterNumber);
}
});

chapterLangsSet.forEach((chapterNumber: string) => {
const curChapters: Chapter[] = chapters.filter(
(c: Chapter) =>
c.chapterNumber === chapterNumber &&
(!chapterLanguages.length || chapterLanguages.includes(c.languageKey))
);

curChapters.forEach((c) => newLanguageChapterList.push(c));
});

setLanguageChapterList(
newLanguageChapterList.sort((a, b) => {
if (a.languageKey && b.languageKey) {
return a.languageKey.localeCompare(b.languageKey);
}
return 0;
})
);
};

const loadDownloadedChapterData = async (
series: Series,
chapter: Chapter,
Expand Down Expand Up @@ -180,9 +216,8 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
const series: Series | null = library.fetchSeries(seriesId);
if (chapter === null || series === null) return;

if (relevantChapterList.length === 0) {
createRelevantChapterList(series, chapter);
}
createLanguageChapterList(series, chapter);
createRelevantChapterList(series, chapter);

setReaderSeries(series);
setReaderChapter(chapter);
Expand Down Expand Up @@ -331,6 +366,7 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
setPageUrls([]);
setLastPageNumber(0);
setRelevantChapterList([]);
setLanguageChapterList([]);
setShowingNoNextChapter(false);
removeRootStyles();
removeKeybindings();
Expand Down Expand Up @@ -495,14 +531,15 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
if (
readerSeries !== undefined &&
readerChapter !== undefined &&
languageChapterList.every(chapter => readerChapter.chapterNumber === chapter.chapterNumber) &&
!readerChapter.read &&
lastPageNumber > 0
) {
if (pageNumber >= Math.floor(0.8 * lastPageNumber)) {
markChapters(
[readerChapter],
[readerChapter, ...languageChapterList],
readerSeries,
!readerChapter.read,
true,
setChapterList,
setLibrarySeries,
chapterLanguages
Expand Down
16 changes: 15 additions & 1 deletion src/state/libraryStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,28 @@ export const sortedFilteredChapterListState = selector<Chapter[]>({
const chapterListVolOrder = get(chapterListVolOrderState);
const chapterListChOrder = get(chapterListChOrderState);

const uniqueChapters = new Map();

if (chapterLanguages.length > 0) {
chapterLanguages.forEach((lang) => {
chapterList.filter((chapter: Chapter) =>
chapter.languageKey === lang &&
!uniqueChapters.has(chapter.chapterNumber) &&
uniqueChapters.set(chapter.chapterNumber, chapter))
})
}

return chapterList
.filter(
(chapter: Chapter) =>
(chapterLanguages.includes(chapter.languageKey) || chapterLanguages.length === 0) &&
chapter.title !== null &&
chapter.title.toLowerCase().includes(chapterFilterTitle.toLowerCase()) &&
chapter.groupName !== null &&
chapter.groupName.toLowerCase().includes(chapterFilterGroup.toLowerCase())
chapter.groupName.toLowerCase().includes(chapterFilterGroup.toLowerCase()) &&
((uniqueChapters.has(chapter.chapterNumber) &&
uniqueChapters.get(chapter.chapterNumber) === chapter) ||
chapterLanguages.length === 0)
)
.sort((a, b) => {
const volumeComp = {
Expand Down
5 changes: 5 additions & 0 deletions src/state/readerStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export const relevantChapterListState = atom({
default: [] as Chapter[],
});

export const languageChapterListState = atom({
key: 'languageChapterListState',
default: [] as Chapter[],
});

export const showingSettingsModalState = atom({
key: 'readerShowingSettingsModalState',
default: false,
Expand Down

0 comments on commit 42546a4

Please sign in to comment.