mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-26 03:40:56 +01:00
Add context menus to chat folders.
This commit is contained in:
committed by
Greyson Parrelli
parent
6b66e4666b
commit
bfa5703aaa
@@ -11,6 +11,7 @@ import org.signal.donations.InAppPaymentType
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.chats.folders.CreateFoldersFragmentArgs
|
||||
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.EditNotificationProfileScheduleFragmentArgs
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentComponent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.StripeRepository
|
||||
@@ -68,6 +69,10 @@ class AppSettingsActivity : DSLSettingsActivity(), InAppPaymentComponent {
|
||||
StartLocation.USERNAME_LINK -> AppSettingsFragmentDirections.actionDirectToUsernameLinkSettings()
|
||||
StartLocation.RECOVER_USERNAME -> AppSettingsFragmentDirections.actionDirectToUsernameRecovery()
|
||||
StartLocation.REMOTE_BACKUPS -> AppSettingsFragmentDirections.actionDirectToRemoteBackupsSettingsFragment()
|
||||
StartLocation.CHAT_FOLDERS -> AppSettingsFragmentDirections.actionDirectToChatFoldersFragment()
|
||||
StartLocation.CREATE_CHAT_FOLDER -> AppSettingsFragmentDirections.actionDirectToCreateFoldersFragment(
|
||||
CreateFoldersFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).folderId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +203,18 @@ class AppSettingsActivity : DSLSettingsActivity(), InAppPaymentComponent {
|
||||
@JvmStatic
|
||||
fun remoteBackups(context: Context): Intent = getIntentForStartLocation(context, StartLocation.REMOTE_BACKUPS)
|
||||
|
||||
@JvmStatic
|
||||
fun chatFolders(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CHAT_FOLDERS)
|
||||
|
||||
@JvmStatic
|
||||
fun createChatFolder(context: Context, id: Long = -1): Intent {
|
||||
val arguments = CreateFoldersFragmentArgs.Builder(id)
|
||||
.build()
|
||||
.toBundle()
|
||||
|
||||
return getIntentForStartLocation(context, StartLocation.CREATE_CHAT_FOLDER).putExtra(START_ARGUMENTS, arguments)
|
||||
}
|
||||
|
||||
private fun getIntentForStartLocation(context: Context, startLocation: StartLocation): Intent {
|
||||
return Intent(context, AppSettingsActivity::class.java)
|
||||
.putExtra(ARG_NAV_GRAPH, R.navigation.app_settings_with_change_number)
|
||||
@@ -222,7 +239,9 @@ class AppSettingsActivity : DSLSettingsActivity(), InAppPaymentComponent {
|
||||
LINKED_DEVICES(13),
|
||||
USERNAME_LINK(14),
|
||||
RECOVER_USERNAME(15),
|
||||
REMOTE_BACKUPS(16);
|
||||
REMOTE_BACKUPS(16),
|
||||
CHAT_FOLDERS(17),
|
||||
CREATE_CHAT_FOLDER(18);
|
||||
|
||||
companion object {
|
||||
fun fromCode(code: Int?): StartLocation {
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.chats.folders
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import org.signal.core.util.DimensionUnit
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.menu.ActionItem
|
||||
import org.thoughtcrime.securesms.components.menu.SignalContextMenu
|
||||
|
||||
/**
|
||||
* A context menu shown when long pressing on a chat folder.
|
||||
*/
|
||||
object ChatFolderContextMenu {
|
||||
|
||||
fun show(
|
||||
context: Context,
|
||||
anchorView: View,
|
||||
rootView: ViewGroup = anchorView.rootView as ViewGroup,
|
||||
folderType: ChatFolderRecord.FolderType,
|
||||
onEdit: () -> Unit = {},
|
||||
onAdd: () -> Unit = {},
|
||||
onMuteAll: () -> Unit = {},
|
||||
onReadAll: () -> Unit = {},
|
||||
onDelete: () -> Unit = {},
|
||||
onReorder: () -> Unit = {}
|
||||
) {
|
||||
show(
|
||||
context = context,
|
||||
anchorView = anchorView,
|
||||
rootView = rootView,
|
||||
folderType = folderType,
|
||||
callbacks = object : Callbacks {
|
||||
override fun onEdit() = onEdit()
|
||||
override fun onAdd() = onAdd()
|
||||
override fun onMuteAll() = onMuteAll()
|
||||
override fun onReadAll() = onReadAll()
|
||||
override fun onDelete() = onDelete()
|
||||
override fun onReorder() = onReorder()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun show(
|
||||
context: Context,
|
||||
anchorView: View,
|
||||
rootView: ViewGroup,
|
||||
folderType: ChatFolderRecord.FolderType,
|
||||
callbacks: Callbacks
|
||||
) {
|
||||
val actions = mutableListOf<ActionItem>().apply {
|
||||
if (folderType == ChatFolderRecord.FolderType.ALL) {
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_plus_24, context.getString(R.string.ChatFoldersFragment__add_new_folder)) {
|
||||
callbacks.onAdd()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_bell_slash_24, context.getString(R.string.ChatFoldersFragment__mute_all)) {
|
||||
callbacks.onMuteAll()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_chat_check, context.getString(R.string.ChatFoldersFragment__mark_all_read)) {
|
||||
callbacks.onReadAll()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_exchange_24, context.getString(R.string.ChatFoldersFragment__reorder_folder)) {
|
||||
callbacks.onReorder()
|
||||
}
|
||||
)
|
||||
} else {
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_edit_24, context.getString(R.string.ChatFoldersFragment__edit_folder)) {
|
||||
callbacks.onEdit()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_plus_24, context.getString(R.string.ChatFoldersFragment__add_new_folder)) {
|
||||
callbacks.onAdd()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_bell_slash_24, context.getString(R.string.ChatFoldersFragment__mute_all)) {
|
||||
callbacks.onMuteAll()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_chat_check, context.getString(R.string.ChatFoldersFragment__mark_all_read)) {
|
||||
callbacks.onReadAll()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_trash_24, context.getString(R.string.ChatFoldersFragment__delete_folder)) {
|
||||
callbacks.onDelete()
|
||||
}
|
||||
)
|
||||
add(
|
||||
ActionItem(R.drawable.symbol_exchange_24, context.getString(R.string.ChatFoldersFragment__reorder_folder)) {
|
||||
callbacks.onReorder()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SignalContextMenu.Builder(anchorView, rootView)
|
||||
.preferredHorizontalPosition(SignalContextMenu.HorizontalPosition.START)
|
||||
.preferredVerticalPosition(SignalContextMenu.VerticalPosition.BELOW)
|
||||
.offsetY(DimensionUnit.DP.toPixels(8f).toInt())
|
||||
.show(actions)
|
||||
}
|
||||
|
||||
private interface Callbacks {
|
||||
fun onEdit()
|
||||
fun onAdd()
|
||||
fun onMuteAll()
|
||||
fun onReadAll()
|
||||
fun onDelete()
|
||||
fun onReorder()
|
||||
}
|
||||
}
|
||||
@@ -77,8 +77,7 @@ class ChatFoldersFragment : ComposeFragment() {
|
||||
state = state,
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
onFolderClicked = {
|
||||
viewModel.setCurrentFolder(it)
|
||||
navController.safeNavigate(R.id.action_chatFoldersFragment_to_createFoldersFragment)
|
||||
navController.safeNavigate(ChatFoldersFragmentDirections.actionChatFoldersFragmentToCreateFoldersFragment(it.id))
|
||||
},
|
||||
onAdd = { folder ->
|
||||
Toast.makeText(requireContext(), getString(R.string.ChatFoldersFragment__folder_added, folder.name), Toast.LENGTH_SHORT).show()
|
||||
|
||||
@@ -40,4 +40,8 @@ object ChatFoldersRepository {
|
||||
fun updatePositions(folders: List<ChatFolderRecord>) {
|
||||
SignalDatabase.chatFolders.updatePositions(folders)
|
||||
}
|
||||
|
||||
fun getFolder(id: Long): ChatFolderRecord {
|
||||
return SignalDatabase.chatFolders.getChatFolder(id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,12 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
val suggestedFolders = getSuggestedFolders(context, folders)
|
||||
|
||||
internalState.update {
|
||||
it.copy(folders = folders, suggestedFolders = suggestedFolders)
|
||||
it.copy(
|
||||
folders = folders,
|
||||
suggestedFolders = suggestedFolders,
|
||||
currentFolder = ChatFolderRecord(),
|
||||
originalFolder = ChatFolderRecord()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,4 +315,13 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
originalFolder.excludedRecipients != currentFolder.excludedRecipients
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurrentFolderId(folderId: Long) {
|
||||
if (folderId != -1L) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val folder = ChatFoldersRepository.getFolder(folderId)
|
||||
setCurrentFolder(folder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -87,6 +88,12 @@ class CreateFoldersFragment : ComposeFragment() {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val isNewFolder = state.originalFolder.id == -1L
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
if (state.originalFolder == state.currentFolder) {
|
||||
viewModel.setCurrentFolderId(arguments?.getLong(KEY_FOLDER_ID) ?: -1)
|
||||
}
|
||||
}
|
||||
|
||||
Scaffolds.Settings(
|
||||
title = if (isNewFolder) stringResource(id = R.string.CreateFoldersFragment__create_a_folder) else stringResource(id = R.string.CreateFoldersFragment__edit_folder),
|
||||
onNavigationClick = {
|
||||
@@ -143,6 +150,10 @@ class CreateFoldersFragment : ComposeFragment() {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KEY_FOLDER_ID = "folder_id"
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
Reference in New Issue
Block a user