/* * 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.Context; import android.content.Intent; import android.graphics.Typeface; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.content.Loader; import android.support.v4.os.AsyncTaskCompat; import android.text.SpannableStringBuilder; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import com.gh4a.R; import com.gh4a.activities.CollaboratorListActivity; import com.gh4a.activities.ContributorListActivity; import com.gh4a.activities.DownloadsActivity; import com.gh4a.activities.ForkListActivity; import com.gh4a.activities.IssueListActivity; import com.gh4a.activities.ReleaseListActivity; import com.gh4a.activities.RepositoryActivity; import com.gh4a.activities.UserActivity; import com.gh4a.activities.WatcherListActivity; import com.gh4a.activities.WikiListActivity; import com.gh4a.loader.LoaderCallbacks; import com.gh4a.loader.LoaderResult; import com.gh4a.loader.PullRequestCountLoader; import com.gh4a.loader.ReadmeLoader; import com.gh4a.utils.ApiHelpers; import com.gh4a.utils.HttpImageGetter; import com.gh4a.utils.StringUtils; import com.gh4a.utils.UiUtils; import com.gh4a.widget.IntentSpan; import org.eclipse.egit.github.core.Permissions; import org.eclipse.egit.github.core.Repository; public class RepositoryFragment extends LoadingFragmentBase implements OnClickListener { public static RepositoryFragment newInstance(Repository repository, String ref) { RepositoryFragment f = new RepositoryFragment(); Bundle args = new Bundle(); args.putSerializable("repo", repository); args.putString("ref", ref); f.setArguments(args); return f; } private Repository mRepository; private View mContentView; private String mRef; private HttpImageGetter mImageGetter; private final LoaderCallbacks<String> mReadmeCallback = new LoaderCallbacks<String>(this) { @Override protected Loader<LoaderResult<String>> onCreateLoader() { return new ReadmeLoader(getActivity(), mRepository.getOwner().getLogin(), mRepository.getName(), StringUtils.isBlank(mRef) ? mRepository.getDefaultBranch() : mRef); } @Override protected void onResultReady(String result) { TextView readmeView = (TextView) mContentView.findViewById(R.id.readme); View progress = mContentView.findViewById(R.id.pb_readme); AsyncTaskCompat.executeParallel(new FillReadmeTask( mRepository.getId(), readmeView, progress, mImageGetter), result); } }; private final LoaderCallbacks<Integer> mPullRequestsCallback = new LoaderCallbacks<Integer>(this) { @Override protected Loader<LoaderResult<Integer>> onCreateLoader() { return new PullRequestCountLoader(getActivity(), mRepository, ApiHelpers.IssueState.OPEN); } @Override protected void onResultReady(Integer result) { View v = getView(); v.findViewById(R.id.issues_progress).setVisibility(View.GONE); v.findViewById(R.id.pull_requests_progress).setVisibility(View.GONE); TextView tvIssuesCount = (TextView) mContentView.findViewById(R.id.tv_issues_count); tvIssuesCount.setText(String.valueOf(mRepository.getOpenIssues() - result)); TextView tvPullRequestsCountView = (TextView) v.findViewById(R.id.tv_pull_requests_count); tvPullRequestsCountView.setText(String.valueOf(result)); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRepository = (Repository) getArguments().getSerializable("repo"); mRef = getArguments().getString("ref"); } @Override protected View onCreateContentView(LayoutInflater inflater, ViewGroup parent) { mContentView = inflater.inflate(R.layout.repository, parent, false); return mContentView; } @Override public void onDestroyView() { super.onDestroyView(); mImageGetter.destroy(); mImageGetter = null; } @Override public void onRefresh() { if (mContentView != null) { mContentView.findViewById(R.id.readme).setVisibility(View.GONE); mContentView.findViewById(R.id.pb_readme).setVisibility(View.VISIBLE); mContentView.findViewById(R.id.pull_requests_progress).setVisibility(View.VISIBLE); } if (mImageGetter != null) { mImageGetter.clearHtmlCache(); } hideContentAndRestartLoaders(0, 1); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mImageGetter = new HttpImageGetter(getActivity()); fillData(); setContentShown(true); getLoaderManager().initLoader(0, null, mReadmeCallback); getLoaderManager().initLoader(1, null, mPullRequestsCallback); } @Override public void onResume() { super.onResume(); mImageGetter.resume(); } @Override public void onPause() { super.onPause(); mImageGetter.pause(); } public void setRef(String ref) { mRef = ref; getArguments().putString("ref", ref); // reload readme getLoaderManager().restartLoader(0, null, mReadmeCallback); if (mContentView != null) { mContentView.findViewById(R.id.readme).setVisibility(View.GONE); mContentView.findViewById(R.id.pb_readme).setVisibility(View.VISIBLE); } } private void fillData() { TextView tvRepoName = (TextView) mContentView.findViewById(R.id.tv_repo_name); SpannableStringBuilder repoName = new SpannableStringBuilder(); repoName.append(mRepository.getOwner().getLogin()); repoName.append("/"); repoName.append(mRepository.getName()); repoName.setSpan(new IntentSpan(tvRepoName.getContext()) { @Override protected Intent getIntent() { return UserActivity.makeIntent(getActivity(), mRepository.getOwner()); } }, 0, mRepository.getOwner().getLogin().length(), 0); tvRepoName.setText(repoName); tvRepoName.setMovementMethod(UiUtils.CHECKING_LINK_METHOD); TextView tvParentRepo = (TextView) mContentView.findViewById(R.id.tv_parent); if (mRepository.isFork() && mRepository.getParent() != null) { Repository parent = mRepository.getParent(); tvParentRepo.setVisibility(View.VISIBLE); tvParentRepo.setText(getString(R.string.forked_from, parent.getOwner().getLogin() + "/" + parent.getName())); tvParentRepo.setOnClickListener(this); tvParentRepo.setTag(parent); } else { tvParentRepo.setVisibility(View.GONE); } fillTextView(R.id.tv_desc, 0, mRepository.getDescription()); fillTextView(R.id.tv_language,R.string.repo_language, mRepository.getLanguage()); fillTextView(R.id.tv_url, 0, !StringUtils.isBlank(mRepository.getHomepage()) ? mRepository.getHomepage() : mRepository.getHtmlUrl()); mContentView.findViewById(R.id.cell_stargazers).setOnClickListener(this); mContentView.findViewById(R.id.cell_forks).setOnClickListener(this); mContentView.findViewById(R.id.cell_pull_requests).setOnClickListener(this); mContentView.findViewById(R.id.tv_contributors_label).setOnClickListener(this); mContentView.findViewById(R.id.other_info).setOnClickListener(this); mContentView.findViewById(R.id.tv_releases_label).setOnClickListener(this); Permissions permissions = mRepository.getPermissions(); updateClickableLabel(R.id.tv_collaborators_label, permissions != null && permissions.hasPushAccess()); updateClickableLabel(R.id.tv_downloads_label, mRepository.isHasDownloads()); updateClickableLabel(R.id.tv_wiki_label, mRepository.isHasWiki()); TextView tvStargazersCount = (TextView) mContentView.findViewById(R.id.tv_stargazers_count); tvStargazersCount.setText(String.valueOf(mRepository.getWatchers())); TextView tvForksCount = (TextView) mContentView.findViewById(R.id.tv_forks_count); tvForksCount.setText(String.valueOf(mRepository.getForks())); LinearLayout llIssues = (LinearLayout) mContentView.findViewById(R.id.cell_issues); if (mRepository.isHasIssues()) { llIssues.setVisibility(View.VISIBLE); llIssues.setOnClickListener(this); // value will be filled when PR count arrives } else { llIssues.setVisibility(View.GONE); } mContentView.findViewById(R.id.tv_private).setVisibility( mRepository.isPrivate() ? View.VISIBLE : View.GONE); } private void updateClickableLabel(int id, boolean enable) { View view = mContentView.findViewById(id); if (enable) { view.setOnClickListener(this); view.setVisibility(View.VISIBLE); } else { view.setVisibility(View.GONE); } } private void fillTextView(int id, int stringId, String text) { TextView view = (TextView) mContentView.findViewById(id); if (!StringUtils.isBlank(text)) { view.setText(stringId != 0 ? getString(stringId, text) : text); view.setVisibility(View.VISIBLE); } else { view.setVisibility(View.GONE); } } public void updateStargazerCount(boolean starring) { if (starring) { mRepository.setWatchers(mRepository.getWatchers() + 1); } else { mRepository.setWatchers(mRepository.getWatchers() - 1); } TextView tvStargazersCount = (TextView) mContentView.findViewById(R.id.tv_stargazers_count); tvStargazersCount.setText(String.valueOf(mRepository.getWatchers())); } @Override public void onClick(View view) { int id = view.getId(); String owner = mRepository.getOwner().getLogin(); String name = mRepository.getName(); Intent intent = null; if (id == R.id.cell_pull_requests) { intent = IssueListActivity.makeIntent(getActivity(), owner, name, true); } else if (id == R.id.tv_contributors_label) { intent = ContributorListActivity.makeIntent(getActivity(), owner, name); } else if (id == R.id.tv_collaborators_label) { intent = CollaboratorListActivity.makeIntent(getActivity(), owner, name); } else if (id == R.id.cell_issues) { intent = IssueListActivity.makeIntent(getActivity(), owner, name); } else if (id == R.id.cell_stargazers) { intent = WatcherListActivity.makeIntent(getActivity(), owner, name); } else if (id == R.id.cell_forks) { intent = ForkListActivity.makeIntent(getActivity(), owner, name); } else if (id == R.id.tv_wiki_label) { intent = WikiListActivity.makeIntent(getActivity(), owner, name, null); } else if (id == R.id.tv_downloads_label) { intent = DownloadsActivity.makeIntent(getActivity(), owner, name); } else if (id == R.id.tv_releases_label) { intent = ReleaseListActivity.makeIntent(getActivity(), owner, name); } else if (view.getTag() instanceof Repository) { intent = RepositoryActivity.makeIntent(getActivity(), (Repository) view.getTag()); } if (intent != null) { startActivity(intent); } } private static class FillReadmeTask extends AsyncTask<String, Void, String> { private final Long mId; private final Context mContext; private final TextView mReadmeView; private final View mProgressView; private final HttpImageGetter mImageGetter; public FillReadmeTask(long id, TextView readmeView, View progressView, HttpImageGetter imageGetter) { mId = id; mContext = readmeView.getContext(); mReadmeView = readmeView; mProgressView = progressView; mImageGetter = imageGetter; } @Override protected String doInBackground(String... params) { String readme = params[0]; if (readme != null) { mImageGetter.encode(mContext, mId, readme); } return readme; } @Override protected void onPostExecute(String result) { if (result != null) { mReadmeView.setMovementMethod(UiUtils.CHECKING_LINK_METHOD); mImageGetter.bind(mReadmeView, result, mId); } else { mReadmeView.setText(R.string.repo_no_readme); mReadmeView.setTypeface(Typeface.DEFAULT, Typeface.ITALIC); } mReadmeView.setVisibility(View.VISIBLE); mProgressView.setVisibility(View.GONE); } } }