🌟 Bulletin lets you display a changelog in your app quickly and easily with Jetpack Compose! 🌟
In your project-level build.gradle file:
allprojects {
repositories {
mavenCentral()
}
}In your app or module build.gradle file:
dependencies {
implementation("com.tobianoapps:bulletin:1.0.3")
}Bulletin lets you provide a changelog:
val sampleBulletin = bulletin {
releases = listOf(
Release(
time = 1652229320349,
label = "1.0.0-RC2",
changes = listOf(
change {
changeType = NEW
summary = "Bulletin is easy!"
},
change {
changeType = DEFAULT
summary = "Kotlin DSL FTW!"
}
)
),
Release(...)
...
)
}
Then:
BulletinScreen(bulletin = sampleBulletin)Save a .json file in your Android project's assets folder then:
BulletinScreen(
filename = "bulletin.json",
onError = { /* handle error */ }
)Note: implementing the error callback is optional but strongly recommended.
Click to see JSON format
[
{
"time":1652229320349,
"label":"1.0.0-RC2",
"changes":[
{
"changeType":"NEW",
"summary":"Bulletin is easy!"
},
{
"changeType":"DEFAULT",
"summary":"Kotlin DSL FTW!"
}
]
},
{
"more..."
}
]Expose a public endpoint that serves json data then:
BulletinScreen(
url = "https://mywebsite.com/api/changelog/",
onError = { /* handle error */ }
)Note: implementing the error callback is optional but strongly recommended.
Click to see JSON format
[
{
"time":1652229320349,
"label":"1.0.0-RC2",
"changes":[
{
"changeType":"NEW",
"summary":"Bulletin is easy!"
},
{
"changeType":"DEFAULT",
"summary":"Kotlin DSL FTW!"
}
]
},
{
"more..."
}
]To display a custom loading indicator, just pass your own Composable:
BulletinScreen(
url = "https://mywebsite.com/api/changelog/",
urlLoadingView = { CustomLoadingView() },
onError = { /* handle error */ }
)The default HTTP timeout duration of 5 seconds can be customized as follows:
BulletinScreen(
url = "https://mywebsite.com/api/changelog/",
timeout = 10000L,
onError = { /* handle error */ }
)Check out the sample project for detailed examples.
Bulletin provides callbacks that you can optionally implement.
BulletinScreen(
...
onReleaseHeaderClick = { release ->
Log.i("TAG", "Release ${release.label} header clicked")
},
onChangeClick = { change ->
Log.i("TAG", "Clicked on \"${change.summary}\"")
},
onError = { error ->
Log.e("TAG", "An error occurred: $error")
}
)Although displaying a Bulletin as a dialog is left for the user to implement, the sample project includes a demonstration, so make sure to check it out!
While Bulletin is meant to be a quick and easy way to display a changelog in your app (with light and dark modes supported out-of-the box), the library also provides some extensive customization options.
To customize a Bulletin's attributes, simply implement a custom BulletinConfig. You can choose to implement as few or as many custom attributes as desired.
val customBulletinConfig = bulletinConfig {
bulletinColors = customBulletinColors
style = customBulletinStyle
groupByChangeType = true
showHeaderDivider = false
showReleaseDate = true
zoneId = ZoneId.of("Europe/Paris")
locale = Locale.FRANCE
}
val customBulletinStyle = bulletinStyle {
cardStyle = customCardStyle
tagStyle = customTagStyle
}
fun cardDateStyle(): TextStyle = TextStyle(
color = Color.Blue,
fontWeight = FontWeight.Thin,
fontStyle = FontStyle.Italic
)
fun cardTitleStyle(): TextStyle = TextStyle(
color = Color.Green,
fontSize = 23.sp,
fontWeight = FontWeight.Bold
)
val customCardStyle = bulletinCardStyle {
shape = CutCornerShape(8.dp)
elevation = 10.dp
paddingHorizontal = 34.dp
verticalSpacing = 32.dp
cardDateStyle = {
if (isSystemInDarkTheme())
cardDateStyle().copy(color = Color.White)
else
cardDateStyle()
}
cardTitleStyle = {
if (isSystemInDarkTheme())
cardTitleStyle().copy(color = Color.LightGray)
else
cardTitleStyle()
}
borderStroke = BorderStroke(width = 3.dp, color = Color.DarkGray)
}
val customTagStyle = bulletinTagStyle {
// custom values
}
// more custom valuesThen:
Bulletin(
...
bulletin = sampleBulletin,
bulletinConfig = customBulletinConfig
...
)A complete implementation of a BulletinConfig is included in the sample project.
To override the strings used on the change type labels, simply provide your custom implementation in your project's strings.xml file:
<resources>
<string name="bulletin_change_type_default">misc</string>
<string name="bulletin_change_type_improved">enhanced</string>
<string name="bulletin_change_type_fixed">bug</string>
<string name="bulletin_change_type_maintenance">these can be anything</string>
<string name="bulletin_change_type_new">🚀</string>
<string name="bulletin_change_type_removed">gone</string>
<string name="bulletin_change_type_deprecated">obsolete</string>
<string name="bulletin_change_type_security">notice</string>
</resources>Contributions, suggestions, bug reports are welcomed. Keep in mind that this is developed in my spare time, which means limited time can be dedicated to the project. I'll do my best to fix bugs but new features may not be added.









