From 8ee6121ce9d704d43ebcfe95567ca44236538ec7 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:11:30 +0200
Subject: [PATCH 01/17] migrate to rock
---
.gitignore | 3 +
android/app/build.gradle | 2 +-
android/settings.gradle | 4 +-
ios/LNReader.xcodeproj/project.pbxproj | 2 +-
ios/Podfile | 2 +-
package.json | 15 +-
pnpm-lock.yaml | 287 +++++++++++++++++++++++--
rock.config.mjs | 14 ++
8 files changed, 296 insertions(+), 33 deletions(-)
create mode 100644 rock.config.mjs
diff --git a/.gitignore b/.gitignore
index b58ccbf0ab..6bd0e1d75c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,3 +94,6 @@ flake.lock
.claude/
.jj/
.sisyphus/
+
+# Rock
+.rock/
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6913012930..20ebf419b2 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -15,7 +15,7 @@ react {
// 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")
+ cliFile = file("../../node_modules/rock/dist/src/bin.js")
/* Variants */
// The list of variants to that are debuggable. For those we're going to
diff --git a/android/settings.gradle b/android/settings.gradle
index 5bd85f93a4..f99ada0795 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -24,9 +24,9 @@ plugins {
extensions.configure(com.facebook.react.ReactSettingsExtension) { ex ->
if (System.getenv('EXPO_USE_COMMUNITY_AUTOLINKING') == '1') {
- ex.autolinkLibrariesFromCommand()
+ ex.autolinkLibrariesFromCommand(['npx', 'rock', 'config', '-p', 'android'])
} else {
- ex.autolinkLibrariesFromCommand(expoAutolinking.rnConfigCommand)
+ ex.autolinkLibrariesFromCommand(['npx', 'rock', 'config', '-p', 'android'])
}
}
diff --git a/ios/LNReader.xcodeproj/project.pbxproj b/ios/LNReader.xcodeproj/project.pbxproj
index ad17a7e0c7..e86eba4fd6 100644
--- a/ios/LNReader.xcodeproj/project.pbxproj
+++ b/ios/LNReader.xcodeproj/project.pbxproj
@@ -265,7 +265,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
+ shellScript = "set -e\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\nsource \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\nsource \"$PODS_ROOT/../.xcode.env.local\"\nfi\nexport CONFIG_CMD=\"dummy-workaround-value\"\nexport CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('rock/package.json')) + '/dist/src/bin.js'\")\"\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\n";
};
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
diff --git a/ios/Podfile b/ios/Podfile
index fc71ca6de9..24affabb0c 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -33,7 +33,7 @@ target 'LNReader' do
]
end
- config = use_native_modules!(config_command)
+ config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])(config_command)
use_react_native!(
:path => config[:reactNativePath],
diff --git a/package.json b/package.json
index 605b0361cf..49473f8bd0 100644
--- a/package.json
+++ b/package.json
@@ -3,10 +3,10 @@
"version": "2.0.3",
"private": true,
"scripts": {
- "dev:android": "pnpm run generate:env:debug && react-native run-android --appIdSuffix \"debug\" --active-arch-only",
- "dev:android:release": "pnpm run generate:env:release && react-native run-android --mode \"release\" --active-arch-only",
- "dev:ios": "react-native run-ios",
- "dev:start": "react-native start",
+ "dev:android:release": "pnpm run generate:env:release && rock run:android --variant \"release\" --active-arch-only",
+ "dev:android": "pnpm run generate:env:debug && rock run:android --app-id-suffix \"debug\" --active-arch-only",
+ "dev:ios": "rock run:ios",
+ "dev:start": "rock start",
"dev:clean-start": "pnpm run dev:start -- --reset-cache",
"build:release:android": "pnpm run generate:env:release && cd android && ./gradlew clean && ./gradlew assembleRelease",
"build:open-apk": "open ./android/app/build/outputs/apk/release/",
@@ -125,14 +125,14 @@
"@babel/plugin-transform-export-namespace-from": "^7.27.1",
"@babel/preset-env": "^7.29.2",
"@babel/runtime": "^7.29.2",
- "@react-native-community/cli": "^20.1.3",
- "@react-native-community/cli-platform-android": "^20.1.3",
- "@react-native-community/cli-platform-ios": "^20.1.3",
"@react-native/babel-preset": "^0.83.4",
"@react-native/eslint-config": "^0.83.4",
"@react-native/eslint-plugin": "^0.83.4",
"@react-native/metro-config": "^0.83.4",
"@react-native/typescript-config": "^0.83.4",
+ "@rock-js/platform-android": "^0.12.12",
+ "@rock-js/platform-ios": "^0.12.12",
+ "@rock-js/plugin-metro": "^0.12.12",
"@testing-library/react-native": "^13.3.3",
"@types/better-sqlite3": "^7.6.13",
"@types/color": "^4.2.1",
@@ -161,6 +161,7 @@
"lint-staged": "^12.5.0",
"prettier": "2.8.8",
"react-test-renderer": "19.2.4",
+ "rock": "^0.12.12",
"typescript": "~5.9.3"
},
"lint-staged": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c90f5c76f0..1df6533c37 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -231,15 +231,6 @@ importers:
'@babel/runtime':
specifier: ^7.29.2
version: 7.29.2
- '@react-native-community/cli':
- specifier: ^20.1.3
- version: 20.1.3(typescript@5.9.3)
- '@react-native-community/cli-platform-android':
- specifier: ^20.1.3
- version: 20.1.3
- '@react-native-community/cli-platform-ios':
- specifier: ^20.1.3
- version: 20.1.3
'@react-native/babel-preset':
specifier: ^0.83.4
version: 0.83.4(@babel/core@7.29.0)
@@ -255,6 +246,15 @@ importers:
'@react-native/typescript-config':
specifier: ^0.83.4
version: 0.83.4
+ '@rock-js/platform-android':
+ specifier: ^0.12.12
+ version: 0.12.12
+ '@rock-js/platform-ios':
+ specifier: ^0.12.12
+ version: 0.12.12(typescript@5.9.3)
+ '@rock-js/plugin-metro':
+ specifier: ^0.12.12
+ version: 0.12.12
'@testing-library/react-native':
specifier: ^13.3.3
version: 13.3.3(jest@29.7.0(@types/node@25.5.0))(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react-test-renderer@19.2.4(react@19.2.4))(react@19.2.4)
@@ -339,6 +339,9 @@ importers:
react-test-renderer:
specifier: 19.2.4
version: 19.2.4(react@19.2.4)
+ rock:
+ specifier: ^0.12.12
+ version: 0.12.12(typescript@5.9.3)
typescript:
specifier: ~5.9.3
version: 5.9.3
@@ -1121,6 +1124,12 @@ packages:
react: '*'
react-native: '*'
+ '@clack/core@0.5.0':
+ resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==}
+
+ '@clack/prompts@0.11.0':
+ resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
+
'@drizzle-team/brocli@0.11.0':
resolution: {integrity: sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg==}
@@ -1496,6 +1505,10 @@ packages:
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
deprecated: Use @eslint/object-schema instead
+ '@isaacs/fs-minipass@4.0.1':
+ resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
+ engines: {node: '>=18.0.0'}
+
'@isaacs/ttlcache@1.4.1':
resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==}
engines: {node: '>=12'}
@@ -1906,6 +1919,27 @@ packages:
react-native-safe-area-context: '>= 4.0.0'
react-native-screens: '>= 4.0.0'
+ '@rock-js/config@0.12.12':
+ resolution: {integrity: sha512-EMdmUOPQ7TJq4kzHdxID6rJlN64ovPPz5hr3dP3wA5B3t/HWf02idmL28yrOWV3ICgSWMI/2QNAnEadAlwnVZw==}
+
+ '@rock-js/platform-android@0.12.12':
+ resolution: {integrity: sha512-3CzqSOb6WT+ovAqaHpQ0V+73HO+17AeZVnZydHVWqZQ8frrXD2ik3zDD4Fjqocrouc5MtllNJBKkpscTZPdcQQ==}
+
+ '@rock-js/platform-apple-helpers@0.12.12':
+ resolution: {integrity: sha512-P0gllR++x5dwAopwX/bV25tzESbp43YglvHK7HeruZcwAvUAEefElaVlaK4Y/go6VkYBYwogt3LF3ceF4vTuOA==}
+
+ '@rock-js/platform-ios@0.12.12':
+ resolution: {integrity: sha512-/kBq8CCe43eLlqF1VWaDeTnntBcASXNtwUaAKuSbIE5GoBOxgdjeGcuZXnvxLLYKJSHuTrrNO2cF3th1fMki2A==}
+
+ '@rock-js/plugin-metro@0.12.12':
+ resolution: {integrity: sha512-TeUFkXmOSyl6Wq7G1SKxNbnMrlwuduj833glDmdl8Ug90+6jYCRCsUC47Xy9svKz3XEDBJtEbcQfm0qX8XP30A==}
+
+ '@rock-js/provider-github@0.12.12':
+ resolution: {integrity: sha512-+5eoluqIVYtBmUC3yLPEmuSG/YdVFpaxVKOe3gIc7V/UZzMNGiaJx6dTeqOh8UDBKJb3Q8KqeV6f7rjKHIrU4g==}
+
+ '@rock-js/tools@0.12.12':
+ resolution: {integrity: sha512-/uXanOQp2biH92G/2YFqlitH7l+8dQ6oRb4o/GDd5z27gFp3+b1E7xVsyhLumcfEoSzQKm6vjr/7u98d+qAyKQ==}
+
'@sideway/address@4.1.5':
resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==}
@@ -2130,6 +2164,10 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
+ adm-zip@0.5.17:
+ resolution: {integrity: sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==}
+ engines: {node: '>=12.0'}
+
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
@@ -2499,6 +2537,10 @@ packages:
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
+ chownr@3.0.0:
+ resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
+ engines: {node: '>=18'}
+
chrome-launcher@0.15.2:
resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==}
engines: {node: '>=12.13.0'}
@@ -3439,6 +3481,10 @@ packages:
fast-xml-builder@1.1.4:
resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==}
+ fast-xml-parser@4.5.6:
+ resolution: {integrity: sha512-Yd4vkROfJf8AuJrDIVMVmYfULKmIJszVsMv7Vo71aocsKgFxpdlpSHXSaInvyYfgw2PRuObQSW2GFpVMUjxu9A==}
+ hasBin: true
+
fast-xml-parser@5.5.9:
resolution: {integrity: sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==}
hasBin: true
@@ -3536,6 +3582,10 @@ packages:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
engines: {node: '>=6 <7 || >=8'}
+ fs-fingerprint@0.11.0:
+ resolution: {integrity: sha512-EpEtmn1T9bLxxf+506gVdpehs6pAIFAM6UCDtT9/J7tfLXg8FPn+3jmuVnMjjRFshJohR2lb2TZGwuZAhIOcKg==}
+ engines: {node: '>=20.0.0'}
+
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
@@ -3961,6 +4011,10 @@ packages:
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
engines: {node: '>=10'}
+ is-unicode-supported@2.1.0:
+ resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
+ engines: {node: '>=18'}
+
is-weakmap@2.0.2:
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
engines: {node: '>= 0.4'}
@@ -4696,6 +4750,10 @@ packages:
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
engines: {node: '>=16 || 14 >=14.17'}
+ minizlib@3.1.0:
+ resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
+ engines: {node: '>= 18'}
+
mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
@@ -4718,6 +4776,10 @@ packages:
multitars@0.2.4:
resolution: {integrity: sha512-XgLbg1HHchFauMCQPRwMj6MSyDd5koPlTA1hM3rUFkeXzGpjU/I9fP3to7yrObE9jcN8ChIOQGrM0tV0kUZaKg==}
+ nano-spawn@0.2.1:
+ resolution: {integrity: sha512-/pULofvsF8mOVcl/nUeVXL/GYOEvc7eJWSIxa+K4OYUolvXa5zwSgevsn4eoHs1xvh/BO3vx/PZiD9+Ow2ZVuw==}
+ engines: {node: '>=18.19'}
+
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -4894,6 +4956,10 @@ packages:
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ p-limit@7.3.0:
+ resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==}
+ engines: {node: '>=20'}
+
p-locate@3.0.0:
resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
engines: {node: '>=6'}
@@ -5463,6 +5529,10 @@ packages:
deprecated: Rimraf versions prior to v4 are no longer supported
hasBin: true
+ rock@0.12.12:
+ resolution: {integrity: sha512-wyTwi52tFvM9MFKwwAaz6mgKTF7Djkhg1cqG8r8x9zl4SZGgsDDG/NwSHXUgER7GNZYm1Zx+u6zDFMnRNvvceg==}
+ hasBin: true
+
rtl-detect@1.1.2:
resolution: {integrity: sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==}
@@ -5780,6 +5850,9 @@ packages:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
+ strnum@1.1.2:
+ resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==}
+
strnum@2.2.2:
resolution: {integrity: sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==}
@@ -5820,6 +5893,10 @@ packages:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
+ tar@7.5.13:
+ resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==}
+ engines: {node: '>=18'}
+
tarn@3.0.2:
resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==}
engines: {node: '>=8.0.0'}
@@ -5886,6 +5963,10 @@ packages:
peerDependencies:
typescript: '>=4.8.4'
+ ts-regex-builder@1.8.2:
+ resolution: {integrity: sha512-Y8HovHFheDKm/jgLIWSO8o81xA/I9O5AGc3/vNG1sVSskatOifr3SQzAsatBXGLjL3nYhQif1MpwQRS5GF8ADg==}
+ engines: {node: '>= 18.0.0'}
+
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -6193,6 +6274,10 @@ packages:
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+ yallist@5.0.0:
+ resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
+ engines: {node: '>=18'}
+
yaml@1.10.3:
resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==}
engines: {node: '>= 6'}
@@ -7272,6 +7357,17 @@ snapshots:
react-native-saf-x: 2.2.3(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
react-native-zip-archive: 6.1.2(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
+ '@clack/core@0.5.0':
+ dependencies:
+ picocolors: 1.1.1
+ sisteransi: 1.0.5
+
+ '@clack/prompts@0.11.0':
+ dependencies:
+ '@clack/core': 0.5.0
+ picocolors: 1.1.1
+ sisteransi: 1.0.5
+
'@drizzle-team/brocli@0.11.0': {}
'@egjs/hammerjs@2.0.17':
@@ -7737,6 +7833,10 @@ snapshots:
'@humanwhocodes/object-schema@2.0.3': {}
+ '@isaacs/fs-minipass@4.0.1':
+ dependencies:
+ minipass: 7.1.3
+
'@isaacs/ttlcache@1.4.1': {}
'@istanbuljs/load-nyc-config@1.1.0':
@@ -8016,6 +8116,7 @@ snapshots:
execa: 5.1.1
fast-glob: 3.3.3
picocolors: 1.1.1
+ optional: true
'@react-native-community/cli-config-android@20.1.3':
dependencies:
@@ -8061,6 +8162,7 @@ snapshots:
yaml: 2.8.3
transitivePeerDependencies:
- typescript
+ optional: true
'@react-native-community/cli-platform-android@20.1.3':
dependencies:
@@ -8069,6 +8171,7 @@ snapshots:
execa: 5.1.1
logkitty: 0.7.1
picocolors: 1.1.1
+ optional: true
'@react-native-community/cli-platform-apple@20.1.3':
dependencies:
@@ -8077,10 +8180,12 @@ snapshots:
execa: 5.1.1
fast-xml-parser: 5.5.9
picocolors: 1.1.1
+ optional: true
'@react-native-community/cli-platform-ios@20.1.3':
dependencies:
'@react-native-community/cli-platform-apple': 20.1.3
+ optional: true
'@react-native-community/cli-server-api@20.1.3':
dependencies:
@@ -8139,6 +8244,7 @@ snapshots:
- supports-color
- typescript
- utf-8-validate
+ optional: true
'@react-native-community/slider@5.1.2': {}
@@ -8424,6 +8530,74 @@ snapshots:
transitivePeerDependencies:
- '@react-native-masked-view/masked-view'
+ '@rock-js/config@0.12.12':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@rock-js/provider-github': 0.12.12
+ '@rock-js/tools': 0.12.12
+ joi: 17.13.3
+ tslib: 2.8.1
+
+ '@rock-js/platform-android@0.12.12':
+ dependencies:
+ '@react-native-community/cli-config-android': 20.1.3
+ '@rock-js/tools': 0.12.12
+ tslib: 2.8.1
+
+ '@rock-js/platform-apple-helpers@0.12.12(typescript@5.9.3)':
+ dependencies:
+ '@react-native-community/cli-config': 20.1.3(typescript@5.9.3)
+ '@react-native-community/cli-config-apple': 20.1.3
+ '@rock-js/tools': 0.12.12
+ adm-zip: 0.5.17
+ fast-xml-parser: 4.5.6
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - typescript
+
+ '@rock-js/platform-ios@0.12.12(typescript@5.9.3)':
+ dependencies:
+ '@react-native-community/cli-config-apple': 20.1.3
+ '@react-native-community/cli-types': 20.1.3
+ '@rock-js/platform-apple-helpers': 0.12.12(typescript@5.9.3)
+ '@rock-js/tools': 0.12.12
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - typescript
+
+ '@rock-js/plugin-metro@0.12.12':
+ dependencies:
+ '@react-native-community/cli-server-api': 20.1.3
+ '@rock-js/tools': 0.12.12
+ metro: 0.83.5
+ metro-config: 0.83.5
+ metro-core: 0.83.5
+ metro-resolver: 0.83.5
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ '@rock-js/provider-github@0.12.12':
+ dependencies:
+ '@rock-js/tools': 0.12.12
+ ts-regex-builder: 1.8.2
+ tslib: 2.8.1
+
+ '@rock-js/tools@0.12.12':
+ dependencies:
+ '@clack/prompts': 0.11.0
+ adm-zip: 0.5.17
+ appdirsjs: 1.2.7
+ fs-fingerprint: 0.11.0
+ is-unicode-supported: 2.1.0
+ nano-spawn: 0.2.1
+ picocolors: 1.1.1
+ string-argv: 0.3.2
+ tar: 7.5.13
+ tslib: 2.8.1
+
'@sideway/address@4.1.5':
dependencies:
'@hapi/hoek': 9.3.0
@@ -8699,6 +8873,8 @@ snapshots:
acorn@8.16.0: {}
+ adm-zip@0.5.17: {}
+
agent-base@6.0.2:
dependencies:
debug: 4.4.3(supports-color@9.4.0)
@@ -8732,6 +8908,7 @@ snapshots:
colorette: 1.4.0
slice-ansi: 2.1.0
strip-ansi: 5.2.0
+ optional: true
ansi-regex@4.1.1: {}
@@ -8825,7 +9002,8 @@ snapshots:
asap@2.0.6: {}
- astral-regex@1.0.0: {}
+ astral-regex@1.0.0:
+ optional: true
astral-regex@2.0.0: {}
@@ -9177,6 +9355,8 @@ snapshots:
chownr@1.1.4: {}
+ chownr@3.0.0: {}
+
chrome-launcher@0.15.2:
dependencies:
'@types/node': 25.5.0
@@ -9230,6 +9410,7 @@ snapshots:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
+ optional: true
cliui@8.0.1:
dependencies:
@@ -9285,7 +9466,8 @@ snapshots:
color-convert: 3.1.3
color-string: 2.1.4
- colorette@1.4.0: {}
+ colorette@1.4.0:
+ optional: true
colorette@2.0.20: {}
@@ -9293,7 +9475,8 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
- command-exists@1.2.9: {}
+ command-exists@1.2.9:
+ optional: true
commander@11.1.0: {}
@@ -9430,7 +9613,8 @@ snapshots:
optionalDependencies:
supports-color: 9.4.0
- decamelize@1.2.0: {}
+ decamelize@1.2.0:
+ optional: true
decimal.js@10.6.0: {}
@@ -9601,7 +9785,8 @@ snapshots:
env-paths@2.2.1: {}
- envinfo@7.21.0: {}
+ envinfo@7.21.0:
+ optional: true
error-ex@1.3.4:
dependencies:
@@ -10166,6 +10351,10 @@ snapshots:
dependencies:
path-expression-matcher: 1.2.0
+ fast-xml-parser@4.5.6:
+ dependencies:
+ strnum: 1.1.2
+
fast-xml-parser@5.5.9:
dependencies:
fast-xml-builder: 1.1.4
@@ -10269,6 +10458,12 @@ snapshots:
graceful-fs: 4.2.11
jsonfile: 4.0.0
universalify: 0.1.2
+ optional: true
+
+ fs-fingerprint@0.11.0:
+ dependencies:
+ p-limit: 7.3.0
+ tinyglobby: 0.2.15
fs.realpath@1.0.0: {}
@@ -10620,7 +10815,8 @@ snapshots:
dependencies:
call-bound: 1.0.4
- is-fullwidth-code-point@2.0.0: {}
+ is-fullwidth-code-point@2.0.0:
+ optional: true
is-fullwidth-code-point@3.0.0: {}
@@ -10695,6 +10891,8 @@ snapshots:
is-unicode-supported@0.1.0: {}
+ is-unicode-supported@2.1.0: {}
+
is-weakmap@2.0.2: {}
is-weakref@1.1.1:
@@ -11229,6 +11427,7 @@ snapshots:
jsonfile@4.0.0:
optionalDependencies:
graceful-fs: 4.2.11
+ optional: true
jsonwebtoken@9.0.3:
dependencies:
@@ -11433,6 +11632,7 @@ snapshots:
ansi-fragments: 0.2.1
dayjs: 1.11.20
yargs: 15.4.1
+ optional: true
long@5.3.2: {}
@@ -11886,6 +12086,10 @@ snapshots:
minipass@7.1.3: {}
+ minizlib@3.1.0:
+ dependencies:
+ minipass: 7.1.3
+
mkdirp-classic@0.5.3: {}
mkdirp@1.0.4: {}
@@ -11908,6 +12112,8 @@ snapshots:
multitars@0.2.4: {}
+ nano-spawn@0.2.1: {}
+
nanoid@3.3.11: {}
napi-build-utils@2.0.0: {}
@@ -11941,7 +12147,8 @@ snapshots:
node-releases@2.0.36: {}
- node-stream-zip@1.15.0: {}
+ node-stream-zip@1.15.0:
+ optional: true
normalize-path@3.0.0: {}
@@ -12100,6 +12307,10 @@ snapshots:
dependencies:
yocto-queue: 1.2.2
+ p-limit@7.3.0:
+ dependencies:
+ yocto-queue: 1.2.2
+
p-locate@3.0.0:
dependencies:
p-limit: 2.3.0
@@ -12667,7 +12878,8 @@ snapshots:
require-directory@2.1.1: {}
- require-main-filename@2.0.0: {}
+ require-main-filename@2.0.0:
+ optional: true
require-resolve@0.0.2:
dependencies:
@@ -12724,6 +12936,18 @@ snapshots:
dependencies:
glob: 7.2.3
+ rock@0.12.12(typescript@5.9.3):
+ dependencies:
+ '@react-native-community/cli-config': 20.1.3(typescript@5.9.3)
+ '@rock-js/config': 0.12.12
+ '@rock-js/tools': 0.12.12
+ adm-zip: 0.5.17
+ commander: 12.1.0
+ tar: 7.5.13
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - typescript
+
rtl-detect@1.1.2: {}
run-applescript@7.1.0: {}
@@ -12811,7 +13035,8 @@ snapshots:
server-only@0.0.1: {}
- set-blocking@2.0.0: {}
+ set-blocking@2.0.0:
+ optional: true
set-function-length@1.2.2:
dependencies:
@@ -12906,6 +13131,7 @@ snapshots:
ansi-styles: 3.2.1
astral-regex: 1.0.0
is-fullwidth-code-point: 2.0.0
+ optional: true
slice-ansi@3.0.0:
dependencies:
@@ -13088,6 +13314,8 @@ snapshots:
strip-json-comments@3.1.1: {}
+ strnum@1.1.2: {}
+
strnum@2.2.2: {}
structured-headers@0.4.1: {}
@@ -13130,6 +13358,14 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
+ tar@7.5.13:
+ dependencies:
+ '@isaacs/fs-minipass': 4.0.1
+ chownr: 3.0.0
+ minipass: 7.1.3
+ minizlib: 3.1.0
+ yallist: 5.0.0
+
tarn@3.0.2: {}
tedious@18.6.2(@azure/core-client@1.10.1):
@@ -13218,6 +13454,8 @@ snapshots:
dependencies:
typescript: 5.9.3
+ ts-regex-builder@1.8.2: {}
+
tslib@2.8.1: {}
tunnel-agent@0.6.0:
@@ -13299,7 +13537,8 @@ snapshots:
unicorn-magic@0.1.0: {}
- universalify@0.1.2: {}
+ universalify@0.1.2:
+ optional: true
universalify@0.2.0: {}
@@ -13422,7 +13661,8 @@ snapshots:
is-weakmap: 2.0.2
is-weakset: 2.0.4
- which-module@2.0.1: {}
+ which-module@2.0.1:
+ optional: true
which-typed-array@1.1.20:
dependencies:
@@ -13493,12 +13733,15 @@ snapshots:
xmlchars@2.2.0: {}
- y18n@4.0.3: {}
+ y18n@4.0.3:
+ optional: true
y18n@5.0.8: {}
yallist@3.1.1: {}
+ yallist@5.0.0: {}
+
yaml@1.10.3: {}
yaml@2.8.3: {}
@@ -13507,6 +13750,7 @@ snapshots:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
+ optional: true
yargs-parser@21.1.1: {}
@@ -13523,6 +13767,7 @@ snapshots:
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 18.1.3
+ optional: true
yargs@17.7.2:
dependencies:
diff --git a/rock.config.mjs b/rock.config.mjs
new file mode 100644
index 0000000000..d52660d6b5
--- /dev/null
+++ b/rock.config.mjs
@@ -0,0 +1,14 @@
+// @ts-check
+import { platformIOS } from '@rock-js/platform-ios';
+import { platformAndroid } from '@rock-js/platform-android';
+import { pluginMetro } from '@rock-js/plugin-metro';
+
+/** @type {import('rock').Config} */
+export default {
+ bundler: pluginMetro(),
+ platforms: {
+ ios: platformIOS(),
+ android: platformAndroid(),
+ },
+ remoteCacheProvider: null,
+};
From 53e0ca3d605bd1d5a7ceab867a4dd94eea956fd4 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 14:44:24 +0200
Subject: [PATCH 02/17] Update build.yml
---
.github/workflows/build.yml | 48 +++++++++++++------------------------
1 file changed, 16 insertions(+), 32 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 903ae3acc5..51531d63bc 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,4 +1,5 @@
name: Build
+
on:
push:
branches:
@@ -14,6 +15,7 @@ jobs:
name: Build App
runs-on: ubuntu-latest
timeout-minutes: 60
+
steps:
- name: Checkout Repository
uses: actions/checkout@v4
@@ -41,17 +43,6 @@ jobs:
restore-keys: |
${{ 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
@@ -65,30 +56,23 @@ jobs:
BUILD_TYPE=Github Action
EOF
- - name: Make Gradlew Executable
- run: cd android && chmod +x ./gradlew
-
- name: Set Environment Variables
run: |
- set -x
- echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> $GITHUB_ENV
- echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+ 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 }}
+ - name: Update App Name
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
+ sed -i \
+ "s/lnreader/lnreader-r${{ env.COMMIT_COUNT }}(${
+ { env.COMMIT_ID }})/g" \
+ android/app/src/main/res/values/strings.xml
- - name: Upload Release Artifact
- env:
- COMMIT_COUNT: ${{ env.COMMIT_COUNT }}
- COMMIT_ID: ${{ env.COMMIT_ID }}
- uses: actions/upload-artifact@v4
+ - name: Build Android Release with Rock
+ uses: callstackincubator/android@v3
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
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ variant: release
+ rock-build-extra-params: >-
+ -PcustomAppId=com.rajarsheechatterjee.LNReader.commit_${{
+ env.COMMIT_ID }}
From 19a29bd334956ffb187e0d3b754518fb01491868 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 15:02:35 +0200
Subject: [PATCH 03/17] Update build.yml again and changed build.gradle
---
.github/workflows/build.yml | 17 +----------------
android/app/build.gradle | 13 +++++++++++--
2 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 51531d63bc..4f3b983b27 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -56,23 +56,8 @@ jobs:
BUILD_TYPE=Github Action
EOF
- - name: Set Environment Variables
- run: |
- echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> "$GITHUB_ENV"
- echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
-
- - name: Update App Name
- run: |
- sed -i \
- "s/lnreader/lnreader-r${{ env.COMMIT_COUNT }}(${
- { env.COMMIT_ID }})/g" \
- android/app/src/main/res/values/strings.xml
-
- name: Build Android Release with Rock
uses: callstackincubator/android@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- variant: release
- rock-build-extra-params: >-
- -PcustomAppId=com.rajarsheechatterjee.LNReader.commit_${{
- env.COMMIT_ID }}
+ variant: preRelease
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 20ebf419b2..6013dc159d 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -84,7 +84,7 @@ android {
compileSdk rootProject.ext.compileSdkVersion
namespace "com.rajarsheechatterjee.LNReader"
defaultConfig {
- applicationId project.hasProperty('customAppId') ? project.getProperty('customAppId') : 'com.rajarsheechatterjee.LNReader'
+ applicationId 'com.rajarsheechatterjee.LNReader'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
// Generated version code. Supports versions up to 1024.1024.2048
@@ -105,6 +105,15 @@ android {
applicationIdSuffix 'debug'
versionNameSuffix '-debug'
}
+ preRelease {
+ // Caution! In production, you need to generate your own keystore file.
+ // see https://reactnative.dev/docs/signed-apk-android.
+ applicationIdSuffix 'pre-release'
+ versionNameSuffix '-pre-release'
+ signingConfig signingConfigs.debug
+ minifyEnabled enableProguardInReleaseBuilds
+ proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
+ }
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
@@ -134,4 +143,4 @@ dependencies {
} else {
implementation jscFlavor
}
-}
\ No newline at end of file
+}
From 5738766d09f6696729f845e32b2b5d9a7fa49079 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 15:25:10 +0200
Subject: [PATCH 04/17] fixed actions build crash
---
android/app/build.gradle | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6013dc159d..6aa7b52f98 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -106,9 +106,11 @@ android {
versionNameSuffix '-debug'
}
preRelease {
+ initWith release
+ matchingFallbacks = ["release"]
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
- applicationIdSuffix 'pre-release'
+ applicationIdSuffix 'preRelease'
versionNameSuffix '-pre-release'
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
From fee5212bebf437b59488c404b0ef3b891c600b8d Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 15:28:24 +0200
Subject: [PATCH 05/17] add flashlist to avoid bottomsheet crash
---
package.json | 1 +
pnpm-lock.yaml | 21 ++++++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 49473f8bd0..6f0ce393d9 100644
--- a/package.json
+++ b/package.json
@@ -67,6 +67,7 @@
"@react-navigation/native": "^7.2.2",
"@react-navigation/native-stack": "^7.14.10",
"@react-navigation/stack": "^7.8.9",
+ "@shopify/flash-list": "^2.3.1",
"babel-plugin-inline-import": "^3.0.0",
"cheerio": "1.0.0-rc.12",
"color": "^5.0.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1df6533c37..3351018f9f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -62,6 +62,9 @@ importers:
'@react-navigation/stack':
specifier: ^7.8.9
version: 7.8.9(05167d8527e2c9f68e950b4e3fb9e48b)
+ '@shopify/flash-list':
+ specifier: ^2.3.1
+ version: 2.3.1(@babel/runtime@7.29.2)(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
babel-plugin-inline-import:
specifier: ^3.0.0
version: 3.0.0
@@ -1940,6 +1943,13 @@ packages:
'@rock-js/tools@0.12.12':
resolution: {integrity: sha512-/uXanOQp2biH92G/2YFqlitH7l+8dQ6oRb4o/GDd5z27gFp3+b1E7xVsyhLumcfEoSzQKm6vjr/7u98d+qAyKQ==}
+ '@shopify/flash-list@2.3.1':
+ resolution: {integrity: sha512-7oktg2NQR7KAODjFoDaWe8/OBzyYbdTE3zQTrUBMxjIbxHTHN7UXRX1hX3DHk8KvtkgQdRfZOV8Gjj2l4fGrXw==}
+ peerDependencies:
+ '@babel/runtime': '*'
+ react: '*'
+ react-native: '*'
+
'@sideway/address@4.1.5':
resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==}
@@ -3719,9 +3729,6 @@ packages:
hermes-compiler@0.14.1:
resolution: {integrity: sha512-+RPPQlayoZ9n6/KXKt5SFILWXCGJ/LV5d24L5smXrvTDrPS4L6dSctPczXauuvzFP3QEJbD1YO7Z3Ra4a+4IhA==}
- hermes-compiler@250829098.0.2:
- resolution: {integrity: sha512-9+la7TeGGZg5Cj0UV5MbqhqyT/Hd/PUlQZ3Uhggy0jiaiG2qxFJbi/uGWALTqa7GwETyQa4A7ngus1A1aXA8QQ==}
-
hermes-eslint@0.33.3:
resolution: {integrity: sha512-eGY0l6T5U9LDdC+uN88NrSOrvPPtXGPxN7EaD38hytWuBEVXypq0eQ1SNVsnQPBZLWi+b1jkF4F5aVtTCQC6wg==}
@@ -8598,6 +8605,12 @@ snapshots:
tar: 7.5.13
tslib: 2.8.1
+ '@shopify/flash-list@2.3.1(@babel/runtime@7.29.2)(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
+ dependencies:
+ '@babel/runtime': 7.29.2
+ react: 19.2.4
+ react-native: 0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4)
+
'@sideway/address@4.1.5':
dependencies:
'@hapi/hoek': 9.3.0
@@ -10596,8 +10609,6 @@ snapshots:
hermes-compiler@0.14.1: {}
- hermes-compiler@250829098.0.2: {}
-
hermes-eslint@0.33.3:
dependencies:
esrecurse: 4.3.0
From 9b9f5e7b86d6206cf7327450b34fc3489b80bc11 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 15:31:55 +0200
Subject: [PATCH 06/17] fix Novelscreen filter highlight
---
.../novel/components/Info/NovelInfoHeader.tsx | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/screens/novel/components/Info/NovelInfoHeader.tsx b/src/screens/novel/components/Info/NovelInfoHeader.tsx
index e21caf75a3..491e732562 100644
--- a/src/screens/novel/components/Info/NovelInfoHeader.tsx
+++ b/src/screens/novel/components/Info/NovelInfoHeader.tsx
@@ -236,7 +236,7 @@ const NovelInfoHeader = ({
chapters,
deleteDownloadsSnackbar,
fetching,
- filter,
+ filter = [],
firstUnreadChapter,
isLoading = false,
lastRead,
@@ -427,13 +427,19 @@ const NovelInfoHeader = ({
) : (
- {`${totalChapters} ${getString('novelScreen.chapters')}`}
+ {`${totalChapters ?? 0} ${getString(
+ 'novelScreen.chapters',
+ )}`}
)}
0
+ ? filterColor(theme.isDark)
+ : theme.onSurface
+ }
size={24}
onPress={handleOpenBottomSheet}
/>
From ec450913a2b0bdea9eb7b98599390cb6b6898fdd Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 16:11:32 +0200
Subject: [PATCH 07/17] upload artifact
---
.github/workflows/build.yml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 4f3b983b27..4e34f7e6d7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -61,3 +61,19 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
variant: preRelease
+
+ - name: Set Environment Variables
+ run: |
+ set -x
+ echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> $GITHUB_ENV
+ echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+
+ - 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/prRelease/app-preRelease.apk
+ retention-days: 30
From c177566034929431b1a33f5d38b2da1cfc9e3b20 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 17:57:46 +0200
Subject: [PATCH 08/17] update rock config
---
package.json | 2 +-
rock.config.mjs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 6f0ce393d9..13592f28ff 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
"dev:ios": "rock run:ios",
"dev:start": "rock start",
"dev:clean-start": "pnpm run dev:start -- --reset-cache",
- "build:release:android": "pnpm run generate:env:release && cd android && ./gradlew clean && ./gradlew assembleRelease",
+ "build:release:android": "pnpm run generate:env:release && rock build:android --variant \"release\"",
"build:open-apk": "open ./android/app/build/outputs/apk/release/",
"generate:env:debug": "node scripts/generate-env-file.cjs Debug",
"generate:env:release": "node scripts/generate-env-file.cjs Release",
diff --git a/rock.config.mjs b/rock.config.mjs
index d52660d6b5..e89c5110db 100644
--- a/rock.config.mjs
+++ b/rock.config.mjs
@@ -10,5 +10,5 @@ export default {
ios: platformIOS(),
android: platformAndroid(),
},
- remoteCacheProvider: null,
+ remoteCacheProvider: 'github-actions',
};
From bd6de7d9b1529b4b43337ebc370d9b963bca31db Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 17:58:25 +0200
Subject: [PATCH 09/17] update build.yml apk path
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 4e34f7e6d7..55a5c1970e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -75,5 +75,5 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: LNReader-r${{ env.COMMIT_COUNT }}-${{ env.COMMIT_ID }}
- path: android/app/build/outputs/apk/prRelease/app-preRelease.apk
+ path: android/app/build/outputs/apk/preRelease/app-preRelease.apk
retention-days: 30
From 96eedd88b508b0bbe616e1fdf4f5823b8c937a00 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 18:16:41 +0200
Subject: [PATCH 10/17] update rock.config again
---
.github/workflows/build.yml | 2 ++
package.json | 1 +
pnpm-lock.yaml | 3 +++
rock.config.mjs | 8 +++++++-
4 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 55a5c1970e..ab80f53829 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -58,6 +58,8 @@ jobs:
- name: Build Android Release with Rock
uses: callstackincubator/android@v3
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
variant: preRelease
diff --git a/package.json b/package.json
index 13592f28ff..23fee6c36b 100644
--- a/package.json
+++ b/package.json
@@ -134,6 +134,7 @@
"@rock-js/platform-android": "^0.12.12",
"@rock-js/platform-ios": "^0.12.12",
"@rock-js/plugin-metro": "^0.12.12",
+ "@rock-js/provider-github": "^0.12.12",
"@testing-library/react-native": "^13.3.3",
"@types/better-sqlite3": "^7.6.13",
"@types/color": "^4.2.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3351018f9f..b63d86357e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -258,6 +258,9 @@ importers:
'@rock-js/plugin-metro':
specifier: ^0.12.12
version: 0.12.12
+ '@rock-js/provider-github':
+ specifier: ^0.12.12
+ version: 0.12.12
'@testing-library/react-native':
specifier: ^13.3.3
version: 13.3.3(jest@29.7.0(@types/node@25.5.0))(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react-test-renderer@19.2.4(react@19.2.4))(react@19.2.4)
diff --git a/rock.config.mjs b/rock.config.mjs
index e89c5110db..3591f33cae 100644
--- a/rock.config.mjs
+++ b/rock.config.mjs
@@ -2,6 +2,7 @@
import { platformIOS } from '@rock-js/platform-ios';
import { platformAndroid } from '@rock-js/platform-android';
import { pluginMetro } from '@rock-js/plugin-metro';
+import { providerGitHub } from '@rock-js/provider-github';
/** @type {import('rock').Config} */
export default {
@@ -10,5 +11,10 @@ export default {
ios: platformIOS(),
android: platformAndroid(),
},
- remoteCacheProvider: 'github-actions',
+ remoteCacheProvider: providerGitHub({
+ repository: 'lnreader',
+ owner: 'CD-Z',
+ //@ts-expect-error
+ token: process.env.GITHUB_TOKEN,
+ }),
};
From e8e9023959a5ba26b217ea463e043bdc5b61f498 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 20:29:25 +0200
Subject: [PATCH 11/17] Test env file
---
.github/workflows/build.yml | 1 +
env.d.ts | 1 +
src/screens/library/components/LibraryListView.tsx | 3 ++-
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ab80f53829..d85b33869e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -54,6 +54,7 @@ jobs:
GIT_HASH=$(git rev-parse --short HEAD)
RELEASE_DATE=$(date --utc +'%d/%m/%y %I:%M %p %Z')
BUILD_TYPE=Github Action
+ TEST="This is a test"
EOF
- name: Build Android Release with Rock
diff --git a/env.d.ts b/env.d.ts
index a62595a633..ff527becc2 100644
--- a/env.d.ts
+++ b/env.d.ts
@@ -5,6 +5,7 @@ declare module 'react-native-config' {
GIT_HASH: string;
RELEASE_DATE: string;
BUILD_TYPE: 'Debug' | 'Release' | 'Beta' | 'Github Action';
+ TEST: string;
}
export const Config: NativeConfig;
diff --git a/src/screens/library/components/LibraryListView.tsx b/src/screens/library/components/LibraryListView.tsx
index 51316d216e..6f4d37be22 100644
--- a/src/screens/library/components/LibraryListView.tsx
+++ b/src/screens/library/components/LibraryListView.tsx
@@ -14,6 +14,7 @@ import ServiceManager from '@services/ServiceManager';
import { getPlugin } from '@plugins/pluginManager';
import { useSelectionContext } from '../SelectionContext';
import { ImageRequestInit } from '@plugins/types';
+import Config from 'react-native-config';
interface Props {
categoryId: number;
@@ -91,7 +92,7 @@ export const LibraryView: React.FC = ({
Date: Mon, 6 Apr 2026 20:40:15 +0200
Subject: [PATCH 12/17] Update build.yml
---
.github/workflows/build.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d85b33869e..5cf5307c19 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -62,6 +62,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
+ re-sign: true
github-token: ${{ secrets.GITHUB_TOKEN }}
variant: preRelease
From b06f7c430aab434c72f12c4675d440fb7ae1ec93 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Mon, 6 Apr 2026 22:21:01 +0200
Subject: [PATCH 13/17] remove react-native-config
---
.github/workflows/build.yml | 14 +-
.gitignore | 2 +
babel.config.js | 1 +
env.d.ts | 13 --
jest.config.js | 1 +
package.json | 5 +-
pnpm-lock.yaml | 18 ---
scripts/generate-env-file.cjs | 148 +++++++++++++-----
.../library/components/LibraryListView.tsx | 2 +-
src/screens/more/About.tsx | 2 +-
src/services/Trackers/aniList.ts | 2 +-
src/services/Trackers/myAnimeList.ts | 2 +-
tsconfig.json | 1 +
13 files changed, 124 insertions(+), 87 deletions(-)
delete mode 100644 env.d.ts
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5cf5307c19..77f33b47be 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -46,16 +46,12 @@ jobs:
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- - name: Create Environment File
+ - name: Generate Environment Variables
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
- TEST="This is a test"
- EOF
+ pnpm generate:env:release \
+ --build-type "Github Action" \
+ --myanimelist-client-id "${{ vars.MYANIMELIST_CLIENT_ID }}" \
+ --anilist-client-id "${{ vars.ANILIST_CLIENT_ID }}"
- name: Build Android Release with Rock
uses: callstackincubator/android@v3
diff --git a/.gitignore b/.gitignore
index 6bd0e1d75c..0bfd2b2a0c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -89,6 +89,8 @@ flake.lock
# pnpm
.pnpm-store
+src/generated/**/*
+
.cursor/
.agents/
.claude/
diff --git a/babel.config.js b/babel.config.js
index d5de9ae37a..ba8f201809 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -27,6 +27,7 @@ export default function (api) {
'@type': './src/type',
'@specs': './specs',
'@test-utils': './__tests-modules__/test-utils',
+ '@env': './src/generated/build-info',
'react-native-vector-icons/MaterialCommunityIcons':
'@react-native-vector-icons/material-design-icons',
},
diff --git a/env.d.ts b/env.d.ts
deleted file mode 100644
index ff527becc2..0000000000
--- a/env.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-declare module 'react-native-config' {
- export interface NativeConfig {
- MYANIMELIST_CLIENT_ID: string;
- ANILIST_CLIENT_ID: string;
- GIT_HASH: string;
- RELEASE_DATE: string;
- BUILD_TYPE: 'Debug' | 'Release' | 'Beta' | 'Github Action';
- TEST: string;
- }
-
- export const Config: NativeConfig;
- export default Config;
-}
diff --git a/jest.config.js b/jest.config.js
index 5268de4553..dd3677fd31 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -17,6 +17,7 @@ const baseModuleNameMapper = {
'^@type/(.*)$': '/src/type/$1',
'^@specs/(.*)$': '/specs/$1',
'^@test-utils$': '/__tests-modules__/test-utils',
+ '^@env$': '/src/generated/build-info',
// Mock static assets
'\\.(jpg|jpeg|png|gif|webp|svg)$': '/__mocks__/fileMock.js',
};
diff --git a/package.json b/package.json
index 23fee6c36b..7b6e98cc11 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,8 @@
"dev:clean-start": "pnpm run dev:start -- --reset-cache",
"build:release:android": "pnpm run generate:env:release && rock build:android --variant \"release\"",
"build:open-apk": "open ./android/app/build/outputs/apk/release/",
- "generate:env:debug": "node scripts/generate-env-file.cjs Debug",
- "generate:env:release": "node scripts/generate-env-file.cjs Release",
+ "generate:env:debug": "node scripts/generate-env-file.cjs --build-type Debug",
+ "generate:env:release": "node scripts/generate-env-file.cjs --build-type Release",
"generate:string-types": "node scripts/generate-string-types.cjs",
"generate:db-migration": "drizzle-kit generate",
"upgrade:migration-format": "drizzle-kit up",
@@ -95,7 +95,6 @@
"react": "^19.2.4",
"react-native": "^0.83.4",
"react-native-background-actions": "^4.0.1",
- "react-native-config": "^1.6.1",
"react-native-device-info": "^15.0.2",
"react-native-draggable-flatlist": "^4.0.3",
"react-native-drawer-layout": "^4.2.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b63d86357e..01635ce04c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -146,9 +146,6 @@ importers:
react-native-background-actions:
specifier: ^4.0.1
version: 4.0.1(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))
- react-native-config:
- specifier: ^1.6.1
- version: 1.6.1(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
react-native-device-info:
specifier: ^15.0.2
version: 15.0.2(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))
@@ -5219,16 +5216,6 @@ packages:
peerDependencies:
react-native: '>=0.47.0'
- react-native-config@1.6.1:
- resolution: {integrity: sha512-HvKtxr6/Tq3iMdFx5REYZsjCtPi0RxQOMCs15+DqrUPTNFtWHuEuh+zw7fJp+dmuO79YMfdtlsPWIGTHtaXwjg==}
- peerDependencies:
- react: '*'
- react-native: '*'
- react-native-windows: '>=0.61'
- peerDependenciesMeta:
- react-native-windows:
- optional: true
-
react-native-device-info@15.0.2:
resolution: {integrity: sha512-dd71eXG2l3Cwp66IvKNadMTB8fhU3PEjyVddI97sYan+D4bgIAUmgGDhbSOFvHcGavksb2U17kiQYaDiK2WK2g==}
peerDependencies:
@@ -12579,11 +12566,6 @@ snapshots:
eventemitter3: 4.0.7
react-native: 0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4)
- react-native-config@1.6.1(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4))(react@19.2.4):
- dependencies:
- react: 19.2.4
- react-native: 0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4)
-
react-native-device-info@15.0.2(react-native@0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4)):
dependencies:
react-native: 0.83.4(@babel/core@7.29.0)(@react-native-community/cli@20.1.3(typescript@5.9.3))(@react-native/metro-config@0.83.4(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.4)
diff --git a/scripts/generate-env-file.cjs b/scripts/generate-env-file.cjs
index ff7ee15b2e..480594b472 100644
--- a/scripts/generate-env-file.cjs
+++ b/scripts/generate-env-file.cjs
@@ -1,59 +1,127 @@
const fs = require('fs');
-const os = require('os');
const path = require('path');
const { execSync } = require('child_process');
-const formattedDate = new Date().getTime();
-const commitHash = execSync('git rev-parse --short HEAD').toString().trim();
-const buildType = process.argv[2] || 'Beta';
+function parseArgs(argv) {
+ const out = {};
-const newEnvVars = [
- `BUILD_TYPE=${buildType}`,
- `GIT_HASH=${commitHash}`,
- `RELEASE_DATE=${formattedDate}`,
- `NODE_ENV=${buildType === 'Release' ? 'production' : 'development'}`,
-].join(os.EOL);
+ for (let i = 2; i < argv.length; i += 1) {
+ const token = argv[i];
-const envFilePath = path.join(__dirname, '..', '.env');
-let existingEnvData = '';
+ if (!token.startsWith('--')) {
+ continue;
+ }
-try {
- if (fs.existsSync(envFilePath)) {
- const existingContent = fs.readFileSync(envFilePath, 'utf8');
-
- existingEnvData = existingContent
- .split(os.EOL)
- .filter(line => {
- const trimmedLine = line.trim();
- return (
- trimmedLine &&
- !trimmedLine.startsWith('BUILD_TYPE=') &&
- !trimmedLine.startsWith('GIT_HASH=') &&
- !trimmedLine.startsWith('RELEASE_DATE=') &&
- !trimmedLine.startsWith('NODE_ENV=')
- );
- })
- .join(os.EOL);
+ const eqIndex = token.indexOf('=');
+
+ if (eqIndex !== -1) {
+ out[token.slice(2, eqIndex)] = token.slice(eqIndex + 1);
+ continue;
+ }
+
+ const key = token.slice(2);
+ const next = argv[i + 1];
+
+ if (next && !next.startsWith('--')) {
+ out[key] = next;
+ i += 1;
+ } else {
+ out[key] = true;
+ }
}
-} catch (err) {
- console.warn('Warning: Could not read existing .env file:', err.message);
+
+ return out;
}
-const finalContent = existingEnvData
- ? `${newEnvVars}${os.EOL}${existingEnvData}${os.EOL}`
- : `${newEnvVars}${os.EOL}`;
+function formatUtcDate(date) {
+ const pad = n => String(n).padStart(2, '0');
+
+ const day = pad(date.getUTCDate());
+ const month = pad(date.getUTCMonth() + 1);
+ const year = String(date.getUTCFullYear()).slice(-2);
+
+ let hours = date.getUTCHours();
+ const minutes = pad(date.getUTCMinutes());
+ const ampm = hours >= 12 ? 'PM' : 'AM';
+
+ hours %= 12;
+ if (hours === 0) {
+ hours = 12;
+ }
+
+ return `${day}/${month}/${year} ${pad(hours)}:${minutes} ${ampm} UTC`;
+}
+
+function getGitHash() {
+ return execSync('git rev-parse --short HEAD').toString().trim();
+}
+
+const args = parseArgs(process.argv);
+
+const buildType = args['build-type'] || 'Beta';
+const myanimelistClientId = args['myanimelist-client-id'];
+const anilistClientId = args['anilist-client-id'];
+
+const gitHash = args['git-hash'] || getGitHash();
+const releaseDate = args['release-date'] || formatUtcDate(new Date());
+const nodeEnv =
+ args['node-env'] ||
+ (buildType.toLowerCase().includes('release') ? 'production' : 'development');
+const testValue =
+ args.test || 'This is a test variable to verify .env generation';
+
+const envContent = [
+ `BUILD_TYPE=${JSON.stringify(buildType)}`,
+ `GIT_HASH=${JSON.stringify(gitHash)}`,
+ `RELEASE_DATE=${JSON.stringify(releaseDate)}`,
+ `NODE_ENV=${JSON.stringify(nodeEnv)}`,
+ `MYANIMELIST_CLIENT_ID=${JSON.stringify(myanimelistClientId)}`,
+ `ANILIST_CLIENT_ID=${JSON.stringify(anilistClientId)}`,
+ `TEST=${JSON.stringify(testValue)}`,
+ '',
+].join('\n');
+
+const envFilePath = path.join(__dirname, '..', '.env');
+const buildInfoPath = path.join(
+ __dirname,
+ '..',
+ 'src',
+ 'generated',
+ 'build-info.ts',
+);
+
+const buildInfoContent = `// This file is generated. Do not edit manually.
+export const BUILD_TYPE = ${JSON.stringify(buildType)};
+export const GIT_HASH = ${JSON.stringify(gitHash)};
+export const RELEASE_DATE = ${JSON.stringify(releaseDate)};
+export const NODE_ENV = ${JSON.stringify(nodeEnv)};
+export const MYANIMELIST_CLIENT_ID = ${JSON.stringify(myanimelistClientId)};
+export const ANILIST_CLIENT_ID = ${JSON.stringify(anilistClientId)};
+export const TEST = ${JSON.stringify(testValue)};
+
+export default {
+ BUILD_TYPE,
+ GIT_HASH,
+ RELEASE_DATE,
+ NODE_ENV,
+ MYANIMELIST_CLIENT_ID,
+ ANILIST_CLIENT_ID,
+ TEST,
+};
+`;
try {
- fs.writeFileSync(envFilePath, finalContent, 'utf8');
+ fs.mkdirSync(path.dirname(buildInfoPath), { recursive: true });
+ fs.writeFileSync(buildInfoPath, buildInfoContent, 'utf8');
+ fs.writeFileSync(envFilePath, envContent, 'utf8');
- console.log(`Generated .env file for ${buildType} build\n`);
+ console.log(`Generated .env for ${buildType} build`);
console.table({
BUILD_TYPE: buildType,
- GIT_HASH: commitHash,
- RELEASE_DATE: formattedDate,
- NODE_ENV: buildType === 'Release' ? 'production' : 'development',
+ GIT_HASH: gitHash,
+ RELEASE_DATE: releaseDate,
+ NODE_ENV: nodeEnv,
});
- console.log('\n');
} catch (err) {
console.error('Error: Could not write .env file:', err.message);
process.exit(1);
diff --git a/src/screens/library/components/LibraryListView.tsx b/src/screens/library/components/LibraryListView.tsx
index 6f4d37be22..3301e93226 100644
--- a/src/screens/library/components/LibraryListView.tsx
+++ b/src/screens/library/components/LibraryListView.tsx
@@ -14,7 +14,7 @@ import ServiceManager from '@services/ServiceManager';
import { getPlugin } from '@plugins/pluginManager';
import { useSelectionContext } from '../SelectionContext';
import { ImageRequestInit } from '@plugins/types';
-import Config from 'react-native-config';
+import Config from '@env';
interface Props {
categoryId: number;
diff --git a/src/screens/more/About.tsx b/src/screens/more/About.tsx
index b872babd64..0c97eacd01 100644
--- a/src/screens/more/About.tsx
+++ b/src/screens/more/About.tsx
@@ -8,7 +8,7 @@ import { MoreHeader } from './components/MoreHeader';
import { useTheme } from '@hooks/persisted';
import { List, SafeAreaView } from '@components';
import { AboutScreenProps } from '@navigators/types';
-import Config from 'react-native-config';
+import Config from '@env';
import * as Clipboard from 'expo-clipboard';
import { version } from '../../../package.json';
diff --git a/src/services/Trackers/aniList.ts b/src/services/Trackers/aniList.ts
index 50b72d43d8..30d392a4ae 100644
--- a/src/services/Trackers/aniList.ts
+++ b/src/services/Trackers/aniList.ts
@@ -1,6 +1,6 @@
import * as Linking from 'expo-linking';
import * as WebBrowser from 'expo-web-browser';
-import Config from 'react-native-config';
+import Config from '@env';
import { AuthenticationResult, Tracker } from './index';
const apiEndpoint = 'https://graphql.anilist.co';
diff --git a/src/services/Trackers/myAnimeList.ts b/src/services/Trackers/myAnimeList.ts
index 0791db13fd..3af314f195 100644
--- a/src/services/Trackers/myAnimeList.ts
+++ b/src/services/Trackers/myAnimeList.ts
@@ -1,6 +1,6 @@
import * as Linking from 'expo-linking';
import * as WebBrowser from 'expo-web-browser';
-import Config from 'react-native-config';
+import Config from '@env';
import { Tracker, UserListStatus } from './index';
const clientId = Config.MYANIMELIST_CLIENT_ID;
diff --git a/tsconfig.json b/tsconfig.json
index 944a7e841c..62eddd3349 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -33,6 +33,7 @@
"@type/*": ["./src/type/*"],
"@specs/*": ["./specs/*"],
"@test-utils": ["./__tests-modules__/test-utils"],
+ "@env": ["./src/generated/build-info"]
},
"types": ["react-native", "jest"]
}
From 5b14a9065442370a0b750bacaa231d13a3d74fc2 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Tue, 7 Apr 2026 12:35:37 +0200
Subject: [PATCH 14/17] Update to use split apk and enable custom rock provider
paths.
---
.github/workflows/build.yml | 18 ++----------
.gitignore | 2 +-
android/app/build.gradle | 8 ++++++
rock.config.mjs | 8 ++++--
scripts/generate-env-file.cjs | 52 ++++++++++++++++++++++++++++++++---
5 files changed, 65 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 77f33b47be..ef208f2a99 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -57,23 +57,9 @@ jobs:
uses: callstackincubator/android@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REPO_OWNER: ${{ github.repository_owner }}
+ REPO_NAME: ${{ github.event.repository.name }}
with:
re-sign: true
github-token: ${{ secrets.GITHUB_TOKEN }}
variant: preRelease
-
- - name: Set Environment Variables
- run: |
- set -x
- echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> $GITHUB_ENV
- echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
-
- - 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/preRelease/app-preRelease.apk
- retention-days: 30
diff --git a/.gitignore b/.gitignore
index 0bfd2b2a0c..0682ca440f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@ npm-debug.*
*.mobileprovision
*.orig.*
web-build/
-.env
+.*env
reader_playground/index.html
# macOS
.DS_Store
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6aa7b52f98..62e242acf1 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -83,6 +83,14 @@ android {
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
namespace "com.rajarsheechatterjee.LNReader"
+ splits {
+ abi {
+ enable true
+ reset()
+ include "arm64-v8a", "armeabi-v7a", "x86_64", "x86"
+ universalApk true
+ }
+ }
defaultConfig {
applicationId 'com.rajarsheechatterjee.LNReader'
minSdkVersion rootProject.ext.minSdkVersion
diff --git a/rock.config.mjs b/rock.config.mjs
index 3591f33cae..0ef72aec5a 100644
--- a/rock.config.mjs
+++ b/rock.config.mjs
@@ -3,6 +3,10 @@ import { platformIOS } from '@rock-js/platform-ios';
import { platformAndroid } from '@rock-js/platform-android';
import { pluginMetro } from '@rock-js/plugin-metro';
import { providerGitHub } from '@rock-js/provider-github';
+import { loadEnvFile } from 'node:process';
+
+// Loads environment variables from the default .env file
+loadEnvFile();
/** @type {import('rock').Config} */
export default {
@@ -12,8 +16,8 @@ export default {
android: platformAndroid(),
},
remoteCacheProvider: providerGitHub({
- repository: 'lnreader',
- owner: 'CD-Z',
+ repository: process.env.REPO_NAME || 'lnreader',
+ owner: process.env.REPO_OWNER || 'lnreader',
//@ts-expect-error
token: process.env.GITHUB_TOKEN,
}),
diff --git a/scripts/generate-env-file.cjs b/scripts/generate-env-file.cjs
index 480594b472..e88787780a 100644
--- a/scripts/generate-env-file.cjs
+++ b/scripts/generate-env-file.cjs
@@ -56,7 +56,37 @@ function getGitHash() {
return execSync('git rev-parse --short HEAD').toString().trim();
}
+function getHiddenEnvFiles(rootDir) {
+ return fs
+ .readdirSync(rootDir, { withFileTypes: true })
+ .filter(entry => {
+ return (
+ entry.isFile() &&
+ /^\..*\.env$/.test(entry.name) &&
+ entry.name !== '.env'
+ );
+ })
+ .map(entry => path.join(rootDir, entry.name))
+ .sort();
+}
+
+function readHiddenEnvFiles(rootDir) {
+ const files = getHiddenEnvFiles(rootDir);
+
+ const content = files
+ .map(filePath => {
+ const fileName = path.basename(filePath);
+ const fileContent = fs.readFileSync(filePath, 'utf8').trimEnd();
+
+ return `# Imported from ${fileName}\n${fileContent}`;
+ })
+ .join('\n\n');
+
+ return { files, content };
+}
+
const args = parseArgs(process.argv);
+const projectRoot = path.join(__dirname, '..');
const buildType = args['build-type'] || 'Beta';
const myanimelistClientId = args['myanimelist-client-id'];
@@ -70,7 +100,7 @@ const nodeEnv =
const testValue =
args.test || 'This is a test variable to verify .env generation';
-const envContent = [
+const generatedEnvContent = [
`BUILD_TYPE=${JSON.stringify(buildType)}`,
`GIT_HASH=${JSON.stringify(gitHash)}`,
`RELEASE_DATE=${JSON.stringify(releaseDate)}`,
@@ -81,10 +111,16 @@ const envContent = [
'',
].join('\n');
-const envFilePath = path.join(__dirname, '..', '.env');
+const { files: hiddenEnvFiles, content: hiddenEnvContent } =
+ readHiddenEnvFiles(projectRoot);
+
+const envContent = hiddenEnvContent
+ ? `${generatedEnvContent}\n# Imported hidden env files\n${hiddenEnvContent}\n`
+ : generatedEnvContent;
+
+const envFilePath = path.join(projectRoot, '.env');
const buildInfoPath = path.join(
- __dirname,
- '..',
+ projectRoot,
'src',
'generated',
'build-info.ts',
@@ -116,6 +152,14 @@ try {
fs.writeFileSync(envFilePath, envContent, 'utf8');
console.log(`Generated .env for ${buildType} build`);
+
+ if (hiddenEnvFiles.length > 0) {
+ console.log(
+ `Imported ${hiddenEnvFiles.length} hidden env file(s):`,
+ hiddenEnvFiles.map(filePath => path.basename(filePath)),
+ );
+ }
+
console.table({
BUILD_TYPE: buildType,
GIT_HASH: gitHash,
From 1081579b9ee575cbce67264cdd09af992ecfee89 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Tue, 7 Apr 2026 13:21:42 +0200
Subject: [PATCH 15/17] added upload artifact
---
.github/workflows/build.yml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ef208f2a99..5242fc8a5e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -63,3 +63,19 @@ jobs:
re-sign: true
github-token: ${{ secrets.GITHUB_TOKEN }}
variant: preRelease
+
+ - name: Set Environment Variables
+ run: |
+ set -x
+ echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> $GITHUB_ENV
+ echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+
+ - 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/**/app-*.apk
+ retention-days: 30
From 74472b474d70b621c8310454d0ca741ade56c134 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Tue, 7 Apr 2026 15:58:08 +0200
Subject: [PATCH 16/17] remove split apk
---
.github/workflows/build.yml | 17 +----------------
android/app/build.gradle | 8 --------
2 files changed, 1 insertion(+), 24 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5242fc8a5e..4e3f9b11b3 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -50,6 +50,7 @@ jobs:
run: |
pnpm generate:env:release \
--build-type "Github Action" \
+ --node-env "production" \
--myanimelist-client-id "${{ vars.MYANIMELIST_CLIENT_ID }}" \
--anilist-client-id "${{ vars.ANILIST_CLIENT_ID }}"
@@ -63,19 +64,3 @@ jobs:
re-sign: true
github-token: ${{ secrets.GITHUB_TOKEN }}
variant: preRelease
-
- - name: Set Environment Variables
- run: |
- set -x
- echo "COMMIT_COUNT=$(git rev-list --count HEAD)" >> $GITHUB_ENV
- echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
-
- - 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/**/app-*.apk
- retention-days: 30
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 62e242acf1..6aa7b52f98 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -83,14 +83,6 @@ android {
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
namespace "com.rajarsheechatterjee.LNReader"
- splits {
- abi {
- enable true
- reset()
- include "arm64-v8a", "armeabi-v7a", "x86_64", "x86"
- universalApk true
- }
- }
defaultConfig {
applicationId 'com.rajarsheechatterjee.LNReader'
minSdkVersion rootProject.ext.minSdkVersion
From 0dfc884c7f2645394be5ba9eea6f21e570f6a451 Mon Sep 17 00:00:00 2001
From: CD-Z <69157453+CD-Z@users.noreply.github.com>
Date: Tue, 7 Apr 2026 16:09:58 +0200
Subject: [PATCH 17/17] remove test env
---
scripts/generate-env-file.cjs | 5 -----
src/screens/library/components/LibraryListView.tsx | 3 +--
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/scripts/generate-env-file.cjs b/scripts/generate-env-file.cjs
index e88787780a..f020cd56b9 100644
--- a/scripts/generate-env-file.cjs
+++ b/scripts/generate-env-file.cjs
@@ -97,8 +97,6 @@ const releaseDate = args['release-date'] || formatUtcDate(new Date());
const nodeEnv =
args['node-env'] ||
(buildType.toLowerCase().includes('release') ? 'production' : 'development');
-const testValue =
- args.test || 'This is a test variable to verify .env generation';
const generatedEnvContent = [
`BUILD_TYPE=${JSON.stringify(buildType)}`,
@@ -107,7 +105,6 @@ const generatedEnvContent = [
`NODE_ENV=${JSON.stringify(nodeEnv)}`,
`MYANIMELIST_CLIENT_ID=${JSON.stringify(myanimelistClientId)}`,
`ANILIST_CLIENT_ID=${JSON.stringify(anilistClientId)}`,
- `TEST=${JSON.stringify(testValue)}`,
'',
].join('\n');
@@ -133,7 +130,6 @@ export const RELEASE_DATE = ${JSON.stringify(releaseDate)};
export const NODE_ENV = ${JSON.stringify(nodeEnv)};
export const MYANIMELIST_CLIENT_ID = ${JSON.stringify(myanimelistClientId)};
export const ANILIST_CLIENT_ID = ${JSON.stringify(anilistClientId)};
-export const TEST = ${JSON.stringify(testValue)};
export default {
BUILD_TYPE,
@@ -142,7 +138,6 @@ export default {
NODE_ENV,
MYANIMELIST_CLIENT_ID,
ANILIST_CLIENT_ID,
- TEST,
};
`;
diff --git a/src/screens/library/components/LibraryListView.tsx b/src/screens/library/components/LibraryListView.tsx
index 3301e93226..51316d216e 100644
--- a/src/screens/library/components/LibraryListView.tsx
+++ b/src/screens/library/components/LibraryListView.tsx
@@ -14,7 +14,6 @@ import ServiceManager from '@services/ServiceManager';
import { getPlugin } from '@plugins/pluginManager';
import { useSelectionContext } from '../SelectionContext';
import { ImageRequestInit } from '@plugins/types';
-import Config from '@env';
interface Props {
categoryId: number;
@@ -92,7 +91,7 @@ export const LibraryView: React.FC = ({