Skip to content

Commit 95317e5

Browse files
committed
Merge branch 'main' of github.com:opendocument-app/OpenDocument.droid into add-password-protected-tests
2 parents dbb74eb + 48d7180 commit 95317e5

6 files changed

Lines changed: 289 additions & 12 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
# Optional: Only run on specific file changes
7+
# paths:
8+
# - "src/**/*.ts"
9+
# - "src/**/*.tsx"
10+
# - "src/**/*.js"
11+
# - "src/**/*.jsx"
12+
13+
jobs:
14+
claude-review:
15+
# Optional: Filter by PR author
16+
# if: |
17+
# github.event.pull_request.user.login == 'external-contributor' ||
18+
# github.event.pull_request.user.login == 'new-developer' ||
19+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20+
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
pull-requests: read
25+
issues: read
26+
id-token: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 1
33+
34+
- name: Run Claude Code Review
35+
id: claude-review
36+
uses: anthropics/claude-code-action@beta
37+
with:
38+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39+
40+
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
41+
model: "claude-opus-4-20250514"
42+
43+
# Direct prompt for automated review (no @claude mention needed)
44+
direct_prompt: |
45+
Please review this pull request and provide feedback on:
46+
- Code quality and best practices
47+
- Potential bugs or issues
48+
- Performance considerations
49+
- Security concerns
50+
- Test coverage
51+
52+
Be constructive and helpful in your feedback.
53+
54+
use_sticky_comment: true
55+
56+
# Optional: Customize review based on file types
57+
# direct_prompt: |
58+
# Review this PR focusing on:
59+
# - For TypeScript files: Type safety and proper interface usage
60+
# - For API endpoints: Security, input validation, and error handling
61+
# - For React components: Performance, accessibility, and best practices
62+
# - For tests: Coverage, edge cases, and test quality
63+
64+
# Optional: Different prompts for different authors
65+
# direct_prompt: |
66+
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
67+
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
68+
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
69+
70+
# Optional: Add specific tools for running tests or linting
71+
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
72+
73+
# Optional: Skip review for certain conditions
74+
# if: |
75+
# !contains(github.event.pull_request.title, '[skip-review]') &&
76+
# !contains(github.event.pull_request.title, '[WIP]')
77+

.github/workflows/claude.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@beta
36+
with:
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
39+
# This is an optional setting that allows Claude to read CI results on PRs
40+
additional_permissions: |
41+
actions: read
42+
43+
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
44+
model: "claude-opus-4-20250514"
45+
46+
# Optional: Customize the trigger phrase (default: @claude)
47+
# trigger_phrase: "/claude"
48+
49+
# Optional: Trigger when specific user is assigned to an issue
50+
# assignee_trigger: "claude-bot"
51+
52+
# Optional: Allow Claude to run specific commands
53+
# allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
54+
55+
# Optional: Add custom instructions for Claude to customize its behavior for your project
56+
# custom_instructions: |
57+
# Follow our coding standards
58+
# Ensure all new code has tests
59+
# Use TypeScript for new files
60+
61+
# Optional: Custom environment variables for Claude
62+
# claude_env: |
63+
# NODE_ENV: test
64+

CLAUDE.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Development Commands
6+
7+
### Building
8+
- `./gradlew assembleProDebug` - Build the Pro debug variant
9+
- `./gradlew assembleProDebugAndroidTest` - Build the Pro debug test APK
10+
- `./gradlew assembleLiteDebug` - Build the Lite debug variant
11+
- `./gradlew bundleProRelease` - Build Pro release bundle for Play Store
12+
- `./gradlew bundleLiteRelease` - Build Lite release bundle for Play Store
13+
- `./build-test.sh` - Convenience script to build Pro debug and test APKs
14+
15+
### Testing
16+
- `./gradlew connectedAndroidTest` - Run instrumented tests on connected device
17+
- `fastlane android tests` - Alternative way to run connected tests
18+
19+
### Linting
20+
- `./gradlew lint` - Run Android lint checks (configured to not abort on errors)
21+
22+
### Deployment
23+
- `fastlane android deployPro` - Deploy Pro version to Google Play internal track
24+
- `fastlane android deployLite` - Deploy Lite version to Google Play internal track
25+
26+
### Clean
27+
- `./gradlew clean` - Clean build artifacts (includes custom .cxx directory cleanup)
28+
29+
## Architecture Overview
30+
31+
### Core Components
32+
33+
**Document Processing Pipeline:**
34+
- `CoreLoader` - Primary document processor using the native C++ ODR core library
35+
- `WvwareDocLoader` - MS Word document processor using wvware library
36+
- `RawLoader` - Plain text and other raw file processor
37+
- `OnlineLoader` - Remote document fetcher
38+
- `MetadataLoader` - Document metadata extractor
39+
40+
**Service Architecture:**
41+
- `LoaderService` - Background service managing all document loading operations
42+
- `LoaderServiceQueue` - Queue management for multiple document loading requests
43+
- Document loaders implement `FileLoaderListener` interface for async communication
44+
45+
**UI Architecture:**
46+
- `MainActivity` - Main activity with service binding and menu management
47+
- `DocumentFragment` - Primary document display fragment using WebView
48+
- `PageView` - Custom WebView for document rendering
49+
- Action mode callbacks for edit, find, and TTS functionality
50+
51+
### Build System
52+
53+
**Multi-flavor Android App:**
54+
- **Lite flavor**: Free version with ads and tracking enabled
55+
- **Pro flavor**: Paid version with ads disabled and tracking disabled
56+
57+
**Native Dependencies:**
58+
- Uses Conan package manager for C++ dependencies
59+
- CMake build system for native C++ core library (`odr-core`)
60+
- NDK version 26.3.11579264 required
61+
- C++20 standard
62+
63+
**Core Library Integration:**
64+
- Native C++ wrapper (`CoreWrapper.cpp`) provides JNI interface
65+
- Supports multiple architectures: armv8, armv7, x86, x86_64
66+
- Assets deployed to `assets/core` directory via custom Conan deployer
67+
68+
### Key Directories
69+
70+
- `app/src/main/java/at/tomtasche/reader/background/` - Document processing services
71+
- `app/src/main/java/at/tomtasche/reader/ui/` - UI components and activities
72+
- `app/src/main/java/at/tomtasche/reader/nonfree/` - Analytics, billing, and ads
73+
- `app/src/main/cpp/` - Native C++ JNI wrapper
74+
- `app/src/main/assets/` - HTML templates and fonts for document rendering
75+
76+
### Dependencies
77+
78+
**Core Android:**
79+
- AndroidX libraries (AppCompat, Core, Material, WebKit)
80+
- Firebase (Analytics, Crashlytics, Storage, Auth, Remote Config)
81+
- Google Play Services (Ads, Review, User Messaging Platform)
82+
83+
**Document Processing:**
84+
- `app.opendocument:wvware-android` - MS Word document support
85+
- Custom ODR core library via Conan
86+
87+
**Testing:**
88+
- Espresso for UI testing
89+
- JUnit for unit testing
90+
- Test APKs require connected device/emulator
91+
92+
### Configuration Notes
93+
94+
- Minimum SDK: 23, Target SDK: 34
95+
- MultiDex enabled for large dependency set
96+
- R8/ProGuard enabled for release builds with resource shrinking
97+
- Configuration cache enabled for parallel Conan installs
98+
- Custom lint configuration allows non-fatal errors

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ tasks.register('conanProfile', Copy) {
3030
android {
3131
defaultConfig {
3232
applicationId "at.tomtasche.reader"
33-
minSdkVersion 23
33+
minSdkVersion 34
3434
compileSdkVersion 34
3535
targetSdkVersion 34
3636

app/conanfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[requires]
2-
odrcore/5.0.1
2+
odrcore/5.0.2
33

44
[generators]
55
CMakeToolchain

app/src/main/AndroidManifest.xml

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools"
44
android:installLocation="auto"
5-
android:versionCode="189"
6-
android:versionName="3.35"
5+
android:versionCode="192"
6+
android:versionName="3.38"
77
tools:ignore="GoogleAppIndexingWarning">
88

99
<uses-permission android:name="android.permission.INTERNET" />
@@ -218,6 +218,7 @@
218218
android:label="@string/app_title"
219219
android:targetActivity="at.tomtasche.reader.ui.activity.MainActivity"
220220
tools:ignore="AppLinkUrlError">
221+
<!-- STRICT_CATCH: Supports ODT, ODS, ODP, ODG, PDF, DOCX, DOC -->
221222
<intent-filter>
222223
<action android:name="android.intent.action.VIEW" />
223224

@@ -231,6 +232,9 @@
231232
<data android:mimeType="application/vnd.oasis.opendocument.presentation" />
232233
<data android:mimeType="application/vnd.oasis.opendocument.presentation-template" />
233234
<data android:mimeType="application/octet-stream" />
235+
<data android:mimeType="application/pdf" />
236+
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
237+
<data android:mimeType="application/msword" />
234238
</intent-filter>
235239
<intent-filter>
236240
<action android:name="android.intent.action.VIEW" />
@@ -269,10 +273,27 @@
269273
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.odg" />
270274
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.odg" />
271275
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.odg" />
272-
<data android:pathPattern=".*\\.odt" />
273-
<data android:pathPattern=".*\\.ods" />
274-
<data android:pathPattern=".*\\.odp" />
275-
<data android:pathPattern=".*\\.odg" />
276+
<data android:pathPattern=".*\\.pdf" />
277+
<data android:pathPattern=".*\\..*\\.pdf" />
278+
<data android:pathPattern=".*\\..*\\..*\\.pdf" />
279+
<data android:pathPattern=".*\\..*\\..*\\..*\\.pdf" />
280+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.pdf" />
281+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.pdf" />
282+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.pdf" />
283+
<data android:pathPattern=".*\\.docx" />
284+
<data android:pathPattern=".*\\..*\\.docx" />
285+
<data android:pathPattern=".*\\..*\\..*\\.docx" />
286+
<data android:pathPattern=".*\\..*\\..*\\..*\\.docx" />
287+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.docx" />
288+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.docx" />
289+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.docx" />
290+
<data android:pathPattern=".*\\.doc" />
291+
<data android:pathPattern=".*\\..*\\.doc" />
292+
<data android:pathPattern=".*\\..*\\..*\\.doc" />
293+
<data android:pathPattern=".*\\..*\\..*\\..*\\.doc" />
294+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.doc" />
295+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.doc" />
296+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.doc" />
276297
</intent-filter>
277298
<intent-filter>
278299
<action android:name="android.intent.action.VIEW" />
@@ -312,10 +333,27 @@
312333
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.odg" />
313334
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.odg" />
314335
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.odg" />
315-
<data android:pathPattern=".*\\.odt" />
316-
<data android:pathPattern=".*\\.ods" />
317-
<data android:pathPattern=".*\\.odp" />
318-
<data android:pathPattern=".*\\.odg" />
336+
<data android:pathPattern=".*\\.pdf" />
337+
<data android:pathPattern=".*\\..*\\.pdf" />
338+
<data android:pathPattern=".*\\..*\\..*\\.pdf" />
339+
<data android:pathPattern=".*\\..*\\..*\\..*\\.pdf" />
340+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.pdf" />
341+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.pdf" />
342+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.pdf" />
343+
<data android:pathPattern=".*\\.docx" />
344+
<data android:pathPattern=".*\\..*\\.docx" />
345+
<data android:pathPattern=".*\\..*\\..*\\.docx" />
346+
<data android:pathPattern=".*\\..*\\..*\\..*\\.docx" />
347+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.docx" />
348+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.docx" />
349+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.docx" />
350+
<data android:pathPattern=".*\\.doc" />
351+
<data android:pathPattern=".*\\..*\\.doc" />
352+
<data android:pathPattern=".*\\..*\\..*\\.doc" />
353+
<data android:pathPattern=".*\\..*\\..*\\..*\\.doc" />
354+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.doc" />
355+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.doc" />
356+
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.doc" />
319357
</intent-filter>
320358
</activity-alias>
321359

0 commit comments

Comments
 (0)