UI changes and hiding events

Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
sowjanyakch 2025-04-08 17:14:30 +02:00 committed by Marcel Hibbe
parent 83b8915787
commit fd47146729
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
10 changed files with 216 additions and 21 deletions

View File

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 13, "version": 13,
"identityHash": "a521f027909f69f4c7d1855f84a2e67f", "identityHash": "506abc931eb3b657cafe6ad1b25f635d",
"entities": [ "entities": [
{ {
"tableName": "User", "tableName": "User",
@ -138,7 +138,7 @@
}, },
{ {
"tableName": "Conversations", "tableName": "Conversations",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `objectId` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [ "fields": [
{ {
"fieldPath": "internalId", "fieldPath": "internalId",
@ -320,6 +320,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true "notNull": true
}, },
{
"fieldPath": "objectId",
"columnName": "objectId",
"affinity": "TEXT",
"notNull": true
},
{ {
"fieldPath": "participantType", "fieldPath": "participantType",
"columnName": "participantType", "columnName": "participantType",
@ -743,7 +749,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a521f027909f69f4c7d1855f84a2e67f')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '506abc931eb3b657cafe6ad1b25f635d')"
] ]
} }
} }

View File

@ -38,12 +38,14 @@ import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.AbsListView import android.widget.AbsListView
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.PopupMenu import android.widget.PopupMenu
import android.widget.PopupWindow
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
@ -51,6 +53,7 @@ import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.view.ContextThemeWrapper
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -82,6 +85,7 @@ import coil.request.CachePolicy
import coil.request.ImageRequest import coil.request.ImageRequest
import coil.target.Target import coil.target.Target
import coil.transform.CircleCropTransformation import coil.transform.CircleCropTransformation
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.nextcloud.android.common.ui.color.ColorUtil import com.nextcloud.android.common.ui.color.ColorUtil
import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.android.common.ui.theme.utils.ColorRole
@ -127,6 +131,7 @@ import com.nextcloud.talk.databinding.ActivityChatBinding
import com.nextcloud.talk.events.UserMentionClickEvent import com.nextcloud.talk.events.UserMentionClickEvent
import com.nextcloud.talk.events.WebSocketCommunicationEvent import com.nextcloud.talk.events.WebSocketCommunicationEvent
import com.nextcloud.talk.extensions.loadAvatarOrImagePreview import com.nextcloud.talk.extensions.loadAvatarOrImagePreview
import com.nextcloud.talk.jobs.DeleteConversationWorker
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.jobs.ShareOperationWorker import com.nextcloud.talk.jobs.ShareOperationWorker
import com.nextcloud.talk.jobs.UploadAndShareFilesWorker import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
@ -210,11 +215,14 @@ import java.io.File
import java.io.IOException import java.io.IOException
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.set
import kotlin.math.roundToInt import kotlin.math.roundToInt
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
@ -1892,7 +1900,7 @@ class ChatActivity :
} }
} }
private fun isEventConversation() { private fun isEventConversation() {
if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) {
if (eventConversationMenuItem != null) { if (eventConversationMenuItem != null) {
eventConversationMenuItem?.icon?.alpha = FULLY_OPAQUE_INT eventConversationMenuItem?.icon?.alpha = FULLY_OPAQUE_INT
@ -2870,10 +2878,11 @@ class ChatActivity :
setActionBarTitle() setActionBarTitle()
} }
if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) {
eventConversationMenuItem = menu.findItem(R.id.conversation_event_icon) eventConversationMenuItem = menu.findItem(R.id.conversation_event)
} else { } else {
menu.removeItem(R.id.conversation_event_icon) menu.removeItem(R.id.conversation_event)
} }
return true return true
} }
@ -2922,7 +2931,6 @@ class ChatActivity :
menu.removeItem(R.id.conversation_voice_call) menu.removeItem(R.id.conversation_voice_call)
} }
} }
return true return true
} }
@ -2953,9 +2961,139 @@ class ChatActivity :
true true
} }
R.id.conversation_event -> {
val anchorView = findViewById<View>(R.id.conversation_event)
showPopupWindow(anchorView)
true
}
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
private fun showPopupWindow(anchorView: View) {
val popupView = layoutInflater.inflate(R.layout.item_event_schedule, null)
val titleTextView = popupView.findViewById<TextView>(R.id.event_scheduled)
val subtitleTextView = popupView.findViewById<TextView>(R.id.meetingTime)
val deleteConversation = popupView.findViewById<TextView>(R.id.delete_conversation)
val popupWindow = PopupWindow(
popupView,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
true
)
popupWindow.isOutsideTouchable = true
popupWindow.isFocusable = true
popupWindow.showAsDropDown(anchorView, 0, -anchorView.height)
val meetingStatus = showEventSchedule()
titleTextView.text = "Scheduled"
subtitleTextView.text = meetingStatus
if (meetingStatus == "Meeting Ended" && currentConversation?.canDeleteConversation == true) {
deleteConversation.visibility = View.VISIBLE
deleteConversation.setOnClickListener {
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon(
viewThemeUtils.dialog
.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)
)
.setTitle(R.string.nc_delete_call)
.setMessage(R.string.nc_delete_conversation_more)
.setPositiveButton(R.string.nc_delete) { _, _ ->
currentConversation?.let { conversation ->
deleteConversation(conversation)
}
}
.setNegativeButton(R.string.nc_cancel) { _, _ ->
}
viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
)
}
} else {
deleteConversation.visibility = View.GONE
}
}
private fun deleteConversation(conversation: ConversationModel) {
val data = Data.Builder()
data.putLong(
KEY_INTERNAL_USER_ID,
conversationUser?.id!!
)
data.putString(KEY_ROOM_TOKEN, conversation.token)
val deleteConversationWorker =
OneTimeWorkRequest.Builder(DeleteConversationWorker::class.java).setInputData(data.build()).build()
WorkManager.getInstance().enqueue(deleteConversationWorker)
WorkManager.getInstance(context).getWorkInfoByIdLiveData(deleteConversationWorker.id)
.observeForever { workInfo: WorkInfo? ->
if (workInfo != null) {
when (workInfo.state) {
WorkInfo.State.SUCCEEDED -> {
val successMessage = String.format(
context.resources.getString(R.string.deleted_conversation),
conversation.displayName
)
Snackbar.make(binding.root, successMessage, Snackbar.LENGTH_LONG).show()
finish()
}
WorkInfo.State.FAILED -> {
val errorMessage = context.resources.getString(R.string.nc_common_error_sorry)
Snackbar.make(binding.root, errorMessage, Snackbar.LENGTH_LONG).show()
}
else -> {
}
}
}
}
}
private fun showEventSchedule(): String {
val objectId = currentConversation?.objectId ?: ""
val status = getMeetingSchedule(objectId)
return status
}
private fun getMeetingSchedule(objectId: String): String {
val timestamps = objectId.split("#")
if (timestamps.size != 2) return "Invalid Time"
val startEpoch = timestamps[0].toLong()
val endEpoch = timestamps[1].toLong()
val startDateTime = Instant.ofEpochSecond(startEpoch).atZone(ZoneId.systemDefault())
val endDateTime = Instant.ofEpochSecond(endEpoch).atZone(ZoneId.systemDefault())
val now = ZonedDateTime.now(ZoneId.systemDefault())
return when {
now.isBefore(startDateTime) -> {
val isToday = startDateTime.toLocalDate().isEqual(now.toLocalDate())
val isTomorrow = startDateTime.toLocalDate().isEqual(now.toLocalDate().plusDays(1))
when {
isToday -> "Today at ${startDateTime.format(DateTimeFormatter.ofPattern("HH:mm"))}"
isTomorrow -> "Tomorrow at ${startDateTime.format(DateTimeFormatter.ofPattern("HH:mm"))}"
else -> startDateTime.format(DateTimeFormatter.ofPattern("MMM d, yyyy, HH:mm"))
}
}
now.isAfter(endDateTime) -> "Meeting Ended"
else -> "Ongoing"
}
}
private fun showSharedItems() { private fun showSharedItems() {
val intent = Intent(this, SharedItemsActivity::class.java) val intent = Intent(this, SharedItemsActivity::class.java)
intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName) intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName)

View File

@ -185,6 +185,11 @@ class ConversationInfoEditActivity : BaseActivity() {
binding.conversationDescription.isEnabled = false binding.conversationDescription.isEnabled = false
} }
if (conversation?.objectType == ConversationEnums.ObjectType.EVENT) {
binding.conversationName.isEnabled = false
binding.conversationDescription.isEnabled = false
}
loadConversationAvatar() loadConversationAvatar()
} }
@ -266,6 +271,7 @@ class ConversationInfoEditActivity : BaseActivity() {
override fun onPrepareOptionsMenu(menu: Menu): Boolean { override fun onPrepareOptionsMenu(menu: Menu): Boolean {
super.onPrepareOptionsMenu(menu) super.onPrepareOptionsMenu(menu)
return true return true
} }

View File

@ -18,6 +18,7 @@ import com.nextcloud.talk.data.database.model.ConversationEntity
import com.nextcloud.talk.data.network.NetworkMonitor import com.nextcloud.talk.data.network.NetworkMonitor
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.models.json.conversations.ConversationEnums
import com.nextcloud.talk.utils.CapabilitiesUtil.isUserStatusAvailable import com.nextcloud.talk.utils.CapabilitiesUtil.isUserStatusAvailable
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import io.reactivex.Observer import io.reactivex.Observer
@ -121,7 +122,15 @@ class OfflineFirstConversationsRepository @Inject constructor(
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.blockingSingle() .blockingSingle()
conversationsFromSync = conversationsList.map { val currentTime = System.currentTimeMillis() / 1000
val conversationListWithoutEvents = conversationsList.filterNot { conversation ->
conversation.objectType == ConversationEnums.ObjectType.EVENT &&
conversation.objectId.split("#")[0].toLong() - currentTime >
AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS
}
conversationsFromSync = conversationListWithoutEvents.map {
it.asEntity(user.id!!) it.asEntity(user.id!!)
} }
@ -156,5 +165,6 @@ class OfflineFirstConversationsRepository @Inject constructor(
companion object { companion object {
val TAG = OfflineFirstConversationsRepository::class.simpleName val TAG = OfflineFirstConversationsRepository::class.simpleName
private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 86400
} }
} }

View File

@ -34,6 +34,7 @@ fun ConversationModel.asEntity() =
unreadMention = unreadMention, unreadMention = unreadMention,
lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) }, lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) },
objectType = objectType, objectType = objectType,
objectId = objectId,
notificationLevel = notificationLevel, notificationLevel = notificationLevel,
conversationReadOnlyState = conversationReadOnlyState, conversationReadOnlyState = conversationReadOnlyState,
lobbyState = lobbyState, lobbyState = lobbyState,
@ -85,6 +86,7 @@ fun ConversationEntity.asModel() =
lastMessage = lastMessage?.let lastMessage = lastMessage?.let
{ LoganSquare.parse(lastMessage, ChatMessageJson::class.java) }, { LoganSquare.parse(lastMessage, ChatMessageJson::class.java) },
objectType = objectType, objectType = objectType,
objectId = objectId,
notificationLevel = notificationLevel, notificationLevel = notificationLevel,
conversationReadOnlyState = conversationReadOnlyState, conversationReadOnlyState = conversationReadOnlyState,
lobbyState = lobbyState, lobbyState = lobbyState,
@ -135,6 +137,7 @@ fun Conversation.asEntity(accountId: Long) =
unreadMention = unreadMention, unreadMention = unreadMention,
lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) }, lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) },
objectType = objectType, objectType = objectType,
objectId = objectId,
notificationLevel = notificationLevel, notificationLevel = notificationLevel,
conversationReadOnlyState = conversationReadOnlyState, conversationReadOnlyState = conversationReadOnlyState,
lobbyState = lobbyState, lobbyState = lobbyState,

View File

@ -78,6 +78,7 @@ data class ConversationEntity(
@ColumnInfo(name = "notificationCalls") var notificationCalls: Int = 0, @ColumnInfo(name = "notificationCalls") var notificationCalls: Int = 0,
@ColumnInfo(name = "notificationLevel") var notificationLevel: ConversationEnums.NotificationLevel, @ColumnInfo(name = "notificationLevel") var notificationLevel: ConversationEnums.NotificationLevel,
@ColumnInfo(name = "objectType") var objectType: ConversationEnums.ObjectType, @ColumnInfo(name = "objectType") var objectType: ConversationEnums.ObjectType,
@ColumnInfo(name = "objectId") var objectId: String,
@ColumnInfo(name = "participantType") var participantType: Participant.ParticipantType, @ColumnInfo(name = "participantType") var participantType: Participant.ParticipantType,
@ColumnInfo(name = "permissions") var permissions: Int = 0, @ColumnInfo(name = "permissions") var permissions: Int = 0,
@ColumnInfo(name = "readOnly") var conversationReadOnlyState: ConversationEnums.ConversationReadOnlyState, @ColumnInfo(name = "readOnly") var conversationReadOnlyState: ConversationEnums.ConversationReadOnlyState,

View File

@ -89,6 +89,7 @@ class ConversationModel(
unreadMention = conversation.unreadMention, unreadMention = conversation.unreadMention,
lastMessage = conversation.lastMessage, lastMessage = conversation.lastMessage,
objectType = conversation.objectType.let { ConversationEnums.ObjectType.valueOf(it.name) }, objectType = conversation.objectType.let { ConversationEnums.ObjectType.valueOf(it.name) },
objectId = conversation.objectId,
notificationLevel = conversation.notificationLevel.let { notificationLevel = conversation.notificationLevel.let {
ConversationEnums.NotificationLevel.valueOf( ConversationEnums.NotificationLevel.valueOf(
it.name it.name

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud Talk - Android Client
~
~ SPDX-FileCopyrightText: 2025 Sowjanya Kota <sowjanya.kota@gmail.com>
~ SPDX-License-Identifier: GPL-3.0-or-later
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp"
android:background="@color/bg_bottom_sheet">
<TextView
android:id="@+id/event_scheduled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scheduled"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:id="@+id/meetingTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp"
android:text="Meeting at 8:00 pm"/>
<TextView
android:id="@+id/delete_conversation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete Conversation"
android:textColor="@android:color/holo_red_dark"
android:visibility = "gone"
android:paddingTop="16dp"/>
</LinearLayout>

View File

@ -9,23 +9,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/conversation_event_icon" android:id="@+id/conversation_event"
android:icon="@drawable/calendar_clock" android:icon="@drawable/calendar_clock"
android:orderInCategory="0" android:orderInCategory="0"
android:title="@string/nc_event_conversation_menu" android:title="@string/nc_event_conversation_menu"
app:showAsAction="ifRoom"> app:showAsAction="ifRoom">
<menu>
<item
android:id="@+id/action_option_one"
android:title="Scheduled event" />
<item
android:id="@+id/action_option_two"
android:title="@string/nc_delete_call"
android:icon = "@drawable/ic_delete"/>
</menu>
</item> </item>
<item <item

View File

@ -242,6 +242,7 @@ How to translate with transifex:
<string name="nc_rename">Rename conversation</string> <string name="nc_rename">Rename conversation</string>
<string name="nc_rename_confirm">Rename</string> <string name="nc_rename_confirm">Rename</string>
<string name="nc_delete_call">Delete conversation</string> <string name="nc_delete_call">Delete conversation</string>
<string name="nc_event_schedule">Schedule</string>
<string name="nc_delete">Delete</string> <string name="nc_delete">Delete</string>
<string name="nc_delete_all">Delete all</string> <string name="nc_delete_all">Delete all</string>
<string name="nc_delete_conversation_more">If you delete the conversation, it will also be deleted for all other participants.</string> <string name="nc_delete_conversation_more">If you delete the conversation, it will also be deleted for all other participants.</string>