even more fixes
This commit is contained in:
parent
9a615777ad
commit
52fced08ea
7 changed files with 89 additions and 37 deletions
|
|
@ -24,6 +24,8 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.buffer
|
import kotlinx.coroutines.flow.buffer
|
||||||
import kotlinx.coroutines.flow.cache
|
import kotlinx.coroutines.flow.cache
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
|
@ -32,6 +34,7 @@ import kotlinx.coroutines.flow.flattenMerge
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
@ -45,6 +48,21 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
||||||
private val queryFilter = MutableStateFlow("")
|
private val queryFilter = MutableStateFlow("")
|
||||||
private val typeFilter = MutableStateFlow("")
|
private val typeFilter = MutableStateFlow("")
|
||||||
|
|
||||||
|
var filterCount : StateFlow<Int> = combine(
|
||||||
|
websiteFilter,
|
||||||
|
statusFilter
|
||||||
|
) { website, status ->
|
||||||
|
val activeFilters = listOf(
|
||||||
|
website.isNotEmpty(),
|
||||||
|
status != HistoryStatus.ALL
|
||||||
|
)
|
||||||
|
activeFilters.count { it }
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(5000),
|
||||||
|
initialValue = 0
|
||||||
|
)
|
||||||
|
|
||||||
enum class HistoryStatus {
|
enum class HistoryStatus {
|
||||||
UNSET, DELETED, NOT_DELETED, ALL
|
UNSET, DELETED, NOT_DELETED, ALL
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -324,9 +324,6 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
||||||
if (currentDownloadItem == null || !containers.contains(downloadItem.container.ifEmpty { getString(R.string.defaultValue) })){
|
if (currentDownloadItem == null || !containers.contains(downloadItem.container.ifEmpty { getString(R.string.defaultValue) })){
|
||||||
downloadItem.container = if (containerPreference == getString(R.string.defaultValue)) "" else containerPreference!!
|
downloadItem.container = if (containerPreference == getString(R.string.defaultValue)) "" else containerPreference!!
|
||||||
}
|
}
|
||||||
if (downloadItem.videoPreferences.compatibilityMode) {
|
|
||||||
container.editText?.setText("mkv")
|
|
||||||
}
|
|
||||||
containerAutoCompleteTextView!!.setText(
|
containerAutoCompleteTextView!!.setText(
|
||||||
downloadItem.container.ifEmpty { getString(R.string.defaultValue) },
|
downloadItem.container.ifEmpty { getString(R.string.defaultValue) },
|
||||||
false)
|
false)
|
||||||
|
|
@ -347,7 +344,9 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
||||||
downloadItem.videoPreferences.recodeVideo = false
|
downloadItem.videoPreferences.recodeVideo = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (downloadItem.videoPreferences.compatibilityMode) {
|
||||||
|
containerAutoCompleteTextView.setText("mkv",false)
|
||||||
|
}
|
||||||
view.findViewById<LinearLayout>(R.id.adjust).apply {
|
view.findViewById<LinearLayout>(R.id.adjust).apply {
|
||||||
visibility = if (shownFields.contains("adjust_video")) View.VISIBLE else View.GONE
|
visibility = if (shownFields.contains("adjust_video")) View.VISIBLE else View.GONE
|
||||||
if (isVisible){
|
if (isVisible){
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.paging.PagingData
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
|
@ -48,8 +49,10 @@ import com.deniscerri.ytdl.database.repository.HistoryRepository
|
||||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
||||||
import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel
|
import com.deniscerri.ytdl.database.viewmodel.HistoryViewModel
|
||||||
import com.deniscerri.ytdl.ui.adapter.HistoryPaginatedAdapter
|
import com.deniscerri.ytdl.ui.adapter.HistoryPaginatedAdapter
|
||||||
|
import com.deniscerri.ytdl.util.Extensions.createBadge
|
||||||
import com.deniscerri.ytdl.util.Extensions.enableFastScroll
|
import com.deniscerri.ytdl.util.Extensions.enableFastScroll
|
||||||
import com.deniscerri.ytdl.util.Extensions.toListString
|
import com.deniscerri.ytdl.util.Extensions.toListString
|
||||||
|
import com.deniscerri.ytdl.util.Extensions.updateMenuItemBadge
|
||||||
import com.deniscerri.ytdl.util.FileUtil
|
import com.deniscerri.ytdl.util.FileUtil
|
||||||
import com.deniscerri.ytdl.util.NavbarUtil
|
import com.deniscerri.ytdl.util.NavbarUtil
|
||||||
import com.deniscerri.ytdl.util.UiUtil
|
import com.deniscerri.ytdl.util.UiUtil
|
||||||
|
|
@ -143,6 +146,12 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
historyViewModel.filterCount.collectLatest {
|
||||||
|
topAppBar.updateMenuItemBadge(R.id.filters, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
historyViewModel.websites.collectLatest {
|
historyViewModel.websites.collectLatest {
|
||||||
if(it.isEmpty()) {
|
if(it.isEmpty()) {
|
||||||
|
|
@ -288,6 +297,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
deleteDialog.setMessage(getString(R.string.confirm_delete_history_desc))
|
deleteDialog.setMessage(getString(R.string.confirm_delete_history_desc))
|
||||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||||
|
historyAdapter.submitData(lifecycle, PagingData.empty())
|
||||||
historyViewModel.clearDeleted()
|
historyViewModel.clearDeleted()
|
||||||
}
|
}
|
||||||
deleteDialog.show()
|
deleteDialog.show()
|
||||||
|
|
@ -302,6 +312,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
deleteDialog.setMessage(getString(R.string.confirm_delete_history_desc))
|
deleteDialog.setMessage(getString(R.string.confirm_delete_history_desc))
|
||||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||||
|
historyAdapter.submitData(lifecycle, PagingData.empty())
|
||||||
historyViewModel.deleteDuplicates()
|
historyViewModel.deleteDuplicates()
|
||||||
}
|
}
|
||||||
deleteDialog.show()
|
deleteDialog.show()
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ class GenerateYoutubePoTokensFragment : Fragment() {
|
||||||
|
|
||||||
val intent = Intent(requireContext(), PoTokenWebViewLoginActivity::class.java)
|
val intent = Intent(requireContext(), PoTokenWebViewLoginActivity::class.java)
|
||||||
intent.putExtra("url", "https://www.youtube.com")
|
intent.putExtra("url", "https://www.youtube.com")
|
||||||
//intent.putExtra("redirect_url", "https://www.youtube.com/embed/${editText.text.toString().getIDFromYoutubeURL()}")
|
intent.putExtra("redirect_url", "https://www.youtube.com/embed/${editText.text.toString().getIDFromYoutubeURL()}")
|
||||||
intent.putExtra("no_auth", true)
|
intent.putExtra("no_auth", true)
|
||||||
webPoTokenResultLauncher.launch(intent)
|
webPoTokenResultLauncher.launch(intent)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import android.view.MenuItem
|
||||||
import android.webkit.CookieManager
|
import android.webkit.CookieManager
|
||||||
import android.webkit.WebChromeClient
|
import android.webkit.WebChromeClient
|
||||||
import android.webkit.WebSettings
|
import android.webkit.WebSettings
|
||||||
import android.webkit.WebStorage
|
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
|
@ -25,7 +24,6 @@ import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.core.view.forEach
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
|
@ -35,10 +33,6 @@ import com.deniscerri.ytdl.database.viewmodel.CookieViewModel
|
||||||
import com.deniscerri.ytdl.ui.BaseActivity
|
import com.deniscerri.ytdl.ui.BaseActivity
|
||||||
import com.deniscerri.ytdl.util.UiUtil
|
import com.deniscerri.ytdl.util.UiUtil
|
||||||
import com.deniscerri.ytdl.util.extractors.newpipe.potoken.NewPipePoTokenGenerator
|
import com.deniscerri.ytdl.util.extractors.newpipe.potoken.NewPipePoTokenGenerator
|
||||||
import com.google.accompanist.web.AccompanistWebChromeClient
|
|
||||||
import com.google.accompanist.web.AccompanistWebViewClient
|
|
||||||
import com.google.accompanist.web.WebView
|
|
||||||
import com.google.accompanist.web.rememberWebViewState
|
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
|
|
@ -127,29 +121,32 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//update cookies
|
|
||||||
withContext(Dispatchers.IO) {
|
if (!noAuth) {
|
||||||
val cookieURL = "Po Token Generated Cookies"
|
//update cookies
|
||||||
cookiesViewModel.getCookiesFromDB(cookieURL).getOrNull()?.let {
|
withContext(Dispatchers.IO) {
|
||||||
kotlin.runCatching {
|
val cookieURL = "Po Token Generated Cookies"
|
||||||
cookiesViewModel.insert(
|
cookiesViewModel.getCookiesFromDB(cookieURL).getOrNull()?.let {
|
||||||
CookieItem(
|
kotlin.runCatching {
|
||||||
0,
|
cookiesViewModel.insert(
|
||||||
cookieURL,
|
CookieItem(
|
||||||
it,
|
0,
|
||||||
"",
|
cookieURL,
|
||||||
true
|
it,
|
||||||
|
"",
|
||||||
|
true
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
cookiesViewModel.updateCookiesFile()
|
||||||
cookiesViewModel.updateCookiesFile()
|
preferences.edit().putBoolean("use_cookies", true).apply()
|
||||||
preferences.edit().putBoolean("use_cookies", true).apply()
|
}.onFailure {
|
||||||
}.onFailure {
|
withContext(Dispatchers.Main) {
|
||||||
withContext(Dispatchers.Main) {
|
Toast.makeText(
|
||||||
Toast.makeText(
|
this@PoTokenWebViewLoginActivity,
|
||||||
this@PoTokenWebViewLoginActivity,
|
"Tokens were generated but cookies were not updated",
|
||||||
"Tokens were generated but cookies were not updated",
|
Toast.LENGTH_SHORT
|
||||||
Toast.LENGTH_SHORT
|
).show()
|
||||||
).show()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +166,10 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
|
||||||
if (value?.trim('"') == "complete") {
|
if (value?.trim('"') == "complete") {
|
||||||
Handler(Looper.getMainLooper()).postDelayed({
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
redirectUrl?.apply {
|
redirectUrl?.apply {
|
||||||
webView.loadUrl(this)
|
val extraHeaders: MutableMap<String?, String?> =
|
||||||
|
HashMap()
|
||||||
|
extraHeaders["Referer"] = url
|
||||||
|
webView.loadUrl(this, extraHeaders)
|
||||||
}
|
}
|
||||||
redirectUrl = null
|
redirectUrl = null
|
||||||
}, 2500)
|
}, 2500)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import android.text.Spanned
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
|
@ -33,6 +34,7 @@ import android.widget.ScrollView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.annotation.Px
|
import androidx.annotation.Px
|
||||||
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
import androidx.core.graphics.drawable.DrawableCompat
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
|
|
@ -46,6 +48,7 @@ import com.deniscerri.ytdl.database.models.DownloadItem
|
||||||
import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem
|
import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem
|
||||||
import com.deniscerri.ytdl.database.repository.DownloadRepository
|
import com.deniscerri.ytdl.database.repository.DownloadRepository
|
||||||
import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository.EveryCategory
|
import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository.EveryCategory
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.badge.BadgeDrawable
|
import com.google.android.material.badge.BadgeDrawable
|
||||||
import com.google.android.material.badge.BadgeUtils
|
import com.google.android.material.badge.BadgeUtils
|
||||||
import com.google.android.material.badge.ExperimentalBadgeUtils
|
import com.google.android.material.badge.ExperimentalBadgeUtils
|
||||||
|
|
@ -67,7 +70,9 @@ import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||||
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import org.json.JSONTokener
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.HttpCookie
|
import java.net.HttpCookie
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
|
@ -257,9 +262,9 @@ object Extensions {
|
||||||
runCatching {
|
runCatching {
|
||||||
val tmp = this.getString(it)
|
val tmp = this.getString(it)
|
||||||
if (tmp != "null") {
|
if (tmp != "null") {
|
||||||
return if (tmp.startsWith("[") && tmp.endsWith("]")) {
|
return try {
|
||||||
Json.decodeFromString<List<String>>(tmp).joinToString(", ")
|
Json.decodeFromString<List<String>>(tmp).joinToString(", ")
|
||||||
}else{
|
} catch (e: Exception) {
|
||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -324,6 +329,25 @@ object Extensions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalBadgeUtils::class)
|
||||||
|
fun MaterialToolbar.updateMenuItemBadge(menuItemId: Int, nr: Int) {
|
||||||
|
this.findViewById<View>(menuItemId).overlay.clear()
|
||||||
|
|
||||||
|
val badge = BadgeDrawable.create(context).apply {
|
||||||
|
number = nr
|
||||||
|
backgroundColor = ContextCompat.getColor(context, R.color.white)
|
||||||
|
badgeTextColor = ContextCompat.getColor(context, R.color.black)
|
||||||
|
verticalOffset = dpToPx(resources, 4f)
|
||||||
|
horizontalOffset = dpToPx(resources, 4f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr > 0) {
|
||||||
|
BadgeUtils.attachBadgeDrawable(badge, this, menuItemId)
|
||||||
|
} else {
|
||||||
|
BadgeUtils.detachBadgeDrawable(badge, this, menuItemId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun TabLayout.Tab.createBadge(nr: Int){
|
fun TabLayout.Tab.createBadge(nr: Int){
|
||||||
removeBadge()
|
removeBadge()
|
||||||
if (nr > 0) {
|
if (nr > 0) {
|
||||||
|
|
|
||||||
|
|
@ -509,5 +509,5 @@
|
||||||
<string name="app_icon">App Icon</string>
|
<string name="app_icon">App Icon</string>
|
||||||
<string name="show_quick_download_share_menu">Show option to download immediately in the share menu</string>
|
<string name="show_quick_download_share_menu">Show option to download immediately in the share menu</string>
|
||||||
<string name="quick_download_title">Don\'t fetch data</string>
|
<string name="quick_download_title">Don\'t fetch data</string>
|
||||||
<string name="sponsorblock_hook">Hook</string>
|
<string name="sponsorblock_hook">Hook/Greetings</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue