Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
react-native-notifications
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Jira
Jira
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
冷佳娟
react-native-notifications
Commits
c0e921c1
Commit
c0e921c1
authored
Aug 01, 2019
by
yogevbd
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
typescript WIP
parent
f666b856
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
377 additions
and
140 deletions
+377
-140
RNNotifications/RCTConvert+RNNotifications.m
RNNotifications/RCTConvert+RNNotifications.m
+1
-1
RNNotifications/RNNotificationParser.m
RNNotifications/RNNotificationParser.m
+2
-6
example/index.ios.js
example/index.ios.js
+59
-86
example/ios/NotificationsExampleApp.xcodeproj/project.pbxproj
...ple/ios/NotificationsExampleApp.xcodeproj/project.pbxproj
+45
-0
lib/src/Notifications.ts
lib/src/Notifications.ts
+5
-2
lib/src/adapters/CompletionCallbackWrapper.ts
lib/src/adapters/CompletionCallbackWrapper.ts
+29
-0
lib/src/adapters/NativeCommandsSender.mock.ts
lib/src/adapters/NativeCommandsSender.mock.ts
+1
-0
lib/src/adapters/NativeCommandsSender.ts
lib/src/adapters/NativeCommandsSender.ts
+12
-2
lib/src/adapters/NativeEventsReceiver.ts
lib/src/adapters/NativeEventsReceiver.ts
+20
-3
lib/src/commands/Commands.test.ts
lib/src/commands/Commands.test.ts
+5
-5
lib/src/commands/Commands.ts
lib/src/commands/Commands.ts
+1
-1
lib/src/events/EventsRegistry.test.ts
lib/src/events/EventsRegistry.test.ts
+140
-0
lib/src/events/EventsRegistry.test.tsx
lib/src/events/EventsRegistry.test.tsx
+0
-25
lib/src/events/EventsRegistry.ts
lib/src/events/EventsRegistry.ts
+30
-6
lib/src/interfaces/Notification.ts
lib/src/interfaces/Notification.ts
+12
-0
lib/src/interfaces/NotificationEvents.ts
lib/src/interfaces/NotificationEvents.ts
+15
-3
No files found.
RNNotifications/RCTConvert+RNNotifications.m
View file @
c0e921c1
...
...
@@ -109,7 +109,7 @@
formattedNotification
[
@"body"
]
=
RCTNullIfNil
(
content
.
body
);
formattedNotification
[
@"category"
]
=
RCTNullIfNil
(
content
.
categoryIdentifier
);
formattedNotification
[
@"thread"
]
=
RCTNullIfNil
(
content
.
threadIdentifier
);
[
formattedNotification
addEntriesFrom
Dictionary
:
RCTNullIfNil
(
RCTJSONClean
(
content
.
userInfo
))];
formattedNotification
[
@"data"
]
=
[
NSDictionary
dictionaryWith
Dictionary
:
RCTNullIfNil
(
RCTJSONClean
(
content
.
userInfo
))];
return
formattedNotification
;
}
...
...
RNNotifications/RNNotificationParser.m
View file @
c0e921c1
...
...
@@ -4,15 +4,11 @@
@implementation
RNNotificationParser
+
(
NSDictionary
*
)
parseNotification
:(
UNNotification
*
)
notification
{
NSDictionary
*
notificationDict
=
@{
@"identifier"
:
notification
.
request
.
identifier
,
@"payload"
:
[
RCTConvert
UNNotificationPayload
:
notification
]
};
return
notificationDict
;
return
[
RCTConvert
UNNotificationPayload
:
notification
];
}
+
(
NSDictionary
*
)
parseNotificationResponse
:(
UNNotificationResponse
*
)
response
{
NSDictionary
*
responseDict
=
@{
@"
payload
"
:
[
RCTConvert
UNNotificationPayload
:
response
.
notification
],
@"identifier"
:
response
.
notification
.
request
.
identifier
,
@"action"
:
[
self
parseNotificationResponseAction
:
response
]};
NSDictionary
*
responseDict
=
@{
@"
notification
"
:
[
RCTConvert
UNNotificationPayload
:
response
.
notification
],
@"identifier"
:
response
.
notification
.
request
.
identifier
,
@"action"
:
[
self
parseNotificationResponseAction
:
response
]};
return
responseDict
;
}
...
...
example/index.ios.js
View file @
c0e921c1
...
...
@@ -6,90 +6,92 @@ import {
Button
}
from
'
react-native
'
;
import
React
,
{
Component
}
from
'
react
'
;
import
{
Notifications
}
from
'
../lib/dist/index
'
;
// let upvoteAction = new NotificationAction({
// activationMode: 'background',
// title: String.fromCodePoint(0x1F44D),
// identifier: 'UPVOTE_ACTION'
// });
// let replyAction = new NotificationAction({
// activationMode: 'background',
// title: 'Reply',
// authenticationRequired: true,
// textInput: {
// buttonTitle: 'Reply now',
// placeholder: 'Insert message'
// },
// identifier: 'REPLY_ACTION'
// });
class
NotificationsExampleApp
extends
Component
{
constructor
()
{
super
();
this
.
state
=
{
notifications
:
[]
};
Notifications
.
events
().
registerNotificationsReceived
((
notification
)
=>
{
alert
(
JSON
.
stringify
(
notification
));
})
// NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
// NotificationsIOS.addEventListener('remoteNotificationsRegistrationFailed', this.onPushRegisteredFailed.bind(this));
this
.
registerNotificationEvents
();
}
// NotificationsIOS.addEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
// NotificationsIOS.registerPushKit();
registerNotificationEvents
()
{
Notifications
.
events
().
registerNotificationReceived
((
notification
,
completion
)
=>
{
this
.
setState
({
notifications
:
[...
this
.
state
.
notifications
,
notification
.
data
.
link
]
});
// NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
// NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this));
// NotificationsIOS.addEventListener('pushKitNotificationReceived', this.onPushKitNotificationReceived.bind(this));
}
completion
({
alert
:
true
,
sound
:
false
,
badge
:
false
});
});
async
componentDidMount
()
{
const
initialNotification
=
await
Notifications
.
getInitialNotification
();
if
(
initialNotification
)
{
this
.
setState
({
notifications
:
[
initialNotification
.
getData
().
link
,
...
this
.
state
.
notifications
]});
}
}
Notifications
.
events
().
registerRemoteNotificationOpened
((
response
,
completion
)
=>
{
this
.
setState
({
notifications
:
[...
this
.
state
.
notifications
,
`Notification Clicked:
${
response
.
notification
.
data
.
link
}
`
]
});
onPushRegistered
(
deviceToken
)
{
console
.
log
(
'
Device Token Received:
'
+
deviceToken
);
completion
();
}
);
}
onPushRegisteredFailed
(
error
)
{
console
.
log
(
'
Remote notifiction registration failed:
'
+
error
)
;
renderNotification
(
notification
)
{
return
<
Text
>
{
`
${
notification
}
`
}
<
/Text>
;
}
onPushKitRegistered
(
deviceToken
)
{
console
.
log
(
'
PushKit Token Received:
'
+
deviceToken
);
requestPermissions
(
)
{
Notifications
.
requestPermissions
(
);
}
onPushKitNotificationReceived
(
notification
)
{
console
.
log
(
'
PushKit notification Received:
'
+
JSON
.
stringify
(
notification
));
setCategories
()
{
const
upvoteAction
=
{
activationMode
:
'
background
'
,
title
:
String
.
fromCodePoint
(
0x1F44D
),
identifier
:
'
UPVOTE_ACTION
'
};
const
replyAction
=
{
activationMode
:
'
background
'
,
title
:
'
Reply
'
,
authenticationRequired
:
true
,
textInput
:
{
buttonTitle
:
'
Reply now
'
,
placeholder
:
'
Insert message
'
},
identifier
:
'
REPLY_ACTION
'
};
const
category
=
{
identifier
:
'
SOME_CATEGORY
'
,
actions
:
[
upvoteAction
,
replyAction
]
};
Notifications
.
setCategories
([
category
]);
}
onNotificationReceivedForeground
(
notification
,
completion
)
{
console
.
log
(
'
Notification Received Foreground with title:
'
+
JSON
.
stringify
(
notification
));
this
.
setState
({
notifications
:
[...
this
.
state
.
notifications
,
notification
.
getData
().
link
]
sendLocalNotification
()
{
Notifications
.
localNotification
({
body
:
'
Local notificiation!
'
,
title
:
'
Local Notification Title
'
,
sound
:
'
chime.aiff
'
,
category
:
'
SOME_CATEGORY
'
,
userInfo
:
{
link
:
'
localNotificationLink
'
},
});
}
completion
({
alert
:
notification
.
getData
().
showAlert
,
sound
:
false
,
badge
:
false
});
removeAllDeliveredNotifications
()
{
Notifications
.
removeAllDeliveredNotifications
();
}
onNotificationOpened
(
notification
,
completion
,
action
)
{
console
.
log
(
'
Notification Opened:
'
+
JSON
.
stringify
(
notification
)
+
JSON
.
stringify
(
action
));
this
.
setState
({
notifications
:
[...
this
.
state
.
notifications
,
`Notification Clicked:
${
notification
.
getData
().
link
}
`
]
});
completion
();
async
componentDidMount
()
{
const
initialNotification
=
await
Notifications
.
getInitialNotification
();
if
(
initialNotification
)
{
this
.
setState
({
notifications
:
[
initialNotification
.
data
.
link
,
...
this
.
state
.
notifications
]});
}
}
renderNotification
(
notification
)
{
return
<
Text
>
{
`
${
notification
}
`
}
<
/Text>
;
componentWillUnmount
()
{
}
render
()
{
...
...
@@ -109,35 +111,6 @@ class NotificationsExampleApp extends Component {
<
/View
>
);
}
requestPermissions
()
{
// let cat = new NotificationCategory({
// identifier: 'SOME_CATEGORY',
// actions: [upvoteAction, replyAction]
// });
Notifications
.
requestPermissions
(
/*[cat]*/
);
}
sendLocalNotification
()
{
Notifications
.
localNotification
({
body
:
'
Local notificiation!
'
,
title
:
'
Local Notification Title
'
,
sound
:
'
chime.aiff
'
,
category
:
'
SOME_CATEGORY
'
,
userInfo
:
{
link
:
'
localNotificationLink
'
},
});
}
removeAllDeliveredNotifications
()
{
// NotificationsIOS.removeAllDeliveredNotifications();
}
componentWillUnmount
()
{
// NotificationsIOS.removeEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
// NotificationsIOS.removeEventListener('notificationOpened', this.onNotificationOpened.bind(this));
// NotificationsIOS.removeEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
// NotificationsIOS.removeEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
}
}
const
styles
=
StyleSheet
.
create
({
...
...
example/ios/NotificationsExampleApp.xcodeproj/project.pbxproj
View file @
c0e921c1
...
...
@@ -11,6 +11,7 @@
13B07FBD1A68108700A75B9A
/* LaunchScreen.xib in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
13B07FB11A68108700A75B9A
/* LaunchScreen.xib */
;
};
13B07FBF1A68108700A75B9A
/* Images.xcassets in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
13B07FB51A68108700A75B9A
/* Images.xcassets */
;
};
13B07FC11A68108700A75B9A
/* main.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
13B07FB71A68108700A75B9A
/* main.m */
;
};
50CBD3CD22F2558C00142352
/* libRCTAnimation.a in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
50CBD3A922F2556900142352
/* libRCTAnimation.a */
;
};
50F1F0CC22CE3B4700FD5829
/* libReact.a in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
50F1F06022CE3A6100FD5829
/* libReact.a */
;
};
50F1F0CD22CE3B6300FD5829
/* libRCTActionSheet.a in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
50F1F08A22CE3AA000FD5829
/* libRCTActionSheet.a */
;
};
50F1F0CF22CE3B6300FD5829
/* libRCTImage.a in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
50F1F09522CE3ABE00FD5829
/* libRCTImage.a */
;
};
...
...
@@ -27,6 +28,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
50CBD3A822F2556900142352
/* PBXContainerItemProxy */
=
{
isa
=
PBXContainerItemProxy
;
containerPortal
=
50CBD3A222F2556900142352
/* RCTAnimation.xcodeproj */
;
proxyType
=
2
;
remoteGlobalIDString
=
134814201AA4EA6300B7C361
;
remoteInfo
=
RCTAnimation
;
};
50CBD3AA22F2556900142352
/* PBXContainerItemProxy */
=
{
isa
=
PBXContainerItemProxy
;
containerPortal
=
50CBD3A222F2556900142352
/* RCTAnimation.xcodeproj */
;
proxyType
=
2
;
remoteGlobalIDString
=
2D2A28201D9B03D100D4039D
;
remoteInfo
=
"RCTAnimation-tvOS"
;
};
50E49F4022D1F06C007160C1
/* PBXContainerItemProxy */
=
{
isa
=
PBXContainerItemProxy
;
containerPortal
=
146833FF1AC3E56700842450
/* React.xcodeproj */
;
...
...
@@ -283,6 +298,7 @@
13B07FB61A68108700A75B9A
/* Info.plist */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.plist.xml
;
name
=
Info.plist
;
path
=
NotificationsExampleApp/Info.plist
;
sourceTree
=
"<group>"
;
};
13B07FB71A68108700A75B9A
/* main.m */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.c.objc
;
name
=
main.m
;
path
=
NotificationsExampleApp/main.m
;
sourceTree
=
"<group>"
;
};
146833FF1AC3E56700842450
/* React.xcodeproj */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
"wrapper.pb-project"
;
name
=
React.xcodeproj
;
path
=
"../../node_modules/react-native/React/React.xcodeproj"
;
sourceTree
=
"<group>"
;
};
50CBD3A222F2556900142352
/* RCTAnimation.xcodeproj */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
"wrapper.pb-project"
;
name
=
RCTAnimation.xcodeproj
;
path
=
"../../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"
;
sourceTree
=
"<group>"
;
};
50F1F08522CE3A9F00FD5829
/* RCTActionSheet.xcodeproj */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
"wrapper.pb-project"
;
name
=
RCTActionSheet.xcodeproj
;
path
=
"../../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"
;
sourceTree
=
"<group>"
;
};
50F1F0A022CE3B0600FD5829
/* RCTNetwork.xcodeproj */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
"wrapper.pb-project"
;
name
=
RCTNetwork.xcodeproj
;
path
=
"../../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"
;
sourceTree
=
"<group>"
;
};
78C398B01ACF4ADC00677621
/* RCTLinking.xcodeproj */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
"wrapper.pb-project"
;
name
=
RCTLinking.xcodeproj
;
path
=
"../../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"
;
sourceTree
=
"<group>"
;
};
...
...
@@ -296,6 +312,7 @@
isa
=
PBXFrameworksBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
50CBD3CD22F2558C00142352
/* libRCTAnimation.a in Frameworks */
,
50F1F0D722CE3C1E00FD5829
/* libcxxreact.a in Frameworks */
,
50F1F0D622CE3C0F00FD5829
/* libyoga.a in Frameworks */
,
50F1F0CD22CE3B6300FD5829
/* libRCTActionSheet.a in Frameworks */
,
...
...
@@ -346,6 +363,15 @@
name
=
NotificationsExampleApp
;
sourceTree
=
"<group>"
;
};
50CBD3A322F2556900142352
/* Products */
=
{
isa
=
PBXGroup
;
children
=
(
50CBD3A922F2556900142352
/* libRCTAnimation.a */
,
50CBD3AB22F2556900142352
/* libRCTAnimation.a */
,
);
name
=
Products
;
sourceTree
=
"<group>"
;
};
50F1F04D22CE3A6100FD5829
/* Products */
=
{
isa
=
PBXGroup
;
children
=
(
...
...
@@ -444,6 +470,7 @@
832341AE1AAA6A7D00B99B32
/* Libraries */
=
{
isa
=
PBXGroup
;
children
=
(
50CBD3A222F2556900142352
/* RCTAnimation.xcodeproj */
,
50F1F0A022CE3B0600FD5829
/* RCTNetwork.xcodeproj */
,
D85498C21D97B31100DEEE06
/* RNNotifications.xcodeproj */
,
146833FF1AC3E56700842450
/* React.xcodeproj */
,
...
...
@@ -542,6 +569,10 @@
ProductGroup
=
50F1F08622CE3A9F00FD5829
/* Products */
;
ProjectRef
=
50F1F08522CE3A9F00FD5829
/* RCTActionSheet.xcodeproj */
;
},
{
ProductGroup
=
50CBD3A322F2556900142352
/* Products */
;
ProjectRef
=
50CBD3A222F2556900142352
/* RCTAnimation.xcodeproj */
;
},
{
ProductGroup
=
50F1F09022CE3ABE00FD5829
/* Products */
;
ProjectRef
=
00C302BB1ABCB91800DB3ED1
/* RCTImage.xcodeproj */
;
...
...
@@ -587,6 +618,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
50CBD3A922F2556900142352
/* libRCTAnimation.a */
=
{
isa
=
PBXReferenceProxy
;
fileType
=
archive.ar
;
path
=
libRCTAnimation.a
;
remoteRef
=
50CBD3A822F2556900142352
/* PBXContainerItemProxy */
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
50CBD3AB22F2556900142352
/* libRCTAnimation.a */
=
{
isa
=
PBXReferenceProxy
;
fileType
=
archive.ar
;
path
=
libRCTAnimation.a
;
remoteRef
=
50CBD3AA22F2556900142352
/* PBXContainerItemProxy */
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
50E49F4122D1F06C007160C1
/* libjsi.a */
=
{
isa
=
PBXReferenceProxy
;
fileType
=
archive.ar
;
...
...
lib/src/Notifications.ts
View file @
c0e921c1
...
...
@@ -4,6 +4,7 @@ import { Commands } from './commands/Commands';
import
{
EventsRegistry
}
from
'
./events/EventsRegistry
'
;
import
{
Notification
,
NotificationCategory
}
from
'
./interfaces/Notification
'
;
import
{
UniqueIdProvider
}
from
'
./adapters/UniqueIdProvider
'
;
import
{
CompletionCallbackWrapper
}
from
'
./adapters/CompletionCallbackWrapper
'
;
export
class
NotificationsRoot
{
private
readonly
nativeEventsReceiver
:
NativeEventsReceiver
;
...
...
@@ -11,16 +12,18 @@ export class NotificationsRoot {
private
readonly
commands
:
Commands
;
private
readonly
eventsRegistry
:
EventsRegistry
;
private
readonly
uniqueIdProvider
:
UniqueIdProvider
;
private
readonly
completionCallbackWrapper
:
CompletionCallbackWrapper
;
constructor
()
{
this
.
nativeEventsReceiver
=
new
NativeEventsReceiver
();
this
.
nativeCommandsSender
=
new
NativeCommandsSender
();
this
.
completionCallbackWrapper
=
new
CompletionCallbackWrapper
(
this
.
nativeCommandsSender
);
this
.
uniqueIdProvider
=
new
UniqueIdProvider
();
this
.
commands
=
new
Commands
(
this
.
nativeCommandsSender
,
this
.
uniqueIdProvider
);
this
.
eventsRegistry
=
new
EventsRegistry
(
this
.
nativeEventsReceiver
);
this
.
eventsRegistry
=
new
EventsRegistry
(
this
.
nativeEventsReceiver
,
this
.
completionCallbackWrapper
);
}
/**
...
...
@@ -45,7 +48,7 @@ export class NotificationsRoot {
}
/**
*
*
getInitialNotification
*/
public
getInitialNotification
():
Promise
<
Notification
>
{
return
this
.
commands
.
getInitialNotification
();
...
...
lib/src/adapters/CompletionCallbackWrapper.ts
0 → 100644
View file @
c0e921c1
import
{
NativeCommandsSender
}
from
'
./NativeCommandsSender
'
;
import
{
NotificationCompletion
,
Notification
}
from
'
../interfaces/Notification
'
;
import
{
NotificationResponse
}
from
'
../interfaces/NotificationEvents
'
;
export
class
CompletionCallbackWrapper
{
constructor
(
private
readonly
nativeCommandsSender
:
NativeCommandsSender
)
{}
public
wrapReceivedCallback
(
callback
:
Function
):
(
notification
:
Notification
)
=>
void
{
return
(
notification
)
=>
{
const
completion
=
(
response
:
NotificationCompletion
)
=>
{
this
.
nativeCommandsSender
.
finishPresentingNotification
(
notification
.
identifier
,
response
);
};
callback
(
notification
,
completion
);
}
}
public
wrapOpenedCallback
(
callback
:
Function
):
(
response
:
NotificationResponse
)
=>
void
{
return
(
response
)
=>
{
const
completion
=
()
=>
{
this
.
nativeCommandsSender
.
finishHandlingAction
(
response
.
notification
.
identifier
);
};
callback
(
response
,
completion
);
}
}
}
lib/src/adapters/NativeCommandsSender.mock.ts
0 → 100644
View file @
c0e921c1
export
const
{
NativeCommandsSender
}
=
jest
.
genMockFromModule
(
'
./NativeCommandsSender
'
);
lib/src/adapters/NativeCommandsSender.ts
View file @
c0e921c1
import
{
NativeModules
}
from
'
react-native
'
;
import
{
Notification
,
NotificationCategory
,
NotificationPermissions
}
from
'
../interfaces/Notification
'
;
import
{
Notification
,
NotificationCategory
,
NotificationPermissions
,
NotificationCompletion
}
from
'
../interfaces/Notification
'
;
interface
NativeCommandsModule
{
getInitialNotification
():
Promise
<
Notification
>
;
...
...
@@ -16,6 +16,8 @@ interface NativeCommandsModule {
removeDeliveredNotifications
(
identifiers
:
Array
<
string
>
):
void
;
removeAllDeliveredNotifications
():
void
;
setCategories
(
categories
:
[
NotificationCategory
?]):
void
;
finishPresentingNotification
(
notificationId
:
string
,
callback
:
NotificationCompletion
):
void
;
finishHandlingAction
(
notificationId
:
string
):
void
;
}
export
class
NativeCommandsSender
{
...
...
@@ -28,7 +30,7 @@ export class NativeCommandsSender {
return
this
.
nativeCommandsModule
.
localNotification
(
notification
,
id
);
}
getInitialNotification
()
{
getInitialNotification
()
:
Promise
<
Notification
>
{
return
this
.
nativeCommandsModule
.
getInitialNotification
();
}
...
...
@@ -79,4 +81,12 @@ export class NativeCommandsSender {
removeDeliveredNotifications
(
identifiers
:
Array
<
string
>
)
{
return
this
.
nativeCommandsModule
.
removeDeliveredNotifications
(
identifiers
);
}
finishPresentingNotification
(
notificationId
:
string
,
notificationCompletion
:
NotificationCompletion
):
void
{
this
.
nativeCommandsModule
.
finishPresentingNotification
(
notificationId
,
notificationCompletion
);
}
finishHandlingAction
(
notificationId
:
string
):
void
{
this
.
nativeCommandsModule
.
finishHandlingAction
(
notificationId
);
}
}
lib/src/adapters/NativeEventsReceiver.ts
View file @
c0e921c1
import
{
NativeModules
,
NativeEventEmitter
,
EventEmitter
,
EmitterSubscription
}
from
'
react-native
'
;
import
{
NotificationRegisteredEvent
,
NotificationReceived
Registered
,
RegistrationError
,
RegisteredPushKit
,
NotificationResponse
}
from
'
../interfaces/NotificationEvents
'
;
import
{
Notification
}
from
'
../interfaces/Notification
'
;
export
class
NativeEventsReceiver
{
private
emitter
:
EventEmitter
;
...
...
@@ -9,11 +10,27 @@ export class NativeEventsReceiver {
this
.
emitter
=
new
NativeEventEmitter
(
NativeModules
.
RNEventEmitter
);
}
public
registerRemoteNotificationsRegistered
(
callback
:
(
event
:
NotificationRegisteredEvent
)
=>
void
):
EmitterSubscription
{
public
registerRemoteNotificationsRegistered
(
callback
:
(
event
:
Registered
)
=>
void
):
EmitterSubscription
{
return
this
.
emitter
.
addListener
(
'
remoteNotificationsRegistered
'
,
callback
);
}
public
registerRemoteNotificationReceived
(
callback
:
(
event
:
NotificationReceived
)
=>
void
):
EmitterSubscription
{
public
registerPushKitRegistered
(
callback
:
(
event
:
RegisteredPushKit
)
=>
void
):
EmitterSubscription
{
return
this
.
emitter
.
addListener
(
'
pushKitRegistered
'
,
callback
);
}
public
registerRemoteNotificationReceived
(
callback
:
(
notification
:
Notification
)
=>
void
):
EmitterSubscription
{
return
this
.
emitter
.
addListener
(
'
notificationReceivedForeground
'
,
callback
);
}
public
registerPushKitNotificationReceived
(
callback
:
(
event
:
object
)
=>
void
):
EmitterSubscription
{
return
this
.
emitter
.
addListener
(
'
notificationReceivedForeground
'
,
callback
);
}
public
registerRemoteNotificationOpened
(
callback
:
(
response
:
NotificationResponse
,
completion
:
()
=>
void
)
=>
void
):
EmitterSubscription
{
return
this
.
emitter
.
addListener
(
'
notificationOpened
'
,
callback
);
}
public
registerRemoteNotificationsRegistrationFailed
(
callback
:
(
event
:
RegistrationError
)
=>
void
):
EmitterSubscription
{
return
this
.
emitter
.
addListener
(
'
remoteNotificationsRegistrationFailed
'
,
callback
);
}
}
lib/src/commands/Commands.test.ts
View file @
c0e921c1
import
*
as
_
from
'
lodash
'
;
import
{
mock
,
verify
,
instance
,
deepEqual
,
when
,
anything
,
anyString
}
from
'
ts-mockito
'
;
import
{
mock
,
verify
,
instance
,
when
,
anything
,
anyString
}
from
'
ts-mockito
'
;
import
{
Commands
}
from
'
./Commands
'
;
import
{
NativeCommandsSender
}
from
'
../adapters/NativeCommandsSender
'
;
...
...
@@ -28,7 +28,7 @@ describe('Commands', () => {
});
it
(
'
returns a promise with the initial notification
'
,
async
()
=>
{
const
expectedNotification
:
Notification
=
{
data
:
{},
alert
:
'
alert
'
};
const
expectedNotification
:
Notification
=
{
identifier
:
'
id
'
,
data
:
{},
alert
:
'
alert
'
};
when
(
mockedNativeCommandsSender
.
getInitialNotification
()).
thenResolve
(
expectedNotification
);
...
...
@@ -75,19 +75,19 @@ describe('Commands', () => {
describe
(
'
sendLocalNotification
'
,
()
=>
{
it
(
'
sends to native
'
,
()
=>
{
const
notification
:
Notification
=
{
data
:
{},
alert
:
'
alert
'
};
const
notification
:
Notification
=
{
identifier
:
'
id
'
,
alert
:
'
alert
'
,
data
:
{}
};
uut
.
sendLocalNotification
(
notification
);
verify
(
mockedNativeCommandsSender
.
sendLocalNotification
(
notification
,
anyString
())).
called
();
});
it
(
'
generates unique identifier
'
,
()
=>
{
const
notification
:
Notification
=
{
data
:
{},
alert
:
'
alert
'
};
const
notification
:
Notification
=
{
identifier
:
'
id
'
,
data
:
{},
alert
:
'
alert
'
};
uut
.
sendLocalNotification
(
notification
);
verify
(
mockedNativeCommandsSender
.
sendLocalNotification
(
notification
,
`Notification_+UNIQUE_ID`
)).
called
();
});
it
(
'
use passed notification id
'
,
()
=>
{
const
notification
:
Notification
=
{
data
:
{},
alert
:
'
alert
'
};
const
notification
:
Notification
=
{
identifier
:
'
id
'
,
data
:
{},
alert
:
'
alert
'
};
const
passedId
:
string
=
"
passedId
"
;
uut
.
sendLocalNotification
(
notification
,
passedId
);
verify
(
mockedNativeCommandsSender
.
sendLocalNotification
(
notification
,
passedId
)).
called
();
...
...
lib/src/commands/Commands.ts
View file @
c0e921c1
...
...
@@ -15,7 +15,7 @@ export class Commands {
return
result
;
}
public
getInitialNotification
()
{
public
getInitialNotification
()
:
Promise
<
Notification
>
{
const
result
=
this
.
nativeCommandsSender
.
getInitialNotification
();
return
result
;
}
...
...
lib/src/events/EventsRegistry.test.ts
0 → 100644
View file @
c0e921c1
import
{
EventsRegistry
}
from
'
./EventsRegistry
'
;
import
{
NativeEventsReceiver
}
from
'
../adapters/NativeEventsReceiver.mock
'
;
import
{
NotificationCompletion
,
Notification
}
from
'
../interfaces/Notification
'
;
import
{
CompletionCallbackWrapper
}
from
'
../adapters/CompletionCallbackWrapper
'
;
import
{
NativeCommandsSender
}
from
'
../adapters/NativeCommandsSender.mock
'
;
import
{
NotificationResponse
}
from
'
../interfaces/NotificationEvents
'
;
describe
(
'
EventsRegistry
'
,
()
=>
{
let
uut
:
EventsRegistry
;
const
mockNativeEventsReceiver
=
new
NativeEventsReceiver
();
const
mockNativeCommandsSender
=
new
NativeCommandsSender
();
const
completionCallbackWrapper
=
new
CompletionCallbackWrapper
(
mockNativeCommandsSender
);
beforeEach
(()
=>
{
uut
=
new
EventsRegistry
(
mockNativeEventsReceiver
,
completionCallbackWrapper
);
});
describe
(
'
registerRemoteNotificationsReceived
'
,
()
=>
{
it
(
'
delegates to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerNotificationReceived
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
).
toHaveBeenCalledWith
(
expect
.
any
(
Function
));
});
it
(
'
should wrap callback with completion block
'
,
()
=>
{
const
wrappedCallback
=
jest
.
fn
();
const
notification
:
Notification
=
{
identifier
:
'
identifier
'
,
data
:
{},
alert
:
'
alert
'
}
uut
.
registerNotificationReceived
(
wrappedCallback
);
const
call
=
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
.
mock
.
calls
[
0
][
0
];
call
(
notification
);
expect
(
wrappedCallback
).
toBeCalledWith
(
notification
,
expect
.
any
(
Function
));
expect
(
wrappedCallback
).
toBeCalledTimes
(
1
);
});
it
(
'
should wrap callback with completion block
'
,
()
=>
{
const
expectedNotification
:
Notification
=
{
identifier
:
'
identifier
'
,
data
:
{},
alert
:
'
alert
'
}
uut
.
registerNotificationReceived
((
notification
)
=>
{
expect
(
notification
).
toEqual
(
expectedNotification
);
});
const
call
=
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
.
mock
.
calls
[
0
][
0
];
call
(
expectedNotification
);
});
it
(
'
calling completion should invoke finishPresentingNotification
'
,
()
=>
{
const
notification
:
Notification
=
{
identifier
:
'
notificationId
'
,
data
:
{},
alert
:
'
alert
'
}
const
response
:
NotificationCompletion
=
{
alert
:
true
}
uut
.
registerNotificationReceived
((
notification
,
completion
)
=>
{
completion
(
response
);
expect
(
mockNativeCommandsSender
.
finishPresentingNotification
).
toBeCalledWith
(
notification
.
identifier
,
response
);
});
const
call
=
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
.
mock
.
calls
[
0
][
0
];
call
(
notification
);
});
});
describe
(
''
,
()
=>
{
it
(
'
delegates to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerRemoteNotificationOpened
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationOpened
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationOpened
).
toHaveBeenCalledWith
(
expect
.
any
(
Function
));
});
it
(
'
should wrap callback with completion block
'
,
()
=>
{
const
wrappedCallback
=
jest
.
fn
();
const
notification
:
Notification
=
{
identifier
:
'
identifier
'
,
data
:
{},
alert
:
'
alert
'
};
const
response
:
NotificationResponse
=
{
notification
,
identifier
:
'
responseId
'
};
uut
.
registerRemoteNotificationOpened
(
wrappedCallback
);
const
call
=
mockNativeEventsReceiver
.
registerRemoteNotificationOpened
.
mock
.
calls
[
0
][
0
];
call
(
response
);
expect
(
wrappedCallback
).
toBeCalledWith
(
response
,
expect
.
any
(
Function
));
expect
(
wrappedCallback
).
toBeCalledTimes
(
1
);
});
it
(
'
should wrap callback with completion block
'
,
()
=>
{
const
notification
:
Notification
=
{
identifier
:
'
identifier
'
,
data
:
{},
alert
:
'
alert
'
}
const
expectedResponse
:
NotificationResponse
=
{
notification
,
identifier
:
'
responseId
'
}
uut
.
registerRemoteNotificationOpened
((
response
)
=>
{
expect
(
response
).
toEqual
(
expectedResponse
);
});
const
call
=
mockNativeEventsReceiver
.
registerRemoteNotificationOpened
.
mock
.
calls
[
0
][
0
];
call
(
expectedResponse
);
});
it
(
'
calling completion should invoke finishHandlingAction
'
,
()
=>
{
const
notification
:
Notification
=
{
identifier
:
'
notificationId
'
,
data
:
{},
alert
:
'
alert
'
}
const
expectedResponse
:
NotificationResponse
=
{
identifier
:
'
responseId
'
,
notification
};
uut
.
registerRemoteNotificationOpened
((
response
,
completion
)
=>
{
completion
();
expect
(
response
).
toEqual
(
expectedResponse
);
expect
(
mockNativeCommandsSender
.
finishHandlingAction
).
toBeCalledWith
(
notification
.
identifier
);
});
const
call
=
mockNativeEventsReceiver
.
registerRemoteNotificationOpened
.
mock
.
calls
[
0
][
0
];
call
(
expectedResponse
);
});
});
it
(
'
delegates registerRemoteNotificationsRegistered to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerRemoteNotificationsRegistered
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationsRegistered
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationsRegistered
).
toHaveBeenCalledWith
(
cb
);
});
it
(
'
delegates registerPushKitRegistered to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerPushKitRegistered
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerPushKitRegistered
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerPushKitRegistered
).
toHaveBeenCalledWith
(
cb
);
});
it
(
'
delegates registerPushKitNotificationReceived to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerPushKitNotificationReceived
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerPushKitNotificationReceived
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerPushKitNotificationReceived
).
toHaveBeenCalledWith
(
cb
);
});
it
(
'
delegates registerRemoteNotificationsRegistrationFailed to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerRemoteNotificationsRegistrationFailed
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationsRegistrationFailed
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationsRegistrationFailed
).
toHaveBeenCalledWith
(
cb
);
});
});
lib/src/events/EventsRegistry.test.tsx
deleted
100644 → 0
View file @
f666b856
import
{
EventsRegistry
}
from
'
./EventsRegistry
'
;
import
{
NativeEventsReceiver
}
from
'
../adapters/NativeEventsReceiver.mock
'
;
describe
(
'
EventsRegistry
'
,
()
=>
{
let
uut
:
EventsRegistry
;
const
mockNativeEventsReceiver
=
new
NativeEventsReceiver
();
beforeEach
(()
=>
{
uut
=
new
EventsRegistry
(
mockNativeEventsReceiver
);
});
it
(
'
delegates registerRemoteNotificationsRegistered to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerRemoteNotificationsRegistered
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationsRegistered
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationsRegistered
).
toHaveBeenCalledWith
(
cb
);
});
it
(
'
delegates registerRemoteNotificationsReceived to nativeEventsReceiver
'
,
()
=>
{
const
cb
=
jest
.
fn
();
uut
.
registerNotificationReceived
(
cb
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockNativeEventsReceiver
.
registerRemoteNotificationReceived
).
toHaveBeenCalledWith
(
cb
);
});
});
lib/src/events/EventsRegistry.ts
View file @
c0e921c1
import
{
EmitterSubscription
}
from
'
react-native
'
;
import
{
NativeEventsReceiver
}
from
'
../adapters/NativeEventsReceiver
'
;
import
{
NotificationRegisteredEvent
,
NotificationReceived
Registered
,
RegistrationError
,
RegisteredPushKit
,
NotificationResponse
}
from
'
../interfaces/NotificationEvents
'
;
import
{
CompletionCallbackWrapper
}
from
'
../adapters/CompletionCallbackWrapper
'
;
import
{
NotificationCompletion
,
Notification
}
from
'
../interfaces/Notification
'
;
export
class
EventsRegistry
{
constructor
(
private
nativeEventsReceiver
:
NativeEventsReceiver
)
{
}
constructor
(
private
nativeEventsReceiver
:
NativeEventsReceiver
,
private
completionCallbackWrapper
:
CompletionCallbackWrapper
)
{}
public
registerRemoteNotificationsRegistered
(
callback
:
(
event
:
NotificationRegisteredEvent
)
=>
void
):
EmitterSubscription
{
public
registerRemoteNotificationsRegistered
(
callback
:
(
event
:
Registered
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
registerRemoteNotificationsRegistered
(
callback
);
}
public
register
NotificationReceived
(
callback
:
(
event
:
NotificationReceived
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
register
RemoteNotificationReceiv
ed
(
callback
);
public
register
PushKitRegistered
(
callback
:
(
event
:
RegisteredPushKit
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
register
PushKitRegister
ed
(
callback
);
}
public
registerNotificationReceived
(
callback
:
(
notification
:
Notification
,
completion
:
(
response
:
NotificationCompletion
)
=>
void
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
registerRemoteNotificationReceived
(
this
.
completionCallbackWrapper
.
wrapReceivedCallback
(
callback
));
}
public
registerPushKitNotificationReceived
(
callback
:
(
event
:
object
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
registerPushKitNotificationReceived
(
callback
);
}
public
registerRemoteNotificationOpened
(
callback
:
(
response
:
NotificationResponse
,
completion
:
()
=>
void
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
registerRemoteNotificationOpened
(
this
.
completionCallbackWrapper
.
wrapOpenedCallback
(
callback
));
}
public
registerRemoteNotificationsRegistrationFailed
(
callback
:
(
event
:
RegistrationError
)
=>
void
):
EmitterSubscription
{
return
this
.
nativeEventsReceiver
.
registerRemoteNotificationsRegistrationFailed
(
callback
);
}
}
lib/src/interfaces/Notification.ts
View file @
c0e921c1
export
interface
Notification
{
identifier
:
string
;
data
:
object
;
alert
:
string
sound
?:
string
;
...
...
@@ -31,3 +32,14 @@ export interface NotificationAction {
authenticationRequired
:
boolean
;
textInput
:
NotificationTextInput
}
export
interface
NotificationActionResponse
{
identifier
:
string
;
text
:
string
;
}
export
interface
NotificationCompletion
{
badge
?:
boolean
;
alert
?:
boolean
;
sound
?:
boolean
;
}
lib/src/interfaces/NotificationEvents.ts
View file @
c0e921c1
import
{
Notification
}
from
'
./Notification
'
;
import
{
Notification
,
NotificationActionResponse
}
from
'
./Notification
'
;
export
interface
NotificationRegisteredEvent
{
export
interface
Registered
{
deviceToken
:
string
;
}
export
interface
NotificationReceived
{
export
interface
RegistrationError
{
code
:
string
;
domain
:
string
;
localizedDescription
:
string
;
}
export
interface
RegisteredPushKit
{
pushKitToken
:
string
;
}
export
interface
NotificationResponse
{
identifier
:
string
;
notification
:
Notification
;
action
?:
NotificationActionResponse
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment