Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@

<!-- Message Forwarding -->
<activity
android:name=".ui.conversationlist.ForwardMessageActivity"
android:name=".ui.conversationpicker.host.forward.ForwardMessageActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="user"
android:label="@string/forward_message_activity_title"
android:theme="@style/BugleTheme.DialogActivity">
</activity>
android:theme="@style/Theme.Compose"
android:windowSoftInputMode="stateHidden|adjustResize" />

<!-- Entry point for handling remote input/actions. Currently, this is only used by Android
Wear to send voice replies. Since that uses PendingIntents, we don't need to export
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ internal class PickerTopAppBarTest {
inSelectionMode = inSelectionMode,
selectedCount = 1,
searchState = TextFieldState(initialText = searchText),
title = R.string.share_intent_activity_label,
searchHint = R.string.share_search_hint,
onNavigateBack = {},
onSearchOpen = {},
onSearchClose = {},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package com.android.messaging.domain.conversationpicker.usecase

import android.net.Uri
import com.android.messaging.data.conversation.model.draft.ConversationDraftAttachment
import com.android.messaging.datamodel.data.MessageData
import com.android.messaging.datamodel.data.MessagePartData
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
internal class BuildConversationDraftFromMessageImplTest {

private val buildConversationDraftFromMessage = BuildConversationDraftFromMessageImpl()

@Test
fun invoke_textSubjectAndMediaPart_mapsAllFields() {
val message = messageData(
text = "Forwarded body",
subject = "Forwarded subject",
parts = listOf(
mediaPart(
contentType = "image/jpeg",
uri = "content://media/1",
caption = "Caption",
),
),
)

val draft = buildConversationDraftFromMessage(message)

assertEquals("Forwarded body", draft.messageText)
assertEquals("Forwarded subject", draft.subjectText)
assertEquals(
listOf(
ConversationDraftAttachment(
contentType = "image/jpeg",
contentUri = "content://media/1",
captionText = "Caption",
),
),
draft.attachments,
)
}

@Test
fun invoke_mediaPartWithoutCaption_mapsToEmptyCaption() {
val message = messageData(
text = "Body",
subject = "",
parts = listOf(
mediaPart(
contentType = "image/png",
uri = "content://media/1",
caption = null,
),
),
)

val draft = buildConversationDraftFromMessage(message)

assertEquals("", draft.attachments.single().captionText)
}

@Test
fun invoke_nullSubject_mapsToEmptyString() {
val message = messageData(
text = "Body",
subject = null,
parts = emptyList(),
)

val draft = buildConversationDraftFromMessage(message)

assertEquals("", draft.subjectText)
}

@Test
fun invoke_nonMediaParts_areExcludedFromAttachments() {
val message = messageData(
text = "Body",
subject = "",
parts = listOf(
mediaPart(
contentType = "text/plain",
uri = "content://text/1",
caption = null,
),
mediaPart(
contentType = "image/png",
uri = "content://media/2",
caption = null,
),
),
)

val draft = buildConversationDraftFromMessage(message)

assertEquals(
listOf(
ConversationDraftAttachment(
contentType = "image/png",
contentUri = "content://media/2",
),
),
draft.attachments,
)
}

@Test
fun invoke_mediaPartWithoutUri_isExcludedFromAttachments() {
val partWithoutUri = mockk<MessagePartData> {
every { contentType } returns "image/jpeg"
every { contentUri } returns null
}

val message = messageData(
text = "Body",
subject = "",
parts = listOf(partWithoutUri),
)

val draft = buildConversationDraftFromMessage(message)

assertEquals(emptyList<ConversationDraftAttachment>(), draft.attachments)
}

@Test
fun invoke_noParts_producesEmptyAttachments() {
val message = messageData(
text = "",
subject = "",
parts = emptyList(),
)

val draft = buildConversationDraftFromMessage(message)

assertEquals(emptyList<ConversationDraftAttachment>(), draft.attachments)
}

private fun messageData(
text: String,
subject: String?,
parts: List<MessagePartData>,
): MessageData {
return mockk {
every { messageText } returns text
every { mmsSubject } returns subject
every { this@mockk.parts } returns parts
}
}

private fun mediaPart(
contentType: String,
uri: String,
caption: String?,
): MessagePartData {
return mockk {
every { this@mockk.contentType } returns contentType
every { contentUri } returns Uri.parse(uri)
every { text } returns caption
}
}
}
4 changes: 4 additions & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@
<string name="vcard_detail_notes_label">Notes</string>
<!-- Title for the message forwarding dialog -->
<string name="forward_message_activity_title">Forward message</string>
<!-- Text shown when no contacts are available to forward a message to -->
<string name="forward_picker_empty_text">Enter a contact name or phone number to forward to</string>
<!-- Title for the message reply dialog -->
<string name="reply_activity_title">Reply</string>

Expand Down Expand Up @@ -1074,6 +1076,8 @@
<string name="widget_new_message_content_description">New message</string>
<!-- Content description for conversation list button in desktop widget -->
<string name="widget_conversation_list_content_description">Conversation list</string>
<!-- Text shown when no contacts are available while picking a conversation for the widget -->
<string name="widget_picker_empty_text">Enter a contact name or phone number to pick a conversation</string>
<!-- Shown when loading conversations in the widget -->
<string name="loading_conversations">Loading conversations</string>
<!-- Shown when loading messages in the widget -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.android.messaging.di.conversationpicker

import com.android.messaging.data.conversationpicker.repository.TargetsRepository
import com.android.messaging.data.conversationpicker.repository.TargetsRepositoryImpl
import com.android.messaging.domain.conversationpicker.usecase.BuildConversationDraftFromMessage
import com.android.messaging.domain.conversationpicker.usecase.BuildConversationDraftFromMessageImpl
import com.android.messaging.domain.conversationpicker.usecase.BuildMessageDataFromDraft
import com.android.messaging.domain.conversationpicker.usecase.BuildMessageDataFromDraftImpl
import com.android.messaging.domain.conversationpicker.usecase.ResolveTargetsToConversationIds
Expand Down Expand Up @@ -42,6 +44,12 @@ internal abstract class ConversationPickerBindsModule {
impl: TargetsRepositoryImpl,
): TargetsRepository

@Binds
@Reusable
abstract fun bindBuildConversationDraftFromMessage(
impl: BuildConversationDraftFromMessageImpl,
): BuildConversationDraftFromMessage

@Binds
@Reusable
abstract fun bindBuildMessageDataFromDraft(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.android.messaging.domain.conversationpicker.usecase

import com.android.messaging.data.conversation.model.draft.ConversationDraft
import com.android.messaging.data.conversation.model.draft.ConversationDraftAttachment
import com.android.messaging.datamodel.data.MessageData
import com.android.messaging.util.ContentType
import javax.inject.Inject
import kotlinx.collections.immutable.toImmutableList

internal interface BuildConversationDraftFromMessage {
operator fun invoke(message: MessageData): ConversationDraft
}

internal class BuildConversationDraftFromMessageImpl @Inject constructor() :
BuildConversationDraftFromMessage {

override fun invoke(message: MessageData): ConversationDraft {
val attachments = message.parts
.filter { part ->
ContentType.isMediaType(part.contentType) && part.contentUri != null
}
.map { part ->
ConversationDraftAttachment(
contentType = part.contentType,
contentUri = part.contentUri.toString(),
captionText = part.text.orEmpty(),
)
}
.toImmutableList()

return ConversationDraft(
messageText = message.messageText,
subjectText = message.mmsSubject.orEmpty(),
attachments = attachments,
)
}
}
2 changes: 1 addition & 1 deletion src/com/android/messaging/ui/UIIntentsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
import com.android.messaging.ui.conversation.LaunchConversationActivity;
import com.android.messaging.ui.conversationlist.ArchivedConversationListActivity;
import com.android.messaging.ui.conversationlist.ConversationListActivity;
import com.android.messaging.ui.conversationlist.ForwardMessageActivity;
import com.android.messaging.ui.conversationpicker.host.forward.ForwardMessageActivity;
import com.android.messaging.ui.conversationsettings.ConversationSettingsActivity;
import com.android.messaging.ui.debug.DebugMmsConfigActivity;
import com.android.messaging.ui.permissioncheck.PermissionCheckActivity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import com.android.messaging.R
import com.android.messaging.ui.conversation.preview.previewSimSelectorUiState
import com.android.messaging.ui.conversation.recipientpicker.component.simselector.NewChatSimSelectorRow
import com.android.messaging.ui.core.MessagingPreviewTheme
Expand Down Expand Up @@ -232,6 +233,7 @@ private fun RecipientSelectionArmedContactsArea(
onRecipientDestinationClick = onRecipientDestinationClickWrapped,
onRecipientDestinationLongClick = onRecipientDestinationLongClickWrapped
.takeIf { onRecipientDestinationLongClick != null },
emptyStateText = R.string.contact_list_empty_text,
topListContent = topListContent,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,11 @@
public class ConversationListFragment extends Fragment implements ConversationListDataListener,
ConversationListItemView.HostInterface {
private static final String BUNDLE_ARCHIVED_MODE = "archived_mode";
private static final String BUNDLE_FORWARD_MESSAGE_MODE = "forward_message_mode";
private static final boolean VERBOSE = false;

private MenuItem mShowBlockedMenuItem;
private boolean mArchiveMode;
private boolean mBlockedAvailable;
private boolean mForwardMessageMode;

public interface ConversationListFragmentHost {
public void onConversationClick(final ConversationListData listData,
Expand Down Expand Up @@ -108,10 +106,6 @@ public static ConversationListFragment createArchivedConversationListFragment()
return createConversationListFragment(BUNDLE_ARCHIVED_MODE);
}

public static ConversationListFragment createForwardMessageConversationListFragment() {
return createConversationListFragment(BUNDLE_FORWARD_MESSAGE_MODE);
}

public static ConversationListFragment createConversationListFragment(String modeKeyName) {
final ConversationListFragment fragment = new ConversationListFragment();
final Bundle bundle = new Bundle();
Expand Down Expand Up @@ -142,7 +136,6 @@ public void onResume() {

public void setScrolledToNewestConversationIfNeeded() {
if (!mArchiveMode
&& !mForwardMessageMode
&& isScrolledToFirstConversation()
&& mHost.hasWindowFocus()) {
mListBinding.getData().setScrolledToNewestConversation(true);
Expand Down Expand Up @@ -253,7 +246,6 @@ public void onAttach(final Activity activity) {
final Bundle arguments = getArguments();
if (arguments != null) {
mArchiveMode = arguments.getBoolean(BUNDLE_ARCHIVED_MODE, false);
mForwardMessageMode = arguments.getBoolean(BUNDLE_FORWARD_MESSAGE_MODE, false);
}
mListBinding.bind(DataModel.get().createConversationListData(activity, this, mArchiveMode));
}
Expand Down
Loading