react-native-alarms 0.0.1 → 0.0.3

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/AlarmDemo.tsx DELETED
@@ -1,223 +0,0 @@
1
- import React, { useCallback, useEffect, useState } from 'react';
2
- import {
3
- View,
4
- Text,
5
- TouchableOpacity,
6
- StyleSheet,
7
- Alert,
8
- AppState,
9
- NativeEventEmitter,
10
- NativeModules,
11
- Platform,
12
- } from 'react-native';
13
- import type { AlarmEvent, AlarmPermission } from './specs/NativeAlarm';
14
-
15
- // Same module name and API on Android (AlarmModule.kt) and iOS (AlarmModule.swift).
16
- const { Alarm } = NativeModules;
17
- console.log(
18
- '[AlarmDemo] NativeModules.Alarm =',
19
- Alarm,
20
- Object.keys(Alarm ?? {}),
21
- );
22
-
23
- // Guard: creating an emitter with an undefined module crashes the app
24
- const alarmEmitter = Alarm ? new NativeEventEmitter(Alarm) : null;
25
-
26
- const pad = (n: number) => n.toString().padStart(2, '0');
27
-
28
- export function AlarmDemo() {
29
- const [perms, setPerms] = useState<AlarmPermission | null>(null);
30
-
31
- const refreshPermissions = useCallback(async () => {
32
- if (!Alarm) return;
33
- try {
34
- setPerms(await Alarm.checkPermission());
35
- } catch {}
36
- }, []);
37
-
38
- useEffect(() => {
39
- refreshPermissions();
40
- // Re-check when coming back from a settings screen.
41
- const sub = AppState.addEventListener('change', s => {
42
- if (s === 'active') refreshPermissions();
43
- });
44
- return () => sub.remove();
45
- }, [refreshPermissions]);
46
-
47
- useEffect(() => {
48
- if (!alarmEmitter) return;
49
-
50
- const subscriptions = [
51
- alarmEmitter.addListener('onAlarmFired', data => {
52
- console.log('Alarm fired', (data as AlarmEvent)?.alarmId);
53
- }),
54
- alarmEmitter.addListener('onAlarmDismissed', data => {
55
- console.log('Alarm dismissed', (data as AlarmEvent)?.alarmId);
56
- }),
57
- alarmEmitter.addListener('onAlarmSnoozed', data => {
58
- console.log('Alarm snoozed', (data as AlarmEvent)?.alarmId);
59
- }),
60
- ];
61
-
62
- return () => subscriptions.forEach(sub => sub.remove());
63
- }, []);
64
-
65
- const requestPermissions = async () => {
66
- if (!Alarm) return;
67
- try {
68
- setPerms(await Alarm.requestPermission());
69
- } catch (error: any) {
70
- Alert.alert('Error', error?.message || 'Permission request failed');
71
- }
72
- };
73
-
74
- const openAutoStart = async () => {
75
- if (!Alarm) return;
76
- try {
77
- const opened = await Alarm.openAutoStartSettings();
78
- if (!opened) {
79
- Alert.alert(
80
- 'Not needed',
81
- 'This device has no vendor Autostart screen; nothing to change.',
82
- );
83
- }
84
- } catch {}
85
- };
86
-
87
- const isAndroid = Platform.OS === 'android';
88
-
89
- const allGranted =
90
- !!perms &&
91
- perms.notifications &&
92
- perms.canScheduleExact &&
93
- (!isAndroid || (perms.canDrawOverlays && perms.canUseFullScreenIntent));
94
-
95
- const scheduleInOneMinute = async () => {
96
- if (!Alarm) {
97
- Alert.alert('Error', 'Alarm native module is not linked');
98
- return;
99
- }
100
-
101
- try {
102
- const alarmTime = new Date(Date.now() + 30 * 1000);
103
- const label = `${pad(alarmTime.getHours())}:${pad(
104
- alarmTime.getMinutes(),
105
- )}`;
106
-
107
- const alarmId = await Alarm.scheduleAlarm({
108
- alarmId: `alarm_${Date.now()}`,
109
- timestamp: alarmTime.getTime(),
110
- enabled: true,
111
- repeat: { type: 'none' },
112
- title: `Alarm at ${label}`,
113
- body: 'Test Alarm',
114
- data: 'Test Alarm',
115
- vibrate: true,
116
- sound: 'default',
117
- snoozeEnabled: true,
118
- snoozeMinutes: 1,
119
- });
120
-
121
- Alert.alert('Alarm set', `Rings at ${label} (ID: ${alarmId})`);
122
- } catch (error: any) {
123
- Alert.alert('Error', error?.message || 'Failed to schedule alarm');
124
- }
125
- };
126
-
127
- return (
128
- <View style={styles.container}>
129
- {perms && !allGranted ? (
130
- <View style={styles.permBox}>
131
- <Text style={styles.permTitle}>
132
- Permissions needed to ring reliably
133
- </Text>
134
- {isAndroid ? (
135
- <>
136
- <Text style={styles.permLine}>
137
- Notifications: {perms.notifications ? 'ok' : 'missing'}
138
- </Text>
139
- <Text style={styles.permLine}>
140
- Exact alarms: {perms.canScheduleExact ? 'ok' : 'missing'}
141
- </Text>
142
- <Text style={styles.permLine}>
143
- Display over other apps:{' '}
144
- {perms.canDrawOverlays ? 'ok' : 'missing'}
145
- </Text>
146
- <Text style={styles.permLine}>
147
- Full-screen intent:{' '}
148
- {perms.canUseFullScreenIntent ? 'ok' : 'missing'}
149
- </Text>
150
- </>
151
- ) : (
152
- <Text style={styles.permLine}>
153
- {perms.backend === 'alarmkit' ? 'Alarms' : 'Notifications'}:{' '}
154
- {perms.status}
155
- </Text>
156
- )}
157
- <TouchableOpacity
158
- style={styles.permButton}
159
- onPress={requestPermissions}
160
- >
161
- <Text style={styles.buttonText}>Grant next permission</Text>
162
- </TouchableOpacity>
163
- </View>
164
- ) : null}
165
-
166
- <TouchableOpacity style={styles.button} onPress={scheduleInOneMinute}>
167
- <Text style={styles.buttonText}>Set alarm in 1 minute</Text>
168
- </TouchableOpacity>
169
-
170
- {isAndroid ? (
171
- <TouchableOpacity style={styles.linkButton} onPress={openAutoStart}>
172
- <Text style={styles.linkText}>
173
- Xiaomi / Oppo / Vivo: enable Autostart for this app
174
- </Text>
175
- </TouchableOpacity>
176
- ) : null}
177
- </View>
178
- );
179
- }
180
-
181
- const styles = StyleSheet.create({
182
- container: {
183
- flex: 1,
184
- justifyContent: 'center',
185
- alignItems: 'center',
186
- padding: 16,
187
- backgroundColor: '#f5f5f5',
188
- },
189
- permBox: {
190
- backgroundColor: '#FFF3E0',
191
- borderRadius: 8,
192
- padding: 16,
193
- marginBottom: 24,
194
- alignSelf: 'stretch',
195
- },
196
- permTitle: {
197
- fontWeight: '600',
198
- fontSize: 16,
199
- marginBottom: 8,
200
- color: '#333',
201
- },
202
- permLine: { color: '#555', marginBottom: 2 },
203
- permButton: {
204
- marginTop: 12,
205
- backgroundColor: '#FB8C00',
206
- paddingVertical: 12,
207
- borderRadius: 8,
208
- alignItems: 'center',
209
- },
210
- button: {
211
- backgroundColor: '#007AFF',
212
- paddingVertical: 14,
213
- paddingHorizontal: 24,
214
- borderRadius: 8,
215
- },
216
- buttonText: {
217
- color: '#fff',
218
- fontSize: 16,
219
- fontWeight: '600',
220
- },
221
- linkButton: { marginTop: 20, padding: 8 },
222
- linkText: { color: '#007AFF', textDecorationLine: 'underline' },
223
- });
@@ -1,117 +0,0 @@
1
- import React, { useEffect } from 'react';
2
- import {
3
- BackHandler,
4
- NativeModules,
5
- StyleSheet,
6
- Text,
7
- TouchableOpacity,
8
- View,
9
- } from 'react-native';
10
-
11
- const { Alarm } = NativeModules;
12
-
13
- /**
14
- * Initial props come from the native AlarmRingActivity (AlarmData.toBundle()).
15
- */
16
- type Props = {
17
- alarmId?: string;
18
- title?: string;
19
- body?: string;
20
- snoozeEnabled?: boolean;
21
- snoozeMinutes?: number;
22
- data?: string;
23
- };
24
-
25
- const pad = (n: number) => n.toString().padStart(2, '0');
26
-
27
- export function AlarmRingScreen({
28
- alarmId = '',
29
- title = 'Alarm',
30
- body = '',
31
- snoozeEnabled = true,
32
- snoozeMinutes = 5,
33
- }: Props) {
34
- // The only ways out are Stop and Snooze: swallow the back button.
35
- useEffect(() => {
36
- const sub = BackHandler.addEventListener('hardwareBackPress', () => true);
37
- return () => sub.remove();
38
- }, []);
39
-
40
- const now = new Date();
41
- const clock = `${pad(now.getHours())}:${pad(now.getMinutes())}`;
42
-
43
- const stop = () => {
44
- Alarm?.stopAlarm(alarmId).catch(() => {});
45
- };
46
-
47
- const snooze = () => {
48
- Alarm?.snoozeAlarm(alarmId, snoozeMinutes).catch(() => {});
49
- };
50
-
51
- return (
52
- <View style={styles.root}>
53
- <Text style={styles.clock}>{clock}</Text>
54
- <Text style={styles.title}>{title}</Text>
55
- {body ? <Text style={styles.body}>{body}</Text> : null}
56
-
57
- <View style={styles.actions}>
58
- {snoozeEnabled ? (
59
- <TouchableOpacity
60
- style={[styles.button, styles.snooze]}
61
- onPress={snooze}
62
- >
63
- <Text style={styles.buttonText}>Snooze {snoozeMinutes} min</Text>
64
- </TouchableOpacity>
65
- ) : null}
66
- <TouchableOpacity style={[styles.button, styles.stop]} onPress={stop}>
67
- <Text style={styles.buttonText}>Stop</Text>
68
- </TouchableOpacity>
69
- </View>
70
- </View>
71
- );
72
- }
73
-
74
- const styles = StyleSheet.create({
75
- root: {
76
- flex: 1,
77
- backgroundColor: '#0F1430',
78
- alignItems: 'center',
79
- justifyContent: 'center',
80
- padding: 24,
81
- },
82
- clock: {
83
- color: '#fff',
84
- fontSize: 72,
85
- fontWeight: '200',
86
- marginBottom: 16,
87
- },
88
- title: {
89
- color: '#fff',
90
- fontSize: 26,
91
- fontWeight: '600',
92
- textAlign: 'center',
93
- },
94
- body: {
95
- color: '#C5CAE9',
96
- fontSize: 16,
97
- marginTop: 8,
98
- textAlign: 'center',
99
- },
100
- actions: {
101
- position: 'absolute',
102
- bottom: 48,
103
- left: 24,
104
- right: 24,
105
- gap: 12,
106
- },
107
- button: {
108
- paddingVertical: 18,
109
- borderRadius: 14,
110
- alignItems: 'center',
111
- },
112
- snooze: { backgroundColor: '#2E3560' },
113
- stop: { backgroundColor: '#FF8F2E' },
114
- buttonText: { color: '#fff', fontSize: 18, fontWeight: '600' },
115
- });
116
-
117
- export default AlarmRingScreen;
package/App.tsx DELETED
@@ -1,14 +0,0 @@
1
- import { StatusBar } from 'react-native';
2
- import { SafeAreaProvider } from 'react-native-safe-area-context';
3
- import { AlarmDemo } from './AlarmDemo';
4
-
5
- function App() {
6
- return (
7
- <SafeAreaProvider>
8
- <StatusBar barStyle="dark-content" />
9
- <AlarmDemo />
10
- </SafeAreaProvider>
11
- );
12
- }
13
-
14
- export default App;
package/Gemfile DELETED
@@ -1,17 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4
- ruby ">= 2.6.10"
5
-
6
- # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7
- gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8
- gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9
- gem 'xcodeproj', '< 1.26.0'
10
- gem 'concurrent-ruby', '< 1.3.4'
11
-
12
- # Ruby 3.4.0 has removed some libraries from the standard library.
13
- gem 'bigdecimal'
14
- gem 'logger'
15
- gem 'benchmark'
16
- gem 'mutex_m'
17
- gem 'nkf'
package/Gemfile.lock DELETED
@@ -1,114 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- CFPropertyList (3.0.9)
5
- activesupport (6.1.7.10)
6
- concurrent-ruby (~> 1.0, >= 1.0.2)
7
- i18n (>= 1.6, < 2)
8
- minitest (>= 5.1)
9
- tzinfo (~> 2.0)
10
- zeitwerk (~> 2.3)
11
- addressable (2.9.0)
12
- public_suffix (>= 2.0.2, < 8.0)
13
- algoliasearch (1.27.5)
14
- httpclient (~> 2.8, >= 2.8.3)
15
- json (>= 1.5.1)
16
- atomos (0.1.3)
17
- benchmark (0.5.0)
18
- bigdecimal (4.1.3)
19
- claide (1.1.0)
20
- cocoapods (1.15.2)
21
- addressable (~> 2.8)
22
- claide (>= 1.0.2, < 2.0)
23
- cocoapods-core (= 1.15.2)
24
- cocoapods-deintegrate (>= 1.0.3, < 2.0)
25
- cocoapods-downloader (>= 2.1, < 3.0)
26
- cocoapods-plugins (>= 1.0.0, < 2.0)
27
- cocoapods-search (>= 1.0.0, < 2.0)
28
- cocoapods-trunk (>= 1.6.0, < 2.0)
29
- cocoapods-try (>= 1.1.0, < 2.0)
30
- colored2 (~> 3.1)
31
- escape (~> 0.0.4)
32
- fourflusher (>= 2.3.0, < 3.0)
33
- gh_inspector (~> 1.0)
34
- molinillo (~> 0.8.0)
35
- nap (~> 1.0)
36
- ruby-macho (>= 2.3.0, < 3.0)
37
- xcodeproj (>= 1.23.0, < 2.0)
38
- cocoapods-core (1.15.2)
39
- activesupport (>= 5.0, < 8)
40
- addressable (~> 2.8)
41
- algoliasearch (~> 1.0)
42
- concurrent-ruby (~> 1.1)
43
- fuzzy_match (~> 2.0.4)
44
- nap (~> 1.0)
45
- netrc (~> 0.11)
46
- public_suffix (~> 4.0)
47
- typhoeus (~> 1.0)
48
- cocoapods-deintegrate (1.0.5)
49
- cocoapods-downloader (2.1)
50
- cocoapods-plugins (1.0.0)
51
- nap
52
- cocoapods-search (1.0.1)
53
- cocoapods-trunk (1.6.0)
54
- nap (>= 0.8, < 2.0)
55
- netrc (~> 0.11)
56
- cocoapods-try (1.2.0)
57
- colored2 (3.1.2)
58
- concurrent-ruby (1.3.3)
59
- escape (0.0.4)
60
- ethon (0.18.0)
61
- ffi (>= 1.15.0)
62
- logger
63
- ffi (1.17.4)
64
- fourflusher (2.3.1)
65
- fuzzy_match (2.0.4)
66
- gh_inspector (1.1.3)
67
- httpclient (2.9.0)
68
- mutex_m
69
- i18n (1.14.8)
70
- concurrent-ruby (~> 1.0)
71
- json (2.7.6)
72
- logger (1.7.0)
73
- minitest (5.25.4)
74
- molinillo (0.8.0)
75
- mutex_m (0.3.0)
76
- nanaimo (0.3.0)
77
- nap (1.1.0)
78
- netrc (0.11.0)
79
- nkf (0.3.0)
80
- public_suffix (4.0.7)
81
- rexml (3.4.4)
82
- ruby-macho (2.5.1)
83
- typhoeus (1.6.0)
84
- ethon (>= 0.18.0)
85
- tzinfo (2.0.6)
86
- concurrent-ruby (~> 1.0)
87
- xcodeproj (1.25.1)
88
- CFPropertyList (>= 2.3.3, < 4.0)
89
- atomos (~> 0.1.3)
90
- claide (>= 1.0.2, < 2.0)
91
- colored2 (~> 3.1)
92
- nanaimo (~> 0.3.0)
93
- rexml (>= 3.3.6, < 4.0)
94
- zeitwerk (2.6.18)
95
-
96
- PLATFORMS
97
- ruby
98
-
99
- DEPENDENCIES
100
- activesupport (>= 6.1.7.5, != 7.1.0)
101
- benchmark
102
- bigdecimal
103
- cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
104
- concurrent-ruby (< 1.3.4)
105
- logger
106
- mutex_m
107
- nkf
108
- xcodeproj (< 1.26.0)
109
-
110
- RUBY VERSION
111
- ruby 2.6.10p210
112
-
113
- BUNDLED WITH
114
- 1.17.2
@@ -1,13 +0,0 @@
1
- /**
2
- * @format
3
- */
4
-
5
- import React from 'react';
6
- import ReactTestRenderer from 'react-test-renderer';
7
- import App from '../App';
8
-
9
- test('renders correctly', async () => {
10
- await ReactTestRenderer.act(() => {
11
- ReactTestRenderer.create(<App />);
12
- });
13
- });
package/babel.config.js DELETED
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- presets: ['module:@react-native/babel-preset'],
3
- };
package/jest.config.js DELETED
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- preset: '@react-native/jest-preset',
3
- };
package/metro.config.js DELETED
@@ -1,11 +0,0 @@
1
- const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
2
-
3
- /**
4
- * Metro configuration
5
- * https://reactnative.dev/docs/metro
6
- *
7
- * @type {import('@react-native/metro-config').MetroConfig}
8
- */
9
- const config = {};
10
-
11
- module.exports = mergeConfig(getDefaultConfig(__dirname), config);
package/tsconfig.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "extends": "@react-native/typescript-config",
3
- "include": ["**/*.ts", "**/*.tsx"],
4
- "exclude": ["**/node_modules", "**/Pods"]
5
- }