From 614ba3c882addc6b2b037fb54d56f984ef8fe09d Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Sun, 16 Aug 2026 00:17:19 +0200 Subject: [PATCH] more fixes --- app/src/main/AndroidManifest.xml | 1 + .../database/viewmodel/TerminalViewModel.kt | 6 ++ .../ytdl/terminal/SessionService.kt | 6 +- .../ui/more/terminal/KeyShortcutHandler.kt | 2 +- .../ytdl/ui/more/terminal/TerminalBackEnd.kt | 2 +- .../ytdl/ui/more/terminal/TerminalFragment.kt | 77 ++++++++++--------- .../ytdl/ui/more/terminal/TerminalUtils.kt | 9 +-- .../terminal/virtualkeys/VirtualKeysView.kt | 12 +-- .../res/drawable/baseline_format_size_24.xml | 5 ++ app/src/main/res/layout/fragment_terminal.xml | 2 +- app/src/main/res/menu/log_detail_menu.xml | 2 +- app/src/main/res/menu/terminal_menu.xml | 6 ++ app/src/main/res/menu/terminal_top_menu.xml | 11 ++- 13 files changed, 81 insertions(+), 60 deletions(-) create mode 100644 app/src/main/res/drawable/baseline_format_size_24.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 59f5038b..f4bcaacd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -354,6 +354,7 @@ android:configChanges="smallestScreenSize|layoutDirection|orientation|screenSize" android:exported="true" android:label="@string/terminal" + android:windowSoftInputMode="adjustResize" android:parentActivityName=".MainActivity"> diff --git a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/TerminalViewModel.kt b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/TerminalViewModel.kt index 0980c076..0f68ad32 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/TerminalViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/TerminalViewModel.kt @@ -24,8 +24,10 @@ import com.deniscerri.ytdl.ui.more.terminal.virtualkeys.VirtualKeysListener import com.deniscerri.ytdl.ui.more.terminal.virtualkeys.VirtualKeysView import com.deniscerri.ytdl.ui.more.terminal.TerminalUtils import com.termux.view.TerminalView +import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.receiveAsFlow import java.lang.ref.WeakReference @@ -96,11 +98,15 @@ class TerminalViewModel(private val application: Application) : AndroidViewModel private val _isBoundState = MutableStateFlow(false) val isBoundState: StateFlow = _isBoundState + private val _serviceConnectedEvent = Channel(Channel.BUFFERED) + val serviceConnectedEvent = _serviceConnectedEvent.receiveAsFlow() + private val serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { sessionBinder = service as SessionService.SessionBinder isBound = true _isBoundState.value = true + _serviceConnectedEvent.trySend(Unit) } override fun onServiceDisconnected(name: ComponentName?) { diff --git a/app/src/main/java/com/deniscerri/ytdl/terminal/SessionService.kt b/app/src/main/java/com/deniscerri/ytdl/terminal/SessionService.kt index 97084827..eda82bc7 100644 --- a/app/src/main/java/com/deniscerri/ytdl/terminal/SessionService.kt +++ b/app/src/main/java/com/deniscerri/ytdl/terminal/SessionService.kt @@ -23,7 +23,7 @@ import com.termux.terminal.TerminalSessionClient class SessionService : Service() { private val sessions = hashMapOf() val sessionList = mutableStateMapOf() - var currentSession = mutableStateOf("main") + var currentSession = mutableStateOf("main1") inner class SessionBinder : Binder() { fun getService(): SessionService = this@SessionService @@ -59,7 +59,7 @@ class SessionService : Service() { } sessions.remove(id) sessionList.remove(id) - if (sessions.isNotEmpty()) { + if (sessions.isEmpty()) { stopSelf() } else { updateNotification() @@ -114,7 +114,7 @@ class SessionService : Service() { ) return NotificationCompat.Builder(this, CHANNEL_ID) - .setContentTitle("ReTerminal") + .setContentTitle("YTDLnis Terminal") .setContentText(getNotificationContentText()) .setSmallIcon(R.drawable.ic_terminal) .setContentIntent(pendingIntent) diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/KeyShortcutHandler.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/KeyShortcutHandler.kt index e9648a9f..b1bca2a9 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/KeyShortcutHandler.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/KeyShortcutHandler.kt @@ -39,7 +39,7 @@ object KeyShortcutHandler { val clipboard: ClipboardManager = App.instance.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager val clip = clipboard.primaryClip if (clip != null) { - val clipText = clip.toString() + val clipText = clip.getItemAt(0).text.toString() if (clipText.trim().isNotEmpty()) { viewModel.terminalView?.mEmulator?.paste(clipText) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalBackEnd.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalBackEnd.kt index 51b9eef3..10a99346 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalBackEnd.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalBackEnd.kt @@ -47,7 +47,7 @@ class TerminalBackEnd( val clipboard: ClipboardManager = activity.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager val clip = clipboard.primaryClip if (clip != null) { - val clipText = clip.toString() + val clipText = clip.getItemAt(0).text.toString() if (clipText.trim().isNotEmpty() && terminal.mEmulator != null) { terminal.mEmulator.paste(clipText) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt index 4b9dd36e..c1f8b03e 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt @@ -2,6 +2,8 @@ package com.deniscerri.ytdl.ui.more.terminal import android.annotation.SuppressLint import android.app.Activity +import android.content.ClipboardManager +import android.content.Context.CLIPBOARD_SERVICE import android.content.Intent import android.content.SharedPreferences import android.os.Bundle @@ -41,6 +43,7 @@ import com.termux.view.TerminalView import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlin.text.toInt class TerminalFragment : Fragment() { @@ -68,6 +71,7 @@ class TerminalFragment : Fragment() { } override fun onResume() { + arguments?.remove("new") arguments?.remove("share") super.onResume() } @@ -122,6 +126,19 @@ class TerminalFragment : Fragment() { } } + + val slider = requireActivity().findViewById(R.id.textsize_seekbar) + slider?.apply { + valueFrom = 10f + valueTo = 37f + value = sharedPreferences.getFloat("terminal_zoom", 35f) + + addOnChangeListener { _, value, _ -> + terminalView.setTextSize(value.toInt()) + sharedPreferences.edit { putFloat("terminal_zoom", value) } + } + } + bottomAppBar.setOnMenuItemClickListener { when(it.itemId){ R.id.command_templates -> { @@ -165,6 +182,9 @@ class TerminalFragment : Fragment() { intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) commandPathResultLauncher.launch(intent) } + R.id.text_size -> { + slider?.visibility = if (slider.visibility == View.VISIBLE) View.GONE else View.VISIBLE + } } true @@ -173,10 +193,13 @@ class TerminalFragment : Fragment() { notificationUtil = NotificationUtil(requireContext()) initMenu() - viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - terminalViewModel.isBoundState.collect { isBound -> - if (isBound) { + if (terminalViewModel.isBound && terminalViewModel.sessionBinder != null) { + initSession() + } else { + // If not bound yet, wait for the service connection event + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + terminalViewModel.serviceConnectedEvent.collect { initSession() } } @@ -187,15 +210,19 @@ class TerminalFragment : Fragment() { @SuppressLint("UseKtx") private fun initMenu() { topAppBar.menu?.findItem(R.id.export_clipboard)?.isVisible = true - topAppBar.menu?.findItem(R.id.text_size)?.isVisible = true + topAppBar.menu?.findItem(R.id.delete)?.isVisible = true - val slider = requireActivity().findViewById(R.id.textsize_seekbar) topAppBar.setOnMenuItemClickListener { menuItem: MenuItem -> when (menuItem.itemId) { R.id.add -> { findNavController().navigate(R.id.terminalFragment, bundleOf(Pair("new", true)), NavOptions.Builder().setPopUpTo(R.id.terminalFragment, true).build()) } + R.id.delete -> { + sessionId?.apply { + terminalViewModel.sessionBinder?.terminateSession(this) + } + } R.id.wrap -> { // var scrollView = requireView().findViewById(R.id.horizontalscroll_output) // if(scrollView != null){ @@ -219,34 +246,15 @@ class TerminalFragment : Fragment() { // } } R.id.export_clipboard -> { -// lifecycleScope.launch(Dispatchers.IO){ -// val clipboard: ClipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager -// clipboard.setText(output.text) -// } - } - R.id.text_size -> { - slider?.visibility = if (slider.visibility == View.VISIBLE) View.GONE else View.VISIBLE + lifecycleScope.launch(Dispatchers.IO){ + val clipboard: ClipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager + clipboard.setText(session.emulator.screen.transcriptText) + } } } true } - slider?.apply { - valueFrom = 10f - valueTo = 30f - value = sharedPreferences.getFloat("terminal_zoom", 14f).coerceIn(10f, 30f) - - addOnChangeListener { _, value, _ -> - terminalView.setTextSize(value.toInt()) - sharedPreferences.edit { putFloat("terminal_zoom", value) } - } - } - - sharedPreferences.getBoolean("wrap_text_terminal", false).apply { - if (this){ - bottomAppBar.menu.performIdentifierAction(R.id.wrap, 0) - } - } } private fun initSession() { @@ -262,15 +270,14 @@ class TerminalFragment : Fragment() { if (!sessionId.isNullOrBlank()) { terminalViewModel.changeSession(requireContext(), sessionBinder, sessionId!!) - sessionId = null } val newSession = arguments?.getBoolean("new") ?: false val currentSession = sessionBinder.getSession(service.currentSession.value) session = if (newSession || currentSession == null) { - val sessionId = KeyShortcutHandler.generateUniqueSessionId(activity) + sessionId = KeyShortcutHandler.generateUniqueSessionId(activity) sessionBinder.createSession( - sessionId, + sessionId!!, client ) } else { @@ -285,7 +292,7 @@ class TerminalFragment : Fragment() { val termView = view as TerminalView termView.setTextSize( - sharedPreferences.getFloat("terminal_zoom", 14f).coerceIn(10f, 30f).toInt() + sharedPreferences.getFloat("terminal_zoom", 35f).coerceIn(10f, 30f).toInt() ) termView.setTypeface(TerminalUtils.typeface) @@ -294,7 +301,7 @@ class TerminalFragment : Fragment() { termView.requestFocus() - val color = TerminalUtils.getViewColor() + val color = TerminalUtils.getViewColor(requireContext()) val bgColor = TerminalUtils.getBackgroundColor(requireContext()) termView.mEmulator?.mColors?.mCurrentColors?.apply { set(256, color) @@ -308,7 +315,7 @@ class TerminalFragment : Fragment() { it ) } - //buttonTextColor = TerminalUtils.getViewColor() + buttonTextColor = TerminalUtils.getViewColor(requireContext()) reload(VirtualKeysInfo(virtualKeys, "", VirtualKeysConstants.CONTROL_CHARS_ALIASES)) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalUtils.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalUtils.kt index 557d80b9..085c75a6 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalUtils.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalUtils.kt @@ -9,6 +9,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.ColorUtils import com.anggrayudi.storage.file.child import com.deniscerri.ytdl.App +import com.google.android.material.color.MaterialColors object TerminalUtils { var typeface: Typeface = Typeface.MONOSPACE @@ -20,13 +21,9 @@ object TerminalUtils { } } - fun getViewColor(): Int = Color.WHITE + fun getViewColor(context: Context): Int = MaterialColors.getColor(context, android.R.attr.textColorPrimary, Color.BLACK) - fun getBackgroundColor(context: Context): Int { - val typedValue = TypedValue() - context.theme.resolveAttribute(android.R.attr.windowBackground, typedValue, true) - return typedValue.data - } + fun getBackgroundColor(context: Context): Int = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, Color.BLACK) fun getComposeColor(): androidx.compose.ui.graphics.Color = androidx.compose.ui.graphics.Color.White diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/virtualkeys/VirtualKeysView.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/virtualkeys/VirtualKeysView.kt index ab8cf451..8e0c5063 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/virtualkeys/VirtualKeysView.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/virtualkeys/VirtualKeysView.kt @@ -76,9 +76,9 @@ class VirtualKeysView @JvmOverloads constructor( _repetitiveKeys = value } - var buttonTextColor: Int = DEFAULT_BUTTON_TEXT_COLOR + var buttonTextColor: Int = MaterialColors.getColor(context, android.R.attr.textColorPrimary, Color.BLACK) var buttonActiveTextColor: Int = DEFAULT_BUTTON_ACTIVE_TEXT_COLOR - var buttonBackgroundColor: Int = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, Color.BLACK) + var buttonBackgroundColor: Int = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurfaceContainer, Color.BLACK) var buttonActiveBackgroundColor: Int = DEFAULT_BUTTON_ACTIVE_BACKGROUND_COLOR var isButtonTextAllCaps: Boolean = true @@ -110,10 +110,10 @@ class VirtualKeysView @JvmOverloads constructor( repetitiveKeys = VirtualKeysConstants.PRIMARY_REPETITIVE_KEYS specialButtons = getDefaultSpecialButtons(this) setButtonColors( - DEFAULT_BUTTON_TEXT_COLOR, - DEFAULT_BUTTON_ACTIVE_TEXT_COLOR, - DEFAULT_BUTTON_BACKGROUND_COLOR, - DEFAULT_BUTTON_ACTIVE_BACKGROUND_COLOR + buttonTextColor, + buttonActiveTextColor, + buttonBackgroundColor, + buttonActiveBackgroundColor ) longPressTimeout = ViewConfiguration.getLongPressTimeout() longPressRepeatDelay = DEFAULT_LONG_PRESS_REPEAT_DELAY diff --git a/app/src/main/res/drawable/baseline_format_size_24.xml b/app/src/main/res/drawable/baseline_format_size_24.xml new file mode 100644 index 00000000..ed230057 --- /dev/null +++ b/app/src/main/res/drawable/baseline_format_size_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_terminal.xml b/app/src/main/res/layout/fragment_terminal.xml index 47bf8196..61cbae95 100644 --- a/app/src/main/res/layout/fragment_terminal.xml +++ b/app/src/main/res/layout/fragment_terminal.xml @@ -46,7 +46,7 @@ android:id="@+id/bottomAppBar" style="@style/Widget.Material3.BottomAppBar" android:layout_width="match_parent" - android:layout_height="50dp" + android:layout_height="wrap_content" android:layout_gravity="bottom" app:menu="@menu/terminal_menu" /> diff --git a/app/src/main/res/menu/log_detail_menu.xml b/app/src/main/res/menu/log_detail_menu.xml index e77ea10e..a27f945e 100644 --- a/app/src/main/res/menu/log_detail_menu.xml +++ b/app/src/main/res/menu/log_detail_menu.xml @@ -18,7 +18,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/terminal_top_menu.xml b/app/src/main/res/menu/terminal_top_menu.xml index 1add4a4a..c4380115 100644 --- a/app/src/main/res/menu/terminal_top_menu.xml +++ b/app/src/main/res/menu/terminal_top_menu.xml @@ -7,17 +7,16 @@ app:showAsAction="always" android:id="@+id/add"/> + + - -