This commit is contained in:
Mariotaku Lee 2017-04-16 21:09:56 +08:00
parent 0a1d934aab
commit ea924cb262
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
56 changed files with 459 additions and 531 deletions

View File

@ -1,78 +0,0 @@
package org.mariotaku.twidere.fragment;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.PreferenceDialogFragmentCompat;
import android.view.View;
import android.view.Window;
import org.mariotaku.kpreferences.KPreferences;
import org.mariotaku.twidere.extension.AlertDialogExtensionsKt;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
import javax.inject.Inject;
/**
* Created by mariotaku on 16/3/15.
*/
public abstract class ThemedPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
@Inject
@NonNull
protected KPreferences kPreferences;
@Override
public void onAttach(Context context) {
super.onAttach(context);
GeneralComponentHelper.build(context).inject(this);
}
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getContext();
final DialogPreference preference = getPreference();
onClick(null, DialogInterface.BUTTON_NEGATIVE);
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setTitle(preference.getDialogTitle())
.setIcon(preference.getDialogIcon())
.setPositiveButton(preference.getPositiveButtonText(), this)
.setNegativeButton(preference.getNegativeButtonText(), this);
View contentView = onCreateDialogView(context);
if (contentView != null) {
onBindDialogView(contentView);
builder.setView(contentView);
} else {
builder.setMessage(preference.getDialogMessage());
}
onPrepareDialogBuilder(builder);
// Create the dialog
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(final DialogInterface dialog) {
AlertDialogExtensionsKt.applyTheme((AlertDialog) dialog);
}
});
if (needInputMethod()) {
supportRequestInputMethod(dialog);
}
return dialog;
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
}
private void supportRequestInputMethod(Dialog dialog) {
Window window = dialog.getWindow();
window.setSoftInputMode(5);
}
}

View File

@ -15,13 +15,12 @@ import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.ThemedPreferenceDialogFragmentCompat;
import org.mariotaku.twidere.preference.iface.IDialogPreference;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
import org.mariotaku.twidere.util.dagger.GeneralComponent;
import javax.inject.Inject;
@ -55,7 +54,7 @@ public class KeyboardShortcutPreference extends DialogPreference implements IDia
}
private void init(Context context, AttributeSet set) {
GeneralComponentHelper.build(context).inject(this);
GeneralComponent.Companion.get(context).inject(this);
TypedArray a = context.obtainStyledAttributes(set, R.styleable.KeyboardShortcutPreference);
mContextTag = a.getString(R.styleable.KeyboardShortcutPreference_android_tag);
mAction = a.getString(R.styleable.KeyboardShortcutPreference_android_action);

View File

@ -1,134 +0,0 @@
package org.mariotaku.twidere.util;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.UserKey;
/**
* Created by mariotaku on 16/1/31.
*/
public class ErrorInfoStore {
public static final String KEY_DIRECT_MESSAGES = "direct_messages";
public static final String KEY_INTERACTIONS = "interactions";
public static final String KEY_HOME_TIMELINE = "home_timeline";
public static final String KEY_ACTIVITIES_BY_FRIENDS = "activities_by_friends";
public static final int CODE_NO_DM_PERMISSION = 1;
public static final int CODE_NO_ACCESS_FOR_CREDENTIALS = 2;
public static final int CODE_NETWORK_ERROR = 3;
public static final int CODE_TIMESTAMP_ERROR = 4;
private final SharedPreferences mPreferences;
public ErrorInfoStore(Application application) {
mPreferences = application.getSharedPreferences("error_info", Context.MODE_PRIVATE);
}
public int get(String key) {
return mPreferences.getInt(key, 0);
}
public int get(String key, String extraId) {
return get(key + "_" + extraId);
}
public int get(String key, UserKey extraId) {
final String host = extraId.getHost();
if (host == null) {
return get(key, extraId.getId());
} else {
return get(key + "_" + extraId.getId() + "_" + host);
}
}
public void set(String key, int code) {
mPreferences.edit().putInt(key, code).apply();
}
public void set(String key, String extraId, int code) {
set(key + "_" + extraId, code);
}
public void set(String key, UserKey extraId, int code) {
final String host = extraId.getHost();
if (host == null) {
set(key, extraId.getId(), code);
} else {
set(key + "_" + extraId.getId() + "_" + host, code);
}
}
@Nullable
public static DisplayErrorInfo getErrorInfo(@NonNull Context context, int code) {
switch (code) {
case CODE_NO_DM_PERMISSION: {
return new DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.error_no_dm_permission));
}
case CODE_NO_ACCESS_FOR_CREDENTIALS: {
return new DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.error_no_access_for_credentials));
}
case CODE_NETWORK_ERROR: {
return new DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.message_toast_network_error));
}
case CODE_TIMESTAMP_ERROR: {
return new DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.error_info_oauth_timestamp_error));
}
}
return null;
}
public void remove(String key, String extraId) {
remove(key + "_" + extraId);
}
public void remove(String key, UserKey extraId) {
final String host = extraId.getHost();
if (host == null) {
remove(key, extraId.getId());
} else {
remove(key + "_" + extraId.getId() + "_" + host);
}
}
public void remove(String key) {
mPreferences.edit().remove(key).apply();
}
public static class DisplayErrorInfo {
int code;
@DrawableRes
int icon;
String message;
public DisplayErrorInfo(int code, @DrawableRes int icon, String message) {
this.code = code;
this.icon = icon;
this.message = message;
}
public int getCode() {
return code;
}
@DrawableRes
public int getIcon() {
return icon;
}
public String getMessage() {
return message;
}
}
}

View File

@ -1,141 +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;
import android.app.Application;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v4.content.res.ResourcesCompat;
import android.util.LruCache;
import java.util.Locale;
import javax.inject.Singleton;
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_EMOJI_SUPPORT;
/**
* Created by mariotaku on 15/12/20.
*/
@Singleton
public class ExternalThemeManager {
private final Application application;
private final SharedPreferencesWrapper preferences;
private Emoji emoji;
private String emojiPackageName;
public ExternalThemeManager(Application application, SharedPreferencesWrapper preferences) {
this.application = application;
this.preferences = preferences;
reloadEmojiPreferences();
}
public String getEmojiPackageName() {
return emojiPackageName;
}
public void reloadEmojiPreferences() {
final String emojiComponentName = preferences.getString(KEY_EMOJI_SUPPORT, null);
if (emojiComponentName != null) {
final ComponentName componentName = ComponentName.unflattenFromString(emojiComponentName);
if (componentName != null) {
emojiPackageName = componentName.getPackageName();
} else {
emojiPackageName = null;
}
} else {
emojiPackageName = null;
}
initEmojiSupport();
}
public void initEmojiSupport() {
if (emojiPackageName == null) {
emoji = null;
return;
}
emoji = new Emoji(application, emojiPackageName);
}
@Nullable
public Emoji getEmoji() {
return emoji;
}
public static class Emoji {
private final String packageName;
private boolean useMipmap;
private Resources resources;
private LruCache<int[], Integer> identifierCache = new LruCache<>(512);
public Emoji(Application application, String packageName) {
this.packageName = packageName;
initResources(application, packageName);
}
private void initResources(Application application, String packageName) {
if (packageName == null) {
useMipmap = false;
resources = null;
return;
}
try {
final PackageManager pm = application.getPackageManager();
final ApplicationInfo info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
if (info.metaData != null) {
this.useMipmap = info.metaData.getBoolean("org.mariotaku.twidere.extension.emoji.mipmap");
}
this.resources = pm.getResourcesForApplication(info);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
}
}
public Drawable getEmojiDrawableFor(int... codePoints) {
final Integer cached = identifierCache.get(codePoints);
if (cached == null) {
final StringBuilder sb = new StringBuilder("emoji_u");
for (int i = 0; i < codePoints.length; i++) {
if (i != 0) {
sb.append("_");
}
sb.append(String.format(Locale.US, "%04x", codePoints[i]));
}
final int identifier = resources.getIdentifier(sb.toString(),
useMipmap ? "mipmap" : "drawable", packageName);
identifierCache.put(codePoints, identifier);
if (identifier == 0) return null;
return ResourcesCompat.getDrawable(resources, identifier, null);
} else if (cached != 0) {
return ResourcesCompat.getDrawable(resources, cached, null);
}
return null;
}
public boolean isSupported() {
return resources != null;
}
}
}

View File

@ -82,25 +82,29 @@ public class InternalTwitterContentUtils {
}
@NonNull
public static String getBestBannerUrl(@NonNull final String baseUrl, final int width) {
final String type = getBestBannerType(width);
public static String getBestBannerUrl(@NonNull final String baseUrl, final int width, final int height) {
final String type;
if (width <= 0) {
type = "1500x500";
} else {
type = getBestBannerType(width, height);
}
final String authority = UriUtils.getAuthority(baseUrl);
return authority != null && authority.endsWith(".twimg.com") ? baseUrl + "/" + type : baseUrl;
}
public static String getBestBannerType(final int width) {
if (width <= 320)
return "mobile";
else if (width <= 520)
return "web";
else if (width <= 626)
return "ipad";
else if (width <= 640)
return "mobile_retina";
else if (width <= 1040)
return "web_retina";
else
return "ipad_retina";
public static String getBestBannerType(final int width, int height) {
if (height > 0 && width / height >= 3) {
if (width <= 300) return "300x100";
else if (width <= 600) return "600x200";
else return "1500x500";
}
if (width <= 320) return "mobile";
else if (width <= 520) return "web";
else if (width <= 626) return "ipad";
else if (width <= 640) return "mobile_retina";
else if (width <= 1040) return "web_retina";
else return "ipad_retina";
}
@Nullable

View File

@ -1,39 +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.dagger;
import android.content.Context;
import android.support.annotation.NonNull;
/**
* Created by mariotaku on 15/12/31.
*/
public class GeneralComponentHelper {
private static GeneralComponent sGeneralComponent;
private GeneralComponentHelper() {
}
@NonNull
public static GeneralComponent build(@NonNull Context context) {
if (sGeneralComponent != null) return sGeneralComponent;
return sGeneralComponent = DaggerGeneralComponent.builder().applicationModule(ApplicationModule.Companion.get(context)).build();
}
}

View File

@ -61,7 +61,7 @@ import org.mariotaku.twidere.model.DefaultFeatures
import org.mariotaku.twidere.preference.iface.IDialogPreference
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.gifshare.GifShareProvider
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.schedule.StatusScheduleProvider
@ -203,7 +203,7 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
super.onCreate(savedInstanceState)
ActivitySupport.setTaskDescription(this, TaskDescriptionCompat(title.toString(), null,
ColorUtils.setAlphaComponent(overrideTheme.colorToolbar, 0xFF)))
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
}
override fun onResume() {

View File

@ -97,7 +97,7 @@ import org.mariotaku.twidere.text.MarkForDeleteSpan
import org.mariotaku.twidere.text.style.EmojiSpan
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.view.ViewAnimator
import org.mariotaku.twidere.util.view.ViewProperties
@ -195,7 +195,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
nameFirst = preferences[nameFirstKey]
setContentView(R.layout.activity_compose)

View File

@ -64,7 +64,7 @@ import org.mariotaku.twidere.util.AsyncTaskUtils
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.PermissionUtils
import org.mariotaku.twidere.util.ThemeUtils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.support.WindowSupport
import org.mariotaku.twidere.view.viewer.MediaSwipeCloseContainer
import java.io.File
@ -132,7 +132,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
super.onCreate(savedInstanceState)
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
mediaViewerHelper = IMediaViewerActivity.Helper(this)
controlBarShowHideHelper = ControlBarShowHideHelper(this)
mediaViewerHelper.onCreate(savedInstanceState)

View File

@ -29,7 +29,7 @@ import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.schedule.StatusScheduleProvider
import org.mariotaku.twidere.view.ContainerView
@ -178,7 +178,7 @@ class PremiumDashboardActivity : BaseActivity() {
override fun onCreate() {
super.onCreate()
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun onCreateView(parent: ContainerView): View {

View File

@ -28,7 +28,7 @@ import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.R
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.view.holder.AccountViewHolder
class AccountDetailsAdapter(
@ -54,7 +54,7 @@ class AccountDetailsAdapter(
}
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {

View File

@ -30,7 +30,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.model.ItemCounts
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
open class BaseArrayAdapter<T>(
@ -81,7 +81,7 @@ open class BaseArrayAdapter<T>(
init {
@Suppress("UNCHECKED_CAST")
GeneralComponentHelper.build(context).inject(this as BaseArrayAdapter<Any>)
GeneralComponent.get(context).inject(this as BaseArrayAdapter<Any>)
linkify = TwidereLinkify(OnLinkClickHandler(context, multiSelectManager, preferences))
profileImageStyle = preferences[profileImageStyleKey]
textSize = preferences[textSizeKey].toFloat()

View File

@ -32,7 +32,7 @@ import org.mariotaku.twidere.constant.showAbsoluteTimeKey
import org.mariotaku.twidere.constant.textSizeKey
import org.mariotaku.twidere.model.DefaultFeatures
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
/**
@ -67,7 +67,7 @@ abstract class BaseRecyclerViewAdapter<VH : RecyclerView.ViewHolder>(
init {
@Suppress("UNCHECKED_CAST")
GeneralComponentHelper.build(context).inject(this as BaseRecyclerViewAdapter<RecyclerView.ViewHolder>)
GeneralComponent.get(context).inject(this as BaseRecyclerViewAdapter<RecyclerView.ViewHolder>)
profileImageStyle = preferences[profileImageStyleKey]
textSize = preferences[textSizeKey].toFloat()
profileImageEnabled = preferences[displayProfileImageKey]

View File

@ -37,7 +37,7 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.view.ProfileImageView
import javax.inject.Inject
@ -57,7 +57,7 @@ class ComposeAutoCompleteAdapter(context: Context, val requestManager: RequestMa
private var token: Char = ' '
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
displayProfileImage = preferences[displayProfileImageKey]
profileImageStyle = preferences[profileImageStyleKey]
}

View File

@ -31,7 +31,7 @@ import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.twidere.constant.mediaPreviewStyleKey
import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.view.holder.DraftViewHolder
import javax.inject.Inject
@ -54,7 +54,7 @@ class DraftsAdapter(
private var indices: ObjectCursor.CursorIndices<Draft>? = null
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
mediaPreviewStyle = preferences[mediaPreviewStyleKey]
}

View File

@ -17,7 +17,7 @@ import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.TwidereLinkify
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
import javax.inject.Inject
@ -65,7 +65,7 @@ class DummyItemAdapter(
private var showingActionCardPosition = RecyclerView.NO_POSITION
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
updateOptions()
}

View File

@ -43,7 +43,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.view.ProfileImageView
import javax.inject.Inject
@ -66,7 +66,7 @@ class UserAutoCompleteAdapter(
var accountKey: UserKey? = null
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
displayProfileImage = preferences[displayProfileImageKey]
profileImageStyle = preferences[profileImageStyleKey]
}

View File

@ -53,7 +53,7 @@ import org.mariotaku.twidere.receiver.ConnectivityStateReceiver
import org.mariotaku.twidere.service.StreamingService
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.media.MediaPreloader
import org.mariotaku.twidere.util.media.ThumborWrapper
import org.mariotaku.twidere.util.net.TwidereDns
@ -129,7 +129,7 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis
updateEasterEggIcon()
migrateUsageStatisticsPreferences()
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
autoRefreshController.appStarted()
syncController.appStarted()

View File

@ -131,7 +131,8 @@ fun RequestManager.loadOriginalProfileImage(context: Context, user: ParcelableUs
}
fun RequestManager.loadProfileBanner(context: Context, user: ParcelableUser, width: Int): DrawableTypeRequest<String?> {
return load(user.getBestProfileBanner(width))
val ratio = context.resources.getFraction(R.fraction.aspect_ratio_profile_banner, 1, 1)
return load(user.getBestProfileBanner(width, (width / ratio).toInt()))
}
internal inline fun <T> configureLoadProfileImage(context: Context, @ImageShapeStyle shapeStyle: Int,

View File

@ -27,9 +27,9 @@ import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.util.InternalTwitterContentUtils
import org.mariotaku.twidere.util.Utils
fun ParcelableUser.getBestProfileBanner(width: Int): String? {
fun ParcelableUser.getBestProfileBanner(width: Int, height: Int = 0): String? {
return profile_banner_url?.let {
InternalTwitterContentUtils.getBestBannerUrl(it, width)
InternalTwitterContentUtils.getBestBannerUrl(it, width, height)
} ?: if (USER_TYPE_FANFOU_COM == key.host) {
profile_background_url
} else {

View File

@ -28,7 +28,7 @@ import org.mariotaku.twidere.model.CustomAPIConfig
import org.mariotaku.twidere.model.account.cred.Credentials
import org.mariotaku.twidere.util.JsonSerializer
import org.mariotaku.twidere.util.ParseUtils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.view.ConsumerKeySecretValidator
import java.io.IOException
import javax.inject.Inject
@ -192,7 +192,7 @@ class APIEditorDialogFragment : BaseDialogFragment() {
lateinit var client: RestHttpClient
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun loadInBackground(): List<CustomAPIConfig>? {

View File

@ -26,7 +26,7 @@ import com.twitter.Validator
import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.restfu.http.RestHttpClient
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import javax.inject.Inject
@ -53,7 +53,7 @@ open class BaseDialogFragment : DialogFragment() {
override fun onAttach(context: Context?) {
super.onAttach(context)
GeneralComponentHelper.build(context!!).inject(this)
GeneralComponent.get(context!!).inject(this)
}
override fun onDestroy() {

View File

@ -30,7 +30,7 @@ import org.mariotaku.restfu.http.RestHttpClient
import org.mariotaku.twidere.fragment.iface.IBaseFragment
import org.mariotaku.twidere.model.DefaultFeatures
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.schedule.StatusScheduleProvider
import org.mariotaku.twidere.util.sync.TimelineSyncManager
@ -89,7 +89,7 @@ open class BaseFragment : Fragment(), IBaseFragment<BaseFragment> {
override fun onAttach(context: Context?) {
super.onAttach(context)
GeneralComponentHelper.build(context!!).inject(this)
GeneralComponent.get(context!!).inject(this)
}
override fun executeAfterFragmentResumed(useHandler: Boolean, action: (BaseFragment) -> Unit)

View File

@ -36,7 +36,7 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment
import org.mariotaku.twidere.preference.RingtonePreference
import org.mariotaku.twidere.util.KeyboardShortcutsHandler
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.sync.SyncController
import javax.inject.Inject
@ -65,7 +65,7 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat(), IBaseFragmen
override fun onAttach(context: Context) {
super.onAttach(context)
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun onSaveInstanceState(outState: Bundle) {

View File

@ -0,0 +1,62 @@
package org.mariotaku.twidere.fragment
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.support.v7.preference.PreferenceDialogFragmentCompat
import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
/**
* Created by mariotaku on 16/3/15.
*/
abstract class ThemedPreferenceDialogFragmentCompat : PreferenceDialogFragmentCompat() {
@Inject
lateinit var kPreferences: KPreferences
override fun onAttach(context: Context) {
super.onAttach(context)
GeneralComponent.get(context).inject(this)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val context = context
val preference = preference
onClick(null, DialogInterface.BUTTON_NEGATIVE)
val builder = AlertDialog.Builder(context)
.setTitle(preference.dialogTitle)
.setIcon(preference.dialogIcon)
.setPositiveButton(preference.positiveButtonText, this)
.setNegativeButton(preference.negativeButtonText, this)
val contentView = onCreateDialogView(context)
if (contentView != null) {
onBindDialogView(contentView)
builder.setView(contentView)
} else {
builder.setMessage(preference.dialogMessage)
}
onPrepareDialogBuilder(builder)
// Create the dialog
val dialog = builder.create()
dialog.setOnShowListener { dialog -> (dialog as AlertDialog).applyTheme() }
if (needInputMethod()) {
supportRequestInputMethod(dialog)
}
return dialog
}
override fun onPrepareDialogBuilder(builder: AlertDialog.Builder?) {
}
private fun supportRequestInputMethod(dialog: Dialog) {
val window = dialog.window
window?.setSoftInputMode(5)
}
}

View File

@ -1230,7 +1230,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey])
}
R.id.profileBanner -> {
val url = user.getBestProfileBanner(Integer.MAX_VALUE) ?: return
val url = user.getBestProfileBanner(0) ?: return
val profileBanner = ParcelableMediaUtils.image(url)
profileBanner.type = ParcelableMedia.Type.IMAGE
val media = arrayOf(profileBanner)

View File

@ -39,7 +39,7 @@ import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.ThemeUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.content.ContentResolverUtils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
class FilteredUsersFragment : BaseFiltersFragment() {
@ -159,7 +159,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context)
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
nameFirst = preferences[nameFirstKey]
}

View File

@ -67,7 +67,7 @@ import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.CacheProvider
import org.mariotaku.twidere.task.SaveFileTask
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
import java.io.InputStream
import javax.inject.Inject
@ -175,7 +175,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
override fun onAttach(context: Context) {
super.onAttach(context)
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun onStart() {

View File

@ -41,7 +41,7 @@ import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableUserListUtils
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.util.*
import javax.inject.Inject
@ -63,7 +63,7 @@ abstract class BaseUserListsLoader(
override var prevCursor: Long = 0
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
if (data != null) {
this.data.addAll(data)
}

View File

@ -13,7 +13,7 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.text.Collator
import java.util.*
import javax.inject.Inject
@ -30,7 +30,7 @@ class CacheUserSearchLoader(
internal lateinit var userColorNameManager: UserColorNameManager
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun getUsers(twitter: MicroBlog, details: AccountDetails): List<User> {

View File

@ -44,7 +44,7 @@ import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.cache.JsonCache
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.io.IOException
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
@ -81,7 +81,7 @@ abstract class MicroBlogAPIStatusesLoader(
lateinit var userColorNameManager: UserColorNameManager
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
@SuppressWarnings("unchecked")

View File

@ -36,7 +36,7 @@ import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.deleteActivityStatus
import javax.inject.Inject
@ -57,7 +57,7 @@ class ParcelableStatusLoader(
internal lateinit var restHttpClient: RestHttpClient
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun loadInBackground(): SingleResponse<ParcelableStatus> {

View File

@ -50,7 +50,7 @@ import org.mariotaku.twidere.task.UpdateAccountInfoTask
import org.mariotaku.twidere.util.ContentValuesCreator
import org.mariotaku.twidere.util.TwitterWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
class ParcelableUserLoader(
@ -69,7 +69,7 @@ class ParcelableUserLoader(
lateinit var userColorNameManager: UserColorNameManager
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun loadInBackground(): SingleResponse<ParcelableUser> {

View File

@ -36,7 +36,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_PREFERENCES_NAME_PREFIX
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.media.MediaPreloader
import javax.inject.Inject
@ -88,7 +88,7 @@ abstract class AccountsListPreference(context: Context, attrs: AttributeSet? = n
internal lateinit var mediaPreloader: MediaPreloader
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
val switchPreferenceName = "$ACCOUNT_PREFERENCES_NAME_PREFIX${account.key}"
switchPreference = context.getSharedPreferences(switchPreferenceName, Context.MODE_PRIVATE)
switchPreference.registerOnSharedPreferenceChangeListener(this)

View File

@ -9,7 +9,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.REQUEST_PURCHASE_EXTRA_FEATURES
import org.mariotaku.twidere.extension.findParent
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import javax.inject.Inject
@ -23,7 +23,7 @@ class PremiumEntryPreference(context: Context, attrs: AttributeSet) : Preference
internal lateinit var extraFeaturesService: ExtraFeaturesService
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
val a = context.obtainStyledAttributes(attrs, R.styleable.PremiumEntryPreference)
val requiredFeature: String = a.getString(R.styleable.PremiumEntryPreference_requiredFeature)
a.recycle()

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.util.AttributeSet
import org.mariotaku.twidere.R
import org.mariotaku.twidere.extension.findParent
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import javax.inject.Inject
@ -37,7 +37,7 @@ class PremiumEntryPreferenceCategory(context: Context, attrs: AttributeSet) : Ti
internal lateinit var extraFeaturesService: ExtraFeaturesService
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
val a = context.obtainStyledAttributes(attrs, R.styleable.PremiumEntryPreference)
a.recycle()
isEnabled = extraFeaturesService.isSupported()

View File

@ -7,7 +7,7 @@ import android.view.View
import android.widget.TextView
import org.mariotaku.twidere.R
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.sync.SyncPreferences
import javax.inject.Inject
@ -24,7 +24,7 @@ class SyncItemPreference(
val syncType: String
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
val a = context.obtainStyledAttributes(attrs, R.styleable.SyncItemPreference)
syncType = a.getString(R.styleable.SyncItemPreference_syncType)
key = SyncPreferences.getSyncEnabledKey(syncType)

View File

@ -16,7 +16,7 @@ import org.mariotaku.twidere.model.CacheMetadata
import org.mariotaku.twidere.task.SaveFileTask
import org.mariotaku.twidere.util.BitmapUtils
import org.mariotaku.twidere.util.JsonSerializer
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.io.ByteArrayInputStream
import java.io.FileNotFoundException
import java.io.IOException
@ -31,7 +31,7 @@ class CacheProvider : ContentProvider() {
internal lateinit var fileCache: FileCache
override fun onCreate(): Boolean {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
return true
}

View File

@ -50,7 +50,7 @@ import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.SQLiteDatabaseWrapper.LazyLoadCallback
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.database.CachedUsersQueryBuilder
import org.mariotaku.twidere.util.database.SuggestionsCursorCreator
import java.util.concurrent.Executor
@ -86,7 +86,7 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
override fun onCreate(): Boolean {
val context = context!!
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
handler = Handler(Looper.getMainLooper())
databaseWrapper = SQLiteDatabaseWrapper(this)
backgroundExecutor = Executors.newSingleThreadExecutor()

View File

@ -7,7 +7,7 @@ import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.NotificationManagerWrapper
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
abstract class BaseIntentService(tag: String) : IntentService(tag) {
@ -27,6 +27,6 @@ abstract class BaseIntentService(tag: String) : IntentService(tag) {
override fun onCreate() {
super.onCreate()
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
}
}

View File

@ -24,7 +24,7 @@ import android.net.ConnectivityManager
import com.twitter.Extractor
import com.twitter.Validator
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
abstract class BaseService : Service() {
@ -52,6 +52,6 @@ abstract class BaseService : Service() {
override fun onCreate() {
super.onCreate()
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
}
}

View File

@ -31,7 +31,7 @@ import org.mariotaku.twidere.annotation.AutoRefreshType
import org.mariotaku.twidere.constant.autoRefreshCompatibilityModeKey
import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.TaskServiceRunner
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.support.JobServiceSupport
import javax.inject.Inject
@ -50,7 +50,7 @@ class JobTaskService : JobService() {
override fun onCreate() {
super.onCreate()
Log.d(LOGTAG, "JobTaskService started")
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
}
override fun onDestroy() {

View File

@ -30,7 +30,7 @@ import org.mariotaku.twidere.constant.autoRefreshCompatibilityModeKey
import org.mariotaku.twidere.util.TaskServiceRunner.Companion.ACTION_REFRESH_DIRECT_MESSAGES
import org.mariotaku.twidere.util.TaskServiceRunner.Companion.ACTION_REFRESH_HOME_TIMELINE
import org.mariotaku.twidere.util.TaskServiceRunner.Companion.ACTION_REFRESH_NOTIFICATIONS
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
class LegacyTaskService : BaseService() {
@ -39,7 +39,7 @@ class LegacyTaskService : BaseService() {
override fun onCreate() {
super.onCreate()
Log.d(LOGTAG, "LegacyTaskService created")
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
}
override fun onDestroy() {

View File

@ -44,7 +44,7 @@ import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.streaming.TwitterTimelineStreamCallback
import java.util.*
import java.util.concurrent.ExecutorService
@ -66,7 +66,7 @@ class StreamingService : BaseService() {
override fun onCreate() {
super.onCreate()
GeneralComponentHelper.build(this).inject(this)
GeneralComponent.get(this).inject(this)
threadPoolExecutor = Executors.newCachedThreadPool(BasicThreadFactory.Builder()
.namingPattern("twidere-streaming-%d")
.priority(Thread.NORM_PRIORITY - 1).build())

View File

@ -7,7 +7,7 @@ import org.mariotaku.abstask.library.AbstractTask
import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.twidere.model.DefaultFeatures
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import org.mariotaku.twidere.util.media.MediaPreloader
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.schedule.StatusScheduleProvider
@ -58,6 +58,6 @@ abstract class BaseAbstractTask<Params, Result, Callback>(val context: Context)
private fun injectMembers() {
@Suppress("UNCHECKED_CAST")
GeneralComponentHelper.build(context).inject(this as BaseAbstractTask<Any, Any, Any>)
GeneralComponent.get(context).inject(this as BaseAbstractTask<Any, Any, Any>)
}
}

View File

@ -29,7 +29,7 @@ import org.mariotaku.twidere.util.AsyncTaskManager
import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
@ -51,7 +51,7 @@ abstract class ManagedAsyncTask<Params, Progress, Result> @JvmOverloads construc
init {
@Suppress("UNCHECKED_CAST")
GeneralComponentHelper.build(context).inject(this as ManagedAsyncTask<Any, Any, Any>)
GeneralComponent.get(context).inject(this as ManagedAsyncTask<Any, Any, Any>)
}
override fun onCancelled() {

View File

@ -27,7 +27,7 @@ import org.mariotaku.twidere.text.SafeSpannableStringBuilder
import org.mariotaku.twidere.util.EmojiSupportUtils
import org.mariotaku.twidere.util.ExternalThemeManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
@ -40,7 +40,7 @@ class EmojiEditableFactory(textView: TextView) : Editable.Factory() {
lateinit internal var externalThemeManager: ExternalThemeManager
init {
GeneralComponentHelper.build(textView.context).inject(this)
GeneralComponent.get(textView.context).inject(this)
}
override fun newEditable(source: CharSequence): Editable {

View File

@ -25,7 +25,7 @@ import org.mariotaku.twidere.text.SafeSpannableString
import org.mariotaku.twidere.util.EmojiSupportUtils
import org.mariotaku.twidere.util.ExternalThemeManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
@ -38,7 +38,7 @@ class EmojiSpannableFactory(textView: TextView) : Spannable.Factory() {
lateinit internal var externalThemeManager: ExternalThemeManager
init {
GeneralComponentHelper.build(textView.context).inject(this)
GeneralComponent.get(textView.context).inject(this)
}
override fun newSpannable(source: CharSequence): Spannable {

View File

@ -0,0 +1,116 @@
package org.mariotaku.twidere.util
import android.content.Context
import android.support.annotation.DrawableRes
import org.mariotaku.twidere.R
import org.mariotaku.twidere.model.UserKey
/**
* Created by mariotaku on 16/1/31.
*/
class ErrorInfoStore(application: Context) {
private val preferences = application.getSharedPreferences("error_info", Context.MODE_PRIVATE)
operator fun get(key: String): Int {
return preferences.getInt(key, 0)
}
operator fun get(key: String, extraId: String): Int {
return get(key + "_" + extraId)
}
operator fun get(key: String, extraId: UserKey): Int {
val host = extraId.host
if (host == null) {
return get(key, extraId.id)
} else {
return get(key + "_" + extraId.id + "_" + host)
}
}
operator fun set(key: String, code: Int) {
preferences.edit().putInt(key, code).apply()
}
operator fun set(key: String, extraId: String, code: Int) {
set(key + "_" + extraId, code)
}
operator fun set(key: String, extraId: UserKey, code: Int) {
val host = extraId.host
if (host == null) {
set(key, extraId.id, code)
} else {
set(key + "_" + extraId.id + "_" + host, code)
}
}
fun remove(key: String, extraId: String) {
remove(key + "_" + extraId)
}
fun remove(key: String, extraId: UserKey) {
val host = extraId.host
if (host == null) {
remove(key, extraId.id)
} else {
remove(key + "_" + extraId.id + "_" + host)
}
}
fun remove(key: String) {
preferences.edit().remove(key).apply()
}
class DisplayErrorInfo(code: Int, @DrawableRes icon: Int, message: String) {
var code: Int = 0
internal set
var icon: Int = 0
internal set
var message: String
internal set
init {
this.code = code
this.icon = icon
this.message = message
}
}
companion object {
val KEY_DIRECT_MESSAGES = "direct_messages"
val KEY_INTERACTIONS = "interactions"
val KEY_HOME_TIMELINE = "home_timeline"
val KEY_ACTIVITIES_BY_FRIENDS = "activities_by_friends"
val CODE_NO_DM_PERMISSION = 1
val CODE_NO_ACCESS_FOR_CREDENTIALS = 2
val CODE_NETWORK_ERROR = 3
val CODE_TIMESTAMP_ERROR = 4
fun getErrorInfo(context: Context, code: Int): DisplayErrorInfo? {
when (code) {
CODE_NO_DM_PERMISSION -> {
return DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.error_no_dm_permission))
}
CODE_NO_ACCESS_FOR_CREDENTIALS -> {
return DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.error_no_access_for_credentials))
}
CODE_NETWORK_ERROR -> {
return DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.message_toast_network_error))
}
CODE_TIMESTAMP_ERROR -> {
return DisplayErrorInfo(code, R.drawable.ic_info_error_generic,
context.getString(R.string.error_info_oauth_timestamp_error))
}
}
return null
}
}
}

View File

@ -0,0 +1,124 @@
/*
* 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
import android.content.ComponentName
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.support.v4.content.res.ResourcesCompat
import android.util.LruCache
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_EMOJI_SUPPORT
import java.util.*
/**
* Created by mariotaku on 15/12/20.
*/
class ExternalThemeManager(private val context: Context, private val preferences: SharedPreferences) {
var emoji: Emoji? = null
private set
var emojiPackageName: String? = null
private set
init {
reloadEmojiPreferences()
}
fun reloadEmojiPreferences() {
val emojiComponentName = preferences.getString(KEY_EMOJI_SUPPORT, null)
if (emojiComponentName != null) {
val componentName = ComponentName.unflattenFromString(emojiComponentName)
if (componentName != null) {
emojiPackageName = componentName.packageName
} else {
emojiPackageName = null
}
} else {
emojiPackageName = null
}
initEmojiSupport()
}
fun initEmojiSupport() {
val pkgName = emojiPackageName
if (pkgName == null) {
emoji = null
return
}
emoji = Emoji(context, pkgName)
}
class Emoji(context: Context, private val packageName: String) {
private var useMipmap: Boolean = false
private var resources: Resources? = null
private val identifierCache = LruCache<IntArray, Int>(512)
init {
initResources(context, packageName)
}
private fun initResources(context: Context, packageName: String?) {
if (packageName == null) {
useMipmap = false
resources = null
return
}
try {
val pm = context.packageManager
val info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
if (info.metaData != null) {
this.useMipmap = info.metaData.getBoolean("org.mariotaku.twidere.extension.emoji.mipmap")
}
this.resources = pm.getResourcesForApplication(info)
} catch (e: PackageManager.NameNotFoundException) {
// Ignore
}
}
fun getEmojiDrawableFor(vararg codePoints: Int): Drawable? {
val resources = resources ?: return null
val cached = identifierCache.get(codePoints)
if (cached == null) {
val sb = StringBuilder("emoji_u")
for (i in codePoints.indices) {
if (i != 0) {
sb.append("_")
}
sb.append(String.format(Locale.US, "%04x", codePoints[i]))
}
val identifier = resources.getIdentifier(sb.toString(),
if (useMipmap) "mipmap" else "drawable", packageName)
identifierCache.put(codePoints, identifier)
if (identifier == 0) return null
return ResourcesCompat.getDrawable(resources, identifier, null)
} else if (cached != 0) {
return ResourcesCompat.getDrawable(resources, cached, null)
}
return null
}
val isSupported: Boolean
get() = resources != null
}
}

View File

@ -41,7 +41,7 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.util.content.ContentResolverUtils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.util.*
import javax.inject.Inject
@ -61,7 +61,7 @@ class MultiSelectEventHandler(
private var accountActionProvider: AccountActionProvider? = null
init {
GeneralComponentHelper.build(activity).inject(this)
GeneralComponent.get(activity).inject(this)
}
/**

View File

@ -19,7 +19,6 @@
package org.mariotaku.twidere.util.dagger
import android.app.Application
import android.content.Context
import android.location.LocationManager
import android.net.ConnectivityManager
@ -71,7 +70,7 @@ import javax.inject.Singleton
* Created by mariotaku on 15/10/5.
*/
@Module
class ApplicationModule(private val application: Application) {
class ApplicationModule(private val context: Context) {
init {
if (Thread.currentThread() !== Looper.getMainLooper().thread) {
@ -82,25 +81,25 @@ class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun keyboardShortcutsHandler(): KeyboardShortcutsHandler {
return KeyboardShortcutsHandler(application)
return KeyboardShortcutsHandler(context)
}
@Provides
@Singleton
fun externalThemeManager(preferences: SharedPreferencesWrapper): ExternalThemeManager {
return ExternalThemeManager(application, preferences)
return ExternalThemeManager(context, preferences)
}
@Provides
@Singleton
fun notificationManagerWrapper(): NotificationManagerWrapper {
return NotificationManagerWrapper(application)
return NotificationManagerWrapper(context)
}
@Provides
@Singleton
fun sharedPreferences(): SharedPreferencesWrapper {
return SharedPreferencesWrapper.getInstance(application, Constants.SHARED_PREFERENCES_NAME,
return SharedPreferencesWrapper.getInstance(context, Constants.SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE, SharedPreferenceConstants::class.java)
}
@ -113,13 +112,13 @@ class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun permissionsManager(): PermissionsManager {
return PermissionsManager(application)
return PermissionsManager(context)
}
@Provides
@Singleton
fun userColorNameManager(): UserColorNameManager {
return UserColorNameManager(application)
return UserColorNameManager(context)
}
@Provides
@ -164,28 +163,28 @@ class ApplicationModule(private val application: Application) {
@Singleton
fun asyncTwitterWrapper(bus: Bus, preferences: SharedPreferencesWrapper,
asyncTaskManager: AsyncTaskManager, notificationManagerWrapper: NotificationManagerWrapper): AsyncTwitterWrapper {
return AsyncTwitterWrapper(application, bus, preferences, asyncTaskManager, notificationManagerWrapper)
return AsyncTwitterWrapper(context, bus, preferences, asyncTaskManager, notificationManagerWrapper)
}
@Provides
@Singleton
fun readStateManager(): ReadStateManager {
return ReadStateManager(application)
return ReadStateManager(context)
}
@Provides
@Singleton
fun contentNotificationManager(activityTracker: ActivityTracker, userColorNameManager: UserColorNameManager,
notificationManagerWrapper: NotificationManagerWrapper, preferences: SharedPreferencesWrapper): ContentNotificationManager {
return ContentNotificationManager(application, activityTracker, userColorNameManager, notificationManagerWrapper, preferences)
return ContentNotificationManager(context, activityTracker, userColorNameManager, notificationManagerWrapper, preferences)
}
@Provides
@Singleton
fun mediaLoaderWrapper(preferences: SharedPreferencesWrapper): MediaPreloader {
val preloader = MediaPreloader(application)
val preloader = MediaPreloader(context)
preloader.reloadOptions(preferences)
val cm = application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
preloader.isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(cm)
return preloader
}
@ -193,14 +192,14 @@ class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun dns(preferences: SharedPreferencesWrapper): Dns {
return TwidereDns(application, preferences)
return TwidereDns(context, preferences)
}
@Provides
@Singleton
fun mediaDownloader(preferences: SharedPreferencesWrapper, client: RestHttpClient,
thumbor: ThumborWrapper): MediaDownloader {
return TwidereMediaDownloader(application, client, thumbor)
return TwidereMediaDownloader(context, client, thumbor)
}
@Provides
@ -218,7 +217,7 @@ class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun errorInfoStore(): ErrorInfoStore {
return ErrorInfoStore(application)
return ErrorInfoStore(context)
}
@Provides
@ -238,30 +237,30 @@ class ApplicationModule(private val application: Application) {
@Singleton
fun autoRefreshController(kPreferences: KPreferences): AutoRefreshController {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !kPreferences[autoRefreshCompatibilityModeKey]) {
return JobSchedulerAutoRefreshController(application, kPreferences)
return JobSchedulerAutoRefreshController(context, kPreferences)
}
return LegacyAutoRefreshController(application, kPreferences)
return LegacyAutoRefreshController(context, kPreferences)
}
@Provides
@Singleton
fun syncController(): SyncController {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return JobSchedulerSyncController(application)
return JobSchedulerSyncController(context)
}
return LegacySyncController(application)
return LegacySyncController(context)
}
@Provides
@Singleton
fun syncPreferences(): SyncPreferences {
return SyncPreferences(application)
return SyncPreferences(context)
}
@Provides
@Singleton
fun taskCreator(kPreferences: KPreferences, bus: Bus): TaskServiceRunner {
return TaskServiceRunner(application, kPreferences, bus)
return TaskServiceRunner(context, kPreferences, bus)
}
@Provides
@ -275,23 +274,23 @@ class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun extraFeaturesService(): ExtraFeaturesService {
return ExtraFeaturesService.newInstance(application)
return ExtraFeaturesService.newInstance(context)
}
@Provides
@Singleton
fun etagCache(): ETagCache {
return ETagCache(application)
return ETagCache(context)
}
@Provides
fun locationManager(): LocationManager {
return application.getSystemService(Context.LOCATION_SERVICE) as LocationManager
return context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
@Provides
fun connectivityManager(): ConnectivityManager {
return application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}
@Provides
@ -310,7 +309,7 @@ class ApplicationModule(private val application: Application) {
val conf = HttpClientFactory.HttpClientConfiguration(preferences)
val builder = OkHttpClient.Builder()
HttpClientFactory.initOkHttpClient(conf, builder, dns, connectionPool, cache)
val userAgent = UserAgentUtils.getDefaultUserAgentStringSafe(application)
val userAgent = UserAgentUtils.getDefaultUserAgentStringSafe(context)
return OkHttpDataSourceFactory(builder.build(), userAgent, null)
}
@ -359,19 +358,21 @@ class ApplicationModule(private val application: Application) {
}
private fun getCacheDir(dirName: String, sizeInBytes: Long): File {
return Utils.getExternalCacheDir(application, dirName, sizeInBytes) ?:
Utils.getInternalCacheDir(application, dirName)
return Utils.getExternalCacheDir(context, dirName, sizeInBytes) ?:
Utils.getInternalCacheDir(context, dirName)
}
companion object {
private var sApplicationModule: ApplicationModule? = null
private var instance: ApplicationModule? = null
fun get(context: Context): ApplicationModule {
if (sApplicationModule != null) return sApplicationModule!!
val application = context.applicationContext as Application
sApplicationModule = ApplicationModule(application)
return sApplicationModule!!
return instance ?: run {
val module = ApplicationModule(context.applicationContext)
instance = module
return@run module
}
}
}
}

View File

@ -84,7 +84,7 @@ class DependencyHolder internal constructor(context: Context) {
internal set
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
companion object {

View File

@ -19,6 +19,7 @@
package org.mariotaku.twidere.util.dagger
import android.content.Context
import android.support.v7.widget.RecyclerView
import dagger.Component
import org.mariotaku.twidere.activity.BaseActivity
@ -143,4 +144,16 @@ interface GeneralComponent {
fun inject(service: StreamingService)
fun inject(service: BaseService)
companion object {
private var instance: GeneralComponent? = null
fun get(context: Context): GeneralComponent {
return instance ?: run {
val helper = DaggerGeneralComponent.builder().applicationModule(ApplicationModule.get(context)).build()
instance = helper
return@run helper
}
}
}
}

View File

@ -14,7 +14,7 @@ import org.mariotaku.twidere.extension.newPullParser
import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.util.ETagCache
import org.mariotaku.twidere.util.JsonSerializer
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.io.IOException
import javax.inject.Inject
@ -30,7 +30,7 @@ class UrlFiltersSubscriptionProvider(context: Context, val arguments: Arguments)
private var filters: FiltersData? = null
init {
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
@Throws(IOException::class)

View File

@ -5,7 +5,7 @@ import com.squareup.otto.Bus
import nl.komponents.kovenant.task
import org.mariotaku.twidere.util.TaskServiceRunner
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.dagger.GeneralComponent
import java.util.*
import javax.inject.Inject
@ -23,7 +23,7 @@ abstract class SyncTaskRunner(val context: Context) {
init {
@Suppress("LeakingThis")
GeneralComponentHelper.build(context).inject(this)
GeneralComponent.get(context).inject(this)
}
/**