package com.khmelenko.lab.varis.activity; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import com.khmelenko.lab.varis.R; import com.khmelenko.lab.varis.TravisApp; import com.khmelenko.lab.varis.converter.BuildStateHelper; import com.khmelenko.lab.varis.fragment.JobsFragment; import com.khmelenko.lab.varis.fragment.RawLogFragment; import com.khmelenko.lab.varis.mvp.MvpActivity; import com.khmelenko.lab.varis.network.response.Build; import com.khmelenko.lab.varis.network.response.BuildDetails; import com.khmelenko.lab.varis.network.response.Commit; import com.khmelenko.lab.varis.network.response.Job; import com.khmelenko.lab.varis.presenter.BuildsDetailsPresenter; import com.khmelenko.lab.varis.view.BuildDetailsView; import com.khmelenko.lab.varis.widget.BuildView; import java.util.List; import javax.inject.Inject; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; /** * Build details * * @author Dmytro Khmelenko */ public final class BuildDetailsActivity extends MvpActivity<BuildsDetailsPresenter> implements BuildDetailsView, JobsFragment.JobsListener, RawLogFragment.OnRawLogFragmentListener { public static final String EXTRA_REPO_SLUG = "RepoSlug"; public static final String EXTRA_BUILD_ID = "BuildId"; public static final String BUILD_STATE_CHANGED = "BuildsStateChanged"; private static final String RAW_LOG_FRAGMENT_TAG = "RawLogFragment"; private static final String JOBS_FRAGMENT_TAG = "JobsFragment"; @Bind(R.id.progressbarview) View mProgressBar; @Bind(R.id.build_details_build_data) View mBuildDetailsData; @Bind(R.id.build_details_layout) ScrollView mBuildDetailsLayout; @Bind(R.id.build_details_scroll_btn) FloatingActionButton mScrollBtn; @Bind(R.id.build_details_scroll_up_btn) FloatingActionButton mScrollUpBtn; @Inject BuildsDetailsPresenter mPresenter; private JobsFragment mJobsFragment; private RawLogFragment mRawLogFragment; private boolean mCanContributeToRepo; private boolean mBuildInProgressState; private boolean mBuildStateChanged; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_build_details); ButterKnife.bind(this); TravisApp.instance().activityInjector().inject(this); initToolbar(); } @Override public void onSaveInstanceState(Bundle outState) { if (mJobsFragment != null) { detachFragment(mJobsFragment); } if (mRawLogFragment != null) { detachFragment(mRawLogFragment); } super.onSaveInstanceState(outState); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.menu_build_details, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem itemCancel = menu.findItem(R.id.build_activity_action_cancel); MenuItem itemRestart = menu.findItem(R.id.build_activity_action_restart); if (mCanContributeToRepo) { if (mBuildInProgressState) { itemCancel.setVisible(true); } else { itemRestart.setVisible(true); } } else { itemCancel.setVisible(false); itemRestart.setVisible(false); } return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.build_activity_action_restart: getPresenter().restartBuild(); handleBuildAction(); return true; case R.id.build_activity_action_cancel: getPresenter().cancelBuild(); handleBuildAction(); return true; } return super.onOptionsItemSelected(item); } @Override public void onJobSelected(Job job) { if (mRawLogFragment == null) { mRawLogFragment = RawLogFragment.newInstance(); } replaceFragment(R.id.build_details_container, mRawLogFragment, RAW_LOG_FRAGMENT_TAG, null); getPresenter().startLoadingLog(job.getId()); } @Override public void onLogLoaded() { mScrollBtn.show(); } @OnClick(R.id.build_details_scroll_btn) public void scrollContent() { mScrollBtn.hide(); mScrollUpBtn.show(); mBuildDetailsLayout.post(new Runnable() { @Override public void run() { mBuildDetailsLayout.fullScroll(View.FOCUS_DOWN); } }); } @OnClick(R.id.build_details_scroll_up_btn) public void setScrollUpContent() { mScrollBtn.show(); mScrollUpBtn.hide(); mBuildDetailsLayout.post(new Runnable() { @Override public void run() { mBuildDetailsLayout.fullScroll(View.FOCUS_UP); } }); } @Override public void onBackPressed() { Intent intent = new Intent(); intent.putExtra(BUILD_STATE_CHANGED, mBuildStateChanged); setResult(RESULT_OK, intent); super.onBackPressed(); mScrollBtn.hide(); mScrollUpBtn.hide(); } @Override protected BuildsDetailsPresenter getPresenter() { return mPresenter; } @Override protected void attachPresenter() { getPresenter().attach(this); final Intent intent = getIntent(); final String action = intent.getAction(); String intentUrl = null; String repoSlug = null; long buildId = 0L; if (Intent.ACTION_VIEW.equals(action)) { intentUrl = intent.getDataString(); } else { repoSlug = getIntent().getStringExtra(EXTRA_REPO_SLUG); buildId = getIntent().getLongExtra(EXTRA_BUILD_ID, 0L); } getPresenter().startLoadingData(intentUrl, repoSlug, buildId); } /** * Shows additional actions for build * * @param details Build details */ @Override public void showAdditionalActionsForBuild(BuildDetails details) { // check whether the user can contribute to this repo mCanContributeToRepo = getPresenter().canUserContributeToRepo(); if (mCanContributeToRepo) { mBuildInProgressState = BuildStateHelper.isInProgress(details.getBuild().getState()); invalidateOptionsMenu(); } } @Override public void showProgress() { mProgressBar.setVisibility(View.VISIBLE); } @Override public void hideProgress() { mProgressBar.setVisibility(View.GONE); } @Override public void showLoadingError(String message) { String msg = getString(R.string.error_failed_loading_build_details, message); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } @Override public void updateBuildDetails(BuildDetails buildDetails) { if (buildDetails != null) { mBuildDetailsData.setVisibility(View.VISIBLE); showBuildDetails(buildDetails); } else { mBuildDetailsData.setVisibility(View.GONE); } checkIfEmpty(buildDetails); } @Override public void showLogError() { mRawLogFragment.showProgress(false); mRawLogFragment.showError(true); } @Override public void setLogUrl(String logUrl) { mRawLogFragment.loadUrl(logUrl); } @Override public void showBuildJobs(List<Job> jobs) { if (mJobsFragment == null) { mJobsFragment = JobsFragment.newInstance(); } mJobsFragment.setJobs(jobs); addFragment(R.id.build_details_container, mJobsFragment, JOBS_FRAGMENT_TAG); } @Override public void showBuildLogs() { if (mRawLogFragment == null) { mRawLogFragment = RawLogFragment.newInstance(); } addFragment(R.id.build_details_container, mRawLogFragment, RAW_LOG_FRAGMENT_TAG); } /** * Handles build action */ private void handleBuildAction() { showProgress(); mCanContributeToRepo = false; invalidateOptionsMenu(); mBuildStateChanged = true; } /** * Initializes toolbar */ private void initToolbar() { final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); final ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); } } /** * Shows build details * * @param details Build details */ private void showBuildDetails(BuildDetails details) { Build build = details.getBuild(); Commit commit = details.getCommit(); BuildView buildView = (BuildView) findViewById(R.id.build_details_build_data); buildView.setState(build); buildView.setCommit(commit); } /** * Checks whether data existing or not */ private void checkIfEmpty(BuildDetails details) { TextView emptyText = (TextView) findViewById(R.id.empty_text); emptyText.setText(R.string.build_details_empty); if (details == null) { emptyText.setVisibility(View.VISIBLE); } else { emptyText.setVisibility(View.GONE); } } }