Forward & ephemeral messages feature
|
@ -27,10 +27,13 @@ import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import org.linphone.LinphoneManager;
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.activities.MainActivity;
|
import org.linphone.activities.MainActivity;
|
||||||
import org.linphone.contacts.ContactAddress;
|
import org.linphone.contacts.ContactAddress;
|
||||||
import org.linphone.core.Address;
|
import org.linphone.core.Address;
|
||||||
|
import org.linphone.core.ChatMessage;
|
||||||
|
import org.linphone.core.ChatRoom;
|
||||||
import org.linphone.core.Factory;
|
import org.linphone.core.Factory;
|
||||||
import org.linphone.core.tools.Log;
|
import org.linphone.core.tools.Log;
|
||||||
import org.linphone.utils.FileUtils;
|
import org.linphone.utils.FileUtils;
|
||||||
|
@ -39,6 +42,7 @@ public class ChatActivity extends MainActivity {
|
||||||
public static final String NAME = "Chat";
|
public static final String NAME = "Chat";
|
||||||
|
|
||||||
private String mSharedText, mSharedFiles;
|
private String mSharedText, mSharedFiles;
|
||||||
|
private ChatMessage mForwardMessage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -212,6 +216,18 @@ public class ChatActivity extends MainActivity {
|
||||||
mSharedFiles = null;
|
mSharedFiles = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mForwardMessage != null) {
|
||||||
|
Log.i("[Chat] Found message to forward");
|
||||||
|
ChatRoom room = LinphoneManager.getCore().getChatRoom(peerAddress, localAddress);
|
||||||
|
if (room != null) {
|
||||||
|
Log.i("[Chat] Found chat room in which to forward message");
|
||||||
|
ChatMessage message = room.createForwardMessage(mForwardMessage);
|
||||||
|
message.send();
|
||||||
|
mForwardMessage = null;
|
||||||
|
Log.i("[Chat] Message forwarded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChatMessagesFragment fragment = new ChatMessagesFragment();
|
ChatMessagesFragment fragment = new ChatMessagesFragment();
|
||||||
fragment.setArguments(extras);
|
fragment.setArguments(extras);
|
||||||
changeFragment(fragment, "Chat room", isChild);
|
changeFragment(fragment, "Chat room", isChild);
|
||||||
|
@ -302,4 +318,21 @@ public class ChatActivity extends MainActivity {
|
||||||
fragment.setArguments(extras);
|
fragment.setArguments(extras);
|
||||||
changeFragment(fragment, "Chat room group info", true);
|
changeFragment(fragment, "Chat room group info", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showChatRoomEphemeral(Address peerAddress) {
|
||||||
|
Bundle extras = new Bundle();
|
||||||
|
if (peerAddress != null) {
|
||||||
|
extras.putSerializable("RemoteSipUri", peerAddress.asStringUriOnly());
|
||||||
|
}
|
||||||
|
EphemeralFragment fragment = new EphemeralFragment();
|
||||||
|
fragment.setArguments(extras);
|
||||||
|
changeFragment(fragment, "Chat room ephemeral", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forwardMessage(ChatMessage message) {
|
||||||
|
Log.i("[Chat] Message forwarding enabled");
|
||||||
|
goBack();
|
||||||
|
mForwardMessage = message;
|
||||||
|
Toast.makeText(this, R.string.toast_choose_chat_room_for_sharing, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.CountDownTimer;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -81,6 +82,11 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
|
||||||
private final FlexboxLayout multiFileContents;
|
private final FlexboxLayout multiFileContents;
|
||||||
private final RelativeLayout singleFileContent;
|
private final RelativeLayout singleFileContent;
|
||||||
|
|
||||||
|
private final LinearLayout forwardLayout;
|
||||||
|
private final LinearLayout ephemeralLayout;
|
||||||
|
private final TextView ephemeralCountdown;
|
||||||
|
private CountDownTimer countDownTimer;
|
||||||
|
|
||||||
public final CheckBox delete;
|
public final CheckBox delete;
|
||||||
public boolean isEditionEnabled;
|
public boolean isEditionEnabled;
|
||||||
|
|
||||||
|
@ -117,6 +123,11 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
|
||||||
singleFileContent = view.findViewById(R.id.single_content);
|
singleFileContent = view.findViewById(R.id.single_content);
|
||||||
multiFileContents = view.findViewById(R.id.multi_content);
|
multiFileContents = view.findViewById(R.id.multi_content);
|
||||||
|
|
||||||
|
forwardLayout = view.findViewById(R.id.forward_layout);
|
||||||
|
ephemeralLayout = view.findViewById(R.id.ephemeral_layout);
|
||||||
|
ephemeralCountdown = view.findViewById(R.id.ephemeral_time);
|
||||||
|
countDownTimer = null;
|
||||||
|
|
||||||
delete = view.findViewById(R.id.delete_event);
|
delete = view.findViewById(R.id.delete_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +152,10 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
|
||||||
singleFileContent.setVisibility(View.GONE);
|
singleFileContent.setVisibility(View.GONE);
|
||||||
multiFileContents.setVisibility(View.GONE);
|
multiFileContents.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
forwardLayout.setVisibility(message.isForward() ? View.VISIBLE : View.GONE);
|
||||||
|
ephemeralLayout.setVisibility(message.isEphemeral() ? View.VISIBLE : View.GONE);
|
||||||
|
updateEphemeralTimer(message);
|
||||||
|
|
||||||
ChatMessage.State status = message.getState();
|
ChatMessage.State status = message.getState();
|
||||||
Address remoteSender = message.getFromAddress();
|
Address remoteSender = message.getFromAddress();
|
||||||
String displayName;
|
String displayName;
|
||||||
|
@ -411,4 +426,54 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
|
||||||
private void loadBitmap(String path, ImageView imageView) {
|
private void loadBitmap(String path, ImageView imageView) {
|
||||||
Glide.with(mContext).load(path).into(imageView);
|
Glide.with(mContext).load(path).into(imageView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateEphemeralTimer(ChatMessage message) {
|
||||||
|
if (!message.isEphemeral()) {
|
||||||
|
if (countDownTimer != null) {
|
||||||
|
countDownTimer.cancel();
|
||||||
|
countDownTimer = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.getEphemeralExpireTime() == 0) {
|
||||||
|
// This means the message hasn't been read by all participants yet, so the countdown
|
||||||
|
// hasn't started
|
||||||
|
// In this case we simply display the configured value for lifetime
|
||||||
|
ephemeralCountdown.setText(formatLifetime(message.getEphemeralLifetime()));
|
||||||
|
if (countDownTimer != null) {
|
||||||
|
countDownTimer.cancel();
|
||||||
|
countDownTimer = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Countdown has started, display remaining time
|
||||||
|
long remaining = message.getEphemeralExpireTime() - (System.currentTimeMillis() / 1000);
|
||||||
|
ephemeralCountdown.setText(formatLifetime(remaining));
|
||||||
|
|
||||||
|
if (countDownTimer == null) {
|
||||||
|
countDownTimer =
|
||||||
|
new CountDownTimer(remaining * 1000, 1000) {
|
||||||
|
@Override
|
||||||
|
public void onTick(long millisUntilFinished) {
|
||||||
|
ephemeralCountdown.setText(
|
||||||
|
formatLifetime(millisUntilFinished / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {}
|
||||||
|
};
|
||||||
|
countDownTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatLifetime(long seconds) {
|
||||||
|
long days = seconds / 86400;
|
||||||
|
if (days == 0) {
|
||||||
|
return String.format(
|
||||||
|
"%02d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, (seconds % 60));
|
||||||
|
} else {
|
||||||
|
return mContext.getResources().getQuantityString(R.plurals.days, (int) days, days);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,6 +214,30 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
|
||||||
holder.eventMessage.setText(
|
holder.eventMessage.setText(
|
||||||
mContext.getString(R.string.device_removed).replace("%s", displayName));
|
mContext.getString(R.string.device_removed).replace("%s", displayName));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ConferenceEphemeralMessageDisabled:
|
||||||
|
holder.eventLayout.setVisibility(View.VISIBLE);
|
||||||
|
holder.eventMessage.setText(
|
||||||
|
mContext.getString(R.string.chat_event_ephemeral_disabled));
|
||||||
|
break;
|
||||||
|
case ConferenceEphemeralMessageEnabled:
|
||||||
|
holder.eventLayout.setVisibility(View.VISIBLE);
|
||||||
|
holder.eventMessage.setText(
|
||||||
|
mContext.getString(R.string.chat_event_ephemeral_enabled)
|
||||||
|
.replace(
|
||||||
|
"%s",
|
||||||
|
formatEphemeralExpiration(
|
||||||
|
event.getEphemeralMessageLifetime())));
|
||||||
|
break;
|
||||||
|
case ConferenceEphemeralMessageLifetimeChanged:
|
||||||
|
holder.eventLayout.setVisibility(View.VISIBLE);
|
||||||
|
holder.eventMessage.setText(
|
||||||
|
mContext.getString(R.string.chat_event_ephemeral_lifetime_changed)
|
||||||
|
.replace(
|
||||||
|
"%s",
|
||||||
|
formatEphemeralExpiration(
|
||||||
|
event.getEphemeralMessageLifetime())));
|
||||||
|
break;
|
||||||
case ConferenceSecurityEvent:
|
case ConferenceSecurityEvent:
|
||||||
holder.securityEventLayout.setVisibility(View.VISIBLE);
|
holder.securityEventLayout.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
@ -255,6 +279,24 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatEphemeralExpiration(long duration) {
|
||||||
|
if (duration == 0) {
|
||||||
|
return mContext.getString(R.string.chat_room_ephemeral_message_disabled);
|
||||||
|
} else if (duration == 60) {
|
||||||
|
return mContext.getString(R.string.chat_room_ephemeral_message_one_minute);
|
||||||
|
} else if (duration == 3600) {
|
||||||
|
return mContext.getString(R.string.chat_room_ephemeral_message_one_hour);
|
||||||
|
} else if (duration == 86400) {
|
||||||
|
return mContext.getString(R.string.chat_room_ephemeral_message_one_day);
|
||||||
|
} else if (duration == 259200) {
|
||||||
|
return mContext.getString(R.string.chat_room_ephemeral_message_three_days);
|
||||||
|
} else if (duration == 604800) {
|
||||||
|
return mContext.getString(R.string.chat_room_ephemeral_message_one_week);
|
||||||
|
} else {
|
||||||
|
return "Unexpected duration";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return mHistory.size();
|
return mHistory.size();
|
||||||
|
@ -303,6 +345,14 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
|
||||||
notifyItemRemoved(i);
|
notifyItemRemoved(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFromHistory(EventLog eventLog) {
|
||||||
|
int index = mHistory.indexOf(eventLog);
|
||||||
|
if (index >= 0) {
|
||||||
|
removeItem(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void changeBackgroundDependingOnPreviousAndNextEvents(
|
private void changeBackgroundDependingOnPreviousAndNextEvents(
|
||||||
ChatMessage message, ChatMessageViewHolder holder, int position) {
|
ChatMessage message, ChatMessageViewHolder holder, int position) {
|
||||||
boolean hasPrevious = false, hasNext = false;
|
boolean hasPrevious = false, hasNext = false;
|
||||||
|
|
|
@ -50,6 +50,8 @@ import android.widget.CheckBox;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import androidx.appcompat.view.menu.MenuBuilder;
|
||||||
|
import androidx.appcompat.view.menu.MenuPopupHelper;
|
||||||
import androidx.core.view.inputmethod.InputConnectionCompat;
|
import androidx.core.view.inputmethod.InputConnectionCompat;
|
||||||
import androidx.core.view.inputmethod.InputContentInfoCompat;
|
import androidx.core.view.inputmethod.InputContentInfoCompat;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
@ -102,8 +104,8 @@ public class ChatMessagesFragment extends Fragment
|
||||||
|
|
||||||
private ImageView mCallButton;
|
private ImageView mCallButton;
|
||||||
private ImageView mBackToCallButton;
|
private ImageView mBackToCallButton;
|
||||||
private ImageView mGroupInfosButton;
|
private ImageView mPopupMenu;
|
||||||
private ImageView mAttachImageButton, mSendMessageButton;
|
private ImageView mAttachImageButton, mSendMessageButton, mSendEphemeralIcon;
|
||||||
private TextView mRoomLabel, mParticipantsLabel, mSipUriLabel, mRemoteComposing;
|
private TextView mRoomLabel, mParticipantsLabel, mSipUriLabel, mRemoteComposing;
|
||||||
private RichEditText mMessageTextToSend;
|
private RichEditText mMessageTextToSend;
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
|
@ -153,30 +155,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
boolean oneParticipantOneDevice = false;
|
goToDevices();
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
|
||||||
ParticipantDevice[] devices =
|
|
||||||
mChatRoom.getParticipants()[0].getDevices();
|
|
||||||
// Only start a call automatically if both ourselves and the remote
|
|
||||||
// have 1 device exactly, otherwise show devices list.
|
|
||||||
oneParticipantOneDevice =
|
|
||||||
devices.length == 1
|
|
||||||
&& mChatRoom.getMe().getDevices().length == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LinphonePreferences.instance().isLimeSecurityPopupEnabled()) {
|
|
||||||
showSecurityDialog(oneParticipantOneDevice);
|
|
||||||
} else {
|
|
||||||
if (oneParticipantOneDevice) {
|
|
||||||
ParticipantDevice device =
|
|
||||||
mChatRoom.getParticipants()[0].getDevices()[0];
|
|
||||||
LinphoneManager.getCallManager()
|
|
||||||
.inviteAddress(device.getAddress(), true);
|
|
||||||
} else {
|
|
||||||
((ChatActivity) getActivity())
|
|
||||||
.showDevices(mLocalSipAddress, mRemoteSipAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -210,35 +189,12 @@ public class ChatMessagesFragment extends Fragment
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mGroupInfosButton = view.findViewById(R.id.group_infos);
|
mPopupMenu = view.findViewById(R.id.menu);
|
||||||
mGroupInfosButton.setOnClickListener(
|
mPopupMenu.setOnClickListener(
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (mChatRoom == null) return;
|
showPopupMenu();
|
||||||
ArrayList<ContactAddress> participants = new ArrayList<>();
|
|
||||||
for (Participant p : mChatRoom.getParticipants()) {
|
|
||||||
Address a = p.getAddress();
|
|
||||||
LinphoneContact c =
|
|
||||||
ContactsManager.getInstance().findContactFromAddress(a);
|
|
||||||
if (c == null) {
|
|
||||||
c = new LinphoneContact();
|
|
||||||
String displayName = LinphoneUtils.getAddressDisplayName(a);
|
|
||||||
c.setFullName(displayName);
|
|
||||||
}
|
|
||||||
ContactAddress ca =
|
|
||||||
new ContactAddress(c, a.asString(), "", p.isAdmin());
|
|
||||||
participants.add(ca);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean encrypted =
|
|
||||||
mChatRoom.hasCapability(ChatRoomCapabilities.Encrypted.toInt());
|
|
||||||
((ChatActivity) getActivity())
|
|
||||||
.showChatRoomGroupInfo(
|
|
||||||
mRemoteSipAddress,
|
|
||||||
participants,
|
|
||||||
mChatRoom.getSubject(),
|
|
||||||
encrypted);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -265,8 +221,10 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mAttachImageButton.setVisibility(View.GONE);
|
mAttachImageButton.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSendEphemeralIcon = view.findViewById(R.id.send_ephemeral_message);
|
||||||
mSendMessageButton = view.findViewById(R.id.send_message);
|
mSendMessageButton = view.findViewById(R.id.send_message);
|
||||||
mSendMessageButton.setEnabled(false);
|
mSendMessageButton.setEnabled(false);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
mSendMessageButton.setOnClickListener(
|
mSendMessageButton.setOnClickListener(
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -287,6 +245,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mSendMessageButton.setEnabled(
|
mSendMessageButton.setEnabled(
|
||||||
mMessageTextToSend.getText().length() > 0
|
mMessageTextToSend.getText().length() > 0
|
||||||
|| mFilesUploadLayout.getChildCount() > 0);
|
|| mFilesUploadLayout.getChildCount() > 0);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
if (mChatRoom != null && mMessageTextToSend.getText().length() > 0) {
|
if (mChatRoom != null && mMessageTextToSend.getText().length() > 0) {
|
||||||
if (!getResources().getBoolean(R.bool.allow_multiple_images_and_text)) {
|
if (!getResources().getBoolean(R.bool.allow_multiple_images_and_text)) {
|
||||||
mAttachImageButton.setEnabled(false);
|
mAttachImageButton.setEnabled(false);
|
||||||
|
@ -511,14 +470,9 @@ public class ChatMessagesFragment extends Fragment
|
||||||
EventLog eventLog = (EventLog) obj;
|
EventLog eventLog = (EventLog) obj;
|
||||||
eventLog.deleteFromDatabase();
|
eventLog.deleteFromDatabase();
|
||||||
}
|
}
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
|
||||||
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter())
|
|
||||||
.refresh(mChatRoom.getHistoryMessageEvents(MESSAGES_PER_PAGE));
|
|
||||||
} else {
|
|
||||||
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter())
|
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter())
|
||||||
.refresh(mChatRoom.getHistoryEvents(MESSAGES_PER_PAGE));
|
.refresh(mChatRoom.getHistoryEvents(MESSAGES_PER_PAGE));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(
|
public void onCreateContextMenu(
|
||||||
|
@ -590,6 +544,10 @@ public class ChatMessagesFragment extends Fragment
|
||||||
((ChatActivity) getActivity()).showImdn(mLocalSipAddress, mRemoteSipAddress, messageId);
|
((ChatActivity) getActivity()).showImdn(mLocalSipAddress, mRemoteSipAddress, messageId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (item.getItemId() == R.id.forward) {
|
||||||
|
((ChatActivity) getActivity()).forwardMessage(message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (item.getItemId() == R.id.copy_text) {
|
if (item.getItemId() == R.id.copy_text) {
|
||||||
if (message.hasTextContent()) {
|
if (message.hasTextContent()) {
|
||||||
ClipboardManager clipboard =
|
ClipboardManager clipboard =
|
||||||
|
@ -636,27 +594,14 @@ public class ChatMessagesFragment extends Fragment
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int maxSize;
|
int maxSize = mChatRoom.getHistoryEventsSize();
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
|
||||||
maxSize = mChatRoom.getHistorySize();
|
|
||||||
} else {
|
|
||||||
maxSize = mChatRoom.getHistoryEventsSize();
|
|
||||||
}
|
|
||||||
if (totalItemsCount < maxSize) {
|
if (totalItemsCount < maxSize) {
|
||||||
int upperBound = totalItemsCount + MESSAGES_PER_PAGE;
|
int upperBound = totalItemsCount + MESSAGES_PER_PAGE;
|
||||||
if (upperBound > maxSize) {
|
if (upperBound > maxSize) {
|
||||||
upperBound = maxSize;
|
upperBound = maxSize;
|
||||||
}
|
}
|
||||||
EventLog[] newLogs;
|
EventLog[] newLogs;
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
newLogs = mChatRoom.getHistoryRangeEvents(totalItemsCount, upperBound);
|
||||||
newLogs =
|
|
||||||
mChatRoom.getHistoryRangeMessageEvents(
|
|
||||||
totalItemsCount, upperBound);
|
|
||||||
} else {
|
|
||||||
newLogs =
|
|
||||||
mChatRoom.getHistoryRangeEvents(
|
|
||||||
totalItemsCount, upperBound);
|
|
||||||
}
|
|
||||||
ArrayList<EventLog> logsList = new ArrayList<>(Arrays.asList(newLogs));
|
ArrayList<EventLog> logsList = new ArrayList<>(Arrays.asList(newLogs));
|
||||||
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter())
|
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter())
|
||||||
.addAllToHistory(logsList);
|
.addAllToHistory(logsList);
|
||||||
|
@ -722,6 +667,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mMessageTextToSend.setEnabled(false);
|
mMessageTextToSend.setEnabled(false);
|
||||||
mAttachImageButton.setEnabled(false);
|
mAttachImageButton.setEnabled(false);
|
||||||
mSendMessageButton.setEnabled(false);
|
mSendMessageButton.setEnabled(false);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getContactsForParticipants() {
|
private void getContactsForParticipants() {
|
||||||
|
@ -798,7 +744,15 @@ public class ChatMessagesFragment extends Fragment
|
||||||
|
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||||
mCallButton.setVisibility(View.VISIBLE);
|
mCallButton.setVisibility(View.VISIBLE);
|
||||||
mGroupInfosButton.setVisibility(View.GONE);
|
|
||||||
|
if (mChatRoom.hasCapability(ChatRoomCapabilities.Basic.toInt())) {
|
||||||
|
mPopupMenu.setVisibility(View.GONE);
|
||||||
|
mSelectionHelper.setEditButtonVisibility(true);
|
||||||
|
} else {
|
||||||
|
mPopupMenu.setVisibility(View.VISIBLE);
|
||||||
|
mSelectionHelper.setEditButtonVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
mParticipantsLabel.setVisibility(View.GONE);
|
mParticipantsLabel.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (mContext.getResources().getBoolean(R.bool.show_sip_uri_in_chat)) {
|
if (mContext.getResources().getBoolean(R.bool.show_sip_uri_in_chat)) {
|
||||||
|
@ -827,7 +781,8 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mSipUriLabel.setText(mRemoteParticipantAddress.asStringUriOnly());
|
mSipUriLabel.setText(mRemoteParticipantAddress.asStringUriOnly());
|
||||||
} else {
|
} else {
|
||||||
mCallButton.setVisibility(View.GONE);
|
mCallButton.setVisibility(View.GONE);
|
||||||
mGroupInfosButton.setVisibility(View.VISIBLE);
|
mPopupMenu.setVisibility(View.VISIBLE);
|
||||||
|
mSelectionHelper.setEditButtonVisibility(false);
|
||||||
mRoomLabel.setText(mChatRoom.getSubject());
|
mRoomLabel.setText(mChatRoom.getSubject());
|
||||||
mParticipantsLabel.setVisibility(View.VISIBLE);
|
mParticipantsLabel.setVisibility(View.VISIBLE);
|
||||||
mSipUriLabel.setVisibility(View.GONE);
|
mSipUriLabel.setVisibility(View.GONE);
|
||||||
|
@ -838,6 +793,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mBackToCallButton.setVisibility(View.VISIBLE);
|
mBackToCallButton.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSendEphemeralIcon.setVisibility(mChatRoom.ephemeralEnabled() ? View.VISIBLE : View.GONE);
|
||||||
if (mChatRoom.hasBeenLeft()) {
|
if (mChatRoom.hasBeenLeft()) {
|
||||||
setReadOnly();
|
setReadOnly();
|
||||||
}
|
}
|
||||||
|
@ -1044,6 +1000,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mSendMessageButton.setEnabled(
|
mSendMessageButton.setEnabled(
|
||||||
mMessageTextToSend.getText().length() > 0
|
mMessageTextToSend.getText().length() > 0
|
||||||
|| mFilesUploadLayout.getChildCount() > 0);
|
|| mFilesUploadLayout.getChildCount() > 0);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1054,6 +1011,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mMessageTextToSend.setEnabled(false);
|
mMessageTextToSend.setEnabled(false);
|
||||||
}
|
}
|
||||||
mSendMessageButton.setEnabled(true);
|
mSendMessageButton.setEnabled(true);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addImageToPendingList(String path) {
|
private void addImageToPendingList(String path) {
|
||||||
|
@ -1083,6 +1041,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mSendMessageButton.setEnabled(
|
mSendMessageButton.setEnabled(
|
||||||
mMessageTextToSend.getText().length() > 0
|
mMessageTextToSend.getText().length() > 0
|
||||||
|| mFilesUploadLayout.getChildCount() > 0);
|
|| mFilesUploadLayout.getChildCount() > 0);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1093,6 +1052,7 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mMessageTextToSend.setEnabled(false);
|
mMessageTextToSend.setEnabled(false);
|
||||||
}
|
}
|
||||||
mSendMessageButton.setEnabled(true);
|
mSendMessageButton.setEnabled(true);
|
||||||
|
mSendEphemeralIcon.setEnabled(mSendMessageButton.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Message sending */
|
/** Message sending */
|
||||||
|
@ -1160,6 +1120,97 @@ public class ChatMessagesFragment extends Fragment
|
||||||
mMessageTextToSend.setText("");
|
mMessageTextToSend.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPopupMenu() {
|
||||||
|
MenuBuilder builder = new MenuBuilder(getActivity());
|
||||||
|
MenuPopupHelper popupMenu = new MenuPopupHelper(getActivity(), builder, mPopupMenu);
|
||||||
|
popupMenu.setForceShowIcon(true);
|
||||||
|
|
||||||
|
new MenuInflater(getActivity()).inflate(R.menu.chat_room_menu, builder);
|
||||||
|
|
||||||
|
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||||
|
builder.removeItem(R.id.chat_room_group_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mChatRoom.hasCapability(ChatRoomCapabilities.Encrypted.toInt())) {
|
||||||
|
builder.removeItem(R.id.chat_room_participants_devices);
|
||||||
|
builder.removeItem(R.id.chat_room_ephemeral_messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setCallback(
|
||||||
|
new MenuBuilder.Callback() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.chat_room_group_info) {
|
||||||
|
goToGroupInfo();
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.chat_room_participants_devices) {
|
||||||
|
goToDevices();
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.chat_room_ephemeral_messages) {
|
||||||
|
goToEphemeral();
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.chat_room_delete_messages) {
|
||||||
|
mSelectionHelper.enterEditionMode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMenuModeChange(MenuBuilder menu) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
popupMenu.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void goToDevices() {
|
||||||
|
boolean oneParticipantOneDevice = false;
|
||||||
|
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||||
|
ParticipantDevice[] devices = mChatRoom.getParticipants()[0].getDevices();
|
||||||
|
// Only start a call automatically if both ourselves and the remote
|
||||||
|
// have 1 device exactly, otherwise show devices list.
|
||||||
|
oneParticipantOneDevice =
|
||||||
|
devices.length == 1 && mChatRoom.getMe().getDevices().length == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LinphonePreferences.instance().isLimeSecurityPopupEnabled()) {
|
||||||
|
showSecurityDialog(oneParticipantOneDevice);
|
||||||
|
} else {
|
||||||
|
if (oneParticipantOneDevice) {
|
||||||
|
ParticipantDevice device = mChatRoom.getParticipants()[0].getDevices()[0];
|
||||||
|
LinphoneManager.getCallManager().inviteAddress(device.getAddress(), true);
|
||||||
|
} else {
|
||||||
|
((ChatActivity) getActivity()).showDevices(mLocalSipAddress, mRemoteSipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void goToGroupInfo() {
|
||||||
|
if (mChatRoom == null) return;
|
||||||
|
ArrayList<ContactAddress> participants = new ArrayList<>();
|
||||||
|
for (Participant p : mChatRoom.getParticipants()) {
|
||||||
|
Address a = p.getAddress();
|
||||||
|
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(a);
|
||||||
|
if (c == null) {
|
||||||
|
c = new LinphoneContact();
|
||||||
|
String displayName = LinphoneUtils.getAddressDisplayName(a);
|
||||||
|
c.setFullName(displayName);
|
||||||
|
}
|
||||||
|
ContactAddress ca = new ContactAddress(c, a.asString(), "", p.isAdmin());
|
||||||
|
participants.add(ca);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean encrypted = mChatRoom.hasCapability(ChatRoomCapabilities.Encrypted.toInt());
|
||||||
|
((ChatActivity) getActivity())
|
||||||
|
.showChatRoomGroupInfo(
|
||||||
|
mRemoteSipAddress, participants, mChatRoom.getSubject(), encrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void goToEphemeral() {
|
||||||
|
if (mChatRoom == null) return;
|
||||||
|
((ChatActivity) getActivity()).showChatRoomEphemeral(mRemoteSipAddress);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Chat room callbacks
|
* Chat room callbacks
|
||||||
*/
|
*/
|
||||||
|
@ -1334,6 +1385,19 @@ public class ChatMessagesFragment extends Fragment
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEphemeralEvent(ChatRoom chatRoom, EventLog eventLog) {
|
||||||
|
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter()).addToHistory(eventLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEphemeralMessageTimerStarted(ChatRoom chatRoom, EventLog eventLog) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEphemeralMessageDeleted(ChatRoom chatRoom, EventLog eventLog) {
|
||||||
|
((ChatMessagesGenericAdapter) mChatEventsList.getAdapter()).removeFromHistory(eventLog);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onParticipantAdminStatusChanged(ChatRoom cr, EventLog event) {
|
public void onParticipantAdminStatusChanged(ChatRoom cr, EventLog event) {
|
||||||
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) return;
|
if (mChatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) return;
|
||||||
|
|
|
@ -37,4 +37,6 @@ interface ChatMessagesGenericAdapter {
|
||||||
Object getItem(int i);
|
Object getItem(int i);
|
||||||
|
|
||||||
void removeItem(int i);
|
void removeItem(int i);
|
||||||
|
|
||||||
|
void removeFromHistory(EventLog eventLog);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.linphone.chat;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
@ -45,6 +46,7 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder
|
||||||
public final TextView unreadMessages;
|
public final TextView unreadMessages;
|
||||||
public final CheckBox delete;
|
public final CheckBox delete;
|
||||||
private final RelativeLayout avatarLayout;
|
private final RelativeLayout avatarLayout;
|
||||||
|
public final ImageView ephemeral;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ClickListener mListener;
|
private final ClickListener mListener;
|
||||||
|
@ -59,6 +61,7 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder
|
||||||
unreadMessages = itemView.findViewById(R.id.unreadMessages);
|
unreadMessages = itemView.findViewById(R.id.unreadMessages);
|
||||||
delete = itemView.findViewById(R.id.delete_chatroom);
|
delete = itemView.findViewById(R.id.delete_chatroom);
|
||||||
avatarLayout = itemView.findViewById(R.id.avatar_layout);
|
avatarLayout = itemView.findViewById(R.id.avatar_layout);
|
||||||
|
ephemeral = itemView.findViewById(R.id.ephemeral);
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
|
|
||||||
itemView.setOnClickListener(this);
|
itemView.setOnClickListener(this);
|
||||||
|
@ -88,6 +91,7 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder
|
||||||
lastMessageView.setText("");
|
lastMessageView.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ephemeral.setVisibility(room.ephemeralEnabled() ? View.VISIBLE : View.GONE);
|
||||||
displayName.setText(getContact(room));
|
displayName.setText(getContact(room));
|
||||||
unreadMessages.setText(String.valueOf(room.getUnreadMessagesCount()));
|
unreadMessages.setText(String.valueOf(room.getUnreadMessagesCount()));
|
||||||
getAvatar(room);
|
getAvatar(room);
|
||||||
|
|
160
app/src/main/java/org/linphone/chat/EphemeralFragment.java
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2019 Belledonne Communications SARL.
|
||||||
|
*
|
||||||
|
* This file is part of linphone-android
|
||||||
|
* (see https://www.linphone.org).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.linphone.chat;
|
||||||
|
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import org.linphone.LinphoneManager;
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.core.Address;
|
||||||
|
import org.linphone.core.ChatRoom;
|
||||||
|
import org.linphone.core.Factory;
|
||||||
|
import org.linphone.core.tools.Log;
|
||||||
|
|
||||||
|
public class EphemeralFragment extends Fragment {
|
||||||
|
private ChatRoom mChatRoom;
|
||||||
|
private long mCurrentValue;
|
||||||
|
|
||||||
|
private LayoutInflater mInflater;
|
||||||
|
private ViewGroup mContainer;
|
||||||
|
private LinearLayout mItems;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(
|
||||||
|
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
View view = inflater.inflate(R.layout.chat_ephemeral, container, false);
|
||||||
|
mInflater = inflater;
|
||||||
|
mContainer = container;
|
||||||
|
|
||||||
|
if (getArguments() == null || getArguments().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String address = getArguments().getString("RemoteSipUri");
|
||||||
|
Address peerAddress = null;
|
||||||
|
mChatRoom = null;
|
||||||
|
if (address != null && address.length() > 0) {
|
||||||
|
peerAddress = Factory.instance().createAddress(address);
|
||||||
|
}
|
||||||
|
if (peerAddress != null) {
|
||||||
|
mChatRoom = LinphoneManager.getCore().getChatRoom(peerAddress);
|
||||||
|
}
|
||||||
|
if (mChatRoom == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
mCurrentValue = mChatRoom.ephemeralEnabled() ? mChatRoom.getEphemeralLifetime() : 0;
|
||||||
|
Log.i(
|
||||||
|
"[Ephemeral Messages] Current duration is ",
|
||||||
|
mCurrentValue,
|
||||||
|
", ephemeral enabled? ",
|
||||||
|
mChatRoom.ephemeralEnabled());
|
||||||
|
|
||||||
|
view.findViewById(R.id.back)
|
||||||
|
.setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
getFragmentManager().popBackStack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
view.findViewById(R.id.valid)
|
||||||
|
.setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Log.i("[Ephemeral Messages] Selected value is ", mCurrentValue);
|
||||||
|
if (mCurrentValue > 0) {
|
||||||
|
if (mChatRoom.getEphemeralLifetime() != mCurrentValue) {
|
||||||
|
Log.i(
|
||||||
|
"[Ephemeral Messages] Setting new lifetime for ephemeral messages to ",
|
||||||
|
mCurrentValue);
|
||||||
|
mChatRoom.setEphemeralLifetime(mCurrentValue);
|
||||||
|
} else {
|
||||||
|
Log.i(
|
||||||
|
"[Ephemeral Messages] Configured lifetime for ephemeral messages was already ",
|
||||||
|
mCurrentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mChatRoom.ephemeralEnabled()) {
|
||||||
|
Log.i(
|
||||||
|
"[Ephemeral Messages] Ephemeral messages were disabled, enable them");
|
||||||
|
mChatRoom.enableEphemeral(true);
|
||||||
|
}
|
||||||
|
} else if (mChatRoom.ephemeralEnabled()) {
|
||||||
|
Log.i(
|
||||||
|
"[Ephemeral Messages] Ephemeral messages were enabled, disable them");
|
||||||
|
mChatRoom.enableEphemeral(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFragmentManager().popBackStack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mItems = view.findViewById(R.id.items);
|
||||||
|
|
||||||
|
computeItems();
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View getView(int id, final long value) {
|
||||||
|
View view = mInflater.inflate(R.layout.chat_ephemeral_item, mContainer, false);
|
||||||
|
((TextView) view.findViewById(R.id.text)).setText(id);
|
||||||
|
((TextView) view.findViewById(R.id.text))
|
||||||
|
.setTextAppearance(
|
||||||
|
getActivity(),
|
||||||
|
mCurrentValue == value
|
||||||
|
? R.style.chat_room_ephemeral_selected_item_font
|
||||||
|
: R.style.chat_room_ephemeral_item_font);
|
||||||
|
view.findViewById(R.id.selected)
|
||||||
|
.setVisibility(mCurrentValue == value ? View.VISIBLE : View.GONE);
|
||||||
|
view.setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (mCurrentValue != value) {
|
||||||
|
mCurrentValue = value;
|
||||||
|
computeItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeItems() {
|
||||||
|
mItems.removeAllViews();
|
||||||
|
mItems.addView(getView(R.string.chat_room_ephemeral_message_disabled, 0));
|
||||||
|
mItems.addView(getView(R.string.chat_room_ephemeral_message_one_minute, 60));
|
||||||
|
mItems.addView(getView(R.string.chat_room_ephemeral_message_one_hour, 3600));
|
||||||
|
mItems.addView(getView(R.string.chat_room_ephemeral_message_one_day, 86400));
|
||||||
|
mItems.addView(getView(R.string.chat_room_ephemeral_message_three_days, 259200));
|
||||||
|
mItems.addView(getView(R.string.chat_room_ephemeral_message_one_week, 604800));
|
||||||
|
}
|
||||||
|
}
|
|
@ -187,6 +187,10 @@ public class SelectableHelper {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setEditButtonVisibility(boolean visible) {
|
||||||
|
mEditButton.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
public interface DeleteListener {
|
public interface DeleteListener {
|
||||||
void onDeleteSelection(Object[] objectsToDelete);
|
void onDeleteSelection(Object[] objectsToDelete);
|
||||||
}
|
}
|
||||||
|
|
BIN
app/src/main/res/drawable-xhdpi/ephemeral_messages_default.png
Normal file
After Width: | Height: | Size: 9 KiB |
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/forwarded_message_default.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/menu_delete_default.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/menu_group_info_default.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/menu_security_default.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/more_menu_default.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
7
app/src/main/res/drawable/chat_room_menu_delete.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<bitmap android:src="@drawable/menu_delete_default"
|
||||||
|
android:tint="?attr/drawableTintColor"/>
|
||||||
|
</item>
|
||||||
|
</selector>
|
7
app/src/main/res/drawable/chat_room_menu_ephemeral.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<bitmap android:src="@drawable/menu_ephemeral_messages_default"
|
||||||
|
android:tint="?attr/drawableTintColor"/>
|
||||||
|
</item>
|
||||||
|
</selector>
|
7
app/src/main/res/drawable/chat_room_menu_group_info.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<bitmap android:src="@drawable/menu_group_info_default"
|
||||||
|
android:tint="?attr/drawableTintColor"/>
|
||||||
|
</item>
|
||||||
|
</selector>
|
7
app/src/main/res/drawable/chat_room_menu_security.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<bitmap android:src="@drawable/menu_security_default"
|
||||||
|
android:tint="?attr/drawableTintColor"/>
|
||||||
|
</item>
|
||||||
|
</selector>
|
11
app/src/main/res/drawable/chat_send_ephemeral_message.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_enabled="false">
|
||||||
|
<bitmap android:src="@drawable/ephemeral_messages_small_default"
|
||||||
|
android:tint="?attr/drawableTintDisabledColor"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<bitmap android:src="@drawable/ephemeral_messages_small_default" />
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
|
15
app/src/main/res/drawable/menu_more.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<bitmap android:src="@drawable/more_menu_default"
|
||||||
|
android:tint="?attr/drawableTintOverColor"/>
|
||||||
|
</item>
|
||||||
|
<item android:state_enabled="false">
|
||||||
|
<bitmap android:src="@drawable/more_menu_default"
|
||||||
|
android:tint="?attr/drawableTintDisabledColor"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<bitmap android:src="@drawable/more_menu_default"
|
||||||
|
android:tint="?attr/drawableTintColor"/>
|
||||||
|
</item>
|
||||||
|
</selector>
|
|
@ -79,17 +79,17 @@
|
||||||
android:src="@drawable/call_alt_start" />
|
android:src="@drawable/call_alt_start" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/group_infos"
|
android:id="@+id/menu"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="0.2"
|
android:layout_weight="0.2"
|
||||||
android:background="?attr/button_background_drawable"
|
android:background="?attr/button_background_drawable"
|
||||||
android:contentDescription="@string/content_description_conversation_infos"
|
|
||||||
android:padding="15dp"
|
android:padding="15dp"
|
||||||
android:src="@drawable/chat_room_group_infos" />
|
android:src="@drawable/menu_more"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/edit"
|
android:id="@+id/edit"
|
||||||
|
android:visibility="gone"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="0.2"
|
android:layout_weight="0.2"
|
||||||
|
@ -97,6 +97,7 @@
|
||||||
android:contentDescription="@string/content_description_edit_list"
|
android:contentDescription="@string/content_description_edit_list"
|
||||||
android:padding="15dp"
|
android:padding="15dp"
|
||||||
android:src="@drawable/delete" />
|
android:src="@drawable/delete" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<include layout="@layout/edit_list" android:visibility="gone" />
|
<include layout="@layout/edit_list" android:visibility="gone" />
|
||||||
|
@ -159,14 +160,30 @@
|
||||||
android:textColor="@color/black_color"
|
android:textColor="@color/black_color"
|
||||||
android:textCursorDrawable="@null" />
|
android:textCursorDrawable="@null" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/send_message"
|
android:id="@+id/send_message"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/content_description_send_message"
|
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:src="@drawable/chat_send_message" />
|
android:src="@drawable/chat_send_message" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/send_ephemeral_message"
|
||||||
|
android:clickable="false"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:layout_alignRight="@id/send_message"
|
||||||
|
android:layout_alignBottom="@id/send_message"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:src="@drawable/chat_send_ephemeral_message" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -88,6 +88,31 @@
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
android:paddingBottom="5dp">
|
android:paddingBottom="5dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/forward_layout"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical|right"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:layout_marginLeft="5dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="15dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:src="@drawable/forwarded_message_default"
|
||||||
|
android:layout_marginRight="3dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/chat_bubble_forward_font"
|
||||||
|
android:text="@string/chat_message_forwarded" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.flexbox.FlexboxLayout
|
<com.google.android.flexbox.FlexboxLayout
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/multi_content"
|
android:id="@+id/multi_content"
|
||||||
|
@ -118,6 +143,32 @@
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:textAppearance="@style/chat_bubble_message_font" />
|
android:textAppearance="@style/chat_bubble_message_font" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ephemeral_layout"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_gravity="right"
|
||||||
|
android:gravity="center_vertical|right"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:layout_marginLeft="5dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ephemeral_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:textAppearance="@style/chat_bubble_ephemeral_font" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="13dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:src="@drawable/ephemeral_messages_small_default"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
|
|
89
app/src/main/res/layout/chat_ephemeral.xml
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/top_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:background="?attr/lighToolbarBackgroundColor"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.2"
|
||||||
|
android:background="?attr/button_background_drawable"
|
||||||
|
android:padding="18dp"
|
||||||
|
android:src="@drawable/back" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/toolbar_small_title_font"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.6"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="15dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/chat_room_ephemeral_fragment_title" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/valid"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.2"
|
||||||
|
android:background="?attr/button_background_drawable"
|
||||||
|
android:padding="18dp"
|
||||||
|
android:src="@drawable/valid" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/top_bar">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:src="@drawable/ephemeral_messages_default" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/chat_room_ephemeral_desc_font"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:text="@string/chat_room_ephemeral_messages_desc"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:background="?attr/dividerColor" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/items"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
32
app/src/main/res/layout/chat_ephemeral_item.xml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:text="@string/chat_room_ephemeral_message_disabled"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_toLeftOf="@id/selected"
|
||||||
|
style="@style/chat_room_ephemeral_item_font" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/selected"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:src="@drawable/check_selected" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:background="?attr/dividerColor" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
|
@ -90,6 +90,17 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ephemeral"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:src="@drawable/ephemeral_messages_small_default"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
android:id="@+id/copy_text"
|
android:id="@+id/copy_text"
|
||||||
android:title="@string/copy_text" />
|
android:title="@string/copy_text" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/forward"
|
||||||
|
android:title="@string/chat_message_context_menu_forward" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/imdn_infos"
|
android:id="@+id/imdn_infos"
|
||||||
android:title="@string/imdn_info" />
|
android:title="@string/imdn_info" />
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
android:id="@+id/copy_text"
|
android:id="@+id/copy_text"
|
||||||
android:title="@string/copy_text" />
|
android:title="@string/copy_text" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/forward"
|
||||||
|
android:title="@string/chat_message_context_menu_forward" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/imdn_infos"
|
android:id="@+id/imdn_infos"
|
||||||
android:title="@string/imdn_info" />
|
android:title="@string/imdn_info" />
|
||||||
|
|
24
app/src/main/res/menu/chat_room_menu.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/chat_room_group_info"
|
||||||
|
android:icon="@drawable/chat_room_menu_group_info"
|
||||||
|
android:title="@string/chat_room_context_menu_group_info" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/chat_room_participants_devices"
|
||||||
|
android:icon="@drawable/chat_room_menu_security"
|
||||||
|
android:title="@string/chat_room_context_menu_participants_devices" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/chat_room_ephemeral_messages"
|
||||||
|
android:icon="@drawable/chat_room_menu_ephemeral"
|
||||||
|
android:title="@string/chat_message_context_menu_ephemeral_messages" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/chat_room_delete_messages"
|
||||||
|
android:icon="@drawable/chat_room_menu_delete"
|
||||||
|
android:title="@string/chat_message_context_menu_delete_messages" />
|
||||||
|
|
||||||
|
</menu>
|
|
@ -256,6 +256,27 @@
|
||||||
<string name="toast_choose_chat_room_for_sharing">Select a conversation or create a new one</string>
|
<string name="toast_choose_chat_room_for_sharing">Select a conversation or create a new one</string>
|
||||||
<string name="trust_denied">Trust has been denied. Make a call to start the authentication process again.</string>
|
<string name="trust_denied">Trust has been denied. Make a call to start the authentication process again.</string>
|
||||||
<string name="cant_open_file_no_app_found">Can\'t open file, no application available for this format.</string>
|
<string name="cant_open_file_no_app_found">Can\'t open file, no application available for this format.</string>
|
||||||
|
<string name="chat_message_forwarded">Forwarded</string>
|
||||||
|
<string name="chat_room_context_menu_group_info">Group info</string>
|
||||||
|
<string name="chat_room_context_menu_participants_devices">Conversation\'s devices</string>
|
||||||
|
<string name="chat_message_context_menu_ephemeral_messages">Ephemeral messages</string>
|
||||||
|
<string name="chat_message_context_menu_delete_messages">Delete messages</string>
|
||||||
|
<string name="chat_message_context_menu_forward">Forward</string>
|
||||||
|
<string name="chat_room_ephemeral_fragment_title">Ephemeral messages</string>
|
||||||
|
<string name="chat_room_ephemeral_messages_desc">This message will be deleted on both ends once it has been read and after the selected timeout.</string>
|
||||||
|
<string name="chat_room_ephemeral_message_disabled">Disabled</string>
|
||||||
|
<string name="chat_room_ephemeral_message_one_minute">1 minute</string>
|
||||||
|
<string name="chat_room_ephemeral_message_one_hour">1 hour</string>
|
||||||
|
<string name="chat_room_ephemeral_message_one_day">1 day</string>
|
||||||
|
<string name="chat_room_ephemeral_message_three_days">3 days</string>
|
||||||
|
<string name="chat_room_ephemeral_message_one_week">1 week</string>
|
||||||
|
<plurals name="days">
|
||||||
|
<item quantity="one">%d day</item>
|
||||||
|
<item quantity="other">%d days</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="chat_event_ephemeral_disabled">You disabled ephemeral messages</string>
|
||||||
|
<string name="chat_event_ephemeral_enabled">You enabled ephemeral messages: %s</string>
|
||||||
|
<string name="chat_event_ephemeral_lifetime_changed">Ephemeral messages expiry date: %s</string>
|
||||||
|
|
||||||
<!-- Status Bar -->
|
<!-- Status Bar -->
|
||||||
<string name="status_connected">Connected</string>
|
<string name="status_connected">Connected</string>
|
||||||
|
|
|
@ -101,6 +101,39 @@
|
||||||
<item name="android:lineSpacingExtra">0sp</item>
|
<item name="android:lineSpacingExtra">0sp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="chat_bubble_forward_font" parent="@android:style/TextAppearance.Small">
|
||||||
|
<item name="android:textColor">@color/chat_bubble_text_color</item>
|
||||||
|
<item name="android:textSize">10sp</item>
|
||||||
|
<item name="android:fontFamily">sans-serif</item>
|
||||||
|
<item name="android:textStyle">normal</item>
|
||||||
|
<item name="android:lineSpacingExtra">3.3sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="chat_bubble_ephemeral_font" parent="@android:style/TextAppearance.Small">
|
||||||
|
<item name="android:textColor">@color/primary_color</item>
|
||||||
|
<item name="android:textSize">10sp</item>
|
||||||
|
<item name="android:fontFamily">sans-serif</item>
|
||||||
|
<item name="android:textStyle">normal</item>
|
||||||
|
<item name="android:lineSpacingExtra">3.3sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="chat_room_ephemeral_desc_font" parent="android:style/TextAppearance.Large">
|
||||||
|
<item name="android:textColor">?attr/primaryTextColor</item>
|
||||||
|
<item name="android:textSize">20sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="chat_room_ephemeral_item_font" parent="android:style/TextAppearance.Large">
|
||||||
|
<item name="android:textColor">?attr/primaryTextColor</item>
|
||||||
|
<item name="android:textStyle">normal</item>
|
||||||
|
<item name="android:textSize">20sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="chat_room_ephemeral_selected_item_font" parent="android:style/TextAppearance.Large">
|
||||||
|
<item name="android:textColor">?attr/primaryTextColor</item>
|
||||||
|
<item name="android:textStyle">bold</item>
|
||||||
|
<item name="android:textSize">20sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="chat_bubble_message_font" parent="@android:style/TextAppearance.Medium">
|
<style name="chat_bubble_message_font" parent="@android:style/TextAppearance.Medium">
|
||||||
<item name="android:textColor">@color/dark_grey_color</item>
|
<item name="android:textColor">@color/dark_grey_color</item>
|
||||||
<item name="android:textSize">15sp</item>
|
<item name="android:textSize">15sp</item>
|
||||||
|
|