Compare commits

..

573 Commits

Author SHA1 Message Date
Rajarshee Chatterjee d43c95f98c chore: Release v2.0.2
[skip ci]
2025-12-07 00:44:30 +05:30
Rajarshee Chatterjee 52d9d9ea1d feat: Continue Reading While App Runs in Background 2025-12-06 19:03:44 +05:30
Rajarshee Chatterjee 2cabc9849c fix: Skip Failed Entities During Backup Creation and Add Error Handling 2025-12-06 15:16:22 +05:30
Rajarshee Chatterjee 17049aca1c feat: Use All Chapters in Jump-to-Chapter Modal 2025-12-06 14:39:17 +05:30
Rajarshee Chatterjee 9608d59efe fix: Update Battery Level on Chapter Change (Closes #1650) 2025-12-06 13:27:19 +05:30
Rajarshee Chatterjee a7942212a0 fix: Show Page Names Instead of Numbers (Closes #1647) 2025-12-06 13:09:39 +05:30
Rajarshee Chatterjee a22aa53c51 fix: Add Unique Keys to All LegendList Implementations 2025-12-06 13:03:00 +05:30
Rajarshee Chatterjee 1ce16dc643 chore: Cleanup Unused Imports 2025-12-06 12:56:51 +05:30
Rajarshee Chatterjee 0ed6e9a463 fix: Start TTS From First Paragraph on Initial Press 2025-12-06 12:55:02 +05:30
Rajarshee Chatterjee b7ecd1d749 chore: Update Website Link (Closes #1666) 2025-12-06 12:48:42 +05:30
Rajarshee Chatterjee 44e177a5ca feat: Allow <ref> Links in Sanitised HTML (Closes #1672) 2025-12-06 12:48:21 +05:30
Rajarshee Chatterjee b09cd3d587 fix: Sort Updates Correctly (Closes #1652) 2025-12-06 12:44:11 +05:30
Rajarshee Chatterjee b70ebcf5f9 chore: Bump Version Patch to 1 in build.gradle (Closes #1662) 2025-12-06 12:20:19 +05:30
Gabriel Vasconcelos 9d58161729 feat(tts): Refactor Reading Logic to Fix Overflow and Add New Settings (#1664)
feat(tts): refactor reading logic and add new settings (voice, speed, pitch, auto page advance)

- Improved how TTS reads page content for smoother playback
- Added settings for voice selection, speed, and pitch control
- Added auto page advance support
- Added scroll-to-top behavior after advancing pages
- Updated UI to expose new TTS configuration options

[skip ci]
2025-12-06 12:18:35 +05:30
Rajarshee Chatterjee e07eed4a95 fix: Prevent App Crash in Offline Mode (Closes #1651) 2025-12-06 12:14:54 +05:30
Patrick Loser e09704c711 fix: Replace react native paper components
* updated debs

* Added Custom Menu component

* Added new BottomTabBar

---------

Co-authored-by: CD-Z <github.verify097@passmail.com>
2025-11-29 12:39:01 +01:00
Rajarshee Chatterjee 3af24f0815 fix: Improve Migration Error Handling 2025-11-16 13:18:58 +05:30
Rajarshee Chatterjee 4c0e7f6013 fix: Add Backward Compatibility to Tasks Queue 2025-11-16 12:36:42 +05:30
Rajarshee Chatterjee ea298273af fix: Categories Not Sorting
Closes #1642
2025-11-15 20:54:55 +05:30
Rajarshee Chatterjee f60a5af3f2 fix: Add Error Handling Around PRAGMA Query 2025-11-15 20:29:05 +05:30
Rajarshee Chatterjee 6ae5c1cdac chore: Release v2.0.1
[skip ci]
2025-11-15 15:37:34 +05:30
Rajarshee Chatterjee dcf667b176 fix: Rerun Migrations and Update Insert Chapter Queries 2025-11-15 14:36:57 +05:30
Rajarshee Chatterjee 3a313b9441 feat: Add Progress Notifications for Local Backup Creation and Restore 2025-11-15 11:07:48 +05:30
Rajarshee Chatterjee ae8211a4c0 fix: Use INSERT OR IGNORE for Library Updates 2025-11-15 10:08:55 +05:30
Rajarshee Chatterjee 3452478aa1 fix: Create Default Category Only If It Does Not Exist
[skip ci]
2025-11-14 21:32:01 +05:30
Rajarshee Chatterjee 0c14018996 chore: Release v2.0.0
[skip ci]
2025-11-14 21:22:04 +05:30
Palloxin 41ea7eb7b7 chore: Add onScrollEnd Polyfill (#1609) 2025-11-14 19:01:27 +05:30
Rajarshee Chatterjee e31eb9d457 fix: Move WebView Button to Right Actions
[skip ci]
2025-11-14 18:55:30 +05:30
Rajarshee Chatterjee 7842e860cb chore: Update Translations (#1346)
[skip ci]
2025-11-14 15:46:29 +05:30
Rajarshee Chatterjee daf7bf2ccb refactor: Move to Pagination Component and Replace Drawer with BottomSheet 2025-11-14 14:14:41 +05:30
Rajarshee Chatterjee a712100cfc feat: TTS Improvements
Closes #1500
Closes #1210
Closes #1244
Closes #1110
2025-11-14 13:07:37 +05:30
Rajarshee Chatterjee 92e1210fc8 feat: Add In-App Language Selector in Appearance Settings
Closes #1577
2025-11-13 17:19:20 +05:30
Rajarshee Chatterjee 5b4058c093 feat: Add “Has Result” Filter for Global Search
Closes #1512
2025-11-13 16:48:56 +05:30
Rajarshee Chatterjee 77ebdebcca fix: Center Align Button Labels 2025-11-12 21:25:23 +05:30
Rajarshee Chatterjee ea72de0113 fix: Ensure 'Download All' and 'Unread' Download Entire List, Not Just Batch 2025-11-12 21:17:18 +05:30
Rajarshee Chatterjee a1c0820da8 fix: BottomSheets After React Native 0.81 Upgrade 2025-11-12 20:11:29 +05:30
Rajarshee Chatterjee c9eb42ff4d chore: Upgrade React Native to 0.81
This is a manual cherry-pick from @CD-Z’s PR that updates React Native to 0.81. Thanks for originally working on it
2025-10-23 16:39:11 +05:30
Rajarshee Chatterjee 8f0c39ab41 chore: Update Kotlin Version to 2.1.20 2025-10-23 15:35:14 +05:30
Rajarshee Chatterjee 4de059d5bb chore: Add Missing Gradle Plugin 2025-10-23 15:29:32 +05:30
Rajarshee Chatterjee 969572b5a0 chore: Remove Unnecessary PNPM Setup Option 2025-10-23 14:55:02 +05:30
Rajarshee Chatterjee 4236037b6b chore: Switch to PNPM and Rename Scripts 2025-10-23 14:48:12 +05:30
Rajarshee Chatterjee a800c98d02 feat: Revamp Reader Settings UI (#1612)
[skip ci]
2025-10-23 14:10:55 +05:30
Rajarshee Chatterjee f1c825f826 feat: Implement Structured Database Migration System (#1621) 2025-10-23 13:00:10 +05:30
Rider21 fba8974699 fix: Pass imageRequestInit at Missing Places
Closes #1771
2025-10-23 00:49:23 +05:30
Rajarshee Chatterjee 10b90de171 feat: Replace FlashList with LegendList (Closes #1589) 2025-10-22 22:17:31 +05:30
Rajarshee Chatterjee 3785dddebc feat: Add Drag and Drop Support in Categories Screen
Closes #1592
2025-10-22 19:49:45 +05:30
Rajarshee Chatterjee 259dd6acc7 feat: Fetch All Chapters for EPUB Export and Add Range Selection
Closes #1605
Closes #1606
2025-10-22 18:45:08 +05:30
Rajarshee Chatterjee 90160f7f40 fix: Miscellaneous Issues
[skip ci]
2025-10-22 18:22:20 +05:30
Rajarshee Chatterjee 8bdc86c974 feat: Check for New Release Once Per Day
[skip ci]
2025-10-22 17:31:33 +05:30
Rajarshee Chatterjee 5b441562f8 feat: Add Toasts for Creating and Restoring Backups
[skip ci]
2025-10-22 17:24:59 +05:30
Rajarshee Chatterjee 4e1a67efc8 fix: Refactor and Fix EPUB Export (Closes #1611) 2025-10-22 17:03:55 +05:30
Rajarshee Chatterjee cc217e2b04 feat: Add Scroll-to-Top Functionality in Chapter List (Closes #1470)
[skip ci]
2025-10-22 16:19:27 +05:30
Rajarshee Chatterjee f8d4f50307 feat: Add Pinned Plugins and Refactor Plugin List Components
[skip ci]
2025-10-22 15:56:37 +05:30
Rajarshee Chatterjee d0e14d518e feat: Implement Multi-Tracker Support (Closes #1381) 2025-10-22 12:54:27 +05:30
Rajarshee Chatterjee c06d6f9326 feat: Add MangaUpdates Tracker (#1613)
* feat: Add MangaUpdates Tracker

* refactor: Migrate Tracker Components to TypeScript
2025-10-22 12:46:50 +05:30
Rajarshee Chatterjee 1200b7f75b fix: Make Advanced Section Scrollable (Closes #1513)
[skip ci]
2025-10-21 20:33:52 +05:30
Rajarshee Chatterjee ee7d96daf9 feat: Add System Theme Support, Yin & Yang Theme, and Adaptive Plugin Badge Color
Closes #437
Closes #1374
Closes #1578
2025-10-21 19:05:00 +05:30
Rajarshee Chatterjee 5a6f324638 feat: Add Sort by Unread Chapters (Closes #1524) 2025-10-21 16:36:53 +05:30
Rajarshee Chatterjee 4b1ff0efc1 fix: Skip Updating Imported Entries During Library Update (Closes #1404)
[skip ci]
2025-10-21 15:26:09 +05:30
Rajarshee Chatterjee 45174af3c2 fix: Include Imported Entries in “Downloaded Only” Mode (Closes #1261) 2025-10-21 15:20:34 +05:30
Rajarshee Chatterjee baabc073f0 fix: Search Functionality on History Screen (Closes #1418) 2025-10-21 14:11:35 +05:30
Rajarshee Chatterjee 37969da3e9 fix: Prevent Crash When App Is Closed During Onboarding (Closes #1517) 2025-10-21 14:02:56 +05:30
Rajarshee Chatterjee a81b32ae7f chore: Update README 2025-10-18 23:55:38 +05:30
Rajarshee Chatterjee 389fee8ecb chore: Update CI Workflows 2025-10-18 23:55:12 +05:30
Rajarshee Chatterjee 8fcfd22767 chore: Update CI Workflows 2025-10-18 22:20:50 +05:30
Rajarshee Chatterjee b216d3739a chore: Update CI Workflows 2025-10-18 22:17:33 +05:30
yammyy dcceea064a fix: Update Only the Selected Category During Category Update (#1594)
For this:
1) Select all novelIds that are in chosen category
2) Select novels by chosen Ids
2025-10-18 21:56:08 +05:30
Rajarshee Chatterjee 64c027c695 chore: Temporarily Disable Type Check 2025-10-18 21:39:54 +05:30
ilona 0dd9f2bd94 feat: Reimplement Local Backup Based on Self-Hosted Backup (#1603)
Closes #1276
2025-10-18 21:33:59 +05:30
ilona 80228ada1e chore: Improve General Plugin DX (#1604)
* enable webview debugging in dev builds only

* Fixed error downloading empty files (#1601)

* Allow data attributes in chapter HTML #1602
2025-10-18 09:51:10 +05:30
Palloxin 00c180927e Fix broken Bionic Reading (#1588)
fix broken Bionic Reading
2025-09-21 21:11:21 +07:00
Palloxin 7f61219bb0 Improve ‘remove extra spacing’ feature (#1579)
* Improve ‘remove extra paragraphs’ feature

* fix lint

* fix little mistake

* lil edit of code comment

* a little bit faster regex

* forgot to add final \s*
2025-09-21 21:10:11 +07:00
Palloxin 00d3a441e3 Improve regex of import and bionic reading (#1485)
* Improve regex of import

* Update import.ts

* Update import.ts

* lint

* lint

* bionic reading

* lint

* resolve conflict

* fix lint

* Update import.ts

* [^]

* lil fix
2025-09-07 22:07:43 +07:00
Palloxin f6b82939de chore: Update Readme to Display 2.0 Prereleases (#1572)
* Update readme to display 2.0 prereleases

* Change "preview" to "beta"

* last
2025-09-01 23:51:46 +05:30
Patrick Loser 3f2cfc253b added nix flake for a reproducible environment (#1565)
* added flake.nix

* added documentation

* added reference to CONTRIBUTING.md
2025-08-16 13:44:47 +02:00
Palloxin b107d3ca54 fix: Default Line Height ofsup Tag in Reader Mode (#1546) 2025-08-14 21:02:56 +05:30
rvx05 6bda33efd4 feat: Add Catppuccin Theme (#1561)
* Added Catppuccin Theme

* catppuccin theme fixes
2025-08-14 20:52:48 +05:30
Palloxin 1baa3e914c feat: Allow "details" And "summary" HTML Tags In The Sanitizer (#1551) 2025-08-14 20:50:19 +05:30
Patrick Loser ccbbe36ce6 Readd commits from before force push
Fixing mistake
2025-06-06 18:51:32 +02:00
nyagami 9e81f805c0 fix: epub parsing (#1518)
* fix: decode path before save

* fix: absolute path to label
2025-05-25 16:39:18 +07:00
nyagami 47428ec484 feat: import epub cpp (android) (#1514) 2025-05-25 08:15:58 +07:00
Patrick Loser 58f9427008 Small fixes & rendering time improvements (#1511)
* fix not being able to change from chapter drawer

* add UpdatesContext

* fix library search

* Add Switch for plugin settings

* improved BrowseScreen rendering time

* improved rendering time further

* fix download button
2025-05-24 18:18:16 +02:00
Patrick Loser 5e0f375f7f chore: fix all lint warnings (#1510)
* fix all lint warnings

* fix types
2025-05-20 00:02:24 +02:00
Patrick Loser 21611de3aa feat: Added chapter caching & page reader improvements
* update dependencies

* added stopPropagation

* change setInterval to onscrollend

* update progress save logic

* update chapter progress on reader exit

* chapter preloading

* reduced rerender on chapter change

* organize index.css

* added styles

* context restructure

* working page reader upgrade

* reduced unnecessary rerenders

* preserve reader settings during chapter change
2025-05-19 22:33:48 +02:00
nyagami 70520223cd feat: ios native modules (unstable) 2025-05-18 13:49:45 +07:00
nyagami 2c8880c9af [skip ci] splash screen ios (unusable) 2025-05-18 01:47:10 +07:00
nyagami ee864d3e81 [skip ci] feat: IOS (unusable) (#1504)
* feat: IOS (unusable)

* rename action

* remove Gem.lock
2025-05-11 15:46:16 +07:00
nyagami 6730c773f3 [skip ci]: new action for types checking 2025-05-11 10:14:24 +07:00
Patrick Loser 241cb0a664 Improvement: change bottom tabs implementation
* change bottom tabs implementation

* show navbar outside of chapter
2025-05-09 23:13:51 +02:00
Patrick Loser 3d59b8f774 fix: categories and update library on novel import (#1498)
* update epub

* fix categorization of novels

* fix: update library when importing novel

* update categories on change
2025-05-09 20:39:41 +02:00
Patrick Loser 188700112a fix library update crashing the app (#1496) 2025-05-09 19:11:50 +02:00
Patrick Loser 03f582da98 fix backup modal positioning (#1495) 2025-05-09 10:34:21 +02:00
Patrick Loser ed215a1d54 fix focusmode and readerscreen animations (#1494)
* update addToLibrary logic

* replace GlobalSearchNovelItem with NovelCover

* fix NovelCover and related type issues

* fix addToLibrary logic

* installed react-native-edge-to-edge

* fix Footer behaviour in Reader

* fix type issue

* fix Header behaviour in Reader

* fix ToolWrapper animation

* fix
2025-05-09 10:29:31 +02:00
Patrick Loser c487bd2ca6 fix: type errors
* fix app.tsx

* fix InfoItem

* fix helpers

* fix webview ref

* fix MoreScreen

* fix NovelScreenButtonGroup

* fix ReaderScreen

* fix readerTextAlignSelector

* fix ReaderValueChange

* fix UpdateNovelCard

* fix myAnimeList

* fixed legacy backup

* fix migrateNovel
2025-05-08 22:39:02 +02:00
Patrick Loser f90a4d1103 fix: logic related to LibraryContext
* update addToLibrary logic

* replace GlobalSearchNovelItem with NovelCover

* fix replace chaptersRead with chaptersUnread

* remove LegendList from browseTabs

* remove Legendlist from LibraryBottomSheet

* remove LegendList from JumpToChapterModal

* remove LegendList from NovelDrawer

* remove LegendList from ChapterDrawer

* fix NovelCover and related type issues

* added check for pages

* fix addToLibrary logic

* fix lint
2025-05-08 21:38:41 +02:00
nyagami 8306296736 added typescript checking 2025-05-04 21:06:12 +07:00
nyagami ae022052d5 [skip ci] more strict linter 2025-05-04 20:58:09 +07:00
Patrick Loser 7299e53df6 [skip ci] fix: correct save novel cover alignment
fix: fix alignment of save novel cover button
2025-05-04 15:22:03 +02:00
Neel Narayan Shetty c513361a5e fix: fix alignment of save novel cover button 2025-05-04 18:36:27 +05:30
Neel Shetty 429829b80b feat: Save Novel Cover (#1481)
* feat: Save novel cover (#1454)

* fix: handle storage permission for saving novel cover image

* fix: resolve conflicts with new arch
2025-05-04 17:35:16 +05:30
CD-Z ad1ccd815a lint + prettier 2025-05-04 10:48:50 +02:00
CD-Z 036608f7a8 back to Flashlist 2025-05-04 10:41:17 +02:00
CD-Z 8747e8ad39 fix themepicker style 2025-05-04 10:10:12 +02:00
CD-Z 537cf48fb4 fix chapter insert 2025-05-04 09:49:55 +02:00
CD-Z 9f51adb196 update packages 2025-05-04 09:49:55 +02:00
nyagami f2d3de4470 [skip ci] fix: eslint (except insert chapters) (#1487) 2025-05-03 22:53:04 +07:00
Soopyboo32 5f4507cfd5 Better chapter download notification (#1401)
* Better chapter download notification

* fix

* Update starting tasks list when new tasks are added to queue

* Give tasks an id

* Requested changes
2025-05-03 22:28:33 +07:00
Rajarshee Chatterjee ecc7a7a6e7 fix: Database Schema 2025-05-03 18:46:07 +05:30
nyagami 8d5b92bc9e Feat: React Native new architecture (#1420)
* update depedencies (buidable)

* fix: init db once

* upgrade react navigation v7

* better deeplink handler

* upgrade react naitve vector icons

* updated sql querries (may need further adjustments)

* fix: added type for icon name

* update react-native-reanimated, react-native-gesture-handler

* update google signin

* update tabivew & bottom sheet

* make all repository queries synchroniuously

* update categoryqueries

* import db in categoryqueries

* update chapter queries

* update import novel

* updated LibraryUpdateQueries

* fix download chapter

* fixed stats

* update history queries

* improved updates tab logic

* update LibraryQueries

* update NovelQueries

* improved import novel

* fixed notifications for android 14 and up

* fix Cant parse on first opening

* fixed loss of precision error

* Partial Loading of NovelScreen

* NovelScreenButtonGroup animation

* NovelScreen appbar animations

* update migrate novel

* feat: rewrite VolumeButtonListener to turbor module

* minor: clean up

* fixed type errors

* Novelscreen updates

* fix: better material-design-icons for react-native-paper

* migrate react-native to 0.77, good bye metro console streaming

* replace elevation with boxShadow

* rewrite FileManager -> NativeFile in TurborModule

* rewrite ZipArchive -> NativeZipArchive

* rewrite EpubUtil -> NativeEpubUtil

* dev improvement: active arch only for ndk and run launch debug id

* experimental React compiler (works but no significant improvements)

* ReaderBotttomSheet rewrite

* remove db from all query helper functions

* simplified db helper types

* better helper functions

* switch to native-stack

* removed console.log

* Change loading in UpdatesScreen

* pass novelcover on opening novel

* cleanup UpdateNovelCard

* fixed lint errors

* changed novelscreen animation behaviour

* fix UpdatesScreen

* fix lint errors

* fix unwanted downloadbutton behaviour

* fix: wrong key for multi

* fix: react-native-screens override

* remove abi filters for debug

* fix selecting chapters not working correctly

* adjust novelappbar animation

* preserve Layout when opening novel image

* added SafeAreaViews

* set Modal shadow to transparent

* replace rn paper modal with @components modal

* fix go prev chapter goes to first chapter

* fix open drawer with button

* fix SafeAreaView

* fix LibraryScreen

* improve BottomSheet performance

* SafeAreaView for global search

* fix NovelScreen SafeArea

* restructure useNovel

* remove useNovel from NovelScreenList due to possible db lock

* fix NovelCover not showing on first opening

* fix library not updating  changes to novels

* fix menu covering taskbar

* added FadeIn transition to appbar elements

* added SafeSnapPoints to keep bottomsheet inside of the safe area

* upgrade packages

* maybe round download button for jacubb

* fix space after autoscroll

* fix ReaderBottomSheet switch

* fix Jump to Chapter style

* fix Jump to chapter behaviour

* add Loading state to novelcover

* insertChapters performance improvement

* getChapter and getNovel db optimization

* updated db indexes

* New Skeleton for NovelScreen

* smoother FAB button

* add fetching state to useNovel

* fix paged novel chapter navigation

* fix type issues

* fix expanded novelCover on rotation

* add batched loading for chapters

* fix download button

* fix novelScreen loading state

* upgrade react native 0.78

* update to LegendList and fixed type errors

* fix chapter drawer

* added novel context + moved chapter & novel into ReaderStack

* fix lint

* improved chapterlist performance

* improved ChapterListSkeleton performance

* improved updates skeleton

* reworked onboading screen

* fix chapter drawer render error

* add NovelContext [unstable]

* fix filter compatibility

* upgrade eslint + add tanstack query

* eslint auto fix

* fix eslint errors

* upgrade expo 53, react native 0.79.1

* remove console

* remove unused package

* fix: exact vesion for core packages

* update contributing versions

---------

Co-authored-by: CD-Z <p_loser_Austria@gmx.at>
2025-05-01 23:05:30 +07:00
Batorian 0f5eee1bdb Improvement: Updated Sanitizer (#1129)
* update: GitHub workflow-dispatch

* fix: separate app for testing

* fix: separate app for testing

* fix: separate app for testing

* fix: new css for chapter content

* fix: separate app for testing

* branch: new test branch

* Enhancement: added more CSS

* build

* Enhancement: git build

* Fix: git build

* merge

* Enhancement: added more CSS

* dev: update build.yml

* dev: update sanitizer

* sanitizer: updated sanitizer

* dev: update index css

* dev: update sanitizer

* dev: update sanitizer

* sanitizer: update sanitizer

* sanitizer: added more allowed tags

* filter: fix filters

* progress-tracking: initial commit

* progress-tracking: implemented tracking

* progress-tracking: update tracker

* progress-tracking: complete rework

* progress-tracking: improvements

* sanitizer: update sanitizer

* sanitizer: block text-align

* sanitizer: update img

* sanitizer: reworked

* sanitizer: reworked

* sanitizer: fixed lazyloaded images

* sanitizer: revert sanitizer

* sanitizer: remove alt and title from images

* sanitizer: revert other changes

* sanitizer: fix

* sanitizer: update
2025-03-01 11:23:21 +07:00
Adam Kemish 4e3f817792 Update global search result if added to library (#1414) 2025-02-25 21:56:34 +07:00
Adam Kemish c61c4d0105 Fix app crash when downloading novel entry if it is on the recent updates page (#1395) 2025-01-20 23:23:07 +07:00
Adam Kemish 659988330c Fix some bugs with task queue (#1384)
* Fix novel chapter downloading spinner not showing in chapter list

* Fix novel chapter download notification staying on 'Prepairing'
2025-01-18 15:43:04 +07:00
jacksin125 430a067105 Fixed last read not updating and bookmark button in reader mode. (#1368)
* Fixed "Continue Reading" button

The lastRead chapter object that the "Continue Reading" button uses for everything is now updated on entering and leaving the chapter, instead of never updating when information changes.

* Fixed bookmark button not saving state

Done by passing the bookmark state down from the parent.

* Fixed bug caused by my own code

More thorough testing revealed that lastRead did not update properly on chapter switch

* Fixed issue that rendered previous fix ineffective

The original fix caused a new bug when changing chapters, and fixing that caused some of the old bugs to return. It should now be completely fixed.

---------

Co-authored-by: orionduffy <45501204+orionduffy@users.noreply.github.com>
2025-01-13 09:06:35 +07:00
MOAYAD c2c8935068 fix : ERROR $ open failed: EPERM (Operation not permitted) (#1371)
When you try to create a backup file on Android 11+ device you get this error 
/storage/emulated/0/h/inreader_backup_YYYY-MM-DD_HH_mm.json: open failed: EPERM (Operation not permitted)
2025-01-04 16:16:28 +07:00
Adam Kemish 9636aab53f fix: Resolve Service Manager Issue Caused by Unbound ‘this’ (#1375)
* Fix servicemanager broken due to unbound this

* Can use  here now!
2025-01-01 17:27:32 +05:30
Palloxin 22915914fb feat: Improve ‘Remove Extra Paragraph Spacing’ Feature (#1203)
* Improve "Remove extra paragraph spacing" feature

* Adjust in case of p with classes

* Lint

* Lint - part 2

* Lint - part 3

* forgot \s*

* \u00a exception

found here https://readnovelfull.com/the-wife-of-a-powerful-family-huo-shao-how-dare-you-flirt-with-me/chapter-1.html

* Better

* Fix

* fix lint

* forgot ``?:``

* Remove zero width

Removed until a concrete source example has them.

* fix lint

* lint

* better v2

* better 2.1

* Lint

* \s

* Exception: double br are used to simulate paragraphs

NovelUpdates - The Extra of The Bad Ending Game, chapter 159

* double br exception correction

* -

* better exception

* Lint

* flaw correction

doest match ``ahahah<br><br><br><br><br>ahahahaha``

* fix little flaw

* Shortening regex

* faster regex

* comment + faster regex

* lint

* lint

* Improve double br exception

* Correct flaw

* forgot

* \b for p

* Revert correct flaw

* Minimal faster regex

* remove useless piece

* forgot

* Faster regex

* very minor change

* Max level fast

* forgot a thing

* missing \s

* plus ultra

* suppefast

* ops

* u200b
2024-12-29 20:20:14 +05:30
Adam Kemish d39dabef68 Improve Task Queue (#1363)
* Improve Task Queue

* Seperate setMeta function
2024-12-29 13:00:24 +07:00
MOAYAD e01cbefdae fix: legacy backup file name (#1365)
in android file system you can't use the char  ' : ' 
so lnreader file name:
"Inreader_backup_YYYY-MM-DD_HH:mm.json"
you can't write it as a file. 
so i edit it to looks like
"Inreader_backup_YYYY-MM-DD_HH_mm.json"
2024-12-27 22:17:18 +07:00
Brian Fernandez 73fcba007a fix: "Add tag" input does not work correctly (#1357)
* fix: "Add tag" entry does not add tags correctly if there is at least 1 tag

* fix: "Add tag" entry allows to add empty tags when there is at least 1 tag
2024-12-20 22:34:53 +07:00
Brian Fernandez 54a3feb08c fix: "Edit cover" function is not called (#1354) 2024-12-15 12:52:31 +07:00
Rajarshee Chatterjee ecb3875fe2 chore: Update Translations (#1317)
* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Assamese)
[ci skip]

* New translations strings.json (Odia)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Assamese)
[ci skip]

* New translations strings.json (Odia)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Assamese)
[ci skip]

* New translations strings.json (Odia)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (German)
[ci skip]
2024-12-01 21:11:44 +05:30
nyagami 2c9df1d93f more useful empty chapter message 2024-11-27 20:46:58 +07:00
nyagami 5db79a09eb fix: missing history navigation 2024-11-26 23:39:10 +07:00
Adam Kemish ff771fdd68 Better bottom navigation (#1335)
* Better bottom navigation

* Add double press actions to the rest of the tabs

* Fix history screen double press

* Fix lint error

* Fix more lint errors 😢

* 😢

* memo
2024-11-26 23:09:49 +07:00
Nil Silva 169c4b9de1 Add 'multi' language option (#1314)
* Added plugin settings

* Get plugin settings from plugin.

* Added multi language option

* Translate multi string

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-11-26 23:08:04 +07:00
nyagami 4bcd22b9de fix: margin for flatlist container not content container 2024-11-26 22:44:54 +07:00
nyagami 8a2dc15da6 fix: novel status 2024-11-26 22:39:56 +07:00
nyagami 3f3a407820 closes #1263; fix: invoke old refreshChapters 2024-11-26 22:06:20 +07:00
nyagami c72808d72f closes #1322; fix: tracking sheet position 2024-11-26 21:21:29 +07:00
nyagami dabe4710bb Fix: reader page padding & back press (#1339)
* fix: remove bottom padding in page reader

* fix: disable drag transition when holding

* reader bottom sheet backpress handler

* close drawer on backpress

* fix: undefined index

* chores: added onboading strings
2024-11-26 20:47:58 +07:00
Adam Kemish cdc4ddcc97 perf: Small changes following faster global search pr (#1320)
* Small changes following faster global search pr

* Fix lint error
2024-11-25 22:17:18 +07:00
Rajarshee Chatterjee 8f783fd4c2 refactor: Miscellaneous Cleanup (Closes #1307) 2024-11-10 11:12:08 +05:30
Rajarshee Chatterjee 048119e530 chore: Update Translations (#1308)
* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]
2024-11-09 08:14:52 +05:30
nyagami b68d44d500 refactor: Remove Unused Translations (#1316) 2024-11-09 08:13:00 +05:30
Rider21 4bc3638b38 link fixing (#1302)
* test

* Update downloadChapter.ts

* react-native-url-polyfill

* -urlencode

* oops

* +urlencode

* fix prettier

* wrong
2024-11-06 21:07:22 +07:00
Rajarshee Chatterjee bc5e2f1fd1 fix: Use onSurface Color for Chapter Names (Closes #1259) 2024-11-05 09:23:41 +05:30
Rajarshee Chatterjee e8e7519c40 fix: Show Empty Search State When No Results in Available Tab 2024-11-05 08:39:19 +05:30
Rajarshee Chatterjee 5460047e41 fix: Use Safe Area Insets for WebView Screen (Closes #1301) 2024-11-05 08:16:53 +05:30
Rajarshee Chatterjee bdd00cd87d perf: Add Lazy Loading for All Screens 2024-11-05 08:12:35 +05:30
Rajarshee Chatterjee f83c017e09 fix: fix: Display Loading Animation on Novel Screen 2024-11-05 08:07:31 +05:30
Rajarshee Chatterjee e38cb9972f chore: Update Translations (#1305)
* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Assamese)
[ci skip]

* New translations strings.json (Odia)
[ci skip]

* Update crowdin.yml
2024-11-04 20:21:22 +05:30
Rajarshee Chatterjee ac9c789a89 chore: Update Translations 2024-11-04 20:09:48 +05:30
Adam Kemish 445187cf11 perf: Optimize Global Search Performance (#1255)
* Faster and less laggy global search

- Memoise each row in the search results page
- Limit number of concurrent searches (has setting, defaults to 5 sources at once)
- Load sources in the same order as they show in menu so from the user's pov it loads in faster
- Cancel search when u close global search
- Made the order of sources that are still loading follow the sorted order so theres less popin
- Added setting to remove animations from the loading placeholders
- Pause global search if u open a sub window (eg opening a novel)
- Change no results color to look less active

* Cancel previous global search when starting another

* Dont clear global search on unfocus
2024-11-04 18:30:11 +05:30
Rajarshee Chatterjee 52ec11a33d refactor: Prevent Multiple Database Connections 2024-11-04 17:30:36 +05:30
Palloxin c498d7e9cd feat: Increase Transparency of Android Navigation Bar (#1267)
Makes it more transparent in the reader mode.
2024-10-30 21:36:48 +05:30
Nil Silva 0fad9b907f feat: Add User Input Support for Plugin Configurations (#1273)
* Added plugin settings

* Get plugin settings from plugin.
2024-10-30 21:36:00 +05:30
Adam Kemish 0a170f14bc fix: Adjust Cover Height for Screen Width Changes (#1295) 2024-10-30 21:32:21 +05:30
Adam Kemish 8245e77672 feat: Add Switch and TextInput Support to Plugin Filters (#1271)
* Add FilterTypes.Switch support to plugin filters

* Add FilterTypes.TextInput support to plugin filters
2024-10-12 15:39:49 +05:30
nguyd1 9c68260592 fix: Resolve 'Can't Parse Page' SQL Syntax Error (#1266)
fix cant parse page sql syntax error
2024-10-04 17:24:37 +05:30
Palloxin b1778c5802 chore: Genericize Preview Novel Details (#1239) 2024-09-05 10:54:10 +05:30
Justin COLLON be4ed6de79 setEnvFile: fix error when no .env file (#1237) 2024-09-01 17:33:14 +07:00
Skeltons 3597b542d3 Fix: novel info not saving (#1232) 2024-08-27 20:44:56 +07:00
Palloxin fd6d912391 Disable user-select on next-button and info-text (#1225)
Disable user-select on next-button and info-text
2024-08-21 23:01:54 +07:00
Rider21 d9dc18da43 fix: download files with relative url (#1216)
* hard fix

* test

* Revert "test"

This reverts commit 1fe9247752fcbadf348b6017f2d1fbf05165cfce.

* error handler

[URL](https://github.com/facebook/react-native/blob/v0.72.10/packages/react-native/Libraries/Blob/URL.js)
2024-08-21 21:25:39 +07:00
Skeltons a22d754f95 feat: Reduce Sensitivity of Swiping for Plugins/Sources (#1220)
* Enhancement: Make swiping of plugins/sources less sensitive

* Update swiping offset to be less aggressive
2024-08-17 22:15:52 +05:30
Skeltons d9d7d3aaf0 feat: Reduce Sensitivity of Swiping for Plugins/Sources (#1219) 2024-08-17 15:15:09 +05:30
S.M.A Sayem Prodhan a399927264 fix: Resolve Search Error with Query Containing ' (#1133)
* fix search error when query contains '

* change search to prepared statement

* added missing semicolons
2024-08-17 15:12:12 +05:30
Palloxin b4b00a5c66 fix: Improve Progress Bar Proportions (#1197)
Progress bar better proportions
2024-08-17 15:10:04 +05:30
Justin COLLON 9861f81589 fix: Infinite Plugin Updates in Development Mode (#1217)
* re fix setEnvFile.cjs

* infinit plugin update if in dev mode
2024-08-17 15:09:08 +05:30
Skeltons d06aecb5f8 feat: Sort Source List Alphabetically (#1218) 2024-08-17 15:07:30 +05:30
nyagami 86c82c1a61 Fix reader bugs (#1212)
* fix: tts algorithm

* update: turn off tts by default

* update default padding

* change tts transition to 500ms

* update reader body padding

* cleanup

* fix: throw Exception
2024-08-15 23:07:01 +07:00
nyagami 1131446ddc Improvemed bottomsheets (#1195)
* smooth scroll behavior for reader bottom sheet

* fix: BottomSheet flatlist

* add bottom inset for reader bottom sheet
2024-08-11 16:15:15 +07:00
nyagami f6b2516643 Feat: rewrite Reader in vanjs (#1194)
* setup van.js

* scrollbar

* Reader Footer

* move state to reader object

* scroll to previous progress

* image modal

* TTS bubble

* swipe gestures

* binoic reading & remove extra spacing

* tap to scroll

* tap & scroll to move page

* page reader move chapter

* display page in footer

* hide progress bar in page reader mode

* remember postion when switch reader mode

* refactor: move initial scroll out of scrollbar

* scroll bar in page reader mode

* chapter ending content

* fix: tts controller

* fix: tts highlight & stopping

* optional tts

* custom js

* update preview reader

* cleanup

* fix: css
2024-08-11 10:37:28 +07:00
Palloxin 7cf8692e77 fix: Reduce Font Size of Reader Progress Bar (#1153)
From 16px to 14px.
It's better looking.
2024-07-19 11:12:46 +05:30
nyagami d6290294f7 Improvement: not using replace screen to navigate chpater 2024-07-17 21:58:38 +07:00
nyagami d5cb0a234f improvement: simplify shared chapter states with react context 2024-07-16 23:11:41 +07:00
nyagami 306d8d1d42 Improvement: move chapter logic to useChapter (almost) 2024-07-16 22:04:48 +07:00
nyagami 7b1eb7dd9d Improvement: Optimise available plugins by flashlist 2024-07-15 23:42:51 +07:00
nyagami 1ad2c98473 Feat: search plugin with id 2024-07-15 22:39:03 +07:00
nyagami f0b8df93b4 Fix: better download chapter error handling
at least
2024-07-15 22:30:11 +07:00
nyagami 19ce7da32e Feat: voice rate/pitch settings 2024-07-15 21:47:33 +07:00
nyagami 9d35f6d303 minor: allow title tag 2024-07-15 20:44:13 +07:00
Patrick Loser 31d0aa1787 feat: Add Horizontal Reading Mode (#1021)
* Horizontal Reading Mode (#733)

Closes #29
Closes #149

* fixed first few compatibility issues

* added WebView debugging help

* fixed pages logic + open next chapter at end

* hopefully fixed infinity glitch

* removed logs

* fixed small issues

* working page numbering

* double L shape navigation

* changed let to const

* fixed scrollTo function

* cleanup and fixed css issues

* fixed display bug

* fixed settings bug

* added change padding setting

* added strings

* save + scroll on opening chapter logic

* resolved totalpages detection issue

* simplified getInt function

* css cleanup

* removed useless

* fixed padding scaling bug

* deleted debug items

* additional top padding

* smaller chapter height

* fixed contextMenu

* replaced name: readerPages » pageReader

* fixed ReaderSettings Preview Reader behaviour

* cleanup

* ReaderValueChange improvements

* moved page state to js

* fixed type issues

* functionality test

* fix: NaN page on scrollbar

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-07-14 18:10:38 +05:30
nyagami ea5fde4156 Fix: add check multiplicable tasks & repace download queue by task queue 2024-07-14 00:42:52 +07:00
Rajarshee Chatterjee 03e3816ab8 fix: Optimize Marking Chapters as Read or Unread 2024-07-13 20:10:50 +05:30
Justin COLLON 9d6e407c40 fix: Retain Existing Data in .env File (#1130)
* setEnvFile: keeps data from .env file

* prettier for scripts
2024-07-13 18:37:32 +05:30
Batorian 6781b5d6a4 fix: Display Filter Label if Present (#1134)
filter: fix filters
2024-07-13 18:34:30 +05:30
Palloxin 352913f00e fix: Improve Image Placement in Preview (#1094)
* Better place the image in preview

The preview has to.. preview decently:
1. the image is too big (screen space taken)
2. in raw-chapter-text mode the img link is HUGE and one has to scroll a lot.

* Better place the image preview V2
2024-07-13 18:20:32 +05:30
Rajarshee Chatterjee 73f7ebf7b5 fix: Reset Chapter Progress When Marked as Unread (Closes #678) 2024-07-13 13:16:24 +05:30
Rajarshee Chatterjee 045d6419d8 fix: Fix Default Chapter Sorting (Closes #1060) 2024-07-13 12:59:35 +05:30
Rajarshee Chatterjee acc9d8e7ed feat: Pre-fill Edit Information with Existing Data and Add a Reset Option
Closes #1081
Closes #960
2024-07-13 12:52:47 +05:30
Rajarshee Chatterjee a29cce9eba feat: Add Description for "Disable haptic feedback" (Closes #1057) 2024-07-13 12:25:40 +05:30
Rajarshee Chatterjee 1292f520bb feat: Export as EPUB (Closes #1137) 2024-07-13 12:19:02 +05:30
Rajarshee Chatterjee 8bd6131862 feat: Add Option for "Keep screen on" (Closes #1137) 2024-07-13 11:06:29 +05:30
Rajarshee Chatterjee ed6c2b7ba2 feat: Add Empty State in Available Plugins Tab 2024-07-13 10:53:25 +05:30
nyagami f68a7a4e6a Fix: legacy restore 2024-07-12 10:07:50 +07:00
nyagami c9d2ce382f [skip ci] Dev improvement: Different configs for debug app 2024-07-12 09:29:53 +07:00
nyagami 5262567d61 Minor: hide reload button for custom page novels 2024-07-07 07:30:11 +07:00
nyagami b45a30f0cc Fix: avoid re-render in novel screen 2024-07-07 07:20:47 +07:00
nyagami 867b63af22 Feat: Plugin Custom JS/CSS 2024-07-06 11:42:18 +07:00
nyagami b3a5e237f4 added default cover 2024-07-06 11:41:29 +07:00
nyagami 7aae3a81c3 Fix: inlibrary badge 2024-07-06 11:32:25 +07:00
nyagami 078796784b Feat: Service Manager (#1124)
* feat: ServiceManager & import multiple epub files

* Fix: merge chapter based on index of toc in file list

* notifcation when jobs get done

* Fix epub: only read table of content in navmap

* add update library to service manager

* add drive backup/restore to service manager

* add self host backup/restore to service manager

* add migrate novel to service manager

* add download chapter to service manager

* clean up
2024-07-05 23:32:10 +07:00
Patrick Loser 15aed61aa6 Feat: tailing skeletons (#1064)
* tailing loading covers

* fix type issues

* fixed compatibility issues

* show skeleton even if row complete

* cleanup

* replaced !! with Boolean()

* Update type names

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

* updated type occurances

* fixed key issue

* deleted unused vars and comments

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-07-05 23:31:53 +07:00
Justin COLLON b67d6f8088 fix: update defaultCover URL (#1122) 2024-06-30 02:14:04 +05:30
nyagami 9b4bdfea89 Merge epub chapters (#1117)
* Fix: ignore non existed files

* merge chapters & scan cover

* remove unused tocMap

* clean code
2024-06-27 16:04:50 +07:00
r1di 70220a5a87 Fix: Volume scrolling (#1114)
* Volume scrolling fix

the scrolling by volume button right now scrolls 100% of the screen, which hides text when scrolled so, the commit is just changing the the scrolling to 50%.

* typo

* 50% to 75% scroll

---------

Co-authored-by: Ridi <ridi.culous.progger@gmail.com>
2024-06-25 20:48:10 +07:00
Patrick Loser aa95743d1c Fix: hide progressbar on opening drawer (#1102) 2024-06-25 20:20:47 +07:00
nyagami eb818ef55b add website to about page 2024-06-23 17:37:35 +07:00
nyagami 0bda5fd055 No default repo 2024-06-23 17:37:29 +07:00
Patrick Loser ea336902f2 Fix: Scroll to current Chapter (#1101)
* cleanup + fixed scroll to current Chapter

* removed unused memoization

* removed unused import

* ChapterDrawer.tsx => index.tsx

* added correct types

* applied suggestion

* changed chapter.position to scrollIndex + 2

* refactored index.ts
2024-06-14 23:17:22 +07:00
nyagami 58a633e5b9 [skip ci] ignore prettier for android folder 2024-06-13 00:39:19 +07:00
nyagami 74ed5a446d Fix: background color for plugin icon 2024-06-13 00:17:41 +07:00
nyagami a5d073a1ec Fix: Adding Category/Repo buttons position 2024-06-12 23:45:51 +07:00
nyagami f4d3d9d4eb Fix: navigation bar content color after closing reader 2024-06-12 23:40:51 +07:00
nyagami 772a9ef3a2 Feat: Plugin lazy init(#1104)
* move plugins to single folder

* lazy initial

* clean up

* fix: restore novels
2024-06-12 16:26:55 +07:00
Patrick Loser 6f3278f6ff Fix: Allow id and class attributes (#1066)
added exceptions to sanitizeHtml

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-06-10 20:26:34 +07:00
Adam Kemish f11a10ba22 Feat: Add open random entry button (#1098)
* Add open random entry button

* Move menu logic to searchbarv2
2024-06-10 20:20:54 +07:00
Justin COLLON 02304fd394 [skip ci] version increase for default plugins repo(#1074) 2024-06-09 12:18:05 +07:00
nyagami 94d11a12ff Fix: detect gzip images 2024-06-09 10:42:08 +07:00
nyagami fca37868f1 Feat: NOVEL and CHAPTER reader context 2024-06-08 23:01:07 +07:00
nyagami 574f54a9bc Fix: update novel logic for custom page 2024-06-08 22:12:38 +07:00
nyagami fb0649f07f Minor fix: update novel toast 2024-06-08 22:06:12 +07:00
nyagami e3def3821e Fix: Repository add button position 2024-06-08 21:44:44 +07:00
nyagami 334c981013 Fix: add imageRequestInit for Reader instead of fetching base64 2024-06-08 21:42:07 +07:00
nyagami b62c8e3aea Download file with cookie persisted from RN (#1100)
* download file

* clean up
2024-06-08 20:15:41 +07:00
nyagami 09a482e4b7 Fix: do not modify available plugins 2024-06-08 01:57:51 +07:00
nyagami b7bbbbe962 Fix: revert to app storage 2024-06-08 01:42:47 +07:00
Elfing 30265471b5 [skip ci] Adding support for French localization (#1092)
synchro Text translate
2024-06-04 21:35:02 +07:00
nyagami b4b038dd42 fix: use back button instead of previous 2024-06-04 19:37:45 +07:00
nyagami 6517028cd4 minor fix: more header & error on first time launching 2024-06-04 19:28:21 +07:00
nyagami 3f62f6f225 Feat: Permissions requesting (#1096)
fix: app permissions & remove restore errors
2024-06-04 18:52:51 +07:00
nyagami 822256229f Refactor: convert Java to Kotlin (#1095)
* kotlin migrating

* fix: kotlin generations

* fix: unzip & cleanup
2024-06-04 14:14:03 +07:00
nyagami 4f23e1814e Feat: Onboarding screen & FileManager (#1093)
* base onboard screen

* pick theme step

* cleanup

* refactor: TextFile -> FileManager

* pick storage folder

* default root storage

* refactor: fixed storage -> custom storage

* replace rnfs by native module FileManager

* clean up

* refactor: corresponding theme list
2024-06-03 21:21:46 +07:00
Justin COLLON aec6c34b66 Update: Version utils & Github actions (#1072)
* github action:
 - custom apk:
   - packet name with git commit id
   - app name with git commit id
 - cached `npm install`
 - update actions versions

* About page:
 - Version based on package.json
 - added git hash to the version if not Stable
 - RELEASE_DATE, GIT_HASH, BUILD_TYPE created at build time from setEnvFile.cjs
 - special BUILD_TYPE for github actions
 - Version modal copy on click
 - removed versionUtils

* expo-clipboard instead of react-native clipboard

* buildRelease Release instead of Debug ^^'
Gihtub Actions => Github Action
2024-05-31 00:00:07 +07:00
Rider21 e50b6c4a47 Feat: Plugin storages (#986)
* test

* fix

* Update pluginManager.ts

* test

* fix lint

* test

* test webview

* sync

* /

* Update WebviewScreen.tsx

* CookieManager

* Update storage.ts

* Update сookie.ts

* fix title

* MarqueeText...

* Slow

* Even slower

* Squashed commit of the following:

commit da4d7e878aced6567b98fc802c34715b27dfbe00
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Fri Mar 8 13:21:19 2024 +0300

    /

commit 592c4dbfca2d04931ffffba19d1eec20db3ac183
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Fri Mar 8 13:20:34 2024 +0300

    test

commit 63240502d67cda6e851d602728b873e0b6d2aed0
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Fri Mar 8 12:38:13 2024 +0300

    /

commit 591d2592a7f64e65da4f2c61216b564f3eafa2e6
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Fri Mar 8 11:42:03 2024 +0300

    fix progressbar

commit 3d34cfb72827fdcf61267eafbb128b9e893ef40f
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 21:13:49 2024 +0300

    forgot

commit c36d090a60eadfcc4bee1f0cae04bf9213a694a4
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 20:51:31 2024 +0300

    /

commit 3c4e43b7bb6f845d94737aa8cba96b0dc1714b4b
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 20:15:38 2024 +0300

    /

commit 0a20a483968fa42d24996a1d74f4c8e91f86d49a
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 19:46:31 2024 +0300

    add zIndex

commit 7d4490110457f1ae189890268731fc1726a87825
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 19:27:32 2024 +0300

    test

commit b585d5ee0a6d36707ddc323547fdd1976451ee5a
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 18:28:49 2024 +0300

    /

commit cb7241c33d6cea3c1493f41b46fdd67f70455731
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 18:06:30 2024 +0300

    Update Appbar.tsx

commit 5fab766e17708a1be6a9f53029918cad122110bb
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 17:55:24 2024 +0300

    Update WebviewScreen.tsx

commit aec9b92d033156936b97a8455f6198fa20570906
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 17:15:16 2024 +0300

    xd

commit 1fa385b4bd85bea4da34ff9c23021fb92bc622d9
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 17:11:23 2024 +0300

    2

commit 589870de27cee2fcf29c894bd055a936bb0e7a5d
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 16:28:24 2024 +0300

    1

commit 343d2dd5b64404a3ea54d8e0366d8c856c9ea429
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 16:11:08 2024 +0300

    test

commit f2dbf34a7962b04cee46fdb37a9d0ea83ca541fe
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Thu Mar 7 14:36:48 2024 +0300

    test

commit 04c04d97a9dd87815c36145b3e0bd63e1bb3d118
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Wed Mar 6 22:37:45 2024 +0300

    test zoom

commit 6b80559e053a0d1a31f4c4762570b894bb5f70e5
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Wed Mar 6 22:33:55 2024 +0300

    fix

commit 287ce94efc18036ff9cca3054e9ca182137ffe8c
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Wed Mar 6 19:00:01 2024 +0300

    test

commit 67bdddc4d10920b559122f3d7df0225cea65497b
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Wed Mar 6 11:10:22 2024 +0300

    Test newArch

commit 762353788716341474832815f332ad6ff9ebe5be
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Tue Mar 5 20:49:29 2024 +0300

    Update Appbar.tsx

commit 2a876cb942847fb4c67085a6736b2d9e6e9a3012
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Tue Mar 5 20:42:28 2024 +0300

    modal

commit ba4cadec3f87d565fe045e3c977f604444a06571
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Tue Mar 5 16:50:38 2024 +0300

    1

commit 6c14a18b7083fc3292f796408e2defdad2728b10
Author: Rider21 <58046032+Rider21@users.noreply.github.com>
Date:   Tue Mar 5 14:54:27 2024 +0300

    test

* fix

* fix

* Update pluginManager.ts

* test

* fix

* fix lint

* -marquee

* fix defaultCover

* test

* Update src/plugins/helpers/storage.ts

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

* test

* Typescript fixes

* private pluginID

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-05-28 15:50:24 +07:00
nyagami 1ac6d116a2 Fix: Reader footer position & system bar (#1076)
* replace native Navigation bar by expo-navigation-bar

* fix fullscreen logic

* fix: navigation button color

* fix: navigation color when theme changed

* fix: status bar color on full screen mode

* 40 is too large

* no 40 is acceptable :)

* refactor setBarColor

* refactor: rename setStatusBarColor

* no padding for landscape mode
2024-05-28 15:13:46 +07:00
K1ngfish3r 6864d07dd9 Remove html entity replace function when sanitizing text (#1049)
* add spacing between <>

* remove check entirely

* fix ol tag
2024-05-28 11:21:36 +05:30
Lukas Richter 671e4f4bfd Fix: updateNovelTotalPages query (#1069) 2024-05-16 23:29:06 +07:00
nyagami e2d22a5b05 enhance TTS (#1054)
* fix: read by paragraph and empty string

* add voice picker modal

* add tts voice picker for preview

* fix: tts for bionic reading

* stop speak when get out of reader

* search voice

* temporary fix: original font

* fix: start & resume

* fix: close context menu on copy
2024-05-01 00:29:53 +07:00
Rajarshee Chatterjee 3cb2eb6b11 Make Reader Appbar and Footer Animation Smoother 2024-04-30 21:09:03 +05:30
Rajarshee Chatterjee 4597a95e9c Prevent Crash on Promise Rejection 2024-04-30 20:19:28 +05:30
Rajarshee Chatterjee cf4d97e7f9 Use Promise.allSettled and Update Plugin Repository Regex 2024-04-30 20:13:57 +05:30
Rajarshee Chatterjee 09f7319f2f feat: Repositories (#1051)
* feat: Repositories

* feat: Repositories

* Cleanup

* Cleanup

* Cleanup
2024-04-28 18:38:52 +05:30
Rajarshee Chatterjee c77dc52f29 Tweak UX (#1052)
* Tweak UX

* Prevent Crash in Migrate Screen

* Cleanup
2024-04-28 18:38:30 +05:30
Rajarshee Chatterjee 3cd5b40c25 Show Chapter Titles By Default 2024-04-28 09:37:49 +05:30
Rajarshee Chatterjee 42570d29f3 Move Update Icon Outside of Swipe Actions 2024-04-28 09:29:42 +05:30
nyagami 7e7a8866ca Fix: update novel pages (#1048)
* refreshPage button

* no latestChapter

* no hasUpdate in novel page
2024-04-27 09:44:54 +07:00
K1ngfish3r ed5e599edb add table style (#1020) 2024-04-26 00:16:46 +07:00
Patrick Loser addcadeba2 Feature: dynamic novel appbar (#998)
* update depd

* dynamic novel appbar

* fixed merge problems

* changed color from background to surface2

* added gitignore
2024-04-26 00:15:06 +07:00
Palloxin 484c2b7e33 Fix arabic alignment and language list order (#1024)
* Fix arabic alignment and language list order

- Left-to-Right for arabic language with u200e
- Fix alpabethic order

* Cleanup

---------

Co-authored-by: Rajarshee Chatterjee <rajarshee.adm@gmail.com>
2024-04-13 10:59:23 +05:30
nyagami b6fea9111c Fix: insert/update novel/chapter logic (#1019)
* fix: always create novelDir

* fix: download new chapters

* update novel totalPages if refreshNovelMetadata is off

* fix: updateChapter logic

* fix: insertId could be -1
2024-03-30 23:49:48 +07:00
K1ngfish3r 9ef8cab475 fix chapter.page when containing special character (#1015)
* fix page when containing special character

* page always defaults to 1

* AND page = ?
2024-03-26 22:29:19 +07:00
nyagami 7ea8ebacd1 Update plugin sanbox (#1014)
* add htmlparser2

* fix typo

* flatten plugins
2024-03-26 17:46:38 +07:00
nyagami e171dfebc1 Update lastest chapter logic (#1011)
update lastest chapter logic
2024-03-24 13:55:23 +07:00
nyagami 9f6ffc23bf Fix bugs & Reader improvement (#1009)
* fix: wrong chapter order

* fix: reader footer styles

* make swipe getures less sensitive

* fix: update only ongoing novels option

* synchonize update library

* add horizontal scrollbar

* update swipe gesture sensitive

* no swipe when image modal is visible

* add bionic reading

* fix: import untitled epub
2024-03-23 11:50:35 +07:00
nyagami 8906253527 Feat: protobuf support (#1003)
* feat: protobuf support

* fix: spead operator is slower

* fix: redundant JSON encoding

* add fetchProto to plugin sandbox
2024-03-21 16:37:07 +07:00
nyagami 817e4dc9d1 Cheaper epub parsing (#1007)
* cheaper epub parsing

* cleaner process

* no empty page list

* more epub detail

* fix nullable
2024-03-20 13:37:55 +07:00
nyagami 762945497b Fixes & Features (#1002)
* stop loading even no chapters

* edit artist

* more detail reader settings
2024-03-16 20:42:04 +07:00
nyagami a7aa203c30 refactor: safe ternary operator rendering 2024-03-14 14:24:11 +07:00
nyagami aeaecda0cd Fix app logics (#1001)
* fix: DocumentPicker apis

* fix: retry on browse source screen

* fix: set categories logic

* fix: dont fire noti when pausing downloading
2024-03-14 00:28:23 +07:00
nyagami a54ed6de0e Fix: Novel Drawer & Navigation color (#999)
* fix: replace DrawerLayoutAndroid with React Navigation DrawerLayout
slower

* fix: bottom navigation color

* fix: drawer background

* fix: theme dependency
2024-03-11 19:30:40 +07:00
nyagami dde33a0576 Fix themes & Added Reader Image Modal (#997)
* fix: annoying scroll on context menu

* fix app theme

* fix: android textselecthandle color

* fix plugin render callback dependencies

* add image modal for reader
2024-03-10 23:04:50 +07:00
nyagami 40b7542a78 Adjust UI for chilling (#995)
* more screen

* browse screen: reduce re-renders

* fix description styles

* browse screen tabs and swipe styles
2024-03-10 17:34:54 +07:00
Patrick Loser 88059fd6b9 Fix: Midnight Dusk Theme (#983)
* fix midnight Dusk

* added string
2024-03-10 17:34:35 +07:00
nyagami 0d5d7ad084 New Switch look (#994)
* new Switch look

* refactor: merge SwitchSetting to SwitchItem

* fix: remove margin
2024-03-10 14:00:59 +07:00
nyagami 202feb1f41 Fix chapters logic & Rework Plugins management (UI) (#993)
* fix: not download/remove local chapters

* fix: deleteChapters callback

* remove plugin id: no sense fot user

* rework plugin management
2024-03-10 00:23:34 +07:00
nyagami db478130e6 Fix Filter Sheet color & Reader Context menu (#991)
* fix: initialize once

* fix: filter sheet color

* fix: jump to chapter modal

* move volume button to context menu

* rework TTS

* fix: cleanup

* minor fix
2024-03-08 18:51:39 +07:00
Justin COLLON 607941ea1b Language: Add Thai (#989)
* Add Thai

* Thai in languagesMapping
2024-03-06 18:33:31 +07:00
nyagami da1631ba38 Upgrade RN 0.72, Prettier FilterSheet (#985)
* upgrade RN to 0.72, expo to 49

* prettier filter sheet

* fix: use react-native activity indicator

* uninstall @react-navigation/material-bottom-tabs

* fix: plugin card loading size
2024-03-05 13:22:11 +07:00
nyagami 2eb6f96b8e Fix: remove redundant install-time permissions 2024-03-03 00:25:07 +07:00
Patrick Loser d244001a18 Fix: replaced animation (#982)
* replaced animation

* lint issue
2024-03-02 23:39:30 +07:00
nyagami a25e8cb358 Add Polish 2024-03-01 19:57:31 +07:00
Patrick Loser 03b19479c9 Feat: new icons and splashscreen (#974)
* new icons and splashscreen

* removed playstore image

* changed ic_stat_name to notification_icon

* smaller splashscreen animation
2024-02-28 20:36:26 +07:00
Rider21 4f5451495f Fix: Webview theme (#977)
* fast fix

* hotfix

* fixed browser opening

* rewritten

* Update Appbar.tsx

* Update Appbar.tsx

* added BackHandler

* Update Appbar.tsx

* Update src/screens/WebviewScreen/components/Appbar.tsx

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

* Update src/screens/WebviewScreen/components/Appbar.tsx

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-02-28 20:09:27 +07:00
Rider21 6510270037 Fix: webview improved (#975)
* Update pluginManager.ts

* test

* fix

* fix Share

* add qs

* test webview

* Update WebviewScreen.tsx

* Update WebviewScreen.tsx

* webview

* test

* fix crash

* react-native-cookies/cookies

* Update SettingsAdvancedScreen.tsx

* yes

* Compact

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

* expandURL -> resolveUrl

* delete button

* Update fetch.ts

* test

* fix crash

* Update src/services/plugin/fetch.ts

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
2024-02-26 20:33:50 +07:00
nyagami 0208b4265f Fix: backup/restore covers | clean build configs (#976)
fix: backup/restore covers | clean build configs
2024-02-26 11:35:18 +07:00
Rajarshee Chatterjee 334475431c Sort Plugins by Name & Center Plugin's Spinner 2024-02-26 09:19:44 +05:30
nyagami a2220cf3b8 Beta (#973)
* revert: plugin host

* fix: totalPages for legacy backup
2024-02-25 16:47:45 +07:00
nyagami 9c05266c3c Feat: Add features from main and fixes (#972)
* fix: download chapters filter

* fix: deletechapters missing

* fix: tweak chapter

* optimise: chapters preprocess

* fix: bookmark chapter

* fix: not showToast when no network

* fix: preprocess updates|history|download

* fix: ScrollView for morescreen

* feat: exclude download chapter filter

* fix: show labels in nav by default
2024-02-25 13:30:59 +07:00
nyagami 21e46d5493 Fix: Bug fixes (#969)
* fix: Range selection text

* fix: backup novel transaction

* fix: not show fetch plugins error

* fix: Filter button color

* adjust: plugin detail weight

* minor: plugin tab bar ripple color

* fix: category card buttons
2024-02-24 20:58:23 +07:00
nyagami ca688bb294 Upgrade TTS (#968)
* fix: plugins in/uninstall problem

* fix: remove useCallback for plugin item

* feat: implement new UI for TTS

* magic TTS

* fix: infinite loop

* fix: safe epub path

* magic: chose start point for TTS
2024-02-24 11:43:36 +07:00
nyagami 93f5871f1a Optimizations and bug fixes (#964)
* upgrade react-native-webview

* optimise: no render reader content when change reader settings

* optimise: no render reader content when change general settings

* fix: missing page when open reader

* fix: library only downloaded filter

* fix: center reader footer

* fix: reader footer padding

* fix: stop loading after fetch chapters

* showToast if cancel epub

* optimise: plugin list

* fix: remove LNReader path

* optimise: replace RNFS utf-8 by native

* fix: add description as epub  summary

* feat: hot reload for assets files (reader statics files)
2024-02-22 18:51:16 +07:00
nyagami 1bcc0e6664 LNReader beta version (#961)
* beta host

* Refactor: url -> path (#944)

* refactor: url -> pathr

* fix: pluginId

* page support (#947)

* add new fields

* minor fix

* pages for novel

* render novel pages with drawer

* support real paginated novels

* descending novel chapter list

* update when has new latest chapter

* set hasUpdate for all pages after update

* fix: insert pageIndex

* fix: refreshChapters

* minor refactor: pageIndex

* fix: update page logic

* fix: order by pageIndex

* refactor: Chapter.pageindex -> index (position in page)

* Revert "refactor: Chapter.pageindex -> index (position in page)"

This reverts commit 109298e0ccfa4a0d3d369087e05cb6f307a786b4.

* refactor: pageindex -> position

* fix: reader drawer

* temporary fix migration

* fix: Serialize plugins into one file (#949)

* serialize plugins into one file

* fix typo

* Fix: insertChapters (#950)

* Fix: re-renders in novel screen(#951)

* remove unnecessary wrap

* fix: add local novel back to local category

* fix: use variables for default states

* fix: do not re-render when no FAB

* close drawer if pages length = 1

* add Portal.Host

* Cheaper useNovel hook (#952)

* fix: using pure state for novel and chapters

* fix: remove latestChapter mmkv hook

* shorter key

* fix: bookmark

* fix: save chapter progress in db

* minor refactor: chapterProgressElement

* Fix: Error/Empty actions (#956)

* fix: reader error handler

* fix: opacity for novel summary

* fix: library empty view

* fix: upsert and pages logic

* fix: update novel logic

* fix: import epub

* fix: plugin site in global search

* fix: scrollbar font size

* minor fix
2024-02-19 12:48:42 +07:00
nyagami 1b5e345236 more default headers (#942)
more default headers
2024-02-07 18:53:52 +07:00
nyagami e5a1753e52 Fix tabiew (#939)
* fix: tabview look

* fix: error when library is not fetched fully

* fix: legacy backup

* fix: handle error for plugin methods
2024-02-03 10:19:09 +07:00
uy/sun 4bf615477e Fix update only when chapter info changed (#935)
fix: update only when info changed
2024-02-01 12:04:09 +07:00
uy/sun e0dbf87ca7 Fix chapters status lost problem (#934)
* ci: rename workflows

* chore: update translations

* fix: use upsert
2024-02-01 09:44:57 +07:00
nyagami ad2412eb62 Zip backup (#933)
* add remote zip/unzip

* reimplement: remote backup

* fix: close backup request

* get response for remote zip

* add zip drive backup

* add zip drive restore

* fix: categories are not restored

* change scope to drive.file

* add description for backup action

* refactor: Backup types
2024-01-31 19:19:30 +07:00
nyagami 6c20d1855d Pre alpha patch 5 (#928)
* fix: `default` category is added after id = 1 was deleted

* add new fields for Novel and Chapter table
2024-01-31 14:30:27 +07:00
nyagami 3f59bcf751 fix: display native lang in plugin card 2024-01-29 18:15:46 +07:00
nyagami aeafe9d1ca minor: add NativeLanguage type 2024-01-29 18:06:48 +07:00
nyagami 2501e5a20e Merge remote-tracking branch 'origin/update-drive-auth' 2024-01-29 17:16:57 +07:00
nyagami bd3ccdbc07 Pre alpha patch 4 (#919)
* update google-services.json

* fix: wrong package name - ZipArchive
2024-01-28 19:55:23 +07:00
nyagami 8c70e39492 refactor: EpubParser -> ZipArchive 2024-01-28 18:45:52 +07:00
nyagami 58f6475749 update: use cheerio to parse local novel 2024-01-28 18:43:20 +07:00
nyagami de9763e83e update google-services 2024-01-27 12:22:00 +07:00
nyagami fdc15a0936 Fix: pre-alpha-patch-3 (#914)
* fix: not allow to delete local category

* fix: throw github cache issue

* refactor: use english key

* minor: native language details

* add translatable strings
2024-01-27 09:26:37 +07:00
uy/sun 0e633b42ba chore: add more translatable strings (#908)
* chore: strings in browseScreen

* chore: update translations in strings.json

* chore: translate MoreScreen and downloader.serviceRunning

* chore: translate all things in moreScreen

* feat: support passing options

* chore: update more translations in settings

* chore: translation in LibraryScreen

* chore: add missing en translations

* chore: rearrange strings path

* chore: translate backupScreen

* chore: translate SettingsReaderScreen

* chore: translate statsScreen

* chore: translate HistoryScreen

* chore: translate NovelScreen

* chore: translate remaining strings

* chore: missing translations

* chore: add missing and improve Chinese translation

* chore: improve naming

* chore: remove toast section and add more translations related to notifications

* revert: status translations

* chore: translate NovelStatus

* chore: translate error messages I have encountered

* chore: add more translations used in updateNotification

* chore: update missing translations

* chore: translate backup modal

* chore: translate all taskTitle

* chore: improve translations

* chore: add common.example

* chore: improve emptyChapterMessage

* chore: rearrange backup strings

* chore: flatten keys

* chore: remove unused strings

* chore: translate more stuff

* chore: flatten aboutScreen

* chore: flatten generalSettingsScreen

* chore: flatten readerSettings

* chore: flatten browseSettingsScreen

* chore: flatten settingsScreen

* chore: updated based on review

* chore: translate DefaultCategory

* chore: fix sources translation
2024-01-26 18:47:39 +07:00
nyagami bf4d761c05 fix: not allow to delete local category 2024-01-26 16:18:39 +07:00
nyagami 09d51b26c6 update plugins host (#910)
* update plugins host

* fix: missing branch
2024-01-25 20:04:17 +07:00
nyagami 8f6c390dc2 Fix issues reported by pre-alpha users - patch 2 (#906)
* delete background_action key before action done

* force to delete BACKGROUND_ACTION.
in case app is shutdowned while running bg actions
2024-01-24 09:02:53 +07:00
nyagami 0cf75fd6f9 Fix: pre-alpha-patch-1 (#905)
* fix: wrong version checker, update lastused

* fix: only show update dialog if newer version

* fix: remove chapter id in chapter item

* fix: date in chapter drawer

* fix: decode uri for local epub

* fix: simpler SetCategoriesModal

* fix: not allow local as default

* fix: no delay on selfhost backup/restore
2024-01-22 23:08:27 +07:00
nyagami b823c913b5 Last step to Alpha (#904)
* update CONTRIBUTING.md

* fix: change host branch

* fix: remove showToast from plugin sandbox

* update actions

* update version
2024-01-22 08:55:30 +07:00
nyagami 01e6e9873e More fetch, add urlencode (#903)
* feat: add fetchText

* minor: add urlencode
2024-01-21 15:35:01 +07:00
nyagami d299e91a93 Merge pull request #897 from nyagami/main-feats
Add some features from main, improve UI
2024-01-21 13:05:32 +07:00
nyagami 430e5712fa fix: add chapter number, fix novel screen ui 2024-01-20 20:49:16 +07:00
nyagami 551425c018 feat: artist name,
fix: chapter release as local time
2024-01-20 18:26:45 +07:00
nyagami 665bca00ea fix: regex freeze app 2024-01-18 23:16:09 +07:00
nyagami 2ec6032673 chores: add translations 2024-01-18 15:40:37 +07:00
nyagami d52f630775 fix: circle requires in deleteCachedNovels 2024-01-18 15:04:22 +07:00
nyagami 3e7f51e9ae feat: custom UserAgent 2024-01-18 14:56:31 +07:00
nyagami bc977fd0cb feat: useUserAgent 2024-01-18 14:23:32 +07:00
nyagami deef93172b fix: clear novel settings when deleting 2024-01-18 14:12:26 +07:00
nyagami fa8b69a630 fix: chapter drawer layout 2024-01-18 14:07:04 +07:00
nyagami abd8d65914 fix: cleanup 2024-01-18 12:50:36 +07:00
Nyagami c71dda77d4 feat: save novel cover to download folder (if possible)
remove clear cached covers
2024-01-18 00:18:57 +07:00
Nyagami c2caee6ef9 replace FastImage by regular Image
- Glide -> Fresco (image loader)
2024-01-17 18:41:22 +07:00
Nyagami e2588908c1 minor: page number required in searchNovels 2024-01-16 17:39:40 +07:00
Nyagami 9b36043a00 feat: search next page 2024-01-15 23:24:19 +07:00
Nyagami 72fe3bb0f3 remove Flipper (which may cause internet stuck) 2024-01-15 21:01:13 +07:00
Nyagami 9f75945cf6 fix: skip chapter when error downloading 2024-01-15 20:47:36 +07:00
Nyagami 82f2b4e3b5 fix: filter picker value text color 2024-01-15 20:22:15 +07:00
Nyagami bdb7eb4521 fix: expo notification icon (not app icon) 2024-01-15 19:59:37 +07:00
Nyagami c42f0a0bb0 fix: background actions notification icon 2024-01-15 19:57:37 +07:00
Nyagami a33db07583 fix: expo notification icon 2024-01-15 19:45:23 +07:00
Nyagami 2b99c3d17d fix: android user-agent 2024-01-14 23:22:48 +07:00
Nyagami 6ea1ecb43d fix: handle fetchApi for 2 kind of headers 2024-01-14 23:22:18 +07:00
Nyagami bbe5ccea81 remove cookie stuffs 2024-01-14 23:19:05 +07:00
Nyagami da3a589c88 refactor MMKV backup data to util 2024-01-14 14:56:47 +07:00
Nyagami 26b312372e add tracker client variables for build action 2024-01-14 14:22:13 +07:00
Nyagami 39dc3ec8d6 fix: center label when no badge in library 2024-01-14 11:34:04 +07:00
Nyagami 560848f5d5 fix: reader bottom tab border 2024-01-14 11:32:55 +07:00
Nyagami 0bbd0da68c fix: ui for tracker 2024-01-14 10:24:39 +07:00
Nyagami bbdd569522 fix: jump to chapter modal keyboard 2024-01-14 10:02:08 +07:00
Nyagami 937e789b67 fix: exclude some MMKV keys when backup 2024-01-14 09:47:58 +07:00
Nyagami f8647a8e49 upgrade react-native-paper to fix modal ondismis 2024-01-14 02:12:12 +07:00
Nyagami f93bceb136 remove play button from history 2024-01-13 22:46:58 +07:00
Nyagami e8d343893f add animated fab 2024-01-13 22:38:48 +07:00
Nyagami 769ff36352 custom js, css modal 2024-01-13 22:02:30 +07:00
Nyagami 1253f44413 update ui for installed plugined 2024-01-13 17:52:02 +07:00
Nyagami 1c802c5e3b fix: update plugin logic 2024-01-13 17:50:55 +07:00
Nyagami a19b374cb4 fix: small plugin card, loading when installing 2024-01-13 16:25:53 +07:00
nyagami 420603f911 Replace Redux thunk by react native MMKV (#893)
* refactor: useBoolean hook

* refactor: useGithubUpdateChecker hook

* refactor: move showToast to utils

* refactor: useBackHandler hook

* refactor: useTextToSpeech hook

* refactor: useDeviceOrientation hook

* refactor: usePreviousRouteName hook

* refactor: useFullscreenMode hook

* refactor: useSearch hook

* refactor: useTheme hook

* fix: remove updates reducer

* refactor: useCategories hook

* refactor: useHistory hook

* refactor: useLibrarySettings hook
remove unused useCategories hook

* fix: reanimated version for expo

* refactor: library, chatper hooks

* refactor: app, browse settings hooks

* refactor: usePlugins hook

* fix: max depth in useEffect, plugins state logic

* feat: add Anilist tracker

* refactor: useTracker hook

* useTrackedNovel hook

* minor fixs

* refactor: useNovel hook

* minor fix: book mark button

* refactor: useDownload hook

* fix: migrate function

* remove redux + cleanup

* update node version for build

* fix: download Queue, migrate action

* fix: increaes hit slop for thumb, add reader playground

* fix: plugins not updated when installing while searching

* fix: safe plugin management

* Squashed commit of the following:

commit 51968f66bdd69f28f1863b5668f9511ba53c3fff
Author: Nyagami <hoangquan05112002@gmail.com>
Date:   Sat Jan 13 13:20:33 2024 +0700

    better logic for download progress bar

commit 5069de11644e7aece39efc73dfd80d093982b032
Author: Nyagami <hoangquan05112002@gmail.com>
Date:   Sat Jan 13 13:14:33 2024 +0700

    fix: delete BACKGROUND_ACTION in finally clause

commit 181103e994831da6744d122faaa60c48da529a63
Author: Nyagami <hoangquan05112002@gmail.com>
Date:   Sat Jan 13 13:10:56 2024 +0700

    update react-native-background-actions
2024-01-13 14:28:24 +05:30
nyagami 7a6710dc0b feat: Google Drive Backup (#872)
* setup google signin

* minify build scripts, add google signin modal

* feat: Drive backup

* feat: drive restore

* fix: remote backup

* upgrade react native to stable version
+ less build configs

* fix: path separator.
feat: sync backup between 2 methods

* legacy backup

* fix: expo speech
2024-01-07 16:58:05 +05:30
Marcin Majewski 7262f1d249 Filters Redesign (#856)
New filters system adding intelisense

Co-authored-by: Rajarshee Chatterjee <rajarshee.adm@gmail.com>
2023-12-27 19:36:45 +05:30
nyagami 5c12540071 refactor: Convert Javascript files into Typescript (#845)
* cheaper debug build

* index.ts, App.tsx

* TS for navigators

* TS NovelScreen

* TS Reader Screen

* TS More Screen

* TS Source Screen

* TS Browse Settings Screen

* TS Global Search Screen

* fix: useNavigation for more stack

* fix: Composite Types for More Screen

* TS Browse + Migrate Screen

* TS Settings Screen

* TS util

* TS services

* fix: Library query

* TS Components

* refactor: settingsSliceV1

* refactor: Preference reducer

* TS for MAL

* refactor: Native modules

* Not TS the entry file

* fix: zip folder entry, special file name

* fix: plugin is undefined if 'local'

* fix: add param for morestack navigation

* fix: Component is bool

* fix: novel reducer

* fix: not updating local novels
2023-12-27 19:35:05 +05:30
nyagami 7fbdd92117 feat: Import EPUB (#833)
* implement classes for plugins

* feat: plugin manages UA, cookie itself

* fix: repo path

* safer regexString

* feat: EpubParser native module

* add reject to parser

* local category, better insert category trigger

* add isLocal field to Novel

* category update logic for local novels

* feat: import epub

* delete downloaded folder when delete novel

* local novel screen

* update build.yml

* fix: novel without cover
2023-11-10 18:31:09 +05:30
nyagami 5c818be5ab refactor: Classes for Plugins (#824)
* implement classes for plugins

* feat: plugin manages UA, cookie itself

* fix: repo path

* safer regexString
2023-11-04 15:46:18 +05:30
nyagami 1b25acba26 refactor: Using classes for reader UI (#775)
using classes
2023-09-15 07:46:28 +05:30
nyagami 434d03615c fix: Remove Description and Protected (#753) 2023-08-22 18:07:20 +05:30
nyagami 9bde9528df feat: FileSystem, Highlight TTS (#741)
* fix restoreCategory

* feat: using file for js, css
- cheaper seekbar (maybe)
- cheaper showScrollPercentage
- autoSaveInterval
- cheaper loading image
- cheaper error images handler (no need protected attribute anymore)

* feat: store downloads in file

* move plugins to app download folder

* Feat: Hightlight TTS
- optimise render chapter text
- scroll fix
2023-08-18 21:44:05 +05:30
nyagami 191975f0f9 Tssupport, backup AppVersion (#680)
* add exports variable

* fix: remove pinned and lasteUsed after uninstall

* fix: language filter for installed plugin

* create index for Chapter in novelId

* reorder headers parame in fetchApi

* remove Language from plugin libs

* fix: not backup empty cover

* feat: backup app version

* fix: chapter index

* feat: checkAppVersion when restoring

* update: using normal exports instead of default
move fetchFile into fetch.ts

* defaultCoverUri -> defaultCover
2023-08-17 08:49:28 +05:30
nyagami f8895b80b4 fix: wrong mincroll in Update, History. TS Reader, Navigation (Main) (#665)
* fetch prev&next chapter and text at the same time.

* typescript for Main and Reader (and some related screens)

* fix: update time order

* feat: three dots button for browse

* fix: reader got wrong minscroll

* remove unused package drawer

* fix: seekbar bottom position

* add data-set in script (Reader)
2023-08-17 08:49:14 +05:30
nyagami e5c73615f1 feat: Remote Backup (#659)
* feat: remote backup (novel, category)

* feat: full backup

* fix: throw when downloading without installed plugin

* update: using websocket to tranfer data

* remote restore

* error handler for restore

* normalize code by recursion

* Not backuping tracker.
Because users can share their backup.
And tracker setting cotains their own token.

* fix: not create .nomedia in download dir

* fix:  2 children have same key in filter input

* fix: 2 children have same key in Picker Item
2023-06-30 09:41:10 +05:30
K1ngfish3r 800eb5ee30 Update pluginManager.ts (#661)
add showToast
2023-06-30 09:39:16 +05:30
nyagami 721b7edf1c fix: new github path for plugins json files (#636)
* change plugins host

* remove suffix

* update: new github path
2023-05-16 21:10:36 +05:30
nyagami 27501b223d fix: Update Plugins Host (#627)
* change plugins host

* remove suffix
2023-05-11 21:08:21 +05:30
nyagami 0e5c4b8243 feat: Plugins & Rework Database (#579)
* remove AsyncStorage, disable hermes

* init

* update logic

* update libs for plugins

* move interface to types

* refactor, add language type

* small refactor of languages

* getPlugin

* update alias

* collect plugin on launch

* update interface Plugin

* move lang to PluginItem

* implement install plugins

* fix plugins reference

* fix fetching logic

* fix empty list

* refactor Browscreen

* implement searchNovels

* refactor plugin reducer

* try to remove old sources

* try to refactor

* tabview with theme, remove rn-fetch-blob

* update lib for plugin, temp fix for browse

* try to replace source by plugin in db

* many updates

* update db

* fix queries error

* update db

* update db

* update History table

* update db types

* format table name

* rename service

* rename field

* refactor interfaces

* update constrait

* update novel queries

* update constrait

* update novel and category queries

* more flexible category

* update library queris

* create category trigger, add constraints

* sync variables name with js rule :(

* setup database 90%

* updates queries

* queries to add novel to lib

* remove delete updates => delete download

* minor

* app work 20%

* query default one time

* createdb first

* remove 90% sources

* fix library queries

* temporary fix

* remove all source

* remove old languages constant

* update trigger

* update types

* refactor types, update trigger, refactor queries

* at least can go to novel screen

* update novel redux

* can go to novel screen

* remove generator

* change sourceId to pluginId

* can read chapter :(

* minor fix

* can use history screen

* unique key in historyscreen

* remove never use hook

* at least can use reader

* minor

* fix download queries

* fix history and chapterDrawer doenst need setNovel

* fix last read

* update click heart to follow novel

* insertNovel

* long press novels in library,

* change default category by move up

* update edit category, fix foreign constrait

* loading before get novel done

* fix categories were added.
Dont know why trigger didnt work.
So I decide to use normal queries

* fix errors when edit infos

* shorter init plugin

* fix stats screen

* minor fix for seekbar

* set re-request, fix download chapter

* hard fix:), maybe refactor it later

* must use sum to count :D

* update query

* fix migrate screen

* minor fix

* fix migrate screen and global search display

* minor

* quick fix for update screen

* update plugin props

* lol :D

* Backup work now.
But need to install plugins

* restore error backup

* If get novel without chapters. Fetch it again

* if all error novels are restored, remove error file

* minor fix

* remove never used packages.

* Complete plugin feature. Bump to RN 0.69.
I will write a  changelog soon

* fetchFile for app side

* Fix: transparent bottem sheet, undefined index.
hideNavigationBar causes transparent bottem sheet (still opening but invisible.
Hope to find an actual fix later

* newUpdateDialog without markdown

* fix: Browse plugins behaviors

* fix: reader screen crashs when plugin is not installed

* Minor fix: undefined variables when updating

* minor fix: fetchFile return base64

* only update newversion

* fix: buildReleas succesfully but app crashes when opening.
from: https://github.com/facebook/react-native/issues/34114

* fix: webview send correct body height

* Refactor: remove HistoryTable.
remove PluginStatus

* Refactor: Migrate Update and History into Chapter.
- remove nerver used hook: useChapter

* fix: edit categories modal in novel screen

* minor: LL date format

* minor: remove html2text lib

* minor: migrate inlibrary novel

* Migrate novel and clean up

* small fix for migrate function

* Database Diagram

* optimise: O(1) to determine if lastread is read

* fix: position could be undefined

* refactor: change prop name. postion.position -> postion.offsetY

* fix filter

* fix: missing param in parseChapterNumber

* not a good fix, but it works xD

* fix: Text trunct almost title, should find a better fix later.

* enable feature: migrate from browse screen

* add data-plugin-id tag

* no `ghost` novel (which has no category)

* minor fix: detele all novel categories when removing novel form lib

* minor: deleteDownloadsSnackbar

* edit warning

* add chapter tag on preview

* add id for plugin, novel, chapter. smaller padding

* Use BottomSheetModal

* implement cookies bypass

* default language filter

* change default user agent

* shorter langue native name

* missing NOVEL_ERROR

* add filterInputs

* correct spelling :)

* add dayjs

* minor: remove console.log

* update site for pluginItem

* update icon,

* minor: remove unnecessary things
2023-05-08 07:09:20 +05:30
Jaydeep Patel 2d986f263d feat: Add custom Javascript (Closes #572) (#575)
feat: Add custom Javascript
2023-03-11 11:52:16 +05:30
Rajarshee Chatterjee 684463754c chore: Update translations (#546)
* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]
2023-03-05 12:08:28 +05:30
Rajarshee Chatterjee 6879d77ef1 feat: Add Last Updated Sort (Closes #482) 2023-03-05 11:56:02 +05:30
Rajarshee Chatterjee 41ed198a1d refactor: Remove totalPages 2023-03-05 11:39:52 +05:30
Rajarshee Chatterjee 550e116be5 feat: Add Chapter Name Sort (Closes #525) 2023-03-05 11:12:43 +05:30
Rajarshee Chatterjee 1c21c180ab refactor: Tweak Updates Card 2023-03-05 11:08:53 +05:30
nyagami 08860c0715 fix: Minor Fixes and Optimizations (#566)
Closes #557
2023-03-05 09:43:00 +05:30
K1ngfish3r d65170c85a Minor: prerequisites/build cmd to CONTRIBUTING.md (#565)
* Minor: prerequisites/build cmd to CONTRIBUTING.md

* switch npm start under developing section

* link CONTRIBUTING.md in README.md

* make clearer
2023-03-01 14:30:39 +05:30
Patrick Loser cf19eb6892 feat: Collapsible Updates and Downloads (#562)
* implemented extendable list for updates

* finished creating extendable list (buggy deleteChapter)

* fixed downloadbutton bug

* fixed ts problems

* set navigatetonovel to onLongPress

* removed

* key fixes

* implemented extendable list for updates

* finished creating extendable list (buggy deleteChapter)

* fixed downloadbutton bug

* fixed ts problems

* set navigatetonovel to onLongPress

* removed

* key fixes

* translation strings

* single chapter + style updates

* removed test method
2023-03-01 14:29:48 +05:30
nyagami 3289f357d9 refactor: Downloading Images Logic (#554)
* default language for browse source.
To test this. please clear all all app data

* fix: for some reason, locale from expo is uncorrect

* bypass some sites with referer in header.

* update logic for loading img on reader.
some sources should have headers when fetch image data

* minor fix

* fix warning: 2 childs have the same key

* fix(download): Download chapter image fixes

- Saving images in binary form, not utf-8 base64 so that gallery etc can see them
- Downloads work with new WebViewReader's image loading features
- Added loading icons when images are loading asynchronusely

* fix(dq.ts): DownloadQueries type

* fix(img): remove delayed-src from downloaded imgs

* fix(download): Fix promise rejection and css issue

- Fix promise rejection when trying to overwrite image file (shouldn't happen in production, but it miraculously did in dev)
- Fix CSS class 'loadIcon' not being applied to downladed chapter image loader icons and loader spinners not spinning
- Made loader spinners smaller. Now they look "a bit better" (according to my friend whom I showed the spinners)

* fix(loadimg): Change loadImage to smaller one

* fix(loadImg): change the class to load-img

* minor fix

* fix hako source: popular novels and novel cover

* update sendHeight logic

---------

Co-authored-by: SkillGG <skilletssgames@gmail.com>
2023-02-26 13:15:13 +05:30
K1ngfish3r fe2b2524a7 feat(source): Add Pawread (#561)
Closes LNReader/lnreader-sources#439
2023-02-23 07:40:27 +05:30
Patrick Loser 2e4ff916aa fix(source): Foxaholic (#563) 2023-02-23 07:38:38 +05:30
K1ngfish3r b40e9331d7 fix(source): SakuraNovel (#560)
Closes LNReader/lnreader-sources#456
2023-02-22 10:05:45 +05:30
Rajarshee Chatterjee 84a2561c41 Minor Fixes 2023-02-18 14:02:04 +05:30
K1ngfish3r 929bd2c97d feat(source): Add New multiSrc WQMangaStreamScraper & PandaMtl (#552)
Closes #LNReader/lnreader-sources#453
2023-02-18 09:00:20 +05:30
Rajarshee Chatterjee 9028a82318 Minor Fix 2023-02-17 23:22:17 +05:30
Rajarshee Chatterjee c6c41a2d1b Cleanup 2023-02-17 22:59:20 +05:30
Nyagami 9a0c08e7b8 refactor: Remove Swipe Margins (#553)
* refactor swipeGesture, remove swipeMargin

* trying to resolve conflict

* again :(

* cleanup
2023-02-17 22:21:17 +05:30
Patrick Loser 0abdff25eb feat: Add Settings and Translations (#548)
* started setting repositioning

* started setting repositioning

* added novel badges and sort to general + some js to ts

* translations General

* readersettingsscreen + fix font style selection in Bottomsheet

* started setting repositioning

* added novel badges and sort to general + some js to ts

* translations General

* readersettingsscreen + fix font style selection in Bottomsheet

* update

* ts map

* small fix
2023-02-17 21:39:30 +05:30
Patrick Loser f238b20f6d fix: Cleanup Sources (#545)
* removed Asada Translation (dead)

* update boxnovel.online to cratenovel

* fixed Daonovel

* updated fastnovel.net to fastnovel.org

* removed JPMTL (dead)

* removed Kisslightnovels (dead)

* removed Asada Translation (dead)

* update boxnovel.online to cratenovel

* fixed Daonovel

* updated fastnovel.net to fastnovel.org

* removed JPMTL (dead)

* removed Kisslightnovels (dead)

* update latestnovel to lightnovelfull (Doesn't work since there are multiple pages and can't find source API)

* fixed LightNovelReader search and metadata

* added ts-ignore to sourceManager

* removed LightNovelsHub (dead)

* fixed lnmtl metadata

* update mtnovel to novelfull.net

* fixed MTL-Novel

* removed MTL-Corner (dead)

* fixed mylovenovel

* removed NovelCake (dead)

* removed NovelOwl (is lightnovelfull.com)

* removed NovelPassion (dead)

* removed NovelsCafe (dead)

* removed NovelsRock (dead)

* removed noveltrench (dead)

* fixed novelupdatescc partly (can't open Novel)

* fixed OnlyMTL

* tried fix still broken but lists some novels

* removed SkyNovel (dead)

* changed scraping page of wuxiacity

* removed wuxiaworldcloud (dead)

* fixed wuxiaworld.site

* removed wuxiaworldsite (broken website)

* removed Asada Translation (dead)

* update boxnovel.online to cratenovel

* fixed Daonovel

* updated fastnovel.net to fastnovel.org

* removed JPMTL (dead)

* removed Kisslightnovels (dead)

* update latestnovel to lightnovelfull (Doesn't work since there are multiple pages and can't find source API)

* fixed LightNovelReader search and metadata

* added ts-ignore to sourceManager

* removed LightNovelsHub (dead)

* fixed lnmtl metadata

* update mtnovel to novelfull.net

* fixed MTL-Novel

* removed MTL-Corner (dead)

* fixed mylovenovel

* removed NovelCake (dead)

* removed NovelOwl (is lightnovelfull.com)

* removed NovelPassion (dead)

* removed NovelsCafe (dead)

* removed NovelsRock (dead)

* removed noveltrench (dead)

* fixed novelupdatescc partly (can't open Novel)

* fixed OnlyMTL

* tried fix still broken but lists some novels

* removed SkyNovel (dead)

* changed scraping page of wuxiacity

* removed wuxiaworldcloud (dead)

* fixed wuxiaworld.site

* removed wuxiaworldsite (broken website)

* fixed errors

* removed readfreenovel (without js list only kidsbooks and crashes the app)

* small change
2023-02-17 16:40:05 +05:30
Nyagami cc9022cf12 fix: App Crashing when Deleting Downloaded Chapter (#549)
* fix: app crashes when deleting downloaded chapter

* fix lint
2023-02-17 09:23:05 +05:30
Rajarshee Chatterjee fbadd41733 Minor Fix 2023-02-17 09:19:57 +05:30
Rajarshee Chatterjee c30b884428 refactor: Replace lodash with lodash-es 2023-02-17 09:17:28 +05:30
dependabot[bot] 8fc9e04d97 chore(deps): bump @sideway/formula from 3.0.0 to 3.0.1 (#532)
Bumps [@sideway/formula](https://github.com/sideway/formula) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/sideway/formula/releases)
- [Commits](https://github.com/sideway/formula/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: "@sideway/formula"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-17 09:00:44 +05:30
dependabot[bot] 84bc83b7a2 chore(deps): bump ua-parser-js from 0.7.31 to 0.7.33 (#519)
Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 0.7.31 to 0.7.33.
- [Release notes](https://github.com/faisalman/ua-parser-js/releases)
- [Changelog](https://github.com/faisalman/ua-parser-js/blob/master/changelog.md)
- [Commits](https://github.com/faisalman/ua-parser-js/compare/0.7.31...0.7.33)

---
updated-dependencies:
- dependency-name: ua-parser-js
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-17 09:00:36 +05:30
dependabot[bot] 2bb0c28591 chore(deps): bump minimatch from 3.0.4 to 3.1.2 (#469)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-17 09:00:09 +05:30
dependabot[bot] 52ae111e98 chore(deps): bump @xmldom/xmldom from 0.7.5 to 0.7.9 (#491)
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.7.5 to 0.7.9.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.7.5...0.7.9)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-17 08:59:51 +05:30
dependabot[bot] ecd383b586 chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#490)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-17 08:59:41 +05:30
Rajarshee Chatterjee 606b2c8f12 Cleanup 2023-02-17 08:55:36 +05:30
Nyagami d9bbae444a refactor: Remove Text Reader (#538)
* auto scroll using saved position.
not using currentScroll cause it maybe baka sometimes

* merge 2 navigate chapter function

* merge text and web scroll. enable scrollToTop for web

* seekbar display better after sliding

* minor fix

* trying to remove wvUseNewSwipes var

* Starting remove TextView.
Firstly, always use WebView

* remove useWebViewForChapter var

* remove TextView related thing

* scroll to save position when layout on

* always scroll with mooth mode

* no need scrollview

* move volume scroll effect

* complete the removal

* Better logic for volumeButton.
change state name

* also rename showsipemargins state

* drawerSwipe doesnt support webview.
So maybe re-implement if it supports one day

* update logic for autoScroll

* wrap useCallback for saveProgress

* only position state is enough

* remove reset progree in mark as read action

* mini fix for volumebutton. rename state variables

* fix bug on volumeButton.
2023-02-17 05:08:16 +05:30
K1ngfish3r 2e9a7adc2c fix(source): Add Author and Status for WPMangaStreamScraper (#547)
Closes LNReader/lnreader-sources#444
2023-02-17 04:57:59 +05:30
K1ngfish3r 63909bf52e fix(source): Update WPMangaStreamScraper's Cover Selector (#543)
* fixes images on noblemtl

* fix images on noblemtl

* fix ESLint errors
2023-02-15 23:18:58 +05:30
Vigneshwar M 8fe1dacab0 feat(source): Add Agitoon (#542)
* add: kr sources

* add: latest/popular novels

* bug: parseNovelAndChapters()

* fix: parse parseNovelAndChapters bug and add: parseChapter

* add: search feature

* add: popular gets the popular list of the current day; refactor

* fix: 'chapterId doesnt exist'

* fix: reverted back the package-lock.json file

---------

Co-authored-by: Vigneshwar M <vigneshwarm@Vigneshwars-MacBook-Pro.local>
2023-02-15 22:39:20 +05:30
Rajarshee Chatterjee a193656cb2 Update Crowdin configuration file 2023-02-15 09:53:55 +05:30
Rajarshee Chatterjee ed23040287 chore: Update Translation Locales 2023-02-15 09:48:11 +05:30
Rajarshee Chatterjee c9d834a2f0 chore: Update translations (#521)
* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]
2023-02-14 15:21:32 +05:30
Nyagami 7faabc5d9c fix: Update Seekbar Position Logic (#535)
* fix slider displays uncorrectly, rearrange seekbar props

* Removal contensize variable, using math to solve.
Also need percen of device height as float.
Format readerscreen.js easilier to read (at least for me :>)

* set loadding when "scroll to" is unnecessary

* enable scroll even on loading (no making re-rerender)

* add attributes to chapter element for custom css

* shorten variable name. remove unuse function

* seekbar display more correctly for webview.
removal duplicate var

* trying to removal webViewScroll state

* Seekbar should work properly.
Need to implement save position.
And sync TextView and WebView

* just rearrange props to make easier for handling

* using state currentScroll instead of scrollPercentage

* share offsetY between text and web view.
Still issue when turn back from web to text. It cant scroll back.

* this should work well, unless users touch so fast

* clean up code

* use Promise.all instead

* the same logic but shoten code

* not saving croll when closing layout
2023-02-14 15:19:43 +05:30
Rajarshee Chatterjee 330abf25d7 fix(source): Add reverseChapters Option in WPMangaStreamScraper 2023-02-14 15:15:51 +05:30
Rajarshee Chatterjee d75ef3f444 feat(source): Add NobleMtl
Closes LNReader/lnreader-sources #409
2023-02-13 09:42:49 +05:30
Rajarshee Chatterjee 6e665dabf4 fix(source): Add sourceId in WPMangaStreamScraper 2023-02-13 09:42:49 +05:30
Nyagami 12b83f4de7 fix: Simplify TTS Logic to Prevent Freezing the App (#530)
* simply tts to prevent it freezes the app

* ensure tts uses the chapter text. correct spelling
2023-02-09 13:07:43 +05:30
Rajarshee Chatterjee 518f73f6fd Update README.md 2023-01-31 07:49:45 +05:30
Rajarshee Chatterjee cab9a83dc0 Release v1.1.14 2023-01-29 20:53:08 +05:30
Rajarshee Chatterjee 934798809d Minor Fixes 2023-01-29 20:45:49 +05:30
Rajarshee Chatterjee 4ceacdf324 fix(source): IndoWebNovel
Closes LNReader/lnreader-sources#405
2023-01-29 18:24:13 +05:30
Rajarshee Chatterjee 650ed2ff67 Minor Fixes 2023-01-29 18:22:30 +05:30
Rajarshee Chatterjee c38fc3232e chore: Update translations (#493)
* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]
2023-01-29 17:11:26 +05:30
Rajarshee Chatterjee f109c5747e fix: Fix Lint 2023-01-29 17:09:07 +05:30
Rajarshee Chatterjee 79b4db0cd2 fix: Reader Settings Screen Crash (Closes #322) 2023-01-29 17:05:11 +05:30
Rajarshee Chatterjee 8858ea3d94 fix(source): Minor Fixes 2023-01-29 17:03:59 +05:30
Rajarshee Chatterjee dea534557e fix(source): Ranobes
Closes LNReader/lnreader-sources#435
2023-01-29 16:20:08 +05:30
Rajarshee Chatterjee 0b112d9465 Minor Fixes 2023-01-29 16:09:00 +05:30
Rajarshee Chatterjee ddb8cd402a refactor: Use Batch Queries 2023-01-29 15:14:00 +05:30
Rajarshee Chatterjee 172145278f feat: Bypass Cloudflare
Closes LNReader/lnreader-sources#146
Closes LNReader/lnreader-sources#172
Closes LNReader/lnreader-sources#150
Closes LNReader/lnreader-sources#319
Closes LNReader/lnreader-sources#397
Closes LNReader/lnreader-sources#404
Closes LNReader/lnreader-sources#406
Closes LNReader/lnreader-sources#407
Closes LNReader/lnreader-sources#411
2023-01-29 14:53:42 +05:30
Rider21 7acb63e0f0 fix(source): Jaomix (#520)
* fix

* Update jaomix.js
2023-01-29 10:56:54 +05:30
Patrick Loser deefc10d41 feat: New Bottom Sheet Package (#515)
* setup

* implemented new bottomsheets

* set containerHeight

* NovelBottomSheet fix

* fixed BottomInsets

* edited FilterBottomSheet + cleanup

* TrackSheet + cleanup

* removal of rn-sliding-up-panel

Closes #506
2023-01-13 05:02:45 +05:30
Patrick Loser 7880cd0187 fix: Bottom Navbar Icon Color (#513)
* fixed library button color

* changed to onSecondaryContainer
2023-01-13 04:56:15 +05:30
Patrick Loser 9a594c4dd3 feat: Skeleton Loading Screens (#510)
* CategorySkeletonLoading

* getLoadingColors

* UpdatesSkeletonLoading

* Loading for Migrate

* HistorySkeletonLoading

* HistoryScreen fix

* HistoryScreen fix

* GlobalSearchLoading name change

* SourceScreenSkeletonLoading + implementation in Library + set unread fix

* set SkeletonLoading for LoadingMoreIndicator

* ESLint fix
2023-01-11 06:52:53 +05:30
Rajarshee Chatterjee 11a32d6776 fix: Mark Chapter as Read on TTS Finish (Closes #466) 2022-12-30 10:36:11 +05:30
Rajarshee Chatterjee 49e4e87f9e feat: Add Error Boundary 2022-12-30 10:28:54 +05:30
Rajarshee Chatterjee 1d0d7be968 Minor Fixes 2022-12-30 10:20:59 +05:30
Patrick Loser 06c5efd3a6 feat: Skeleton Loading Screens (#504)
* chapter drawer themed textcolor

* started with skeleton loading

* added new package

* added way to adebt to reader styles

* MAL loading

* type fix

* SourceScreenLoading

* NovelScreenLoading

* ESLint fix

* cleanup

* resolved conflict

* GlobalSearchLoading

Co-authored-by: Patrick <patrick.los@proton.me>
2022-12-28 13:20:44 +05:30
Patrick Loser 6d67c67d5f feat: Animated Splashscreen (#499)
* chapter drawer themed textcolor

* animated splashscreen

* added lotti animation

* splashscreen centered

* upgrade to android sdk 31

* reverted sdk changes

* fixed unstyled bars

* fixed animation

Co-authored-by: Patrick <patrick.los@proton.me>
2022-12-22 16:03:49 +05:30
Patrick Loser e559824718 feat: FAB for Last Read Chapter in Library (#500)
* chapter drawer themed textcolor

* added FAB to Library screen + some insets

* Added Settings butten

Co-authored-by: Patrick <patrick.los@proton.me>
2022-12-20 21:39:30 +05:30
Patrick Loser 2aaedfcfbf feat: Adaptive Icon (#497)
Closes #475

Co-authored-by: Patrick <patrick.los@proton.me>
2022-12-18 21:26:44 +05:30
Rajarshee Chatterjee 4cbd52a369 fix: Tweak Jump to Modal UI 2022-12-10 18:55:55 +05:30
Patrick Loser 87a42d2766 fix: Chapter Drawer Themed Text Color (#492)
Co-authored-by: Patrick <patrick.los@proton.me>
2022-12-10 17:08:22 +05:30
Patrick Loser 1453c39fc3 feat: Jump to Chapter Modal Redesign (#486)
* start up

* started to change jumpToChapterModal

* finished JumpToChapterModal redesign

* delete of results and no result if no text

* edited listElement width

* reverted (automatic) changes in package-lock and build.gradle

* design changes & bugfixes

* added translations

Co-authored-by: Patrick <patrick.los@proton.me>

Closes #472
2022-12-10 16:36:46 +05:30
Rajarshee Chatterjee eccb84b4a3 chore: Update translations (#448)
* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (French)
[ci skip]
2022-12-10 10:18:57 +05:30
Rajarshee Chatterjee 3d69f46b44 fix: Minor Fixes 2022-12-10 10:09:55 +05:30
Rajarshee Chatterjee cc94bbd152 fix: Tweak Chapter Drawer UI 2022-12-10 09:34:29 +05:30
Patrick Loser 599224a5d4 feat: Chapter Drawer (#485)
* start up

* started with the implementation of chapter_Drawer

* changed data transer via route and the navigation between chapters

* changed ReadButton and butten at the end of chapter

* changed ReadButton and butten at the end of chapter

* changed ReadButton and butten at the end of chapter

* worked on behaviour, added buttons and styled

* fixed Buttons

* highlighted current chapter

* fixed bug caused of fast scrolling

* Changed Padding/Margin Behaviour of WebViewReader for Drawer to work properly

* fixed gradients in chapter list

* changed GestureRecognizer back

* shorted given props at chapter change

* fixed and changed scroll behaviour

* added Translation

* Changed drawer chapter naming

* review

* added chapterDrawer setting

* unessecary

* swipe optional for normal ReaderScreen, impossible for WebView, openDrawerButton in the middle of footer

* changed setting name "chapterDrawer" to "useChapterDrawerSwipeNavigation"

* put useNovel Hook in chapterDrawer and reverted navigate functions

* reverted changes from original ReaderScreen line 356-359

* removed Chapter transformation

* fixed switch between chapters and mistake in switch

* unified nacigation Params + changed name and location of handleNavigateChapterParams

* fixed loading problems from other screens than Novel and added LoadingScreenV2

Co-authored-by: Patrick <patrick.los@proton.me>
Co-authored-by: Patrick Loser <69157453+AustriaGamer@users.noreply.github.com>
2022-12-10 08:39:43 +05:30
Rajarshee Chatterjee 70a22518be fix(source): NovelUpdates: Add WordPress Selector
Closes LNReader/lnreader-sources#412
2022-12-09 21:15:29 +05:30
Rajarshee Chatterjee 900a569886 fix(source): NovelRingan: Remove Duplicated Chapter Text
Closes LNReader/lnreader-sources#414
2022-12-09 10:44:19 +05:30
Rajarshee Chatterjee 6e851eed94 fix(source): ReadLightNovel Search
Closes LNReader/lnreader-sources#371
2022-12-09 10:27:17 +05:30
Rajarshee Chatterjee a2ceba9019 fix(source): ReinoWuxia
Closes LNReader/lnreader-sources#186
2022-12-09 10:11:29 +05:30
Rajarshee Chatterjee 412f216bf5 fix(source): ReadNovelFull
Closes LNReader/lnreader-sources#325
2022-12-09 09:58:09 +05:30
dependabot[bot] 1e2dddf46c chore(deps): bump qs from 6.10.1 to 6.10.3 (#488)
Bumps [qs](https://github.com/ljharb/qs) from 6.10.1 to 6.10.3.
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.10.1...v6.10.3)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-08 09:10:30 +05:30
Rider21 3e526658bf fix(source): Ranobes (#489) 2022-12-07 09:22:59 +05:30
Rider21 15cdeb30ad fix(source): Update Rulate (#483)
update
2022-12-02 07:03:47 +05:30
Marcin Majewski 3cb573681f fix(delete_chapter): Excessive number of pending callbacks warn (#481)
* fix(delete_chapter): fix delete all not working

Sometimes there would be "Excessive number of pending callbacks" warn shown.
Removing chapters in batches of 10 (I tried 30 but it was still an issue) seems to work fine now.
TODO: Add some icon about deletion status and make it not lag the entire app.

* fix(delete_chapter): always-coccurent deletion

Make deleting chapters do 3 coccurent deletion at a time making it work similarly to bluebird's `Promise.map(,{coccurent:3})` and removing the `Excessive number of pending callbacks` warn gone.

* Remove unnecesarry console.log
2022-11-26 06:48:53 +05:30
Rajarshee Chatterjee 383c8f791b fix: Stats Screen Fixes 2022-11-05 23:13:02 +05:30
Rajarshee Chatterjee 125632b9ff fix: Workaround for Build Failures
https://github.com/facebook/react-native/issues/35210
2022-11-05 23:12:29 +05:30
Rider21 cb67d17747 Fix Date String (#457)
* typo correction

* fix image

* agree
2022-10-26 17:43:11 +05:30
Rajarshee Chatterjee 7ec578639e feat: Stats Screen 2022-10-24 08:08:28 +05:30
Rajarshee Chatterjee a1d6e1d6ce fix(source): WBNovel: Update Language
Closes LNReader/lnreader-sources##408
2022-10-24 07:02:04 +05:30
Rajarshee Chatterjee 1fed66792d build: Upload Artifact 2022-10-22 09:57:26 +05:30
Rajarshee Chatterjee abc815e413 Revert "chore(deps): bump react-native-reanimated from 2.2.4 to 2.10.0" (#455)
Revert "chore(deps): bump react-native-reanimated from 2.2.4 to 2.10.0 (#452)"

This reverts commit 8cb27bf95f.
2022-10-21 17:02:49 +05:30
dependabot[bot] 8cb27bf95f chore(deps): bump react-native-reanimated from 2.2.4 to 2.10.0 (#452)
Bumps [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) from 2.2.4 to 2.10.0.
- [Release notes](https://github.com/software-mansion/react-native-reanimated/releases)
- [Commits](https://github.com/software-mansion/react-native-reanimated/compare/2.2.4...2.10.0)

---
updated-dependencies:
- dependency-name: react-native-reanimated
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-21 16:44:28 +05:30
Rajarshee Chatterjee a84ee5ade4 chore: Update translations (#424)
* New translations strings.json (French)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]
2022-10-10 20:01:49 +05:30
Rajarshee Chatterjee 30ce798c2a feat(source): Add WebNovelOku (Closes LNReader/lnreader-sources#378) 2022-10-10 19:59:22 +05:30
Rajarshee Chatterjee 5ed221648c fix: Add Cloudflare Error Message for LightNovelPub 2022-09-27 21:01:11 +05:30
Rajarshee Chatterjee 93bc5f19ff fix: Update NovelTrench baseUrl (Closes LNReader/lnreader-sources#385) 2022-09-27 08:56:12 +05:30
Rider21 d527319901 feat(source): Add AuthorToday (#434)
* AuthorToday

* fix

* prettier

* test

* ok
2022-09-11 11:57:18 +05:30
Rhino 20470929e5 fix: updates tab sort as data displayed is wrong when release datetime similar (#427)
* Added following sources Zetro Translation, Nocturne, Asada Translation and Sugar Babies

* added time stamp to backup file

* fixed: updates tab sort as data displayed is wrong when release datetime similar
2022-09-10 17:19:15 +05:30
J. Fronny 69dc329fdb build: Generate versionCode (#432)
* Generate versionCode

* Fix comment
2022-09-10 17:18:27 +05:30
Rajarshee Chatterjee 78165b072e Release v1.1.13 2022-09-02 09:30:49 +05:30
Rajarshee Chatterjee d749225820 chore: Update translations (#343)
* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Indonesian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Russian)
[ci skip]
2022-09-02 09:30:32 +05:30
Rajarshee Chatterjee d6d487101b feat(source): Add Madara Sources
Closes LNReader/lnreader-sources#365
Closes LNReader/lnreader-sources#363
2022-08-28 11:49:05 +05:30
Rajarshee Chatterjee ba62c1ba0a Minor Fixes 2022-08-28 11:37:04 +05:30
Rajarshee Chatterjee 75f4f18448 Minor Fixes 2022-08-28 11:05:25 +05:30
Rajarshee Chatterjee f9ebec4a30 fix: Global Search Navigation (Closes #406) 2022-08-28 10:56:05 +05:30
Rajarshee Chatterjee de18e3d9d8 fix: Category Fixes 2022-08-28 10:56:05 +05:30
Rajarshee Chatterjee acaac74db4 fix: Add Chapter Name Back in Reader (Closes #410) 2022-08-28 10:56:05 +05:30
Rajarshee Chatterjee d8845661a7 fix: Long Category Names (Closes #407) 2022-08-28 10:56:05 +05:30
Rider21 b66a6130c5 feat(source): Add Ficbook (#409)
* update

* fix

* oops
2022-08-25 07:15:34 +05:30
Rhino 220f25bf72 feat: Update chapter tab sort (#402)
* Added following sources Zetro Translation, Nocturne, Asada Translation and Sugar Babies

* added time stamp to backup file

* tweaks updated chapter sort order in Updates Tab
2022-08-25 07:12:45 +05:30
Rajarshee Chatterjee 934edbb84c feat: Add Change Default Category (Closes #383) 2022-08-18 21:16:35 +05:30
Rajarshee Chatterjee 0d8a5d6172 fix: Navbar Color (Closes #386) 2022-08-18 21:13:36 +05:30
Rajarshee Chatterjee e706745f30 feat: Select Current Category in Library (Closes #396) 2022-08-18 09:43:05 +05:30
Rajarshee Chatterjee dce3652ae8 feat: Add Select All in Library (Closes #380) 2022-08-18 09:07:12 +05:30
Rajarshee Chatterjee 0ca3b8ce15 fix: Cleanup
Closes #378
Closes #393
2022-08-18 08:40:49 +05:30
Rajarshee Chatterjee c62db5cb23 chore: Update Source Icon Links 2022-08-18 07:44:55 +05:30
Rajarshee Chatterjee e33b433e84 fix: Change status bar style on background color change (Closes #150) 2022-08-17 08:18:12 +05:30
Rhino c95f376e20 feat(source): Add following sources Zetro, Nocturne, Asada and SugarBB (#389)
* Added following sources Zetro Translation, Nocturne, Asada Translation and Sugar Babies

* added time stamp to backup file
2022-08-16 23:20:00 +05:30
Rhino 9b45375638 feat: Add time stamp to backup file (#390) 2022-08-16 23:17:03 +05:30
Rajarshee Chatterjee 7fbdc6732c fix: Reset Category to default on removing from current category (Closes #379) 2022-08-16 13:27:54 +05:30
Rajarshee Chatterjee 3f9549d320 fix: Path Aliases 2022-08-16 13:03:29 +05:30
Rajarshee Chatterjee 079010b6ca chore: Fix Issue Template Label 2022-08-16 13:00:34 +05:30
Rajarshee Chatterjee 107e534565 Cleanup 2022-08-16 12:38:13 +05:30
Rajarshee Chatterjee f0665866ae feat: Custom Order in Categories (Closes #376) 2022-08-16 10:56:08 +05:30
Rajarshee Chatterjee 706b4581b1 fix: Hide "Removed from library" toast if novel is in library 2022-08-16 07:26:06 +05:30
Rajarshee Chatterjee a8d9c3abfa chore: Add Issue Templates and Moderator 2022-08-15 20:27:19 +05:30
Rajarshee Chatterjee 66798c46db Minor fixes
Closes #373
Closes #374
2022-08-15 16:51:21 +05:30
Rajarshee Chatterjee 87fa081cfd feat: Material You (#377)
* feat: Material You

* feat: Material You
2022-08-15 15:36:06 +05:30
Rajarshee Chatterjee ea26cd67e4 fix(source): Add Status in Ranobes (Closes LNReader/lnreader-sources#359) 2022-08-14 15:44:09 +05:30
Rajarshee Chatterjee 9400fcd252 feat(source): Add NeoSekai Translations and MTL-Novel
Closes LNReader/lnreader-sources#306
Closes LNReader/lnreader-sources#328
2022-08-14 15:43:22 +05:30
Rajarshee Chatterjee 30ca05df06 feat: Add novel in library on long press in search results (Closes #151) 2022-08-14 13:00:21 +05:30
Rajarshee Chatterjee eac3ee32c8 fix: Add Empty Summary placeholder and show Full Novel Title (Closes #355) 2022-08-14 11:43:49 +05:30
Rajarshee Chatterjee 0cf249eec5 fix: Use Separate States for Search Results in Browse Screen (Closes #359) 2022-08-14 11:15:56 +05:30
Rajarshee Chatterjee 27e5300f4f fix: Clear Searchbar when Screen is Unfocused (Closes #358) 2022-08-14 11:13:10 +05:30
Rajarshee Chatterjee 97e02177a4 fix: Global Search from Novel and MAL Screen (Closes #356) 2022-08-14 10:23:04 +05:30
Rajarshee Chatterjee 42b37f87fe fix(source): Remove NovelSpace and Move ArNovel to MadaraGenerator
(Closes LNReader/lnreader-sources#353)
2022-08-14 10:06:03 +05:30
Rajarshee Chatterjee 4ad1c0253b fix: Reset Novel Categories on deleting a Category (Closes #370) 2022-08-14 09:52:00 +05:30
Rajarshee Chatterjee a57ed7a7a2 feat: Add category-wise updates 2022-08-14 09:30:16 +05:30
Rajarshee Chatterjee 9fa00d9d9b fix(source): Update WuxiaWorldCo baseUrl 2022-08-14 09:28:33 +05:30
Rajarshee Chatterjee 18f63a217f fix: Category/Library bugs 2022-08-14 07:44:53 +05:30
Rajarshee Chatterjee 05401ada6b fix: Fix deleting downloaded chapters (Closes #341) 2022-08-14 07:02:25 +05:30
Rajarshee Chatterjee e256537079 feat: Add Categories (#366)
* feat: Add Categories (Closes #45)

* fix: ESLint Errors

* feat: Add Validation for Duplicate Category Name

* feat: Multiple Categories Support & Hide Default Category

* fix: Creating Tables on Clean Installation

* feat: Add Started Filter
2022-08-13 23:07:58 +05:30
Rider21 0eec38f26f feat: Source Updates (#350)
- Fix ranobes.net (Closes LNReader/lnreader-sources#70)
- Add ranobes.com source
2022-08-05 21:22:24 +05:30
Rider21 fa90d57eff refactor: Replace moment with Dayjs (#346)
* dayjs

* locales added

* fix
2022-08-02 13:17:45 +05:30
Rajarshee Chatterjee fd6a907c5f Release v1.1.12 2022-07-30 21:36:45 +05:30
Rajarshee Chatterjee c7561fc3dd fix: New Update Dialog Enhancements 2022-07-30 21:33:26 +05:30
Rajarshee Chatterjee e1401ba39f fix(source): Fix Riwyat Chapter Text 2022-07-30 21:32:20 +05:30
Rajarshee Chatterjee cbb3c7cfa2 Release v1.1.11 2022-07-30 09:53:23 +05:30
Rajarshee Chatterjee 4b515502bf fix(source): Fix ComradeMao (Closes LNReader/lnreader-sources#215) 2022-07-30 08:53:25 +05:30
Rajarshee Chatterjee baba8814f0 fix(source): Fix TravisTranslations Chapter Selector (Closes LNReader/lnreader-sources#339) 2022-07-30 08:52:59 +05:30
Rajarshee Chatterjee 5b01f61c9f feat(source): Add Novelstic (Closes LNReader/lnreader-sources#345) 2022-07-30 08:46:35 +05:30
Rajarshee Chatterjee c02a72018d fix: Remove Text Selectable Option (Closes #332) 2022-07-30 08:09:32 +05:30
Rajarshee Chatterjee 4d446d7c0b fix: Chapter not available when navigating from History/Updates (Closes #336) 2022-07-30 07:59:18 +05:30
Marcin Majewski e580f8f151 fix(wv-reader): Remove unnecesarry console.logs() (#331) 2022-07-21 21:23:26 +05:30
Rajarshee Chatterjee 92f164fc23 feat(source): Add Riwyat (Closes LNReader/lnreader-sources#332) 2022-07-21 20:35:08 +05:30
Rajarshee Chatterjee 44c805b6f2 feat(source): Add Light Novels Brasil (Closes LNReader/lnreader-sources#335) 2022-07-21 20:22:48 +05:30
Rajarshee Chatterjee d3f5619276 feat: Add option to disable Haptic Feedback (Closes #326) 2022-07-21 20:15:34 +05:30
Rajarshee Chatterjee 0261c6373d chore: Add Strings 2022-07-21 20:05:46 +05:30
Rajarshee Chatterjee fd5b9a7c17 chore: Update translations (#329)
* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]
2022-07-21 20:04:23 +05:30
Rajarshee Chatterjee b884600dfb chore: Update translations (#296)
* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (German)
[ci skip]

* New translations strings.json (Hungarian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

* New translations strings.json (Vietnamese)
[ci skip]

* New translations strings.json (Chinese Traditional)
[ci skip]

* New translations strings.json (Chinese Simplified)
[ci skip]

* New translations strings.json (Swedish)
[ci skip]

* New translations strings.json (Serbian (Cyrillic))
[ci skip]

* New translations strings.json (Albanian)
[ci skip]

* New translations strings.json (Portuguese)
[ci skip]

* New translations strings.json (Polish)
[ci skip]

* New translations strings.json (Norwegian)
[ci skip]

* New translations strings.json (Dutch)
[ci skip]

* New translations strings.json (Korean)
[ci skip]

* New translations strings.json (Japanese)
[ci skip]

* New translations strings.json (Hebrew)
[ci skip]

* New translations strings.json (Italian)
[ci skip]

* New translations strings.json (Finnish)
[ci skip]

* New translations strings.json (Greek)
[ci skip]

* New translations strings.json (Danish)
[ci skip]

* New translations strings.json (Czech)
[ci skip]

* New translations strings.json (Catalan)
[ci skip]

* New translations strings.json (Afrikaans)
[ci skip]

* New translations strings.json (Spanish)
[ci skip]

* New translations strings.json (French)
[ci skip]

* New translations strings.json (Romanian)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Hindi)
[ci skip]

* New translations strings.json (Turkish)
[ci skip]

* New translations strings.json (Arabic)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* New translations strings.json (Russian)
[ci skip]

* chore: add french translation (#315)

Some small hesitations on how to translate :
    - "Offset" is difficult to translate with this context
    - "Badges" For me, it's "a small piece of metal, plastic, or cloth bearing a design or words, typically worn to identify a person or to indicate membership of an organization or support for a cause." (I know it can be virtual but I'm not sure I have the context of the application but it is a transparent word according to this definition)
    - "grid" translated into "grille" is a bit weird
    - Should I translate "Novel" by its translation ("roman") ?

* New translations strings.json (Ukrainian)
[ci skip]

* New translations strings.json (Portuguese, Brazilian)
[ci skip]

Co-authored-by: Raphael <67842535+Snowad14@users.noreply.github.com>
2022-07-21 19:28:09 +05:30
dependabot[bot] 8355907a76 chore(deps): bump moment from 2.29.2 to 2.29.4 (#327)
Bumps [moment](https://github.com/moment/moment) from 2.29.2 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.2...2.29.4)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-21 19:27:45 +05:30
Marcin Majewski b391e09e53 feat(img-dl): Downloading the chapter now downloads all img files (#321)
* fix(lint): fixed ChapterQueries.ts linting

* feat(img_download): Download images for offline reading

* fix(dl): imgs in Downloads/LNReader/source/novel/chapter

* fix(dl): deleteChapter now requires novelId/sourceId to remove images
2022-07-20 16:41:38 +05:30
Marcin Majewski a4c27924f8 fix(source): Fix NovelUpdates genres (#318) 2022-07-05 20:57:10 +05:30
Rider21 221c77d2cb feat(source): Add NovelTop1 (#313)
* test

* add NovelTop1

* ok
2022-07-01 22:22:02 +05:30
Rider21 3a0047ee25 feat: Moment Sync (#310)
* moment locale sync

* da
2022-06-26 17:45:52 +05:30
Rajarshee Chatterjee 3afbb5c45d feat: Add Option to Delete Read Chapters 2022-06-19 09:16:09 +05:30
Rajarshee Chatterjee 47102ff65e feat(source): Add More Filters 2022-06-19 08:12:22 +05:30
Rider21 c10eac6cd6 feat(source): Source Updates (#306)
* update

* sort

* removed the special characters
2022-06-19 06:27:34 +05:30
Rajarshee Chatterjee b4c234ef93 feat(source): Add Madara Sources
Closes LNReader/lnreader-sources#247, Closes LNReader/lnreader-sources#271, Closes LNReader/lnreader-sources#273, Closes LNReader/lnreader-sources#284
2022-06-18 13:57:39 +05:30
Rajarshee Chatterjee 3487bbd4cf Minor fixes 2022-06-18 13:37:52 +05:30
Rajarshee Chatterjee bece88663f refactor: Global Search Screen
Closes #302
2022-06-18 12:32:15 +05:30
dependabot[bot] 054124a004 chore(deps): bump jpeg-js from 0.4.3 to 0.4.4 (#301)
Bumps [jpeg-js](https://github.com/eugeneware/jpeg-js) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/eugeneware/jpeg-js/releases)
- [Commits](https://github.com/eugeneware/jpeg-js/compare/v0.4.3...v0.4.4)

---
updated-dependencies:
- dependency-name: jpeg-js
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-17 08:39:26 +05:30
Rider21 d2b62c0e8b feat: Source Updates (#297)
* update

* xm
2022-06-14 06:19:06 +05:30
Rajarshee Chatterjee e98980bdb9 chore: Update translations (#279)
* New translations strings.json (German)

* New translations strings.json (Russian)

* New translations strings.json (Ukrainian)

* New translations strings.json (Arabic)

* New translations strings.json (German)

* New translations strings.json (Hungarian)

* New translations strings.json (Vietnamese)

* New translations strings.json (Chinese Traditional)

* New translations strings.json (Swedish)

* New translations strings.json (Serbian (Cyrillic))

* New translations strings.json (Albanian)

* New translations strings.json (Portuguese)

* New translations strings.json (Polish)

* New translations strings.json (Norwegian)

* New translations strings.json (Dutch)

* New translations strings.json (Korean)

* New translations strings.json (Japanese)

* New translations strings.json (Hebrew)

* New translations strings.json (Italian)

* New translations strings.json (Finnish)

* New translations strings.json (Greek)

* New translations strings.json (Danish)

* New translations strings.json (Czech)

* New translations strings.json (Catalan)

* New translations strings.json (Afrikaans)

* New translations strings.json (Spanish)

* New translations strings.json (French)

* New translations strings.json (Romanian)

* New translations strings.json (Arabic)

* New translations strings.json (Ukrainian)

* New translations strings.json (Turkish)

* New translations strings.json (Russian)

* New translations strings.json (Portuguese, Brazilian)

* New translations strings.json (Turkish)

* New translations strings.json (German)

* New translations strings.json (Hungarian)

* New translations strings.json (Vietnamese)

* New translations strings.json (Chinese Traditional)

* New translations strings.json (Swedish)

* New translations strings.json (Serbian (Cyrillic))

* New translations strings.json (Albanian)

* New translations strings.json (Portuguese)

* New translations strings.json (Polish)

* New translations strings.json (Norwegian)

* New translations strings.json (Dutch)

* New translations strings.json (Korean)

* New translations strings.json (Japanese)

* New translations strings.json (Hebrew)

* New translations strings.json (Italian)

* New translations strings.json (Finnish)

* New translations strings.json (Greek)

* New translations strings.json (Danish)

* New translations strings.json (Czech)

* New translations strings.json (Catalan)

* New translations strings.json (Afrikaans)

* New translations strings.json (Spanish)

* New translations strings.json (French)

* New translations strings.json (Romanian)

* New translations strings.json (Arabic)

* New translations strings.json (Ukrainian)

* New translations strings.json (Turkish)

* New translations strings.json (Russian)

* New translations strings.json (Portuguese, Brazilian)
2022-06-13 09:57:21 +05:30
Rajarshee Chatterjee 62a847acb2 build: Skip CI in translations 2022-06-13 09:38:57 +05:30
Rajarshee Chatterjee 13f394c76d build: Only run CI on main branch 2022-06-13 09:11:30 +05:30
Marcin Majewski 71f6d863c0 fix(reader-settings): Fix reader settings crash (#292) 2022-06-13 08:21:25 +05:30
Rajarshee Chatterjee d5a8ca2b47 feat(source): Add Liebe Schnee Hiver Novel (Closes LNReader/lnreader-sources#232) 2022-06-12 21:15:25 +05:30
Rajarshee Chatterjee c969916cd5 feat(source): Initial Source Filter Support (Closes #285) 2022-06-12 20:27:57 +05:30
Rajarshee Chatterjee e68c72ce02 fix(source):Fix ReadLightNovel's Novel Info 2022-06-12 13:53:15 +05:30
Rajarshee Chatterjee 5f83104171 feat: Add Ability to View Latest Novels 2022-06-12 13:50:16 +05:30
Rajarshee Chatterjee 7837d7cdaf feat: Add Option to Remove Extra Paragraph Spacing (Closes #248) 2022-06-12 13:01:10 +05:30
Rajarshee Chatterjee b243d764ce feat: Add New Themes (Closes #254) 2022-06-12 12:05:39 +05:30
Rajarshee Chatterjee 56c7716595 fix: Cross Icon Overlapping Search Text (Closes #273) 2022-06-12 11:23:34 +05:30
Rajarshee Chatterjee d44abc9039 feat: Add Last Read Sorting (Closes #255) 2022-06-12 09:20:26 +05:30
Rajarshee Chatterjee 6f30bfeeab fix: Add progressViewOffset (Closes #270) 2022-06-12 08:58:50 +05:30
Rajarshee Chatterjee 3d90e04415 fix: Global Search (Closes #256) 2022-06-12 08:51:49 +05:30
Rajarshee Chatterjee 23e27e8d40 fix(source): HakoLightNovel (Closes LNReader/lnreader-sources#239) 2022-06-12 08:48:14 +05:30
Marcin Majewski d0f7e25956 feat(volume-scroll): Added option to scroll WebView using volume buttons (#290)
* feat(volume-scroll): Added webview volume scroll

Scrolling with volume buttons in WebView

* feat(volume-settings): Add volume button settings
2022-06-12 07:47:39 +05:30
Rajarshee Chatterjee 9b297620fe refactor: Browse Source Screen 2022-06-06 07:58:07 +05:30
Marcin Majewski df851bf9d1 Webview improvements (#283)
* feat(webview): Added few webview improvements

Added buttons from TextReader on the bottom of the chapter (Closes #250)
Added webview seekbar (Closes #218)
Switched the handling of the navigation bar visibility to WebView. This might solve the issue from #229 because WebView is a bit more strict in what it interprets as "click/tap"
Migrating WebViewReader.js to TypeScript

* fix(webview): Removed unnecesarry console.logs

* feat(wv-autoscroll): WebView AutoScroll

* feat(wv-swipes): WebView new swipe detection

Added webview internal swipe detection instead of the react-native one
Hopefully making the detection a bit better (effects unknown yet)
This option can be turned on/off in the settings

* fix(wv-scrollbar): Added option to switch vertical

You can now switch vertical/horizontal scrollbar setting in reader screen options
2022-06-05 07:24:36 +05:30
Rajarshee Chatterjee 5fc411e14c Merge branch 'main' of https://github.com/LNReader/lnreader into main 2022-06-04 09:04:48 +05:30
Rajarshee Chatterjee 0f221b2823 fix: Build 2022-06-04 09:04:40 +05:30
Marcin Majewski 9e50159589 fix(clipboard): Fixed clipboard dependency (#282)
Closes #257
2022-06-04 08:59:31 +05:30
Rajarshee Chatterjee 58752a5589 fix: ESLint 2022-06-04 08:57:06 +05:30
Rajarshee Chatterjee c1a76458a8 fix: Novel Updates (Closes LNReader/lnreader-sources#227) 2022-06-01 05:35:34 +05:30
Rajarshee Chatterjee 5b3a6ceff4 fix: ReadLightNovel Crash 2022-06-01 05:19:32 +05:30
Rajarshee Chatterjee c4a14784f0 fix(source): Remove RewayatAr 2022-06-01 05:08:14 +05:30
Rajarshee Chatterjee d64e2e7fdb chore: Update Translations 2022-05-31 21:11:24 +05:30
Marcin Majewski 5d8463509c fix(tts): Android11 Manifest TTS Support (#277)
Add to AndroidManifest.xml a clause about querying TTS to remove `Unresolved Promise: No TTS Engine Installed` error in Android 11 Phones.
2022-05-28 09:13:46 +05:30
Marcin Majewski 5b4e32e184 fix(syosetu): Change cover to unavailable (#275)
fix(syosetu): Set cover to not available
2022-05-28 08:05:58 +05:30
Marcin Majewski a7fb3962f1 fix(typo): spelling mistake causing a crash (#276) 2022-05-28 08:05:11 +05:30
Marcin Majewski d333381959 feat(webview-scroll): webview scrolls to saved (#274)
Now webview has webViewScroll which after any change scrolls webView to given percentage

Co-authored-by: unknown <SkillGG>
2022-05-27 20:43:33 +05:30
Rajarshee Chatterjee d599e6669f chore: Update translations (#251)
* New translations strings.json (Turkish)

* New translations strings.json (Korean)

* New translations strings.json (Vietnamese)

* New translations strings.json (Chinese Traditional)

* New translations strings.json (Ukrainian)

* New translations strings.json (Swedish)

* New translations strings.json (Serbian (Cyrillic))

* New translations strings.json (Albanian)

* New translations strings.json (Russian)

* New translations strings.json (Portuguese)

* New translations strings.json (Polish)

* New translations strings.json (Norwegian)

* New translations strings.json (Dutch)

* New translations strings.json (Japanese)

* New translations strings.json (Romanian)

* New translations strings.json (Italian)

* New translations strings.json (Hungarian)

* New translations strings.json (Hebrew)

* New translations strings.json (Finnish)

* New translations strings.json (Greek)

* New translations strings.json (German)

* New translations strings.json (Danish)

* New translations strings.json (Czech)

* New translations strings.json (Catalan)

* New translations strings.json (Arabic)

* New translations strings.json (Afrikaans)

* New translations strings.json (Spanish)

* New translations strings.json (French)

* New translations strings.json (Portuguese, Brazilian)

* New translations strings.json (Turkish)

* New translations strings.json (Korean)

* New translations strings.json (Vietnamese)

* New translations strings.json (Chinese Traditional)

* New translations strings.json (Ukrainian)

* New translations strings.json (Swedish)

* New translations strings.json (Serbian (Cyrillic))

* New translations strings.json (Albanian)

* New translations strings.json (Russian)

* New translations strings.json (Portuguese)

* New translations strings.json (Polish)

* New translations strings.json (Norwegian)

* New translations strings.json (Dutch)

* New translations strings.json (Japanese)

* New translations strings.json (Romanian)

* New translations strings.json (Italian)

* New translations strings.json (Hungarian)

* New translations strings.json (Hebrew)

* New translations strings.json (Finnish)

* New translations strings.json (Greek)

* New translations strings.json (German)

* New translations strings.json (Danish)

* New translations strings.json (Czech)

* New translations strings.json (Catalan)

* New translations strings.json (Arabic)

* New translations strings.json (Afrikaans)

* New translations strings.json (Spanish)

* New translations strings.json (French)

* New translations strings.json (Portuguese, Brazilian)

* New translations strings.json (Turkish)

* New translations strings.json (German)

* New translations strings.json (German)

* New translations strings.json (Italian)

* New translations strings.json (Russian)

* New translations strings.json (Russian)
2022-05-27 05:21:49 +05:30
Rider21 5436bf8aaf fix: Source Fixes (#272)
* updated link

* small correction

* Bypass

* Update renovels.js
2022-05-27 05:14:17 +05:30
Rajarshee Chatterjee 9f6f9e71ca fix: Remove Circular Dependencies 2022-05-09 07:06:48 +05:30
Rajarshee Chatterjee 6caba807df fix:(source) 1stKissNovel: No Chapters 2022-05-08 12:29:37 +05:30
Rajarshee Chatterjee 9dabf1a60e Minor fixes 2022-05-08 12:26:29 +05:30
Rajarshee Chatterjee 7716ab75de refactor: Reader Settings Screen 2022-05-08 11:47:22 +05:30
Rajarshee Chatterjee 94b2dd51cb fix(source): ReaperScans (Closes LNReader/lnreader-sources#224) 2022-05-08 07:51:59 +05:30
Rajarshee Chatterjee 010d49daea fix: Update Icon Links 2022-05-08 07:27:31 +05:30
Rajarshee Chatterjee 6eb733eb66 feat: Ability to Save Custom Themes (Closes #145) 2022-05-07 18:33:40 +05:30
Rajarshee Chatterjee 33a33842c6 feat: Add WebView Button in Reader 2022-05-07 17:21:58 +05:30
Rajarshee Chatterjee 1bfd24a1b4 fix: History Screen Fixes 2022-05-07 16:53:22 +05:30
Rajarshee Chatterjee 7e1bf4dd3f feat: Add Path Aliases 2022-05-07 16:50:53 +05:30
Rajarshee Chatterjee 955e552597 fix: Make MyAnimeListCard Scrollable 2022-05-07 16:50:23 +05:30
Rajarshee Chatterjee 8b586754d2 fix: MyAnimeList Search 2022-05-07 15:16:40 +05:30
Rajarshee Chatterjee b921f9b764 refactor: Remove Ununsed Files and Dependencies 2022-05-07 14:44:42 +05:30
Rajarshee Chatterjee 4d30546b9a build: Remove Upload Artifact 2022-05-07 14:44:32 +05:30
Rajarshee Chatterjee 58eac42b14 refactor: Refactor Reader Bottomsheet (#249)
* refactor: Refactor Reader Bottomsheet

* refactor: Remove Unused Files
2022-05-07 13:36:36 +05:30
Rajarshee Chatterjee 872ec15ca5 build: Fix Artifact Name 2022-05-06 21:23:28 +05:30
Rajarshee Chatterjee e013b3cc55 build: Fix Artifact Name 2022-05-06 20:58:20 +05:30
Rajarshee Chatterjee 8e58ce2eb1 feat(source): Add SonicMTL and MTLNovel.Club
Closes LNReader/lnreader-sources#221, Closes LNReader/lnreader-sources#223
2022-05-06 20:31:44 +05:30
Rajarshee Chatterjee a9e2d872f2 build: Add Upload Artifact 2022-05-06 20:23:01 +05:30
Rajarshee Chatterjee ccdb150d6a fix: Add Strings to Translations 2022-05-06 20:12:23 +05:30
Rajarshee Chatterjee 4e1d8533e3 Release v1.1.10 2022-05-04 07:21:14 +05:30
833 changed files with 91229 additions and 68985 deletions
-3
View File
@@ -1,3 +0,0 @@
# Windows files
[*.bat]
end_of_line = crlf
+10 -6
View File
@@ -1,18 +1,22 @@
module.exports = {
root: true,
extends: '@react-native-community',
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: '@react-native',
overrides: [
{
files: ['*.js', '*.jsx', '*.ts', '*.tsx'],
rules: {
'@typescript-eslint/no-shadow': ['warn'],
'no-shadow': 'off',
'no-undef': 'off',
'react-native/no-inline-styles': 'warn',
'no-console': 'warn',
'no-console': 'error',
'@typescript-eslint/no-shadow': 'warn',
'react-hooks/exhaustive-deps': 'warn',
'curly': ['error', 'multi-line', 'consistent'],
'no-useless-return': 'error',
'block-scoped-var': 'error',
'no-var': 'error',
'prefer-const': 'error',
'no-dupe-else-if': 'error',
'no-duplicate-imports': 'error',
},
},
],
-3
View File
@@ -1,3 +0,0 @@
# Windows files should use crlf line endings
# https://help.github.com/articles/dealing-with-line-endings/
*.bat text eol=crlf
+94
View File
@@ -0,0 +1,94 @@
# Cloned from tachiyomi
name: Issue report
description: Report an issue in LNReader
labels: [Bug]
body:
- type: textarea
id: reproduce-steps
attributes:
label: Steps to reproduce
description: Provide an example of the issue.
placeholder: |
Example:
1. First step
2. Second step
3. Issue here
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: Explain what you should expect to happen.
placeholder: |
Example:
"This should happen..."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: Explain what actually happens.
placeholder: |
Example:
"This happened instead..."
validations:
required: true
- type: input
id: lnreader-version
attributes:
label: LNReader version
description: You can find your LNReader version in **More → About**.
placeholder: |
Example: "2.0.2"
validations:
required: true
- type: input
id: android-version
attributes:
label: Android version
description: You can find this somewhere in your Android settings.
placeholder: |
Example: "Android 11"
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: List your device and model.
placeholder: |
Example: "Google Pixel 5"
validations:
required: true
- type: textarea
id: other-details
attributes:
label: Other details
placeholder: |
Additional details and attachments.
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
options:
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
required: true
- label: I have written a short but informative title.
required: true
- label: If this is an issue with a plugin, I should be opening an issue in the [plugins repository](https://github.com/lnreader/lnreader-plugins/issues/new/choose).
required: true
- label: I have updated the app to version **[2.0.2](https://github.com/lnreader/lnreader/releases/latest)**.
required: true
- label: I will fill out all of the requested information in this form.
required: true
@@ -0,0 +1,40 @@
# Cloned from tachiyomi
name: Feature request
description: Suggest a feature to improve LNReader
labels: [Feature Request]
body:
- type: textarea
id: feature-description
attributes:
label: Describe your suggested feature
description: How can LNReader be improved?
placeholder: |
Example:
"It should work like this..."
validations:
required: true
- type: textarea
id: other-details
attributes:
label: Other details
placeholder: |
Additional details and attachments.
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
options:
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
required: true
- label: I have written a short but informative title.
required: true
- label: If this is an issue with a source, I should be opening an issue in the [sources repository](https://github.com/LNReader/lnreader-sources/issues/new/choose).
required: true
- label: I have updated the app to version **[2.0.2](https://github.com/LNReader/lnreader/releases/latest)**.
required: true
- label: I will fill out all of the requested information in this form.
required: true
Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

+78 -19
View File
@@ -1,35 +1,94 @@
name: CI
name: Build
on:
push:
branches:
- main
- master
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-android:
name: Build app
name: Build App
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Get pnpm Store Directory
shell: bash
run: |
npm install
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache Gradle Wrapper
uses: actions/cache@v2
- name: Setup pnpm Cache
uses: actions/cache@v4
with:
path: ~/.gradle/wrapper
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Cache Gradle Dependencies
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-caches-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-gradle-caches-
${{ runner.os }}-pnpm-store-
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: false
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Create Environment File
run: |
cat > .env << EOF
MYANIMELIST_CLIENT_ID=${{ vars.MYANIMELIST_CLIENT_ID }}
ANILIST_CLIENT_ID=${{ vars.ANILIST_CLIENT_ID }}
GIT_HASH=$(git rev-parse --short HEAD)
RELEASE_DATE=$(date --utc +'%d/%m/%y %I:%M %p %Z')
BUILD_TYPE=Github Action
EOF
- name: Make Gradlew Executable
run: cd android && chmod +x ./gradlew
- name: Build Android Release
- name: Set Environment Variables
run: |
cd android && ./gradlew assembleRelease --no-daemon
set -x
echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> $GITHUB_ENV
echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Build Android Release
env:
COMMIT_COUNT: ${{ env.COMMIT_COUNT }}
COMMIT_ID: ${{ env.COMMIT_ID }}
run: |
sed -i 's/LNReader/LNReader-r${{ env.COMMIT_COUNT }}(${{ env.COMMIT_ID }})/g' android/app/src/main/res/values/strings.xml
cd android && ./gradlew assembleRelease -PcustomAppId=com.rajarsheechatterjee.LNReader.commit_${{ env.COMMIT_ID }} --build-cache
mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/LNReader-r${{ env.COMMIT_COUNT }}-${{ env.COMMIT_ID }}.apk
- name: Upload Release Artifact
env:
COMMIT_COUNT: ${{ env.COMMIT_COUNT }}
COMMIT_ID: ${{ env.COMMIT_ID }}
uses: actions/upload-artifact@v4
with:
name: LNReader-r${{ env.COMMIT_COUNT }}-${{ env.COMMIT_ID }}
path: android/app/build/outputs/apk/release/LNReader-r${{ env.COMMIT_COUNT }}-${{ env.COMMIT_ID }}.apk
retention-days: 30
+31
View File
@@ -0,0 +1,31 @@
# Cloned from tachiyomi
name: Issue moderator
on:
issues:
types: [opened, edited, reopened]
issue_comment:
types: [created]
jobs:
moderate:
runs-on: ubuntu-latest
steps:
- name: Moderate issues
uses: tachiyomiorg/issue-moderator-action@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
auto-close-rules: |
[
{
"type": "body",
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
"message": "The acknowledgment section was not removed."
},
{
"type": "body",
"regex": ".*\\* (LNReader version|Android version|Device): \\?.*",
"message": "Requested information in the template was not filled out."
}
]
+41 -5
View File
@@ -1,12 +1,48 @@
name: Lint
on: [push, pull_request]
on:
push:
branches:
- master
pull_request:
branches:
- master
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: ESLint
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
- name: Install modules
run: npm i
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Get pnpm Store Directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm Cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Run ESLint
run: npm run lint
run: pnpm run lint
+45
View File
@@ -0,0 +1,45 @@
# Temporarily Disabled
name: Type Check
on:
workflow_dispatch:
# push:
# branches:
# - master
# pull_request:
# branches:
# - master
jobs:
build:
name: Type Checking
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Get pnpm Store Directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm Cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Check Types
run: pnpm run type-check
+19 -3
View File
@@ -8,7 +8,8 @@ npm-debug.*
*.mobileprovision
*.orig.*
web-build/
.env
reader_playground/index.html
# macOS
.DS_Store
@@ -37,7 +38,7 @@ DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
**/.xcode.env.local
# Android/IntelliJ
#
@@ -47,6 +48,10 @@ build/
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore
.kotlin/
# node.js
#
@@ -65,6 +70,7 @@ buck-out/
# CocoaPods
/ios/Pods/
Gemfile.lock
# Expo
.expo/
@@ -73,4 +79,14 @@ web-build/
# @end expo-cli
.vscode/
src/sources/en/generators/
src/sources/en/generators/
*.lockb
*.lock
!pnpm-lock.yaml
.tool-versions
flake.lock
# pnpm
.pnpm-store
.cursor/
+3 -1
View File
@@ -1 +1,3 @@
**/node_modules
**/node_modules
android/**/js/van.js
android/**/js/text-vibe.js
+1
View File
@@ -7,4 +7,5 @@ module.exports = {
trailingComma: 'all',
arrowParens: 'avoid',
quoteProps: 'preserve',
endOfLine: 'auto', // stop prettier from getting mad on windows
};
-39
View File
@@ -1,39 +0,0 @@
import { enableFreeze } from 'react-native-screens';
enableFreeze(true);
import React, { useEffect } from 'react';
import { StatusBar } from 'react-native';
import { Provider as PaperProvider } from 'react-native-paper';
import { Provider } from 'react-redux';
import { persistor, store } from './src/redux/store';
import { PersistGate } from 'redux-persist/lib/integration/react';
import * as SplashScreen from 'expo-splash-screen';
import Main from './src/navigators/Main';
import { createDB } from './src/database/db';
import { SafeAreaProvider } from 'react-native-safe-area-context';
const App = () => {
useEffect(() => {
SplashScreen.preventAutoHideAsync();
createDB();
}, []);
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<SafeAreaProvider>
<PaperProvider>
<StatusBar translucent={true} backgroundColor="transparent" />
<Main />
</PaperProvider>
</SafeAreaProvider>
</PersistGate>
</Provider>
);
};
export default App;
+122
View File
@@ -0,0 +1,122 @@
import 'react-native-url-polyfill/auto';
import { enableFreeze } from 'react-native-screens';
enableFreeze(true);
import React, { useEffect } from 'react';
import { StatusBar, StyleSheet } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import LottieSplashScreen from 'react-native-lottie-splash-screen';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Provider as PaperProvider } from 'react-native-paper';
import * as Notifications from 'expo-notifications';
import AppErrorBoundary, {
ErrorFallback,
} from '@components/AppErrorBoundary/AppErrorBoundary';
import { useDatabaseInitialization } from '@hooks';
import Main from './src/navigators/Main';
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
Notifications.setNotificationHandler({
handleNotification: async () => {
return {
shouldPlaySound: false,
shouldSetBadge: false,
shouldShowBanner: true,
shouldShowList: true,
};
},
});
Notifications.setNotificationCategoryAsync('TTS_CONTROLS', [
{
identifier: 'TTS_PLAY_PAUSE',
buttonTitle: '▶️ Play',
options: {
opensAppToForeground: false,
},
},
{
identifier: 'TTS_STOP',
buttonTitle: '⏹️ Stop',
options: {
opensAppToForeground: false,
},
},
{
identifier: 'TTS_NEXT',
buttonTitle: '⏭️ Next',
options: {
opensAppToForeground: false,
},
},
]);
Notifications.setNotificationChannelAsync('tts-controls', {
name: 'TTS Controls',
description: 'Text-to-Speech playback controls',
importance: Notifications.AndroidImportance.HIGH,
vibrationPattern: [],
enableLights: false,
enableVibrate: false,
});
const App = () => {
const { isDbReady, dbError, retryInitialization } =
useDatabaseInitialization();
useEffect(() => {
if (isDbReady || dbError) {
LottieSplashScreen.hide();
}
}, [isDbReady, dbError]);
useEffect(() => {
const subscription = Notifications.addNotificationResponseReceivedListener(
response => {
const actionIdentifier = response.actionIdentifier;
if (actionIdentifier.startsWith('TTS_')) {
const { setTTSAction } = require('@utils/ttsNotification');
setTTSAction(actionIdentifier);
}
},
);
return () => {
subscription.remove();
};
}, []);
if (dbError) {
return <ErrorFallback error={dbError} resetError={retryInitialization} />;
}
if (!isDbReady) {
return null;
}
return (
<GestureHandlerRootView style={styles.flex}>
<AppErrorBoundary>
<SafeAreaProvider>
<PaperProvider>
<BottomSheetModalProvider>
<StatusBar translucent={true} backgroundColor="transparent" />
<Main />
</BottomSheetModalProvider>
</PaperProvider>
</SafeAreaProvider>
</AppErrorBoundary>
</GestureHandlerRootView>
);
};
export default App;
const styles = StyleSheet.create({
flex: {
flex: 1,
},
});
+108
View File
@@ -0,0 +1,108 @@
# React Native Development Nix Environment Setup
This document outlines how to set up your React Native development environment using Nix flakes for reproducibility and isolation.
## Disclaimer
This was tested on an Arch Linux system with AMD CPU and GPU. There are likely problems with NVIDIA GPUs.
Compatibility with Microsoft WSL2 is not guaranteed, but should work withoud major issues, except for the emulator.
## Prerequisites
- **Nix installed**: [https://nixos.org/download.html](https://nixos.org/download.html)
- **Git**: Required for cloning the repository.
- **KVM (for emulator, if enabled)**: Ensure KVM is enabled and your user is in the `kvm` group for optimal emulator performance:
```bash
sudo usermod -aG kvm $USER && newgrp kvm # (or log out/in)
kvm-ok # Verify KVM acceleration
```
- **GPU Drivers (for emulator, if enabled)**: For hardware-accelerated emulator (AMD/Intel), ensure host Vulkan drivers are working:
```bash
vulkaninfo | grep -i "device name" # Should show your GPU
```
If not, install `vulkan-radeon` (AMD) or `vulkan-intel` (Intel) on your host system and reboot.
## Getting Started
1. **Clone the Project:**
```bash
git clone <your-fork-url>
cd <your-fork-name>
```
2. **Enter the Development Shell:**
If you have `pnpm` installed, use the defined scripts:
- **For Physical Device Only (default):**
```bash
pnpm run nix:shell
```
- **For Emulator Development (explicitly enable):**
```bash
pnpm run nix:emulator
```
If you do not have `pnpm` installed, execute the commands manually:
- **For Physical Device Only (default):**
```bash
nix develop --extra-experimental-features nix-command --extra-experimental-features flakes
```
- **For Emulator Development (explicitly enable):**
```
nix develop .#emulator --extra-experimental-features nix-command --extra-experimental-features flakes
```
The first time, this will download and set up all required tools, which can take considerable time. Subsequent entries will be much faster. You will also see a message about "Setting up writable Android SDK..." which only happens once.
## Development Workflow
Once inside the `nix develop` shell, all tools are available.
### 1. Start Metro Bundler
Open a new terminal or run in the background:
```bash
pnpm run dev:start
```
### 2. Physical Device Development
1. **Connect Device**: Enable USB debugging on your Android device and connect it via USB.
2. **Verify Device**:
```bash
adb devices
```
3. **Mirror Screen (Optional)**:
```bash
scrcpy # Mirrors screen, provides control
scrcpy -s <device_serial> # If multiple devices connected
```
4. **Run App**:
```bash
npx run android
```
### 3. Android Emulator Development (if enabled)
1. **Launch Emulator**:
```bash
emulator -avd ReactNative_API35 -gpu host -no-metrics -no-audio
```
- Use `-gpu swiftshader_indirect` if hardware acceleration (`-gpu host`) fails.
2. **Verify Emulator**:
```bash
adb devices
```
3. **Run App**:
Launches the the emulater automatically, if it is not already running.
```bash
npx run android
```
+32 -8
View File
@@ -2,30 +2,54 @@
Contributions are welcome and are greatly appreciated!
## Setup your environment with nix
If you are on a Linux system, you can install the nix package manager and use the nix flakes to set up your development environment.
See [CONTRIBUTING-NIX.md](CONTRIBUTING-NIX.md)
## Setting up your environment
After forking to your own github org or account, do the following steps to get started:
```bash
# prerequisites
node --version >= 20 (for version management, get nvm [recommended])
java sdk --version >= 17 (for version management, get jenv [optional])
android sdk (https://developer.android.com/studio)
# clone your fork to your local machine
git clone https://github.com/<your-account-name>/lnreader.git
# step into local repo
cd lnreader
# install dependencies
npm install
# install pnpm (if not already installed)
npm install -g pnpm
# run metro for development
npm start
# install dependencies
pnpm install
# build the apk (the built apk will be found in ~/lnreader/android/app/build/outputs/apk/release/)
pnpm run build:release:android
```
### Developing on Android
While the packager is running and you have an Android device or emulator connected to your computer, build and launch the Android app.
You will need an Android device or emulator connected to your computer as well as an IDE of your choice. (eg: vscode)
```
npm run android
```bash
# prerequisites
adb (https://developer.android.com/studio/command-line/adb)
IDE
# check if android device/emulator is connected
adb devices
# run metro for development
pnpm run dev:start
# then to view on your android device (new terminal)
pnpm run dev:android
```
### Style & Linting
@@ -36,5 +60,5 @@ It is recommended that you install an eslint plugin for your editor of choice wh
codebase, however you can always check to see if the source code is compliant by running:
```bash
npm run lint
pnpm run lint
```
+16
View File
@@ -0,0 +1,16 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
gem 'xcodeproj', '< 1.26.0'
gem 'concurrent-ruby', '< 1.3.4'
# Ruby 3.4.0 has removed some libraries from the standard library.
gem 'bigdecimal'
gem 'logger'
gem 'benchmark'
gem 'mutex_m'
+54 -29
View File
@@ -1,48 +1,73 @@
<p align="center">
<img src="./.github/readme-images/icon_alt.png" align="center" width="128" />
<p>
<h1 align="center">
LNReader
</h1>
<p align="center">
LNReader is a Tachiyomi-like, free and open source light novel reader for Android.
<a href="https://lnreader.app">
<img src="./.github/readme-images/icon_new.png" align="center" width="128" />
</a>
</p>
<h1 align="center">LNReader</h1>
<p align="center">
LNReader is a free and open source light novel reader for Android, inspired by Tachiyomi.
</p>
<div align="center">
<a href="https://github.com/LNReader/lnreader/actions/workflows/build.yml">
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/LNReader/lnreader/CI">
</a>
<a href="https://discord.gg/QdcWN4MD63">
<img alt="Discord Chat" src="https://img.shields.io/discord/835746409357246465.svg?logo=discord&logoColor=white&logoWidth=20&labelColor=7289DA&label=Discord&color=17cf48">
<img alt="Discord Chat" src="https://img.shields.io/discord/835746409357246465.svg?logo=discord&logoColor=white&logoWidth=20&labelColor=5865F2&color=4752C4&label=discord&style=flat">
</a>
<a href="https://github.com/LNReader/lnreader/releases/latest">
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/LNReader/lnreader">
</a>
<a href="https://github.com/LNReader/lnreader-preview/releases/latest">
<img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/LNReader/lnreader-preview?color=red&label=preview">
</a>
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/lnreader"><img src="https://badges.crowdin.net/lnreader/localized.svg"></a>
<a href="https://github.com/LNReader/lnreader/blob/main/LICENSE">
<img alt="GitHub" src="https://img.shields.io/github/license/LNReader/lnreader">
<a href="https://github.com/LNReader/lnreader/releases">
<img alt="GitHub Downloads" src="https://img.shields.io/github/downloads/LNReader/lnreader/total?label=downloads&labelColor=27303D&color=0D1117&logo=github&logoColor=FFFFFF&style=flat">
</a>
</div>
<br>
<br>
<div align="center">
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/LNReader/lnreader/build.yml?labelColor=27303D&style=flat">
<a href="https://github.com/LNReader/lnreader/blob/main/LICENSE">
<img alt="GitHub" src="https://img.shields.io/github/license/LNReader/lnreader?labelColor=27303D&color=1a73e8&style=flat">
</a>
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/lnreader">
<img src="https://badges.crowdin.net/lnreader/localized.svg">
</a>
</div>
<h2 align="center">Download</h2>
<p align="center">
<a href="https://github.com/LNReader/lnreader/releases/latest">
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/LNReader/lnreader?label=Stable&labelColor=0d7377&color=084c4e&style=flat">
</a>
<a href="https://github.com/LNReader/lnreader/releases/latest">
<img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/LNReader/lnreader?include_prereleases&sort=semver&label=Beta&labelColor=3d3d5c&color=2a2a47&style=flat">
</a>
</p>
<p align="center">
Get the app from our <a href="https://github.com/LNReader/lnreader/releases">releases page</a>.
</p>
<p align="center">
<em>Android 7.0 or higher.</em>
</p>
<h2 align="center">Screenshots</h2>
<p align="center">
<img src="./.github/readme-images/screenshots.png" align="center" />
</p>
## Download
Get the app from our [releases page](https://github.com/rajarsheechatterjee/LNReader/releases).
## Sources
## Plugins
LNReader does not have any affiliation with the content providers available.
Source requests should be created at [LNReader/lnreader-sources](https://github.com/LNReader/lnreader-sources).
Plugin requests should be created at [lnreader-plugins](https://github.com/LNReader/lnreader-plugins).
## Translation
Help translate LNReader into your language on [Crowdin](https://crowdin.com/project/lnreader).
## Building & Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md)
## License
[MIT ](https://github.com/rajarsheechatterjee/lnreader/blob/main/LICENSE)
[MIT](https://github.com/LNReader/lnreader/blob/main/LICENSE)
-55
View File
@@ -1,55 +0,0 @@
# To learn about Buck see [Docs](https://buckbuild.com/).
# To run your application with Buck:
# - install Buck
# - `npm start` - to start the packager
# - `cd android`
# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
# - `buck install -r android/app` - compile, install and run application
#
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
lib_deps = []
create_aar_targets(glob(["libs/*.aar"]))
create_jar_targets(glob(["libs/*.jar"]))
android_library(
name = "all-libs",
exported_deps = lib_deps,
)
android_library(
name = "app-code",
srcs = glob([
"src/main/java/**/*.java",
]),
deps = [
":all-libs",
":build_config",
":res",
],
)
android_build_config(
name = "build_config",
package = "com.rajarsheechatterjee.LNReader",
)
android_resource(
name = "res",
package = "com.rajarsheechatterjee.LNReader",
res = "src/main/res",
)
android_binary(
name = "app",
keystore = "//android/keystores:debug",
manifest = "src/main/AndroidManifest.xml",
package_type = "debug",
deps = [
":app-code",
],
)
+81 -168
View File
@@ -1,150 +1,95 @@
apply plugin: "com.android.application"
import com.android.build.OutputFile
apply plugin: "com.facebook.react"
apply plugin: 'org.jetbrains.kotlin.android'
/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation. If none specified and
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
* // default. Can be overridden with ENTRY_FILE environment variable.
* entryFile: "index.android.js",
*
* // https://reactnative.dev/docs/performance#enable-the-ram-format
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
* This is the configuration block to customize your React Native Android app.
* By default you don't need to apply any configuration, just uncomment the lines you need.
*/
react {
/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '../..'
// root = file("../../")
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native
// reactNativeDir = file("../../node_modules/react-native")
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
// codegenDir = file("../../node_modules/@react-native/codegen")
// The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
// cliFile = file("../../node_modules/react-native/cli.js")
project.ext.react = [
enableHermes: true
]
/* Variants */
// The list of variants to that are debuggable. For those we're going to
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
// debuggableVariants = ["liteDebug", "prodDebug"]
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"
/* Bundling */
// A list containing the node command and its flags. Default is just 'node'.
// nodeExecutableAndArgs = ["node"]
//
// The command to run when bundling. By default is 'bundle'
// bundleCommand = "ram-bundle"
//
// The path to the CLI configuration file. Default is empty.
// bundleConfig = file(../rn-cli.config.js)
//
// The name of the generated asset file containing your JS bundle
// bundleAssetName = "MyApplication.android.bundle"
//
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
// entryFile = file("../js/index.android.js")
//
// A list of extra flags to pass to the 'bundle' commands.
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
// extraPackagerArgs = []
/* Hermes Commands */
// The hermes compiler command to run. By default it is 'hermesc'
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
//
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
// hermesFlags = ["-O", "-output-source-map"]
/* Autolinking */
autolinkLibrariesWithApp()
}
/**
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* Run Proguard to shrink the Java bytecode in release builds.
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = false
/**
* The preferred build flavor of JavaScriptCore.
* The preferred build flavor of JavaScriptCore (JSC).
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
* `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
/**
* Whether to enable the Hermes VM.
*
* This should be set on project.ext.react and mirrored here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);
ext {
versionMajor = 2
versionMinor = 0
versionPatch = 2
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
ndkVersion rootProject.ext.ndkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
namespace "com.rajarsheechatterjee.LNReader"
defaultConfig {
applicationId 'com.rajarsheechatterjee.LNReader'
applicationId project.hasProperty('customAppId') ? project.getProperty('customAppId') : 'com.rajarsheechatterjee.LNReader'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.1.9"
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
// Generated version code. Supports versions up to 1024.1024.2048
versionCode ((((versionMajor << 10) | versionMinor) << 11) | versionPatch)
versionName "$versionMajor.$versionMinor.$versionPatch"
}
signingConfigs {
debug {
@@ -157,6 +102,8 @@ android {
buildTypes {
debug {
signingConfig signingConfigs.debug
applicationIdSuffix 'debug'
versionNameSuffix '-debug'
}
release {
// Caution! In production, you need to generate your own keystore file.
@@ -166,58 +113,24 @@ android {
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
kotlinOptions {
jvmTarget = '17'
}
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation 'androidx.core:core-ktx:1.15.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
addUnimodulesDependencies()
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
}
-19
View File
@@ -1,19 +0,0 @@
"""Helper definitions to glob .aar and .jar targets"""
def create_aar_targets(aarfiles):
for aarfile in aarfiles:
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
lib_deps.append(":" + name)
android_prebuilt_aar(
name = name,
aar = aarfile,
)
def create_jar_targets(jarfiles):
for jarfile in jarfiles:
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
lib_deps.append(":" + name)
prebuilt_jar(
name = name,
binary_jar = jarfile,
)
+47
View File
@@ -0,0 +1,47 @@
{
"project_info": {
"project_number": "523872485654",
"project_id": "lnreader-backup",
"storage_bucket": "lnreader-backup.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:523872485654:android:169cd062458db962ce1037",
"android_client_info": {
"package_name": "com.rajarsheechatterjee.LNReader"
}
},
"oauth_client": [
{
"client_id": "523872485654-14jtut8orr7dbrk2chea279d7k8889sr.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.rajarsheechatterjee.LNReader",
"certificate_hash": "5e8f16062ea3cd2c4a0d547876baa6f38cabf625"
}
},
{
"client_id": "523872485654-liarmq8nl0g5an2cki3bpg9jc0d8a21j.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBH_j-0Jyo9aFJ_KV8Nr3te2hs_L_ZYhrE"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "523872485654-liarmq8nl0g5an2cki3bpg9jc0d8a21j.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
+2 -8
View File
@@ -8,13 +8,7 @@
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }
-keep class com.facebook.hermes.unicode.** { *; }
-keep class com.facebook.jni.** { *; }
-keep public class com.dylanvann.fastimage.* {*;}
-keep public class com.dylanvann.fastimage.** {*;}
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
+6 -4
View File
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
</manifest>
<application
android:usesCleartextTraffic="true"
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning"/>
</manifest>
@@ -1,69 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.lnreader;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new ReactFlipperPlugin());
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
NetworkingModule.setCustomClientBuilder(
new NetworkingModule.CustomClientBuilder() {
@Override
public void apply(OkHttpClient.Builder builder) {
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
}
});
client.addPlugin(networkFlipperPlugin);
client.start();
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been initialized
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
new ReactInstanceManager.ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
reactContext.runOnNativeModulesQueueThread(
new Runnable() {
@Override
public void run() {
client.addPlugin(new FrescoFlipperPlugin());
}
});
}
});
} else {
client.addPlugin(new FrescoFlipperPlugin());
}
}
}
}
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">LNReader debug</string>
</resources>
+42 -62
View File
@@ -1,90 +1,70 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rajarsheechatterjee.LNReader">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Internet -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<!-- Storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- For background jobs -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<queries>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
</queries>
<application
android:name=".MainApplication"
<application
android:name=".MainApplication"
android:largeHeap="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:roundIcon="@mipmap/ic_launcher"
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"/>
android:usesCleartextTraffic="true"
android:supportsRtl="true">
<meta-data
android:name="expo.modules.notifications.default_notification_icon"
android:resource="@drawable/notification_icon"/>
android:resource="@drawable/notification_icon" />
<meta-data
android:name="expo.modules.notifications.default_notification_color"
android:resource="@color/notification_icon_color"/>
android:resource="@color/notification_icon_color" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:theme="@style/Theme.App.SplashScreen"
android:screenOrientation="unspecified">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="lnreader"/>
<data android:scheme="com.rajarsheechatterjee.LNReader"/>
</intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="lnreader" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" />
</application>
<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="shortService" />
</application>
</manifest>
+183
View File
@@ -0,0 +1,183 @@
html {
scroll-behavior: smooth;
overflow-x: hidden;
word-wrap: break-word;
}
::selection {
color: var(--theme-onSecondary);
background-color: var(--theme-secondary);
}
::-moz-selection {
color: var(--theme-onSecondary);
background-color: var(--theme-secondary);
}
body {
margin-left: 0;
margin-right: 0;
padding-bottom: 40px;
padding-top: var(--StatusBar-currentHeight);
font-size: var(--readerSettings-textSize);
background-color: var(--readerSettings-theme);
color: var(--readerSettings-textColor);
text-align: var(--readerSettings-textAlign);
line-height: var(--readerSettings-lineHeight);
font-family: var(--readerSettings-fontFamily);
}
#LNReader-chapter {
padding-left: var(--readerSettings-padding);
padding-right: var(--readerSettings-padding);
}
hr {
margin-top: 20px;
margin-bottom: 20px;
}
a {
color: var(--theme-primary);
}
sup {
line-height: 0.1em;
}
img {
display: block;
width: auto;
height: auto;
max-width: 100%;
}
table {
background-color: var(--theme-onPrimary);
border-collapse: collapse;
color: var(--theme-primary);
}
th {
font-weight: bold;
}
td {
padding: 10px;
text-align: center;
}
table,
th,
td {
border: 1px solid var(--theme-outline);
}
.hidden {
visibility: hidden;
}
.next-button,
.info-text {
margin-left: var(--readerSettings-padding);
margin-right: var(--readerSettings-padding);
border-radius: 50px;
border-width: 1;
color: var(--theme-onPrimary);
background-color: var(--theme-primary);
font-family: var(--readerSettings-fontFamily);
font-size: 16px;
border-width: 0;
user-select: none;
}
.next-button {
min-height: 40px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
padding: 0 16px;
width: calc(100% - var(--readerSettings-padding) * 2);
}
.info-text {
background-color: transparent;
text-align: center;
border: none;
margin: 0px;
color: inherit;
padding-top: 16px;
padding-bottom: 16px;
}
.d-none {
display: none;
}
#reader-footer-wrapper {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 9999999;
}
#reader-footer {
display: flex;
flex: 3;
padding: 0.2rem 2rem;
background-color: var(--readerSettings-theme);
color: var(--readerSettings-textColor);
font-size: 1rem;
text-align: center;
user-select: none;
}
.reader-footer-item {
flex: 1;
}
.reader-footer-item:first-child {
text-align: left;
}
.reader-footer-item:last-child {
text-align: right;
}
.highlight {
color: var(--readerSettings-textColor) !important;
background-color: color-mix(
in srgb,
var(--readerSettings-textColor) 20%,
var(--readerSettings-theme)
);
}
.highlight * {
color: var(--readerSettings-textColor) !important;
background-color: transparent;
}
#Image-Modal {
position: fixed;
left: 0;
top: 0;
user-select: none;
}
#Image-Modal.show {
display: flex;
height: 100%;
width: 100%;
background-color: var(--theme-surface-0-9);
align-items: center;
justify-content: center;
overflow: scroll;
}
#Image img {
display: block;
width: 100%;
}
@@ -0,0 +1,29 @@
body.page-reader {
overflow: hidden;
padding-bottom: unset;
}
body.page-reader > #LNReader-chapter {
height: calc(90vh);
column-width: calc(100vw - var(--readerSettings-padding) * 2);
column-gap: calc(var(--readerSettings-padding) * 2);
transition: 200ms;
}
.transition-chapter {
height: 100vh;
width: 100vw;
max-width: 100vw;
position: fixed;
left: 100vw;
top: 0;
box-sizing: border-box;
padding: var(--readerSettings-padding);
padding-top: 30vh;
text-align: center;
font-size: 2rem;
z-index: 888888;
background-color: var(--readerSettings-theme);
}
@@ -0,0 +1,151 @@
#ToolWrapper {
position: fixed;
top: 50%;
transform: translateY(-50%);
right: 5vw;
transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1);
z-index: 9999999;
}
#ToolWrapper.horizontal {
top: unset;
right: unset;
left: 50%;
transform: translateX(-50%);
bottom: 120px;
display: flex;
flex-direction: row-reverse;
align-items: center;
}
@media only screen and (min-width: 500px) {
#ToolWrapper.horizontal {
bottom: 80px;
}
}
#ToolWrapper.hidden {
opacity: 0;
right: 0;
transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
#ToolWrapper.hidden.horizontal {
opacity: 0;
bottom: 80px;
right: unset;
}
#ToolWrapper > #ScrollBar {
margin-top: 8px;
width: 2.4rem;
height: 50vh;
min-height: 200px;
border-radius: 1.2rem;
background-color: var(--theme-surface-0-9);
touch-action: none;
font-size: 14px;
user-select: none;
}
#ScrollBar > .scrollbar-item {
display: flex;
justify-content: center;
align-items: center;
color: var(--theme-onSurface);
}
#ScrollBar > .scrollbar-item.scrollbar-text {
height: 12.5%;
}
#ScrollBar > .scrollbar-item#scrollbar-slider {
height: 75%;
align-items: unset;
}
#ScrollBar #scrollbar-track {
width: 0.1rem;
height: 100%;
background-color: var(--theme-outline);
}
#ScrollBar #scrollbar-progress {
width: 100%;
height: 0;
background-color: var(--theme-primary);
}
#ScrollBar #scrollbar-thumb-wrapper {
position: relative;
top: 100%;
height: 2rem;
width: 2rem;
display: flex;
align-items: center;
justify-content: center;
transform: translate(-0.95rem, -1rem);
}
#ScrollBar #scrollbar-thumb {
top: 100%;
height: 1rem;
width: 1rem;
border-radius: 100%;
background-color: var(--theme-primary);
}
#ToolWrapper.horizontal > #ScrollBar {
display: flex;
width: 95.5vw;
height: 2.4rem;
min-height: unset;
align-items: center;
margin-top: unset;
}
#ToolWrapper.horizontal > #ScrollBar > .scrollbar-item {
display: flex;
justify-content: center;
color: var(--theme-onSurface);
}
#ToolWrapper.horizontal > #ScrollBar > .scrollbar-item.scrollbar-text {
width: 12.5%;
}
#ToolWrapper.horizontal > #ScrollBar > .scrollbar-item#scrollbar-slider {
width: 75%;
align-items: center;
}
#ToolWrapper.horizontal > #ScrollBar #scrollbar-track {
height: 0.1rem;
width: 100%;
background-color: var(--theme-outline);
}
#ToolWrapper.horizontal > #ScrollBar #scrollbar-progress {
height: 100%;
width: 0;
background-color: var(--theme-primary);
}
#ToolWrapper.horizontal > #ScrollBar #scrollbar-thumb-wrapper {
position: relative;
left: 100%;
height: 2rem;
width: 2rem;
display: flex;
align-items: center;
justify-content: center;
transform: translate(-0.95rem, -1rem);
}
#ToolWrapper.horizontal > #ScrollBar #scrollbar-thumb {
top: 100%;
height: 1rem;
width: 1rem;
border-radius: 100%;
background-color: var(--theme-primary);
}
+48
View File
@@ -0,0 +1,48 @@
#TTS-Controller {
position: fixed;
top: 50%;
left: 20px;
opacity: 0.5;
}
#TTS-Controller button {
background: color-mix(
in srgb,
var(--readerSettings-theme) 85%,
var(--readerSettings-textColor) 15%
);
outline: none;
border-width: 1px;
border-style: solid;
border-color: color-mix(
in srgb,
var(--readerSettings-textColor) 30%,
var(--readerSettings-theme) 70%
);
display: flex;
justify-items: center;
align-items: center;
padding: 4px;
border-radius: 100%;
transition: 0.5s;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
#TTS-Controller.active {
opacity: 1;
}
#TTS-Controller.active button {
padding: 16px;
}
#TTS-Controller svg {
fill: var(--readerSettings-textColor);
width: 20px;
height: 20px;
}
#TTS-Controller.active svg {
width: 24px;
height: 24px;
}
File diff suppressed because one or more lines are too long
+772
View File
@@ -0,0 +1,772 @@
/* eslint-disable no-console */
window.reader = new (function () {
const {
readerSettings,
chapterGeneralSettings,
novel,
chapter,
nextChapter,
prevChapter,
batteryLevel,
autoSaveInterval,
DEBUG,
strings,
} = initialReaderConfig;
// state
this.hidden = van.state(true);
this.batteryLevel = van.state(batteryLevel);
this.readerSettings = van.state(readerSettings);
this.generalSettings = van.state(chapterGeneralSettings);
this.chapterElement = document.querySelector('#LNReader-chapter');
this.selection = window.getSelection();
this.viewport = document.querySelector('meta[name=viewport]');
this.novel = novel;
this.chapter = chapter;
this.nextChapter = nextChapter;
this.prevChapter = prevChapter;
this.strings = strings;
this.autoSaveInterval = autoSaveInterval;
this.rawHTML = this.chapterElement.innerHTML;
//layout props
this.paddingTop = parseInt(
getComputedStyle(document.querySelector('body')).getPropertyValue(
'padding-top',
),
10,
);
this.chapterHeight = this.chapterElement.scrollHeight + this.paddingTop;
this.layoutHeight = window.screen.height;
this.layoutWidth = window.screen.width;
this.layoutEvent = undefined;
this.chapterEndingVisible = van.state(false);
this.post = obj => window.ReactNativeWebView.postMessage(JSON.stringify(obj));
this.refresh = () => {
if (this.generalSettings.val.pageReader) {
this.chapterWidth = this.chapterElement.scrollWidth;
} else {
this.chapterHeight = this.chapterElement.scrollHeight + this.paddingTop;
}
};
van.derive(() => {
const settings = this.readerSettings.val;
document.documentElement.style.setProperty(
'--readerSettings-theme',
settings.theme,
);
document.documentElement.style.setProperty(
'--readerSettings-padding',
settings.padding + 'px',
);
document.documentElement.style.setProperty(
'--readerSettings-textSize',
settings.textSize + 'px',
);
document.documentElement.style.setProperty(
'--readerSettings-textColor',
settings.textColor,
);
document.documentElement.style.setProperty(
'--readerSettings-textAlign',
settings.textAlign,
);
document.documentElement.style.setProperty(
'--readerSettings-lineHeight',
settings.lineHeight,
);
document.documentElement.style.setProperty(
'--readerSettings-fontFamily',
settings.fontFamily,
);
if (settings.fontFamily) {
new FontFace(
settings.fontFamily,
'url("file:///android_asset/fonts/' + settings.fontFamily + '.ttf")',
)
.load()
.then(function (loadedFont) {
document.fonts.add(loadedFont);
});
} else {
// have no affect with a font declared in head
document.fonts.forEach(fontFace => document.fonts.delete(fontFace));
}
});
document.onscrollend = () => {
if (!this.generalSettings.val.pageReader) {
this.post({
type: 'save',
data: parseInt(
((window.scrollY + this.layoutHeight) / this.chapterHeight) * 100,
10,
),
});
}
};
if (DEBUG) {
// eslint-disable-next-line no-global-assign, no-new-object
console = new Object();
console.log = function (...data) {
reader.post({ 'type': 'console', 'msg': data?.join(' ') });
};
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;
}
// end reader
})();
window.tts = new (function () {
this.readableNodeNames = [
'#text',
'B',
'I',
'SPAN',
'EM',
'BR',
'STRONG',
'A',
];
this.prevElement = null;
this.currentElement = reader.chapterElement;
this.started = false;
this.reading = false;
this.elementsRead = 0;
this.totalElements = 0;
this.allReadableElements = []; // Store all readable elements at start
this.textQueue = []; // Flat list of normalized text for native fallback
this.readable = element => {
const ele = element ?? this.currentElement;
if (
ele.nodeName !== 'SPAN' &&
this.readableNodeNames.includes(ele.nodeName)
) {
return false;
}
if (!ele.hasChildNodes()) {
return false;
}
for (let i = 0; i < ele.childNodes.length; i++) {
if (!this.readableNodeNames.includes(ele.childNodes.item(i).nodeName)) {
return false;
}
}
return true;
};
this.normalizeText = text => {
if (!text) return '';
return text
.replace(/\s+/g, ' ')
.replace(/\s*([.,!?;:])\s*/g, '$1 ')
.trim();
};
// if can find a readable node, else stop tts
// FIXED: Added proper boundary checks to prevent stack overflow
this.findNextTextNode = (depth = 0) => {
// Prevent deep recursion
if (depth > 500) {
console.warn('TTS: findNextTextNode max depth reached');
return false;
}
if (this.currentElement.isSameNode(reader.chapterElement) && this.started) {
return false;
} else {
this.started = true;
}
// Safety check: ensure currentElement is valid
if (!this.currentElement || !this.currentElement.nodeName) {
return false;
}
// is read, have to go next or go back
if (this.currentElement.isSameNode(this.prevElement)) {
this.prevElement = this.currentElement;
if (this.currentElement.nextElementSibling) {
this.currentElement = this.currentElement.nextElementSibling;
return this.findNextTextNode(depth + 1);
} else if (
this.currentElement.parentElement &&
!this.currentElement.parentElement.isSameNode(document.body) &&
!this.currentElement.parentElement.isSameNode(document.documentElement)
) {
this.currentElement = this.currentElement.parentElement;
return this.findNextTextNode(depth + 1);
} else {
return false;
}
} else {
// can read? read it
if (this.readable()) {
return true;
}
if (
!this.prevElement?.parentElement?.isSameNode(this.currentElement) &&
this.currentElement.firstElementChild
) {
// go deep
this.prevElement = this.currentElement;
this.currentElement = this.currentElement.firstElementChild;
return this.findNextTextNode(depth + 1);
} else if (this.currentElement.nextElementSibling) {
this.prevElement = this.currentElement;
this.currentElement = this.currentElement.nextElementSibling;
return this.findNextTextNode(depth + 1);
} else if (
this.currentElement.parentElement &&
!this.currentElement.parentElement.isSameNode(document.body) &&
!this.currentElement.parentElement.isSameNode(document.documentElement)
) {
this.prevElement = this.currentElement;
this.currentElement = this.currentElement.parentElement;
return this.findNextTextNode(depth + 1);
} else {
return false;
}
}
};
this.next = () => {
try {
this.currentElement?.classList?.remove('highlight');
// Use array-based approach instead of DOM traversal (no recursion!)
while (this.elementsRead < this.totalElements) {
const nextElement = this.allReadableElements[this.elementsRead];
if (!nextElement) break;
const text = this.normalizeText(nextElement.innerText);
if (text) {
// Found valid text - speak it
this.currentElement = nextElement;
this.reading = true;
this.elementsRead++;
this.speak();
return;
} else {
// Empty text, skip to next in array (no recursion!)
this.elementsRead++;
}
}
// Reached the end (elementsRead >= totalElements or no more valid elements)
this.reading = false;
const autoPageAdvance =
reader.readerSettings.val.tts?.autoPageAdvance === true;
const hasNextChapter = !!reader.nextChapter;
if (autoPageAdvance && hasNextChapter) {
reader.post({ type: 'next', autoStartTTS: true });
} else {
this.stop();
const controller = document.getElementById('TTS-Controller');
if (controller?.firstElementChild) {
controller.firstElementChild.innerHTML = volumnIcon;
}
}
} catch (e) {
this.stop();
alert('TTS Error: ' + e.message);
}
};
this.start = element => {
this.stop();
const startElement = element ?? reader.chapterElement;
this.currentElement = startElement;
// Get all readable elements from the chapter
this.allReadableElements = this.getAllReadableElements(
reader.chapterElement,
);
this.totalElements = this.allReadableElements.length;
this.textQueue = this.allReadableElements
.map(el => this.normalizeText(el.innerText))
.filter(text => !!text);
reader.post({
type: 'tts-queue',
data: {
queue: this.textQueue,
startIndex: this.elementsRead,
},
});
// If starting from a specific element, count how many are before it
if (element && element !== reader.chapterElement) {
const startIndex = this.allReadableElements.indexOf(element);
this.elementsRead = startIndex >= 0 ? startIndex : 0;
} else {
this.elementsRead = 0;
}
this.next();
};
// Get all readable elements in order
this.getAllReadableElements = element => {
const elements = [];
const traverse = el => {
if (!el) return;
if (this.readable(el)) {
elements.push(el);
}
for (let i = 0; i < el.children.length; i++) {
traverse(el.children[i]);
}
};
traverse(element);
return elements;
};
this.resume = () => {
if (!this.reading) {
if (
this.currentElement &&
this.currentElement.id !== 'LNReader-chapter'
) {
this.speak();
this.reading = true;
} else {
this.next();
}
}
};
this.pause = () => {
this.reading = false;
reader.post({ type: 'stop-speak' });
reader.post({ type: 'tts-state', data: { isReading: false } });
};
this.stop = () => {
reader.post({ type: 'stop-speak' });
this.currentElement?.classList?.remove('highlight');
this.prevElement = null;
this.currentElement = reader.chapterElement;
this.started = false;
this.reading = false;
this.elementsRead = 0;
this.totalElements = 0;
this.allReadableElements = [];
this.textQueue = [];
reader.post({ type: 'tts-state', data: { isReading: false } });
// Ensure icon updates to stopped state
const controller = document.getElementById('TTS-Controller');
if (controller?.firstElementChild) {
controller.firstElementChild.innerHTML = volumnIcon;
}
};
this.isElementInViewport = element => {
if (!element) return false;
const rect = element.getBoundingClientRect();
const windowHeight =
window.innerHeight || document.documentElement.clientHeight;
const windowWidth =
window.innerWidth || document.documentElement.clientWidth;
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= windowHeight &&
rect.right <= windowWidth
);
};
// UPDATED: Scroll to top or center based on settings with padding for notch/camera
this.scrollToElement = element => {
if (!element) return;
// Check if element is partially visible (at least some part is in viewport)
const rect = element.getBoundingClientRect();
const windowHeight =
window.innerHeight || document.documentElement.clientHeight;
const isPartiallyVisible =
rect.top < windowHeight &&
rect.bottom > 0 &&
rect.left < window.innerWidth &&
rect.right > 0;
// Only scroll if element is not visible or barely visible
if (!isPartiallyVisible || rect.top < 0 || rect.bottom > windowHeight) {
// Check scrollToTop setting (default to true for better reading experience)
const scrollToTop = reader.readerSettings.val.tts?.scrollToTop !== false;
if (scrollToTop) {
// Scroll to top with padding for notch/camera (80px from top)
const elementTop =
element.getBoundingClientRect().top + window.pageYOffset;
const offsetPosition = elementTop - 80; // 80px padding for notch/camera
window.scrollTo({
top: offsetPosition,
behavior: 'smooth',
});
} else {
// Center scroll (original behavior)
element.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest',
});
}
}
};
this.speak = () => {
if (!this.currentElement) return;
this.prevElement = this.currentElement;
this.scrollToElement(this.currentElement);
this.currentElement.classList.add('highlight');
const text = this.normalizeText(this.currentElement.innerText);
if (text) {
reader.post({
type: 'speak',
data: text,
index: this.elementsRead - 1,
});
reader.post({ type: 'tts-state', data: { isReading: true } });
} else {
this.next();
}
};
})();
// Watch for TTSEnable changes and stop TTS when disabled
van.derive(() => {
if (!reader.generalSettings.val.TTSEnable && window.tts) {
if (tts.reading || tts.started) {
tts.stop();
}
}
});
window.pageReader = new (function () {
this.page = van.state(0);
this.totalPages = van.state(0);
this.chapterEndingVisible = van.state(
initialPageReaderConfig.nextChapterScreenVisible,
);
this.chapterEnding = document.getElementsByClassName('transition-chapter')[0];
this.showChapterEnding = (bool, instant, left) => {
if (!this.chapterEnding) {
this.chapterEnding =
document.getElementsByClassName('transition-chapter')[0];
if (!this.chapterEnding) return;
}
this.chapterEnding.style.transition = 'unset';
if (bool) {
this.chapterEnding.style.transform = `translateX(${left ? -200 : 0}vw)`;
requestAnimationFrame(() => {
if (!instant) this.chapterEnding.style.transition = '200ms';
this.chapterEnding.style.transform = 'translateX(-100vw)';
});
this.chapterEndingVisible.val = true;
} else {
if (!instant) this.chapterEnding.style.transition = '200ms';
this.chapterEnding.style.transform = `translateX(${left ? -200 : 0}vw)`;
this.chapterEndingVisible.val = false;
}
};
this.movePage = destPage => {
if (this.chapterEndingVisible.val) {
if (destPage < 0) {
this.showChapterEnding(false);
return;
}
if (destPage < this.totalPages.val) {
this.showChapterEnding(false, false, true);
return;
}
if (destPage >= this.totalPages.val) {
return reader.post({ type: 'next' });
}
}
destPage = parseInt(destPage, 10);
if (destPage < 0) {
document.getElementsByClassName('transition-chapter')[0].innerText =
reader.prevChapter.name;
this.showChapterEnding(true, false, true);
setTimeout(() => {
reader.post({ type: 'prev' });
}, 200);
return;
}
if (destPage >= this.totalPages.val) {
document.getElementsByClassName('transition-chapter')[0].innerText =
reader.nextChapter.name;
this.showChapterEnding(true);
setTimeout(() => {
reader.post({ type: 'next' });
}, 200);
return;
}
this.page.val = destPage;
reader.chapterElement.style.transform =
'translateX(-' + destPage * 100 + '%)';
const newProgress = parseInt(
((pageReader.page.val + 1) / pageReader.totalPages.val) * 100,
10,
);
if (newProgress > reader.chapter.progress) {
reader.post({
type: 'save',
data: parseInt(
((pageReader.page.val + 1) / pageReader.totalPages.val) * 100,
10,
),
});
}
};
van.derive(() => {
// ignore if initial or other states change
if (
reader.generalSettings.val.pageReader ===
reader.generalSettings.oldVal.pageReader
) {
return;
}
if (reader.generalSettings.val.pageReader) {
const ratio = Math.min(
0.99,
(window.scrollY + reader.layoutHeight) / reader.chapterHeight,
);
document.body.classList.add('page-reader');
setTimeout(() => {
reader.refresh();
this.totalPages.val = parseInt(
(reader.chapterWidth + reader.readerSettings.val.padding * 2) /
reader.layoutWidth,
10,
);
this.movePage(this.totalPages.val * ratio);
}, 100);
} else {
reader.chapterElement.style = '';
document.body.classList.remove('page-reader');
setTimeout(() => {
reader.refresh();
window.scrollTo({
top:
(reader.chapterHeight * (this.page.val + 1)) / this.totalPages.val -
reader.layoutHeight,
behavior: 'smooth',
});
}, 100);
}
});
})();
document.addEventListener('DOMContentLoaded', () => {
if (pageReader.chapterEndingVisible.val) {
pageReader.showChapterEnding(true, true);
}
});
function calculatePages() {
reader.refresh();
if (reader.generalSettings.val.pageReader) {
pageReader.totalPages.val = parseInt(
(reader.chapterWidth + reader.readerSettings.val.padding * 2) /
reader.layoutWidth,
10,
);
if (initialPageReaderConfig.nextChapterScreenVisible) return;
pageReader.movePage(
Math.max(
0,
Math.round(
(pageReader.totalPages.val * reader.chapter.progress) / 100,
) - 1,
),
);
} else {
window.scrollTo({
top:
(reader.chapterHeight * reader.chapter.progress) / 100 -
reader.layoutHeight,
behavior: 'smooth',
});
}
}
const ro = new ResizeObserver(() => {
if (pageReader.totalPages.val) {
calculatePages();
}
});
ro.observe(reader.chapterElement);
// Also call once on load
window.addEventListener('load', () => {
document.fonts.ready.then(() => {
requestAnimationFrame(() => setTimeout(calculatePages, 0));
});
});
// click handler
(function () {
const detectTapPosition = (x, y, horizontal) => {
if (horizontal) {
if (x < 0.33) {
return 'left';
}
if (x > 0.66) {
return 'right';
}
} else {
if (y < 0.33) {
return 'top';
}
if (y > 0.66) {
return 'bottom';
}
}
return 'center';
};
document.onclick = e => {
const { clientX, clientY } = e;
const { x, y } = {
x: clientX / reader.layoutWidth,
y: clientY / reader.layoutHeight,
};
if (reader.generalSettings.val.pageReader) {
const position = detectTapPosition(x, y, true);
if (position === 'left') {
pageReader.movePage(pageReader.page.val - 1);
return;
}
if (position === 'right') {
pageReader.movePage(pageReader.page.val + 1);
return;
}
} else {
if (reader.generalSettings.val.tapToScroll) {
const position = detectTapPosition(x, y, false);
if (position === 'top') {
window.scrollBy({
top: -reader.layoutHeight * 0.75,
behavior: 'smooth',
});
return;
}
if (position === 'bottom') {
window.scrollBy({
top: reader.layoutHeight * 0.75,
behavior: 'smooth',
});
return;
}
}
}
reader.post({ type: 'hide' });
};
})();
// swipe handler
(function () {
this.initialX = null;
this.initialY = null;
reader.chapterElement.addEventListener('touchstart', e => {
this.initialX = e.changedTouches[0].screenX;
this.initialY = e.changedTouches[0].screenY;
});
reader.chapterElement.addEventListener('touchmove', e => {
if (reader.generalSettings.val.pageReader) {
const diffX =
(e.changedTouches[0].screenX - this.initialX) / reader.layoutWidth;
reader.chapterElement.style.transition = 'unset';
reader.chapterElement.style.transform =
'translateX(-' + (pageReader.page.val - diffX) * 100 + '%)';
}
});
reader.chapterElement.addEventListener('touchend', e => {
const diffX = e.changedTouches[0].screenX - this.initialX;
const diffY = e.changedTouches[0].screenY - this.initialY;
if (reader.generalSettings.val.pageReader) {
reader.chapterElement.style.transition = '200ms';
const diffXPercentage = diffX / reader.layoutWidth;
if (diffXPercentage < -0.3) {
pageReader.movePage(pageReader.page.val + 1);
} else if (diffXPercentage > 0.3) {
pageReader.movePage(pageReader.page.val - 1);
} else {
pageReader.movePage(pageReader.page.val);
}
return;
}
if (
e.target.id?.startsWith('scrollbar') ||
e.target.id === 'Image-Modal-img'
) {
return;
}
if (
reader.generalSettings.val.swipeGestures &&
Math.abs(diffX) > Math.abs(diffY) * 2 &&
Math.abs(diffX) > 180
) {
if (diffX < 0 && this.initialX >= window.innerWidth / 2) {
e.preventDefault();
reader.post({ type: 'next' });
} else if (diffX > 0 && this.initialX <= window.innerWidth / 2) {
e.preventDefault();
reader.post({ type: 'prev' });
}
}
});
})();
// text options
(function () {
van.derive(() => {
let html = reader.rawHTML;
if (reader.generalSettings.val.bionicReading) {
html = textVide.textVide(reader.rawHTML);
}
if (reader.generalSettings.val.removeExtraParagraphSpacing) {
html = html
.replace(/(?:&nbsp;\s*|[\u200b]\s*)+(?=<\/?p[> ])/g, '')
.replace(/<br>\s*<br>\s*(?:<br>\s*)+/g, '<br><br>') //force max 2 consecutive <br>, chaining regex
.replace(
/<br>\s*<br>[^]+/,
_ =>
`${
/\/p>/.test(_)
? _.replace(
/<br>\s*<br>(?:(?=\s*<\/?p[> ])|(?<=<\/?p\b[^>]*><br>\s*<br>))\s*/g,
'',
)
: _
}`,
) //if p found, delete all double br near p
.replace(/<br>(?:(?=\s*<\/?p[> ])|(?<=<\/?p>\s*<br>))\s*/g, '');
}
reader.chapterElement.innerHTML = html;
});
})();
+6
View File
@@ -0,0 +1,6 @@
const volumnIcon =
'<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M552-152v-75q86-23 139-93.5T744-480q0-89-53.5-158.5T552-734v-75q116 25 190 117t74 211q0 119-73.5 211.5T552-152ZM144-385v-192h144l192-192v576L288-385H144Zm408 55v-302q45 20 70.5 61t25.5 90q0 49-25.5 89.5T552-330Z"/></svg>';
const pauseIcon =
'<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M564-228v-504h168v504H564Zm-336 0v-504h168v504H228Z"/></svg>';
const resumeIcon =
'<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M240-240v-480h72v480h-72Zm144 0 384-240-384-240v480Z"/></svg>';
+62
View File
@@ -0,0 +1,62 @@
import { ChapterInfo, NovelInfo } from '@database/types';
import {
ChapterGeneralSettings,
ChapterReaderSettings,
} from '@hooks/persisted/useSettings';
import { State } from './van';
export interface Reader {
// element
chapterElement: HTMLElement;
viewport: HTMLMetaElement;
selection: Selection;
// state
hidden: State<boolean>;
generalSettings: State<ChapterGeneralSettings>;
readerSettings: State<ChapterReaderSettings>;
batteryLevel: State<number>;
novel: NovelInfo;
chapter: ChapterInfo;
nextChapter?: ChapterInfo;
autoSaveInterval: number;
rawHTML: string;
strings: {
finished: string;
nextChapter: string;
noNextChapter: string;
};
//layout props
paddingTop: number;
layoutHeight: number;
layoutWidth: number;
chapterHeight: number;
chapterWidth: number;
post: (obj: Record<string, any>) => void;
refresh: () => void;
}
interface PageReader {
page: State<number>;
totalPages: State<number>;
movePage: (page: number) => void;
}
interface TTS {
started: boolean;
reading: boolean;
start: (element?: HTMLElement) => void;
resume: () => void;
stop: () => void;
pause: () => void;
readable: (element?: HTMLElement) => void;
}
declare global {
const reader: Reader;
const tts: TTS;
const pageReader: PageReader;
}
+351
View File
@@ -0,0 +1,351 @@
const { div, p, img, button } = van.tags;
const ChapterEnding = () => {
return () =>
reader.generalSettings.val.pageReader
? div()
: div(div({ class: 'info-text' }, reader.strings.finished), () =>
reader.nextChapter
? button(
{
class: 'next-button',
onclick: e => {
e.stopPropagation();
reader.post({ type: 'next' });
},
},
reader.strings.nextChapter,
)
: div({ class: 'info-text' }, reader.strings.noNextChapter),
);
};
const Scrollbar = () => {
const horizontal = van.derive(
() => !reader.generalSettings.val.verticalSeekbar,
);
let lock = false;
const percentage = van.state(0);
const update = ratio => {
if (ratio === undefined) {
ratio = (window.scrollY + reader.layoutHeight) / reader.chapterHeight;
}
if (ratio > 1) {
ratio = 1;
}
if (reader.generalSettings.val.pageReader) {
pageReader.movePage(
parseInt(pageReader.totalPages.val * Math.min(0.99, ratio)),
);
return;
}
percentage.val = parseInt(ratio * 100);
if (lock) {
window.scrollTo({
top: reader.chapterHeight * ratio - reader.layoutHeight,
behavior: 'instant',
});
}
};
window.addEventListener(
'scroll',
() => !lock && !reader.generalSettings.val.pageReader && update(),
);
return div(
{ id: 'ScrollBar' },
div(
{ class: 'scrollbar-item scrollbar-text', id: 'scrollbar-percentage' },
() =>
reader.generalSettings.val.pageReader
? pageReader.page.val + 1
: percentage.val,
),
div(
{ class: 'scrollbar-item', id: 'scrollbar-slider' },
div(
{ id: 'scrollbar-track' },
div(
{
id: 'scrollbar-progress',
style: () => {
const percentageValue = reader.generalSettings.val.pageReader
? ((pageReader.page.val + 1) / pageReader.totalPages.val) * 100
: percentage.val;
return horizontal.val
? `width: ${percentageValue}%; height: 100%;`
: `height: ${percentageValue}%; width: 100%;`;
},
},
div(
{
id: 'scrollbar-thumb-wrapper',
ontouchstart: () => {
lock = true;
},
ontouchend: () => {
lock = false;
},
ontouchmove: function (e) {
const slider = this.parentElement.parentElement.parentElement;
const sliderHeight = horizontal.val
? slider.clientWidth
: slider.clientHeight;
const sliderOffsetY = horizontal.val
? slider.getBoundingClientRect().left
: slider.getBoundingClientRect().top;
const ratio =
((horizontal.val
? e.changedTouches[0].clientX
: e.changedTouches[0].clientY) -
sliderOffsetY) /
sliderHeight;
update(ratio < 0 ? 0 : ratio);
},
},
div({ id: 'scrollbar-thumb' }),
),
),
),
),
div(
{
class: 'scrollbar-item scrollbar-text',
id: 'scrollbar-percentage-max',
},
() =>
reader.generalSettings.val.pageReader ? pageReader.totalPages.val : 100,
),
);
};
const ToolWrapper = () => {
const horizontal = van.derive(
() => !reader.generalSettings.val.verticalSeekbar,
);
return div(
{
id: 'ToolWrapper',
class: () =>
`${reader.hidden.val ? 'hidden' : ''} ${
horizontal.val ? 'horizontal' : ''
}`,
},
Scrollbar(),
);
};
const ImageModal = ({ src }) => {
return div(
{
id: 'Image-Modal',
class: () => (src.val ? 'show' : ''),
onclick: e => {
if (e.target.id !== 'Image-Modal-img') {
e.stopPropagation();
src.val = '';
}
},
},
img({
id: 'Image-Modal-img',
src: src,
alt: () => (src.val ? `Cant not render image from ${src.val}` : ''),
}),
);
};
const ModalWrapper = () => {
const imgSrc = van.state('');
const showImage = src => {
imgSrc.val = src;
reader.viewport.setAttribute(
'content',
'width=device-width, initial-scale=1.0, maximum-scale=10',
);
};
const hideImage = () => {
imgSrc.val = '';
reader.viewport.setAttribute(
'content',
'width=device-width, initial-scale=1.0, maximum-scale=1.0',
);
};
document.addEventListener('contextmenu', e => {
if (e.target instanceof HTMLImageElement) {
if (!imgSrc.val) {
showImage(e.target.src);
} else {
hideImage();
}
}
});
return div(ImageModal({ src: imgSrc }));
};
const Footer = () => {
const percentage = van.state(0);
const time = van.state(
new Date().toLocaleTimeString(undefined, {
hour: '2-digit',
minute: '2-digit',
hour12: false,
}),
);
window.addEventListener('scroll', () => {
let ratio = (window.scrollY + reader.layoutHeight) / reader.chapterHeight;
if (ratio > 1) {
ratio = 1;
}
percentage.val = parseInt(ratio * 100);
});
setInterval(() => {
time.val = new Date().toLocaleTimeString(undefined, {
hour: '2-digit',
minute: '2-digit',
hour12: false,
});
}, 10000);
return div(
{
id: 'reader-footer-wrapper',
class: () =>
reader.generalSettings.val.showBatteryAndTime ||
reader.generalSettings.val.showScrollPercentage
? ''
: 'd-none',
},
div(
{ id: 'reader-footer' },
div(
{
id: 'reader-battery',
class: () =>
`reader-footer-item ${
reader.generalSettings.val.showBatteryAndTime ? '' : 'hidden'
}`,
},
() => Math.ceil(reader.batteryLevel.val * 100) + '%',
),
div(
{
id: 'reader-percentage',
class: () =>
`reader-footer-item ${
reader.generalSettings.val.showScrollPercentage ? '' : 'hidden'
}`,
},
() =>
reader.generalSettings.val.pageReader
? `${pageReader.page.val + 1}/${pageReader.totalPages.val}`
: percentage.val + '%',
),
div(
{
id: 'reader-time',
class: () =>
`reader-footer-item ${
reader.generalSettings.val.showBatteryAndTime ? '' : 'hidden'
}`,
},
time,
),
),
);
};
const TTSController = () => {
let controllerElement = null;
let hoverElement = null;
let clientX = null;
let clientY = null;
return div(
{
id: 'TTS-Controller',
class: () => `${reader.generalSettings.val.TTSEnable ? '' : 'hidden'}`,
style: () =>
reader.generalSettings.val.TTSEnable
? 'pointer-events: auto;'
: 'pointer-events: none; display: none !important; opacity: 0; transition: none;',
ontouchstart: () => {
if (!controllerElement) {
controllerElement = document.getElementById('TTS-Controller');
}
controllerElement.classList.add('active');
controllerElement.style.transition = '';
},
ontouchmove: e => {
e.preventDefault();
e.stopPropagation();
clientX = e.changedTouches[0].clientX;
clientY = e.changedTouches[0].clientY;
controllerElement.style.left = `${clientX}px`;
controllerElement.style.top = `${clientY}px`;
const hoverElements = document.elementsFromPoint(clientX, clientY);
const newHoverElement = hoverElements.reverse().find(e => {
if (e.id.includes('scrollbar')) {
return false;
}
return tts.readable(e);
});
hoverElement?.classList.remove('highlight');
if (newHoverElement) {
newHoverElement.classList.add('highlight');
hoverElement = newHoverElement;
} else {
hoverElement = null;
}
},
ontouchend: () => {
controllerElement.style.transition = '1s';
controllerElement.classList.remove('active');
controllerElement.style.left = '20px';
if (clientX && clientY) {
let top = clientY < 120 ? 120 : clientY;
if (top + 120 > reader.layoutHeight) {
top = reader.layoutHeight - 120;
}
controllerElement.style.top = `${top}px`;
// Check if TTS is still enabled before starting
if (hoverElement && reader.generalSettings.val.TTSEnable) {
tts.start(hoverElement);
controllerElement.firstElementChild.innerHTML = pauseIcon;
}
}
clientX = null;
clientY = null;
},
onclick: e => {
e.stopPropagation();
// Don't allow interaction if TTS is disabled
if (!reader.generalSettings.val.TTSEnable) {
return;
}
if (tts.reading) {
tts.pause();
controllerElement.firstElementChild.innerHTML = resumeIcon;
} else if (tts.started) {
tts.resume();
controllerElement.firstElementChild.innerHTML = pauseIcon;
} else {
tts.start();
controllerElement.firstElementChild.innerHTML = pauseIcon;
}
},
},
button({ innerHTML: volumnIcon }),
);
};
const ReaderUI = () => {
return div(
ToolWrapper(),
TTSController(),
ModalWrapper(),
Footer(),
ChapterEnding(),
);
};
van.add(document.getElementById('reader-ui'), ReaderUI());
@@ -0,0 +1,91 @@
/* eslint-disable eslint-comments/no-unlimited-disable */
/* eslint-disable */
'use strict';
(() => {
function f(i, o, r, s = !1) {
if (!(o in i) || typeof r != 'function') return !1;
let t = i[o];
return (
(i[o] = function (...e) {
return (
s || t.apply(this, e), (t = t.bind(this)), r.apply(this, [t, ...e])
);
}),
!0
);
}
if (typeof window == 'undefined') throw 'Not in a browser.';
var p = 'onscrollend' in window;
if (!p) {
let s = function (e, u, l) {
if (u !== 'scrollend') {
e.apply(this, [u, l]);
return;
}
let c = this,
n = i.get(c);
if (!n) {
let d;
(n = {
scrollFn: () => {
clearTimeout(d),
(d = setTimeout(() => {
l();
}, 100));
},
handlers: [l],
}),
e.apply(c, ['scroll', n.scrollFn, !1]),
i.set(c, n);
}
},
t = function (e, u, l) {
if (u !== 'scrollend') {
e.apply(this, [u, l]);
return;
}
let c = this,
n = i.get(c);
if (n) {
if (
(typeof n.scrollFn == 'function' &&
e.apply(this, ['scroll', n.scrollFn]),
typeof l == 'undefined')
)
n.handlers = [];
else {
let d = n.handlers.indexOf(l);
d > -1 && n.handlers.splice(d, 1);
}
n.handlers.length === 0 && i.delete(c);
}
};
(a = s), (w = t);
let i = new WeakMap(),
o = null,
r = null;
f(window, 'addEventListener', s, !0),
f(window, 'removeEventListener', t, !0),
Object.defineProperty(window, 'onscrollend', {
set: e => {
(typeof e != 'function' || o) &&
t.call(window, window.removeEventListener, 'scrollend', o),
(o = e),
e && s.call(window, window.addEventListener, 'scrollend', e);
},
get: () => o,
}),
f(document, 'addEventListener', s, !0),
f(document, 'removeEventListener', t, !0),
Object.defineProperty(document, 'onscrollend', {
set: e => {
(typeof e != 'function' || r) &&
t.call(document, document.removeEventListener, 'scrollend', r),
(r = e),
e && s.call(document, document.addEventListener, 'scrollend', e);
},
get: () => r,
});
}
var a, w;
})();
@@ -0,0 +1 @@
var textVide = function(L){'use strict'; const f = t=>t == null || t === '',h = (t,n)=>Object.keys(t).reduce((e,s)=>(n(e[s]) && delete e[s],e),t),I = (t,n)=>({...n,...h(t,f)}),_ = ['<b>','</b>'],y = t=>I(t,{sep:_,fixationPoint:1,ignoreHtmlTag:!0,ignoreHtmlEntity:!0}),u = [[0,4,12,17,24,29,35,42,48],[1,2,7,10,13,14,19,22,25,28,31,34,37,40,43,46,49],[1,2,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49],[0,2,4,5,6,8,9,11,14,15,17,18,20,0,21,23,24,26,27,29,30,32,33,35,36,38,39,41,42,44,45,47,48],[0,2,3,5,6,7,8,10,11,12,14,15,17,19,20,21,23,24,25,26,28,29,30,32,33,34,35,37,38,39,41,42,43,44,46,47,48]],A = (t,n)=>{const {length:i} = t,e = u[n - 1] ?? u[0],s = e.findIndex(c=>i <= c); let o = i - s; return s === -1 && (o = i - e.length),Math.max(o,0);},R = (t,n)=>typeof n === 'string' ? `${n}${t}${n}` : `${n[0]}${t}${n[1]}`,m = t=>Array.from(t).map(n=>{const i = n.index,[e] = n,{length:s} = e; return [i,i + s - 1];}),H = /<!--[^]*?-->|(<[^>]+>)/g,N = t=>{const n = t.matchAll(H),e = m(n).reverse(); return s=>{const o = s.index,c = e.find(([r])=>o > r); if (!c) {return !1;} const [,a] = c; return o < a;};},O = /&[\w#]+;/g,M = t=>{const n = t.matchAll(O),e = m(n).reverse(); return s=>{const o = s.index,c = e.find(([r])=>o > r); if (!c) {return !1;} const [,a] = c; return o < a;};},x = /(\p{L}|\p{Nd})*\p{L}(\p{L}|\p{Nd})*/gu,F = (t,n = {})=>{if (!(t != null && t.length)) {return '';} const {fixationPoint:i,sep:e,ignoreHtmlTag:s,ignoreHtmlEntity:o} = y(n),c = Array.from(t.matchAll(x)); let a = '',l = 0,r; s && (r = N(t)); let d; o && (d = M(t)); for (const g of c){if ((r == null ? void 0 : r(g)) || (d == null ? void 0 : d(g))) {continue;} const [D] = g,T = g.index,E = T + A(D,i),U = t.slice(l,T); a += U,T !== E && (a += R(t.slice(T,E),e)),l = E;} const G = t.slice(l); return a + G;}; return L.textVide = F,Object.defineProperty(L,Symbol.toStringTag,{value:'Module'}),L;}({});
+70
View File
@@ -0,0 +1,70 @@
import 'typescript';
import 'typescript/lib/lib.dom';
export interface State<T> {
val: T;
readonly oldVal: T;
readonly rawVal: T;
}
// Defining readonly view of State<T> for covariance.
// Basically we want StateView<string> to implement StateView<string | number>
export type StateView<T> = Readonly<State<T>>;
export type Val<T> = State<T> | T;
export type Primitive = string | number | boolean | bigint;
export type PropValue = Primitive | ((e: any) => void) | null;
export type PropValueOrDerived =
| PropValue
| StateView<PropValue>
| (() => PropValue);
export type Props = Record<string, PropValueOrDerived> & {
class?: PropValueOrDerived;
};
export type PropsWithKnownKeys<ElementType> = Partial<{
[K in keyof ElementType]: PropValueOrDerived;
}>;
export type ValidChildDomValue = Primitive | Node | null | undefined;
export type BindingFunc =
| ((dom?: Node) => ValidChildDomValue)
| ((dom?: Element) => Element);
export type ChildDom =
| ValidChildDomValue
| StateView<Primitive | null | undefined>
| BindingFunc
| readonly ChildDom[];
export type TagFunc<Result> = (
first?: (Props & PropsWithKnownKeys<Result>) | ChildDom,
...rest: readonly ChildDom[]
) => Result;
type Tags = Readonly<Record<string, TagFunc<Element>>> & {
[K in keyof HTMLElementTagNameMap]: TagFunc<HTMLElementTagNameMap[K]>;
};
declare function state<T>(): State<T>;
declare function state<T>(initVal: T): State<T>;
export interface Van {
readonly state: typeof state;
readonly derive: <T>(f: () => T) => State<T>;
readonly add: (dom: Element, ...children: readonly ChildDom[]) => Element;
readonly tags: Tags &
((namespaceURI: string) => Readonly<Record<string, TagFunc<Element>>>);
readonly hydrate: <T extends Node>(
dom: T,
f: (dom: T) => T | null | undefined,
) => T;
}
declare global {
const van: Van;
}
+1
View File
@@ -0,0 +1 @@
{let e,t,r,o,n,l,s,f,i,h,w,a,d,u,_,c,S,g,y,b,m,v,j,x,O; s = Object.getPrototypeOf,i = {},h = s(f = {isConnected:1}),w = s(s),a = (e,t,r,o)=>(e ?? (setTimeout(r,o),new Set())).add(t),d = (e,t,o)=>{let n = r; r = t; try {return e(o);} catch (e){return console.error(e),o;} finally {r = n;}},u = e=>e.filter(e=>e.t?.isConnected),_ = e=>n = a(n,e,()=>{for (let e of n){e.o = u(e.o),e.l = u(e.l);}n = l;},1e3),c = {get val(){return r?.i?.add(this),this.rawVal;},get oldVal(){return r?.i?.add(this),this.h;},set val(o){r?.u?.add(this),o !== this.rawVal && (this.rawVal = o,this.o.length + this.l.length ? (t?.add(this),e = a(e,this,x)) : this.h = o);}},S = e=>({__proto__:c,rawVal:e,h:e,o:[],l:[]}),g = (e,t)=>{let r = {i:new Set(),u:new Set()},n = {f:e},l = o; o = []; let s = d(e,r,t); s = (s ?? document).nodeType ? s : new Text(s); for (let e of r.i){r.u.has(e) || (_(e),e.o.push(n));} for (let e of o){e.t = s;} return o = l,n.t = s;},y = (e,t = S(),r)=>{let n = {i:new Set(),u:new Set()},l = {f:e,s:t}; l.t = r ?? o?.push(l) ?? f,t.val = d(e,n,t.rawVal); for (let e of n.i){n.u.has(e) || (_(e),e.l.push(l));} return t;},b = (e,...t)=>{for (let r of t.flat(1 / 0)){let t = s(r ?? 0),o = t === c ? g(()=>r.val) : t === w ? g(r) : r; o != l && e.append(o);} return e;},m = (e,t,...r)=>{let [o,...n] = s(r[0] ?? 0) === h ? r : [{},...r],f = e ? document.createElementNS(e,t) : document.createElement(t); for (let [e,r] of Object.entries(o)){let o = t=>t ? Object.getOwnPropertyDescriptor(t,e) ?? o(s(t)) : l,n = t + ',' + e,h = i[n] ?? (i[n] = o(s(f))?.set ?? 0),a = e.startsWith('on') ? (t,r)=>{let o = e.slice(2); f.removeEventListener(o,r),f.addEventListener(o,t);} : h ? h.bind(f) : f.setAttribute.bind(f,e),d = s(r ?? 0); e.startsWith('on') || d === w && (r = y(r),d = c),d === c ? g(()=>(a(r.val,r.h),f)) : a(r);} return b(f,n);},v = e=>({get:(t,r)=>m.bind(l,e,r)}),j = (e,t)=>t ? t !== e && e.replaceWith(t) : e.remove(),x = ()=>{let r = 0,o = [...e].filter(e=>e.rawVal !== e.h); do {t = new Set(); for (let e of new Set(o.flatMap(e=>e.l = u(e.l)))){y(e.f,e.s,e.t),e.t = l;}} while (++r < 100 && (o = [...t]).length); let n = [...e].filter(e=>e.rawVal !== e.h); e = l; for (let e of new Set(n.flatMap(e=>e.o = u(e.o)))){j(e.t,g(e.f,e.t)),e.t = l;} for (let e of n){e.h = e.rawVal;}},O = {tags:new Proxy(e=>new Proxy(m,v(e)),v()),hydrate:(e,t)=>j(e,g(t,e)),add:b,state:S,derive:y},window.van = O;}
@@ -1,71 +0,0 @@
package com.rajarsheechatterjee.LNReader;
import android.content.res.Configuration;
import android.content.Intent;
import android.os.Bundle;
import android.graphics.Color;
import android.view.WindowManager;
import android.os.Build;
import android.view.View;
import android.view.Window;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
import expo.modules.splashscreen.singletons.SplashScreen;
import expo.modules.splashscreen.SplashScreenImageResizeMode;
public class MainActivity extends ReactActivity {
// Added automatically by Expo Config
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
sendBroadcast(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// SplashScreen.show(...) has to be called after super.onCreate(...)
// Below line is handled by '@expo/configure-splash-screen' command and it's discouraged to modify it manually
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(layoutParams);
}
Window w = getWindow();
w.setStatusBarColor(Color.TRANSPARENT);
w.setNavigationBarColor(Color.TRANSPARENT);
w.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
super.onCreate(null);
SplashScreen.show(this, SplashScreenImageResizeMode.COVER, ReactRootView.class, false);
}
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "main";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
@@ -0,0 +1,74 @@
package com.rajarsheechatterjee.LNReader
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import com.rajarsheechatterjee.NativeVolumeButtonListener.NativeVolumeButtonListener
import expo.modules.ReactActivityDelegateWrapper
import org.devio.rn.splashscreen.SplashScreen
class MainActivity : ReactActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val layoutParams = WindowManager.LayoutParams()
layoutParams.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
window.attributes = layoutParams
}
window.statusBarColor = Color.TRANSPARENT
window.navigationBarColor = Color.TRANSPARENT
@Suppress("DEPRECATION")
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
super.onCreate(null)
SplashScreen.show(this, R.style.SplashScreenTheme, R.id.lottie)
SplashScreen.setAnimationFinished(true)
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (NativeVolumeButtonListener.isActive) {
val action = event.action
return when (event.keyCode) {
KeyEvent.KEYCODE_VOLUME_UP -> {
if (action == KeyEvent.ACTION_DOWN) {
NativeVolumeButtonListener.sendEvent(true)
}
true
}
KeyEvent.KEYCODE_VOLUME_DOWN -> {
if (action == KeyEvent.ACTION_DOWN) {
NativeVolumeButtonListener.sendEvent(false)
}
true
}
else -> super.dispatchKeyEvent(event)
}
}
return super.dispatchKeyEvent(event)
}
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
override fun getMainComponentName(): String = "main"
override fun createReactActivityDelegate(): ReactActivityDelegate {
return ReactActivityDelegateWrapper(
this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, DefaultReactActivityDelegate(
this,
mainComponentName, // If you opted-in for the New Architecture, we enable the Fabric Renderer.
fabricEnabled
)
)
}
}
@@ -1,129 +0,0 @@
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;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.rajarsheechatterjee.LNReader.generated.BasePackageList;
import org.unimodules.adapters.react.ReactAdapterPackage;
import org.unimodules.adapters.react.ModuleRegistryAdapter;
import org.unimodules.adapters.react.ReactModuleRegistryProvider;
import org.unimodules.core.interfaces.Package;
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;
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(
new BasePackageList().getPackageList()
);
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider));
packages.add(new NavigationBarColorPackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
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
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (!BuildConfig.DEBUG) {
UpdatesController.initialize(this);
}
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* @param context
* @param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.rajarsheechatterjee.LNReader.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
@@ -0,0 +1,52 @@
package com.rajarsheechatterjee.LNReader
import android.app.Application
import android.content.res.Configuration
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
import com.rajarsheechatterjee.NativeFile.NativePackage
import com.rajarsheechatterjee.NativeVolumeButtonListener.NativeVolumeButtonListenerPackage
import com.rajarsheechatterjee.NativeZipArchive.NativeZipArchivePackage
import expo.modules.ApplicationLifecycleDispatcher
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(NativePackage())
add(NativeVolumeButtonListenerPackage())
add(NativeZipArchivePackage())
}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
loadReactNative(this)
ApplicationLifecycleDispatcher.onApplicationCreate(this)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
}
}
@@ -1,29 +0,0 @@
package com.rajarsheechatterjee.LNReader.generated;
import java.util.Arrays;
import java.util.List;
import org.unimodules.core.interfaces.Package;
public class BasePackageList {
public List<Package> getPackageList() {
return Arrays.<Package>asList(
new expo.modules.application.ApplicationPackage(),
new expo.modules.constants.ConstantsPackage(),
new expo.modules.documentpicker.DocumentPickerPackage(),
new expo.modules.errorrecovery.ErrorRecoveryPackage(),
new expo.modules.filesystem.FileSystemPackage(),
new expo.modules.font.FontLoaderPackage(),
new expo.modules.haptics.HapticsPackage(),
new expo.modules.imageloader.ImageLoaderPackage(),
new expo.modules.keepawake.KeepAwakePackage(),
new expo.modules.lineargradient.LinearGradientPackage(),
new expo.modules.localization.LocalizationPackage(),
new expo.modules.notifications.NotificationsPackage(),
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()
);
}
}
@@ -0,0 +1,227 @@
package com.rajarsheechatterjee.NativeFile
import android.net.Uri
import android.os.Build
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeArray
import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.modules.network.CookieJarContainer
import com.facebook.react.modules.network.ForwardingCookieHandler
import com.facebook.react.modules.network.OkHttpClientProvider
import com.lnreader.spec.NativeFileSpec
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Headers
import okhttp3.JavaNetCookieJar
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.io.File
import java.io.FileOutputStream
import java.io.FileWriter
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.io.PushbackInputStream
import java.util.zip.GZIPInputStream
class NativeFile(context: ReactApplicationContext) :
NativeFileSpec(context) {
private val BUFFER_SIZE = 4096
private val okHttpClient = OkHttpClientProvider.createClient()
private val coroutineScope = CoroutineScope(Dispatchers.IO)
init {
val cookieContainer = okHttpClient.cookieJar as CookieJarContainer
val cookieHandler = ForwardingCookieHandler(reactApplicationContext)
cookieContainer.setCookieJar(JavaNetCookieJar(cookieHandler))
}
private fun getFileUri(filepath: String): Uri {
var uri = Uri.parse(filepath)
if (uri.scheme == null) {
// No prefix, assuming that provided path is absolute path to file
val file = File(filepath)
if (file.isDirectory) {
throw Exception("Invalid file, folder found!")
}
uri = Uri.parse("file://$filepath")
}
return uri
}
private fun getInputStream(filepath: String): InputStream {
val uri = getFileUri(filepath)
return reactApplicationContext.contentResolver.openInputStream(uri)
?: throw Exception("ENOENT: could not open an input stream for '$filepath'")
}
private val writeAccessByAPILevel: String
get() = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) "w" else "rwt"
private fun getOutputStream(filepath: String): OutputStream {
val uri = getFileUri(filepath)
return reactApplicationContext.contentResolver.openOutputStream(uri, writeAccessByAPILevel)
?: throw Exception("ENOENT: could not open an output stream for '$filepath'")
}
override fun writeFile(path: String, content: String) {
val fw = FileWriter(path)
fw.write(content)
fw.close()
}
override fun readFile(path: String): String {
return File(path).bufferedReader().readText()
}
override fun copyFile(filepath: String, destPath: String) {
copyFileContent(filepath, destPath)
}
override fun moveFile(filepath: String, destPath: String) {
val inFile = File(filepath)
copyFileContent(filepath, destPath, { inFile.delete() })
}
private fun copyFileContent(
filepath: String,
destPath: String,
onDone: (() -> Unit)? = null,
) {
val inputStream = getInputStream(filepath)
val outputStream = getOutputStream(destPath)
val buffer = ByteArray(BUFFER_SIZE)
var length: Int
while (inputStream.read(buffer).also { length = it } > 0) {
outputStream.write(buffer, 0, length)
}
inputStream.close()
outputStream.close()
if (onDone != null) {
onDone()
}
}
override fun exists(filepath: String) = File(filepath).exists()
override fun mkdir(filepath: String) {
val file = File(filepath)
if (!file.exists()) {
val created = file.mkdirs()
if (!created) throw Exception("Directory could not be created")
}
}
private fun deleteRecursive(fileOrDirectory: File) {
if (fileOrDirectory.isDirectory) {
for (child in fileOrDirectory.listFiles()!!) {
deleteRecursive(child)
}
}
fileOrDirectory.delete()
}
override fun unlink(filepath: String) {
val file = File(filepath)
if (!file.exists()) throw Exception("File does not exist")
deleteRecursive(file)
}
override fun readDir(directory: String): WritableArray {
val file = File(directory)
if (!file.exists()) throw Exception("Folder does not exist")
val files = file.listFiles()
val fileMaps: WritableArray = WritableNativeArray()
for (childFile in files!!) {
val fileMap: WritableMap = WritableNativeMap()
fileMap.putString("name", childFile.name)
fileMap.putString("path", childFile.absolutePath)
fileMap.putBoolean("isDirectory", childFile.isDirectory)
fileMaps.pushMap(fileMap)
}
return fileMaps
}
private fun decompressStream(input: InputStream?): InputStream {
val pb = PushbackInputStream(input, 2)
val signature = ByteArray(2)
val len = pb.read(signature)
if(len == -1) return pb;
pb.unread(signature, 0, len)
return if (signature[0] == 0x1f.toByte() && signature[1] == 0x8b.toByte())
GZIPInputStream(pb) else pb
}
override fun downloadFile(
url: String,
destPath: String,
method: String,
headers: ReadableMap,
body: String?,
promise: Promise
) {
coroutineScope.launch {
try {
val headersBuilder = Headers.Builder()
headers.entryIterator.forEach { entry ->
headersBuilder.add(entry.key, entry.value.toString())
}
val requestBuilder = Request.Builder()
.url(url)
.headers(headersBuilder.build())
if (method.lowercase() == "get") {
requestBuilder.get()
} else if (body != null) {
requestBuilder.post(body.toRequestBody())
}
okHttpClient.newCall(requestBuilder.build())
.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
promise.reject(e)
}
override fun onResponse(call: Call, response: Response) {
if (!response.isSuccessful || response.body == null) {
promise.reject(Exception("Failed to download load: ${response.code}"))
return
}
try {
val inputStream = decompressStream(response.body!!.byteStream())
FileOutputStream(destPath).use { fos ->
inputStream.copyTo(fos, BUFFER_SIZE)
}
promise.resolve(null)
} catch (e: Exception) {
promise.reject(e)
}
}
})
} catch (e: Exception) {
promise.reject(e)
}
}
}
override fun getTypedExportedConstants(): MutableMap<String, Any> {
val constants: MutableMap<String, Any> = HashMap()
val externalDirectory = this.reactApplicationContext.getExternalFilesDir(null)
if (externalDirectory != null) {
constants["ExternalDirectoryPath"] = externalDirectory.absolutePath
}
val externalCachesDirectory = this.reactApplicationContext.externalCacheDir
if (externalCachesDirectory != null) {
constants["ExternalCachesDirectoryPath"] = externalCachesDirectory.absolutePath
}
return constants
}
}
@@ -0,0 +1,30 @@
package com.rajarsheechatterjee.NativeFile
import com.facebook.react.BaseReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.lnreader.spec.NativeFileSpec
class NativePackage : BaseReactPackage() {
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
if (name == NativeFileSpec.NAME) {
NativeFile(reactContext)
} else {
null
}
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf(
NativeFileSpec.NAME to ReactModuleInfo(
NativeFileSpec.NAME,
NativeFileSpec.NAME,
canOverrideExistingModule = false,
needsEagerInit = false,
isCxxModule = false,
isTurboModule = true
)
)
}
}
@@ -0,0 +1,32 @@
package com.rajarsheechatterjee.NativeVolumeButtonListener
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.lnreader.spec.NativeVolumeButtonListenerSpec
class NativeVolumeButtonListener(appContext: ReactApplicationContext) :
NativeVolumeButtonListenerSpec(appContext) {
init {
NativeVolumeButtonListener.appContext = appContext
}
override fun addListener(eventName: String?) {
isActive = true
}
override fun removeListeners(count: Double) {
isActive = false
}
companion object {
lateinit var appContext: ReactApplicationContext
var isActive = false
fun sendEvent(up: Boolean) {
if (isActive) {
appContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(if (up) "VolumeUp" else "VolumeDown", null)
}
}
}
}
@@ -0,0 +1,30 @@
package com.rajarsheechatterjee.NativeVolumeButtonListener
import com.facebook.react.BaseReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.lnreader.spec.NativeVolumeButtonListenerSpec
class NativeVolumeButtonListenerPackage : BaseReactPackage() {
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
if (name == NativeVolumeButtonListenerSpec.NAME) {
NativeVolumeButtonListener(reactContext)
} else {
null
}
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf(
NativeVolumeButtonListenerSpec.NAME to ReactModuleInfo(
NativeVolumeButtonListenerSpec.NAME,
NativeVolumeButtonListenerSpec.NAME,
canOverrideExistingModule = false,
needsEagerInit = false,
isCxxModule = false,
isTurboModule = true
)
)
}
}
@@ -0,0 +1,137 @@
package com.rajarsheechatterjee.NativeZipArchive
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.ReadableMap
import com.lnreader.spec.NativeZipArchiveSpec
import java.io.File
import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
class NativeZipArchive(context: ReactApplicationContext) : NativeZipArchiveSpec(context) {
@ReactMethod
override fun unzip(sourceFilePath: String, distDirPath: String, promise: Promise) {
Thread {
try {
ZipFile(sourceFilePath).use { zis ->
zis.entries().asSequence().filterNot { it.isDirectory }.forEach { zipEntry ->
val newFile = File(distDirPath, zipEntry.name)
newFile.parentFile?.mkdirs()
zis.getInputStream(zipEntry).use { inputStream ->
FileOutputStream(newFile).use { fos -> inputStream.copyTo(fos, 4096) }
}
Thread.yield()
}
}
promise.resolve(null)
} catch (e: Exception) {
promise.reject(e)
}
}.start()
}
@ReactMethod
override fun zip(sourceDirPath: String, zipFilePath: String, promise: Promise) {
Thread {
try {
FileOutputStream(zipFilePath).use { fos ->
ZipOutputStream(fos).use { zos -> zipProcess(sourceDirPath, zos) }
}
promise.resolve(null)
} catch (e: Exception) {
promise.reject(e)
}
}.start()
}
@ReactMethod
override fun remoteUnzip(
distDirPath: String,
urlString: String,
headers: ReadableMap,
promise: Promise
) {
val connection = URL(urlString).openConnection() as HttpURLConnection
Thread {
try {
connection.requestMethod = "GET"
val it = headers.entryIterator
while (it.hasNext()) {
val (key, value) = it.next()
connection.setRequestProperty(key, value.toString())
}
ZipInputStream(connection.inputStream).use { zis ->
generateSequence { zis.nextEntry }
.filterNot { it.isDirectory }
.forEach { zipEntry ->
val newFile = File(distDirPath, zipEntry.name)
newFile.parentFile?.mkdirs()
FileOutputStream(newFile).use { fos -> zis.copyTo(fos, 4096) }
Thread.yield()
}
}
if (connection.responseCode == 200) {
promise.resolve(null)
} else {
throw Exception("Network request failed")
}
} catch (e: Exception) {
promise.reject(e)
} finally {
connection.disconnect()
}
}.start()
}
private fun zipProcess(sourceDirPath: String, zos: ZipOutputStream) {
val sourceDir = File(sourceDirPath)
sourceDir.walkBottomUp().filter { it.isFile }.forEach { file ->
val zipFileName =
file.absolutePath.removePrefix(sourceDir.absolutePath).removePrefix("/")
val entry = ZipEntry("$zipFileName${(if (file.isDirectory) "/" else "")}")
zos.putNextEntry(entry)
file.inputStream().use { fis ->
fis.copyTo(zos, 4096)
fis.close()
}
Thread.yield()
}
}
@ReactMethod
override fun remoteZip(
sourceDirPath: String,
urlString: String,
headers: ReadableMap,
promise: Promise
) {
Thread {
val connection = URL(urlString).openConnection() as HttpURLConnection
try {
connection.requestMethod = "POST"
val it = headers.entryIterator
while (it.hasNext()) {
val (key, value) = it.next()
connection.setRequestProperty(key, value.toString())
}
ZipOutputStream(connection.outputStream).use { zipProcess(sourceDirPath, it) }
if (connection.responseCode == 200) {
promise.resolve(
connection.inputStream.bufferedReader().use { it.readText() })
} else {
throw Exception("Network request failed")
}
} catch (e: Exception) {
promise.reject(e)
} finally {
connection.disconnect()
}
}.start()
}
}
@@ -0,0 +1,30 @@
package com.rajarsheechatterjee.NativeZipArchive
import com.facebook.react.BaseReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.lnreader.spec.NativeZipArchiveSpec
class NativeZipArchivePackage : BaseReactPackage() {
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
if (name == NativeZipArchiveSpec.NAME) {
NativeZipArchive(reactContext)
} else {
null
}
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf(
NativeZipArchiveSpec.NAME to ReactModuleInfo(
NativeZipArchiveSpec.NAME,
NativeZipArchiveSpec.NAME,
canOverrideExistingModule = false,
needsEagerInit = false,
isCxxModule = false,
isTurboModule = true
)
)
}
}
@@ -1,170 +0,0 @@
package com.rajarsheechatterjee.LNReader;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.graphics.Color;
import android.os.Build;
import android.app.Activity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.UiThread;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import java.util.HashMap;
import java.util.Map;
import com.facebook.react.uimanager.IllegalViewOperationException;
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
public class NavigationBarColorModule extends ReactContextBaseJavaModule {
public static final String REACT_CLASS = "NavigationBarColor";
private static final String ERROR_NO_ACTIVITY = "E_NO_ACTIVITY";
private static final String ERROR_NO_ACTIVITY_MESSAGE = "Tried to change the navigation bar while not attached to an Activity";
private static final String ERROR_API_LEVEL = "API_LEVEl";
private static final String ERROR_API_LEVEL_MESSAGE = "Only Android Oreo and above is supported";
private static ReactApplicationContext reactContext = null;
private static final int UI_FLAG_HIDE_NAV_BAR = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
public NavigationBarColorModule(ReactApplicationContext context) {
super(context);
reactContext = context;
}
public void setNavigationBarTheme(Activity activity, Boolean light) {
if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Window window = activity.getWindow();
int flags = window.getDecorView().getSystemUiVisibility();
if (light) {
flags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
} else {
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
}
window.getDecorView().setSystemUiVisibility(flags);
}
}
@Override
public String getName() {
return REACT_CLASS;
}
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put("EXAMPLE_CONSTANT", "example");
return constants;
}
@ReactMethod
public void changeNavigationBarColor(final String color, final Boolean light, final Boolean animated, final Promise promise) {
final WritableMap map = Arguments.createMap();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (getCurrentActivity() != null) {
try {
final Window window = getCurrentActivity().getWindow();
runOnUiThread(new Runnable() {
@Override
public void run() {
if (color.equals("transparent") || color.equals("translucent")) {
window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
if (color.equals("transparent")) {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else {
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
setNavigationBarTheme(getCurrentActivity(), light);
map.putBoolean("success", true);
promise.resolve(map);
return;
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
if (animated) {
Integer colorFrom = window.getNavigationBarColor();
Integer colorTo = Color.parseColor(String.valueOf(color));
//window.setNavigationBarColor(colorTo);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
window.setNavigationBarColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.start();
} else {
window.setNavigationBarColor(Color.parseColor(String.valueOf(color)));
}
setNavigationBarTheme(getCurrentActivity(), light);
WritableMap map = Arguments.createMap();
map.putBoolean("success", true);
promise.resolve(map);
}
});
} catch (IllegalViewOperationException e) {
map.putBoolean("success", false);
promise.reject("error", e);
}
} else {
promise.reject(ERROR_NO_ACTIVITY, new Throwable(ERROR_NO_ACTIVITY_MESSAGE));
}
} else {
promise.reject(ERROR_API_LEVEL, new Throwable(ERROR_API_LEVEL_MESSAGE));
}
}
@ReactMethod
public void hideNavigationBar(Promise promise) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (getCurrentActivity() != null) {
View decorView = getCurrentActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(UI_FLAG_HIDE_NAV_BAR);
}
}
});
} catch (IllegalViewOperationException e) {
WritableMap map = Arguments.createMap();
map.putBoolean("success", false);
promise.reject("error", e);
}
}
@ReactMethod
public void showNavigationBar(Promise promise) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (getCurrentActivity() != null) {
Window w = getCurrentActivity().getWindow();
w.setStatusBarColor(Color.TRANSPARENT);
w.setNavigationBarColor(Color.TRANSPARENT);
View decorView = w.getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
});
} catch (IllegalViewOperationException e) {
WritableMap map = Arguments.createMap();
map.putBoolean("success", false);
promise.reject("error", e);
}
}
}
@@ -1,25 +0,0 @@
package com.rajarsheechatterjee.LNReader;
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 NavigationBarColorPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new NavigationBarColorModule(reactContext));
return modules;
}
}
+17
View File
@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
# Define the library name here.
project(appmodules)
# This file includes all the necessary to let you build your React Native application
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
# Define where the additional source code lives. We need to crawl back the jni, main, src, app, android folders
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
../../../../../shared/NativeEpub.cpp
../../../../../shared/Epub.cpp
../../../../../shared/pugixml.cpp
)
# Define where CMake can find the additional header files. We need to crawl back the jni, main, src, app, android folders
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ../../../../../shared)
+138
View File
@@ -0,0 +1,138 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// This C++ file is part of the default configuration used by apps and is placed
// inside react-native to encapsulate it from user space (so you won't need to
// touch C++/Cmake code at all on Android).
//
// If you wish to customize it (because you want to manually link a C++ library
// or pass a custom compilation flag) you can:
//
// 1. Copy this CMake file inside the `android/app/src/main/jni` folder of your
// project
// 2. Copy the OnLoad.cpp (in this same folder) file inside the same folder as
// above.
// 3. Extend your `android/app/build.gradle` as follows
//
// android {
// // Other config here...
// externalNativeBuild {
// cmake {
// path "src/main/jni/CMakeLists.txt"
// }
// }
// }
#include <DefaultComponentsRegistry.h>
#include <DefaultTurboModuleManagerDelegate.h>
#include <autolinking.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <FBReactNativeSpec.h>
#include <NativeEpub.hpp>
#ifdef REACT_NATIVE_APP_CODEGEN_HEADER
#include REACT_NATIVE_APP_CODEGEN_HEADER
#endif
#ifdef REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER
#include REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER
#endif
namespace facebook::react
{
void registerComponents(
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry)
{
// Custom Fabric Components go here. You can register custom
// components coming from your App or from 3rd party libraries here.
//
// providerRegistry->add(concreteComponentDescriptorProvider<
// MyComponentDescriptor>());
// We link app local components if available
#ifdef REACT_NATIVE_APP_COMPONENT_REGISTRATION
REACT_NATIVE_APP_COMPONENT_REGISTRATION(registry);
#endif
// And we fallback to the components autolinked
autolinking_registerProviders(registry);
}
std::shared_ptr<TurboModule> cxxModuleProvider(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker)
{
// Here you can provide your CXX Turbo Modules coming from
// either your application or from external libraries. The approach to follow
// is similar to the following (for a module called `NativeCxxModuleExample`):
//
// if (name == NativeCxxModuleExample::kModuleName) {
// return std::make_shared<NativeCxxModuleExample>(jsInvoker);
// }
if (name == NativeEpub::kModuleName)
{
return std::make_shared<NativeEpub>(jsInvoker);
}
// And we fallback to the CXX module providers autolinked
return autolinking_cxxModuleProvider(name, jsInvoker);
}
std::shared_ptr<TurboModule> javaModuleProvider(
const std::string &name,
const JavaTurboModule::InitParams &params)
{
// Here you can provide your own module provider for TurboModules coming from
// either your application or from external libraries. The approach to follow
// is similar to the following (for a library called `samplelibrary`):
//
// auto module = samplelibrary_ModuleProvider(name, params);
// if (module != nullptr) {
// return module;
// }
// return FBReactNativeSpec_ModuleProvider(name, params);
// We link app local modules if available
#ifdef REACT_NATIVE_APP_MODULE_PROVIDER
auto module = REACT_NATIVE_APP_MODULE_PROVIDER(name, params);
if (module != nullptr)
{
return module;
}
#endif
// We first try to look up core modules
if (auto module = FBReactNativeSpec_ModuleProvider(name, params))
{
return module;
}
// And we fallback to the module providers autolinked
if (auto module = autolinking_ModuleProvider(name, params))
{
return module;
}
return nullptr;
}
} // namespace facebook::react
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *)
{
return facebook::jni::initialize(vm, []
{
facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider =
&facebook::react::cxxModuleProvider;
facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider =
&facebook::react::javaModuleProvider;
facebook::react::DefaultComponentsRegistry::
registerComponentDescriptorsFromEntryPoint =
&facebook::react::registerComponents; });
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,93 @@
<vector android:alpha="0" android:height="1dp"
android:viewportHeight="1024" android:viewportWidth="1024"
android:width="1dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="0.994" android:fillColor="#132c33"
android:pathData="M479.5,-0.5C500.8,-0.5 522.2,-0.5 543.5,-0.5C704.4,13.5 832.9,84.8 929,213.5C985.1,293.3 1016.5,382 1023.5,479.5C1023.5,500.8 1023.5,522.2 1023.5,543.5C1009.2,709.4 934.5,840.2 799.5,936C722,987.8 636.6,1017 543.5,1023.5C522.2,1023.5 500.8,1023.5 479.5,1023.5C333.8,1011.4 213.3,950.4 118,840.5C47.3,754.3 7.8,655.3 -0.5,543.5C-0.5,522.2 -0.5,500.8 -0.5,479.5C13.5,318.6 84.8,190.1 213.5,94C293.3,37.9 382,6.4 479.5,-0.5Z" android:strokeAlpha="0.994"/>
<path android:fillColor="#106476" android:pathData="M870.5,325.5C876.8,340.6 882.7,355.9 888,371.5C889.7,373.2 891.1,375.2 892,377.5C895.1,386.3 897.4,395.3 899,404.5C900,406.7 901.5,408.4 903.5,409.5C903.5,410.2 903.5,410.8 903.5,411.5C907.2,436.2 910.8,460.8 914.5,485.5C915.4,500.5 915.7,515.5 915.5,530.5C911.7,612.8 885.4,686.8 836.5,752.5C836.5,750.7 837,749 838,747.5C894.4,667.2 918.8,577.8 911,479.5C899,365 848.5,271.8 759.5,200C652.9,120.8 534.9,97.5 405.5,130C299,161.6 218.1,225.4 163,321.5C108.7,424.4 99.1,531.4 134,642.5C147,680.2 165,715.2 188,747.5C189,749 189.5,750.7 189.5,752.5C141.4,688 115.1,615.3 110.5,534.5C110.3,518.5 110.5,502.5 111,486.5C112.8,477.3 113.8,467.9 114,458.5C119,435.8 124.4,413.1 130,390.5C140,359.6 153.3,330.6 170,303.5C184.2,283.1 199.4,263.5 215.5,244.5C231.1,229.1 246.7,213.9 262.5,199C273.8,191.7 285.1,184.4 296.5,177C297.3,175.5 298.3,174.2 299.5,173C303.2,172.6 306.5,171.3 309.5,169C313,166 316.3,162.9 319.5,159.5C330.1,155.2 340.1,149.9 349.5,143.5C360.1,142.3 370.1,139.2 379.5,134C385.7,132.1 392.1,130.5 398.5,129C400.5,128 402.5,127 404.5,126C452.1,113.9 500.4,109.7 549.5,113.5C567,115.2 584.3,117.7 601.5,121C620.6,126.7 639.8,132.6 659,138.5C668,141.9 676.8,145.8 685.5,150C695.4,156.1 705.8,161.5 716.5,166C717.2,167 717.8,168 718.5,169C733.7,175.2 747.1,184.2 758.5,196C764.2,199.9 769.5,204.2 774.5,209C776.6,210.8 778.9,212.1 781.5,213C785.3,218.2 789.8,222.7 795,226.5C797.1,228.3 798.4,230.7 799,233.5C807,241.6 815,249.6 823,257.5C823.3,258.8 823.7,260.2 824,261.5C828,266.5 832.4,271.2 837,275.5C841.8,284.4 847.1,293.1 853,301.5C858.3,307.4 862.6,314.1 866,321.5C867,323.4 868.5,324.7 870.5,325.5Z"/>
<path android:fillColor="#126e81" android:pathData="M836.5,752.5C791,813.4 733,858.3 662.5,887C545.5,931 431.5,924.3 320.5,867C268.3,838.7 224.7,800.5 189.5,752.5C189.5,750.7 189,749 188,747.5C165,715.2 147,680.2 134,642.5C99.1,531.4 108.7,424.4 163,321.5C218.1,225.4 299,161.6 405.5,130C534.9,97.5 652.9,120.8 759.5,200C848.5,271.8 899,365 911,479.5C918.8,577.8 894.4,667.2 838,747.5C837,749 836.5,750.7 836.5,752.5Z"/>
<path android:fillColor="#a1abaf" android:pathData="M660.5,203.5C657.7,203.4 655,202.8 652.5,201.5C641.6,195.4 629.9,191.5 617.5,190C609.7,188 602.4,185 595.5,181C580.9,179.2 566.6,176.6 552.5,173C521.2,169 490.2,169.9 459.5,175.5C447.6,178.3 435.6,180.5 423.5,182C418.2,183.8 412.9,185.3 407.5,186.5C388.5,192.1 370.1,199.6 352.5,209C351.2,209.5 349.9,209.7 348.5,209.5C423.4,170 502.4,159.1 585.5,177C611.8,182.6 636.8,191.4 660.5,203.5Z"/>
<path android:fillColor="#d7e2e6" android:pathData="M688.5,223.5C690.9,224.3 692.9,225.7 694.5,227.5C695.4,229.8 696.7,232 698.5,234C734,257.8 763.8,287.3 788,322.5C789.3,323.9 790.8,324.9 792.5,325.5C793.2,325.8 793.8,326.2 794.5,326.5C794.3,327.9 794.5,329.2 795,330.5C851.6,424.2 862.9,523.2 829,627.5C824.9,638.7 820.3,649.7 815,660.5C812.6,667.1 810.4,673.7 808.5,680.5C806.4,682.7 803.9,684.7 801,686.5C790.6,704.3 778.8,720.7 765.5,735.5C765.5,737.2 765.5,738.8 765.5,740.5C721,790.4 666.4,824.1 601.5,841.5C586.8,843.9 572.2,846.4 557.5,849C523.2,853.2 488.9,853.4 454.5,849.5C364.7,834.1 292.3,790.4 237.5,718.5C236.2,715.7 235.4,712.7 235,709.5C188.1,642.5 167.8,567.8 174,485.5C176.7,456.8 182.5,428.8 191.5,401.5C194.1,391.7 197.3,382 201,372.5C201.9,372 202.8,371.3 203.5,370.5C208.1,361.7 212.3,352.7 216,343.5C220.2,338.6 223.9,333.3 227,327.5C242.1,304 260,282.5 280.5,263C290.7,256.1 300.3,248.4 309.5,240C314.3,237.6 318.9,235.1 323.5,232.5C408.4,179.1 499.7,164.2 597.5,188C611.5,191.7 625.2,196.3 638.5,202C641.5,202.3 644.5,202.7 647.5,203C661.2,209.8 674.9,216.7 688.5,223.5Z"/>
<path android:fillColor="#cfdade" android:pathData="M556.5,177.5C577.5,179.3 597.9,184.2 617.5,192C621.3,192.3 624.9,192.9 628.5,194C636.6,198 645,201.2 653.5,203.5C663.6,208.4 673.6,213.6 683.5,219C685.6,220 687.3,221.5 688.5,223.5C674.9,216.7 661.2,209.8 647.5,203C644.5,202.7 641.5,202.3 638.5,202C625.2,196.3 611.5,191.7 597.5,188C499.7,164.2 408.4,179.1 323.5,232.5C330.8,226.2 338.8,220.9 347.5,216.5C348.5,215.1 349.5,213.8 350.5,212.5C363.9,207 377.2,201.1 390.5,195C402.2,191.3 413.8,187.7 425.5,184C448.7,180 472.1,177 495.5,175C505.5,174.3 515.5,174.3 525.5,175C535.8,176.1 546.2,176.9 556.5,177.5Z"/>
<path android:fillColor="#c4ced2" android:pathData="M556.5,177.5C546.2,176.9 535.8,176.1 525.5,175C515.5,174.3 505.5,174.3 495.5,175C472.1,177 448.7,180 425.5,184C413.8,187.7 402.2,191.3 390.5,195C377.2,201.1 363.9,207 350.5,212.5C368.9,202.5 387.9,193.8 407.5,186.5C412.9,185.3 418.2,183.8 423.5,182C435.6,180.5 447.6,178.3 459.5,175.5C491.2,171.4 522.9,171.5 554.5,176C555.4,176.3 556.1,176.8 556.5,177.5Z"/>
<path android:fillColor="#bac3c7" android:pathData="M652.5,201.5C652.8,202.2 653.2,202.8 653.5,203.5C645,201.2 636.6,198 628.5,194C624.9,192.9 621.3,192.3 617.5,192C597.9,184.2 577.5,179.3 556.5,177.5C556.1,176.8 555.4,176.3 554.5,176C522.9,171.5 491.2,171.4 459.5,175.5C490.2,169.9 521.2,169 552.5,173C566.6,176.6 580.9,179.2 595.5,181C602.4,185 609.7,188 617.5,190C629.9,191.5 641.6,195.4 652.5,201.5Z"/>
<path android:fillColor="#0e5565" android:pathData="M870.5,325.5C868.5,324.7 867,323.4 866,321.5C862.6,314.1 858.3,307.4 853,301.5C847.1,293.1 841.8,284.4 837,275.5C832.4,271.2 828,266.5 824,261.5C823.7,260.2 823.3,258.8 823,257.5C815,249.6 807,241.6 799,233.5C798.4,230.7 797.1,228.3 795,226.5C789.8,222.7 785.3,218.2 781.5,213C778.9,212.1 776.6,210.8 774.5,209C769.5,204.2 764.2,199.9 758.5,196C747.1,184.2 733.7,175.2 718.5,169C717.8,168 717.2,167 716.5,166C705.8,161.5 695.4,156.1 685.5,150C676.8,145.8 668,141.9 659,138.5C639.8,132.6 620.6,126.7 601.5,121C584.3,117.7 567,115.2 549.5,113.5C500.4,109.7 452.1,113.9 404.5,126C402.5,127 400.5,128 398.5,129C392.1,130.5 385.7,132.1 379.5,134C370.1,139.2 360.1,142.3 349.5,143.5C420.7,111.5 495,101.3 572.5,113C678.8,130.2 765.3,180.7 832,264.5C846.7,283.7 859.5,304 870.5,325.5Z"/>
<path android:fillColor="#a9b3b7" android:pathData="M652.5,201.5C655,202.8 657.7,203.4 660.5,203.5C704.9,224.6 742.6,254.2 773.5,292.5C765,283.5 756.4,274.7 747.5,266C744,263.6 741,260.8 738.5,257.5C733.8,254.1 729.1,250.8 724.5,247.5C722.4,245.3 720.1,243.3 717.5,241.5C709.8,236.7 702.1,232 694.5,227.5C692.9,225.7 690.9,224.3 688.5,223.5C687.3,221.5 685.6,220 683.5,219C673.6,213.6 663.6,208.4 653.5,203.5C653.2,202.8 652.8,202.2 652.5,201.5Z"/>
<path android:fillColor="#cfdadd" android:pathData="M694.5,227.5C702.1,232 709.8,236.7 717.5,241.5C720.1,243.3 722.4,245.3 724.5,247.5C740.5,264 756.6,280.3 773,296.5C779.5,304.9 785.8,313.3 792,321.5C792.5,322.8 792.7,324.1 792.5,325.5C790.8,324.9 789.3,323.9 788,322.5C763.8,287.3 734,257.8 698.5,234C696.7,232 695.4,229.8 694.5,227.5Z"/>
<path android:fillColor="#a8b3b6" android:pathData="M407.5,186.5C387.9,193.8 368.9,202.5 350.5,212.5C348.1,212.5 345.7,213 343.5,214C280.9,251.6 233.3,303.1 200.5,368.5C200,369.3 199.4,369.6 198.5,369.5C231,299.7 281,246.4 348.5,209.5C349.9,209.7 351.2,209.5 352.5,209C370.1,199.6 388.5,192.1 407.5,186.5Z"/>
<path android:fillColor="#c7d1d5" android:pathData="M350.5,212.5C349.5,213.8 348.5,215.1 347.5,216.5C338.8,220.9 330.8,226.2 323.5,232.5C318.9,235.1 314.3,237.6 309.5,240C300.3,248.4 290.7,256.1 280.5,263C260,282.5 242.1,304 227,327.5C223.9,333.3 220.2,338.6 216,343.5C212.3,352.7 208.1,361.7 203.5,370.5C202.8,371.3 201.9,372 201,372.5C197.3,382 194.1,391.7 191.5,401.5C187.7,410.3 184.4,419.3 181.5,428.5C183.2,412.5 188.1,397.5 196,383.5C196.7,378.7 197.5,374.1 198.5,369.5C199.4,369.6 200,369.3 200.5,368.5C233.3,303.1 280.9,251.6 343.5,214C345.7,213 348.1,212.5 350.5,212.5Z"/>
<path android:fillColor="#0f5969" android:pathData="M349.5,143.5C340.1,149.9 330.1,155.2 319.5,159.5C316.3,162.9 313,166 309.5,169C306.5,171.3 303.2,172.6 299.5,173C298.3,174.2 297.3,175.5 296.5,177C285.1,184.4 273.8,191.7 262.5,199C246.7,213.9 231.1,229.1 215.5,244.5C199.4,263.5 184.2,283.1 170,303.5C153.3,330.6 140,359.6 130,390.5C124.4,413.1 119,435.8 114,458.5C113.8,467.9 112.8,477.3 111,486.5C110.5,502.5 110.3,518.5 110.5,534.5C105.6,408 149,301.1 240.5,214C273,184.7 309.3,161.2 349.5,143.5Z"/>
<path android:fillColor="#b5bfc3" android:pathData="M724.5,247.5C729.1,250.8 733.8,254.1 738.5,257.5C741,260.8 744,263.6 747.5,266C756.4,274.7 765,283.5 773.5,292.5C804,327.4 825.6,367.4 838.5,412.5C837.5,412 836.7,411.4 836,410.5C833.5,403.3 831,396.2 828.5,389C820.3,372.7 812.4,356.2 805,339.5C803.9,338.7 802.7,338 801.5,337.5C799.9,333.3 797.6,329.6 794.5,326.5C793.8,326.2 793.2,325.8 792.5,325.5C792.7,324.1 792.5,322.8 792,321.5C785.8,313.3 779.5,304.9 773,296.5C756.6,280.3 740.5,264 724.5,247.5Z"/>
<path android:fillColor="#d0dade" android:pathData="M558.5,314.5C570.2,314.3 581.8,314.5 593.5,315C603.6,318.9 605.1,325 598,333.5C597.2,342.4 597.3,351.2 598.5,360C629.8,360.3 661.2,360.7 692.5,361C694.7,361.8 696.2,363.3 697,365.5C697.7,376.5 697.7,387.5 697,398.5C696.2,400 695,401.2 693.5,402C661.6,403.5 629.6,404 597.5,403.5C597.2,411.8 597.5,419.9 598.5,428C623.3,428 647.9,428.7 672.5,430C673.7,430.9 674.5,432.1 675,433.5C675.7,444.2 675.7,454.8 675,465.5C674.2,468.8 672,470.7 668.5,471C638.7,471.2 608.8,471.3 579,471.5C547.8,471.7 516.6,471.2 485.5,470C483.5,468.7 482.3,466.8 482,464.5C481.3,454.5 481.3,444.5 482,434.5C482.3,432.7 483.1,431.2 484.5,430C507.1,428.5 529.7,428 552.5,428.5C552.5,420.2 552.5,411.8 552.5,403.5C525.2,403.7 497.8,403.5 470.5,403C467.2,403.1 465.1,401.6 464,398.5C462,387.2 462,375.8 464,364.5C465.2,363 466.7,361.8 468.5,361C496.5,360.5 524.5,360.3 552.5,360.5C552.1,346.5 552.6,332.5 554,318.5C555.4,316.9 556.9,315.6 558.5,314.5Z"/>
<path android:fillColor="#849094" android:pathData="M591.5,317.5C580.5,317.5 569.5,317.5 558.5,317.5C558.8,332.7 558.5,347.7 557.5,362.5C557.5,347.2 557.5,331.8 557.5,316.5C569,316.2 580.3,316.5 591.5,317.5Z"/>
<path android:fillColor="#132c33" android:pathData="M591.5,317.5C599,318.8 599.5,321.8 593,326.5C592.5,338.5 592.3,350.5 592.5,362.5C625.8,362.5 659.2,362.5 692.5,362.5C692.5,373.2 692.5,383.8 692.5,394.5C658.8,394.5 625.2,394.5 591.5,394.5C591.2,406.7 591.5,418.7 592.5,430.5C618,431.5 643.7,431.8 669.5,431.5C669.5,441.8 669.5,452.2 669.5,462.5C608.8,462.5 548.2,462.5 487.5,462.5C487.5,451.8 487.5,441.2 487.5,430.5C510.2,430.5 532.8,430.5 555.5,430.5C556.2,430.5 556.8,430.5 557.5,430.5C558.5,418.7 558.8,406.7 558.5,394.5C528.5,394.5 498.5,394.5 468.5,394.5C468.5,383.8 468.5,373.2 468.5,362.5C498.2,362.5 527.8,362.5 557.5,362.5C558.5,347.7 558.8,332.7 558.5,317.5C569.5,317.5 580.5,317.5 591.5,317.5Z"/>
<path android:fillColor="#cfdade" android:pathData="M331.5,324.5C366.9,324 402.2,324.5 437.5,326C439.5,327.3 440.7,329.2 441,331.5C441.9,342.2 441.6,352.9 440,363.5C439,365.3 437.5,366.4 435.5,367C399.8,368 364.1,367.6 328.5,366C327.3,365.1 326.5,363.9 326,362.5C325.3,351.5 325.3,340.5 326,329.5C327.4,327.3 329.2,325.6 331.5,324.5Z"/>
<path android:fillColor="#b8c1c4" android:pathData="M330.5,331.5C330.2,341 330.5,350.3 331.5,359.5C331.6,360.1 331.9,360.6 332.5,361C349.3,361.2 366.2,361.3 383,361.5C400.2,361.5 417,360.8 433.5,359.5C434.2,359.5 434.8,359.5 435.5,359.5C435.8,359.5 436.2,359.5 436.5,359.5C436.4,361.4 435.4,362.6 433.5,363C399.2,363.7 364.8,363.7 330.5,363C329.9,362.3 329.4,361.4 329,360.5C328.3,351.2 328.3,341.8 329,332.5C329.4,331.9 329.9,331.6 330.5,331.5Z"/>
<path android:fillColor="#a3abaf" android:pathData="M331.5,359.5C365.5,359.5 399.5,359.5 433.5,359.5C417,360.8 400.2,361.5 383,361.5C366.2,361.3 349.3,361.2 332.5,361C331.9,360.6 331.6,360.1 331.5,359.5Z"/>
<path android:fillColor="#142d34" android:pathData="M330.5,327.5C365.5,327.5 400.5,327.5 435.5,327.5C435.5,338.2 435.5,348.8 435.5,359.5C434.8,359.5 434.2,359.5 433.5,359.5C399.5,359.5 365.5,359.5 331.5,359.5C330.5,350.3 330.2,341 330.5,331.5C330.5,330.2 330.5,328.8 330.5,327.5Z"/>
<path android:fillColor="#79868a" android:pathData="M330.5,327.5C365.7,326.5 401,326.2 436.5,326.5C436.5,337.5 436.5,348.5 436.5,359.5C436.2,359.5 435.8,359.5 435.5,359.5C435.5,348.8 435.5,338.2 435.5,327.5C400.5,327.5 365.5,327.5 330.5,327.5Z"/>
<path android:fillColor="#0f5a6b" android:pathData="M870.5,325.5C884.8,352.1 895.8,380.1 903.5,409.5C901.5,408.4 900,406.7 899,404.5C897.4,395.3 895.1,386.3 892,377.5C891.1,375.2 889.7,373.2 888,371.5C882.7,355.9 876.8,340.6 870.5,325.5Z"/>
<path android:fillColor="#8e979a" android:pathData="M468.5,394.5C498.5,394.5 528.5,394.5 558.5,394.5C558.8,406.7 558.5,418.7 557.5,430.5C558.1,419.1 557.5,407.9 555.5,397C528.2,396.7 500.8,396.3 473.5,396C471.6,395.8 470,395.3 468.5,394.5Z"/>
<path android:fillColor="#a6aeb1" android:pathData="M690.5,395.5C690.4,396.1 690.1,396.6 689.5,397C658.2,397.3 626.8,397.7 595.5,398C594.6,399 593.6,399.9 592.5,400.5C592.5,398.8 592.5,397.2 592.5,395.5C625.2,395.5 657.8,395.5 690.5,395.5Z"/>
<path android:fillColor="#b4bec1" android:pathData="M468.5,362.5C468.5,373.2 468.5,383.8 468.5,394.5C470,395.3 471.6,395.8 473.5,396C500.8,396.3 528.2,396.7 555.5,397C557.5,407.9 558.1,419.1 557.5,430.5C556.8,430.5 556.2,430.5 555.5,430.5C556.6,420.9 556.8,411.2 556,401.5C555.5,401 555,400.5 554.5,400C526.5,399.7 498.5,399.3 470.5,399C469.7,398.2 468.8,397.3 468,396.5C467.2,385 467.3,373.7 468.5,362.5Z"/>
<path android:fillColor="#b9c3c6" android:pathData="M690.5,395.5C691.2,395.5 691.8,395.5 692.5,395.5C691.9,396.5 691.2,397.5 690.5,398.5C658.8,399.3 627.2,399.8 595.5,400C595,400.5 594.5,401 594,401.5C593.2,411.2 593.4,420.9 594.5,430.5C593.8,430.5 593.2,430.5 592.5,430.5C592.5,420.5 592.5,410.5 592.5,400.5C593.6,399.9 594.6,399 595.5,398C626.8,397.7 658.2,397.3 689.5,397C690.1,396.6 690.4,396.1 690.5,395.5Z"/>
<path android:fillColor="#515f63" android:pathData="M692.5,394.5C692.5,394.8 692.5,395.2 692.5,395.5C691.8,395.5 691.2,395.5 690.5,395.5C657.8,395.5 625.2,395.5 592.5,395.5C592.5,397.2 592.5,398.8 592.5,400.5C592.5,410.5 592.5,420.5 592.5,430.5C591.5,418.7 591.2,406.7 591.5,394.5C625.2,394.5 658.8,394.5 692.5,394.5Z"/>
<path android:fillColor="#ced9dd" android:pathData="M191.5,401.5C182.5,428.8 176.7,456.8 174,485.5C167.8,567.8 188.1,642.5 235,709.5C235.4,712.7 236.2,715.7 237.5,718.5C214.2,688.9 196.9,655.9 185.5,619.5C182.6,606.1 179.5,592.8 176,579.5C174,566 171.8,552.6 169.5,539.5C167.9,501.8 171.9,464.8 181.5,428.5C184.4,419.3 187.7,410.3 191.5,401.5Z"/>
<path android:fillColor="#ced8dc" android:pathData="M313.5,384.5C359.2,384.3 404.8,384.5 450.5,385C452,386.2 453.2,387.7 454,389.5C454.7,400.5 454.7,411.5 454,422.5C451.8,425.8 448.6,427.3 444.5,427C400.5,428 356.5,427.6 312.5,426C311,424.8 309.8,423.3 309,421.5C308.3,410.8 308.3,400.2 309,389.5C310,387.3 311.5,385.6 313.5,384.5Z"/>
<path android:fillColor="#bbc4c8" android:pathData="M313.5,389.5C313.5,399.2 313.5,408.8 313.5,418.5C314.4,419.3 315.4,420.1 316.5,421C360.2,421.7 403.8,421.7 447.5,421C448.4,420.3 449,419.5 449.5,418.5C449.5,408.8 449.5,399.2 449.5,389.5C450.7,399.7 450.8,410 450,420.5C449.1,421.7 447.9,422.5 446.5,423C402.5,423.7 358.5,423.7 314.5,423C313.8,421.7 313,420.6 312,419.5C311.3,409.8 311.3,400.2 312,390.5C312.4,389.9 312.9,389.6 313.5,389.5Z"/>
<path android:fillColor="#9da6a9" android:pathData="M313.5,418.5C358.8,418.5 404.2,418.5 449.5,418.5C449,419.5 448.4,420.3 447.5,421C403.8,421.7 360.2,421.7 316.5,421C315.4,420.1 314.4,419.3 313.5,418.5Z"/>
<path android:fillColor="#132c33" android:pathData="M449.5,389.5C449.5,399.2 449.5,408.8 449.5,418.5C404.2,418.5 358.8,418.5 313.5,418.5C313.5,408.8 313.5,399.2 313.5,389.5C313.5,388.5 313.5,387.5 313.5,386.5C358.8,386.5 404.2,386.5 449.5,386.5C449.5,387.5 449.5,388.5 449.5,389.5Z"/>
<path android:fillColor="#273b41" android:pathData="M592.5,430.5C593.2,430.5 593.8,430.5 594.5,430.5C620.2,429.8 645.5,430.5 670.5,432.5C670.5,432.8 670.5,433.2 670.5,433.5C670.5,443.2 670.5,452.8 670.5,462.5C670.2,462.5 669.8,462.5 669.5,462.5C669.5,452.2 669.5,441.8 669.5,431.5C643.7,431.8 618,431.5 592.5,430.5Z"/>
<path android:fillColor="#b8c4c8" android:pathData="M198.5,369.5C197.5,374.1 196.7,378.7 196,383.5C188.1,397.5 183.2,412.5 181.5,428.5C171.9,464.8 167.9,501.8 169.5,539.5C163.8,480.3 173.5,423.6 198.5,369.5Z"/>
<path android:fillColor="#cfdadd" android:pathData="M330.5,445.5C365.8,445.3 401.2,445.5 436.5,446C439.1,447.3 440.6,449.5 441,452.5C441.9,463.2 441.6,473.9 440,484.5C439.2,485.3 438.3,486.2 437.5,487C401.5,487.7 365.5,487.7 329.5,487C327.3,486.3 326.1,484.8 326,482.5C325.3,471.8 325.3,461.2 326,450.5C327,448.3 328.5,446.6 330.5,445.5Z"/>
<path android:fillColor="#132c32" android:pathData="M435.5,448.5C435.5,458.8 435.5,469.2 435.5,479.5C400.8,479.5 366.2,479.5 331.5,479.5C331.5,469.2 331.5,458.8 331.5,448.5C366.2,448.5 400.8,448.5 435.5,448.5Z"/>
<path android:fillColor="#273b41" android:pathData="M435.5,447.5C435.5,447.8 435.5,448.2 435.5,448.5C400.8,448.5 366.2,448.5 331.5,448.5C331.5,458.8 331.5,469.2 331.5,479.5C330.5,470.7 330.2,461.7 330.5,452.5C330.5,450.8 330.5,449.2 330.5,447.5C365.5,447.5 400.5,447.5 435.5,447.5Z"/>
<path android:fillColor="#6b7679" android:pathData="M487.5,430.5C487.5,441.2 487.5,451.8 487.5,462.5C548.2,462.5 608.8,462.5 669.5,462.5C669.8,462.5 670.2,462.5 670.5,462.5C670.2,463.3 669.5,463.7 668.5,463.5C608.5,463.5 548.5,463.5 488.5,463.5C488.2,463.5 487.8,463.5 487.5,463.5C486.5,453 486.2,442.3 486.5,431.5C486.5,430.8 486.8,430.5 487.5,430.5Z"/>
<path android:fillColor="#c8d3d6" android:pathData="M486.5,431.5C486.2,442.3 486.5,453 487.5,463.5C487.8,465.8 489.1,466.9 491.5,467C550.8,467.7 610.2,467.7 669.5,467C670.9,465.8 671.7,464.3 672,462.5C672.7,453.2 672.7,443.8 672,434.5C671.6,433.9 671.1,433.6 670.5,433.5C670.5,433.2 670.5,432.8 670.5,432.5C672.4,432.6 673.6,433.6 674,435.5C674.7,445.2 674.7,454.8 674,464.5C672.6,466.1 671.1,467.6 669.5,469C608.8,469.7 548.2,469.7 487.5,469C486.2,467.6 485,466.1 484,464.5C483.3,454.2 483.3,443.8 484,433.5C484.7,432.6 485.5,432 486.5,431.5Z"/>
<path android:fillColor="#bac3c7" android:pathData="M670.5,433.5C671.1,433.6 671.6,433.9 672,434.5C672.7,443.8 672.7,453.2 672,462.5C671.7,464.3 670.9,465.8 669.5,467C610.2,467.7 550.8,467.7 491.5,467C489.1,466.9 487.8,465.8 487.5,463.5C487.8,463.5 488.2,463.5 488.5,463.5C488.6,464.1 488.9,464.6 489.5,465C548.8,465.7 608.2,465.7 667.5,465C668.1,464.6 668.4,464.1 668.5,463.5C669.5,463.7 670.2,463.3 670.5,462.5C670.5,452.8 670.5,443.2 670.5,433.5Z"/>
<path android:fillColor="#a6aeb1" android:pathData="M488.5,463.5C548.5,463.5 608.5,463.5 668.5,463.5C668.4,464.1 668.1,464.6 667.5,465C608.2,465.7 548.8,465.7 489.5,465C488.9,464.6 488.6,464.1 488.5,463.5Z"/>
<path android:fillColor="#0f5b6c" android:pathData="M903.5,411.5C914.1,450.5 918.1,490.2 915.5,530.5C915.7,515.5 915.4,500.5 914.5,485.5C910.8,460.8 907.2,436.2 903.5,411.5Z"/>
<path android:fillColor="#9fa8ab" android:pathData="M435.5,447.5C436.4,448.6 436.8,449.9 436.5,451.5C436.8,461.5 436.5,471.5 435.5,481.5C434.7,481.8 434,482.3 433.5,483C399.5,483.7 365.5,483.7 331.5,483C331,482.3 330.3,481.8 329.5,481.5C329.2,471.7 329.5,462 330.5,452.5C330.2,461.7 330.5,470.7 331.5,479.5C366.2,479.5 400.8,479.5 435.5,479.5C435.5,469.2 435.5,458.8 435.5,448.5C435.5,448.2 435.5,447.8 435.5,447.5Z"/>
<path android:fillColor="#c2ccd0" android:pathData="M436.5,451.5C437.1,451.6 437.6,451.9 438,452.5C438.7,462.2 438.7,471.8 438,481.5C437.6,482.4 437.1,483.3 436.5,484C418.2,485.1 399.9,485.6 381.5,485.5C364.5,485.2 347.5,484.8 330.5,484.5C329.9,483.6 329.5,482.6 329.5,481.5C330.3,481.8 331,482.3 331.5,483C365.5,483.7 399.5,483.7 433.5,483C434,482.3 434.7,481.8 435.5,481.5C436.5,471.5 436.8,461.5 436.5,451.5Z"/>
<path android:fillColor="#142c33" android:pathData="M459.5,485.5C538.8,485.5 618.2,485.5 697.5,485.5C697.5,509.5 697.5,533.5 697.5,557.5C686.2,557.5 674.8,557.5 663.5,557.5C663.5,545.8 663.5,534.2 663.5,522.5C663.5,521.8 663.5,521.2 663.5,520.5C663.5,519.5 663.5,518.5 663.5,517.5C606.8,517.5 550.2,517.5 493.5,517.5C493.5,531.5 493.5,545.5 493.5,559.5C482.2,559.5 470.8,559.5 459.5,559.5C459.5,536.5 459.5,513.5 459.5,490.5C459.5,489.2 459.5,487.8 459.5,486.5C459.5,486.2 459.5,485.8 459.5,485.5Z"/>
<path android:fillColor="#8f9a9e" android:pathData="M459.5,485.5C499.2,484.8 539,484.5 579,484.5C619.2,484.5 659,485.2 698.5,486.5C698.8,510.7 698.5,534.7 697.5,558.5C686,558.8 674.7,558.5 663.5,557.5C674.8,557.5 686.2,557.5 697.5,557.5C697.5,533.5 697.5,509.5 697.5,485.5C618.2,485.5 538.8,485.5 459.5,485.5Z"/>
<path android:fillColor="#bac6ca" android:pathData="M838.5,412.5C841.3,419.5 843.4,426.9 845,434.5C854.7,478.4 855.8,522.4 848.5,566.5C851.3,530.5 851.1,494.5 848,458.5C846.2,447.9 843.5,437.6 840,427.5C839.5,422.5 839,417.5 838.5,412.5Z"/>
<path android:fillColor="#132c32" android:pathData="M331.5,507.5C366.2,507.5 400.8,507.5 435.5,507.5C435.5,517.8 435.5,528.2 435.5,538.5C400.8,538.5 366.2,538.5 331.5,538.5C331.5,528.2 331.5,517.8 331.5,507.5Z"/>
<path android:fillColor="#cbd6d9" android:pathData="M459.5,486.5C459.5,487.8 459.5,489.2 459.5,490.5C458.3,514.3 458.2,538.3 459,562.5C459.5,563 460,563.5 460.5,564C471.2,564.7 481.8,564.7 492.5,564C493.3,563.7 494,563.2 494.5,562.5C495.3,549.9 495.8,537.2 496,524.5C496.9,523.3 498.1,522.5 499.5,522C553.2,521.3 606.8,521.3 660.5,522C661,522.5 661.5,523 662,523.5C662.3,535.5 662.7,547.5 663,559.5C663.8,560.3 664.7,561.2 665.5,562C675.2,562.7 684.8,562.7 694.5,562C695.7,561 696.7,559.8 697.5,558.5C698.5,534.7 698.8,510.7 698.5,486.5C699.5,487 700.3,487.6 701,488.5C701.7,511.8 701.7,535.2 701,558.5C700.3,561.3 698.4,562.8 695.5,563C684.5,563.7 673.5,563.7 662.5,563C662,562.5 661.5,562 661,561.5C659.9,549.4 659,537.2 658.5,525C605.2,524.5 551.8,524.3 498.5,524.5C498.7,537.5 498.5,550.5 498,563.5C496.2,566.3 493.7,567.8 490.5,568C479.8,568.9 469.1,568.5 458.5,567C456.3,565.4 454.9,563.2 454.5,560.5C455.3,537.2 455.8,513.9 456,490.5C456.7,488.7 457.8,487.3 459.5,486.5Z"/>
<path android:fillColor="#aab3b7" android:pathData="M663.5,520.5C663.5,521.2 663.5,521.8 663.5,522.5C662.7,522.2 662,521.7 661.5,521C605.8,520.2 550.1,520.3 494.5,521.5C494.9,520.1 495.9,519.2 497.5,519C552.2,518.3 606.8,518.3 661.5,519C662,519.7 662.7,520.2 663.5,520.5Z"/>
<path android:fillColor="#9ca4a7" android:pathData="M663.5,520.5C662.7,520.2 662,519.7 661.5,519C606.8,518.3 552.2,518.3 497.5,519C495.9,519.2 494.9,520.1 494.5,521.5C494.8,534.3 494.5,547 493.5,559.5C493.5,545.5 493.5,531.5 493.5,517.5C550.2,517.5 606.8,517.5 663.5,517.5C663.5,518.5 663.5,519.5 663.5,520.5Z"/>
<path android:fillColor="#132c33" android:pathData="M629.5,538.5C629.9,541.8 628.5,544.1 625.5,545.5C624.2,582 624.2,618.3 625.5,654.5C625.7,658.6 627.7,661.4 631.5,663C641.5,663.7 651.5,663.7 661.5,663C665.1,661.1 667.6,658.3 669,654.5C671.2,646.6 673,638.6 674.5,630.5C675,629.1 675.6,627.8 676.5,626.5C686.4,629.9 696.4,632.9 706.5,635.5C707.1,636.4 707.4,637.4 707.5,638.5C704.9,648.7 702.4,659 700,669.5C698.8,673.6 697.3,677.6 695.5,681.5C691.1,688.5 684.8,692.9 676.5,694.5C655.5,695.5 634.5,695.8 613.5,695.5C600.6,694.3 593.1,687.3 591,674.5C590.5,630.5 590.3,586.5 590.5,542.5C590.5,541.2 590.5,539.8 590.5,538.5C596.1,537.2 602.1,536.5 608.5,536.5C614.5,536.7 620.5,536.8 626.5,537C627.7,537.2 628.7,537.7 629.5,538.5Z"/>
<path android:fillColor="#2b3e44" android:pathData="M331.5,507.5C331.5,517.8 331.5,528.2 331.5,538.5C366.2,538.5 400.8,538.5 435.5,538.5C435.2,539.3 434.5,539.7 433.5,539.5C399.8,539.5 366.2,539.5 332.5,539.5C330.5,531.2 329.9,522.6 330.5,513.5C330.5,512.2 330.5,510.8 330.5,509.5C330.3,508.5 330.7,507.8 331.5,507.5Z"/>
<path android:fillColor="#b3bcbf" android:pathData="M435.5,507.5C436.2,508.8 437.1,510.1 438,511.5C438.7,521.2 438.7,530.8 438,540.5C437.6,542.4 436.4,543.4 434.5,543.5C400.5,543.7 366.5,543.5 332.5,543C331.7,542.2 330.8,541.3 330,540.5C329.2,531.3 329.3,522.3 330.5,513.5C329.9,522.6 330.5,531.2 332.5,539.5C332.8,540.2 333.1,540.8 333.5,541.5C366.5,542.7 399.5,542.8 432.5,542C433.3,541.3 433.6,540.5 433.5,539.5C434.5,539.7 435.2,539.3 435.5,538.5C435.5,528.2 435.5,517.8 435.5,507.5Z"/>
<path android:fillColor="#a5aeb1" android:pathData="M332.5,539.5C366.2,539.5 399.8,539.5 433.5,539.5C433.6,540.5 433.3,541.3 432.5,542C399.5,542.8 366.5,542.7 333.5,541.5C333.1,540.8 332.8,540.2 332.5,539.5Z"/>
<path android:fillColor="#c7d1d5" android:pathData="M330.5,509.5C330.5,510.8 330.5,512.2 330.5,513.5C329.3,522.3 329.2,531.3 330,540.5C330.8,541.3 331.7,542.2 332.5,543C366.5,543.5 400.5,543.7 434.5,543.5C417.5,544.8 400.2,545.5 382.5,545.5C365.2,545.3 347.8,545.2 330.5,545C330,544.1 329.3,543.2 328.5,542.5C327.3,532.2 327.2,521.8 328,511.5C328.7,510.6 329.5,510 330.5,509.5Z"/>
<path android:fillColor="#cdd8dc" android:pathData="M794.5,326.5C797.6,329.6 799.9,333.3 801.5,337.5C802.7,338 803.9,338.7 805,339.5C812.4,356.2 820.3,372.7 828.5,389C831,396.2 833.5,403.3 836,410.5C836.7,411.4 837.5,412 838.5,412.5C839,417.5 839.5,422.5 840,427.5C843.5,437.6 846.2,447.9 848,458.5C851.1,494.5 851.3,530.5 848.5,566.5C842.5,607.2 829.2,645.2 808.5,680.5C810.4,673.7 812.6,667.1 815,660.5C820.3,649.7 824.9,638.7 829,627.5C862.9,523.2 851.6,424.2 795,330.5C794.5,329.2 794.3,327.9 794.5,326.5Z"/>
<path android:fillColor="#b4bdc0" android:pathData="M459.5,490.5C459.5,513.5 459.5,536.5 459.5,559.5C470.8,559.5 482.2,559.5 493.5,559.5C494.5,547 494.8,534.3 494.5,521.5C550.1,520.3 605.8,520.2 661.5,521C662,521.7 662.7,522.2 663.5,522.5C663.5,534.2 663.5,545.8 663.5,557.5C674.7,558.5 686,558.8 697.5,558.5C696.7,559.8 695.7,561 694.5,562C684.8,562.7 675.2,562.7 665.5,562C664.7,561.2 663.8,560.3 663,559.5C662.7,547.5 662.3,535.5 662,523.5C661.5,523 661,522.5 660.5,522C606.8,521.3 553.2,521.3 499.5,522C498.1,522.5 496.9,523.3 496,524.5C495.8,537.2 495.3,549.9 494.5,562.5C494,563.2 493.3,563.7 492.5,564C481.8,564.7 471.2,564.7 460.5,564C460,563.5 459.5,563 459,562.5C458.2,538.3 458.3,514.3 459.5,490.5Z"/>
<path android:fillColor="#becacd" android:pathData="M169.5,539.5C171.8,552.6 174,566 176,579.5C179.5,592.8 182.6,606.1 185.5,619.5C176.5,593.7 171.1,567 169.5,539.5Z"/>
<path android:fillColor="#ccd7db" android:pathData="M674.5,630.5C673,638.6 671.2,646.6 669,654.5C667.6,658.3 665.1,661.1 661.5,663C651.5,663.7 641.5,663.7 631.5,663C627.7,661.4 625.7,658.6 625.5,654.5C625.3,619.5 625.5,584.5 626,549.5C630.1,546.6 631.3,542.9 629.5,538.5C628.7,537.7 627.7,537.2 626.5,537C620.5,536.8 614.5,536.7 608.5,536.5C602.1,536.5 596.1,537.2 590.5,538.5C589.8,538.8 589.2,539.1 588.5,539.5C587.3,586.2 587.2,632.8 588,679.5C588.6,683.6 590.1,687.2 592.5,690.5C593.3,691.4 594.3,691.7 595.5,691.5C599.4,695.2 604.1,697.7 609.5,699C631.2,699.7 652.8,699.7 674.5,699C678.4,697.5 682.4,696.4 686.5,695.5C691,693.2 694.3,689.7 696.5,685C697.8,684.7 698.9,684.2 700,683.5C702.3,679.1 703.9,674.4 705,669.5C705.5,659.1 706.3,648.7 707.5,638.5C707.4,637.4 707.1,636.4 706.5,635.5C708,636.2 708.9,637.6 709,639.5C710.4,656.8 707.1,673.1 699,688.5C693.4,696.1 685.9,701 676.5,703C653.8,703.7 631.2,703.7 608.5,703C595.4,699.9 587.9,691.8 586,678.5C585.3,631.8 585.3,585.2 586,538.5C587.1,536.2 588.9,534.7 591.5,534C602.5,533.3 613.5,533.3 624.5,534C630.5,534.3 633.8,537.3 634.5,543C633.9,546.9 632.4,550.4 630,553.5C629,588.5 629.4,623.5 631,658.5C632.5,660 634.3,660.8 636.5,661C644.6,661.9 652.6,661.6 660.5,660C667.7,652.6 671.7,643.8 672.5,633.5C672.6,632 673.3,631 674.5,630.5Z"/>
<path android:fillColor="#aeb7ba" android:pathData="M590.5,542.5C590.3,586.5 590.5,630.5 591,674.5C593.1,687.3 600.6,694.3 613.5,695.5C633.7,696.7 654,696.8 674.5,696C675.4,695.7 676.1,695.2 676.5,694.5C684.8,692.9 691.1,688.5 695.5,681.5C694,687.1 691,691.8 686.5,695.5C682.4,696.4 678.4,697.5 674.5,699C652.8,699.7 631.2,699.7 609.5,699C604.1,697.7 599.4,695.2 595.5,691.5C594.5,687.4 592.7,683.8 590,680.5C589.2,634.3 589.3,588.3 590.5,542.5Z"/>
<path android:fillColor="#838d90" android:pathData="M676.5,694.5C676.1,695.2 675.4,695.7 674.5,696C654,696.8 633.7,696.7 613.5,695.5C634.5,695.8 655.5,695.5 676.5,694.5Z"/>
<path android:fillColor="#bdc7ca" android:pathData="M707.5,638.5C706.3,648.7 705.5,659.1 705,669.5C703.9,674.4 702.3,679.1 700,683.5C698.9,684.2 697.8,684.7 696.5,685C694.3,689.7 691,693.2 686.5,695.5C691,691.8 694,687.1 695.5,681.5C697.3,677.6 698.8,673.6 700,669.5C702.4,659 704.9,648.7 707.5,638.5Z"/>
<path android:fillColor="#aeb7bb" android:pathData="M629.5,538.5C631.3,542.9 630.1,546.6 626,549.5C625.5,584.5 625.3,619.5 625.5,654.5C624.2,618.3 624.2,582 625.5,545.5C628.5,544.1 629.9,541.8 629.5,538.5Z"/>
<path android:fillColor="#c3cdd1" android:pathData="M590.5,538.5C590.5,539.8 590.5,541.2 590.5,542.5C589.3,588.3 589.2,634.3 590,680.5C592.7,683.8 594.5,687.4 595.5,691.5C594.3,691.7 593.3,691.4 592.5,690.5C590.1,687.2 588.6,683.6 588,679.5C587.2,632.8 587.3,586.2 588.5,539.5C589.2,539.1 589.8,538.8 590.5,538.5Z"/>
<path android:fillColor="#cad6db" android:pathData="M808.5,680.5C796.6,702.3 782.3,722.3 765.5,740.5C765.5,738.8 765.5,737.2 765.5,735.5C778.8,720.7 790.6,704.3 801,686.5C803.9,684.7 806.4,682.7 808.5,680.5Z"/>
<path android:fillColor="#d0dbdf" android:pathData="M474.5,666.5C466.2,669.7 457.6,671.4 448.5,671.5C447.8,671.9 447.3,672.6 447,673.5C446.7,673.2 446.3,672.8 446,672.5C445.7,640.8 445.3,609.2 445,577.5C444.8,576.3 444.3,575.3 443.5,574.5C443.5,572.8 443.5,571.2 443.5,569.5C403.3,569.2 363.3,569.5 323.5,570.5C323.5,571.5 323.5,572.5 323.5,573.5C322.9,573.6 322.4,573.9 322,574.5C321.3,619.5 321.3,664.5 322,709.5C322.8,710.3 323.7,711.2 324.5,712C333.8,714 343.2,714 352.5,712C353.9,710.8 354.7,709.3 355,707.5C355.3,703.8 355.7,700.2 356,696.5C356.4,695.6 356.9,694.8 357.5,694C374.2,693.3 390.8,693.3 407.5,694C408.4,694.4 409.3,694.9 410,695.5C409.7,700.1 411.2,703.9 414.5,707C423.2,707.7 431.8,707.7 440.5,707C442.3,706.2 443.8,705 445,703.5C446,697.9 446.9,692.2 447.5,686.5C448.7,687.3 449.7,688.3 450.5,689.5C452.8,693.9 454.6,698.5 456,703.5C459.1,710.8 464.6,713.3 472.5,711C481.2,708.8 489.2,705.3 496.5,700.5C502.5,698 507.8,694.5 512.5,690C513.8,689.5 515.1,689.3 516.5,689.5C518.3,688.9 519.9,688.1 521.5,687C527.7,679.8 534.2,673 541,666.5C552.5,646.5 558.9,624.8 560,601.5C560.3,584.5 560.7,567.5 561,550.5C563.7,548.3 564.8,545.5 564.5,542C564.4,540 563.8,538.5 562.5,537.5C560.9,537 559.2,536.6 557.5,536.5C546.3,535.5 535,535.2 523.5,535.5C523.5,536.5 523.5,537.5 523.5,538.5C522.2,539.1 521.4,540.1 521,541.5C520.8,565.5 520.2,589.5 519,613.5C517.2,619.1 515.7,624.8 514.5,630.5C508.7,644 499.4,654.3 486.5,661.5C486.6,660.5 486.3,659.7 485.5,659C499.8,650.4 509.3,637.9 514,621.5C515.8,614.9 517.2,608.3 518,601.5C518.3,582.2 518.7,562.8 519,543.5C518.8,538.6 521,535.5 525.5,534C536.5,533.3 547.5,533.3 558.5,534C569.5,537.3 571.3,543.5 564,552.5C563.9,572.5 563.2,592.5 562,612.5C554.2,670.8 521.4,705.1 463.5,715.5C461,715.2 458.8,714.2 457,712.5C454.1,706.2 451.5,699.9 449,693.5C448.2,697.1 447.6,700.8 447,704.5C445.2,707.3 442.7,708.8 439.5,709C430.4,709.8 421.4,709.5 412.5,708C411.7,707.2 410.8,706.3 410,705.5C409.8,702.2 409.3,699.1 408.5,696C391.8,695.3 375.2,695.3 358.5,696C357.7,701.1 357.2,706.3 357,711.5C356.5,713.3 355.3,714.5 353.5,715C343.5,715.7 333.5,715.7 323.5,715C322.1,714.5 320.9,713.7 320,712.5C318.3,666.3 318,619.9 319,573.5C319.9,570.2 322.1,568.4 325.5,568C365.2,567 404.9,567.4 444.5,569C445.7,569.9 446.5,571.1 447,572.5C447.5,605.2 447.7,637.8 447.5,670.5C456.5,669.2 465.5,667.8 474.5,666.5Z"/>
<path android:fillColor="#c5d0d3" android:pathData="M323.5,573.5C323.5,574.2 323.5,574.8 323.5,575.5C322.5,619.7 322.2,664 322.5,708.5C331.6,710.5 341,711 350.5,710C351.4,709.3 352,708.5 352.5,707.5C353.5,703 353.8,698.4 353.5,693.5C354.3,693.2 355,692.7 355.5,692C373.5,691.3 391.5,691.3 409.5,692C410,692.7 410.7,693.2 411.5,693.5C412.2,696.3 412.8,699 413.5,701.5C413.8,701.5 414.2,701.5 414.5,701.5C414.4,702.5 414.7,703.3 415.5,704C424.9,704.9 434.2,704.6 443.5,703C444.1,693.9 444.9,684.7 446,675.5C446.9,677.7 448,679.7 449.5,681.5C450.5,684.1 450.8,686.8 450.5,689.5C449.7,688.3 448.7,687.3 447.5,686.5C446.9,692.2 446,697.9 445,703.5C443.8,705 442.3,706.2 440.5,707C431.8,707.7 423.2,707.7 414.5,707C411.2,703.9 409.7,700.1 410,695.5C409.3,694.9 408.4,694.4 407.5,694C390.8,693.3 374.2,693.3 357.5,694C356.9,694.8 356.4,695.6 356,696.5C355.7,700.2 355.3,703.8 355,707.5C354.7,709.3 353.9,710.8 352.5,712C343.2,714 333.8,714 324.5,712C323.7,711.2 322.8,710.3 322,709.5C321.3,664.5 321.3,619.5 322,574.5C322.4,573.9 322.9,573.6 323.5,573.5Z"/>
<path android:fillColor="#737e82" android:pathData="M413.5,687.5C414.5,691.6 414.8,696 414.5,700.5C423.8,700.5 433.2,700.5 442.5,700.5C433.3,701.5 424,701.8 414.5,701.5C414.2,701.5 413.8,701.5 413.5,701.5C413.5,698.5 413.5,695.5 413.5,692.5C413.5,690.8 413.5,689.2 413.5,687.5Z"/>
<path android:fillColor="#b6bfc2" android:pathData="M413.5,692.5C413.5,695.5 413.5,698.5 413.5,701.5C412.8,699 412.2,696.3 411.5,693.5C410.7,693.2 410,692.7 409.5,692C391.5,691.3 373.5,691.3 355.5,692C355,692.7 354.3,693.2 353.5,693.5C353.5,692.2 353.5,690.8 353.5,689.5C372.2,689.3 390.8,689.5 409.5,690C411,690.7 412.3,691.5 413.5,692.5Z"/>
<path android:fillColor="#a2aaae" android:pathData="M413.5,687.5C413.5,689.2 413.5,690.8 413.5,692.5C412.3,691.5 411,690.7 409.5,690C390.8,689.5 372.2,689.3 353.5,689.5C353.5,690.8 353.5,692.2 353.5,693.5C353.8,698.4 353.5,703 352.5,707.5C352.5,700.8 352.5,694.2 352.5,687.5C372.8,687.5 393.2,687.5 413.5,687.5Z"/>
<path android:fillColor="#a5aeb1" android:pathData="M547.5,645.5C546.6,651.6 544.5,657.3 541,662.5C533.3,672 525.1,681 516.5,689.5C515.1,689.3 513.8,689.5 512.5,690C507.8,694.5 502.5,698 496.5,700.5C486.3,703.7 475.9,706.7 465.5,709.5C461.2,709.8 459.2,707.8 459.5,703.5C460.6,704.6 461.4,705.9 462,707.5C490.8,703.1 514.8,690.1 534,668.5C539.2,661.2 543.7,653.5 547.5,645.5Z"/>
<path android:fillColor="#b8c2c6" android:pathData="M562.5,537.5C563.8,538.5 564.4,540 564.5,542C564.8,545.5 563.7,548.3 561,550.5C560.7,567.5 560.3,584.5 560,601.5C558.9,624.8 552.5,646.5 541,666.5C534.2,673 527.7,679.8 521.5,687C519.9,688.1 518.3,688.9 516.5,689.5C525.1,681 533.3,672 541,662.5C544.5,657.3 546.6,651.6 547.5,645.5C553,630.3 556.5,614.6 558,598.5C558.3,580.8 558.7,563.2 559,545.5C562.5,543.6 563.7,540.9 562.5,537.5Z"/>
<path android:fillColor="#b4bdc0" android:pathData="M323.5,575.5C323.5,619.5 323.5,663.5 323.5,707.5C333.2,707.5 342.8,707.5 352.5,707.5C352,708.5 351.4,709.3 350.5,710C341,711 331.6,710.5 322.5,708.5C322.2,664 322.5,619.7 323.5,575.5Z"/>
<path android:fillColor="#bcc5c9" android:pathData="M443.5,574.5C444.3,575.3 444.8,576.3 445,577.5C445.3,609.2 445.7,640.8 446,672.5C446.3,672.8 446.7,673.2 447,673.5C447.3,672.6 447.8,671.9 448.5,671.5C452.2,682.2 455.8,692.8 459.5,703.5C459.2,707.8 461.2,709.8 465.5,709.5C475.9,706.7 486.3,703.7 496.5,700.5C489.2,705.3 481.2,708.8 472.5,711C464.6,713.3 459.1,710.8 456,703.5C454.6,698.5 452.8,693.9 450.5,689.5C450.8,686.8 450.5,684.1 449.5,681.5C448,679.7 446.9,677.7 446,675.5C444.9,684.7 444.1,693.9 443.5,703C434.2,704.6 424.9,704.9 415.5,704C414.7,703.3 414.4,702.5 414.5,701.5C424,701.8 433.3,701.5 442.5,700.5C443.5,658.7 443.8,616.7 443.5,574.5Z"/>
<path android:fillColor="#8e999d" android:pathData="M323.5,570.5C363.3,569.5 403.3,569.2 443.5,569.5C443.5,571.2 443.5,572.8 443.5,574.5C443.8,616.7 443.5,658.7 442.5,700.5C442.5,657.2 442.5,613.8 442.5,570.5C402.8,570.5 363.2,570.5 323.5,570.5Z"/>
<path android:fillColor="#142c33" android:pathData="M323.5,570.5C363.2,570.5 402.8,570.5 442.5,570.5C442.5,613.8 442.5,657.2 442.5,700.5C433.2,700.5 423.8,700.5 414.5,700.5C414.8,696 414.5,691.6 413.5,687.5C393.2,687.5 372.8,687.5 352.5,687.5C352.5,694.2 352.5,700.8 352.5,707.5C342.8,707.5 333.2,707.5 323.5,707.5C323.5,663.5 323.5,619.5 323.5,575.5C323.5,574.8 323.5,574.2 323.5,573.5C323.5,572.5 323.5,571.5 323.5,570.5Z"/>
<path android:fillColor="#728084" android:pathData="M413.5,597.5C414.5,618.3 414.8,639.3 414.5,660.5C393.7,660.8 373,660.5 352.5,659.5C352.8,659.5 353.2,659.5 353.5,659.5C354.2,659.5 354.8,659.5 355.5,659.5C374.5,659.5 393.5,659.5 412.5,659.5C413.5,640 413.8,620.3 413.5,600.5C413.5,599.5 413.5,598.5 413.5,597.5Z"/>
<path android:fillColor="#bcc6ca" android:pathData="M413.5,600.5C413.8,620.3 413.5,640 412.5,659.5C412.8,640.8 412.5,622.2 411.5,603.5C393.2,602.3 374.9,602.2 356.5,603C356,603.5 355.5,604 355,604.5C354.2,622.9 354.3,641.2 355.5,659.5C354.8,659.5 354.2,659.5 353.5,659.5C353.2,639.9 353.5,620.4 354.5,601C364.4,599.9 374.4,599.4 384.5,599.5C394.2,599.5 403.9,599.9 413.5,600.5Z"/>
<path android:fillColor="#cfdade" android:pathData="M412.5,659.5C393.5,659.5 374.5,659.5 355.5,659.5C354.3,641.2 354.2,622.9 355,604.5C355.5,604 356,603.5 356.5,603C374.9,602.2 393.2,602.3 411.5,603.5C412.5,622.2 412.8,640.8 412.5,659.5Z"/>
<path android:fillColor="#d7e2e6" android:pathData="M358.5,605.5C375.2,605.5 391.8,605.5 408.5,605.5C408.5,622.8 408.5,640.2 408.5,657.5C391.6,657.8 374.8,657.5 358,656.5C357.2,639.4 357.3,622.4 358.5,605.5Z"/>
<path android:fillColor="#a0a8ab" android:pathData="M413.5,597.5C413.5,598.5 413.5,599.5 413.5,600.5C403.9,599.9 394.2,599.5 384.5,599.5C374.4,599.4 364.4,599.9 354.5,601C353.5,620.4 353.2,639.9 353.5,659.5C353.2,659.5 352.8,659.5 352.5,659.5C352.5,638.8 352.5,618.2 352.5,597.5C372.8,597.5 393.2,597.5 413.5,597.5Z"/>
<path android:fillColor="#8e999d" android:pathData="M557.5,536.5C546.5,536.5 535.5,536.5 524.5,536.5C524.8,555 524.5,573.3 523.5,591.5C523.5,573.8 523.5,556.2 523.5,538.5C523.5,537.5 523.5,536.5 523.5,535.5C535,535.2 546.3,535.5 557.5,536.5Z"/>
<path android:fillColor="#c4ced2" android:pathData="M523.5,538.5C523.5,556.2 523.5,573.8 523.5,591.5C523.6,605.4 520.6,618.4 514.5,630.5C515.7,624.8 517.2,619.1 519,613.5C520.2,589.5 520.8,565.5 521,541.5C521.4,540.1 522.2,539.1 523.5,538.5Z"/>
<path android:fillColor="#142c33" android:pathData="M557.5,536.5C559.2,536.6 560.9,537 562.5,537.5C563.7,540.9 562.5,543.6 559,545.5C558.7,563.2 558.3,580.8 558,598.5C556.5,614.6 553,630.3 547.5,645.5C543.7,653.5 539.2,661.2 534,668.5C514.8,690.1 490.8,703.1 462,707.5C461.4,705.9 460.6,704.6 459.5,703.5C455.8,692.8 452.2,682.2 448.5,671.5C457.6,671.4 466.2,669.7 474.5,666.5C478.9,665.6 482.9,663.9 486.5,661.5C499.4,654.3 508.7,644 514.5,630.5C520.6,618.4 523.6,605.4 523.5,591.5C524.5,573.3 524.8,555 524.5,536.5C535.5,536.5 546.5,536.5 557.5,536.5Z"/>
<path android:fillColor="#cad8dc" android:pathData="M601.5,841.5C553.1,855.4 504.1,858.1 454.5,849.5C488.9,853.4 523.2,853.2 557.5,849C572.2,846.4 586.8,843.9 601.5,841.5Z"/>
</vector>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
android:insetTop="@dimen/abc_edit_text_inset_top_material"
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
<selector>
<!--
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
-->
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
</selector>
</inset>
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/splashscreen_background"
android:gravity="center"
android:orientation="vertical"
android:scaleType="centerCrop"
android:navigationBarColor="#333333"
tools:context=".MainActivity">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="130dp"
app:lottie_rawRes="@raw/loading"
app:lottie_autoPlay="true"
app:lottie_loop="false"
/>
</LinearLayout>
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/iconBackground"/>
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Some files were not shown because too many files have changed in this diff Show More