added custom command and shortcuts buttons to terminal screen
This commit is contained in:
parent
506929b453
commit
467c0bd16e
12 changed files with 452 additions and 131 deletions
|
|
@ -41,6 +41,10 @@ class CommandTemplateViewModel(private val application: Application) : AndroidVi
|
|||
return repository.getAll()
|
||||
}
|
||||
|
||||
fun getAllShortcuts() : List<TemplateShortcut> {
|
||||
return repository.getAllShortCuts()
|
||||
}
|
||||
|
||||
fun getTotalNumber(): Int {
|
||||
return repository.getTotalNumber()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
|||
private val repository : HistoryRepository
|
||||
val sortOrder = MutableLiveData(HistorySort.DESC)
|
||||
val sortType = MutableLiveData(HistorySortType.DATE)
|
||||
private val websiteFilter = MutableLiveData("")
|
||||
val websiteFilter = MutableLiveData("")
|
||||
private val queryFilter = MutableLiveData("")
|
||||
private val formatFilter = MutableLiveData("")
|
||||
val allItems : LiveData<List<HistoryItem>>
|
||||
|
|
@ -48,6 +48,7 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
|||
return _items
|
||||
}
|
||||
|
||||
|
||||
fun setSorting(sort: HistorySortType){
|
||||
if (sortType.value != sort){
|
||||
sortOrder.value = HistorySort.DESC
|
||||
|
|
|
|||
|
|
@ -333,6 +333,7 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
|
||||
private fun updateWebsiteChips(list : List<HistoryItem>) {
|
||||
val websites = mutableListOf<String>()
|
||||
val websiteFilter = historyViewModel.websiteFilter.value
|
||||
for (item in list){
|
||||
if (!websites.contains(item.website)) websites.add(item.website)
|
||||
}
|
||||
|
|
@ -353,6 +354,9 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
tmp.isChecked = false
|
||||
}
|
||||
}
|
||||
if (w == websiteFilter){
|
||||
tmp.isChecked = true
|
||||
}
|
||||
websiteGroup!!.addView(tmp)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
package com.deniscerri.ytdlnis.ui.more
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CheckBox
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.Navigation
|
||||
|
|
@ -18,10 +20,13 @@ import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
|||
import com.deniscerri.ytdlnis.ui.downloads.DownloadQueueActivity
|
||||
import com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogListActivity
|
||||
import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.util.ArrayList
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class MoreFragment : Fragment() {
|
||||
private lateinit var mainSharedPreferences: SharedPreferences
|
||||
private lateinit var mainSharedPreferencesEditor: SharedPreferences.Editor
|
||||
private lateinit var terminal: TextView
|
||||
private lateinit var logs: TextView
|
||||
private lateinit var commandTemplates: TextView
|
||||
|
|
@ -42,6 +47,7 @@ class MoreFragment : Fragment() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mainSharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
mainSharedPreferencesEditor = mainSharedPreferences.edit()
|
||||
terminal = view.findViewById(R.id.terminal)
|
||||
logs = view.findViewById(R.id.logs)
|
||||
commandTemplates = view.findViewById(R.id.command_templates)
|
||||
|
|
@ -79,7 +85,33 @@ class MoreFragment : Fragment() {
|
|||
}
|
||||
|
||||
terminateApp.setOnClickListener {
|
||||
exitProcess(0)
|
||||
if (mainSharedPreferences.getBoolean("ask_terminate_app", true)){
|
||||
var doNotShowAgain = false
|
||||
val terminateDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
terminateDialog.setTitle(getString(R.string.confirm_delete_history))
|
||||
val dialogView = layoutInflater.inflate(R.layout.dialog_terminate_app, null)
|
||||
val checkbox = dialogView.findViewById<CheckBox>(R.id.doNotShowAgain)
|
||||
terminateDialog.setView(dialogView)
|
||||
|
||||
|
||||
|
||||
checkbox.setOnCheckedChangeListener { compoundButton, b ->
|
||||
doNotShowAgain = compoundButton.isChecked
|
||||
}
|
||||
|
||||
terminateDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
terminateDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
if (doNotShowAgain){
|
||||
mainSharedPreferencesEditor.putBoolean("ask_terminate_app", false)
|
||||
mainSharedPreferencesEditor.commit()
|
||||
}
|
||||
exitProcess(0)
|
||||
}
|
||||
terminateDialog.show()
|
||||
}else{
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
settings.setOnClickListener {
|
||||
|
|
|
|||
|
|
@ -7,22 +7,40 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.text.format.DateFormat
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.work.Data
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.App
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.deniscerri.ytdlnis.work.DownloadWorker
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
import io.reactivex.Observable
|
||||
|
|
@ -30,8 +48,14 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
|||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class TerminalActivity : AppCompatActivity() {
|
||||
|
|
@ -40,8 +64,9 @@ class TerminalActivity : AppCompatActivity() {
|
|||
private var output: TextView? = null
|
||||
private var input: EditText? = null
|
||||
private var fab: ExtendedFloatingActionButton? = null
|
||||
private var cancelFab: ExtendedFloatingActionButton? = null
|
||||
private var scrollView: ScrollView? = null
|
||||
private lateinit var bottomAppBar: BottomAppBar
|
||||
private lateinit var commandTemplateViewModel: CommandTemplateViewModel
|
||||
var context: Context? = null
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -51,23 +76,38 @@ class TerminalActivity : AppCompatActivity() {
|
|||
scrollView = findViewById(R.id.custom_command_scrollview)
|
||||
topAppBar = findViewById(R.id.custom_command_toolbar)
|
||||
topAppBar!!.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
|
||||
|
||||
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
|
||||
|
||||
|
||||
bottomAppBar = findViewById(R.id.bottomAppBar)
|
||||
bottomAppBar.setOnMenuItemClickListener {
|
||||
when(it.itemId){
|
||||
R.id.command_templates -> showCommandTemplates()
|
||||
R.id.shortcuts -> showShortcuts()
|
||||
else -> {}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
output = findViewById(R.id.custom_command_output)
|
||||
output!!.setTextIsSelectable(true)
|
||||
input = findViewById(R.id.command_edittext)
|
||||
input!!.requestFocus()
|
||||
fab = findViewById(R.id.command_fab)
|
||||
fab!!.setOnClickListener {
|
||||
input!!.visibility = View.GONE
|
||||
output!!.text = "${output!!.text}\n~ $ ${input!!.text}\n"
|
||||
swapFabs()
|
||||
startDownload(
|
||||
input!!.text.toString()
|
||||
)
|
||||
}
|
||||
cancelFab = findViewById(R.id.cancel_command_fab)
|
||||
cancelFab!!.setOnClickListener {
|
||||
cancelDownload()
|
||||
input!!.visibility = View.VISIBLE
|
||||
if (fab!!.text == getString(R.string.run_command)){
|
||||
input!!.visibility = View.GONE
|
||||
output!!.text = "${output!!.text}\n~ $ ${input!!.text}\n"
|
||||
showCancelFab()
|
||||
startDownload(
|
||||
input!!.text.toString()
|
||||
)
|
||||
}else {
|
||||
cancelDownload()
|
||||
input!!.visibility = View.VISIBLE
|
||||
hideCancelFab()
|
||||
}
|
||||
}
|
||||
notificationUtil = NotificationUtil(this)
|
||||
handleIntent(intent)
|
||||
|
|
@ -90,13 +130,73 @@ class TerminalActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
|
||||
private fun swapFabs() {
|
||||
val cancel = cancelFab!!.visibility
|
||||
val start = fab!!.visibility
|
||||
cancelFab!!.visibility = start
|
||||
fab!!.visibility = cancel
|
||||
private fun hideCancelFab() {
|
||||
fab!!.text = getString(R.string.run_command)
|
||||
fab!!.setIconResource(R.drawable.ic_baseline_keyboard_arrow_right_24)
|
||||
}
|
||||
private fun showCancelFab() {
|
||||
fab!!.text = getString(R.string.cancel_download)
|
||||
fab!!.setIconResource(R.drawable.ic_cancel)
|
||||
}
|
||||
|
||||
private fun showCommandTemplates(){
|
||||
lifecycleScope.launch {
|
||||
val bottomSheet = BottomSheetDialog(this@TerminalActivity)
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.command_template_list)
|
||||
|
||||
val linearLayout = bottomSheet.findViewById<LinearLayout>(R.id.command_list_linear_layout)
|
||||
val list = withContext(Dispatchers.IO){
|
||||
commandTemplateViewModel.getAll()
|
||||
}
|
||||
|
||||
linearLayout!!.removeAllViews()
|
||||
list.forEach {template ->
|
||||
val item = layoutInflater.inflate(R.layout.command_template_item, linearLayout, false) as ConstraintLayout
|
||||
item.findViewById<TextView>(R.id.title).text = template.title
|
||||
item.findViewById<TextView>(R.id.content).text = template.content
|
||||
item.setOnClickListener {
|
||||
input!!.text.insert(input!!.selectionStart, template.content + " ")
|
||||
}
|
||||
linearLayout.addView(item)
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showShortcuts() {
|
||||
lifecycleScope.launch {
|
||||
val bottomSheet = BottomSheetDialog(this@TerminalActivity)
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.template_shortcuts_list)
|
||||
|
||||
val chipGroup = bottomSheet.findViewById<ChipGroup>(R.id.shortcutsChipGroup)
|
||||
val shortcutList = withContext(Dispatchers.IO){
|
||||
commandTemplateViewModel.getAllShortcuts()
|
||||
}
|
||||
|
||||
chipGroup!!.removeAllViews()
|
||||
shortcutList.forEach {shortcut ->
|
||||
val chip = layoutInflater.inflate(R.layout.suggestion_chip, chipGroup, false) as Chip
|
||||
chip.text = shortcut.content
|
||||
chip.setOnClickListener {
|
||||
input!!.text.insert(input!!.selectionStart, shortcut.content + " ")
|
||||
}
|
||||
chipGroup.addView(chip)
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startDownload(command: String?) {
|
||||
val cmd = if (command!!.contains("yt-dlp")) command.replace("yt-dlp", "")
|
||||
|
|
@ -137,10 +237,10 @@ class TerminalActivity : AppCompatActivity() {
|
|||
}.absolutePath
|
||||
)
|
||||
|
||||
//request.addOption("-P", tempFileDir.absolutePath)
|
||||
|
||||
cancelFab!!.visibility = View.VISIBLE
|
||||
fab!!.visibility = View.GONE
|
||||
request.addOption("-P", tempFileDir.absolutePath)
|
||||
|
||||
showCancelFab()
|
||||
val disposable: Disposable = Observable.fromCallable {
|
||||
try{
|
||||
YoutubeDL.getInstance().execute(request, downloadID.toString()){ progress, _, line ->
|
||||
|
|
@ -167,8 +267,7 @@ class TerminalActivity : AppCompatActivity() {
|
|||
|
||||
input!!.visibility = View.VISIBLE
|
||||
|
||||
cancelFab!!.visibility = View.GONE
|
||||
fab!!.visibility = View.VISIBLE
|
||||
hideCancelFab()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,15 +280,7 @@ class TerminalActivity : AppCompatActivity() {
|
|||
input!!.setText("yt-dlp ")
|
||||
input!!.visibility = View.VISIBLE
|
||||
|
||||
cancelFab!!.visibility = View.GONE
|
||||
fab!!.visibility = View.VISIBLE
|
||||
|
||||
//move file from internal to set download directory
|
||||
try {
|
||||
moveFile(tempFileDir.absoluteFile, getString(R.string.command_path)){ }
|
||||
}catch (e: Exception){
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
hideCancelFab()
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}) { e ->
|
||||
e.printStackTrace()
|
||||
|
|
@ -198,32 +289,19 @@ class TerminalActivity : AppCompatActivity() {
|
|||
input!!.setText("yt-dlp ")
|
||||
input!!.visibility = View.VISIBLE
|
||||
|
||||
cancelFab!!.visibility = View.GONE
|
||||
fab!!.visibility = View.VISIBLE
|
||||
hideCancelFab();
|
||||
|
||||
tempFileDir.delete()
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
|
||||
Log.e(DownloadWorker.TAG, context?.getString(R.string.failed_download), e)
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}
|
||||
compositeDisposable.add(disposable)
|
||||
|
||||
}
|
||||
@Throws(Exception::class)
|
||||
private fun moveFile(originDir: File, downLocation: String, progress: (progress: Int) -> Unit){
|
||||
val fileUtil = FileUtil()
|
||||
fileUtil.moveFile(originDir, context!!, downLocation){ p ->
|
||||
progress(p)
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelDownload() {
|
||||
lifecycleScope.launch {
|
||||
compositeDisposable.dispose()
|
||||
YoutubeDL.getInstance().destroyProcessById(downloadID.toString())
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}
|
||||
YoutubeDL.getInstance().destroyProcessById(downloadID.toString())
|
||||
WorkManager.getInstance(this).cancelUniqueWork(downloadID.toString())
|
||||
notificationUtil.cancelDownloadNotification(downloadID)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -6,64 +6,6 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context="com.deniscerri.ytdlnis.ui.more.TerminalActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/custom_command_frame_layout"
|
||||
android:layout_width="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/custom_command_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="100dp"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_command_output"
|
||||
android:layout_width="match_parent"
|
||||
android:textIsSelectable="true"
|
||||
android:fontFamily="monospace"
|
||||
android:gravity="bottom"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/command_edittext"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:fontFamily="monospace"
|
||||
android:text="yt-dlp "
|
||||
android:textSize="13sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:gravity="start"
|
||||
android:maxLines="100" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -82,25 +24,90 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/command_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/run_command"
|
||||
app:icon="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
/>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/cancel_command_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/cancel_download"
|
||||
android:visibility="gone"
|
||||
app:icon="@drawable/ic_delete_all"
|
||||
/>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_command_frame_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/coordinatorLayout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/custom_command_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="100dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_command_output"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="monospace"
|
||||
android:gravity="bottom"
|
||||
android:textIsSelectable="true" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/command_edittext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:fontFamily="monospace"
|
||||
android:gravity="start"
|
||||
android:inputType="textMultiLine"
|
||||
android:maxLines="100"
|
||||
android:text="yt-dlp "
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/bottomAppBar"
|
||||
style="@style/Widget.Material3.BottomAppBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:menu="@menu/terminal_menu" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/command_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/run_command"
|
||||
app:icon="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
app:layout_anchor="@id/bottomAppBar" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
66
app/src/main/res/layout/command_template_list.xml
Normal file
66
app/src/main/res/layout/command_template_list.xml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="20dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/command_templates"
|
||||
android:textSize="25sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/select"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bottom_sheet_title" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:scrollbars="none"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/command_list_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
21
app/src/main/res/layout/dialog_terminate_app.xml
Normal file
21
app/src/main/res/layout/dialog_terminate_app.xml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="20dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/confirm_terminate"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/doNotShowAgain"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/dont_ask_again"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -26,6 +26,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/terminal"
|
||||
android:textStyle="bold"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:paddingHorizontal="15dp"
|
||||
android:paddingVertical="15dp"
|
||||
android:drawablePadding="35dp"
|
||||
|
|
@ -38,6 +41,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/logs"
|
||||
android:textStyle="bold"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:paddingHorizontal="15dp"
|
||||
android:paddingVertical="15dp"
|
||||
android:drawablePadding="35dp"
|
||||
|
|
@ -54,6 +60,9 @@
|
|||
android:paddingVertical="15dp"
|
||||
android:text="@string/command_templates"
|
||||
android:textStyle="bold"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:paddingHorizontal="15dp"
|
||||
app:drawableLeftCompat="@drawable/ic_baseline_keyboard_arrow_right_24" />
|
||||
|
||||
|
|
@ -66,6 +75,9 @@
|
|||
android:paddingVertical="15dp"
|
||||
android:text="@string/download_queue"
|
||||
android:textStyle="bold"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:paddingHorizontal="15dp"
|
||||
app:drawableLeftCompat="@drawable/ic_concurrent_downloads" />
|
||||
|
||||
|
|
@ -75,6 +87,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="35dp"
|
||||
android:textSize="16sp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:paddingVertical="15dp"
|
||||
android:text="@string/kill_app"
|
||||
android:textStyle="bold"
|
||||
|
|
@ -93,6 +108,9 @@
|
|||
android:paddingVertical="15dp"
|
||||
android:text="@string/settings"
|
||||
android:textStyle="bold"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:paddingHorizontal="15dp"
|
||||
app:drawableLeftCompat="@drawable/ic_settings" />
|
||||
|
||||
|
|
|
|||
74
app/src/main/res/layout/template_shortcuts_list.xml
Normal file
74
app/src/main/res/layout/template_shortcuts_list.xml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shortcuts"
|
||||
android:textSize="25sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shortcuts_desc"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bottom_sheet_title" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="15dp">
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/shortcutsChipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
app:chipSpacingVertical="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:singleLine="false">
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
14
app/src/main/res/menu/terminal_menu.xml
Normal file
14
app/src/main/res/menu/terminal_menu.xml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:theme="@style/AppDefaultTheme">
|
||||
|
||||
<item android:title="@string/command_templates"
|
||||
android:icon="@drawable/ic_terminal"
|
||||
app:showAsAction="ifRoom"
|
||||
android:id="@+id/command_templates"/>
|
||||
<item android:title="@string/shortcuts"
|
||||
android:icon="@drawable/ic_shortcut"
|
||||
app:showAsAction="ifRoom"
|
||||
android:id="@+id/shortcuts"/>
|
||||
</menu>
|
||||
|
|
@ -184,4 +184,6 @@
|
|||
<string name="restrict_filenames">Restrict Filenames</string>
|
||||
<string name="restrict_filenames_summary"><![CDATA[Restrict filenames to only ASCII characters, and avoid \"&\" and spaces in filenames]]></string>
|
||||
<string name="kill_app">Terminate App</string>
|
||||
<string name="confirm_terminate"><![CDATA[All downloads will be stopped & the app will be force closed]]></string>
|
||||
<string name="dont_ask_again">Don\'t ask again</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue