Skip to content
Snippets Groups Projects
Commit f16b99cf authored by John Carlson's avatar John Carlson
Browse files

Merge branch 'develop'

parents 2995603f eb7397c0
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 552 additions and 72 deletions
package com.commit451.gitlab.model.api;
import android.graphics.Color;
import android.support.annotation.ColorInt;
import com.google.gson.annotations.SerializedName;
import org.parceler.Parcel;
/**
* A label
*/
@Parcel
public class Label {
@SerializedName("color")
String mColor;
@SerializedName("name")
String mName;
protected Label() {
//for json parsing
}
public Label(String name, String color) {
mName = name;
mColor = color;
}
public String getName() {
return mName;
}
public @ColorInt int getColor() {
try {
return Color.parseColor(mColor);
} catch (IllegalArgumentException e) {
return Color.TRANSPARENT;
}
}
}
package com.commit451.gitlab.model.api;
 
import android.support.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
 
import org.parceler.Parcel;
Loading
Loading
@@ -49,6 +51,11 @@ public class MergeRequest {
Milestone mMilestone;
@SerializedName("merge_when_build_succeeds")
boolean mMergeWhenBuildSucceeds;
@SerializedName("merge_status")
String mMergeStatus;
@SerializedName("changes")
@Nullable
List<Diff> mChanges;
 
public MergeRequest() {}
 
Loading
Loading
@@ -132,6 +139,19 @@ public class MergeRequest {
return mMergeWhenBuildSucceeds;
}
 
public String getMergeStatus() {
return mMergeStatus;
}
/**
* Get the changes. Only not null if this merge request was retrieved via {@link com.commit451.gitlab.api.GitLab#getMergeRequestChanges(long, long)}
* @return the changes
*/
@Nullable
public List<Diff> getChanges() {
return mChanges;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MergeRequest)) {
Loading
Loading
Loading
Loading
@@ -19,12 +19,19 @@ import timber.log.Timber;
 
@Parcel
public class Milestone {
public static final String STATE_REOPEN = "reopen";
public static final String STATE_CLOSE = "close";
public static final String STATE_ACTIVE = "active";
public static final String STATE_CLOSED = "closed";
 
@StringDef({STATE_REOPEN, STATE_CLOSE})
@StringDef({STATE_ACTIVE, STATE_CLOSED})
@Retention(RetentionPolicy.SOURCE)
public @interface EditState {}
public @interface State {}
public static final String STATE_EVENT_ACTIVATE = "activate";
public static final String STATE_EVENT_CLOSE = "close";
@StringDef({STATE_EVENT_ACTIVATE, STATE_EVENT_CLOSE})
@Retention(RetentionPolicy.SOURCE)
public @interface StateEvent {}
 
public static final SimpleDateFormat DUE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-d", Locale.US);
 
Loading
Loading
@@ -39,7 +46,7 @@ public class Milestone {
@SerializedName("description")
String mDescription;
@SerializedName("state")
State mState;
String mState;
@SerializedName("created_at")
Date mCreatedAt;
@SerializedName("updated_at")
Loading
Loading
@@ -69,7 +76,9 @@ public class Milestone {
return mDescription;
}
 
public State getState() {
@State
public String getState() {
return mState;
}
 
Loading
Loading
@@ -113,13 +122,4 @@ public class Milestone {
public String toString() {
return mTitle;
}
public enum State {
@SerializedName("opened")
OPENED,
@SerializedName("reopened")
REOPENED,
@SerializedName("closed")
CLOSED
}
}
package com.commit451.gitlab.observable;
import android.util.Base64;
import rx.Observable;
import rx.functions.Func0;
/**
* Observable that decodes a byte array
*/
public class DecodeObservableFactory {
public static Observable<byte[]> newDecode(final String string) {
return Observable.defer(new Func0<Observable<byte[]>>() {
@Override
public Observable<byte[]> call() {
return Observable.just(decode(string));
}
});
}
private static byte[] decode(String string) {
return Base64.decode(string, Base64.DEFAULT);
}
}
Loading
Loading
@@ -21,7 +21,6 @@ import java.util.Date;
 
/**
* Get a properly configured Gson object
* Created by Jawn on 12/4/2015.
*/
public final class GsonProvider {
 
Loading
Loading
Loading
Loading
@@ -5,10 +5,11 @@ import com.commit451.gitlab.api.AuthenticationRequestInterceptor;
import com.commit451.gitlab.api.TimberRequestInterceptor;
import com.commit451.gitlab.model.Account;
import com.commit451.gitlab.ssl.CustomTrustManager;
import com.squareup.okhttp.OkHttpClient;
 
import java.util.concurrent.TimeUnit;
 
import okhttp3.OkHttpClient;
/**
* Creates an OkHttpClient with the needed defaults
* Created by Jawn on 12/4/2015.
Loading
Loading
@@ -34,14 +35,17 @@ public final class OkHttpClientProvider {
 
private static OkHttpClient createInstance(Account account) {
sCustomTrustManager.setTrustedCertificate(account.getTrustedCertificate());
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30, TimeUnit.SECONDS);
client.setSslSocketFactory(sCustomTrustManager.getSSLSocketFactory());
client.interceptors().add(new AuthenticationRequestInterceptor(account));
sCustomTrustManager.setTrustedHostname(account.getTrustedHostname());
sCustomTrustManager.setPrivateKeyAlias(account.getPrivateKeyAlias());
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.sslSocketFactory(sCustomTrustManager.getSSLSocketFactory())
.hostnameVerifier(sCustomTrustManager.getHostnameVerifier());
clientBuilder.addInterceptor(new AuthenticationRequestInterceptor(account));
if (BuildConfig.DEBUG) {
client.networkInterceptors().add(new TimberRequestInterceptor());
clientBuilder.addInterceptor(new TimberRequestInterceptor());
}
return client;
return clientBuilder.build();
}
}
package com.commit451.gitlab.ssl;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import okhttp3.internal.tls.OkHostnameVerifier;
public class CustomHostnameVerifier implements HostnameVerifier {
private static final HostnameVerifier DEFAULT_HOSTNAME_VERIFIER = OkHostnameVerifier.INSTANCE;
private static String sLastFailedHostname;
private final String mTrustedHostname;
public CustomHostnameVerifier(String trustedHostname) {
this.mTrustedHostname = trustedHostname;
}
@Override
public boolean verify(String hostname, SSLSession session) {
if (DEFAULT_HOSTNAME_VERIFIER.verify(hostname, session)) {
sLastFailedHostname = null;
return true;
}
if (mTrustedHostname != null && mTrustedHostname.equals(hostname)) {
sLastFailedHostname = null;
return true;
}
sLastFailedHostname = hostname;
return false;
}
public static String getLastFailedHostname() {
return sLastFailedHostname;
}
}
package com.commit451.gitlab.ssl;
import android.content.Context;
import android.os.AsyncTask;
import android.security.KeyChain;
import java.net.Socket;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.net.ssl.X509ExtendedKeyManager;
public class CustomKeyManager extends X509ExtendedKeyManager {
private static final Map<String, KeyEntry> sKeyCache = new ConcurrentHashMap<>();
public static boolean isCached(String alias) {
return sKeyCache.containsKey(alias);
}
public static KeyEntry getCachedKey(String alias) {
return sKeyCache.get(alias);
}
public static void cache(final Context context, final String alias, final KeyCallback callback) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
X509Certificate[] chain = KeyChain.getCertificateChain(context, alias);
PrivateKey privateKey = KeyChain.getPrivateKey(context, alias);
KeyEntry entry = new KeyEntry(alias, chain, privateKey);
sKeyCache.put(alias, entry);
callback.onSuccess(entry);
} catch (Exception e) {
callback.onError(e);
}
return null;
}
}.execute();
}
private final KeyEntry mEntry;
public CustomKeyManager(String alias) {
mEntry = getCachedKey(alias);
if (mEntry == null) {
throw new IllegalStateException("No cached key available");
}
}
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
return mEntry.alias;
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
return null;
}
@Override
public X509Certificate[] getCertificateChain(String alias) {
if (!mEntry.alias.equals(alias)) {
return null;
}
return mEntry.chain;
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers) {
return new String[] { mEntry.alias };
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers) {
return new String[0];
}
@Override
public PrivateKey getPrivateKey(String alias) {
if (!mEntry.alias.equals(alias)) {
return null;
}
return mEntry.privateKey;
}
public static class KeyEntry {
public final String alias;
public final X509Certificate[] chain;
public final PrivateKey privateKey;
public KeyEntry(String alias, X509Certificate[] chain, PrivateKey privateKey) {
this.alias = alias;
this.chain = chain;
this.privateKey = privateKey;
}
}
public interface KeyCallback {
void onSuccess(KeyEntry entry);
void onError(Exception e);
}
}
Loading
Loading
@@ -10,53 +10,61 @@ import java.util.Set;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
 
/**
* Custom SSL factory so that we can enforce using TLS 1.2 on Android 4.1-4.4
*/
public class CustomSSLSocketFactory extends SSLSocketFactory {
private final SSLSocketFactory mInternalFactory;
/**
* You may be wondering why this is named "delegate" which seems to break the convention
* of the rest of the project. See here for deets:
* https://github.com/square/okhttp/issues/2323
*/
private final SSLSocketFactory delegate;
 
public CustomSSLSocketFactory(SSLSocketFactory internalFactory) {
super();
 
this.mInternalFactory = internalFactory;
this.delegate = internalFactory;
}
 
@Override
public String[] getDefaultCipherSuites() {
return mInternalFactory.getDefaultCipherSuites();
return delegate.getDefaultCipherSuites();
}
 
@Override
public String[] getSupportedCipherSuites() {
return mInternalFactory.getSupportedCipherSuites();
return delegate.getSupportedCipherSuites();
}
 
@Override
public Socket createSocket() throws IOException {
return enableProtocols(mInternalFactory.createSocket());
return enableProtocols(delegate.createSocket());
}
 
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableProtocols(mInternalFactory.createSocket(s, host, port, autoClose));
return enableProtocols(delegate.createSocket(s, host, port, autoClose));
}
 
@Override
public Socket createSocket(String host, int port) throws IOException {
return enableProtocols(mInternalFactory.createSocket(host, port));
return enableProtocols(delegate.createSocket(host, port));
}
 
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return enableProtocols(mInternalFactory.createSocket(host, port, localHost, localPort));
return enableProtocols(delegate.createSocket(host, port, localHost, localPort));
}
 
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableProtocols(mInternalFactory.createSocket(host, port));
return enableProtocols(delegate.createSocket(host, port));
}
 
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableProtocols(mInternalFactory.createSocket(address, port, localAddress, localPort));
return enableProtocols(delegate.createSocket(address, port, localAddress, localPort));
}
 
private static Socket enableProtocols(Socket socket) {
Loading
Loading
Loading
Loading
@@ -8,6 +8,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
 
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
Loading
Loading
@@ -39,7 +41,10 @@ public class CustomTrustManager implements X509TrustManager {
}
 
private String mTrustedCertificate;
private String mTrustedHostname;
private String mPrivateKeyAlias;
private SSLSocketFactory mSSLSocketFactory;
private HostnameVerifier mHostnameVerifier;
 
public CustomTrustManager() {}
 
Loading
Loading
@@ -52,6 +57,24 @@ public class CustomTrustManager implements X509TrustManager {
mSSLSocketFactory = null;
}
 
public void setTrustedHostname(String trustedHostname) {
if ((mTrustedHostname == null && trustedHostname == null) || (mTrustedHostname != null && mTrustedHostname.equals(trustedHostname))) {
return;
}
mTrustedHostname = trustedHostname;
mHostnameVerifier = null;
}
public void setPrivateKeyAlias(String privateKeyAlias) {
if ((mPrivateKeyAlias == null && privateKeyAlias == null) || (mPrivateKeyAlias != null && mPrivateKeyAlias.equals(privateKeyAlias))) {
return;
}
mPrivateKeyAlias = privateKeyAlias;
mSSLSocketFactory = null;
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (sDefaultTrustManager == null) {
Loading
Loading
@@ -96,9 +119,14 @@ public class CustomTrustManager implements X509TrustManager {
return mSSLSocketFactory;
}
 
KeyManager[] keyManagers = null;
if (mPrivateKeyAlias != null) {
keyManagers = new KeyManager[] { new CustomKeyManager(mPrivateKeyAlias) };
}
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{this}, null);
sslContext.init(keyManagers, new TrustManager[]{this}, null);
mSSLSocketFactory = new CustomSSLSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
throw new IllegalStateException(e);
Loading
Loading
@@ -106,4 +134,12 @@ public class CustomTrustManager implements X509TrustManager {
 
return mSSLSocketFactory;
}
public HostnameVerifier getHostnameVerifier() {
if (mHostnameVerifier == null) {
mHostnameVerifier = new CustomHostnameVerifier(mTrustedHostname);
}
return mHostnameVerifier;
}
}
package com.commit451.gitlab.util;
import android.content.Context;
import android.util.TypedValue;
import com.afollestad.appthemeengine.ATE;
import com.afollestad.appthemeengine.Config;
import com.commit451.gitlab.R;
public class AppThemeUtil {
public static void setupDefaultConfigs(Context context) {
if (!ATE.config(context, "light_theme").isConfigured(0)) {
ATE.config(context, "light_theme")
.activityTheme(R.style.AppThemeLight)
.primaryColorRes(R.color.primary_default)
.accentColorRes(R.color.accent_default)
.coloredNavigationBar(false)
.commit();
}
if (!ATE.config(context, "dark_theme").isConfigured(0)) {
ATE.config(context, "dark_theme")
.activityTheme(R.style.AppTheme)
.primaryColorRes(R.color.primary_default)
.accentColorRes(R.color.accent_default)
.coloredNavigationBar(true)
.commit();
}
}
public static String resolveThemeKey(Context context) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.ate_key, typedValue, true);
return (String) typedValue.coerceToString();
}
public static int resolvePrimaryColor(Context context) {
return Config.primaryColor(context, resolveThemeKey(context));
}
public static int resolvePrimaryColorDark(Context context) {
return Config.primaryColorDark(context, resolveThemeKey(context));
}
public static int resolveAccentColor(Context context) {
return Config.accentColor(context, resolveThemeKey(context));
}
}
Loading
Loading
@@ -9,17 +9,18 @@ import java.util.Date;
/**
* Our own DateUtils, which call forwards to {@link android.text.format.DateUtils} with some
* nice defaults
* Created by Jawnnypoo on 11/17/2015.
*/
public class DateUtils {
 
public static CharSequence getRelativeTimeSpanString(Context context, Date startTime) {
Date now = new Date();
if (startTime.before(now) && now.getTime() - startTime.getTime() < android.text.format.DateUtils.SECOND_IN_MILLIS) {
if (Math.abs(now.getTime() - startTime.getTime()) < android.text.format.DateUtils.SECOND_IN_MILLIS) {
return context.getString(R.string.just_now);
}
return android.text.format.DateUtils.getRelativeTimeSpanString(startTime.getTime(),
now.getTime(),
android.text.format.DateUtils.SECOND_IN_MILLIS);
android.text.format.DateUtils.SECOND_IN_MILLIS)
.toString();
}
}
Loading
Loading
@@ -9,6 +9,7 @@ import android.support.design.widget.Snackbar;
import android.text.TextUtils;
import android.view.View;
 
import com.afollestad.appthemeengine.Config;
import com.commit451.easel.Easel;
import com.commit451.gitlab.R;
import com.commit451.gitlab.customtabs.BrowserFallback;
Loading
Loading
@@ -26,7 +27,7 @@ public class IntentUtil {
}
 
CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder();
intentBuilder.setToolbarColor(Easel.getThemeAttrColor(activity, R.attr.colorPrimary));
intentBuilder.setToolbarColor(Config.primaryColor(activity, AppThemeUtil.resolveThemeKey(activity)));
intentBuilder.setStartAnimations(activity, R.anim.fade_in, R.anim.do_nothing);
intentBuilder.setExitAnimations(activity, R.anim.do_nothing, R.anim.fade_out);
CustomTabsActivityHelper.openCustomTab(activity, intentBuilder.build(), Uri.parse(url), new BrowserFallback());
Loading
Loading
Loading
Loading
@@ -14,6 +14,7 @@ import com.commit451.gitlab.activity.AboutActivity;
import com.commit451.gitlab.activity.AddIssueActivity;
import com.commit451.gitlab.activity.AddMilestoneActivity;
import com.commit451.gitlab.activity.AddUserActivity;
import com.commit451.gitlab.activity.DiffActivity;
import com.commit451.gitlab.activity.FileActivity;
import com.commit451.gitlab.activity.GroupActivity;
import com.commit451.gitlab.activity.GroupsActivity;
Loading
Loading
@@ -24,6 +25,7 @@ import com.commit451.gitlab.activity.MilestoneActivity;
import com.commit451.gitlab.activity.ProjectActivity;
import com.commit451.gitlab.activity.ProjectsActivity;
import com.commit451.gitlab.activity.SearchActivity;
import com.commit451.gitlab.activity.SettingsActivity;
import com.commit451.gitlab.activity.UserActivity;
import com.commit451.gitlab.model.Account;
import com.commit451.gitlab.model.api.Group;
Loading
Loading
@@ -31,15 +33,13 @@ import com.commit451.gitlab.model.api.Issue;
import com.commit451.gitlab.model.api.MergeRequest;
import com.commit451.gitlab.model.api.Milestone;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.model.api.RepositoryCommit;
import com.commit451.gitlab.model.api.UserBasic;
 
import java.util.List;
import timber.log.Timber;
 
/**
* Manages navigation so that we can override things as needed
* Created by Jawn on 9/21/2015.
*/
public class NavigationManager {
 
Loading
Loading
@@ -47,6 +47,10 @@ public class NavigationManager {
activity.startActivity(AboutActivity.newInstance(activity));
}
 
public static void navigateToSettings(Activity activity) {
activity.startActivity(SettingsActivity.newInstance(activity));
}
public static void navigateToProject(Activity activity, Project project) {
activity.startActivity(ProjectActivity.newInstance(activity, project));
}
Loading
Loading
@@ -67,6 +71,10 @@ public class NavigationManager {
activity.startActivity(LoginActivity.newInstance(activity));
}
 
public static void navigateToLogin(Activity activity, boolean showClose) {
activity.startActivity(LoginActivity.newInstance(activity, showClose));
}
public static void navigateToSearch(Activity activity) {
activity.startActivity(SearchActivity.newInstance(activity));
}
Loading
Loading
@@ -118,6 +126,10 @@ public class NavigationManager {
activity.startActivity(FileActivity.newIntent(activity, projectId, path, branchName));
}
 
public static void navigateToDiffActivity(Activity activity, Project project, RepositoryCommit commit) {
activity.startActivity(DiffActivity.newInstance(activity, project, commit));
}
public static void navigateToAddProjectMember(Activity activity, View fab, long projectId) {
Intent intent = AddUserActivity.newIntent(activity, projectId);
startMorphActivity(activity, fab, intent);
Loading
Loading
@@ -182,21 +194,21 @@ public class NavigationManager {
*/
private static boolean navigateToUrl(Activity activity, Uri uri) {
//TODO figure out the url to activity mapping
if (uri.getPath().contains("issues")) {
List<String> pathSegments = uri.getPathSegments();
for (int i=0; i<pathSegments.size(); i++) {
//segment == issues, and there is one more segment in the path
if (pathSegments.get(i).equals("issues") && i != pathSegments.size()-1) {
//TODO this would probably break if we had query params or anything else in the url
String issueId = pathSegments.get(i+1);
//TODO actually navigate to issue activity which will load the needed project and issue
//navigateToIssue(activity, null, issueId);
return true;
}
}
navigateToProject(activity, -1);
return true;
}
// if (uri.getPath().contains("issues")) {
// List<String> pathSegments = uri.getPathSegments();
// for (int i=0; i<pathSegments.size(); i++) {
// //segment == issues, and there is one more segment in the path
// if (pathSegments.get(i).equals("issues") && i != pathSegments.size()-1) {
// //TODO this would probably break if we had query params or anything else in the url
// String issueId = pathSegments.get(i+1);
// //TODO actually navigate to issue activity which will load the needed project and issue
// //navigateToIssue(activity, null, issueId);
// return true;
// }
// }
// navigateToProject(activity, -1);
// return true;
// }
return false;
}
}
Loading
Loading
@@ -2,7 +2,7 @@ package com.commit451.gitlab.util;
 
import android.net.Uri;
 
import retrofit.Response;
import retrofit2.Response;
import timber.log.Timber;
 
/**
Loading
Loading
package com.commit451.gitlab.view;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.widget.Adapter;
import com.commit451.adapterlayout.AdapterLayoutDelegate;
import com.wefika.flowlayout.FlowLayout;
/**
* {@link com.wefika.flowlayout.FlowLayout} with {@link Adapter} support.
*/
public class AdapterFlowLayout extends FlowLayout {
private AdapterLayoutDelegate mAdapterLayoutDelegate;
public AdapterFlowLayout(Context context) {
super(context);
}
public AdapterFlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AdapterFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setAdapter(RecyclerView.Adapter adapter) {
if (mAdapterLayoutDelegate == null) {
mAdapterLayoutDelegate = new AdapterLayoutDelegate(this);
}
mAdapterLayoutDelegate.setAdapter(adapter);
}
@Nullable
public RecyclerView.Adapter getAdapter() {
if (mAdapterLayoutDelegate != null) {
return mAdapterLayoutDelegate.getAdapter();
}
return null;
}
@Nullable
public RecyclerView.ViewHolder getViewHolderAt(int index) {
return mAdapterLayoutDelegate.getViewHolderAt(index);
}
}
\ No newline at end of file
package com.commit451.gitlab.view;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class GitLabCardView extends CardView {
private boolean mAreMarginsAdjusted = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
private Rect mShadowPadding;
public GitLabCardView(Context context) {
super(context);
}
public GitLabCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GitLabCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* This makes sure that the CardView looks correct on pre-Lollipop devices
*/
@Override
public void setShadowPadding(int left, int top, int right, int bottom) {
super.setShadowPadding(left, top, right, bottom);
mShadowPadding = new Rect(left, top, right, bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Update the margins to clip the outer border on pre-Lollipop devices
if (!mAreMarginsAdjusted) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec)
+ mShadowPadding.left + mShadowPadding.right, MeasureSpec.getMode(widthMeasureSpec));
heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec)
+ mShadowPadding.top + mShadowPadding.bottom, MeasureSpec.getMode(heightMeasureSpec));
MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
params.setMargins(params.leftMargin - mShadowPadding.left,
params.topMargin - mShadowPadding.top,
params.rightMargin - mShadowPadding.right,
params.bottomMargin - mShadowPadding.bottom);
requestLayout();
mAreMarginsAdjusted = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
Loading
Loading
@@ -3,6 +3,7 @@ package com.commit451.gitlab.view;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
Loading
Loading
@@ -19,6 +20,7 @@ import com.commit451.gitlab.R;
import com.commit451.gitlab.activity.GroupsActivity;
import com.commit451.gitlab.activity.ProjectsActivity;
import com.commit451.gitlab.adapter.AccountsAdapter;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.data.Prefs;
import com.commit451.gitlab.event.CloseDrawerEvent;
Loading
Loading
@@ -38,9 +40,6 @@ import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
 
/**
Loading
Loading
@@ -82,6 +81,10 @@ public class GitLabNavigationView extends NavigationView {
}
LabCoatApp.bus().post(new CloseDrawerEvent());
return true;
case R.id.nav_settings:
LabCoatApp.bus().post(new CloseDrawerEvent());
NavigationManager.navigateToSettings((Activity) getContext());
return true;
case R.id.nav_about:
LabCoatApp.bus().post(new CloseDrawerEvent());
NavigationManager.navigateToAbout((Activity) getContext());
Loading
Loading
@@ -99,7 +102,7 @@ public class GitLabNavigationView extends NavigationView {
 
@Override
public void onAddAccountClicked() {
NavigationManager.navigateToLogin((Activity) getContext());
NavigationManager.navigateToLogin((Activity) getContext(), true);
toggleAccounts();
LabCoatApp.bus().post(new CloseDrawerEvent());
}
Loading
Loading
@@ -120,23 +123,20 @@ public class GitLabNavigationView extends NavigationView {
}
};
 
private final Callback<UserFull> mUserCallback = new Callback<UserFull>() {
private final EasyCallback<UserFull> mUserCallback = new EasyCallback<UserFull>() {
 
@Override
public void onResponse(Response<UserFull> response, Retrofit retrofit) {
if (!response.isSuccess()) {
return;
}
public void onResponse(@NonNull UserFull response) {
//Store the newly retrieved user to the account so that it stays up to date
// in local storage
Account account = GitLabClient.getAccount();
account.setUser(response.body());
account.setUser(response);
Prefs.updateAccount(getContext(), account);
bindUser(response.body());
bindUser(response);
}
 
@Override
public void onFailure(Throwable t) {
public void onAllFailure(Throwable t) {
Timber.e(t, null);
}
};
Loading
Loading
@@ -181,7 +181,7 @@ public class GitLabNavigationView extends NavigationView {
mAccountList.setLayoutManager(new LinearLayoutManager(getContext()));
addView(mAccountList);
LayoutParams params = (FrameLayout.LayoutParams) mAccountList.getLayoutParams();
params.setMargins(0, getResources().getDimensionPixelSize(R.dimen.navigation_drawer_header_height), 0, 0);
params.setMargins(0, getResources().getDimensionPixelSize(R.dimen.account_header_height), 0, 0);
mAccountList.setBackgroundColor(colorPrimary);
mAccountList.setVisibility(View.GONE);
mAccountAdapter = new AccountsAdapter(getContext(), mAccountsAdapterListener);
Loading
Loading
package com.commit451.gitlab.view;
import android.content.Context;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import com.afollestad.appthemeengine.Config;
import com.commit451.gitlab.util.AppThemeUtil;
import com.pnikosis.materialishprogress.ProgressWheel;
/**
* A subclass of ProgressWheel that automagically themes itself to the accent color
*/
public class GitLabProgressView extends ProgressWheel {
public GitLabProgressView(Context context) {
super(context);
init();
}
public GitLabProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setBarColor(Config.accentColor(getContext(), AppThemeUtil.resolveThemeKey(getContext())));
}
}
Loading
Loading
@@ -4,7 +4,9 @@ import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
 
import com.afollestad.appthemeengine.Config;
import com.commit451.gitlab.R;
import com.commit451.gitlab.util.AppThemeUtil;
 
 
/**
Loading
Loading
@@ -24,6 +26,8 @@ public class GitLabSwipeRefreshLayout extends SwipeRefreshLayout {
}
 
private void init() {
setColorSchemeResources(R.color.red, R.color.orange, R.color.yellow);
int accentColor = Config.accentColor(getContext(),
AppThemeUtil.resolveThemeKey(getContext()));
setColorSchemeColors(accentColor, accentColor, accentColor);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment