bug fixes random

This commit is contained in:
deniscerri 2025-09-18 20:39:36 +02:00
parent adec4485de
commit 3d56cd6e50
No known key found for this signature in database
GPG key ID: 95C43D517D830350
5 changed files with 77 additions and 71 deletions

View file

@ -18,7 +18,7 @@ interface TerminalDao {
fun getActiveTerminalDownloadsFlow() : Flow<List<TerminalItem>> fun getActiveTerminalDownloadsFlow() : Flow<List<TerminalItem>>
@Query("SELECT * from terminalDownloads where id=:id") @Query("SELECT * from terminalDownloads where id=:id")
fun getActiveTerminalFlow(id: Long) : Flow<TerminalItem> fun getActiveTerminalFlow(id: Long) : Flow<TerminalItem?>
@Query("SELECT COUNT(*) FROM terminalDownloads") @Query("SELECT COUNT(*) FROM terminalDownloads")
fun getActiveTerminalsCount() : Int fun getActiveTerminalsCount() : Int

View file

@ -30,7 +30,7 @@ class TerminalViewModel(private val application: Application) : AndroidViewModel
return dao.getActiveTerminalDownloadsFlow() return dao.getActiveTerminalDownloadsFlow()
} }
fun getTerminal(id: Long) : Flow<TerminalItem> { fun getTerminal(id: Long) : Flow<TerminalItem?> {
return dao.getActiveTerminalFlow(id) return dao.getActiveTerminalFlow(id)
} }

View file

@ -46,7 +46,7 @@ class FormatAdapter(onItemClickListener: OnItemClickListener, activity: Activity
if (list != null) { if (list != null) {
formats = list formats = list
} }
super.submitList(list) super.submitList(list ?: listOf<FormatRecyclerView>())
} }
fun setCanMultiSelectAudio(it: Boolean) { fun setCanMultiSelectAudio(it: Boolean) {

View file

@ -18,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
@ -64,7 +65,7 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
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)
//hide incognito //hide incognito
toolbar.menu.findItem(1).isVisible = false toolbar.menu.children.firstOrNull { it.itemId == R.id.incognito }?.isVisible = false
toolbar.setOnMenuItemClickListener { m : MenuItem -> toolbar.setOnMenuItemClickListener { m : MenuItem ->
when(m.itemId) { when(m.itemId) {
R.id.get_data_sync_id -> { R.id.get_data_sync_id -> {

View file

@ -1,5 +1,6 @@
package com.deniscerri.ytdl.ui.more.terminal package com.deniscerri.ytdl.ui.more.terminal
import android.annotation.SuppressLint
import android.app.ActionBar.LayoutParams import android.app.ActionBar.LayoutParams
import android.app.Activity import android.app.Activity
import android.content.ClipboardManager import android.content.ClipboardManager
@ -53,13 +54,13 @@ import kotlin.properties.Delegates
class TerminalFragment : Fragment() { class TerminalFragment : Fragment() {
private var topAppBar: MaterialToolbar? = null private lateinit var topAppBar: MaterialToolbar
private lateinit var notificationUtil: NotificationUtil private lateinit var notificationUtil: NotificationUtil
private lateinit var terminalViewModel: TerminalViewModel private lateinit var terminalViewModel: TerminalViewModel
private var output: TextView? = null private lateinit var output: TextView
private var input: EditText? = null private lateinit var input: EditText
private var fab: ExtendedFloatingActionButton? = null private lateinit var fab: ExtendedFloatingActionButton
private var scrollView: ScrollView? = null private lateinit var scrollView: ScrollView
private lateinit var bottomAppBar: BottomAppBar private lateinit var bottomAppBar: BottomAppBar
private lateinit var commandTemplateViewModel: CommandTemplateViewModel private lateinit var commandTemplateViewModel: CommandTemplateViewModel
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
@ -80,9 +81,9 @@ class TerminalFragment : Fragment() {
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
outState.putString("input", input?.text.toString()) outState.putString("input", input.text.toString())
outState.putString("output", output?.text.toString()) outState.putString("output", output.text.toString())
outState.putBoolean("run", fab!!.text == requireActivity().getString(R.string.run_command)) outState.putBoolean("run", fab.text == requireActivity().getString(R.string.run_command))
outState.putLong("downloadID", downloadID) outState.putLong("downloadID", downloadID)
} }
@ -97,8 +98,8 @@ class TerminalFragment : Fragment() {
imm = requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager imm = requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
scrollView = view.findViewById(R.id.custom_command_scrollview) scrollView = view.findViewById(R.id.custom_command_scrollview)
topAppBar = requireActivity().findViewById(R.id.custom_command_toolbar) topAppBar = requireActivity().findViewById(R.id.custom_command_toolbar)
topAppBar!!.setNavigationOnClickListener { requireActivity().finish() } topAppBar.setNavigationOnClickListener { requireActivity().finish() }
topAppBar!!.setOnClickListener { scrollView?.scrollTo(0,0) } topAppBar.setOnClickListener { scrollView.scrollTo(0,0) }
input = view.findViewById(R.id.command_edittext) input = view.findViewById(R.id.command_edittext)
fab = view.findViewById(R.id.command_fab) fab = view.findViewById(R.id.command_fab)
@ -106,7 +107,7 @@ class TerminalFragment : Fragment() {
if (arguments?.getLong("id") != null){ if (arguments?.getLong("id") != null){
downloadID = requireArguments().getLong("id") downloadID = requireArguments().getLong("id")
if(downloadID != 0L){ if(downloadID != 0L){
input!!.visibility = View.GONE input.visibility = View.GONE
showCancelFab() showCancelFab()
} }
} }
@ -133,18 +134,18 @@ class TerminalFragment : Fragment() {
commandTemplateViewModel.getTotalNumber() commandTemplateViewModel.getTotalNumber()
} }
if (templateCount == 0){ if (templateCount == 0){
bottomAppBar.menu.getItem(0).icon?.alpha = 30 bottomAppBar.menu[0].icon?.alpha = 30
}else{ }else{
bottomAppBar.menu.getItem(0).icon?.alpha = 255 bottomAppBar.menu[0].icon?.alpha = 255
} }
shortcutCount = withContext(Dispatchers.IO){ shortcutCount = withContext(Dispatchers.IO){
commandTemplateViewModel.getTotalShortcutNumber() commandTemplateViewModel.getTotalShortcutNumber()
} }
if (shortcutCount == 0) { if (shortcutCount == 0) {
bottomAppBar.menu.getItem(1).icon?.alpha = 30 bottomAppBar.menu[1].icon?.alpha = 30
}else{ }else{
bottomAppBar.menu.getItem(1).icon?.alpha = 255 bottomAppBar.menu[1].icon?.alpha = 255
} }
} }
@ -157,11 +158,11 @@ class TerminalFragment : Fragment() {
lifecycleScope.launch { lifecycleScope.launch {
UiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel){ templates -> UiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel){ templates ->
templates.forEach {c -> templates.forEach {c ->
input!!.text.insert(input!!.selectionStart, c.content + " ") input.text.insert(input.selectionStart, c.content + " ")
} }
input!!.postDelayed({ input.postDelayed({
input!!.requestFocus() input.requestFocus()
imm.showSoftInput(input!!, 0) imm.showSoftInput(input, 0)
}, 200) }, 200)
} }
} }
@ -172,11 +173,12 @@ class TerminalFragment : Fragment() {
if (shortcutCount > 0){ if (shortcutCount > 0){
UiUtil.showShortcuts(requireActivity(), commandTemplateViewModel, UiUtil.showShortcuts(requireActivity(), commandTemplateViewModel,
itemSelected = {sh -> itemSelected = {sh ->
input!!.setText("${input!!.text} $sh") val txt = "${input.text} $sh"
input.setText(txt)
}, },
itemRemoved = {removed -> itemRemoved = {removed ->
input!!.setText(input!!.text.replace("(${Regex.escape(removed)})(?!.*\\1)".toRegex(), "").trimEnd()) input.setText(input.text.replace("(${Regex.escape(removed)})(?!.*\\1)".toRegex(), "").trimEnd())
input!!.setSelection(input!!.text.length) input.setSelection(input.text.length)
}) })
} }
} }
@ -194,45 +196,46 @@ class TerminalFragment : Fragment() {
} }
output = view.findViewById(R.id.custom_command_output) output = view.findViewById(R.id.custom_command_output)
output!!.setTextIsSelectable(true) output.setTextIsSelectable(true)
output!!.layoutParams!!.width = LayoutParams.WRAP_CONTENT output.layoutParams!!.width = LayoutParams.WRAP_CONTENT
input!!.requestFocus() input.requestFocus()
fab!!.setOnClickListener { fab.setOnClickListener {
if (fab!!.text == requireActivity().getString(R.string.run_command)){ if (fab.text == requireActivity().getString(R.string.run_command)){
input!!.visibility = View.GONE input.visibility = View.GONE
output!!.text = "${output!!.text}\n~ $ ${input!!.text}\n" val txt = "${output.text}\n~ $ ${input.text}\n"
output.text = txt
showCancelFab() showCancelFab()
imm.hideSoftInputFromWindow(input?.windowToken, 0) imm.hideSoftInputFromWindow(input.windowToken, 0)
lifecycleScope.launch { lifecycleScope.launch {
val command = input!!.text.toString().replaceFirst("yt-dlp", "") val command = input.text.toString().replaceFirst("yt-dlp", "")
downloadID = withContext(Dispatchers.IO){ downloadID = withContext(Dispatchers.IO){
terminalViewModel.insert(TerminalItem(command = command, log = output!!.text.toString())) terminalViewModel.insert(TerminalItem(command = command, log = output.text.toString()))
} }
terminalViewModel.startTerminalDownloadWorker(TerminalItem(downloadID, command)) terminalViewModel.startTerminalDownloadWorker(TerminalItem(downloadID, command))
input!!.visibility = View.GONE input.visibility = View.GONE
showCancelFab() showCancelFab()
runWorkerListener() runWorkerListener()
} }
}else { }else {
terminalViewModel.cancelTerminalDownload(downloadID) terminalViewModel.cancelTerminalDownload(downloadID)
input!!.visibility = View.VISIBLE input.visibility = View.VISIBLE
hideCancelFab() hideCancelFab()
} }
} }
notificationUtil = NotificationUtil(requireContext()) notificationUtil = NotificationUtil(requireContext())
initMenu() initMenu()
lifecycleScope.launch(Dispatchers.IO) { requireView().post {
if (sharedPreferences.getBoolean("use_code_color_highlighter", true)) { if (sharedPreferences.getBoolean("use_code_color_highlighter", true)) {
input?.enableTextHighlight() input.enableTextHighlight()
} }
}
input?.append(bundle?.getString("input") ?: "") input.append(bundle?.getString("input") ?: "")
input!!.requestFocus() input.requestFocus()
input!!.setSelection(input!!.text.length) input.setSelection(input.text.length)
output?.text = bundle?.getString("output") ?: output?.text output.text = bundle?.getString("output") ?: output.text
output?.isVisible = output?.text.toString().isNotEmpty() output.isVisible = output.text.toString().isNotEmpty()
}
if (bundle?.getBoolean("run") == true){ if (bundle?.getBoolean("run") == true){
showCancelFab() showCancelFab()
@ -240,13 +243,14 @@ class TerminalFragment : Fragment() {
runWorkerListener() runWorkerListener()
} }
@SuppressLint("UseKtx")
private fun initMenu() { private fun initMenu() {
topAppBar?.menu?.get(0)?.isVisible = false topAppBar.menu?.get(0)?.isVisible = false
topAppBar?.menu?.get(1)?.isVisible = true topAppBar.menu?.get(1)?.isVisible = true
topAppBar?.menu?.get(2)?.isVisible = true topAppBar.menu?.get(2)?.isVisible = true
topAppBar?.menu?.get(3)?.isVisible = true topAppBar.menu?.get(3)?.isVisible = true
val slider = requireActivity().findViewById<Slider>(R.id.textsize_seekbar) val slider = requireActivity().findViewById<Slider>(R.id.textsize_seekbar)
topAppBar?.setOnMenuItemClickListener { m: MenuItem -> topAppBar.setOnMenuItemClickListener { m: MenuItem ->
when(m.itemId){ when(m.itemId){
R.id.wrap -> { R.id.wrap -> {
var scrollView = requireView().findViewById<HorizontalScrollView>(R.id.horizontalscroll_output) var scrollView = requireView().findViewById<HorizontalScrollView>(R.id.horizontalscroll_output)
@ -257,7 +261,7 @@ class TerminalFragment : Fragment() {
parent.addView(output, 0) parent.addView(output, 0)
sharedPreferences.edit().putBoolean("wrap_text_terminal", true).apply() sharedPreferences.edit().putBoolean("wrap_text_terminal", true).apply()
}else{ }else{
val parent = output?.parent as ViewGroup val parent = output.parent as ViewGroup
parent.removeView(output) parent.removeView(output)
scrollView = HorizontalScrollView(requireContext()) scrollView = HorizontalScrollView(requireContext())
scrollView.layoutParams = LinearLayout.LayoutParams( scrollView.layoutParams = LinearLayout.LayoutParams(
@ -273,7 +277,7 @@ class TerminalFragment : Fragment() {
R.id.export_clipboard -> { R.id.export_clipboard -> {
lifecycleScope.launch(Dispatchers.IO){ lifecycleScope.launch(Dispatchers.IO){
val clipboard: ClipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager val clipboard: ClipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
clipboard.setText(output?.text) clipboard.setText(output.text)
} }
} }
@ -288,11 +292,11 @@ class TerminalFragment : Fragment() {
this.valueFrom = 0f this.valueFrom = 0f
this.valueTo = 10f this.valueTo = 10f
this.value = sharedPreferences.getFloat("terminal_zoom", 2f) this.value = sharedPreferences.getFloat("terminal_zoom", 2f)
output?.setCustomTextSize(this.value + 13f) output.setCustomTextSize(this.value + 13f)
input?.setCustomTextSize(this.value + 13f) input.setCustomTextSize(this.value + 13f)
this.addOnChangeListener { slider, value, fromUser -> this.addOnChangeListener { slider, value, fromUser ->
output?.setCustomTextSize(value + 13f) output.setCustomTextSize(value + 13f)
input?.setCustomTextSize(value + 13f) input.setCustomTextSize(value + 13f)
sharedPreferences.edit(true){ sharedPreferences.edit(true){
putFloat("terminal_zoom", value) putFloat("terminal_zoom", value)
} }
@ -307,14 +311,14 @@ class TerminalFragment : Fragment() {
} }
private fun hideCancelFab() { private fun hideCancelFab() {
kotlin.runCatching { kotlin.runCatching {
fab!!.text = getString(R.string.run_command) fab.text = getString(R.string.run_command)
fab!!.setIconResource(R.drawable.ic_baseline_keyboard_arrow_right_24) fab.setIconResource(R.drawable.ic_baseline_keyboard_arrow_right_24)
} }
} }
private fun showCancelFab() { private fun showCancelFab() {
kotlin.runCatching { kotlin.runCatching {
fab!!.text = getString(R.string.cancel_task) fab.text = getString(R.string.cancel_task)
fab!!.setIconResource(R.drawable.ic_cancel) fab.setIconResource(R.drawable.ic_cancel)
} }
} }
@ -329,7 +333,7 @@ class TerminalFragment : Fragment() {
Intent.FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION
) )
} }
input!!.text.insert(input!!.selectionStart, FileUtil.formatPath(result.data?.data.toString())) input.text.insert(input.selectionStart, FileUtil.formatPath(result.data?.data.toString()))
} }
} }
@ -340,12 +344,12 @@ class TerminalFragment : Fragment() {
requireActivity().runOnUiThread{ requireActivity().runOnUiThread{
if (it != null){ if (it != null){
if (!it.log.isNullOrBlank()) { if (!it.log.isNullOrBlank()) {
output?.isVisible = true output.isVisible = true
output?.text = it.log output.text = it.log
} }
output?.scrollTo(0, output!!.height) output.scrollTo(0, output.height)
scrollView?.fullScroll(View.FOCUS_DOWN) scrollView.fullScroll(View.FOCUS_DOWN)
input!!.visibility = View.GONE input.visibility = View.GONE
showCancelFab() showCancelFab()
} }
} }
@ -364,15 +368,16 @@ class TerminalFragment : Fragment() {
} }
private val workerObserver = object: Observer<List<WorkInfo>> { private val workerObserver = object: Observer<List<WorkInfo>> {
@SuppressLint("SetTextI18n")
override fun onChanged(value: List<WorkInfo>) { override fun onChanged(value: List<WorkInfo>) {
value.forEach { work -> value.forEach { work ->
if (listOf(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED).contains(work.state)) { if (listOf(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED).contains(work.state)) {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
kotlin.runCatching { kotlin.runCatching {
input!!.setText("yt-dlp ") input.setText("yt-dlp ")
input!!.visibility = View.VISIBLE input.visibility = View.VISIBLE
input!!.requestFocus() input.requestFocus()
input!!.setSelection(input!!.text.length) input.setSelection(input.text.length)
hideCancelFab() hideCancelFab()
} }
} }