this commit fixes #597

improves trending overall and some layouts improvements
This commit is contained in:
Kosh 2017-06-03 13:16:08 +08:00
parent 5d5f28c431
commit 91a2cc15f7
36 changed files with 560 additions and 557 deletions

View File

@ -34,6 +34,7 @@ grab **FastHub** from [Here](https://github.com/thermatk/FastHub-Libre) maintain
- Notifications overview and "Mark all as read"
- Search users/orgs, repos, issues/prs & code.
- Pinned Repos
- Trending
- **Repositories**
- Search Repos
- Browse and search Repos
@ -81,6 +82,7 @@ Ads are no longer available until further notice
# Specs / Open-source libraries:
- Minimum **SDK 21**, _but AppCompat is used all the way ;-)_
- **Kotlin** all new modules starting from 2.5.3 will be written in **#Kotlin**.
- **MVP**-architecture: [**ThirtyInch**](https://github.com/grandcentrix/ThirtyInch) because its ThirtyInch.
- [**RxJava2**](https://github.com/ReactiveX/RxJava) & [**RxAndroid**](https://github.com/ReactiveX/RxAndroid) for Retrofit & background threads
- [**Retrofit**](https://github.com/square/retrofit) for constructing the REST API

View File

@ -9,7 +9,6 @@ import com.annimon.stream.Stream;
import com.fastaccess.R;
import com.fastaccess.data.dao.model.Commit;
import com.fastaccess.data.dao.model.Gist;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.Login;
import com.fastaccess.data.dao.model.PullRequest;
import com.fastaccess.data.dao.types.IssueState;
@ -101,8 +100,8 @@ import lombok.Setter;
.collect(Collectors.toList());
}
@NonNull public static List<FragmentPagerAdapterModel> buildForIssues(@NonNull Context context, @NonNull Issue issueModel) {
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), IssueTimelineFragment.newInstance(issueModel)))
@NonNull public static List<FragmentPagerAdapterModel> buildForIssues(@NonNull Context context) {
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), IssueTimelineFragment.newInstance()))
.collect(Collectors.toList());
}
@ -111,7 +110,7 @@ import lombok.Setter;
String login = pullRequest.getLogin();
String repoId = pullRequest.getRepoId();
int number = pullRequest.getNumber();
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), PullRequestTimelineFragment.newInstance(pullRequest)),
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), PullRequestTimelineFragment.newInstance()),
new FragmentPagerAdapterModel(context.getString(R.string.commits), PullRequestCommitsFragment.newInstance(repoId, login, number)),
new FragmentPagerAdapterModel(context.getString(R.string.files), PullRequestFilesFragment.newInstance(repoId, login, number)))
.collect(Collectors.toList());

View File

@ -280,6 +280,7 @@ import static com.annimon.stream.Collectors.toList;
return comment != null ? (int) comment.getId() : 0;
}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
@ -290,6 +291,8 @@ import static com.annimon.stream.Collectors.toList;
dest.writeParcelable(this.pullRequest, flags);
dest.writeParcelable(this.status, flags);
dest.writeParcelable(this.review, flags);
dest.writeParcelable(this.groupedReview, flags);
dest.writeParcelable(this.reviewComment, flags);
dest.writeLong(this.sortedDate != null ? this.sortedDate.getTime() : -1);
}
@ -301,6 +304,8 @@ import static com.annimon.stream.Collectors.toList;
this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
this.status = in.readParcelable(PullRequestStatusModel.class.getClassLoader());
this.review = in.readParcelable(ReviewModel.class.getClassLoader());
this.groupedReview = in.readParcelable(GroupedReviewModel.class.getClassLoader());
this.reviewComment = in.readParcelable(ReviewCommentModel.class.getClassLoader());
long tmpSortedDate = in.readLong();
this.sortedDate = tmpSortedDate == -1 ? null : new Date(tmpSortedDate);
}

View File

@ -1,5 +1,6 @@
package com.fastaccess.data.service;
import com.fastaccess.data.dao.TrendingResponse;
import com.github.florent37.retrojsoup.annotations.Select;

View File

@ -23,6 +23,7 @@ import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import io.reactivex.Observable;
@ -33,6 +34,9 @@ import io.reactivex.Observable;
public class ColorsProvider {
private static List<String> popularLanguages = Stream.of("Java", "Kotlin", "Javascript", "Python", "CSS", "PHP",
"Ruby", "C++", "C", "GO", "Swift").toList();//predefined languages.
private static Map<String, LanguageColorModel> colors = new LinkedHashMap<>();
public static void load() {
@ -60,6 +64,7 @@ public class ColorsProvider {
return Stream.of(colors)
.filter(value -> value != null && !InputHelper.isEmpty(value.getKey()))
.map(Map.Entry::getKey)
.sortBy(s -> !popularLanguages.contains(s))
.collect(Collectors.toCollection(ArrayList::new));
}

View File

@ -60,7 +60,7 @@ public class RestProvider {
.setPrettyPrinting()
.create();
public static OkHttpClient provideOkHttpClient(boolean isRawString) {
private static OkHttpClient provideOkHttpClient(boolean isRawString) {
if (okHttpClient == null) {
OkHttpClient.Builder client = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {

View File

@ -1,5 +1,7 @@
package com.fastaccess.provider.rest.interceptors;
import android.support.annotation.NonNull;
import com.fastaccess.data.service.NotificationService;
import com.fastaccess.helper.InputHelper;
@ -18,7 +20,7 @@ public class AuthenticationInterceptor implements Interceptor {
private String authToken;
private String otp;
@Override public Response intercept(Chain chain) throws IOException {
@Override public Response intercept(@NonNull Chain chain) throws IOException {
Request original = chain.request();
if (original.url() != HttpUrl.get(URI.create(NotificationService.SUBSCRIPTION_URL))) {
Request.Builder builder = original.newBuilder();
@ -28,6 +30,7 @@ public class AuthenticationInterceptor implements Interceptor {
if (!InputHelper.isEmpty(otp)) {
builder.addHeader("X-GitHub-OTP", otp.trim());
}
builder.addHeader("User-Agent", "FastHub");
Request request = builder.build();
return chain.proceed(request);
}

View File

@ -90,12 +90,6 @@ public class HtmlHelper {
return mySpanner;
}
private static final String TAG_ROOT = "githubroot";
private static final String ROOT_START = '<' + TAG_ROOT + '>';
private static final String ROOT_END = "</" + TAG_ROOT + '>';
private static final String TOGGLE_START = "<span class=\"email-hidden-toggle\">";
private static final String TOGGLE_END = "</span>";
@ -122,23 +116,16 @@ public class HtmlHelper {
private static final String PARAGRAPH_END = "</p>";
private static final String BLOCKQUOTE_START = "<blockquote>";
private static final String BLOCKQUOTE_END = "</blockquote>";
//https://github.com/k0shk0sh/GitHubSdk/blob/master/library/src/main/java/com/meisolsson/githubsdk/core/HtmlUtils.java
@NonNull public static CharSequence format(final String html) {
if (html == null || html.length() == 0) return "";
StringBuilder formatted = new StringBuilder(html);
strip(formatted, TOGGLE_START, TOGGLE_END);
strip(formatted, SIGNATURE_START, SIGNATURE_END);
replace(formatted, REPLY_START, REPLY_END, BLOCKQUOTE_START, BLOCKQUOTE_END);
strip(formatted, REPLY_START, REPLY_END);
strip(formatted, HIDDEN_REPLY_START, HIDDEN_REPLY_END);
if (replace(formatted, PARAGRAPH_START, BREAK)) replace(formatted, PARAGRAPH_END, BREAK);
formatEmailFragments(formatted);
trim(formatted);
formatted.insert(0, ROOT_START);
formatted.append(ROOT_END);
return formatted;
}
@ -165,65 +152,15 @@ public class HtmlHelper {
return true;
}
private static void replace(final StringBuilder input, final String fromStart, final String fromEnd,
final String toStart, final String toEnd) {
int start = input.indexOf(fromStart);
if (start == -1)
return;
final int fromStartLength = fromStart.length();
final int fromEndLength = fromEnd.length();
final int toStartLength = toStart.length();
while (start != -1) {
input.replace(start, start + fromStartLength, toStart);
int end = input.indexOf(fromEnd, start + toStartLength);
if (end != -1)
input.replace(end, end + fromEndLength, toEnd);
start = input.indexOf(fromStart);
}
}
private static void formatEmailFragments(final StringBuilder input) {
int emailStart = input.indexOf(EMAIL_START);
int breakAdvance = BREAK.length() - 1;
while (emailStart != -1) {
int startLength = EMAIL_START.length();
int emailEnd = input.indexOf(EMAIL_END, emailStart + startLength);
if (emailEnd == -1)
break;
input.delete(emailEnd, emailEnd + EMAIL_END.length());
input.delete(emailStart, emailStart + startLength);
int fullEmail = emailEnd - startLength;
for (int i = emailStart; i < fullEmail; i++)
if (input.charAt(i) == '\n') {
input.deleteCharAt(i);
input.insert(i, BREAK);
i += breakAdvance;
fullEmail += breakAdvance;
}
emailStart = input.indexOf(EMAIL_START, fullEmail);
}
}
private static void trim(final StringBuilder input) {
int length = input.length();
int breakLength = BREAK.length();
while (length > 0) {
if (input.indexOf(BREAK) == 0)
input.delete(0, breakLength);
else if (length >= breakLength
&& input.lastIndexOf(BREAK) == length - breakLength)
input.delete(length - breakLength, length);
else if (Character.isWhitespace(input.charAt(0)))
input.deleteCharAt(0);
else if (Character.isWhitespace(input.charAt(length - 1)))
input.deleteCharAt(length - 1);
else
break;
if (input.indexOf(BREAK) == 0) input.delete(0, breakLength);
else if (length >= breakLength && input.lastIndexOf(BREAK) == length - breakLength) input.delete(length - breakLength, length);
else if (Character.isWhitespace(input.charAt(0))) input.deleteCharAt(0);
else if (Character.isWhitespace(input.charAt(length - 1))) input.deleteCharAt(length - 1);
else break;
length = input.length();
}
}

View File

@ -66,11 +66,7 @@ public class IssuePullsTimelineAdapter extends BaseRecyclerAdapter<TimelineModel
@Override protected void onBindView(BaseViewHolder holder, int position) {
TimelineModel model = getItem(position);
if (model.getType() == TimelineModel.HEADER) {
if (model.getIssue() != null) {
((IssueDetailsViewHolder) holder).bind(model);
} else if (model.getPullRequest() != null) {
((IssueDetailsViewHolder) holder).bind(model);
}
((IssueDetailsViewHolder) holder).bind(model);
} else if (model.getType() == TimelineModel.EVENT) {
((IssueTimelineViewHolder) holder).bind(model);
} else if (model.getType() == TimelineModel.COMMENT) {

View File

@ -13,6 +13,7 @@ import com.fastaccess.data.dao.ReactionsModel;
import com.fastaccess.data.dao.TimelineModel;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.PullRequest;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.helper.ParseDateFormat;
@ -26,6 +27,8 @@ import com.fastaccess.ui.widgets.SpannableBuilder;
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
import java.util.Date;
import butterknife.BindView;
/**
@ -159,30 +162,34 @@ public class IssueDetailsViewHolder extends BaseViewHolder<TimelineModel> {
}
private void bind(@NonNull Issue issueModel) {
avatar.setUrl(issueModel.getUser().getAvatarUrl(), issueModel.getUser().getLogin());
name.setText(issueModel.getUser().getLogin());
date.setText(ParseDateFormat.getTimeAgo(issueModel.getCreatedAt()));
if (!InputHelper.isEmpty(issueModel.getBodyHtml())) {
HtmlHelper.htmlIntoTextView(comment, issueModel.getBodyHtml());
} else {
comment.setText(R.string.no_description_provided);
}
if (issueModel.getReactions() != null) {
appendEmojies(issueModel.getReactions());
}
setup(issueModel.getUser(), issueModel.getBodyHtml(), issueModel.getReactions());
setupDate(issueModel.getCreatedAt(), issueModel.getUpdatedAt());
}
private void bind(@NonNull PullRequest pullRequest) {
avatar.setUrl(pullRequest.getUser().getAvatarUrl(), pullRequest.getUser().getLogin());
name.setText(pullRequest.getUser().getLogin());
date.setText(ParseDateFormat.getTimeAgo(pullRequest.getCreatedAt()));
if (!InputHelper.isEmpty(pullRequest.getBodyHtml())) {
HtmlHelper.htmlIntoTextView(comment, pullRequest.getBodyHtml());
setup(pullRequest.getUser(), pullRequest.getBodyHtml(), pullRequest.getReactions());
setupDate(pullRequest.getCreatedAt(), pullRequest.getUpdatedAt());
}
private void setup(User user, String description, ReactionsModel reactionsModel) {
avatar.setUrl(user.getAvatarUrl(), user.getLogin(), user.isOrganizationType());
name.setText(user.getLogin());
if (reactionsModel != null) {
appendEmojies(reactionsModel);
}
if (!InputHelper.isEmpty(description)) {
HtmlHelper.htmlIntoTextView(comment, description);
} else {
comment.setText(R.string.no_description_provided);
}
if (pullRequest.getReactions() != null) {
appendEmojies(pullRequest.getReactions());
}
private void setupDate(@NonNull Date createdDate, @NonNull Date updated) {
if (createdDate.before(updated)) {
date.setText(String.format("%s %s", ParseDateFormat.getTimeAgo(updated),
date.getResources().getString(R.string.edited)));
} else {
date.setText(ParseDateFormat.getTimeAgo(createdDate));
}
}

View File

@ -18,6 +18,7 @@ import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListView;
import com.evernote.android.state.State;
import com.fastaccess.BuildConfig;
import com.fastaccess.R;
import com.fastaccess.data.dao.EditReviewCommentModel;
@ -46,7 +47,6 @@ import butterknife.OnClick;
import butterknife.OnItemClick;
import butterknife.OnTextChanged;
import es.dmoral.toasty.Toasty;
import com.evernote.android.state.State;
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
import static android.view.View.GONE;
@ -70,16 +70,15 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
@BindView(R.id.sentVia) CheckBox sentVia;
@BindView(R.id.list_divider) View listDivider;
@BindView(R.id.parentView) View parentView;
@State @BundleConstant.ExtraTYpe String extraType;
@BindView(R.id.autocomplete) ListView mention;
@State @BundleConstant.ExtraTYpe String extraType;
@State String itemId;
@State String login;
@State int issueNumber;
@State long commentId = 0;
@State String sha;
@State EditReviewCommentModel reviewComment;
@BindView(R.id.autocomplete)
ListView mention;
@Override protected int layout() {
return R.layout.editor_layout;
@ -239,36 +238,6 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
editText.requestFocus();
}
private void onCreate() {
Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
Bundle bundle = intent.getExtras();
//noinspection WrongConstant
extraType = bundle.getString(BundleConstant.EXTRA_TYPE);
reviewComment = bundle.getParcelable(BundleConstant.REVIEW_EXTRA);
itemId = bundle.getString(BundleConstant.ID);
login = bundle.getString(BundleConstant.EXTRA_TWO);
if (extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.EDIT_COMMIT_COMMENT_EXTRA) ||
extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.NEW_COMMIT_COMMENT_EXTRA)) {
sha = bundle.getString(BundleConstant.EXTRA_THREE);
} else {
issueNumber = bundle.getInt(BundleConstant.EXTRA_THREE);
}
commentId = bundle.getLong(BundleConstant.EXTRA_FOUR);
String textToUpdate = bundle.getString(BundleConstant.EXTRA);
if (!InputHelper.isEmpty(textToUpdate)) {
editText.setText(String.format("%s ", textToUpdate));
editText.setSelection(InputHelper.toString(editText).length());
}
if (bundle.getString("message", "").isEmpty())
replyQuote.setVisibility(GONE);
else {
MarkDownProvider.setMdText(quote, bundle.getString("message", ""));
}
participants = bundle.getStringArrayList("participants");
}
}
@Override public void onSendResultAndFinish(@NonNull Comment commentModel, boolean isNew) {
hideProgress();
Intent intent = new Intent();
@ -307,7 +276,7 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
if (item.getItemId() == R.id.submit) {
if (PrefGetter.isSentViaEnabled()) {
String temp = savedText.toString();
if (!temp.contains(sentFromFastHub) && !InputHelper.isEmpty(savedText)) {
if (!temp.contains(sentFromFastHub)) {
savedText = savedText + sentFromFastHub;
}
}
@ -361,6 +330,36 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
}
}
private void onCreate() {
Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
Bundle bundle = intent.getExtras();
//noinspection WrongConstant
extraType = bundle.getString(BundleConstant.EXTRA_TYPE);
reviewComment = bundle.getParcelable(BundleConstant.REVIEW_EXTRA);
itemId = bundle.getString(BundleConstant.ID);
login = bundle.getString(BundleConstant.EXTRA_TWO);
if (extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.EDIT_COMMIT_COMMENT_EXTRA) ||
extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.NEW_COMMIT_COMMENT_EXTRA)) {
sha = bundle.getString(BundleConstant.EXTRA_THREE);
} else {
issueNumber = bundle.getInt(BundleConstant.EXTRA_THREE);
}
commentId = bundle.getLong(BundleConstant.EXTRA_FOUR);
String textToUpdate = bundle.getString(BundleConstant.EXTRA);
if (!InputHelper.isEmpty(textToUpdate)) {
editText.setText(String.format("%s ", textToUpdate));
editText.setSelection(InputHelper.toString(editText).length());
}
if (bundle.getString("message", "").isEmpty())
replyQuote.setVisibility(GONE);
else {
MarkDownProvider.setMdText(quote, bundle.getString("message", ""));
}
participants = bundle.getStringArrayList("participants");
}
}
private void updateMentionList(@NonNull String mentioning) {
if (participants != null) {
ArrayList<String> mentions = new ArrayList<>();

View File

@ -20,6 +20,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.LicenseModel;
import com.fastaccess.data.dao.NameParser;
@ -58,7 +59,6 @@ import butterknife.BindView;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import butterknife.OnLongClick;
import com.evernote.android.state.State;
import it.sephiroth.android.library.bottomnavigation.BottomNavigation;
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
@ -313,7 +313,7 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
}
@Override public void onFinishActivity() {
// finish();
//do nothing here, github might return 404 if even the repo don't have anything but issues.
}
@Override public void onInitRepo() {

View File

@ -32,6 +32,7 @@ import com.fastaccess.ui.modules.repos.RepoPagerActivity;
import com.fastaccess.ui.modules.repos.code.commit.details.comments.CommitCommentsFragments;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.SpannableBuilder;
import com.fastaccess.ui.widgets.ViewPagerView;
import com.fastaccess.ui.widgets.dialog.MessageDialogView;
@ -162,7 +163,9 @@ public class CommitPagerActivity extends BaseActivity<CommitPagerMvp.View, Commi
HtmlHelper.htmlIntoTextView(title, commit.getGitCommit().getMessage());
detailsIcon.setVisibility(View.VISIBLE);
size.setVisibility(View.GONE);
date.setText(ParseDateFormat.getTimeAgo(dateValue));
date.setText(SpannableBuilder.builder().append(ParseDateFormat.getTimeAgo(dateValue))
.append(" ")
.bold(getPresenter().repoId));
avatarLayout.setUrl(avatar, login);
addition.setText(String.valueOf(commit.getStats() != null ? commit.getStats().getAdditions() : 0));
deletion.setText(String.valueOf(commit.getStats() != null ? commit.getStats().getDeletions() : 0));

View File

@ -11,6 +11,7 @@ import android.support.v4.app.Fragment;
import android.view.MotionEvent;
import android.view.View;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.PullRequest;
@ -27,7 +28,6 @@ import com.fastaccess.ui.widgets.FontTextView;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.OnTouch;
import com.evernote.android.state.State;
/**
* Created by Kosh on 19 Feb 2017, 12:33 PM
@ -127,7 +127,7 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
@Override public void onSetCode(@NonNull CharSequence charSequence) {
this.savedText = charSequence;
MarkDownProvider.setMdText(description, InputHelper.toString(charSequence));
MarkDownProvider.setMdText(description, InputHelper.toString(savedText));
}
@Override public void onTitleError(boolean isEmptyTitle) {

View File

@ -12,6 +12,7 @@ import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.PullRequest;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.provider.rest.RestProvider;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
@ -26,6 +27,7 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
if (intent != null && intent.getExtras() != null) {
CharSequence charSequence = intent.getExtras().getCharSequence(BundleConstant.EXTRA);
if (!InputHelper.isEmpty(charSequence)) {
Logger.e(charSequence);
sendToView(view -> view.onSetCode(charSequence));
}
}
@ -61,6 +63,7 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
makeRestCall(RestProvider.getIssueService().editIssue(login, repo, number, requestModel),
issueModel -> {
if (issueModel != null) {
Logger.e(issueModel.getBodyHtml());
sendToView(view -> view.onSuccessSubmission(issueModel));
} else {
sendToView(view -> view.showMessage(R.string.error, R.string.error_creating_issue));

View File

@ -13,6 +13,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.FragmentPagerAdapterModel;
import com.fastaccess.data.dao.LabelModel;
@ -47,7 +48,6 @@ import java.util.List;
import butterknife.BindView;
import butterknife.OnClick;
import com.evernote.android.state.State;
/**
* Created by Kosh on 10 Dec 2016, 9:23 AM
@ -126,7 +126,7 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
if (savedInstanceState == null) {
getPresenter().onActivityCreated(getIntent());
} else {
if (getPresenter().getIssue() != null) onSetupIssue();
if (getPresenter().getIssue() != null) onSetupIssue(false);
}
startGist.setVisibility(View.GONE);
forkGist.setVisibility(View.GONE);
@ -222,59 +222,44 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
labels.setVisible(isCollaborator || isRepoOwner);
assignees.setVisible(isCollaborator || isRepoOwner);
edit.setVisible(isCollaborator || isRepoOwner || isOwner);
menu.findItem(R.id.closeIssue).setVisible(isOwner || isCollaborator);
menu.findItem(R.id.lockIssue).setVisible(isOwner || isCollaborator);
menu.findItem(R.id.labels).setVisible(getPresenter().isRepoOwner() || isCollaborator);
if (isOwner || isCollaborator) {
if (getPresenter().getIssue() == null) return super.onPrepareOptionsMenu(menu);
lockIssue.setVisible(isOwner || isCollaborator);
labels.setVisible(getPresenter().isRepoOwner() || isCollaborator);
closeIssue.setVisible(isOwner || isCollaborator);
if (getPresenter().getIssue() != null) {
closeIssue.setTitle(getPresenter().getIssue().getState() == IssueState.closed ? getString(R.string.re_open) : getString(R.string.close));
lockIssue.setTitle(isLocked ? getString(R.string.unlock_issue) : getString(R.string.lock_issue));
}
return super.onPrepareOptionsMenu(menu);
}
@Override public void onSetupIssue() {
@Override public void onSetupIssue(boolean isUpdate) {
hideProgress();
if (getPresenter().getIssue() == null) {
return;
}
onUpdateMenu();
Issue issueModel = getPresenter().getIssue();
invalidateOptionsMenu();
setTitle(String.format("#%s", issueModel.getNumber()));
User userModel = issueModel.getUser();
title.setText(issueModel.getTitle());
detailsIcon.setVisibility(InputHelper.isEmpty(issueModel.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
if (userModel != null) {
size.setVisibility(View.GONE);
String username;
CharSequence parsedDate;
if (issueModel.getState() == IssueState.closed) {
username = issueModel.getClosedBy() != null ? issueModel.getClosedBy().getLogin() : "N/A";
parsedDate = issueModel.getClosedAt() != null ? ParseDateFormat.getTimeAgo(issueModel.getClosedAt()) : "N/A";
} else {
parsedDate = ParseDateFormat.getTimeAgo(issueModel.getCreatedAt());
username = issueModel.getUser() != null ? issueModel.getUser().getLogin() : "N/A";
}
date.setText(SpannableBuilder.builder()
.append(ContextCompat.getDrawable(this,
issueModel.getState() == IssueState.open ? R.drawable.ic_issue_opened_small : R.drawable.ic_issue_closed_small))
.append(" ")
.append(getString(issueModel.getState().getStatus()))
.append(" ").append(getString(R.string.by)).append(" ").append(username).append(" ")
.append(parsedDate).append("\n").append(issueModel.getRepoId()));
avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
}
if (pager.getAdapter() == null) {
pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForIssues(this, issueModel)));
if (!getPresenter().isLocked() || getPresenter().isOwner()) {
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override public void onPageSelected(int position) {
super.onPageSelected(position);
hideShowFab();
}
});
updateViews(issueModel);
if (isUpdate) {
IssueTimelineFragment issueDetailsView = (IssueTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
if (issueDetailsView != null && getPresenter().getIssue() != null) {
issueDetailsView.onUpdateHeader();
}
} else {
onUpdateTimeline();
if (pager.getAdapter() == null) {
pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForIssues(this)));
} else {
onUpdateTimeline();
}
}
if (!getPresenter().isLocked() || getPresenter().isOwner()) {
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override public void onPageSelected(int position) {
super.onPageSelected(position);
hideShowFab();
}
});
}
hideShowFab();
}
@ -309,15 +294,15 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
}
@Override public void onUpdateTimeline() {
showMessage(R.string.success, R.string.labels_added_successfully);
if (pager == null || pager.getAdapter() == null) return;
IssueTimelineFragment issueDetailsView = (IssueTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
if (issueDetailsView != null && getPresenter().getIssue() != null) {
issueDetailsView.onRefresh(getPresenter().getIssue());
issueDetailsView.onRefresh();
}
}
@Override public void onUpdateMenu() {
supportInvalidateOptionsMenu();
invalidateOptionsMenu();
}
@Override public void onMileStoneSelected(@NonNull MilestoneModel milestoneModel) {
@ -329,6 +314,10 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
finish();
}
@Nullable @Override public Issue getData() {
return getPresenter().getIssue();
}
@Override public void onMessageDialogActionClicked(boolean isOk, @Nullable Bundle bundle) {
super.onMessageDialogActionClicked(isOk, bundle);
if (isOk) {
@ -370,4 +359,30 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
}
fab.show();
}
private void updateViews(@NonNull Issue issueModel) {
User userModel = issueModel.getUser();
title.setText(issueModel.getTitle());
detailsIcon.setVisibility(InputHelper.isEmpty(issueModel.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
if (userModel != null) {
size.setVisibility(View.GONE);
String username;
CharSequence parsedDate;
if (issueModel.getState() == IssueState.closed) {
username = issueModel.getClosedBy() != null ? issueModel.getClosedBy().getLogin() : "N/A";
parsedDate = issueModel.getClosedAt() != null ? ParseDateFormat.getTimeAgo(issueModel.getClosedAt()) : "N/A";
} else {
parsedDate = ParseDateFormat.getTimeAgo(issueModel.getCreatedAt());
username = issueModel.getUser() != null ? issueModel.getUser().getLogin() : "N/A";
}
date.setText(SpannableBuilder.builder()
.append(ContextCompat.getDrawable(this,
issueModel.getState() == IssueState.open ? R.drawable.ic_issue_opened_small : R.drawable.ic_issue_closed_small))
.append(" ")
.append(getString(issueModel.getState().getStatus()))
.append(" ").append(getString(R.string.by)).append(" ").append(username).append(" ")
.append(parsedDate).append(" ").bold(issueModel.getRepoId()));
avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
}
}
}

View File

@ -23,8 +23,8 @@ import java.util.List;
public interface IssuePagerMvp {
interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener,
AssigneesMvp.SelectedAssigneesListener {
void onSetupIssue();
AssigneesMvp.SelectedAssigneesListener, IssuePrCallback<Issue> {
void onSetupIssue(boolean isUpdate);
void showSuccessIssueActionMsg(boolean isClose);
@ -39,6 +39,7 @@ public interface IssuePagerMvp {
void onMileStoneSelected(@NonNull MilestoneModel milestoneModel);
void onFinishActivity();
}
interface Presenter extends BaseMvp.FAPresenter {
@ -82,4 +83,8 @@ public interface IssuePagerMvp {
void onSubscribeOrMute(boolean mute);
}
interface IssuePrCallback<T> {
@Nullable T getData();
}
}

View File

@ -70,31 +70,14 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
showToRepoBtn = intent.getExtras().getBoolean(BundleConstant.EXTRA_THREE);
if (issueModel != null) {
issueNumber = issueModel.getNumber();
sendToView(IssuePagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
return;
} else if (issueNumber > 0 && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
getIssueFromApi();
return;
}
}
sendToView(IssuePagerMvp.View::onSetupIssue);
}
private void getIssueFromApi() {
Observable<Issue> observable = RestProvider.getIssueService().getIssue(login, repoId, issueNumber)
.flatMap(issue -> RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
(issue, booleanResponse) -> {
isCollaborator = booleanResponse.code() == 204;
return issue;
});
makeRestCall(observable, this::setupIssue);
}
private void setupIssue(Issue issue) {
issueModel = issue;
issueModel.setRepoId(repoId);
issueModel.setLogin(login);
sendToView(IssuePagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
}
@Override public void onWorkOffline(long issueNumber, @NonNull String repoId, @NonNull String login) {
@ -103,7 +86,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
.subscribe(issueModel1 -> {
if (issueModel1 != null) {
issueModel = issueModel1;
sendToView(IssuePagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
}
}));
} else {
@ -163,7 +146,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
issue.setRepoId(issueModel.getRepoId());
issue.setLogin(issueModel.getLogin());
issueModel = issue;
sendToView(IssuePagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(true));
}
})
.subscribe(issue -> {/**/},
@ -184,7 +167,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
int code = booleanResponse.code();
if (code == 204) {
issueModel.setLocked(!isLocked());
sendToView(IssuePagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(true));
}
sendToView(IssuePagerMvp.View::hideProgress);
});
@ -217,7 +200,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
issueModel.setLogin(login);
issueModel.setRepoId(repoId);
manageObservable(issue.save(issueModel).toObservable());
sendToView(IssuePagerMvp.View::onUpdateTimeline);
sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
});
}
@ -227,7 +210,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
Stream.of(labels).filter(value -> value != null && value.getName() != null)
.map(LabelModel::getName).collect(Collectors.toList())),
labelModels -> {
sendToView(IssuePagerMvp.View::onUpdateTimeline);
sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
LabelListModel listModel = new LabelListModel();
listModel.addAll(labels);
issueModel.setLabels(listModel);
@ -249,7 +232,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
assignee.addAll(users);
issueModel.setAssignees(assignee);
manageObservable(issueModel.save(issueModel).toObservable());
sendToView(IssuePagerMvp.View::onUpdateTimeline);
sendToView(view -> updateTimeline(view, R.string.assignee_added));
}
);
}
@ -267,7 +250,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
this.issueModel.setLogin(login);
this.issueModel.setRepoId(repoId);
manageObservable(issueModel.save(issueModel).toObservable());
sendToView(IssuePagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(true));
}
@Override public void onSubscribeOrMute(boolean mute) {
@ -288,4 +271,25 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
}
});
}
private void getIssueFromApi() {
makeRestCall(RxHelper.getObserver(Observable.zip(RestProvider.getIssueService().getIssue(login, repoId, issueNumber),
RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
(issue, booleanResponse) -> {
isCollaborator = booleanResponse.code() == 204;
return issue;
})), this::setupIssue);
}
private void setupIssue(Issue issue) {
issueModel = issue;
issueModel.setRepoId(repoId);
issueModel.setLogin(login);
sendToView(view -> view.onSetupIssue(false));
}
private void updateTimeline(IssuePagerMvp.View view, int assignee_added) {
view.showMessage(R.string.success, assignee_added);
view.onUpdateTimeline();
}
}

View File

@ -1,6 +1,7 @@
package com.fastaccess.ui.modules.repos.issues.issue.details.timeline;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -8,6 +9,7 @@ import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.view.View;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.TimelineModel;
import com.fastaccess.data.dao.model.Comment;
@ -24,6 +26,7 @@ import com.fastaccess.ui.adapter.IssuePullsTimelineAdapter;
import com.fastaccess.ui.adapter.viewholder.TimelineCommentsViewHolder;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.editor.EditorActivity;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
import com.fastaccess.ui.modules.repos.reactions.ReactionsDialogFragment;
import com.fastaccess.ui.widgets.AppbarRefreshLayout;
import com.fastaccess.ui.widgets.StateLayout;
@ -36,7 +39,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import butterknife.BindView;
import com.evernote.android.state.State;
/**
* Created by Kosh on 31 Mar 2017, 7:35 PM
@ -50,16 +52,32 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
@BindView(R.id.stateLayout) StateLayout stateLayout;
@State HashMap<Long, Boolean> toggleMap = new LinkedHashMap<>();
private IssuePullsTimelineAdapter adapter;
private OnLoadMore onLoadMore;
private OnLoadMore<Issue> onLoadMore;
private IssuePagerMvp.IssuePrCallback<Issue> issueCallback;
public static IssueTimelineFragment newInstance(@NonNull Issue issueModel) {
IssueTimelineFragment view = new IssueTimelineFragment();
view.setArguments(Bundler.start().put(BundleConstant.ITEM, issueModel).end());//TODO fix this
return view;
@NonNull public static IssueTimelineFragment newInstance() {
return new IssueTimelineFragment();
}
@SuppressWarnings("unchecked") @Override public void onAttach(Context context) {
super.onAttach(context);
if (getParentFragment() instanceof IssuePagerMvp.IssuePrCallback) {
issueCallback = (IssuePagerMvp.IssuePrCallback) getParentFragment();
} else if (context instanceof IssuePagerMvp.IssuePrCallback) {
issueCallback = (IssuePagerMvp.IssuePrCallback) context;
} else {
throw new IllegalArgumentException(String.format("%s or parent fragment must implement IssuePagerMvp.IssuePrCallback", context.getClass()
.getSimpleName()));
}
}
@Override public void onDetach() {
issueCallback = null;
super.onDetach();
}
@Override public void onRefresh() {
getPresenter().onCallApi(1, null);
getPresenter().onCallApi(1, getIssue());
}
@Override public void onNotifyAdapter(@Nullable List<TimelineModel> items, int page) {
@ -69,17 +87,16 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
return;
}
if (page == 1) {
items.add(0, TimelineModel.constructHeader(getPresenter().getIssue()));
adapter.insertItems(items);
} else {
adapter.addItems(items);
adapter.subList(1, adapter.getItemCount());
}
adapter.addItems(items);
}
@SuppressWarnings("unchecked") @NonNull @Override public OnLoadMore getLoadMore() {
@NonNull @Override public OnLoadMore<Issue> getLoadMore() {
if (onLoadMore == null) {
onLoadMore = new OnLoadMore(getPresenter());
onLoadMore = new OnLoadMore<>(getPresenter());
}
onLoadMore.setParameter(getIssue());
return onLoadMore;
}
@ -88,12 +105,15 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
}
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (getIssue() == null) {
throw new NullPointerException("Issue went missing!!!");
}
adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this);
recycler.setVerticalScrollBarEnabled(false);
stateLayout.setEmptyText(R.string.no_events);
recycler.setEmptyView(stateLayout, refresh);
refresh.setOnRefreshListener(this);
stateLayout.setOnReloadListener(this);
adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this);
adapter.setListener(getPresenter());
recycler.setAdapter(adapter);
fastScroller.setVisibility(View.VISIBLE);
@ -102,8 +122,9 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
recycler.addOnScrollListener(getLoadMore());
if (savedInstanceState == null) {
getPresenter().onFragmentCreated(getArguments());
} else if (getPresenter().getEvents().size() == 1 && !getPresenter().isApiCalled()) {
onSetHeader(TimelineModel.constructHeader(getIssue()));
onRefresh();
} else if (getPresenter().getEvents().isEmpty() || getPresenter().getEvents().size() == 1) {
onRefresh();
}
}
@ -135,12 +156,13 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
}
@Override public void onEditComment(@NonNull Comment item) {
if (getIssue() == null) return;
Intent intent = new Intent(getContext(), EditorActivity.class);
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getIssue().getRepoId())
.put(BundleConstant.EXTRA_TWO, getIssue().getLogin())
.put(BundleConstant.EXTRA_THREE, getIssue().getNumber())
.put(BundleConstant.EXTRA_FOUR, item.getId())
.put(BundleConstant.EXTRA, item.getBody())
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.EDIT_ISSUE_COMMENT_EXTRA)
@ -169,12 +191,13 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
}
@Override public void onTagUser(@Nullable User user) {
if (getIssue() == null) return;
Intent intent = new Intent(getContext(), EditorActivity.class);
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getIssue().getRepoId())
.put(BundleConstant.EXTRA_TWO, getIssue().getLogin())
.put(BundleConstant.EXTRA_THREE, getIssue().getNumber())
.put(BundleConstant.EXTRA, user != null ? "@" + user.getLogin() : "")
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
.putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
@ -184,12 +207,13 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
}
@Override public void onReply(User user, String message) {
if (getIssue() == null) return;
Intent intent = new Intent(getContext(), EditorActivity.class);
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getIssue().getRepoId())
.put(BundleConstant.EXTRA_TWO, getIssue().getLogin())
.put(BundleConstant.EXTRA_THREE, getIssue().getNumber())
.put(BundleConstant.EXTRA, "@" + user.getLogin())
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
.putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
@ -206,14 +230,22 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
}
@Override public void onSetHeader(@NonNull TimelineModel timelineModel) {
if (adapter != null && adapter.isEmpty()) {
adapter.addItem(timelineModel, 0);
if (adapter != null) {
if (adapter.isEmpty()) {
adapter.addItem(timelineModel, 0);
} else {
adapter.swapItem(timelineModel, 0);
}
}
}
@Override public void onRefresh(@NonNull Issue issue) {
getPresenter().onUpdateIssue(issue);
onRefresh();
@Nullable @Override public Issue getIssue() {
return issueCallback.getData();
}
@Override public void onUpdateHeader() {
if (getIssue() == null) return;
onSetHeader(TimelineModel.constructHeader(getIssue()));
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {

View File

@ -32,7 +32,7 @@ public interface IssueTimelineMvp {
void onNotifyAdapter(@Nullable List<TimelineModel> items, int page);
@NonNull OnLoadMore getLoadMore();
@NonNull OnLoadMore<Issue> getLoadMore();
void onEditComment(@NonNull Comment item);
@ -50,32 +50,24 @@ public interface IssueTimelineMvp {
void onSetHeader(@NonNull TimelineModel timelineModel);
void onRefresh(@NonNull Issue issue);
@Nullable Issue getIssue();
void onUpdateHeader();
}
interface Presenter extends BaseMvp.FAPresenter, BaseViewHolder.OnItemClickListener<TimelineModel>,
BaseMvp.PaginationListener {
BaseMvp.PaginationListener<Issue> {
boolean isPreviouslyReacted(long commentId, int vId);
@NonNull ArrayList<TimelineModel> getEvents();
void onFragmentCreated(@Nullable Bundle bundle);
void onWorkOffline();
void onHandleDeletion(@Nullable Bundle bundle);
@Nullable String repoId();
@Nullable String login();
int number();
void onHandleReaction(@IdRes int viewId, long id, @ReactionsProvider.ReactionType int reactionType);
boolean isCallingApi(long id, int vId);
void onUpdateIssue(@NonNull Issue issue);
}
}

View File

@ -37,7 +37,6 @@ import lombok.Getter;
*/
@Getter public class IssueTimelinePresenter extends BasePresenter<IssueTimelineMvp.View> implements IssueTimelineMvp.Presenter {
@com.evernote.android.state.State Issue issue;
private ArrayList<TimelineModel> timeline = new ArrayList<>();
private ReactionsProvider reactionsProvider;
private int page;
@ -51,12 +50,13 @@ import lombok.Getter;
@Override public void onItemClick(int position, View v, TimelineModel item) {
if (getView() != null) {
if (item.getType() == TimelineModel.COMMENT) {
if (getHeader() == null) return;
if (getView().getIssue() == null) return;
Issue issue = getView().getIssue();
if (v.getId() == R.id.commentMenu) {
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
popupMenu.inflate(R.menu.comments_menu);
String username = Login.getUser().getLogin();
boolean isOwner = CommentsHelper.isOwner(username, getHeader().getLogin(), item.getComment().getUser().getLogin());
boolean isOwner = CommentsHelper.isOwner(username, issue.getLogin(), item.getComment().getUser().getLogin());
popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
popupMenu.setOnMenuItemClickListener(item1 -> {
@ -113,8 +113,10 @@ import lombok.Getter;
@Override public void onItemLongClick(int position, View v, TimelineModel item) {
if (getView() == null) return;
if (item.getType() == TimelineModel.COMMENT || item.getType() == TimelineModel.HEADER) {
String login = login();
String repoId = repoId();
if (getView().getIssue() == null) return;
Issue issue = getView().getIssue();
String login = issue.getLogin();
String repoId = issue.getRepoId();
if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
ReactionTypes type = ReactionTypes.get(v.getId());
if (type != null) {
@ -136,23 +138,6 @@ import lombok.Getter;
return timeline;
}
@Override protected void onCreate() {
super.onCreate();
if (issue != null && timeline.isEmpty()) {
sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(issue)));
onCallApi(1, null);
}
}
@Override public void onFragmentCreated(@Nullable Bundle bundle) {
if (bundle == null) throw new NullPointerException("Bundle is null?");
issue = bundle.getParcelable(BundleConstant.ITEM);
if (timeline.isEmpty() && issue != null) {
sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(issue)));
onCallApi(1, null);
}
}
@Override public void onWorkOffline() {
//TODO
}
@ -161,7 +146,9 @@ import lombok.Getter;
if (bundle != null) {
long commId = bundle.getLong(BundleConstant.EXTRA, 0);
if (commId != 0) {
makeRestCall(RestProvider.getIssueService().deleteIssueComment(login(), repoId(), commId),
if (getView() == null || getView().getIssue() == null) return;
Issue issue = getView().getIssue();
makeRestCall(RestProvider.getIssueService().deleteIssueComment(issue.getLogin(), issue.getRepoId(), commId),
booleanResponse -> sendToView(view -> {
if (booleanResponse.code() == 204) {
Comment comment = new Comment();
@ -175,25 +162,11 @@ import lombok.Getter;
}
}
@Nullable @Override public String repoId() {
return getHeader() != null ? getHeader().getRepoId() : null;
}
@Nullable @Override public String login() {
return getHeader() != null ? getHeader().getLogin() : null;
}
@Override public int number() {
return getHeader() != null ? getHeader().getNumber() : -1;
}
@Nullable private Issue getHeader() {
return issue;
}
@Override public void onHandleReaction(int viewId, long id, @ReactionsProvider.ReactionType int reactionType) {
String login = login();
String repoId = repoId();
if (getView() == null || getView().getIssue() == null) return;
Issue issue = getView().getIssue();
String login = issue.getLogin();
String repoId = issue.getRepoId();
Observable observable = getReactionsProvider().onHandleReaction(viewId, id, login, repoId, reactionType);
if (observable != null) manageObservable(observable);
}
@ -202,10 +175,6 @@ import lombok.Getter;
return getReactionsProvider().isCallingApi(id, vId);
}
@Override public void onUpdateIssue(@NonNull Issue issue) {
this.issue = issue;
}
@NonNull private ReactionsProvider getReactionsProvider() {
if (reactionsProvider == null) {
reactionsProvider = new ReactionsProvider();
@ -229,8 +198,8 @@ import lombok.Getter;
this.previousTotal = previousTotal;
}
@Override public void onCallApi(int page, @Nullable Object parameter) {
if (getHeader() == null) {
@Override public void onCallApi(int page, @Nullable Issue parameter) {
if (parameter == null) {
sendToView(BaseMvp.FAView::hideProgress);
return;
}
@ -243,19 +212,19 @@ import lombok.Getter;
return;
}
setCurrentPage(page);
String login = getHeader().getLogin();
String repoID = getHeader().getRepoId();
int number = getHeader().getNumber();
String login = parameter.getLogin();
String repoId = parameter.getRepoId();
int number = parameter.getNumber();
Observable<List<TimelineModel>> observable;
if (page > 1) {
observable = RestProvider.getIssueService().getIssueComments(login, repoID, number, page)
observable = RestProvider.getIssueService().getIssueComments(login, repoId, number, page)
.map(comments -> {
lastPage = comments != null ? comments.getLast() : 0;
return TimelineModel.construct(comments != null ? comments.getItems() : null);
});
} else {
observable = Observable.zip(RestProvider.getIssueService().getTimeline(login, repoID, number),
RestProvider.getIssueService().getIssueComments(login, repoID, number, page),
observable = Observable.zip(RestProvider.getIssueService().getTimeline(login, repoId, number),
RestProvider.getIssueService().getIssueComments(login, repoId, number, page),
(issueEventPageable, commentPageable) -> {
lastPage = commentPageable != null ? commentPageable.getLast() : 0;
return TimelineModel.construct(commentPageable != null ? commentPageable.getItems() : null,

View File

@ -13,6 +13,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.FragmentPagerAdapterModel;
import com.fastaccess.data.dao.LabelModel;
@ -49,7 +50,6 @@ import java.util.List;
import butterknife.BindView;
import butterknife.OnClick;
import com.evernote.android.state.State;
/**
* Created by Kosh on 10 Dec 2016, 9:23 AM
@ -127,7 +127,7 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
if (savedInstanceState == null) {
getPresenter().onActivityCreated(getIntent());
} else {
if (getPresenter().getPullRequest() != null) onSetupIssue();
if (getPresenter().getPullRequest() != null) onSetupIssue(false);
}
startGist.setVisibility(View.GONE);
forkGist.setVisibility(View.GONE);
@ -140,7 +140,11 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
if (requestCode == BundleConstant.REQUEST_CODE) {
Bundle bundle = data.getExtras();
PullRequest pullRequest = bundle.getParcelable(BundleConstant.ITEM);
if (pullRequest != null) getPresenter().onUpdatePullRequest(pullRequest);
if (pullRequest != null) {
getPresenter().onUpdatePullRequest(pullRequest);
} else {
getPresenter().onRefresh();
}
}
}
}
@ -241,72 +245,44 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
return super.onPrepareOptionsMenu(menu);
}
@Override public void onSetupIssue() {
@Override public void onSetupIssue(boolean update) {
hideProgress();
if (getPresenter().getPullRequest() == null) {
return;
}
supportInvalidateOptionsMenu();
invalidateOptionsMenu();
PullRequest pullRequest = getPresenter().getPullRequest();
setTitle(String.format("#%s", pullRequest.getNumber()));
date.setText(String.format("%s\n%s", getPresenter().getMergeBy(pullRequest, getApplicationContext()), pullRequest.getRepoId()));
size.setVisibility(View.GONE);
User userModel = pullRequest.getUser();
if (userModel != null) {
title.setText(SpannableBuilder.builder().append(userModel.getLogin()).append("/").append(pullRequest.getTitle()));
avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
updateViews(pullRequest);
Logger.e(pullRequest.getBodyHtml());
if (update) {
PullRequestTimelineFragment issueDetailsView = (PullRequestTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
if (issueDetailsView != null && getPresenter().getPullRequest() != null) {
issueDetailsView.onUpdateHeader();
}
} else {
title.setText(SpannableBuilder.builder().append(pullRequest.getTitle()));
}
detailsIcon.setVisibility(InputHelper.isEmpty(pullRequest.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
if (pager.getAdapter() == null) {
pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForPullRequest(this,
pullRequest)));
tabs.setupWithViewPager(pager);
if (!getPresenter().isLocked() || getPresenter().isOwner()) {
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override public void onPageSelected(int position) {
super.onPageSelected(position);
if (pager.getAdapter() == null) {
pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForPullRequest(this,
pullRequest)));
tabs.setupWithViewPager(pager);
tabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager) {
@Override public void onTabReselected(TabLayout.Tab tab) {
super.onTabReselected(tab);
onScrollTop(tab.getPosition());
}
});
} else {
onUpdateTimeline();
}
tabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager) {
@Override public void onTabReselected(TabLayout.Tab tab) {
super.onTabReselected(tab);
onScrollTop(tab.getPosition());
}
if (!getPresenter().isLocked() || getPresenter().isOwner()) {
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override public void onPageSelected(int position) {
super.onPageSelected(position);
}
});
if (tabs.getTabAt(2) != null) {
tabs.getTabAt(2)
.setText(SpannableBuilder.builder()
.append(getString(R.string.files))
.append(" ")
.append("(")
.append(String.valueOf(pullRequest.getChangedFiles()))
.append(")"));
}
if (tabs.getTabAt(1) != null) {
tabs.getTabAt(1)
.setText(SpannableBuilder.builder()
.append(getString(R.string.commits))
.append(" ")
.append("(")
.append(String.valueOf(pullRequest.getCommits()))
.append(")"));
}
if (tabs.getTabAt(0) != null) {
tabs.getTabAt(0)
.setText(SpannableBuilder.builder()
.append(getString(R.string.details))
.append(" ")
.append("(")
.append(String.valueOf(pullRequest.getComments()))
.append(")"));
}
} else {
onUpdateTimeline();
}
initTabs(pullRequest);
hideShowFab();
}
@ -332,10 +308,6 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
.show(getSupportFragmentManager(), "LabelsDialogFragment");
}
@Override public void onUpdateMenu() {
supportInvalidateOptionsMenu();
}
@Override public void onSelectedLabels(@NonNull ArrayList<LabelModel> labels) {
Logger.e(labels, labels.size());
getPresenter().onPutLabels(labels);
@ -364,10 +336,9 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
}
@Override public void onUpdateTimeline() {
showMessage(R.string.success, R.string.labels_added_successfully);
PullRequestTimelineFragment pullRequestDetailsView = (PullRequestTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
if (pullRequestDetailsView != null && getPresenter().getPullRequest() != null) {
pullRequestDetailsView.onRefresh(getPresenter().getPullRequest());
pullRequestDetailsView.onRefresh();
}
}
@ -404,6 +375,56 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
getPresenter().onPutAssignees(users, isAssignees);
}
@Nullable @Override public PullRequest getData() {
return getPresenter().getPullRequest();
}
private void initTabs(@NonNull PullRequest pullRequest) {
TabLayout.Tab tab1 = tabs.getTabAt(0);
TabLayout.Tab tab2 = tabs.getTabAt(1);
TabLayout.Tab tab3 = tabs.getTabAt(2);
if (tab3 != null) {
tab3.setText(SpannableBuilder.builder()
.append(getString(R.string.files))
.append(" ")
.append("(")
.append(String.valueOf(pullRequest.getChangedFiles()))
.append(")"));
}
if (tab2 != null) {
tab2.setText(SpannableBuilder.builder()
.append(getString(R.string.commits))
.append(" ")
.append("(")
.append(String.valueOf(pullRequest.getCommits()))
.append(")"));
}
if (tab1 != null) {
tab1.setText(SpannableBuilder.builder()
.append(getString(R.string.details))
.append(" ")
.append("(")
.append(String.valueOf(pullRequest.getComments()))
.append(")"));
}
}
private void updateViews(@NonNull PullRequest pullRequest) {
setTitle(String.format("#%s", pullRequest.getNumber()));
date.setText(SpannableBuilder.builder().append(getPresenter().getMergeBy(pullRequest, getApplicationContext()))
.append(" ")
.bold(pullRequest.getRepoId()));
size.setVisibility(View.GONE);
User userModel = pullRequest.getUser();
if (userModel != null) {
title.setText(SpannableBuilder.builder().append(userModel.getLogin()).append("/").append(pullRequest.getTitle()));
avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
} else {
title.setText(SpannableBuilder.builder().append(pullRequest.getTitle()));
}
detailsIcon.setVisibility(InputHelper.isEmpty(pullRequest.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
}
private void hideShowFab() {
if (getPresenter().isLocked() && !getPresenter().isOwner()) {
fab.hide();

View File

@ -13,6 +13,7 @@ import com.fastaccess.data.dao.model.User;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesMvp;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsMvp;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.merge.MergePullReqeustMvp;
import com.fastaccess.ui.widgets.SpannableBuilder;
@ -26,14 +27,13 @@ import java.util.List;
public interface PullRequestPagerMvp {
interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener,
AssigneesMvp.SelectedAssigneesListener, MergePullReqeustMvp.MergeCallback {
AssigneesMvp.SelectedAssigneesListener, MergePullReqeustMvp.MergeCallback,
IssuePagerMvp.IssuePrCallback<PullRequest> {
void onSetupIssue();
void onSetupIssue(boolean update);
void onLabelsRetrieved(@NonNull List<LabelModel> items);
void onUpdateMenu();
void showSuccessIssueActionMsg(boolean isClose);
void showErrorIssueActionMsg(boolean isClose);
@ -88,6 +88,8 @@ public interface PullRequestPagerMvp {
boolean isCollaborator();
void onUpdatePullRequest(@NonNull PullRequest pullRequestModel);
void onRefresh();
}
}

View File

@ -67,33 +67,14 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
repoId = intent.getExtras().getString(BundleConstant.EXTRA_TWO);
showToRepoBtn = intent.getExtras().getBoolean(BundleConstant.EXTRA_THREE);
if (pullRequest != null) {
sendToView(PullRequestPagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
return;
} else if (issueNumber > 0 && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
makeRestCall(RestProvider.getPullRequestService()
.getPullRequest(login, repoId, issueNumber)
.flatMap(pullRequest1 -> RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
(pullRequest1, booleanResponse) -> {
isCollaborator = booleanResponse.code() == 204;
return pullRequest1;
})
.flatMap(pullRequest1 -> RestProvider.getIssueService().getIssue(login, repoId, issueNumber),
(pullRequest1, issue) -> {//hack to get reactions from issue api
if (issue != null) {
pullRequest1.setReactions(issue.getReactions());
}
return pullRequest1;
}), pullRequestModelResponse -> {
pullRequest = pullRequestModelResponse;
pullRequest.setRepoId(repoId);
pullRequest.setLogin(login);
sendToView(PullRequestPagerMvp.View::onSetupIssue);
manageObservable(pullRequest.save(pullRequest).toObservable());
});
callApi();
return;
}
}
sendToView(PullRequestPagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
}
@Override public void onWorkOffline() {
@ -102,7 +83,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
.subscribe(pullRequestModel -> {
if (pullRequestModel != null) {
pullRequest = pullRequestModel;
sendToView(PullRequestPagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
}
}));
}
@ -158,7 +139,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
int code = booleanResponse.code();
if (code == 204) {
pullRequest.setLocked(!isLocked());
sendToView(PullRequestPagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
}
});
}
@ -175,7 +156,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
issue.setRepoId(getPullRequest().getRepoId());
issue.setLogin(getPullRequest().getLogin());
pullRequest = issue;
sendToView(PullRequestPagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(false));
}
}, throwable -> sendToView(view -> view.showErrorIssueActionMsg(getPullRequest().getState() == IssueState.open))));
}
@ -195,9 +176,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
} else {
sendToView(view -> view.showMessage(R.string.error, R.string.no_labels));
}
}, throwable -> {
sendToView(view -> view.showMessage(R.string.error, R.string.no_labels));
})
}, throwable -> sendToView(view -> view.showMessage(R.string.error, R.string.no_labels)))
);
}
@ -206,7 +185,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
Stream.of(labels).filter(value -> value != null && value.getName() != null)
.map(LabelModel::getName).collect(Collectors.toList())),
labelModels -> {
sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
LabelListModel listModel = new LabelListModel();
listModel.addAll(labels);
pullRequest.setLabels(listModel);
@ -223,7 +202,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
pullRequest.setLogin(login);
pullRequest.setRepoId(repoId);
manageObservable(pr.save(pullRequest).toObservable());
sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
});
}
@ -244,13 +223,13 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
assignee.addAll(users);
pullRequest.setAssignees(assignee);
manageObservable(pullRequest.save(pullRequest).toObservable());
sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
sendToView(view -> updateTimeline(view, R.string.assignee_added));
}
);
} else {
assigneesRequestModel.setReviewers(assignees);
makeRestCall(RestProvider.getPullRequestService().putReviewers(login, repoId, issueNumber, assigneesRequestModel),
pullRequestResponse -> sendToView(PullRequestPagerMvp.View::onUpdateTimeline)
pullRequestResponse -> sendToView(view -> updateTimeline(view, R.string.reviewer_added))
);
}
}
@ -266,10 +245,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
.doOnSubscribe(disposable -> sendToView(view -> view.showProgress(0)))
.subscribe(mergeResponseModel -> {
if (mergeResponseModel.isMerged()) {
sendToView(view -> {
view.showMessage(R.string.success, R.string.success_merge);
view.onUpdateTimeline();
});
sendToView(view -> updateTimeline(view, R.string.success_merge));
} else {
sendToView(view -> view.showErrorMessage(mergeResponseModel.getMessage()));
}
@ -291,10 +267,44 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
}
@Override public void onUpdatePullRequest(@NonNull PullRequest pullRequestModel) {
this.pullRequest = pullRequestModel;
this.pullRequest.setTitle(pullRequestModel.getTitle());
this.pullRequest.setBody(pullRequestModel.getBody());
this.pullRequest.setBodyHtml(pullRequestModel.getBodyHtml());
this.pullRequest.setLogin(login);
this.pullRequest.setRepoId(repoId);
manageObservable(pullRequest.save(pullRequest).toObservable());
sendToView(PullRequestPagerMvp.View::onSetupIssue);
sendToView(view -> view.onSetupIssue(true));
}
@Override public void onRefresh() {
callApi();
}
private void callApi() {
makeRestCall(RxHelper.getObserver(Observable.zip(RestProvider.getPullRequestService()
.getPullRequest(login, repoId, issueNumber),
RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
RestProvider.getIssueService().getIssue(login, repoId, issueNumber),
(pullRequestModel, booleanResponse, issue) -> {
this.pullRequest = pullRequestModel;
if (issue != null) {
this.pullRequest.setReactions(issue.getReactions());
this.pullRequest.setTitle(issue.getTitle());
this.pullRequest.setBody(issue.getBody());
this.pullRequest.setBodyHtml(issue.getBodyHtml());
}
this.pullRequest.setLogin(login);
this.pullRequest.setRepoId(repoId);
isCollaborator = booleanResponse.code() == 204;
return pullRequest;
})), pullRequest -> {
sendToView(view -> view.onSetupIssue(false));
manageObservable(pullRequest.save(pullRequest).toObservable());
});
}
private void updateTimeline(PullRequestPagerMvp.View view, int assignee_added) {
view.showMessage(R.string.success, assignee_added);
view.onUpdateTimeline();
}
}

View File

@ -1,6 +1,7 @@
package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.timeline.timeline;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -8,6 +9,7 @@ import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.view.View;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.EditReviewCommentModel;
import com.fastaccess.data.dao.ReviewCommentModel;
@ -25,6 +27,7 @@ import com.fastaccess.ui.adapter.IssuePullsTimelineAdapter;
import com.fastaccess.ui.adapter.viewholder.TimelineCommentsViewHolder;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.editor.EditorActivity;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
import com.fastaccess.ui.modules.repos.reactions.ReactionsDialogFragment;
import com.fastaccess.ui.widgets.AppbarRefreshLayout;
import com.fastaccess.ui.widgets.StateLayout;
@ -37,7 +40,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import butterknife.BindView;
import com.evernote.android.state.State;
/**
* Created by Kosh on 31 Mar 2017, 7:35 PM
@ -52,16 +54,33 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
@BindView(R.id.stateLayout) StateLayout stateLayout;
@State HashMap<Long, Boolean> toggleMap = new LinkedHashMap<>();
private IssuePullsTimelineAdapter adapter;
private OnLoadMore onLoadMore;
private OnLoadMore<PullRequest> onLoadMore;
public static PullRequestTimelineFragment newInstance(@NonNull PullRequest pullRequest) {
PullRequestTimelineFragment view = new PullRequestTimelineFragment();
view.setArguments(Bundler.start().put(BundleConstant.ITEM, pullRequest).end());//TODO fix this
return view;
private IssuePagerMvp.IssuePrCallback<PullRequest> issueCallback;
@NonNull public static PullRequestTimelineFragment newInstance() {
return new PullRequestTimelineFragment();
}
@SuppressWarnings("unchecked") @Override public void onAttach(Context context) {
super.onAttach(context);
if (getParentFragment() instanceof IssuePagerMvp.IssuePrCallback) {
issueCallback = (IssuePagerMvp.IssuePrCallback) getParentFragment();
} else if (context instanceof IssuePagerMvp.IssuePrCallback) {
issueCallback = (IssuePagerMvp.IssuePrCallback) context;
} else {
throw new IllegalArgumentException(String.format("%s or parent fragment must implement IssuePagerMvp.IssuePrCallback", context.getClass()
.getSimpleName()));
}
}
@Override public void onDetach() {
issueCallback = null;
super.onDetach();
}
@Override public void onRefresh() {
getPresenter().onCallApi(1, null);
getPresenter().onCallApi(1, getPullRequest());
}
@Override protected int fragmentLayout() {
@ -69,24 +88,27 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
}
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (getPullRequest() == null) {
throw new NullPointerException("PullRequest went missing!!!");
}
boolean isMerged = getPresenter().isMerged(getPullRequest());
adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this, isMerged, getPresenter());
recycler.setVerticalScrollBarEnabled(false);
getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
recycler.addOnScrollListener(getLoadMore());
stateLayout.setEmptyText(R.string.no_events);
recycler.setEmptyView(stateLayout, refresh);
refresh.setOnRefreshListener(this);
stateLayout.setOnReloadListener(this);
boolean isMerged = getPresenter().isMerged();
adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this,
isMerged, getPresenter());
adapter.setListener(getPresenter());
recycler.setAdapter(adapter);
fastScroller.setVisibility(View.VISIBLE);
fastScroller.attachRecyclerView(recycler);
recycler.setAdapter(adapter);
recycler.addDivider(TimelineCommentsViewHolder.class);
getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
recycler.addOnScrollListener(getLoadMore());
if (savedInstanceState == null) {
getPresenter().onFragmentCreated(getArguments());
} else if (getPresenter().getEvents().size() == 1 && !getPresenter().isApiCalled()) {
onSetHeader(TimelineModel.constructHeader(getPullRequest()));
onRefresh();
} else if (getPresenter().getEvents().isEmpty() || getPresenter().getEvents().size() == 1) {
onRefresh();
}
}
@ -134,27 +156,27 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
return;
}
if (page == 1) {
items.add(0, TimelineModel.constructHeader(getPresenter().pullRequest));
adapter.insertItems(items);
} else {
adapter.addItems(items);
adapter.subList(1, adapter.getItemCount());
}
adapter.addItems(items);
}
@SuppressWarnings("unchecked") @NonNull @Override public OnLoadMore getLoadMore() {
@NonNull @Override public OnLoadMore<PullRequest> getLoadMore() {
if (onLoadMore == null) {
onLoadMore = new OnLoadMore(getPresenter());
onLoadMore = new OnLoadMore<>(getPresenter());
}
onLoadMore.setParameter(getPullRequest());
return onLoadMore;
}
@Override public void onEditComment(@NonNull Comment item) {
Intent intent = new Intent(getContext(), EditorActivity.class);
if (getPullRequest() == null) return;
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getPullRequest().getRepoId())
.put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
.put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
.put(BundleConstant.EXTRA_FOUR, item.getId())
.put(BundleConstant.EXTRA, item.getBody())
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.EDIT_ISSUE_COMMENT_EXTRA)
@ -170,11 +192,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
model.setGroupPosition(groupPosition);
model.setInReplyTo(item.getId());
Intent intent = new Intent(getContext(), EditorActivity.class);
if (getPullRequest() == null) return;
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getPullRequest().getRepoId())
.put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
.put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
.put(BundleConstant.EXTRA_FOUR, item.getId())
.put(BundleConstant.EXTRA, item.getBody())
.put(BundleConstant.REVIEW_EXTRA, model)
@ -192,11 +215,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
@Override public void onStartNewComment() {
Intent intent = new Intent(getContext(), EditorActivity.class);
if (getPullRequest() == null) return;
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getPullRequest().getRepoId())
.put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
.put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
.putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
.end());
@ -215,11 +239,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
@Override public void onReply(User user, String message) {
Intent intent = new Intent(getContext(), EditorActivity.class);
if (getPullRequest() == null) return;
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getPullRequest().getRepoId())
.put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
.put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
.put(BundleConstant.EXTRA, "@" + user.getLogin())
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
.putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
@ -232,11 +257,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
@Override public void onReplyOrCreateReview(@Nullable User user, String message, int groupPosition, int childPosition,
@NonNull EditReviewCommentModel model) {
Intent intent = new Intent(getContext(), EditorActivity.class);
if (getPullRequest() == null) return;
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().number())
.put(BundleConstant.ID, getPullRequest().getRepoId())
.put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
.put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
.put(BundleConstant.EXTRA, user != null ? "@" + user.getLogin() : "")
.put(BundleConstant.REVIEW_EXTRA, model)
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_REVIEW_COMMENT_EXTRA)
@ -279,14 +305,22 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
}
@Override public void onSetHeader(@NonNull TimelineModel timelineModel) {
if (adapter != null && adapter.isEmpty()) {
adapter.addItem(timelineModel, 0);
if (adapter != null) {
if (adapter.isEmpty()) {
adapter.addItem(timelineModel, 0);
} else {
adapter.swapItem(timelineModel, 0);
}
}
}
@Override public void onRefresh(@NonNull PullRequest pullRequest) {
getPresenter().onUpdatePullRequest(pullRequest);
onRefresh();
@Nullable @Override public PullRequest getPullRequest() {
return issueCallback.getData();
}
@Override public void onUpdateHeader() {
if (getPullRequest() == null) return;
onSetHeader(TimelineModel.constructHeader(getPullRequest()));
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {

View File

@ -40,7 +40,7 @@ public interface PullRequestTimelineMvp {
void onNotifyAdapter(@Nullable List<TimelineModel> items, int page);
@NonNull OnLoadMore getLoadMore();
@NonNull OnLoadMore<PullRequest> getLoadMore();
void onEditComment(@NonNull Comment item);
@ -66,34 +66,26 @@ public interface PullRequestTimelineMvp {
void onSetHeader(@NonNull TimelineModel timelineModel);
void onRefresh(@NonNull PullRequest pullRequest);
@Nullable PullRequest getPullRequest();
void onUpdateHeader();
}
interface Presenter extends BaseMvp.FAPresenter, BaseViewHolder.OnItemClickListener<TimelineModel>,
ReviewCommentCallback, BaseMvp.PaginationListener {
ReviewCommentCallback, BaseMvp.PaginationListener<PullRequest> {
@NonNull ArrayList<TimelineModel> getEvents();
void onFragmentCreated(@Nullable Bundle bundle);
void onWorkOffline();
void onHandleDeletion(@Nullable Bundle bundle);
@Nullable String repoId();
@Nullable String login();
int number();
boolean isPreviouslyReacted(long commentId, int vId);
void onHandleReaction(@IdRes int vId, long idOrNumber, @ReactionsProvider.ReactionType int reactionType);
boolean isMerged();
boolean isMerged(PullRequest pullRequest);
boolean isCallingApi(long id, int vId);
void onUpdatePullRequest(@NonNull PullRequest pullRequest);
}
}

View File

@ -41,20 +41,19 @@ import io.reactivex.Observable;
public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimelineMvp.View> implements PullRequestTimelineMvp.Presenter {
private ArrayList<TimelineModel> timeline = new ArrayList<>();
private ReactionsProvider reactionsProvider;
@com.evernote.android.state.State PullRequest pullRequest;
private int page;
private int previousTotal;
private int lastPage = Integer.MAX_VALUE;
@Override public void onItemClick(int position, View v, TimelineModel item) {
if (getView() != null) {
if (getView() != null && getView().getPullRequest() != null) {
if (item.getType() == TimelineModel.COMMENT) {
if (getHeader() == null) return;
PullRequest pullRequest = getView().getPullRequest();
if (v.getId() == R.id.commentMenu) {
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
popupMenu.inflate(R.menu.comments_menu);
String username = Login.getUser().getLogin();
boolean isOwner = CommentsHelper.isOwner(username, getHeader().getLogin(), item.getComment().getUser().getLogin());
boolean isOwner = CommentsHelper.isOwner(username, pullRequest.getLogin(), item.getComment().getUser().getLogin());
popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
popupMenu.setOnMenuItemClickListener(item1 -> {
@ -119,10 +118,11 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
}
@Override public void onItemLongClick(int position, View v, TimelineModel item) {
if (getView() == null) return;
if (getView() == null || getView().getPullRequest() == null) return;
if (item.getType() == TimelineModel.COMMENT || item.getType() == TimelineModel.HEADER) {
String login = login();
String repoId = repoId();
PullRequest pullRequest = getView().getPullRequest();
String login = pullRequest.getLogin();
String repoId = pullRequest.getRepoId();
if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
ReactionTypes type = ReactionTypes.get(v.getId());
if (type != null) {
@ -144,37 +144,20 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
return timeline;
}
@Override protected void onCreate() {
super.onCreate();
if (pullRequest != null && timeline.isEmpty()) {
sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(pullRequest)));
onCallApi(1, null);
}
}
@Override public void onFragmentCreated(@Nullable Bundle bundle) {
if (bundle == null) throw new NullPointerException("Bundle is null?");
pullRequest = bundle.getParcelable(BundleConstant.ITEM);
if (timeline.isEmpty() && pullRequest != null) {
sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(pullRequest)));
onCallApi(1, null);
}
}
@Override public void onWorkOffline() {
//TODO
}
@Nullable private PullRequest getHeader() {
return pullRequest;
}
@Override public void onHandleDeletion(@Nullable Bundle bundle) {
if (getView() == null || getView().getPullRequest() == null) return;
if (bundle != null) {
PullRequest pullRequest = getView().getPullRequest();
String login = pullRequest.getLogin();
String repoId = pullRequest.getRepoId();
long commId = bundle.getLong(BundleConstant.EXTRA, 0);
boolean isReviewComment = bundle.getBoolean(BundleConstant.YES_NO_EXTRA);
if (commId != 0 && !isReviewComment) {
makeRestCall(RestProvider.getIssueService().deleteIssueComment(login(), repoId(), commId),
makeRestCall(RestProvider.getIssueService().deleteIssueComment(login, repoId, commId),
booleanResponse -> sendToView(view -> {
if (booleanResponse.code() == 204) {
Comment comment = new Comment();
@ -187,7 +170,7 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
} else {
int groupPosition = bundle.getInt(BundleConstant.EXTRA_TWO);
int commentPosition = bundle.getInt(BundleConstant.EXTRA_THREE);
makeRestCall(RestProvider.getReviewService().deleteComment(login(), repoId(), commId),
makeRestCall(RestProvider.getReviewService().deleteComment(login, repoId, commId),
booleanResponse -> sendToView(view -> {
if (booleanResponse.code() == 204) {
view.onRemoveReviewComment(groupPosition, commentPosition);
@ -199,38 +182,24 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
}
}
@Nullable @Override public String repoId() {
return getHeader() != null ? getHeader().getRepoId() : null;
}
@Nullable @Override public String login() {
return getHeader() != null ? getHeader().getLogin() : null;
}
@Override public int number() {
return getHeader() != null ? getHeader().getNumber() : -1;
}
@Override public void onHandleReaction(int vId, long idOrNumber, @ReactionsProvider.ReactionType int reactionType) {
String login = login();
String repoId = repoId();
if (getView() == null || getView().getPullRequest() == null) return;
PullRequest pullRequest = getView().getPullRequest();
String login = pullRequest.getLogin();
String repoId = pullRequest.getRepoId();
Observable observable = getReactionsProvider().onHandleReaction(vId, idOrNumber, login, repoId, reactionType);
if (observable != null) //noinspection unchecked
manageObservable(observable);
}
@Override public boolean isMerged() {
return getHeader() != null && (getHeader().isMerged() || !InputHelper.isEmpty(getHeader().getMergedAt()));
@Override public boolean isMerged(PullRequest pullRequest) {
return pullRequest != null && (pullRequest.isMerged() || !InputHelper.isEmpty(pullRequest.getMergedAt()));
}
@Override public boolean isCallingApi(long id, int vId) {
return getReactionsProvider().isCallingApi(id, vId);
}
@Override public void onUpdatePullRequest(@NonNull PullRequest pullRequest) {
this.pullRequest = pullRequest;
}
@Override public boolean isPreviouslyReacted(long commentId, int vId) {
return getReactionsProvider().isPreviouslyReacted(commentId, vId);
}
@ -243,12 +212,12 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
}
@Override public void onClick(int groupPosition, int commentPosition, @NonNull View v, @NonNull ReviewCommentModel comment) {
if (getHeader() == null || getView() == null) return;
if (getView() == null || getView().getPullRequest() == null) return;
if (v.getId() == R.id.commentMenu) {
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
popupMenu.inflate(R.menu.comments_menu);
String username = Login.getUser().getLogin();
boolean isOwner = CommentsHelper.isOwner(username, getHeader().getLogin(), comment.getUser().getLogin());
boolean isOwner = CommentsHelper.isOwner(username, getView().getPullRequest().getLogin(), comment.getUser().getLogin());
popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
popupMenu.setOnMenuItemClickListener(item1 -> {
@ -275,9 +244,10 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
}
@Override public void onLongClick(int groupPosition, int commentPosition, @NonNull View v, @NonNull ReviewCommentModel model) {
if (getView() == null) return;
String login = login();
String repoId = repoId();
if (getView() == null || getView().getPullRequest() == null) return;
PullRequest pullRequest = getView().getPullRequest();
String login = pullRequest.getLogin();
String repoId = pullRequest.getRepoId();
if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
ReactionTypes type = ReactionTypes.get(v.getId());
if (type != null) {
@ -304,14 +274,14 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
this.previousTotal = previousTotal;
}
@Override public void onCallApi(int page, @Nullable Object parameter) {
if (getHeader() == null) {
@Override public void onCallApi(int page, @Nullable PullRequest parameter) {
if (parameter == null) {
sendToView(BaseMvp.FAView::hideProgress);
return;
}
String login = getHeader().getLogin();
String repoId = getHeader().getRepoId();
int number = getHeader().getNumber();
String login = parameter.getLogin();
String repoId = parameter.getRepoId();
int number = parameter.getNumber();
if (page <= 1) {
lastPage = Integer.MAX_VALUE;
sendToView(view -> view.getLoadMore().reset());
@ -321,7 +291,7 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
return;
}
setCurrentPage(page);
loadEverything(login, repoId, number, getHeader().getHead().getSha(), getHeader().isMergeable(), page);
loadEverything(login, repoId, number, parameter.getHead().getSha(), parameter.isMergeable(), page);
}
private void loadEverything(String login, String repoId, int number, @NonNull String sha, boolean isMergeable, int page) {

View File

@ -12,7 +12,6 @@ import com.fastaccess.R
import com.fastaccess.helper.Logger
import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.modules.trending.fragment.TrendingFragment
import es.dmoral.toasty.Toasty
/**
@ -31,7 +30,6 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
@State var selectedTitle: String = ""
fun onDailyClicked() {
Toasty.info(applicationContext, "Hello").show()
Logger.e()
daily.isSelected = true
weekly.isSelected = false
@ -40,7 +38,6 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
}
fun onWeeklyClicked() {
Toasty.info(applicationContext, "Hello").show()
weekly.isSelected = true
daily.isSelected = false
monthly.isSelected = false
@ -48,7 +45,6 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
}
fun onMonthlyClicked() {
Toasty.info(applicationContext, "Hello").show()
monthly.isSelected = true
weekly.isSelected = false
daily.isSelected = false
@ -137,4 +133,4 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
else -> return "daily"
}
}
}
}

View File

@ -10,9 +10,7 @@ import io.reactivex.Observable
class TrendingPresenter : BasePresenter<TrendingMvp.View>(), TrendingMvp.Presenter {
override fun onLoadLanguage() {
manageObservable(Observable.create<String> {
ColorsProvider.languages().forEach({ t: String? -> it.onNext(t) })
it.onComplete()
}.doOnNext({ t: String -> sendToView({ it.onAppend(t) }) }))
manageObservable(Observable.fromIterable(ColorsProvider.languages())
.doOnNext({ t: String -> sendToView({ it.onAppend(t) }) }))
}
}

View File

@ -20,7 +20,6 @@ import android.text.style.TypefaceSpan;
import com.fastaccess.App;
import com.fastaccess.R;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundSpan {
private Rect rect = new Rect();
@ -68,8 +67,8 @@ public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundS
String[] split = text.split("\\r?\\n|\\r");
if (split.length > 0) {
int lines = split.length;
int index = -1;
for (int i = 0; i < lines; i++) {
Logger.e(lines, i, lines + i, lines - i);
if (truncate && (lines - i) > 3) continue;
String token = split[i];
if (i < (lines - 1)) {
@ -85,7 +84,7 @@ public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundS
color = patchRefColor;
} else if (firstChar == '\\') {
token = token.replace("\\ No newline at end of file", "");
noNewlineRemoved = true;
index = i;
}
SpannableString spannableDiff = new SpannableString(token);
if (color != Color.TRANSPARENT) {
@ -94,12 +93,12 @@ public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundS
}
builder.append(spannableDiff);
}
if (index != -1) {
builder.insert(index, SpannableBuilder.builder()
.append(ContextCompat.getDrawable(App.getInstance(), R.drawable.ic_newline)));
}
}
}
if (noNewlineRemoved) {
builder.insert(builder.length() - 1, SpannableBuilder.builder()
.append(ContextCompat.getDrawable(App.getInstance(), R.drawable.ic_newline)));
}
builder.setSpan(new TypefaceSpan("monospace"), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return builder;
}

View File

@ -82,10 +82,10 @@
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/avatar_margin"
android:layout_marginTop="@dimen/spacing_normal"
android:layout_marginStart="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_micro"
android:textIsSelectable="true"/>
<com.fastaccess.ui.widgets.FontTextView

View File

@ -84,10 +84,10 @@
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/avatar_margin"
android:layout_marginTop="@dimen/spacing_normal"
android:layout_marginStart="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_micro"
android:textIsSelectable="true"/>
<com.fastaccess.ui.widgets.FontTextView

View File

@ -69,10 +69,10 @@
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/avatar_margin"
android:layout_marginTop="@dimen/spacing_normal"
android:layout_marginStart="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_micro"
android:textIsSelectable="true"/>
</LinearLayout>

View File

@ -80,10 +80,10 @@
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/avatar_margin"
android:layout_marginTop="@dimen/spacing_normal"
android:layout_marginStart="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_micro"
android:textIsSelectable="true"
tools:text="Hello World"/>

View File

@ -475,4 +475,7 @@
<string name="type">Type</string>
<string name="Sort">Sort</string>
<string name="sort_direction">Sort direction</string>
<string name="assignee_added">Assignee added successfully</string>
<string name="reviewer_added">Reviewer added successfully</string>
<string name="milestone_added">Milestone added successfully</string>
</resources>

View File

@ -5,4 +5,5 @@ android_key_alias=ALIAS
github_client_id=GITHUB_CLIENT_ID
github_secret=GITHUB_SECRET
imgur_client_id=imgur_client_id
imgur_secret=imgur_secret
imgur_secret=imgur_secret
redirect_url=fasthub://login