mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Open from homescreen/add shortcut to launcher (#435)
* Add very basic "Add to homescreen" action in manga info fragment. * Fix open from homescreen opening current manga (if a manga is open). Code cleanup. * Improve fix for "Opening from homescreen opens currently open manga if a manga is currently open" and fix "Going back to the main app via a Manga opened through a shortcut repeats the launcher open animation". * Implement custom icons, add star icon and optimize some things. * Remove Tachiyomi and custom image icon types. * Move icon creation task into an observable. Added some extra error handling.
This commit is contained in:
		| @@ -24,6 +24,7 @@ class MangaActivity : BaseRxActivity<MangaPresenter>() { | ||||
|  | ||||
|         const val FROM_CATALOGUE_EXTRA = "from_catalogue" | ||||
|         const val MANGA_EXTRA = "manga" | ||||
|         const val FROM_LAUNCHER_EXTRA = "from_launcher" | ||||
|         const val INFO_FRAGMENT = 0 | ||||
|         const val CHAPTERS_FRAGMENT = 1 | ||||
|         const val MYANIMELIST_FRAGMENT = 2 | ||||
| @@ -47,6 +48,11 @@ class MangaActivity : BaseRxActivity<MangaPresenter>() { | ||||
|         super.onCreate(savedState) | ||||
|         setContentView(R.layout.activity_manga) | ||||
|  | ||||
|         val fromLauncher = intent.getBooleanExtra(FROM_LAUNCHER_EXTRA, false) | ||||
|  | ||||
|         //Remove any current manga if we are launching from launcher | ||||
|         if(fromLauncher) SharedData.remove(MangaEvent::class.java) | ||||
|  | ||||
|         presenter.setMangaEvent(SharedData.getOrPut(MangaEvent::class.java) { | ||||
|             val id = intent.getLongExtra(MANGA_EXTRA, 0) | ||||
|             MangaEvent(presenter.db.getManga(id).executeAsBlocking()!!) | ||||
|   | ||||
| @@ -1,21 +1,44 @@ | ||||
| package eu.kanade.tachiyomi.ui.manga.info | ||||
|  | ||||
| import android.app.Activity | ||||
| import android.content.Intent | ||||
| import android.graphics.Bitmap | ||||
| import android.graphics.BitmapFactory | ||||
| import android.graphics.drawable.BitmapDrawable | ||||
| import android.net.Uri | ||||
| import android.os.Bundle | ||||
| import android.support.customtabs.CustomTabsIntent | ||||
| import android.support.design.widget.Snackbar | ||||
| import android.util.SparseArray | ||||
| import android.view.* | ||||
| import com.afollestad.materialdialogs.MaterialDialog | ||||
| import com.bumptech.glide.BitmapRequestBuilder | ||||
| import com.bumptech.glide.BitmapTypeRequest | ||||
| import com.bumptech.glide.Glide | ||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy | ||||
| import com.bumptech.glide.load.resource.bitmap.CenterCrop | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.data.source.Source | ||||
| import eu.kanade.tachiyomi.data.source.online.OnlineSource | ||||
| import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment | ||||
| import eu.kanade.tachiyomi.ui.library.LibraryFragment | ||||
| import eu.kanade.tachiyomi.ui.manga.MangaActivity | ||||
| import eu.kanade.tachiyomi.util.getResourceColor | ||||
| import eu.kanade.tachiyomi.util.toast | ||||
| import jp.wasabeef.glide.transformations.CropCircleTransformation | ||||
| import jp.wasabeef.glide.transformations.CropSquareTransformation | ||||
| import jp.wasabeef.glide.transformations.MaskTransformation | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation | ||||
| import kotlinx.android.synthetic.main.fragment_manga_info.* | ||||
| import kotlinx.android.synthetic.main.item_download.* | ||||
| import nucleus.factory.RequiresPresenter | ||||
| import rx.Observable | ||||
| import rx.android.schedulers.AndroidSchedulers | ||||
| import rx.schedulers.Schedulers | ||||
| import timber.log.Timber | ||||
| import java.io.IOException | ||||
| import kotlin.concurrent.thread | ||||
|  | ||||
| /** | ||||
|  * Fragment that shows manga information. | ||||
| @@ -34,6 +57,7 @@ class MangaInfoFragment : BaseRxFragment<MangaInfoPresenter>() { | ||||
|         fun newInstance(): MangaInfoFragment { | ||||
|             return MangaInfoFragment() | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     override fun onCreate(savedState: Bundle?) { | ||||
| @@ -61,6 +85,7 @@ class MangaInfoFragment : BaseRxFragment<MangaInfoPresenter>() { | ||||
|         when (item.itemId) { | ||||
|             R.id.action_open_in_browser -> openInBrowser() | ||||
|             R.id.action_share -> shareManga() | ||||
|             R.id.action_add_to_home_screen -> addToHomeScreen() | ||||
|             else -> return super.onOptionsItemSelected(item) | ||||
|         } | ||||
|         return true | ||||
| @@ -178,6 +203,80 @@ class MangaInfoFragment : BaseRxFragment<MangaInfoPresenter>() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the manga to the home screen | ||||
|      */ | ||||
|     fun addToHomeScreen() { | ||||
|         val shortcutIntent = activity.intent | ||||
|         shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) | ||||
|                 .putExtra(MangaActivity.FROM_LAUNCHER_EXTRA, true) | ||||
|  | ||||
|         val addIntent = Intent() | ||||
|         addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent) | ||||
|                 .action = "com.android.launcher.action.INSTALL_SHORTCUT" | ||||
|  | ||||
|         //Set shortcut title | ||||
|         MaterialDialog.Builder(activity) | ||||
|                 .title(R.string.shortcut_title) | ||||
|                 .input("", presenter.manga.title, { md, text -> | ||||
|                     //Set shortcut title | ||||
|                     addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, text.toString()) | ||||
|  | ||||
|                     reshapeIconBitmap(addIntent, | ||||
|                             Glide.with(context).load(presenter.manga).asBitmap()) | ||||
|                 }) | ||||
|                 .negativeText(android.R.string.cancel) | ||||
|                 .onNegative { materialDialog, dialogAction -> materialDialog.cancel() } | ||||
|                 .show() | ||||
|     } | ||||
|  | ||||
|     fun reshapeIconBitmap(addIntent: Intent, request: BitmapTypeRequest<out Any>) { | ||||
|         val modes = intArrayOf(R.string.circular_icon, | ||||
|                 R.string.rounded_icon, | ||||
|                 R.string.square_icon, | ||||
|                 R.string.star_icon) | ||||
|  | ||||
|         fun BitmapRequestBuilder<out Any, Bitmap>.toIcon(): Bitmap { | ||||
|             return this.into(96, 96).get() | ||||
|         } | ||||
|  | ||||
|         MaterialDialog.Builder(activity) | ||||
|                 .title(R.string.icon_shape) | ||||
|                 .negativeText(android.R.string.cancel) | ||||
|                 .items(modes.map { getString(it) }) | ||||
|                 .itemsCallback { dialog, view, i, charSequence -> | ||||
|                     Observable.fromCallable { | ||||
|                         // i = 0: Circular icon | ||||
|                         // i = 1: Rounded icon | ||||
|                         // i = 2: Square icon | ||||
|                         // i = 3: Star icon (because boredom) | ||||
|                         when (i) { | ||||
|                             0 -> request.transform(CropCircleTransformation(context)).toIcon() | ||||
|                             1 -> request.transform(RoundedCornersTransformation(context, 5, 0)).toIcon() | ||||
|                             2 -> request.transform(CropSquareTransformation(context)).toIcon() | ||||
|                             3 -> request.transform(CenterCrop(context), MaskTransformation(context, R.drawable.mask_star)).toIcon() | ||||
|                             else -> null | ||||
|                         } | ||||
|                     }.subscribeOn(Schedulers.io()) | ||||
|                     .observeOn(AndroidSchedulers.mainThread()) | ||||
|                     .subscribe({ if (it != null) createShortcut(addIntent, it) }, | ||||
|                             { context.toast(R.string.icon_creation_fail) }) | ||||
|                 }.show() | ||||
|     } | ||||
|  | ||||
|     fun createShortcut(addIntent: Intent, icon: Bitmap) { | ||||
|         //Send shortcut intent | ||||
|         addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon) | ||||
|         context.sendBroadcast(addIntent) | ||||
|         //Go to launcher to show this shiny new shortcut! | ||||
|         val startMain = Intent(Intent.ACTION_MAIN) | ||||
|         startMain.addCategory(Intent.CATEGORY_HOME) | ||||
|                 .flags = Intent.FLAG_ACTIVITY_NEW_TASK | ||||
|         activity.runOnUiThread { | ||||
|             startActivity(startMain) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update FAB with correct drawable. | ||||
|      * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user