updated travis config

This commit is contained in:
Mariotaku Lee 2017-03-02 16:26:12 +08:00
parent 85d39a39c0
commit 23b889fe1b
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
8 changed files with 89 additions and 45 deletions

View File

@ -62,8 +62,16 @@ before_install:
install:
# Extracts build configs into source tree
- tar zxf travis/configs/twidere_private_config.tar.gz
# I REALLY don't want to use StrictHostKeyChecking, but SSH don't let me check hostname only
- GIT_SSH="ssh -i private/ssh_id_rsa -o StrictHostKeyChecking=no $@" git clone $COMPONENT_GOOGLE_REPO twidere/src/google > /dev/null 2>&1
# Make sure ~/.ssh/ exists
- mkdir -p ~/.ssh/
# Make it secure
- chmod 700 ~/.ssh/
# Append ssh_config
- cat private/ssh_config >> ~/.ssh/config
# Append known_hosts
- cat private/ssh_known_hosts >> ~/.ssh/known_hosts
# Checkout Google components
- ssh-agent bash -c "ssh-add private/ssh_id_rsa; git clone $COMPONENT_GOOGLE_REPO twidere/src/google" > /dev/null 2>&1
before_script:
# Validate if patches work

View File

@ -0,0 +1,35 @@
/*
* 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.annotation;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Created by mariotaku on 2017/3/2.
*/
@IntDef({ImageShapeStyle.SHAPE_CIRCLE, ImageShapeStyle.SHAPE_RECTANGLE})
@Retention(RetentionPolicy.SOURCE)
public @interface ImageShapeStyle {
int SHAPE_CIRCLE = 0x1;
int SHAPE_RECTANGLE = 0x2;
}

View File

@ -33,7 +33,6 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.os.Build;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
@ -41,23 +40,17 @@ import android.view.View;
import android.widget.ImageView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.annotation.ImageShapeStyle;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.util.support.graphics.OutlineCompat;
import org.mariotaku.twidere.util.support.view.ViewOutlineProviderCompat;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* An ImageView class with a circle mask so that all images are drawn in a
* circle instead of a square.
*/
public class ShapedImageView extends ImageView {
@ShapeStyle
public static final int SHAPE_CIRCLE = 0x1;
@ShapeStyle
public static final int SHAPE_RECTANGLE = 0x2;
private static final int SHADOW_START_COLOR = 0x37000000;
public static final boolean OUTLINE_DRAW = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
@ -100,8 +93,8 @@ public class ShapedImageView extends ImageView {
}
setBorderColor(a.getColor(R.styleable.ShapedImageView_sivBorderColor, Color.TRANSPARENT));
setBorderWidth(a.getDimensionPixelSize(R.styleable.ShapedImageView_sivBorderWidth, 0));
@ShapeStyle
final int shapeStyle = a.getInt(R.styleable.ShapedImageView_sivShape, SHAPE_RECTANGLE);
@ImageShapeStyle
final int shapeStyle = a.getInt(R.styleable.ShapedImageView_sivShape, ImageShapeStyle.SHAPE_RECTANGLE);
setStyle(shapeStyle);
setCornerRadius(a.getDimension(R.styleable.ShapedImageView_sivCornerRadius, 0));
setCornerRadiusRatio(a.getFraction(R.styleable.ShapedImageView_sivCornerRadiusRatio, 1, 1, -1));
@ -125,12 +118,12 @@ public class ShapedImageView extends ImageView {
return mBorderColors;
}
@ShapeStyle
@ImageShapeStyle
public int getStyle() {
return mStyle;
}
public void setStyle(@ShapeStyle final int style) {
public void setStyle(@ImageShapeStyle final int style) {
mStyle = style;
}
@ -244,7 +237,7 @@ public class ShapedImageView extends ImageView {
ViewCompat.setTranslationZ(this, 0);
}
mBorderPaint.setStrokeWidth(strokeWidth);
if (getStyle() == SHAPE_CIRCLE) {
if (getStyle() == ImageShapeStyle.SHAPE_CIRCLE) {
final float circleRadius = Math.min(dest.width(), dest.height()) / 2f - strokeWidth / 2;
canvas.drawCircle(dest.centerX(), dest.centerY(), circleRadius, mBorderPaint);
} else {
@ -324,7 +317,7 @@ public class ShapedImageView extends ImageView {
paint.setColor(0xFF000000);
paint.setShadowLayer(radius, 0, radius * 1.5f / 2, SHADOW_START_COLOR);
final RectF rect = new RectF(radius, radius, size - radius, size - radius);
if (getStyle() == SHAPE_CIRCLE) {
if (getStyle() == ImageShapeStyle.SHAPE_CIRCLE) {
canvas.drawOval(rect, paint);
paint.setShadowLayer(0, 0, 0, 0);
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
@ -343,11 +336,6 @@ public class ShapedImageView extends ImageView {
return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP && !isInEditMode();
}
@IntDef({SHAPE_CIRCLE, SHAPE_RECTANGLE})
@Retention(RetentionPolicy.SOURCE)
public @interface ShapeStyle {
}
private static class CircularOutlineProvider extends ViewOutlineProviderCompat {
boolean drawShadow;
@ -362,7 +350,7 @@ public class ShapedImageView extends ImageView {
contentRight = viewWidth - view.getPaddingRight(),
contentBottom = viewHeight - view.getPaddingBottom();
final ShapedImageView imageView = (ShapedImageView) view;
if (imageView.getStyle() == SHAPE_CIRCLE) {
if (imageView.getStyle() == ImageShapeStyle.SHAPE_CIRCLE) {
final int contentWidth = contentRight - contentLeft,
contentHeight = contentBottom - contentTop;
final int size = Math.min(contentWidth, contentHeight);

View File

@ -23,7 +23,7 @@ import android.support.v4.text.BidiFormatter
import com.bumptech.glide.RequestManager
import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle
import org.mariotaku.twidere.annotation.ImageShapeStyle
/**
* Created by mariotaku on 15/1/3.
@ -34,7 +34,7 @@ interface IContentAdapter {
fun getItemCount(): Int
@ShapeStyle
@ImageShapeStyle
val profileImageStyle: Int
val profileImageEnabled: Boolean

View File

@ -9,6 +9,7 @@ import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.TwidereConstants.KEY_MEDIA_PRELOAD
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.ImageShapeStyle
import org.mariotaku.twidere.annotation.PreviewStyle
import org.mariotaku.twidere.extension.getNonEmptyString
import org.mariotaku.twidere.model.CustomAPIConfig
@ -82,14 +83,14 @@ object themeBackgroundAlphaKey : KSimpleKey<Int>(KEY_THEME_BACKGROUND_ALPHA, 0xF
}
}
object profileImageStyleKey : KSimpleKey<Int>(KEY_PROFILE_IMAGE_STYLE, ProfileImageView.SHAPE_CIRCLE) {
object profileImageStyleKey : KSimpleKey<Int>(KEY_PROFILE_IMAGE_STYLE, ImageShapeStyle.SHAPE_CIRCLE) {
override fun read(preferences: SharedPreferences): Int {
if (preferences.getString(key, null) == VALUE_PROFILE_IMAGE_STYLE_SQUARE) return ProfileImageView.SHAPE_RECTANGLE
return ProfileImageView.SHAPE_CIRCLE
if (preferences.getString(key, null) == VALUE_PROFILE_IMAGE_STYLE_SQUARE) return ImageShapeStyle.SHAPE_RECTANGLE
return ImageShapeStyle.SHAPE_CIRCLE
}
override fun write(editor: SharedPreferences.Editor, value: Int): Boolean {
editor.putString(key, if (value == ProfileImageView.SHAPE_CIRCLE) VALUE_PROFILE_IMAGE_STYLE_ROUND else VALUE_PROFILE_IMAGE_STYLE_SQUARE)
editor.putString(key, if (value == ImageShapeStyle.SHAPE_CIRCLE) VALUE_PROFILE_IMAGE_STYLE_ROUND else VALUE_PROFILE_IMAGE_STYLE_SQUARE)
return true
}

View File

@ -26,29 +26,33 @@ import com.bumptech.glide.RequestManager
import com.bumptech.glide.load.engine.DiskCacheStrategy
import jp.wasabeef.glide.transformations.CropCircleTransformation
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.ImageShapeStyle
import org.mariotaku.twidere.extension.model.user
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.view.ShapedImageView
fun RequestManager.loadProfileImage(context: Context, url: String?,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
val size = context.getString(R.string.profile_image_size)
return configureLoadProfileImage(context, shapeStyle) { load(Utils.getTwitterProfileImageOfSize(url, size)) }
fun RequestManager.loadProfileImage(
context: Context,
url: String?,
@ImageShapeStyle style: Int = ImageShapeStyle.SHAPE_CIRCLE,
size: String = context.getString(R.string.profile_image_size)
): DrawableRequestBuilder<String?> {
return configureLoadProfileImage(context, style) { load(Utils.getTwitterProfileImageOfSize(url, size)) }
}
fun RequestManager.loadProfileImage(context: Context, resourceId: Int,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<Int> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<Int> {
return configureLoadProfileImage(context, shapeStyle) { load(resourceId) }
}
fun RequestManager.loadProfileImage(context: Context, account: AccountDetails,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
return loadProfileImage(context, account.user, shapeStyle)
}
fun RequestManager.loadProfileImage(context: Context, user: ParcelableUser,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
if (user.extras != null && user.extras.profile_image_url_fallback == null) {
// No fallback image, use compatible logic
return loadProfileImage(context, user.profile_image_url)
@ -57,17 +61,17 @@ fun RequestManager.loadProfileImage(context: Context, user: ParcelableUser,
}
fun RequestManager.loadProfileImage(context: Context, userList: ParcelableUserList,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
return configureLoadProfileImage(context, shapeStyle) { load(userList.user_profile_image_url) }
}
fun RequestManager.loadProfileImage(context: Context, group: ParcelableGroup,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
return configureLoadProfileImage(context, shapeStyle) { load(group.homepage_logo) }
}
fun RequestManager.loadProfileImage(context: Context, status: ParcelableStatus,
@ShapedImageView.ShapeStyle shapeStyle: Int = ShapedImageView.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
if (status.extras != null && status.extras.user_profile_image_url_fallback == null) {
// No fallback image, use compatible logic
return loadProfileImage(context, status.user_profile_image_url)
@ -89,6 +93,13 @@ fun RequestManager.loadProfileImage(context: Context, conversation: ParcelableMe
}
}
fun RequestManager.loadOriginalProfileImage(context: Context, user: ParcelableUser,
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String> {
val original = user.extras.profile_image_url_original?.takeIf(String::isEmpty)
?: Utils.getOriginalTwitterProfileImage(user.profile_image_url)
return configureLoadProfileImage(context, shapeStyle) { load(original) }
}
internal inline fun <T> configureLoadProfileImage(context: Context, shapeStyle: Int,
create: () -> DrawableTypeRequest<T>): DrawableRequestBuilder<T> {
val builder = create()
@ -96,10 +107,10 @@ internal inline fun <T> configureLoadProfileImage(context: Context, shapeStyle:
builder.dontAnimate()
if (!ShapedImageView.OUTLINE_DRAW) {
when (shapeStyle) {
ShapedImageView.SHAPE_CIRCLE -> {
ImageShapeStyle.SHAPE_CIRCLE -> {
builder.bitmapTransform(CropCircleTransformation(context))
}
ShapedImageView.SHAPE_RECTANGLE -> {
ImageShapeStyle.SHAPE_RECTANGLE -> {
}
}
}

View File

@ -79,7 +79,6 @@ import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.promiseOnUi
import nl.komponents.kovenant.ui.successUi
import org.apache.commons.lang3.ObjectUtils
import org.mariotaku.chameleon.Chameleon
import org.mariotaku.chameleon.ChameleonUtils
import org.mariotaku.kpreferences.get
@ -89,7 +88,6 @@ import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.FriendshipUpdate
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.UserList
import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.AccountSelectorActivity
@ -106,6 +104,8 @@ import org.mariotaku.twidere.constant.lightFontKey
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.loadOriginalProfileImage
import org.mariotaku.twidere.extension.loadProfileImage
import org.mariotaku.twidere.extension.model.applyTo
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
import org.mariotaku.twidere.fragment.UserTimelineFragment.UserTimelineFragmentDelegate
@ -126,7 +126,7 @@ import org.mariotaku.twidere.model.util.*
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.InternalTwitterContentUtils.*
import org.mariotaku.twidere.util.InternalTwitterContentUtils.getBestBannerUrl
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener
import org.mariotaku.twidere.util.UserColorNameManager.UserColorChangedListener
@ -511,7 +511,6 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
listedContainer.visibility = if (user.listed_count < 0) View.GONE else View.VISIBLE
groupsContainer.visibility = if (groupsCount < 0) View.GONE else View.VISIBLE
mediaLoader.displayOriginalProfileImage(profileImage, user)
if (user.color != 0) {
setUiColor(user.color)
} else if (user.link_color != 0) {
@ -523,7 +522,9 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val defWidth = resources.displayMetrics.widthPixels
val width = if (bannerWidth > 0) bannerWidth else defWidth
val bannerUrl = getBestBannerUrl(ParcelableUserUtils.getProfileBannerUrl(user), width)
Glide.with(this).load(bannerUrl).into(profileBanner)
val requestManager = Glide.with(this)
requestManager.load(bannerUrl).into(profileBanner)
requestManager.loadOriginalProfileImage(context, user, profileImage.style).into(profileImage)
val relationship = relationship
if (relationship == null) {
getFriendship()