<commit_before>package acr.browser.lightning.browser.fragment

import acr.browser.lightning.BrowserApp
import acr.browser.lightning.R
import acr.browser.lightning.animation.AnimationUtils
import acr.browser.lightning.browser.BookmarksView
import acr.browser.lightning.browser.TabsManager
import acr.browser.lightning.browser.bookmark.BookmarkUiModel
import acr.browser.lightning.constant.LOAD_READING_URL
import acr.browser.lightning.controller.UIController
import acr.browser.lightning.database.HistoryItem
import acr.browser.lightning.database.bookmark.BookmarkRepository
import acr.browser.lightning.dialog.LightningDialogBuilder
import acr.browser.lightning.favicon.FaviconModel
import acr.browser.lightning.preference.UserPreferences
import acr.browser.lightning.reading.activity.ReadingActivity
import acr.browser.lightning.utils.ThemeUtils
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.PorterDuff
import android.os.Bundle
import android.support.annotation.IdRes
import android.support.v4.app.Fragment
import android.support.v7.util.DiffUtil
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import io.reactivex.Scheduler
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.bookmark_drawer.*
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Named

class BookmarksFragment : Fragment(), View.OnClickListener, View.OnLongClickListener, BookmarksView {

    // Managers
    @Inject internal lateinit var bookmarkModel: BookmarkRepository

    // Dialog builder
    @Inject internal lateinit var bookmarksDialogBuilder: LightningDialogBuilder

    @Inject internal lateinit var userPreferences: UserPreferences

    @Inject internal lateinit var faviconModel: FaviconModel

    @Inject @field:Named("database") internal lateinit var databaseScheduler: Scheduler
    @Inject @field:Named("network") internal lateinit var networkScheduler: Scheduler

    private lateinit var uiController: UIController

    // Adapter
    private var bookmarkAdapter: BookmarkListAdapter? = null

    // Preloaded images
    private var webPageBitmap: Bitmap? = null
    private var folderBitmap: Bitmap? = null

    // Colors
    private var iconColor: Int = 0
    private var scrollIndex: Int = 0

    private var isIncognito: Boolean = false

    private var bookmarksSubscription: Disposable? = null
    private var bookmarkUpdateSubscription: Disposable? = null

    private val uiModel = BookmarkUiModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        BrowserApp.appComponent.inject(this)

        val context = requireNotNull(context) { "Context should never be null in onCreate" }

        uiController = context as UIController
        isIncognito = arguments?.getBoolean(INCOGNITO_MODE, false) == true
        val darkTheme = userPreferences.useTheme != 0 || isIncognito
        webPageBitmap = ThemeUtils.getThemedBitmap(context, R.drawable.ic_webpage, darkTheme)
        folderBitmap = ThemeUtils.getThemedBitmap(context, R.drawable.ic_folder, darkTheme)
        iconColor = ThemeUtils.getIconThemeColor(context, darkTheme)
    }

    override fun onResume() {
        super.onResume()
        if (bookmarkAdapter != null) {
            setBookmarksShown(null, false)
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
        inflater.inflate(R.layout.bookmark_drawer, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        bookmark_back_button_image?.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
        val backView = view.findViewById<View>(R.id.bookmark_back_button)
        backView.setOnClickListener {
            if (!uiModel.isCurrentFolderRoot()) {
                setBookmarksShown(null, true)
                bookmark_list_view?.layoutManager?.scrollToPosition(scrollIndex)
            }
        }
        setupNavigationButton(view, R.id.action_add_bookmark, R.id.action_add_bookmark_image)
        setupNavigationButton(view, R.id.action_reading, R.id.action_reading_image)
        setupNavigationButton(view, R.id.action_toggle_desktop, R.id.action_toggle_desktop_image)


        bookmarkAdapter = BookmarkListAdapter(
            faviconModel,
            folderBitmap!!,
            webPageBitmap!!,
            networkScheduler,
            this::handleItemLongPress,
            this::handleItemClick
        )

        bookmark_list_view?.let {
            it.layoutManager = LinearLayoutManager(context)
            it.adapter = bookmarkAdapter
        }

        setBookmarksShown(null, true)
    }

    override fun onDestroyView() {
        super.onDestroyView()

        bookmarksSubscription?.dispose()
        bookmarkUpdateSubscription?.dispose()

        bookmarkAdapter?.cleanupSubscriptions()
    }

    override fun onDestroy() {
        super.onDestroy()

        bookmarksSubscription?.dispose()
        bookmarkUpdateSubscription?.dispose()

        bookmarkAdapter?.cleanupSubscriptions()
    }

    private fun getTabsManager(): TabsManager = uiController.getTabModel()

    fun reinitializePreferences() {
        val activity = activity ?: return
        val darkTheme = userPreferences.useTheme != 0 || isIncognito
        webPageBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_webpage, darkTheme)
        folderBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_folder, darkTheme)
        iconColor = ThemeUtils.getIconThemeColor(activity, darkTheme)
    }

    private fun updateBookmarkIndicator(url: String) {
        bookmarkUpdateSubscription?.dispose()
        bookmarkUpdateSubscription = bookmarkModel.isBookmark(url)
            .subscribeOn(databaseScheduler)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { boolean ->
                bookmarkUpdateSubscription = null
                val activity = activity
                if (action_add_bookmark_image == null || activity == null) {
                    return@subscribe
                }
                if (boolean) {
                    action_add_bookmark_image?.setImageResource(R.drawable.ic_action_star)
                    action_add_bookmark_image?.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
                } else {
                    action_add_bookmark_image?.setImageResource(R.drawable.ic_bookmark)
                    action_add_bookmark_image?.setColorFilter(ThemeUtils.getAccentColor(activity), PorterDuff.Mode.SRC_IN)
                }
            }
    }

    override fun handleBookmarkDeleted(item: HistoryItem) {
        if (item.isFolder) {
            setBookmarksShown(null, false)
        } else {
            bookmarkAdapter?.deleteItem(item)
        }
    }

    private fun setBookmarksShown(folder: String?, animate: Boolean) {
        bookmarksSubscription?.dispose()
        bookmarksSubscription = bookmarkModel.getBookmarksFromFolderSorted(folder)<commit_msg>Fixing bug where bookmark icon is not displayed correctly<commit_after>package acr.browser.lightning.browser.fragment

import acr.browser.lightning.BrowserApp
import acr.browser.lightning.R
import acr.browser.lightning.animation.AnimationUtils
import acr.browser.lightning.browser.BookmarksView
import acr.browser.lightning.browser.TabsManager
import acr.browser.lightning.browser.bookmark.BookmarkUiModel
import acr.browser.lightning.constant.LOAD_READING_URL
import acr.browser.lightning.controller.UIController
import acr.browser.lightning.database.HistoryItem
import acr.browser.lightning.database.bookmark.BookmarkRepository
import acr.browser.lightning.dialog.LightningDialogBuilder
import acr.browser.lightning.favicon.FaviconModel
import acr.browser.lightning.preference.UserPreferences
import acr.browser.lightning.reading.activity.ReadingActivity
import acr.browser.lightning.utils.ThemeUtils
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.PorterDuff
import android.os.Bundle
import android.support.annotation.IdRes
import android.support.v4.app.Fragment
import android.support.v7.util.DiffUtil
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import io.reactivex.Scheduler
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.bookmark_drawer.*
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Named

class BookmarksFragment : Fragment(), View.OnClickListener, View.OnLongClickListener, BookmarksView {

    // Managers
    @Inject internal lateinit var bookmarkModel: BookmarkRepository

    // Dialog builder
    @Inject internal lateinit var bookmarksDialogBuilder: LightningDialogBuilder

    @Inject internal lateinit var userPreferences: UserPreferences

    @Inject internal lateinit var faviconModel: FaviconModel

    @Inject @field:Named("database") internal lateinit var databaseScheduler: Scheduler
    @Inject @field:Named("network") internal lateinit var networkScheduler: Scheduler

    private lateinit var uiController: UIController

    // Adapter
    private var bookmarkAdapter: BookmarkListAdapter? = null

    // Preloaded images
    private var webPageBitmap: Bitmap? = null
    private var folderBitmap: Bitmap? = null

    // Colors
    private var iconColor: Int = 0
    private var scrollIndex: Int = 0

    private var isIncognito: Boolean = false

    private var bookmarksSubscription: Disposable? = null
    private var bookmarkUpdateSubscription: Disposable? = null

    private val uiModel = BookmarkUiModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        BrowserApp.appComponent.inject(this)

        val context = requireNotNull(context) { "Context should never be null in onCreate" }

        uiController = context as UIController
        isIncognito = arguments?.getBoolean(INCOGNITO_MODE, false) == true
        val darkTheme = userPreferences.useTheme != 0 || isIncognito
        webPageBitmap = ThemeUtils.getThemedBitmap(context, R.drawable.ic_webpage, darkTheme)
        folderBitmap = ThemeUtils.getThemedBitmap(context, R.drawable.ic_folder, darkTheme)
        iconColor = ThemeUtils.getIconThemeColor(context, darkTheme)
    }

    override fun onResume() {
        super.onResume()
        if (bookmarkAdapter != null) {
            setBookmarksShown(null, false)
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
        inflater.inflate(R.layout.bookmark_drawer, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        bookmark_back_button_image?.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
        val backView = view.findViewById<View>(R.id.bookmark_back_button)
        backView.setOnClickListener {
            if (!uiModel.isCurrentFolderRoot()) {
                setBookmarksShown(null, true)
                bookmark_list_view?.layoutManager?.scrollToPosition(scrollIndex)
            }
        }
        setupNavigationButton(view, R.id.action_add_bookmark, R.id.action_add_bookmark_image)
        setupNavigationButton(view, R.id.action_reading, R.id.action_reading_image)
        setupNavigationButton(view, R.id.action_toggle_desktop, R.id.action_toggle_desktop_image)


        bookmarkAdapter = BookmarkListAdapter(
            faviconModel,
            folderBitmap!!,
            webPageBitmap!!,
            networkScheduler,
            this::handleItemLongPress,
            this::handleItemClick
        )

        bookmark_list_view?.let {
            it.layoutManager = LinearLayoutManager(context)
            it.adapter = bookmarkAdapter
        }

        setBookmarksShown(null, true)
    }

    override fun onDestroyView() {
        super.onDestroyView()

        bookmarksSubscription?.dispose()
        bookmarkUpdateSubscription?.dispose()

        bookmarkAdapter?.cleanupSubscriptions()
    }

    override fun onDestroy() {
        super.onDestroy()

        bookmarksSubscription?.dispose()
        bookmarkUpdateSubscription?.dispose()

        bookmarkAdapter?.cleanupSubscriptions()
    }

    private fun getTabsManager(): TabsManager = uiController.getTabModel()

    fun reinitializePreferences() {
        val activity = activity ?: return
        val darkTheme = userPreferences.useTheme != 0 || isIncognito
        webPageBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_webpage, darkTheme)
        folderBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_folder, darkTheme)
        iconColor = ThemeUtils.getIconThemeColor(activity, darkTheme)
    }

    private fun updateBookmarkIndicator(url: String) {
        bookmarkUpdateSubscription?.dispose()
        bookmarkUpdateSubscription = bookmarkModel.isBookmark(url)
            .subscribeOn(databaseScheduler)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { boolean ->
                bookmarkUpdateSubscription = null
                val activity = activity
                if (action_add_bookmark_image == null || activity == null) {
                    return@subscribe
                }
                if (boolean) {
                    action_add_bookmark_image?.setImageResource(R.drawable.ic_bookmark)
                    action_add_bookmark_image?.setColorFilter(ThemeUtils.getAccentColor(activity), PorterDuff.Mode.SRC_IN)
                } else {
                    action_add_bookmark_image?.setImageResource(R.drawable.ic_action_star)
                    action_add_bookmark_image?.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
                }
            }
    }

    override fun handleBookmarkDeleted(item: HistoryItem) {
        if (item.isFolder) {
            setBookmarksShown(null, false)
        } else {
            bookmarkAdapter?.deleteItem(item)
        }
    }

    private fun setBookmarksShown(folder: String?, animate: Boolean) {
        bookmarksSubscription?.dispose()
        bookmarksSubscription = bookmarkModel.getBookmarksFromFolderSorted(folder)
{'fraction_non_alphanumeric': 0.07752764086852271, 'fraction_numerical': 0.0010656720394298656, 'mean_word_length': 3.396778916544656, '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': '832484', 'n_tokens_mistral': 4133, 'n_tokens_neox': 3969, 'n_words': 761}