- TypeScript 91%
- HTML 6.8%
- JavaScript 1.3%
- Kotlin 0.4%
- Ruby 0.2%
- Other 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| .husky | ||
| .vscode | ||
| __mocks__ | ||
| android | ||
| app | ||
| assets | ||
| docs | ||
| fdroid/metadata | ||
| ios | ||
| LICENSES | ||
| scripts | ||
| src | ||
| .gitignore | ||
| .prettierignore | ||
| ADDITIONAL-PERMISSIONS.md | ||
| AGENTS.md | ||
| app.json | ||
| AUTHORS | ||
| babel.config.js | ||
| CHANGELOG.md | ||
| commitlint.config.ts | ||
| CONTRIBUTING.md | ||
| declarations.d.ts | ||
| eas.json | ||
| eslint.config.mts | ||
| fsd-high-level-dependencies.html | ||
| jest.config.ts | ||
| knip.config.ts | ||
| LICENSE | ||
| lint-staged.config.js | ||
| openAPI.yaml | ||
| orval.config.ts | ||
| package.json | ||
| prettier.config.cjs | ||
| README.md | ||
| REUSE.toml | ||
| SECURITY.md | ||
| slovo-istiny-mobile.code-workspace | ||
| steiger.config.ts | ||
| THIRD-PARTY-LICENSES-DISCLAIMER.md | ||
| THIRD-PARTY-LICENSES.md | ||
| tsconfig.json | ||
| yarn.lock | ||
React Native app for church based on Feature Sliced Design
🍰 Architecture design guidelines
Technology stack
- UI:
react,react-native,expo - Navigation:
expo-router(file-based routing) - State Management:
@reatom/core,@reatom/framework,@reatom/npm-react - Audio:
expo-audio - HTTP:
axios - Storage:
@react-native-async-storage/async-storage - Validation:
zod - Pattern Matching:
ts-pattern - UI Components:
@gorhom/bottom-sheet - Animations:
react-native-reanimated - Gestures:
react-native-gesture-handler - Tab View:
react-native-tab-view - Notifications:
expo-notifications - Book Parsing:
xml-js(FB2 format) - Lang:
typescript - Lint:
prettier,eslint - Architecture:
feature-sliced
License
This project is Free/Libre Open Source Software, licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later).
Distribution via the Apple App Store and Google Play Store is permitted under the App Store Additional Permission — a Section 7 exception that allows GPL-3.0 to coexist with store terms of service.
- Source code: https://git.lightnode.ru/Slovo_Propovedi/slovo-propovedi-mobile
- Bug reports & contact: https://git.lightnode.ru/Slovo_Propovedi/slovo-propovedi-mobile/issues
- License text: LICENSE
- Third-party licenses: THIRD-PARTY-LICENSES.md
- Authors: AUTHORS
All project dependencies (1,710 transitive packages per yarn.lock audit, including development dependencies) are GPL-3.0-compatible. Production-only enumeration: 864 packages — see THIRD-PARTY-LICENSES.md. No proprietary code is included in the distributed binary.
Getting Started
Installation
yarn install
Running the App
yarn start
This will start the Expo development server. You can then scan the QR code with the Expo Go app on your mobile device or press a to run on Android emulator / i to run on iOS simulator.
Available Scripts
Development
yarn start— Start Expo dev serveryarn start -- --clear— Start with cleared cacheyarn run:android— Run on Android device/emulatoryarn run:ios— Run on iOS device/simulator
Linting & Type Checking
yarn lint— Run ESLintyarn lint:fix— Run ESLint with auto-fixyarn check:types— TypeScript type checkingyarn check:fsd— FSD architecture linting (steiger)yarn check:fsd-watch— FSD linting in watch modeyarn check:unused— Check for unused code (knip)
Testing
yarn test— Jest in watch mode, changed files only (vs main)yarn testFinal— Run all tests onceyarn testDebug— Run tests for locally changed files onlyyarn updateSnapshots— Update test snapshots
Formatting
yarn prettier:write— Format all files with Prettier
API Generation
yarn api:generate— Generate API client from OpenAPI spec (orval)
Building & Deployment (EAS)
yarn build:android— Build Android with EASyarn build:ios— Build iOS with EASyarn build:all— Build all platformsyarn build:list— List EAS buildsyarn build-local-debug:android— Build Android debug locallyyarn build-local-release:android— Build Android release locallyyarn update-app— Disabled. OTA updates are off; see docs/OTA-STRATEGY.md for the decision and re-enablement path.
Additional Commands
yarn build-preview:android— Build Android with preview profileyarn build-preview:ios— Build iOS with preview profileyarn build-preview:all— Build all platforms with preview profileyarn emulator-run-builds— Run EAS builds on emulatoryarn visualize-deps— Visualize FSD dependenciesyarn prepare— Set up git hooks (husky)
Project Architecture
This project follows Feature-Sliced Design (FSD) architecture with Expo Router for navigation.
FSD Layers (top to bottom)
app/ # Expo Router entry points and layouts only
src/
├── pages/ # Screen components with UI
├── widgets/ # Composed UI blocks (sliders, cards)
├── features/ # User interactions and business logic
├── entities/ # Domain models and business entities
└── shared/ # Reusable utilities, UI components, and types
Expo Router Structure
app/
├── _layout.tsx # Root layout
├── _RootLayout.tsx # Root layout component
├── index.tsx # Redirect entry
├── about.tsx # About screen
├── settings.tsx # Settings screen
└── (tabs)/ # Tab navigation group
├── _layout.tsx # Tab bar layout
├── listen/ # Listen tab with nested screens
│ ├── _layout.tsx
│ ├── index.tsx
│ ├── playlist.tsx
│ └── playlist-list.tsx
├── read.tsx # Read tab (single screen)
├── study.tsx # Study tab
└── more.tsx # More tab
Important: Screen logic lives in src/pages/, app/ only re-exports.
FSD Slice Structure
src/entities/player/
├── index.ts # Public API exports
├── model.ts # State, atoms, types
├── lib/ # Hooks and utilities
│ ├── index.ts
│ ├── usePlayer.ts
│ └── PlayerService/ # Platform-specific implementations
└── ui/ # Components
├── PlayerControls.tsx
└── PlayerControls.test.tsx
Key Technologies
State Management: Reatom
The project uses Reatom for state management, providing a reactive and atomic approach to state management.
Usage Example:
// model.ts
import { atom, action } from '@reatom/framework'
export const currentAudioAtom = atom<AudioPlayerData | null>(null, 'currentAudioAtom')
export const setCurrentAudio = action(async (ctx, audio: AudioPlayerData) => {
await ctx.schedule(() => {
currentAudioAtom(ctx, audio)
})
return audio
}, 'setCurrentAudio')
// Component
import { useAtom, useAction } from '@reatom/npm-react'
const currentAudio = useAtom(currentAudioAtom)[0]
const setCurrentAudio = useAction(setCurrentAudio)
Navigation: expo-router
File-based routing powered by Expo Router, with support for:
- Nested navigation
- Tab navigation
- Link-based navigation
- URL parameters
Audio: expo-audio
Cross-platform audio playback for sermons and audio content.
Book Parsing: xml-js
FB2 format book parsing for the reading section.
HTTP: axios
Modern HTTP client for API requests with interceptors and automatic token refresh.
Code Quality
Linting & Formatting
-
ESLint: Comprehensive linting with rules for:
- React and React Hooks
- TypeScript
- Import ordering (perfectionist)
- Code style and best practices
-
Prettier: Consistent code formatting with project-specific configurations
-
TypeScript: Strict type checking enabled
-
FSD Linting: Enforces Feature-Sliced Design architecture rules using
steiger
Testing
- Jest with
jest-expopreset for React Native/Expo testing - @testing-library/react-native for component testing
- Test files placed alongside components (
ComponentName.test.tsx) - Snapshot testing support
Pre-commit Hooks
The project uses husky + lint-staged + commitlint to ensure code quality before commits.
What runs on commit (pre-commit):
yarn lint:staged && yarn check:types
This runs ESLint fix + Prettier on staged files, then TypeScript type checking.
What runs on commit (commit-msg):
yarn commitlint
This validates that commit messages follow the Conventional Commits format.
Package Manager
This project uses yarn as the package manager. Always use yarn instead of npm for all operations:
- Install dependencies:
yarnoryarn install - Add packages:
yarn add <package> - Add dev packages:
yarn add -D <package> - Run scripts:
yarn <script> - Run CLI tools:
yarn <tool>(e.g.,yarn jest)
Commit Convention
The project follows Conventional Commits with these types:
feat— New featurefix— Bug fixrefactor— Code change without feature/fixtest— Adding/modifying testsdocs— Documentation onlystyle— Formatting onlychore— Maintenance tasksbuild— Build system changesci— CI configuration changesperf— Performance improvementsrevert— Reverting changes
Max header length: 100 characters
Setup Development Environment
To set up the development environment:
# Install dependencies
yarn install
# Set up git hooks
yarn prepare
# Start the dev server
yarn start
Testing
To run tests:
# Run tests in watch mode
yarn test
# Run all tests once
yarn testFinal
# Update snapshots
yarn updateSnapshots
To run a single test file:
yarn jest path/to/file.test.tsx
Building
Local Builds (Recommended)
The app can be built entirely locally without proprietary cloud services. See docs/BUILD-LOCAL.md for detailed instructions.
Quick reference:
- Android release:
yarn build-local-release:android→ outputs APK atandroid/app/build/outputs/apk/release/app-release.apk - Android debug:
yarn build-local-debug:android - iOS release:
yarn run:ios -- --configuration Release
Note: Default local builds are signed with the debug keystore. For production signing, follow the steps in docs/BUILD-LOCAL.md.
EAS Cloud Build (Optional Alternative)
Expo Application Services (EAS) Build is also supported as an optional convenience. Note: EAS Build is a proprietary cloud service and is not part of the FLOSS distribution.
yarn build:android/yarn build:ios/yarn build:allyarn build-preview:android/yarn build-preview:ios
OTA updates are disabled — see docs/OTA-STRATEGY.md.
OTA Updates
OTA updates are currently disabled. Users receive updates through the Apple App Store and Google Play Store only.
This is an intentional decision to decouple the app from proprietary EAS (Expo Application Services) cloud infrastructure, in keeping with the project's FLOSS (Free/Libre Open Source Software) commitments under GPL-3.0-or-later.
For the full rationale, current state, and future re-enablement path (including self-hosted OTA server options), see docs/OTA-STRATEGY.md.