Minor fixes
This commit is contained in:
@@ -10,7 +10,7 @@ const EmptyView = ({ icon, description, style, children, iconStyle }) => {
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyViewIcon,
|
||||
{ color: theme.textColorSecondary },
|
||||
{ color: theme.textColorHint },
|
||||
style,
|
||||
iconStyle,
|
||||
]}
|
||||
@@ -20,7 +20,7 @@ const EmptyView = ({ icon, description, style, children, iconStyle }) => {
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyViewText,
|
||||
{ color: theme.textColorSecondary },
|
||||
{ color: theme.textColorHint },
|
||||
style,
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -17,7 +17,7 @@ const ErrorView = ({ theme, onRetry, error, openWebView }) => (
|
||||
icon="reload"
|
||||
size={25}
|
||||
style={{ margin: 0, marginTop: 24 }}
|
||||
color={theme.textColorSecondary}
|
||||
color={theme.text}
|
||||
onPress={onRetry}
|
||||
/>
|
||||
<Text style={{ color: theme.textColorPrimary }}>Retry</Text>
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
irisBlueTheme,
|
||||
hotPinkTheme,
|
||||
strawberryDaiquiri,
|
||||
palenightTheme,
|
||||
} from "../../theme/theme";
|
||||
import { setRippleColor } from "./settings.actions";
|
||||
|
||||
@@ -27,6 +28,7 @@ const themes = {
|
||||
5: irisBlueTheme,
|
||||
6: hotPinkTheme,
|
||||
7: strawberryDaiquiri,
|
||||
8: palenightTheme,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -224,13 +224,10 @@ const Chapter = ({ route, navigation }) => {
|
||||
|
||||
const readerStyles = [
|
||||
{
|
||||
paddingVertical: 16,
|
||||
paddingBottom: 32,
|
||||
fontSize: reader.textSize,
|
||||
color: reader.textColor || readerTextColor(reader.theme),
|
||||
lineHeight: readerLineHeight(reader.textSize, reader.lineHeight),
|
||||
textAlign: reader.textAlign,
|
||||
paddingHorizontal: `${reader.padding}%`,
|
||||
},
|
||||
reader.fontFamily && {
|
||||
fontFamily: reader.fontFamily,
|
||||
@@ -296,11 +293,9 @@ const Chapter = ({ route, navigation }) => {
|
||||
{error ? (
|
||||
<View style={{ flex: 1, justifyContent: "center" }}>
|
||||
<EmptyView
|
||||
icon="(-_-;)・・・"
|
||||
icon="Σ(ಠ_ಠ)"
|
||||
description={error}
|
||||
style={{
|
||||
color: errorTextColor(reader.theme),
|
||||
}}
|
||||
style={{ color: errorTextColor(reader.theme) }}
|
||||
>
|
||||
<IconButton
|
||||
icon="reload"
|
||||
@@ -339,31 +334,68 @@ const Chapter = ({ route, navigation }) => {
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
<Pressable
|
||||
style={{ flex: 1 }}
|
||||
style={{
|
||||
flex: 1,
|
||||
paddingVertical: 16,
|
||||
paddingBottom: 32,
|
||||
paddingHorizontal: `${reader.padding}%`,
|
||||
}}
|
||||
onLayout={scrollToSavedProgress}
|
||||
onPress={hideHeader}
|
||||
>
|
||||
{chapter.chapterText
|
||||
.split(/(\[https.*?\])/g)
|
||||
.trim()
|
||||
.split(/(\[https.*?\])|(_.*?_)/g)
|
||||
.map((part, index) => {
|
||||
if (part.match(/\[https.*?\]/)) {
|
||||
return (
|
||||
<FitImage
|
||||
source={{
|
||||
uri: part.slice(1, -1),
|
||||
}}
|
||||
key={index}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Text
|
||||
style={readerStyles}
|
||||
selectable={textSelectable}
|
||||
>
|
||||
{part}
|
||||
</Text>
|
||||
);
|
||||
if (part) {
|
||||
const isItalic =
|
||||
part.match(/_(.*?)_/);
|
||||
const isImage =
|
||||
part.match(/\[https.*?\]/);
|
||||
|
||||
if (isImage) {
|
||||
return (
|
||||
<FitImage
|
||||
source={{
|
||||
uri: part.slice(
|
||||
1,
|
||||
-1
|
||||
),
|
||||
}}
|
||||
key={index}
|
||||
/>
|
||||
);
|
||||
} else if (isItalic) {
|
||||
return (
|
||||
<Text
|
||||
style={[
|
||||
readerStyles,
|
||||
{
|
||||
fontStyle:
|
||||
"italic",
|
||||
},
|
||||
]}
|
||||
selectable={
|
||||
textSelectable
|
||||
}
|
||||
key={index}
|
||||
>
|
||||
{isItalic[1]}
|
||||
</Text>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Text
|
||||
style={readerStyles}
|
||||
selectable={
|
||||
textSelectable
|
||||
}
|
||||
key={index}
|
||||
>
|
||||
{part}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
}
|
||||
})}
|
||||
</Pressable>
|
||||
|
||||
@@ -87,6 +87,7 @@ const History = ({ navigation }) => {
|
||||
]}
|
||||
/>
|
||||
<FlatList
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
data={searchText ? searchResults : history}
|
||||
keyExtractor={(item, index) => item.date}
|
||||
renderItem={({ item }) => (
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { FlatList, View, Text, StyleSheet } from "react-native";
|
||||
import { FAB, ProgressBar } from "react-native-paper";
|
||||
import {
|
||||
FAB,
|
||||
ProgressBar,
|
||||
Appbar as MaterialAppbar,
|
||||
Menu,
|
||||
} from "react-native-paper";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { Appbar } from "../../components/Appbar";
|
||||
@@ -17,6 +22,7 @@ import {
|
||||
|
||||
import BackgroundService from "react-native-background-actions";
|
||||
import { downloadAllChaptersAction } from "../../redux/novel/novel.actions";
|
||||
import { showToast } from "../../hooks/showToast";
|
||||
|
||||
const DownloadQueue = ({ navigation }) => {
|
||||
const theme = useTheme();
|
||||
@@ -24,6 +30,10 @@ const DownloadQueue = ({ navigation }) => {
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
const openMenu = () => setVisible(true);
|
||||
const closeMenu = () => setVisible(false);
|
||||
|
||||
useEffect(() => {
|
||||
// if (!BackgroundService.isRunning() && downloadQueue.length > 0) {
|
||||
// dispatch(cancelDownload());
|
||||
@@ -35,7 +45,31 @@ const DownloadQueue = ({ navigation }) => {
|
||||
|
||||
return (
|
||||
<ScreenContainer theme={theme}>
|
||||
<Appbar title="Download queue" onBackAction={navigation.goBack} />
|
||||
<Appbar title="Download queue" onBackAction={navigation.goBack}>
|
||||
<Menu
|
||||
visible={visible}
|
||||
onDismiss={closeMenu}
|
||||
anchor={
|
||||
<MaterialAppbar.Action
|
||||
icon="dots-vertical"
|
||||
color={theme.textColorPrimary}
|
||||
onPress={openMenu}
|
||||
/>
|
||||
}
|
||||
contentStyle={{ backgroundColor: theme.menuColor }}
|
||||
>
|
||||
<Menu.Item
|
||||
onPress={() => {
|
||||
dispatch(cancelDownload());
|
||||
showToast("Downloads cancelled.");
|
||||
BackgroundService.stop();
|
||||
closeMenu();
|
||||
}}
|
||||
title="Cancel downloads"
|
||||
titleStyle={{ color: theme.textColorPrimary }}
|
||||
/>
|
||||
</Menu>
|
||||
</Appbar>
|
||||
<FlatList
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
keyExtractor={(item) => item.chapterId.toString()}
|
||||
@@ -46,7 +80,10 @@ const DownloadQueue = ({ navigation }) => {
|
||||
{item.chapterName}
|
||||
</Text>
|
||||
<ProgressBar
|
||||
indeterminate={true}
|
||||
indeterminate={
|
||||
BackgroundService.isRunning() ? true : false
|
||||
}
|
||||
progress={!BackgroundService.isRunning() && 0}
|
||||
color={theme.colorAccent}
|
||||
style={{ marginTop: 8 }}
|
||||
/>
|
||||
|
||||
@@ -14,7 +14,7 @@ let headers = new Headers({
|
||||
|
||||
const popularNovels = async (page) => {
|
||||
const totalPages = 100;
|
||||
let url = `${baseUrl}series-ranking/?rank=sixmonths&pg=` + page;
|
||||
let url = `${baseUrl}series-ranking/?rank=week&pg=` + page;
|
||||
|
||||
const result = await fetch(url, {
|
||||
method: "GET",
|
||||
@@ -123,61 +123,93 @@ const parseNovelAndChapters = async (novelUrl) => {
|
||||
const parseChapter = async (novelUrl, chapterUrl) => {
|
||||
const url = chapterUrl;
|
||||
|
||||
const result = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: headers,
|
||||
});
|
||||
let body = await result.text();
|
||||
// console.log("Original URL: ", url);
|
||||
|
||||
let result, body;
|
||||
|
||||
try {
|
||||
result = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: headers,
|
||||
});
|
||||
body = await result.text();
|
||||
} catch (error) {
|
||||
chapterText =
|
||||
"Chapter not available.\n\nReport if it's available in webview.";
|
||||
}
|
||||
|
||||
// console.log("Redirected URL: ", result.url);
|
||||
|
||||
$ = cheerio.load(body);
|
||||
|
||||
let chapterName = "";
|
||||
|
||||
let isWuxiaWorld = $('meta[name="application-name"]').attr("content");
|
||||
isWuxiaWorld =
|
||||
isWuxiaWorld && isWuxiaWorld.includes("Wuxiaworld") ? true : false;
|
||||
let isWuxiaWorld = result.url.toLowerCase().includes("wuxiaworld");
|
||||
|
||||
/**
|
||||
* Checks if its a wwordpress site
|
||||
*/
|
||||
let isWordPress = $('meta[name="generator"]').attr("content");
|
||||
let isWordPress =
|
||||
$('meta[name="generator"]').attr("content") || $("footer").text();
|
||||
|
||||
if (isWordPress) {
|
||||
isWordPress =
|
||||
isWordPress.toLowerCase().includes("wordpress") ||
|
||||
isWordPress.toLowerCase().includes("Site Kit by Google 1.36.0") ||
|
||||
$(".powered-by").text().toLowerCase().includes("wordpress")
|
||||
$(".powered-by").text().toLowerCase().includes("wordpress") ||
|
||||
$(".entry-content").html() ||
|
||||
$("section.content").html()
|
||||
? true
|
||||
: false;
|
||||
|
||||
// console.log(isWordPress);
|
||||
}
|
||||
|
||||
let isWebNovel =
|
||||
$("header > a").attr("alt") === "Webnovel.com" ? true : false;
|
||||
let isWebNovel = result.url.toLowerCase().includes("webnovel");
|
||||
|
||||
if (isWuxiaWorld) {
|
||||
chapterText = $("#chapter-content").html();
|
||||
} else if (isWordPress) {
|
||||
/**
|
||||
* Remove wordpress bloat tags
|
||||
*/
|
||||
$(".c-ads").remove();
|
||||
$("#madara-comments").remove();
|
||||
$(".sharedaddy").remove();
|
||||
|
||||
chapterText = $(".entry-content").html();
|
||||
|
||||
if (!chapterText) {
|
||||
chapterText = $("#chp_raw").html();
|
||||
chapterText = $("section.content").html();
|
||||
}
|
||||
|
||||
if (!chapterText) {
|
||||
chapterText = $(".single_post").html();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format anchor tags properly Eg. [title](https://www.example.com)
|
||||
*/
|
||||
// .replace(
|
||||
// /<\s*a[^>]*href=['"](.*?)['"][^>]*>([\s\S]*?)<\/\s*a\s*>/gi,
|
||||
// "[$2]($1)"
|
||||
// );
|
||||
} else if (isWebNovel) {
|
||||
chapterText = $(".cha-words").html();
|
||||
} else {
|
||||
/**
|
||||
* Tags and classes to remove
|
||||
* Remove unnecessary tags
|
||||
*/
|
||||
const tags = ["nav", "footer"];
|
||||
const tags = ["nav", "header", "footer", ".hidden"];
|
||||
|
||||
tags.map((tag) => $(tag).remove());
|
||||
|
||||
chapterText = $("body").html();
|
||||
}
|
||||
|
||||
chapterText = htmlToText(chapterText);
|
||||
if (!chapterText) {
|
||||
chapterText =
|
||||
"Chapter not available.\n\nReport if it's available in webview.";
|
||||
}
|
||||
|
||||
chapterText = htmlToText(chapterText);
|
||||
|
||||
@@ -5,6 +5,7 @@ const htmlToText = (html, options = {}) => {
|
||||
text = html
|
||||
// Turn <br>'s into single line breaks.
|
||||
.replace(/<\s*br[^>]*>/gi, "\n")
|
||||
.replace(/<\s*hr[^>]*>/gi, `\n\n${"-".repeat(40)}\n\n`)
|
||||
// Turn </li>'s into line breaks.
|
||||
.replace(/<\s*\/li[^>]*>/gi, "\n")
|
||||
// Turn <p>'s into double line breaks.
|
||||
@@ -16,6 +17,13 @@ const htmlToText = (html, options = {}) => {
|
||||
// Remove content in comments.
|
||||
.replace(/<!--.*?-->/gim, "")
|
||||
// Format anchor tags properly.
|
||||
.replace(/<em>(.*?)<\/em>/gi, "_$1_")
|
||||
// .replace(
|
||||
// /<\s*h(\d)[^>]*>(.*?)<\/h(\d)>/gim,
|
||||
// `${"#".repeat("$1")}$2${"#".repeat("$1")}`
|
||||
// )
|
||||
// .replace(/<strong>(.*?)<\/strong>/gi, "*$1*")
|
||||
|
||||
.replace(
|
||||
/<\s*a[^>]*href=['"](.*?)['"][^>]*>([\s\S]*?)<\/\s*a\s*>/gi,
|
||||
"$2"
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ export const greenAppleTheme = {
|
||||
filterColor: "#FFEB3B",
|
||||
dividerColor: "rgba(255,255,255,0.1)",
|
||||
colorDisabled: "rgba(57,57,57,255)",
|
||||
colorButtonText: "#FFFFFF",
|
||||
colorButtonText: "#000000",
|
||||
statusBar: StatusBarStyle.LIGHT,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user