diff --git a/android/app/build.gradle b/android/app/build.gradle index 33f1a13..326f973 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -109,6 +109,7 @@ dependencies { implementation("com.facebook.react:react-android") implementation("com.facebook.react:flipper-integration") implementation project(':react-native-fs') + implementation 'org.jsoup:jsoup:1.17.2' if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") diff --git a/android/app/src/main/java/com/novelscraper/MainApplication.kt b/android/app/src/main/java/com/novelscraper/MainApplication.kt index e28787a..7de7158 100644 --- a/android/app/src/main/java/com/novelscraper/MainApplication.kt +++ b/android/app/src/main/java/com/novelscraper/MainApplication.kt @@ -22,6 +22,7 @@ class MainApplication : Application(), ReactApplication { // Packages that cannot be autolinked yet can be added manually here, for example: // add(MyReactNativePackage()) // add(RNFSPackage()) + add(NovelScraperPackage()) } override fun getJSMainModuleName(): String = "index" diff --git a/android/app/src/main/java/com/novelscraper/NovelScraperPackage.java b/android/app/src/main/java/com/novelscraper/NovelScraperPackage.java new file mode 100644 index 0000000..a46d360 --- /dev/null +++ b/android/app/src/main/java/com/novelscraper/NovelScraperPackage.java @@ -0,0 +1,28 @@ +package com.novelscraper; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class NovelScraperPackage implements ReactPackage { + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @Override + public List createNativeModules( + ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + + modules.add(new ScraperModule(reactContext)); + + return modules; + } + +} diff --git a/android/app/src/main/java/com/novelscraper/ScraperModule.java b/android/app/src/main/java/com/novelscraper/ScraperModule.java new file mode 100644 index 0000000..44ae775 --- /dev/null +++ b/android/app/src/main/java/com/novelscraper/ScraperModule.java @@ -0,0 +1,102 @@ +package com.novelscraper; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.Arguments; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; + +public class ScraperModule extends ReactContextBaseJavaModule { + private int listenerCount = 0; + + ScraperModule(ReactApplicationContext context) { + super(context); + } + + @ReactMethod + public void getNovelPaginationPages(String pagePrefixURL, double startPage, double totalPages, Callback callback) { + try { + WritableArray novelPaginationPages = Arguments.createArray(); + for (int i = (int)startPage; i <= (int)totalPages; i++) { + Document doc = Jsoup + .connect(pagePrefixURL + i) + .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") + .header("Accept-Language", "*") + .get(); + novelPaginationPages.pushString(doc.html()); + } + callback.invoke(null, novelPaginationPages); + } catch (IOException e) { + Log.d("ERROR", e.toString()); + callback.invoke(e, null); + } + } + + @ReactMethod + public void getNovelChapterPages(ReadableArray chapterLinks, Callback callback) { + try { + WritableArray novelChapterPages = Arguments.createArray(); + for (int i = 0; i < chapterLinks.size(); i++) { + Log.d("INFO", "Downloading: " + chapterLinks.getString(i)); + Document doc = Jsoup + .connect(chapterLinks.getString(i)) + .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") + .header("Accept-Language", "*") + .get(); + novelChapterPages.pushString(doc.html()); + } + callback.invoke(null, novelChapterPages); + } catch (IOException e) { + Log.d("ERROR", e.toString()); + callback.invoke(e, null); + } + } + + private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) { + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, params); + } + + @ReactMethod + public void addListener(String eventName) { + if (listenerCount == 0) { + // Set up any upstream listeners or background tasks as necessary + } + + listenerCount += 1; + } + + @ReactMethod + public void removeListeners(Integer count) { + listenerCount -= count; + if (listenerCount == 0) { + // Remove upstream listeners, stop unnecessary background tasks + } + } + + @Override + public String getName() { + return "ScraperModule"; + } +} diff --git a/android/gradle.properties b/android/gradle.properties index a46a5b9..067c7a0 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -39,3 +39,5 @@ newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true + +org.gradle.daemon=true diff --git a/babel.config.js b/babel.config.js index 7f8c7d0..251c80c 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,4 +1,17 @@ -module.exports = { - presets: ["module:@react-native/babel-preset"], - plugins: ["transform-remove-console"] -}; +module.exports = function (api) { + api.cache(false); + + const presets = ["module:@react-native/babel-preset"]; + const plugins = []; + + console.log("NODE_ENV", process.env["NODE_ENV"]) + if (!!process.env["NODE_ENV"] && process.env["NODE_ENV"] !== "development") { + console.log("NOT IN DEV") + plugins.push("transform-remove-console"); + } + + return { + presets, + plugins + } +} diff --git a/src/lib/sources/sources.ts b/src/lib/sources/sources.ts index d4c5b1f..0b332e3 100644 --- a/src/lib/sources/sources.ts +++ b/src/lib/sources/sources.ts @@ -1,4 +1,22 @@ import { NovelT } from "../types"; +import { NativeModules } from "react-native"; +const { ScraperModule } = NativeModules; + +export const getNovelPaginationPages = ( + pagePrefixURL: string, + startPage: number, + totalPage: number, + callback: (error: any, novelPaginationPages: string[]) => void +) => { + ScraperModule.getNovelPaginationPages(pagePrefixURL, startPage, totalPage, callback) +} + +export const getNovelChapterPages = ( + chapterLinks: string[], + callback: (error: any, novelPaginationPages: string[]) => void +) => { + ScraperModule.getNovelChapterPages(chapterLinks, callback); +} export const stripDatabaseInfoFromNovel = (novel: NovelT): NovelT => { let newNovel = { ...novel };