/* * Copyright 2011 Azwan Adli Abdullah * * 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.gh4a.fragment; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.widget.RecyclerView; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import com.gh4a.BaseActivity; import com.gh4a.Gh4Application; import com.gh4a.R; import com.gh4a.activities.CommitActivity; import com.gh4a.activities.CompareActivity; import com.gh4a.activities.GistActivity; import com.gh4a.activities.IssueActivity; import com.gh4a.activities.IssueListActivity; import com.gh4a.activities.PullRequestActivity; import com.gh4a.activities.ReleaseInfoActivity; import com.gh4a.activities.RepositoryActivity; import com.gh4a.activities.UserActivity; import com.gh4a.activities.WikiListActivity; import com.gh4a.adapter.EventAdapter; import com.gh4a.adapter.RootAdapter; import com.gh4a.utils.IntentUtils; import com.gh4a.utils.UiUtils; import com.gh4a.widget.ContextMenuAwareRecyclerView; import org.eclipse.egit.github.core.Commit; import org.eclipse.egit.github.core.CommitComment; import org.eclipse.egit.github.core.Download; import org.eclipse.egit.github.core.GollumPage; import org.eclipse.egit.github.core.Issue; import org.eclipse.egit.github.core.PullRequest; import org.eclipse.egit.github.core.Release; import org.eclipse.egit.github.core.Repository; import org.eclipse.egit.github.core.User; import org.eclipse.egit.github.core.client.PageIterator; import org.eclipse.egit.github.core.event.CommitCommentPayload; import org.eclipse.egit.github.core.event.CreatePayload; import org.eclipse.egit.github.core.event.DownloadPayload; import org.eclipse.egit.github.core.event.Event; import org.eclipse.egit.github.core.event.EventRepository; import org.eclipse.egit.github.core.event.FollowPayload; import org.eclipse.egit.github.core.event.ForkPayload; import org.eclipse.egit.github.core.event.GistPayload; import org.eclipse.egit.github.core.event.GollumPayload; import org.eclipse.egit.github.core.event.IssueCommentPayload; import org.eclipse.egit.github.core.event.IssuesPayload; import org.eclipse.egit.github.core.event.PullRequestPayload; import org.eclipse.egit.github.core.event.PullRequestReviewCommentPayload; import org.eclipse.egit.github.core.event.PushPayload; import org.eclipse.egit.github.core.event.ReleasePayload; import org.eclipse.egit.github.core.service.EventService; import java.util.Arrays; import java.util.List; public abstract class EventListFragment extends PagedDataBaseFragment<Event> { private static final int MENU_DOWNLOAD_START = 100; private static final int MENU_DOWNLOAD_END = 199; protected String mLogin; private EventAdapter mAdapter; private static final String[] REPO_EVENTS = new String[] { Event.TYPE_PUSH, Event.TYPE_ISSUES, Event.TYPE_WATCH, Event.TYPE_CREATE, Event.TYPE_PULL_REQUEST, Event.TYPE_COMMIT_COMMENT, Event.TYPE_DELETE, Event.TYPE_DOWNLOAD, Event.TYPE_FORK_APPLY, Event.TYPE_PUBLIC, Event.TYPE_MEMBER, Event.TYPE_ISSUE_COMMENT }; protected static Bundle makeArguments(String user) { Bundle args = new Bundle(); args.putString("login", user); return args; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLogin = getArguments().getString("login"); } @Override protected void onRecyclerViewInflated(RecyclerView view, LayoutInflater inflater) { super.onRecyclerViewInflated(view, inflater); registerForContextMenu(view); } @Override protected RootAdapter<Event, ? extends RecyclerView.ViewHolder> onCreateAdapter() { mAdapter = new EventAdapter(getActivity()); mAdapter.setContextMenuSupported(true); return mAdapter; } @Override protected int getEmptyTextResId() { return R.string.no_events_found; } @Override protected PageIterator<Event> onCreateIterator() { EventService eventService = (EventService) Gh4Application.get().getService(Gh4Application.EVENT_SERVICE); return eventService.pageUserEvents(mLogin, false); } @Override public void onItemClick(Event event) { if (EventAdapter.hasInvalidPayload(event)) { return; } String eventType = event.getType(); EventRepository eventRepo = event.getRepo(); String repoOwner = ""; String repoName = ""; Intent intent = null; if (eventRepo != null) { String[] repoNamePart = eventRepo.getName().split("/"); if (repoNamePart.length == 2) { repoOwner = repoNamePart[0]; repoName = repoNamePart[1]; } } if (Arrays.binarySearch(REPO_EVENTS, eventType) >= 0 && eventRepo == null) { Toast.makeText(getActivity(), R.string.repo_not_found_toast, Toast.LENGTH_LONG).show(); return; } if (Event.TYPE_COMMIT_COMMENT.equals(eventType)) { CommitCommentPayload payload = (CommitCommentPayload) event.getPayload(); CommitComment comment = payload.getComment(); if (comment != null) { intent = CommitActivity.makeIntent(getActivity(), repoOwner, repoName, comment.getCommitId(), new IntentUtils.InitialCommentMarker(comment.getId())); } } else if (Event.TYPE_CREATE.equals(eventType)) { CreatePayload payload = (CreatePayload) event.getPayload(); String ref = null; if ("branch".equals(payload.getRefType()) || "tag".equals(payload.getRefType())) { ref = payload.getRef(); } intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName, ref); } else if (Event.TYPE_DELETE.equals(eventType)) { intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName); } else if (Event.TYPE_DOWNLOAD.equals(eventType)) { DownloadPayload payload = (DownloadPayload) event.getPayload(); Download download = payload.getDownload(); UiUtils.enqueueDownloadWithPermissionCheck((BaseActivity) getActivity(), download.getHtmlUrl(), download.getContentType(), download.getName(), download.getDescription(), null); } else if (Event.TYPE_FOLLOW.equals(eventType)) { FollowPayload payload = (FollowPayload) event.getPayload(); intent = UserActivity.makeIntent(getActivity(), payload.getTarget()); } else if (Event.TYPE_FORK.equals(eventType)) { ForkPayload payload = (ForkPayload) event.getPayload(); Repository forkee = payload.getForkee(); if (forkee != null) { intent = RepositoryActivity.makeIntent(getActivity(), forkee); } else { Toast.makeText(getActivity(), R.string.repo_not_found_toast, Toast.LENGTH_LONG).show(); } } else if (Event.TYPE_FORK_APPLY.equals(eventType)) { intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName); } else if (Event.TYPE_GIST.equals(eventType)) { GistPayload payload = (GistPayload) event.getPayload(); intent = GistActivity.makeIntent(getActivity(), payload.getGist().getId()); } else if (Event.TYPE_GOLLUM.equals(eventType)) { GollumPayload payload = (GollumPayload) event.getPayload(); intent = WikiListActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getPages().isEmpty() ? null : payload.getPages().get(0)); } else if (Event.TYPE_ISSUE_COMMENT.equals(eventType)) { IssueCommentPayload payload = (IssueCommentPayload) event.getPayload(); Issue issue = payload.getIssue(); PullRequest request = issue != null ? issue.getPullRequest() : null; IntentUtils.InitialCommentMarker initialComment = payload.getComment() != null ? new IntentUtils.InitialCommentMarker(payload.getComment().getId()) : null; if (request != null && request.getHtmlUrl() != null) { intent = PullRequestActivity.makeIntent(getActivity(), repoOwner, repoName, issue.getNumber(), initialComment != null ? PullRequestActivity.PAGE_CONVERSATION : -1, initialComment); } else if (issue != null) { intent = IssueActivity.makeIntent(getActivity(), repoOwner, repoName, issue.getNumber(), initialComment); } } else if (Event.TYPE_ISSUES.equals(eventType)) { IssuesPayload payload = (IssuesPayload) event.getPayload(); startActivity(IssueActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getIssue().getNumber())); } else if (Event.TYPE_MEMBER.equals(eventType)) { intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName); } else if (Event.TYPE_PUBLIC.equals(eventType)) { intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName); } else if (Event.TYPE_PULL_REQUEST.equals(eventType)) { PullRequestPayload payload = (PullRequestPayload) event.getPayload(); intent = PullRequestActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getNumber()); } else if (Event.TYPE_PULL_REQUEST_REVIEW_COMMENT.equals(eventType)) { PullRequestReviewCommentPayload payload = (PullRequestReviewCommentPayload) event.getPayload(); PullRequest pr = payload.getPullRequest(); CommitComment comment = payload.getComment(); IntentUtils.InitialCommentMarker initialComment = comment != null ? new IntentUtils.InitialCommentMarker(comment.getId()) : null; if (pr != null) { intent = PullRequestActivity.makeIntent(getActivity(), repoOwner, repoName, pr.getNumber(), initialComment != null ? PullRequestActivity.PAGE_CONVERSATION : -1, initialComment); } else if (comment != null) { intent = CommitActivity.makeIntent(getActivity(), repoOwner, repoName, comment.getCommitId(), initialComment); } } else if (Event.TYPE_PUSH.equals(eventType)) { PushPayload payload = (PushPayload) event.getPayload(); List<Commit> commits = payload.getCommits(); if (commits != null && !commits.isEmpty()) { if (commits.size() > 1) { // if commit > 1, then show compare activity intent = CompareActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getBefore(), payload.getHead()); } else { // only 1 commit, then show the commit details intent = CommitActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getCommits().get(0).getSha()); } } else { intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName); } } else if (Event.TYPE_RELEASE.equals(eventType)) { ReleasePayload payload = (ReleasePayload) event.getPayload(); Release release = payload.getRelease(); if (release != null) { intent = ReleaseInfoActivity.makeIntent(getActivity(), repoOwner, repoName, release.getId()); } } else if (Event.TYPE_WATCH.equals(eventType)) { intent = RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName); } if (intent != null) { startActivity(intent); } } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); ContextMenuAwareRecyclerView.RecyclerContextMenuInfo info = (ContextMenuAwareRecyclerView.RecyclerContextMenuInfo) menuInfo; Event event = mAdapter.getItemFromAdapterPosition(info.position); if (EventAdapter.hasInvalidPayload(event)) { return; } String eventType = event.getType(); EventRepository eventRepo = event.getRepo(); String[] repoNamePart = eventRepo.getName().split("/"); String repoOwner = repoNamePart.length == 2 ? repoNamePart[0] : null; String repoName = repoNamePart.length == 2 ? repoNamePart[1] : null; menu.setHeaderTitle(R.string.go_to); /** Common menu */ menu.add(getString(R.string.menu_user, event.getActor().getLogin())) .setIntent(UserActivity.makeIntent(getActivity(), event.getActor())); if (repoOwner != null) { menu.add(getString(R.string.menu_repo, eventRepo.getName())) .setIntent(RepositoryActivity.makeIntent(getActivity(), repoOwner, repoName)); } if (Event.TYPE_COMMIT_COMMENT.equals(eventType) && repoOwner != null) { CommitCommentPayload payload = (CommitCommentPayload) event.getPayload(); String sha = payload.getComment().getCommitId(); menu.add(getString(R.string.menu_commit, sha.substring(0, 7))) .setIntent(CommitActivity.makeIntent(getActivity(), repoOwner, repoName, sha)); } else if (Event.TYPE_DOWNLOAD.equals(eventType)) { DownloadPayload payload = (DownloadPayload) event.getPayload(); menu.add(Menu.NONE, MENU_DOWNLOAD_START, Menu.NONE, getString(R.string.menu_file, payload.getDownload().getName())); } else if (Event.TYPE_FOLLOW.equals(eventType)) { FollowPayload payload = (FollowPayload) event.getPayload(); User target = payload.getTarget(); if (target != null) { menu.add(getString(R.string.menu_user, target.getLogin())) .setIntent(UserActivity.makeIntent(getActivity(), target)); } } else if (Event.TYPE_FORK.equals(eventType)) { ForkPayload payload = (ForkPayload) event.getPayload(); Repository forkee = payload.getForkee(); if (forkee != null) { menu.add(getString(R.string.menu_fork, forkee.getOwner().getLogin() + "/" + forkee.getName())) .setIntent(RepositoryActivity.makeIntent(getActivity(), forkee)); } } else if (Event.TYPE_GIST.equals(eventType)) { GistPayload payload = (GistPayload) event.getPayload(); String gistId = payload.getGist().getId(); menu.add(getString(R.string.menu_gist, gistId)) .setIntent(GistActivity.makeIntent(getActivity(), gistId)); } else if (Event.TYPE_GOLLUM.equals(eventType)) { GollumPayload payload = (GollumPayload) event.getPayload(); List<GollumPage> pages = payload.getPages(); if (pages != null && !pages.isEmpty()) { //TODO: now just open the first page menu.add(getString(R.string.menu_wiki)) .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(pages.get(0).getHtmlUrl()))); } } else if (Event.TYPE_ISSUE_COMMENT.equals(eventType)) { menu.add(getString(R.string.menu_issues)) .setIntent(IssueListActivity.makeIntent(getActivity(),repoOwner, repoName)); } else if (Event.TYPE_ISSUES.equals(eventType)) { IssuesPayload payload = (IssuesPayload) event.getPayload(); int issueNumber = payload.getIssue().getNumber(); menu.add(getString(R.string.menu_issue, issueNumber)) .setIntent(IssueActivity.makeIntent(getActivity(), repoOwner, repoName, issueNumber)); } else if (Event.TYPE_PULL_REQUEST.equals(eventType)) { PullRequestPayload payload = (PullRequestPayload) event.getPayload(); menu.add(getString(R.string.menu_pull, payload.getNumber())) .setIntent(PullRequestActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getNumber())); } else if (Event.TYPE_PUSH.equals(eventType) && repoOwner != null) { PushPayload payload = (PushPayload) event.getPayload(); menu.add(getString(R.string.menu_compare, payload.getHead().substring(0, 7))) .setIntent(CompareActivity.makeIntent(getActivity(), repoOwner, repoName, payload.getBefore(), payload.getHead())); List<Commit> commits = payload.getCommits(); for (int i = 0; i < commits.size(); i++) { String sha = commits.get(i).getSha(); menu.add(getString(R.string.menu_commit, sha.substring(0, 7))) .setIntent(CommitActivity.makeIntent(getActivity(), repoOwner, repoName, sha)); } } else if (Event.TYPE_RELEASE.equals(eventType)) { ReleasePayload payload = (ReleasePayload) event.getPayload(); List<Download> downloads = payload.getRelease().getAssets(); int count = downloads != null ? downloads.size() : 0; for (int i = 0; i < count; i++) { menu.add(Menu.NONE, MENU_DOWNLOAD_START + i, Menu.NONE, getString(R.string.menu_file, downloads.get(i).getName())); } } } @Override public boolean onContextItemSelected(MenuItem item) { ContextMenuAwareRecyclerView.RecyclerContextMenuInfo info = (ContextMenuAwareRecyclerView.RecyclerContextMenuInfo) item.getMenuInfo(); if (info.position >= mAdapter.getItemCount()) { return false; } int id = item.getItemId(); Event event = mAdapter.getItemFromAdapterPosition(info.position); if (id >= MENU_DOWNLOAD_START && id <= MENU_DOWNLOAD_END) { final Download download; if (Event.TYPE_RELEASE.equals(event.getType())) { ReleasePayload payload = (ReleasePayload) event.getPayload(); download = payload.getRelease().getAssets().get(id - MENU_DOWNLOAD_START); } else if (Event.TYPE_DOWNLOAD.equals(event.getType())) { DownloadPayload payload = (DownloadPayload) event.getPayload(); download = payload.getDownload(); } else { download = null; } if (download != null) { UiUtils.enqueueDownloadWithPermissionCheck((BaseActivity) getActivity(), download.getHtmlUrl(), download.getContentType(), download.getName(), download.getDescription(), null); } return true; } return false; } }