From cea5cc42e86cd6c2c75ab1bd4702a348db8cb559 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Mon, 11 Dec 2017 20:43:55 +0800 Subject: [PATCH] removed legacy shitty icon tint implementation --- build.gradle | 4 +- .../twidere/graphic/ActionIconDrawable.java | 73 ----------------- .../support/v7/widget/TwidereToolbar.kt | 3 +- .../mariotaku/ktextension/MenuExtensions.kt | 14 ---- .../twidere/activity/HomeActivity.kt | 2 +- .../twidere/activity/MediaViewerActivity.kt | 15 ++-- .../activity/QuickSearchBarActivity.kt | 5 +- .../adapter/ComposeAutoCompleteAdapter.kt | 4 +- .../twidere/extension/DrawableExtensions.kt | 8 +- .../twidere/fragment/CustomTabsFragment.kt | 16 ++-- .../fragment/FileSelectorDialogFragment.kt | 20 +++-- .../twidere/fragment/UserFragment.kt | 16 ++-- .../twidere/fragment/UserQrDialogFragment.kt | 56 ++++++++----- .../fragment/filter/BaseFiltersFragment.kt | 8 +- .../fragment/filter/FilteredUsersFragment.kt | 7 +- .../fragment/media/ExoPlayerPageFragment.kt | 8 +- .../message/MessagesConversationFragment.kt | 4 +- .../twidere/menu/FavoriteItemProvider.kt | 15 ++-- .../mariotaku/twidere/model/SaveFileInfo.kt | 45 ++++++++++ .../mariotaku/twidere/model/SaveFileResult.kt | 24 ++++++ .../promise/file/SaveFilePromises.java | 27 ++++++ .../twidere/provider/CacheProvider.kt | 8 +- .../twidere/task/ProgressSaveFileTask.kt | 3 +- .../mariotaku/twidere/task/SaveFileTask.kt | 53 +++--------- .../twidere/task/SaveMediaToGalleryTask.kt | 3 +- .../org/mariotaku/twidere/util/MenuUtils.kt | 41 ++++------ .../org/mariotaku/twidere/util/ThemeUtils.kt | 81 ++++-------------- .../twidere/view/ActionIconThemedTextView.kt | 3 +- .../twidere/view/LabeledImageButton.kt | 5 ++ .../holder/status/DetailStatusViewHolder.kt | 11 +-- .../view/holder/status/StatusViewHolder.kt | 3 +- .../res/color/btn_tint_favorite_stateful.xml | 1 + .../main/res/color/btn_tint_like_stateful.xml | 1 + .../res/color/btn_tint_retweet_stateful.xml | 1 + .../res/layout/activity_quick_search_bar.xml | 1 - .../adapter_item_large_media_status.xml | 5 +- .../src/main/res/layout/fragment_user_qr.xml | 82 ++++++++++++++----- .../layout_actionbar_message_user_picker.xml | 3 +- .../main/res/layout/list_item_custom_tab.xml | 5 +- .../src/main/res/layout/list_item_status.xml | 4 - .../layout/spinner_item_custom_tab_icon.xml | 8 +- .../res/values-notnight/themes_daynight.xml | 2 + twidere/src/main/res/values/themes.xml | 5 ++ .../src/main/res/values/themes_base_dark.xml | 12 +++ .../src/main/res/values/themes_base_light.xml | 12 +++ .../src/main/res/values/themes_daynight.xml | 2 + 46 files changed, 372 insertions(+), 357 deletions(-) delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/graphic/ActionIconDrawable.java create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileInfo.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileResult.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/promise/file/SaveFilePromises.java diff --git a/build.gradle b/build.gradle index acb8fcb6f..36f9b5556 100644 --- a/build.gradle +++ b/build.gradle @@ -42,12 +42,12 @@ subprojects { ] libVersions = [ Kotlin : "${kotlinVersion}", - SupportLib : '27.0.1', + SupportLib : '27.0.2', SupportTest : '1.0.0', MariotakuCommons : '0.9.21', RestFu : '0.9.61', ObjectCursor : '0.9.21', - PlayServices : '11.6.0', + PlayServices : '11.6.2', PlayBilling : '1.0', MapsUtils : '0.5', DropboxCoreSdk : '3.0.3', diff --git a/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionIconDrawable.java b/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionIconDrawable.java deleted file mode 100644 index 01a595b1f..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionIconDrawable.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * 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 . - */ - -package org.mariotaku.twidere.graphic; - -import android.graphics.PorterDuff.Mode; -import android.graphics.drawable.Drawable; -import android.support.v7.graphics.drawable.DrawableWrapper; -import android.support.v7.view.menu.TwidereActionMenuItemView; -import android.view.MenuItem; - -import org.mariotaku.twidere.util.menu.TwidereMenuInfo; - -/** - * Created by mariotaku on 15/1/16. - */ -@SuppressWarnings("RestrictedApi") -public class ActionIconDrawable extends DrawableWrapper implements TwidereActionMenuItemView.IgnoreTinting { - - private int mDefaultColor; - private int mHighlightColor; - - public ActionIconDrawable(Drawable drawable, int defaultColor) { - super(drawable); - setDefaultColor(defaultColor); - setHighlightColor(0); - } - - public int getDefaultColor() { - return mDefaultColor; - } - - public void setDefaultColor(int defaultColor) { - mDefaultColor = defaultColor; - updateColorFilter(); - } - - - public static void setMenuHighlight(MenuItem item, TwidereMenuInfo info) { - final Drawable icon = item.getIcon(); - if (icon instanceof ActionIconDrawable) { - ((ActionIconDrawable) icon).setHighlightColor(info.isHighlight() ? info.getHighlightColor(0) : 0); - } - } - - private void setHighlightColor(int color) { - mHighlightColor = color; - updateColorFilter(); - } - - private void updateColorFilter() { - final int color = mHighlightColor == 0 ? mDefaultColor : mHighlightColor; - setColorFilter(color, Mode.SRC_ATOP); - invalidateSelf(); - } - -} diff --git a/twidere/src/main/kotlin/android/support/v7/widget/TwidereToolbar.kt b/twidere/src/main/kotlin/android/support/v7/widget/TwidereToolbar.kt index 3931eefd4..e2f0edc0f 100644 --- a/twidere/src/main/kotlin/android/support/v7/widget/TwidereToolbar.kt +++ b/twidere/src/main/kotlin/android/support/v7/widget/TwidereToolbar.kt @@ -22,6 +22,7 @@ package android.support.v7.widget import android.content.Context import android.graphics.PorterDuff import android.graphics.drawable.Drawable +import android.support.v4.graphics.drawable.DrawableCompat import android.util.AttributeSet import android.view.Menu import android.view.View @@ -58,7 +59,7 @@ class TwidereToolbar(context: Context, attrs: AttributeSet?) : Toolbar(context, override fun setNavigationIcon(icon: Drawable?) { if (icon != null && itemColor != 0) { - icon.setColorFilter(itemColor, PorterDuff.Mode.SRC_ATOP) + DrawableCompat.setTint(icon, itemColor) } super.setNavigationIcon(icon) } diff --git a/twidere/src/main/kotlin/org/mariotaku/ktextension/MenuExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/ktextension/MenuExtensions.kt index 5283fb4b9..66a1bc08d 100644 --- a/twidere/src/main/kotlin/org/mariotaku/ktextension/MenuExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/ktextension/MenuExtensions.kt @@ -19,16 +19,12 @@ package org.mariotaku.ktextension -import android.content.Context import android.graphics.drawable.Drawable -import android.support.annotation.DrawableRes -import android.support.v4.content.ContextCompat import android.support.v4.view.ActionProvider import android.support.v4.view.MenuItemCompat import android.view.Menu import android.view.MenuItem import android.view.SubMenu -import org.mariotaku.twidere.graphic.ActionIconDrawable fun Menu.setItemAvailability(id: Int, available: Boolean) { val item = findItem(id) ?: return @@ -74,16 +70,6 @@ fun Menu.findSubmenu(id: Int): SubMenu? { return findItem(id)?.subMenu } -fun MenuItem.setActionIcon(context: Context, @DrawableRes iconRes: Int) { - val oldIcon = this.icon - if (oldIcon is ActionIconDrawable) { - val starIcon = ContextCompat.getDrawable(context, iconRes) - this.icon = ActionIconDrawable(starIcon, oldIcon.defaultColor) - } else { - setIcon(iconRes) - } -} - var MenuItem.supportActionProvider: ActionProvider? get() = MenuItemCompat.getActionProvider(this) set(value) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt index 325fc5efa..dc018c244 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt @@ -919,7 +919,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp private fun updateActionsButton() { if (!propertiesInitialized) return val fragment = run { - if (pagerAdapter.getCount() == 0) return@run null + if (pagerAdapter.count == 0) return@run null val position = mainPager.currentItem val f = pagerAdapter.instantiateItem(mainPager, position) as? IFloatingActionButtonFragment if (f is Fragment && (f.isDetached || f.host == null)) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt index 720df7564..a276fffc8 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt @@ -60,6 +60,7 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment import org.mariotaku.twidere.fragment.media.* import org.mariotaku.twidere.model.ParcelableMedia import org.mariotaku.twidere.model.ParcelableStatus +import org.mariotaku.twidere.model.SaveFileInfo import org.mariotaku.twidere.provider.CacheProvider import org.mariotaku.twidere.provider.ShareProvider import org.mariotaku.twidere.task.SaveFileTask @@ -106,7 +107,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos return adapter.instantiateItem(viewPager, currentItem) as? MediaViewerFragment } - private fun getCurrentCacheFileInfo(position: Int): SaveFileTask.FileInfo? { + private fun getCurrentCacheFileInfo(position: Int): SaveFileInfo? { if (position == -1) return null val viewPager = findViewPager() val adapter = viewPager.adapter ?: return null @@ -521,11 +522,11 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) intent.type = fileInfo.mimeType ?: "*/*" intent.addCategory(Intent.CATEGORY_OPENABLE) - val extension = fileInfo.fileExtension + val extension = fileInfo.extension val saveFileName = if (extension != null) { - "${fileInfo.fileName?.removeSuffix("_$extension")}.$extension" + "${fileInfo.name?.removeSuffix("_$extension")}.$extension" } else { - fileInfo.fileName + fileInfo.name } intent.putExtra(Intent.EXTRA_TITLE, saveFileName) startActivityForResult(intent, REQUEST_SELECT_SAVE_MEDIA) @@ -536,7 +537,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos val weakThis = toWeak() (showProgressDialog("save_media_to_progress") and task { val a = weakThis.get() ?: throw InterruptedException() - fileInfo.inputStream().use { st -> + fileInfo.stream().use { st -> st.copyTo(a.contentResolver.openOutputStream(data)) } }).successUi { @@ -548,7 +549,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos } } - private fun MediaViewerFragment.cacheFileInfo(): SaveFileTask.FileInfo? { + private fun MediaViewerFragment.cacheFileInfo(): SaveFileInfo? { val context = this.context ?: return null return when (this) { is CacheDownloadMediaViewerFragment -> { @@ -568,7 +569,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos } } - class SaveMediaTask(activity: MediaViewerActivity, destination: File, fileInfo: FileInfo) : + class SaveMediaTask(activity: MediaViewerActivity, destination: File, fileInfo: SaveFileInfo) : SaveFileTask(activity, destination, fileInfo) { private val PROGRESS_FRAGMENT_TAG = "progress" diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt index 7bdb0f956..f85f933d7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt @@ -34,6 +34,7 @@ import android.support.v4.content.Loader import android.support.v4.view.ViewCompat import android.support.v4.view.WindowInsetsCompat import android.support.v4.widget.CursorAdapter +import android.support.v4.widget.ImageViewCompat import android.text.Editable import android.text.TextWatcher import android.view.* @@ -417,7 +418,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks< cursor.getString(indices.title)) holder.text2.visibility = View.VISIBLE holder.text2.spannable = "@${cursor.getString(indices.summary)}" - holder.icon.clearColorFilter() + ImageViewCompat.setImageTintList(holder.icon, null) requestManager.loadProfileImage(context, cursor.getString(indices.icon), profileImageStyle, cornerRadius = holder.icon.cornerRadius, cornerRadiusRatio = holder.icon.cornerRadiusRatio, @@ -427,7 +428,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks< val holder = view.tag as UserViewHolder holder.text1.spannable = "@${cursor.getString(indices.title)}" holder.text2.visibility = View.GONE - holder.icon.setColorFilter(holder.text1.currentTextColor, Mode.SRC_ATOP) + ImageViewCompat.setImageTintList(holder.icon, holder.text1.textColors) //TODO cancel image load holder.icon.setImageResource(R.drawable.ic_action_user) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt index c6c9cdedb..69686fb89 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt @@ -22,7 +22,7 @@ package org.mariotaku.twidere.adapter import android.content.Context import android.content.SharedPreferences import android.database.Cursor -import android.graphics.PorterDuff.Mode +import android.support.v4.widget.ImageViewCompat import android.support.v4.widget.SimpleCursorAdapter import android.view.View import android.widget.TextView @@ -99,7 +99,7 @@ class ComposeAutoCompleteAdapter(context: Context, val requestManager: RequestMa text2.setText(R.string.hashtag) icon.setImageResource(R.drawable.ic_action_hashtag) - icon.setColorFilter(text1.currentTextColor, Mode.SRC_ATOP) + ImageViewCompat.setImageTintList(icon, text1.textColors) } icon.visibility = if (displayProfileImage) View.VISIBLE else View.GONE super.bindView(view, context, cursor) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/DrawableExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/DrawableExtensions.kt index 9129ee912..77dd35e1f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/DrawableExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/DrawableExtensions.kt @@ -41,4 +41,10 @@ fun Drawable.setBoundsFitCenter(left: Int, top: Int, right: Int, bottom: Int) { setBounds(left, boundsHeight / 2 - actualHeight / 2, right, boundsHeight / 2 + actualHeight / 2) } -} \ No newline at end of file +} + +var Drawable.isActivated: Boolean + get() = android.R.attr.state_activated in state + set(value) { + state = if (value) intArrayOf(android.R.attr.state_activated) else intArrayOf() + } \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt index f39a2bbfc..7b6100949 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt @@ -27,12 +27,13 @@ import android.content.DialogInterface import android.content.Intent import android.database.Cursor import android.graphics.Paint -import android.graphics.PorterDuff.Mode import android.os.Bundle import android.support.v4.app.Fragment import android.support.v4.app.LoaderManager.LoaderCallbacks import android.support.v4.content.CursorLoader import android.support.v4.content.Loader +import android.support.v4.graphics.drawable.DrawableCompat +import android.support.v4.widget.ImageViewCompat import android.support.v7.app.AlertDialog import android.util.SparseArray import android.view.* @@ -152,9 +153,10 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice val shouldDisable = disabledByDuplicateTab || disabledByNoAccount subItem.isVisible = !shouldDisable subItem.isEnabled = !shouldDisable - val icon = conf.icon.createDrawable(context) - icon.mutate().setColorFilter(theme.textColorPrimary, Mode.SRC_ATOP) - subItem.icon = icon + subItem.icon = conf.icon.createDrawable(context).apply { + mutate() + DrawableCompat.setTint(this, theme.textColorPrimary) + } val weakFragment = WeakReference(this) subItem.setOnMenuItemClickListener { val fragment = weakFragment.get()?.takeUnless(Fragment::isDetached) ?: @@ -470,10 +472,9 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice } open class TabIconViewHolder(val adapter: TabIconsAdapter, itemView: View) : ViewHolder(itemView) { - private val icon: ImageView = itemView.findViewById(android.R.id.icon) + protected val icon: ImageView = itemView.findViewById(android.R.id.icon) open fun display(item: DrawableHolder) { - icon.setColorFilter(adapter.iconColor, Mode.SRC_ATOP) icon.setImageDrawable(item.createDrawable(icon.context)) } } @@ -483,6 +484,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice private val text2: TextView = itemView.findViewById(android.R.id.text2) override fun display(item: DrawableHolder) { super.display(item) + ImageViewCompat.setImageTintList(icon, text1.textColors) text1.spannable = item.name text2.visibility = View.GONE } @@ -492,7 +494,6 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice class CustomTabsAdapter(context: Context) : SimpleDragSortCursorAdapter(context, R.layout.list_item_custom_tab, null, emptyArray(), intArrayOf(), 0) { - private val iconColor: Int = ThemeUtils.getThemeForegroundColor(context) private val tempTab: Tab = Tab() private var indices: ObjectCursor.CursorIndices? = null @@ -521,7 +522,6 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice } else { holder.icon.setImageResource(R.drawable.ic_action_list) } - holder.icon.setColorFilter(iconColor, Mode.SRC_ATOP) } override fun changeCursor(cursor: Cursor?) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/FileSelectorDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/FileSelectorDialogFragment.kt index 4f9440ab8..3b6cd57df 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/FileSelectorDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/FileSelectorDialogFragment.kt @@ -23,13 +23,13 @@ import android.app.Dialog import android.content.Context import android.content.DialogInterface import android.content.DialogInterface.OnClickListener -import android.graphics.PorterDuff import android.os.Bundle import android.os.Environment.getExternalStorageDirectory 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.res.ResourcesCompat +import android.support.v4.graphics.drawable.DrawableCompat import android.support.v7.app.AlertDialog import android.text.TextUtils.TruncateAt import android.view.View @@ -194,19 +194,19 @@ class FileSelectorDialogFragment : BaseDialogFragment(), LoaderCallbacks(android.R.id.text1)) as TextView - val file = getItem(position) + val file = getItem(position)!! if (file == currentPath?.parentFile) { - text.text = "build/generated/source/rs/androidTest" + text.text = ".." } else { - text.text = file!!.name + text.text = file.name } text.setSingleLine(true) text.ellipsize = TruncateAt.MARQUEE text.setPadding(padding, padding, position, padding) - val icon = ResourcesCompat.getDrawable(resources, - if (file!!.isDirectory) R.drawable.ic_folder else R.drawable.ic_file, null)!! - icon.mutate() - icon.setColorFilter(actionIconColor, PorterDuff.Mode.SRC_ATOP) + val icon = ContextCompat.getDrawable(context, file.icon)!!.apply { + mutate() + DrawableCompat.setTint(this, actionIconColor) + } text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null) return view } @@ -219,6 +219,8 @@ class FileSelectorDialogFragment : BaseDialogFragment(), LoaderCallbacks?) : FixedAsyncTaskLoader>(context) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt index 18a90660c..a3fb743a2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt @@ -27,7 +27,6 @@ import android.content.DialogInterface import android.content.Intent import android.content.res.ColorStateList import android.graphics.Color -import android.graphics.PorterDuff import android.graphics.Rect import android.net.Uri import android.nfc.NdefMessage @@ -105,7 +104,6 @@ import org.mariotaku.twidere.fragment.timeline.AbsTimelineFragment import org.mariotaku.twidere.fragment.timeline.FavoritesTimelineFragment import org.mariotaku.twidere.fragment.timeline.UserMediaTimelineFragment import org.mariotaku.twidere.fragment.timeline.UserTimelineFragment -import org.mariotaku.twidere.graphic.ActionIconDrawable import org.mariotaku.twidere.graphic.drawable.userprofile.ActionBarDrawable import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.event.FriendshipTaskEvent @@ -127,7 +125,6 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallb 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 @@ -145,7 +142,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, override val currentVisibleFragment: Fragment? get() { val currentItem = viewPager.currentItem - if (currentItem < 0 || currentItem >= pagerAdapter.getCount()) return null + if (currentItem < 0 || currentItem >= pagerAdapter.count) return null return pagerAdapter.instantiateItem(viewPager, currentItem) } @@ -447,7 +444,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, relationship.following) menu.findItem(R.id.block)?.apply { - ActionIconDrawable.setMenuHighlight(this, TwidereMenuInfo(relationship.blocking)) + icon?.isActivated = relationship.blocking this.setTitle(if (relationship.blocking) R.string.action_unblock else R.string.action_block) } menu.findItem(R.id.mute_user)?.apply { @@ -669,14 +666,14 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, when (action) { ACTION_NAVIGATION_PREVIOUS_TAB -> { val previous = viewPager.currentItem - 1 - if (previous >= 0 && previous < pagerAdapter.getCount()) { + if (previous >= 0 && previous < pagerAdapter.count) { viewPager.setCurrentItem(previous, true) } return true } ACTION_NAVIGATION_NEXT_TAB -> { val next = viewPager.currentItem + 1 - if (next >= 0 && next < pagerAdapter.getCount()) { + if (next >= 0 && next < pagerAdapter.count) { viewPager.setCurrentItem(next, true) } return true @@ -859,7 +856,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } R.id.profileBirthdayBanner -> { hideBirthdayView = true - profileBirthdayBanner.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out)) + profileBirthdayBanner.startAnimation(AnimationUtils.loadAnimation(activity, android.R.anim.fade_out)) profileBirthdayBanner.visibility = View.GONE } } @@ -1088,7 +1085,6 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, private fun setFollowEditButton(@DrawableRes icon: Int, @ColorRes color: Int, @StringRes label: Int) { val followButton = followContainer.follow followButton.setImageResource(icon) - ViewCompat.setBackgroundTintMode(followButton, PorterDuff.Mode.SRC_ATOP) val backgroundTintList = ContextCompat.getColorStateList(context!!, color)!! ViewCompat.setBackgroundTintList(followButton, backgroundTintList) ImageViewCompat.setImageTintList(followButton, @@ -1105,7 +1101,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, private fun displayUser(user: ParcelableUser) { val activity = activity ?: return val adapter = pagerAdapter - (0 until adapter.getCount()).forEach { i -> + (0 until adapter.count).forEach { i -> val sf = adapter.instantiateItem(viewPager, i) as? AbsTimelineFragment ?: return@forEach if (sf.view == null) return@forEach } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt index a3727fe27..3f2f163f4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt @@ -54,7 +54,6 @@ import org.mariotaku.twidere.util.TwidereColorUtils import org.mariotaku.twidere.util.qr.QrCodeData import org.mariotaku.uniqr.AndroidPlatform import org.mariotaku.uniqr.UniqR -import java.lang.ref.WeakReference import java.util.concurrent.ExecutionException /** @@ -66,8 +65,9 @@ class UserQrDialogFragment : BaseDialogFragment() { private val user: ParcelableUser get() = arguments!!.user!! - init { - setStyle(STYLE_NO_TITLE, 0) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NO_FRAME, R.style.Theme_Twidere_Dark_Dialog_NoFrame) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { @@ -76,15 +76,19 @@ class UserQrDialogFragment : BaseDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - qrContainer.setAspectRatio(1.0) - val weakThis = WeakReference(this) - + val weakThis by weak(this) + qrShare.setOnClickListener { + shareQrImage() + } + qrSave.setOnClickListener { + saveQrImage() + } promiseOnUi { - val fragment = weakThis.get()?.takeIf { it.view != null } ?: return@promiseOnUi + val fragment = weakThis?.takeIf { it.view != null } ?: return@promiseOnUi fragment.qrView.visibility = View.INVISIBLE fragment.qrProgress.visibility = View.VISIBLE } and loadProfileImage().then { drawable -> - val fragment = weakThis.get()?.takeIf { it.context != null } ?: throw InterruptedException() + val fragment = weakThis?.takeIf { it.context != null } ?: throw InterruptedException() val background = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) val canvas = Canvas(background) @@ -104,7 +108,7 @@ class UserQrDialogFragment : BaseDialogFragment() { background.recycle() return@then result }.successUi { bitmap -> - val fragment = weakThis.get()?.takeIf { it.context != null && it.view != null } ?: return@successUi + val fragment = weakThis?.takeIf { it.context != null && it.view != null } ?: return@successUi fragment.qrView.visibility = View.VISIBLE fragment.qrProgress.visibility = View.GONE fragment.qrView.setImageDrawable(BitmapDrawable(fragment.resources, bitmap).apply { @@ -112,12 +116,19 @@ class UserQrDialogFragment : BaseDialogFragment() { this.isFilterBitmap = false }) }.failUi { - val fragment = weakThis.get()?.takeIf { it.dialog != null } ?: return@failUi + val fragment = weakThis?.takeIf { it.dialog != null } ?: return@failUi Toast.makeText(fragment.context, R.string.message_toast_error_occurred, Toast.LENGTH_SHORT).show() fragment.dismiss() } } + private fun saveQrImage() { + + } + + private fun shareQrImage() { + } + private fun loadProfileImage(): Promise { val activity = this.activity ?: return Promise.ofFail(InterruptedException()) if (isDetached || dialog == null || activity.isFinishing) { @@ -153,18 +164,19 @@ class UserQrDialogFragment : BaseDialogFragment() { return color } - private val Palette.patternColor: Int get() { - var color = getDarkVibrantColor(0) - if (color == 0) { - color = getDominantColor(0) + private val Palette.patternColor: Int + get() { + var color = getDarkVibrantColor(0) + if (color == 0) { + color = getDominantColor(0) + } + if (color == 0) { + color = getDarkMutedColor(0) + } + if (color == 0) { + return Color.BLACK + } + return getOptimalPatternColor(color) } - if (color == 0) { - color = getDarkMutedColor(0) - } - if (color == 0) { - return Color.BLACK - } - return getOptimalPatternColor(color) - } } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersFragment.kt index 6ccda1d4b..e2de23c67 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersFragment.kt @@ -21,13 +21,13 @@ package org.mariotaku.twidere.fragment.filter import android.content.Context import android.database.Cursor -import android.graphics.PorterDuff import android.net.Uri import android.os.Bundle import android.support.v4.app.LoaderManager import android.support.v4.content.ContextCompat import android.support.v4.content.CursorLoader import android.support.v4.content.Loader +import android.support.v4.graphics.drawable.DrawableCompat import android.support.v4.view.ViewCompat import android.support.v4.widget.SimpleCursorAdapter import android.text.SpannableStringBuilder @@ -54,7 +54,6 @@ import org.mariotaku.twidere.fragment.AbsContentListViewFragment import org.mariotaku.twidere.model.FiltersData import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.text.style.EmojiSpan -import org.mariotaku.twidere.util.ThemeUtils abstract class BaseFiltersFragment : AbsContentListViewFragment(), @@ -250,7 +249,6 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment? = null - private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context) override fun swapCursor(c: Cursor?): Cursor? { indices = c?.let { ObjectCursor.indicesFrom(it, FiltersData.BaseItem::class.java) } @@ -267,8 +265,8 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment Boolean)? = null override fun onCreateActionView() = null @@ -54,8 +54,10 @@ class FavoriteItemProvider(context: Context) : ActionProvider(context) { fun init(menuBar: ActionMenuView, item: MenuItem) { assert(MenuItemCompat.getActionProvider(item) === this) val icon = ContextCompat.getDrawable(context, this.icon) - val drawable = LikeAnimationDrawable(icon, - if (useStar) Style.FAVORITE else Style.LIKE) + val drawable = LikeAnimationDrawable(icon, if (useStar) Style.FAVORITE else Style.LIKE) + if (tint != 0) { + DrawableCompat.setTintList(drawable, ContextCompat.getColorStateList(context, tint)) + } drawable.mutate() drawable.callback = ViewCallback(menuBar) item.icon = drawable @@ -69,8 +71,7 @@ class FavoriteItemProvider(context: Context) : ActionProvider(context) { if (MenuItemCompat.getActionProvider(item) !== this) throw IllegalArgumentException() val icon = item.icon if (icon is LikeAnimationDrawable) { - icon.mutate() - icon.setColorFilter(if (isFavorite) activatedColor else defaultColor, PorterDuff.Mode.SRC_ATOP) + icon.isActivated = isFavorite } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileInfo.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileInfo.kt new file mode 100644 index 000000000..19c222450 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileInfo.kt @@ -0,0 +1,45 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.model + +import android.webkit.MimeTypeMap +import java.io.Closeable +import java.io.InputStream +import java.util.* + +interface SaveFileInfo : Closeable { + val name: String + + val mimeType: String? + + val extension: String? + get() { + val typeLowered = mimeType?.toLowerCase(Locale.US) ?: return null + return when (typeLowered) { + // Hack for fanfou image type + "image/jpg" -> "jpg" + else -> MimeTypeMap.getSingleton().getExtensionFromMimeType(typeLowered) + } + } + + val specialCharacter: Char + + fun stream(): InputStream +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileResult.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileResult.kt new file mode 100644 index 000000000..9e1fa1c8f --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/SaveFileResult.kt @@ -0,0 +1,24 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.model + +import java.io.File + +data class SaveFileResult(val savedFile: File, val mimeType: String?) \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/file/SaveFilePromises.java b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/file/SaveFilePromises.java new file mode 100644 index 000000000..77f20d17a --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/file/SaveFilePromises.java @@ -0,0 +1,27 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.promise.file; + +/** + * Created by mariotaku on 2017/12/11. + */ + +public class SaveFilePromises { +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/provider/CacheProvider.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/provider/CacheProvider.kt index 3bbfc9aa9..a5b376ad2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/provider/CacheProvider.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/provider/CacheProvider.kt @@ -16,7 +16,7 @@ import org.mariotaku.twidere.annotation.CacheFileType import org.mariotaku.twidere.dagger.component.GeneralComponent import org.mariotaku.twidere.extension.get import org.mariotaku.twidere.model.CacheMetadata -import org.mariotaku.twidere.task.SaveFileTask +import org.mariotaku.twidere.model.SaveFileInfo import org.mariotaku.twidere.util.JsonSerializer import java.io.ByteArrayInputStream import java.io.FileNotFoundException @@ -106,8 +106,8 @@ class CacheProvider : ContentProvider() { private val context: Context, private val uri: Uri, @CacheFileType override val cacheFileType: String? - ) : SaveFileTask.FileInfo, CacheFileTypeSupport { - override val fileName: String by lazy { + ) : SaveFileInfo, CacheFileTypeSupport { + override val name: String by lazy { var cacheKey = getCacheKey(uri) val indexOfSsp = cacheKey.indexOf("://") if (indexOfSsp != -1) { @@ -128,7 +128,7 @@ class CacheProvider : ContentProvider() { override val specialCharacter: Char get() = '_' - override fun inputStream(): InputStream { + override fun stream(): InputStream { return context.contentResolver.openInputStream(uri) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt index bd1567707..98599df1c 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt @@ -23,6 +23,7 @@ import android.content.Context import android.support.v4.app.DialogFragment import org.mariotaku.twidere.activity.iface.IBaseActivity import org.mariotaku.twidere.fragment.ProgressDialogFragment +import org.mariotaku.twidere.model.SaveFileInfo import java.io.File /** @@ -31,7 +32,7 @@ import java.io.File abstract class ProgressSaveFileTask( context: Context, destination: File, - fileInfo: FileInfo + fileInfo: SaveFileInfo ) : SaveFileTask(context, destination, fileInfo) { override fun showProgress() { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveFileTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveFileTask.kt index 2594a49e3..91dde1076 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveFileTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveFileTask.kt @@ -23,20 +23,18 @@ import android.content.Context import android.os.AsyncTask import android.text.TextUtils.isEmpty import android.util.Log -import android.webkit.MimeTypeMap import org.mariotaku.twidere.TwidereConstants.LOGTAG -import java.io.Closeable +import org.mariotaku.twidere.model.SaveFileInfo +import org.mariotaku.twidere.model.SaveFileResult import java.io.File import java.io.IOException -import java.io.InputStream import java.lang.ref.WeakReference -import java.util.* abstract class SaveFileTask( context: Context, private val destination: File, - private val fileInfo: FileInfo -) : AsyncTask() { + private val fileInfo: SaveFileInfo +) : AsyncTask() { private val contextRef = WeakReference(context) @@ -54,8 +52,8 @@ abstract class SaveFileTask( override fun onPostExecute(result: SaveFileResult?) { dismissProgress() - if (result != null && result.savedFile != null) { - onFileSaved(result.savedFile!!, result.mimeType) + if (result != null) { + onFileSaved(result.savedFile, result.mimeType) } else { onFileSaveFailed() } @@ -74,48 +72,17 @@ abstract class SaveFileTask( protected val context: Context? get() = contextRef.get() - interface FileInfo : Closeable { - val fileName: String? - - val mimeType: String? - - val fileExtension: String? get() { - val typeLowered = mimeType?.toLowerCase(Locale.US) ?: return null - return when (typeLowered) { - // Hack for fanfou image type - "image/jpg" -> "jpg" - else -> MimeTypeMap.getSingleton().getExtensionFromMimeType(typeLowered) - } - } - - val specialCharacter: Char - - fun inputStream(): InputStream - } - - class SaveFileResult(savedFile: File, mimeType: String) { - var savedFile: File? = null - internal set - var mimeType: String - internal set - - init { - this.savedFile = savedFile - this.mimeType = mimeType - } - } - companion object { - fun saveFile(fileInfo: FileInfo, destinationDir: File, requiresValidExtension: Boolean) = try { + fun saveFile(fileInfo: SaveFileInfo, destinationDir: File, requiresValidExtension: Boolean) = try { fileInfo.use { - var name: String = it.fileName ?: return null + var name: String = it.name if (isEmpty(name)) return null if (name.length > 32) { name = name.substring(0, 32) } val mimeType = it.mimeType ?: return null - val extension = it.fileExtension + val extension = it.extension if (requiresValidExtension && extension == null) { return null } @@ -130,7 +97,7 @@ abstract class SaveFileTask( saveFile = File(destinationDir, nameToSave) } saveFile.outputStream().use { output -> - it.inputStream().use { input -> + it.stream().use { input -> input.copyTo(output) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt index 75f44a444..71027a567 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt @@ -23,6 +23,7 @@ import android.app.Activity import android.media.MediaScannerConnection import android.widget.Toast import org.mariotaku.twidere.R +import org.mariotaku.twidere.model.SaveFileInfo import java.io.File /** @@ -30,7 +31,7 @@ import java.io.File */ class SaveMediaToGalleryTask( activity: Activity, - fileInfo: FileInfo, + fileInfo: SaveFileInfo, destination: File ) : ProgressSaveFileTask(activity, destination, fileInfo) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt index 89704c12c..7c989de56 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt @@ -26,12 +26,13 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.content.pm.PackageManager -import android.graphics.PorterDuff +import android.content.res.ColorStateList import android.os.Parcelable import android.support.annotation.UiThread import android.support.v4.app.Fragment import android.support.v4.app.FragmentManager import android.support.v4.content.ContextCompat +import android.support.v4.graphics.drawable.DrawableCompat import android.support.v4.view.MenuItemCompat import android.support.v7.widget.ShareActionProvider import android.util.Log @@ -42,7 +43,6 @@ import android.widget.Toast import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.Bundle import org.mariotaku.ktextension.set -import org.mariotaku.ktextension.setActionIcon import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.microblog.library.mastodon.annotation.StatusVisibility import org.mariotaku.twidere.Constants.* @@ -62,7 +62,6 @@ import org.mariotaku.twidere.fragment.BaseFragment import org.mariotaku.twidere.fragment.SetUserNicknameDialogFragment import org.mariotaku.twidere.fragment.status.* import org.mariotaku.twidere.fragment.timeline.AbsTimelineFragment -import org.mariotaku.twidere.graphic.ActionIconDrawable import org.mariotaku.twidere.graphic.PaddingDrawable import org.mariotaku.twidere.menu.FavoriteItemProvider import org.mariotaku.twidere.menu.SupportStatusShareProvider @@ -72,7 +71,6 @@ import org.mariotaku.twidere.task.CreateFavoriteTask import org.mariotaku.twidere.task.DestroyFavoriteTask import org.mariotaku.twidere.task.DestroyStatusTask import org.mariotaku.twidere.task.RetweetStatusTask -import org.mariotaku.twidere.util.menu.TwidereMenuInfo import java.io.IOException object MenuUtils { @@ -140,47 +138,42 @@ object MenuUtils { when (status.extras?.visibility) { StatusVisibility.PRIVATE -> { - retweet.setActionIcon(context, R.drawable.ic_action_lock) + retweet.setIcon(R.drawable.ic_action_lock) } StatusVisibility.DIRECT -> { - retweet.setActionIcon(context, R.drawable.ic_action_message) retweet.setIcon(R.drawable.ic_action_message) } else -> { - retweet.setActionIcon(context, R.drawable.ic_action_retweet) + retweet.setIcon(R.drawable.ic_action_retweet) } } - + MenuItemCompat.setIconTintList(retweet, if (isMyRetweet) ColorStateList.valueOf(retweetHighlight) else null) retweet.setTitle(if (isMyRetweet) R.string.action_cancel_retweet else R.string.action_retweet) - - ActionIconDrawable.setMenuHighlight(retweet, TwidereMenuInfo(isMyRetweet, retweetHighlight)) } val favorite = menu.findItem(R.id.favorite) if (favorite != null) { - val isFavorite: Boolean - if (CreateFavoriteTask.isRunning(status.account_key, status.id)) { - isFavorite = true - } else if (DestroyFavoriteTask.isRunning(status.account_key, status.id)) { - isFavorite = false - } else { - isFavorite = status.is_favorite + val isFavorite = when { + CreateFavoriteTask.isRunning(status.account_key, status.id) -> true + DestroyFavoriteTask.isRunning(status.account_key, status.id) -> false + else -> status.is_favorite } val provider = MenuItemCompat.getActionProvider(favorite) val useStar = preferences[iWantMyStarsBackKey] if (provider is FavoriteItemProvider) { provider.setIsFavorite(favorite, isFavorite) } else { - if (useStar) { - favorite.setActionIcon(context, R.drawable.ic_action_star) - ActionIconDrawable.setMenuHighlight(favorite, TwidereMenuInfo(isFavorite, favoriteHighlight)) - } else { - ActionIconDrawable.setMenuHighlight(favorite, TwidereMenuInfo(isFavorite, likeHighlight)) - } + MenuItemCompat.setIconTintList(retweet, when { + !isFavorite -> null + useStar -> ColorStateList.valueOf(favoriteHighlight) + else -> ColorStateList.valueOf(likeHighlight) + }) } if (useStar) { favorite.setTitle(if (isFavorite) R.string.action_unfavorite else R.string.action_favorite) + favorite.setIcon(R.drawable.ic_action_star) } else { favorite.setTitle(if (isFavorite) R.string.action_undo_like else R.string.action_like) + favorite.setIcon(R.drawable.ic_action_heart) } } val translate = menu.findItem(R.id.translate) @@ -397,7 +390,7 @@ object MenuUtils { val actionIconColor = ThemeUtils.getThemeForegroundColor(context) if (metaDataDrawable != null) { metaDataDrawable.mutate() - metaDataDrawable.setColorFilter(actionIconColor, PorterDuff.Mode.SRC_ATOP) + DrawableCompat.setTint(metaDataDrawable, actionIconColor) item.icon = metaDataDrawable } else { val icon = info.loadIcon(pm) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ThemeUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ThemeUtils.kt index a5078f170..076ee3ea7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ThemeUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ThemeUtils.kt @@ -25,15 +25,15 @@ import android.content.SharedPreferences import android.content.res.ColorStateList import android.content.res.Resources import android.graphics.Color -import android.graphics.PorterDuff import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.os.Build import android.support.annotation.AttrRes -import android.support.annotation.ColorInt import android.support.annotation.StyleRes import android.support.v4.content.ContextCompat import android.support.v4.graphics.ColorUtils +import android.support.v4.graphics.drawable.DrawableCompat +import android.support.v4.view.MenuItemCompat import android.support.v7.app.TwilightManagerAccessor import android.support.v7.view.menu.ActionMenuItemView import android.support.v7.widget.ActionMenuView @@ -52,10 +52,7 @@ import org.mariotaku.twidere.annotation.ThemeBackgroundOption.MIN_ALPHA import org.mariotaku.twidere.constant.SharedPreferenceConstants.VALUE_THEME_BACKGROUND_SOLID import org.mariotaku.twidere.constant.SharedPreferenceConstants.VALUE_THEME_BACKGROUND_TRANSPARENT import org.mariotaku.twidere.constant.themeColorKey -import org.mariotaku.twidere.graphic.ActionIconDrawable import org.mariotaku.twidere.graphic.WindowBackgroundDrawable -import org.mariotaku.twidere.graphic.iface.DoNotWrapDrawable -import org.mariotaku.twidere.util.menu.TwidereMenuInfo import org.mariotaku.twidere.util.support.ViewSupport object ThemeUtils { @@ -145,7 +142,7 @@ object ThemeUtils { fun wrapMenuIcon(menu: Menu, itemColor: Int, subItemColor: Int, vararg excludeGroups: Int) { for (i in 0 until menu.size()) { val item = menu.getItem(i) - wrapMenuItemIcon(item, itemColor, *excludeGroups) + setTint(item, itemColor, *excludeGroups) if (item.hasSubMenu()) { wrapMenuIcon(item.subMenu, subItemColor, subItemColor, *excludeGroups) } @@ -165,7 +162,7 @@ object ThemeUtils { var k = 0 for (i in 0 until menu.size()) { val item = menu.getItem(i) - wrapMenuItemIcon(item, itemColor, *excludeGroups) + setTint(item, itemColor, *excludeGroups) if (item.hasSubMenu()) { wrapMenuIcon(item.subMenu, popupItemColor, popupItemColor, *excludeGroups) } @@ -181,7 +178,7 @@ object ThemeUtils { var k = 0 for (i in 0 until menu.size()) { val item = menu.getItem(i) - wrapMenuItemIcon(item, itemColor, *excludeGroups) + setTint(item, itemColor, *excludeGroups) if (item.hasSubMenu()) { wrapMenuIcon(item.subMenu, popupItemColor, popupItemColor, *excludeGroups) } @@ -191,24 +188,9 @@ object ThemeUtils { } } - fun wrapMenuItemIcon(item: MenuItem, itemColor: Int, vararg excludeGroups: Int) { + fun setTint(item: MenuItem, itemColor: Int, vararg excludeGroups: Int) { if (item.groupId in excludeGroups) return - val icon = item.icon?.takeUnless { it is DoNotWrapDrawable } ?: return - if (icon is ActionIconDrawable) { - icon.defaultColor = itemColor - item.icon = icon - return - } - icon.mutate() - val callback = icon.callback - val newIcon = ActionIconDrawable(icon, itemColor) - newIcon.callback = callback - item.icon = newIcon - } - - fun getActionIconColor(context: Context): Int { - val itemBackgroundColor = getColorBackground(context) - return getActionIconColor(context, itemBackgroundColor) + MenuItemCompat.setIconTintList(item, ColorStateList.valueOf(itemColor)) } fun getActionIconColor(context: Context, backgroundColor: Int): Int { @@ -354,39 +336,9 @@ object ThemeUtils { if (toolbar is TwidereToolbar) { toolbar.setItemColor(itemColor) } - val overflowIcon = toolbar.overflowIcon - if (overflowIcon != null) { - overflowIcon.setColorFilter(itemColor, PorterDuff.Mode.SRC_ATOP) - toolbar.overflowIcon = overflowIcon - } - } - - fun applyColorFilterToMenuIcon(menu: Menu, @ColorInt color: Int, - @ColorInt popupColor: Int, @ColorInt highlightColor: Int, mode: PorterDuff.Mode, - vararg excludedGroups: Int) { - var i = 0 - val j = menu.size() - while (i < j) { - val item = menu.getItem(i) - val icon = item.icon - val info = item.menuInfo - if (icon != null && item.groupId !in excludedGroups) { - icon.mutate() - if (info is TwidereMenuInfo) { - val sInfo = info - val stateColor = if (sInfo.isHighlight) sInfo.getHighlightColor(highlightColor) else color - if (stateColor != 0) { - icon.setColorFilter(stateColor, mode) - } - } else if (color != 0) { - icon.setColorFilter(color, mode) - } - } - if (item.hasSubMenu()) { - // SubMenu item is always in popup - applyColorFilterToMenuIcon(item.subMenu, popupColor, popupColor, highlightColor, mode, *excludedGroups) - } - i++ + toolbar.overflowIcon = toolbar.overflowIcon?.apply { + mutate() + DrawableCompat.setTint(this, itemColor) } } @@ -394,17 +346,14 @@ object ThemeUtils { val contrastForegroundColor = getColorDependent(toolbarColor) toolbar.setTitleTextColor(contrastForegroundColor) toolbar.setSubtitleTextColor(contrastForegroundColor) - val popupItemColor: Int val popupTheme = toolbar.popupTheme - if (popupTheme != 0) { - popupItemColor = getThemeForegroundColor(context, popupTheme) + val popupItemColor = if (popupTheme != 0) { + getThemeForegroundColor(context, popupTheme) } else { - popupItemColor = getThemeForegroundColor(context) + getThemeForegroundColor(context) } - val navigationIcon = toolbar.navigationIcon - if (navigationIcon != null) { - navigationIcon.setColorFilter(contrastForegroundColor, PorterDuff.Mode.SRC_ATOP) - toolbar.navigationIcon = navigationIcon + toolbar.navigationIcon = toolbar.navigationIcon?.apply { + DrawableCompat.setTint(this, contrastForegroundColor) } getThemeForegroundColor(context) setActionBarOverflowColor(toolbar, contrastForegroundColor) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/ActionIconThemedTextView.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/ActionIconThemedTextView.kt index 9b1cf9a01..7f95de656 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/ActionIconThemedTextView.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/ActionIconThemedTextView.kt @@ -21,7 +21,6 @@ package org.mariotaku.twidere.view import android.annotation.SuppressLint import android.content.Context -import android.graphics.PorterDuff.Mode import android.support.annotation.ColorInt import android.support.v4.widget.TextViewCompat import android.util.AttributeSet @@ -103,7 +102,7 @@ class ActionIconThemedTextView( d.setBounds(left, top, left + iconWidth, top + iconHeight) } - d.setColorFilter(color, Mode.SRC_ATOP) +// d.setColorFilter(color, Mode.SRC_ATOP) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/LabeledImageButton.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/LabeledImageButton.kt index e8194b16d..73fd9bbf7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/LabeledImageButton.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/LabeledImageButton.kt @@ -21,6 +21,7 @@ package org.mariotaku.twidere.view import android.content.Context import android.graphics.Canvas +import android.graphics.ColorFilter import android.graphics.Paint import android.support.annotation.Dimension import android.support.v4.view.ViewCompat @@ -128,6 +129,10 @@ class LabeledImageButton(context: Context, attrs: AttributeSet?) : AppCompatImag textSize = TypedValue.applyDimension(unit, size, resources.displayMetrics) } + override fun setColorFilter(cf: ColorFilter?) { + super.setColorFilter(cf) + } + private fun updateLayout() { val text = this.text if (text == null) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt index 8716e7a81..bc88b7302 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt @@ -23,7 +23,6 @@ import android.content.Context import android.content.SharedPreferences import android.graphics.Rect import android.support.annotation.UiThread -import android.support.v4.content.ContextCompat import android.support.v4.view.ViewCompat import android.support.v7.widget.ActionMenuView import android.support.v7.widget.LinearLayoutManager @@ -43,7 +42,7 @@ import kotlinx.android.synthetic.main.header_status.view.* import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.* import org.mariotaku.microblog.library.twitter.model.TranslationResult -import org.mariotaku.twidere.Constants +import org.mariotaku.twidere.Constants.MENU_GROUP_STATUS_SHARE import org.mariotaku.twidere.R import org.mariotaku.twidere.adapter.BaseRecyclerViewAdapter import org.mariotaku.twidere.adapter.StatusDetailsAdapter @@ -440,13 +439,9 @@ class DetailStatusViewHolder( val favoriteItem = menu.findItem(R.id.favorite) val favoriteProvider = favoriteItem?.supportActionProvider if (favoriteProvider is FavoriteItemProvider) { - val defaultColor = ThemeUtils.getActionIconColor(activity) - favoriteProvider.defaultColor = defaultColor - val favoriteHighlight = ContextCompat.getColor(activity, R.color.highlight_favorite) - val likeHighlight = ContextCompat.getColor(activity, R.color.highlight_like) val useStar = adapter.useStarsForLikes - favoriteProvider.activatedColor = if (useStar) favoriteHighlight else likeHighlight favoriteProvider.icon = if (useStar) R.drawable.ic_action_star else R.drawable.ic_action_heart + favoriteProvider.tint = if (useStar) R.color.btn_tint_favorite_stateful else R.color.btn_tint_like_stateful favoriteProvider.useStar = useStar favoriteProvider.longClickListener = { val status = adapter.getStatus(layoutPosition) @@ -467,7 +462,7 @@ class DetailStatusViewHolder( retweetProvider.init(itemView.menuBar, retweetItem) } - ThemeUtils.wrapMenuIcon(itemView.menuBar, excludeGroups = Constants.MENU_GROUP_STATUS_SHARE) + ThemeUtils.wrapMenuIcon(itemView.menuBar, excludeGroups = *intArrayOf(MENU_GROUP_STATUS_SHARE)) itemView.mediaPreviewLoad.setOnClickListener(this) itemView.profileContainer.setOnClickListener(this) retweetedByView.setOnClickListener(this) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/StatusViewHolder.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/StatusViewHolder.kt index 6f0e6cb2f..a2d51257e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/StatusViewHolder.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/StatusViewHolder.kt @@ -394,6 +394,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter, itemView: View) : replyButton.text = null replyButton.contentDescription = context.getString(R.string.action_reply) } + replyButton.drawable?.mutate() when (status.extras?.visibility) { StatusVisibility.PRIVATE -> { @@ -406,6 +407,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter, itemView: View) : retweetButton.setImageResource(R.drawable.ic_action_retweet) } } + retweetButton.drawable?.mutate() retweetButton.isActivated = isRetweetIconActivated(status) @@ -548,7 +550,6 @@ class StatusViewHolder(private val adapter: IStatusesAdapter, itemView: View) : mediaPreview.style = adapter.mediaPreviewStyle quotedMediaPreview.style = adapter.mediaPreviewStyle - // profileImageView.setStyle(adapter.getProfileImageStyle()); val nameFirst = adapter.nameFirst nameView.nameFirst = nameFirst diff --git a/twidere/src/main/res/color/btn_tint_favorite_stateful.xml b/twidere/src/main/res/color/btn_tint_favorite_stateful.xml index 0907fa9fc..2ecf1a281 100644 --- a/twidere/src/main/res/color/btn_tint_favorite_stateful.xml +++ b/twidere/src/main/res/color/btn_tint_favorite_stateful.xml @@ -20,5 +20,6 @@ + \ No newline at end of file diff --git a/twidere/src/main/res/color/btn_tint_like_stateful.xml b/twidere/src/main/res/color/btn_tint_like_stateful.xml index 07056b3e0..e0335267c 100644 --- a/twidere/src/main/res/color/btn_tint_like_stateful.xml +++ b/twidere/src/main/res/color/btn_tint_like_stateful.xml @@ -20,5 +20,6 @@ + \ No newline at end of file diff --git a/twidere/src/main/res/color/btn_tint_retweet_stateful.xml b/twidere/src/main/res/color/btn_tint_retweet_stateful.xml index f13ea3db8..52b2ba2bd 100644 --- a/twidere/src/main/res/color/btn_tint_retweet_stateful.xml +++ b/twidere/src/main/res/color/btn_tint_retweet_stateful.xml @@ -20,5 +20,6 @@ + \ No newline at end of file diff --git a/twidere/src/main/res/layout/activity_quick_search_bar.xml b/twidere/src/main/res/layout/activity_quick_search_bar.xml index e62fa138d..76e06643e 100644 --- a/twidere/src/main/res/layout/activity_quick_search_bar.xml +++ b/twidere/src/main/res/layout/activity_quick_search_bar.xml @@ -26,7 +26,6 @@ android:layout_height="match_parent" android:padding="@dimen/element_spacing_normal"> - @@ -116,7 +116,6 @@ app:layout_constraintTop_toBottomOf="@+id/text" app:srcCompat="@drawable/ic_action_reply" app:tint="?android:textColorSecondary" - app:tintMode="multiply" tools:text="255"/> . --> - - + tools:layout_gravity="center"> - + + + + + + + + - - + android:gravity="center" + android:orientation="horizontal" + android:paddingBottom="@dimen/element_spacing_xlarge" + android:paddingTop="@dimen/element_spacing_xlarge" + app:layout_constraintTop_toBottomOf="@+id/qrContainer"> - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout/layout_actionbar_message_user_picker.xml b/twidere/src/main/res/layout/layout_actionbar_message_user_picker.xml index 10d115bac..43326c1e6 100644 --- a/twidere/src/main/res/layout/layout_actionbar_message_user_picker.xml +++ b/twidere/src/main/res/layout/layout_actionbar_message_user_picker.xml @@ -63,8 +63,7 @@ android:layout_gravity="end|center_vertical" android:contentDescription="@string/action_search" android:scaleType="centerInside" - android:src="@drawable/ic_action_search" - app:backgroundTintMode="src_atop"/> + android:src="@drawable/ic_action_search"/> \ No newline at end of file diff --git a/twidere/src/main/res/layout/list_item_custom_tab.xml b/twidere/src/main/res/layout/list_item_custom_tab.xml index ad188f268..fc4ea4628 100644 --- a/twidere/src/main/res/layout/list_item_custom_tab.xml +++ b/twidere/src/main/res/layout/list_item_custom_tab.xml @@ -38,14 +38,15 @@ android:layout_weight="0" android:background="@drawable/list_drag_handle"/> - + android:scaleType="fitCenter" + app:tint="?android:colorForeground"/> @@ -411,7 +408,6 @@ android:focusable="false" app:srcCompat="@drawable/ic_action_more_horizontal" app:tint="?android:textColorSecondary" - app:tintMode="multiply" tools:visibility="visible"/> \ No newline at end of file diff --git a/twidere/src/main/res/layout/spinner_item_custom_tab_icon.xml b/twidere/src/main/res/layout/spinner_item_custom_tab_icon.xml index 239de376c..7f87f5114 100644 --- a/twidere/src/main/res/layout/spinner_item_custom_tab_icon.xml +++ b/twidere/src/main/res/layout/spinner_item_custom_tab_icon.xml @@ -20,14 +20,18 @@ - + android:padding="@dimen/element_spacing_small" + app:tint="?android:textColorPrimary" + tools:srcCompat="@drawable/ic_action_twidere"/> \ No newline at end of file diff --git a/twidere/src/main/res/values-notnight/themes_daynight.xml b/twidere/src/main/res/values-notnight/themes_daynight.xml index 938c5580a..467b4b349 100644 --- a/twidere/src/main/res/values-notnight/themes_daynight.xml +++ b/twidere/src/main/res/values-notnight/themes_daynight.xml @@ -13,6 +13,8 @@ + + + + + +