diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index a5d456928..f39734eb4 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,16 +1,12 @@ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index a9c0c498c..7edadea9f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -366,11 +366,11 @@ android { compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "11" + jvmTarget = "17" } buildToolsVersion buildToolsVersion diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt index d39b69f29..821e30f6f 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt @@ -13,6 +13,11 @@ import android.view.Window import android.widget.Button import android.widget.ImageButton import android.widget.TextView +import android.view.Menu +import android.view.MenuItem +import android.widget.PopupMenu +import androidx.appcompat.app.AlertDialog + import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -59,6 +64,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import timber.log.Timber import java.io.File import java.lang.Integer.max import javax.inject.Inject @@ -147,6 +153,13 @@ class CustomSelectorActivity : private var showPartialAccessIndicator by mutableStateOf(false) + /** + * Show delete button on folder + */ + private var showOverflowMenu = false + + + /** * onCreate Activity, sets theme, initialises the view model, setup view. */ @@ -173,9 +186,9 @@ class CustomSelectorActivity : } }, modifier = - Modifier - .padding(vertical = 8.dp, horizontal = 4.dp) - .fillMaxWidth(), + Modifier + .padding(vertical = 8.dp, horizontal = 4.dp) + .fillMaxWidth(), ) } val view = binding.root @@ -204,6 +217,7 @@ class CustomSelectorActivity : } } + override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, @@ -414,7 +428,7 @@ class CustomSelectorActivity : } /** - * Set up the toolbar, back listener, done listener. + * Set up the toolbar, back listener, done listener, overflow menu listener. */ private fun setUpToolbar() { val back: ImageButton = findViewById(R.id.back) @@ -423,16 +437,72 @@ class CustomSelectorActivity : val limitError: ImageButton = findViewById(R.id.image_limit_error) limitError.visibility = View.INVISIBLE limitError.setOnClickListener { displayUploadLimitWarning() } + + val overflowMenu: ImageButton = findViewById(R.id.menu_overflow) + overflowMenu.visibility = if (showOverflowMenu) View.VISIBLE else View.INVISIBLE + + // Set up popup menu when overflow menu is clicked + overflowMenu.setOnClickListener { showPopupMenu(overflowMenu) } + } + private fun showPopupMenu(anchorView: View) { + val popupMenu = PopupMenu(this, anchorView) + popupMenu.menuInflater.inflate(R.menu.menu_custom_selector, popupMenu.menu) + + // Handle menu item clicks + popupMenu.setOnMenuItemClickListener { item -> + when (item.itemId) { + R.id.action_delete_folder -> { + deleteFolder() // Call the delete folder logic here + true + } + else -> false + } + } + popupMenu.show() + } + + private fun deleteFolder() { + Timber.tag("FolderAction").d("Delete folder action triggered") + + + // Run on UI thread to ensure dialog shows correctly + runOnUiThread { + val builder = AlertDialog.Builder(this) + builder.setTitle("Delete Folder") + builder.setMessage("Are you sure you want to delete this folder?") + + // Set the positive button to confirm deletion + builder.setPositiveButton("Delete") { dialog, _ -> + // Perform folder deletion here + Timber.tag("FolderAction").d("Folder deleted") + dialog.dismiss() + } + + // Set the negative button to cancel + builder.setNegativeButton("Cancel") { dialog, _ -> + Timber.tag("FolderAction").d("Delete action cancelled") + dialog.dismiss() // Dismiss the dialog + } + + // Show the AlertDialog + builder.create().show() + } + } + + + /** - * override on folder click, change the toolbar title on folder click. + * override on folder click, + * change the toolbar title on folder click, make overflow menu visible */ override fun onFolderClick( folderId: Long, folderName: String, - lastItemId: Long, + lastItemId: Long ) { + supportFragmentManager .beginTransaction() .add(R.id.fragment_container, ImageFragment.newInstance(folderId, lastItemId)) @@ -444,8 +514,14 @@ class CustomSelectorActivity : bucketId = folderId bucketName = folderName isImageFragmentOpen = true + + // Show the overflow menu only when a folder is clicked + showOverflowMenu = true + setUpToolbar() + } + /** * override Selected Images Change, update view model selected images and change UI. */ @@ -559,6 +635,10 @@ class CustomSelectorActivity : isImageFragmentOpen = false changeTitle(getString(R.string.custom_selector_title), 0) } + + //hide overflow menu when not in folder + showOverflowMenu = false + setUpToolbar() } /** @@ -616,9 +696,9 @@ fun partialStorageAccessIndicator( OutlinedCard( modifier = modifier, colors = - CardDefaults.cardColors( - containerColor = colorResource(R.color.primarySuperLightColor), - ), + CardDefaults.cardColors( + containerColor = colorResource(R.color.primarySuperLightColor), + ), border = BorderStroke(0.5.dp, color = colorResource(R.color.primaryColor)), shape = RoundedCornerShape(8.dp), ) { @@ -631,9 +711,9 @@ fun partialStorageAccessIndicator( onClick = onManage, modifier = Modifier.align(Alignment.Bottom), colors = - ButtonDefaults.buttonColors( - containerColor = colorResource(R.color.primaryColor), - ), + ButtonDefaults.buttonColors( + containerColor = colorResource(R.color.primaryColor), + ), shape = RoundedCornerShape(8.dp), ) { Text( @@ -655,9 +735,9 @@ fun partialStorageAccessIndicatorPreview() { isVisible = true, onManage = {}, modifier = - Modifier - .padding(vertical = 8.dp, horizontal = 4.dp) - .fillMaxWidth(), + Modifier + .padding(vertical = 8.dp, horizontal = 4.dp) + .fillMaxWidth(), ) } -} +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index 94e799aa2..b6b5b6d18 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -12,6 +12,7 @@ import android.net.Uri; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; +import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; @@ -58,6 +59,7 @@ import java.util.Locale; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; +import timber.log.Timber; public class SettingsFragment extends PreferenceFragmentCompat { @@ -80,6 +82,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { private ListPreference themeListPreference; private Preference descriptionLanguageListPreference; private Preference appUiLanguageListPreference; + private Preference showDeletionButtonPreference; private String keyLanguageListPreference; private TextView recentLanguagesTextView; private View separator; @@ -178,6 +181,18 @@ public class SettingsFragment extends PreferenceFragmentCompat { } }); + // + showDeletionButtonPreference = findPreference("displayDeletionButton"); + if (showDeletionButtonPreference != null) { + showDeletionButtonPreference.setOnPreferenceChangeListener((preference, newValue) -> { + boolean isEnabled = (boolean) newValue; + // Save preference when user toggles the button + defaultKvStore.putBoolean("displayDeletionButton", isEnabled); + return true; + }); + } + + Preference betaTesterPreference = findPreference("becomeBetaTester"); betaTesterPreference.setOnPreferenceClickListener(preference -> { Utils.handleWebUrl(getActivity(), Uri.parse(getResources().getString(R.string.beta_opt_in_link))); diff --git a/app/src/main/res/layout/custom_selector_toolbar.xml b/app/src/main/res/layout/custom_selector_toolbar.xml index f788561c8..8e6b5ce37 100644 --- a/app/src/main/res/layout/custom_selector_toolbar.xml +++ b/app/src/main/res/layout/custom_selector_toolbar.xml @@ -52,5 +52,20 @@ app:layout_constraintVertical_bias="1.0" app:srcCompat="@drawable/ic_error_red_24dp" /> + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_custom_selector.xml b/app/src/main/res/menu/menu_custom_selector.xml new file mode 100644 index 000000000..981c59469 --- /dev/null +++ b/app/src/main/res/menu/menu_custom_selector.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0c6be3129..014cc5a6e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -117,6 +117,7 @@ Search categories Search for items that your media depicts (mountain, Taj Mahal, etc.) Save + Overflow menu Refresh List (No uploads yet) @@ -831,4 +832,5 @@ Upload your first media by tapping on the add button. Pending Failed Could not load place data + Delete Folder diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 8ac890545..5d2dabb59 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -51,6 +51,13 @@ android:summary="@string/display_campaigns_explanation" android:title="@string/display_campaigns" /> + +