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

Merge branch 'master' into fdroid

# Conflicts:
#	.gitlab-ci.yml
#	.magnum.yml
#	app/build.gradle
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/commit451/gitlab/GitLabApp.java
parents 0216e5f3 d79d79f5
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 694 additions and 551 deletions
package com.commit451.gitlab.api;
 
import com.commit451.gitlab.model.Branch;
import com.commit451.gitlab.model.Contributor;
import com.commit451.gitlab.model.DeleteResponse;
import com.commit451.gitlab.model.Diff;
import com.commit451.gitlab.model.DiffLine;
import com.commit451.gitlab.model.FileResponse;
import com.commit451.gitlab.model.Group;
import com.commit451.gitlab.model.Issue;
import com.commit451.gitlab.model.MergeRequest;
import com.commit451.gitlab.model.MergeRequestComment;
import com.commit451.gitlab.model.Milestone;
import com.commit451.gitlab.model.Note;
import com.commit451.gitlab.model.Project;
import com.commit451.gitlab.model.Session;
import com.commit451.gitlab.model.TreeItem;
import com.commit451.gitlab.model.User;
import android.support.annotation.Nullable;
import com.commit451.gitlab.model.api.Branch;
import com.commit451.gitlab.model.api.Contributor;
import com.commit451.gitlab.model.api.Diff;
import com.commit451.gitlab.model.api.Group;
import com.commit451.gitlab.model.api.GroupDetail;
import com.commit451.gitlab.model.api.Issue;
import com.commit451.gitlab.model.api.Member;
import com.commit451.gitlab.model.api.MergeRequest;
import com.commit451.gitlab.model.api.Milestone;
import com.commit451.gitlab.model.api.Note;
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.UserBasic;
import com.commit451.gitlab.model.api.UserFull;
import com.commit451.gitlab.model.api.UserLogin;
 
import java.util.List;
 
Loading
Loading
@@ -30,27 +33,82 @@ import retrofit.http.Path;
import retrofit.http.Query;
import retrofit.http.Url;
 
/**
* Defines the interface for Retrofit for the GitLab API
* http://doc.gitlab.com/ce/api/README.html
*/
public interface GitLab {
String API_VERSION = "api/v3";
/* --- LOGIN --- */
 
@FormUrlEncoded
@POST(API_VERSION + "/session")
Call<Session> getSessionByUsername(@Field("login") String login,
@Field("password") String password);
Call<UserLogin> loginWithUsername(@Field("login") String login,
@Field("password") String password);
 
@FormUrlEncoded
@POST(API_VERSION + "/session")
Call<Session> getSessionByEmail(@Field("email") String email,
@Field("password") String password);
/* --- MAIN --- */
Call<UserLogin> loginWithEmail(@Field("email") String email,
@Field("password") String password);
/* --- USERS --- */
/**
* Get currently authenticated user
*/
@GET(API_VERSION + "/user")
Call<UserFull> getThisUser();
 
@GET(API_VERSION + "/groups?per_page=100")
@GET(API_VERSION + "/users")
Call<List<UserBasic>> getUsers();
@GET
Call<List<UserBasic>> getUsers(@Url String url);
@GET(API_VERSION + "/users")
Call<List<UserBasic>> searchUsers(@Query("search") String query);
@GET
Call<List<UserBasic>> searchUsers(@Url String url, @Query("search") String query);
@GET(API_VERSION + "/users/{id}")
Call<UserBasic> getUser(@Path("id") long userId);
/* --- GROUPS --- */
@GET(API_VERSION + "/groups")
Call<List<Group>> getGroups();
 
@GET(API_VERSION + "/users?per_page=100")
Call<List<User>> getUsers();
@GET
Call<List<Group>> getGroups(@Url String url);
@GET(API_VERSION + "/groups/{id}")
Call<GroupDetail> getGroup(@Path("id") long id);
@GET(API_VERSION + "/groups/{id}/projects?order_by=last_activity_at")
Call<List<Project>> getGroupProjects(@Path("id") long id);
@GET(API_VERSION + "/groups/{id}/members")
Call<List<Member>> getGroupMembers(@Path("id") long groupId);
@FormUrlEncoded
@POST(API_VERSION + "/groups/{id}/members")
Call<Member> addGroupMember(@Path("id") long groupId,
@Field("user_id") long userId,
@Field("access_level") int accessLevel);
@FormUrlEncoded
@PUT(API_VERSION + "/groups/{id}/members/{user_id}")
Call<Member> editGroupMember(@Path("id") long groupId,
@Path("user_id") long userId,
@Field("access_level") int accessLevel);
@DELETE(API_VERSION + "/groups/{id}/members/{user_id}")
Call<Void> removeGroupMember(@Path("id") long groupId,
@Path("user_id") long userId);
/* --- PROJECTS --- */
 
@GET(API_VERSION + "/projects?order_by=last_activity_at")
Call<List<Project>> getAllProjects();
Loading
Loading
@@ -58,136 +116,172 @@ public interface GitLab {
@GET(API_VERSION + "/projects/owned?order_by=last_activity_at")
Call<List<Project>> getMyProjects();
 
@GET(API_VERSION + "/projects?order_by=last_activity_at")
Call<List<Project>> searchAllProjects(@Query("search") String query);
@GET(API_VERSION + "/projects/starred")
Call<List<Project>> getStarredProjects();
@GET(API_VERSION + "/projects/{id}")
Call<Project> getProject(@Path("id") long projectId);
 
@GET
Call<List<Project>> getProjectsNextPage(@Url String url);
Call<List<Project>> getProjects(@Url String url);
 
/* --- PROJECTS --- */
@GET(API_VERSION + "/projects/search/{query}")
Call<List<Project>> searchAllProjects(@Path("query") String query);
 
@GET(API_VERSION + "/projects/{id}/repository/branches?per_page=100&order_by=last_activity_at")
Call<List<Branch>> getBranches(@Path("id") long projectId);
@GET(API_VERSION + "/projects/{id}/members")
Call<List<Member>> getProjectMembers(@Path("id") long projectId);
 
@GET(API_VERSION + "/projects/{id}/milestones?per_page=100")
Call<List<Milestone>> getMilestones(@Path("id") long projectId);
@GET
Call<List<Member>> getProjectMembers(@Url String url);
 
@GET(API_VERSION + "/projects/{id}/members?per_page=100")
Call<List<User>> getUsersFallback(@Path("id") long projectId);
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/members")
Call<Member> addProjectMember(@Path("id") long projectId,
@Field("user_id") long userId,
@Field("access_level") int accessLevel);
 
@GET(API_VERSION + "/projects/{id}/repository/contributors")
Call<List<Contributor>> getContributors(@Path("id") long projectId);
@FormUrlEncoded
@PUT(API_VERSION + "/projects/{id}/members/{user_id}")
Call<Member> editProjectMember(@Path("id") long projectId,
@Path("user_id") long userId,
@Field("access_level") int accessLevel);
 
@GET(API_VERSION + "/projects/{id}/merge_requests?state=opened")
Call<List<MergeRequest>> getMergeRequests(@Path("id") long projectId,
@Query("state") String state);
@DELETE(API_VERSION + "/projects/{id}/members/{user_id}")
Call<Void> removeProjectMember(@Path("id") long projectId,
@Path("user_id") long userId);
 
@GET(API_VERSION + "/projects/{id}/merge_request/{mergeRequestId}/comments")
Call<List<MergeRequestComment>> getMergeRequestNotes(@Path("id") long projectId,
@Path("mergeRequestId") long mergeRequestId);
/* --- MILESTONES --- */
 
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/merge_request/{merge_request_id}/comments")
Call<MergeRequestComment> postMergeRequestComment(@Path("id") long projectId,
@Path("merge_request_id") long mergeRequestId,
@Field("note") String body);
@GET(API_VERSION + "/projects/{id}/milestones")
Call<List<Milestone>> getMilestones(@Path("id") long projectId);
 
@GET(API_VERSION + "/projects/{id}/members")
Call<List<User>> getProjectTeamMembers(@Path("id") long projectId);
@GET
Call<List<Milestone>> getMilestones(@Url String url);
@GET(API_VERSION + "/projects/{id}/milestones/{milestone_id}/issues")
Call<List<Issue>> getMilestoneIssues(@Path("id") long projectId,
@Path("milestone_id") long milestoneId);
@GET
Call<List<Issue>> getMilestoneIssues(@Url String url);
 
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/members")
Call<User> addProjectTeamMember(@Path("id") long projectId,
@Field("user_id") long userId,
@Field("access_level") String accessLevel);
/* --- COMMITS --- */
@POST(API_VERSION + "/projects/{id}/milestones")
Call<Milestone> createMilestone(@Path("id") long projectId,
@Field("title") String title,
@Field("description") String description,
@Field("due_date") String dueDate);
 
@GET(API_VERSION + "/projects/{id}/repository/commits?per_page=100")
Call<List<DiffLine>> getCommits(@Path("id") long projectId,
@Query("ref_name") String branchName);
@FormUrlEncoded
@PUT(API_VERSION + "/projects/{id}/milestones/{milestone_id}")
Call<Milestone> editMilestone(@Path("id") long projectId,
@Path("milestone_id") long milestoneId,
@Field("title") String title,
@Field("description") String description,
@Field("due_date") String dueDate);
 
@GET(API_VERSION + "/projects/{id}/repository/commits/{sha}")
Call<DiffLine> getCommit(@Path("id") long projectId,
@Path("sha") String commitSHA);
/* --- MERGE REQUESTS --- */
 
@GET(API_VERSION + "/projects/{id}/repository/commits/{sha}/diff")
Call<List<Diff>> getCommitDiff(@Path("id") long projectId,
@Path("sha") String commitSHA);
@GET(API_VERSION + "/projects/{id}/merge_requests")
Call<List<MergeRequest>> getMergeRequests(@Path("id") long projectId,
@Query("state") String state);
@GET
Call<List<MergeRequest>> getMergeRequests(@Url String url,
@Query("state") String state);
@GET(API_VERSION + "/projects/{id}/merge_request/{merge_request_id}")
Call<MergeRequest> getMergeRequest(@Path("id") long projectId,
@Path("merge_request_id") long mergeRequestId);
@GET(API_VERSION + "/projects/{id}/merge_requests/{merge_request_id}/notes")
Call<List<Note>> getMergeRequestNotes(@Path("id") long projectId,
@Path("merge_request_id") long mergeRequestId);
@GET
Call<List<Note>> getMergeRequestNotes(@Url String url);
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/merge_requests/{merge_request_id}/notes")
Call<Note> addMergeRequestNote(@Path("id") long projectId,
@Path("merge_request_id") long mergeRequestId,
@Field("body") String body);
 
/* --- ISSUE --- */
/* --- ISSUES --- */
 
@GET(API_VERSION + "/projects/{id}/issues?per_page=100")
@GET(API_VERSION + "/projects/{id}/issues")
Call<List<Issue>> getIssues(@Path("id") long projectId,
@Query("state") String state);
 
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/issues")
Call<Issue> postIssue(@Path("id") long projectId,
@Field("title") String title,
@Field("description") String description);
@GET
Call<List<Issue>> getIssues(@Url String url,
@Query("state") String state);
 
@GET(API_VERSION + "/projects/{id}/issues/{issue_id}/notes?order_by=last_activity_at")
Call<List<Note>> getIssueNotes(@Path("id") long projectId,
@Path("issue_id") long issueId);
@GET(API_VERSION + "/projects/{id}/issues/{issue_id}")
Call<Issue> getIssue(@Path("id") long projectId,
@Path("issue_id") long issueId);
 
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/issues/{issue_id}/notes")
Call<Note> postIssueNote(@Path("id") long projectId,
@Path("issue_id") long issueId,
@Field("body") String body);
@PUT(API_VERSION + "/projects/{id}/issues/{issue_id}")
Call<Issue> setIssueStatus(@Path("id") long projectId,
@Path("issue_id") long issueId,
@Query("state_event") @Issue.EditState String status);
@POST(API_VERSION + "/projects/{id}/issues")
Call<Issue> createIssue(@Path("id") long projectId,
@Field("title") String title,
@Field("description") String description,
@Field("assignee_id") @Nullable Long assigneeId,
@Field("milestone_id") @Nullable Long milestoneId);
 
@PUT(API_VERSION + "/projects/{id}/issues/{issue_id}")
Call<Issue> updateIssue(@Path("id") long projectId,
@Path("issue_id") long issueId,
@Query("title") String title,
@Query("description") String description);
/* --- FILES --- */
@Query("description") String description,
@Query("assignee_id") @Nullable Long assigneeId,
@Query("milestone_id") @Nullable Long milestoneId);
 
@GET(API_VERSION + "/projects/{id}/repository/tree?per_page=100")
Call<List<TreeItem>> getTree(@Path("id") long projectId,
@Query("ref_name") String branchName,
@Query("path") String path);
@PUT(API_VERSION + "/projects/{id}/issues/{issue_id}")
Call<Issue> updateIssueStatus(@Path("id") long projectId,
@Path("issue_id") long issueId,
@Query("state_event") @Issue.EditState String status);
 
@GET(API_VERSION + "/projects/{id}/repository/files")
Call<FileResponse> getFile(@Path("id") long projectId,
@Query("file_path") String path,
@Query("ref") String ref);
/* --- USER --- */
@GET(API_VERSION + "/projects/{id}/issues/{issue_id}/notes")
Call<List<Note>> getIssueNotes(@Path("id") long projectId,
@Path("issue_id") long issueId);
 
@GET(API_VERSION + "/users/{id}")
Call<User> getUser(@Path("id") long userId);
@GET
Call<List<Note>> getIssueNotes(@Url String url);
 
/**
* Get currently authenticated user
*/
@GET(API_VERSION + "/user")
Call<User> getUser();
@FormUrlEncoded
@POST(API_VERSION + "/projects/{id}/issues/{issue_id}/notes")
Call<Note> addIssueNote(@Path("id") long projectId,
@Path("issue_id") long issueId,
@Field("body") String body);
 
/* --- GROUPS --- */
/* --- REPOSITORY --- */
 
@GET(API_VERSION + "/groups/{id}/members?per_page=100")
Call<List<User>> getGroupMembers(@Path("id") long groupId);
@GET(API_VERSION + "/projects/{id}/repository/branches?order_by=last_activity_at")
Call<List<Branch>> getBranches(@Path("id") long projectId);
 
@FormUrlEncoded
@POST(API_VERSION + "/groups/{id}/members")
Call<User> addGroupMember(@Path("id") long groupId,
@Field("user_id") long userId,
@Field("access_level") String accessLevel);
@GET(API_VERSION + "/projects/{id}/repository/contributors")
Call<List<Contributor>> getContributors(@Path("id") long projectId);
 
@DELETE(API_VERSION + "/groups/{id}/members/{user_id}")
Call<DeleteResponse> removeProjectTeamMember(@Path("id") long projectId,
@Path("user_id") long userId);
@GET(API_VERSION + "/projects/{id}/repository/tree")
Call<List<RepositoryTreeObject>> getTree(@Path("id") long projectId,
@Query("ref_name") String branchName,
@Query("path") String path);
 
@GET(API_VERSION + "/groups/{id}")
Call<Group> getGroupDetails(@Path("id") long id);
@GET(API_VERSION + "/projects/{id}/repository/files")
Call<RepositoryFile> getFile(@Path("id") long projectId,
@Query("file_path") String path,
@Query("ref") String ref);
 
@GET(API_VERSION + "/users")
Call<List<User>> searchUsers(@Query("search") String query);
@GET(API_VERSION + "/projects/{id}/repository/commits")
Call<List<RepositoryCommit>> getCommits(@Path("id") long projectId,
@Query("ref_name") String branchName,
@Query("page") int page);
@GET(API_VERSION + "/projects/{id}/repository/commits/{sha}")
Call<RepositoryCommit> getCommit(@Path("id") long projectId,
@Path("sha") String commitSHA);
@GET(API_VERSION + "/projects/{id}/repository/commits/{sha}/diff")
Call<List<Diff>> getCommitDiff(@Path("id") long projectId,
@Path("sha") String commitSHA);
}
\ No newline at end of file
package com.commit451.gitlab.api;
 
import com.commit451.gitlab.BuildConfig;
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.data.Prefs;
import com.commit451.gitlab.ssl.CustomTrustManager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.squareup.okhttp.OkHttpClient;
import org.joda.time.format.ISODateTimeFormat;
import java.lang.reflect.Type;
import java.util.Date;
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.squareup.picasso.OkHttpDownloader;
import com.squareup.picasso.Picasso;
 
import retrofit.GsonConverterFactory;
import retrofit.Retrofit;
import retrofit.SimpleXmlConverterFactory;
 
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
/**
* Pulls all the GitLab stuff from the API
* Created by Jawn on 7/28/2015.
*/
public class GitLabClient {
public final class GitLabClient {
 
private static GitLab gitLab;
private static Account sAccount;
private static GitLab sGitLab;
private static GitLabRss sGitLabRss;
private static Picasso sPicasso;
 
public static GitLab instance() {
private GitLabClient() {}
 
if(gitLab == null) {
// Configure Gson to handle dates correctly
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
return ISODateTimeFormat.dateTimeParser().parseDateTime(json.getAsString()).toDate();
}
});
Gson gson = gsonBuilder.create();
OkHttpClient client = new OkHttpClient();
client.setSslSocketFactory(createSSLSocketFactory());
client.interceptors().add(new ApiKeyRequestInterceptor());
client.interceptors().add(new TimberRequestInterceptor());
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Prefs.getServerUrl(GitLabApp.instance()))
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
gitLab = restAdapter.create(GitLab.class);
public static void setAccount(Account account) {
sAccount = account;
sGitLab = null;
sGitLabRss = null;
sPicasso = null;
}
public static Account getAccount() {
return sAccount;
}
public static GitLab instance(Account account) {
checkAccountSet(account);
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(account.getServerUrl().toString())
.client(OkHttpClientProvider.getInstance(account))
.addConverterFactory(GsonConverterFactory.create(GsonProvider.createInstance(account)))
.build();
return restAdapter.create(GitLab.class);
}
public static GitLab instance() {
if (sGitLab == null) {
sGitLab = instance(sAccount);
}
 
return gitLab;
return sGitLab;
}
public static GitLabRss rssInstance(Account account) {
checkAccountSet(account);
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(account.getServerUrl().toString())
.client(OkHttpClientProvider.getInstance(account))
.addConverterFactory(SimpleXmlConverterFactory.create(SimpleXmlProvider.createPersister(account)))
.build();
return restAdapter.create(GitLabRss.class);
}
 
public static GitLabRss rssInstance() {
if (sGitLabRss == null) {
OkHttpClient client = new OkHttpClient();
client.setSslSocketFactory(createSSLSocketFactory());
if (BuildConfig.DEBUG) {
client.networkInterceptors().add(new TimberRequestInterceptor());
}
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Prefs.getServerUrl(GitLabApp.instance()))
.addConverterFactory(SimpleXmlConverterFactory.create())
.client(client)
.build();
sGitLabRss = restAdapter.create(GitLabRss.class);
sGitLabRss = rssInstance(sAccount);
}
return sGitLabRss;
}
 
public static void reset() {
gitLab = null;
public static Picasso getPicasso(Account account) {
checkAccountSet(account);
return new Picasso.Builder(GitLabApp.instance())
.downloader(new OkHttpDownloader(OkHttpClientProvider.getInstance(account)))
.build();
}
public static Picasso getPicasso() {
if (sPicasso == null) {
sPicasso = getPicasso(sAccount);
}
return sPicasso;
}
 
private static SSLSocketFactory createSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new CustomTrustManager()}, null);
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new IllegalStateException(e);
private static void checkAccountSet(Account account) {
if (account == null) {
throw new IllegalStateException("You cannot do any network calls before the account is set!");
}
}
}
package com.commit451.gitlab.api;
 
import com.commit451.gitlab.model.rss.UserFeed;
import com.commit451.gitlab.model.rss.Feed;
 
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Url;
 
/**
* Gets the RSS of stuff
* Created by John on 10/8/15.
*/
public interface GitLabRss {
 
@GET
Call<UserFeed> getUserFeed(@Url String url);
Call<Feed> getFeed(@Url String url);
}
Loading
Loading
@@ -3,62 +3,71 @@ package com.commit451.gitlab.data;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;
 
import java.util.Collections;
import java.util.Set;
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.util.ArrayList;
import java.util.List;
 
/**
* Shared prefs things
* Created by Jawn on 7/28/2015.
*/
public class Prefs {
 
private static final String LOGGED_IN = "logged_in";
private static final String SERVER_URL = "server_url";
private static final String PRIVATE_TOKEN = "private_token";
private static final String TRUSTED_CERTIFICATES = "trusted_certificates";
private static final String KEY_ACCOUNTS = "accounts";
private static final String KEY_VERSION = "current_version";
 
private static SharedPreferences getSharedPrefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
 
public static boolean isLoggedIn(Context context) {
return getSharedPrefs(context).getBoolean(LOGGED_IN, false);
}
public static void setLoggedIn(Context context, boolean loggedIn) {
SharedPreferences.Editor editor = getSharedPrefs(context).edit();
editor.putBoolean(LOGGED_IN, loggedIn);
editor.commit();
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());
} else {
return new ArrayList<>();
}
}
 
public static void setServerUrl(Context context, String serverUrl) {
SharedPreferences.Editor editor = getSharedPrefs(context).edit();
editor.putString(SERVER_URL, serverUrl);
editor.commit();
public static void addAccount(Context context, Account account) {
List<Account> accounts = getAccounts(context);
accounts.add(account);
setAccounts(context, accounts);
}
 
public static String getServerUrl(Context context) {
return getSharedPrefs(context).getString(SERVER_URL, "");
public static void removeAccount(Context context, Account account) {
List<Account> accounts = getAccounts(context);
accounts.remove(account);
setAccounts(context, accounts);
}
 
public static void setPrivateToken(Context context, String privateToken) {
SharedPreferences.Editor editor = getSharedPrefs(context).edit();
editor.putString(PRIVATE_TOKEN, privateToken);
editor.commit();
public static void updateAccount(Context context, Account account) {
List<Account> accounts = getAccounts(context);
accounts.remove(account);
accounts.add(account);
setAccounts(context, accounts);
}
 
public static String getPrivateToken(Context context) {
return getSharedPrefs(context).getString(PRIVATE_TOKEN, null);
private static void setAccounts(Context context, List<Account> accounts) {
getSharedPrefs(context)
.edit()
.putString(KEY_ACCOUNTS, GsonProvider.getInstance().toJson(accounts))
.commit();
}
 
public static void setTrustedCertificates(Context context, Set<String> certificates) {
SharedPreferences.Editor editor = getSharedPrefs(context).edit();
editor.putStringSet(TRUSTED_CERTIFICATES, certificates);
editor.commit();
public static int getSavedVersion(Context context) {
return getSharedPrefs(context).getInt(KEY_VERSION, -1);
}
 
public static Set<String> getTrustedCertificates(Context context) {
return getSharedPrefs(context).getStringSet(TRUSTED_CERTIFICATES, Collections.<String>emptySet());
public static void setSavedVersion(Context context) {
getSharedPrefs(context)
.edit()
.putInt(KEY_VERSION, BuildConfig.VERSION_CODE)
.commit();
}
}
package com.commit451.gitlab.dialog;
import android.content.Context;
import android.support.v7.app.AppCompatDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.AccessAdapter;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.api.Group;
import com.commit451.gitlab.model.api.Member;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
/**
* Change a users access level, either for a group or for a project
* Created by Jawn on 9/16/2015.
*/
public class AccessDialog extends AppCompatDialog {
@Bind(R.id.list) RecyclerView mRecyclerView;
AccessAdapter mAdapter;
@Bind(R.id.progress) View mProgress;
@Bind(R.id.content_root) View mContentRoot;
@OnClick(R.id.apply)
void onApply() {
String accessLevel = mAdapter.getSelectedValue();
if (accessLevel == null) {
Toast.makeText(getContext(), R.string.please_select_access_level, Toast.LENGTH_LONG)
.show();
} else {
changeAccess(Member.getAccessLevel(accessLevel));
}
}
@OnClick(R.id.cancel_button)
void onCancel() {
dismiss();
}
OnAccessChangedListener mAccessChangedListener;
OnAccessAppliedListener mAccessAppliedListener;
String[] mRoleNames;
String[] mRoleValues;
long mProjectId = -1;
Group mGroup;
Member mMember;
private final Callback<Member> mEditUserCallback = new Callback<Member>() {
@Override
public void onResponse(Response<Member> response, Retrofit retrofit) {
if (!response.isSuccess()) {
onError();
return;
}
if (mAccessChangedListener != null) {
mAccessChangedListener.onAccessChanged(mMember, mAdapter.getSelectedValue());
}
dismiss();
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
onError();
}
};
public AccessDialog(Context context, OnAccessAppliedListener accessAppliedListener) {
this(context, null, null, -1);
mAccessAppliedListener = accessAppliedListener;
}
public AccessDialog(Context context, Member member, Group group) {
this(context, member, group, -1);
}
public AccessDialog(Context context, Member member, long projectId) {
this(context, member, null, projectId);
}
private AccessDialog(Context context, Member member, Group group, long projectId) {
super(context);
setContentView(R.layout.dialog_access);
ButterKnife.bind(this);
mMember = member;
if (group == null) {
mRoleValues = getContext().getResources().getStringArray(R.array.project_role_values);
mRoleNames = getContext().getResources().getStringArray(R.array.project_role_names);
} else {
mRoleValues = getContext().getResources().getStringArray(R.array.group_role_values);
mRoleNames = getContext().getResources().getStringArray(R.array.group_role_names);
}
mGroup = group;
mProjectId = projectId;
mAdapter = new AccessAdapter(getContext(), mRoleNames);
if (mMember != null) {
mAdapter.setSelectedAccess(Member.getAccessLevel(mMember.getAccessLevel()));
}
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.setAdapter(mAdapter);
}
private void changeAccess(int accessLevel) {
if (mGroup != null) {
showLoading();
GitLabClient.instance().editGroupMember(mGroup.getId(), mMember.getId(), accessLevel).enqueue(mEditUserCallback);
} else if (mProjectId != -1) {
showLoading();
GitLabClient.instance().editProjectMember(mProjectId, mMember.getId(), accessLevel).enqueue(mEditUserCallback);
} else if (mAccessAppliedListener != null) {
mAccessAppliedListener.onAccessApplied(accessLevel);
} else {
throw new IllegalStateException("Not sure what to apply this access change to. Check the constructors plz");
}
}
public void showLoading() {
mContentRoot.animate().alpha(0.0f);
mProgress.setVisibility(View.VISIBLE);
}
private void onError() {
Toast.makeText(getContext(), R.string.failed_to_apply_access_level, Toast.LENGTH_SHORT).show();
dismiss();
}
public void setOnAccessChangedListener(OnAccessChangedListener listener) {
mAccessChangedListener = listener;
}
public interface OnAccessChangedListener {
void onAccessChanged(Member member, String accessLevel);
}
public interface OnAccessAppliedListener {
void onAccessApplied(int accessLevel);
}
}
package com.commit451.gitlab.dialog;
import android.content.Context;
import android.support.v7.app.AppCompatDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.AssigneeAdapter;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.api.Member;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.model.api.UserBasic;
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;
/**
* Assign peeps to an issue
*/
public class AssigneeDialog extends AppCompatDialog {
@Bind(R.id.list) RecyclerView mRecyclerView;
AssigneeAdapter mAssigneeAdapter;
@Bind(R.id.progress) View mProgress;
@Bind(R.id.content_root) View mContentRoot;
@OnClick(R.id.cancel_button)
void onCancel() {
dismiss();
}
@OnClick(R.id.assign_button)
void onAssign() {
//TODO assign user
mProgress.setVisibility(View.VISIBLE);
mContentRoot.animate().alpha(0.0f);
}
UserBasic mAssignee;
private final Callback<List<Member>> mUsersCallback = new Callback<List<Member>>() {
@Override
public void onResponse(Response<List<Member>> response, Retrofit retrofit) {
if (!response.isSuccess()) {
return;
}
mAssigneeAdapter.setUsers(response.body());
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
dismiss();
}
};
public AssigneeDialog(Context context, UserBasic assignee, Project project) {
super(context);
setContentView(R.layout.dialog_assignee);
ButterKnife.bind(this);
mAssignee = assignee;
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mAssigneeAdapter = new AssigneeAdapter(context, assignee);
mRecyclerView.setAdapter(mAssigneeAdapter);
GitLabClient.instance().getProjectMembers(project.getId()).enqueue(mUsersCallback);
}
}
package com.commit451.gitlab.dialog;
import com.commit451.gitlab.R;
import android.content.Context;
import android.support.v7.app.AppCompatDialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
public class HttpLoginDialog extends AppCompatDialog {
@Bind(R.id.message_text) TextView mMessageTextView;
@Bind(R.id.login_username) EditText mUsernameView;
@Bind(R.id.login_password) EditText mPasswordView;
@Bind(R.id.ok_button) Button mOkButton;
@Bind(R.id.cancel_button) Button mCancelButton;
public HttpLoginDialog(Context context, String realm, final LoginListener loginListener) {
super(context);
setContentView(R.layout.dialog_http_login);
ButterKnife.bind(this);
mMessageTextView.setText(String.format(context.getResources().getString(R.string.realm_message), realm));
mOkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginListener.onLogin(mUsernameView.getText().toString(), mPasswordView.getText().toString());
HttpLoginDialog.this.dismiss();
}
});
mCancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginListener.onCancel();
HttpLoginDialog.this.dismiss();
}
});
setTitle(R.string.login_activity);
}
public interface LoginListener {
void onLogin(String username, String password);
void onCancel();
}
}
package com.commit451.gitlab.dialogs;
import android.content.Context;
import android.support.v7.app.AppCompatDialog;
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.R;
import com.commit451.gitlab.events.LogoutEvent;
import com.commit451.gitlab.tools.NavigationManager;
import com.commit451.gitlab.data.Prefs;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Log out confirmation
* Created by Jawn on 8/21/2015.
*/
public class LogoutDialog extends AppCompatDialog {
@OnClick(R.id.logout_button)
void onLogoutClick() {
Prefs.setLoggedIn(getContext(), false);
Prefs.setPrivateToken(getContext(), null);
NavigationManager.navigateToLogin(getContext());
GitLabApp.bus().post(new LogoutEvent());
}
@OnClick(R.id.cancel_button)
void onCancelClick() {
dismiss();
}
public LogoutDialog(Context context) {
super(context);
setContentView(R.layout.dialog_logout);
ButterKnife.bind(this);
}
}
package com.commit451.gitlab.dialogs;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.transition.ArcMotion;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.EditText;
import android.widget.Toast;
import com.commit451.easel.Easel;
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.R;
import com.commit451.gitlab.activities.BaseActivity;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.events.IssueChangedEvent;
import com.commit451.gitlab.events.IssueCreatedEvent;
import com.commit451.gitlab.model.Issue;
import com.commit451.gitlab.model.Project;
import com.commit451.gitlab.transitions.MorphDialogToFab;
import com.commit451.gitlab.transitions.MorphFabToDialog;
import org.parceler.Parcels;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
/**
* Dialog to input new issues, but not really a dialog at all wink wink
*/
public class NewIssuePopupDialog extends BaseActivity {
private static final String KEY_PROJECT = "project";
private static final String KEY_ISSUE = "issue";
public static Intent newIntent(Context context, Project project, Issue issue) {
Intent intent = new Intent(context, NewIssuePopupDialog.class);
intent.putExtra(KEY_PROJECT, Parcels.wrap(project));
if (issue != null) {
intent.putExtra(KEY_ISSUE, Parcels.wrap(issue));
}
return intent;
}
@Bind(R.id.container) ViewGroup mContainer;
@Bind(R.id.input_root) ViewGroup mInputRoot;
@Bind(R.id.titleInputLayout) TextInputLayout mTitleInputLayout;
@Bind(R.id.title_input) EditText mTitleInput;
@Bind(R.id.descriptionInputLayout) TextInputLayout mDescriptionInputLayout;
@Bind(R.id.description_input) EditText mDescriptionInput;
@Bind(R.id.progress) View mProgress;
private Project mProject;
private Issue mIssue;
@OnClick(R.id.root)
public void onClickOutsideDialog() {
dismiss();
}
@OnClick(R.id.save_button)
public void onSaveClick() {
if(!TextUtils.isEmpty(mTitleInput.getText())) {
mTitleInputLayout.setError(null);
showLoading();
if (mIssue == null) {
GitLabClient.instance().postIssue(mProject.getId(), mTitleInput.getText().toString().trim(), mDescriptionInput.getText().toString().trim())
.enqueue(mIssueCallback);
} else {
GitLabClient.instance().updateIssue(mProject.getId(), mIssue.getId(), mTitleInput.getText().toString(), mDescriptionInput.getText().toString())
.enqueue(mIssueCallback);
}
}
else {
mTitleInputLayout.setError(getString(R.string.required_field));
}
}
@OnClick(R.id.cancel_button)
public void onCancelClick() {
this.dismiss();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup);
ButterKnife.bind(this);
mProject = Parcels.unwrap(getIntent().getParcelableExtra(KEY_PROJECT));
mIssue = Parcels.unwrap(getIntent().getParcelableExtra(KEY_ISSUE));
if (mIssue != null) {
bindIssue();
}
if (Build.VERSION.SDK_INT >= 21) {
int fabColor = Easel.getThemeAttrColor(this, R.attr.colorAccent);
int dialogColor = ContextCompat.getColor(this, R.color.grey);
setupSharedElementTransitionsFab(this, mContainer,
fabColor,
dialogColor,
getResources().getDimensionPixelSize(R.dimen.dialog_corners));
}
}
@TargetApi(21)
public void setupSharedElementTransitionsFab(@NonNull Activity activity,
@Nullable View target,
int fabColor,
int dialogColor,
int dialogCornerRadius) {
ArcMotion arcMotion = new ArcMotion();
arcMotion.setMinimumHorizontalAngle(50f);
arcMotion.setMinimumVerticalAngle(50f);
Interpolator easeInOut = AnimationUtils.loadInterpolator(activity, android.R.interpolator.fast_out_slow_in);
MorphFabToDialog sharedEnter = new MorphFabToDialog(fabColor, dialogColor, dialogCornerRadius);
sharedEnter.setPathMotion(arcMotion);
sharedEnter.setInterpolator(easeInOut);
MorphDialogToFab sharedReturn = new MorphDialogToFab(dialogColor, fabColor);
sharedReturn.setPathMotion(arcMotion);
sharedReturn.setInterpolator(easeInOut);
if (target != null) {
sharedEnter.addTarget(target);
sharedReturn.addTarget(target);
}
activity.getWindow().setSharedElementEnterTransition(sharedEnter);
activity.getWindow().setSharedElementReturnTransition(sharedReturn);
}
@TargetApi(21)
public void dismiss() {
if (Build.VERSION.SDK_INT >= 21) {
finishAfterTransition();
} else {
finish();
}
}
@Override
public void onBackPressed() {
dismiss();
}
private Callback<Issue> mIssueCallback = new Callback<Issue>() {
@Override
public void onResponse(Response<Issue> response, Retrofit retrofit) {
if (!response.isSuccess()) {
Toast.makeText(NewIssuePopupDialog.this, getString(R.string.failed_to_create_issue), Toast.LENGTH_SHORT)
.show();
showLayout();
return;
}
if (mIssue == null) {
GitLabApp.bus().post(new IssueCreatedEvent(response.body()));
} else {
GitLabApp.bus().post(new IssueChangedEvent(response.body()));
}
dismiss();
}
@Override
public void onFailure(Throwable t) {
Timber.e(t.toString());
showLayout();
Toast.makeText(NewIssuePopupDialog.this, getString(R.string.connection_error), Toast.LENGTH_SHORT)
.show();
}
};
private void showLoading() {
mInputRoot.animate().alpha(0.0f).withEndAction(new Runnable() {
@Override
public void run() {
if (mInputRoot != null) {
mInputRoot.setVisibility(View.INVISIBLE);
}
}
});
mProgress.setVisibility(View.VISIBLE);
mProgress.setAlpha(0.0f);
mProgress.animate().alpha(1.0f);
}
private void showLayout() {
mProgress.animate().alpha(0.0f).withEndAction(new Runnable() {
@Override
public void run() {
if (mInputRoot != null) {
mInputRoot.setVisibility(View.GONE);
}
}
});
mInputRoot.setVisibility(View.VISIBLE);
mInputRoot.setAlpha(0.0f);
mInputRoot.animate().alpha(1.0f);
}
private void bindIssue() {
if (!TextUtils.isEmpty(mIssue.getTitle())) {
mTitleInput.setText(mIssue.getTitle());
}
if (!TextUtils.isEmpty(mIssue.getDescription())) {
mDescriptionInput.setText(mIssue.getDescription());
}
}
}
\ No newline at end of file
package com.commit451.gitlab.dialogs;
import android.content.Context;
import android.support.v7.app.AppCompatDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.ProjectAccessAdapter;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* Created by Jawn on 9/16/2015.
*/
public class UserRoleDialog extends AppCompatDialog {
public interface Listener {
void onAccessLevelClicked(String accessLevel);
}
Listener mListener;
@Bind(R.id.list) RecyclerView mRecyclerView;
ProjectAccessAdapter mAdapter;
String[] mRoleNames;
String[] mRoleValues;
private final ProjectAccessAdapter.Listener mAccessListener = new ProjectAccessAdapter.Listener() {
@Override
public void onAccessLevelClicked(String accessLevel) {
for (int i=0; i<mRoleNames.length; i++) {
if (mRoleNames[i].equals(accessLevel)) {
mListener.onAccessLevelClicked(mRoleValues[i]);
return;
}
}
Toast.makeText(getContext(), R.string.user_error, Toast.LENGTH_SHORT)
.show();
}
};
public UserRoleDialog(Context context, Listener listener) {
super(context);
setContentView(R.layout.dialog_user_role);
ButterKnife.bind(this);
mRoleValues = getContext().getResources().getStringArray(R.array.role_values);
mRoleNames = getContext().getResources().getStringArray(R.array.role_names);
mListener = listener;
mAdapter = new ProjectAccessAdapter(getContext(), mAccessListener);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.setAdapter(mAdapter);
}
}
package com.commit451.gitlab.events;
package com.commit451.gitlab.event;
 
/**
* Close the drawer!
Loading
Loading
package com.commit451.gitlab.events;
package com.commit451.gitlab.event;
 
import com.commit451.gitlab.model.Issue;
import com.commit451.gitlab.model.api.Issue;
 
/**
* Event indicating that an issue has changed
* Created by Jawnnypoo on 10/19/2015.
*/
public class IssueChangedEvent {
public Issue issue;
public final Issue mIssue;
 
public IssueChangedEvent(Issue issue) {
this.issue = issue;
this.mIssue = issue;
}
}
package com.commit451.gitlab.events;
package com.commit451.gitlab.event;
 
import com.commit451.gitlab.model.Issue;
import com.commit451.gitlab.model.api.Issue;
 
/**
* Oh no! An Issue!
* Created by Jawn on 7/31/2015.
*/
public class IssueCreatedEvent {
public Issue issue;
public final Issue mIssue;
 
public IssueCreatedEvent(Issue issue) {
this.issue = issue;
this.mIssue = issue;
}
}
package com.commit451.gitlab.event;
/**
* Reload all the issues!
*/
public class IssueReloadEvent {
}
package com.commit451.gitlab.event;
import com.commit451.gitlab.model.Account;
/**
* Called when a user logs in
* Created by John on 12/23/15.
*/
public class LoginEvent {
public Account account;
public LoginEvent(Account account) {
this.account = account;
}
}
package com.commit451.gitlab.events;
package com.commit451.gitlab.event;
 
/**
* Created by Jawn on 8/21/2015.
Loading
Loading
package com.commit451.gitlab.event;
import com.commit451.gitlab.model.api.Member;
/**
* Indicates that a user was added
* Created by Jawn on 9/17/2015.
*/
public class MemberAddedEvent {
public final Member mMember;
public MemberAddedEvent(Member member) {
this.mMember = member;
}
}
package com.commit451.gitlab.event;
import com.commit451.gitlab.model.api.Milestone;
/**
* Shows that a milestone has changed (been edited)
*/
public class MilestoneChangedEvent {
public final Milestone mMilestone;
public MilestoneChangedEvent(Milestone milestone) {
this.mMilestone = milestone;
}
}
package com.commit451.gitlab.event;
import com.commit451.gitlab.model.api.Milestone;
/**
* Signifies that a milestone was created
*/
public class MilestoneCreatedEvent {
public final Milestone mMilestone;
public MilestoneCreatedEvent(Milestone milestone) {
this.mMilestone = milestone;
}
}
package com.commit451.gitlab.events;
package com.commit451.gitlab.event;
 
import com.commit451.gitlab.model.Project;
import com.commit451.gitlab.model.api.Project;
 
/**
* Signifies that either a project or its branch has changed and there needs to be a reaload
* Signifies that either a project or its branch has changed and there needs to be a reload
* Created by Jawn on 9/22/2015.
*/
public class ProjectReloadEvent {
public Project project;
public String branchName;
public final Project mProject;
public final String mBranchName;
 
public ProjectReloadEvent(Project project, String branchName) {
this.project = project;
this.branchName = branchName;
this.mProject = project;
this.mBranchName = branchName;
}
}
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