add incognito/desktop toggle in cookies webview & add reverse option when selecting items after sharing playlist

This commit is contained in:
deniscerri 2025-07-12 23:36:39 +02:00
parent 5f43da1e4e
commit cfa700d6fc
No known key found for this signature in database
GPG key ID: 95C43D517D830350
10 changed files with 164 additions and 25 deletions

View file

@ -67,4 +67,6 @@ interface ResultDao {
@Query("SELECT * from results WHERE id > :item1 AND id < :item2 ORDER BY id") @Query("SELECT * from results WHERE id > :item1 AND id < :item2 ORDER BY id")
fun getResultsBetweenTwoItems(item1: Long, item2: Long) : List<ResultItem> fun getResultsBetweenTwoItems(item1: Long, item2: Long) : List<ResultItem>
@Query("UPDATE results SET id = :newID where id = :id")
fun updateID(id: Long, newID: Long)
} }

View file

@ -370,6 +370,10 @@ class ResultRepository(private val resultDao: ResultDao, private val commandTemp
return resultDao.getAllByIDs(ids) return resultDao.getAllByIDs(ids)
} }
fun updateID(id: Long, newID: Long) {
resultDao.updateID(id, newID)
}
suspend fun getResultsFromSource(inputQuery: String, resetResults: Boolean, addToResults: Boolean = true, singleItem: Boolean = false) : List<ResultItem> { suspend fun getResultsFromSource(inputQuery: String, resetResults: Boolean, addToResults: Boolean = true, singleItem: Boolean = false) : List<ResultItem> {
return when(getQueryType(inputQuery)){ return when(getQueryType(inputQuery)){
SourceType.YOUTUBE_VIDEO -> { SourceType.YOUTUBE_VIDEO -> {

View file

@ -26,6 +26,7 @@ import com.deniscerri.ytdl.util.NotificationUtil
import com.yausername.youtubedl_android.YoutubeDLException import com.yausername.youtubedl_android.YoutubeDLException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.joinAll import kotlinx.coroutines.joinAll
@ -383,4 +384,23 @@ class ResultViewModel(private val application: Application) : AndroidViewModel(a
fun getStreamingUrlAndChapters(url: String) : Pair<List<String>, List<ChapterItem>?> { fun getStreamingUrlAndChapters(url: String) : Pair<List<String>, List<ChapterItem>?> {
return repository.getStreamingUrlAndChapters(url) return repository.getStreamingUrlAndChapters(url)
} }
fun reverseResults(resultItems: List<Long>): List<Long> {
val latestResult = resultItems.max()
val newIdsMap = mutableListOf<Pair<Long, Long>>()
var i = 0
resultItems.reversed().forEach {
newIdsMap.add(Pair(it, latestResult + (++i)))
}
viewModelScope.launch(Dispatchers.IO) {
delay(1000)
newIdsMap.forEach {
repository.updateID(it.first, it.second)
}
}
return newIdsMap.map { it.second }
}
} }

View file

@ -232,6 +232,10 @@ class SelectPlaylistItemsDialog : BottomSheetDialogFragment(), PlaylistAdapter.O
count.text = "${listAdapter.getCheckedItems().size} ${resources.getString(R.string.selected)}" count.text = "${listAdapter.getCheckedItems().size} ${resources.getString(R.string.selected)}"
} }
} }
R.id.reverse -> {
resultItemIDs = resultViewModel.reverseResults(resultItemIDs)
reset()
}
} }
true true
} }
@ -251,7 +255,6 @@ class SelectPlaylistItemsDialog : BottomSheetDialogFragment(), PlaylistAdapter.O
toTextInput.isEnabled = !isLoading toTextInput.isEnabled = !isLoading
items = it items = it
resultItemIDs = items.map { itm -> itm.id }
} }
} }

View file

@ -6,7 +6,10 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import android.webkit.CookieManager import android.webkit.CookieManager
import android.webkit.WebSettings
import android.webkit.WebStorage
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewDatabase
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -15,6 +18,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.core.view.children
import androidx.core.view.forEach import androidx.core.view.forEach
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -32,6 +36,7 @@ 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
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -57,27 +62,52 @@ class WebViewActivity : BaseActivity() {
lifecycleScope.launch { lifecycleScope.launch {
val appbar = findViewById<AppBarLayout>(R.id.webview_appbarlayout) val appbar = findViewById<AppBarLayout>(R.id.webview_appbarlayout)
toolbar = appbar.findViewById(R.id.webviewToolbar) toolbar = appbar.findViewById(R.id.webviewToolbar)
if (!url.isYoutubeURL()) {
toolbar.menu.forEach { it.isVisible = false }
}else {
toolbar.setOnMenuItemClickListener { m : MenuItem ->
when(m.itemId) {
R.id.get_data_sync_id -> {
webView?.evaluateJavascript("ytcfg.get('DATASYNC_ID')") { id ->
UiUtil.copyToClipboard(id.replace("\"", ""), this@WebViewActivity)
}
}
else -> {}
}
true
}
}
generateBtn = toolbar.findViewById(R.id.generate) generateBtn = toolbar.findViewById(R.id.generate)
webViewCompose = findViewById(R.id.webview_compose) webViewCompose = findViewById(R.id.webview_compose)
if (!url.isYoutubeURL()) {
toolbar.menu.children.firstOrNull { it.itemId == R.id.get_data_sync_id }?.isVisible = false
}
toolbar.setOnMenuItemClickListener { m : MenuItem ->
when(m.itemId) {
R.id.get_data_sync_id -> {
webView?.evaluateJavascript("ytcfg.get('DATASYNC_ID')") { id ->
UiUtil.copyToClipboard(id.replace("\"", ""), this@WebViewActivity)
}
}
R.id.incognito -> {
m.isChecked = !m.isChecked
webView.apply {
if (this == null) {
m.isChecked = false
return@apply
}
configureIncognito(this, m.isChecked)
this.reload()
}
}
R.id.desktop -> {
m.isChecked = !m.isChecked
webView.apply {
if (this == null) {
m.isChecked = false
return@apply
}
configureDesktopMode(this, m.isChecked)
this.reload()
}
}
else -> {}
}
true
}
cookieManager = CookieManager.getInstance() cookieManager = CookieManager.getInstance()
cookieManager.removeAllCookies(null) cookieManager.removeAllCookies(null)
cookieManager.flush()
preferences = PreferenceManager.getDefaultSharedPreferences(this@WebViewActivity) preferences = PreferenceManager.getDefaultSharedPreferences(this@WebViewActivity)
@ -134,6 +164,50 @@ class WebViewActivity : BaseActivity() {
} }
private fun configureIncognito(webView: WebView, incognito: Boolean) {
if (!incognito) {
webView.settings.run {
cacheMode = WebSettings.LOAD_DEFAULT
domStorageEnabled = true
setGeolocationEnabled(true)
}
}else {
webView.settings.run {
cacheMode = WebSettings.LOAD_NO_CACHE
domStorageEnabled = false
setGeolocationEnabled(false)
}
}
if (incognito) {
WebStorage.getInstance().deleteAllData()
}
if (incognito) {
webView.apply {
clearHistory()
clearCache(true)
clearFormData()
}
}
}
private fun configureDesktopMode(webView: WebView, desktop: Boolean) {
webView.settings.apply {
if (desktop) {
userAgentString = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
useWideViewPort = true
loadWithOverviewMode = true
} else {
userAgentString = WebSettings.getDefaultUserAgent(webView.context)
useWideViewPort = false
loadWithOverviewMode = false
}
}
}
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
@Composable @Composable
fun WebViewView() { fun WebViewView() {

View file

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#FF0000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M9.01,14H2v2h7.01v3L13,15l-3.99,-4V14zM14.99,13v-3H22V8h-7.01V5L11,9L14.99,13z"/>
</vector>

View file

@ -22,18 +22,23 @@
app:menu="@menu/select_playlist_menu" app:menu="@menu/select_playlist_menu"
android:layout_gravity="bottom"> android:layout_gravity="bottom">
<LinearLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_marginStart="50dp" android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_marginVertical="10dp" android:layout_marginVertical="10dp"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/from_textinput" android:id="@+id/from_textinput"
style="@style/Widget.Material3.TextInputLayout.FilledBox.Dense" style="@style/Widget.Material3.TextInputLayout.FilledBox.Dense"
android:layout_width="70dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintEnd_toStartOf="@id/to_textinput"
app:layout_constraintStart_toStartOf="parent"
android:hint="@string/start"> android:hint="@string/start">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
@ -47,11 +52,15 @@
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/to_textinput" android:id="@+id/to_textinput"
style="@style/Widget.Material3.TextInputLayout.FilledBox.Dense" style="@style/Widget.Material3.TextInputLayout.FilledBox.Dense"
android:layout_width="70dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/end" android:hint="@string/end"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/colon"> app:layout_constraintStart_toEndOf="@id/from_textinput"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,7 +70,7 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.bottomappbar.BottomAppBar> </com.google.android.material.bottomappbar.BottomAppBar>

View file

@ -14,4 +14,11 @@
android:icon="@drawable/ic_terminal" android:icon="@drawable/ic_terminal"
app:showAsAction="never" app:showAsAction="never"
android:id="@+id/invert_selected"/> android:id="@+id/invert_selected"/>
<item
android:id="@+id/reverse"
android:title="@string/reverse"
android:icon="@drawable/baseline_compare_arrows_24"
app:showAsAction="never" />
</menu> </menu>

View file

@ -1,10 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools" <menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/get_data_sync_id" android:id="@+id/get_data_sync_id"
android:title="Get Data Sync ID" android:title="Get Data Sync ID"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<item
android:id="@+id/incognito"
android:title="@string/incognito"
android:checkable="true"
app:showAsAction="never" />
<item
android:id="@+id/desktop"
android:title="Desktop"
android:checkable="true"
app:showAsAction="never" />
</menu> </menu>

View file

@ -480,4 +480,5 @@
<string name="select_between_desc">Specify the range of items to select</string> <string name="select_between_desc">Specify the range of items to select</string>
<string name="potoken">PO Token</string> <string name="potoken">PO Token</string>
<string name="web_client_po_token">Web Client PO Token</string> <string name="web_client_po_token">Web Client PO Token</string>
<string name="reverse">Reverse</string>
</resources> </resources>