<commit_before>package jp.toastkid.yobidashi.tab

import android.content.Context
import android.net.Uri
import android.view.View
import androidx.annotation.UiThread
import androidx.lifecycle.ViewModelProvider
import jp.toastkid.lib.AppBarViewModel
import jp.toastkid.lib.ContentViewModel
import jp.toastkid.lib.TabListViewModel
import jp.toastkid.lib.preference.ColorPair
import jp.toastkid.lib.preference.PreferenceApplier
import jp.toastkid.yobidashi.R
import jp.toastkid.yobidashi.browser.BrowserFragment
import jp.toastkid.yobidashi.browser.BrowserHeaderViewModel
import jp.toastkid.yobidashi.browser.FaviconApplier
import jp.toastkid.yobidashi.browser.archive.IdGenerator
import jp.toastkid.yobidashi.browser.archive.auto.AutoArchive
import jp.toastkid.yobidashi.browser.block.AdRemover
import jp.toastkid.yobidashi.browser.webview.GlobalWebViewPool
import jp.toastkid.yobidashi.browser.webview.WebViewFactoryUseCase
import jp.toastkid.yobidashi.browser.webview.WebViewStateUseCase
import jp.toastkid.yobidashi.browser.webview.factory.WebViewClientFactory
import jp.toastkid.yobidashi.libs.BitmapCompressor
import jp.toastkid.yobidashi.libs.ThumbnailGenerator
import jp.toastkid.yobidashi.main.MainActivity
import jp.toastkid.yobidashi.tab.model.ArticleListTab
import jp.toastkid.yobidashi.tab.model.ArticleTab
import jp.toastkid.yobidashi.tab.model.CalendarTab
import jp.toastkid.yobidashi.tab.model.EditorTab
import jp.toastkid.yobidashi.tab.model.PdfTab
import jp.toastkid.yobidashi.tab.model.Tab
import jp.toastkid.yobidashi.tab.model.WebTab
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

/**
 * ModuleAdapter of [Tab].
 *
 * @author toastkidjp
 */
class TabAdapter(
        private val contextSupplier: () -> Context,
        private val tabEmptyCallback: () -> Unit
) {

    private val tabList: TabList = TabList.loadOrInit(contextSupplier())

    private val colorPair: ColorPair

    private val tabThumbnails: TabThumbnails

    private val preferenceApplier: PreferenceApplier

    private val autoArchive = AutoArchive.make(contextSupplier())

    private val webViewStateUseCase = WebViewStateUseCase.make(contextSupplier())

    private val disposables = Job()

    private var browserHeaderViewModel: BrowserHeaderViewModel? = null

    private var appBarViewModel: AppBarViewModel? = null

    private val bitmapCompressor = BitmapCompressor()

    private var tabListViewModel: TabListViewModel? = null

    private var webViewFactory: WebViewFactoryUseCase? = null

    init {
        val viewContext = contextSupplier()
        tabThumbnails = TabThumbnails.with(contextSupplier())
        preferenceApplier = PreferenceApplier(viewContext)
        colorPair = preferenceApplier.colorPair()

        if (viewContext is MainActivity) {
            val viewModelProvider = ViewModelProvider(viewContext)
            browserHeaderViewModel = viewModelProvider.get(BrowserHeaderViewModel::class.java)
            appBarViewModel = viewModelProvider.get(AppBarViewModel::class.java)
            tabListViewModel = viewModelProvider.get(TabListViewModel::class.java)

            webViewFactory = WebViewFactoryUseCase(
                    webViewClientFactory = WebViewClientFactory(
                            viewModelProvider.get(ContentViewModel::class.java),
                            AdRemover.make(viewContext.assets),
                            FaviconApplier(viewContext),
                            preferenceApplier
                    )
            )
        }

        CoroutineScope(Dispatchers.IO).launch {
            tabThumbnails.deleteUnused(tabList.thumbnailNames())
            autoArchive.deleteUnused(tabList.archiveIds())
            webViewStateUseCase.deleteUnused(tabList.ids())
        }
    }

    private val thumbnailGenerator = ThumbnailGenerator()

    /**
     * Save new thumbnail asynchronously.
     */
    @UiThread
    fun saveNewThumbnail(view: View?) {
        val bitmap = thumbnailGenerator(view) ?: return

        val currentTab = tabList.currentTab() ?: return

        val file = tabThumbnails.assignNewFile(currentTab.thumbnailPath())
        bitmapCompressor(bitmap, file)
    }

    /**
     * Open new tab with URL string.
     *
     * @param url URL (default = homeUrl)
     */
    fun openNewWebTab(url: String = preferenceApplier.homeUrl) {
        val newTab = WebTab.make("New tab: $url", url)
        tabList.add(newTab)
        setCount()
        setIndexByTab(newTab)
    }

    /**
     * Open background tab with URL string.
     *
     * @param title Tab's title
     * @param url Tab's URL
     */
    fun openBackgroundTab(title: String, url: String) {
        val context = contextSupplier()
        val tabTitle =
                if (title.isNotBlank()) title
                else context.getString(R.string.new_tab)

        val newTab = WebTab.makeBackground(tabTitle, url)
        tabList.add(newTab)
        tabList.save()

        val webView = webViewFactory?.invoke(context) ?: return
        webView.loadUrl(url)
        GlobalWebViewPool.put(newTab.id(), webView)
        setCount()
    }

    /**
     * This method allow calling from only [BrowserFragment].
     */
    internal fun openNewEditorTab(path: String? = null) {
        val editorTab = EditorTab()
        if (path != null) {
            editorTab.path = path
        }
        tabList.add(editorTab)
        setCount()
        setIndexByTab(editorTab)
    }
<commit_msg>feature #523 Return callback for implementing snackbar action.<commit_after>package jp.toastkid.yobidashi.tab

import android.content.Context
import android.net.Uri
import android.view.View
import androidx.annotation.UiThread
import androidx.lifecycle.ViewModelProvider
import jp.toastkid.lib.AppBarViewModel
import jp.toastkid.lib.ContentViewModel
import jp.toastkid.lib.TabListViewModel
import jp.toastkid.lib.preference.ColorPair
import jp.toastkid.lib.preference.PreferenceApplier
import jp.toastkid.yobidashi.R
import jp.toastkid.yobidashi.browser.BrowserFragment
import jp.toastkid.yobidashi.browser.BrowserHeaderViewModel
import jp.toastkid.yobidashi.browser.FaviconApplier
import jp.toastkid.yobidashi.browser.archive.IdGenerator
import jp.toastkid.yobidashi.browser.archive.auto.AutoArchive
import jp.toastkid.yobidashi.browser.block.AdRemover
import jp.toastkid.yobidashi.browser.webview.GlobalWebViewPool
import jp.toastkid.yobidashi.browser.webview.WebViewFactoryUseCase
import jp.toastkid.yobidashi.browser.webview.WebViewStateUseCase
import jp.toastkid.yobidashi.browser.webview.factory.WebViewClientFactory
import jp.toastkid.yobidashi.libs.BitmapCompressor
import jp.toastkid.yobidashi.libs.ThumbnailGenerator
import jp.toastkid.yobidashi.main.MainActivity
import jp.toastkid.yobidashi.tab.model.ArticleListTab
import jp.toastkid.yobidashi.tab.model.ArticleTab
import jp.toastkid.yobidashi.tab.model.CalendarTab
import jp.toastkid.yobidashi.tab.model.EditorTab
import jp.toastkid.yobidashi.tab.model.PdfTab
import jp.toastkid.yobidashi.tab.model.Tab
import jp.toastkid.yobidashi.tab.model.WebTab
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

/**
 * ModuleAdapter of [Tab].
 *
 * @author toastkidjp
 */
class TabAdapter(
        private val contextSupplier: () -> Context,
        private val tabEmptyCallback: () -> Unit
) {

    private val tabList: TabList = TabList.loadOrInit(contextSupplier())

    private val colorPair: ColorPair

    private val tabThumbnails: TabThumbnails

    private val preferenceApplier: PreferenceApplier

    private val autoArchive = AutoArchive.make(contextSupplier())

    private val webViewStateUseCase = WebViewStateUseCase.make(contextSupplier())

    private val disposables = Job()

    private var browserHeaderViewModel: BrowserHeaderViewModel? = null

    private var appBarViewModel: AppBarViewModel? = null

    private val bitmapCompressor = BitmapCompressor()

    private var tabListViewModel: TabListViewModel? = null

    private var webViewFactory: WebViewFactoryUseCase? = null

    init {
        val viewContext = contextSupplier()
        tabThumbnails = TabThumbnails.with(contextSupplier())
        preferenceApplier = PreferenceApplier(viewContext)
        colorPair = preferenceApplier.colorPair()

        if (viewContext is MainActivity) {
            val viewModelProvider = ViewModelProvider(viewContext)
            browserHeaderViewModel = viewModelProvider.get(BrowserHeaderViewModel::class.java)
            appBarViewModel = viewModelProvider.get(AppBarViewModel::class.java)
            tabListViewModel = viewModelProvider.get(TabListViewModel::class.java)

            webViewFactory = WebViewFactoryUseCase(
                    webViewClientFactory = WebViewClientFactory(
                            viewModelProvider.get(ContentViewModel::class.java),
                            AdRemover.make(viewContext.assets),
                            FaviconApplier(viewContext),
                            preferenceApplier
                    )
            )
        }

        CoroutineScope(Dispatchers.IO).launch {
            tabThumbnails.deleteUnused(tabList.thumbnailNames())
            autoArchive.deleteUnused(tabList.archiveIds())
            webViewStateUseCase.deleteUnused(tabList.ids())
        }
    }

    private val thumbnailGenerator = ThumbnailGenerator()

    /**
     * Save new thumbnail asynchronously.
     */
    @UiThread
    fun saveNewThumbnail(view: View?) {
        val bitmap = thumbnailGenerator(view) ?: return

        val currentTab = tabList.currentTab() ?: return

        val file = tabThumbnails.assignNewFile(currentTab.thumbnailPath())
        bitmapCompressor(bitmap, file)
    }

    /**
     * Open new tab with URL string.
     *
     * @param url URL (default = homeUrl)
     */
    fun openNewWebTab(url: String = preferenceApplier.homeUrl) {
        val newTab = WebTab.make("New tab: $url", url)
        tabList.add(newTab)
        setCount()
        setIndexByTab(newTab)
    }

    /**
     * Open background tab with URL string.
     *
     * @param title Tab's title
     * @param url Tab's URL
     */
    fun openBackgroundTab(title: String, url: String): () -> Unit {
        val context = contextSupplier()
        val tabTitle =
                if (title.isNotBlank()) title
                else context.getString(R.string.new_tab)

        val newTab = WebTab.makeBackground(tabTitle, url)
        tabList.add(newTab)
        tabList.save()

        val webView = webViewFactory?.invoke(context) ?: return { }
        webView.loadUrl(url)
        GlobalWebViewPool.put(newTab.id(), webView)
        setCount()
        return { setIndexByTab(newTab) }
    }

    /**
     * This method allow calling from only [BrowserFragment].
     */
    internal fun openNewEditorTab(path: String? = null) {
        val editorTab = EditorTab()
        if (path != null) {
            editorTab.path = path
        }
        tabList.add(editorTab)
        setCount()
        setIndexByTab(editorTab)
    }

{'fraction_non_alphanumeric': 0.08533309455587393, 'fraction_numerical': 0.0002686246418338109, 'mean_word_length': 3.110783952889216, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, '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': '3868800', 'n_tokens_mistral': 3477, 'n_tokens_neox': 3299, 'n_words': 590}