expo-rotation-module 0.1.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,77 +1,173 @@
1
1
  # expo-rotation-module
2
2
 
3
- An Expo native module that controls the Android system rotation settings (ACCELEROMETER_ROTATION and USER_ROTATION).
3
+ A small Expo native module that lets an Android app read and control the system rotation settings (ACCELEROMETER_ROTATION and USER_ROTATION) and request the `WRITE_SETTINGS` permission.
4
4
 
5
- ## Overview
6
- This package exposes a small API to check and request the WRITE_SETTINGS permission and to read/set the global rotation mode. This module is Android-only; iOS and web are no-ops.
5
+ This module exposes a tiny JS/TS API and includes Android and iOS native source. The runtime behavior is Android-only; iOS/web are no-ops.
7
6
 
8
- ## Install (local development with pnpm)
7
+ ---
9
8
 
10
- From the module repo:
9
+ ## Usage
11
10
 
12
- - `pnpm install`
13
- - (optional) `pnpm build` — runs the expo-module build scripts
11
+ ### Install
14
12
 
15
- From your Expo app project:
13
+ - From your app project (local development):
14
+ - `pnpm add ../path/to/expo-rotation-module` (or use a published package: `pnpm add expo-rotation-module`)
16
15
 
17
- - Add the module locally: `pnpm add ../expo-rotation-module` (or `pnpm add file:../expo-rotation-module`)
18
- - IMPORTANT: Add the plugin to your app config so the permission is injected during prebuild:
16
+ - IMPORTANT: add the config plugin to your app config so the permission is injected during `prebuild`.
19
17
 
20
- In `app.json` or `app.config.js` add the following to your `expo.plugins` array:
18
+ In `app.json` or `app.config.js` add the package name to `expo.plugins`:
21
19
 
22
20
  ```json
23
- "plugins": [
24
- "expo-rotation-module"
25
- ]
21
+ {
22
+ "expo": {
23
+ "plugins": [
24
+ "expo-rotation-module"
25
+ ]
26
+ }
27
+ }
26
28
  ```
27
29
 
28
- - Run `npx expo prebuild` to apply the config plugin and update `AndroidManifest.xml`.
29
- - Rebuild the Android app (use EAS dev client or Android Studio):
30
- - Recommended: `pnpm add expo-dev-client` then `eas build --profile development --platform android` and run with `expo start --dev-client`.
30
+ - The plugin is implemented in `plugin/index.js` and will insert the `WRITE_SETTINGS` permission into your `AndroidManifest.xml` during `expo prebuild`.
31
+
32
+ - Apply native changes and build the app:
33
+ - `npx expo prebuild` (or `expo run:android` which runs prebuild automatically)
34
+ - Rebuild/install the app on device/emulator (use a custom dev client or a standalone build for WRITE_SETTINGS tests — Expo Go is not suitable).
31
35
 
32
- ## API
36
+ ### API
33
37
 
34
- Import functions:
38
+ Import the module in JS/TS:
35
39
 
36
40
  ```ts
37
- import Rotation, { canWrite, requestWritePermission, getRotationState, setRotationState } from 'expo-rotation-module';
41
+ import Rotation, {
42
+ canWrite,
43
+ requestWritePermission,
44
+ getRotationState,
45
+ setRotationState,
46
+ getPackageName,
47
+ } from 'expo-rotation-module';
38
48
  ```
39
49
 
40
- - `canWrite(): Promise<boolean>` — true if WRITE_SETTINGS is granted (Android M+), otherwise true on older OS.
41
- - `requestWritePermission(): void` — opens Settings where the user can grant WRITE_SETTINGS.
42
- - `getRotationState(): Promise<'AUTOROTATE'|'PORTRAIT'|'LANDSCAPE'>` — reads current rotation state.
43
- - `setRotationState(state): Promise<void>` — sets rotation. Rejects with an Error object that may include a `.code` property.
50
+ - `canWrite(): Promise<boolean>` — returns true if the app has `WRITE_SETTINGS` granted (Android M+). Returns `true` on older OS versions.
51
+ - `requestWritePermission(): void` — opens the Android Settings screen where the user can grant the permission for your app.
52
+ - `getRotationState(): Promise<'AUTOROTATE'|'PORTRAIT'|'LANDSCAPE'>` — reads the current global rotation state.
53
+ - `setRotationState(state): Promise<void>` — sets the rotation state. Rejects with an Error that may contain a `code` property (e.g. `E_PERMISSION`).
54
+ - `getPackageName(): Promise<string>` — returns the package name the native module is using (useful for diagnostics).
44
55
 
45
- Error codes on the Error object (if available): `E_PERMISSION`, `E_INVALID_STATE`, `E_SET_ROTATION`, `E_GET_ROTATION`, `E_NO_MODULE`.
56
+ All functions are Android-only. On non-Android platforms the functions are no-ops or return safe defaults.
46
57
 
47
- ## Example
58
+ ### Example
48
59
 
49
60
  ```ts
50
- import * as Rotation from 'expo-rotation-module';
61
+ import Rotation from 'expo-rotation-module';
51
62
 
52
- async function example() {
53
- if (!(await Rotation.canWrite())) {
63
+ async function ensureAndSet() {
64
+ const hasPermission = await Rotation.canWrite();
65
+ if (!hasPermission) {
66
+ // Opens Settings where the user can grant WRITE_SETTINGS for your app
54
67
  Rotation.requestWritePermission();
55
68
  return;
56
69
  }
57
70
 
58
- try {
59
- await Rotation.setRotationState('PORTRAIT');
60
- } catch (e: any) {
61
- if (e.code === 'E_PERMISSION') {
62
- console.warn('Permission missing');
63
- }
64
- }
71
+ await Rotation.setRotationState('PORTRAIT');
65
72
  }
66
73
  ```
67
74
 
68
- ## Plugin
69
- The package contains `plugin/index.js` that injects `android.permission.WRITE_SETTINGS` into the host app's AndroidManifest during `expo prebuild`.
75
+ ### Troubleshooting
70
76
 
71
- ## Package id and Android settings
72
- The Android package/namespace used within module sources is `ktsierra.expo.rotationmodule`.
77
+ - WRITE_SETTINGS switch is greyed out in the Settings screen:
78
+ - Ensure your app has the `WRITE_SETTINGS` permission declared in the manifest. The config plugin adds this when you run `expo prebuild`.
79
+ - Do not test this inside Expo Go — the Settings screen will target the Expo Go package. Build a custom dev client or standalone build.
80
+ - Confirm the package name by calling `Rotation.getPackageName()` and check device logs for the `Opening WRITE_SETTINGS for package: <pkg>` message.
73
81
 
74
- ## Contributing & tests
75
- If you want CI or tests added (TS checks, build smoke tests), I can add a GitHub Actions workflow that runs `pnpm install` and `pnpm build`.
82
+ - ESLint/type errors in consuming projects:
83
+ - Ensure your app can resolve the package. For local linking with pnpm workspaces, `pnpm install` in the app and a restart of the editor/TS server is sometimes required.
76
84
 
77
85
  ---
86
+
87
+ ## Development
88
+
89
+ This section explains how to develop, test and publish this module.
90
+
91
+ ### Repo layout (important files)
92
+
93
+ - `src/` — TypeScript JS wrapper and types.
94
+ - `android/` — Android native sources (Kotlin) and Gradle files.
95
+ - `ios/` — iOS native sources (Swift) and podspec.
96
+ - `plugin/` — config plugin that injects the `WRITE_SETTINGS` permission.
97
+ - `app.plugin.js` — plugin entry point for Expo to discover the config plugin.
98
+ - `index.js` — package entry that re-exports the JS wrapper.
99
+ - `package.json` — package metadata, scripts and publish config.
100
+
101
+ ### Local development
102
+
103
+ 1. Install dependencies in the module repo:
104
+ - `pnpm install`
105
+
106
+ 2. Make changes to `src/` or native code.
107
+
108
+ 3. Build/prepare artifacts (some scripts expect `tsc`/expo-module-scripts):
109
+ - `pnpm run prepare` (runs `expo-module prepare`) or `pnpm run build` (if you prefer).
110
+
111
+ 4. Test in an app:
112
+ - Create or use an example app. From the app root:
113
+ - Add the local package: `pnpm add ../path/to/expo-rotation-module` (or `pnpm add file:...`)
114
+ - Ensure `app.json` includes the plugin (see Usage).
115
+ - Run `npx expo prebuild` and verify `android/app/src/main/AndroidManifest.xml` contains `<uses-permission android:name="android.permission.WRITE_SETTINGS" />`.
116
+ - Build and run the app on device/emulator (`expo run:android` or a dev client build).
117
+
118
+ 5. Faster iteration (optional):
119
+ - Instead of building the package, map Metro to the module `src` in the app `metro.config.js` during development:
120
+ ```js
121
+ // example: app/metro.config.js
122
+ const path = require('path');
123
+ module.exports = {
124
+ resolver: {
125
+ extraNodeModules: {
126
+ 'expo-rotation-module': path.resolve(__dirname, '../path/to/expo-rotation-module/src'),
127
+ },
128
+ },
129
+ watchFolders: [path.resolve(__dirname, '..')],
130
+ };
131
+ ```
132
+ - This lets the app load the TypeScript source directly without rebuilding the package on every change.
133
+
134
+ ### Publishing
135
+
136
+ We publish the source package (native sources included). Before publishing, ensure:
137
+
138
+ - `package.json` fields are correct (`name`, `version`, `main`, `types`, `files`).
139
+ - `devDependencies` contains `typescript` so `expo-module prepare` runs in CI.
140
+ - The plugin and native sources are included in the published package (use the `files` array in `package.json` to control this).
141
+
142
+ Manual publish (local):
143
+
144
+ 1. Prepare the package locally:
145
+ - `pnpm install`
146
+ - `pnpm run prepare`
147
+
148
+ 2. Create a tarball to test what will be published:
149
+ - `npm pack`
150
+ - Install the tarball into a test app: `pnpm add ../expo-rotation-module-<version>.tgz`
151
+ - Run `npx expo prebuild` in the test app to confirm the plugin and native sources are applied.
152
+
153
+ 3. Publish:
154
+ - If your environment has an npm automation token configured in CI, run `npm publish --access public` from the package root.
155
+ - If `prepublishOnly` scripts fail in your environment, you can publish with scripts ignored after preparing locally:
156
+ - `npm publish --access public --ignore-scripts`
157
+
158
+ ### Continuous Integration / GitHub Actions
159
+
160
+ - Recommended CI flow:
161
+ - `pnpm install --frozen-lockfile`
162
+ - `pnpm run prepare` (ensure `typescript` is installed in `devDependencies` so `tsc` is available)
163
+ - Run tests/lint (optional)
164
+ - Bump version, push tags
165
+ - Authenticate to npm (use an automation token or GitHub OIDC if your npm org supports trusted publishers)
166
+ - `npm publish --access public` or `pnpm publish --access public`
167
+
168
+ - Example workflow (summary):
169
+ - Checkout, setup Node + pnpm, `pnpm install`, run `pnpm run prepare`, bump version, publish.
170
+
171
+ ---
172
+
173
+ If you find anything missing or unclear (examples, API signatures, or CI details) open an issue or submit a PR. Contributions welcome.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-rotation-module",
3
- "version": "0.1.0",
3
+ "version": "1.0.1",
4
4
  "description": "Screen Orientation Native Module",
5
5
  "main": "index.js",
6
6
  "types": "src/index.d.ts",
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/react": "~19.1.0",
39
+ "typescript": "~5.9.2",
39
40
  "expo": "^54.0.27",
40
41
  "expo-module-scripts": "^5.0.8",
41
42
  "react-native": "0.81.5"
File without changes
File without changes
File without changes
@@ -1,2 +0,0 @@
1
- #Tue Jan 06 14:23:37 EST 2026
2
- gradle.version=9.2.0
@@ -1,2 +0,0 @@
1
- #Tue Jan 06 13:19:56 EST 2026
2
- java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home
File without changes
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="AndroidProjectSystem">
4
- <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
5
- </component>
6
- </project>