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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .githooks/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
# .githooks — enforcement de versionado (Atenea)
# .githooks — versioning enforcement

Hooks git-native (POSIX, sin dependencias). Corren para **cualquier** commit, hecho por una
persona o por un agente. Alinean el manual de versionado del equipo.
Git-native hooks (POSIX, no dependencies). They run for **every** commit, whether made by a
person or by an agent, and enforce the team's versioning rules.

- **`commit-msg`** — bloquea el commit si el mensaje no sigue Conventional Commits
(`<tipo>(<alcance>)(!): descripción`). Avisa (no bloquea) si el tipo no cuadra con el prefijo
de la rama.
- **`pre-commit`** — bloquea commits directos sobre `main` o `beta` (el desarrollo va en ramas
temporales). Escape para promoción de release: `ATENEA_ALLOW_PROTECTED=1 git commit ...`.
- **`commit-msg`** — rejects the commit if the message is not a Conventional Commit
(`<type>(<scope>)(!): description`). Warns (does not block) when the type does not match the
branch prefix.
- **`pre-commit`** — blocks direct commits on `main` or `beta` (development happens on
temporary branches). Escape for release promotion: `ATENEA_ALLOW_PROTECTED=1 git commit ...`.

## Activación
## Activation

`core.hooksPath` es config local por clon (no se versiona), así que cada clon la activa una vez.
El proyecto lo automatiza con un script `prepare` en `package.json`:
`core.hooksPath` is a per-clone local setting (it is not versioned), so each clone enables it
once. The project automates it with a `prepare` script in `package.json`:

```json
"scripts": { "prepare": "git config core.hooksPath .githooks || true" }
```

Así, en cada `yarn install` queda cableado. Manual, si hiciera falta:
That way every `npm install` wires it up. Manually, if needed:

```bash
git config core.hooksPath .githooks
chmod +x .githooks/*
```

Bypass puntual de un hook (no recomendado): `git commit --no-verify`.
One-off bypass of a hook (not recommended): `git commit --no-verify`.
48 changes: 24 additions & 24 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
#!/bin/sh
# ─────────────────────────────────────────────────────────────────────────
# Atenea · commit-msg · valida Conventional Commits (manual de versionado Venteks)
# Atenea · commit-msg · validates Conventional Commits (Venteks versioning manual)
#
# Git-native: corre para CUALQUIER commit (humano o agente), esté o no Claude.
# Bloquea el commit si el mensaje no cumple. Escape puntual: git commit --no-verify.
# Git-native: runs for ANY commit (human or agent), with or without Claude.
# Blocks the commit if the message does not comply. One-off escape: git commit --no-verify.
#
# Formato exigido: <tipo>(<alcance opcional>)(!): <descripción en imperativo>
# tipos: feat fix docs style refactor perf test build ci chore revert
# ejemplos: feat(auth): agregar login por sesión
# fix: corregir cálculo de permisos
# feat(store)!: cambiar shape del estado (BREAKING CHANGE)
# Required format: <type>(<optional scope>)(!): <imperative description>
# types: feat fix docs style refactor perf test build ci chore revert
# examples: feat(auth): add session login
# fix: correct permission calculation
# feat(store)!: change the state shape (BREAKING CHANGE)
# ─────────────────────────────────────────────────────────────────────────

msg_file="$1"
first_line="$(head -n 1 "$msg_file")"

# Saltar commits de merge/revert automáticos y fixup/squash.
# Skip automatic merge/revert commits and fixup/squash.
case "$first_line" in
"Merge "*|"Revert "*|"fixup!"*|"squash!"*) exit 0 ;;
esac

pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9._/-]+\))?(!)?: .+'

if printf '%s' "$first_line" | grep -Eq "$pattern"; then
# Aviso suave: coherencia tipo ↔ prefijo de rama (no bloquea).
# Una rama feat/* es un contenedor de feature: acumula fix/docs/refactor/chore/
# test intermedios de forma legítima, así que NO se avisa sobre ella. Solo se
# revisan fix/* y hotfix/*, que son de propósito único.
# Soft warning: type ↔ branch prefix consistency (does not block).
# A feat/* branch is a feature container: it legitimately accumulates intermediate
# fix/docs/refactor/chore/test commits, so it is NOT warned about. Only fix/* and
# hotfix/* are checked, since they have a single purpose.
branch="$(git symbolic-ref --short HEAD 2>/dev/null || echo '')"
type="$(printf '%s' "$first_line" | sed -E 's/^([a-z]+).*/\1/')"
case "$branch" in
fix/*) [ "$type" = "fix" ] || printf '⚠️ Atenea: rama fix/* pero commit "%s" (¿debería ser fix?)\n' "$type" >&2 ;;
hotfix/*) [ "$type" = "fix" ] || printf '⚠️ Atenea: rama hotfix/* pero commit "%s" (¿debería ser fix?)\n' "$type" >&2 ;;
fix/*) [ "$type" = "fix" ] || printf '⚠️ Atenea: fix/* branch but commit "%s" (should it be fix?)\n' "$type" >&2 ;;
hotfix/*) [ "$type" = "fix" ] || printf '⚠️ Atenea: hotfix/* branch but commit "%s" (should it be fix?)\n' "$type" >&2 ;;
esac
exit 0
fi

cat >&2 <<'EOF'
✕ Atenea · commit rechazado: el mensaje no sigue Conventional Commits.
✕ Atenea · commit rejected: the message does not follow Conventional Commits.

Formato: <tipo>(<alcance>)(!): <descripción en imperativo>
Tipos: feat fix docs style refactor perf test build ci chore revert
Format: <type>(<scope>)(!): <imperative description>
Types: feat fix docs style refactor perf test build ci chore revert

Ejemplos válidos:
feat(auth): agregar login por sesión
fix: corregir cálculo de permisos
feat(store)!: cambiar shape del estado
Valid examples:
feat(auth): add session login
fix: correct permission calculation
feat(store)!: change the state shape

Manual de versionado del equipo (plugin Atenea, skill git-flow).
Bypass puntual (no recomendado): git commit --no-verify
Team versioning manual (Atenea plugin, git-flow skill).
One-off bypass (not recommended): git commit --no-verify
EOF
exit 1
28 changes: 14 additions & 14 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/bin/sh
# ─────────────────────────────────────────────────────────────────────────
# Atenea · pre-commit · protege ramas permanentes (manual de versionado Venteks)
# Atenea · pre-commit · protects the permanent branches (Venteks versioning manual)
#
# Regla del md: "nunca desarrolles directo sobre main". El desarrollo va en ramas
# temporales (feat/ fix/ chore/) desde beta; hotfix/ desde main. Este hook
# bloquea commits DIRECTOS sobre main o beta.
# Rule: "never develop directly on main". Development happens on temporary branches
# (feat/ fix/ chore/ docs/) created from beta; hotfix/ from main. This hook blocks
# DIRECT commits on main or beta.
#
# Escape para promoción/merge de release: ATENEA_ALLOW_PROTECTED=1 git commit ...
# Bypass total puntual: git commit --no-verify
# Escape for release promotion/merge: ATENEA_ALLOW_PROTECTED=1 git commit ...
# One-off full bypass: git commit --no-verify
# ─────────────────────────────────────────────────────────────────────────

[ "${ATENEA_ALLOW_PROTECTED:-}" = "1" ] && exit 0
Expand All @@ -17,17 +17,17 @@ branch="$(git symbolic-ref --short HEAD 2>/dev/null || echo '')"
case "$branch" in
main|beta)
cat >&2 <<EOF
✕ Atenea · commit directo sobre '$branch' bloqueado.
✕ Atenea · direct commit on '$branch' blocked.

El desarrollo va en ramas temporales:
feat/<func> · fix/<bug> · chore/<ajuste> (desde beta)
hotfix/<bug> (desde main)
Development happens on temporary branches:
feat/<feature> · fix/<bug> · chore/<task> · docs/<topic> (from beta)
hotfix/<bug> (from main)

Crea la rama y muévete a ella:
git switch -c feat/mi-cambio
Create the branch and switch to it:
git switch -c feat/my-change

Promoción de release (merge a $branch): ATENEA_ALLOW_PROTECTED=1 git commit ...
Bypass puntual (no recomendado): git commit --no-verify
Release promotion (merge into $branch): ATENEA_ALLOW_PROTECTED=1 git commit ...
One-off bypass (not recommended): git commit --no-verify
EOF
exit 1
;;
Expand Down
63 changes: 34 additions & 29 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,69 @@
# Changelog

Todas las notas relevantes de este proyecto se documentan aquí.
Formato basado en [Keep a Changelog](https://keepachangelog.com/es-ES/); versionado [SemVer](https://semver.org/lang/es/).
All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/).

## [Sin liberar]
## [Unreleased]

### Añadido
### Added

- CI en GitHub Actions para cada PR y push a `beta` y `main`: typecheck, lint, formato y tests.
- Hooks de git (`.githooks/`) que exigen Conventional Commits y bloquean commits directos sobre `main` y `beta`, y guía de contribución con el flujo de ramas.
- Screen reader support (VoiceOver and TalkBack): an invisible adjustable control announces the current page ("Page 3 of 12", or "Pages 3 and 4 of 12" in book mode) and turns pages with the increment/decrement actions. Headings are exposed with the `header` role.
- `accessibilityLabels` prop on `DocumentViewer` to override the spoken strings, plus the `ViewerAccessibilityLabels` type and the `DEFAULT_ACCESSIBILITY_LABELS` export.
- GitHub Actions CI for every PR and push to `beta` and `main`: typecheck, lint, formatting and tests.
- Git hooks (`.githooks/`) that require Conventional Commits and block direct commits on `main` and `beta`, and a contributing guide with the branching model.

### Cambiado
### Changed

- El repositorio se mudó de GitLab a GitHub (`acertijosapps/react-native-md-document`): `repository` y `bugs` de `package.json` y `source` del podspec, que ahora usa el tag `vX.Y.Z`.
- Peer dependency ranges now match what the library supports: `react-native` ≥ 0.76, `react` ≥ 18.3.1, `react-native-reanimated` ≥ 3.16 and < 4, `react-native-gesture-handler` ≥ 2.20 and < 3. Reanimated 4 and Gesture Handler 3 are not supported yet.
- The repository moved from GitLab to GitHub (`acertijosapps/react-native-md-document`): `repository` and `bugs` in `package.json` and `source` in the podspec, which now uses the `vX.Y.Z` tag.
- The public documentation (README, changelog, contributing guide) is now in English.

### Corregido
### Fixed

### Eliminado
- The pages stacked behind the current one for the flip animation are hidden from the accessibility tree, so screen readers no longer read them.
- The error thrown when the native speech module is not linked now names the published package (`@acertijosapps/react-native-md-document`) instead of the old `react-native-document`, and is in English.

## [1.2.0] - 2026-10-25

### Añadido
### Added

- Modo libro: en tablets y plegables en horizontal, el documento se muestra en dos páginas enfrentadas con volteo de página. Props `dualPage` (activo por defecto), `dualPageMinWidth` y `spreadGap` (separación para la bisagra de un plegable).
- `onPageChange` recibe un cuarto argumento, `pagesPerView` (1 o 2).
- Secciones «Modo libro» y «Plegables» en el README, con capturas.
- Book mode: on tablets and foldables in landscape, the document is shown as two facing pages with page-turning. Props `dualPage` (on by default), `dualPageMinWidth` and `spreadGap` (space for a foldable's hinge).
- `onPageChange` receives a fourth argument, `pagesPerView` (1 or 2).
- "Book mode" and "Foldables" sections in the README, with screenshots.

### Corregido
### Fixed

- Paginación en tablets: ya no queda atascada ni deja páginas en blanco por eventos de layout tardíos.
- El modo libro solo se activa en pantallas de tablet o plegable (lado corto de la ventana de al menos 600 dp); un teléfono en horizontal sigue mostrando una página.
- Pagination on tablets: it no longer gets stuck or leaves blank pages because of late layout events.
- Book mode only turns on for tablet- or foldable-sized screens (window short side of at least 600 dp); a phone in landscape still shows a single page.

## [1.1.2] - 2026-10-13

### Cambiado
### Changed

- `author`, correo y `homepage` de AcertijosApps en `package.json` y el podspec.
- `author`, email and `homepage` of AcertijosApps in `package.json` and the podspec.

## [1.1.1] - 2026-09-19

### Añadido
### Added

- `homepage`, `repository` y `bugs` en `package.json`, y podspec alineado.
- `homepage`, `repository` and `bugs` in `package.json`, and an aligned podspec.

## [1.1.0] - 2026-09-19

### Añadido
### Added

- Carga del documento por `source` con estados de carga y error (`onLoad*`, `renderLoading`, `renderError`).
- Loading the document through `source`, with loading and error states (`onLoad*`, `renderLoading`, `renderError`).

## [1.0.1] - 2026-09-19

### Cambiado
### Changed

- README con el nombre del paquete publicado y las imágenes por URL absoluta, para que rendericen en npm; `media/` se incluye en el paquete.
- Podspec renombrado a `react-native-md-document.podspec`.
- Keywords `android`, `ios` y `zoom`.
- README with the published package name and absolute image URLs, so they render on npm; `media/` is included in the package.
- Podspec renamed to `react-native-md-document.podspec`.
- Keywords `android`, `ios` and `zoom`.

## [1.0.0] - 2026-09-19

### Añadido
### Added

- Primera versión pública: visor de Markdown como PDF con volteo de página, zoom, resaltados persistentes, lectura en voz alta (TTS) y tokens de color claro/oscuro, con almacenamiento, fuente y voz inyectables.
- First public release: Markdown-as-PDF viewer with page-turning, zoom, persistent highlights, text-to-speech (TTS) and light/dark color tokens, with injectable storage, source and speech engine.
Loading
Loading