Skip to content

Commit

Permalink
Updated advanced topic examples + deprecated NotifyCreator#cancel() (K…
Browse files Browse the repository at this point in the history
…arn#24)

- The Advanced Topics document has been updated with examples of click and clear handling, as well as examples of notification actions and stackable notifications.
- Additionally, the 'NotifyCreator#cancel()' function has been deprecated in favor of the static implementation 'Notify#cancelNotification()'. This is because the NotifyCreator class should act primarily as the notification construction interface and should not expose functions which manage notification states or attributes post-construction.
  • Loading branch information
Karn authored Jan 2, 2019
1 parent b26b154 commit 6d5c04c
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 27 deletions.
13 changes: 0 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,6 @@ If you run into a case in which the library does not provide the requisite build
> **Tip:** Advanced usage topics are documented [here](./docs/advanced.md).
#### NOTIFICATION ANATOMY

![Anatomy](./docs/assets/anatomy.svg)

| ID | Name | Description |
| --- | --- | --- |
| 1 | Icon | Set using the `Header#icon` field. |
| 2 | App Name | Application name, immutable. |
| 3 | Header Text | Optional description text. Set using the `Header#headerText` field. |
| 4 | Timestamp | Timestamp of the notification. |
| 5 | Expand Icon | Indicates that the notification is expandable. |
| 6 | Content | The "meat" of the notification set using of of the `NotifyCreator#as[Type]((Type) -> Unit)` scoped functions. |
| 7 | Actions | Set using the `NotifyCreator#actions((ArrayList<Action>) -> Unit)` scoped function. |

#### CONTRIBUTING
There are many ways to [contribute](./.github/CONTRIBUTING.md), you can
Expand Down
98 changes: 96 additions & 2 deletions docs/advanced.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,104 @@
## Advanced Usage
> **Note:** This page is still a work-in-progress. You can help complete the documentation by contributing to the project.
#### NOTIFICATION ANATOMY

![Anatomy](./docs/assets/anatomy.svg)

| ID | Name | Description |
| --- | --- | --- |
| 1 | Icon | Set using the `Header#icon` field. |
| 2 | App Name | Application name, immutable. |
| 3 | Header Text | Optional description text. Set using the `Header#headerText` field. |
| 4 | Timestamp | Timestamp of the notification. |
| 5 | Expand Icon | Indicates that the notification is expandable. |
| 6 | Content | The "meat" of the notification set using of of the `NotifyCreator#as[Type]((Type) -> Unit)` scoped functions. |
| 7 | Actions | Set using the `NotifyCreator#actions((ArrayList<Action>) -> Unit)` scoped function. |

#### RESPONDING TO CLICKS
The `Payload.Meta` object provides `clickIntent` and `clearIntent` members which when not `null` will be fired when clicked or dismissed.

The `Payload.Meta` object provides `clickIntent` and `clearIntent` members which when not `null`, will be fired when clicked or dismissed.

```Kotlin
Notify
.with(context)
.meta { // this: Payload.Meta
// Launch the MainActivity once the notification is clicked.
clickIntent = PendingIntent.getActivity(this@MainActivity,
0,
Intent(this@MainActivity, MainActivity::class.java),
0)
// Start a service which clears the badge count once the notification is dismissed.
clearIntent = PendingIntent.getService(this@MainActivity,
0,
Intent(this@MainActivity, MyNotificationService::class.java)
.putExtra("action", "clear_badges"),
0)
}
.content { // this: Payload.Content.Default
title = "New dessert menu"
text = "The Cheesecake Factory has a new dessert for you to try!"
}
.show()
```


#### ACTIONS

Similarly, we can construct actions which can be used to quickly perform tasks without opening your app. The actions are the collection of buttons that are shown below the notification to quickly perform tasks.

```Kotlin
Notify
.with(context)
.content { // this: Payload.Content.Default
title = "New dessert menu"
text = "The Cheesecake Factory has a new dessert for you to try!"
}
.actions { // this: ArrayList<Action>
add(Action(
// The icon corresponding to the action.
R.drawable.ic_app_icon,
// The text corresponding to the action -- this is what shows .
"Clear",
// Swap this PendingIntent for whatever Intent is to be processed when the action is clicked.
PendingIntent.getService(this@MainActivity,
0,
Intent(this@MainActivity, MyNotificationService::class.java)
.putExtra("action", "clear_badges"),
0)
))
}
.show()
```


#### STACKABLE NOTIFICATIONS

#### ACTIONS
Notify provides a solution to the idea of grouping notifications into a "stack". I.e the notifications are grouped into a single notification when there is more than one of the same type as defined by `stackable.key`.
This is a particularly effective method of reducing the clutter of the notification tray while also providing the relevant information.

```Kotlin
Notify
.with(this)
.content { // this: Payload.Content.Default
title = "New dessert menu"
text = "The Cheesecake Factory has a new dessert for you to try!"
}
// Define the notification as being stackable. This block should be the same for all notifications which
// are to be grouped together.
.stackable { // this: Payload.Stackable
// In particular, this key should be the same. The properties of this stackable notification as
// taken from the latest stackable notification's stackable block.
key = "test_key"
// This is the summary of this notification as it appears when it is as part of a stacked notification. This
// String value is what is shown as a single line in the stacked notification.
summaryContent = "test summary content"
// The number of notifications with the same key is passed as the 'count' argument. We happen not to
// use it, but it is there if needed.
summaryTitle = { count -> "Summary title" }
// ... here as well, but we instead choose to use to to update the summary for when the notification
// is collapsed.
summaryDescription = { count -> count.toString() + " new notifications." }
}
.show()
```
14 changes: 7 additions & 7 deletions library/src/main/java/io/karn/notify/Notify.kt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ class Notify internal constructor(internal var context: Context) {
fun with(context: Context): NotifyCreator {
return NotifyCreator(Notify(context), defaultConfig)
}

/**
* Cancel an existing notification with a particular id.
*/
fun cancelNotification(id: Int) {
return NotificationInterop.cancelNotification(Notify.defaultConfig.notificationManager!!, id)
}
}

init {
Expand Down Expand Up @@ -111,11 +118,4 @@ class Notify internal constructor(internal var context: Context) {
internal fun show(builder: NotificationCompat.Builder): Int {
return NotificationInterop.showNotification(Notify.defaultConfig.notificationManager!!, builder)
}

/**
* Cancel an existing notification with a particular id.
*/
internal fun cancel(id: Int) {
return NotificationInterop.cancelNotification(Notify.defaultConfig.notificationManager!!, id)
}
}
10 changes: 9 additions & 1 deletion library/src/main/java/io/karn/notify/NotifyCreator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,15 @@ class NotifyCreator internal constructor(private val notify: Notify, config: Not
return notify.show(asBuilder())
}

/**
* Cancel an existing notification given an ID.
*
* @deprecated Choose to instead use the static function {@see Notify#cancelNotification()} which provides the correct
* encapsulation of the this `cancel` function.
*/
@Deprecated(message = "Exposes function under the incorrect API -- NotifyCreator is reserved strictly for notification construction.",
replaceWith = ReplaceWith("Notify.cancelNotification(id)", "io.karn.notify.Notify"))
fun cancel(id: Int) {
return notify.cancel(id)
return Notify.cancelNotification(id)
}
}
3 changes: 1 addition & 2 deletions library/src/test/java/io/karn/notify/NotifyTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ class NotifyTest : NotifyTestBase() {

Assert.assertEquals(1, NotificationInterop.getActiveNotifications(shadowNotificationManager).size)

Notify.with(this.context)
.cancel(notificationId)
Notify.cancelNotification(notificationId)

Assert.assertEquals(0, NotificationInterop.getActiveNotifications(shadowNotificationManager).size)
}
Expand Down
4 changes: 2 additions & 2 deletions sample/src/main/java/presentation/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package presentation
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Bundle
import androidx.core.app.NotificationCompat
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import io.karn.notify.Notify
import io.karn.notify.sample.R
import java.util.*
Expand Down

0 comments on commit 6d5c04c

Please sign in to comment.