<commit_before>package com.kickstarter.ui.activities

import android.content.Intent
import android.os.Bundle
import android.util.Pair
import android.view.View
import androidx.core.view.isVisible
import com.kickstarter.R
import com.kickstarter.databinding.ActivityCommentsLayoutBinding
import com.kickstarter.libs.BaseActivity
import com.kickstarter.libs.RecyclerViewPaginator
import com.kickstarter.libs.SwipeRefresher
import com.kickstarter.libs.qualifiers.RequiresActivityViewModel
import com.kickstarter.libs.utils.ApplicationUtils
import com.kickstarter.libs.utils.TransitionUtils
import com.kickstarter.libs.utils.UrlUtils
import com.kickstarter.libs.utils.extensions.showAlertDialog
import com.kickstarter.libs.utils.extensions.toVisibility
import com.kickstarter.models.Comment
import com.kickstarter.ui.IntentKey
import com.kickstarter.ui.adapters.CommentsAdapter
import com.kickstarter.ui.data.CommentCardData
import com.kickstarter.ui.extensions.hideKeyboard
import com.kickstarter.ui.viewholders.EmptyCommentsViewHolder
import com.kickstarter.ui.views.OnCommentComposerViewClickedListener
import com.kickstarter.viewmodels.CommentsViewModel
import org.joda.time.DateTime
import rx.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit

@RequiresActivityViewModel(CommentsViewModel.ViewModel::class)
class CommentsActivity :
    BaseActivity<CommentsViewModel.ViewModel>(),
    CommentsAdapter.Delegate {
    private lateinit var binding: ActivityCommentsLayoutBinding
    private val adapter = CommentsAdapter(this)

    private lateinit var recyclerViewPaginator: RecyclerViewPaginator
    private lateinit var swipeRefresher: SwipeRefresher

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCommentsLayoutBinding.inflate(layoutInflater)
        val view: View = binding.root
        setContentView(view)
        binding.commentsRecyclerView.adapter = adapter

        binding.backButton.setOnClickListener {
            viewModel.inputs.checkIfThereAnyPendingComments(true)
        }

        setupPagination()

        viewModel.outputs.commentsList()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                comments ->
                adapter.takeData(comments)
            }

        viewModel.outputs.currentUserAvatar()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentComposer.setAvatarUrl(it)
            }

        viewModel.outputs.commentComposerStatus()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentComposer.setCommentComposerStatus(it)
            }

        viewModel.outputs.showCommentComposer()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentComposer.isVisible = it
            }

        viewModel.outputs.setEmptyState()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::setEmptyState)

        viewModel.outputs.initialLoadCommentsError()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                setEmptyState(false)
                adapter.insertPageError()
            }

        /*
         * A little delay after new item is inserted
         * This is necessary for the scroll to take effect
         */
        viewModel.outputs.scrollToTop()
            .filter { it == true }
            .compose(bindToLifecycle())
            .delay(200, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentsRecyclerView.smoothScrollToPosition(0)
            }

        viewModel.outputs.closeCommentsPage()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                closeCommentsActivity()
            }

        viewModel.outputs.shouldShowPaginationErrorUI()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                adapter.addErrorPaginationCell(it)
            }

        binding.commentComposer.setCommentComposerActionClickListener(object : OnCommentComposerViewClickedListener {
            override fun onClickActionListener(string: String) {
                postComment(string)
                hideKeyboard()
            }
        })

        viewModel.outputs.showCommentGuideLinesLink()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                ApplicationUtils.openUrlExternally(this, UrlUtils.appendPath(environment().webEndpoint(), COMMENT_KICKSTARTER_GUIDELINES))
            }

        viewModel.outputs.hasPendingComments()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                if (it.first) {
                    handleBackAction(it.second)
                } else {
                    executeActions(it.second)
                }
            }
    }

    private fun handleBackAction(isBackAction: Boolean) {
        this.showAlertDialog(
            getString(R.string.Your_comment_wasnt_posted),
            getString(R.string.You_will_lose_the_comment),
            getString(R.string.Cancel),
            getString(R.string.leave_page),
            false,
            positiveAction = {
                if (!isBackAction) {
                    binding.commentsSwipeRefreshLayout.isRefreshing = false
                }
            },
            negativeAction = {
                executeActions(isBackAction)
            }
        )
    }

    fun executeActions(isBackAction: Boolean) {
        if (!isBackAction) {
            viewModel.inputs.refresh()
        } else {
            viewModel.inputs.backPressed()
        }
    }

    override fun back() {
        if (binding.commentComposer.isCommentComposerEmpty() == true) {
            viewModel.inputs.checkIfThereAnyPendingComments(true)
        } else {
            handleBackAction(true)
        }
    }

    private fun closeCommentsActivity() {
        super.back()
        this.finishActivity(taskId)
    }

    private fun setupPagination() {

        recyclerViewPaginator = RecyclerViewPaginator(binding.commentsRecyclerView, { viewModel.inputs.nextPage() }, viewModel.outputs.isFetchingComments())

        swipeRefresher = SwipeRefresher(
            this, binding.commentsSwipeRefreshLayout,
            {
                viewModel.inputs.checkIfThereAnyPendingComments(false)
            }
        ) { viewModel.outputs.isFetchingComments() }
<commit_msg>handle back Icon press (#1336)<commit_after>package com.kickstarter.ui.activities

import android.content.Intent
import android.os.Bundle
import android.util.Pair
import android.view.View
import androidx.core.view.isVisible
import com.kickstarter.R
import com.kickstarter.databinding.ActivityCommentsLayoutBinding
import com.kickstarter.libs.BaseActivity
import com.kickstarter.libs.RecyclerViewPaginator
import com.kickstarter.libs.SwipeRefresher
import com.kickstarter.libs.qualifiers.RequiresActivityViewModel
import com.kickstarter.libs.utils.ApplicationUtils
import com.kickstarter.libs.utils.TransitionUtils
import com.kickstarter.libs.utils.UrlUtils
import com.kickstarter.libs.utils.extensions.showAlertDialog
import com.kickstarter.libs.utils.extensions.toVisibility
import com.kickstarter.models.Comment
import com.kickstarter.ui.IntentKey
import com.kickstarter.ui.adapters.CommentsAdapter
import com.kickstarter.ui.data.CommentCardData
import com.kickstarter.ui.extensions.hideKeyboard
import com.kickstarter.ui.viewholders.EmptyCommentsViewHolder
import com.kickstarter.ui.views.OnCommentComposerViewClickedListener
import com.kickstarter.viewmodels.CommentsViewModel
import org.joda.time.DateTime
import rx.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit

@RequiresActivityViewModel(CommentsViewModel.ViewModel::class)
class CommentsActivity :
    BaseActivity<CommentsViewModel.ViewModel>(),
    CommentsAdapter.Delegate {
    private lateinit var binding: ActivityCommentsLayoutBinding
    private val adapter = CommentsAdapter(this)

    private lateinit var recyclerViewPaginator: RecyclerViewPaginator
    private lateinit var swipeRefresher: SwipeRefresher

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCommentsLayoutBinding.inflate(layoutInflater)
        val view: View = binding.root
        setContentView(view)
        binding.commentsRecyclerView.adapter = adapter

        binding.backButton.setOnClickListener {
            handleBackAction()
        }

        setupPagination()

        viewModel.outputs.commentsList()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                comments ->
                adapter.takeData(comments)
            }

        viewModel.outputs.currentUserAvatar()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentComposer.setAvatarUrl(it)
            }

        viewModel.outputs.commentComposerStatus()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentComposer.setCommentComposerStatus(it)
            }

        viewModel.outputs.showCommentComposer()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentComposer.isVisible = it
            }

        viewModel.outputs.setEmptyState()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::setEmptyState)

        viewModel.outputs.initialLoadCommentsError()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                setEmptyState(false)
                adapter.insertPageError()
            }

        /*
         * A little delay after new item is inserted
         * This is necessary for the scroll to take effect
         */
        viewModel.outputs.scrollToTop()
            .filter { it == true }
            .compose(bindToLifecycle())
            .delay(200, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                binding.commentsRecyclerView.smoothScrollToPosition(0)
            }

        viewModel.outputs.closeCommentsPage()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                closeCommentsActivity()
            }

        viewModel.outputs.shouldShowPaginationErrorUI()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                adapter.addErrorPaginationCell(it)
            }

        binding.commentComposer.setCommentComposerActionClickListener(object : OnCommentComposerViewClickedListener {
            override fun onClickActionListener(string: String) {
                postComment(string)
                hideKeyboard()
            }
        })

        viewModel.outputs.showCommentGuideLinesLink()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                ApplicationUtils.openUrlExternally(this, UrlUtils.appendPath(environment().webEndpoint(), COMMENT_KICKSTARTER_GUIDELINES))
            }

        viewModel.outputs.hasPendingComments()
            .compose(bindToLifecycle())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                if (it.first) {
                    handleBackAction(it.second)
                } else {
                    executeActions(it.second)
                }
            }
    }

    private fun handleBackAction(isBackAction: Boolean) {
        this.showAlertDialog(
            getString(R.string.Your_comment_wasnt_posted),
            getString(R.string.You_will_lose_the_comment),
            getString(R.string.Cancel),
            getString(R.string.leave_page),
            false,
            positiveAction = {
                if (!isBackAction) {
                    binding.commentsSwipeRefreshLayout.isRefreshing = false
                }
            },
            negativeAction = {
                executeActions(isBackAction)
            }
        )
    }

    fun executeActions(isBackAction: Boolean) {
        if (!isBackAction) {
            viewModel.inputs.refresh()
        } else {
            viewModel.inputs.backPressed()
        }
    }

    override fun back() {
        handleBackAction()
    }

    private fun handleBackAction() {
        if (binding.commentComposer.isCommentComposerEmpty() == true) {
            viewModel.inputs.checkIfThereAnyPendingComments(true)
        } else {
            handleBackAction(true)
        }
    }

    private fun closeCommentsActivity() {
        super.back()
        this.finishActivity(taskId)
    }

    private fun setupPagination() {

        recyclerViewPaginator = RecyclerViewPaginator(binding.commentsRecyclerView, { viewModel.inputs.nextPage() }, viewModel.outputs.isFetchingComments())

        swipeRefresher = SwipeRefresher(
            this, binding.commentsSwipeRefreshLayout,
            {
                viewModel.inputs.checkIfThereAnyPendingComments(false)
            }
        ) { viewModel.outputs.isFetchingComments() }

{'fraction_non_alphanumeric': 0.081457282863433, 'fraction_numerical': 0.0008522122008380086, 'mean_word_length': 2.3306527909176915, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2653587', 'n_tokens_mistral': 3805, 'n_tokens_neox': 3549, 'n_words': 492}