blob: d355ac33a8c2a505b6332194adef62dcbd6ecde3 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.reviewit.widget;
import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.support.annotation.ColorRes;
import android.support.annotation.IdRes;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.reviewit.R;
import com.google.reviewit.app.Change;
import com.google.reviewit.app.Preferences;
import com.google.reviewit.app.ReviewItApp;
import com.google.reviewit.util.FormatUtil;
import com.google.reviewit.util.ObservableAsyncTask;
import com.google.reviewit.util.WidgetUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ChangeBox extends RelativeLayout {
private static final String TAG = ChangeBox.class.getName();
private final WidgetUtil widgetUtil;
public ChangeBox(Context context) {
this(context, null);
}
public ChangeBox(Context context, AttributeSet attrs) {
super(context, attrs);
this.widgetUtil = new WidgetUtil(context);
inflate(context, R.layout.change_box, this);
RelativeLayout.LayoutParams layoutParams =
new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
int activityHorizontalMargin = widgetUtil.getDimension(
R.dimen.activity_horizontal_margin);
int activityVerticalMargin = widgetUtil.getDimension(
R.dimen.activity_vertical_margin);
int reviewitBottomAreaHeight = widgetUtil.getDimension(
R.dimen.reviewit_bottom_area_height);
layoutParams.setMargins(activityHorizontalMargin, activityVerticalMargin,
activityHorizontalMargin, reviewitBottomAreaHeight);
setLayoutParams(layoutParams);
if (getId() < 0) {
setId(R.id.changeBox);
}
GradientDrawable gd = new GradientDrawable();
gd.setColor(widgetUtil.color(R.color.commitMessage));
gd.setCornerRadius(widgetUtil.dpToPx(20));
gd.setStroke(1, widgetUtil.color(R.color.commitMessage4));
WidgetUtil.setBackground(this, gd);
}
public void display(ReviewItApp app, Change change) {
configureInfo(app);
ChangeInfo info = change.info;
((ProjectBranchTopicAgeView)v(R.id.projectBranchTopicAge)).init(change);
((UserView)v(R.id.owner)).init(app, info.owner);
WidgetUtil.setText(v(R.id.subject), info.subject);
WidgetUtil.setText(v(R.id.commitMessage),
FormatUtil.formatMessage(change));
WidgetUtil.setText(v(R.id.patchsets),
FormatUtil.format(change.currentRevision()._number));
setInlineCommentCount(app, change);
Change.Voters codeReviewVoters = change.voters("Code-Review");
WidgetUtil.setText(this, R.id.likes,
FormatUtil.format(codeReviewVoters.likers.size()));
WidgetUtil.setText(this, R.id.dislikes,
FormatUtil.format(codeReviewVoters.dislikers.size()));
Collection<AccountInfo> reviewers = change.reviewers(true);
WidgetUtil.setText(v(R.id.reviewers),
FormatUtil.format(reviewers.size()));
setCommitMessageFont(app);
colorIcons(app, codeReviewVoters, reviewers);
}
private void configureInfo(ReviewItApp app) {
Preferences prefs = app.getPrefs();
WidgetUtil.setVisible(prefs.showPatchSets,
v(R.id.patchsets, R.id.patchSetIcon));
WidgetUtil.setVisible(prefs.showPositiveCodeReviewVotes,
v(R.id.likes, R.id.positiveReviewIcon));
WidgetUtil.setVisible(prefs.showNegativeCodeReviewVotes,
v(R.id.dislikes, R.id.negativeReviewIcon));
WidgetUtil.setVisible(prefs.showComments,
v(R.id.comments, R.id.commentIcon));
WidgetUtil.setVisible(prefs.showReviewers,
v(R.id.reviewers, R.id.reviewerIcon));
}
private void setCommitMessageFont(ReviewItApp app) {
Preferences prefs = app.getPrefs();
if (!prefs.autoFontSizeForCommitMessage()) {
MaxFontSizeTextView commitMessage =
((MaxFontSizeTextView) v(R.id.commitMessage));
commitMessage.setMinTextSize(prefs.commitMessageFontSize);
commitMessage.setMaxTextSize(prefs.commitMessageFontSize);
}
}
/**
* Highlight icons for the current user by a different color.
*/
private void colorIcons(
ReviewItApp app, Change.Voters codeReviewVoters,
Collection<AccountInfo> reviewers) {
colorIcon(R.id.positiveReviewIcon,
containsSelf(app, codeReviewVoters.likers)
? R.color.iconHighlightedGreen
: R.color.icon);
colorIcon(R.id.negativeReviewIcon,
containsSelf(app, codeReviewVoters.dislikers)
? R.color.iconHighlightedRed
: R.color.icon);
colorIcon(R.id.commentIcon, R.color.icon);
colorIcon(R.id.reviewerIcon,
containsSelf(app, reviewers)
? R.color.iconHighlightedGreen
: R.color.icon);
}
private void colorIcon(@IdRes int id, @ColorRes int colorId) {
((ImageView) v(id)).setColorFilter(widgetUtil.color(colorId));
}
private void setInlineCommentCount(final ReviewItApp app, Change change) {
new ObservableAsyncTask<Change, Void, Integer>() {
private TextView comments;
@Override
protected void preExecute() {
super.preExecute();
comments = (TextView) v(R.id.comments);
}
@Override
protected Integer doInBackground(Change... changes) {
Change change = changes[0];
try {
return change.getInlineCommentCount();
} catch (RestApiException e) {
Log.e(TAG, "Failed to count inline comments of change "
+ change.info._number, e);
return null;
}
}
@Override
protected void postExecute(Integer count) {
if (count == null) {
return;
}
comments.setText(FormatUtil.format(count));
if (app.getPrefs().showComments) {
WidgetUtil.setVisible(comments);
}
}
}.executeOnExecutor(app.getExecutor(), change);
}
private boolean containsSelf(
ReviewItApp app, Collection<AccountInfo> accounts) {
AccountInfo self = app.getSelf();
if (self == null) {
return false;
}
for (AccountInfo account : accounts) {
if (self._accountId.equals(account._accountId)) {
return true;
}
}
return false;
}
private View v(@IdRes int id) {
return findViewById(id);
}
private View[] v(@IdRes int id, @IdRes int... moreIds) {
List<View> views = new ArrayList<>(moreIds.length + 1);
views.add(v(id));
for (@IdRes int yaId : moreIds) {
views.add(v(yaId));
}
return views.toArray(new View[views.size()]);
}
}