Skip to content

MalekKamel/Bulletin

Repository files navigation

Bulletin

An abstraction for alert messages in android.

More and more you need to report bulletins (messages) to the user and you spread its code everywhere. And sometimes you ask yoursef, what if I want to avoid duplicate bulletins at the same time? what if I want to queue bulletins? what if I want to apply default configurations to each bulletin only in one place? what if I want to manage all bulletins?..... πŸ‘Ώ πŸ‘Ώ

Bulletin can answer all you queustions! πŸ™ πŸ™

   // ignore any Bulletin if another Bulletin is diplayed with the
   // same content
   BulletinConfig.duplicateStrategy = ContentDuplicateStrategy()
   
   // queue any BulletinSheet if another BulletinSheet is diplayed 
   // and show the next queued one after dismissing the current.
   // the same applies to BulletinToast.
   BulletinConfig.queueStrategies {
       + SheetQueueStrategy()
       + ToastQueueStrategy()
   }
   
   // Will be displayed
   showMessageSheet("Sheet1, after dismissing, Sheet2 will be displayed!")
   
   // will be queued as we deined SheetQueueStrategy
   showMessageSheet("Sheet2, after dismissing, Sheet3 will be displayed!")
   
   // will be queued like Sheet2
   showMessageSheet("Sheet3")
   
   // Will be displayed
   shortToast("Toast")
   
   // will be ignored as its content is similar to the previous displayed bulletin
   // NOTE: remember that we defined ContentDuplicateStrategy
   shortToast("Toast")
   
   // Will dismiss any displayed Bulletin
   BulletinManager.dismissAll()

Features

  • Reusable widgets.
  • Predefined APIs for displaying bulletins.
  • Fully customizable.
  • Define queue strategies.
  • Define duplicate strategies
  • Global configuration for all bulletins
  • Manage all bulletins

Installation

Gradle:

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

dependencies {
        implementation 'com.github.ShabanKamell:Bulletin:x.y.z'
}

(Please replace x, y and z with the latest version numbers: )

Bulletins

Any widget implements Bulletin Interface is a Bulletin. There're 8 predefined widgets in the library:

Name Description
InfoDialog A concrete implementaion of BulletinDialog
RetryDialog A concrete implementaion of BulletinDialog
LoadingDialog A concrete implementaion of BulletinDialog
InfoSheet A concrete implementaion of BulletinSheet
RetrySheet A concrete implementaion of BulletinSheet
StandardFlashBar A concrete implementaion of BulletinFlashBar
StandardToast A concrete implementaion of BulletinToast
StandardSnackbar A concrete implementaion of BulletinSnackbar

Bulletin Interface

Bulletin is implemented by all widgets of the library. If you want to create your custom bulletin, you must implement this interface.

interface Bulletin {
    val name: String
    val content: String
    var status: BulletinStatus
    var duplicateStrategy: DuplicateStrategy
    fun showBulletin(activity: FragmentActivity?)
    fun dismiss()
}

BulletinManager

It's the brain of the library that's responsible for showing/hiding bulletins and managing the state of each bulletin. Take a look at BulletinManager to see all functionalities.

Alertable Interface

Alertable interface contains a group of default functions that make it easy to show any predefined Bulletin. If you want to make all these functions available for your class, just implement it. The interface is a composite of interfaces for each bulletin. Take a look at Alertable to see all functionalities.

interface Alertable:
        InfoDialogAlertable,
        InfoSheetAlertable,
        RetryDialogAlertable,
        RetrySheetAlertable,
        ToastAlertable,
        LoadingDialogAlertable,
        FlashBarAlertable

In case you don't need all functions, you can implement any interface that Alertable inhertits.

IMPORTANT: To use Alertable with Kotlin, you must add this to apps' Gradle:
android {
...
    // This configuration enables using @JvmDefault annotation with Kotlin
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8
        freeCompilerArgs = ['-Xjvm-default=compatibility']
    }
}

Duplicate Strategy

What if there are 2 or more netwrok responses display the same content in a dialog and you don't need to show all dialogs with the same content? OR in another words you want to ignore the dialog if there's a dialog with the same content displayed?

DuplicateStrategy provides the solution:

  BulletinConfig.duplicateStrategy = ContentDuplicateStrategy()

The previous line tells Bulletin to ignore the new bulletin as long as a bulletin with the same content is displayed.

Duplicate Strategy Interface:

interface DuplicateStrategy {
    var onIgnoreStrategy: IgnoreDuplicateStrategy
    fun shouldIgnore(bulletin: Bulletin, displayedBulletins: Set<Bulletin>): Boolean
}

BUT what happens to the ignored bulletins? see Ignore Duplicate Strategy πŸ€” πŸ€”

There are multiple predefined implementaions for DuplicateStrategy you can find them in the next section. However, you can define your own custom strategy.

Predefined Duplicate Strategies

Name Description Default IgnoreDuplicateStrategy
DefaultDuplicateStrategy Allows any diplication DROP
NameDuplicateStrategy Ignore if a Bulletin with the same NAME is displayed. QUEUE
ContentDuplicateStrategy Ignore if a Bulletin with the same CONTENT is displayed. DROP
NameContentDuplicateStrategy Ignore if a Bulletin with the same NAME & CONTENT is displayed. DROP
SingleDuplicateStrategy Display a single Bulletin at a time . QUEUE

Ignore Duplicate Strategy

If a Bulletin has been ignored bucause it's a duplicate one, you can define 1 of 3 behaviors for the ignored bulletin:

  • Drop: The bulletin will be dropped and won't be displayed forever.
  • Queue: The bulletin will be queued, and will be displayed once it's the first bulletin in the queue.
  • Try Queue: The bulletin will be queued only if there's any Duplicate Strategy allows queuing the bulletin.

These behavioiors are defined inIgnoreDuplicateStrategy.

IgnoreDuplicateStrategy Enum

IgnoreDuplicateStrategy contains the ignoring behaviors that can be defined in in DuplicateStrategy Inteface.

enum class IgnoreDuplicateStrategy { DROP, QUEUE, TRY_QUEUE }

Queue Strategy

What if you need to show 2 bulletins or more in a sequntial order? In another worders, what if you want to show each bulletin after dismissing the previous one?

QueueStrategy interface provides a solution for queuing problem:

BulletinConfig.queueStrategies { +SheetQueueStrategy() }

Queue Strategy Interface:

interface QueueStrategy {
    fun shouldQueue(bulletin: Bulletin, displayedBulletins: Set<Bulletin>): Boolean
}

There are multiple predefined implementaions for QueueStrategy you can find them in the next section. However, you can define your own custom strategy.

Predefined Queue Strategies

Name Description
NoneQueueStrategy Don't queue any bulletin. This is the default behavior
AllQueueStrategy Queue all bulletins
DialogQueueStrategy Queue if a BulletinDialog is displayed.
SheetQueueStrategy Queue if a BulletinSheet is displayed.
FlashbarQueueStrategy Queue if a BulletinFlashbar is displayed.
SnackbarQueueStrategy Queue if a BulletinSnackar is displayed.
ToastQueueStrategy Queue if a BulletinToast is displayed.

Bulletin Status

Each Bulletin has a status of 5 statuses defined in BulletinStatus

enum class BulletinStatus {
    PENDING,
    DISPLAYED,
    QUEUED,
    IGNORED,
    DISMISSED
}
  • PENDING: The bulletin is created. It's the default status.
  • DISPLAYED: The bulleitn is visible on the screen.
  • QUEUED: The bulletin is queued because 1) it's queued by a QueueStratedy 2) it's ignored by a DuplicateStratedy then queued, see Ignore Duplicate Strategy.
  • IGNORED: The bulletin is ignored by a QueueStratedy
  • DISMISSED: The bulletin is no longer visible.

Custom Bulletins

As mentioned in Bulletin Interface, you can create your custom bulletin by implementing [Bulletin] interface. Alternatively, you can extend abstract widget like BulletinDialog and implement your customization. see MyCstomLadingDialog

Credit

πŸ›‘ License

click to reveal License
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.