/* * Copyright 2012 GitHub Inc. * * 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.github.mobile.ui; import static android.content.Intent.ACTION_VIEW; import static android.content.Intent.CATEGORY_BROWSABLE; import static org.eclipse.egit.github.core.event.Event.TYPE_COMMIT_COMMENT; import static org.eclipse.egit.github.core.event.Event.TYPE_DOWNLOAD; import static org.eclipse.egit.github.core.event.Event.TYPE_PUSH; import android.app.AlertDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.ListView; import com.github.kevinsawicki.wishlist.SingleTypeAdapter; import com.github.kevinsawicki.wishlist.ViewFinder; import com.github.mobile.R.id; import com.github.mobile.R.layout; import com.github.mobile.R.string; import com.github.mobile.core.gist.GistEventMatcher; import com.github.mobile.core.issue.IssueEventMatcher; import com.github.mobile.core.repo.RepositoryEventMatcher; import com.github.mobile.core.user.UserEventMatcher; import com.github.mobile.core.user.UserEventMatcher.UserPair; import com.github.mobile.ui.commit.CommitCompareViewActivity; import com.github.mobile.ui.commit.CommitViewActivity; import com.github.mobile.ui.gist.GistsViewActivity; import com.github.mobile.ui.issue.IssuesViewActivity; import com.github.mobile.ui.repo.RepositoryViewActivity; import com.github.mobile.ui.user.NewsListAdapter; import com.github.mobile.util.AvatarLoader; import com.google.inject.Inject; import java.util.List; 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.Gist; import org.eclipse.egit.github.core.Issue; import org.eclipse.egit.github.core.Repository; import org.eclipse.egit.github.core.User; import org.eclipse.egit.github.core.event.CommitCommentPayload; import org.eclipse.egit.github.core.event.DownloadPayload; import org.eclipse.egit.github.core.event.Event; import org.eclipse.egit.github.core.event.PushPayload; import org.eclipse.egit.github.core.service.EventService; /** * Base news fragment class with utilities for subclasses to built on */ public abstract class NewsFragment extends PagedItemFragment<Event> { /** * Matcher for finding an {@link Issue} from an {@link Event} */ protected final IssueEventMatcher issueMatcher = new IssueEventMatcher(); /** * Matcher for finding a {@link Gist} from an {@link Event} */ protected final GistEventMatcher gistMatcher = new GistEventMatcher(); /** * Matcher for finding a {@link Repository} from an {@link Event} */ protected final RepositoryEventMatcher repoMatcher = new RepositoryEventMatcher(); /** * Matcher for finding a {@link User} from an {@link Event} */ protected final UserEventMatcher userMatcher = new UserEventMatcher(); @Inject private AvatarLoader avatars; /** * Event service */ @Inject protected EventService service; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setEmptyText(string.no_news); } @Override public void onListItemClick(ListView l, View v, int position, long id) { Event event = (Event) l.getItemAtPosition(position); if (TYPE_DOWNLOAD.equals(event.getType())) { openDownload(event); return; } if (TYPE_PUSH.equals(event.getType())) { openPush(event); return; } if (TYPE_COMMIT_COMMENT.equals(event.getType())) { openCommitComment(event); return; } Issue issue = issueMatcher.getIssue(event); if (issue != null) { Repository repo = RepositoryEventMatcher.getRepository( event.getRepo(), event.getActor(), event.getOrg()); viewIssue(issue, repo); return; } Gist gist = gistMatcher.getGist(event); if (gist != null) { startActivity(GistsViewActivity.createIntent(gist)); return; } Repository repo = repoMatcher.getRepository(event); if (repo != null) viewRepository(repo); UserPair users = userMatcher.getUsers(event); if (users != null) viewUser(users); } @Override public boolean onListItemLongClick(ListView l, View v, int position, long itemId) { if (!isUsable()) return false; final Event event = (Event) l.getItemAtPosition(position); final Repository repo = RepositoryEventMatcher.getRepository( event.getRepo(), event.getActor(), event.getOrg()); final User user = event.getActor(); if (repo != null && user != null) { final AlertDialog dialog = LightAlertDialog.create(getActivity()); dialog.setTitle(string.navigate_to); dialog.setCanceledOnTouchOutside(true); View view = getActivity().getLayoutInflater().inflate( layout.nav_dialog, null); ViewFinder finder = new ViewFinder(view); avatars.bind(finder.imageView(id.iv_user_avatar), user); avatars.bind(finder.imageView(id.iv_repo_avatar), repo.getOwner()); finder.setText(id.tv_login, user.getLogin()); finder.setText(id.tv_repo_name, repo.generateId()); finder.onClick(id.ll_user_area, new OnClickListener() { public void onClick(View v) { dialog.dismiss(); viewUser(user); } }); finder.onClick(id.ll_repo_area, new OnClickListener() { public void onClick(View v) { dialog.dismiss(); viewRepository(repo); } }); dialog.setView(view); dialog.show(); return true; } return false; } private void openDownload(Event event) { Download download = ((DownloadPayload) event.getPayload()) .getDownload(); if (download == null) return; String url = download.getHtmlUrl(); if (TextUtils.isEmpty(url)) return; Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); intent.addCategory(CATEGORY_BROWSABLE); startActivity(intent); } private void openCommitComment(Event event) { Repository repo = RepositoryEventMatcher.getRepository(event.getRepo(), event.getActor(), event.getOrg()); if (repo == null) return; CommitCommentPayload payload = (CommitCommentPayload) event .getPayload(); CommitComment comment = payload.getComment(); if (comment == null) return; String sha = comment.getCommitId(); if (!TextUtils.isEmpty(sha)) startActivity(CommitViewActivity.createIntent(repo, sha)); } private void openPush(Event event) { Repository repo = RepositoryEventMatcher.getRepository(event.getRepo(), event.getActor(), event.getOrg()); if (repo == null) return; PushPayload payload = (PushPayload) event.getPayload(); List<Commit> commits = payload.getCommits(); if (commits == null || commits.isEmpty()) return; if (commits.size() > 1) { String base = payload.getBefore(); String head = payload.getHead(); if (!TextUtils.isEmpty(base) && !TextUtils.isEmpty(head)) startActivity(CommitCompareViewActivity.createIntent(repo, base, head)); } else { Commit commit = commits.get(0); String sha = commit != null ? commit.getSha() : null; if (!TextUtils.isEmpty(sha)) startActivity(CommitViewActivity.createIntent(repo, sha)); } } /** * Start an activity to view the given repository * * @param repository */ protected void viewRepository(Repository repository) { startActivity(RepositoryViewActivity.createIntent(repository)); } /** * Start an activity to view the given {@link UserPair} * <p> * This method does nothing by default, subclasses should override * * @param users */ protected void viewUser(UserPair users) { } /** * Start an activity to view the given {@link User} * * @param user * @return true if new activity started, false otherwise */ protected boolean viewUser(User user) { return false; } /** * Start an activity to view the given {@link Issue} * * @param issue * @param repository */ protected void viewIssue(Issue issue, Repository repository) { if (repository != null) startActivity(IssuesViewActivity.createIntent(issue, repository)); else startActivity(IssuesViewActivity.createIntent(issue)); } @Override protected SingleTypeAdapter<Event> createAdapter(List<Event> items) { return new NewsListAdapter(getActivity().getLayoutInflater(), items.toArray(new Event[items.size()]), avatars); } @Override protected int getLoadingMessage() { return string.loading_news; } @Override protected int getErrorMessage(Exception exception) { return string.error_news_load; } }