Skip to content
Snippets Groups Projects
Commit a7c1cae6 authored by Michi302's avatar Michi302
Browse files

Merge branch 'master' into fdroid

# Conflicts:
#	.gitlab-ci.yml
#	app/build.gradle
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/commit451/gitlab/App.java
parents c265a2ab dfef4962
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 527 additions and 233 deletions
Loading
Loading
@@ -12,10 +12,10 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.MergeRequestSectionsPagerAdapter;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.MergeRequestChangedEvent;
import com.commit451.gitlab.model.api.MergeRequest;
Loading
Loading
@@ -58,15 +58,15 @@ public class MergeRequestActivity extends BaseActivity {
 
private final EasyCallback<MergeRequest> mMergeRequestCallback = new EasyCallback<MergeRequest>() {
@Override
public void onResponse(@NonNull MergeRequest response) {
public void success(@NonNull MergeRequest response) {
mProgress.setVisibility(View.GONE);
Snackbar.make(mRoot, R.string.merge_request_accepted, Snackbar.LENGTH_LONG)
.show();
LabCoatApp.bus().post(new MergeRequestChangedEvent(response));
App.bus().post(new MergeRequestChangedEvent(response));
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
mProgress.setVisibility(View.GONE);
Snackbar.make(mRoot, R.string.unable_to_merge, Snackbar.LENGTH_LONG)
Loading
Loading
Loading
Loading
@@ -15,17 +15,17 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.DividerItemDecoration;
import com.commit451.gitlab.adapter.MilestoneIssuesAdapter;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.MilestoneChangedEvent;
import com.commit451.gitlab.model.api.Issue;
import com.commit451.gitlab.model.api.Milestone;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.navigation.NavigationManager;
import com.commit451.gitlab.navigation.Navigator;
import com.commit451.gitlab.util.PaginationUtil;
import com.squareup.otto.Subscribe;
 
Loading
Loading
@@ -77,17 +77,17 @@ public class MilestoneActivity extends BaseActivity {
 
@OnClick(R.id.add)
void onAddClick() {
NavigationManager.navigateToAddIssue(MilestoneActivity.this, null, mProject);
Navigator.navigateToAddIssue(MilestoneActivity.this, null, mProject);
}
 
@OnClick(R.id.edit)
void onEditClicked(View fab) {
NavigationManager.navigateToEditMilestone(MilestoneActivity.this, fab, mProject, mMilestone);
Navigator.navigateToEditMilestone(MilestoneActivity.this, fab, mProject, mMilestone);
}
 
private final Callback<List<Issue>> mIssuesCallback = new EasyCallback<List<Issue>>() {
@Override
public void onResponse(@NonNull List<Issue> response) {
public void success(@NonNull List<Issue> response) {
mSwipeRefreshLayout.setRefreshing(false);
mLoading = false;
 
Loading
Loading
@@ -104,7 +104,7 @@ public class MilestoneActivity extends BaseActivity {
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
mLoading = false;
mSwipeRefreshLayout.setRefreshing(false);
Loading
Loading
@@ -116,14 +116,14 @@ public class MilestoneActivity extends BaseActivity {
 
private final Callback<List<Issue>> mMoreIssuesCallback = new EasyCallback<List<Issue>>() {
@Override
public void onResponse(@NonNull List<Issue> response) {
public void success(@NonNull List<Issue> response) {
mLoading = false;
mNextPageUrl = PaginationUtil.parse(getResponse()).getNext();
mMilestoneIssuesAdapter.addIssues(response);
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
mLoading = false;
}
Loading
Loading
@@ -131,15 +131,15 @@ public class MilestoneActivity extends BaseActivity {
 
private final Callback<Milestone> mOpenCloseCallback = new EasyCallback<Milestone>() {
@Override
public void onResponse(@NonNull Milestone response) {
public void success(@NonNull Milestone response) {
mProgress.setVisibility(View.GONE);
mMilestone = response;
LabCoatApp.bus().post(new MilestoneChangedEvent(mMilestone));
App.bus().post(new MilestoneChangedEvent(mMilestone));
setOpenCloseMenuStatus();
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
mProgress.setVisibility(View.GONE);
Snackbar.make(mRoot, getString(R.string.failed_to_create_milestone), Snackbar.LENGTH_SHORT)
Loading
Loading
@@ -166,7 +166,7 @@ public class MilestoneActivity extends BaseActivity {
setContentView(R.layout.activity_milestone);
ButterKnife.bind(this);
mEventReceiver = new EventReceiver();
LabCoatApp.bus().register(mEventReceiver);
App.bus().register(mEventReceiver);
 
mProject = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_PROJECT));
mMilestone = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_MILESTONE));
Loading
Loading
@@ -195,7 +195,7 @@ public class MilestoneActivity extends BaseActivity {
mMilestoneIssuesAdapter = new MilestoneIssuesAdapter(new MilestoneIssuesAdapter.Listener() {
@Override
public void onIssueClicked(Issue issue) {
NavigationManager.navigateToIssue(MilestoneActivity.this, mProject, issue);
Navigator.navigateToIssue(MilestoneActivity.this, mProject, issue);
}
});
bind(mMilestone);
Loading
Loading
@@ -217,7 +217,7 @@ public class MilestoneActivity extends BaseActivity {
@Override
protected void onDestroy() {
super.onDestroy();
LabCoatApp.bus().unregister(mEventReceiver);
App.bus().unregister(mEventReceiver);
}
 
private void bind(Milestone milestone) {
Loading
Loading
Loading
Loading
@@ -20,11 +20,11 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.SectionsPagerAdapter;
import com.commit451.gitlab.animation.HideRunnable;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.ProjectReloadEvent;
import com.commit451.gitlab.fragment.BaseFragment;
Loading
Loading
@@ -92,14 +92,14 @@ public class ProjectActivity extends BaseActivity {
 
private final Callback<Project> mProjectCallback = new EasyCallback<Project>() {
@Override
public void onResponse(@NonNull Project response) {
public void success(@NonNull Project response) {
mProject = response;
setupTabs();
loadBranches();
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
mProgress.animate()
.alpha(0.0f)
Loading
Loading
@@ -112,7 +112,7 @@ public class ProjectActivity extends BaseActivity {
private final Callback<List<Branch>> mBranchesCallback = new EasyCallback<List<Branch>>() {
 
@Override
public void onResponse(@NonNull List<Branch> response) {
public void success(@NonNull List<Branch> response) {
mProgress.animate()
.alpha(0.0f)
.withEndAction(new HideRunnable(mProgress));
Loading
Loading
@@ -140,7 +140,7 @@ public class ProjectActivity extends BaseActivity {
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
mProgress.animate()
.alpha(0.0f)
Loading
Loading
@@ -221,7 +221,7 @@ public class ProjectActivity extends BaseActivity {
}
 
private void broadcastLoad() {
LabCoatApp.bus().post(new ProjectReloadEvent(mProject, mBranchName));
App.bus().post(new ProjectReloadEvent(mProject, mBranchName));
}
 
@Override
Loading
Loading
Loading
Loading
@@ -12,11 +12,11 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.ProjectsPagerAdapter;
import com.commit451.gitlab.event.CloseDrawerEvent;
import com.commit451.gitlab.navigation.NavigationManager;
import com.commit451.gitlab.navigation.Navigator;
import com.squareup.otto.Subscribe;
 
import butterknife.BindView;
Loading
Loading
@@ -45,7 +45,7 @@ public class ProjectsActivity extends BaseActivity {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
NavigationManager.navigateToSearch(ProjectsActivity.this);
Navigator.navigateToSearch(ProjectsActivity.this);
return true;
}
return false;
Loading
Loading
@@ -58,7 +58,7 @@ public class ProjectsActivity extends BaseActivity {
setContentView(R.layout.activity_projects);
ButterKnife.bind(this);
mEventReceiver = new EventReceiver();
LabCoatApp.bus().register(mEventReceiver);
App.bus().register(mEventReceiver);
 
mToolbar.setTitle(R.string.projects);
mToolbar.setNavigationIcon(R.drawable.ic_menu_24dp);
Loading
Loading
@@ -77,7 +77,7 @@ public class ProjectsActivity extends BaseActivity {
@Override
protected void onDestroy() {
super.onDestroy();
LabCoatApp.bus().unregister(mEventReceiver);
App.bus().unregister(mEventReceiver);
}
 
private class EventReceiver {
Loading
Loading
Loading
Loading
@@ -7,9 +7,14 @@ import android.os.Bundle;
import android.widget.Toast;
 
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.Account;
import com.commit451.gitlab.navigation.DeepLinker;
import com.commit451.gitlab.navigation.Navigator;
import com.commit451.gitlab.navigation.RoutingNavigator;
import com.commit451.gitlab.navigation.RoutingRouter;
import com.commit451.gitlab.util.IntentUtil;
import com.commit451.gitlab.navigation.NavigationManager;
import com.novoda.simplechromecustomtabs.SimpleChromeCustomTabs;
 
import timber.log.Timber;
 
Loading
Loading
@@ -18,6 +23,56 @@ import timber.log.Timber;
*/
public class RoutingActivity extends Activity {
 
RoutingRouter mRouter;
private final RoutingNavigator mNavigator = new RoutingNavigator() {
@Override
public void onRouteToIssue(String projectNamespace, String projectName, String issueIid) {
Navigator.navigateToIssue(RoutingActivity.this, projectNamespace, projectName, issueIid);
}
@Override
public void onRouteToCommit(String projectNamespace, String projectName, String commitSha) {
startActivity(LoadSomeInfoActivity.newIntent(RoutingActivity.this, projectNamespace, projectName, commitSha));
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing);
}
@Override
public void onRouteToMergeRequest(String projectNamespace, String projectName, String mergeRequestId) {
startActivity(LoadSomeInfoActivity.newMergeRequestIntent(RoutingActivity.this, projectNamespace, projectName, mergeRequestId));
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing);
}
@Override
public void onRouteToProject(String namespace, String projectId) {
Navigator.navigateToProject(RoutingActivity.this, projectId);
}
@Override
public void onRouteToBuild(String projectNamespace, String projectName, String buildNumber) {
startActivity(LoadSomeInfoActivity.newBuildIntent(RoutingActivity.this, projectNamespace, projectName, Long.valueOf(buildNumber)));
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing);
}
@Override
public void onRouteToMilestone(String projectNamespace, String projectName, String milestoneNumber) {
startActivity(LoadSomeInfoActivity.newMilestoneIntent(RoutingActivity.this, projectNamespace, projectName, milestoneNumber));
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing);
}
@Override
public void onRouteUnknown(Uri uri) {
if (mOriginalUri != null) {
IntentUtil.openPage(RoutingActivity.this, uri.toString());
} else {
Toast.makeText(RoutingActivity.this, R.string.deeplink_navigate_error, Toast.LENGTH_SHORT)
.show();
}
}
};
Uri mOriginalUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Loading
Loading
@@ -30,6 +85,20 @@ public class RoutingActivity extends Activity {
handleIntent(intent);
}
 
@Override
protected void onResume() {
super.onResume();
SimpleChromeCustomTabs.getInstance().connectTo(this);
}
@Override
protected void onPause() {
if (SimpleChromeCustomTabs.getInstance().isConnected()) {
SimpleChromeCustomTabs.getInstance().disconnectFrom(this);
}
super.onPause();
}
private void handleIntent(Intent intent) {
if (intent == null || intent.getData() == null) {
Timber.e("No url was passed. How did that happen?");
Loading
Loading
@@ -38,96 +107,21 @@ public class RoutingActivity extends Activity {
}
//If it has an original uri, this means that it is an internal deep link and we
//can still fall back to what the original uri was and just show it
Uri originalUri = intent.getParcelableExtra(DeepLinker.EXTRA_ORIGINAL_URI);
mOriginalUri = intent.getParcelableExtra(DeepLinker.EXTRA_ORIGINAL_URI);
Uri link = intent.getData();
Timber.d("Received deep link %s", link);
Timber.d("Original link was %s", originalUri);
boolean handled = false;
if (link.getPath().contains("issues")) {
Timber.d("Parsing as issue uri");
if (link.getLastPathSegment().equals("issues")) {
//this means it was just a link to something like
//gitlab.com/Commit451/LabCoat/issues
launchProject(link);
handled = true;
} else {
int indexOfIssuesPathSegment = -1;
for (int i=0; i<link.getPathSegments().size(); i++) {
if (link.getPathSegments().get(i).equals("issues")) {
indexOfIssuesPathSegment = i;
break;
}
}
//this is good, it means it is a link to an actual issue
String projectNamespace = link.getPathSegments().get(0);
String projectName = link.getPathSegments().get(1);
String lastSegment = link.getPathSegments().get(3);
//We have to do this cause there can be args on the url, such as
//https://gitlab.com/Commit451/LabCoat/issues/158#note_4560580
String[] stuff = lastSegment.split("#");
String issueIid = stuff[0];
Timber.d("Navigating to project %s with issue number %s", projectName, issueIid);
NavigationManager.navigateToIssue(this, projectNamespace, projectName, issueIid);
handled = true;
}
} else if (link.getPath().contains("commit")) {
if (link.getPathSegments().size() == 4) {
String projectNamespace = link.getPathSegments().get(0);
String projectName = link.getPathSegments().get(1);
String commitSha = link.getPathSegments().get(3);
startActivity(LoadSomeInfoActivity.newIntent(this, projectNamespace, projectName, commitSha));
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing);
handled = true;
}
} else if (link.getPath().contains("commits")) {
launchProject(link);
handled = true;
} else if (link.getPath().contains("compare")) {
//comparing two commit shas
String[] shas = link.getLastPathSegment().split("...");
//TODO do the rest
} else if (link.getPath().contains("merge_requests")) {
for (int i=0; i<link.getPathSegments().size(); i++) {
if (link.getPathSegments().get(i).equals("merge_requests")) {
if (i < link.getPathSegments().size() - 1) {
String projectNamespace = link.getPathSegments().get(i-2);
String projectName = link.getPathSegments().get(i-1);
String mergeRequestId = link.getPathSegments().get(i+1);
startActivity(LoadSomeInfoActivity.newMergeRequestIntent(this, projectNamespace, projectName, mergeRequestId));
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing);
handled = true;
break;
} else {
launchProject(link);
handled = true;
break;
}
}
}
}
Timber.d("Original link was %s", mOriginalUri);
 
if (!handled) {
if (originalUri != null) {
launchOriginalUri(originalUri);
} else {
showError();
}
//okay so last thing, if the user has followed a link, but the user
//is not actually signed in, we want to direct them to signin
if (GitLabClient.getAccount() == null && Account.getAccounts(this).isEmpty()) {
Navigator.navigateToLogin(this);
finish();
return;
}
mRouter = new RoutingRouter(mNavigator);
mRouter.route(link);
finish();
}
private void launchProject(Uri uri) {
String projectId = uri.getPathSegments().get(2);
NavigationManager.navigateToProject(this, projectId);
}
private void launchOriginalUri(Uri uri) {
IntentUtil.openPage(this, uri.toString());
}
private void showError() {
Toast.makeText(RoutingActivity.this, R.string.deeplink_navigate_error, Toast.LENGTH_SHORT)
.show();
}
}
 
Loading
Loading
@@ -34,9 +34,9 @@ public class FilesAdapter extends RecyclerView.Adapter<FileViewHolder> {
int position = (int) v.getTag(R.id.list_position);
RepositoryTreeObject treeItem = getValueAt(position);
 
if (treeItem.getType() == RepositoryTreeObject.Type.FOLDER) {
if (treeItem.getType().equals(RepositoryTreeObject.TYPE_FOLDER)) {
mListener.onFolderClicked(treeItem);
} else if (treeItem.getType() == RepositoryTreeObject.Type.FILE) {
} else if (treeItem.getType().equals(RepositoryTreeObject.TYPE_FILE)) {
mListener.onFileClicked(treeItem);
}
}
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ import android.view.View;
import android.view.ViewGroup;
 
import com.commit451.gitlab.R;
import com.commit451.gitlab.viewHolder.LabelViewHolder;
import com.commit451.gitlab.viewHolder.IssueLabelViewHolder;
 
import java.util.ArrayList;
import java.util.Collection;
Loading
Loading
@@ -13,10 +13,10 @@ import java.util.Collection;
/**
* So many labels
*/
public class IssueLabelsAdapter extends RecyclerView.Adapter<LabelViewHolder> {
public class IssueLabelsAdapter extends RecyclerView.Adapter<IssueLabelViewHolder> {
 
public interface Listener {
void onLabelClicked(String label, LabelViewHolder viewHolder);
void onLabelClicked(String label, IssueLabelViewHolder viewHolder);
}
private Listener mListener;
 
Loading
Loading
@@ -31,7 +31,7 @@ public class IssueLabelsAdapter extends RecyclerView.Adapter<LabelViewHolder> {
@Override
public void onClick(View v) {
int position = (int) v.getTag(R.id.list_position);
LabelViewHolder holder = (LabelViewHolder) v.getTag(R.id.list_view_holder);
IssueLabelViewHolder holder = (IssueLabelViewHolder) v.getTag(R.id.list_view_holder);
mListener.onLabelClicked(getEntry(position), holder);
}
};
Loading
Loading
@@ -49,14 +49,14 @@ public class IssueLabelsAdapter extends RecyclerView.Adapter<LabelViewHolder> {
}
 
@Override
public LabelViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LabelViewHolder holder = LabelViewHolder.inflate(parent);
public IssueLabelViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
IssueLabelViewHolder holder = IssueLabelViewHolder.inflate(parent);
holder.itemView.setOnClickListener(mOnItemClickListener);
return holder;
}
 
@Override
public void onBindViewHolder(final LabelViewHolder holder, int position) {
public void onBindViewHolder(final IssueLabelViewHolder holder, int position) {
holder.itemView.setTag(R.id.list_position, position);
holder.itemView.setTag(R.id.list_view_holder, holder);
holder.bind(getEntry(position));
Loading
Loading
package com.commit451.gitlab.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.commit451.gitlab.R;
import com.commit451.gitlab.model.api.Label;
import com.commit451.gitlab.viewHolder.LabelViewHolder;
import com.commit451.gitlab.viewHolder.ProjectMemberFooterViewHolder;
import java.util.ArrayList;
import java.util.Collection;
/**
* Shows a projects members and a groups members
*/
public class LabelAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_ITEM = 0;
private static final int TYPE_FOOTER = 1;
//TODO bring this back maybe?
private static final int FOOTER_COUNT = 0;
private Listener mListener;
private ArrayList<Label> mItems;
private final View.OnClickListener mProjectMemberClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = (int) v.getTag(R.id.list_position);
LabelViewHolder viewHolder = (LabelViewHolder) v.getTag(R.id.list_view_holder);
mListener.onLabelClicked(getItem(position), viewHolder);
}
};
private final View.OnClickListener mFooterClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onAddLabelClicked();
}
};
public LabelAdapter(Listener listener) {
mListener = listener;
mItems = new ArrayList<>();
}
public Label getItem(int position) {
return mItems.get(position);
}
public void setItems(Collection<Label> data) {
mItems.clear();
if (data != null) {
mItems.addAll(data);
}
notifyDataSetChanged();
}
public void addLabel(Label label) {
mItems.add(label);
notifyItemInserted(mItems.size());
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_ITEM:
LabelViewHolder itemViewHolder = LabelViewHolder.inflate(parent);
itemViewHolder.itemView.setOnClickListener(mProjectMemberClickListener);
return itemViewHolder;
case TYPE_FOOTER:
ProjectMemberFooterViewHolder footerHolder = ProjectMemberFooterViewHolder.inflate(parent);
footerHolder.itemView.setOnClickListener(mFooterClickListener);
return footerHolder;
}
throw new IllegalStateException("No idea what to inflate with view type of " + viewType);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ProjectMemberFooterViewHolder) {
//
} else if (holder instanceof LabelViewHolder) {
final Label label = getItem(position);
((LabelViewHolder) holder).bind(label);
holder.itemView.setTag(R.id.list_position, position);
holder.itemView.setTag(R.id.list_view_holder, holder);
}
}
@Override
public int getItemCount() {
return mItems.size() + FOOTER_COUNT;
}
@Override
public int getItemViewType(int position) {
if (position == mItems.size()) {
return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
public interface Listener {
void onLabelClicked(Label label, LabelViewHolder viewHolder);
void onAddLabelClicked();
}
}
Loading
Loading
@@ -15,6 +15,7 @@ import com.commit451.gitlab.fragment.MilestonesFragment;
import com.commit451.gitlab.fragment.ProjectMembersFragment;
import com.commit451.gitlab.fragment.MergeRequestsFragment;
import com.commit451.gitlab.fragment.ProjectFragment;
import com.commit451.gitlab.fragment.SnippetsFragment;
import com.commit451.gitlab.model.api.Project;
 
import java.util.HashSet;
Loading
Loading
@@ -27,7 +28,6 @@ import timber.log.Timber;
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
 
private static final int SECTION_COUNT = 9;
private static final int PROJECT_POS = 0;
private static final int ACTIVITY_POS = 1;
private static final int FILES_POS = 2;
Loading
Loading
@@ -37,6 +37,7 @@ public class SectionsPagerAdapter extends FragmentPagerAdapter {
private static final int ISSUES_POS = 6;
private static final int MERGE_REQUESTS_POS = 7;
private static final int PROJECT_MEMBERS_POS = 8;
private static final int SNIPPETS_POS = 9;
 
private final Project mProject;
private final String[] mTitles;
Loading
Loading
@@ -65,11 +66,16 @@ public class SectionsPagerAdapter extends FragmentPagerAdapter {
Timber.d("Milestones are disabled");
mDisabledSections.add(MILESTONES_POS);
}
//TODO change this back when we do snippets
if (true){//!project.isSnippetsEnabled()) {
Timber.d("Snippets are disabled");
mDisabledSections.add(SNIPPETS_POS);
}
}
 
@Override
public int getCount() {
return SECTION_COUNT - mDisabledSections.size();
return mTitles.length - mDisabledSections.size();
}
 
@Override
Loading
Loading
@@ -102,6 +108,8 @@ public class SectionsPagerAdapter extends FragmentPagerAdapter {
return MergeRequestsFragment.newInstance();
case PROJECT_MEMBERS_POS:
return ProjectMembersFragment.newInstance();
case SNIPPETS_POS:
return SnippetsFragment.newInstance();
}
 
throw new IllegalStateException("Position exceeded on view pager");
Loading
Loading
package com.commit451.gitlab.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.commit451.gitlab.R;
import com.commit451.gitlab.model.api.Snippet;
import com.commit451.gitlab.viewHolder.LoadingFooterViewHolder;
import com.commit451.gitlab.viewHolder.SnippetViewHolder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class SnippetAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static final int FOOTER_COUNT = 1;
private static final int TYPE_ITEM = 0;
private static final int TYPE_FOOTER = 1;
public interface Listener {
void onSnippetClicked(Snippet snippet);
}
private Listener mListener;
private List<Snippet> mValues;
private boolean mLoading;
private final View.OnClickListener mOnItemClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = (int) v.getTag(R.id.list_position);
mListener.onSnippetClicked(getValueAt(position));
}
};
public SnippetAdapter(Listener listener) {
mListener = listener;
mValues = new ArrayList<>();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_ITEM:
SnippetViewHolder holder = SnippetViewHolder.inflate(parent);
holder.itemView.setOnClickListener(mOnItemClickListener);
return holder;
case TYPE_FOOTER:
return LoadingFooterViewHolder.inflate(parent);
}
throw new IllegalStateException("No holder for viewType " + viewType);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof SnippetViewHolder) {
Snippet snippet = getValueAt(position);
((SnippetViewHolder) holder).bind(snippet);
holder.itemView.setTag(R.id.list_position, position);
} else if (holder instanceof LoadingFooterViewHolder) {
((LoadingFooterViewHolder) holder).bind(mLoading);
}
}
@Override
public int getItemCount() {
return mValues.size() + FOOTER_COUNT;
}
@Override
public int getItemViewType(int position) {
if (position == mValues.size()) {
return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
public Snippet getValueAt(int position) {
return mValues.get(position);
}
public void setData(Collection<Snippet> milestones) {
mValues.clear();
addData(milestones);
}
public void addData(Collection<Snippet> milestones) {
if (milestones != null) {
mValues.addAll(milestones);
}
notifyDataSetChanged();
}
public void addSnippet(Snippet milestone) {
mValues.add(0, milestone);
notifyItemInserted(0);
}
public void updateIssue(Snippet snippet) {
int indexToDelete = -1;
for (int i=0; i<mValues.size(); i++) {
if (mValues.get(i).getId() == snippet.getId()) {
indexToDelete = i;
break;
}
}
if (indexToDelete != -1) {
mValues.remove(indexToDelete);
mValues.add(indexToDelete, snippet);
}
notifyItemChanged(indexToDelete);
}
public void setLoading(boolean loading) {
mLoading = loading;
notifyItemChanged(mValues.size());
}
}
\ No newline at end of file
package com.commit451.gitlab.api;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.commit451.gitlab.api.exception.HttpException;
import com.commit451.gitlab.api.exception.NullBodyException;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* An easier version of a Retrofit callback that simplifies
* the response block so that you do not have to check
* {@link Response#isSuccessful()}. You can still call {@link #getResponse()}
* if you need it. If there is a HTTP error, {@link #onAllFailure(Throwable)}
* will be called with a {@link HttpException}
*/
public abstract class EasyCallback<T> implements Callback<T> {
@Nullable
private Response<T> mResponse;
private Call<T> mCall;
public abstract void onResponse(@NonNull T response);
public abstract void onAllFailure(Throwable t);
@Override
public void onResponse(Call<T> call, Response<T> response) {
mCall = call;
mResponse = response;
if (!response.isSuccessful()) {
onAllFailure(new HttpException(response.code(), response.errorBody()));
return;
}
if (response.body() == null) {
onAllFailure(new NullBodyException());
return;
}
onResponse(response.body());
}
@Override
public void onFailure(Call<T> call, Throwable t) {
mCall = call;
onAllFailure(t);
}
@Nullable
public Response<T> getResponse() {
return mResponse;
}
@Nullable
public Call<T> getCall() {
return mCall;
}
}
Loading
Loading
@@ -20,6 +20,7 @@ import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.model.api.RepositoryCommit;
import com.commit451.gitlab.model.api.RepositoryFile;
import com.commit451.gitlab.model.api.RepositoryTreeObject;
import com.commit451.gitlab.model.api.Snippet;
import com.commit451.gitlab.model.api.User;
import com.commit451.gitlab.model.api.UserBasic;
import com.commit451.gitlab.model.api.UserFull;
Loading
Loading
@@ -180,11 +181,16 @@ public interface GitLab {
/* --- MILESTONES --- */
 
@GET(API_VERSION + "/projects/{id}/milestones")
Call<List<Milestone>> getMilestones(@Path("id") long projectId);
Call<List<Milestone>> getMilestones(@Path("id") long projectId,
@Query("state") String state);
 
@GET
Call<List<Milestone>> getMilestones(@Url String url);
 
@GET(API_VERSION + "/projects/{id}/issues")
Call<List<Milestone>> getMilestonesByIid(@Path("id") long projectId,
@Query("iid") String internalMilestoneId);
@GET(API_VERSION + "/projects/{id}/milestones/{milestone_id}/issues")
Call<List<Issue>> getMilestoneIssues(@Path("id") long projectId,
@Path("milestone_id") long milestoneId);
Loading
Loading
@@ -222,6 +228,10 @@ public interface GitLab {
Call<List<MergeRequest>> getMergeRequests(@Url String url,
@Query("state") String state);
 
@GET(API_VERSION + "/projects/{id}/merge_requests")
Call<List<MergeRequest>> getMergeRequestsByIid(@Path("id") long projectId,
@Query("iid") String internalMergeRequestId);
@GET(API_VERSION + "/projects/{id}/merge_request/{merge_request_id}")
Call<MergeRequest> getMergeRequest(@Path("id") long projectId,
@Path("merge_request_id") long mergeRequestId);
Loading
Loading
@@ -258,8 +268,7 @@ public interface GitLab {
@Query("state") String state);
 
@GET
Call<List<Issue>> getIssues(@Url String url,
@Query("state") String state);
Call<List<Issue>> getIssues(@Url String url);
 
@GET(API_VERSION + "/projects/{id}/issues/{issue_id}")
Call<Issue> getIssue(@Path("id") long projectId,
Loading
Loading
@@ -267,7 +276,7 @@ public interface GitLab {
 
@GET(API_VERSION + "/projects/{id}/issues")
Call<List<Issue>> getIssuesByIid(@Path("id") long projectId,
@Query("iid") String internalIssueId);
@Query("iid") String internalIssueId);
 
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/issues")
Loading
Loading
@@ -395,4 +404,11 @@ public interface GitLab {
@GET(API_VERSION + "/projects/{id}/builds/{build_id}/artifacts")
Call<List<Artifact>> getBuildArtifacts(@Path("id") long projectId,
@Path("build_id") long buildId);
/* --- SNIPPETS --- */
@GET(API_VERSION + "/projects/{id}/snippets")
Call<List<Snippet>> getSnippets(@Path("id") long projectId);
@GET
Call<List<Snippet>> getSnippets(@Url String url);
}
\ No newline at end of file
package com.commit451.gitlab.api;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.model.Account;
import com.commit451.gitlab.provider.GsonProvider;
import com.commit451.gitlab.provider.OkHttpClientProvider;
import com.commit451.gitlab.provider.SimpleXmlProvider;
import com.github.aurae.retrofit2.LoganSquareConverterFactory;
import com.jakewharton.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;
 
Loading
Loading
@@ -12,7 +12,6 @@ import java.util.List;
 
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;
 
/**
Loading
Loading
@@ -26,8 +25,6 @@ public final class GitLabClient {
private static GitLabRss sGitLabRss;
private static Picasso sPicasso;
 
private GitLabClient() {}
public static void setAccount(Account account) {
sAccount = account;
sGitLab = null;
Loading
Loading
@@ -40,15 +37,15 @@ public final class GitLabClient {
}
 
/**
* Get a GitLab instance with the current account passed. Used for login only
* Create a GitLab instance with the current account passed.
* @param account the account to try and log in with
* @return the GitLab instance
*/
public static GitLab instance(Account account) {
public static GitLab create(Account account) {
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(account.getServerUrl().toString())
.client(OkHttpClientProvider.getInstance(account))
.addConverterFactory(GsonConverterFactory.create(GsonProvider.createInstance(account)))
.client(OkHttpClientProvider.createInstance(account))
.addConverterFactory(LoganSquareConverterFactory.create())
.build();
return restAdapter.create(GitLab.class);
}
Loading
Loading
@@ -56,7 +53,7 @@ public final class GitLabClient {
public static GitLab instance() {
if (sGitLab == null) {
checkAccountSet();
sGitLab = instance(sAccount);
sGitLab = create(sAccount);
}
 
return sGitLab;
Loading
Loading
@@ -82,7 +79,7 @@ public final class GitLabClient {
 
public static Picasso getPicasso(Account account) {
OkHttpClient client = OkHttpClientProvider.getInstance(account);
return new Picasso.Builder(LabCoatApp.instance())
return new Picasso.Builder(App.instance())
.downloader(new OkHttp3Downloader(client))
.build();
}
Loading
Loading
@@ -98,7 +95,7 @@ public final class GitLabClient {
 
private static void checkAccountSet() {
if (sAccount == null) {
List<Account> accounts = Account.getAccounts(LabCoatApp.instance());
List<Account> accounts = Account.getAccounts(App.instance());
if (accounts.isEmpty()) {
throw new IllegalStateException("No accounts found");
}
Loading
Loading
@@ -106,4 +103,6 @@ public final class GitLabClient {
GitLabClient.setAccount(accounts.get(0));
}
}
private GitLabClient() {}
}
package com.commit451.gitlab.api;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.activity.LoginActivity;
import com.commit451.gitlab.data.Prefs;
import com.commit451.gitlab.model.Account;
import java.io.IOException;
import okhttp3.Authenticator;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
/**
* If it detects a 401, redirect the user to the login screen, clearing the stack.
* Kinda a weird global way of forcing the user to the login screen if their auth has expired
*/
public class OpenSignInAuthenticator implements Authenticator {
private Account mAccount;
public OpenSignInAuthenticator(Account account) {
mAccount = account;
}
@Override
public Request authenticate(Route route, Response response) throws IOException {
//Special case for if someone just put in their username or password wrong
if (!"session".equals(response.request().url().pathSegments().get(response.request().url().pathSegments().size()-1))) {
//Off the background thread
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
//Remove the account, so that the user can sign in again
Prefs.removeAccount(App.instance(), mAccount);
Toast.makeText(App.instance(), R.string.error_401, Toast.LENGTH_LONG)
.show();
Intent intent = LoginActivity.newIntent(App.instance());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
App.instance().startActivity(intent);
}
});
}
return null;
}
}
package com.commit451.gitlab.api.converter;
import android.net.Uri;
import com.bluelinelabs.logansquare.typeconverters.StringBasedTypeConverter;
/**
* Simple Uri type converter
*/
public class UriTypeConverter extends StringBasedTypeConverter<Uri> {
@Override
public String convertToString(Uri object) {
return object.toString();
}
@Override
public Uri getFromString(String string) {
if (string != null) {
return Uri.parse(string);
} else {
return null;
}
}
}
Loading
Loading
@@ -4,13 +4,14 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.text.TextUtils;
 
import com.bluelinelabs.logansquare.LoganSquare;
import com.commit451.gitlab.BuildConfig;
import com.commit451.gitlab.model.Account;
import com.commit451.gitlab.provider.GsonProvider;
import com.google.gson.reflect.TypeToken;
 
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
Loading
Loading
@@ -37,10 +38,17 @@ public class Prefs {
return PreferenceManager.getDefaultSharedPreferences(context);
}
 
@NonNull
public static List<Account> getAccounts(Context context) {
String accountsJson = getSharedPrefs(context).getString(KEY_ACCOUNTS, null);
if (!TextUtils.isEmpty(accountsJson)) {
return GsonProvider.getInstance().fromJson(accountsJson, new TypeToken<List<Account>>(){}.getType());
try {
return LoganSquare.parseList(accountsJson, Account.class);
} catch (IOException e) {
//why would this ever happen?!?!?1
getSharedPrefs(context).edit().remove(KEY_ACCOUNTS).commit();
}
return new ArrayList<>();
} else {
return new ArrayList<>();
}
Loading
Loading
@@ -66,10 +74,15 @@ public class Prefs {
}
 
private static void setAccounts(Context context, List<Account> accounts) {
getSharedPrefs(context)
.edit()
.putString(KEY_ACCOUNTS, GsonProvider.getInstance().toJson(accounts))
.commit();
try {
String json = LoganSquare.serialize(accounts);
getSharedPrefs(context)
.edit()
.putString(KEY_ACCOUNTS, json)
.commit();
} catch (IOException e) {
//this wont happen! Right?!?!?!
}
}
 
public static int getSavedVersion(Context context) {
Loading
Loading
Loading
Loading
@@ -8,7 +8,7 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.api.Group;
import com.commit451.gitlab.model.api.Member;
Loading
Loading
@@ -47,7 +47,7 @@ public class AccessDialog extends MaterialDialog {
 
private final Callback<Member> mEditUserCallback = new EasyCallback<Member>() {
@Override
public void onResponse(@NonNull Member response) {
public void success(@NonNull Member response) {
if (mAccessChangedListener != null) {
mAccessChangedListener.onAccessChanged(mMember, mRoleNames[getSelectedIndex()]);
}
Loading
Loading
@@ -55,7 +55,7 @@ public class AccessDialog extends MaterialDialog {
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
onError();
}
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.event.ReloadDataEvent;
import com.squareup.otto.Subscribe;
 
Loading
Loading
@@ -18,13 +18,13 @@ public class BaseFragment extends Fragment{
super.onViewCreated(view, savedInstanceState);
 
mBaseEventReceiever = new EventReceiver();
LabCoatApp.bus().register(mBaseEventReceiever);
App.bus().register(mBaseEventReceiever);
}
 
@Override
public void onDestroyView() {
super.onDestroyView();
LabCoatApp.bus().unregister(mBaseEventReceiever);
App.bus().unregister(mBaseEventReceiever);
}
 
protected void loadData() {
Loading
Loading
Loading
Loading
@@ -11,11 +11,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.BuildArtifactsAdapter;
import com.commit451.gitlab.adapter.DividerItemDecoration;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.BuildChangedEvent;
import com.commit451.gitlab.model.api.Artifact;
Loading
Loading
@@ -59,7 +59,7 @@ public class BuildArtifactsFragment extends ButterKnifeFragment {
 
private final EasyCallback<List<Artifact>> mCommitsCallback = new EasyCallback<List<Artifact>>() {
@Override
public void onResponse(@NonNull List<Artifact> response) {
public void success(@NonNull List<Artifact> response) {
if (getView() == null) {
return;
}
Loading
Loading
@@ -74,7 +74,7 @@ public class BuildArtifactsFragment extends ButterKnifeFragment {
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
if (getView() == null) {
return;
Loading
Loading
@@ -141,13 +141,13 @@ public class BuildArtifactsFragment extends ButterKnifeFragment {
});
loadData();
mEventReceiver = new EventReceiver();
LabCoatApp.bus().register(mEventReceiver);
App.bus().register(mEventReceiver);
}
 
@Override
public void onDestroyView() {
super.onDestroyView();
LabCoatApp.bus().unregister(mEventReceiver);
App.bus().unregister(mEventReceiver);
}
 
@Override
Loading
Loading
Loading
Loading
@@ -10,9 +10,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
import com.commit451.gitlab.LabCoatApp;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.EasyCallback;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.BuildChangedEvent;
import com.commit451.gitlab.model.api.Build;
Loading
Loading
@@ -70,16 +70,22 @@ public class BuildDescriptionFragment extends ButterKnifeFragment {
 
private final EasyCallback<Build> mLoadBuildCallback = new EasyCallback<Build>() {
@Override
public void onResponse(@NonNull Build response) {
public void success(@NonNull Build response) {
if (getView() == null) {
return;
}
mSwipeRefreshLayout.setRefreshing(false);
mBuild = response;
bindBuild(response);
LabCoatApp.bus().post(new BuildChangedEvent(response));
App.bus().post(new BuildChangedEvent(response));
}
 
@Override
public void onAllFailure(Throwable t) {
public void failure(Throwable t) {
Timber.e(t, null);
if (getView() == null) {
return;
}
Snackbar.make(mRoot, R.string.unable_to_load_build, Snackbar.LENGTH_LONG)
.show();
}
Loading
Loading
@@ -109,7 +115,7 @@ public class BuildDescriptionFragment extends ButterKnifeFragment {
});
bindBuild(mBuild);
mEventReceiver = new EventReceiver();
LabCoatApp.bus().register(mEventReceiver);
App.bus().register(mEventReceiver);
}
 
private void load() {
Loading
Loading
@@ -133,8 +139,12 @@ public class BuildDescriptionFragment extends ButterKnifeFragment {
} else {
mTextFinished.setVisibility(View.GONE);
}
bindRunner(build.getRunner());
bindCommit(build.getCommit());
if (build.getRunner() != null) {
bindRunner(build.getRunner());
}
if(build.getCommit() != null) {
bindCommit(build.getCommit());
}
}
 
private void bindRunner(Runner runner) {
Loading
Loading
@@ -152,7 +162,7 @@ public class BuildDescriptionFragment extends ButterKnifeFragment {
@Override
public void onDestroyView() {
super.onDestroyView();
LabCoatApp.bus().unregister(mEventReceiver);
App.bus().unregister(mEventReceiver);
}
 
private class EventReceiver {
Loading
Loading
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