added custom command and shortcuts buttons to terminal screen

pull/72/head
deniscerri 3 years ago
parent 506929b453
commit 467c0bd16e
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -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,29 +6,46 @@
android:layout_height="match_parent"
tools:context="com.deniscerri.ytdlnis.ui.more.TerminalActivity">
<FrameLayout
android:id="@+id/custom_command_frame_layout"
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true"
android:background="@android:color/transparent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/custom_command_toolbar"
android:elevation="0dp"
app:title="@string/terminal"
android:layout_width="match_parent"
app:navigationIcon="@drawable/ic_back"
android:layout_height="match_parent"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
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">
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/custom_command_frame_layout"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="wrap_content"
android:orientation="vertical">
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"
>
android:paddingBottom="100dp">
<LinearLayout
android:layout_width="match_parent"
@ -38,22 +55,22 @@
<TextView
android:id="@+id/custom_command_output"
android:layout_width="match_parent"
android:textIsSelectable="true"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:gravity="bottom"
android:layout_height="wrap_content" />
android:textIsSelectable="true" />
<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:background="@android:color/transparent"
android:fontFamily="monospace"
android:gravity="start"
android:maxLines="100" />
android:inputType="textMultiLine"
android:maxLines="100"
android:text="yt-dlp "
android:textSize="14sp" />
</LinearLayout>
@ -61,46 +78,36 @@
</LinearLayout>
</FrameLayout>
<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.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true"
android:background="@android:color/transparent"
android:fitsSystemWindows="true">
<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.appbar.MaterialToolbar
android:id="@+id/custom_command_toolbar"
android:elevation="0dp"
app:title="@string/terminal"
android:layout_width="match_parent"
app:navigationIcon="@drawable/ic_back"
android:layout_height="match_parent"/>
<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>
</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.coordinatorlayout.widget.CoordinatorLayout>

@ -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>

@ -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" />

@ -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>

@ -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…
Cancel
Save