refactor: Remove Ununsed Files and Dependencies

This commit is contained in:
Rajarshee Chatterjee
2022-05-07 14:44:42 +05:30
parent 4d30546b9a
commit b921f9b764
29 changed files with 18 additions and 1624 deletions
-1
View File
@@ -84,7 +84,6 @@ project.ext.react = [
apply from: '../../node_modules/react-native-unimodules/gradle.groovy'
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/expo-constants/scripts/get-app-config-android.gradle"
apply from: "../../node_modules/expo-updates/scripts/create-manifest-android.gradle"
/**
* Set this to true to create two separate APKs instead of one:
-20
View File
@@ -30,26 +30,6 @@
android:allowBackup="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<meta-data
android:name="expo.modules.updates.EXPO_UPDATE_URL"
android:value="https://exp.host/@rajarsheechatterjee/LNReader"/>
<meta-data
android:name="expo.modules.updates.EXPO_SDK_VERSION"
android:value="41.0.0"/>
<meta-data
android:name="expo.modules.updates.ENABLED"
android:value="false"/>
<meta-data
android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH"
android:value="ALWAYS"/>
<meta-data
android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS"
android:value="0"/>
<meta-data
android:name="expo.modules.notifications.default_notification_icon"
@@ -2,7 +2,6 @@ package com.rajarsheechatterjee.LNReader;
import android.app.Application;
import android.content.Context;
import android.net.Uri;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
@@ -21,7 +20,6 @@ import org.unimodules.core.interfaces.SingletonModule;
import expo.modules.constants.ConstantsPackage;
import expo.modules.permissions.PermissionsPackage;
import expo.modules.filesystem.FileSystemPackage;
import expo.modules.updates.UpdatesController;
import com.facebook.react.bridge.JSIModulePackage;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
@@ -29,7 +27,6 @@ import com.swmansion.reanimated.ReanimatedJSIModulePackage;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
public class MainApplication extends Application implements ReactApplication {
private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(
@@ -59,24 +56,6 @@ public class MainApplication extends Application implements ReactApplication {
protected JSIModulePackage getJSIModulePackage() {
return new ReanimatedJSIModulePackage();
}
@Override
protected @Nullable String getJSBundleFile() {
if (BuildConfig.DEBUG) {
return super.getJSBundleFile();
} else {
return UpdatesController.getInstance().getLaunchAssetFile();
}
}
@Override
protected @Nullable String getBundleAssetName() {
if (BuildConfig.DEBUG) {
return super.getBundleAssetName();
} else {
return UpdatesController.getInstance().getBundleAssetName();
}
}
};
@Override
@@ -89,10 +68,6 @@ public class MainApplication extends Application implements ReactApplication {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (!BuildConfig.DEBUG) {
UpdatesController.initialize(this);
}
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
@@ -22,7 +22,6 @@ public class BasePackageList {
new expo.modules.permissions.PermissionsPackage(),
new expo.modules.splashscreen.SplashScreenPackage(),
new expo.modules.sqlite.SQLitePackage(),
new expo.modules.updates.UpdatesPackage(),
new expo.modules.webbrowser.WebBrowserPackage()
);
}
+5 -219
View File
@@ -10,18 +10,15 @@
"dependencies": {
"@react-native-async-storage/async-storage": "^1.15.11",
"@react-native-community/masked-view": "^0.1.11",
"@react-native-community/netinfo": "^7.1.1",
"@react-native-community/slider": "^4.1.12",
"@react-navigation/material-bottom-tabs": "^6.0.9",
"@react-navigation/native": "^6.0.6",
"@react-navigation/stack": "^6.0.11",
"@reduxjs/toolkit": "^1.7.2",
"@types/react-native-vector-icons": "^6.4.10",
"cheerio": "^1.0.0-rc.10",
"expo": "^41.0.1",
"expo-document-picker": "^9.2.4",
"expo-file-system": "~11.0.2",
"expo-font": "~9.1.0",
"expo-haptics": "~10.0.0",
"expo-keep-awake": "~9.1.2",
"expo-linear-gradient": "~9.1.0",
@@ -30,7 +27,6 @@
"expo-notifications": "~0.11.6",
"expo-splash-screen": "^0.11.4",
"expo-sqlite": "~9.1.0",
"expo-updates": "~0.5.4",
"expo-web-browser": "~9.1.0",
"i18n-js": "^3.8.0",
"lodash": "^4.17.21",
@@ -51,18 +47,15 @@
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.9.0",
"react-native-skeleton-placeholder": "^5.0.0",
"react-native-swipe-gestures": "^1.0.5",
"react-native-tab-view": "^3.1.1",
"react-native-tts": "^4.1.0",
"react-native-unimodules": "^0.13.3",
"react-native-vector-icons": "^9.0.0",
"react-native-web": "^0.17.5",
"react-native-webview": "^11.14.3",
"react-redux": "^7.2.6",
"redux": "^4.1.2",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.4.0",
"rn-sliding-up-panel": "^2.4.4",
"sanitize-html": "^2.7.0"
},
@@ -73,6 +66,7 @@
"@types/jest": "^27.4.0",
"@types/lodash": "^4.14.179",
"@types/react-native": "^0.66.15",
"@types/react-native-vector-icons": "^6.4.10",
"@types/react-test-renderer": "^17.0.1",
"@types/sanitize-html": "^2.6.2",
"@typescript-eslint/eslint-plugin": "^5.10.2",
@@ -3781,14 +3775,6 @@
"react-native": ">=0.57"
}
},
"node_modules/@react-native-community/netinfo": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-7.1.1.tgz",
"integrity": "sha512-i8mSbp4JqIH0nEpHJGlVyr4Xb2/jtkK2YZbtiVU+gOih3FvhK2MzRLaEaDGr/DW8DTSKCo0QupUaiqrA3Lvcqg==",
"peerDependencies": {
"react-native": ">=0.59"
}
},
"node_modules/@react-native-community/slider": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-4.1.12.tgz",
@@ -4076,6 +4062,7 @@
"version": "0.66.15",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.66.15.tgz",
"integrity": "sha512-qNK3LZhNpSd2Hdr0OFdvQ/VOb1qcjNhmw96LsOtxIN+1RtXHO/1dVzxYUlWnKMCtV+E5WSaWM703c9Q7gG9tyg==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
@@ -4084,6 +4071,7 @@
"version": "6.4.10",
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.10.tgz",
"integrity": "sha512-z4sexbuZ7nmYsp7Z9YB5fSQoN3KFn6nZA3QsCkQLOYnVmVlxX4U22v/bM9Xx/6dOA1vClxoRZo2CFDX16uryXQ==",
"dev": true,
"dependencies": {
"@types/react": "*",
"@types/react-native": "*"
@@ -4864,14 +4852,6 @@
"resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
"integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
},
"node_modules/array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/array-includes": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
@@ -6192,15 +6172,6 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/create-react-class": {
"version": "15.7.0",
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz",
"integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==",
"dependencies": {
"loose-envify": "^1.3.1",
"object-assign": "^4.1.1"
}
},
"node_modules/cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@@ -6248,15 +6219,6 @@
"node": ">=4"
}
},
"node_modules/css-in-js-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
"integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==",
"dependencies": {
"hyphenate-style-name": "^1.0.2",
"isobject": "^3.0.1"
}
},
"node_modules/css-to-react-native": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
@@ -7754,24 +7716,6 @@
"lodash": "^4.17.15"
}
},
"node_modules/expo-structured-headers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/expo-structured-headers/-/expo-structured-headers-1.0.1.tgz",
"integrity": "sha512-U4frE8rT5x1LqZv5Ru/9CtzY8gh0wp1MfwTu5hetPydnwxXfWchuXvKgWRjEHglFU2X/29kYFY/J1UkPvCN8xg=="
},
"node_modules/expo-updates": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.5.5.tgz",
"integrity": "sha512-1R8EKkT3GoDjMRQnDaTYv31gIYIaYQGHOrjHJfwq8ai9f1W1AHux6KAH2/H6sc2o9a7roWVwjDn2kKwCm9AeHg==",
"dependencies": {
"@expo/config-plugins": "^1.0.18",
"@expo/metro-config": "^0.1.59",
"expo-structured-headers": "~1.0.1",
"fbemitter": "^2.1.1",
"resolve-from": "^5.0.0",
"uuid": "^3.4.0"
}
},
"node_modules/expo-web-browser": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-9.1.0.tgz",
@@ -8626,11 +8570,6 @@
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/hyphenate-style-name": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
},
"node_modules/i18n-js": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-3.8.0.tgz",
@@ -8751,14 +8690,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/inline-style-prefixer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz",
"integrity": "sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg==",
"dependencies": {
"css-in-js-utils": "^2.0.0"
}
},
"node_modules/internal-slot": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
@@ -11577,11 +11508,6 @@
"resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz",
"integrity": "sha1-XzPUfxPSFQ35PgywNmmemC94/78="
},
"node_modules/normalize-css-color": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/normalize-css-color/-/normalize-css-color-1.0.2.tgz",
"integrity": "sha1-Apkel8zOxmI/5XOvu/Deah8+n40="
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -12955,17 +12881,6 @@
"react": "^17.0.0"
}
},
"node_modules/react-native-skeleton-placeholder": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-skeleton-placeholder/-/react-native-skeleton-placeholder-5.0.0.tgz",
"integrity": "sha512-7sdG+Y2ENEVcxFC9XlpCgHy59XKkxaUyVqDwuAb66hvl7lwFr25uA5kHJ+JuDJ84ptVil5UEowW/2avwhsfoYg==",
"peerDependencies": {
"@react-native-masked-view/masked-view": "^0.2.3",
"react": ">=0.14.8",
"react-native": ">=0.50.1",
"react-native-linear-gradient": "^2.5.6"
}
},
"node_modules/react-native-swipe-gestures": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz",
@@ -13154,38 +13069,6 @@
"node": ">=10"
}
},
"node_modules/react-native-web": {
"version": "0.17.5",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.17.5.tgz",
"integrity": "sha512-pdieIZi2/YeVTaOuIaeaLC6FMkk8h3pvPNruedH+6cWiE15Oz6BGjJ+5IafdXEyiipb1Y0+QuecW81fa3DVM4g==",
"dependencies": {
"array-find-index": "^1.0.2",
"create-react-class": "^15.7.0",
"fbjs": "^3.0.0",
"hyphenate-style-name": "^1.0.4",
"inline-style-prefixer": "^6.0.0",
"normalize-css-color": "^1.0.2",
"prop-types": "^15.6.0"
},
"peerDependencies": {
"react": ">=17.0.1",
"react-dom": ">=17.0.1"
}
},
"node_modules/react-native-web/node_modules/fbjs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz",
"integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==",
"dependencies": {
"cross-fetch": "^3.0.4",
"fbjs-css-vars": "^1.0.0",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
"ua-parser-js": "^0.7.18"
}
},
"node_modules/react-native-webview": {
"version": "11.14.3",
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-11.14.3.tgz",
@@ -18933,11 +18816,6 @@
"resolved": "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.11.tgz",
"integrity": "sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw=="
},
"@react-native-community/netinfo": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-7.1.1.tgz",
"integrity": "sha512-i8mSbp4JqIH0nEpHJGlVyr4Xb2/jtkK2YZbtiVU+gOih3FvhK2MzRLaEaDGr/DW8DTSKCo0QupUaiqrA3Lvcqg=="
},
"@react-native-community/slider": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-4.1.12.tgz",
@@ -19175,6 +19053,7 @@
"version": "0.66.15",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.66.15.tgz",
"integrity": "sha512-qNK3LZhNpSd2Hdr0OFdvQ/VOb1qcjNhmw96LsOtxIN+1RtXHO/1dVzxYUlWnKMCtV+E5WSaWM703c9Q7gG9tyg==",
"dev": true,
"requires": {
"@types/react": "*"
}
@@ -19183,6 +19062,7 @@
"version": "6.4.10",
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.10.tgz",
"integrity": "sha512-z4sexbuZ7nmYsp7Z9YB5fSQoN3KFn6nZA3QsCkQLOYnVmVlxX4U22v/bM9Xx/6dOA1vClxoRZo2CFDX16uryXQ==",
"dev": true,
"requires": {
"@types/react": "*",
"@types/react-native": "*"
@@ -19696,11 +19576,6 @@
"resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
"integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
},
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
},
"array-includes": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
@@ -20700,15 +20575,6 @@
}
}
},
"create-react-class": {
"version": "15.7.0",
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz",
"integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==",
"requires": {
"loose-envify": "^1.3.1",
"object-assign": "^4.1.1"
}
},
"cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@@ -20746,15 +20612,6 @@
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
},
"css-in-js-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
"integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==",
"requires": {
"hyphenate-style-name": "^1.0.2",
"isobject": "^3.0.1"
}
},
"css-to-react-native": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
@@ -21932,24 +21789,6 @@
"lodash": "^4.17.15"
}
},
"expo-structured-headers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/expo-structured-headers/-/expo-structured-headers-1.0.1.tgz",
"integrity": "sha512-U4frE8rT5x1LqZv5Ru/9CtzY8gh0wp1MfwTu5hetPydnwxXfWchuXvKgWRjEHglFU2X/29kYFY/J1UkPvCN8xg=="
},
"expo-updates": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.5.5.tgz",
"integrity": "sha512-1R8EKkT3GoDjMRQnDaTYv31gIYIaYQGHOrjHJfwq8ai9f1W1AHux6KAH2/H6sc2o9a7roWVwjDn2kKwCm9AeHg==",
"requires": {
"@expo/config-plugins": "^1.0.18",
"@expo/metro-config": "^0.1.59",
"expo-structured-headers": "~1.0.1",
"fbemitter": "^2.1.1",
"resolve-from": "^5.0.0",
"uuid": "^3.4.0"
}
},
"expo-web-browser": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-9.1.0.tgz",
@@ -22602,11 +22441,6 @@
"integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==",
"dev": true
},
"hyphenate-style-name": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
},
"i18n-js": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-3.8.0.tgz",
@@ -22687,14 +22521,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"inline-style-prefixer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz",
"integrity": "sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg==",
"requires": {
"css-in-js-utils": "^2.0.0"
}
},
"internal-slot": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
@@ -24876,11 +24702,6 @@
"resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz",
"integrity": "sha1-XzPUfxPSFQ35PgywNmmemC94/78="
},
"normalize-css-color": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/normalize-css-color/-/normalize-css-color-1.0.2.tgz",
"integrity": "sha1-Apkel8zOxmI/5XOvu/Deah8+n40="
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -26170,11 +25991,6 @@
}
}
},
"react-native-skeleton-placeholder": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-skeleton-placeholder/-/react-native-skeleton-placeholder-5.0.0.tgz",
"integrity": "sha512-7sdG+Y2ENEVcxFC9XlpCgHy59XKkxaUyVqDwuAb66hvl7lwFr25uA5kHJ+JuDJ84ptVil5UEowW/2avwhsfoYg=="
},
"react-native-swipe-gestures": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz",
@@ -26324,36 +26140,6 @@
}
}
},
"react-native-web": {
"version": "0.17.5",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.17.5.tgz",
"integrity": "sha512-pdieIZi2/YeVTaOuIaeaLC6FMkk8h3pvPNruedH+6cWiE15Oz6BGjJ+5IafdXEyiipb1Y0+QuecW81fa3DVM4g==",
"requires": {
"array-find-index": "^1.0.2",
"create-react-class": "^15.7.0",
"fbjs": "^3.0.0",
"hyphenate-style-name": "^1.0.4",
"inline-style-prefixer": "^6.0.0",
"normalize-css-color": "^1.0.2",
"prop-types": "^15.6.0"
},
"dependencies": {
"fbjs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz",
"integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==",
"requires": {
"cross-fetch": "^3.0.4",
"fbjs-css-vars": "^1.0.0",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
"ua-parser-js": "^0.7.18"
}
}
}
},
"react-native-webview": {
"version": "11.14.3",
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-11.14.3.tgz",
+1 -7
View File
@@ -17,18 +17,15 @@
"dependencies": {
"@react-native-async-storage/async-storage": "^1.15.11",
"@react-native-community/masked-view": "^0.1.11",
"@react-native-community/netinfo": "^7.1.1",
"@react-native-community/slider": "^4.1.12",
"@react-navigation/material-bottom-tabs": "^6.0.9",
"@react-navigation/native": "^6.0.6",
"@react-navigation/stack": "^6.0.11",
"@reduxjs/toolkit": "^1.7.2",
"@types/react-native-vector-icons": "^6.4.10",
"cheerio": "^1.0.0-rc.10",
"expo": "^41.0.1",
"expo-document-picker": "^9.2.4",
"expo-file-system": "~11.0.2",
"expo-font": "~9.1.0",
"expo-haptics": "~10.0.0",
"expo-keep-awake": "~9.1.2",
"expo-linear-gradient": "~9.1.0",
@@ -37,7 +34,6 @@
"expo-notifications": "~0.11.6",
"expo-splash-screen": "^0.11.4",
"expo-sqlite": "~9.1.0",
"expo-updates": "~0.5.4",
"expo-web-browser": "~9.1.0",
"i18n-js": "^3.8.0",
"lodash": "^4.17.21",
@@ -58,18 +54,15 @@
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.9.0",
"react-native-skeleton-placeholder": "^5.0.0",
"react-native-swipe-gestures": "^1.0.5",
"react-native-tab-view": "^3.1.1",
"react-native-tts": "^4.1.0",
"react-native-unimodules": "^0.13.3",
"react-native-vector-icons": "^9.0.0",
"react-native-web": "^0.17.5",
"react-native-webview": "^11.14.3",
"react-redux": "^7.2.6",
"redux": "^4.1.2",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.4.0",
"rn-sliding-up-panel": "^2.4.4",
"sanitize-html": "^2.7.0"
},
@@ -80,6 +73,7 @@
"@types/jest": "^27.4.0",
"@types/lodash": "^4.14.179",
"@types/react-native": "^0.66.15",
"@types/react-native-vector-icons": "^6.4.10",
"@types/react-test-renderer": "^17.0.1",
"@types/sanitize-html": "^2.6.2",
"@typescript-eslint/eslint-plugin": "^5.10.2",
-8
View File
@@ -1,8 +0,0 @@
/* eslint-disable no-unused-vars */
import React from 'react';
import { StyleSheet } from 'react-native';
export const Dialog = ({ visible, theme }) => {};
const styles = StyleSheet.create({});
-28
View File
@@ -1,28 +0,0 @@
import React from 'react';
import { Text, View } from 'react-native';
import { IconButton } from 'react-native-paper';
// import {Row} from './Common';
import EmptyView from './EmptyView';
const ErrorView = ({ theme, onRetry, error, openWebView }) => (
<View style={{ flex: 1, justifyContent: 'center' }}>
<EmptyView
icon="(; ̄Д ̄)"
description={error}
style={{ color: theme.textColorSecondary }}
>
<IconButton
icon="reload"
size={25}
style={{ margin: 0, marginTop: 24 }}
color={theme.text}
onPress={onRetry}
/>
<Text style={{ color: theme.textColorPrimary }}>Retry</Text>
</EmptyView>
</View>
);
export default ErrorView;
-1
View File
@@ -14,7 +14,6 @@ import ListView from './ListView';
import { useDeviceOrientation } from '../services/utils/helpers';
import { useSettings } from '../hooks/reduxHooks';
import { defaultCoverUri } from '../sources/helpers/constants';
import { coverPlaceholderColor } from '../theme/colors';
const NovelCover = ({
-180
View File
@@ -1,180 +0,0 @@
import React from 'react';
import {
Pressable,
PressableProps,
StyleSheet,
Text,
View,
} from 'react-native';
import FastImage from 'react-native-fast-image';
import { useAppearanceSettings, useLibrarySettings } from '../../redux/hooks';
import { LibraryNovelInfo, NovelInfo } from '../../database/types';
import { SourceNovelItem } from '../../sources/types';
import { ThemeType } from '../../theme/types';
import {
UnreadBadge,
DownloadsBadge,
InLibraryBadge,
} from './NovelCoverBadges';
import { DisplayModes } from '../../redux/settings/settingsSlice';
import { LinearGradient } from 'expo-linear-gradient';
import { useDeviceOrientation, useNovelCoverHeight } from '../../hooks';
import { DeviceOrientation } from '../../hooks/useDeviceOrientation';
interface Props extends PressableProps {
item: LibraryNovelInfo | SourceNovelItem | NovelInfo;
isSelected: boolean;
theme: ThemeType;
showInLibraryBadge?: boolean;
}
const NovelItem: React.FC<Props> = props => {
const { item, showInLibraryBadge = false, theme, isSelected = false } = props;
const { displayMode } = useAppearanceSettings();
const { novelsPerRowLandscape, novelsPerRowPotrait } =
useAppearanceSettings();
const { showUnreadBadge, showDownloadsBadge } = useLibrarySettings();
const orientation = useDeviceOrientation();
const coverHeight = useNovelCoverHeight();
const coverSelectedStyle = {
backgroundColor: theme.primary,
opacity: 0.8,
};
return (
<View
style={[
{
flex:
1 /
(orientation === DeviceOrientation.POTRAIT
? novelsPerRowPotrait
: novelsPerRowLandscape),
},
styles.container,
isSelected && coverSelectedStyle,
]}
>
<Pressable
style={styles.pressable}
android_ripple={{ color: theme.rippleColor }}
{...props}
>
<View style={styles.badgeContainer}>
{'chaptersDownloaded' in item &&
item.chaptersDownloaded &&
showDownloadsBadge ? (
<DownloadsBadge
unreadCount={item.chaptersUnread}
downloadCount={item.chaptersDownloaded}
showUnreadBadge={showUnreadBadge}
theme={theme}
/>
) : null}
{'chaptersUnread' in item &&
item.chaptersUnread &&
showUnreadBadge ? (
<UnreadBadge
unreadCount={item.chaptersUnread}
downloadCount={item.chaptersDownloaded}
showDownloadsBadge={showDownloadsBadge}
theme={theme}
/>
) : null}
</View>
{showInLibraryBadge ? <InLibraryBadge theme={theme} /> : null}
<FastImage
source={{ uri: item.novelCover }}
style={[
{ height: coverHeight },
styles.image,
showInLibraryBadge && styles.inLibrary,
]}
>
{displayMode === DisplayModes.Compact ? (
<CompactTitle name={item.novelName} />
) : null}
</FastImage>
{displayMode === DisplayModes.Comfortable ? (
<Text
numberOfLines={2}
style={[{ color: theme.textColorPrimary }, styles.title]}
>
{item.novelName}
</Text>
) : null}
</Pressable>
</View>
);
};
export default NovelItem;
const CompactTitle = ({ name }: { name: string }) => (
<View style={styles.compactTitleContainer}>
<LinearGradient
colors={['transparent', 'rgba(0,0,0,0.7)']}
style={styles.linearGradient}
>
<Text numberOfLines={2} style={[styles.title, styles.compactTitle]}>
{name}
</Text>
</LinearGradient>
</View>
);
const styles = StyleSheet.create({
container: {
overflow: 'hidden',
borderRadius: 6,
margin: 2,
},
pressable: {
flex: 1,
padding: 4,
},
badgeContainer: {
position: 'absolute',
zIndex: 1,
top: 12,
left: 12,
flexDirection: 'row',
},
image: {
borderRadius: 4,
},
inLibrary: {
opacity: 0.5,
},
title: {
padding: 4,
fontSize: 12,
},
compactTitleContainer: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
flex: 1,
borderRadius: 4,
},
linearGradient: {
borderRadius: 4,
padding: 4,
paddingTop: 16,
},
compactTitle: {
color: 'rgba(255,255,255,1)',
textShadowColor: 'rgba(0, 0, 0, 0.75)',
textShadowOffset: {
width: -1,
height: 1,
},
textShadowRadius: 10,
},
});
@@ -1,104 +0,0 @@
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import { ThemeType } from '../../theme/types';
interface UnreadBadgeProps {
unreadCount: number;
downloadCount: number;
showDownloadsBadge: boolean;
theme: ThemeType;
}
const UnreadBadge: React.FC<UnreadBadgeProps> = ({
unreadCount,
downloadCount,
showDownloadsBadge,
theme,
}) => (
<Text
style={[
styles.unreadBadge,
(!downloadCount || !showDownloadsBadge) && styles.borderLeftRadius,
{ backgroundColor: theme.primary, color: theme.onPrimary },
]}
>
{unreadCount}
</Text>
);
interface DownloadsBadgeProps {
unreadCount: number;
downloadCount: number;
showUnreadBadge: boolean;
theme: ThemeType;
}
const DownloadsBadge: React.FC<DownloadsBadgeProps> = ({
unreadCount,
downloadCount,
showUnreadBadge,
theme,
}) => (
<Text
style={[
styles.downloadBadge,
(!unreadCount || !showUnreadBadge) && styles.borderRightRadius,
{ backgroundColor: theme.tertiary, color: theme.onTertiary },
]}
>
{downloadCount}
</Text>
);
interface InLibraryBadgeProps {
theme: ThemeType;
}
const InLibraryBadge: React.FC<InLibraryBadgeProps> = ({ theme }) => (
<Text
style={[
styles.inLibraryBadge,
{ backgroundColor: theme.primary, color: theme.onPrimary },
]}
>
In library
</Text>
);
export { UnreadBadge, DownloadsBadge, InLibraryBadge };
const styles = StyleSheet.create({
borderLeftRadius: {
borderTopLeftRadius: 4,
borderBottomLeftRadius: 4,
},
borderRightRadius: {
borderTopRightRadius: 4,
borderBottomRightRadius: 4,
},
unreadBadge: {
borderTopRightRadius: 4,
borderBottomRightRadius: 4,
paddingVertical: 2,
paddingHorizontal: 4,
fontSize: 12,
},
downloadBadge: {
borderTopLeftRadius: 4,
borderBottomLeftRadius: 4,
paddingVertical: 2,
paddingHorizontal: 4,
fontSize: 12,
},
inLibraryBadge: {
position: 'absolute',
top: 12,
right: 12,
borderRadius: 4,
paddingVertical: 2,
paddingHorizontal: 4,
fontSize: 12,
zIndex: 2,
},
});
-20
View File
@@ -1,20 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text as NativeText, TextPropTypes } from 'react-native';
const Text = ({ type, children, style, theme }) => {
const color =
type === 'primary'
? theme.textColorPrimary
: type === 'secondary'
? theme.textColorSecondary
: theme.textColorHint;
return <NativeText style={[style, { color }]}>{children}</NativeText>;
};
Text.propType = {
style: TextPropTypes.style,
type: PropTypes.oneOf(['primary', 'secondary', 'hint']),
theme: PropTypes.object.isRequired,
};
-65
View File
@@ -1,65 +0,0 @@
import { useEffect, useRef, useState } from 'react';
import { useAppDispatch, useSavedChapterData } from '../redux/hooks';
import { saveChapterProgress } from '../redux/localStorage/localStorageSlice';
export const useChapterProgress = (chapterId: number, readerRef: any) => {
const dispatch = useAppDispatch();
const { progressPercentage = 0, progressLocation = 0 } =
useSavedChapterData(chapterId);
const [percentage, setPercentage] = useState(progressPercentage);
const [location, setLocation] = useState(progressLocation);
const percentageRef = useRef(0);
percentageRef.current = percentage;
const locationRef = useRef(0);
locationRef.current = location;
const setProgress = ({ nativeEvent }: { nativeEvent: any }) => {
const currentOffsetY = nativeEvent.contentOffset.y;
const currentPosition =
nativeEvent.contentOffset.y + nativeEvent.layoutMeasurement.height;
const currentProgressPercentage = Math.round(
(currentPosition / nativeEvent.contentSize.height) * 100,
);
setPercentage(currentProgressPercentage);
setLocation(currentOffsetY);
};
useEffect(() => {
return () => {
dispatch(
saveChapterProgress({
chapterId,
progressLocation: locationRef.current,
progressPercentage: percentageRef.current,
}),
);
};
}, []);
const [firstLayout, setFirstLayout] = useState(true);
const scrollToSavedProgress = () => {
if (firstLayout) {
percentage < 100 &&
readerRef.current.scrollTo({
x: 0,
y: location,
animated: false,
});
setFirstLayout(false);
}
};
return {
progressLocation,
progressPercentage: percentage,
setProgress,
scrollToSavedProgress,
};
};
-61
View File
@@ -1,61 +0,0 @@
import { useCallback, useState } from 'react';
import { useFocusEffect } from '@react-navigation/native';
import { LibraryNovelInfo } from '../database/types';
import { getLibraryNovelsFromDb } from '../database/queries/LibraryQueries';
import { useLibrarySettings } from '../redux/hooks';
const useLibrary = () => {
const [isLoading, setIsLoading] = useState(true);
const [novels, setNovels] = useState<LibraryNovelInfo[]>([]);
const [error, setError] = useState<string>();
const { filters, sort } = useLibrarySettings();
const getLibraryNovels = useCallback(async () => {
try {
const res = await getLibraryNovelsFromDb(filters, sort);
setNovels(res);
} catch (err) {
if (err instanceof Error) {
setError(err.message);
}
} finally {
setIsLoading(false);
}
}, [filters, sort]);
const getLibrarySearchResults = useCallback(
async (searchText: string) => {
try {
const res = await getLibraryNovelsFromDb(filters, sort, searchText);
setNovels(res);
} catch (err) {
if (err instanceof Error) {
setError(err.message);
}
} finally {
setIsLoading(false);
}
},
[filters, sort],
);
const clearSearchResults = () => getLibraryNovels();
useFocusEffect(
useCallback(() => {
getLibraryNovels();
}, [getLibraryNovels]),
);
return {
isLoading,
novels,
error,
getLibrarySearchResults,
clearSearchResults,
getLibraryNovels,
};
};
export default useLibrary;
View File
+10 -100
View File
@@ -1,68 +1,13 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
// import { defaultDarkTheme } from '../../theme/dark';
import { BrowseSettingsMap } from './types';
export enum DisplayModes {
Compact = 'compact',
Comfortable = 'comfortable',
NoTitle = 'no title',
List = 'list',
}
export enum TextAlignments {
Left = 'left',
Center = 'center',
Justify = 'justfy',
Right = 'right',
}
// interface ReaderTheme {
// backgroundColor: string;
// textColor: string;
// }
interface SettingsState {
appearance: {
// theme: ThemeType;
displayMode: DisplayModes;
novelsPerRowPotrait: number;
novelsPerRowLandscape: number;
showLabelsInNav: boolean;
showHistoryTab: boolean;
showUpdatesTab: boolean;
};
reader: {
fontFamily: string | null;
fontSize: number;
lineHeight: number;
textAlign: TextAlignments;
backgroundColor: string;
textColor: string;
paddingHorizontal: number;
customCSS: string | null;
fullScreenMode: boolean;
useWebViewReader: boolean;
showProgressPercentage: boolean;
useSwipeGestures: boolean;
};
library: {
filters: string[];
sort: string;
showDownloadsBadge: boolean;
showUnreadBadge: boolean;
updateLibraryOnLaunch: boolean;
};
updates: {
lastUpdateTime: Date | null;
onlyUpdateOngoingNovels: boolean;
updateNovelMetadata: boolean;
showLastUpdateTime: boolean;
};
app: {
incognitoMode: boolean;
downloadOnlyMode: boolean;
};
appearance: {};
reader: {};
library: {};
updates: {};
app: {};
browse: {
onlyShowPinnedSources: boolean;
showMyAnimeList: boolean;
@@ -71,46 +16,11 @@ interface SettingsState {
}
const initialState: SettingsState = {
appearance: {
// theme: defaultDarkTheme,
displayMode: DisplayModes.Compact,
novelsPerRowPotrait: 3,
novelsPerRowLandscape: 6,
showLabelsInNav: true,
showHistoryTab: true,
showUpdatesTab: true,
},
reader: {
fontFamily: '',
fontSize: 16,
lineHeight: 1.5,
textAlign: TextAlignments.Left,
backgroundColor: '#000000',
textColor: 'rgba(255,255,255,0.7)',
paddingHorizontal: 5,
customCSS: null,
fullScreenMode: true,
useWebViewReader: false,
showProgressPercentage: false,
useSwipeGestures: false,
},
library: {
filters: [],
sort: 'novelId DESC',
showDownloadsBadge: true,
showUnreadBadge: true,
updateLibraryOnLaunch: false,
},
updates: {
lastUpdateTime: null,
onlyUpdateOngoingNovels: false,
updateNovelMetadata: false,
showLastUpdateTime: false,
},
app: {
incognitoMode: false,
downloadOnlyMode: false,
},
appearance: {},
reader: {},
library: {},
updates: {},
app: {},
browse: {
onlyShowPinnedSources: false,
showMyAnimeList: true,
-32
View File
@@ -1,35 +1,3 @@
// export interface SettingsMap {
// 'app.downloadOnlyMode': 'string';
// 'app.incognitoMode': 'string';
// 'appearance.displayMode': 'string';
// 'appearance.novelsPerRowLandscape': 'string';
// 'appearance.novelsPerRowPotrait': 'string';
// 'appearance.showHistoryTab': 'string';
// 'appearance.showLabelsInNav': 'string';
// 'appearance.showUpdatesTab': 'string';
// 'appearance.theme': 'string';
// 'library.showDownloadsBadge': 'string';
// 'library.showUnreadBadge': 'string';
// 'library.sort': 'string';
// 'library.updateLibraryOnLaunch': 'string';
// 'reader.backgroundColor': 'string';
// 'reader.customCSS': 'string';
// 'reader.fontFamily': 'string';
// 'reader.fontSize': 'string';
// 'reader.fullScreenMode': 'string';
// 'reader.lineHeight': 'string';
// 'reader.paddingHorizontal': 'string';
// 'reader.showProgressPercentage': 'string';
// 'reader.textAlign': 'string';
// 'reader.textColor': 'string';
// 'reader.useSwipeGestures': 'string';
// 'reader.useWebViewReader': 'string';
// 'updates.lastUpdateTime': 'string';
// 'updates.onlyUpdateOngoingNovels': 'string';
// 'updates.showLastUpdateTime': 'string';
// 'updates.updateNovelMetadata': 'string';
// }
export interface BrowseSettingsMap {
onlyShowPinnedSources: 'string';
searchAllSources: 'string';
-57
View File
@@ -1,57 +0,0 @@
import {
ENABLE_DISCOVER,
FILTER_LANGUAGE,
GET_SOURCES,
PIN_SOURCES,
SEARCH_SOURCES,
} from './source.types';
import { showToast } from '../../hooks/showToast';
import sources from '../../sources/sources.json';
export const getSourcesAction = () => async dispatch => {
try {
/**
* Sort sources aplhabetically
*/
let sortedSources = sources.sort((a, b) =>
a.sourceName.localeCompare(b.sourceName),
);
dispatch({
type: GET_SOURCES,
payload: sortedSources,
});
} catch (error) {
showToast(error.message);
}
};
export const searchSourcesAction = searchText => async dispatch => {
const res = searchText.toLowerCase();
dispatch({
type: SEARCH_SOURCES,
payload: res,
});
};
export const pinSourceAction = sourceId => async dispatch => {
dispatch({
type: PIN_SOURCES,
payload: sourceId,
});
};
export const filterLanguage = language => async dispatch => {
dispatch({
type: FILTER_LANGUAGE,
payload: language,
});
};
export const enableDiscover = key => async dispatch => {
dispatch({
type: ENABLE_DISCOVER,
payload: key,
});
};
@@ -1,149 +0,0 @@
import React, { useCallback } from 'react';
import { Pressable, StyleSheet, View, Text } from 'react-native';
import moment from 'moment';
import FastImage from 'react-native-fast-image';
import { parseChapterNumber } from '../../../services/utils/helpers';
import { setNovel } from '../../../redux/novel/novel.actions';
import { defaultCoverUri } from '../../../sources/helpers/constants';
import { IconButton } from '../../../components/IconButton/IconButton';
const HistoryItem = ({
history,
theme,
dispatch,
navigation,
deleteHistory,
}) => {
const {
historyId,
historyTimeRead,
historyChapterId,
sourceId,
novelId,
novelUrl,
novelName,
novelCover,
chapterName,
chapterUrl,
bookmark,
} = history;
const getChapterNumber = useCallback(
() =>
`Chapter ${parseChapterNumber(chapterName)} • ${moment(historyTimeRead)
.format('h:mm a')
.toUpperCase()}`,
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
);
const navigateToNovel = () => {
navigation.navigate('Novel', history);
dispatch(setNovel(history));
};
const navigateToChapter = () =>
navigation.navigate('Chapter', {
chapterId: historyChapterId,
chapterUrl,
sourceId,
novelUrl,
novelId,
chapterName,
novelName,
bookmark,
});
const uri =
novelCover && !novelCover.startsWith('/') ? novelCover : defaultCoverUri;
return (
<Pressable
onPress={navigateToNovel}
android_ripple={{ color: theme.rippleColor }}
>
<View style={styles.content}>
<View style={styles.container}>
<View>
<FastImage source={{ uri }} style={styles.novelCover} />
</View>
<View style={styles.textContainer}>
<Text
style={[{ color: theme.textColorPrimary }, styles.chapterTitle]}
numberOfLines={2}
>
{novelName}
</Text>
<Text
style={[
{ color: theme.textColorSecondary },
styles.chapterNumber,
]}
numberOfLines={1}
>
{getChapterNumber()}
</Text>
</View>
</View>
<View style={styles.buttons}>
<IconButton
icon="delete-outline"
size={24}
color={theme.textColorPrimary}
onPress={() => deleteHistory(historyId)}
containerStyle={{ marginLeft: 12 }}
theme={theme}
/>
<IconButton
icon="play"
size={24}
color={theme.textColorPrimary}
onPress={navigateToChapter}
containerStyle={{ marginLeft: 12 }}
theme={theme}
/>
</View>
</View>
</Pressable>
);
};
export default HistoryItem;
const styles = StyleSheet.create({
content: {
paddingVertical: 8,
paddingHorizontal: 16,
flexDirection: 'row',
justifyContent: 'space-between',
},
container: {
flex: 1,
flexDirection: 'row',
overflow: 'hidden',
},
novelCover: {
height: 80,
width: 56,
borderRadius: 4,
},
textContainer: {
flexShrink: 1,
marginLeft: 16,
justifyContent: 'center',
},
chapterTitle: {
fontSize: 15,
flexWrap: 'wrap',
},
buttons: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
chapterNumber: {
marginTop: 4,
},
});
@@ -1,58 +0,0 @@
// import React from 'react';
// import { Menu } from 'react-native-paper';
// import {
// ChapterDownloadingButton,
// DeleteChapterButton,
// DownloadChapterButton,
// } from '../../novel/components/Chapter/ChapterDownloadButtons';
// export const DownloadButton = ({
// downloadQueue,
// theme,
// chapter,
// downloadChapter,
// deleteChapter,
// deleteChapterMenu,
// showDeleteChapterMenu,
// hideDeleteChapterMenu,
// }) => {
// if (downloadQueue.some(chap => chap.chapterId === chapter.chapterId)) {
// return <ChapterDownloadingButton theme={theme} />;
// } else if (chapter.downloaded === 1) {
// return (
// <Menu
// visible={deleteChapterMenu}
// onDismiss={hideDeleteChapterMenu}
// anchor={
// <DeleteChapterButton theme={theme} onPress={showDeleteChapterMenu} />
// }
// contentStyle={{ backgroundColor: theme.menuColor }}
// >
// <Menu.Item
// onPress={() => {
// deleteChapter(chapter.chapterId, chapter.chapterName);
// hideDeleteChapterMenu();
// }}
// title="Delete"
// titleStyle={{ color: theme.textColorPrimary }}
// />
// </Menu>
// );
// } else {
// return (
// <DownloadChapterButton
// theme={theme}
// onPress={() =>
// downloadChapter(
// chapter.sourceId,
// chapter.novelUrl,
// chapter.chapterUrl,
// chapter.chapterName,
// chapter.chapterId,
// )
// }
// />
// );
// }
// };
-149
View File
@@ -1,149 +0,0 @@
import * as SQLite from 'expo-sqlite';
const db = SQLite.openDatabase('lnreader.db');
const getLibraryNovelsQuery = 'SELECT * FROM novels WHERE followed = 1';
const getLibraryNovels = () => {
return new Promise((resolve, reject) =>
db.transaction(tx => {
tx.executeSql(
getLibraryNovelsQuery,
null,
(txObj, { rows: { _array } }) => resolve(_array),
(txObj, error) => {
// console.log('Error ', error)
},
);
}),
);
};
const getLibraryChaptersQuery =
'SELECT chapters.* FROM chapters JOIN novels ON chapters.novelId = novels.novelId WHERE novels.followed = 1';
const getLibraryChapters = () => {
return new Promise((resolve, reject) =>
db.transaction(tx => {
tx.executeSql(
getLibraryChaptersQuery,
null,
(txObj, { rows: { _array } }) => resolve(_array),
(txObj, error) => {
// console.log('Error ', error)
},
);
}),
);
};
const getLibraryDownloadsQuery =
'SELECT downloads.* FROM downloads JOIN chapters ON downloads.downloadChapterId = chapters.chapterId JOIN novels ON chapters.novelId = novels.novelId WHERE novels.followed = 1';
const getLibraryDownloads = () => {
return new Promise((resolve, reject) =>
db.transaction(tx => {
tx.executeSql(
getLibraryDownloadsQuery,
null,
(txObj, { rows: { _array } }) => resolve(_array),
(txObj, error) => {
// console.log('Error ', error)
},
);
}),
);
};
const restoreNovelsQuery =
'INSERT OR REPLACE INTO novels (novelId, novelUrl, sourceUrl, sourceId, source, novelName, novelCover, novelSummary, author, artist, status, genre, followed, unread) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
const restoreNovels = async novel => {
db.transaction(tx =>
tx.executeSql(
restoreNovelsQuery,
[
novel.novelId,
novel.novelUrl,
novel.sourceUrl,
novel.sourceId,
novel.source,
novel.novelName,
novel.novelCover,
novel.novelSummary,
novel.author,
novel.artist,
novel.status,
novel.genre,
novel.followed,
novel.unread,
],
(txObj, res) => {},
(txObj, error) => {
// console.log('Error ', error)
},
),
);
};
const restoreChaptersQuery =
'INSERT OR IGNORE INTO chapters (novelId, chapterId, chapterUrl, chapterName, releaseDate, bookmark, `read`, downloaded) VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
const restoreChapters = async chapter => {
const {
novelId,
chapterId,
chapterUrl,
chapterName,
releaseDate,
bookmark,
read,
downloaded,
} = chapter;
db.transaction(tx =>
tx.executeSql(
restoreChaptersQuery,
[
novelId,
chapterId,
chapterUrl,
chapterName,
releaseDate,
bookmark,
read,
downloaded,
],
(txObj, res) => {},
(txObj, error) => {
// console.log('Error ', error)
},
),
);
};
const restoreDownloadsQuery =
'INSERT OR IGNORE INTO downloads (downloadChapterId, chapterName, chapterText) VALUES (?, ?, ?)';
const restoreDownloads = async chapter => {
const { downloadChapterId, chapterName, chapterText } = chapter;
db.transaction(tx =>
tx.executeSql(
restoreDownloadsQuery,
[downloadChapterId, chapterName, chapterText],
(txObj, res) => {},
(txObj, error) => {
// console.log('Error ', error)
},
),
);
};
export {
getLibraryNovels,
getLibraryChapters,
getLibraryDownloads,
restoreNovels,
restoreChapters,
restoreDownloads,
};
-71
View File
@@ -1,71 +0,0 @@
import * as DocumentPicker from 'expo-document-picker';
import { StorageAccessFramework } from 'expo-file-system';
import moment from 'moment';
import { showToast } from '../../hooks/showToast';
import {
getLibraryChapters,
getLibraryDownloads,
getLibraryNovels,
restoreChapters,
restoreDownloads,
restoreNovels,
} from './BackupQueries';
const createFullBackup = async () => {
const novels = await getLibraryNovels();
const chapters = await getLibraryChapters();
const downloads = await getLibraryDownloads();
const backup = { novels, chapters, downloads };
/**
* Request permissions
*/
const permissions =
await StorageAccessFramework.requestDirectoryPermissionsAsync();
if (!permissions.granted) {
return;
}
const uri = permissions.directoryUri;
const date = moment().format('YYYY-MM-DD');
const fileName = 'lnreader_backup_' + date;
if (uri) {
const fileUri = await StorageAccessFramework.createFileAsync(
uri,
fileName,
'application/json',
);
await StorageAccessFramework.writeAsStringAsync(
fileUri,
JSON.stringify(backup),
);
showToast('Backup created.');
}
};
const restoreFullBackup = async () => {
const backup = await DocumentPicker.getDocumentAsync();
if (backup.uri) {
let data = await StorageAccessFramework.readAsStringAsync(backup.uri);
data = JSON.parse(data);
const { novels, chapters, downloads } = data;
novels.map(novel => restoreNovels(novel));
chapters.map(chapter => restoreChapters(chapter));
downloads.map(chapter => restoreDownloads(chapter));
}
showToast('Backup restored.');
};
export { createFullBackup, restoreFullBackup };
-191
View File
@@ -1,191 +0,0 @@
import * as cheerio from 'cheerio';
const baseUrl = 'https://boxnovel.com/novel';
const searchUrl = 'https://boxnovel.com/';
const sourceId = 1;
const popularNovels = async page => {
let url = `${baseUrl}/page/${page}/?m_orderby=rating`;
let totalPages = 73;
const result = await fetch(url);
const body = await result.text();
const loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.page-item-detail').each(function () {
const novelName = loadedCheerio(this).find('h3 > a').text();
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('h3 > a').attr('href');
novelUrl = novelUrl.replace(`${baseUrl}/`, '');
const novel = {
sourceId,
novelName,
novelCover,
novelUrl,
};
novels.push(novel);
});
return { totalPages, novels };
};
const parseNovelAndChapters = async novelUrl => {
const url = `${baseUrl}/${novelUrl}`;
const result = await fetch(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {};
loadedCheerio('.post-title > h3 > span').remove();
novel.sourceId = 1;
novel.sourceName = 'BoxNovel';
novel.url = url;
novel.novelUrl = novelUrl;
novel.novelName = loadedCheerio('.post-title > h3')
.text()
.replace(/[\t\n]/g, '')
.trim();
novel.novelCover = loadedCheerio('.summary_image > a > img').attr('src');
loadedCheerio('.post-content_item').each(function () {
const detailName = loadedCheerio(this)
.find('.summary-heading > h5')
.text()
.replace(/[\t\n]/g, '')
.trim();
const detail = loadedCheerio(this)
.find('.summary-content')
.text()
.replace(/[\t\n]/g, '')
.trim();
switch (detailName) {
case 'Genre(s)':
novel.genre = detail.trim().replace(/[\t\n]/g, ',');
break;
case 'Author(s)':
novel.author = detail.trim();
break;
case 'Artist(s)':
novel.status = detail.trim();
break;
}
});
loadedCheerio('.description-summary > div.summary__content')
.find('em')
.remove();
novel.summary = loadedCheerio('.description-summary > div.summary__content')
.text()
.replace(/[\t\n]|Description|Summary/g, '');
let novelChapters = [];
const data = await fetch(`${url}ajax/chapters/`, { method: 'POST' });
const text = await data.text();
loadedCheerio = cheerio.load(text);
loadedCheerio('.wp-manga-chapter').each(function () {
const chapterName = loadedCheerio(this)
.find('a')
.text()
.replace(/[\t\n]/g, '')
.trim();
const releaseDate = loadedCheerio(this)
.find('span')
.text()
.replace(/[\t\n]/g, '')
.trim();
const chapterUrl = loadedCheerio(this)
.find('a')
.attr('href')
.replace(url, '');
const chapter = { chapterName, releaseDate, chapterUrl };
novelChapters.push(chapter);
});
novel.chapters = novelChapters.reverse();
return novel;
};
const parseChapter = async (novelUrl, chapterUrl) => {
const url = `${baseUrl}/${novelUrl}/${chapterUrl}`;
const result = await fetch(url);
const body = await result.text();
const loadedCheerio = cheerio.load(body);
const chapterName = loadedCheerio('div.text-left > h3').text();
let chapterText = loadedCheerio('.reading-content').html();
const chapter = {
sourceId,
novelUrl,
chapterUrl,
chapterName,
chapterText,
};
return chapter;
};
const searchNovels = async searchTerm => {
const url = `${searchUrl}?s=${searchTerm}&post_type=wp-manga&m_orderby=rating`;
const result = await fetch(url);
const body = await result.text();
const loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.c-tabs-item__content').each(function () {
const novelName = loadedCheerio(this).find('h4 > a').text();
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('h4 > a').attr('href');
novelUrl = novelUrl.replace(`${baseUrl}/`, '');
const novel = {
sourceId,
novelName,
novelCover,
novelUrl,
};
novels.push(novel);
});
return novels;
};
const BoxNovelScraper = {
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
};
export default BoxNovelScraper;
-36
View File
@@ -1,36 +0,0 @@
export const cleanHtml = html => {
let text = html;
if (!text) {
return "Chapter is empty.\n\nReport if it's available in webview.";
}
text = text
/**
* Remove inline styles
*/
.replace(
/style="((?:font-family|line-height|font-size|text-align).*?)"/gi,
'',
)
.replace(/class=".*?"/gi, '')
.replace(/id=".*?"/gi, '')
/**
* Remove comments
*/
.replace(/<!--.*?-->/gim, '')
.replace(/<\s*script[^>]*>[\s\S]*?<\/script>/gim, '')
.replace(/<\s*noscript[^>]*>[\s\S]*?<\/noscript>/gim, '')
.replace(/<\s*form[^>]*>[\s\S]*?<\/form>/gim, '')
/**
* Remove relative links
*/
.replace(
/<\s*a[^>]*href=['"](\/.*?)['"][^>]*>([\s\S]*?)<\/\s*a\s*>/gi,
'$2',
)
.trim();
return text;
};
@@ -1,3 +1,5 @@
export const coverPlaceholderColor = '#8888881F';
const AccentColors = {
default: '#2979FF',
defaultDark: '#3399FF',
@@ -1,30 +0,0 @@
import { NativeModules, Platform } from 'react-native';
const { NavigationBarColor } = NativeModules;
const changeNavigationBarColor = (
color = String,
light = false,
animated = true,
) => {
if (Platform.OS === 'android') {
const LightNav = light ? true : false;
NavigationBarColor.changeNavigationBarColor(color, LightNav, animated);
}
};
const hideNavigationBar = () => {
if (Platform.OS === 'android') {
return NavigationBarColor.hideNavigationBar();
} else {
return false;
}
};
const showNavigationBar = () => {
if (Platform.OS === 'android') {
NavigationBarColor.showNavigationBar();
} else {
return false;
}
};
export { changeNavigationBarColor, hideNavigationBar, showNavigationBar };
-4
View File
@@ -1,4 +0,0 @@
import { ColorScheme, ThemeType } from '../types';
export const getFilterColor = (theme: ThemeType): string =>
theme.type === ColorScheme.DARK ? '#FFEB3B' : '#FFC107';
-7
View File
@@ -1,7 +0,0 @@
import { StatusBar } from 'react-native';
import { ColorScheme, ThemeType } from '../types';
export const setStatusBarColor = (theme: ThemeType) =>
StatusBar.setBarStyle(
theme.type === ColorScheme.DARK ? 'light-content' : 'dark-content',
);