Skip to content

Commit

Permalink
Added the dynamic app shortcuts based on the app shorting order
Browse files Browse the repository at this point in the history
Signed-off-by: Keval Patel <[email protected]>
  • Loading branch information
kevalpatel2106 committed Mar 12, 2019
1 parent 001c854 commit da4bf70
Show file tree
Hide file tree
Showing 19 changed files with 122 additions and 47 deletions.
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".utils.LocaleChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
<receiver android:name=".notifications.ProgressNotificationReceiver" />
</application>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.kevalpatel2106.yip.recyclerview.representable.YipItemRepresentable
import com.kevalpatel2106.yip.repo.YipRepo
import com.kevalpatel2106.yip.repo.billing.BillingRepo
import com.kevalpatel2106.yip.repo.providers.SharedPrefsProvider
import com.kevalpatel2106.yip.utils.AppShortcutHelper
import io.reactivex.BackpressureStrategy
import io.reactivex.Flowable
import io.reactivex.functions.BiFunction
Expand All @@ -31,7 +32,8 @@ internal class DashboardViewModel @Inject constructor(
private val application: Application,
private val yipRepo: YipRepo,
private val sharedPrefsProvider: SharedPrefsProvider,
private val billingRepo: BillingRepo
private val billingRepo: BillingRepo,
private val appShortcutHelper: AppShortcutHelper
) : BaseViewModel() {
internal val progresses = MutableLiveData<ArrayList<YipItemRepresentable>>()
internal val askForRating = MutableLiveData<Unit>()
Expand All @@ -56,6 +58,8 @@ internal class DashboardViewModel @Inject constructor(
progresses.value?.clear()
progresses.value?.add(LoadingRepresentable)
progresses.recall()
}.doOnNext { (progresses, _) ->
appShortcutHelper.updateDynamicShortcuts(progresses)
}.map { (progresses, isPro) ->

// Add Ads if the user is not pro.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal class DetailFragment : Fragment() {
menuItem.itemId == R.id.menu_delete_progress -> {
model.viewState.value?.progressTitleText?.let { title -> conformDelete(title) }
}
menuItem.itemId == R.id.menu_pin_shortcut -> model.pinShortcut()
menuItem.itemId == R.id.menu_pin_shortcut -> model.requestPinShortcut()
}
true
}
Expand Down
32 changes: 8 additions & 24 deletions app/src/main/java/com/kevalpatel2106/yip/detail/DetailViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package com.kevalpatel2106.yip.detail

import android.app.Application
import android.text.SpannableString
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.MutableLiveData
import com.kevalpatel2106.yip.R
import com.kevalpatel2106.yip.core.BaseViewModel
Expand All @@ -14,13 +11,15 @@ import com.kevalpatel2106.yip.core.addTo
import com.kevalpatel2106.yip.core.darkenColor
import com.kevalpatel2106.yip.repo.YipRepo
import com.kevalpatel2106.yip.repo.utils.DateFormatter
import com.kevalpatel2106.yip.splash.AppLaunchHelper
import com.kevalpatel2106.yip.utils.AppLaunchHelper
import com.kevalpatel2106.yip.utils.AppShortcutHelper
import timber.log.Timber
import javax.inject.Inject

internal class DetailViewModel @Inject internal constructor(
private val application: Application,
private val yipRepo: YipRepo,
private val appShortcutHelper: AppShortcutHelper,
private val sdf: DateFormatter
) : BaseViewModel() {

Expand Down Expand Up @@ -91,25 +90,10 @@ internal class DetailViewModel @Inject internal constructor(
.addTo(compositeDisposable)
}

internal fun pinShortcut() {
if (!ShortcutManagerCompat.isRequestPinShortcutSupported(application)) return

val shortcutInfo = ShortcutInfoCompat.Builder(
application,
application.getString(R.string.progress_pin_shortcut_id)
).setIcon(
IconCompat.createWithResource(application, R.drawable.progress_app_shortcut)
).setShortLabel(
viewState.value?.progressTitleText ?: application.getString(R.string.application_name)
).setIntent(
AppLaunchHelper.launchWithProgressDetail(application, progressId)
).setAlwaysBadged()
.build()

ShortcutManagerCompat.requestPinShortcut(
application,
shortcutInfo,
null
)
internal fun requestPinShortcut() {
val title = viewState.value?.progressTitleText
?: application.getString(R.string.application_name)
val launchIntent = AppLaunchHelper.launchWithProgressDetail(application, progressId)
appShortcutHelper.requestPinShortcut(title, launchIntent)
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/com/kevalpatel2106/yip/di/AppComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.kevalpatel2106.yip.payment.PaymentActivity
import com.kevalpatel2106.yip.settings.SettingsActivity
import com.kevalpatel2106.yip.settings.SettingsFragment
import com.kevalpatel2106.yip.splash.SplashActivity
import com.kevalpatel2106.yip.utils.NotificationViewer
import com.kevalpatel2106.yip.views.NotificationViewer
import com.kevalpatel2106.yip.webviews.WebViewActivity
import com.kevalpatel2106.yip.widget.ProgressListRemoteService
import dagger.Component
Expand Down Expand Up @@ -50,4 +50,4 @@ internal fun Context.getAppComponent(): AppComponent {
return DaggerAppComponent.builder()
.coreComponent((applicationContext as? YIPApplication)?.coreComponent)
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.kevalpatel2106.yip.edit.EditProgressUseCases.conformBeforeExit
import com.kevalpatel2106.yip.edit.EditProgressUseCases.getDatePicker
import com.kevalpatel2106.yip.payment.PaymentActivity
import com.kevalpatel2106.yip.repo.utils.DateFormatter
import com.kevalpatel2106.yip.utils.ColorPicker
import com.kevalpatel2106.yip.views.ColorPicker
import kotlinx.android.synthetic.main.activity_edit_progress.edit_color
import kotlinx.android.synthetic.main.activity_edit_progress.edit_end_time
import kotlinx.android.synthetic.main.activity_edit_progress.edit_progress_title
Expand Down Expand Up @@ -177,4 +177,4 @@ internal class EditProgressActivity : AppCompatActivity() {
})
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.app.NotificationCompat
import com.kevalpatel2106.yip.R
import com.kevalpatel2106.yip.entity.Progress
import com.kevalpatel2106.yip.splash.AppLaunchHelper
import com.kevalpatel2106.yip.utils.AppLaunchHelper

/**
* Helper class for showing and canceling progress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.kevalpatel2106.yip.core.di.provideViewModel
import com.kevalpatel2106.yip.di.getAppComponent
import com.kevalpatel2106.yip.utils.AppLaunchHelper
import javax.inject.Inject

internal class SplashActivity : AppCompatActivity() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.kevalpatel2106.yip.splash
package com.kevalpatel2106.yip.utils

import android.content.Context
import android.content.Intent
import androidx.core.app.TaskStackBuilder
import com.kevalpatel2106.yip.core.prepareLaunchIntent
import com.kevalpatel2106.yip.dashboard.DashboardActivity
import com.kevalpatel2106.yip.edit.EditProgressActivity
import com.kevalpatel2106.yip.splash.SplashActivity

internal object AppLaunchHelper {
private const val ACTION_CREATE_PROGRESS = "com.kevalpatel2106.yip.create_new"
Expand Down Expand Up @@ -33,16 +34,16 @@ internal object AppLaunchHelper {

internal fun launchFlow(splashActivity: SplashActivity, intent: Intent) {
when {
intent.action == AppLaunchHelper.ACTION_CREATE_PROGRESS -> {
intent.action == ACTION_CREATE_PROGRESS -> {
TaskStackBuilder.create(splashActivity)
.addNextIntent(DashboardActivity.launchIntent(splashActivity))
.addNextIntent(EditProgressActivity.createNewDeadlineIntent(splashActivity))
.startActivities()
}
intent.action == AppLaunchHelper.ACTION_LAUNCH_WITH_PROGRESS -> {
intent.action == ACTION_LAUNCH_WITH_PROGRESS -> {
DashboardActivity.launch(
splashActivity,
intent.getLongExtra(AppLaunchHelper.ARG_PROGRESS_ID, -1)
intent.getLongExtra(ARG_PROGRESS_ID, -1)
)
}
else -> DashboardActivity.launch(splashActivity)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.kevalpatel2106.yip.utils

import android.app.Application
import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.kevalpatel2106.yip.R
import com.kevalpatel2106.yip.entity.Progress
import javax.inject.Inject

class AppShortcutHelper @Inject internal constructor(
private val application: Application
) {

internal fun requestPinShortcut(title: String, launchIntent: Intent) {
if (!ShortcutManagerCompat.isRequestPinShortcutSupported(application)) return

val shortcutInfo = ShortcutInfoCompat.Builder(
application,
application.getString(R.string.progress_pin_shortcut_id)
).setIcon(IconCompat.createWithResource(application, R.drawable.progress_app_shortcut))
.setShortLabel(title)
.setIntent(launchIntent)
.setAlwaysBadged()
.build()

ShortcutManagerCompat.requestPinShortcut(
application,
shortcutInfo,
null
)
}

internal fun updateDynamicShortcuts(progresses: List<Progress>): Boolean {
ShortcutManagerCompat.removeAllDynamicShortcuts(application)
if (progresses.isEmpty()) return true

val icon = IconCompat.createWithResource(application, R.drawable.progress_app_shortcut)
val shortcuts = progresses.subList(
0,
ShortcutManagerCompat.getMaxShortcutCountPerActivity(application) - NUMBER_OF_STATIC_APP_SHORTCUT
).map { progress ->
ShortcutInfoCompat.Builder(
application,
application.getString(R.string.progress_app_shortcut_id, progress.id)
).setIcon(icon)
.setShortLabel(progress.title)
.setIntent(AppLaunchHelper.launchWithProgressDetail(application, progress.id))
.build()
}
return ShortcutManagerCompat.addDynamicShortcuts(application, shortcuts)
}

companion object {
private const val NUMBER_OF_STATIC_APP_SHORTCUT = 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.kevalpatel2106.yip.utils

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.kevalpatel2106.yip.notifications.ProgressNotificationReceiver
import com.kevalpatel2106.yip.repo.providers.AlarmProvider
import dagger.android.AndroidInjection
import javax.inject.Inject

internal class LocaleChangedReceiver : BroadcastReceiver() {

@Inject
internal lateinit var alarmProvider: AlarmProvider

override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action != Intent.ACTION_LOCALE_CHANGED || context == null) return
AndroidInjection.inject(this, context)
alarmProvider.updateAlarms(ProgressNotificationReceiver::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kevalpatel2106.yip.utils
package com.kevalpatel2106.yip.views

import android.content.Context
import android.graphics.Canvas
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kevalpatel2106.yip.utils
package com.kevalpatel2106.yip.views

import android.annotation.SuppressLint
import android.content.Context
Expand Down Expand Up @@ -146,4 +146,4 @@ internal class NotificationViewer @JvmOverloads constructor(
}
}.show()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import android.widget.RemoteViewsService
import com.kevalpatel2106.yip.R
import com.kevalpatel2106.yip.entity.Progress
import com.kevalpatel2106.yip.repo.YipRepo
import com.kevalpatel2106.yip.splash.AppLaunchHelper
import com.kevalpatel2106.yip.utils.AppLaunchHelper
import timber.log.Timber
import javax.inject.Inject

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import android.net.Uri
import android.widget.RemoteViews
import com.kevalpatel2106.yip.R
import com.kevalpatel2106.yip.repo.providers.SharedPrefsProvider
import com.kevalpatel2106.yip.splash.AppLaunchHelper
import com.kevalpatel2106.yip.utils.AppLaunchHelper
import dagger.android.AndroidInjection
import javax.inject.Inject

Expand Down
6 changes: 3 additions & 3 deletions app/src/main/res/layout/activity_edit_progress.xml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/edit_end_time" />

<com.kevalpatel2106.yip.utils.ColorPicker
<com.kevalpatel2106.yip.views.ColorPicker
android:id="@+id/edit_color"
android:layout_width="0dp"
android:layout_height="@dimen/spacing_huge"
Expand Down Expand Up @@ -169,7 +169,7 @@
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/edit_color" />

<com.kevalpatel2106.yip.utils.NotificationViewer
<com.kevalpatel2106.yip.views.NotificationViewer
android:id="@+id/notification_times"
android:layout_width="0dp"
android:layout_height="wrap_content"
Expand All @@ -189,4 +189,4 @@
app:srcCompat="@drawable/ic_notification_bell" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>
</LinearLayout>
3 changes: 2 additions & 1 deletion app/src/main/res/values/const.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<!--App shortcuts ids.-->
<string name="progress_pin_shortcut_id" translatable="false">progress_pin_shortcut</string>
<string name="progress_app_shortcut_id" translatable="false">progress_app_shortcut_%d</string>

<!--Preferences keys-->
<string name="pref_key_buy_pro" translatable="false">pref_key_buy_pro</string>
Expand All @@ -19,4 +20,4 @@
<!--Notification channels-->
<string name="deadline_notification_channel_title" translatable="false">Deadline notifications</string>
<!--TODO: Categorize the constants-->
</resources>
</resources>
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
<string name="detail_progress_complete_title"><![CDATA[Times Up! ⏳]]></string>
<string name="detail_progress_complete_message"><![CDATA[You\'ve reached on the deadline.]]></string>
<string name="detail_progress_complete_share_btn_title">Share #GoalAchived</string>
<string name="meu_title_pin_shortcut">Pin shortcut</string>
<string name="meu_title_pin_shortcut">Add to home screen</string>
<string name="meu_title_delete">Delete</string>

<!--Payment screen-->
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0-alpha06'
classpath 'com.android.tools.build:gradle:3.5.0-alpha07'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
classpath "com.vanniktech:gradle-android-junit-jacoco-plugin:0.13.0"
classpath 'com.google.gms:google-services:4.2.0'
Expand Down Expand Up @@ -166,4 +166,4 @@ subprojects {

task clean(type: Delete) {
delete rootProject.buildDir
}
}

0 comments on commit da4bf70

Please sign in to comment.