/*
* Copyright 2018 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.pitchedapps.frost.activities
import android.annotation.SuppressLint
import android.app.ActivityOptions
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.PointF
import android.graphics.drawable.Drawable
import android.graphics.drawable.RippleDrawable
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.widget.Toolbar
import androidx.core.graphics.alpha
import androidx.core.view.updateLayoutParams
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentPagerAdapter
import ca.allanwang.kau.searchview.SearchItem
import ca.allanwang.kau.searchview.SearchView
import ca.allanwang.kau.searchview.SearchViewHolder
import ca.allanwang.kau.searchview.bindSearchView
import ca.allanwang.kau.ui.ProgressAnimator
import ca.allanwang.kau.utils.blendWith
import ca.allanwang.kau.utils.colorToForeground
import ca.allanwang.kau.utils.dimenPixelSize
import ca.allanwang.kau.utils.drawable
import ca.allanwang.kau.utils.fadeScaleTransition
import ca.allanwang.kau.utils.gone
import ca.allanwang.kau.utils.invisible
import ca.allanwang.kau.utils.materialDialog
import ca.allanwang.kau.utils.restart
import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.setMenuIcons
import ca.allanwang.kau.utils.showIf
import ca.allanwang.kau.utils.string
import ca.allanwang.kau.utils.tint
import ca.allanwang.kau.utils.toDrawable
import ca.allanwang.kau.utils.toast
import ca.allanwang.kau.utils.unboundedHeight
import ca.allanwang.kau.utils.visible
import ca.allanwang.kau.utils.withAlpha
import ca.allanwang.kau.utils.withMinAlpha
import com.afollestad.materialdialogs.checkbox.checkBoxPrompt
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.tabs.TabLayout
import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
import com.pitchedapps.frost.contracts.MainActivityContract
import com.pitchedapps.frost.contracts.VideoViewHolder
import com.pitchedapps.frost.contracts.WebFileChooser
import com.pitchedapps.frost.databinding.ActivityMainBinding
import com.pitchedapps.frost.databinding.ActivityMainBottomTabsBinding
import com.pitchedapps.frost.databinding.ActivityMainDrawerWrapperBinding
import com.pitchedapps.frost.databinding.ViewNavHeaderBinding
import com.pitchedapps.frost.db.CookieDao
import com.pitchedapps.frost.db.CookieEntity
import com.pitchedapps.frost.db.GenericDao
import com.pitchedapps.frost.db.currentCookie
import com.pitchedapps.frost.db.getTabs
import com.pitchedapps.frost.enums.MainActivityLayout
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.parsers.FrostSearch
import com.pitchedapps.frost.facebook.parsers.SearchParser
import com.pitchedapps.frost.facebook.profilePictureUrl
import com.pitchedapps.frost.fragments.BaseFragment
import com.pitchedapps.frost.fragments.WebFragment
import com.pitchedapps.frost.glide.FrostGlide
import com.pitchedapps.frost.glide.GlideApp
import com.pitchedapps.frost.services.scheduleNotificationsFromPrefs
import com.pitchedapps.frost.utils.ACTIVITY_SETTINGS
import com.pitchedapps.frost.utils.BiometricUtils
import com.pitchedapps.frost.utils.EXTRA_COOKIES
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.MAIN_TIMEOUT_DURATION
import com.pitchedapps.frost.utils.REQUEST_FAB
import com.pitchedapps.frost.utils.REQUEST_NAV
import com.pitchedapps.frost.utils.REQUEST_NOTIFICATION
import com.pitchedapps.frost.utils.REQUEST_REFRESH
import com.pitchedapps.frost.utils.REQUEST_RESTART
import com.pitchedapps.frost.utils.REQUEST_RESTART_APPLICATION
import com.pitchedapps.frost.utils.REQUEST_SEARCH
import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
import com.pitchedapps.frost.utils.cookies
import com.pitchedapps.frost.utils.frostChangelog
import com.pitchedapps.frost.utils.frostEvent
import com.pitchedapps.frost.utils.frostNavigationBar
import com.pitchedapps.frost.utils.launchLogin
import com.pitchedapps.frost.utils.launchNewTask
import com.pitchedapps.frost.utils.launchWebOverlay
import com.pitchedapps.frost.utils.urlEncode
import com.pitchedapps.frost.views.BadgedIcon
import com.pitchedapps.frost.views.FrostVideoViewer
import com.pitchedapps.frost.views.FrostViewPager
import com.pitchedapps.frost.widgets.NotificationWidget
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.scopes.ActivityScoped
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import javax.inject.Inject
import kotlin.math.abs
/**
* Created by Allan Wang on 20/12/17.
*
* Most of the logic that is unrelated to handling fragments
*/
@UseExperimental(ExperimentalCoroutinesApi::class)
@AndroidEntryPoint
abstract class BaseMainActivity :
BaseActivity(),
MainActivityContract,
VideoViewHolder,
SearchViewHolder {
/**
* Note that tabs themselves are initialized through a coroutine during onCreate
*/
protected val adapter: SectionsPagerAdapter = SectionsPagerAdapter()
override val frameWrapper: FrameLayout get() = drawerWrapperBinding.mainContainer
lateinit var drawerWrapperBinding: ActivityMainDrawerWrapperBinding
lateinit var contentBinding: ActivityMainContentBinding
@Inject
lateinit var cookieDao: CookieDao
@Inject
lateinit var genericDao: GenericDao
@Inject
lateinit var webFileChooser: WebFileChooser
interface ActivityMainContentBinding {
val root: View
val toolbar: Toolbar
val viewpager: FrostViewPager
val tabs: TabLayout
val appbar: AppBarLayout
val fab: FloatingActionButton
}
protected var lastPosition = -1
override var videoViewer: FrostVideoViewer? = null
private var lastAccessTime = -1L
override var searchView: SearchView? = null
private val searchViewCache = mutableMapOf>()
private var controlWebview: WebView? = null
final override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val start = System.currentTimeMillis()
drawerWrapperBinding = ActivityMainDrawerWrapperBinding.inflate(layoutInflater)
setContentView(drawerWrapperBinding.root)
contentBinding = when (prefs.mainActivityLayout) {
MainActivityLayout.TOP_BAR -> {
val binding = ActivityMainBinding.inflate(layoutInflater)
@SuppressLint("StaticFieldLeak")
object : ActivityMainContentBinding {
override val root: View = binding.root
override val toolbar: Toolbar = binding.toolbar
override val viewpager: FrostViewPager = binding.viewpager
override val tabs: TabLayout = binding.tabs
override val appbar: AppBarLayout = binding.appbar
override val fab: FloatingActionButton = binding.fab
}
}
MainActivityLayout.BOTTOM_BAR -> {
val binding = ActivityMainBottomTabsBinding.inflate(layoutInflater)
@SuppressLint("StaticFieldLeak")
object : ActivityMainContentBinding {
override val root: View = binding.root
override val toolbar: Toolbar = binding.toolbar
override val viewpager: FrostViewPager = binding.viewpager
override val tabs: TabLayout = binding.tabs
override val appbar: AppBarLayout = binding.appbar
override val fab: FloatingActionButton = binding.fab
}
}
}
drawerWrapperBinding.mainContainer.addView(contentBinding.root)
with(contentBinding) {
activityThemer.setFrostColors {
toolbar(toolbar)
themeWindow = false
header(appbar)
background(viewpager)
}
setSupportActionBar(toolbar)
viewpager.adapter = adapter
tabs.setBackgroundColor(prefs.mainActivityLayout.backgroundColor(themeProvider))
}
onNestedCreate(savedInstanceState)
L.i { "Main finished loading UI in ${System.currentTimeMillis() - start} ms" }
launch {
adapter.setPages(genericDao.getTabs())
}
controlWebview = WebView(this)
if (BuildConfig.VERSION_CODE > prefs.versionCode) {
prefs.prevVersionCode = prefs.versionCode
prefs.versionCode = BuildConfig.VERSION_CODE
if (!BuildConfig.DEBUG) {
frostChangelog()
frostEvent(
"Version",
"Version code" to BuildConfig.VERSION_CODE,
"Prev version code" to prefs.prevVersionCode,
"Version name" to BuildConfig.VERSION_NAME,
"Build type" to BuildConfig.BUILD_TYPE,
"Frost id" to prefs.frostId
)
}
}
L.i { "Main started in ${System.currentTimeMillis() - start} ms" }
drawerWrapperBinding.initDrawer()
contentBinding.initFab()
lastAccessTime = System.currentTimeMillis()
}
/**
* Injector to handle creation for sub classes
*/
protected abstract fun onNestedCreate(savedInstanceState: Bundle?)
private var hasFab = false
private var shouldShow = false
private class FrostMenuBuilder(private val context: Context, private val menu: Menu) {
private var order: Int = 0
private var groupId: Int = 13
private val items: MutableList