<commit_before>/*
 * Copyright 2018 Google 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.google.android.apps.muzei.browse

import android.app.PendingIntent
import android.os.Bundle
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil.load
import com.google.android.apps.muzei.room.Artwork
import com.google.android.apps.muzei.room.MuzeiDatabase
import com.google.android.apps.muzei.room.getCommands
import com.google.android.apps.muzei.sync.ProviderManager
import com.google.android.apps.muzei.util.collectIn
import com.google.android.apps.muzei.util.toast
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.nurik.roman.muzei.R
import net.nurik.roman.muzei.databinding.BrowseProviderFragmentBinding
import net.nurik.roman.muzei.databinding.BrowseProviderItemBinding

class BrowseProviderFragment: Fragment(R.layout.browse_provider_fragment) {

    companion object {
        const val REFRESH_DELAY = 300L // milliseconds
    }

    private val viewModel: BrowseProviderViewModel by viewModels()
    private val args: BrowseProviderFragmentArgs by navArgs()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val binding = BrowseProviderFragmentBinding.bind(view)
        val pm = requireContext().packageManager
        val providerInfo = pm.resolveContentProvider(args.contentUri.authority!!, 0)
                ?: run {
                    findNavController().popBackStack()
                    return
                }

        binding.swipeRefresh.setOnRefreshListener {
            refresh(binding.swipeRefresh)
        }
        binding.toolbar.apply {
            navigationIcon = DrawerArrowDrawable(requireContext()).apply {
                progress = 1f
            }
            setNavigationOnClickListener {
                val navController = findNavController()
                if (navController.currentDestination?.id == R.id.browse_provider) {
                    navController.popBackStack()
                }
            }
            title = providerInfo.loadLabel(pm)
            inflateMenu(R.menu.browse_provider_fragment)
            setOnMenuItemClickListener {
                refresh(binding.swipeRefresh)
                true
            }
        }
        val adapter = Adapter()
        binding.list.adapter = adapter

        viewModel.contentUri = args.contentUri
        viewModel.artwork.collectIn(viewLifecycleOwner) {
            adapter.submitList(it)
        }
    }

    private fun refresh(swipeRefreshLayout: SwipeRefreshLayout) {
        lifecycleScope.launch {
            ProviderManager.requestLoad(requireContext(), args.contentUri)
            // Show the refresh indicator for some visible amount of time
            // rather than immediately dismissing it. We don't know how long
            // the provider will actually take to refresh, if it does at all.
            delay(REFRESH_DELAY)
            withContext(Dispatchers.Main.immediate) {
                swipeRefreshLayout.isRefreshing = false
            }
        }
    }

    class ArtViewHolder(
            private val owner: LifecycleOwner,
            private val binding: BrowseProviderItemBinding
    ): RecyclerView.ViewHolder(binding.root) {

        fun bind(artwork: Artwork) {
            val context = itemView.context
            binding.image.contentDescription = artwork.title
            binding.image.load(artwork.imageUri) {<commit_msg>Cancel refresh job when the view is destroyed<commit_after>/*
 * Copyright 2018 Google 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.google.android.apps.muzei.browse

import android.app.PendingIntent
import android.os.Bundle
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil.load
import com.google.android.apps.muzei.room.Artwork
import com.google.android.apps.muzei.room.MuzeiDatabase
import com.google.android.apps.muzei.room.getCommands
import com.google.android.apps.muzei.sync.ProviderManager
import com.google.android.apps.muzei.util.collectIn
import com.google.android.apps.muzei.util.toast
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.nurik.roman.muzei.R
import net.nurik.roman.muzei.databinding.BrowseProviderFragmentBinding
import net.nurik.roman.muzei.databinding.BrowseProviderItemBinding

class BrowseProviderFragment: Fragment(R.layout.browse_provider_fragment) {

    companion object {
        const val REFRESH_DELAY = 300L // milliseconds
    }

    private val viewModel: BrowseProviderViewModel by viewModels()
    private val args: BrowseProviderFragmentArgs by navArgs()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val binding = BrowseProviderFragmentBinding.bind(view)
        val pm = requireContext().packageManager
        val providerInfo = pm.resolveContentProvider(args.contentUri.authority!!, 0)
                ?: run {
                    findNavController().popBackStack()
                    return
                }

        binding.swipeRefresh.setOnRefreshListener {
            refresh(binding.swipeRefresh)
        }
        binding.toolbar.apply {
            navigationIcon = DrawerArrowDrawable(requireContext()).apply {
                progress = 1f
            }
            setNavigationOnClickListener {
                val navController = findNavController()
                if (navController.currentDestination?.id == R.id.browse_provider) {
                    navController.popBackStack()
                }
            }
            title = providerInfo.loadLabel(pm)
            inflateMenu(R.menu.browse_provider_fragment)
            setOnMenuItemClickListener {
                refresh(binding.swipeRefresh)
                true
            }
        }
        val adapter = Adapter()
        binding.list.adapter = adapter

        viewModel.contentUri = args.contentUri
        viewModel.artwork.collectIn(viewLifecycleOwner) {
            adapter.submitList(it)
        }
    }

    private fun refresh(swipeRefreshLayout: SwipeRefreshLayout) {
        viewLifecycleOwner.lifecycleScope.launch {
            ProviderManager.requestLoad(requireContext(), args.contentUri)
            // Show the refresh indicator for some visible amount of time
            // rather than immediately dismissing it. We don't know how long
            // the provider will actually take to refresh, if it does at all.
            delay(REFRESH_DELAY)
            withContext(Dispatchers.Main.immediate) {
                swipeRefreshLayout.isRefreshing = false
            }
        }
    }

    class ArtViewHolder(
            private val owner: LifecycleOwner,
            private val binding: BrowseProviderItemBinding
    ): RecyclerView.ViewHolder(binding.root) {

        fun bind(artwork: Artwork) {
            val context = itemView.context
            binding.image.contentDescription = artwork.title
            binding.image.load(artwork.imageUri) {
{'fraction_non_alphanumeric': 0.07315554633184601, 'fraction_numerical': 0.0026979350420255266, 'mean_word_length': 2.9678880197612187, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3754457', 'n_tokens_mistral': 2627, 'n_tokens_neox': 2534, 'n_words': 581}