chore(to-monorepo): import as-app repo into app

git-subtree-dir: app
git-subtree-mainline: b28b08a80b
git-subtree-split: a6c3dc2641
This commit is contained in:
devthejo 2026-03-09 08:54:57 +01:00
commit 3e56818c1d
912 changed files with 89035 additions and 0 deletions

80
app/.aidigestignore Normal file
View file

@ -0,0 +1,80 @@
# Ignore everything by default
*
# First include the source directory
!src/
!src/**/
!src/**/*.js
!src/**/*.jsx
!src/**/*.ts
!src/**/*.tsx
# Then exclude specific patterns and directories
# Build and dependencies
node_modules/
build/
dist/
coverage/
# Platform specific
ios/
android/
# Configuration files
*.json
*.lock
*.yml
*.yaml
*.env*
*.config.*
.*rc*
Dockerfile*
# Documentation
*.md
*.txt
docs/
# Tests and stories
**/__tests__/
**/*.test.*
**/*.spec.*
**/*.stories.*
e2e/
# Generated and utility files
*.d.ts
*.map
*.log
# Assets and styles
src/assets/
**/*.css
**/*.scss
**/*.style.*
**/*.styles.*
*.svg
*.png
*.jpg
*.ttf
# Common utility/boilerplate directories
src/i18n/
src/theme/
src/utils/
src/lib/
src/components/
src/navigation/
src/hooks/
src/hoc/
# Auto-generated or index files
**/index.js
**/index.ts
**/constants.js
**/constants.ts
**/types.ts
# Deprecated files
*.bak
*.old

57
app/.detoxrc.js Normal file
View file

@ -0,0 +1,57 @@
/** @type {Detox.DetoxConfig} */
module.exports = {
testRunner: {
args: {
'$0': 'jest',
config: 'e2e/jest.config.js'
},
jest: {
setupTimeout: 120000
}
},
apps: {
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
build: 'cd android && ENVFILE=../.env.staging ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
reversePorts: [
8081
]
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
build: 'cd android && ENVFILE=../.env.staging ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release'
},
},
devices: {
simulator: {
type: 'ios.simulator',
device: {
type: 'iPhone 15',
},
},
attached: {
type: 'android.attached',
device: {
adbName: '.*', // any attached device
},
},
emulator: {
type: 'android.emulator',
device: {
avdName: process.env.ANDROID_EMULATOR_NAME || 'Medium_Phone_API_36.0'
}
}
},
configurations: {
'android.emu.debug': {
device: 'emulator',
app: 'android.debug'
},
'android.emu.release': {
device: 'emulator',
app: 'android.release'
}
}
};

66
app/.dockerignore Normal file
View file

@ -0,0 +1,66 @@
.git/
# OSX
#
**/.DS_Store
# Xcode
#
**/build/
**/*.pbxuser
!**/default.pbxuser
**/*.mode1v3
!**/default.mode1v3
**/*.mode2v3
!**/default.mode2v3
**/*.perspectivev3
!**/default.perspectivev3
**/xcuserdata
**/*.xccheckout
**/*.moved-aside
**/DerivedData
**/*.hmap
**/*.ipa
**/*.xcuserstate
**/project.xcworkspace
# Android/IntelliJ
#
**/build/
**/.idea
**/.gradle
**/local.properties
**/*.iml
**/*.hprof
**/.cxx/
**/*.keystore
!**/debug.keystore
# node.js
#
**/node_modules/
**/npm-debug.log
**/yarn-error.log
# Bundle artifacts
**/*.jsbundle
# CocoaPods
ios/Pods/
# Temporary files created by Metro to check the health of the file watcher
**/.metro-health-check*
# Expo
**/.expo/
**/web-build/
**/dist/
# Yarn berry
**/.pnp.*
**/.yarn/*
!**/.yarn/patches
!**/.yarn/plugins
!**/.yarn/releases
!**/.yarn/sdks
!**/.yarn/versions
# !.yarn/cache

20
app/.env.default Normal file
View file

@ -0,0 +1,20 @@
# Sentry configuration
SENTRY_URL=https://sentry.io
SENTRY_DSN=your_sentry_dsn_here
SENTRY_ORG=your_sentry_org_here
SENTRY_PROJECT=alertesecours-application
SENTRY_DISABLE_AUTO_UPLOAD=true
LOCAL_DEV=true
# Android Emulator Configuration
ANDROID_EMULATOR_NAME=Pixel_6_API_30
ASC_API_KEY_ID=
ASC_API_ISSUER_ID=
ASC_API_KEY_PATH=
PROVIDER_ID=
# Background Geolocation License Keys
BACKGROUND_GEOLOCATION_LICENSE_ANDROID=your_license_key_here
BACKGROUND_GEOLOCATION_LICENSE_IOS=your_license_key_here

33
app/.env.prod.example Normal file
View file

@ -0,0 +1,33 @@
APP_OA_FILES_URL=https://files.alertesecours.fr/api/v1/oas
APP_MINIO_URL=https://minio.alertesecours.fr
APP_GRAPHQL_URL=https://hasura.alertesecours.fr/v1/graphql
APP_GRAPHQL_WS_URL=wss://hasura.alertesecours.fr/v1/graphql
APP_GEOLOC_SYNC_URL=https://api.alertesecours.fr/api/v1/oas/geoloc/sync
STAGING_APP_OA_FILES_URL=https://files-staging.alertesecours.fr/api/v1/oas
STAGING_APP_MINIO_URL=https://minio-staging.alertesecours.fr
STAGING_APP_GRAPHQL_URL=https://hasura-staging.alertesecours.fr/v1/graphql
STAGING_APP_GRAPHQL_WS_URL=wss://hasura-staging.alertesecours.fr/v1/graphql
STAGING_APP_GEOLOC_SYNC_URL=https://api-staging.alertesecours.fr/api/v1/oas/geoloc/sync
APP_OSRM_CAR_URL=https://osrm-car.alertesecours.fr
APP_OSRM_FOOT_URL=https://osrm-foot.alertesecours.fr
APP_OSRM_BICYCLE_URL=https://osrm-bicycle.alertesecours.fr
APP_MAPVIEW_STYLE_URL=https://tiles.alertesecours.fr/styles/basic-preview/style.json
APP_MAPVIEW_DARK_STYLE_URL=https://tiles.alertesecours.fr/styles/dark-matter/style.json
CLAIMS_NAMESPACE=https://alertesecours.fr/claims
LOCAL_DEV=false
SENTRY_DISABLE_AUTO_UPLOAD=false
# Sentry configuration
SENTRY_URL=https://sentry.io
SENTRY_DSN=your_sentry_dsn_here
SENTRY_ORG=your_sentry_org_here
SENTRY_PROJECT=alertesecours-application
# App Store Connect API credentials
ASC_API_KEY_ID=your_asc_api_key_id_here
ASC_API_ISSUER_ID=your_asc_api_issuer_id_here
ASC_API_KEY_PATH=/path/to/your/private/key.p8
PROVIDER_ID=your_provider_id_here

26
app/.env.staging.example Normal file
View file

@ -0,0 +1,26 @@
APP_OA_FILES_URL=https://files-staging.alertesecours.fr/api/v1/oas
APP_MINIO_URL=https://minio-staging.alertesecours.fr
APP_GRAPHQL_URL=https://hasura-staging.alertesecours.fr/v1/graphql
APP_GRAPHQL_WS_URL=wss://hasura-staging.alertesecours.fr/v1/graphql
APP_GEOLOC_SYNC_URL=https://api-staging.alertesecours.fr/api/v1/oas/geoloc/sync
APP_OSRM_CAR_URL=https://osrm-car.alertesecours.fr
APP_OSRM_FOOT_URL=https://osrm-foot.alertesecours.fr
APP_OSRM_BICYCLE_URL=https://osrm-bicycle.alertesecours.fr
APP_MAPVIEW_STYLE_URL=https://tiles.alertesecours.fr/styles/basic-preview/style.json
APP_MAPVIEW_DARK_STYLE_URL=https://tiles.alertesecours.fr/styles/dark-matter/style.json
CLAIMS_NAMESPACE=https://alertesecours.fr/claims
# Sentry configuration
SENTRY_URL=https://sentry.io
SENTRY_DSN=your_sentry_dsn_here
SENTRY_ORG=your_sentry_org_here
SENTRY_PROJECT=alertesecours-application
SENTRY_DISABLE_AUTO_UPLOAD=false
LOCAL_DEV=false
# App Store Connect API credentials
ASC_API_KEY_ID=your_asc_api_key_id_here
ASC_API_ISSUER_ID=your_asc_api_issuer_id_here
ASC_API_KEY_PATH=/path/to/your/private/key.p8
PROVIDER_ID=your_provider_id_here

15
app/.envrc Normal file
View file

@ -0,0 +1,15 @@
export PATH=$PWD/bin:$PWD/scripts:$PATH
export PROJECT_WORKINGDIR=$PWD
# appli
export JAVA_HOME=${JAVA_HOME:-"/opt/android-studio/jbr"}
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export NODE_OPTIONS"=--openssl-legacy-provider"
# dotenv
dotenv_if_exists .env.default
dotenv_if_exists .env.local

157
app/.eslintrc.js Normal file
View file

@ -0,0 +1,157 @@
const path = require("path");
module.exports = {
root: true,
env: {
"react-native/react-native": true,
jest: true,
},
extends: [
"plugin:prettier/recommended",
"plugin:import/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended",
],
parser: "@babel/eslint-parser",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2021,
sourceType: "module",
babelOptions: {
configFile: path.resolve(__dirname, "babel.config.js"),
},
},
plugins: [
"babel",
"sort-keys-fix",
"react",
"react-native",
"react-native-a11y",
"unused-imports",
"autoimport-declarative",
],
settings: {
react: {
version: "detect",
},
"import/ignore": ["react-native"],
"import/resolver": {
// Ensure ESLint can resolve regular JS packages under Yarn PnP as well.
// Without this, some deps (ex: expo-sqlite) may be incorrectly flagged
// by import/no-unresolved even though they're present.
node: {
extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
},
typescript: {},
},
},
ignorePatterns: ["build", "node_modules", "e2e", "**/*.bak.js"],
rules: {
"no-undef": [2],
"react/forbid-prop-types": [0],
"react/jsx-uses-react": 1,
"react/jsx-uses-vars": 1,
"react-hooks/exhaustive-deps": "error",
"jsx-a11y/no-autofocus": 0,
// React-Native accessibility: start as warnings to enable gradual adoption
// without breaking the build; we will tighten to errors as we fix surfaces.
"react-native-a11y/has-accessibility-hint": "error",
"react-native-a11y/has-valid-accessibility-descriptors": "error",
"import/no-named-as-default": 0,
"import/no-named-as-default-member": 0,
// 'unused-imports/no-unused-imports-ts': 1, # enable and run yarn lint --fix to autoremove all unused imports
"autoimport-declarative/autoimport": [
1,
{
packages: {
react: [
"useState",
"useEffect",
"useContext",
"useReducer",
"useCallback",
"useMemo",
"useRef",
"useImperativeHandle",
"useLayoutEffect",
"useDebugValue",
"createRef",
"forwardRef",
{
name: "React",
isDefault: true,
},
],
"react-native": [
"useWindowDimensions",
"View",
"TouchableOpacity",
"TouchableHighlight",
"Image",
"StyleSheet",
],
"@react-navigation/native": [
"useNavigation",
"useFocusEffect",
"useIsFocused",
],
"@maplibre/maplibre-react-native": [
{
name: "Maplibre",
isDefault: true,
},
],
"@expo/vector-icons": [
"MaterialCommunityIcons",
"MaterialIcons",
"Entypo",
"FeatherMaterialIcons",
],
"react-native-paper": ["ToggleButton", "Button", "FAB"],
"@apollo/client": ["useQuery", "useMutation", "useLazyQuery"],
"react-hook-form": [
"FormProvider",
"Controller",
"useForm",
"useFormContext",
"useFieldArray",
"useField",
],
moment: [
{
name: "moment",
isDefault: true,
},
],
"hooks/useStreamQueryWithSubscription": [
{
name: "useStreamQueryWithSubscription",
isDefault: true,
},
],
"~/theme": ["useTheme", "createStyles"],
"~/lib/toast-notifications": ["useToast"],
"~/lib/geo/humanizeDistance": [
{
name: "humanizeDistance",
isDefault: true,
},
],
"~/components/Text": [
{
name: "Text",
isDefault: true,
},
],
},
},
],
},
globals: {
AbortController: true,
},
};

View file

@ -0,0 +1,95 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
on:
workflow_dispatch:
# push:
# tags:
# - "**"
# branches:
# - main
concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.event.ref }}
jobs:
build-apk:
env:
RUNNER_TOOL_CACHE: /toolcache # see https://about.gitea.com/resources/tutorials/enable-gitea-actions-cache-to-accelerate-cicd and https://gitea.com/gitea/act_runner/issues/70
GRADLE_USER_HOME: ${{ github.workspace }}/.gradle
runs-on: ubuntu-latest
container:
image: devthefuture/act-runner@sha256:49abd1415cb4230866e995154733ad43f6f4c7513268dd25e412c7206d2b9e0e
steps:
- name: ⏬ Checkout code repository
uses: actions/checkout@v4.1.7
- name: ⬢ Setup node version
uses: actions/setup-node@v4
with:
node-version-file: ".node-version"
- name: 🔽 Yarn install
uses: https://git.devthefuture.org/devthefuture/actions/yarn-install@v0.5.0
- name: ⛾ Gradle cache
uses: actions/cache@v3
with:
path: |
${{ github.workspace }}/.gradle/caches
${{ github.workspace }}/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: 📌 Set metadata output
id: vars
shell: bash
run: |
if [ -n "$GITHUB_HEAD_REF" ]; then
tag=$GITHUB_HEAD_REF
else
tag=$GITHUB_REF
fi
tag=${tag#refs/heads/}
tag=${tag#refs/tags/}
echo "tag=$tag" >> $GITHUB_OUTPUT
- name: ⚙ Setup build env vars
shell: bash
run: |
cat $GITHUB_WORKSPACE/.env.default >> $GITHUB_ENV
cat $GITHUB_WORKSPACE/.env.prod >> $GITHUB_ENV
echo "BUILD_TIME=$(date +%s000)" >> $GITHUB_ENV
- name: 📦 Build APK
# uses: docker://reactnativecommunity/react-native-android:v12.0 # more recent
# uses: docker://reactnativecommunity/react-native-android:9 # actually working
uses: docker://ghcr.io/devthefuture-org/docker-android:9 # use mirror to workaround docker rate limit
# mirror using https://github.com/containers/skopeo :
# skopeo copy docker://reactnativecommunity/react-native-android:9 docker://ghcr.io/devthefuture-org/docker-android:9
with:
entrypoint: /bin/sh
args: |
-c "\
yarn expo prebuild --no-install; \
cd android && ./gradlew assembleRelease --no-daemon && cd ..; \
mv android/app/build/outputs/apk/release/app-release.apk alertesecours-${{ steps.vars.outputs.tag }}.apk; \
"
- name: 🎁 Publish release on repo
uses: https://codeberg.org/devthefuture/release-action@main
if: startsWith(github.ref, 'refs/tags/')
with:
title: ${{ steps.vars.outputs.tag }}
files: |-
alertesecours-${{ steps.vars.outputs.tag }}.apk
api_key: "${{secrets.M8A_ORG_BOT_REPO_TOKEN}}"
- name: 🎀 Publish release on minio-release
uses: https://git.devthefuture.org/devthefuture/actions/minio-upload@v0.5.0
with:
url: https://minio-releases.alertesecours.fr
local-path: alertesecours-${{ steps.vars.outputs.tag }}.apk
access-key: "${{secrets.MINO_RELEASE_ACCESS_KEY}}"
secret-key: "${{secrets.MINO_RELEASE_SECRET_KEY}}"
remote-path: "android/alertesecours-${{ steps.vars.outputs.tag }}.apk android/alertesecours.apk"

5
app/.gitattributes vendored Normal file
View file

@ -0,0 +1,5 @@
ios/AlerteSecours.xcodeproj/project.pbxproj merge=union
ios/**/*.pbxproj merge=union
# Treat these files as binary to prevent Git from trying to merge them
*.pbxproj binary merge=union

3
app/.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,3 @@
liberapay: alerte-secours
github: alerte-secours
buy_me_a_coffee: alertesecours

117
app/.github/workflows/ci-cd-ios.yaml vendored Normal file
View file

@ -0,0 +1,117 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
on:
workflow_dispatch:
# push:
# tags:
# - "**"
# branches:
# - main
concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.event.ref }}
jobs:
build-ios:
env:
GRADLE_USER_HOME: ${{ github.workspace }}/.gradle
# SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
runs-on: macos-latest
steps:
- name: ⏬ Checkout code repository
uses: actions/checkout@v4
- name: ⬢ Setup node version
uses: actions/setup-node@v4
with:
node-version-file: ".node-version"
- name: 🔽 Yarn install
# uses: https://git.devthefuture.org/devthefuture/actions/yarn-install@v0.4.0
uses: devthefuture-org/actions/yarn-install@v0.4.0
- name: ✅ Lint (including a11y rules)
run: yarn lint
- name: ⛾ Gradle cache
uses: actions/cache@v3
with:
path: |
${{ github.workspace }}/.gradle/caches
${{ github.workspace }}/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: 📌 Set metadata output
id: vars
shell: bash
run: |
if [ -n "$GITHUB_HEAD_REF" ]; then
tag=$GITHUB_HEAD_REF
else
tag=${GITHUB_REF#refs/heads/}
tag=${tag#refs/tags/}
fi
echo "tag=$tag" >> $GITHUB_OUTPUT
- name: 💎 Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
bundler-cache: true
- name: ⛾ Restore Pods cache
uses: actions/cache@v2
with:
path: |
ios/Pods
~/Library/Caches/CocoaPods
~/.cocoapods
key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: 🫛 Install Pods
run: cd ios && pod install --repo-update && cd ..
- name: ⚙ Setup build env vars
shell: bash
run: |
cat $GITHUB_WORKSPACE/.env.default >> $GITHUB_ENV
cat $GITHUB_WORKSPACE/.env.prod >> $GITHUB_ENV
echo "BUILD_TIME=$(date +%s000)" >> $GITHUB_ENV
- name: 📦 Build IOS App
uses: yukiarrr/ios-build-action@v1.4.0
with:
project-path: ios/MyApp.xcodeproj
p12-base64: ${{ secrets.IOS_P12_BASE64 }}
mobileprovision-base64: ${{ secrets.IOS_MOBILE_PROVISION_BASE64 }}
code-signing-identity: "iPhone Distribution"
team-id: ${{ secrets.IOS_TEAM_ID }}
certificate-password: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
workspace-path: ios/MyApp.xcworkspace
scheme: MyApp
- name: 🏷 Set asset name
shell: bash
run: |
mv output.ipa alertesecours-${{ steps.vars.outputs.tag }}.ipa
- name: 🎀 Release
uses: devthefuture-org/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
alertesecours-${{ steps.vars.outputs.tag }}.ipa
# - name: 🎁 Upload app to TestFlight
# uses: apple-actions/upload-testflight-build@v1
# if: startsWith(github.ref, 'refs/tags/')
# with:
# app-path: 'alertesecours-${{ steps.vars.outputs.tag }}.ipa'
# issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
# api-key-id: ${{ secrets.APPSTORE_API_KEY_ID }}
# api-private-key: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}

114
app/.gitignore vendored Normal file
View file

@ -0,0 +1,114 @@
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
# project.xcworkspace
ios/AlerteSecours.xcodeproj/project.xcworkspace/**
!ios/AlerteSecours.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
# bunlde sourcemaps
ios/*.map
ios/*.hbc
# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# Bundle artifacts
*.jsbundle
# CocoaPods
/ios/Pods/
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
# Expo
.expo/
web-build/
dist/
# Yarn berry
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# !.yarn/cache
# secrets
/keys
/.env.local
/.env.prod
/.env.staging
## Build generated
build/
DerivedData
/**/*.xcarchive/**
# aidigest
codebase.md
# Build logs
logs/
# Sensitive configuration files
ios/GoogleService-Info.plist
ios/AlerteSecours/GoogleService-Info.plist
ios/AlerteSecours/Supporting/Expo.plist
android/app/google-services.json
# Keep example files
!ios/GoogleService-Info.example.plist
!ios/AlerteSecours/GoogleService-Info.example.plist
!ios/AlerteSecours/Supporting/Expo.example.plist
!android/app/google-services.example.json
screenshot-*.png
/.data
# Geodae preprocessing
scripts/dae/node_modules/
scripts/dae/.yarn/*
!scripts/dae/.yarn/patches
!scripts/dae/.yarn/plugins
!scripts/dae/.yarn/releases
!scripts/dae/.yarn/sdks
!scripts/dae/.yarn/versions
src/assets/db/*.db

1
app/.node-version Normal file
View file

@ -0,0 +1 @@
20

35
app/.versionrc.js Normal file
View file

@ -0,0 +1,35 @@
const packageJsonPath = "package.json";
// Updater for versionCode (as integer)
const versionCodeUpdater = {
readVersion: (contents) => {
const packageJson = JSON.parse(contents);
return packageJson.customExpoVersioning.versionCode.toString();
},
writeVersion: (contents) => {
const packageJson = JSON.parse(contents);
packageJson.customExpoVersioning.versionCode += 1; // Increment as integer
return JSON.stringify(packageJson, null, 2);
}
};
// Updater for buildNumber (as integer)
const buildNumberUpdater = {
readVersion: (contents) => {
const packageJson = JSON.parse(contents);
return packageJson.customExpoVersioning.buildNumber.toString();
},
writeVersion: (contents) => {
const packageJson = JSON.parse(contents);
packageJson.customExpoVersioning.buildNumber += 1; // Increment as integer
return JSON.stringify(packageJson, null, 2);
}
};
module.exports = {
bumpFiles: [
{ filename: packageJsonPath, type: "json" },
{ filename: packageJsonPath, updater: versionCodeUpdater },
{ filename: packageJsonPath, updater: buildNumberUpdater }
]
};

6
app/.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"i18n-ally.localesPaths": [
"src/i18n",
"src/i18n/locales"
]
}

View file

@ -0,0 +1,73 @@
diff --git a/index.js b/index.js
index ad60eccd16d503a5cdfdf67dcb02208b9ed22721..497a74cbd6e66114a2ecca0f7a7b387a145b483d 100644
--- a/index.js
+++ b/index.js
@@ -117,24 +117,27 @@ export default class Drawer extends Component {
this._childDrawer = drawer
}
- componentWillMount() {
- if (this.context.drawer) this.context.drawer._registerChildDrawer(this)
+ componentDidMount() {
+ this.resync(null, this.props);
+ }
+
+ constructor(props) {
+ super(props);
+ if (this.drawer) this.drawer._registerChildDrawer(this)
if (this.props.openDrawerThreshold && process.env.NODE_ENV !== 'production') console.error('react-native-drawer: openDrawerThreshold is obsolete. Use panThreshold instead.')
if (this.props.panStartCompensation && process.env.NODE_ENV !== 'production') console.error('react-native-drawer: panStartCompensation is deprecated.')
if (this.props.relativeDrag && process.env.NODE_ENV !== 'production') console.error('react-native-drawer: relativeDrag is deprecated.')
this.initialize(this.props)
}
- componentWillReceiveProps(nextProps) {
- if (this.requiresResync(nextProps)) this.resync(null, nextProps)
+ componentDidUpdate() {
+ if (this.requiresResync(this.props)) this.resync(null, this.props)
- if (nextProps.open !== null && this._open !== nextProps.open) {
- this._syncAfterUpdate = true
- this._open = nextProps.open
- }
- }
+ if (this.props.open !== null && this._open !== this.props.open) {
+ this._syncAfterUpdate = true
+ this._open = this.props.open
+ }
- componentDidUpdate() {
if (this._syncAfterUpdate) {
this._syncAfterUpdate = false
this._open ? this.open('force') : this.close('force')
@@ -194,11 +197,10 @@ export default class Drawer extends Component {
onMoveShouldSetPanResponderCapture: this.onMoveShouldSetPanResponderCapture,
onPanResponderMove: this.onPanResponderMove,
onPanResponderRelease: this.onPanResponderRelease,
- onPanResponderTerminate: this.onPanResponderTerminate
+ onPanResponderTerminate: this.onPanResponderTerminate
})
}
- this.resync(null, props)
};
updatePosition = () => {
@@ -398,7 +400,7 @@ export default class Drawer extends Component {
duration: this.props.tweenDuration,
easingType: this.props.tweenEasing,
onFrame: (tweenValue) => {
- this._length = Math.round(tweenValue*2)/2;
+ this._length = Math.round(tweenValue*2)/2;
this.updatePosition()
},
onEnd: () => {
@@ -432,7 +434,7 @@ export default class Drawer extends Component {
easingType: this.props.tweenEasing,
duration: this.props.tweenDuration,
onFrame: (tweenValue) => {
- this._length = Math.round(tweenValue*2)/2;
+ this._length = Math.round(tweenValue*2)/2;
this.updatePosition()
},
onEnd: () => {

View file

@ -0,0 +1,16 @@
/* eslint-disable */
//prettier-ignore
module.exports = {
name: "@yarnpkg/plugin-fetch",
factory: function (require) {
var plugin=(()=>{var M=Object.defineProperty;var R=(n,t,e)=>t in n?M(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var o=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+n+'" is not supported')});var f=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports);var g=(n,t,e)=>(R(n,typeof t!="symbol"?t+"":t,e),e);var P=f((ce,F)=>{"use strict";F.exports=function(t){return t.map(function(e){return e&&typeof e=="object"?e.op.replace(/(.)/g,"\\$1"):/["\s]/.test(e)&&!/'/.test(e)?"'"+e.replace(/(['\\])/g,"\\$1")+"'":/["'\s]/.test(e)?'"'+e.replace(/(["\\$`!])/g,"\\$1")+'"':String(e).replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g,"$1\\$2")}).join(" ")}});var E=f((oe,J)=>{var j=o("fs"),z=o("path"),{parseSyml:G}=o("@yarnpkg/parsers");J.exports=function(){let t=j.readFileSync("yarn.lock","utf8"),e=G(t),d=Object.keys(e).filter(i=>i.includes("@workspace:")),s=d.map(i=>{let[,p]=e[i].resolution.trim().split("@workspace:");return p==="."?null:p}).filter(Boolean);d.forEach(i=>{let{dependencies:p,dependenciesMeta:r,peerDependencies:q,peerDependenciesMeta:w,resolution:C,bin:Y}=e[i],[B,b]=C.trim().split("@workspace:"),H=z.join(b,"package.json"),h={name:B,version:"0.0.0",description:"**DON'T COMMIT** Generated file for caching",private:!0,dependencies:p,peerDependencies:q,peerDependenciesMeta:w,bin:Y};if(r){let m={};Object.keys(r).forEach(k=>{m[k]=p[k],delete p[k]}),h.optionalDependencies=m}if(b==="."){s.length>0&&(h.workspaces={packages:s});let m=Object.keys(e),k=c=>{let a=c.trim().split("@");return c.startsWith("@")?a=a.slice(0,2):a=a.slice(0,1),a.join("@")};h.resolutions=m.filter(c=>{if(c.includes("@workspace:")||c.includes(", ")||!c.includes("@npm:"))return!1;let a=k(c);return m.every(y=>c===y?!0:y.split(",").map(l=>k(l)).every(l=>l!==a))}).reduce((c,a)=>{let[y,l]=a.trim().split("@npm:");return c[y]=l.includes("@")?`npm:${l}`:l,c},{})}j.mkdirSync(b,{recursive:!0}),j.writeFileSync(H,`${JSON.stringify(h,null,2)}
`)})}});var S=f((ae,T)=>{var I=E();T.exports=n=>{n.context.stdout.write(`[YARN-FETCH] extracting package.json file(s) from yarn.lock
`),I()}});var O=f((pe,N)=>{var u=o("fs"),K=o("path"),{execSync:U}=o("child_process"),{parseSyml:W}=o("@yarnpkg/parsers"),{BaseCommand:Z}=o("@yarnpkg/cli"),{Command:Q,Option:D}=o("clipanion"),V=P(),X=S(),x;N.exports=(x=class extends Z{protectPackageJson=D.Boolean("--protect-package-json");args=D.Proxy();async execute(){let{protectPackageJson:t=process.stdout.isTTY}=this,e=[];if(t){this.context.stdout.write(`[YARN-FETCH] backup possible package.json file(s)
`);let s=u.readFileSync("yarn.lock","utf8"),i=W(s);e=Object.keys(i).filter(r=>r.includes("@workspace:")).map(r=>{let{resolution:q}=i[r],[,w]=q.trim().split("@workspace:");return K.join(w,"package.json")}),e.forEach(r=>{u.existsSync(r)&&!u.existsSync(`${r}.yarn-plugin-fetch-bak`)&&u.copyFileSync(r,`${r}.yarn-plugin-fetch-bak`)})}X(this);let d=`yarn ${V(this.args)}`;this.context.stdout.write(`[YARN-FETCH] ${d}
`);try{U(d,{stdio:"inherit"})}catch(s){throw s}finally{t&&(this.context.stdout.write(`[YARN-FETCH] restoring possible package.json file(s)
`),e.forEach(s=>{u.existsSync(`${s}.yarn-plugin-fetch-bak`)?u.renameSync(`${s}.yarn-plugin-fetch-bak`,s):u.unlinkSync(s)}))}}},g(x,"paths",[["fetch"]]),g(x,"usage",Q.Usage({description:"fetch dependencies from yarn.lock in Docker build",details:`
expand yarn.lock to package.json file(s) and install dependencies in Docker build.
`,examples:[["yarn fetch --immutable","yarn fetch workspace my-package focus"]]})),x)});var A=f((ke,v)=>{var{BaseCommand:_}=o("@yarnpkg/cli"),ee=S(),$;v.exports=($=class extends _{async execute(){ee(this)}},g($,"paths",[["expand-lock"]]),$)});var se=f((de,L)=>{var te=O(),ne=A();L.exports={commands:[te,ne]}});return se();})();
return plugin;
}
};

934
app/.yarn/releases/yarn-4.5.3.cjs vendored Executable file

File diff suppressed because one or more lines are too long

11
app/.yarnrc.yml Normal file
View file

@ -0,0 +1,11 @@
compressionLevel: mixed
enableGlobalCache: false
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-fetch.cjs
spec: "https://raw.githubusercontent.com/devthejo/yarn-plugin-fetch/master/bundles/@yarnpkg/plugin-fetch.js"
yarnPath: .yarn/releases/yarn-4.5.3.cjs

575
app/CHANGELOG.md Normal file
View file

@ -0,0 +1,575 @@
# Changelog
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [1.16.10](https://github.com/alerte-secours/as-app/compare/v1.16.0...v1.16.10) (2026-02-08)
### Bug Fixes
* a11y regression audio msg sending ([a12bd59](https://github.com/alerte-secours/as-app/commit/a12bd593520299953bc9f883c410b611f4794289))
* a11y wip ([9b92fed](https://github.com/alerte-secours/as-app/commit/9b92fed825877e01faa286b28814c6c14249fdd4))
* **android:** track location battery saving ([a2acbb6](https://github.com/alerte-secours/as-app/commit/a2acbb6d0b19d36803b4130c7360ba0a090ee5cb))
* **audio-message:** ios + up to expo-audio ([4d71c22](https://github.com/alerte-secours/as-app/commit/4d71c229d6a1f904e62bd96270817f0e6a2df42b))
* **audio-message:** iOS regression ([5951f36](https://github.com/alerte-secours/as-app/commit/5951f36291ce9bc7837084b309786e5ff0dfc9fe))
* **audio-messaging:** android + fix dark theme label ([a69321f](https://github.com/alerte-secours/as-app/commit/a69321f82e19bb199ce8655fe5dc7eac187fcda9))
* chat subscription hangs up ([aade47b](https://github.com/alerte-secours/as-app/commit/aade47beb376a8736acbe975a479350dbd3b5e69))
* **ios:** bundle release version ([906e2f1](https://github.com/alerte-secours/as-app/commit/906e2f194d4f5fc73b29c4dece1b6054cd74031a))
* **ios:** deps after up rnbl ([1980822](https://github.com/alerte-secours/as-app/commit/1980822919deda76bc6e186ab3e7addd7ed32618))
* **ios:** up react-native-background-geolocation ([c8fd852](https://github.com/alerte-secours/as-app/commit/c8fd852eca5c66d3f37730878860b5824b900afd))
* load font ([8ba858f](https://github.com/alerte-secours/as-app/commit/8ba858f8763a5aa4c511b82b04387fb01fd81287))
* permissions screen ([6c8153b](https://github.com/alerte-secours/as-app/commit/6c8153bdb114582f9a597a50fd2604f7b90dd181))
* reload + improve subscriptions ([39d2ede](https://github.com/alerte-secours/as-app/commit/39d2ede29554e5fd445ad4a4534850fa607f8e6f))
* revert broken subscriptions ([52aff42](https://github.com/alerte-secours/as-app/commit/52aff4242dd9d9db3b07d2e43cf727748c6e2eb9))
* **sentry:** enlight removing replay and cleaning useless error ([bc5129f](https://github.com/alerte-secours/as-app/commit/bc5129f7bfb0b637f8d4e130c7f4e4cc7879e22a))
* track location ([29d7747](https://github.com/alerte-secours/as-app/commit/29d7747b51d333d9b592eab31c800fcdf4d808a5))
* **track-location:** try 11 ([88fbd72](https://github.com/alerte-secours/as-app/commit/88fbd72e5144c36c01d9e047ea43faf69014c9f6))
* **track-location:** try 3 ([41bb6fc](https://github.com/alerte-secours/as-app/commit/41bb6fcd2dc0999d212ceab0c9a6b6b64fe07cce))
* **track-location:** try 4 ([c7d0b36](https://github.com/alerte-secours/as-app/commit/c7d0b36f1bd3e700ad15bbc3ecff987e61aadbd9))
* **track-location:** try 5 ([69753bc](https://github.com/alerte-secours/as-app/commit/69753bc7e18ebd27715d2c0f6472c3c9ea14c0e5))
* **track-location:** try 6 ([b61aff7](https://github.com/alerte-secours/as-app/commit/b61aff70787e82e05500cbf9c3fda1d7882a040b))
* **track-location:** try 7 (+ up rnbl to v5) ([f4f7708](https://github.com/alerte-secours/as-app/commit/f4f7708e71227301b9cd5624669da8a092a3a379))
* **track-location:** try 8 ([33eb0cf](https://github.com/alerte-secours/as-app/commit/33eb0cfa13eb75308fc549f4289c6eaa15a3ac5c))
* **track-location:** try 8 ([7ba78c7](https://github.com/alerte-secours/as-app/commit/7ba78c7334462d6de6e647d236d39c415fa9cb2b))
* **track-location:** try 9 ([a18baf9](https://github.com/alerte-secours/as-app/commit/a18baf9ae6bf955f4be609d014c9f5cab8dc6268))
* trackLocation ([0cf1139](https://github.com/alerte-secours/as-app/commit/0cf1139f9b3ce953aeb6a48274dfc58ca500dfdf))
* **up:** react-native-background-geolocation (+fix mountain android) ([a1d4f0e](https://github.com/alerte-secours/as-app/commit/a1d4f0e0596f1e00bae608ba191ef700d4c4bd04))
* **ws:** stabilization try 1 ([147e514](https://github.com/alerte-secours/as-app/commit/147e514d03a43e74b5e7d6361183b4006dc1186d))
* **ws:** stabilization try 2 ([239ca4d](https://github.com/alerte-secours/as-app/commit/239ca4d86d78a9f74a78bde74a6bc84f96830e21))
* **ws:** stabilization try 3 ([6e71707](https://github.com/alerte-secours/as-app/commit/6e717077f9acc2cbb853b5bf2f09bc3463a0a861))
* **ws:** stabilization try 4 ([f7656be](https://github.com/alerte-secours/as-app/commit/f7656beb1aa4fc4ed504876252ac4ecc5dae4c1e))
* **ws:** stabilization try 5 ([ef643f7](https://github.com/alerte-secours/as-app/commit/ef643f77cb5f88235a1f92ecd5292c8844124b3e))
* **ws:** stabilization try 6 + typo ([5dfb064](https://github.com/alerte-secours/as-app/commit/5dfb064c2cda2f1a1ca9346d6d659d8339a25af9))
* **ws:** stabilization try 7 ([42d5b18](https://github.com/alerte-secours/as-app/commit/42d5b18b35577eb438f64b38d309f65ea30b7e3f))
## [1.16.9](https://github.com/alerte-secours/as-app/compare/v1.16.8...v1.16.9) (2026-02-08)
### Bug Fixes
* **track-location:** try 11 ([88fbd72](https://github.com/alerte-secours/as-app/commit/88fbd72e5144c36c01d9e047ea43faf69014c9f6))
## [1.16.8](https://github.com/alerte-secours/as-app/compare/v1.16.7...v1.16.8) (2026-02-05)
### Bug Fixes
* **up:** react-native-background-geolocation (+fix mountain android) ([a1d4f0e](https://github.com/alerte-secours/as-app/commit/a1d4f0e0596f1e00bae608ba191ef700d4c4bd04))
## [1.16.7](https://github.com/alerte-secours/as-app/compare/v1.16.6...v1.16.7) (2026-01-27)
### Bug Fixes
* **ios:** deps after up rnbl ([1980822](https://github.com/alerte-secours/as-app/commit/1980822919deda76bc6e186ab3e7addd7ed32618))
* **track-location:** try 5 ([69753bc](https://github.com/alerte-secours/as-app/commit/69753bc7e18ebd27715d2c0f6472c3c9ea14c0e5))
* **track-location:** try 6 ([b61aff7](https://github.com/alerte-secours/as-app/commit/b61aff70787e82e05500cbf9c3fda1d7882a040b))
* **track-location:** try 7 (+ up rnbl to v5) ([f4f7708](https://github.com/alerte-secours/as-app/commit/f4f7708e71227301b9cd5624669da8a092a3a379))
* **track-location:** try 8 ([33eb0cf](https://github.com/alerte-secours/as-app/commit/33eb0cfa13eb75308fc549f4289c6eaa15a3ac5c))
* **track-location:** try 8 ([7ba78c7](https://github.com/alerte-secours/as-app/commit/7ba78c7334462d6de6e647d236d39c415fa9cb2b))
* **track-location:** try 9 ([a18baf9](https://github.com/alerte-secours/as-app/commit/a18baf9ae6bf955f4be609d014c9f5cab8dc6268))
## [1.16.6](https://github.com/alerte-secours/as-app/compare/v1.16.5...v1.16.6) (2026-01-22)
### Bug Fixes
* permissions screen ([6c8153b](https://github.com/alerte-secours/as-app/commit/6c8153bdb114582f9a597a50fd2604f7b90dd181))
* **track-location:** try 3 ([41bb6fc](https://github.com/alerte-secours/as-app/commit/41bb6fcd2dc0999d212ceab0c9a6b6b64fe07cce))
* **track-location:** try 4 ([c7d0b36](https://github.com/alerte-secours/as-app/commit/c7d0b36f1bd3e700ad15bbc3ecff987e61aadbd9))
## [1.16.5](https://github.com/alerte-secours/as-app/compare/v1.16.4...v1.16.5) (2026-01-20)
### Bug Fixes
* **android:** track location battery saving ([a2acbb6](https://github.com/alerte-secours/as-app/commit/a2acbb6d0b19d36803b4130c7360ba0a090ee5cb))
## [1.16.4](https://github.com/alerte-secours/as-app/compare/v1.16.3...v1.16.4) (2026-01-20)
### Bug Fixes
* **audio-message:** iOS regression ([5951f36](https://github.com/alerte-secours/as-app/commit/5951f36291ce9bc7837084b309786e5ff0dfc9fe))
* **audio-messaging:** android + fix dark theme label ([a69321f](https://github.com/alerte-secours/as-app/commit/a69321f82e19bb199ce8655fe5dc7eac187fcda9))
* chat subscription hangs up ([aade47b](https://github.com/alerte-secours/as-app/commit/aade47beb376a8736acbe975a479350dbd3b5e69))
* **ws:** stabilization try 2 ([239ca4d](https://github.com/alerte-secours/as-app/commit/239ca4d86d78a9f74a78bde74a6bc84f96830e21))
* **ws:** stabilization try 3 ([6e71707](https://github.com/alerte-secours/as-app/commit/6e717077f9acc2cbb853b5bf2f09bc3463a0a861))
* **ws:** stabilization try 4 ([f7656be](https://github.com/alerte-secours/as-app/commit/f7656beb1aa4fc4ed504876252ac4ecc5dae4c1e))
* **ws:** stabilization try 5 ([ef643f7](https://github.com/alerte-secours/as-app/commit/ef643f77cb5f88235a1f92ecd5292c8844124b3e))
* **ws:** stabilization try 6 + typo ([5dfb064](https://github.com/alerte-secours/as-app/commit/5dfb064c2cda2f1a1ca9346d6d659d8339a25af9))
* **ws:** stabilization try 7 ([42d5b18](https://github.com/alerte-secours/as-app/commit/42d5b18b35577eb438f64b38d309f65ea30b7e3f))
## [1.16.3](https://github.com/alerte-secours/as-app/compare/v1.16.2...v1.16.3) (2026-01-15)
### Bug Fixes
* a11y regression audio msg sending ([a12bd59](https://github.com/alerte-secours/as-app/commit/a12bd593520299953bc9f883c410b611f4794289))
* **audio-message:** ios + up to expo-audio ([4d71c22](https://github.com/alerte-secours/as-app/commit/4d71c229d6a1f904e62bd96270817f0e6a2df42b))
* **sentry:** enlight removing replay and cleaning useless error ([bc5129f](https://github.com/alerte-secours/as-app/commit/bc5129f7bfb0b637f8d4e130c7f4e4cc7879e22a))
* **ws:** stabilization try 1 ([147e514](https://github.com/alerte-secours/as-app/commit/147e514d03a43e74b5e7d6361183b4006dc1186d))
## [1.16.2](https://github.com/alerte-secours/as-app/compare/v1.16.1...v1.16.2) (2026-01-12)
## [1.16.1](https://github.com/alerte-secours/as-app/compare/v1.15.0...v1.16.1) (2026-01-12)
### Bug Fixes
* a11y wip ([9b92fed](https://github.com/alerte-secours/as-app/commit/9b92fed825877e01faa286b28814c6c14249fdd4))
* **ios:** bundle release version ([906e2f1](https://github.com/alerte-secours/as-app/commit/906e2f194d4f5fc73b29c4dece1b6054cd74031a))
* **ios:** wip ([c5c5703](https://github.com/alerte-secours/as-app/commit/c5c570392ba52a56dd35d77f13844c2acf9bce7f))
* load font ([8ba858f](https://github.com/alerte-secours/as-app/commit/8ba858f8763a5aa4c511b82b04387fb01fd81287))
* reload + improve subscriptions ([39d2ede](https://github.com/alerte-secours/as-app/commit/39d2ede29554e5fd445ad4a4534850fa607f8e6f))
* revert broken subscriptions ([52aff42](https://github.com/alerte-secours/as-app/commit/52aff4242dd9d9db3b07d2e43cf727748c6e2eb9))
* track location ([29d7747](https://github.com/alerte-secours/as-app/commit/29d7747b51d333d9b592eab31c800fcdf4d808a5))
* trackLocation ([0cf1139](https://github.com/alerte-secours/as-app/commit/0cf1139f9b3ce953aeb6a48274dfc58ca500dfdf))
* yarn ios:staging ([c11b05a](https://github.com/alerte-secours/as-app/commit/c11b05a1082489eb8596567036329b142fb0b0b9))
## [1.16.0](https://github.com/alerte-secours/as-app/compare/v1.14.3...v1.16.0) (2026-01-04)
### Features
* **links:** add appui soutien ([43bc7f6](https://github.com/alerte-secours/as-app/commit/43bc7f6f63f5034359eb0f4598386215889a35fe))
### Bug Fixes
* **ios:** wip ([c5c5703](https://github.com/alerte-secours/as-app/commit/c5c570392ba52a56dd35d77f13844c2acf9bce7f))
* yarn ios:staging ([c11b05a](https://github.com/alerte-secours/as-app/commit/c11b05a1082489eb8596567036329b142fb0b0b9))
## [1.15.0](https://github.com/alerte-secours/as-app/compare/v1.13.13...v1.15.0) (2025-12-11)
### Features
* **links:** add appui soutien ([43bc7f6](https://github.com/alerte-secours/as-app/commit/43bc7f6f63f5034359eb0f4598386215889a35fe))
### Bug Fixes
* **ios:** bundle export scipt ([457b9f3](https://github.com/alerte-secours/as-app/commit/457b9f3d5cb884551758df09bf69d09a179610db))
* **ios:** expo 53 upgrade crash and black screen ([bf09f96](https://github.com/alerte-secours/as-app/commit/bf09f968a7937ccfd90171cb12b74cd66d482466))
* **ios:** ok ([c228569](https://github.com/alerte-secours/as-app/commit/c2285691a75591bfa9e17bf20f710cab66c241ac))
* **ios:** wip ([2da80b0](https://github.com/alerte-secours/as-app/commit/2da80b0ca963efdc6df3cc6f3d1c8c86fd4f5c50))
## [1.14.3](https://github.com/alerte-secours/as-app/compare/v1.14.2...v1.14.3) (2025-12-10)
### Bug Fixes
* **ios:** ok ([c228569](https://github.com/alerte-secours/as-app/commit/c2285691a75591bfa9e17bf20f710cab66c241ac))
## [1.14.2](https://github.com/alerte-secours/as-app/compare/v1.14.1...v1.14.2) (2025-12-09)
## [1.14.1](https://github.com/alerte-secours/as-app/compare/v1.14.0...v1.14.1) (2025-12-08)
### Bug Fixes
* **ios:** wip ([2da80b0](https://github.com/alerte-secours/as-app/commit/2da80b0ca963efdc6df3cc6f3d1c8c86fd4f5c50))
## [1.14.0](https://github.com/alerte-secours/as-app/compare/v1.13.11...v1.14.0) (2025-11-30)
### Bug Fixes
* **android:** phone-call ([52fc3bc](https://github.com/alerte-secours/as-app/commit/52fc3bc24b2a2bf1fe5ae919cddca41d95b1053c))
* connect loader ([cccb491](https://github.com/alerte-secours/as-app/commit/cccb49134f55faf5f5d536e91509eba2743f2af8))
* **ios:** bundle export scipt ([457b9f3](https://github.com/alerte-secours/as-app/commit/457b9f3d5cb884551758df09bf69d09a179610db))
* **ios:** expo 53 upgrade crash and black screen ([bf09f96](https://github.com/alerte-secours/as-app/commit/bf09f968a7937ccfd90171cb12b74cd66d482466))
* **menu:** call emergency ([d755217](https://github.com/alerte-secours/as-app/commit/d7552171318cacb4a8df87add6462f49696b5d93))
* phone call ([492904c](https://github.com/alerte-secours/as-app/commit/492904cbe8a5ceec35a79610ea59cf5eaed42735))
## [1.13.13](https://github.com/alerte-secours/as-app/compare/v1.13.12...v1.13.13) (2025-10-23)
### Bug Fixes
* **android:** phone-call ([52fc3bc](https://github.com/alerte-secours/as-app/commit/52fc3bc24b2a2bf1fe5ae919cddca41d95b1053c))
* connect loader ([cccb491](https://github.com/alerte-secours/as-app/commit/cccb49134f55faf5f5d536e91509eba2743f2af8))
* **menu:** call emergency ([d755217](https://github.com/alerte-secours/as-app/commit/d7552171318cacb4a8df87add6462f49696b5d93))
* phone call ([492904c](https://github.com/alerte-secours/as-app/commit/492904cbe8a5ceec35a79610ea59cf5eaed42735))
## [1.13.12](https://github.com/alerte-secours/as-app/compare/v1.13.9...v1.13.12) (2025-10-10)
### Bug Fixes
* notification `undefined souhaite que vous soyez son contact d'urgence` ([7670177](https://github.com/alerte-secours/as-app/commit/76701774d113b72aabdd54bb1117a3d655ffd499))
* **up-wip:** ios bundle and upload ([7588a26](https://github.com/alerte-secours/as-app/commit/7588a26e5b49fa58e54ab3e996c341ceea2e6474))
* **up-wip:** ios radar button design ([4dcf713](https://github.com/alerte-secours/as-app/commit/4dcf71379e2afc93f40c488d3ee03e7337ae2440))
* **up-wip:** ios radar button design (android regression) ([74c3326](https://github.com/alerte-secours/as-app/commit/74c3326376d7e811977b485670f4601ad3519a04))
* **up-wip:** recording permissions ([80f6d1d](https://github.com/alerte-secours/as-app/commit/80f6d1d20d4813343aab55bbc1a0b8c7fbd166f8))
* **up-wip:** recording permissions ([749a09a](https://github.com/alerte-secours/as-app/commit/749a09aa5ebebc94b81cd2a9fdcb085c4bb886f2))
* **up-wip:** register stucked loading ([c5ccfa8](https://github.com/alerte-secours/as-app/commit/c5ccfa8d08a1505cd25980dc6fbf436a59eb6386))
* **up:** deps ([0140be7](https://github.com/alerte-secours/as-app/commit/0140be77c002014dfafbcb2d14d09a0fcb38ac8c))
## [1.13.11](https://github.com/alerte-secours/as-app/compare/v1.13.9...v1.13.11) (2025-10-06)
### Bug Fixes
* notification `undefined souhaite que vous soyez son contact d'urgence` ([7670177](https://github.com/alerte-secours/as-app/commit/76701774d113b72aabdd54bb1117a3d655ffd499))
* **up-wip:** ios bundle and upload ([7588a26](https://github.com/alerte-secours/as-app/commit/7588a26e5b49fa58e54ab3e996c341ceea2e6474))
* **up-wip:** ios radar button design ([4dcf713](https://github.com/alerte-secours/as-app/commit/4dcf71379e2afc93f40c488d3ee03e7337ae2440))
* **up-wip:** ios radar button design (android regression) ([74c3326](https://github.com/alerte-secours/as-app/commit/74c3326376d7e811977b485670f4601ad3519a04))
* **up-wip:** recording permissions ([80f6d1d](https://github.com/alerte-secours/as-app/commit/80f6d1d20d4813343aab55bbc1a0b8c7fbd166f8))
* **up-wip:** recording permissions ([749a09a](https://github.com/alerte-secours/as-app/commit/749a09aa5ebebc94b81cd2a9fdcb085c4bb886f2))
* **up-wip:** register stucked loading ([c5ccfa8](https://github.com/alerte-secours/as-app/commit/c5ccfa8d08a1505cd25980dc6fbf436a59eb6386))
* **up:** deps ([0140be7](https://github.com/alerte-secours/as-app/commit/0140be77c002014dfafbcb2d14d09a0fcb38ac8c))
## [1.13.9](https://github.com/alerte-secours/as-app/compare/v1.13.8...v1.13.9) (2025-10-01)
### Bug Fixes
* **android:** local dev + wip ([fd6ba1c](https://github.com/alerte-secours/as-app/commit/fd6ba1caab783b13bec45584a8db7f12adc1e9c3))
* **android:** photo access ([35753e0](https://github.com/alerte-secours/as-app/commit/35753e0f53df88eceb958eca4eec0a55235cb8a7))
* **flag:** react19 up ([10e2905](https://github.com/alerte-secours/as-app/commit/10e29055c50b62993df05581982f1d9585aaf776))
* **prebuild:** up rn ([44d3ae4](https://github.com/alerte-secours/as-app/commit/44d3ae460fa2ec2d0f517fe142f34db138e7ccbc))
* **prebuild:** wip ([cf46272](https://github.com/alerte-secours/as-app/commit/cf46272382c439eea374b3b7166c5f42ca07c3e3))
* **up:** expo-audio ([4d726d3](https://github.com/alerte-secours/as-app/commit/4d726d3f1a5151b103a03a5ef227337c299e2bc5))
## [1.13.8](https://github.com/alerte-secours/as-app/compare/v1.13.7...v1.13.8) (2025-09-27)
### Bug Fixes
* **android:** 16k issue wip ([311af67](https://github.com/alerte-secours/as-app/commit/311af6799acbf971cc0203b7a729ea192d9f249d))
## [1.13.7](https://github.com/alerte-secours/as-app/compare/v1.13.6...v1.13.7) (2025-09-27)
### Bug Fixes
* **android:** 16k issue wip ([b14245c](https://github.com/alerte-secours/as-app/commit/b14245cead8cec9deda6e4efadd839ee3483afdb))
## [1.13.6](https://github.com/alerte-secours/as-app/compare/v1.13.5...v1.13.6) (2025-09-27)
### Bug Fixes
* **android:** 16k issue wip upgrading deps ([ea29f1f](https://github.com/alerte-secours/as-app/commit/ea29f1fd92a301e1e20516e2f9dc0410d681376c))
## [1.13.5](https://github.com/alerte-secours/as-app/compare/v1.13.4...v1.13.5) (2025-09-26)
### Bug Fixes
* **android:** 16k issue wip ([b8885ee](https://github.com/alerte-secours/as-app/commit/b8885ee95305fe512644493fa3da3d6776096d82))
## [1.13.4](https://github.com/alerte-secours/as-app/compare/v1.13.3...v1.13.4) (2025-09-26)
### Bug Fixes
* **android:** 16k issue wip ([2bae580](https://github.com/alerte-secours/as-app/commit/2bae5800c1eb96a8bc8ba2d9721d7ea63f89bf89))
## [1.13.3](https://github.com/alerte-secours/as-app/compare/v1.13.2...v1.13.3) (2025-09-26)
### Bug Fixes
* **android:** 16k issue wip ([f83edfb](https://github.com/alerte-secours/as-app/commit/f83edfba270debe10294c157248e1eae7501a398))
## [1.13.2](https://github.com/alerte-secours/as-app/compare/v1.13.1...v1.13.2) (2025-09-26)
## [1.13.1](https://github.com/alerte-secours/as-app/compare/v1.13.0...v1.13.1) (2025-09-26)
### Bug Fixes
* **android:** permissions wizard ([a29501b](https://github.com/alerte-secours/as-app/commit/a29501bb7c3c5a9a512a28caf8af31795b11d495))
* rollback permissions flow ([b7a53dd](https://github.com/alerte-secours/as-app/commit/b7a53dd78bae1bfc8ea1abf985f63af04b858055))
## [1.13.0](https://github.com/alerte-secours/as-app/compare/v1.12.2...v1.13.0) (2025-09-22)
### Features
* people around radar ([becb619](https://github.com/alerte-secours/as-app/commit/becb61967cbf2b22d77e337677c8390481e3c9dd))
### Bug Fixes
* **android:** battery optimisation ([cbd1803](https://github.com/alerte-secours/as-app/commit/cbd1803dc0c6e57924ac54b76dde84987a4dab6d))
* **wizard:** scrollview ([36ad5aa](https://github.com/alerte-secours/as-app/commit/36ad5aaf046a611e2d1b61a03ff362259951b04a))
## [1.12.3](https://github.com/alerte-secours/as-app/compare/v1.12.2...v1.12.3) (2025-09-05)
## [1.12.2](https://github.com/alerte-secours/as-app/compare/v1.12.1...v1.12.2) (2025-08-24)
### Bug Fixes
* 112 ([8487573](https://github.com/alerte-secours/as-app/commit/8487573c0f8eb6656cd5825ff217efe046d65407))
## [1.12.1](https://github.com/alerte-secours/as-app/compare/v1.12.0...v1.12.1) (2025-08-10)
### Bug Fixes
* menu index typo ([8d8da91](https://github.com/alerte-secours/as-app/commit/8d8da916965c1dd7feaa8b011ea854591c859e03))
* placeholder in dark theme for chat input ([d5ad23d](https://github.com/alerte-secours/as-app/commit/d5ad23d1dae521e4a99f757505adec3f23a7914c))
* **push-notif:** label "undefined à " ([ef9b503](https://github.com/alerte-secours/as-app/commit/ef9b5037fbb97fa597194760a9d3a22a04eeeeda))
* **theming:** alertes archivées buttons ([d6a3e94](https://github.com/alerte-secours/as-app/commit/d6a3e94ea710a494623a8636ccad71205094d9c6))
* typo ([0b5e936](https://github.com/alerte-secours/as-app/commit/0b5e936714054fe8647b8520d6432ab29fe2ecb7))
* **voice-message:** wip ([28b8b3d](https://github.com/alerte-secours/as-app/commit/28b8b3d826685de053ae5ff7f7931b24a64920b4))
## [1.12.0](https://github.com/alerte-secours/as-app/compare/v1.11.17...v1.12.0) (2025-08-02)
### Features
* **heartbeat:** remove ([69d9fc9](https://github.com/alerte-secours/as-app/commit/69d9fc9a6a1383bbbf5f1b5f5641d01b2378168b))
## [1.11.17](https://github.com/alerte-secours/as-app/compare/v1.11.16...v1.11.17) (2025-07-30)
## [1.11.16](https://github.com/alerte-secours/as-app/compare/v1.11.15...v1.11.16) (2025-07-27)
### Bug Fixes
* **io:** headless ([6ea01c0](https://github.com/alerte-secours/as-app/commit/6ea01c0c6d7f3cb8dbff51138b20f3fbba5b9766))
## [1.11.15](https://github.com/alerte-secours/as-app/compare/v1.11.14...v1.11.15) (2025-07-26)
## [1.11.14](https://github.com/alerte-secours/as-app/compare/v1.11.13...v1.11.14) (2025-07-25)
### Bug Fixes
* **io:** headless + debug wip ([a795e82](https://github.com/alerte-secours/as-app/commit/a795e82bbe30a425698173156862311d0c964207))
## [1.11.13](https://github.com/alerte-secours/as-app/compare/v1.11.12...v1.11.13) (2025-07-24)
### Bug Fixes
* **ios-headless:** wip ([6f62897](https://github.com/alerte-secours/as-app/commit/6f628979c632be7be12bddd52a8b56b105e6cbee))
## [1.11.12](https://github.com/alerte-secours/as-app/compare/v1.11.2...v1.11.12) (2025-07-23)
### Bug Fixes
* **ios-headless:** big wip leap ([5461852](https://github.com/alerte-secours/as-app/commit/5461852adaac33511889d7a2466f435d953b4a7b))
* **ios:** executeHeartbeatSync with silent push notification ([38e2f82](https://github.com/alerte-secours/as-app/commit/38e2f821ddeb5b2b4ad310bf2f32b23f5ca94ea7))
## [1.11.11](https://github.com/alerte-secours/as-app/compare/v1.11.10...v1.11.11) (2025-07-23)
## [1.11.10](https://github.com/alerte-secours/as-app/compare/v1.11.9...v1.11.10) (2025-07-22)
## [1.11.9](https://github.com/alerte-secours/as-app/compare/v1.11.8...v1.11.9) (2025-07-22)
## [1.11.8](https://github.com/alerte-secours/as-app/compare/v1.11.7...v1.11.8) (2025-07-22)
## [1.11.7](https://github.com/alerte-secours/as-app/compare/v1.11.6...v1.11.7) (2025-07-22)
## [1.11.6](https://github.com/alerte-secours/as-app/compare/v1.11.5...v1.11.6) (2025-07-21)
## [1.11.5](https://github.com/alerte-secours/as-app/compare/v1.11.4...v1.11.5) (2025-07-21)
## [1.11.4](https://github.com/alerte-secours/as-app/compare/v1.11.3...v1.11.4) (2025-07-20)
## [1.11.3](https://github.com/alerte-secours/as-app/compare/v1.11.2...v1.11.3) (2025-07-20)
## [1.11.2](https://github.com/alerte-secours/as-app/compare/v1.11.1...v1.11.2) (2025-07-19)
### Bug Fixes
* **ios:** BGTaskSchedulerPermittedIdentifiers + prebuild wip ([e6f23b8](https://github.com/alerte-secours/as-app/commit/e6f23b83be7f30adc6385dc8f3e074521c7caf22))
## [1.11.1](https://github.com/alerte-secours/as-app/compare/v1.11.0...v1.11.1) (2025-07-18)
## [1.11.0](https://github.com/alerte-secours/as-app/compare/v1.10.9...v1.11.0) (2025-07-12)
### Features
* **anchor:** bglost notification scroll to permissions + wip ([fd081d4](https://github.com/alerte-secours/as-app/commit/fd081d46a657059353bfb1e6022b68eedaee4e1a))
* optout sentry reporting ([c1b220f](https://github.com/alerte-secours/as-app/commit/c1b220f0078db8d07b3d58a7ac146d8af159a17d))
### Bug Fixes
* force location sync storage effect on interval ([7f30ef9](https://github.com/alerte-secours/as-app/commit/7f30ef9abf11bbdade5c3db3bfd7269dc212b39c))
* menu paramètres ([754e149](https://github.com/alerte-secours/as-app/commit/754e14946c0fa397558e5983a39c082c9072fe5c))
* message_permission_required ([894d26d](https://github.com/alerte-secours/as-app/commit/894d26dad12c4736cde827232764ed5c8d77df4e))
* **notification:** android background-geolocation-lost ([aea3a26](https://github.com/alerte-secours/as-app/commit/aea3a2609639f01b1d7aa414c67e3bdb99a1a47c))
* title_permission_required ([48b6637](https://github.com/alerte-secours/as-app/commit/48b663799d4bb4ef69671f0291a77a65418e2544))
* wip ([b635f29](https://github.com/alerte-secours/as-app/commit/b635f29f45928210bc9a9a8c5d201d91a6b48a07))
## [1.10.9](https://github.com/alerte-secours/as-app/compare/v1.10.7...v1.10.9) (2025-07-06)
### Bug Fixes
* bg location force sync all 12 hours ([732dc3d](https://github.com/alerte-secours/as-app/commit/732dc3df7b6ab635c70d02d657d066e6c72a49c4))
* **ios:** upgrade bundling ([23ecee5](https://github.com/alerte-secours/as-app/commit/23ecee5061e5e7324407223e7c1ce9a815f96521))
## [1.10.8](https://github.com/alerte-secours/as-app/compare/v1.10.7...v1.10.8) (2025-07-04)
### Bug Fixes
* bg location force sync all 12 hours ([732dc3d](https://github.com/alerte-secours/as-app/commit/732dc3df7b6ab635c70d02d657d066e6c72a49c4))
## [1.10.7](https://github.com/alerte-secours/as-app/compare/v1.10.1...v1.10.7) (2025-07-04)
### Bug Fixes
* **android:** foreground service ([0ac2851](https://github.com/alerte-secours/as-app/commit/0ac28515dff752af30e45ff2f88d52da46c591aa))
* back to stateless refresh (sync endpoint) ([6af5875](https://github.com/alerte-secours/as-app/commit/6af58755c1b3e8c7be0d117d6fc07278406a0459))
* **battery-opti-disable:** integrate permissions view ([d9b5d10](https://github.com/alerte-secours/as-app/commit/d9b5d10684446a01873810382e501e45cd19da1b))
* **battery-opti-disable:** wip ([7082161](https://github.com/alerte-secours/as-app/commit/7082161b7f004b1052adbce2cf3ac9f74b2eee03))
* bettery optimization glitch ([b4b7441](https://github.com/alerte-secours/as-app/commit/b4b7441bacc3728d684a6e2219c84b91c75461af))
* bg location lost notif ([2fa7b48](https://github.com/alerte-secours/as-app/commit/2fa7b4839aedec61a5fdf2e5292440b3b0bb9c6b))
* don't handle refresh in headless mode anymore ([b10ff5a](https://github.com/alerte-secours/as-app/commit/b10ff5a6e735df6323d70a3c5b0d651d1cbd01cc))
* **headless-task:** wip ([c947d49](https://github.com/alerte-secours/as-app/commit/c947d4915ab19377cd2263a86bc9f902c41defdc))
* **headless-task:** wip ([6c290f2](https://github.com/alerte-secours/as-app/commit/6c290f21b4d57513aa90dabcc68e9a7b074a6430))
* **headless:** async-storage in memory first ([9f6452d](https://github.com/alerte-secours/as-app/commit/9f6452d5e368c82e0f93afd06c354756dd7913db))
* **headless:** secure store in memory first ([4280820](https://github.com/alerte-secours/as-app/commit/4280820e0169c4f9e36793d3f0ad460e9bde558f))
* **headless:** use axios instead of apollo for auth ([6444801](https://github.com/alerte-secours/as-app/commit/644480182d8da2ca1197c919262d5a5df0817d25))
* **headless:** use fetch instead of axios for auth ([09ea8cd](https://github.com/alerte-secours/as-app/commit/09ea8cd5634f46c1daeeb24ad4230ee508bd8293))
* import typo generateAlertEmergencyInfoContent ([d780fb4](https://github.com/alerte-secours/as-app/commit/d780fb4190acc24ceb9811682f8684ffb232a716))
* improve error handling ([010aa2c](https://github.com/alerte-secours/as-app/commit/010aa2c2fc0cf80c6afd3eb4fe954f94c94b8bea))
* **ios:** up ios version for rn compat ([8b1c529](https://github.com/alerte-secours/as-app/commit/8b1c5291d4ce0b042d745f76fc6dc62cf8bd6ca4))
* known keys ([be0cd62](https://github.com/alerte-secours/as-app/commit/be0cd62cb943fb4d74243f78df2fb1fc29e97e76))
* memoryAsyncStorage ([6e290bd](https://github.com/alerte-secours/as-app/commit/6e290bdb6997dd06ee8d674087368ad68b97a881))
* prevent race condition ([6a77336](https://github.com/alerte-secours/as-app/commit/6a773367d49ef66a8a896ba18e63c660f30eb143))
* **profile:** button enregistrer should be greysed when stored or no change ([9cfb40e](https://github.com/alerte-secours/as-app/commit/9cfb40e510584567400a6ea6f4871b345d723ac6))
* re-enable expo-updates ([16332cb](https://github.com/alerte-secours/as-app/commit/16332cbb764be5f067aa7cb3c2713399d1959f7c))
* re-up ([8331029](https://github.com/alerte-secours/as-app/commit/8331029e91220cc9c679dce1058ffc5f2cbb0577))
* reduce tracesSampleRate ([b5ae235](https://github.com/alerte-secours/as-app/commit/b5ae235ba4f093451bb7bd41b19aa77a8a0bda96))
* remove debuggin ([b70d6ed](https://github.com/alerte-secours/as-app/commit/b70d6ed9a070e9c01fa0d5206db5cc1a115e074e))
* sentry + re-enable expo-updates + disable debug ([8e8e120](https://github.com/alerte-secours/as-app/commit/8e8e120391f197e7826edaef47817ff8fb14a6b8))
* sentry tracing ([e6924ac](https://github.com/alerte-secours/as-app/commit/e6924ac9ff22b114eff4293f007becebe44e286d))
* sentry tracing ([4a0f3ab](https://github.com/alerte-secours/as-app/commit/4a0f3ab7effd79f75efd976f5fd9e1d1531e5b19))
* sentry tracing ([8ba4056](https://github.com/alerte-secours/as-app/commit/8ba4056187e6bd9ebf8ceec881197d6dc0aaaebc))
* theming ([4e2ea42](https://github.com/alerte-secours/as-app/commit/4e2ea4219501c16f0e74fcd2a5d48dca9845b3ee))
* undefined error ([47f11d1](https://github.com/alerte-secours/as-app/commit/47f11d1b888f4372fcb03db9bd1e839495455df3))
* undefined error ([d4de0b4](https://github.com/alerte-secours/as-app/commit/d4de0b4541fedb29b3e5161f91fc65b3253308e0))
* up android target sdk version ([7918e74](https://github.com/alerte-secours/as-app/commit/7918e74184165509b7a76c2420c24fcf6629a5fa))
* **upgrade:** expo 52 + rn 0.76.9 ([a1ed6cf](https://github.com/alerte-secours/as-app/commit/a1ed6cfca6217ba2068908f12e78af990f91b9c5))
* **wizard hero:** battery opti red inside parameters bubble ([dccf361](https://github.com/alerte-secours/as-app/commit/dccf361dbcb23239d28ea7f860ddeae3377349c0))
* bg location force sync all 12 hours ([71b73e7](https://github.com/alerte-secours/as-app/commit/71b73e7ba4733bd46345d8f73a2a33bb8786726a))
* **ios:** up ios version for rn compat ([8b1c529](https://github.com/alerte-secours/as-app/commit/8b1c5291d4ce0b042d745f76fc6dc62cf8bd6ca4))
## [1.10.6](https://github.com/alerte-secours/as-app/compare/v1.10.5...v1.10.6) (2025-07-04)
## [1.10.5](https://github.com/alerte-secours/as-app/compare/v1.10.4...v1.10.5) (2025-07-04)
### Bug Fixes
* bg location lost notif ([2fa7b48](https://github.com/alerte-secours/as-app/commit/2fa7b4839aedec61a5fdf2e5292440b3b0bb9c6b))
* theming ([4e2ea42](https://github.com/alerte-secours/as-app/commit/4e2ea4219501c16f0e74fcd2a5d48dca9845b3ee))
## [1.10.4](https://github.com/alerte-secours/as-app/compare/v1.10.3...v1.10.4) (2025-07-03)
### Bug Fixes
* remove debuggin ([b70d6ed](https://github.com/alerte-secours/as-app/commit/b70d6ed9a070e9c01fa0d5206db5cc1a115e074e))
## [1.10.3](https://github.com/alerte-secours/as-app/compare/v1.10.2...v1.10.3) (2025-07-03)
### Bug Fixes
* **profile:** button enregistrer should be greysed when stored or no change ([9cfb40e](https://github.com/alerte-secours/as-app/commit/9cfb40e510584567400a6ea6f4871b345d723ac6))
* up android target sdk version ([7918e74](https://github.com/alerte-secours/as-app/commit/7918e74184165509b7a76c2420c24fcf6629a5fa))
* **wizard hero:** battery opti red inside parameters bubble ([dccf361](https://github.com/alerte-secours/as-app/commit/dccf361dbcb23239d28ea7f860ddeae3377349c0))
## [1.10.2](https://github.com/alerte-secours/as-app/compare/v1.10.1...v1.10.2) (2025-07-03)
### Bug Fixes
* **android:** foreground service ([0ac2851](https://github.com/alerte-secours/as-app/commit/0ac28515dff752af30e45ff2f88d52da46c591aa))
* back to stateless refresh (sync endpoint) ([6af5875](https://github.com/alerte-secours/as-app/commit/6af58755c1b3e8c7be0d117d6fc07278406a0459))
* **battery-opti-disable:** integrate permissions view ([d9b5d10](https://github.com/alerte-secours/as-app/commit/d9b5d10684446a01873810382e501e45cd19da1b))
* **battery-opti-disable:** wip ([7082161](https://github.com/alerte-secours/as-app/commit/7082161b7f004b1052adbce2cf3ac9f74b2eee03))
* bettery optimization glitch ([b4b7441](https://github.com/alerte-secours/as-app/commit/b4b7441bacc3728d684a6e2219c84b91c75461af))
* don't handle refresh in headless mode anymore ([b10ff5a](https://github.com/alerte-secours/as-app/commit/b10ff5a6e735df6323d70a3c5b0d651d1cbd01cc))
* **headless-task:** wip ([c947d49](https://github.com/alerte-secours/as-app/commit/c947d4915ab19377cd2263a86bc9f902c41defdc))
* **headless-task:** wip ([6c290f2](https://github.com/alerte-secours/as-app/commit/6c290f21b4d57513aa90dabcc68e9a7b074a6430))
* **headless:** async-storage in memory first ([9f6452d](https://github.com/alerte-secours/as-app/commit/9f6452d5e368c82e0f93afd06c354756dd7913db))
* **headless:** secure store in memory first ([4280820](https://github.com/alerte-secours/as-app/commit/4280820e0169c4f9e36793d3f0ad460e9bde558f))
* **headless:** use axios instead of apollo for auth ([6444801](https://github.com/alerte-secours/as-app/commit/644480182d8da2ca1197c919262d5a5df0817d25))
* **headless:** use fetch instead of axios for auth ([09ea8cd](https://github.com/alerte-secours/as-app/commit/09ea8cd5634f46c1daeeb24ad4230ee508bd8293))
* import typo generateAlertEmergencyInfoContent ([d780fb4](https://github.com/alerte-secours/as-app/commit/d780fb4190acc24ceb9811682f8684ffb232a716))
* improve error handling ([010aa2c](https://github.com/alerte-secours/as-app/commit/010aa2c2fc0cf80c6afd3eb4fe954f94c94b8bea))
* known keys ([be0cd62](https://github.com/alerte-secours/as-app/commit/be0cd62cb943fb4d74243f78df2fb1fc29e97e76))
* memoryAsyncStorage ([6e290bd](https://github.com/alerte-secours/as-app/commit/6e290bdb6997dd06ee8d674087368ad68b97a881))
* prevent race condition ([6a77336](https://github.com/alerte-secours/as-app/commit/6a773367d49ef66a8a896ba18e63c660f30eb143))
* re-enable expo-updates ([16332cb](https://github.com/alerte-secours/as-app/commit/16332cbb764be5f067aa7cb3c2713399d1959f7c))
* re-up ([8331029](https://github.com/alerte-secours/as-app/commit/8331029e91220cc9c679dce1058ffc5f2cbb0577))
* reduce tracesSampleRate ([b5ae235](https://github.com/alerte-secours/as-app/commit/b5ae235ba4f093451bb7bd41b19aa77a8a0bda96))
* sentry + re-enable expo-updates + disable debug ([8e8e120](https://github.com/alerte-secours/as-app/commit/8e8e120391f197e7826edaef47817ff8fb14a6b8))
* sentry tracing ([e6924ac](https://github.com/alerte-secours/as-app/commit/e6924ac9ff22b114eff4293f007becebe44e286d))
* sentry tracing ([4a0f3ab](https://github.com/alerte-secours/as-app/commit/4a0f3ab7effd79f75efd976f5fd9e1d1531e5b19))
* sentry tracing ([8ba4056](https://github.com/alerte-secours/as-app/commit/8ba4056187e6bd9ebf8ceec881197d6dc0aaaebc))
* undefined error ([47f11d1](https://github.com/alerte-secours/as-app/commit/47f11d1b888f4372fcb03db9bd1e839495455df3))
* undefined error ([d4de0b4](https://github.com/alerte-secours/as-app/commit/d4de0b4541fedb29b3e5161f91fc65b3253308e0))
* **upgrade:** expo 52 + rn 0.76.9 ([a1ed6cf](https://github.com/alerte-secours/as-app/commit/a1ed6cfca6217ba2068908f12e78af990f91b9c5))
## [1.10.1](https://github.com/alerte-secours/as-app/compare/v1.10.0...v1.10.1) (2025-06-01)
### Bug Fixes
* remove deprecated ([a2f476f](https://github.com/alerte-secours/as-app/commit/a2f476f8ee9670461dc7babc7f534c43ba4708e9))
## [1.10.0](https://github.com/alerte-secours/as-app/compare/v1.9.2...v1.10.0) (2025-06-01)
### Features
* contribute ([3e70ff2](https://github.com/alerte-secours/as-app/commit/3e70ff23c9361a5d331e15160adbb44a8bf773ac))
* **follow-location:** init ([ca3a2c8](https://github.com/alerte-secours/as-app/commit/ca3a2c8fcce2aaa613817bde047f143915ef8fe0))
* **follow-location:** map bubble ([f3cca81](https://github.com/alerte-secours/as-app/commit/f3cca8182ca52a89f7f6d0785821185db277bbf0))
* **follow-location:** map wip ([ce11db9](https://github.com/alerte-secours/as-app/commit/ce11db9863a7aaa14b28e104645d8ce0b23a235b))
* **follow-location:** overview initial position ([30aeb2a](https://github.com/alerte-secours/as-app/commit/30aeb2a0e41196719977900e08b12d8ae813a69a))
* **follow-location:** wip ([c30c0b0](https://github.com/alerte-secours/as-app/commit/c30c0b0482d946b6b4d6a2421416a59f9d57bfeb))
### Bug Fixes
* call emergency by default on yellow ([991b65d](https://github.com/alerte-secours/as-app/commit/991b65d990b909fb02f9941fedf84637d0a8b71e))
## [1.9.2](https://github.com/alerte-secours/as-app/compare/v1.9.1...v1.9.2) (2025-05-16)
### Bug Fixes
* **ios-reported-bug:** app only displayed the splash screen after enabling access to location ([2e35c41](https://github.com/alerte-secours/as-app/commit/2e35c41e0f3e968df6dc07e7656cf50509557a7c))
## [1.9.1](https://github.com/alerte-secours/as-app/compare/v1.9.0...v1.9.1) (2025-05-14)
### Bug Fixes
* default call emergency on yellow ([8b5d062](https://github.com/alerte-secours/as-app/commit/8b5d0621fed5fafaa366fd16b9280509e3923ca4))
* **geoloc:** server switch + proper auth throttling ([af477ce](https://github.com/alerte-secours/as-app/commit/af477ce8352599124e20894bd1fbdb297317e4cb))
* staging persistence + disconnect and geo auth reload loop ([40b27bf](https://github.com/alerte-secours/as-app/commit/40b27bff297cdf70f45c66009275110c91a60269))
* wording ([42bf5c5](https://github.com/alerte-secours/as-app/commit/42bf5c599520cdd55943fde5f5fc052c72b7991a))
## 1.9.0 (2025-04-24)
### Features
* bg location lost notify ([f08bd08](https://github.com/alerte-secours/as-app/commit/f08bd08ece0aafe43f8bb411953c1e1b504204be))
* **links:** add ijp ([9368ec4](https://github.com/alerte-secours/as-app/commit/9368ec440aa7ef19423db007eb3bd4062aa00de8))
### Bug Fixes
* **profile-form:** optional email ([426054b](https://github.com/alerte-secours/as-app/commit/426054bc0e36025ec3d7d5c544f4cfca6aabc6bf))

266
app/DEVELOPER.md Normal file
View file

@ -0,0 +1,266 @@
# Alerte Secours Mobile App - Developer Documentation
This document contains technical information for developers working on the Alerte Secours mobile application.
## Table of Contents
- [Project Overview](#project-overview)
- [Technical Stack](#technical-stack)
- [Development Quick Start](#development-quick-start)
- [Installation](#installation)
- [Android](#android)
- [iOS](#ios)
- [Project Structure](#project-structure)
- [Accessibility](#accessibility)
- [Troubleshooting](#troubleshooting)
## Project Overview
Alerte Secours is a mobile application built with React Native that handles alerts and emergency-related functionality. The app supports both iOS and Android platforms and includes features such as:
- Alert creation and management with real-time updates
- Location-based features with mapping integration
- Chat/Messaging system with alert-specific chat rooms
- Authentication via SMS verification
- Deep linking for alert sharing
- Push notifications
## Technical Stack
- React Native
- Expo framework
- GraphQL with Hasura
- Apollo Client for frontend
- Federated remote schemas
- Real-time subscriptions support
- Firebase Cloud Messaging (FCM) for push notifications only
- Sentry for error tracking
- MapLibre for mapping functionality
- Zustand for state management
- i18next for internationalization
- React Navigation for navigation
- Expo Updates for OTA updates
- Background Geolocation for location tracking
- Lottie for animations
- React Hook Form for form handling
- Axios for HTTP requests
- Yarn Berry as package manager
- ESLint and Prettier for code quality
- Fastlane for deployment automation
## Development Quick Start
### Prerequisites
- Node.js (version specified in `.node-version`)
- Yarn package manager
- Android Studio (for Android development)
- Xcode (for iOS development)
- Physical device or emulator/simulator
### Environment Setup
1. Clone the repository
2. Install dependencies:
```bash
yarn
```
3. Copy the staging environment file:
```bash
cp .env.staging.example .env.staging
```
4. Start the development server with staging environment:
```bash
yarn start:staging
```
### Running on Devices
#### Android
```bash
yarn android:staging
```
#### iOS
```bash
yarn ios:staging
```
### Staging URLs
The staging environment uses the following URLs:
- GraphQL API: `https://hasura-staging.alertesecours.fr/v1/graphql`
- WebSocket: `wss://hasura-staging.alertesecours.fr/v1/graphql`
- Files API: `https://files-staging.alertesecours.fr/api/v1/oas`
- Minio: `https://minio-staging.alertesecours.fr`
- Geolocation Sync: `https://api-staging.alertesecours.fr/api/v1/oas/geoloc/sync`
## Installation
### Android
#### Using the Yarn Script
The easiest way to install the app is to use the provided yarn script:
```bash
# Set the device ID (emulator or physical device)
export DEVICE=emulator-5554
# Run the installation script
yarn install:android
```
This script (`install-android.sh`) handles the entire installation process, including building APKs with signing, extracting them, and installing on the device.
#### Manual Installation
If you need to install the app manually, you can examine the `install-android.sh` script in the project root to see the detailed steps involved.
### iOS
#### Authentication Key Setup
1. Go to https://appstoreconnect.apple.com/access/integrations/api
2. Click the "+" button to generate a new API key
3. Give it a name (e.g., "AlerteSecours Build Key")
4. Download the .p8 file when prompted
5. Store the .p8 file in a secure location
6. Note down the Key ID and Issuer ID shown on the website
7. Set up environment variables:
```sh
export ASC_API_KEY_ID="YOUR_KEY_ID"
export ASC_API_ISSUER_ID="YOUR_ISSUER_ID"
export ASC_API_KEY_PATH="/path/to/your/AuthKey.p8"
```
#### Building and Running
To build and run the iOS app:
```bash
# Run in development mode with staging environment
yarn ios:staging
# Build for production (version + clean + archive + export)
yarn bundle:ios:build
# Upload the last build to App Store Connect
yarn bundle:ios:upload
# Build + upload
yarn bundle:ios:release
```
Notes on versioning:
- `yarn bundle:ios:build` updates iOS `CFBundleShortVersionString` and `CFBundleVersion` to a timestamp in `Europe/Paris` timezone (format `YYYYMMDDHHMM`) before archiving/exporting.
- `yarn bundle:ios` is an alias of `yarn bundle:ios:build`.
The `bundle:ios` command uses the scripts in the `scripts` directory:
- `ios-archive.sh` - Archives the iOS app
- `ios-export.sh` - Exports the archived app
- `ios-upload.sh` - Uploads the app to App Store Connect (used by `bundle:ios:upload`)
## Project Structure
- `/android` - Android-specific code and configuration
- `/ios` - iOS-specific code and configuration
- `/src` - Main application source code
- `/app` - App initialization and configuration
- `/assets` - Static assets (images, fonts, animations)
- `/auth` - Authentication-related code
- `/biz` - Business logic and constants
- `/components` - Reusable UI components
- `/containers` - Container components
- `/data` - Data management
- `/events` - Event handling
- `/finders` - Search and finder utilities
- `/gql` - GraphQL queries and mutations
- `/hoc` - Higher-order components
- `/hooks` - Custom React hooks
- `/i18n` - Internationalization
- `/layout` - Layout components
- `/lib` - Library code
- `/location` - Location-related functionality
- `/misc` - Miscellaneous utilities
- `/navigation` - Navigation configuration
- `/network` - Network-related code
- `/notifications` - Notification handling
- `/permissions` - Permission handling
- `/scenes` - Scene components
- `/screens` - Screen components
- `/sentry` - Sentry error tracking configuration
- `/stores` - State management stores
- `/theme` - Styling and theming
- `/updates` - Update handling
- `/utils` - Utility functions
- `/docs` - Documentation files
- `/scripts` - Utility scripts for building, deployment, and development
- `/e2e` - End-to-end tests
## Contributing
Guidelines for contributing to the project:
1. Follow the code style and conventions used in the project
2. Write tests for new features
3. Update documentation as needed
4. Use the ESLint and Prettier configurations
## Accessibility
This app has an accessibility baseline (WCAG 2.2 AA, VoiceOver/TalkBack) and app-specific conventions.
### Docs
- Baseline checklist: [`docs/a11y-wcag22-aa.md`](docs/a11y-wcag22-aa.md:1)
- Code conventions + helpers: [`docs/a11y-usage.md`](docs/a11y-usage.md:1)
- Color contrast guidance: [`docs/a11y-color-contrast.md`](docs/a11y-color-contrast.md:1)
- `testID` conventions: [`docs/testids.md`](docs/testids.md:1)
- QA runbook (iOS VoiceOver): [`docs/qa-voiceover.md`](docs/qa-voiceover.md:1)
- QA runbook (Android TalkBack): [`docs/qa-talkback.md`](docs/qa-talkback.md:1)
### PR checklist (required for any UI change)
- [ ] **Roles / labels / hints / states**: all interactive controls expose correct `accessibilityRole`, meaningful `accessibilityLabel`, helpful `accessibilityHint` (especially icon-only actions), and state where applicable.
- [ ] **Focus management**: any modal/dialog/sheet sets initial focus on open, returns focus on close, and avoids focus traps.
- [ ] **Touch target size**: critical tap targets are comfortably tappable (aim ~44x44pt minimum).
- [ ] **Color contrast**: text + icons meet WCAG AA contrast; do not rely on color alone for meaning.
- [ ] **`testID`s for critical controls**: stable `testID` added/updated for key actions and navigation chrome (per [`docs/testids.md`](docs/testids.md:1)).
- [ ] **Tests**: add/update tests covering the new UI behavior (and its states). Prefer assertions that dont depend on translated text; include E2E coverage for critical flows when applicable.
### Manual validation (screen readers)
When a PR changes UI or navigation, do a quick pass with the platform screen reader:
- iOS: follow [`docs/qa-voiceover.md`](docs/qa-voiceover.md:1) and validate labels/hints, navigation order, and activation behavior on the affected screens.
- Android: follow [`docs/qa-talkback.md`](docs/qa-talkback.md:1) with the same focus on discoverability, focus order, and activation.
## Troubleshooting
### Common Issues
#### Development Environment
- **Clearing Yarn Cache**: Use `yarn clean` (removes node_modules and reinstalls dependencies)
- **Cleaning Gradle**: Run `cd android && ./gradlew clean`
- **Clearing Gradle Cache**: Remove gradle caches with `rm -rf ~/.gradle/caches/ android/.gradle/`
- **Stopping Gradle Daemons**: Run `cd android && ./gradlew --stop`
- **Clearing ADB Cache**: Run `adb shell pm clear com.alertesecours`
- **Rebuilding Gradle**: Use `yarn expo run:android`
- **Rebuilding Expo React Native**: Use `yarn expo prebuild`
- **Clearing Metro Cache**: Use `yarn expo start --dev-client --clear`
#### Screenshots and Testing
- For Android screenshots: Use `scripts/screenshot-android.sh`
- For iOS screenshots: Use `scripts/screenshot-ios.sh`
- For Android emulator: Use `scripts/android-emulator`
#### Emulator Issues
- Clear cache / uninstall the app
- Check emulator datetime
- Check network connectivity
For more troubleshooting tips, see the documentation in the `/docs` directory.

22
app/Dockerfile Normal file
View file

@ -0,0 +1,22 @@
FROM reactnativecommunity/react-native-android:9
RUN groupadd -g 1000 ubuntu && useradd -rm -d /home/ubuntu -s /bin/bash -g ubuntu -G sudo -u 1000 ubuntu
USER 1000
WORKDIR /workspace
ENV HUSKY=0
COPY --chown=1000:1000 yarn.lock .yarnrc.yml ./
COPY --chown=1000:1000 .yarn .yarn
RUN yarn fetch --immutable
COPY --chown=1000:1000 . .
RUN yarn postinstall
RUN yarn expo prebuild
RUN cd android && \
./gradlew assemble
ENV APP_PORT=19000
CMD ["/bin/sh", "-c", "adb wait-for-device && yarn run android --port ${APP_PORT} && yarn start --port ${APP_PORT}"]

81
app/LICENSE.md Normal file
View file

@ -0,0 +1,81 @@
# DevTheFuture Ethical Use License (DEF License)
**Effective Date:** 2025
**Licensor:** DevTheFuture.org
**License URL:** [https://devthefuture.org/DEF-LICENSE.md](https://devthefuture.org/DEF-LICENSE.md)
**Licensed Software:** Alerte-Secours
* * *
## 1. **Definitions**
* **Software:** The original software provided under this license, including all parts, components, and any modifications or derivatives, as defined by the Licensor.
* **Nonprofit Use:** For the purposes of this Agreement, “Nonprofit Use” is defined in a manner consistent with similar provisions in licenses such as the PolyForm Noncommercial License. It refers to usage that does not primarily aim to generate financial gain, including activities by educational institutions, public organizations, or private individuals where any incidental revenue is purely ancillary to the primary noncommercial purpose.
* **Profit Use:** Any use of the Software that is intended to generate revenue, provide a commercial advantage, or otherwise support a for-profit enterprise. This includes, but is not limited to, integration into commercial products, services, or platforms where the primary goal is financial gain.
* **Personal Data Monetization:** The process by which personal data collected through the operation of the Software is exploited for commercial gain. For clarity, the License expressly prohibits any use of personal data for:
* Marketing, advertising, or political influence campaigns.
* The creation, maintenance, or enhancement of databases or data aggregation services that are not directly tied to the explicitly exposed functionalities of the Software as communicated to the end user.
* **Competitor:** Any individual, organization, or entity that develops, distributes, or monetizes software that directly competes with the Software in its intended field or market.
* * *
## 2. **Grant of License**
1. **Nonprofit Use:**
* The Licensor grants a perpetual, royalty-free, non-exclusive, and non-transferable license to use, modify, and distribute the Software for Nonprofit Use, provided that all users comply with Section 3 and any additional terms specified herein.
2. **Profit Use:**
* Use of the Software for Profit Use requires obtaining a paid license. The Licensor reserves the exclusive right to determine the terms, cost, and approval of any Profit Use license at its sole discretion.
* All requests for a Profit Use license must be submitted in writing, and the Licensor may approve or deny such requests based on factors including the intended use, the nature of the entity, and other relevant considerations.
* * *
## 3. **Restrictions on Personal Data Monetization**
* The Software **must not be used to monetize, sell, or exploit any personal data** collected through its operation.
* Specifically, any personal data obtained through the Software:
* **May not be used for any marketing or advertising purposes.**
* **May not be used to influence public opinion or political processes.**
* **May not be compiled into databases or used for data aggregation unless such use is an explicit and integral feature of the Software, as clearly disclosed to end users.**
* All users and licensees agree to these conditions. Violation of this section shall be considered a material breach of this Agreement.
* * *
## 4. **Ownership and Intellectual Property**
* The Software and all related intellectual property rights remain the exclusive property of the Licensor.
* Users are prohibited from removing or altering any copyright, trademark, or other proprietary notices contained within the Software.
* * *
## 5. **No Warranty**
* The Software is provided “as is,” without any express or implied warranties, including but not limited to warranties of merchantability, fitness for a particular purpose, or non-infringement.
* Under no circumstances shall the Licensor be liable for any claims, damages, or liabilities arising from the use or inability to use the Software.
* * *
## 6. **Termination and Cure Period**
* In the event of a breach of Sections 2, 3, or 8, the Licensor shall notify the Licensee of the breach and provide a cure period of **30 days** during which the Licensee may remedy the breach.
* If the breach is not remedied within this cure period, or if the breach is of a nature that the Licensor determines is irreparable, this license shall automatically terminate without further notice.
* Profit Use licenses may be terminated or revoked by the Licensor in accordance with the specific terms outlined in each Profit Use agreement.
* * *
## 7. **Governing Law and Dispute Resolution**
* This Agreement shall be governed by and construed in accordance with internationally recognized principles of commercial law, as well as any applicable local laws governing the use or distribution of the Software.
* In the event of any disputes, the parties agree to attempt resolution through negotiation before pursuing legal remedies in a competent jurisdiction.
* * *
## 8. **Competitor Restriction**
* **Competitor Limitation:** Any Competitor is prohibited from using, accessing, or distributing the Software in any capacity (whether under Nonprofit or Profit Use) without the explicit, prior written consent of the Licensor.
* **Profit Use Licensing for Competitors:** The Licensor reserves the right to evaluate and either approve or deny any Profit Use license request from a Competitor at its sole discretion, without obligation to justify the decision.
* * *
By using or accessing the Software, you acknowledge that you have read, understood, and agree to be bound by the terms of this DevTheFuture Ethical Use License (DEF License).
* * *

82
app/README.md Normal file
View file

@ -0,0 +1,82 @@
# Alerte Secours - Le Réflexe qui Sauve
[![Liberapay](https://img.shields.io/liberapay/receives/alerte-secours.svg?logo=liberapay)](https://liberapay.com/alerte-secours)
[![Buy Me a Coffee](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?logo=buy-me-a-coffee)](https://buymeacoffee.com/alertesecours)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/alerte-secours?style=social)](https://github.com/sponsors/alerte-secours)
Une application mobile pour la gestion des alertes et des fonctionnalités liées aux urgences, supportant les plateformes iOS et Android.
**Site Web Officiel :** [alerte-secours.fr](https://alerte-secours.fr)
## Aperçu du Projet
Alerte Secours est une application mobile construite avec React Native qui gère les alertes et les fonctionnalités liées aux urgences. L'application supporte les plateformes iOS et Android et inclut des fonctionnalités telles que :
- Création et gestion d'alertes avec mises à jour en temps réel
- Fonctionnalités basées sur la localisation avec intégration cartographique
- Système de chat/messagerie avec salles de discussion spécifiques aux alertes
- Authentification via vérification SMS
- Liens profonds pour le partage d'alertes
- Notifications push
## Documentation Développeur
Pour les développeurs souhaitant contribuer au projet ou déployer l'application, consultez la [documentation technique complète](DEVELOPER.md) qui contient :
- Aperçu du projet et fonctionnalités
- Stack technique détaillé
- Guide de démarrage rapide
- Instructions d'installation (Android/iOS)
- Structure du projet
- Guide de dépannage
- Instructions de build et déploiement
## Licence
Alerte Secours est sous licence **DevTheFuture Ethical Use License (DEF License)**. Points clés :
### Usage à but non lucratif
- Licence perpétuelle, libre de redevances et non exclusive pour usage à but non lucratif
- Permet l'utilisation, la modification et la distribution à des fins non lucratives
### Usage commercial
- Nécessite l'obtention d'une licence payante
- Conditions déterminées par le Concédant (DevTheFuture.org)
### Restrictions sur les données personnelles
- Ne doit pas être utilisé pour monétiser, vendre ou exploiter les données personnelles
- Les données personnelles ne peuvent pas être utilisées pour le marketing, la publicité ou l'influence politique
- L'agrégation de données n'est autorisée que si c'est une fonctionnalité explicite divulguée aux utilisateurs
### Restriction concurrentielle
- Les concurrents sont interdits d'utiliser le logiciel sans consentement explicite
Pour le texte complet de la licence, voir [LICENSE.md](LICENSE.md).
## 💙 Soutenir le projet
Alerte-Secours est une application mobile citoyenne, librement accessible, sans publicité ni exploitation de données.
Si vous souhaitez contribuer à son développement, sa maintenance et son indépendance :
- 🟡 **[Liberapay Soutien régulier](https://liberapay.com/alerte-secours)**
Pour un soutien **récurrent et engagé**. Chaque don contribue à assurer la stabilité du service sur le long terme.
- ☕ **[Buy Me a Coffee Don ponctuel](https://buymeacoffee.com/alertesecours)**
Pour un **coup de pouce ponctuel**, un café virtuel pour encourager le travail accompli !
- 🧑‍💻 **[GitHub Sponsors](https://github.com/sponsors/alerte-secours)**
Pour les développeurs et utilisateurs de GitHub : soutenez le projet directement via votre compte.
## Contribuer
Directives pour contribuer au projet :
1. Suivez le style de code et les conventions utilisées dans le projet
2. Écrivez des tests pour les nouvelles fonctionnalités
3. Mettez à jour la documentation si nécessaire
4. Utilisez les configurations ESLint et Prettier
## Support
Pour obtenir de l'aide, veuillez ouvrir un ticket sur notre tracker d'issues ou consulter la documentation dans le répertoire `/docs`.

16
app/android/.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
# OSX
#
.DS_Store
# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
*.hprof
.cxx/
# Bundle artifacts
*.jsbundle

11
app/android/Gemfile Normal file
View file

@ -0,0 +1,11 @@
source "https://rubygems.org"
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
gem 'xcodeproj', '< 1.26.0'
gem 'concurrent-ruby', '<= 1.3.4'
gem "fastlane"

View file

@ -0,0 +1,277 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()
static def versionToNumber(major, minor, patch) {
return patch * 100 + minor * 10000 + major * 1000000
}
def getRNVersion() {
def version = providers.exec {
workingDir(projectDir)
commandLine("node", "-e", "console.log(require('react-native/package.json').version);")
}.standardOutput.asText.get().trim()
def coreVersion = version.split("-")[0]
def (major, minor, patch) = coreVersion.tokenize('.').collect { it.toInteger() }
return versionToNumber(
major,
minor,
patch
)
}
def rnVersion = getRNVersion()
/**
* This is the configuration block to customize your React Native Android app.
* By default you don't need to apply any configuration, just uncomment the lines you need.
*/
react {
entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim())
reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc"
codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
// Use Expo CLI to bundle the app, this ensures the Metro config
// works correctly with Expo projects.
cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim())
bundleCommand = "export:embed"
if (rnVersion >= versionToNumber(0, 75, 0)) {
/* Autolinking */
autolinkLibrariesWithApp()
}
}
/**
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean()
/**
* The preferred build flavor of JavaScriptCore (JSC)
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
apply from: new File(["node", "--print", "require.resolve('@sentry/react-native/package.json')"].execute().text.trim(), "../sentry.gradle")
android {
// @generated begin react-native-background-geolocation-project - expo prebuild (DO NOT MODIFY) sync-451bbca0f2f08c9fc8b21a201ef5b476b165ba21
// Project background_geolocation = project(':react-native-background-geolocation')
// apply from: "${background_geolocation.projectDir}/app.gradle"
// @generated end react-native-background-geolocation-project
// @generated begin react-native-background-fetch-project - expo prebuild (DO NOT MODIFY) sync-56d2d70cbc3f26369dd5e711d0ab87bf3c0aebb3
// Project background_fetch = project(':react-native-background-fetch')
// @generated end react-native-background-fetch-project
ndkVersion rootProject.ext.ndkVersion
// buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
namespace 'com.alertesecours'
defaultConfig {
applicationId 'com.alertesecours'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 241
versionName "1.16.10"
multiDexEnabled true
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
// Define ABI flavors so we can install the right dev client on emulator vs device.
flavorDimensions 'abi'
productFlavors {
deviceArm64 {
dimension 'abi'
ndk { abiFilters 'arm64-v8a' }
}
emulatorX86_64 {
dimension 'abi'
ndk { abiFilters 'x86_64' }
}
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.release
// shrinkResources true // disabled, related to https://github.com/facebook/react-native/issues/25290#issuecomment-507700557
minifyEnabled true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
// @generated begin react-native-background-geolocation-proguard - expo prebuild (DO NOT MODIFY) sync-606db7f838db1722ea0ff547adceb798272bd706
// proguardFiles "${background_geolocation.projectDir}/proguard-rules.pro"
// @generated end react-native-background-geolocation-proguard
// @generated begin react-native-background-fetch-proguard - expo prebuild (DO NOT MODIFY) sync-7cb5d9a88ae03463dcde5b7e8571a725ecd5854f
// proguardFiles "${background_fetch.projectDir}/proguard-rules.pro"
// @generated end react-native-background-fetch-proguard
crunchPngs false
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
// Enable R8 full mode
debuggable false
jniDebuggable false
renderscriptDebuggable false
pseudoLocalesEnabled false
zipAlignEnabled true
// Generate and preserve the mapping file
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
// Resolve duplicate native libs shipped by multiple dependencies (e.g. op-sqlite + react-android).
// Needed for debug flavors too (merge<Variant>NativeLibs).
pickFirsts += [
'lib/**/libjsi.so',
'lib/**/libreactnative.so',
]
jniLibs {
useLegacyPackaging (findProperty('expo.useLegacyPackaging')?.toBoolean() ?: false)
}
}
}
// Apply static values from `gradle.properties` to the `android.packagingOptions`
// Accepts values in comma delimited lists, example:
// android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini
["pickFirsts", "excludes", "merges", "doNotStrip"].each { prop ->
// Split option: 'foo,bar' -> ['foo', 'bar']
def options = (findProperty("android.packagingOptions.$prop") ?: "").split(",");
// Trim all elements in place.
for (i in 0..<options.size()) options[i] = options[i].trim();
// `[] - ""` is essentially `[""].filter(Boolean)` removing all empty strings.
options -= ""
if (options.length > 0) {
println "android.packagingOptions.$prop += $options ($options.length)"
// Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
options.each {
android.packagingOptions[prop] += it
}
}
}
configurations.all {
resolutionStrategy {
// Force non-native UCrop artifact (no .so), avoids 64KB page size issue from 2.2.6-native
force "com.github.yalantis:ucrop:2.2.6"
// Force Fresco/FBJNI versions with 16KB page support (or newer)
force "com.facebook.fresco:fresco:3.6.0"
force "com.facebook.fresco:imagepipeline:3.6.0"
force "com.facebook.fresco:imagepipeline-base:3.6.0"
force "com.facebook.fresco:gifdecoder:3.6.0"
force "com.facebook.fresco:nativeimagetranscoder:3.6.0"
force "com.facebook.fresco:static-webp:3.6.0"
force "com.facebook.fresco:webpsupport:3.6.0"
force "com.facebook.fresco:animated-webp:3.6.0"
force "com.facebook.fresco:animated-gif:3.6.0"
force "com.facebook.fbjni:fbjni:0.6.0"
}
// Exclude Huawei UCS native credential libs from Play build (causes 64KB alignment)
exclude group: "com.huawei.hms", module: "ucs-credential"
exclude group: "com.huawei.hms", module: "ucs-credential-developers"
exclude group: "com.huawei.hms.LocationLiteSdk", module: "core"
// Exclude Fresco native pipeline and webp natives to drop 0x1000 .so files
}
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
// Ensure Fresco core API available for app-level initialization (MainApplication)
implementation("com.facebook.fresco:fresco:3.6.0")
// Ensure MemoryChunkType and related API are available
implementation("com.facebook.fresco:imagepipeline-base:3.6.0")
// Include native pipeline so libimagepipeline.so is present (3.6.0 expected 16KB aligned)
implementation("com.facebook.fresco:imagepipeline-native:3.6.0")
def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
if (isGifEnabled) {
// For animated gif support
implementation("com.facebook.fresco:animated-gif:${reactAndroidLibs.versions.fresco.get()}")
}
if (isWebpEnabled) {
// For webp support
implementation("com.facebook.fresco:webpsupport:${reactAndroidLibs.versions.fresco.get()}")
if (isWebpAnimatedEnabled) {
// Animated webp support
implementation("com.facebook.fresco:animated-webp:${reactAndroidLibs.versions.fresco.get()}")
}
}
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
implementation 'androidx.multidex:multidex:2.0.1'
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
}
if (rnVersion < versionToNumber(0, 75, 0)) {
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
}
apply plugin: 'com.google.gms.google-services'
// Add this at the end of the file
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(com.android.build.OutputFile.ABI)
if (abi != null) {
output.versionCodeOverride = variant.versionCode * 1000 + versionCodes.get(abi, 0)
}
output.outputFileName = "alertesecours-${variant.versionName}-${variant.buildType.name}.apk"
}
if (variant.buildType.name == 'release') {
variant.assembleProvider.get().doLast {
copy {
from variant.mappingFileProvider.get().singleFile
into "${rootProject.buildDir}/outputs/mapping/${variant.name}"
rename { String fileName ->
"mapping-${variant.name}-${variant.versionName}.txt"
}
}
}
}
}

Binary file not shown.

View file

@ -0,0 +1,31 @@
{
"project_info": {
"project_number": "YOUR_PROJECT_NUMBER_HERE",
"project_id": "YOUR_PROJECT_ID_HERE",
"storage_bucket": "YOUR_STORAGE_BUCKET_HERE"
},
"client": [{
"client_info": {
"mobilesdk_app_id": "YOUR_MOBILESDK_APP_ID_HERE",
"android_client_info": {
"package_name": "com.alertesecours"
}
},
"oauth_client": [{
"client_id": "YOUR_CLIENT_ID_HERE",
"client_type": 3
}],
"api_key": [{
"current_key": "YOUR_API_KEY_HERE"
}],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [{
"client_id": "YOUR_CLIENT_ID_HERE",
"client_type": 3
}]
}
}
}],
"configuration_version": "1"
}

14
app/android/app/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,14 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# react-native-reanimated
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }
# Add any project specific keep options here:

View file

@ -0,0 +1,29 @@
package com.alertesecours; // (1)
import com.wix.detox.Detox;
import com.wix.detox.config.DetoxConfig;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class DetoxTest {
@Rule // (2)
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
@Test
public void runDetoxTests() {
DetoxConfig detoxConfig = new DetoxConfig();
detoxConfig.idlePolicyConfig.masterTimeoutSec = 90;
detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60;
detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60);
Detox.runTests(mActivityRule, detoxConfig);
}
}

View file

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
</manifest>

View file

@ -0,0 +1,85 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<queries>
<intent>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
</intent>
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="geo"/>
</intent>
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="waze"/>
</intent>
</queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:networkSecurityConfig="@xml/network_security_config" android:fullBackupContent="@xml/secure_store_backup_rules" android:dataExtractionRules="@xml/secure_store_data_extraction_rules">
<meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/notification_icon_color" tools:replace="android:resource"/>
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon"/>
<meta-data android:name="com.transistorsoft.locationmanager.license" android:value="eyJhbGciOiJFZERTQSIsImtpZCI6ImVkMjU1MTktbWFpbi12MSJ9.eyJvcyI6ImFuZHJvaWQiLCJhcHBfaWQiOiJjb20uYWxlcnRlc2Vjb3VycyIsIm9yZGVyX251bWJlciI6ODY0MCwicmVuZXdhbF91cmwiOiJodHRwczovL3Nob3AudHJhbnNpc3RvcnNvZnQuY29tL2NhcnQvMTY1MDc4NjE1MDU6MT9ub3RlPTYxOTMiLCJjdXN0b21lcl9pZCI6NTc0MiwicHJvZHVjdCI6InJlYWN0LW5hdGl2ZS1iYWNrZ3JvdW5kLWdlb2xvY2F0aW9uIiwia2V5X3ZlcnNpb24iOjEsImFsbG93ZWRfc3VmZml4ZXMiOlsiLmRldiIsIi5kZXZlbG9wbWVudCIsIi5zdGFnaW5nIiwiLnN0YWdlIiwiLnFhIiwiLnVhdCIsIi50ZXN0IiwiLmRlYnVnIl0sIm1heF9idWlsZF9zdGFtcCI6MjAyNzAyMjIsImdyYWNlX2J1aWxkcyI6MCwiZW50aXRsZW1lbnRzIjpbImNvcmUiXSwiaWF0IjoxNzY5MTI2Mjg5fQ.sCJRdXJ78r2B0BLfht-AnYXSoF5pcTxAfEkCcX6BN7FiYc8GT9RUMlqDdwacD6UlI0v6WLhQck6lPkRgCq4MDQ"/>
<meta-data android:name="expo.modules.notifications.default_notification_color" android:resource="@color/notification_icon_color"/>
<meta-data android:name="expo.modules.notifications.default_notification_icon" android:resource="@drawable/notification_icon"/>
<meta-data android:name="expo.modules.updates.CODE_SIGNING_CERTIFICATE" android:value="-----BEGIN CERTIFICATE-----&#xD;&#xA;MIICzTCCAbWgAwIBAgIJR0KfFDoMJrYZMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV&#xD;&#xA;BAMTBHRlc3QwIBcNMjQwODE4MTU0OTExWhgPMjEyNDA4MTgxNTQ5MTFaMA8xDTAL&#xD;&#xA;BgNVBAMTBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCk46qR&#xD;&#xA;a0Do2fpBDtif18a/WQNWHm/xseHsh97bZdt8ooV4PQooK6VZUbADUhhJXqqomapa&#xD;&#xA;yFMJX7sZzfBUF7/xMrWDrgS0R4FLbXijAolhpXoqMkBCx3toKUCbU4ljA+Lz/BX1&#xD;&#xA;AEqVWqAweNzNDi4bvd1PG1/sQuuEtoZuSVfTPRAjF8vVkWyn8nfkorTtMYaw2QFu&#xD;&#xA;ugs1wp7YieD4C8CIK5gMX7f8bxx3l7BR50bf+9MHJFI+eTjmoFoJFEVWbCcrOrky&#xD;&#xA;FLM0+NrMI2fZYunrN6jcKc/NKEaDKb1VDO9yrLcFQOtXJJIXz94/lS6kHDjzEgUV&#xD;&#xA;zx3uaDbAdSQsyZxxAgMBAAGjKjAoMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8E&#xD;&#xA;DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEASIjMvS3N9NEPeakUmYXg&#xD;&#xA;MEyjaX+N/62Pbcp4taU4G9vDB/fyDqMMef8+CWBpo/noXqzt4K6k1id7UwdZhRks&#xD;&#xA;xdBTSf1x5yzDB24mbqNAvPa2q8G6KIoNZuvLUDz35366FxR+vTHQmp2d4Yz92kIL&#xD;&#xA;EEmFr8eMHf60tfHG+em97p+evmXDyBjF3CwOvtuzog1wCF/AsJ1d0gbPPMKdAHKC&#xD;&#xA;LZHsiXJ5i/oFuYzWkDDJkO9bb6HaQplt/46iC0CyM6SsT6H8kkDVQbfQCH1JAXsL&#xD;&#xA;Knk10FbAMKJ7GWbAdsdcbNZlDMrzPprw8N/fpGc7RHdHBwKcFm44mNtrMrzEd4eX&#xD;&#xA;pQ==&#xD;&#xA;-----END CERTIFICATE-----&#xD;&#xA;"/>
<meta-data android:name="expo.modules.updates.CODE_SIGNING_METADATA" android:value="{&quot;keyid&quot;:&quot;main&quot;,&quot;alg&quot;:&quot;rsa-v1_5-sha256&quot;}"/>
<meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
<meta-data android:name="expo.modules.updates.EXPO_RUNTIME_VERSION" android:value="@string/expo_runtime_version"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ERROR_RECOVERY_ONLY"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="https://expo-updates.alertesecours.fr/api/manifest?project=alerte-secours&amp;channel=release"/>
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode|locale|layoutDirection" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="com.alertesecours"/>
<data android:scheme="exp+alerte-secours"/>
</intent-filter>
<intent-filter>
<action android:name="com.alertesecours.OPEN_ALERT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="com.alertesecours.OPEN_RELATIVES"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="com.alertesecours.OPEN_BACKGROUND_GEOLOCATION_SETTINGS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter android:autoVerify="true" data-generated="true">
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="https" android:host="app.alertesecours.fr" android:pathPrefix="/"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
<provider android:name="com.facebook.drawee.backends.pipeline.FrescoInitProvider" tools:node="remove"/>
<provider android:name=".FrescoInitProvider" android:authorities="${applicationId}.frescoinit" android:exported="false" android:initOrder="100"/>
</application>
</manifest>

View file

@ -0,0 +1,49 @@
package com.alertesecours
import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig
/**
* Initializes Fresco as early as possible (before Application.onCreate),
* with native code disabled so no libimagepipeline.so is ever requested.
*
* This prevents crashes on devices enforcing 16KB page size when the native
* Fresco pipeline is not packaged.
*/
class FrescoInitProvider : ContentProvider() {
override fun onCreate(): Boolean {
val ctx = context ?: return false
// Use default (native) pipeline; libimagepipeline.so is now packaged (3.6.0, 16KB aligned)
val config = ImagePipelineConfig.newBuilder(ctx).build()
Fresco.initialize(ctx, config)
return true
}
override fun query(
uri: Uri,
projection: Array<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
sortOrder: String?
): Cursor? = null
override fun getType(uri: Uri): String? = null
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int = 0
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<out String>?
): Int = 0
}

View file

@ -0,0 +1,71 @@
package com.alertesecours
import expo.modules.splashscreen.SplashScreenManager
import android.os.Build
import android.os.Bundle
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import expo.modules.ReactActivityDelegateWrapper
import com.github.wumke.RNImmediatePhoneCall.RNImmediatePhoneCallModule
class MainActivity : ReactActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Set the theme to AppTheme BEFORE onCreate to support
// coloring the background, status bar, and navigation bar.
// This is required for expo-splash-screen.
// setTheme(R.style.AppTheme);
// @generated begin expo-splashscreen - expo prebuild (DO NOT MODIFY) sync-f3ff59a738c56c9a6119210cb55f0b613eb8b6af
SplashScreenManager.registerOnActivity(this)
// @generated end expo-splashscreen
super.onCreate(null)
}
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
override fun getMainComponentName(): String = "main"
/**
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
*/
override fun createReactActivityDelegate(): ReactActivityDelegate {
return ReactActivityDelegateWrapper(
this,
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
object : DefaultReactActivityDelegate(
this,
mainComponentName,
fabricEnabled
){})
}
/**
* Align the back button behavior with Android S
* where moving root activities to background instead of finishing activities.
* @see <a href="https://developer.android.com/reference/android/app/Activity#onBackPressed()">onBackPressed</a>
*/
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
RNImmediatePhoneCallModule.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun invokeDefaultOnBackPressed() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
if (!moveTaskToBack(false)) {
// For non-root activities, use the default implementation to finish them.
super.invokeDefaultOnBackPressed()
}
return
}
// Use the default back button implementation on Android S
// because it's doing more than [Activity.moveTaskToBack] in fact.
super.invokeDefaultOnBackPressed()
}
}

View file

@ -0,0 +1,61 @@
package com.alertesecours
import android.app.Application
import android.content.res.Configuration
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.ReactHost
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig
import expo.modules.ApplicationLifecycleDispatcher
import expo.modules.ReactNativeHostWrapper
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
this,
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> {
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return PackageList(this).packages
}
override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
)
override val reactHost: ReactHost
get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
SoLoader.init(this, OpenSourceMergedSoMapping)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
ApplicationLifecycleDispatcher.onApplicationCreate(this)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View file

@ -0,0 +1,6 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/splashscreen_background"/>
<item>
<bitmap android:gravity="center" android:src="@drawable/splashscreen_logo"/>
</item>
</layer-list>

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
android:insetTop="@dimen/abc_edit_text_inset_top_material"
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"
>
<selector>
<!--
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
-->
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
</selector>
</inset>

View file

@ -0,0 +1,3 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/splashscreen_background"/>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,7 @@
<resources>
<string name="app_name">Alerte Secours</string>
<!-- French permission message for background geolocation -->
<string name="message_permission_required">Alerte Secours nécessite la localisation en arrière-plan pour les alertes de proximité.</string>
<string name="title_permission_required">Autorisation requise</string>
</resources>

View file

@ -0,0 +1 @@
<resources/>

View file

@ -0,0 +1,7 @@
<resources>
<color name="splashscreen_background">#364fc7</color>
<color name="iconBackground">#FFFFFF</color>
<color name="colorPrimary">#023c69</color>
<color name="colorPrimaryDark">#364fc7</color>
<color name="notification_icon_color">#364fc7</color>
</resources>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#364fc7</color>
</resources>

View file

@ -0,0 +1,9 @@
<resources>
<string name="app_name">Alerte Secours</string>
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
<string name="expo_system_ui_user_interface_style" translatable="false">automatic</string>
<string name="expo_runtime_version">1.0.0</string>
<string name="message_permission_required">Alerte Secours nécessite la localisation en arrière-plan pour les alertes de proximité.</string>
<string name="title_permission_required">Autorisation requise</string>
</resources>

View file

@ -0,0 +1,20 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textColor">@android:color/black</item>
<item name="android:editTextStyle">@style/ResetEditText</item>
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="android:statusBarColor">#364fc7</item>
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
</style>
<style name="ResetEditText" parent="@android:style/Widget.EditText">
<item name="android:padding">0dp</item>
<item name="android:textColorHint">#c8c8c8</item>
<item name="android:textColor">@android:color/black</item>
</style>
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_logo</item>
<item name="postSplashScreenTheme">@style/AppTheme</item>
</style>
</resources>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>

85
app/android/build.gradle Normal file
View file

@ -0,0 +1,85 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
// @generated begin expo-gradle-ext-vars - expo prebuild (DO NOT MODIFY) sync-a14167d3df9d6380c3d77a8f8070215ea8a94013
googlePlayServicesLocationVersion = "21.1.0"
appCompatVersion = "1.4.2"
// @generated end expo-gradle-ext-vars
// buildToolsVersion = findProperty('android.buildToolsVersion') ?: '34.0.0'
minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24')
compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35')
targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '35')
kotlinVersion = findProperty('android.kotlinVersion') ?: '2.0.21'
ndkVersion = "27.2.12479018"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.google.gms:google-services:4.4.1'
classpath('com.android.tools.build:gradle:8.6.0')
classpath('com.facebook.react:react-native-gradle-plugin')
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
apply plugin: "com.facebook.react.rootproject"
allprojects {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
}
maven {
// Android JSC is installed from npm
url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist'))
}
google()
mavenCentral()
maven { url 'https://www.jitpack.io' }
maven {
url "$rootDir/../node_modules/@notifee/react-native/android/libs"
}
// https://github.com/Lyokone/flutterlocation/issues/802#issuecomment-1415980821
// configurations.all {
// resolutionStrategy {
// force "com.google.android.gms:play-services-location:21.0.1"
// }
// }
maven {
url("$rootDir/../node_modules/detox/Detox-android")
}
}
}
/**
* Force 16KB page size at link time for all subprojects that build native code with CMake.
* Use projectsEvaluated to avoid afterEvaluate on already-evaluated projects.
*/
gradle.projectsEvaluated {
subprojects { proj ->
def androidExt = proj.extensions.findByName("android")
if (androidExt != null &&
androidExt.hasProperty("externalNativeBuild") &&
androidExt.externalNativeBuild?.cmake != null) {
try {
def flag = "-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384"
def args = androidExt.externalNativeBuild.cmake.arguments
if (args == null || args.isEmpty()) {
androidExt.externalNativeBuild.cmake.arguments = [flag]
} else if (!args.contains(flag)) {
androidExt.externalNativeBuild.cmake.arguments += flag
}
} catch (Throwable ignored) {
// ignore if structure differs for a subproject
}
}
}
}

View file

@ -0,0 +1,2 @@
json_key_file("keys/alerte-secours-449609-469f820e5960.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("com.alertesecours") # e.g. com.krausefx.app

View file

@ -0,0 +1,38 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:android)
platform :android do
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
desc "Submit a new Beta Build to Crashlytics Beta"
lane :beta do
gradle(task: "clean assembleRelease")
crashlytics
# sh "your_script.sh"
# You can also use other beta testing services here
end
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(task: "clean assembleRelease")
upload_to_play_store
end
end

View file

@ -0,0 +1,72 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enable AAPT2 PNG crunching
android.enablePngCrunchInReleaseBuilds=true
# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew <task> -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86_64
# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
# Enable GIF support in React Native images (~200 B increase)
expo.gif.enabled=true
# Enable webp support in React Native images (~85 KB increase)
expo.webp.enabled=true
# Enable animated webp support (~3.4 MB increase)
# Disabled by default because iOS doesn't support animated webp
expo.webp.animated=false
# Enable network inspector
EX_DEV_CLIENT_NETWORK_INSPECTOR=true
# Use legacy packaging to compress native libraries in the resulting APK.
expo.useLegacyPackaging=false
android.extraMavenRepos=[]
android.enableProguardInReleaseBuilds=true
# fix notifee + expo-update crash, see https://github.com/expo/expo/issues/15298
EX_UPDATES_ANDROID_DELAY_LOAD_APP=false
# Ensure we always pick the NDK r27 libc++_shared.so we vendor in jniLibs
android.packagingOptions.pickFirsts=**/libc++_shared.so
# Whether the app is configured to use edge-to-edge via the app config or `react-native-edge-to-edge` plugin
expo.edgeToEdgeEnabled=false

Binary file not shown.

View file

@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

249
app/android/gradlew vendored Executable file
View file

@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

92
app/android/gradlew.bat vendored Normal file
View file

@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View file

@ -0,0 +1,19 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.9.24"
id("java-gradle-plugin")
}
repositories {
mavenCentral()
}
gradlePlugin {
plugins {
create("reactSettingsPlugin") {
id = "com.facebook.react.settings"
implementationClass = "expo.plugins.ReactSettingsPlugin"
}
}
}

View file

@ -0,0 +1,10 @@
package expo.plugins
import org.gradle.api.Plugin
import org.gradle.api.initialization.Settings
class ReactSettingsPlugin : Plugin<Settings> {
override fun apply(settings: Settings) {
// Do nothing, just register the plugin.
}
}

View file

@ -0,0 +1,4 @@
defaults.url=https://sentry.io
defaults.org=devthefuture-40
defaults.project=alertesecours-application
# Using SENTRY_AUTH_TOKEN environment variable

View file

@ -0,0 +1,70 @@
pluginManagement {
def version = providers.exec {
commandLine("node", "-e", "console.log(require('react-native/package.json').version);")
}.standardOutput.asText.get().trim()
def (_, reactNativeMinor, reactNativePatch) = version.split("-")[0].tokenize('.').collect { it.toInteger() }
plugins {
id("com.google.devtools.ksp") version "2.0.21-1.0.25"
}
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile().toString())
if(reactNativeMinor == 74 && reactNativePatch <= 3){
includeBuild("react-settings-plugin")
}
}
plugins { id("com.facebook.react.settings") }
def getRNMinorVersion() {
def version = providers.exec {
commandLine("node", "-e", "console.log(require('react-native/package.json').version);")
}.standardOutput.asText.get().trim()
def coreVersion = version.split("-")[0]
def (major, minor, patch) = coreVersion.tokenize('.').collect { it.toInteger() }
return minor
}
if (getRNMinorVersion() >= 75) {
extensions.configure(com.facebook.react.ReactSettingsExtension) { ex ->
if (System.getenv('EXPO_UNSTABLE_CORE_AUTOLINKING') == '1') {
println('\u001B[32mUsing expo-modules-autolinking as core autolinking source\u001B[0m')
def command = [
'node',
'--no-warnings',
'--eval',
'require(require.resolve(\'expo-modules-autolinking\', { paths: [require.resolve(\'expo/package.json\')] }))(process.argv.slice(1))',
'react-native-config',
'--json',
'--platform',
'android'
].toList()
ex.autolinkLibrariesFromCommand(command)
} else {
ex.autolinkLibrariesFromCommand()
}
}
}
rootProject.name = 'Alerte Secours'
dependencyResolutionManagement {
versionCatalogs {
reactAndroidLibs {
from(files(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../gradle/libs.versions.toml")))
}
}
}
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
useExpoModules()
if (getRNMinorVersion() < 75) {
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
applyNativeModulesSettingsGradle(settings)
}
include ':app'
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile())

209
app/app.config.js Normal file
View file

@ -0,0 +1,209 @@
const packageJson = require("./package.json");
const { version, customExpoVersioning } = packageJson;
const withXcode15Fix = require("./plugins/withXcode15Fix");
let config = {
expo: {
name: "Alerte Secours",
slug: "alerte-secours",
runtimeVersion: `${version.split(".")[0]}.0.0`,
version,
updates: {
url: "https://expo-updates.alertesecours.fr/api/manifest?project=alerte-secours&channel=release",
enabled: true,
checkAutomatically: "ON_ERROR_RECOVERY",
fallbackToCacheTimeout: 0,
codeSigningCertificate: "./keys/certificate.pem",
codeSigningPrivateKey: "./keys/private-key.pem",
codeSigningMetadata: {
keyid: "main",
alg: "rsa-v1_5-sha256",
},
},
orientation: "portrait",
userInterfaceStyle: "automatic",
splash: {
image: "./src/assets/img/splash-icon.png",
backgroundColor: "#364fc7",
resizeMode: "contain",
imageWidth: 200,
},
// Add notification configuration at root level
notification: {
androidMode: "default",
androidCollapsedTitle: "#{unread_notifications} nouvelles notifications",
// Use mipmap for the notification icon
icon: "./src/assets/img/notification-android.png",
color: "#364fc7",
},
platforms: ["ios", "android"],
android: {
versionCode: customExpoVersioning.versionCode,
googleServicesFile:
process.env.ANDROID_GOOGLE_SERVICES_FILE_PATH ||
"./android/app/google-services.json",
package: "com.alertesecours",
intentFilters: [
{
action: "VIEW",
data: {
scheme: "https",
host: "app.alertesecours.fr",
pathPrefix: "/",
},
category: ["BROWSABLE", "DEFAULT"],
autoVerify: true,
},
],
permissions: [
"android.permission.ACCESS_BACKGROUND_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.CALL_PHONE",
"android.permission.CAMERA",
"android.permission.INTERNET",
"android.permission.MODIFY_AUDIO_SETTINGS",
"android.permission.READ_CONTACTS",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.READ_MEDIA_IMAGES",
"android.permission.RECORD_AUDIO",
"android.permission.SYSTEM_ALERT_WINDOW",
"android.permission.VIBRATE",
"android.permission.WRITE_CONTACTS",
"android.permission.WRITE_EXTERNAL_STORAGE",
],
},
ios: {
buildNumber: customExpoVersioning.buildNumber.toString(),
googleServicesFile:
process.env.IOS_GOOGLE_SERVICES_FILE_PATH ||
"./ios/GoogleService-Info.plist",
userInterfaceStyle: "automatic",
supportsTablet: true,
bundleIdentifier: "com.alertesecours.alertesecours",
associatedDomains: ["applinks:app.alertesecours.fr"],
icon: "./src/assets/img/logo.png",
entitlements: {
"aps-environment": "production",
},
config: {
usesNonExemptEncryption: false,
},
infoPlist: {
NSCameraUsageDescription:
"Alerte-Secours requiert l'accès à votre caméra pour vous permettre de prendre une photo de profil. Cette fonctionnalité est utilisée uniquement lors de la personnalisation de votre compte.",
NSContactsUsageDescription:
"Alerte-Secours demande l'accès à vos contacts pour afficher les noms associés aux numéros de téléphone. Ces informations restent strictement sur votre appareil et ne sont jamais partagées ni transmises à des tiers.",
NSLocationAlwaysAndWhenInUseUsageDescription:
"Alerte-Secours nécessite la localisation en arrière-plan pour vous alerter en temps réel lorsqu'une personne à proximité a besoin d'aide urgente. Cette fonction est essentielle pour permettre une intervention rapide et efficace en cas d'urgence.",
NSLocationWhenInUseUsageDescription:
"Alerte-Secours utilise votre localisation pour identifier et vous diriger vers les personnes nécessitant une assistance à proximité. Cette fonction est cruciale pour une intervention rapide et précise en cas d'urgence.",
NSLocationAccuracyReduced:
"Alerte-Secours nécessite une localisation précise pour optimiser l'assistance aux personnes en détresse. Cette précision est essentielle pour localiser efficacement et rejoindre rapidement les personnes ayant besoin d'aide.",
NSMicrophoneUsageDescription:
"Alerte-Secours requiert l'accès au microphone pour l'enregistrement de messages vocaux. Cette fonction permet une communication plus rapide et plus claire en situation d'urgence.",
NSMotionUsageDescription:
"Alerte-Secours utilise la détection de mouvement pour optimiser la géolocalisation en arrière-plan, réduisant ainsi la consommation de batterie. Aucune donnée de mouvement n'est stockée ni transmise.",
NSPhotoLibraryUsageDescription:
"Alerte-Secours demande l'accès à votre photothèque uniquement pour vous permettre de sélectionner une photo de profil. Cette fonctionnalité est utilisée exclusivement pour la personnalisation de votre compte.",
NSUserNotificationUsageDescription:
"Alerte-Secours utilise les notifications pour vous informer immédiatement lorsqu'une personne à proximité nécessite une assistance urgente. Ces alertes sont essentielles pour une réponse rapide aux situations d'urgence.",
LSApplicationQueriesSchemes: [
"http",
"https",
"comgooglemaps",
"maps",
"waze",
"citymapper",
"uber",
"lyft",
"transit",
"truckmap",
"waze-na",
"yandexnavi",
"moovit",
"yandexmaps",
"kakaomap",
"szn-mapy",
"mapsme",
"osmand",
"gett",
"nmap",
"dgis",
"tel",
"telprompt",
],
BGTaskSchedulerPermittedIdentifiers: [
"com.transistorsoft",
"com.transistorsoft.fetch",
"com.transistorsoft.customtask",
],
},
UIBackgroundModes: ["location", "fetch", "processing"],
TSLocationManagerLicense: process.env.BACKGROUND_GEOLOCATION_LICENSE_IOS,
},
plugins: [
[
"expo-gradle-ext-vars",
{
googlePlayServicesLocationVersion: "21.1.0",
appCompatVersion: "1.4.2",
},
],
"@maplibre/maplibre-react-native",
"expo-location",
"react-native-map-link",
"expo-localization",
"expo-secure-store",
[
"@sentry/react-native/expo",
{
url: process.env.SENTRY_URL,
organization: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
android: {
// Android release name format
release: `com.alertesecours@${version}+${customExpoVersioning.versionCode}`,
},
ios: {
// iOS release name format
release: `com.alertesecours.alertesecours@${version}+${customExpoVersioning.buildNumber}`,
},
},
],
"@react-native-firebase/app",
"@react-native-firebase/messaging",
[
// see https://rnfirebase.io/#configure-react-native-firebase-modules
"expo-build-properties",
{
ios: {
useFrameworks: "static",
deploymentTarget: "15.1",
},
android: {
enableProguardInReleaseBuilds: true,
enableDexGuardInReleaseBuilds: true,
extraProperties: {
"android.nonTransitiveRClass": true,
"android.useAndroidX": true,
},
},
},
],
"expo-audio",
"./plugins/withXcode15Fix",
"./plugins/withCustomScheme", // Preserve URL schemes during prebuild
],
// Disable Flipper
extra: {
flipperEnabled: false,
},
},
};
// Apply plugins
config = withXcode15Fix(config);
config = require("./plugins/withCustomScheme")(config);
module.exports = config;

Some files were not shown because too many files have changed in this diff Show more