diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9a9379f..1e3e2b5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -26,7 +26,7 @@ If applicable, add screenshots to help explain your problem. **Device (please complete the following information):** - Device: [e.g. Pixel 6] - OS: [e.g. Android 13] - - TriggerX Library Version [e.g. 1.0.0] + - TriggerX Library Version [e.g. 1.1.0] - TriggerX Example App Version (if applicable) [e.g. 1.1] **Additional context** diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 86c6ca5..3d67f3e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: - main env: - VERSION_NAME: 1.0.0 # Update this value for each release + VERSION_NAME: 1.1.0 # Update this value for each release jobs: release: diff --git a/README.md b/README.md index adf8536..8240996 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,10 @@

- -> **Note:** TriggerX is currently in Alpha. APIs may change. - TriggerX is a modular, developer-friendly **alarm execution** library for Android. +[See the full documentation](https://meticha.com/triggerx/docs) + It simplifies scheduling exact alarms and showing user-facing UIs at a specific time, even when your app has been killed or without you managing foreground-service boilerplate, wake-locks, or lock-screen flags. @@ -66,7 +65,7 @@ the system details. ```toml [versions] -triggerx = "0.0.4" +triggerx = "latest-version" [dependencies] triggerx = { module = "com.meticha:triggerx", version.ref = "triggerx" } @@ -79,7 +78,7 @@ triggerx = { module = "com.meticha:triggerx", version.ref = "triggerx" } ```kotlin dependencies { - implementation("com.meticha:triggerx:0.0.4") + implementation("com.meticha:triggerx:latest-version") } ``` @@ -95,6 +94,8 @@ dependencies { + + ``` ### 1. Initialize in your Application class @@ -150,7 +151,7 @@ fun HomeScreen( ) { val context = LocalContext.current val permissionState = rememberAppPermissionState() - + val coroutines = rememberCoroutineScope() Scaffold { paddingValues -> Column( @@ -163,10 +164,12 @@ fun HomeScreen( ) { ElevatedButton( onClick = { - if (permissionState.allRequiredGranted()) { - viewModel.scheduleOneMinuteAlarm(context) - } else { - permissionState.requestPermission() + coroutines.launch { + if (permissionState.allRequiredGranted()) { + viewModel.scheduleOneMinuteAlarm(context) + } else { + permissionState.requestPermission() + } } } ) { @@ -268,6 +271,7 @@ fun HomeScreen( ) { val context = LocalContext.current val permissionState = rememberAppPermissionState() + val coroutines = rememberCoroutineScope() Scaffold { paddingValues -> @@ -281,12 +285,14 @@ fun HomeScreen( ) { ElevatedButton( onClick = { - if (permissionState.allRequiredGranted()) { - viewModel.scheduleOneMinuteAlarm( - context - ) - } else { - permissionState.requestPermission() + coroutines.launch { + if (permissionState.allRequiredGranted()) { + viewModel.scheduleOneMinuteAlarm( + context + ) + } else { + permissionState.requestPermission() + } } } ) { @@ -301,7 +307,7 @@ Covered automatically: | Permission | Version | |--------------------------------|---------| -| ⏰ Exact alarm | API 31+ | +| ⏰ Exact alarm | API 31+ | | 🔋 Ignore battery optimisation | all | | 🖼 Overlay (only if needed) | all | | 📢 Post-notification | API 33+ | diff --git a/app/src/main/java/com/meticha/triggerxexample/TriggerXApplication.kt b/app/src/main/java/com/meticha/triggerxexample/TriggerXApplication.kt index c0d0f4d..deb5a5e 100644 --- a/app/src/main/java/com/meticha/triggerxexample/TriggerXApplication.kt +++ b/app/src/main/java/com/meticha/triggerxexample/TriggerXApplication.kt @@ -33,7 +33,6 @@ class TriggerXApplication : Application() { message = "Your alarm is ringing!", channelName = "My Awesome App Notifications" ) - showAlarmActivityWhenAppIsActive = false activityClass = AppAlarmActivity::class.java alarmDataProvider = object : TriggerXDataProvider { override suspend fun provideData(alarmId: Int, alarmType: String): Bundle { diff --git a/docs/docs/tutorial-basics/1-installation.md b/docs/docs/tutorial-basics/1-installation.md index 833b5e5..7e3d951 100644 --- a/docs/docs/tutorial-basics/1-installation.md +++ b/docs/docs/tutorial-basics/1-installation.md @@ -13,7 +13,7 @@ Add this to your `build.gradle.kts`: ```kotlin dependencies { - implementation("com.meticha:triggerx:0.0.5") + implementation("com.meticha:triggerx:1.1.0") } ``` @@ -23,7 +23,7 @@ If you're using Version Catalogs: ```toml [versions] -triggerx = "0.0.5" +triggerx = "1.1.0" [libraries] triggerx = { module = "com.meticha:triggerx", version.ref = "triggerx" } @@ -44,4 +44,6 @@ dependencies { + + ``` \ No newline at end of file diff --git a/docs/docs/tutorial-basics/4-permission-handling.mdx b/docs/docs/tutorial-basics/4-permission-handling.mdx index f59fb02..eae4fe7 100644 --- a/docs/docs/tutorial-basics/4-permission-handling.mdx +++ b/docs/docs/tutorial-basics/4-permission-handling.mdx @@ -15,6 +15,7 @@ Here’s how to request permissions and schedule an alarm: fun HomeScreen() { val context = LocalContext.current val permissionState = rememberAppPermissionState() + val coroutineScope = rememberCoroutineScope() Scaffold { paddingValues -> Column( @@ -27,10 +28,12 @@ fun HomeScreen() { ) { ElevatedButton( onClick = { - if (permissionState.allRequiredGranted()) { - // do stuff - } else { - permissionState.requestPermission() + coroutineScope.launch{ + if (permissionState.allRequiredGranted()) { + // do stuff + } else { + permissionState.requestPermission() + } } } ) { diff --git a/docs/docs/tutorial-basics/5-scheduling-alarm.md b/docs/docs/tutorial-basics/5-scheduling-alarm.md index 1ac51f9..f6c6265 100644 --- a/docs/docs/tutorial-basics/5-scheduling-alarm.md +++ b/docs/docs/tutorial-basics/5-scheduling-alarm.md @@ -15,6 +15,7 @@ Here’s how to do it: fun HomeScreen() { val context = LocalContext.current val permissionState = rememberAppPermissionState() + val coroutineScope = rememberCoroutineScope() Scaffold { paddingValues -> Column( @@ -27,33 +28,35 @@ fun HomeScreen() { ) { ElevatedButton( onClick = { - if (permissionState.allRequiredGranted()) { - val triggerTime = Calendar.getInstance().apply { - add(Calendar.MINUTE, 1) // Triggers after 1 minute - }.timeInMillis - - val scheduled = TriggerXAlarmScheduler().scheduleAlarm( - context = context, - triggerAtMillis = triggerTime, - type = "MEETING", - alarmId = 1 - ) - - if (scheduled) { - Toast.makeText( - context, - "Alarm scheduled successfully. App can now be closed 🔔", - Toast.LENGTH_SHORT - ).show() + coroutineScope.launch{ + if (permissionState.allRequiredGranted()) { + val triggerTime = Calendar.getInstance().apply { + add(Calendar.MINUTE, 1) // Triggers after 1 minute + }.timeInMillis + + val scheduled = TriggerXAlarmScheduler().scheduleAlarm( + context = context, + triggerAtMillis = triggerTime, + type = "MEETING", + alarmId = 1 + ) + + if (scheduled) { + Toast.makeText( + context, + "Alarm scheduled successfully. App can now be closed 🔔", + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + context, + "Failed to schedule alarm. Please try again.", + Toast.LENGTH_SHORT + ).show() + } } else { - Toast.makeText( - context, - "Failed to schedule alarm. Please try again.", - Toast.LENGTH_SHORT - ).show() + permissionState.requestPermission() } - } else { - permissionState.requestPermission() } } ) { diff --git a/docs/docs/tutorial-extras/img/docsVersionDropdown.png b/docs/docs/tutorial-extras/img/docsVersionDropdown.png deleted file mode 100644 index 97e4164..0000000 Binary files a/docs/docs/tutorial-extras/img/docsVersionDropdown.png and /dev/null differ diff --git a/docs/docs/tutorial-extras/img/localeDropdown.png b/docs/docs/tutorial-extras/img/localeDropdown.png deleted file mode 100644 index e257edc..0000000 Binary files a/docs/docs/tutorial-extras/img/localeDropdown.png and /dev/null differ diff --git a/docs/docs/tutorial-extras/showing-alarm-ui-conditionally.md b/docs/docs/tutorial-extras/showing-alarm-ui-conditionally.md new file mode 100644 index 0000000..1c93ed5 --- /dev/null +++ b/docs/docs/tutorial-extras/showing-alarm-ui-conditionally.md @@ -0,0 +1,47 @@ +--- +title: Showing Alarm UI conditionally +description: Configure TriggerX to show dynamic UI based on your Room database +sidebar_position: 2 +--- + +# 💊 Showing Alarm UI conditionally + +TriggerX gives you full control over **whether** to show the alarm screen based on your App’s logic, such +as values stored in a Room database, preferences, or feature flags. + +You can configure these conditions using the `TriggerX.init()` function inside your `Application` class. + +## 📱 1. Skip Alarm UI When App Is Active + +If you don’t want the alarm UI to appear while the App is already in the foreground (e.g. user is using the app), set +the following: + +```kotlin +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + + TriggerX.init(this) { + showAlarmActivityWhenAppIsActive = false + } + } +} +``` + +This is useful when you want to handle the alarm inside the app manually without launching a separate screen. + +## 💡 2. Skip Alarm UI When Device Is Active + +If you want to avoid interrupting the user when they’re actively using the device (e.g. screen is on), set this: + +```kotlin +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + + TriggerX.init(this) { + shouldShowAlarmActivityWhenDeviceIsActive = false + } + } +} +``` \ No newline at end of file diff --git a/docs/docs/tutorial-extras/showing-dynamic-ui.md b/docs/docs/tutorial-extras/showing-dynamic-ui.md index 1563a15..ab7677c 100644 --- a/docs/docs/tutorial-extras/showing-dynamic-ui.md +++ b/docs/docs/tutorial-extras/showing-dynamic-ui.md @@ -100,24 +100,24 @@ fun HomeScreen() { ElevatedButton( onClick = { - if (permissionState.allRequiredGranted()) { - val db = AppDatabase.getInstance(context) - scope.launch { - db.taskDao().insert(Task(1, "Meeting", "Discuss the roadmap")) - - val triggerTime = Calendar.getInstance().apply { - add(Calendar.MINUTE, 1) - }.timeInMillis - - alarmScheduler.scheduleAlarm( - context = context, - triggerAtMillis = triggerTime, - type = "TASK", - alarmId = 1 - ) - } - } else { - permissionState.requestPermission() + scope.launch { + if (permissionState.allRequiredGranted()) { + val db = AppDatabase.getInstance(context) + db.taskDao().insert(Task(1, "Meeting", "Discuss the roadmap")) + + val triggerTime = Calendar.getInstance().apply { + add(Calendar.MINUTE, 1) + }.timeInMillis + + alarmScheduler.scheduleAlarm( + context = context, + triggerAtMillis = triggerTime, + type = "TASK", + alarmId = 1 + ) + } else { + permissionState.requestPermission() + } } }) { Text("Schedule Dynamic Alarm") diff --git a/docs/src/components/HomepageFeatures/index.tsx b/docs/src/components/HomepageFeatures/index.tsx index eee885a..92a1748 100644 --- a/docs/src/components/HomepageFeatures/index.tsx +++ b/docs/src/components/HomepageFeatures/index.tsx @@ -29,7 +29,7 @@ const FeatureList: FeatureItem[] = [ ), }, { - title: 'Handles Permissions So You Don’t Have To', + title: 'Handles Permissions So That You Don’t Have To', icon: '🔐', description: ( <> diff --git a/settings.gradle.kts b/settings.gradle.kts index 674f6a0..84cbbb2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,5 @@ +@file:Suppress("UnstableApiUsage") + pluginManagement { repositories { google { diff --git a/triggerx/build.gradle.kts b/triggerx/build.gradle.kts index a2c39e0..5913685 100644 --- a/triggerx/build.gradle.kts +++ b/triggerx/build.gradle.kts @@ -100,14 +100,14 @@ mavenPublishing { signAllPublications() - coordinates("com.meticha", "triggerx", "1.0.0") + coordinates("com.meticha", "triggerx", "1.1.0") pom { name = "triggerx" description = "A lightweight Android library for scheduling exact alarms with custom UIs. No foreground services or wake-lock hassle." inceptionYear = "2025" - version = "1.0.0" + version = "1.1.0" url = "https://github.com/meticha/triggerx.git" licenses { license {