Skip to content

Commit f1b2665

Browse files
authored
layout fix (#12)
1 parent 3eb55c1 commit f1b2665

File tree

7 files changed

+228
-132
lines changed

7 files changed

+228
-132
lines changed

README.md

+12-11
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,25 @@ TimerNotification({
6060

6161

6262
```javascript
63-
CustomTimerNotification.TimerNotification({
64-
id: 2,
65-
title: "Special Offer!",
66-
body: "Limited time offer ends in:",
67-
date: "25-12-2024 23:59:59",
68-
gifUrl: "https://example.com/animation.gif",
69-
payload: "offer-456"
63+
TimerNotification({
64+
id: 2,
65+
title: <p style="color: #ff5722; font-size: 18px;"><b>🔥 Limited-Time Deal! Hurry Up!</b></p>,
66+
body: <p style="font-size: 14px;">⏳ Time is running out! <b>Claim your exclusive discount</b> before it's too late.</p>,
67+
subtitle: "💸",
68+
date: new Date(Date.now() + 20000),
69+
giffyUrl: "https://media1.tenor.com/m/EBdqcf-JxpYAAAAC/6m-rain.gif",
70+
payload: "offer-456"
7071
});
7172
```
7273
#### Options
7374
7475
| Parameter | Type | Required | Description |
7576
|-----------|----------|----------|---------------------------------|
7677
| id | number | Yes | Unique notification identifier |
77-
| title | string | Yes | Notification title |
78-
| body | string | Yes | Notification message |
79-
| date | string | Yes | End date (dd-MM-yyyy HH:mm:ss) |
80-
| gifUrl | string | No | URL to GIF animation |
78+
| title | string | Yes | Notification title with HTML support |
79+
| body | string | Yes | Notification message with HTML support |
80+
| date | Date | No | End date with time (dd-MM-yyyy HH:mm:ss) |
81+
| giffyUrl | string | No | URL to GIF animation |
8182
| payload | string | No | Custom data payload |
8283
8384
## Full Custom Notification

android/src/main/java/com/reactnativecustomtimernotification/AnimationManager.kt

+19-10
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ data class NotificationConfig(
3636
val subtitle: String?,
3737
val smallIcon: Int = android.R.drawable.ic_dialog_info,
3838
val countdownDuration: Long = 5000,
39-
val payload: String?
39+
val payload: String?,
40+
val body: String?
4041
)
4142

4243

@@ -60,12 +61,11 @@ class AnimatedNotificationManager(
6061
try {
6162
val extras = intent.extras
6263
val params: WritableMap = Arguments.createMap()
64+
params.putString("id", extras!!.getString("id"))
6365
params.putString("action", extras!!.getString("action"))
6466
params.putString("payload", extras!!.getString("payload"))
6567
Log.d(TAG, extras?.getString("payload")?:"")
66-
if(extras!!.getString("action") == "cancel"){
67-
disableCurrentNotification = true
68-
}
68+
disableCurrentNotification = true
6969
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
7070
.emit(
7171
"notificationClick",
@@ -115,7 +115,8 @@ class AnimatedNotificationManager(
115115
val remoteViews = RemoteViews(context.packageName, R.layout.gen_notification_open)
116116

117117
if(config.gifUrl !== null){
118-
val frames = processGif(config.gifUrl, memoryLimitMB = GIF_MEMORY_LIMIT_MB)
118+
val gifProcessor = GifProcessor()
119+
val frames = gifProcessor.processGif(config.gifUrl, memoryLimitMB = GIF_MEMORY_LIMIT_MB)
119120

120121
frames.forEach { frame ->
121122
val frameView = RemoteViews(context.packageName, R.layout.giffy_image)
@@ -143,25 +144,30 @@ class AnimatedNotificationManager(
143144
}
144145
} else null
145146

146-
val subtitleHtml = if(config.title != null) {
147+
val bodyHtml = if(config.title != null) {
147148
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
148-
Html.fromHtml(config.subtitle, Html.FROM_HTML_MODE_COMPACT)
149+
Html.fromHtml(config.body, Html.FROM_HTML_MODE_COMPACT)
149150
} else {
150-
Html.fromHtml(config.subtitle)
151+
Html.fromHtml(config.body)
151152
}
152153
} else null
153154

154155
if(titleHtml != null)
155156
remoteViews.setTextViewText(R.id.title, titleHtml)
156157

157-
if(subtitleHtml != null)
158-
remoteViews.setTextViewText(R.id.subtitle, subtitleHtml)
158+
if(bodyHtml != null)
159+
remoteViews.setTextViewText(R.id.body, bodyHtml)
159160
}
160161

161162
private fun configureChronometer(remoteViews: RemoteViews, countdownDuration: Long) {
163+
if(countdownDuration !== null){
162164
val chronometerBaseTime = countdownDuration
163165
remoteViews.setChronometerCountDown(R.id.simpleChronometer, true)
164166
remoteViews.setChronometer(R.id.simpleChronometer, chronometerBaseTime, null, true)
167+
} else {
168+
remoteViews.setViewVisibility(R.id.simpleChronometer, View.GONE)
169+
}
170+
165171
}
166172

167173
private fun buildNotification(remoteViews: RemoteViews, config: NotificationConfig): NotificationCompat.Builder {
@@ -204,6 +210,9 @@ class AnimatedNotificationManager(
204210
.setOnlyAlertOnce(true)
205211
.setAutoCancel(true)
206212
.setDeleteIntent(onDismissPendingIntent)
213+
.apply {
214+
config.subtitle?.let { setSubText(it) }
215+
}
207216
.setContentIntent(pendingIntent)
208217

209218

android/src/main/java/com/reactnativecustomtimernotification/CustomTimerNotificationModule.kt

+39-21
Original file line numberDiff line numberDiff line change
@@ -54,29 +54,47 @@ var removedNotification = false;
5454
return "CustomTimerNotification"
5555
}
5656

57-
5857
@ReactMethod
59-
fun TimerNotification(objectData:ReadableMap) {
60-
val payload = objectData.getString(Constants.NOTIFICATION.PAYLOAD);
61-
val title = objectData.getString(Constants.NOTIFICATION.TITLE);
62-
val body = objectData.getString(Constants.NOTIFICATION.BODY);
63-
val id = objectData.getInt(Constants.NOTIFICATION.ID);
64-
val gifUrl = objectData.getString(Constants.NOTIFICATION.GIFFY_URl)
65-
val notificationHelper = AnimatedNotificationManager(myContext)
66-
67-
val datetime = objectData.getString("date")
68-
val sdf = SimpleDateFormat("dd-MM-yyyy HH:mm:ss", Locale.ENGLISH)
69-
70-
val startTime = SystemClock.elapsedRealtime()
71-
val endTime: Calendar = Calendar.getInstance()
72-
endTime.time = sdf.parse(datetime)
73-
74-
val now = Date()
75-
val elapsed: Long = now.getTime() - endTime.timeInMillis
76-
val remainingTime = startTime - elapsed
77-
78-
notificationHelper.showAnimatedNotification(NotificationConfig(gifUrl = gifUrl, title=title, subtitle=body, payload=payload, notificationId=id, countdownDuration = remainingTime))
58+
fun TimerNotification(objectData: ReadableMap) {
59+
val payload = if (objectData.hasKey(Constants.NOTIFICATION.PAYLOAD)) objectData.getString(Constants.NOTIFICATION.PAYLOAD) else ""
60+
val title = if (objectData.hasKey(Constants.NOTIFICATION.TITLE)) objectData.getString(Constants.NOTIFICATION.TITLE) else "Default Title"
61+
val body = if (objectData.hasKey(Constants.NOTIFICATION.BODY)) objectData.getString(Constants.NOTIFICATION.BODY) else "Default Body"
62+
val subtitle = if (objectData.hasKey("subtitle")) objectData.getString("subtitle") else null
63+
val id = if (objectData.hasKey(Constants.NOTIFICATION.ID)) objectData.getInt(Constants.NOTIFICATION.ID) else 0
64+
val gifUrl = if (objectData.hasKey(Constants.NOTIFICATION.GIFFY_URl)) objectData.getString(Constants.NOTIFICATION.GIFFY_URl) else null
65+
66+
val datetime = if (objectData.hasKey("date")) objectData.getString("date") else null
67+
val sdf = SimpleDateFormat("dd-MM-yyyy HH:mm:ss", Locale.ENGLISH)
68+
69+
val endTime: Calendar = Calendar.getInstance()
70+
try {
71+
if (!datetime.isNullOrEmpty()) {
72+
endTime.time = sdf.parse(datetime) ?: Date()
73+
}
74+
} catch (e: Exception) {
75+
Log.e("TimerNotification", "Date parsing failed: ${e.message}")
76+
endTime.time = Date()
77+
}
78+
79+
val startTime = SystemClock.elapsedRealtime()
80+
val now = System.currentTimeMillis()
81+
val elapsed: Long = now - endTime.timeInMillis
82+
val remainingTime = maxOf(startTime - elapsed, 0L)
83+
84+
val notificationHelper = AnimatedNotificationManager(myContext)
85+
notificationHelper.showAnimatedNotification(
86+
NotificationConfig(
87+
gifUrl = gifUrl,
88+
title = title,
89+
subtitle = subtitle,
90+
body = body,
91+
payload = payload,
92+
notificationId = id,
93+
countdownDuration = remainingTime
94+
)
95+
)
7996
}
97+
8098

8199

82100
@ReactMethod

0 commit comments

Comments
 (0)