Skip to content

Commit 55a1254

Browse files
l2hyunwooCopilot
andauthored
feat: Runtime-Mutable Properties Converted to Methods (#34)
* build: set tsconfig * feat: change apis * feat: change native impl * docs: apply changes in documents * feat: apply changes in examples * docs: apply changes in README, CHANGELOG * ci: fix ktlintFormat * docs: apply changelog * Update src/DeviceInfo.nitro.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6bfd7cd commit 55a1254

File tree

19 files changed

+454
-406
lines changed

19 files changed

+454
-406
lines changed

CHANGELOG.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [1.3.0] - 2025-11-29
99

1010
### Added
1111

12+
- **System Language & Navigation Mode API**: New localization and navigation detection capabilities
13+
- `systemLanguage`: Get device system language in BCP 47 format (e.g., "en-US", "ko-KR")
14+
- `navigationMode`: Detect Android navigation mode (`'gesture' | 'buttons' | 'twobuttons' | 'unknown'`)
15+
- `NavigationMode` type: New TypeScript type for navigation mode values
16+
1217
- **Complete API Migration**: All APIs from `react-native-device-info` have been migrated
1318
- Full feature parity with the original library
1419
- All device information methods now available through Nitro Modules
@@ -22,6 +27,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2227
- Automated CI/CD deployment to GitHub Pages
2328
- Visit at: https://l2hyunwoo.github.io/react-native-nitro-device-info/
2429

30+
### Changed
31+
32+
#### BREAKING: Runtime-Mutable Properties Converted to Methods (18 APIs)
33+
34+
Properties that return values which can change during app runtime have been converted from readonly properties to synchronous getter methods. This provides clearer semantics - methods indicate "query on each call" while properties implied cached/stable values.
35+
36+
**Battery & Power** (3 APIs):
37+
38+
- `batteryLevel``getBatteryLevel()`: Returns current battery level (0.0-1.0)
39+
- `powerState``getPowerState()`: Returns PowerState object
40+
- `isBatteryCharging``getIsBatteryCharging()`: Returns charging status
41+
42+
**System Resources** (3 APIs):
43+
44+
- `usedMemory``getUsedMemory()`: Returns current app memory usage
45+
- `freeDiskStorage``getFreeDiskStorage()`: Returns free disk space
46+
- `freeDiskStorageOld``getFreeDiskStorageOld()`: Returns free disk space (legacy API)
47+
48+
**Audio/Peripherals** (3 APIs):
49+
50+
- `isWiredHeadphonesConnected``getIsWiredHeadphonesConnected()`: Wired headphone detection
51+
- `isBluetoothHeadphonesConnected``getIsBluetoothHeadphonesConnected()`: Bluetooth headphone detection
52+
- `isHeadphonesConnectedSync``getIsHeadphonesConnected()`: Any headphone detection
53+
54+
**Network & Connectivity** (6 APIs):
55+
56+
- `isAirplaneMode``getIsAirplaneMode()`: Airplane mode status (Android only)
57+
- `ipAddressSync``getIpAddressSync()`: Current IP address (cached 5s)
58+
- `carrierSync``getCarrierSync()`: Carrier name (cached 5s)
59+
- `isLocationEnabledSync``getIsLocationEnabled()`: Location services status
60+
- `macAddressSync``getMacAddressSync()`: MAC address (cached 5s)
61+
- `availableLocationProviders``getAvailableLocationProviders()`: Enabled location providers
62+
63+
**Display & Orientation** (3 APIs):
64+
65+
- `isLandscape``getIsLandscape()`: Device orientation
66+
- `fontScale``getFontScale()`: System font scale multiplier
67+
- `brightness``getBrightness()`: Screen brightness (iOS only)
68+
69+
**Migration Example**:
70+
71+
```typescript
72+
// Before (v1.2.1)
73+
const level = DeviceInfoModule.batteryLevel;
74+
const charging = DeviceInfoModule.isBatteryCharging;
75+
76+
// After (v1.3.0)
77+
const level = DeviceInfoModule.getBatteryLevel();
78+
const charging = DeviceInfoModule.getIsBatteryCharging();
79+
```
80+
2581
## [1.0.0] - 2025-10-25
2682

2783
### Added
@@ -38,6 +94,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3894
All methods listed below have been converted from Promise-based to synchronous for instant access (<1ms):
3995

4096
**Device Identification** (2 methods):
97+
4198
- `getUniqueId()`: `Promise<string>``string`
4299
- Returns device-unique ID (iOS: IDFV, Android: ANDROID_ID)
43100
- **Before**: `const id = await deviceInfo.getUniqueId()`
@@ -49,6 +106,7 @@ All methods listed below have been converted from Promise-based to synchronous f
49106
- **After**: `const manufacturer = deviceInfo.getManufacturer()`
50107

51108
**Battery & Power** (3 methods):
109+
52110
- `getBatteryLevel()`: `Promise<number>``number`
53111
- Returns battery level (0.0 to 1.0)
54112
- **Before**: `const level = await deviceInfo.getBatteryLevel()`
@@ -65,6 +123,7 @@ All methods listed below have been converted from Promise-based to synchronous f
65123
- **After**: `const state = deviceInfo.getPowerState()`
66124

67125
**Application Metadata** (4 methods):
126+
68127
- `getVersion()`: `Promise<string>``string`
69128
- Returns app version (e.g., "1.0.0")
70129
- **Before**: `const version = await deviceInfo.getVersion()`
@@ -86,6 +145,7 @@ All methods listed below have been converted from Promise-based to synchronous f
86145
- **After**: `const name = deviceInfo.getApplicationName()`
87146

88147
**System Resources** (4 methods):
148+
89149
- `getTotalMemory()`: `Promise<number>``number`
90150
- Returns total device RAM in bytes
91151
- **Before**: `const memory = await deviceInfo.getTotalMemory()`
@@ -107,6 +167,7 @@ All methods listed below have been converted from Promise-based to synchronous f
107167
- **After**: `const free = deviceInfo.getFreeDiskStorage()`
108168

109169
**Device Capabilities** (3 methods):
170+
110171
- `isCameraPresent()`: `Promise<boolean>``boolean`
111172
- Returns camera availability
112173
- **Before**: `const hasCamera = await deviceInfo.isCameraPresent()`
@@ -123,6 +184,7 @@ All methods listed below have been converted from Promise-based to synchronous f
123184
- **After**: `const isEmu = deviceInfo.isEmulator()`
124185

125186
**Platform-Specific** (2 methods):
187+
126188
- `getApiLevel()`: `Promise<number>``number`
127189
- Returns Android API level (or -1 on iOS)
128190
- **Before**: `const apiLevel = await deviceInfo.getApiLevel()`
@@ -154,6 +216,7 @@ All methods listed below have been converted from Promise-based to synchronous f
154216
#### Simplified Component Usage
155217

156218
**Before (v0.1.0)**:
219+
157220
```typescript
158221
function MyComponent() {
159222
const [manufacturer, setManufacturer] = useState('');
@@ -183,6 +246,7 @@ function MyComponent() {
183246
```
184247

185248
**After (v1.0.0)**:
249+
186250
```typescript
187251
function MyComponent() {
188252
// Direct synchronous access - no useState, no useEffect, no async/await!

README-ko.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ console.log(manufacturer); // "Apple"
6666
const isTablet = DeviceInfoModule.isTablet;
6767
console.log(isTablet); // false
6868

69-
const batteryLevel = DeviceInfoModule.batteryLevel;
69+
const batteryLevel = DeviceInfoModule.getBatteryLevel();
7070
console.log(`배터리: ${(batteryLevel * 100).toFixed(0)}%`); // "배터리: 85%"
7171

7272
// 비동기 메서드 (Promise 기반 - <100ms)
@@ -97,9 +97,9 @@ const isEmulator = DeviceInfoModule.isEmulator; // false
9797

9898
// 시스템 리소스
9999
const totalMemory = DeviceInfoModule.totalMemory;
100-
const usedMemory = DeviceInfoModule.usedMemory;
100+
const usedMemory = DeviceInfoModule.getUsedMemory();
101101
const totalDisk = DeviceInfoModule.totalDiskCapacity;
102-
const freeDisk = DeviceInfoModule.freeDiskStorage;
102+
const freeDisk = DeviceInfoModule.getFreeDiskStorage();
103103

104104
console.log(
105105
`RAM: ${(usedMemory / 1024 / 1024).toFixed(0)}MB / ${(totalMemory / 1024 / 1024).toFixed(0)}MB`
@@ -109,9 +109,9 @@ console.log(
109109
);
110110

111111
// 배터리 정보
112-
const batteryLevel = DeviceInfoModule.batteryLevel;
113-
const isCharging = DeviceInfoModule.isBatteryCharging;
114-
const powerState: PowerState = DeviceInfoModule.powerState;
112+
const batteryLevel = DeviceInfoModule.getBatteryLevel();
113+
const isCharging = DeviceInfoModule.getIsBatteryCharging();
114+
const powerState: PowerState = DeviceInfoModule.getPowerState();
115115

116116
console.log(
117117
`배터리: ${(batteryLevel * 100).toFixed(0)}% ${isCharging ? '(충전 중)' : ''}`
@@ -164,7 +164,7 @@ DeviceInfoModule.model; // "iPhone"
164164
DeviceInfoModule.uniqueId; // 동기
165165
DeviceInfoModule.isTablet; // 동기
166166
DeviceInfoModule.totalMemory; // 동기
167-
DeviceInfoModule.batteryLevel; // 동기
167+
DeviceInfoModule.getBatteryLevel(); // 동기 메서드
168168

169169
// 앱 정보
170170
DeviceInfoModule.version; // 동기
@@ -217,10 +217,10 @@ import { DeviceInfoModule } from 'react-native-nitro-device-info';
217217
const deviceId = DeviceInfoModule.deviceId; // 메서드가 아닌 속성
218218
const brand = DeviceInfoModule.brand; // 메서드가 아닌 속성
219219

220-
// 대부분의 값이 이제 동기 속성
220+
// 대부분의 값이 이제 동기 속성 또는 메서드
221221
const uniqueId = DeviceInfoModule.uniqueId; // 속성, 동기!
222222
const totalMemory = DeviceInfoModule.totalMemory; // 속성, 동기!
223-
const batteryLevel = DeviceInfoModule.batteryLevel; // 속성, 동기!
223+
const batteryLevel = DeviceInfoModule.getBatteryLevel(); // 메서드, 동기!
224224
const isTablet = DeviceInfoModule.isTablet; // 속성, 동기!
225225

226226
// 네트워크/연결만 비동기 메서드로 유지

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ console.log(manufacturer); // "Apple"
6565
const isTablet = DeviceInfoModule.isTablet;
6666
console.log(isTablet); // false
6767

68-
const batteryLevel = DeviceInfoModule.batteryLevel;
68+
const batteryLevel = DeviceInfoModule.getBatteryLevel();
6969
console.log(`Battery: ${(batteryLevel * 100).toFixed(0)}%`); // "Battery: 85%"
7070

7171
// Asynchronous methods (Promise-based - <100ms)
@@ -96,9 +96,9 @@ const isEmulator = DeviceInfoModule.isEmulator; // false
9696

9797
// System Resources
9898
const totalMemory = DeviceInfoModule.totalMemory;
99-
const usedMemory = DeviceInfoModule.usedMemory;
99+
const usedMemory = DeviceInfoModule.getUsedMemory();
100100
const totalDisk = DeviceInfoModule.totalDiskCapacity;
101-
const freeDisk = DeviceInfoModule.freeDiskStorage;
101+
const freeDisk = DeviceInfoModule.getFreeDiskStorage();
102102

103103
console.log(
104104
`RAM: ${(usedMemory / 1024 / 1024).toFixed(0)}MB / ${(totalMemory / 1024 / 1024).toFixed(0)}MB`
@@ -108,9 +108,9 @@ console.log(
108108
);
109109

110110
// Battery Information
111-
const batteryLevel = DeviceInfoModule.batteryLevel;
112-
const isCharging = DeviceInfoModule.isBatteryCharging;
113-
const powerState: PowerState = DeviceInfoModule.powerState;
111+
const batteryLevel = DeviceInfoModule.getBatteryLevel();
112+
const isCharging = DeviceInfoModule.getIsBatteryCharging();
113+
const powerState: PowerState = DeviceInfoModule.getPowerState();
114114

115115
console.log(
116116
`Battery: ${(batteryLevel * 100).toFixed(0)}% ${isCharging ? '(charging)' : ''}`
@@ -163,7 +163,7 @@ DeviceInfoModule.model; // "iPhone"
163163
DeviceInfoModule.uniqueId; // Sync
164164
DeviceInfoModule.isTablet; // Sync
165165
DeviceInfoModule.totalMemory; // Sync
166-
DeviceInfoModule.batteryLevel; // Sync
166+
DeviceInfoModule.getBatteryLevel(); // Sync method
167167

168168
// App Info
169169
DeviceInfoModule.version; // Sync
@@ -216,10 +216,10 @@ import { DeviceInfoModule } from 'react-native-nitro-device-info';
216216
const deviceId = DeviceInfoModule.deviceId; // Property, not method
217217
const brand = DeviceInfoModule.brand; // Property, not method
218218

219-
// Most values are now synchronous properties
219+
// Most values are now synchronous properties or methods
220220
const uniqueId = DeviceInfoModule.uniqueId; // Property, sync!
221221
const totalMemory = DeviceInfoModule.totalMemory; // Property, sync!
222-
const batteryLevel = DeviceInfoModule.batteryLevel; // Property, sync!
222+
const batteryLevel = DeviceInfoModule.getBatteryLevel(); // Method, sync!
223223
const isTablet = DeviceInfoModule.isTablet; // Property, sync!
224224

225225
// Only network/connectivity remain async methods

0 commit comments

Comments
 (0)