supported adaptive icon for static shortcuts

This commit is contained in:
Mariotaku Lee 2017-08-24 12:49:38 +08:00
parent 7dedf49c65
commit adc57a0975
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
48 changed files with 276 additions and 74 deletions

View File

@ -23,12 +23,11 @@ import android.app.Activity
import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Canvas
import android.os.Bundle
import android.support.v4.content.pm.ShortcutManagerCompat
import android.support.v7.app.AlertDialog
import com.bumptech.glide.Glide
import nl.komponents.kovenant.combine.and
import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.successUi
import org.mariotaku.kpreferences.get
@ -41,17 +40,16 @@ import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.activity.UserSelectorActivity
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.extension.applyOnShow
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.loadProfileImage
import org.mariotaku.twidere.extension.dismissProgressDialog
import org.mariotaku.twidere.extension.showProgressDialog
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.glide.DeferredTarget
import org.mariotaku.twidere.util.shortcut.ShortcutCreator
import java.lang.ref.WeakReference
class CreateQuickAccessShortcutActivity : BaseActivity() {
@ -159,32 +157,21 @@ class CreateQuickAccessShortcutActivity : BaseActivity() {
finish()
}
else -> {
val displayName = userColorNameManager.getDisplayName(user, preferences[nameFirstKey])
val deferred = Glide.with(this).loadProfileImage(this, user,
shapeStyle = preferences[profileImageStyleKey], cornerRadiusRatio = 0.1f,
size = getString(R.string.profile_image_size)).into(DeferredTarget())
val weakThis = WeakReference(this)
executeAfterFragmentResumed {
ProgressDialogFragment.show(it.supportFragmentManager, TAG_LOAD_ICON_PROGRESS)
} and deferred.promise.successUi { drawable ->
val promise = showProgressDialog(TAG_LOAD_ICON_PROGRESS)
.and(ShortcutCreator.userShortcut(this, user.account_key, user))
promise.successUi { (_, shortcut) ->
val activity = weakThis.get() ?: return@successUi
val launchIntent = IntentUtils.userProfile(accountKey, user.key,
user.screen_name, profileUrl = user.extras?.statusnet_profile_url)
val icon = Bitmap.createBitmap(drawable.intrinsicWidth,
drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(icon)
drawable.setBounds(0, 0, icon.width, icon.height)
drawable.draw(canvas)
activity.setResult(Activity.RESULT_OK, Intent().apply {
putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent)
putExtra(Intent.EXTRA_SHORTCUT_ICON, icon)
putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName)
})
activity.setResult(Activity.RESULT_OK,
ShortcutManagerCompat.createShortcutResultIntent(activity, shortcut))
activity.finish()
}.failUi {
val activity = weakThis.get() ?: return@failUi
activity.setResult(Activity.RESULT_CANCELED)
activity.finish()
}.alwaysUi {
val activity = weakThis.get() ?: return@alwaysUi
activity.dismissProgressDialog(TAG_LOAD_ICON_PROGRESS)
}
}
}
@ -246,5 +233,6 @@ class CreateQuickAccessShortcutActivity : BaseActivity() {
companion object {
private const val TAG_LOAD_ICON_PROGRESS = "load_icon_progress"
}
}

View File

@ -0,0 +1,41 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.extension
import android.support.v4.app.FragmentActivity
import nl.komponents.kovenant.Promise
import org.mariotaku.ktextension.dismissDialogFragment
import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.fragment.ProgressDialogFragment
/**
* Created by mariotaku on 2017/8/23.
*/
fun <A : FragmentActivity> IBaseActivity<A>.showProgressDialog(tag: String): Promise<Unit, Exception> {
return executeAfterFragmentResumed {
ProgressDialogFragment.show(it.supportFragmentManager, tag)
}
}
fun <A : FragmentActivity> IBaseActivity<A>.dismissProgressDialog(tag: String): Promise<Unit, Exception> {
return executeAfterFragmentResumed {
it.supportFragmentManager.dismissDialogFragment(tag)
}
}

View File

@ -0,0 +1,41 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.extension
import android.support.v4.app.Fragment
import nl.komponents.kovenant.Promise
import org.mariotaku.ktextension.dismissDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment
/**
* Created by mariotaku on 2017/8/23.
*/
fun <F : Fragment> IBaseFragment<F>.showProgressDialog(tag: String): Promise<Unit, Exception> {
return executeAfterFragmentResumed {
ProgressDialogFragment.show(it.childFragmentManager, tag)
}
}
fun <F : Fragment> IBaseFragment<F>.dismissProgressDialog(tag: String): Promise<Unit, Exception> {
return executeAfterFragmentResumed {
it.childFragmentManager.dismissDialogFragment(tag)
}
}

View File

@ -53,6 +53,7 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks
import android.support.v4.content.ContextCompat
import android.support.v4.content.FixedAsyncTaskLoader
import android.support.v4.content.Loader
import android.support.v4.content.pm.ShortcutManagerCompat
import android.support.v4.content.res.ResourcesCompat
import android.support.v4.graphics.ColorUtils
import android.support.v4.view.OnApplyWindowInsetsListener
@ -80,6 +81,7 @@ import kotlinx.android.synthetic.main.header_user.*
import kotlinx.android.synthetic.main.header_user.view.*
import kotlinx.android.synthetic.main.layout_content_fragment_common.*
import kotlinx.android.synthetic.main.layout_content_pages_common.*
import nl.komponents.kovenant.combine.and
import nl.komponents.kovenant.task
import nl.komponents.kovenant.then
import nl.komponents.kovenant.ui.alwaysUi
@ -140,6 +142,7 @@ import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener
import org.mariotaku.twidere.util.UserColorNameManager.UserColorChangedListener
import org.mariotaku.twidere.util.UserColorNameManager.UserNicknameChangedListener
import org.mariotaku.twidere.util.menu.TwidereMenuInfo
import org.mariotaku.twidere.util.shortcut.ShortcutCreator
import org.mariotaku.twidere.util.support.ActivitySupport
import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat
import org.mariotaku.twidere.util.support.ViewSupport
@ -802,6 +805,9 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
menu.setItemAvailability(R.id.blocked_users, isMyself)
menu.setItemAvailability(R.id.block, !isMyself)
menu.setItemAvailability(R.id.add_to_home_screen,
ShortcutManagerCompat.isRequestPinShortcutSupported(context))
var canAddToList = false
var canMute = false
var canReportSpam = false
@ -1033,9 +1039,22 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
}
return true
}
R.id.add_to_home_screen -> {
if (!ShortcutManagerCompat.isRequestPinShortcutSupported(context)) return true
val promise = showProgressDialog(FRAGMENT_TAG_ADD_USER_SHORTCUT_TO_HOME_SCREEN)
.and(ShortcutCreator.userShortcut(context, user.account_key, user))
val weakThis = WeakReference(this)
promise.successUi { (_, shortcut) ->
val fragment = weakThis.get() ?: return@successUi
ShortcutManagerCompat.requestPinShortcut(fragment.context, shortcut, null)
}.alwaysUi {
val fragment = weakThis.get() ?: return@alwaysUi
fragment.dismissProgressDialog(FRAGMENT_TAG_ADD_USER_SHORTCUT_TO_HOME_SCREEN)
}
}
else -> {
val intent = item.intent
if (intent != null && intent.resolveActivity(context.packageManager) != null) {
if (intent?.resolveActivity(context.packageManager) != null) {
startActivity(intent)
}
}
@ -1590,7 +1609,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
do {
val resp = microBlog.getUserListOwnerships(paging)
resp.mapTo(ownedLists) { item ->
val userList = item.toParcelable( user.account_key)
val userList = item.toParcelable(user.account_key)
userList.is_user_inside = listMemberships.any { it.id == item.id }
return@mapTo userList
}
@ -1836,12 +1855,13 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
private val LOADER_ID_USER = 1
private val LOADER_ID_FRIENDSHIP = 2
private val TAB_POSITION_STATUSES = 0
private val TAB_POSITION_MEDIA = 1
private val TAB_POSITION_FAVORITES = 2
private val TAB_TYPE_STATUSES = "statuses"
private val TAB_TYPE_STATUSES_WITH_REPLIES = "statuses_with_replies"
private val TAB_TYPE_MEDIA = "media"
private val TAB_TYPE_FAVORITES = "favorites"
private const val TAB_POSITION_STATUSES = 0
private const val TAB_POSITION_MEDIA = 1
private const val TAB_POSITION_FAVORITES = 2
private const val TAB_TYPE_STATUSES = "statuses"
private const val TAB_TYPE_STATUSES_WITH_REPLIES = "statuses_with_replies"
private const val TAB_TYPE_MEDIA = "media"
private const val TAB_TYPE_FAVORITES = "favorites"
private const val FRAGMENT_TAG_ADD_USER_SHORTCUT_TO_HOME_SCREEN = "add_user_shortcut_to_home_screen"
}
}

View File

@ -0,0 +1,106 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util.shortcut
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.os.Build
import android.support.v4.content.pm.ShortcutInfoCompat
import android.support.v4.graphics.drawable.IconCompat
import com.bumptech.glide.Glide
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.then
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.ImageShapeStyle
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.extension.loadProfileImage
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.util.glide.DeferredTarget
import java.lang.ref.WeakReference
/**
* Created by mariotaku on 2017/8/23.
*/
object ShortcutCreator {
private val useAdaptiveIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
private const val adaptiveIconSizeDp = 108
private const val adaptiveIconOuterSidesDp = 18
fun userShortcut(context: Context, accountKey: UserKey?, user: ParcelableUser): Promise<ShortcutInfoCompat, Exception> {
val holder = DependencyHolder.get(context)
val preferences = holder.preferences
val userColorNameManager = holder.userColorNameManager
val profileImageStyle = if (useAdaptiveIcon) ImageShapeStyle.SHAPE_RECTANGLE else preferences[profileImageStyleKey]
val profileImageCornerRadiusRatio = if (useAdaptiveIcon) 0f else 0.1f
val deferred = Glide.with(context).loadProfileImage(context, user,
shapeStyle = profileImageStyle, cornerRadiusRatio = profileImageCornerRadiusRatio,
size = context.getString(R.string.profile_image_size)).into(DeferredTarget())
val weakContext = WeakReference(context)
return deferred.promise.then { drawable ->
val ctx = weakContext.get() ?: throw InterruptedException()
val builder = ShortcutInfoCompat.Builder(ctx, "user-shortcut-$accountKey-${user.key}")
builder.setIcon(drawable.toProfileImageIcon(ctx))
builder.setShortLabel(userColorNameManager.getDisplayName(user, preferences[nameFirstKey]))
val launchIntent = IntentUtils.userProfile(accountKey, user.key,
user.screen_name, profileUrl = user.extras?.statusnet_profile_url)
builder.setIntent(launchIntent)
return@then builder.build()
}
}
private fun Drawable.toProfileImageIcon(context: Context): IconCompat {
if (useAdaptiveIcon) {
val density = context.resources.displayMetrics.density
val adaptiveIconSize = Math.round(adaptiveIconSizeDp * density)
val adaptiveIconOuterSides = Math.round(adaptiveIconOuterSidesDp * density)
val bitmap = Bitmap.createBitmap(adaptiveIconSize, adaptiveIconSize,
Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
setBounds(adaptiveIconOuterSides, adaptiveIconOuterSides,
adaptiveIconSize - adaptiveIconOuterSides,
adaptiveIconSize - adaptiveIconOuterSides)
draw(canvas)
return IconCompat.createWithAdaptiveBitmap(bitmap)
} else {
val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
setBounds(0, 0, bitmap.width, bitmap.height)
draw(canvas)
return IconCompat.createWithBitmap(bitmap)
}
}
}

View File

@ -86,5 +86,9 @@
android:id="@id/open_in_browser"
android:icon="@drawable/ic_action_web"
android:title="@string/action_open_in_browser"/>
<item
android:id="@id/add_to_home_screen"
android:icon="@drawable/ic_action_home"
android:title="@string/action_add_to_home_screen"/>
</menu>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_shortcut_adaptive_background"/>
<foreground android:drawable="@mipmap/ic_shortcut_camera_adaptive_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_shortcut_adaptive_background"/>
<foreground android:drawable="@mipmap/ic_shortcut_compose_adaptive_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 902 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -84,4 +84,5 @@
<item name="messages" type="id"/>
<item name="interactions" type="id"/>
<item name="premium_features" type="id"/>
<item name="add_to_home_screen" type="id"/>
</resources>

View File

@ -23,6 +23,7 @@
<string name="action_add_member">Add member</string>
<string name="action_add_tab">Add tab</string>
<string name="action_add_to_filter">Add to filter</string>
<string name="action_add_to_home_screen">Add to home screen</string>
<string name="action_add_to_list">Add to list</string>
<!-- [verb] Action for blocking user -->
<string name="action_block">Block</string>

View File

@ -5,7 +5,7 @@
tools:targetApi="n_mr1">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_app_shortcut_compose"
android:icon="@mipmap/ic_shortcut_compose"
android:shortcutId="compose"
android:shortcutLongLabel="@string/action_compose"
android:shortcutShortLabel="@string/action_compose">
@ -16,7 +16,7 @@
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/ic_app_shortcut_camera"
android:icon="@mipmap/ic_shortcut_camera"
android:shortcutId="compose-take-photo"
android:shortcutLongLabel="@string/action_take_photo"
android:shortcutShortLabel="@string/action_take_photo">

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title>ic_app_shortcut_camera-mdpi</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Miscellaneous" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ic_app_shortcut_camera-mdpi">
<circle id="Oval-2" fill="#FAFAFA" cx="24" cy="24" r="24"></circle>
<g id="Group" transform="translate(14.000000, 15.000000)" fill="#55ACEE">
<circle id="Oval" cx="10" cy="10" r="3.2"></circle>
<path d="M7,0 L5.17,2 L2,2 C0.9,2 0,2.9 0,4 L0,16 C0,17.1 0.9,18 2,18 L18,18 C19.1,18 20,17.1 20,16 L20,4 C20,2.9 19.1,2 18,2 L14.83,2 L13,0 L7,0 L7,0 Z M10,15 C7.24,15 5,12.76 5,10 C5,7.24 7.24,5 10,5 C12.76,5 15,7.24 15,10 C15,12.76 12.76,15 10,15 L10,15 Z" id="Shape"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.3 (33839) - http://www.bohemiancoding.com/sketch -->
<title>ic_app_shortcut_compose-mdpi</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Miscellaneous" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ic_app_shortcut_compose-mdpi">
<circle id="Oval-2" fill="#FAFAFA" cx="24" cy="24" r="24"></circle>
<path d="M34.9691703,15.5269946 C34.5538589,15.5204967 34.0503207,16.1296754 34.4586385,16.5536638 C34.5812953,16.7594308 35.3500517,17.0123076 35.7922615,17.1563445 C35.4113801,17.7860999 32.8393544,18.3606231 31.9070557,17.9431327 C31.546617,17.7243698 30.8935237,18.2923951 31.226526,18.8604204 C31.3421891,19.0385713 32.3971446,19.8053242 32.8936892,20.1405079 C32.5402442,20.4556563 29.0638941,20.3435675 28.6340575,20.0175892 C28.1445065,19.8394382 27.5317608,20.4004241 27.8857438,20.8866841 L30.1269191,22.4337272 C29.9364784,22.8474273 26.8211049,24.353317 26.0163046,24.3912214 C25.3239396,23.939617 23.8924064,23.9109179 22.9660252,24.3912214 C21.9186013,24.9180933 19.6542934,26.9698071 18.5875026,28.4567446 C18.2507345,29.1157406 17.4088144,29.850004 15.7152907,30.3768759 C20.995448,21.9063139 30.7751707,13.9252608 37,14.0005282 C36.983323,14.7537438 35.8062487,15.4517272 34.9691703,15.5269946 L34.9691703,15.5269946 Z M21.9417339,18.5490624 L13.9932547,18.5490624 C13.6930685,18.5490624 13.4386096,18.5820934 13.4386096,18.9102377 L13.4386096,31.1750353 C13.4386096,31.3916322 13.5591144,31.6174344 13.7931306,31.6174344 L25.5859301,31.6174344 C25.9194703,31.6174344 25.9194703,31.4988477 25.9194703,31.3104084 L25.9194703,28.1697538 C26.3218705,28.6121529 28.255328,27.9022567 28.3586178,27.5259196 L28.3586178,31.8340313 C28.3586178,32.8406653 27.4198634,34 26.2782951,34 L13.1518725,34 C12.1039106,34 11,32.9446318 11,31.8340313 L11,18.2604471 C11,17.2814292 12.0221395,16.2390568 13.1518725,16.2390568 L23.9349059,16.2390568 C22.8939375,17.1081517 22.8035589,17.5565073 21.9417339,18.5490624 L21.9417339,18.5490624 Z" id="未命名-#1" fill="#55ACEE"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB