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

default language for browse source. #554

Merged
merged 16 commits into from
Feb 26, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
{
files: ['*.js', '*.jsx', '*.ts', '*.tsx'],
rules: {
'prettier/prettier': ['error', { 'endOfLine': 'auto' }],
'@typescript-eslint/no-shadow': ['warn'],
'no-shadow': 'off',
'no-undef': 'off',
Expand Down
6 changes: 4 additions & 2 deletions src/database/queries/CategoryQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ export const isCategoryNameDuplicate = (
tx.executeSql(
isCategoryNameDuplicateQuery,
[categoryName],
(txObj, { rows: { _array } }) =>
resolve(Boolean(_array[0]?.isDuplicate)),
(txObj, { rows }) => {
const { _array } = rows as any;
resolve(Boolean(_array[0]?.isDuplicate));
},
txnErrorCallback,
);
}),
Expand Down
59 changes: 41 additions & 18 deletions src/database/queries/ChapterQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ChapterItem } from '../types';
import * as cheerio from 'cheerio';
import RNFetchBlob from 'rn-fetch-blob';
import { txnErrorCallback } from '@database/utils/helpers';
import { LoadingImageSrc } from '@screens/reader/utils/LoadImage';

const db = SQLite.openDatabase('lnreader.db');

Expand Down Expand Up @@ -243,13 +244,15 @@ const createImageFolder = async (
},
): Promise<string> => {
const mkdirIfNot = async (p: string) => {
const nomediaPath =
p + (p.charAt(p.length - 1) === '/' ? '' : '/') + '.nomedia';
if (!(await RNFetchBlob.fs.exists(p))) {
await RNFetchBlob.fs.mkdir(p);
await RNFetchBlob.fs.createFile(nomediaPath, ',', 'utf8');
}
};

await mkdirIfNot(path);
await RNFetchBlob.fs.createFile(path, '.nomedia', 'utf8');

if (data) {
const { sourceId, novelId, chapterId } = data;
Expand All @@ -269,31 +272,55 @@ const downloadImages = async (
chapterId: number,
): Promise<string> => {
try {
const headers = sourceManager(sourceId)?.headers || {};
const loadedCheerio = cheerio.load(html);
const imgs = loadedCheerio('img').toArray();
for (let i = 0; i < imgs.length; i++) {
const elem = loadedCheerio(imgs[i]);
const url = elem.attr('src');
if (url) {
const imageb64 = (await RNFetchBlob.fetch('GET', url)).base64();
const imageb64 = (
await RNFetchBlob.fetch('GET', url, headers)
).base64();
const fileurl =
(await createImageFolder(
`${RNFetchBlob.fs.dirs.DownloadDir}/LNReader`,
{ sourceId, novelId, chapterId },
)) +
).catch(() => {
showToast(
`Unexpected storage error!\nRemove ${fileurl} and try downloading again`,
);
return '--';
})) +
i +
'.b64.png';
if (fileurl.charAt(0) === '-') {
return loadedCheerio.html();
}
elem.replaceWith(
`<img type="file" src="${url}" file-src="${fileurl}" file-id="${i}">`,
`<img class='load-icon' src="${LoadingImageSrc}" file-path="${fileurl}">`,
);
const exists = await RNFetchBlob.fs.exists(fileurl);
const exists = await RNFetchBlob.fs.exists(fileurl).catch(() => {
showToast(
`Unexpected storage error!\nRemove ${fileurl} and try downloading again`,
);
});
if (!exists) {
RNFetchBlob.fs.createFile(fileurl, imageb64, 'utf8');
RNFetchBlob.fs.createFile(fileurl, imageb64, 'base64').catch(() => {
showToast(
`Unexpected storage error!\nRemove ${fileurl} and try downloading again`,
);
});
} else {
RNFetchBlob.fs.writeFile(fileurl, imageb64, 'utf8');
RNFetchBlob.fs.writeFile(fileurl, imageb64, 'base64').catch(() => {
showToast(
`Unexpected storage error!\nRemove ${fileurl} and try downloading again`,
);
});
}
}
}
loadedCheerio('body').prepend("<input type='hidden' offline />");
return loadedCheerio.html();
} catch (e) {
return html;
Expand Down Expand Up @@ -350,20 +377,16 @@ const deleteDownloadedImages = async (
chapterId: number,
) => {
try {
const path = `${RNFetchBlob.fs.dirs.DownloadDir}/LNReader/`;
const files = await RNFetchBlob.fs.ls(
await createImageFolder(path, { sourceId, novelId, chapterId }),
const path = await createImageFolder(
`${RNFetchBlob.fs.dirs.DownloadDir}/LNReader`,
{ sourceId, novelId, chapterId },
);
const files = await RNFetchBlob.fs.ls(path);
for (let i = 0; i < files.length; i++) {
const ex = /(.*?)_(.*?)#(.*?)/.exec(files[i]);
const ex = /\.b64\.png/.exec(files[i]);
if (ex) {
if (
parseInt(ex[1], 10) === sourceId &&
parseInt(ex[2], 10) === chapterId
) {
if (await RNFetchBlob.fs.exists(`${path}${files[i]}`)) {
RNFetchBlob.fs.unlink(`${path}${files[i]}`);
}
if (await RNFetchBlob.fs.exists(`${path}${files[i]}`)) {
RNFetchBlob.fs.unlink(`${path}${files[i]}`);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/database/queries/DownloadQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ export const getChapterFromDb = async (
getChapterFromDbQuery,
[chapterId],
(txObj, results) => resolve(results.rows.item(0)),
(txObj, error) => reject(error),
(_, error) => {
reject(error);
return false;
},
);
}),
);
Expand Down
28 changes: 27 additions & 1 deletion src/redux/source/sourcesSlice.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import AllSources from '../../sources/sources.json';

import { translations } from 'i18n-js';
import { localization } from '../../../strings/translations';
import { Source } from '../../sources/types';

const languages = {
'en': 'English',
'es': 'Spanish',
'tr': 'Turkish',
'ru': 'Russian',
'ar': 'Arabic',
'uk': 'Ukrainian',
'pt': 'Portuguese',
'pt-BR': 'Portuguese',
'de': 'German',
'it': 'Italian',
'zh-CN': 'Chinese',
'zh-TW': 'Chinese',
'vi': 'Vietnamese',
'ja': 'Japanese',
};
// Hope you can do something to synchronize translation system.
// Also take care of some case like vi-VN: Vietnamese not vi
export const defaultLanguage =
localization in translations || localization.split('-')[0] in translations
? languages[localization] || languages[localization.split('-')[0]]
: 'English';
// That's why this code is so long :(

interface SourcesState {
allSources: Source[];
searchResults: Source[];
Expand All @@ -16,7 +42,7 @@ const initialState: SourcesState = {
searchResults: [],
pinnedSourceIds: [],
lastUsed: null,
languageFilters: ['English'],
languageFilters: [defaultLanguage],
};

export const sourcesSlice = createSlice({
Expand Down
3 changes: 2 additions & 1 deletion src/screens/browse/BrowseScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useMemo } from 'react';

import { EmptyView, SearchbarV2 } from '../../components';
import {
defaultLanguage,
getSourcesAction,
searchSourcesAction,
setLastUsedSource,
Expand Down Expand Up @@ -42,7 +43,7 @@ const BrowseScreen = () => {
allSources,
searchResults,
pinnedSourceIds = [],
languageFilters = ['English'],
languageFilters = [defaultLanguage || 'English'], //defaultLang cant be null, but just for sure
lastUsed,
} = useSourcesReducer();

Expand Down
4 changes: 1 addition & 3 deletions src/screens/novel/NovelScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ const Novel = ({ route, navigation }) => {

const [jumpToChapterModal, showJumpToChapterModal] = useState(false);

const keyExtractor = useCallback(i => i.chapterId.toString(), []);

const downloadChapter = (chapterUrl, chapterName, chapterId) =>
dispatch(
downloadChapterAction(
Expand Down Expand Up @@ -585,12 +583,12 @@ const Novel = ({ route, navigation }) => {
estimatedItemSize={64}
data={!loading && chapters}
extraData={[downloadQueue, selected]}
keyExtractor={keyExtractor}
removeClippedSubviews={true}
maxToRenderPerBatch={5}
windowSize={15}
initialNumToRender={7}
renderItem={renderItem}
keyExtractor={(item, index) => 'chapter' + index}
contentContainerStyle={{ paddingBottom: 100 }}
ListHeaderComponent={
<NovelInfoHeader
Expand Down
2 changes: 1 addition & 1 deletion src/screens/novel/components/Info/NovelInfoComponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ const NovelGenres = ({ theme, genre }) => {
contentContainerStyle={styles.genreContainer}
horizontal
data={data}
keyExtractor={item => item}
keyExtractor={(item, index) => 'genre' + index}
renderItem={renderItem}
showsHorizontalScrollIndicator={false}
/>
Expand Down
19 changes: 10 additions & 9 deletions src/screens/reader/ReaderScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,22 +264,22 @@ const ChapterContent = ({ route, navigation }) => {
};

const navigateToChapterBySwipe = name => {
let chapter;
let navChapter;
if (name === 'SWIPE_LEFT') {
chapter = nextChapter;
navChapter = nextChapter;
} else if (name === 'SWIPE_RIGHT') {
chapter = prevChapter;
navChapter = prevChapter;
} else {
return;
}
// you can add more condition for friendly usage. for example: if(name === "SWIPE_LEFT" || name === "right")
chapter
navChapter
? navigation.replace('Chapter', {
...params,
chapterUrl: chapter.chapterUrl,
chapterId: chapter.chapterId,
chapterName: chapter.chapterName,
bookmark: chapter.bookmark,
chapterUrl: navChapter.chapterUrl,
chapterId: navChapter.chapterId,
chapterName: navChapter.chapterName,
bookmark: navChapter.bookmark,
})
: showToast(
name === 'SWIPE_LEFT'
Expand All @@ -299,6 +299,7 @@ const ChapterContent = ({ route, navigation }) => {

const chapterText = sanitizeChapterText(chapter.chapterText, {
removeExtraParagraphSpacing,
sourceId: sourceId,
});
const openDrawer = () => {
navigation.openDrawer();
Expand All @@ -316,7 +317,7 @@ const ChapterContent = ({ route, navigation }) => {
return (
<>
<WebViewReader
chapter={chapter}
chapterInfo={params}
html={chapterText}
chapterName={chapter.chapterName || chapterName}
swipeGestures={swipeGestures}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ const ReaderBottomSheetV2: React.FC<ReaderBottomSheetV2Props> = ({
const backgroundColor = tabHeaderColor;

const renderScene = SceneMap({
first: ReaderTab,
second: GeneralTab,
'readerTab': ReaderTab,
'generalTab': GeneralTab,
});

const layout = useWindowDimensions();
Expand All @@ -145,11 +145,11 @@ const ReaderBottomSheetV2: React.FC<ReaderBottomSheetV2Props> = ({
const routes = useMemo(
() => [
{
key: 'first',
key: 'readerTab',
title: getString('moreScreen.settingsScreen.readerSettings.title'),
},
{
key: 'second',
key: 'generalTab',
title: getString('moreScreen.settingsScreen.generalSettings'),
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const ReaderFontPicker = () => {
<FlatList
data={readerFonts}
renderItem={FontChipItem}
keyExtractor={(item, index) => 'font' + index}
horizontal={true}
showsHorizontalScrollIndicator={false}
/>
Expand Down
Loading