migrating to Glide

This commit is contained in:
Mariotaku Lee 2017-03-01 22:12:25 +08:00
parent 8bfc622b82
commit 097752d30b
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
98 changed files with 566 additions and 859 deletions

View File

@ -138,7 +138,6 @@ dependencies {
compile "com.android.support:design:$android_support_lib_version"
compile "com.android.support:percent:$android_support_lib_version"
compile 'com.twitter:twitter-text:1.14.3'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
compile 'com.squareup:otto:1.3.8'
compile 'dnsjava:dnsjava:2.1.7'
@ -170,6 +169,8 @@ dependencies {
compile 'net.ypresto.androidtranscoder:android-transcoder:0.2.0'
compile "com.google.android.exoplayer:exoplayer:$exoplayer_version"
compile "com.google.android.exoplayer:extension-okhttp:$exoplayer_version"
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'
compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.20'
compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.20'

View File

@ -244,7 +244,7 @@ public abstract class TabConfiguration {
this.view = view;
}
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
public void onActivityResult(@NonNull final TabEditorDialogFragment fragment, int requestCode, int resultCode, @Nullable Intent data) {
}

View File

@ -19,22 +19,14 @@
package org.mariotaku.twidere.util;
import android.graphics.Bitmap;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ProgressBar;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.view.ForegroundImageView;
public class MediaLoadingHandler implements ImageLoadingListener, ImageLoadingProgressListener {
public class MediaLoadingHandler {
private final SparseArray<String> mLoadingUris = new SparseArray<>();
private final int[] mProgressBarIds;
@ -51,66 +43,6 @@ public class MediaLoadingHandler implements ImageLoadingListener, ImageLoadingPr
return mLoadingUris.get(System.identityHashCode(view));
}
@Override
public void onLoadingStarted(final String imageUri, final View view) {
final int viewHashCode = System.identityHashCode(view);
if (view == null || imageUri == null || imageUri.equals(getLoadingUri(view))) return;
ViewGroup parent = (ViewGroup) view.getParent();
if (view instanceof ForegroundImageView) {
ViewSupport.setForeground(view, null);
}
mLoadingUris.put(viewHashCode, imageUri);
final ProgressBar progress = findProgressBar(parent);
if (progress != null) {
progress.setVisibility(View.VISIBLE);
progress.setIndeterminate(true);
progress.setMax(100);
}
}
@Override
public void onLoadingFailed(final String imageUri, final View view, final FailReason reason) {
if (view == null) return;
mLoadingUris.remove(System.identityHashCode(view));
final ProgressBar progress = findProgressBar(view.getParent());
if (progress != null) {
progress.setVisibility(View.GONE);
}
}
@Override
public void onLoadingComplete(final String imageUri, final View view, final Bitmap bitmap) {
if (view == null) return;
mLoadingUris.remove(System.identityHashCode(view));
final ViewGroup parent = (ViewGroup) view.getParent();
final ProgressBar progress = findProgressBar(parent);
if (progress != null) {
progress.setVisibility(View.GONE);
}
}
@Override
public void onLoadingCancelled(final String imageUri, final View view) {
final int viewHashCode = System.identityHashCode(view);
if (view == null || imageUri == null || imageUri.equals(getLoadingUri(view))) return;
mLoadingUris.remove(viewHashCode);
final ProgressBar progress = findProgressBar(view.getParent());
if (progress != null) {
progress.setVisibility(View.GONE);
}
}
@Override
public void onProgressUpdate(final String imageUri, final View view, final int current,
final int total) {
if (total == 0 || view == null) return;
final ProgressBar progress = findProgressBar(view.getParent());
if (progress != null) {
progress.setIndeterminate(false);
progress.setProgress(100 * current / total);
}
}
private ProgressBar findProgressBar(final ViewParent viewParent) {
if (mProgressBarIds == null || !(viewParent instanceof View)) return null;
final View parent = (View) viewParent;

View File

@ -1,56 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 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.imageloader;
import android.support.v7.widget.RecyclerView;
import com.nostra13.universalimageloader.core.ImageLoader;
public class PauseRecyclerViewOnScrollListener extends RecyclerView.OnScrollListener {
private ImageLoader imageLoader;
private final boolean pauseOnScroll;
private final boolean pauseOnFling;
public PauseRecyclerViewOnScrollListener(ImageLoader imageLoader, boolean pauseOnScroll, boolean pauseOnFling) {
this.imageLoader = imageLoader;
this.pauseOnScroll = pauseOnScroll;
this.pauseOnFling = pauseOnFling;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
switch (newState) {
case RecyclerView.SCROLL_STATE_IDLE:
this.imageLoader.resume();
break;
case RecyclerView.SCROLL_STATE_DRAGGING:
if (this.pauseOnScroll) {
this.imageLoader.pause();
}
break;
case RecyclerView.SCROLL_STATE_SETTLING:
if (this.pauseOnFling) {
this.imageLoader.pause();
}
break;
}
}
}

View File

@ -1,70 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 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.imageloader;
import android.graphics.Bitmap;
import com.nostra13.universalimageloader.cache.disc.impl.BaseDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.utils.IoUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by mariotaku on 15/8/28.
*/
public class ReadOnlyDiskLRUNameCache extends BaseDiskCache {
public ReadOnlyDiskLRUNameCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator) {
super(cacheDir, reserveCacheDir, fileNameGenerator);
}
@Override
public boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException {
return false;
}
@Override
public boolean save(String imageUri, Bitmap bitmap) throws IOException {
return false;
}
@Override
public boolean remove(String imageUri) {
return false;
}
@Override
public void clear() {
// No-op
}
@Override
protected File getFile(String imageUri) {
String fileName = fileNameGenerator.generate(imageUri) + ".0";
File dir = cacheDir;
if (!cacheDir.exists() && (!cacheDir.mkdirs()) &&
(reserveCacheDir != null) && (reserveCacheDir.exists() || reserveCacheDir.mkdirs())) {
dir = reserveCacheDir;
}
return new File(dir, fileName);
}
}

View File

@ -1,75 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 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.imageloader;
import android.content.Context;
import android.text.TextUtils;
import com.nostra13.universalimageloader.core.assist.ContentLengthInputStream;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import org.mariotaku.mediaviewer.library.CacheDownloadLoader;
import org.mariotaku.mediaviewer.library.MediaDownloader;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
public class TwidereImageDownloader extends BaseImageDownloader {
private final MediaDownloader mMediaDownloader;
private final String mTwitterProfileImageSize;
public TwidereImageDownloader(final Context context, MediaDownloader downloader) {
super(context);
mMediaDownloader = downloader;
mTwitterProfileImageSize = context.getString(R.string.profile_image_size);
}
@Override
protected InputStream getStreamFromNetwork(String uriString, final Object extras) throws IOException {
if (uriString == null) return null;
try {
if (isTwitterProfileImage(uriString)) {
uriString = Utils.getTwitterProfileImageOfSize(uriString, mTwitterProfileImageSize);
}
return getStreamFromNetworkInternal(uriString, extras);
} catch (final FileNotFoundException e) {
if (isTwitterProfileImage(uriString) && !uriString.contains("_normal.")) {
return getStreamFromNetworkInternal(Utils.getNormalTwitterProfileImage(uriString), extras);
}
throw new IOException(String.format(Locale.US, "Error downloading image %s", uriString));
}
}
private ContentLengthInputStream getStreamFromNetworkInternal(final String uriString, final Object extras) throws IOException {
CacheDownloadLoader.DownloadResult result = mMediaDownloader.get(uriString, extras);
return new ContentLengthInputStream(result.getStream(), (int) result.getLength());
}
private boolean isTwitterProfileImage(final String uriString) {
return !TextUtils.isEmpty(uriString) && TwidereLinkify.PATTERN_TWITTER_PROFILE_IMAGES.matcher(uriString).matches();
}
}

View File

@ -1,43 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 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.imageloader;
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
public class URLFileNameGenerator implements FileNameGenerator {
private final Md5FileNameGenerator mGenerator;
public URLFileNameGenerator() {
mGenerator = new Md5FileNameGenerator();
}
@Override
public String generate(String imageUri) {
if (imageUri == null) return null;
int start = imageUri.indexOf("://");
if (start == -1) {
return mGenerator.generate(imageUri);
}
return mGenerator.generate(imageUri.substring(start + 3));
}
}

View File

@ -1,63 +0,0 @@
package org.mariotaku.twidere.util.media;
import android.net.Uri;
import android.support.annotation.NonNull;
import com.nostra13.universalimageloader.cache.disc.DiskCache;
import com.nostra13.universalimageloader.utils.IoUtils;
import org.mariotaku.mediaviewer.library.FileCache;
import org.mariotaku.twidere.provider.CacheProvider;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by mariotaku on 16/1/20.
*/
public class UILFileCache implements FileCache {
private final DiskCache cache;
public UILFileCache(final DiskCache cache) {
this.cache = cache;
}
@Override
public File get(@NonNull final String key) {
return cache.get(key);
}
@Override
public void remove(@NonNull final String key) {
cache.remove(key);
}
@Override
public void save(@NonNull final String key, @NonNull final InputStream is, byte[] extra,
final CopyListener listener) throws IOException {
cache.save(key, is, new IoUtils.CopyListener() {
@Override
public boolean onBytesCopied(final int current, final int total) {
return listener == null || listener.onCopied(current);
}
});
if (extra != null) {
cache.save(CacheProvider.Companion.getExtraKey(key), new ByteArrayInputStream(extra), null);
}
}
@NonNull
@Override
public Uri toUri(@NonNull final String key) {
return CacheProvider.Companion.getCacheUri(key, null);
}
@NonNull
@Override
public String fromUri(@NonNull final Uri uri) {
return CacheProvider.Companion.getCacheKey(uri);
}
}

View File

@ -5,7 +5,7 @@ package android.support.v4.app
*/
fun LoaderManager.hasRunningLoadersSafe(): Boolean {
if (!(this is LoaderManagerImpl)) return false
if (this !is LoaderManagerImpl) return false
var loadersRunning = false
val count = mLoaders.size()
for (i in 0 until count) {

View File

@ -28,6 +28,7 @@ import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import android.widget.Toast
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_account_selector.*
import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.twidere.R
@ -89,7 +90,7 @@ class AccountSelectorActivity : BaseActivity(), OnItemClickListener {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_account_selector)
DataStoreUtils.prepareDatabase(this)
adapter = AccountDetailsAdapter(this).apply {
adapter = AccountDetailsAdapter(this, { Glide.with(this) }).apply {
setSwitchEnabled(!isSingleSelection)
setSortEnabled(false)
val am = AccountManager.get(context)

View File

@ -55,6 +55,7 @@ import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
import android.widget.TextView
import android.widget.Toast
import com.bumptech.glide.Glide
import com.twitter.Extractor
import com.twitter.Validator
import kotlinx.android.synthetic.main.activity_compose.*
@ -74,6 +75,7 @@ import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_SCREEN_NAME
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.model.getAccountUser
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.extension.model.textLimit
import org.mariotaku.twidere.extension.model.unique_id_non_null
import org.mariotaku.twidere.fragment.BaseDialogFragment
@ -465,7 +467,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
accountProfileImage.setBorderColor(account.color)
} else {
accountsCount.setText(accounts.size.toString())
mediaLoader.cancelDisplayTask(accountProfileImage)
//TODO cancel image load
accountProfileImage.setImageDrawable(null)
accountProfileImage.setBorderColors(*Utils.getAccountColors(accounts))
}
@ -483,7 +485,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
nameFirst = preferences[nameFirstKey]
setContentView(R.layout.activity_compose)
mediaPreviewAdapter = MediaPreviewAdapter(this)
mediaPreviewAdapter = MediaPreviewAdapter(this, { Glide.with(this) })
mediaPreviewAdapter.listener = object : MediaPreviewAdapter.Listener {
override fun onEditClick(position: Int, holder: MediaPreviewViewHolder) {
attachedMediaPreview.showContextMenuForChild(holder.itemView)
@ -1421,10 +1423,9 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
fun showAccount(adapter: AccountIconsAdapter, account: AccountDetails, isSelected: Boolean) {
itemView.alpha = if (isSelected) 1f else 0.33f
(itemView as CheckableLinearLayout).isChecked = isSelected
val loader = adapter.imageLoader
if (ObjectUtils.notEqual(account, iconView.tag) || iconView.drawable == null) {
if (account != iconView.tag || iconView.drawable == null) {
iconView.tag = account
loader.displayProfileImage(iconView, account.user)
adapter.getRequestManager().load(account.user.getBestProfileImage(adapter.context)).into(iconView)
}
iconView.setBorderColor(account.color)
nameView.text = if (adapter.isNameFirst) account.user.name else "@" + account.user.screen_name
@ -1438,7 +1439,9 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
internal class AccountIconsAdapter(private val activity: ComposeActivity) : BaseRecyclerViewAdapter<AccountIconViewHolder>(activity) {
internal class AccountIconsAdapter(
private val activity: ComposeActivity
) : BaseRecyclerViewAdapter<AccountIconViewHolder>(activity, { Glide.with(activity) }) {
private val inflater: LayoutInflater = activity.layoutInflater
private val selection: MutableMap<UserKey, Boolean> = HashMap()
val isNameFirst: Boolean = preferences[nameFirstKey]
@ -1449,9 +1452,6 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
setHasStableIds(true)
}
val imageLoader: MediaLoaderWrapper
get() = mediaLoader
override fun getItemId(position: Int): Long {
return accounts!![position].hashCode().toLong()
}

View File

@ -12,6 +12,8 @@ import android.view.*
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestManager
import kotlinx.android.synthetic.main.activity_premium_dashboard.*
import kotlinx.android.synthetic.main.card_item_extra_feature.view.*
import nl.komponents.kovenant.task
@ -40,7 +42,7 @@ class PremiumDashboardActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_premium_dashboard)
adapter = ControllersAdapter(this)
adapter = ControllersAdapter(this, { Glide.with(this) })
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
if (extraFeaturesService.isSupported()) {
@ -185,7 +187,10 @@ class PremiumDashboardActivity : BaseActivity() {
}
class ControllersAdapter(context: Context) : BaseRecyclerViewAdapter<ControllerViewHolder>(context) {
class ControllersAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : BaseRecyclerViewAdapter<ControllerViewHolder>(context, getRequestManager) {
var controllers: List<Class<out ContainerView.ViewController>>? = null
set(value) {

View File

@ -37,6 +37,7 @@ import android.view.View.OnClickListener
import android.widget.*
import android.widget.AdapterView.OnItemClickListener
import android.widget.AdapterView.OnItemSelectedListener
import com.bumptech.glide.Glide
import jopt.csp.util.SortableIntList
import kotlinx.android.synthetic.main.activity_quick_search_bar.*
import org.mariotaku.kpreferences.get
@ -171,7 +172,8 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
setContentView(R.layout.activity_quick_search_bar)
val am = AccountManager.get(this)
val accounts = AccountUtils.getAllAccountDetails(am, AccountUtils.getAccounts(am), true).toList()
val accountsSpinnerAdapter = AccountsSpinnerAdapter(this, R.layout.spinner_item_account_icon)
val accountsSpinnerAdapter = AccountsSpinnerAdapter(this, R.layout.spinner_item_account_icon,
getRequestManager = { Glide.with(this) })
accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_simple_user)
accountsSpinnerAdapter.addAll(accounts)
accountSpinner.adapter = accountsSpinnerAdapter
@ -324,7 +326,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
holder.text1.text = "@${cursor.getString(indices.title)}"
holder.text2.visibility = View.GONE
holder.icon.setColorFilter(holder.text1.currentTextColor, Mode.SRC_ATOP)
mediaLoader.cancelDisplayTask(holder.icon)
//TODO cancel image load
holder.icon.setImageResource(R.drawable.ic_action_user)
}
}

View File

@ -28,6 +28,7 @@ import android.support.v4.content.Loader
import android.view.View
import android.widget.AdapterView.OnItemClickListener
import android.widget.TextView
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.layout_list_with_empty_view.*
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.set
@ -69,7 +70,7 @@ class UserListSelectorActivity : BaseActivity(),
}
setContentView(R.layout.activity_user_list_selector)
adapter = SimpleParcelableUserListsAdapter(this)
adapter = SimpleParcelableUserListsAdapter(this, { Glide.with(this) })
adapter.loadMoreSupportedPosition = ILoadMoreSupportAdapter.END
listView.addFooterView(layoutInflater.inflate(R.layout.simple_list_item_activated_1,
listView, false).apply {

View File

@ -29,6 +29,7 @@ import android.view.View
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_user_selector.*
import kotlinx.android.synthetic.main.layout_list_with_empty_view.*
import org.mariotaku.ktextension.Bundle
@ -88,7 +89,7 @@ class UserSelectorActivity : BaseActivity(), OnItemClickListener, LoaderManager.
if (savedInstanceState == null) {
editScreenName.setText(intent.getStringExtra(EXTRA_SCREEN_NAME))
}
adapter = SimpleParcelableUsersAdapter(this)
adapter = SimpleParcelableUsersAdapter(this, getRequestManager = { Glide.with(this) })
listView.adapter = adapter
listView.onItemClickListener = this

View File

@ -23,14 +23,19 @@ import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.view.holder.AccountViewHolder
class AccountDetailsAdapter(context: Context) : BaseArrayAdapter<AccountDetails>(context, R.layout.list_item_account) {
class AccountDetailsAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : BaseArrayAdapter<AccountDetails>(context, R.layout.list_item_account, getRequestManager = getRequestManager) {
private var sortEnabled: Boolean = false
private var switchEnabled: Boolean = false
@ -57,9 +62,9 @@ class AccountDetailsAdapter(context: Context) : BaseArrayAdapter<AccountDetails>
holder.screenName.text = String.format("@%s", details.user.screen_name)
holder.setAccountColor(details.color)
if (profileImageEnabled) {
mediaLoader.displayProfileImage(holder.profileImage, details.user)
getRequestManager().load(details.user.getBestProfileImage(context)).into(holder.profileImage)
} else {
mediaLoader.cancelDisplayTask(holder.profileImage)
// TODO: display stub image?
}
val accountType = details.type
holder.accountType.setImageResource(AccountUtils.getAccountTypeIcon(accountType))

View File

@ -23,22 +23,22 @@ import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import kotlinx.android.synthetic.main.list_item_simple_user.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
class AccountsSpinnerAdapter(
context: Context,
itemViewResource: Int = R.layout.list_item_simple_user
) : BaseArrayAdapter<AccountDetails>(context, itemViewResource) {
itemViewResource: Int = R.layout.list_item_simple_user,
accounts: Collection<AccountDetails>? = null,
getRequestManager: () -> RequestManager
) : BaseArrayAdapter<AccountDetails>(context, itemViewResource, accounts, getRequestManager) {
private var dummyItemText: String? = null
constructor(context: Context, accounts: Collection<AccountDetails>) : this(context) {
addAll(accounts)
}
override fun getItemId(position: Int): Long {
return getItem(position).hashCode().toLong()
}
@ -69,10 +69,9 @@ class AccountsSpinnerAdapter(
if (profileImageEnabled) {
icon.visibility = View.VISIBLE
icon.style = profileImageStyle
mediaLoader.displayProfileImage(icon, item.user)
getRequestManager().load(item.user.getBestProfileImage(context)).into(icon)
} else {
icon.visibility = View.GONE
mediaLoader.cancelDisplayTask(icon)
}
}
} else {

View File

@ -2,12 +2,16 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.support.v7.widget.RecyclerView.ViewHolder
import com.bumptech.glide.RequestManager
import java.util.*
/**
* Created by mariotaku on 14/10/27.
*/
abstract class ArrayRecyclerAdapter<T, H : ViewHolder>(context: Context) : BaseRecyclerViewAdapter<H>(context) {
abstract class ArrayRecyclerAdapter<T, H : ViewHolder>(
context: Context,
getRequestManager: () -> RequestManager
) : BaseRecyclerViewAdapter<H>(context, getRequestManager) {
protected val data = ArrayList<T>()

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.support.v4.text.BidiFormatter
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.adapter.iface.IContentAdapter
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
@ -34,7 +35,8 @@ import javax.inject.Inject
open class BaseArrayAdapter<T>(
context: Context,
layoutRes: Int,
collection: Collection<T>? = null
collection: Collection<T>? = null,
override val getRequestManager: () -> RequestManager
) : ArrayAdapter<T>(context, layoutRes, collection), IContentAdapter, ILoadMoreSupportAdapter,
IItemCountsAdapter {
val linkify: TwidereLinkify
@ -42,8 +44,6 @@ open class BaseArrayAdapter<T>(
@Inject
override lateinit var userColorNameManager: UserColorNameManager
@Inject
override lateinit var mediaLoader: MediaLoaderWrapper
@Inject
override lateinit var bidiFormatter: BidiFormatter
@Inject
override lateinit var twitterWrapper: AsyncTwitterWrapper

View File

@ -22,6 +22,7 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.support.v4.text.BidiFormatter
import android.support.v7.widget.RecyclerView
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.adapter.iface.IContentAdapter
import org.mariotaku.twidere.constant.displayProfileImageKey
@ -37,12 +38,13 @@ import javax.inject.Inject
* Created by mariotaku on 15/10/5.
*/
abstract class BaseRecyclerViewAdapter<VH : RecyclerView.ViewHolder>(
val context: Context
val context: Context,
override val getRequestManager: () -> RequestManager
) : RecyclerView.Adapter<VH>(), IContentAdapter {
@Inject
override final lateinit var twitterWrapper: AsyncTwitterWrapper
@Inject
override final lateinit var mediaLoader: MediaLoaderWrapper
@Inject
override final lateinit var userColorNameManager: UserColorNameManager
@Inject

View File

@ -79,7 +79,7 @@ class ComposeAutoCompleteAdapter(context: Context) : SimpleCursorAdapter(context
val profileImageUrl = cursor.getString(indices.icon)
mediaLoader.displayProfileImage(icon, profileImageUrl)
} else {
mediaLoader.cancelDisplayTask(icon)
//TODO cancel image load
}
icon.clearColorFilter()

View File

@ -24,6 +24,7 @@ import android.database.Cursor
import android.support.v4.widget.SimpleCursorAdapter
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.mediaPreviewStyleKey
@ -37,7 +38,10 @@ import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.view.holder.DraftViewHolder
import javax.inject.Inject
class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.list_item_draft, null, arrayOfNulls<String>(0), IntArray(0), 0) {
class DraftsAdapter(
context: Context,
val getRequestManager: () -> RequestManager
) : SimpleCursorAdapter(context, R.layout.list_item_draft, null, arrayOfNulls<String>(0), IntArray(0), 0) {
@Inject
lateinit var imageLoader: MediaLoaderWrapper
@ -73,8 +77,8 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
Draft.Action.UPDATE_STATUS_COMPAT_2, Draft.Action.REPLY, Draft.Action.QUOTE -> {
val media = ParcelableMediaUtils.fromMediaUpdates(draft.media)
holder.mediaPreviewContainer.visibility = View.VISIBLE
holder.mediaPreviewContainer.displayMedia(loader = imageLoader, media = media,
loadingHandler = mediaLoadingHandler)
holder.mediaPreviewContainer.displayMedia(getRequestManager = getRequestManager,
media = media, loadingHandler = mediaLoadingHandler)
}
Draft.Action.FAVORITE, Draft.Action.RETWEET -> {
val extras = draft.action_extras as? StatusObjectExtras

View File

@ -3,6 +3,7 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.support.v4.text.BidiFormatter
import android.support.v7.widget.RecyclerView
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IGapSupportedAdapter
@ -20,17 +21,16 @@ import javax.inject.Inject
/**
* Created by mariotaku on 16/1/22.
*/
class DummyItemAdapter @JvmOverloads constructor(
class DummyItemAdapter(
val context: Context,
override val twidereLinkify: TwidereLinkify = TwidereLinkify(null),
private val adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>? = null
private val adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>? = null,
override val getRequestManager: () -> RequestManager
) : IStatusesAdapter<Any>, IUsersAdapter<Any>, IUserListsAdapter<Any> {
@Inject
lateinit var preferences: SharedPreferencesWrapper
@Inject
override lateinit var mediaLoader: MediaLoaderWrapper
@Inject
override lateinit var twitterWrapper: AsyncTwitterWrapper
@Inject
override lateinit var userColorNameManager: UserColorNameManager

View File

@ -23,12 +23,16 @@ import android.content.Context
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.loader.ExtensionsListLoader.ExtensionInfo
import org.mariotaku.twidere.util.PermissionsManager
import org.mariotaku.twidere.view.holder.TwoLineWithIconViewHolder
class ExtensionsAdapter(context: Context) : BaseArrayAdapter<ExtensionInfo>(context, R.layout.list_item_two_line) {
class ExtensionsAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : BaseArrayAdapter<ExtensionInfo>(context, R.layout.list_item_two_line, getRequestManager = getRequestManager) {
override fun getItemId(position: Int): Long {
return getItem(position).hashCode().toLong()

View File

@ -3,6 +3,7 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
import org.mariotaku.twidere.view.holder.StatusViewHolder
@ -11,7 +12,10 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
/**
* Created by mariotaku on 14/11/19.
*/
class ListParcelableStatusesAdapter(context: Context) : ParcelableStatusesAdapter(context) {
class ListParcelableStatusesAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : ParcelableStatusesAdapter(context, getRequestManager) {
override val progressViewIds: IntArray
get() = intArrayOf(R.id.media_preview_progress)
@ -23,7 +27,7 @@ class ListParcelableStatusesAdapter(context: Context) : ParcelableStatusesAdapte
companion object {
fun createStatusViewHolder(adapter: IStatusesAdapter<*>,
inflater: LayoutInflater, parent: ViewGroup): StatusViewHolder {
inflater: LayoutInflater, parent: ViewGroup): StatusViewHolder {
val view = inflater.inflate(StatusViewHolder.layoutResource, parent, false)
val holder = StatusViewHolder(adapter, view)
holder.setOnClickListeners()

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.support.v7.widget.RecyclerView.ViewHolder
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
@ -28,8 +29,10 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
/**
* Created by mariotaku on 15/4/16.
*/
abstract class LoadMoreSupportAdapter<VH : ViewHolder>(context: Context) :
BaseRecyclerViewAdapter<VH>(context), ILoadMoreSupportAdapter {
abstract class LoadMoreSupportAdapter<VH : ViewHolder>(
context: Context,
getRequestManager: () -> RequestManager
) : BaseRecyclerViewAdapter<VH>(context, getRequestManager), ILoadMoreSupportAdapter {
@IndicatorPosition
override var loadMoreSupportedPosition: Long = 0

View File

@ -23,6 +23,7 @@ import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.model.ParcelableMediaUpdate
import org.mariotaku.twidere.view.helper.SimpleItemTouchHelperCallback
@ -31,8 +32,9 @@ import org.mariotaku.twidere.view.holder.compose.MediaPreviewViewHolder
import java.util.*
class MediaPreviewAdapter(
context: Context
) : ArrayRecyclerAdapter<ParcelableMediaUpdate, MediaPreviewViewHolder>(context) {
context: Context,
getRequestManager: () -> RequestManager
) : ArrayRecyclerAdapter<ParcelableMediaUpdate, MediaPreviewViewHolder>(context, getRequestManager) {
private val inflater = LayoutInflater.from(context)
val touchAdapter: ItemTouchHelperAdapter = object : ItemTouchHelperAdapter {

View File

@ -24,6 +24,7 @@ import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.apache.commons.lang3.time.DateUtils
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
@ -46,7 +47,10 @@ import org.mariotaku.twidere.view.holder.message.NoticeSummaryEventViewHolder
import org.mariotaku.twidere.view.holder.message.StickerMessageViewHolder
import java.util.*
class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
class MessagesConversationAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager),
IItemCountsAdapter {
private val calendars = Pair(Calendar.getInstance(), Calendar.getInstance())
override val itemCounts: ItemCounts = ItemCounts(2)

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
@ -17,7 +18,10 @@ import org.mariotaku.twidere.view.holder.message.MessageEntryViewHolder
* Created by mariotaku on 2017/2/9.
*/
class MessagesEntriesAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
class MessagesEntriesAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager),
IItemCountsAdapter {
override val itemCounts: ItemCounts = ItemCounts(2)

View File

@ -26,6 +26,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.bumptech.glide.RequestManager
import org.apache.commons.lang3.ArrayUtils
import org.mariotaku.ktextension.rangeOfSize
import org.mariotaku.ktextension.safeMoveToPosition
@ -55,14 +56,15 @@ import java.util.*
* Created by mariotaku on 15/1/3.
*/
class ParcelableActivitiesAdapter(
context: Context
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context), IActivitiesAdapter<List<ParcelableActivity>> {
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager), IActivitiesAdapter<List<ParcelableActivity>> {
override val mediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
private val inflater = LayoutInflater.from(context)
private val statusAdapterDelegate = DummyItemAdapter(context,
TwidereLinkify(OnLinkClickHandler(context, null, preferences)), this)
private val twidereLinkify = TwidereLinkify(OnLinkClickHandler(context, null, preferences))
private val statusAdapterDelegate = DummyItemAdapter(context, twidereLinkify, this, getRequestManager)
private val eventListener: EventListener
private var data: List<ParcelableActivity>? = null
private var activityAdapterListener: ActivityAdapterListener? = null

View File

@ -24,8 +24,8 @@ import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
@ -35,21 +35,22 @@ import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.view.holder.GroupViewHolder
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
class ParcelableGroupsAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context), Constants, IGroupsAdapter<List<ParcelableGroup>> {
class ParcelableGroupsAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager), IGroupsAdapter<List<ParcelableGroup>> {
override val showAccountsColor: Boolean
get() = false
override val nameFirst: Boolean
override val nameFirst = preferences[nameFirstKey]
override var groupAdapterListener: IGroupsAdapter.GroupAdapterListener? = null
private val inflater: LayoutInflater
private val mEventListener: EventListener
private val inflater = LayoutInflater.from(context)
private val eventListener: EventListener
private var data: List<ParcelableGroup>? = null
init {
mEventListener = EventListener(this)
inflater = LayoutInflater.from(context)
nameFirst = preferences[nameFirstKey]
eventListener = EventListener(this)
}
fun getData(): List<ParcelableGroup>? {

View File

@ -25,6 +25,7 @@ import android.support.v4.widget.Space
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.findPositionByItemId
import org.mariotaku.ktextension.rangeOfSize
@ -55,8 +56,9 @@ import java.util.*
* Created by mariotaku on 15/10/26.
*/
abstract class ParcelableStatusesAdapter(
context: Context
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context), IStatusesAdapter<List<ParcelableStatus>>,
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager), IStatusesAdapter<List<ParcelableStatus>>,
IItemCountsAdapter {
protected val inflater: LayoutInflater = LayoutInflater.from(context)

View File

@ -23,6 +23,7 @@ import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
@ -34,8 +35,8 @@ import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
import org.mariotaku.twidere.view.holder.UserListViewHolder
class ParcelableUserListsAdapter(
context: Context
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context), IUserListsAdapter<List<ParcelableUserList>> {
context: Context, getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager), IUserListsAdapter<List<ParcelableUserList>> {
override val showAccountsColor: Boolean = false
override val nameFirst: Boolean = preferences[nameFirstKey]
override var userListClickListener: IUserListsAdapter.UserListClickListener? = null

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import org.mariotaku.twidere.Constants
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.Companion.ITEM_VIEW_TYPE_LOAD_INDICATOR
@ -33,8 +33,11 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
import org.mariotaku.twidere.view.holder.UserViewHolder
class ParcelableUsersAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context), Constants, IUsersAdapter<List<ParcelableUser>> {
private val inflater: LayoutInflater
class ParcelableUsersAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager), IUsersAdapter<List<ParcelableUser>> {
private val inflater = LayoutInflater.from(context)
private var data: List<ParcelableUser>? = null
override val showAccountsColor: Boolean = false
@ -43,10 +46,6 @@ class ParcelableUsersAdapter(context: Context) : LoadMoreSupportAdapter<Recycler
override var friendshipClickListener: IUsersAdapter.FriendshipClickListener? = null
override var simpleLayout: Boolean = false
init {
inflater = LayoutInflater.from(context)
}
fun getData(): List<ParcelableUser>? {
return data
}

View File

@ -24,6 +24,7 @@ import android.support.v4.util.ArrayMap
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
@ -33,7 +34,10 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
import org.mariotaku.twidere.view.holder.SelectableUserViewHolder
class SelectableUsersAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context),
class SelectableUsersAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager),
IItemCountsAdapter {
val ITEM_VIEW_TYPE_USER = 2

View File

@ -22,16 +22,19 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.extension.view.holder.display
import org.mariotaku.twidere.model.ItemCounts
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.extension.view.holder.display
import org.mariotaku.twidere.view.holder.SimpleUserListViewHolder
class SimpleParcelableUserListsAdapter(
context: Context
) : BaseArrayAdapter<ParcelableUserList>(context, R.layout.list_item_simple_user_list) {
context: Context,
getRequestManager: () -> RequestManager
) : BaseArrayAdapter<ParcelableUserList>(context, R.layout.list_item_simple_user_list,
getRequestManager = getRequestManager) {
override val itemCounts: ItemCounts = ItemCounts(2)
@ -57,7 +60,7 @@ class SimpleParcelableUserListsAdapter(
return@run h
}
val userList = getItem(position)
holder.display(userList, mediaLoader, userColorNameManager, profileImageEnabled)
holder.display(userList, getRequestManager, userColorNameManager, profileImageEnabled)
return view
}
1 -> {

View File

@ -22,6 +22,7 @@ package org.mariotaku.twidere.adapter
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
@ -29,8 +30,9 @@ import org.mariotaku.twidere.view.holder.SimpleUserViewHolder
class SimpleParcelableUsersAdapter(
context: Context,
layoutRes: Int = R.layout.list_item_simple_user
) : BaseArrayAdapter<ParcelableUser>(context, layoutRes) {
layoutRes: Int = R.layout.list_item_simple_user,
getRequestManager: () -> RequestManager
) : BaseArrayAdapter<ParcelableUser>(context, layoutRes, getRequestManager = getRequestManager) {
override fun getItemId(position: Int): Long {
val item = getItem(position)

View File

@ -25,9 +25,11 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.RequestManager
import com.commonsware.cwac.layouts.AspectLockedFrameLayout
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.ParcelableStatus
@ -39,7 +41,10 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
/**
* Created by mariotaku on 14/11/19.
*/
class StaggeredGridParcelableStatusesAdapter(context: Context) : ParcelableStatusesAdapter(context) {
class StaggeredGridParcelableStatusesAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : ParcelableStatusesAdapter(context, getRequestManager) {
override val progressViewIds: IntArray
get() = intArrayOf(R.id.media_image_progress)
@ -74,7 +79,6 @@ class StaggeredGridParcelableStatusesAdapter(context: Context) : ParcelableStatu
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
displayExtraType: Boolean, displayPinned: Boolean) {
val loader = adapter.mediaLoader
val media = status.media ?: return
if (media.isEmpty()) return
val firstMedia = media[0]
@ -88,9 +92,9 @@ class StaggeredGridParcelableStatusesAdapter(context: Context) : ParcelableStatu
mediaImageContainer.requestLayout()
mediaImageView.setHasPlayIcon(ParcelableMediaUtils.hasPlayIcon(firstMedia.type))
loader.displayProfileImage(profileImageView, status)
loader.displayPreviewImageWithCredentials(mediaImageView, firstMedia.preview_url,
status.account_key, adapter.mediaLoadingHandler)
adapter.getRequestManager().load(status.getBestProfileImage(itemView.context)).into(profileImageView)
// TODO image loaded event and credentials
adapter.getRequestManager().load(firstMedia.preview_url).into(mediaImageView)
}
override val profileTypeView: ImageView?

View File

@ -85,7 +85,7 @@ class UserAutoCompleteAdapter(val context: Context) : SimpleCursorAdapter(contex
val profileImageUrl = cursor.getString(indices.profile_image_url)
profileImageLoader.displayProfileImage(icon, profileImageUrl)
} else {
profileImageLoader.cancelDisplayTask(icon)
//TODO cancel image load
}
icon.visibility = if (displayProfileImage) View.VISIBLE else View.GONE

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.model.ParcelableStatus
@ -18,18 +19,20 @@ import org.mariotaku.twidere.view.holder.UserViewHolder
/**
* Created by mariotaku on 16/3/20.
*/
class VariousItemsAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context) {
class VariousItemsAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, getRequestManager) {
private val mInflater: LayoutInflater
private val inflater = LayoutInflater.from(context)
val dummyAdapter: DummyItemAdapter
private var data: List<*>? = null
init {
mInflater = LayoutInflater.from(context)
val handler = StatusAdapterLinkClickHandler<Any>(context,
preferences)
dummyAdapter = DummyItemAdapter(context, TwidereLinkify(handler), this)
dummyAdapter = DummyItemAdapter(context, TwidereLinkify(handler), this, getRequestManager)
handler.setAdapter(dummyAdapter)
dummyAdapter.updateOptions()
loadMoreIndicatorPosition = ILoadMoreSupportAdapter.NONE
@ -39,13 +42,13 @@ class VariousItemsAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerVie
when (viewType) {
VIEW_TYPE_STATUS -> {
return ListParcelableStatusesAdapter.createStatusViewHolder(dummyAdapter,
mInflater, parent)
inflater, parent)
}
VIEW_TYPE_USER -> {
return ParcelableUsersAdapter.createUserViewHolder(dummyAdapter, mInflater, parent)
return ParcelableUsersAdapter.createUserViewHolder(dummyAdapter, inflater, parent)
}
VIEW_TYPE_USER_LIST -> {
return ParcelableUserListsAdapter.createUserListViewHolder(dummyAdapter, mInflater,
return ParcelableUserListsAdapter.createUserListViewHolder(dummyAdapter, inflater,
parent)
}
}

View File

@ -20,8 +20,8 @@
package org.mariotaku.twidere.adapter.iface
import android.support.v4.text.BidiFormatter
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.MediaLoaderWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle
@ -43,9 +43,10 @@ interface IContentAdapter {
val twitterWrapper: AsyncTwitterWrapper
val mediaLoader: MediaLoaderWrapper
val getRequestManager: () -> RequestManager
val bidiFormatter: BidiFormatter
val showAbsoluteTime: Boolean
}

View File

@ -27,6 +27,7 @@ import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.os.AsyncTask
import android.support.multidex.MultiDex
import com.bumptech.glide.Glide
import nl.komponents.kovenant.android.startKovenant
import nl.komponents.kovenant.android.stopKovenant
import nl.komponents.kovenant.task
@ -217,11 +218,12 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis
}
override fun onTrimMemory(level: Int) {
Glide.with(this).onTrimMemory(level)
super.onTrimMemory(level)
}
override fun onLowMemory() {
mediaLoader.clearMemoryCache()
Glide.with(this).onLowMemory()
super.onLowMemory()
}

View File

@ -4,7 +4,6 @@ import android.content.Context
import android.net.Uri
import android.text.TextUtils
import com.bluelinelabs.logansquare.LoganSquare
import com.nostra13.universalimageloader.utils.IoUtils
import org.apache.james.mime4j.dom.Header
import org.apache.james.mime4j.dom.MessageServiceFactory
import org.apache.james.mime4j.dom.address.Mailbox
@ -235,7 +234,7 @@ private class BodyPartHandler(private val context: Context, private val draft: D
this.type = contentType?.getParameter("media_type").toInt(ParcelableMedia.Type.UNKNOWN)
this.alt_text = contentType?.getParameter("alt_text")
FileOutputStream(mediaFile).use {
IoUtils.copyStream(st, it, null)
st.copyTo(it)
it.flush()
}
this.uri = Uri.fromFile(mediaFile).toString()

View File

@ -2,6 +2,7 @@ package org.mariotaku.twidere.extension.model
import android.content.Context
import android.widget.ImageView
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableMessage
@ -11,7 +12,6 @@ import org.mariotaku.twidere.model.ParcelableMessageConversation.ExtrasType
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.message.conversation.DefaultConversationExtras
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
import org.mariotaku.twidere.util.MediaLoaderWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import java.util.*
@ -112,16 +112,17 @@ fun ParcelableMessageConversation.getSummaryText(context: Context, manager: User
text_unescaped, this)
}
fun ParcelableMessageConversation.displayAvatarTo(mediaLoader: MediaLoaderWrapper, view: ImageView) {
fun ParcelableMessageConversation.displayAvatarTo(getRequestManager: () -> RequestManager, view: ImageView) {
if (conversation_type == ConversationType.ONE_TO_ONE) {
val user = this.user
if (user != null) {
mediaLoader.displayProfileImage(view, user)
getRequestManager().load(user.getBestProfileImage(view.context)).into(view)
} else {
mediaLoader.displayProfileImage(view, null)
// TODO: show default conversation icon
getRequestManager().load(R.drawable.ic_profile_image_default_group).into(view)
}
} else {
mediaLoader.displayGroupConversationAvatar(view, conversation_avatar)
getRequestManager().load(conversation_avatar).placeholder(R.drawable.ic_profile_image_default_group).into(view)
}
}

View File

@ -1,5 +1,6 @@
package org.mariotaku.twidere.extension.model
import android.content.Context
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.ParcelableUser
@ -28,4 +29,8 @@ val ParcelableStatus.referenced_users: Array<ParcelableUser>
mention.screen_name, null))
}
return resultList.toTypedArray()
}
}
fun ParcelableStatus.getBestProfileImage(context: Context): String? {
return user_profile_image_url
}

View File

@ -0,0 +1,33 @@
/*
* 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.model
import android.content.Context
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.util.InternalTwitterContentUtils
fun ParcelableUser.getBestProfileImage(context: Context): String? {
return profile_image_url
}
fun ParcelableUser.getBestProfileBanner(width: Int): String? {
return InternalTwitterContentUtils.getBestBannerUrl(profile_banner_url, width)
}

View File

@ -0,0 +1,28 @@
/*
* 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.model
import android.content.Context
import org.mariotaku.twidere.model.ParcelableUserList
fun ParcelableUserList.getBestProfileImage(context: Context): String? {
return user_profile_image_url
}

View File

@ -20,21 +20,22 @@
package org.mariotaku.twidere.extension.view.holder
import android.view.View
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.util.MediaLoaderWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.view.holder.SimpleUserListViewHolder
fun SimpleUserListViewHolder.display(userList: ParcelableUserList, mediaLoader: MediaLoaderWrapper,
fun SimpleUserListViewHolder.display(userList: ParcelableUserList, getRequestManager: () -> RequestManager,
userColorNameManager: UserColorNameManager, displayProfileImage: Boolean) {
nameView.text = userList.name
createdByView.text = createdByView.context.getString(R.string.created_by,
userColorNameManager.getDisplayName(userList, false))
profileImageView.visibility = if (displayProfileImage) View.VISIBLE else View.GONE
if (displayProfileImage) {
mediaLoader.displayProfileImage(profileImageView, userList)
profileImageView.visibility = View.VISIBLE
getRequestManager().load(userList.getBestProfileImage(itemView.context)).into(profileImageView)
} else {
mediaLoader.cancelDisplayTask(profileImageView)
profileImageView.visibility = View.GONE
}
}

View File

@ -12,6 +12,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.*
import com.bluelinelabs.logansquare.LoganSquare
import com.bumptech.glide.Glide
import com.rengwuxian.materialedittext.MaterialEditText
import org.mariotaku.restfu.annotation.method.GET
import org.mariotaku.restfu.http.HttpRequest
@ -80,7 +81,7 @@ class APIEditorDialogFragment : BaseDialogFragment() {
df.show(childFragmentManager, "load_defaults")
}
accountTypeSpinner.adapter = AccountTypeSpinnerAdapter(context)
accountTypeSpinner.adapter = AccountTypeSpinnerAdapter(this)
editConsumerKey.addValidator(ConsumerKeySecretValidator(context.getString(R.string.invalid_consumer_key)))
editConsumerSecret.addValidator(ConsumerKeySecretValidator(context.getString(R.string.invalid_consumer_secret)))
@ -236,8 +237,10 @@ class APIEditorDialogFragment : BaseDialogFragment() {
}
}
private class AccountTypeSpinnerAdapter(context: Context) : BaseArrayAdapter<String>(context,
R.layout.support_simple_spinner_dropdown_item) {
private class AccountTypeSpinnerAdapter(
fragment: APIEditorDialogFragment
) : BaseArrayAdapter<String>(fragment.context, R.layout.support_simple_spinner_dropdown_item,
getRequestManager = { Glide.with(fragment) }) {
init {
add(AccountType.TWITTER)
add(AccountType.FANFOU)

View File

@ -101,7 +101,7 @@ abstract class AbsActivitiesFragment protected constructor() :
registerForContextMenu(recyclerView)
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
this)
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(adapter.mediaLoader.imageLoader, false, true)
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(false, true)
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true)

View File

@ -128,7 +128,7 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
adapter.statusClickListener = this
registerForContextMenu(recyclerView)
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, this)
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(adapter.mediaLoader.imageLoader, false, true)
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(false, true)
if (shouldInitLoader) {
initLoaderIfNeeded()

View File

@ -38,7 +38,6 @@ import android.net.Uri
import android.os.Bundle
import android.support.design.widget.NavigationView
import android.support.v4.app.LoaderManager.LoaderCallbacks
import android.support.v4.content.AsyncTaskLoader
import android.support.v4.content.ContextCompat
import android.support.v4.content.FixedAsyncTaskLoader
import android.support.v4.content.Loader
@ -52,10 +51,14 @@ import android.view.*
import android.view.View.OnClickListener
import android.view.animation.DecelerateInterpolator
import android.widget.ImageView
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.header_drawer_account_selector.view.*
import org.mariotaku.kpreferences.get
import org.mariotaku.kpreferences.set
import org.mariotaku.ktextension.*
import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.ktextension.setMenuItemIcon
import org.mariotaku.twidere.Constants.EXTRA_FEATURES_NOTICE_VERSION
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
@ -75,8 +78,10 @@ import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.SupportTabSpec
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.InternalTwitterContentUtils.getBestBannerUrl
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
import org.mariotaku.twidere.view.ShapedImageView
import java.lang.ref.WeakReference
@ -214,7 +219,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
}
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler,
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
return false
}
@ -224,7 +229,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
}
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int,
repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
return true
}
@ -490,10 +495,11 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
val width = if (bannerWidth > 0) bannerWidth else defWidth
val bannerView = accountProfileBanner.nextView as ImageView
if (bannerView.drawable == null || account != bannerView.tag) {
mediaLoader.displayProfileBanner(bannerView, account, width)
val url = getBestBannerUrl(ParcelableUserUtils.getProfileBannerUrl(account.user), width)
Glide.with(this).load(url).into(bannerView)
bannerView.tag = account
} else {
mediaLoader.cancelDisplayTask(bannerView)
// TODO cancel loading
}
}

View File

@ -17,6 +17,7 @@ import android.view.*
import android.view.ContextMenu.ContextMenuInfo
import android.widget.AdapterView
import android.widget.AdapterView.AdapterContextMenuInfo
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.layout_draggable_list_with_empty_view.*
import nl.komponents.kovenant.task
import org.mariotaku.ktextension.Bundle
@ -59,7 +60,7 @@ class AccountsManagerFragment : BaseFragment(), LoaderManager.LoaderCallbacks<Li
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
val am = AccountManager.get(context)
adapter = AccountDetailsAdapter(context).apply {
adapter = AccountDetailsAdapter(context, { Glide.with(this) }).apply {
setSortEnabled(true)
setSwitchEnabled(true)
accountToggleListener = { pos, checked ->

View File

@ -28,6 +28,7 @@ import android.os.Bundle
import android.os.Handler
import android.support.v4.content.Loader
import android.widget.Toast
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe
@ -164,7 +165,7 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
}
override fun onCreateAdapter(context: Context): ListParcelableStatusesAdapter {
return ListParcelableStatusesAdapter(context)
return ListParcelableStatusesAdapter(context, { Glide.with(this) })
}
override fun onLoaderReset(loader: Loader<List<ParcelableStatus>?>) {

View File

@ -39,6 +39,7 @@ import android.view.*
import android.widget.*
import android.widget.AbsListView.MultiChoiceModeListener
import android.widget.AdapterView.OnItemClickListener
import com.bumptech.glide.Glide
import com.mobeta.android.dslv.SimpleDragSortCursorAdapter
import kotlinx.android.synthetic.main.layout_draggable_list_with_empty_view.*
import kotlinx.android.synthetic.main.list_item_section_header.view.*
@ -269,7 +270,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
val positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE)
val iconsAdapter = TabIconsAdapter(context)
val accountsAdapter = AccountsSpinnerAdapter(context)
val accountsAdapter = AccountsSpinnerAdapter(context, getRequestManager = { Glide.with(this) })
iconSpinner.adapter = iconsAdapter
accountSpinner.adapter = accountsAdapter
@ -404,7 +405,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val extraConf = activityResultMap.get(requestCode)
activityResultMap.remove(requestCode)
extraConf?.onActivityResult(requestCode and 0xFF, resultCode, data)
extraConf?.onActivityResult(this, requestCode and 0xFF, resultCode, data)
}
fun startExtraConfigurationActivityForResult(extraConf: TabConfiguration.ExtraConfiguration, intent: Intent, requestCode: Int) {

View File

@ -41,6 +41,7 @@ import android.widget.AbsListView.MultiChoiceModeListener
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_drafts.*
import org.mariotaku.kpreferences.get
import org.mariotaku.sqliteqb.library.Expression
@ -64,7 +65,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter = DraftsAdapter(activity).apply {
adapter = DraftsAdapter(activity, { Glide.with(this) }).apply {
textSize = preferences[textSizeKey].toFloat()
}
@ -153,7 +154,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long,
checked: Boolean) {
checked: Boolean) {
updateTitle(mode)
listView.updateSelectionItems(mode.menu)
}

View File

@ -33,6 +33,7 @@ import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import android.widget.AdapterView.AdapterContextMenuInfo
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_content_listview.*
import org.mariotaku.ktextension.isNullOrEmpty
import org.mariotaku.ktextension.setItemAvailability
@ -56,7 +57,7 @@ class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
}
override fun onCreateAdapter(context: Context): ExtensionsAdapter {
return ExtensionsAdapter(activity)
return ExtensionsAdapter(activity, { Glide.with(this) })
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ExtensionInfo>> {

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment
import android.content.Context
import android.net.Uri
import com.bumptech.glide.Glide
import edu.tsinghua.hotmobi.model.TimelineType
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.sqliteqb.library.Expression
@ -82,7 +83,7 @@ class InteractionsTimelineFragment : CursorActivitiesFragment() {
}
override fun onCreateAdapter(context: Context): ParcelableActivitiesAdapter {
val adapter = ParcelableActivitiesAdapter(context)
val adapter = ParcelableActivitiesAdapter(context, { Glide.with(this) })
val arguments = arguments
if (arguments != null) {
val extras = arguments.getParcelable<InteractionsTabExtras>(EXTRA_EXTRAS)

View File

@ -12,6 +12,7 @@ import android.view.ContextMenu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import com.bumptech.glide.Glide
import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.MediaEvent
import edu.tsinghua.hotmobi.model.TimelineType
@ -48,7 +49,7 @@ class ItemsListFragment : AbsContentListRecyclerViewFragment<VariousItemsAdapter
}
override fun onCreateAdapter(context: Context): VariousItemsAdapter {
val adapter = VariousItemsAdapter(context)
val adapter = VariousItemsAdapter(context, { Glide.with(this) })
val dummyItemAdapter = adapter.dummyAdapter
dummyItemAdapter.statusClickListener = object : IStatusViewHolder.StatusClickListener {
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {

View File

@ -26,6 +26,7 @@ import android.support.v4.app.hasRunningLoadersSafe
import android.support.v4.content.Loader
import android.support.v7.widget.RecyclerView
import android.view.KeyEvent
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.twidere.adapter.ParcelableGroupsAdapter
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter.GroupAdapterListener
@ -58,7 +59,7 @@ abstract class ParcelableGroupsFragment : AbsContentListRecyclerViewFragment<Par
}
override fun onCreateAdapter(context: Context): ParcelableGroupsAdapter {
return ParcelableGroupsAdapter(context)
return ParcelableGroupsAdapter(context, { Glide.with(this) })
}
override fun setupRecyclerView(context: Context, recyclerView: RecyclerView) {

View File

@ -24,6 +24,7 @@ import android.os.Bundle
import android.support.v4.app.hasRunningLoadersSafe
import android.support.v4.content.Loader
import android.text.TextUtils
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.ListParcelableStatusesAdapter
@ -123,7 +124,7 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
}
override fun onCreateAdapter(context: Context): ListParcelableStatusesAdapter {
return ListParcelableStatusesAdapter(context)
return ListParcelableStatusesAdapter(context, { Glide.with(this) })
}
override fun onStatusesLoaded(loader: Loader<List<ParcelableStatus>?>, data: List<ParcelableStatus>?) {

View File

@ -26,6 +26,7 @@ import android.support.v4.app.hasRunningLoadersSafe
import android.support.v4.content.Loader
import android.support.v7.widget.RecyclerView
import android.view.KeyEvent
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.twidere.adapter.ParcelableUserListsAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
@ -60,7 +61,7 @@ abstract class ParcelableUserListsFragment : AbsContentListRecyclerViewFragment<
}
override fun onCreateAdapter(context: Context): ParcelableUserListsAdapter {
return ParcelableUserListsAdapter(context)
return ParcelableUserListsAdapter(context, { Glide.with(this) })
}
override fun setupRecyclerView(context: Context, recyclerView: RecyclerView) {

View File

@ -27,6 +27,7 @@ import android.support.v4.content.Loader
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.KeyEvent
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.commons.parcel.ParcelUtils
@ -94,7 +95,7 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
}
override fun onCreateAdapter(context: Context): ParcelableUsersAdapter {
val adapter = ParcelableUsersAdapter(context)
val adapter = ParcelableUsersAdapter(context, { Glide.with(this) })
adapter.simpleLayout = simpleLayout
adapter.friendshipClickListener = this
return adapter
@ -116,17 +117,17 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
}
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int,
event: KeyEvent, metaState: Int): Boolean {
event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
}
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int,
repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
}
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int,
event: KeyEvent, metaState: Int): Boolean {
event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
}
@ -181,11 +182,11 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
}
protected abstract fun onCreateUsersLoader(context: Context,
args: Bundle,
fromUser: Boolean): Loader<List<ParcelableUser>?>
args: Bundle,
fromUser: Boolean): Loader<List<ParcelableUser>?>
override fun createItemDecoration(context: Context, recyclerView: RecyclerView,
layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
val itemDecoration = DividerItemDecoration(context,
(recyclerView.layoutManager as LinearLayoutManager).orientation)
val res = context.resources

View File

@ -34,6 +34,7 @@ import android.text.TextWatcher
import android.view.Gravity
import android.view.View
import android.widget.EditText
import com.bumptech.glide.Glide
import com.twitter.Validator
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.set
@ -90,7 +91,7 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
val editComment = it.findViewById(R.id.edit_comment) as ComposeEditText
val commentMenu = it.findViewById(R.id.comment_menu)!!
val adapter = DummyItemAdapter(context)
val adapter = DummyItemAdapter(context, getRequestManager = { Glide.with(this) })
adapter.setShouldShowAccountsColor(true)
val holder = StatusViewHolder(adapter, itemContent)
holder.displayStatus(status = status, displayInReplyTo = false, displayExtraType = true)
@ -199,7 +200,7 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
@CheckResult
private fun retweetOrQuote(account: AccountDetails, status: ParcelableStatus,
showProtectedConfirmation: Boolean): Boolean {
showProtectedConfirmation: Boolean): Boolean {
val twitter = twitterWrapper
val dialog = dialog ?: return false
val editComment = dialog.findViewById(R.id.edit_comment) as EditText
@ -294,8 +295,8 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
companion object {
fun show(pf: RetweetQuoteDialogFragment,
account: AccountDetails,
status: ParcelableStatus): QuoteProtectedStatusWarnFragment {
account: AccountDetails,
status: ParcelableStatus): QuoteProtectedStatusWarnFragment {
val f = QuoteProtectedStatusWarnFragment()
val args = Bundle()
args.putParcelable(EXTRA_ACCOUNT, account)

View File

@ -57,6 +57,7 @@ import android.view.View.OnClickListener
import android.widget.ImageView
import android.widget.Space
import android.widget.TextView
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.MediaEvent
@ -92,6 +93,7 @@ import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.model.applyTo
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.extension.model.media_type
import org.mariotaku.twidere.extension.view.calculateSpaceItemHeight
import org.mariotaku.twidere.fragment.AbsStatusesFragment.Companion.handleActionClick
@ -790,16 +792,14 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private val linkify: TwidereLinkify
private val locationView: TextView
private val retweetedByView: TextView
private val locationView = itemView.locationView
private val retweetedByView = itemView.retweetedBy
init {
this.linkClickHandler = DetailStatusLinkClickHandler(adapter.context,
adapter.multiSelectManager, adapter, adapter.preferences)
this.linkify = TwidereLinkify(linkClickHandler)
locationView = itemView.locationView
retweetedByView = itemView.retweetedBy
initViews()
}
@ -811,7 +811,6 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
if (account == null || status == null) return
val fragment = adapter.fragment
val context = adapter.context
val loader = adapter.mediaLoader
val formatter = adapter.bidiFormatter
val twitter = adapter.twitterWrapper
val nameFirst = adapter.nameFirst
@ -887,8 +886,9 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
} else if (adapter.isDetailMediaExpanded) {
itemView.quotedMediaLabel.visibility = View.GONE
itemView.quotedMediaPreview.visibility = View.VISIBLE
itemView.quotedMediaPreview.displayMedia(loader = loader, media = quotedMedia,
accountId = status.account_key, mediaClickListener = adapter.fragment)
itemView.quotedMediaPreview.displayMedia(adapter.getRequestManager,
media = quotedMedia, accountId = status.account_key,
mediaClickListener = adapter.fragment)
} else {
itemView.quotedMediaLabel.visibility = View.VISIBLE
itemView.quotedMediaPreview.visibility = View.GONE
@ -927,7 +927,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
itemView.name.screenName = String.format("@%s", status.user_screen_name)
itemView.name.updateText(formatter)
loader.displayProfileImage(itemView.profileImage, status)
adapter.getRequestManager().load(status.getBestProfileImage(context)).into(itemView.profileImage)
val typeIconRes = Utils.getUserTypeIconRes(status.user_is_verified, status.user_is_protected)
val typeDescriptionRes = Utils.getUserTypeDescriptionRes(status.user_is_verified, status.user_is_protected)
@ -1019,7 +1019,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
itemView.mediaPreviewContainer.visibility = View.VISIBLE
itemView.mediaPreview.visibility = View.VISIBLE
itemView.mediaPreviewLoad.visibility = View.GONE
itemView.mediaPreview.displayMedia(loader = loader, media = media,
itemView.mediaPreview.displayMedia(adapter.getRequestManager, media = media,
accountId = status.account_key, mediaClickListener = adapter.fragment,
loadingHandler = adapter.mediaLoadingHandler)
} else {
@ -1217,7 +1217,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private class CountsUsersAdapter(
private val fragment: StatusFragment,
private val statusAdapter: StatusAdapter
) : BaseRecyclerViewAdapter<ViewHolder>(statusAdapter.context) {
) : BaseRecyclerViewAdapter<ViewHolder>(statusAdapter.context, { Glide.with(fragment) }) {
private val inflater = LayoutInflater.from(statusAdapter.context)
@ -1366,15 +1366,14 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
internal class ProfileImageViewHolder(private val adapter: CountsUsersAdapter, itemView: View) : ViewHolder(itemView), OnClickListener {
private val profileImageView: ImageView
private val profileImageView = itemView.findViewById(R.id.profileImage) as ImageView
init {
itemView.setOnClickListener(this)
profileImageView = itemView.findViewById(R.id.profileImage) as ImageView
}
fun displayUser(item: ParcelableUser) {
adapter.mediaLoader.displayProfileImage(profileImageView, item)
adapter.getRequestManager().load(item.getBestProfileImage(adapter.context)).into(profileImageView)
}
override fun onClick(v: View) {
@ -1483,7 +1482,9 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private class SpaceViewHolder(itemView: View) : ViewHolder(itemView)
class StatusAdapter(val fragment: StatusFragment) : LoadMoreSupportAdapter<ViewHolder>(fragment.context), IStatusesAdapter<List<ParcelableStatus>> {
class StatusAdapter(
val fragment: StatusFragment
) : LoadMoreSupportAdapter<ViewHolder>(fragment.context, { Glide.with(fragment) }), IStatusesAdapter<List<ParcelableStatus>> {
private val inflater: LayoutInflater
override val mediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
override val twidereLinkify: TwidereLinkify

View File

@ -63,6 +63,7 @@ import android.view.*
import android.view.View.OnClickListener
import android.view.View.OnTouchListener
import android.view.animation.AnimationUtils
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.UserEvent
@ -125,6 +126,7 @@ import org.mariotaku.twidere.model.util.*
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.InternalTwitterContentUtils.*
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener
import org.mariotaku.twidere.util.UserColorNameManager.UserColorChangedListener
@ -520,10 +522,10 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
}
val defWidth = resources.displayMetrics.widthPixels
val width = if (bannerWidth > 0) bannerWidth else defWidth
val bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user)
val bannerUrl = getBestBannerUrl(ParcelableUserUtils.getProfileBannerUrl(user), width)
if (ObjectUtils.notEqual(profileBanner.tag, bannerUrl) || profileBanner.drawable == null) {
profileBanner.tag = bannerUrl
mediaLoader.displayProfileBanner(profileBanner, bannerUrl, width)
Glide.with(this).load(bannerUrl).into(profileBanner)
}
val relationship = relationship
if (relationship == null) {
@ -1184,7 +1186,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
}
R.id.profileBanner -> {
val bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user) ?: return
val url = InternalTwitterContentUtils.getBestBannerUrl(bannerUrl,
val url = getBestBannerUrl(bannerUrl,
Integer.MAX_VALUE)
val profileBanner = ParcelableMediaUtils.image(url)
profileBanner.type = ParcelableMedia.Type.IMAGE

View File

@ -8,6 +8,7 @@ import android.support.v4.content.Loader
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.StaggeredGridLayoutManager
import android.text.TextUtils
import com.bumptech.glide.Glide
import org.mariotaku.twidere.adapter.StaggeredGridParcelableStatusesAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.constant.IntentConstants.*
@ -77,7 +78,7 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
}
override fun onCreateAdapter(context: Context): StaggeredGridParcelableStatusesAdapter {
return StaggeredGridParcelableStatusesAdapter(context)
return StaggeredGridParcelableStatusesAdapter(context, { Glide.with(this) })
}
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableStatus>> {

View File

@ -37,6 +37,7 @@ import android.text.TextWatcher
import android.view.*
import android.view.View.OnClickListener
import android.widget.Toast
import com.bumptech.glide.Glide
import com.twitter.Validator
import kotlinx.android.synthetic.main.fragment_user_profile_editor.*
import org.mariotaku.abstask.library.AbstractTask
@ -49,6 +50,8 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.ColorPickerDialogActivity
import org.mariotaku.twidere.activity.ThemedMediaPickerActivity
import org.mariotaku.twidere.extension.model.getBestProfileBanner
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.ParcelableUserLoader
import org.mariotaku.twidere.model.AccountDetails
@ -285,10 +288,11 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat
editDescription.setText(ParcelableUserUtils.getExpandedDescription(user))
editLocation.setText(user.location)
editUrl.setText(if (isEmpty(user.url_expanded)) user.url else user.url_expanded)
mediaLoader.displayProfileImage(profileImage, user)
val defWidth = resources.displayMetrics.widthPixels
mediaLoader.displayProfileBanner(profileBanner, user.profile_banner_url, defWidth)
mediaLoader.displayImage(profileBackground, user.profile_background_url)
Glide.with(this).load(user.getBestProfileImage(context)).into(profileImage)
Glide.with(this).load(user.getBestProfileBanner(resources.displayMetrics.widthPixels)).into(profileBanner)
Glide.with(this).load(user.profile_background_url).into(profileBackground)
linkColor.color = user.link_color
backgroundColor.color = user.background_color
if (USER_TYPE_TWITTER_COM == user.key.host) {

View File

@ -14,6 +14,7 @@ import android.view.MenuItem
import android.widget.CheckBox
import android.widget.TextView
import android.widget.Toast
import com.bumptech.glide.Glide
import nl.komponents.kovenant.task
import nl.komponents.kovenant.ui.alwaysUi
import org.mariotaku.ktextension.*
@ -166,7 +167,7 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<Se
}
override fun onCreateAdapter(context: Context): SelectableUsersAdapter {
val adapter = SelectableUsersAdapter(context)
val adapter = SelectableUsersAdapter(context, { Glide.with(this) })
adapter.itemCheckedListener = { position, checked ->
val count = adapter.checkedCount
val actionBar = (activity as BaseActivity).supportActionBar

View File

@ -42,6 +42,8 @@ import android.support.v7.widget.Toolbar
import android.view.*
import android.widget.CompoundButton
import android.widget.EditText
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestManager
import kotlinx.android.synthetic.main.activity_home_content.view.*
import kotlinx.android.synthetic.main.fragment_messages_conversation_info.*
import kotlinx.android.synthetic.main.header_message_conversation_info.view.*
@ -122,7 +124,7 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
}
val theme = Chameleon.getOverrideTheme(context, activity)
adapter = ConversationInfoAdapter(context)
adapter = ConversationInfoAdapter(context, { Glide.with(this) })
adapter.listener = object : ConversationInfoAdapter.Listener {
override fun onUserClick(position: Int) {
val user = adapter.getUser(position) ?: return
@ -243,8 +245,9 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
val name = data.getTitle(context, userColorNameManager, preferences[nameFirstKey]).first
val summary = data.getSubtitle(context)
data.displayAvatarTo(mediaLoader, conversationAvatar)
data.displayAvatarTo(mediaLoader, appBarIcon)
val getRequestManager = { Glide.with(this) }
data.displayAvatarTo(getRequestManager, conversationAvatar)
data.displayAvatarTo(getRequestManager, appBarIcon)
appBarTitle.text = name
conversationTitle.text = name
if (summary != null) {
@ -463,7 +466,10 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
}
class ConversationInfoAdapter(context: Context) : BaseRecyclerViewAdapter<RecyclerView.ViewHolder>(context),
class ConversationInfoAdapter(
context: Context,
getRequestManager: () -> RequestManager
) : BaseRecyclerViewAdapter<RecyclerView.ViewHolder>(context, getRequestManager),
IItemCountsAdapter {
private val inflater = LayoutInflater.from(context)

View File

@ -34,6 +34,7 @@ import android.text.Spannable
import android.text.TextUtils
import android.text.style.ReplacementSpan
import android.view.*
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_messages_conversation_new.*
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.Bundle
@ -81,7 +82,7 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks<List<Parc
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
usersAdapter = SelectableUsersAdapter(context)
usersAdapter = SelectableUsersAdapter(context, { Glide.with(this) })
recyclerView.adapter = usersAdapter
recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)

View File

@ -38,6 +38,7 @@ import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar
import android.view.*
import android.widget.Toast
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.activity_premium_dashboard.*
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
@ -140,7 +141,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
return recyclerView.showContextMenuForChild(holder.itemView)
}
}
mediaPreviewAdapter = MediaPreviewAdapter(context)
mediaPreviewAdapter = MediaPreviewAdapter(context, { Glide.with(this) })
mediaPreviewAdapter.listener = object : MediaPreviewAdapter.Listener {
override fun onRemoveClick(position: Int, holder: MediaPreviewViewHolder) {
@ -268,7 +269,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
}
override fun onCreateAdapter(context: Context): MessagesConversationAdapter {
return MessagesConversationAdapter(context)
return MessagesConversationAdapter(context, { Glide.with(this) })
}
override fun onCreateLayoutManager(context: Context): LinearLayoutManager {
@ -477,7 +478,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(conversationTitle, null,
null, stateIcon, null)
conversation.displayAvatarTo(mediaLoader, conversationAvatar)
conversation.displayAvatarTo({Glide.with(this)}, conversationAvatar)
}
internal class AddMediaTask(

View File

@ -24,6 +24,7 @@ import android.content.Intent
import android.os.Bundle
import android.support.v4.app.LoaderManager.LoaderCallbacks
import android.support.v4.content.Loader
import com.bumptech.glide.Glide
import com.squareup.otto.Subscribe
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.toStringArray
@ -115,7 +116,7 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
}
override fun onCreateAdapter(context: Context): MessagesEntriesAdapter {
return MessagesEntriesAdapter(context)
return MessagesEntriesAdapter(context, { Glide.with(this) })
}
override fun triggerRefresh(): Boolean {

View File

@ -24,8 +24,6 @@ import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.support.annotation.WorkerThread
import android.util.Log
import com.bluelinelabs.logansquare.LoganSquare
import com.nostra13.universalimageloader.cache.disc.DiskCache
import org.mariotaku.kpreferences.get
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
@ -43,7 +41,11 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
import org.mariotaku.twidere.task.twitter.GetStatusesTask
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.TwidereArrayUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.cache.JsonCache
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import java.io.IOException
import java.util.*
@ -74,7 +76,7 @@ abstract class MicroBlogAPIStatusesLoader(
exceptionRef.set(value)
}
@Inject
lateinit var fileCache: DiskCache
lateinit var jsonCache: JsonCache
@Inject
lateinit var preferences: SharedPreferencesWrapper
@Inject
@ -209,8 +211,7 @@ abstract class MicroBlogAPIStatusesLoader(
private val cachedData: List<ParcelableStatus>?
get() {
val key = serializationKey ?: return null
val file = fileCache.get(key) ?: return null
return JsonSerializer.parseList(file, ParcelableStatus::class.java)
return jsonCache.getList(key, ParcelableStatus::class.java)
}
private val serializationKey: String?
@ -225,9 +226,7 @@ abstract class MicroBlogAPIStatusesLoader(
val databaseItemLimit = preferences[loadItemLimitKey]
try {
val statuses = data.subList(0, Math.min(databaseItemLimit, data.size))
fileCache.save(key, tempFileInputStream(context) { os ->
LoganSquare.serialize(statuses, os, ParcelableStatus::class.java)
}) { current, total -> true }
jsonCache.saveList(key, statuses, ParcelableStatus::class.java)
} catch (e: Exception) {
// Ignore
if (e !is IOException) {

View File

@ -14,6 +14,7 @@ import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_LOCATION
import org.mariotaku.twidere.fragment.CustomTabsFragment
import org.mariotaku.twidere.fragment.CustomTabsFragment.TabEditorDialogFragment
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.tab.TabConfiguration
@ -41,7 +42,7 @@ open class TrendsLocationExtraConfiguration(
return LayoutInflater.from(context).inflate(R.layout.layout_extra_config_checkbox, parent, false)
}
override fun onViewCreated(context: Context, view: View, fragment: CustomTabsFragment.TabEditorDialogFragment) {
override fun onViewCreated(context: Context, view: View, fragment: TabEditorDialogFragment) {
super.onViewCreated(context, view, fragment)
val titleView = view.findViewById(android.R.id.title) as TextView
summaryView = view.findViewById(android.R.id.summary) as TextView
@ -56,7 +57,7 @@ open class TrendsLocationExtraConfiguration(
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
override fun onActivityResult(fragment: TabEditorDialogFragment, requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
1 -> {
if (resultCode == Activity.RESULT_OK && data != null) {

View File

@ -6,6 +6,7 @@ import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.layout_extra_config_user.view.*
import kotlinx.android.synthetic.main.list_item_simple_user.view.*
import org.mariotaku.twidere.R
@ -49,7 +50,7 @@ class UserExtraConfiguration(key: String) : TabConfiguration.ExtraConfiguration(
fragment.startExtraConfigurationActivityForResult(this@UserExtraConfiguration, intent, 1)
}
hintView = view.selectUserHint
val adapter = DummyItemAdapter(context)
val adapter = DummyItemAdapter(context, getRequestManager = { Glide.with(fragment) })
adapter.updateOptions()
viewHolder = SimpleUserViewHolder(view.listItem, adapter)
@ -57,7 +58,7 @@ class UserExtraConfiguration(key: String) : TabConfiguration.ExtraConfiguration(
hintView.visibility = View.VISIBLE
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
override fun onActivityResult(fragment: TabEditorDialogFragment, requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
1 -> {
if (resultCode == Activity.RESULT_OK) {
@ -65,7 +66,6 @@ class UserExtraConfiguration(key: String) : TabConfiguration.ExtraConfiguration(
viewHolder.displayUser(user)
viewHolder.itemView.visibility = View.VISIBLE
hintView.visibility = View.GONE
this.value = user
}
}

View File

@ -6,16 +6,17 @@ import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.layout_extra_config_user_list.view.*
import kotlinx.android.synthetic.main.list_item_simple_user_list.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.extension.view.holder.display
import org.mariotaku.twidere.fragment.CustomTabsFragment.TabEditorDialogFragment
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.extension.view.holder.display
import org.mariotaku.twidere.view.holder.SimpleUserListViewHolder
/**
@ -56,12 +57,12 @@ class UserListExtraConfiguration(key: String) : TabConfiguration.ExtraConfigurat
hintView.visibility = View.VISIBLE
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
override fun onActivityResult(fragment: TabEditorDialogFragment, requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
1 -> {
if (resultCode == Activity.RESULT_OK) {
val userList: ParcelableUserList = data!!.getParcelableExtra(EXTRA_USER_LIST)
viewHolder.display(userList, dependencyHolder.mediaLoader,
viewHolder.display(userList, { Glide.with(context) },
dependencyHolder.userColorNameManager, true)
viewHolder.itemView.visibility = View.VISIBLE
hintView.visibility = View.GONE

View File

@ -26,6 +26,7 @@ import android.support.v7.preference.Preference
import android.support.v7.preference.PreferenceViewHolder
import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import com.bumptech.glide.Glide
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
import org.mariotaku.twidere.adapter.DummyItemAdapter
@ -39,7 +40,7 @@ class CardPreviewPreference(
) : Preference(context, attrs), OnSharedPreferenceChangeListener {
private var holder: StatusViewHolder? = null
private val adapter: DummyItemAdapter = DummyItemAdapter(context)
private val adapter: DummyItemAdapter = DummyItemAdapter(context, getRequestManager = { Glide.with(context) })
init {
val preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME,

View File

@ -8,9 +8,9 @@ import android.database.Cursor
import android.net.Uri
import android.os.ParcelFileDescriptor
import android.webkit.MimeTypeMap
import com.nostra13.universalimageloader.cache.disc.DiskCache
import okio.ByteString
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder
import org.mariotaku.mediaviewer.library.FileCache
import org.mariotaku.restfu.RestFuUtils
import org.mariotaku.twidere.TwidereConstants
import org.mariotaku.twidere.annotation.CacheFileType
@ -22,14 +22,12 @@ import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.util.*
import javax.inject.Inject
/**
* Created by mariotaku on 16/1/1.
*/
class CacheProvider : ContentProvider() {
@Inject
internal lateinit var simpleDiskCache: DiskCache
internal lateinit var fileCache: FileCache
override fun onCreate(): Boolean {
GeneralComponentHelper.build(context).inject(this)
@ -37,7 +35,7 @@ class CacheProvider : ContentProvider() {
}
override fun query(uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
return null
}
@ -49,7 +47,7 @@ class CacheProvider : ContentProvider() {
val type = uri.getQueryParameter(TwidereConstants.QUERY_PARAM_TYPE)
when (type) {
CacheFileType.IMAGE -> {
val file = simpleDiskCache.get(getCacheKey(uri)) ?: return null
val file = fileCache.get(getCacheKey(uri)) ?: return null
return BitmapUtils.getImageMimeType(file)
}
CacheFileType.VIDEO -> {
@ -63,7 +61,7 @@ class CacheProvider : ContentProvider() {
}
fun getMetadata(uri: Uri): CacheMetadata? {
val file = simpleDiskCache.get(getMetadataKey(uri)) ?: return null
val file = fileCache.get(getMetadataKey(uri)) ?: return null
var `is`: FileInputStream? = null
try {
val mapper = LoganSquareMapperFinder.mapperFor(CacheMetadata::class.java)
@ -91,7 +89,7 @@ class CacheProvider : ContentProvider() {
@Throws(FileNotFoundException::class)
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
try {
val file = simpleDiskCache.get(getCacheKey(uri)) ?: throw FileNotFoundException()
val file = fileCache.get(getCacheKey(uri)) ?: throw FileNotFoundException()
val modeBits = modeToMode(mode)
if (modeBits != ParcelFileDescriptor.MODE_READ_ONLY)
throw IllegalArgumentException("Cache can't be opened for write")

View File

@ -36,7 +36,6 @@ import android.os.Process
import android.provider.BaseColumns
import android.support.v4.app.NotificationCompat
import android.support.v4.text.BidiFormatter
import com.nostra13.universalimageloader.core.ImageLoader
import com.squareup.otto.Bus
import okhttp3.Dns
import org.apache.commons.lang3.ArrayUtils
@ -74,8 +73,6 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
@Inject
lateinit internal var twitterWrapper: AsyncTwitterWrapper
@Inject
lateinit internal var mediaLoader: ImageLoader
@Inject
lateinit internal var notificationManager: NotificationManagerWrapper
@Inject
lateinit internal var preferences: SharedPreferencesWrapper

View File

@ -13,8 +13,7 @@ import android.support.annotation.UiThread
import android.support.annotation.WorkerThread
import android.text.TextUtils
import android.webkit.MimeTypeMap
import com.nostra13.universalimageloader.core.DisplayImageOptions
import com.nostra13.universalimageloader.core.assist.ImageSize
import com.bumptech.glide.Glide
import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.MediaUploadEvent
import net.ypresto.androidtranscoder.MediaTranscoder
@ -36,8 +35,8 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.model.mediaSizeLimit
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.model.textLimit
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.account.AccountExtras
@ -712,8 +711,8 @@ class UpdateStatusTask(
}
val data = if (sizeLimit != null) when (type) {
ParcelableMedia.Type.IMAGE -> imageStream(context, resolver, mediaLoader, mediaUri,
mediaType, sizeLimit)
ParcelableMedia.Type.IMAGE -> imageStream(context, resolver, mediaUri, mediaType,
sizeLimit)
ParcelableMedia.Type.VIDEO -> videoStream(context, resolver, mediaUri, mediaType,
sizeLimit, chucked)
else -> null
@ -743,7 +742,6 @@ class UpdateStatusTask(
private fun imageStream(
context: Context,
resolver: ContentResolver,
mediaLoader: MediaLoaderWrapper,
mediaUri: Uri,
defaultType: String?,
sizeLimit: SizeLimit
@ -761,12 +759,8 @@ class UpdateStatusTask(
imageLimit.maxWidth, imageLimit.maxHeight)
o.inJustDecodeBounds = false
if (o.outWidth > 0 && o.outHeight > 0 && mediaType != "image/gif") {
val displayOptions = DisplayImageOptions.Builder()
.considerExifParams(true)
.build()
val bitmap = mediaLoader.loadImageSync(mediaUri.toString(),
ImageSize(o.outWidth, o.outHeight).scaleDown(o.inSampleSize),
displayOptions)
val bitmap = Glide.with(context).load(mediaUri).asBitmap().into(o.outWidth, o.outHeight).get()
if (bitmap != null) {
size.set(bitmap.width, bitmap.height)

View File

@ -20,28 +20,16 @@
package org.mariotaku.twidere.util
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.widget.ImageView
import com.nostra13.universalimageloader.core.DisplayImageOptions
import com.nostra13.universalimageloader.core.DisplayImageOptions.Builder
import com.nostra13.universalimageloader.core.ImageLoader
import com.nostra13.universalimageloader.core.assist.ImageSize
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.mediaPreloadKey
import org.mariotaku.twidere.constant.mediaPreloadOnWifiOnlyKey
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.model.util.getActivityStatus
import org.mariotaku.twidere.util.InternalTwitterContentUtils.getBestBannerUrl
import org.mariotaku.twidere.util.media.MediaExtra
import javax.inject.Singleton
@Singleton
class MediaLoaderWrapper(val imageLoader: ImageLoader) {
class MediaLoaderWrapper() {
var isNetworkMetered: Boolean = true
private var preloadEnabled: Boolean = false
@ -49,95 +37,6 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
private val shouldPreload: Boolean get() = preloadEnabled && (!preloadOnWifiOnly || !isNetworkMetered)
private val profileImageDisplayOptions = DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
private val groupConversationAvatarDisplayOptions = DisplayImageOptions.Builder()
.cloneFrom(profileImageDisplayOptions)
.showImageForEmptyUri(R.drawable.ic_profile_image_default_group)
.build()
private val dashboardProfileImageDisplayOptions = DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
private val previewDisplayOptions = DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
private val videoPreviewDisplayOptions = DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.showImageForEmptyUri(R.color.material_grey)
.showImageOnFail(R.color.material_grey)
.build()
private val bannerDisplayOptions = DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.showImageOnLoading(android.R.color.transparent)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
private val stickerDisplayOptions = DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.showImageOnLoading(android.R.color.transparent)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.ARGB_8888)
.build()
fun displayPreviewImage(view: ImageView, url: String?, video: Boolean = false) {
val options = if (video) videoPreviewDisplayOptions else previewDisplayOptions
imageLoader.displayImage(url, view, options)
}
fun displayPreviewImage(view: ImageView, url: String?, loadingHandler: MediaLoadingHandler?,
video: Boolean = false) {
val options = if (video) videoPreviewDisplayOptions else previewDisplayOptions
imageLoader.displayImage(url, view, options, loadingHandler, loadingHandler)
}
fun displayPreviewImageWithCredentials(view: ImageView, url: String?, accountKey: UserKey?,
loadingHandler: MediaLoadingHandler?, video: Boolean = false) {
if (accountKey == null) {
displayPreviewImage(view, url, loadingHandler)
return
}
val b = DisplayImageOptions.Builder()
b.cloneFrom(if (video) videoPreviewDisplayOptions else previewDisplayOptions)
val extra = MediaExtra()
extra.accountKey = accountKey
b.extraForDownloader(extra)
imageLoader.displayImage(url, view, b.build(), loadingHandler, loadingHandler)
}
fun displayProfileBanner(view: ImageView, url: String?, listener: ImageLoadingListener? = null) {
imageLoader.displayImage(url, view, bannerDisplayOptions, listener)
}
fun displayProfileBanner(view: ImageView, baseUrl: String?, width: Int) {
displayProfileBanner(view, getBestBannerUrl(baseUrl, width))
}
fun displayProfileBanner(view: ImageView, account: AccountDetails, width: Int) {
displayProfileBanner(view, getBestBannerUrl(ParcelableUserUtils.getProfileBannerUrl(account.user), width))
}
fun displayOriginalProfileImage(view: ImageView, user: ParcelableUser) {
if (user.extras != null && !TextUtils.isEmpty(user.extras.profile_image_url_original)) {
@ -157,36 +56,7 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
}
}
fun displayProfileImage(view: ImageView, userList: ParcelableUserList) {
displayProfileImage(view, userList.user_profile_image_url)
}
fun displayProfileImage(view: ImageView, account: AccountDetails) {
if (account.user.extras != null && !TextUtils.isEmpty(account.user.extras.profile_image_url_profile_size)) {
displayProfileImage(view, account.user.extras.profile_image_url_profile_size)
} else {
displayProfileImage(view, account.user.profile_image_url)
}
}
fun displayProfileImage(view: ImageView, status: ParcelableStatus) {
if (status.extras != null && !TextUtils.isEmpty(status.extras.user_profile_image_url_profile_size)) {
displayProfileImage(view, status.extras.user_profile_image_url_profile_size)
} else {
displayProfileImage(view, status.user_profile_image_url)
}
}
fun displayProfileImage(view: ImageView, url: String?) {
imageLoader.displayImage(url, view, profileImageDisplayOptions)
}
fun displayGroupConversationAvatar(view: ImageView, url: String?) {
imageLoader.displayImage(url, view, groupConversationAvatarDisplayOptions)
}
fun loadImageSync(url: String, targetImageSize: ImageSize, options: DisplayImageOptions): Bitmap? {
return imageLoader.loadImageSync(url, targetImageSize, options)
}
fun displayDashboardProfileImage(view: ImageView, account: AccountDetails, drawableOnLoading: Drawable?) {
@ -199,23 +69,6 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
}
fun displayImage(view: ImageView, url: String?) {
imageLoader.displayImage(url, view)
}
fun displayStickerImage(view: ImageView, url: String?) {
imageLoader.displayImage(url, view, stickerDisplayOptions)
}
fun displayProfileImage(view: ImageView, url: String?, listener: ImageLoadingListener) {
imageLoader.displayImage(url, view, profileImageDisplayOptions, listener)
}
fun cancelDisplayTask(imageView: ImageView) {
imageLoader.cancelDisplayTask(imageView)
}
fun preloadStatus(status: ParcelableStatus) {
if (!shouldPreload) return
preloadProfileImage(status.user_profile_image_url)
@ -229,29 +82,12 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
activity.getActivityStatus()?.let { preloadStatus(it) }
}
fun clearFileCache() {
imageLoader.clearDiskCache()
}
fun clearMemoryCache() {
imageLoader.clearMemoryCache()
}
fun reloadOptions(preferences: SharedPreferences) {
preloadEnabled = preferences[mediaPreloadKey]
preloadOnWifiOnly = preferences[mediaPreloadOnWifiOnlyKey]
}
private fun displayDashboardProfileImage(view: ImageView, url: String?, drawableOnLoading: Drawable?) {
if (drawableOnLoading != null) {
val builder = Builder()
builder.cloneFrom(dashboardProfileImageDisplayOptions)
builder.showImageOnLoading(drawableOnLoading)
builder.showImageOnFail(drawableOnLoading)
imageLoader.displayImage(url, view, builder.build())
return
}
imageLoader.displayImage(url, view, dashboardProfileImageDisplayOptions)
}
private fun preloadMedia(media: Array<ParcelableMedia>?) {
@ -262,13 +98,9 @@ class MediaLoaderWrapper(val imageLoader: ImageLoader) {
}
private fun preloadProfileImage(url: String?) {
if (url == null) return
imageLoader.loadImage(url, profileImageDisplayOptions, null)
}
private fun preloadPreviewImage(url: String?) {
if (url == null) return
imageLoader.loadImage(url, previewDisplayOptions, null)
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.cache
import org.mariotaku.twidere.model.ParcelableStatus
/**
* Created by mariotaku on 2017/3/1.
*/
class JsonCache {
fun <T> getList(key: String, cls: Class<T>): List<T>? {
return emptyList()
}
fun <T> saveList(key: String, list: List<T>, cls: Class<ParcelableStatus>) {
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.cache
import android.net.Uri
import org.mariotaku.mediaviewer.library.FileCache
import org.mariotaku.twidere.provider.CacheProvider
import java.io.File
import java.io.InputStream
class NoOpFileCache : FileCache {
override fun fromUri(uri: Uri): String {
return CacheProvider.getCacheKey(uri)
}
override fun toUri(key: String): Uri {
return CacheProvider.getCacheUri(key, null)
}
override fun get(key: String): File? {
return null
}
override fun remove(key: String) {
}
override fun save(key: String, stream: InputStream, metadata: ByteArray?, listener: FileCache.CopyListener?) {
}
}

View File

@ -31,12 +31,6 @@ import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.extractor.ExtractorsFactory
import com.google.android.exoplayer2.upstream.DataSource
import com.nostra13.universalimageloader.cache.disc.DiskCache
import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiskCache
import com.nostra13.universalimageloader.core.ImageLoader
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration
import com.nostra13.universalimageloader.core.assist.QueueProcessingType
import com.nostra13.universalimageloader.utils.L
import com.squareup.otto.Bus
import com.squareup.otto.ThreadEnforcer
import com.twitter.Extractor
@ -52,18 +46,15 @@ import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.mediaviewer.library.FileCache
import org.mariotaku.mediaviewer.library.MediaDownloader
import org.mariotaku.restfu.http.RestHttpClient
import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.constant.SharedPreferenceConstants
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_CACHE_SIZE_LIMIT
import org.mariotaku.twidere.constant.autoRefreshCompatibilityModeKey
import org.mariotaku.twidere.model.DefaultFeatures
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.imageloader.ReadOnlyDiskLRUNameCache
import org.mariotaku.twidere.util.imageloader.TwidereImageDownloader
import org.mariotaku.twidere.util.imageloader.URLFileNameGenerator
import org.mariotaku.twidere.util.cache.JsonCache
import org.mariotaku.twidere.util.cache.NoOpFileCache
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
import org.mariotaku.twidere.util.media.UILFileCache
import org.mariotaku.twidere.util.net.TwidereDns
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.refresh.AutoRefreshController
@ -74,7 +65,6 @@ import org.mariotaku.twidere.util.sync.LegacySyncController
import org.mariotaku.twidere.util.sync.SyncController
import org.mariotaku.twidere.util.sync.SyncPreferences
import java.io.File
import java.io.IOException
import javax.inject.Singleton
/**
@ -164,22 +154,6 @@ class ApplicationModule(private val application: Application) {
return AsyncTaskManager()
}
@Provides
@Singleton
fun imageLoader(preferences: SharedPreferencesWrapper, downloader: MediaDownloader): ImageLoader {
val loader = ImageLoader.getInstance()
val cb = ImageLoaderConfiguration.Builder(application)
cb.threadPriority(Thread.NORM_PRIORITY - 2)
cb.denyCacheImageMultipleSizesInMemory()
cb.tasksProcessingOrder(QueueProcessingType.LIFO)
// cb.memoryCache(new ImageMemoryCache(40));
cb.diskCache(createDiskCache("images", preferences))
cb.imageDownloader(TwidereImageDownloader(application, downloader))
L.writeDebugLogs(BuildConfig.DEBUG)
loader.init(cb.build())
return loader
}
@Provides
@Singleton
fun activityTracker(): ActivityTracker {
@ -208,8 +182,8 @@ class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun mediaLoaderWrapper(loader: ImageLoader, preferences: SharedPreferencesWrapper): MediaLoaderWrapper {
val wrapper = MediaLoaderWrapper(loader)
fun mediaLoaderWrapper(preferences: SharedPreferencesWrapper): MediaLoaderWrapper {
val wrapper = MediaLoaderWrapper()
wrapper.reloadOptions(preferences)
val cm = application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
wrapper.isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(cm)
@ -222,18 +196,6 @@ class ApplicationModule(private val application: Application) {
return TwidereDns(application, preferences)
}
@Provides
@Singleton
fun providesDiskCache(preferences: SharedPreferencesWrapper): DiskCache {
return createDiskCache("files", preferences)
}
@Provides
@Singleton
fun fileCache(cache: DiskCache): FileCache {
return UILFileCache(cache)
}
@Provides
@Singleton
fun mediaDownloader(preferences: SharedPreferencesWrapper, client: RestHttpClient): MediaDownloader {
@ -349,19 +311,16 @@ class ApplicationModule(private val application: Application) {
return DefaultExtractorsFactory()
}
private fun createDiskCache(dirName: String, preferences: SharedPreferencesWrapper): DiskCache {
val cacheDir = Utils.getExternalCacheDir(application, dirName)
val fallbackCacheDir = Utils.getInternalCacheDir(application, dirName)
val fileNameGenerator = URLFileNameGenerator()
val cacheSize = preferences.getInt(KEY_CACHE_SIZE_LIMIT, 300).coerceIn(100..500)
try {
val cacheMaxSizeBytes = cacheSize * 1024 * 1024
if (cacheDir != null)
return LruDiskCache(cacheDir, fallbackCacheDir, fileNameGenerator, cacheMaxSizeBytes.toLong(), 0)
return LruDiskCache(fallbackCacheDir, null, fileNameGenerator, cacheMaxSizeBytes.toLong(), 0)
} catch (e: IOException) {
return ReadOnlyDiskLRUNameCache(cacheDir, fallbackCacheDir, fileNameGenerator)
}
@Provides
@Singleton
fun jsonCache(): JsonCache {
return JsonCache()
}
@Provides
@Singleton
fun fileCache(): FileCache {
return NoOpFileCache()
}
private fun getCacheDir(dirName: String): File {

View File

@ -0,0 +1,43 @@
/*
* 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.imageloader
import android.support.v7.widget.RecyclerView
class PauseRecyclerViewOnScrollListener(
private val pauseOnScroll: Boolean,
private val pauseOnFling: Boolean
) : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
when (newState) {
RecyclerView.SCROLL_STATE_IDLE -> {
// TODO resume media load
}
RecyclerView.SCROLL_STATE_DRAGGING -> if (this.pauseOnScroll) {
// TODO pause media load
}
RecyclerView.SCROLL_STATE_SETTLING -> if (this.pauseOnFling) {
// TODO pause media load
}
}
}
}

View File

@ -25,13 +25,13 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ImageView.ScaleType
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.PreviewStyle
import org.mariotaku.twidere.extension.model.aspect_ratio
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.util.MediaLoaderWrapper
import org.mariotaku.twidere.util.MediaLoadingHandler
import java.lang.ref.WeakReference
@ -72,7 +72,7 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
}
}
fun displayMedia(loader: MediaLoaderWrapper, media: Array<ParcelableMedia>?, accountId: UserKey? = null,
fun displayMedia(getRequestManager: () -> RequestManager, media: Array<ParcelableMedia>?, accountId: UserKey? = null,
extraId: Long = -1, withCredentials: Boolean = false,
mediaClickListener: OnMediaClickListener? = null, loadingHandler: MediaLoadingHandler? = null) {
if (media == null || style == PreviewStyle.NONE) {
@ -107,9 +107,13 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
}
if (url != imageView.tag || imageView.drawable == null) {
if (withCredentials) {
loader.displayPreviewImageWithCredentials(imageView, url, accountId, loadingHandler, video)
getRequestManager().load(url).into(imageView)
// TODO handle load progress w/ authentication
// loader.displayPreviewImageWithCredentials(imageView, url, accountId, loadingHandler, video)
} else {
loader.displayPreviewImage(imageView, url, loadingHandler, video)
getRequestManager().load(url).into(imageView)
// TODO handle load progress
// loader.displayPreviewImage(imageView, url, loadingHandler, video)
}
}
imageView.tag = url
@ -124,7 +128,7 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
(child.layoutParams as MediaLayoutParams).media = item
child.visibility = View.VISIBLE
} else {
loader.cancelDisplayTask(imageView)
// TODO cancel image load task
imageView.tag = null
child.visibility = View.GONE
}

View File

@ -29,6 +29,7 @@ import org.mariotaku.ktextension.applyFontFamily
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.ParcelableActivitiesAdapter
import org.mariotaku.twidere.adapter.iface.IActivitiesAdapter
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.model.ActivityTitleSummaryMessage
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.ParcelableUser
@ -121,10 +122,8 @@ class ActivityTitleSummaryViewHolder(
profileImagesContainer.visibility = if (shouldDisplayImages) View.VISIBLE else View.GONE
profileImageSpace.visibility = if (shouldDisplayImages) View.VISIBLE else View.GONE
if (!shouldDisplayImages) return
val imageLoader = adapter.mediaLoader
if (statuses == null) {
for (view in profileImageViews) {
imageLoader.cancelDisplayTask(view)
view.visibility = View.GONE
}
return
@ -135,9 +134,8 @@ class ActivityTitleSummaryViewHolder(
view.setImageDrawable(null)
if (i < length) {
view.visibility = View.VISIBLE
imageLoader.displayProfileImage(view, statuses[i])
adapter.getRequestManager().load(statuses[i].getBestProfileImage(adapter.context)).into(view)
} else {
imageLoader.cancelDisplayTask(view)
view.visibility = View.GONE
}
}

View File

@ -61,7 +61,6 @@ class GroupViewHolder(private val adapter: IGroupsAdapter<*>, itemView: View) :
fun displayGroup(group: ParcelableGroup) {
val context = itemView.context
val loader = adapter.mediaLoader
val formatter = adapter.bidiFormatter
nameView.name = group.fullname
@ -78,10 +77,9 @@ class GroupViewHolder(private val adapter: IGroupsAdapter<*>, itemView: View) :
}
if (adapter.profileImageEnabled) {
profileImageView.visibility = View.VISIBLE
loader.displayProfileImage(profileImageView, group.homepage_logo)
adapter.getRequestManager().load(group.homepage_logo).into(profileImageView)
} else {
profileImageView.visibility = View.GONE
loader.cancelDisplayTask(profileImageView)
}
descriptionView.visibility = if (TextUtils.isEmpty(group.description)) View.GONE else View.VISIBLE
descriptionView.text = formatter.unicodeWrap(group.description)

View File

@ -7,6 +7,7 @@ import android.widget.TextView
import kotlinx.android.synthetic.main.list_item_simple_user.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IContentAdapter
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.view.ProfileImageView
@ -32,10 +33,9 @@ open class SimpleUserViewHolder<out A : IContentAdapter>(
nameView.text = user.name
secondaryNameView.text = "@${user.screen_name}"
if (adapter.profileImageEnabled) {
adapter.mediaLoader.displayProfileImage(profileImageView, user)
adapter.getRequestManager().load(user.getBestProfileImage(itemView.context)).into(profileImageView)
profileImageView.visibility = View.VISIBLE
} else {
adapter.mediaLoader.cancelDisplayTask(profileImageView)
profileImageView.visibility = View.GONE
}
}

View File

@ -12,6 +12,7 @@ import android.view.View
import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
import android.widget.ImageView
import com.bumptech.glide.RequestManager
import kotlinx.android.synthetic.main.list_item_status.view.*
import org.mariotaku.ktextension.applyFontFamily
import org.mariotaku.ktextension.isNotNullOrEmpty
@ -21,6 +22,7 @@ import org.mariotaku.twidere.TwidereConstants.USER_TYPE_FANFOU_COM
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
import org.mariotaku.twidere.constant.SharedPreferenceConstants.VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE
import org.mariotaku.twidere.extension.model.applyTo
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
import org.mariotaku.twidere.model.ParcelableLocation
import org.mariotaku.twidere.model.ParcelableMedia
@ -134,7 +136,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
displayExtraType: Boolean, displayPinned: Boolean) {
val context = itemView.context
val loader = adapter.mediaLoader
val getRequestManager = adapter.getRequestManager
val twitter = adapter.twitterWrapper
val linkify = adapter.twidereLinkify
val formatter = adapter.bidiFormatter
@ -239,13 +241,13 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
quotedView.drawStart(ThemeUtils.getColorFromAttribute(context, R.attr.quoteIndicatorBackgroundColor, 0))
}
displayQuotedMedia(loader, status)
displayQuotedMedia(getRequestManager, status)
} else {
quotedNameView.visibility = View.GONE
quotedTextView.visibility = View.VISIBLE
if (quoteContentAvailable) {
displayQuotedMedia(loader, status)
displayQuotedMedia(getRequestManager, status)
} else {
quotedMediaPreview.visibility = View.GONE
quotedMediaLabel.visibility = View.GONE
@ -297,13 +299,12 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
if (adapter.profileImageEnabled) {
profileImageView.visibility = View.VISIBLE
loader.displayProfileImage(profileImageView, status)
getRequestManager().load(status.getBestProfileImage(context)).into(profileImageView)
profileTypeView.setImageResource(getUserTypeIconRes(status.user_is_verified, status.user_is_protected))
profileTypeView.visibility = View.VISIBLE
} else {
profileImageView.visibility = View.GONE
loader.cancelDisplayTask(profileImageView)
profileTypeView.setImageDrawable(null)
profileTypeView.visibility = View.GONE
@ -331,9 +332,9 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
mediaLabel.visibility = View.GONE
mediaPreview.visibility = View.VISIBLE
mediaPreview.displayMedia(loader = loader, media = status.media,
accountId = status.account_key, mediaClickListener = this,
loadingHandler = adapter.mediaLoadingHandler)
mediaPreview.displayMedia(getRequestManager = getRequestManager,
media = status.media, accountId = status.account_key,
mediaClickListener = this, loadingHandler = adapter.mediaLoadingHandler)
}
} else {
// No media, hide all related views
@ -424,7 +425,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
}
private fun displayQuotedMedia(loader: MediaLoaderWrapper, status: ParcelableStatus) {
private fun displayQuotedMedia(getRequestManager: () -> RequestManager, status: ParcelableStatus) {
if (status.quoted_media?.isNotEmpty() ?: false) {
if (!adapter.sensitiveContentEnabled && status.is_possibly_sensitive) {
@ -440,9 +441,9 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
quotedMediaPreview.visibility = View.VISIBLE
quotedMediaLabel.visibility = View.GONE
quotedMediaPreview.displayMedia(loader = loader, media = status.quoted_media,
accountId = status.account_key, mediaClickListener = this,
loadingHandler = adapter.mediaLoadingHandler)
quotedMediaPreview.displayMedia(getRequestManager = getRequestManager,
media = status.quoted_media, accountId = status.account_key,
mediaClickListener = this, loadingHandler = adapter.mediaLoadingHandler)
}
} else {
// No media, hide all related views

View File

@ -62,7 +62,6 @@ class UserListViewHolder(
fun displayUserList(userList: ParcelableUserList) {
val context = itemView.context
val loader = adapter.mediaLoader
val manager = adapter.userColorNameManager
itemContent.drawStart(manager.getUserColor(userList.user_key))
@ -73,10 +72,9 @@ class UserListViewHolder(
if (adapter.profileImageEnabled) {
profileImageView.visibility = View.VISIBLE
loader.displayProfileImage(profileImageView, userList.user_profile_image_url)
adapter.getRequestManager().load(userList.user_profile_image_url).into(profileImageView)
} else {
profileImageView.visibility = View.GONE
loader.cancelDisplayTask(profileImageView)
}
descriptionView.visibility = if (TextUtils.isEmpty(userList.description)) View.GONE else View.VISIBLE
descriptionView.text = userList.description

View File

@ -29,6 +29,7 @@ import kotlinx.android.synthetic.main.list_item_user.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IUsersAdapter
import org.mariotaku.twidere.adapter.iface.IUsersAdapter.*
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.util.UserKeyUtils
import org.mariotaku.twidere.util.Utils
@ -117,7 +118,6 @@ class UserViewHolder(
fun displayUser(user: ParcelableUser) {
val context = itemView.context
val loader = adapter.mediaLoader
val manager = adapter.userColorNameManager
val twitter = adapter.twitterWrapper
@ -135,10 +135,9 @@ class UserViewHolder(
if (adapter.profileImageEnabled) {
profileImageView.visibility = View.VISIBLE
loader.displayProfileImage(profileImageView, user)
adapter.getRequestManager().load(user.getBestProfileImage(context)).into(profileImageView)
} else {
profileImageView.visibility = View.GONE
loader.cancelDisplayTask(profileImageView)
}
if (twitter.isUpdatingRelationship(user.account_key, user.key)) {
@ -234,7 +233,7 @@ class UserViewHolder(
}
private fun setActionClickListeners(requestClickListener: RequestClickListener?,
friendshipClickListener: FriendshipClickListener?) {
friendshipClickListener: FriendshipClickListener?) {
this.requestClickListener = requestClickListener
this.friendshipClickListener = friendshipClickListener
if (requestClickListener != null || friendshipClickListener != null) {

View File

@ -43,7 +43,7 @@ class MediaPreviewViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}
fun displayMedia(adapter: MediaPreviewAdapter, media: ParcelableMediaUpdate) {
adapter.mediaLoader.displayPreviewImage(imageView, media.uri, true)
adapter.getRequestManager().load(media.uri).into(imageView)
videoIndicatorView.visibility = if (media.type == ParcelableMedia.Type.VIDEO) {
View.VISIBLE
} else {

View File

@ -30,6 +30,7 @@ import android.widget.RelativeLayout
import android.widget.TextView
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesConversationAdapter
import org.mariotaku.twidere.extension.model.getBestProfileImage
import org.mariotaku.twidere.extension.model.timestamp
import org.mariotaku.twidere.model.ParcelableMessage
import org.mariotaku.twidere.view.ProfileImageView
@ -82,10 +83,9 @@ abstract class AbsMessageViewHolder(itemView: View, val adapter: MessagesConvers
if (adapter.displaySenderProfile && adapter.profileImageEnabled && sender != null
&& !message.is_outgoing) {
this.visibility = View.VISIBLE
adapter.mediaLoader.displayProfileImage(this, sender)
adapter.getRequestManager().load(sender.getBestProfileImage(context)).into(this)
} else {
this.visibility = View.GONE
adapter.mediaLoader.cancelDisplayTask(this)
}
}
}

View File

@ -79,7 +79,7 @@ class MessageEntryViewHolder(itemView: View, val adapter: MessagesEntriesAdapter
} else {
stateIndicator.visibility = View.GONE
}
conversation.displayAvatarTo(adapter.mediaLoader, profileImage)
conversation.displayAvatarTo(adapter.getRequestManager, profileImage)
if (conversation.unread_count > 0) {
unreadCount.visibility = View.VISIBLE
unreadCount.text = conversation.unread_count.toString()

View File

@ -108,7 +108,7 @@ class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) :
mediaPreview.visibility = View.GONE
} else {
mediaPreview.visibility = View.VISIBLE
mediaPreview.displayMedia(adapter.mediaLoader, message.media, message.account_key,
mediaPreview.displayMedia(adapter.getRequestManager, message.media, message.account_key,
withCredentials = true, loadingHandler = adapter.mediaLoadingHandler,
mediaClickListener = adapter.mediaClickListener, extraId = layoutPosition.toLong())
}

View File

@ -45,7 +45,7 @@ class StickerMessageViewHolder(itemView: View, adapter: MessagesConversationAdap
override fun display(message: ParcelableMessage, showDate: Boolean) {
super.display(message, showDate)
val extras = message.extras as StickerExtras
adapter.mediaLoader.displayStickerImage(stickerIcon, extras.url)
adapter.getRequestManager().load(extras.url).into(stickerIcon)
stickerIcon.contentDescription = extras.displayName
}