parent
ce02395841
commit
993e95b08c
|
@ -1,22 +0,0 @@
|
|||
package org.mariotaku.twidere.util
|
||||
|
||||
import org.apache.commons.lang3.reflect.TypeUtils
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mariotaku.microblog.library.twitter.model.CursorTimestampResponse
|
||||
import org.mariotaku.microblog.library.twitter.model.ResponseList
|
||||
import org.mariotaku.microblog.library.twitter.model.Status
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/15.
|
||||
*/
|
||||
class TwidereTypeUtilsTest {
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testGetSimpleName() {
|
||||
assertEquals("CursorTimestampResponse", TwidereTypeUtils.toSimpleName(CursorTimestampResponse::class.java))
|
||||
assertEquals("ResponseList<Status>", TwidereTypeUtils.toSimpleName(TypeUtils.parameterize(ResponseList::class.java, Status::class.java)))
|
||||
assertEquals("List<List<Object>>", TwidereTypeUtils.toSimpleName(TypeUtils.parameterize(List::class.java, TypeUtils.parameterize(List::class.java, Any::class.java))))
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ public class ThemedListPreferenceDialogFragmentCompat extends ThemedPreferenceDi
|
|||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||
super.onPrepareDialogBuilder(builder);
|
||||
final ListPreference preference = getListPreference();
|
||||
final String[] entries = TwidereArrayUtils.toStringArray(preference.getEntries());
|
||||
final CharSequence[] entries = preference.getEntries();
|
||||
if (entries == null || preference.getEntryValues() == null) {
|
||||
throw new IllegalStateException(
|
||||
"ListPreference requires an entries array and an entryValues array.");
|
||||
|
|
|
@ -1,93 +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.model;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.util.TwidereArrayUtils;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/3/25.
|
||||
*/
|
||||
public class StringLongPair {
|
||||
@NonNull
|
||||
private final String key;
|
||||
private long value;
|
||||
|
||||
public StringLongPair(@NonNull String key, long value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
StringLongPair that = (StringLongPair) o;
|
||||
|
||||
return key.equals(that.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + ":" + value;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static StringLongPair valueOf(@NonNull String s) throws NumberFormatException {
|
||||
final String[] segs = s.split(":");
|
||||
if (segs.length != 2) throw new NumberFormatException();
|
||||
return new StringLongPair(segs[0], Long.parseLong(segs[1]));
|
||||
}
|
||||
|
||||
public static String toString(StringLongPair[] pairs) {
|
||||
if (pairs == null) return null;
|
||||
return TwidereArrayUtils.toString(pairs, ';', false);
|
||||
}
|
||||
|
||||
public static StringLongPair[] valuesOf(String s) throws NumberFormatException {
|
||||
if (s == null) return null;
|
||||
final String[] segs = s.split(";");
|
||||
final StringLongPair[] pairs = new StringLongPair[segs.length];
|
||||
for (int i = 0, j = segs.length; i < j; i++) {
|
||||
pairs[i] = valueOf(segs[i]);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
}
|
|
@ -1,48 +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;
|
||||
|
||||
import android.support.annotation.CheckResult;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/7.
|
||||
*/
|
||||
public class CollectionUtils {
|
||||
|
||||
private CollectionUtils() {
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
public static <T> String toString(final Collection<T> collection, final char token, final boolean includeSpace) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
int i = 0;
|
||||
for (T item : collection) {
|
||||
final String itemString = String.valueOf(item);
|
||||
if (i > 0) {
|
||||
builder.append(includeSpace ? token + " " : token);
|
||||
}
|
||||
builder.append(itemString);
|
||||
i++;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -1,56 +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;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
public class MediaLoadingHandler {
|
||||
|
||||
private final SparseArray<String> mLoadingUris = new SparseArray<>();
|
||||
private final int[] mProgressBarIds;
|
||||
|
||||
public MediaLoadingHandler() {
|
||||
this(R.id.media_preview_progress);
|
||||
}
|
||||
|
||||
public MediaLoadingHandler(final int... progressBarIds) {
|
||||
mProgressBarIds = progressBarIds;
|
||||
}
|
||||
|
||||
public String getLoadingUri(final View view) {
|
||||
return mLoadingUris.get(System.identityHashCode(view));
|
||||
}
|
||||
|
||||
private ProgressBar findProgressBar(final ViewParent viewParent) {
|
||||
if (mProgressBarIds == null || !(viewParent instanceof View)) return null;
|
||||
final View parent = (View) viewParent;
|
||||
for (final int id : mProgressBarIds) {
|
||||
final View progress = parent.findViewById(id);
|
||||
if (progress instanceof ProgressBar) return (ProgressBar) progress;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -69,19 +69,6 @@ public final class TwidereArrayUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static String toString(final long[] array, final char token, final boolean include_space) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String idString = String.valueOf(array[i]);
|
||||
if (i > 0) {
|
||||
builder.append(include_space ? token + " " : token);
|
||||
}
|
||||
builder.append(idString);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String toString(final Object[] array, final char token, final boolean include_space) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
|
@ -106,14 +93,4 @@ public final class TwidereArrayUtils {
|
|||
return stringArray;
|
||||
}
|
||||
|
||||
public static String[] toStringArray(final Object array) {
|
||||
return toStringArray(array, 0, Array.getLength(array));
|
||||
}
|
||||
|
||||
|
||||
public static void offset(long[] array, long offset) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] += offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package org.mariotaku.twidere.util;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/15.
|
||||
*/
|
||||
public class TwidereTypeUtils {
|
||||
|
||||
private TwidereTypeUtils() {
|
||||
}
|
||||
|
||||
public static String toSimpleName(Type type) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
buildSimpleName(type, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void buildSimpleName(Type type, StringBuilder sb) {
|
||||
if (type instanceof Class) {
|
||||
sb.append(((Class) type).getSimpleName());
|
||||
} else if (type instanceof ParameterizedType) {
|
||||
buildSimpleName(((ParameterizedType) type).getRawType(), sb);
|
||||
sb.append("<");
|
||||
final Type[] args = ((ParameterizedType) type).getActualTypeArguments();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (i != 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
buildSimpleName(args[i], sb);
|
||||
}
|
||||
sb.append(">");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,10 +31,6 @@ public class UriUtils {
|
|||
private UriUtils() {
|
||||
}
|
||||
|
||||
public static Uri appendQueryParameters(final Uri uri, final String key, long value) {
|
||||
return appendQueryParameters(uri, key, String.valueOf(value));
|
||||
}
|
||||
|
||||
public static Uri appendQueryParameters(final Uri uri, final String key, String value) {
|
||||
final Uri.Builder builder = uri.buildUpon();
|
||||
builder.appendQueryParameter(key, value);
|
||||
|
|
|
@ -493,13 +493,6 @@ public final class Utils implements Constants {
|
|||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getNonEmptyString(final SharedPreferences pref, final String key, final String def) {
|
||||
if (pref == null) return def;
|
||||
final String val = pref.getString(key, def);
|
||||
return TextUtils.isEmpty(val) ? def : val;
|
||||
}
|
||||
|
||||
public static String getNormalTwitterProfileImage(final String url) {
|
||||
return getTwitterProfileImageOfSize(url, "normal");
|
||||
}
|
||||
|
|
|
@ -1,161 +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.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.mariotaku.chameleon.Chameleon;
|
||||
import org.mariotaku.chameleon.ChameleonView;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.support.TextViewSupport;
|
||||
import org.mariotaku.twidere.view.iface.IIconActionButton;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/20.
|
||||
*/
|
||||
public class ActionIconThemedTextView extends AppCompatTextView implements IIconActionButton {
|
||||
|
||||
private int mIconWidth, mIconHeight;
|
||||
@ColorInt
|
||||
private int mColor;
|
||||
@ColorInt
|
||||
private int mDisabledColor;
|
||||
@ColorInt
|
||||
private int mActivatedColor;
|
||||
|
||||
public ActionIconThemedTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ActionIconThemedTextView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.textViewStyle);
|
||||
}
|
||||
|
||||
public ActionIconThemedTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public void init(Context context, AttributeSet attrs) {
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton,
|
||||
R.attr.cardActionButtonStyle, R.style.Widget_CardActionButton);
|
||||
mColor = a.getColor(R.styleable.IconActionButton_iabColor, 0);
|
||||
mDisabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0);
|
||||
mActivatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0);
|
||||
mIconWidth = a.getDimensionPixelSize(R.styleable.IconActionButton_iabIconWidth, 0);
|
||||
mIconHeight = a.getDimensionPixelSize(R.styleable.IconActionButton_iabIconHeight, 0);
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
@Override
|
||||
public int getDefaultColor() {
|
||||
if (mColor != 0) return mColor;
|
||||
final ColorStateList colors = getTextColors();
|
||||
if (colors != null) return colors.getDefaultColor();
|
||||
return getCurrentTextColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultColor(@ColorInt int color) {
|
||||
this.mColor = color;
|
||||
refreshDrawableState();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
@Override
|
||||
public int getActivatedColor() {
|
||||
if (mActivatedColor != 0) return mActivatedColor;
|
||||
final ColorStateList colors = getLinkTextColors();
|
||||
if (colors != null) return colors.getDefaultColor();
|
||||
return getCurrentTextColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivatedColor(@ColorInt int color) {
|
||||
this.mActivatedColor = color;
|
||||
refreshDrawableState();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
@Override
|
||||
public int getDisabledColor() {
|
||||
if (mDisabledColor != 0) return mDisabledColor;
|
||||
final ColorStateList colors = getTextColors();
|
||||
if (colors != null) return colors.getColorForState(new int[0], colors.getDefaultColor());
|
||||
return getCurrentTextColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisabledColor(@ColorInt int color) {
|
||||
this.mDisabledColor = color;
|
||||
refreshDrawableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshDrawableState() {
|
||||
updateCompoundDrawables();
|
||||
super.refreshDrawableState();
|
||||
}
|
||||
|
||||
private void updateCompoundDrawables() {
|
||||
for (Drawable d : TextViewSupport.getCompoundDrawablesRelative(this)) {
|
||||
if (d == null) continue;
|
||||
d.mutate();
|
||||
final int color;
|
||||
if (isActivated()) {
|
||||
color = getActivatedColor();
|
||||
} else if (isEnabled()) {
|
||||
color = getDefaultColor();
|
||||
} else {
|
||||
color = getDisabledColor();
|
||||
}
|
||||
if (mIconWidth > 0 && mIconHeight > 0) {
|
||||
d.setBounds(0, 0, mIconWidth, mIconHeight);
|
||||
}
|
||||
d.setColorFilter(color, Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostApplyTheme() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Appearance createAppearance(@NonNull Context context, @NonNull AttributeSet attributeSet, @NonNull Chameleon.Theme theme) {
|
||||
return IIconActionButton.Appearance.create(context, attributeSet, theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyAppearance(@NonNull ChameleonView.Appearance appearance) {
|
||||
IIconActionButton.Appearance.apply(this, (Appearance) appearance);
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.AppCompatImageButton;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.mariotaku.chameleon.Chameleon;
|
||||
import org.mariotaku.chameleon.ChameleonView;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.view.iface.IIconActionButton;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public class IconActionButton extends AppCompatImageButton implements IIconActionButton {
|
||||
|
||||
@ColorInt
|
||||
private int mDefaultColor, mActivatedColor, mDisabledColor;
|
||||
|
||||
public IconActionButton(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public IconActionButton(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.imageButtonStyle);
|
||||
}
|
||||
|
||||
public IconActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton,
|
||||
R.attr.cardActionButtonStyle, R.style.Widget_CardActionButton);
|
||||
mDefaultColor = a.getColor(R.styleable.IconActionButton_iabColor, 0);
|
||||
mActivatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0);
|
||||
mDisabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0);
|
||||
a.recycle();
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getDefaultColor() {
|
||||
if (mDefaultColor == 0) {
|
||||
// Return inverse color for background tint
|
||||
ColorStateList color = ViewCompat.getBackgroundTintList(this);
|
||||
if (color != null) {
|
||||
final int currentColor = color.getColorForState(getDrawableState(), 0);
|
||||
return ThemeUtils.getContrastColor(currentColor, Color.BLACK, Color.WHITE);
|
||||
}
|
||||
}
|
||||
return mDefaultColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getActivatedColor() {
|
||||
if (mActivatedColor != 0) return mActivatedColor;
|
||||
return getDefaultColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getDisabledColor() {
|
||||
if (mDisabledColor != 0) return mDisabledColor;
|
||||
return getDefaultColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultColor(@ColorInt int defaultColor) {
|
||||
mDefaultColor = defaultColor;
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivatedColor(@ColorInt int activatedColor) {
|
||||
mActivatedColor = activatedColor;
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisabledColor(@ColorInt int disabledColor) {
|
||||
mDisabledColor = disabledColor;
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivated(boolean activated) {
|
||||
super.setActivated(activated);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
private void updateColorFilter() {
|
||||
if (isActivated()) {
|
||||
setColorFilter(getActivatedColor());
|
||||
} else if (isEnabled()) {
|
||||
setColorFilter(getDefaultColor());
|
||||
} else {
|
||||
setColorFilter(getDisabledColor());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostApplyTheme() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Appearance createAppearance(@NonNull Context context, @NonNull AttributeSet attributeSet, @NonNull Chameleon.Theme theme) {
|
||||
return IIconActionButton.Appearance.create(context, attributeSet, theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyAppearance(@NonNull ChameleonView.Appearance appearance) {
|
||||
IIconActionButton.Appearance.apply(this, (Appearance) appearance);
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.mariotaku.chameleon.Chameleon;
|
||||
import org.mariotaku.chameleon.ChameleonView;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.view.iface.IIconActionButton;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public class IconActionView extends AppCompatImageView implements IIconActionButton {
|
||||
|
||||
@ColorInt
|
||||
private int mDefaultColor, mActivatedColor, mDisabledColor;
|
||||
|
||||
public IconActionView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public IconActionView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public IconActionView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
if (isInEditMode()) return;
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton,
|
||||
R.attr.cardActionButtonStyle, R.style.Widget_CardActionButton);
|
||||
mDefaultColor = a.getColor(R.styleable.IconActionButton_iabColor, 0);
|
||||
mActivatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0);
|
||||
mDisabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0);
|
||||
a.recycle();
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getDefaultColor() {
|
||||
if (mDefaultColor == 0) {
|
||||
// Return inverse color for background tint
|
||||
ColorStateList color = ViewCompat.getBackgroundTintList(this);
|
||||
if (color != null) {
|
||||
final int currentColor = color.getColorForState(getDrawableState(), 0);
|
||||
return ThemeUtils.getContrastColor(currentColor, Color.BLACK, Color.WHITE);
|
||||
}
|
||||
}
|
||||
return mDefaultColor;
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getActivatedColor() {
|
||||
if (mActivatedColor != 0) return mActivatedColor;
|
||||
return getDefaultColor();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getDisabledColor() {
|
||||
if (mDisabledColor != 0) return mDisabledColor;
|
||||
return getDefaultColor();
|
||||
}
|
||||
|
||||
public void setDefaultColor(@ColorInt int defaultColor) {
|
||||
mDefaultColor = defaultColor;
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
public void setActivatedColor(@ColorInt int activatedColor) {
|
||||
mActivatedColor = activatedColor;
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
public void setDisabledColor(@ColorInt int disabledColor) {
|
||||
mDisabledColor = disabledColor;
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivated(boolean activated) {
|
||||
super.setActivated(activated);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
private void updateColorFilter() {
|
||||
if (isActivated()) {
|
||||
setColorFilter(getActivatedColor());
|
||||
} else if (isEnabled()) {
|
||||
setColorFilter(getDefaultColor());
|
||||
} else {
|
||||
setColorFilter(getDisabledColor());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostApplyTheme() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Appearance createAppearance(@NonNull Context context, @NonNull AttributeSet attributeSet, @NonNull Chameleon.Theme theme) {
|
||||
return IIconActionButton.Appearance.create(context, attributeSet, theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyAppearance(@NonNull ChameleonView.Appearance appearance) {
|
||||
IIconActionButton.Appearance.apply(this, (Appearance) appearance);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
package org.mariotaku.twidere.view.iface;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.mariotaku.chameleon.Chameleon;
|
||||
import org.mariotaku.chameleon.ChameleonView;
|
||||
import org.mariotaku.chameleon.internal.ChameleonTypedArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/19.
|
||||
*/
|
||||
public interface IIconActionButton extends ChameleonView {
|
||||
@ColorInt
|
||||
int getDefaultColor();
|
||||
|
||||
@ColorInt
|
||||
int getActivatedColor();
|
||||
|
||||
@ColorInt
|
||||
int getDisabledColor();
|
||||
|
||||
void setDefaultColor(@ColorInt int defaultColor);
|
||||
|
||||
void setActivatedColor(@ColorInt int activatedColor);
|
||||
|
||||
void setDisabledColor(@ColorInt int disabledColor);
|
||||
|
||||
|
||||
class Appearance implements ChameleonView.Appearance {
|
||||
@ColorInt
|
||||
private int defaultColor, activatedColor, disabledColor;
|
||||
|
||||
public int getActivatedColor() {
|
||||
return activatedColor;
|
||||
}
|
||||
|
||||
public void setActivatedColor(int activatedColor) {
|
||||
this.activatedColor = activatedColor;
|
||||
}
|
||||
|
||||
public int getDefaultColor() {
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
public void setDefaultColor(int defaultColor) {
|
||||
this.defaultColor = defaultColor;
|
||||
}
|
||||
|
||||
public int getDisabledColor() {
|
||||
return disabledColor;
|
||||
}
|
||||
|
||||
public void setDisabledColor(int disabledColor) {
|
||||
this.disabledColor = disabledColor;
|
||||
}
|
||||
|
||||
public static Appearance create(Context context, AttributeSet attributeSet, Chameleon.Theme theme) {
|
||||
Appearance appearance = new Appearance();
|
||||
ChameleonTypedArray a = ChameleonTypedArray.obtain(context, attributeSet, R.styleable.IconActionButton, theme);
|
||||
appearance.setDefaultColor(a.getColor(R.styleable.IconActionButton_iabColor, 0, false));
|
||||
appearance.setActivatedColor(a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0, false));
|
||||
appearance.setDisabledColor(a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0, false));
|
||||
a.recycle();
|
||||
return appearance;
|
||||
}
|
||||
|
||||
public static void apply(IIconActionButton view, Appearance appearance) {
|
||||
final int defaultColor = appearance.getDefaultColor();
|
||||
if (defaultColor != 0) {
|
||||
view.setDefaultColor(defaultColor);
|
||||
}
|
||||
final int activatedColor = appearance.getActivatedColor();
|
||||
if (activatedColor != 0) {
|
||||
view.setActivatedColor(activatedColor);
|
||||
}
|
||||
final int disabledColor = appearance.getDisabledColor();
|
||||
if (disabledColor != 0) {
|
||||
view.setDisabledColor(disabledColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@ import org.mariotaku.twidere.constant.chromeCustomTabKey
|
|||
import org.mariotaku.twidere.constant.defaultAPIConfigKey
|
||||
import org.mariotaku.twidere.constant.randomizeAccountNameKey
|
||||
import org.mariotaku.twidere.extension.applyTheme
|
||||
import org.mariotaku.twidere.extension.getNonEmptyString
|
||||
import org.mariotaku.twidere.extension.model.getColor
|
||||
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
||||
import org.mariotaku.twidere.extension.model.official
|
||||
|
@ -454,12 +455,12 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, APIEditorDi
|
|||
private fun setDefaultAPI() {
|
||||
val apiLastChange = preferences.getLong(KEY_API_LAST_CHANGE, apiChangeTimestamp)
|
||||
val defaultApiChanged = apiLastChange != apiChangeTimestamp
|
||||
val apiUrlFormat = Utils.getNonEmptyString(preferences, KEY_API_URL_FORMAT, DEFAULT_TWITTER_API_URL_FORMAT)
|
||||
val apiUrlFormat = preferences.getNonEmptyString(KEY_API_URL_FORMAT, DEFAULT_TWITTER_API_URL_FORMAT)
|
||||
val authType = preferences.getString(KEY_CREDENTIALS_TYPE, Credentials.Type.OAUTH)
|
||||
val sameOAuthSigningUrl = preferences.getBoolean(KEY_SAME_OAUTH_SIGNING_URL, false)
|
||||
val noVersionSuffix = preferences.getBoolean(KEY_NO_VERSION_SUFFIX, false)
|
||||
val consumerKey = Utils.getNonEmptyString(preferences, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY)
|
||||
val consumerSecret = Utils.getNonEmptyString(preferences, KEY_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET)
|
||||
val consumerKey = preferences.getNonEmptyString(KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY)
|
||||
val consumerSecret = preferences.getNonEmptyString(KEY_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET)
|
||||
if (TextUtils.isEmpty(apiConfig.apiUrlFormat) || defaultApiChanged) {
|
||||
apiConfig.apiUrlFormat = apiUrlFormat
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ class DraftsAdapter(
|
|||
@Inject
|
||||
lateinit var preferences: SharedPreferencesWrapper
|
||||
|
||||
private val mediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
|
||||
private val mediaPreviewStyle: Int
|
||||
|
||||
var textSize: Float = 0f
|
||||
|
@ -78,7 +77,7 @@ class DraftsAdapter(
|
|||
val media = ParcelableMediaUtils.fromMediaUpdates(draft.media)
|
||||
holder.mediaPreviewContainer.visibility = View.VISIBLE
|
||||
holder.mediaPreviewContainer.displayMedia(requestManager = requestManager,
|
||||
media = media, loadingHandler = mediaLoadingHandler)
|
||||
media = media)
|
||||
}
|
||||
Draft.Action.FAVORITE, Draft.Action.RETWEET -> {
|
||||
val extras = draft.action_extras as? StatusObjectExtras
|
||||
|
|
|
@ -36,7 +36,6 @@ class DummyItemAdapter(
|
|||
override lateinit var userColorNameManager: UserColorNameManager
|
||||
@Inject
|
||||
override lateinit var bidiFormatter: BidiFormatter
|
||||
override val mediaLoadingHandler: MediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
|
||||
|
||||
override var profileImageStyle: Int = 0
|
||||
override var mediaPreviewStyle: Int = 0
|
||||
|
|
|
@ -4,7 +4,6 @@ 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
|
||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||
|
@ -17,9 +16,6 @@ class ListParcelableStatusesAdapter(
|
|||
requestManager: RequestManager
|
||||
) : ParcelableStatusesAdapter(context, requestManager) {
|
||||
|
||||
override val progressViewIds: IntArray
|
||||
get() = intArrayOf(R.id.media_preview_progress)
|
||||
|
||||
override fun onCreateStatusViewHolder(parent: ViewGroup): IStatusViewHolder {
|
||||
return createStatusViewHolder(this, inflater, parent)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.mariotaku.twidere.extension.model.timestamp
|
|||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.ParcelableMessage.MessageType
|
||||
import org.mariotaku.twidere.util.DirectMessageOnLinkClickHandler
|
||||
import org.mariotaku.twidere.util.MediaLoadingHandler
|
||||
import org.mariotaku.twidere.util.TwidereLinkify
|
||||
import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener
|
||||
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
|
||||
|
@ -60,7 +59,6 @@ class MessagesConversationAdapter(
|
|||
val linkHighlightingStyle: Int = preferences[linkHighlightOptionKey]
|
||||
val nameFirst: Boolean = preferences[nameFirstKey]
|
||||
val linkify: TwidereLinkify = TwidereLinkify(DirectMessageOnLinkClickHandler(context, null, preferences))
|
||||
val mediaLoadingHandler: MediaLoadingHandler = MediaLoadingHandler()
|
||||
val mediaClickListener: OnMediaClickListener = object : OnMediaClickListener {
|
||||
override fun onMediaClick(view: View, media: ParcelableMedia, accountKey: UserKey?, id: Long) {
|
||||
listener?.onMediaClick(id.toInt(), media, accountKey)
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.mariotaku.twidere.model.*
|
|||
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
|
||||
import org.mariotaku.twidere.model.util.getActivityStatus
|
||||
import org.mariotaku.twidere.util.IntentUtils
|
||||
import org.mariotaku.twidere.util.MediaLoadingHandler
|
||||
import org.mariotaku.twidere.util.OnLinkClickHandler
|
||||
import org.mariotaku.twidere.util.TwidereLinkify
|
||||
import org.mariotaku.twidere.view.holder.*
|
||||
|
@ -60,8 +59,6 @@ class ParcelableActivitiesAdapter(
|
|||
requestManager: RequestManager
|
||||
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, requestManager), IActivitiesAdapter<List<ParcelableActivity>> {
|
||||
|
||||
override val mediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
|
||||
|
||||
private val inflater = LayoutInflater.from(context)
|
||||
private val twidereLinkify = TwidereLinkify(OnLinkClickHandler(context, null, preferences))
|
||||
private val statusAdapterDelegate = DummyItemAdapter(context, twidereLinkify, this, requestManager)
|
||||
|
@ -229,8 +226,7 @@ class ParcelableActivitiesAdapter(
|
|||
ITEM_VIEW_TYPE_STATUS -> {
|
||||
val status = getActivity(position)?.getActivityStatus() ?: return
|
||||
val statusViewHolder = holder as IStatusViewHolder
|
||||
statusViewHolder.displayStatus(status = status, displayInReplyTo = true,
|
||||
displayExtraType = true)
|
||||
statusViewHolder.displayStatus(status = status, displayInReplyTo = true)
|
||||
}
|
||||
ITEM_VIEW_TYPE_TITLE_SUMMARY -> {
|
||||
bindTitleSummaryViewHolder(holder as ActivityTitleSummaryViewHolder, position)
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.mariotaku.twidere.annotation.PreviewStyle
|
|||
import org.mariotaku.twidere.constant.*
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_DISPLAY_SENSITIVE_CONTENTS
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.util.MediaLoadingHandler
|
||||
import org.mariotaku.twidere.util.StatusAdapterLinkClickHandler
|
||||
import org.mariotaku.twidere.util.TwidereLinkify
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
@ -63,7 +62,6 @@ abstract class ParcelableStatusesAdapter(
|
|||
|
||||
protected val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
|
||||
override final val mediaLoadingHandler: MediaLoadingHandler
|
||||
final override val twidereLinkify: TwidereLinkify
|
||||
@PreviewStyle
|
||||
final override val mediaPreviewStyle: Int = preferences[mediaPreviewStyleKey]
|
||||
|
@ -117,8 +115,6 @@ abstract class ParcelableStatusesAdapter(
|
|||
|
||||
override val itemCounts = ItemCounts(4)
|
||||
|
||||
protected abstract val progressViewIds: IntArray
|
||||
|
||||
val statusStartIndex: Int
|
||||
get() = getItemStartPosition(ITEM_INDEX_STATUS)
|
||||
|
||||
|
@ -137,7 +133,6 @@ abstract class ParcelableStatusesAdapter(
|
|||
}
|
||||
|
||||
init {
|
||||
mediaLoadingHandler = MediaLoadingHandler(*progressViewIds)
|
||||
val handler = StatusAdapterLinkClickHandler<List<ParcelableStatus>>(context, preferences)
|
||||
twidereLinkify = TwidereLinkify(handler)
|
||||
handler.setAdapter(this)
|
||||
|
|
|
@ -33,9 +33,6 @@ class StaggeredGridParcelableStatusesAdapter(
|
|||
requestManager: RequestManager
|
||||
) : ParcelableStatusesAdapter(context, requestManager) {
|
||||
|
||||
override val progressViewIds: IntArray
|
||||
get() = intArrayOf(R.id.mediaImageProgress)
|
||||
|
||||
override fun onCreateStatusViewHolder(parent: ViewGroup): IStatusViewHolder {
|
||||
val view = inflater.inflate(R.layout.adapter_item_media_status, parent, false)
|
||||
val holder = MediaStatusViewHolder(this, view)
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.mariotaku.twidere.adapter.iface
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableActivity
|
||||
import org.mariotaku.twidere.util.MediaLoadingHandler
|
||||
import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder
|
||||
|
||||
/**
|
||||
|
@ -32,8 +31,6 @@ interface IActivitiesAdapter<in Data> : IContentAdapter, IGapSupportedAdapter {
|
|||
|
||||
val mediaPreviewStyle: Int
|
||||
|
||||
val mediaLoadingHandler: MediaLoadingHandler
|
||||
|
||||
val mediaPreviewEnabled: Boolean
|
||||
|
||||
val activityEventListener: ActivityEventListener?
|
||||
|
|
|
@ -3,9 +3,7 @@ package org.mariotaku.twidere.adapter.iface
|
|||
import org.mariotaku.twidere.annotation.PreviewStyle
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.util.MediaLoadingHandler
|
||||
import org.mariotaku.twidere.util.TwidereLinkify
|
||||
import org.mariotaku.twidere.view.CardMediaContainer
|
||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||
|
||||
/**
|
||||
|
@ -37,8 +35,6 @@ interface IStatusesAdapter<in Data> : IContentAdapter, IGapSupportedAdapter {
|
|||
|
||||
val useStarsForLikes: Boolean
|
||||
|
||||
val mediaLoadingHandler: MediaLoadingHandler
|
||||
|
||||
val statusClickListener: IStatusViewHolder.StatusClickListener?
|
||||
|
||||
fun isCardActionsShown(position: Int): Boolean
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package org.mariotaku.twidere.extension
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.text.TextUtils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/8/25.
|
||||
*/
|
||||
fun SharedPreferences.getNonEmptyString(key: String, def: String): String {
|
||||
val v = getString(key, def)
|
||||
return if (TextUtils.isEmpty(v)) def else v
|
||||
return getString(key, def)?.takeUnless(String::isEmpty) ?: def
|
||||
}
|
|
@ -94,7 +94,7 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
val adapter = DummyItemAdapter(context, requestManager = Glide.with(this))
|
||||
adapter.setShouldShowAccountsColor(true)
|
||||
val holder = StatusViewHolder(adapter, itemContent)
|
||||
holder.displayStatus(status = status, displayInReplyTo = false, displayExtraType = true)
|
||||
holder.displayStatus(status = status, displayInReplyTo = false)
|
||||
|
||||
textCountView.maxLength = details.textLimit
|
||||
|
||||
|
|
|
@ -1020,8 +1020,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
|
|||
itemView.mediaPreview.visibility = View.VISIBLE
|
||||
itemView.mediaPreviewLoad.visibility = View.GONE
|
||||
itemView.mediaPreview.displayMedia(adapter.requestManager, media = media,
|
||||
accountId = status.account_key, mediaClickListener = adapter.fragment,
|
||||
loadingHandler = adapter.mediaLoadingHandler)
|
||||
accountId = status.account_key, mediaClickListener = adapter.fragment)
|
||||
} else {
|
||||
itemView.mediaPreviewContainer.visibility = View.VISIBLE
|
||||
itemView.mediaPreview.visibility = View.GONE
|
||||
|
@ -1487,7 +1486,6 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
|
|||
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
|
||||
|
||||
override var statusClickListener: StatusClickListener? = null
|
||||
|
|
|
@ -44,14 +44,12 @@ import org.mariotaku.twidere.model.util.ParcelableStatusUtils
|
|||
import org.mariotaku.twidere.task.twitter.GetStatusesTask
|
||||
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.*
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -218,10 +216,7 @@ abstract class MicroBlogAPIStatusesLoader(
|
|||
}
|
||||
|
||||
private val serializationKey: String?
|
||||
get() {
|
||||
if (savedStatusesArgs == null) return null
|
||||
return TwidereArrayUtils.toString(savedStatusesArgs, '_', false)
|
||||
}
|
||||
get() = savedStatusesArgs?.joinToString("_")
|
||||
|
||||
private fun saveCachedData(data: List<ParcelableStatus>?) {
|
||||
val key = serializationKey
|
||||
|
@ -239,9 +234,4 @@ abstract class MicroBlogAPIStatusesLoader(
|
|||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val pool = Executors.newSingleThreadExecutor()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,18 +19,33 @@
|
|||
|
||||
package org.mariotaku.twidere.util.cache
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import com.bluelinelabs.logansquare.LoganSquare
|
||||
import com.bumptech.glide.disklrucache.DiskLruCache
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/3/1.
|
||||
*/
|
||||
|
||||
class JsonCache {
|
||||
fun <T> getList(key: String, cls: Class<T>): List<T>? {
|
||||
return emptyList()
|
||||
class JsonCache(val cacheDir: File) {
|
||||
|
||||
private val cache = try {
|
||||
DiskLruCache.open(cacheDir, BuildConfig.VERSION_CODE, 1, 100 * 1048576)
|
||||
} catch (e: IOException) {
|
||||
null
|
||||
}
|
||||
|
||||
fun <T> saveList(key: String, list: List<T>, cls: Class<ParcelableStatus>) {
|
||||
fun <T> getList(key: String, cls: Class<T>): List<T>? {
|
||||
return cache?.get(key)?.getFile(0)?.inputStream()?.use {
|
||||
LoganSquare.parseList(it, cls)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> saveList(key: String, list: List<T>, cls: Class<T>) {
|
||||
cache?.get(key)?.getFile(0)?.outputStream()?.use {
|
||||
LoganSquare.serialize(list, it, cls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ class ApplicationModule(private val application: Application) {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun jsonCache(): JsonCache {
|
||||
return JsonCache()
|
||||
return JsonCache(getCacheDir("json"))
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff.Mode
|
||||
import android.support.annotation.ColorInt
|
||||
import android.support.v7.widget.AppCompatTextView
|
||||
import android.util.AttributeSet
|
||||
import org.mariotaku.chameleon.Chameleon
|
||||
import org.mariotaku.chameleon.ChameleonView
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.util.support.TextViewSupport
|
||||
import org.mariotaku.twidere.view.iface.IIconActionButton
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/20.
|
||||
*/
|
||||
class ActionIconThemedTextView(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : AppCompatTextView(context, attrs, android.R.attr.textViewStyle), IIconActionButton {
|
||||
|
||||
private var iconWidth: Int = 0
|
||||
private var iconHeight: Int = 0
|
||||
|
||||
override var defaultColor: Int = 0
|
||||
@ColorInt get() {
|
||||
if (field != 0) return field
|
||||
val colors = textColors
|
||||
if (colors != null) return colors.defaultColor
|
||||
return currentTextColor
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
refreshDrawableState()
|
||||
}
|
||||
|
||||
override var disabledColor: Int = 0
|
||||
@ColorInt get() {
|
||||
if (field != 0) return field
|
||||
val colors = textColors
|
||||
if (colors != null) return colors.getColorForState(IntArray(0), colors.defaultColor)
|
||||
return currentTextColor
|
||||
}
|
||||
@ColorInt set(value) {
|
||||
field = value
|
||||
refreshDrawableState()
|
||||
}
|
||||
|
||||
override var activatedColor: Int = 0
|
||||
@ColorInt get() {
|
||||
if (field != 0) return field
|
||||
val colors = linkTextColors
|
||||
if (colors != null) return colors.defaultColor
|
||||
return currentTextColor
|
||||
}
|
||||
@ColorInt set(value) {
|
||||
field = value
|
||||
refreshDrawableState()
|
||||
}
|
||||
|
||||
init {
|
||||
@SuppressLint("CustomViewStyleable")
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton,
|
||||
R.attr.cardActionButtonStyle, R.style.Widget_CardActionButton)
|
||||
defaultColor = a.getColor(R.styleable.IconActionButton_iabColor, 0)
|
||||
disabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0)
|
||||
activatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0)
|
||||
iconWidth = a.getDimensionPixelSize(R.styleable.IconActionButton_iabIconWidth, 0)
|
||||
iconHeight = a.getDimensionPixelSize(R.styleable.IconActionButton_iabIconHeight, 0)
|
||||
a.recycle()
|
||||
}
|
||||
|
||||
|
||||
override fun refreshDrawableState() {
|
||||
updateCompoundDrawables()
|
||||
super.refreshDrawableState()
|
||||
}
|
||||
|
||||
private fun updateCompoundDrawables() {
|
||||
for (d in TextViewSupport.getCompoundDrawablesRelative(this)) {
|
||||
if (d == null) continue
|
||||
d.mutate()
|
||||
val color: Int
|
||||
if (isActivated) {
|
||||
color = activatedColor
|
||||
} else if (isEnabled) {
|
||||
color = defaultColor
|
||||
} else {
|
||||
color = disabledColor
|
||||
}
|
||||
if (iconWidth > 0 && iconHeight > 0) {
|
||||
d.setBounds(0, 0, iconWidth, iconHeight)
|
||||
}
|
||||
d.setColorFilter(color, Mode.SRC_ATOP)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPostApplyTheme(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun createAppearance(context: Context, attributeSet: AttributeSet, theme: Chameleon.Theme): IIconActionButton.Appearance? {
|
||||
return IIconActionButton.Appearance.create(context, attributeSet, theme)
|
||||
}
|
||||
|
||||
override fun applyAppearance(appearance: ChameleonView.Appearance) {
|
||||
IIconActionButton.Appearance.apply(this, appearance as IIconActionButton.Appearance)
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,6 @@ 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.MediaLoadingHandler
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
|
@ -71,7 +70,7 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr
|
|||
|
||||
fun displayMedia(requestManager: RequestManager, media: Array<ParcelableMedia>?, accountId: UserKey? = null,
|
||||
extraId: Long = -1, withCredentials: Boolean = false,
|
||||
mediaClickListener: OnMediaClickListener? = null, loadingHandler: MediaLoadingHandler? = null) {
|
||||
mediaClickListener: OnMediaClickListener? = null) {
|
||||
if (media == null || style == PreviewStyle.NONE) {
|
||||
for (i in 0 until childCount) {
|
||||
val child = getChildAt(i)
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package org.mariotaku.twidere.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.support.annotation.ColorInt
|
||||
import android.support.v4.view.ViewCompat
|
||||
import android.support.v7.widget.AppCompatImageButton
|
||||
import android.util.AttributeSet
|
||||
import org.mariotaku.chameleon.Chameleon
|
||||
import org.mariotaku.chameleon.ChameleonView
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.util.ThemeUtils
|
||||
import org.mariotaku.twidere.view.iface.IIconActionButton
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
class IconActionButton(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : AppCompatImageButton(context, attrs, R.attr.imageButtonStyle), IIconActionButton {
|
||||
|
||||
override var defaultColor: Int = 0
|
||||
@ColorInt
|
||||
get() {
|
||||
if (field == 0) {
|
||||
val color = ViewCompat.getBackgroundTintList(this)
|
||||
if (color != null) {
|
||||
val currentColor = color.getColorForState(drawableState, 0)
|
||||
return ThemeUtils.getContrastColor(currentColor, Color.BLACK, Color.WHITE)
|
||||
}
|
||||
}
|
||||
return field
|
||||
}
|
||||
set(@ColorInt defaultColor) {
|
||||
field = defaultColor
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override var activatedColor: Int = 0
|
||||
@ColorInt
|
||||
get() {
|
||||
if (field != 0) return field
|
||||
return defaultColor
|
||||
}
|
||||
set(@ColorInt activatedColor) {
|
||||
field = activatedColor
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override var disabledColor: Int = 0
|
||||
@ColorInt
|
||||
get() {
|
||||
if (field != 0) return field
|
||||
return defaultColor
|
||||
}
|
||||
set(@ColorInt disabledColor) {
|
||||
field = disabledColor
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
init {
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton,
|
||||
R.attr.cardActionButtonStyle, R.style.Widget_CardActionButton)
|
||||
defaultColor = a.getColor(R.styleable.IconActionButton_iabColor, 0)
|
||||
activatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0)
|
||||
disabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0)
|
||||
a.recycle()
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override fun setActivated(activated: Boolean) {
|
||||
super.setActivated(activated)
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override fun setEnabled(enabled: Boolean) {
|
||||
super.setEnabled(enabled)
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
private fun updateColorFilter() {
|
||||
if (isActivated) {
|
||||
setColorFilter(activatedColor)
|
||||
} else if (isEnabled) {
|
||||
setColorFilter(defaultColor)
|
||||
} else {
|
||||
setColorFilter(disabledColor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPostApplyTheme(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun createAppearance(context: Context, attributeSet: AttributeSet, theme: Chameleon.Theme): IIconActionButton.Appearance? {
|
||||
return IIconActionButton.Appearance.create(context, attributeSet, theme)
|
||||
}
|
||||
|
||||
override fun applyAppearance(appearance: ChameleonView.Appearance) {
|
||||
IIconActionButton.Appearance.apply(this, appearance as IIconActionButton.Appearance)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package org.mariotaku.twidere.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.support.annotation.ColorInt
|
||||
import android.support.v4.view.ViewCompat
|
||||
import android.support.v7.widget.AppCompatImageView
|
||||
import android.util.AttributeSet
|
||||
import org.mariotaku.chameleon.Chameleon
|
||||
import org.mariotaku.chameleon.ChameleonView
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.util.ThemeUtils
|
||||
import org.mariotaku.twidere.view.iface.IIconActionButton
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
open class IconActionView(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : AppCompatImageView(context, attrs), IIconActionButton {
|
||||
|
||||
override final var defaultColor: Int = 0
|
||||
@ColorInt
|
||||
get() {
|
||||
if (field != 0) return field
|
||||
val color = ViewCompat.getBackgroundTintList(this)
|
||||
if (color != null) {
|
||||
val currentColor = color.getColorForState(drawableState, 0)
|
||||
return ThemeUtils.getContrastColor(currentColor, Color.BLACK, Color.WHITE)
|
||||
}
|
||||
return field
|
||||
}
|
||||
set(@ColorInt defaultColor) {
|
||||
field = defaultColor
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override final var activatedColor: Int = 0
|
||||
@ColorInt
|
||||
get() {
|
||||
if (field != 0) return field
|
||||
return defaultColor
|
||||
}
|
||||
set(@ColorInt value) {
|
||||
field = value
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override final var disabledColor: Int = 0
|
||||
@ColorInt
|
||||
get() {
|
||||
if (field != 0) return field
|
||||
return defaultColor
|
||||
}
|
||||
set(@ColorInt value) {
|
||||
field = value
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
init {
|
||||
if (!isInEditMode) {
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton,
|
||||
R.attr.cardActionButtonStyle, R.style.Widget_CardActionButton)
|
||||
defaultColor = a.getColor(R.styleable.IconActionButton_iabColor, 0)
|
||||
activatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0)
|
||||
disabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0)
|
||||
a.recycle()
|
||||
}
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override fun setActivated(activated: Boolean) {
|
||||
super.setActivated(activated)
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
override fun setEnabled(enabled: Boolean) {
|
||||
super.setEnabled(enabled)
|
||||
updateColorFilter()
|
||||
}
|
||||
|
||||
private fun updateColorFilter() {
|
||||
if (isActivated) {
|
||||
setColorFilter(activatedColor)
|
||||
} else if (isEnabled) {
|
||||
setColorFilter(defaultColor)
|
||||
} else {
|
||||
setColorFilter(disabledColor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPostApplyTheme(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun createAppearance(context: Context, attributeSet: AttributeSet, theme: Chameleon.Theme): IIconActionButton.Appearance? {
|
||||
return IIconActionButton.Appearance.create(context, attributeSet, theme)
|
||||
}
|
||||
|
||||
override fun applyAppearance(appearance: ChameleonView.Appearance) {
|
||||
IIconActionButton.Appearance.apply(this, appearance as IIconActionButton.Appearance)
|
||||
}
|
||||
|
||||
}
|
|
@ -70,7 +70,7 @@ class NameView(context: Context, attrs: AttributeSet? = null) : FixedTextView(co
|
|||
secondaryTextStyle = StyleSpan(a.getInt(R.styleable.NameView_nv_secondaryTextStyle, 0))
|
||||
a.recycle()
|
||||
nameFirst = true
|
||||
if (isInEditMode) {
|
||||
if (isInEditMode && text.isNullOrEmpty()) {
|
||||
name = "Name"
|
||||
screenName = "@screenname"
|
||||
updateText()
|
||||
|
|
|
@ -54,7 +54,7 @@ class MediaStatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView:
|
|||
}
|
||||
|
||||
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
|
||||
displayExtraType: Boolean, displayPinned: Boolean) {
|
||||
displayPinned: Boolean) {
|
||||
val media = status.media ?: return
|
||||
if (media.isEmpty()) return
|
||||
val firstMedia = media[0]
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package org.mariotaku.twidere.view.holder
|
||||
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v4.widget.TextViewCompat
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.TextUtils
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.View
|
||||
import android.view.View.OnClickListener
|
||||
|
@ -28,7 +28,6 @@ import org.mariotaku.twidere.model.ParcelableLocation
|
|||
import org.mariotaku.twidere.model.ParcelableMedia
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
|
||||
import org.mariotaku.twidere.task.CreateFavoriteTask
|
||||
import org.mariotaku.twidere.task.DestroyFavoriteTask
|
||||
import org.mariotaku.twidere.task.RetweetStatusTask
|
||||
|
@ -58,7 +57,6 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
private val itemMenu by lazy { itemView.itemMenu }
|
||||
private val statusInfoLabel by lazy { itemView.statusInfoLabel }
|
||||
private val statusInfoIcon by lazy { itemView.statusInfoIcon }
|
||||
private val extraTypeView by lazy { itemView.extraType }
|
||||
private val quotedNameView by lazy { itemView.quotedName }
|
||||
private val timeView by lazy { itemView.time }
|
||||
private val replyCountView by lazy { itemView.replyCount }
|
||||
|
@ -73,8 +71,6 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
private val favoriteIcon by lazy { itemView.favoriteIcon }
|
||||
private val retweetIcon by lazy { itemView.retweetIcon }
|
||||
private val favoriteCountView by lazy { itemView.favoriteCount }
|
||||
private val mediaLabelTextView by lazy { itemView.mediaLabelText }
|
||||
private val quotedMediaLabelTextView by lazy { itemView.quotedMediaLabelText }
|
||||
private val replyButton by lazy { itemView.reply }
|
||||
private val retweetButton by lazy { itemView.retweet }
|
||||
private val favoriteButton by lazy { itemView.favorite }
|
||||
|
@ -131,11 +127,10 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
quotedMediaPreview.visibility = View.GONE
|
||||
quotedMediaLabel.visibility = View.GONE
|
||||
mediaPreview.displayMedia(R.drawable.featured_graphics)
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_gallery)
|
||||
}
|
||||
|
||||
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
|
||||
displayExtraType: Boolean, displayPinned: Boolean) {
|
||||
displayPinned: Boolean) {
|
||||
|
||||
val context = itemView.context
|
||||
val requestManager = adapter.requestManager
|
||||
|
@ -336,7 +331,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
|
||||
mediaPreview.displayMedia(requestManager = requestManager,
|
||||
media = status.media, accountId = status.account_key,
|
||||
mediaClickListener = this, loadingHandler = adapter.mediaLoadingHandler)
|
||||
mediaClickListener = this)
|
||||
}
|
||||
} else {
|
||||
// No media, hide all related views
|
||||
|
@ -414,12 +409,6 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
favoriteCountView.text = null
|
||||
favoriteCountView.visibility = View.GONE
|
||||
}
|
||||
if (displayExtraType) {
|
||||
displayExtraTypeIcon(status.card_name, status.media, status.location,
|
||||
status.place_full_name, status.is_possibly_sensitive)
|
||||
} else {
|
||||
extraTypeView.visibility = View.GONE
|
||||
}
|
||||
|
||||
nameView.updateText(formatter)
|
||||
quotedNameView.updateText(formatter)
|
||||
|
@ -444,7 +433,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
|
||||
quotedMediaPreview.displayMedia(requestManager = requestManager,
|
||||
media = status.quoted_media, accountId = status.account_key,
|
||||
mediaClickListener = this, loadingHandler = adapter.mediaLoadingHandler)
|
||||
mediaClickListener = this)
|
||||
}
|
||||
} else {
|
||||
// No media, hide all related views
|
||||
|
@ -494,7 +483,8 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
timeView.textSize = textSize * 0.85f
|
||||
statusInfoLabel.textSize = textSize * 0.75f
|
||||
|
||||
mediaLabelTextView.textSize = textSize * 0.95f
|
||||
mediaLabel.textSize = textSize * 0.95f
|
||||
quotedMediaLabel.textSize = textSize * 0.95f
|
||||
|
||||
replyCountView.textSize = textSize
|
||||
retweetCountView.textSize = textSize
|
||||
|
@ -537,11 +527,11 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
nameView.applyFontFamily(adapter.lightFont)
|
||||
timeView.applyFontFamily(adapter.lightFont)
|
||||
textView.applyFontFamily(adapter.lightFont)
|
||||
mediaLabelTextView.applyFontFamily(adapter.lightFont)
|
||||
mediaLabel.applyFontFamily(adapter.lightFont)
|
||||
|
||||
quotedNameView.applyFontFamily(adapter.lightFont)
|
||||
quotedTextView.applyFontFamily(adapter.lightFont)
|
||||
quotedMediaLabelTextView.applyFontFamily(adapter.lightFont)
|
||||
quotedMediaLabel.applyFontFamily(adapter.lightFont)
|
||||
}
|
||||
|
||||
override fun playLikeAnimation(listener: LikeAnimationDrawable.OnLikedListener) {
|
||||
|
@ -572,28 +562,13 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
private fun displayExtraTypeIcon(cardName: String?, media: Array<ParcelableMedia?>?,
|
||||
location: ParcelableLocation?, placeFullName: String?,
|
||||
sensitive: Boolean) {
|
||||
if (TwitterCardUtils.CARD_NAME_AUDIO == cardName) {
|
||||
extraTypeView.setImageResource(if (sensitive) R.drawable.ic_action_warning else R.drawable.ic_action_music)
|
||||
extraTypeView.visibility = View.VISIBLE
|
||||
} else if (TwitterCardUtils.CARD_NAME_ANIMATED_GIF == cardName) {
|
||||
extraTypeView.setImageResource(if (sensitive) R.drawable.ic_action_warning else R.drawable.ic_action_movie)
|
||||
extraTypeView.visibility = View.VISIBLE
|
||||
} else if (TwitterCardUtils.CARD_NAME_PLAYER == cardName) {
|
||||
extraTypeView.setImageResource(if (sensitive) R.drawable.ic_action_warning else R.drawable.ic_action_play_circle)
|
||||
extraTypeView.visibility = View.VISIBLE
|
||||
} else if (media?.isNotEmpty() ?: false) {
|
||||
if (hasVideo(media)) {
|
||||
extraTypeView.setImageResource(if (sensitive) R.drawable.ic_action_warning else R.drawable.ic_action_movie)
|
||||
} else {
|
||||
extraTypeView.setImageResource(if (sensitive) R.drawable.ic_action_warning else R.drawable.ic_action_gallery)
|
||||
}
|
||||
extraTypeView.visibility = View.VISIBLE
|
||||
} else if (ParcelableLocationUtils.isValidLocation(location) || !TextUtils.isEmpty(placeFullName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_location)
|
||||
extraTypeView.visibility = View.VISIBLE
|
||||
val icon = if (sensitive) {
|
||||
R.drawable.ic_label_warning
|
||||
} else {
|
||||
extraTypeView.visibility = View.GONE
|
||||
R.drawable.ic_label_gallery
|
||||
}
|
||||
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mediaLabel, icon, 0, 0, 0)
|
||||
mediaLabel.refreshDrawableState()
|
||||
}
|
||||
|
||||
private fun hasVideo(media: Array<ParcelableMedia?>?): Boolean {
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.mariotaku.twidere.view.CardMediaContainer
|
|||
interface IStatusViewHolder : CardMediaContainer.OnMediaClickListener {
|
||||
|
||||
fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean = true,
|
||||
displayExtraType: Boolean = true, displayPinned: Boolean = false)
|
||||
displayPinned: Boolean = false)
|
||||
|
||||
val profileImageView: ImageView?
|
||||
|
||||
|
|
|
@ -109,8 +109,8 @@ class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) :
|
|||
} else {
|
||||
mediaPreview.visibility = View.VISIBLE
|
||||
mediaPreview.displayMedia(adapter.requestManager, message.media, message.account_key,
|
||||
withCredentials = true, loadingHandler = adapter.mediaLoadingHandler,
|
||||
mediaClickListener = adapter.mediaClickListener, extraId = layoutPosition.toLong())
|
||||
extraId = layoutPosition.toLong(), withCredentials = true,
|
||||
mediaClickListener = adapter.mediaClickListener)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package org.mariotaku.twidere.view.iface
|
||||
|
||||
import android.content.Context
|
||||
import android.support.annotation.ColorInt
|
||||
import android.util.AttributeSet
|
||||
|
||||
import org.mariotaku.chameleon.Chameleon
|
||||
import org.mariotaku.chameleon.ChameleonView
|
||||
import org.mariotaku.chameleon.internal.ChameleonTypedArray
|
||||
import org.mariotaku.twidere.R
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/19.
|
||||
*/
|
||||
interface IIconActionButton : ChameleonView {
|
||||
|
||||
var defaultColor: Int
|
||||
@ColorInt get @ColorInt set
|
||||
var activatedColor: Int
|
||||
@ColorInt get @ColorInt set
|
||||
var disabledColor: Int
|
||||
@ColorInt get @ColorInt set
|
||||
|
||||
class Appearance : ChameleonView.Appearance {
|
||||
var defaultColor: Int = 0
|
||||
@ColorInt get @ColorInt set
|
||||
var activatedColor: Int = 0
|
||||
@ColorInt get @ColorInt set
|
||||
var disabledColor: Int = 0
|
||||
@ColorInt get @ColorInt set
|
||||
|
||||
companion object {
|
||||
|
||||
fun create(context: Context, attributeSet: AttributeSet, theme: Chameleon.Theme): Appearance {
|
||||
val appearance = Appearance()
|
||||
val a = ChameleonTypedArray.obtain(context, attributeSet, R.styleable.IconActionButton, theme)
|
||||
appearance.defaultColor = a.getColor(R.styleable.IconActionButton_iabColor, 0, false)
|
||||
appearance.activatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0, false)
|
||||
appearance.disabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0, false)
|
||||
a.recycle()
|
||||
return appearance
|
||||
}
|
||||
|
||||
fun apply(view: IIconActionButton, appearance: Appearance) {
|
||||
val defaultColor = appearance.defaultColor
|
||||
if (defaultColor != 0) {
|
||||
view.defaultColor = defaultColor
|
||||
}
|
||||
val activatedColor = appearance.activatedColor
|
||||
if (activatedColor != 0) {
|
||||
view.activatedColor = activatedColor
|
||||
}
|
||||
val disabledColor = appearance.disabledColor
|
||||
if (disabledColor != 0) {
|
||||
view.disabledColor = disabledColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -111,52 +111,40 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/statusContentUpperSpace"
|
||||
android:layout_toEndOf="@+id/profileImage"
|
||||
android:layout_toRightOf="@+id/profileImage"
|
||||
android:orientation="vertical">
|
||||
android:layout_toRightOf="@+id/profileImage">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/profileContainer"
|
||||
android:layout_width="match_parent"
|
||||
<org.mariotaku.twidere.view.NameView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|start"
|
||||
android:orientation="horizontal">
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toLeftOf="@+id/time"
|
||||
android:layout_toStartOf="@+id/time"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
app:nv_primaryTextColor="?android:textColorPrimary"
|
||||
app:nv_primaryTextStyle="bold"
|
||||
app:nv_secondaryTextColor="?android:textColorSecondary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.NameView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
app:nv_primaryTextColor="?android:textColorPrimary"
|
||||
app:nv_primaryTextStyle="bold"
|
||||
app:nv_secondaryTextColor="?android:textColorSecondary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ShortTimeView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
tools:text="42 mins ago"
|
||||
tools:textSize="@dimen/text_size_extra_small"/>
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionView
|
||||
android:id="@+id/extraType"
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_weight="0"
|
||||
android:color="?android:textColorSecondary"
|
||||
tools:src="@drawable/ic_action_gallery"
|
||||
tools:tint="?android:textColorSecondary"/>
|
||||
|
||||
</LinearLayout>
|
||||
<org.mariotaku.twidere.view.ShortTimeView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@+id/name"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
tools:text="42 mins ago"
|
||||
tools:textSize="@dimen/text_size_extra_small"/>
|
||||
|
||||
<org.mariotaku.twidere.view.TimelineContentTextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/profileContainer"
|
||||
android:layout_alignStart="@+id/profileContainer"
|
||||
android:layout_below="@+id/profileContainer"
|
||||
android:layout_alignLeft="@+id/name"
|
||||
android:layout_alignStart="@+id/name"
|
||||
android:layout_below="@+id/name"
|
||||
android:paddingTop="@dimen/element_spacing_small"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
|
@ -164,7 +152,7 @@
|
|||
tools:text="@string/sample_status_text"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
<org.mariotaku.twidere.view.ActionIconThemedTextView
|
||||
android:id="@+id/mediaLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -175,28 +163,14 @@
|
|||
android:layout_below="@+id/text"
|
||||
android:layout_marginTop="@dimen/element_spacing_xsmall"
|
||||
android:background="?selectableItemBackground"
|
||||
android:drawableLeft="@drawable/ic_label_gallery"
|
||||
android:drawableStart="@drawable/ic_label_gallery"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionView
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_weight="0"
|
||||
android:color="?android:textColorSecondary"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_action_gallery"
|
||||
tools:tint="?android:textColorSecondary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.FixedTextView
|
||||
android:id="@+id/mediaLabelText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/media"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:minHeight="@dimen/element_size_small"
|
||||
android:text="@string/media"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textStyle="bold"
|
||||
app:iabColor="?android:textColorSecondary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/mediaPreview"
|
||||
|
@ -278,7 +252,7 @@
|
|||
tools:text="@string/sample_status_text"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
<org.mariotaku.twidere.view.ActionIconThemedTextView
|
||||
android:id="@+id/quotedMediaLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -288,29 +262,14 @@
|
|||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/quotedText"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:drawableLeft="@drawable/ic_label_gallery"
|
||||
android:drawableStart="@drawable/ic_label_gallery"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:visibility="gone">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionView
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_weight="0"
|
||||
android:color="?android:textColorSecondary"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_action_gallery"
|
||||
tools:tint="?android:textColorSecondary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.FixedTextView
|
||||
android:id="@+id/quotedMediaLabelText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/media"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:text="@string/media"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textStyle="bold"
|
||||
app:iabColor="?android:textColorSecondary"
|
||||
tools:visibility="gone"/>
|
||||
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/quotedMediaPreview"
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>ic_label_gallery-mdpi</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Action-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_label_gallery-mdpi">
|
||||
<g id="image_image" transform="translate(2.000000, 2.000000)">
|
||||
<g id="Group">
|
||||
<polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon>
|
||||
<path d="M17.5,15.8333333 L17.5,4.16666667 C17.5,3.25 16.75,2.5 15.8333333,2.5 L4.16666667,2.5 C3.25,2.5 2.5,3.25 2.5,4.16666667 L2.5,15.8333333 C2.5,16.75 3.25,17.5 4.16666667,17.5 L15.8333333,17.5 C16.75,17.5 17.5,16.75 17.5,15.8333333 Z M7.08333333,11.25 L9.16666667,13.7583333 L12.0833333,10 L15.8333333,15 L4.16666667,15 L7.08333333,11.25 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>ic_label_video-mdpi</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Action-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_label_video-mdpi">
|
||||
<g id="Group" transform="translate(2.000000, 2.000000)">
|
||||
<path d="M15,3.33333333 L16.6666667,6.66666667 L14.1666667,6.66666667 L12.5,3.33333333 L10.8333333,3.33333333 L12.5,6.66666667 L10,6.66666667 L8.33333333,3.33333333 L6.66666667,3.33333333 L8.33333333,6.66666667 L5.83333333,6.66666667 L4.16666667,3.33333333 L3.33333333,3.33333333 C2.41666667,3.33333333 1.675,4.08333333 1.675,5 L1.66666667,15 C1.66666667,15.9166667 2.41666667,16.6666667 3.33333333,16.6666667 L16.6666667,16.6666667 C17.5833333,16.6666667 18.3333333,15.9166667 18.3333333,15 L18.3333333,3.33333333 L15,3.33333333 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>ic_label_warning-mdpi</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Action-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_label_warning-mdpi">
|
||||
<g id="Group" transform="translate(2.000000, 2.000000)">
|
||||
<polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon>
|
||||
<path d="M0.833333333,17.5 L19.1666667,17.5 L10,1.66666667 L0.833333333,17.5 Z M10.8333333,15 L9.16666667,15 L9.16666667,13.3333333 L10.8333333,13.3333333 L10.8333333,15 Z M10.8333333,11.6666667 L9.16666667,11.6666667 L9.16666667,8.33333333 L10.8333333,8.33333333 L10.8333333,11.6666667 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
Loading…
Reference in New Issue