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

Added automatic download / delete chapters #337

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
34 changes: 33 additions & 1 deletion src/components/general/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,19 @@ import {
autoBackupState,
chapterLanguagesState,
refreshOnStartState,
OnStartDownloadUnreadCountState,
OnStartUpDeleteReadState,
OnStartUpDownloadUnreadState,
customDownloadsDirState,
} from '../../state/settingStates';
import DashboardSidebarLink from './DashboardSidebarLink';
import { downloadCover } from '../../util/download';
import { createAutoBackup } from '../../util/backup';
import {
DeleteReadChapters,
DownloadUnreadChapters,
} from '../../features/library/chapterDownloadUtils';
import { getDefaultDownloadDir } from '../settings/GeneralSettings';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface Props {}
Expand All @@ -56,6 +65,11 @@ const DashboardPage: React.FC<Props> = () => {
const [importing, setImporting] = useRecoilState(importingState);
const categoryList = useRecoilValue(categoryListState);

const OnStartUpDownloadUnread = useRecoilValue(OnStartUpDownloadUnreadState);
const OnStartUpDownloadUnreadCount = useRecoilValue(OnStartDownloadUnreadCountState);
const OnStartUpDeleteRead = useRecoilValue(OnStartUpDeleteReadState);
const customDownloadsDir = useRecoilValue(customDownloadsDirState);

useEffect(() => {
if (autoBackup) {
createAutoBackup(autoBackupCount);
Expand All @@ -68,7 +82,25 @@ const DashboardPage: React.FC<Props> = () => {
setReloadingSeriesList,
chapterLanguages,
categoryList
).catch((e) => log.error(e));
)
.then(() => {
if (OnStartUpDeleteRead) {
DeleteReadChapters(
library.fetchSeriesList(),
customDownloadsDir || String(getDefaultDownloadDir())
);
}
if (OnStartUpDownloadUnread) {
DownloadUnreadChapters(
library.fetchSeriesList(),
customDownloadsDir || String(getDefaultDownloadDir()),
chapterLanguages,
false,
OnStartUpDownloadUnreadCount
);
}
})
.catch((e) => log.error(e));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeSeriesList]);
Expand Down
34 changes: 34 additions & 0 deletions src/components/library/SeriesDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,25 @@
import SeriesDetailsIntro from './series/SeriesDetailsIntro';
import SeriesDetailsInfoGrid from './series/SeriesDetailsInfoGrid';

import {
OnSeriesDetailsDeleteReadState,
OnSeriesDetailsDownloadUnreadState,
OnStartDownloadUnreadCountState,
chapterLanguagesState,
customDownloadsDirState,
} from '../../state/settingStates';
import {
DeleteReadChapters,
DownloadUnreadChapters,
} from '../../features/library/chapterDownloadUtils';
import { getDefaultDownloadDir } from '../settings/GeneralSettings';

type Props = unknown;

const SeriesDetails: React.FC<Props> = () => {
const { id } = useParams<{ id: string }>();
let series: Series = library.fetchSeries(id!)!;

Check warning on line 49 in src/components/library/SeriesDetails.tsx

View workflow job for this annotation

GitHub Actions / build (18, macos-latest)

Forbidden non-null assertion

Check warning on line 49 in src/components/library/SeriesDetails.tsx

View workflow job for this annotation

GitHub Actions / build (18, macos-latest)

Forbidden non-null assertion
const seriesArr: Series[] = new Array(1);

const location = useLocation();
const setExtensionMetadata = useSetRecoilState(currentExtensionMetadataState);
Expand All @@ -47,10 +61,17 @@
const setSeriesBannerUrl = useSetRecoilState(seriesBannerUrlState);
const setChapterFilterTitle = useSetRecoilState(chapterFilterTitleState);
const setChapterFilterGroup = useSetRecoilState(chapterFilterGroupState);

const customDownloadsDir = useRecoilValue(customDownloadsDirState);
const OnStartUpDownloadUnreadCount = useRecoilValue(OnStartDownloadUnreadCountState);
const OnSeriesDetailsDownloadUnread = useRecoilValue(OnSeriesDetailsDownloadUnreadState);
const OnSeriesDetailsDeleteRead = useRecoilValue(OnSeriesDetailsDeleteReadState);
const chapterLanguages = useRecoilValue(chapterLanguagesState);

const loadContent = async () => {
log.info(`Series page is loading details from database for series ${id}`);

series = library.fetchSeries(id!)!;

Check warning on line 74 in src/components/library/SeriesDetails.tsx

View workflow job for this annotation

GitHub Actions / build (18, macos-latest)

Forbidden non-null assertion

Check warning on line 74 in src/components/library/SeriesDetails.tsx

View workflow job for this annotation

GitHub Actions / build (18, macos-latest)

Forbidden non-null assertion
setSeries(series);
setChapterList(library.fetchChapters(id!));

Expand All @@ -70,6 +91,19 @@

useEffect(() => {
loadContent();
seriesArr[0] = series;
if (OnSeriesDetailsDeleteRead) {
DeleteReadChapters(seriesArr, customDownloadsDir || String(getDefaultDownloadDir()));
}
if (OnSeriesDetailsDownloadUnread) {
DownloadUnreadChapters(
seriesArr,
customDownloadsDir || String(getDefaultDownloadDir()),
chapterLanguages,
false,
OnStartUpDownloadUnreadCount
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id, seriesList]);

Expand Down
20 changes: 20 additions & 0 deletions src/components/reader/ReaderPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { updateTitlebarText } from '../../util/titlebar';
import * as libraryStates from '../../state/libraryStates';
import * as readerStates from '../../state/readerStates';
import * as settingStates from '../../state/settingStates';
import { DownloadUnreadChapters } from '../../features/library/chapterDownloadUtils';
import { getDefaultDownloadDir } from '../settings/GeneralSettings';
import {
nextOffsetPages,
nextPageStyle,
Expand Down Expand Up @@ -99,6 +101,14 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
const keyToggleFullscreen = useRecoilValue(settingStates.keyToggleFullscreenState);
const keyExit = useRecoilValue(settingStates.keyExitState);
const keyCloseOrBack = useRecoilValue(settingStates.keyCloseOrBackState);
const OnStartUpDownloadUnreadCount = useRecoilValue(
settingStates.OnStartDownloadUnreadCountState
);
const OnScrollingChaptersDownloadUnread = useRecoilValue(
settingStates.OnScrollingChaptersDownloadUnreadState
);

const seriesArr: Series[] = new Array(1);

/**
* Populate the relevantChapterList prop.
Expand Down Expand Up @@ -281,6 +291,16 @@ const ReaderPage: React.FC<Props> = (props: Props) => {
if (newChapterId === null) return false;
const desiredPage = fromPageMovement && previous ? Infinity : 1;
setChapter(newChapterId, desiredPage);
seriesArr[0] = library.fetchSeries(series_id!)!;
if (OnScrollingChaptersDownloadUnread) {
DownloadUnreadChapters(
seriesArr,
customDownloadsDir || String(getDefaultDownloadDir()),
chapterLanguages,
false,
OnStartUpDownloadUnreadCount
);
}
return true;
};

Expand Down
127 changes: 126 additions & 1 deletion src/components/settings/GeneralSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { Language, LanguageKey, Languages } from '@tiyo/common';
import { ipcRenderer } from 'electron';
import { useRecoilState } from 'recoil';
Expand All @@ -13,6 +13,7 @@ import {
Stack,
Text,
Tooltip,
Accordion,
} from '@mantine/core';
import { IconArrowBack } from '@tabler/icons';
import { GeneralSetting } from '../../models/types';
Expand All @@ -27,6 +28,12 @@ import {
customDownloadsDirState,
libraryCropCoversState,
refreshOnStartState,
OnScrollingChaptersDownloadUnreadState,
OnSeriesDetailsDeleteReadState,
OnSeriesDetailsDownloadUnreadState,
OnStartDownloadUnreadCountState,
OnStartUpDeleteReadState,
OnStartUpDownloadUnreadState,
} from '../../state/settingStates';

const languageOptions = Object.values(Languages)
Expand All @@ -48,6 +55,24 @@ const GeneralSettings: React.FC<Props> = () => {
const [libraryCropCovers, setLibraryCropCovers] = useRecoilState(libraryCropCoversState);
const [customDownloadsDir, setCustomDownloadsDir] = useRecoilState(customDownloadsDirState);

const [OnStartUpDownloadUnread, setOnStartUpDownloadUnread] = useRecoilState(
OnStartUpDownloadUnreadState
);
const [OnSeriesDetailsDownloadUnread, setOnSeriesDetailsDownloadUnread] = useRecoilState(
OnSeriesDetailsDownloadUnreadState
);
const [OnScrollingChaptersDownloadUnread, setOnScrollingChaptersDownloadUnread] = useRecoilState(
OnScrollingChaptersDownloadUnreadState
);
const [OnSeriesDetailsDeleteRead, setOnSeriesDetailsDeleteRead] = useRecoilState(
OnSeriesDetailsDeleteReadState
);
const [OnStartUpDeleteRead, setOnStartUpDeleteRead] = useRecoilState(OnStartUpDeleteReadState);
const [OnStartDownloadUnreadCount, setOnStartDownloadUnreadCount] = useRecoilState(
OnStartDownloadUnreadCountState
);
const [automation, setautomation] = useState<string[]>([]);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateGeneralSetting = (generalSetting: GeneralSetting, value: any) => {
switch (generalSetting) {
Expand Down Expand Up @@ -75,6 +100,24 @@ const GeneralSettings: React.FC<Props> = () => {
case GeneralSetting.autoBackupCount:
setAutoBackupCount(value);
break;
case GeneralSetting.OnStartUpDownloadUnread:
setOnStartUpDownloadUnread(value);
break;
case GeneralSetting.OnStartUpDeleteRead:
setOnStartUpDeleteRead(value);
break;
case GeneralSetting.OnStartUpDownloadUnreadCount:
setOnStartDownloadUnreadCount(value);
break;
case GeneralSetting.OnSeriesDetailsDownloadUnread:
setOnSeriesDetailsDownloadUnread(value);
break;
case GeneralSetting.OnSeriesDetailsDeleteRead:
setOnSeriesDetailsDeleteRead(value);
break;
case GeneralSetting.OnScrollingChaptersDownloadUnread:
setOnScrollingChaptersDownloadUnread(value);
break;
default:
break;
}
Expand Down Expand Up @@ -208,8 +251,90 @@ const GeneralSettings: React.FC<Props> = () => {
</Group>
</Flex>
</Stack>

<Text>Automation</Text>
<Accordion multiple value={automation} onChange={setautomation}>
<Accordion.Item value="download">
<Accordion.Control>Auto Download</Accordion.Control>
<Accordion.Panel>
<Stack py="xs" ml="md" spacing={4}>
<Checkbox
label="Download unread chapters upon startup"
size="md"
checked={OnStartUpDownloadUnread}
onChange={(e) =>
updateGeneralSetting(GeneralSetting.OnStartUpDownloadUnread, e.target.checked)
}
/>
<Checkbox
label="Download unread chapters upon loading specific manga details page"
size="md"
checked={OnSeriesDetailsDownloadUnread}
onChange={(e) =>
updateGeneralSetting(
GeneralSetting.OnSeriesDetailsDownloadUnread,
e.target.checked
)
}
/>
<Checkbox
label="Download unread chapters upon scrolling between chapters"
size="md"
checked={OnScrollingChaptersDownloadUnread}
onChange={(e) =>
updateGeneralSetting(
GeneralSetting.OnScrollingChaptersDownloadUnread,
e.target.checked
)
}
/>
<Text>how many unread chapters to keep downloaded</Text>
<NumberInput
disabled={
!OnStartUpDownloadUnread &&
!OnSeriesDetailsDownloadUnread &&
!OnScrollingChaptersDownloadUnread
}
min={1}
value={OnStartDownloadUnreadCount}
onChange={(value) =>
updateGeneralSetting(GeneralSetting.OnStartUpDownloadUnreadCount, value)
}
/>
<br />
</Stack>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="delete">
<Accordion.Control>Auto Delete</Accordion.Control>
<Accordion.Panel>
<Stack py="xs" ml="md" spacing={4}>
<Checkbox
label="Delete read chapters upon startup"
size="md"
checked={OnStartUpDeleteRead}
onChange={(e) =>
updateGeneralSetting(GeneralSetting.OnStartUpDeleteRead, e.target.checked)
}
/>
<Checkbox
label="Delete read chapters upon loading specific manga details page"
size="md"
checked={OnSeriesDetailsDeleteRead}
onChange={(e) =>
updateGeneralSetting(GeneralSetting.OnSeriesDetailsDeleteRead, e.target.checked)
}
/>
</Stack>
</Accordion.Panel>
</Accordion.Item>
</Accordion>
</>
);
};

export default GeneralSettings;

export async function getDefaultDownloadDir(): Promise<any> {
return ipcRenderer.invoke(ipcChannels.GET_PATH.DEFAULT_DOWNLOADS_DIR);
}
Loading
Loading