Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
newhinton committed Feb 9, 2025
2 parents 32130f1 + 119b97c commit 0275673
Show file tree
Hide file tree
Showing 26 changed files with 1,061 additions and 52 deletions.
8 changes: 7 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,13 @@
<activity
android:name=".Activities.TriggerActivity"
android:label="@string/title_activity_trigger"
android:theme="@style/AppTheme.NoActionBar" /> <!-- Auto Language Generation -->
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".Activities.FilterActivity"
android:label="@string/title_activity_filter"
android:theme="@style/AppTheme.NoActionBar" />

<!-- Auto Language Generation -->
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
Expand Down
141 changes: 141 additions & 0 deletions app/src/main/java/ca/pkay/rcloneexplorer/Activities/FilterActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package ca.pkay.rcloneexplorer.Activities

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.view.size
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import ca.pkay.rcloneexplorer.Database.DatabaseHandler
import ca.pkay.rcloneexplorer.Items.Filter
import ca.pkay.rcloneexplorer.Items.FilterEntry
import ca.pkay.rcloneexplorer.R
import ca.pkay.rcloneexplorer.Rclone
import ca.pkay.rcloneexplorer.RecyclerViewAdapters.FilterEntryRecyclerViewAdapter
import ca.pkay.rcloneexplorer.util.ActivityHelper
import com.google.android.material.floatingactionbutton.FloatingActionButton
import es.dmoral.toasty.Toasty
import jp.wasabeef.recyclerview.animators.LandingAnimator

class FilterActivity : AppCompatActivity() {

private lateinit var dbHandler: DatabaseHandler

private lateinit var filterTitle: EditText
private lateinit var filterList: RecyclerView

private var existingFilter: Filter? = null
private var filters: ArrayList<FilterEntry> = arrayListOf()


companion object {
const val ID_EXTRA = "FILTER_EDIT_ID"
const val SAVED_FILTER_ID_EXTRA = "filterId"
}


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ActivityHelper.applyTheme(this)
setContentView(R.layout.activity_filter)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val actionBar = supportActionBar
actionBar?.setDisplayHomeAsUpEnabled(true)

filterTitle = findViewById(R.id.filter_title_textfield)
filterList = findViewById(R.id.filter_filterlist)
val newFilterEntry = findViewById<Button>(R.id.filter_add_filterentry_button)
newFilterEntry.setOnClickListener {
filters.add(FilterEntry(FilterEntry.FILTER_EXCLUDE, ""))
filterList.adapter?.notifyItemInserted(filterList.size)
}


dbHandler = DatabaseHandler(this)
val extras = intent.extras
val filterId: Long
if (extras != null) {
filterId = extras.getLong(ID_EXTRA)
if (filterId != 0L) {
existingFilter = dbHandler.getFilter(filterId)
if (existingFilter == null) {
Toasty.error(
this,
this.resources.getString(R.string.filteractivity_filter_not_found)
).show()
finish()
}
}
}
val fab = findViewById<FloatingActionButton>(R.id.saveButton)
fab.setOnClickListener {
if (existingFilter == null) {
saveFilter()
} else {
persistFilterChanges()
}
}

if(existingFilter != null) {
filters = existingFilter!!.getFilters()
}
filterTitle.setText(existingFilter?.title)
prepareFilterList()
}

override fun onSupportNavigateUp(): Boolean {
finish()
return true
}

private fun persistFilterChanges() {
val updatedFilter = getFilterValues(existingFilter!!.id)
if (updatedFilter != null) {
dbHandler.updateFilter(updatedFilter)
val resultIntent = Intent()
resultIntent.putExtra(SAVED_FILTER_ID_EXTRA, updatedFilter.id)
setResult(Activity.RESULT_OK, resultIntent)
finish()
}
}

private fun saveFilter() {
val newFilter = getFilterValues(0)
if (newFilter != null) {
val filter = dbHandler.createFilter(newFilter)
val resultIntent = Intent()
resultIntent.putExtra(SAVED_FILTER_ID_EXTRA, filter.id)
setResult(Activity.RESULT_OK, resultIntent)
finish()
}
}

private fun getFilterValues(id: Long): Filter? {
val filterToPopulate = Filter(id)
filterToPopulate.title = filterTitle.text.toString()
filterToPopulate.setFilters(filters)
if (filterTitle.text.toString() == "") {
Toasty.error(
this.applicationContext,
getString(R.string.filter_data_validation_error_no_title),
Toast.LENGTH_SHORT,
true
).show()
return null
}
return filterToPopulate
}

private fun prepareFilterList() {
val adapter = FilterEntryRecyclerViewAdapter(filters, this)
filterList.layoutManager = LinearLayoutManager(this)
filterList.itemAnimator = LandingAnimator()
filterList.adapter = adapter
}
}
135 changes: 132 additions & 3 deletions app/src/main/java/ca/pkay/rcloneexplorer/Activities/TaskActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,39 @@ package ca.pkay.rcloneexplorer.Activities
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.widget.*
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.EditText
import android.widget.ImageButton
import android.widget.Spinner
import android.widget.Switch
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import ca.pkay.rcloneexplorer.Database.DatabaseHandler
import ca.pkay.rcloneexplorer.FilePicker
import ca.pkay.rcloneexplorer.Fragments.FolderSelectorCallback
import ca.pkay.rcloneexplorer.Fragments.RemoteFolderPickerFragment
import ca.pkay.rcloneexplorer.Items.Filter
import ca.pkay.rcloneexplorer.Items.RemoteItem
import ca.pkay.rcloneexplorer.Items.SyncDirectionObject
import ca.pkay.rcloneexplorer.Items.Task
import ca.pkay.rcloneexplorer.R
import ca.pkay.rcloneexplorer.Rclone
import ca.pkay.rcloneexplorer.SpinnerAdapters.FilterSpinnerAdapter
import ca.pkay.rcloneexplorer.util.ActivityHelper
import com.google.android.material.floatingactionbutton.FloatingActionButton
import es.dmoral.toasty.Toasty
import java.io.UnsupportedEncodingException
import java.net.URLDecoder

class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
class TaskActivity : AppCompatActivity(), FolderSelectorCallback{


private lateinit var rcloneInstance: Rclone
Expand All @@ -40,8 +52,18 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
private lateinit var switchMD5sum: Switch


private lateinit var filterDropdown: Spinner
private lateinit var createNewFilterButton: Button
private lateinit var switchDeleteExcluded: Switch


private lateinit var filterOptionsButton: ImageButton


private var existingTask: Task? = null
private var remotePathHolder = ""
private var selectedFilter: Filter? = null



override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
Expand Down Expand Up @@ -77,6 +99,12 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
Toasty.error(this, "This Remote is not a RCX-Remote.").show()
}
}
REQUEST_CODE_FILTER -> if (data != null) {
val filterId = data.getLongExtra(FilterActivity.SAVED_FILTER_ID_EXTRA, -1)
if(filterId >= 0) {
selectFilter(filterId)
}
}
}
fab.visibility = View.VISIBLE
}
Expand All @@ -95,6 +123,8 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
remoteDropdown = findViewById(R.id.task_remote_spinner)
syncDirection = findViewById(R.id.task_direction_spinner)
syncDescription = findViewById(R.id.descriptionSyncDirection)
filterDropdown = findViewById(R.id.task_filter_spinner)
switchDeleteExcluded = findViewById(R.id.task_exclude_delete_toggle)
fab = findViewById(R.id.saveButton)
switchWifi = findViewById(R.id.task_wifionly)
switchMD5sum = findViewById(R.id.task_md5sum)
Expand Down Expand Up @@ -126,13 +156,24 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
}
}

filterOptionsButton = findViewById(R.id.task_edit_filter_options_button)
filterOptionsButton.setOnClickListener {
val filter = if(filterDropdown.selectedItemPosition > 0 && filterDropdown.selectedItemPosition < filterDropdown.count) filterItems[filterDropdown.selectedItemPosition - 1] else null
showFilterMenu(filterOptionsButton, filter)
}
createNewFilterButton = findViewById<Button>(R.id.task_edit_filter_add_button)
createNewFilterButton.setOnClickListener {
openFilterActivity()
}

findViewById<TextView>(R.id.task_title_textfield).text = existingTask?.title
switchWifi.isChecked = existingTask?.wifionly ?: false
switchMD5sum.isChecked = existingTask?.md5sum ?: false
switchDeleteExcluded.isChecked = existingTask?.deleteExcluded ?: false
prepareSyncDirectionDropdown()
prepareLocal()
prepareRemote()

prepareFilterDropdown()
}

private val remoteItems: Array<String?>
Expand All @@ -143,6 +184,10 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
}
return remotes
}
private val filterItems: List<Filter>
get() {
return dbHandler.allFilters
}


override fun onSupportNavigateUp(): Boolean {
Expand Down Expand Up @@ -183,6 +228,8 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {

taskToPopulate.wifionly = switchWifi.isChecked
taskToPopulate.md5sum = switchMD5sum.isChecked
taskToPopulate.deleteExcluded = switchDeleteExcluded.isChecked
taskToPopulate.filterId = if(filterDropdown.selectedItemPosition == 0) null else filterItems[filterDropdown.selectedItemPosition - 1].id

// Verify if data is completed
if (localPath.text.toString() == "") {
Expand Down Expand Up @@ -220,6 +267,15 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
remotePath.setText(remotePathHolder)
fab.visibility = View.VISIBLE
}
private fun selectFilter(filterId: Long) {
prepareFilterDropdown()

for ((i, filter) in filterItems.withIndex()) {
if (filter.id == filterId) {
filterDropdown.setSelection(i + 1)
}
}
}

private fun prepareLocal() {
existingTask.let {
Expand Down Expand Up @@ -271,6 +327,78 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
}
}
}
private fun prepareFilterDropdown() {
val filterList = filterItems.toMutableList()

if(filterList.isEmpty()) {
createNewFilterButton.visibility = View.VISIBLE
filterDropdown.visibility = View.INVISIBLE
}
else {
val titles = mutableListOf<String?>().apply {
add(getString(R.string.task_edit_filter_nofilter))
addAll(filterList.map { it.title })
}

val adapter = FilterSpinnerAdapter(this, android.R.layout.simple_spinner_dropdown_item, titles)
filterDropdown.adapter = adapter
createNewFilterButton.visibility = View.INVISIBLE
filterDropdown.visibility = View.VISIBLE

if (existingTask != null) {
for ((i, filter) in filterList.withIndex()) {
if (filter.id == existingTask!!.filterId) {
filterDropdown.setSelection(i + 1)
}
}
}

filterDropdown.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parentView: AdapterView<*>?, selectedItemView: View, position: Int, id: Long) {
selectedFilter = if (position > 0 && position < titles.size) filterItems[position - 1] else null
}
override fun onNothingSelected(parentView: AdapterView<*>?) {}
}
}
}

private fun showFilterMenu(view: View, filter: Filter?) {
val popupMenu = PopupMenu(this, view)
popupMenu.menuInflater.inflate(R.menu.filter_item_menu, popupMenu.menu)
val menu = popupMenu.menu
for (i in 0 until menu.size()) {
val menuItem = menu.getItem(i)
if (menuItem.itemId == R.id.action_edit_filter ||
menuItem.itemId == R.id.action_delete_filter) {
menuItem.isVisible = filter != null
}
}
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
when (item.itemId) {
R.id.action_create_new_filter -> {
openFilterActivity()
}
R.id.action_edit_filter -> {
openFilterActivity(filter)
}
R.id.action_delete_filter -> {
dbHandler.deleteFilter(filter!!.id)
filterDropdown.setSelection(0)
prepareFilterDropdown()
}
else -> return@setOnMenuItemClickListener false
}
true
}
popupMenu.show()
}
private fun openFilterActivity(filter: Filter? = null) {
val intent = Intent(this, FilterActivity::class.java)
if(filter != null) {
intent.putExtra(FilterActivity.ID_EXTRA, filter.id)
}
startActivityForResult(intent, REQUEST_CODE_FILTER)
}

private fun prepareSyncDirectionDropdown() {
val options = SyncDirectionObject.getOptionsArray(this)
Expand Down Expand Up @@ -313,6 +441,7 @@ class TaskActivity : AppCompatActivity(), FolderSelectorCallback {
const val ID_EXTRA = "TASK_EDIT_ID"
const val REQUEST_CODE_FP_LOCAL = 500
const val REQUEST_CODE_FP_REMOTE = 444
const val REQUEST_CODE_FILTER = 333

}
}
Loading

0 comments on commit 0275673

Please sign in to comment.