Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 71 additions & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ name: Build and Release APKs
on:
release:
types: [created]
workflow_dispatch:
inputs:
version:
description: 'Version to build (e.g., 1.0.11, leave empty to use pubspec.yaml)'
required: false
default: ''
skip_tests:
description: 'Skip running tests'
required: false
default: false
type: boolean

jobs:
build-and-release:
Expand Down Expand Up @@ -62,33 +73,67 @@ jobs:
echo "Analysis completed successfully!"

- name: Run tests
if: ${{ !inputs.skip_tests }}
run: |
echo "Running Flutter tests..."
flutter test
echo "Tests completed successfully!"

- name: Update pubspec version
run: |
# Extract version from tag (e.g., v1.2.3 -> 1.2.3, also handles 1.2.3)
TAG_VERSION=$(echo "$GITHUB_REF_NAME" | sed 's/^v//')
# For workflow_dispatch, use input version or keep current
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
INPUT_VERSION="${{ inputs.version }}"
if [[ -n "$INPUT_VERSION" ]]; then
# Use the provided version
TAG_VERSION="$INPUT_VERSION"

# Fix: If version is format 1.2, append .0 to make it 1.2.0
if [[ "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
TAG_VERSION="${TAG_VERSION}.0"
echo "Formatted version to semantic version: $TAG_VERSION"
fi

# Validate version format
if [[ ! "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid version format: $TAG_VERSION"
echo "Expected semantic version format (e.g., 1.2.3)"
exit 1
fi

# Use run_number as build number
BUILD_NUMBER=${{ github.run_number }}
# Update version in pubspec.yaml
sed -i "s/^version: .*/version: ${TAG_VERSION}+${BUILD_NUMBER}/" pubspec.yaml
echo "Updated version to: $TAG_VERSION+$BUILD_NUMBER"
else
echo "No version specified, using current version from pubspec.yaml"
CURRENT_VERSION=$(grep "^version:" pubspec.yaml | sed 's/^version: //')
echo "Current version: $CURRENT_VERSION"
fi
else
# For release events, extract version from tag
# Extract version from tag (e.g., v1.2.3 -> 1.2.3, also handles 1.2.3)
TAG_VERSION=$(echo "$GITHUB_REF_NAME" | sed 's/^v//')

# Fix: If version is format 1.2, append .0 to make it 1.2.0
if [[ "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
TAG_VERSION="${TAG_VERSION}.0"
echo "Formatted version to semantic version: $TAG_VERSION"
fi
# Fix: If version is format 1.2, append .0 to make it 1.2.0
if [[ "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
TAG_VERSION="${TAG_VERSION}.0"
echo "Formatted version to semantic version: $TAG_VERSION"
fi

# Validate version format
if [[ ! "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid version format: $TAG_VERSION"
echo "Expected semantic version format (e.g., 1.2.3)"
exit 1
# Validate version format
if [[ ! "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid version format: $TAG_VERSION"
echo "Expected semantic version format (e.g., 1.2.3)"
exit 1
fi
# Use run_number as build number
BUILD_NUMBER=${{ github.run_number }}
# Update version in pubspec.yaml
sed -i "s/^version: .*/version: ${TAG_VERSION}+${BUILD_NUMBER}/" pubspec.yaml
echo "Updated version to: $TAG_VERSION+$BUILD_NUMBER"
fi
# Use run_number as build number
BUILD_NUMBER=${{ github.run_number }}
# Update version in pubspec.yaml
sed -i "s/^version: .*/version: ${TAG_VERSION}+${BUILD_NUMBER}/" pubspec.yaml
echo "Updated version to: $TAG_VERSION+$BUILD_NUMBER"
grep "^version:" pubspec.yaml

- name: Build all APKs
Expand All @@ -104,8 +149,17 @@ jobs:
mv build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk release-artifacts/openlib-extended-armeabi-v7a-release.apk

- name: Upload Release Assets
if: github.event_name == 'release'
uses: softprops/action-gh-release@v1
with:
files: release-artifacts/*.apk
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Build Artifacts
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: apk-builds
path: release-artifacts/*.apk
retention-days: 7
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ To manually retry a failed build in GitHub Actions:

Alternatively, you can trigger a new release build by creating a new release tag.

### Manual Build (Without Release)

You can manually trigger a build without creating a release to test your changes:

1. Go to the [Actions tab](https://github.com/warreth/OpenlibExtended/actions) in the repository
2. Click on "Build and Release APKs" workflow on the left sidebar
3. Click "Run workflow" button (top right)
4. Optionally:
- Enter a version number (e.g., 1.0.12) or leave empty to use current version from pubspec.yaml
- Check "Skip running tests" if you want to skip tests
5. Click the green "Run workflow" button
6. Wait for the build to complete
7. Download the APK artifacts from the workflow run page

### Android

Make sure that `android/local.properties` has `flutter.minSdkVersion=21` or above
Expand Down
32 changes: 20 additions & 12 deletions lib/ui/epub_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class EpubViewer extends ConsumerStatefulWidget {
class _EpubViewerState extends ConsumerState<EpubViewer> {
late EpubController _epubReaderController;
String? epubConf;
final Set<int> _activePointers = {};

@override
void initState() {
Expand Down Expand Up @@ -218,22 +219,29 @@ class _EpubViewerState extends ConsumerState<EpubViewer> {
children: [
child,
Positioned.fill(
child: GestureDetector(
child: Listener(
behavior: HitTestBehavior.translucent,
onTapUp: (details) {
final screenWidth = MediaQuery.of(context).size.width;
final tapPosition = details.globalPosition.dx;
onPointerDown: (event) => _activePointers.add(event.pointer),
onPointerUp: (event) {
_activePointers.remove(event.pointer);

// Divide screen into three zones: left (30%), center (40%), right (30%)
if (tapPosition < screenWidth * 0.3) {
// Left zone - previous chapter
_navigateToPreviousChapter();
} else if (tapPosition > screenWidth * 0.7) {
// Right zone - next chapter
_navigateToNextChapter();
// Only handle navigation on single-finger taps
if (_activePointers.isEmpty) {
final screenWidth = MediaQuery.of(context).size.width;
final tapPosition = event.position.dx;

// Divide screen into three zones: left (30%), center (40%), right (30%)
if (tapPosition < screenWidth * 0.3) {
// Left zone - previous chapter
_navigateToPreviousChapter();
} else if (tapPosition > screenWidth * 0.7) {
// Right zone - next chapter
_navigateToNextChapter();
}
// Center zone (30-70%) - no action, allows text selection
}
// Center zone (30-70%) - no action, allows text selection
},
onPointerCancel: (event) => _activePointers.remove(event.pointer),
child: Container(color: Colors.transparent),
),
),
Expand Down
33 changes: 20 additions & 13 deletions lib/ui/pdf_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class PdfViewer extends ConsumerStatefulWidget {

class _PdfViewerState extends ConsumerState<PdfViewer> {
late PDFViewController controller;
final Set<int> _activePointers = {};

@override
void initState() {
Expand Down Expand Up @@ -262,23 +263,29 @@ class _PdfViewerState extends ConsumerState<PdfViewer> {
children: [
child,
Positioned.fill(
child: GestureDetector(
child: Listener(
behavior: HitTestBehavior.translucent,
onTapUp: (details) {
final screenWidth = MediaQuery.of(context).size.width;
final tapPosition = details.globalPosition.dx;
onPointerDown: (event) => _activePointers.add(event.pointer),
onPointerUp: (event) {
_activePointers.remove(event.pointer);

// Divide screen into three zones: left (30%), center (40%), right (30%)
if (tapPosition < screenWidth * 0.3) {
// Left zone - previous page
_goToPreviousPage();
} else if (tapPosition > screenWidth * 0.7) {
// Right zone - next page
_goToNextPage();
// Only handle navigation on single-finger taps
if (_activePointers.isEmpty) {
final screenWidth = MediaQuery.of(context).size.width;
final tapPosition = event.position.dx;

// Divide screen into three zones: left (30%), center (40%), right (30%)
if (tapPosition < screenWidth * 0.3) {
// Left zone - previous page
_goToPreviousPage();
} else if (tapPosition > screenWidth * 0.7) {
// Right zone - next page
_goToNextPage();
}
// Center zone (30-70%) - no action, allows zooming and other interactions
}
// Center zone (30-70%) - no action, allows zooming and other interactions
},
// This child is transparent to allow underlying PDF gestures (like zoom) to work
onPointerCancel: (event) => _activePointers.remove(event.pointer),
child: Container(color: Colors.transparent),
),
),
Expand Down