Commit 9d3abf7d authored by Adrien Béraud's avatar Adrien Béraud Committed by Sébastien Blin
Browse files

conversation: add emoji preference

Change-Id: Ie47a58d18a81754bf5a7dca0771bd4293ee2d3fa
parent ef3c38fc
......@@ -50,7 +50,7 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import androidx.core.widget.ImageViewCompat;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.RecyclerView;
import cx.ring.R;
......@@ -100,6 +100,7 @@ public class ContactDetailsActivity extends AppCompatActivity {
final IContactAction callback;
int iconTint;
CharSequence iconSymbol;
ContactAction(@DrawableRes int i, int tint, CharSequence t, IContactAction cb) {
icon = i;
......@@ -118,6 +119,10 @@ public class ContactDetailsActivity extends AppCompatActivity {
void setIconTint(int tint) {
iconTint = tint;
}
void setSymbol(CharSequence t) {
iconSymbol = t;
}
}
static class ContactActionView extends RecyclerView.ViewHolder {
......@@ -152,9 +157,10 @@ public class ContactDetailsActivity extends AppCompatActivity {
@Override
public void onBindViewHolder(@NonNull ContactActionView holder, int position) {
ContactAction action = actions.get(position);
holder.binding.actionIcon.setImageResource(action.icon);
holder.binding.actionIcon.setBackgroundResource(action.icon);
holder.binding.actionIcon.setText(action.iconSymbol);
if (action.iconTint != Color.BLACK)
ImageViewCompat.setImageTintList(holder.binding.actionIcon, ColorStateList.valueOf(action.iconTint));
ViewCompat.setBackgroundTintList(holder.binding.actionIcon, ColorStateList.valueOf(action.iconTint));
holder.binding.actionTitle.setText(action.title);
holder.callback = action.callback;
}
......@@ -169,8 +175,10 @@ public class ContactDetailsActivity extends AppCompatActivity {
private final CompositeDisposable mDisposableBag = new CompositeDisposable();
private ContactAction colorAction;
private ContactAction symbolAction;
private ContactAction contactAction;
private int colorActionPosition;
private int symbolActionPosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -193,6 +201,7 @@ public class ContactDetailsActivity extends AppCompatActivity {
fab.setOnClickListener(view -> goToConversationActivity(mConversation.getAccountId(), mConversation.getUri()));
colorActionPosition = 1;
symbolActionPosition = 2;
mDisposableBag.add(mConversationFacade
.startConversation(path.getAccountId(), path.getConversationUri())
......@@ -240,6 +249,18 @@ public class ContactDetailsActivity extends AppCompatActivity {
collapsingToolbarLayout.setStatusBarScrimColor(color);
adapter.actions.add(colorAction);
symbolAction = new ContactAction(0, getText(R.string.conversation_preference_emoji), () -> {
EmojiChooserBottomSheet frag = new EmojiChooserBottomSheet();
frag.setCallback(s -> {
symbolAction.setSymbol(s);
adapter.notifyItemChanged(symbolActionPosition);
mPreferences.edit().putString(ConversationFragment.KEY_PREFERENCE_CONVERSATION_SYMBOL, s).apply();
});
frag.show(getSupportFragmentManager(), "colorChooser");
});
symbolAction.setSymbol(mPreferences.getString(ConversationFragment.KEY_PREFERENCE_CONVERSATION_SYMBOL, getResources().getString(R.string.conversation_default_emoji)));
adapter.actions.add(symbolAction);
if (mConversation.getContacts().size() <= 2) {
CallContact contact = mConversation.getContact();
adapter.actions.add(new ContactAction(R.drawable.baseline_call_24, getText(R.string.ab_action_audio_call), () ->
......
/*
* Copyright (C) 2004-2021 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package cx.ring.client;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.ArrayRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import cx.ring.R;
public class EmojiChooserBottomSheet extends BottomSheetDialogFragment {
interface IEmojiSelected {
void onEmojiSelected(String emoji);
}
private IEmojiSelected callback;
public void setCallback(IEmojiSelected cb) {
callback = cb;
}
private class EmojiView extends RecyclerView.ViewHolder {
TextView view;
String emoji;
EmojiView(@NonNull View itemView) {
super(itemView);
view = (TextView) itemView;
itemView.setOnClickListener(v -> {
if (callback != null)
callback.onEmojiSelected(emoji);
dismiss();
});
}
}
class ColorAdapter extends RecyclerView.Adapter<EmojiView> {
private final String[] emojis;
public ColorAdapter(@ArrayRes int arrayResId) {
emojis = getResources().getStringArray(arrayResId);
}
@NonNull
@Override
public EmojiView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_emoji, parent, false);
return new EmojiView(v);
}
@Override
public void onBindViewHolder(@NonNull EmojiView holder, int position) {
holder.emoji = emojis[position];
holder.view.setText(holder.emoji);
}
@Override
public int getItemCount() {
return emojis.length;
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
RecyclerView view = (RecyclerView) inflater.inflate(R.layout.frag_color_chooser, container);
view.setAdapter(new ColorAdapter(R.array.conversation_emojis));
return view;
}
}
......@@ -135,6 +135,7 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
public static final String KEY_PREFERENCE_PENDING_MESSAGE = "pendingMessage";
public static final String KEY_PREFERENCE_CONVERSATION_COLOR = "color";
public static final String KEY_PREFERENCE_CONVERSATION_LAST_READ = "lastRead";
public static final String KEY_PREFERENCE_CONVERSATION_SYMBOL = "symbol";
public static final String EXTRA_SHOW_MAP = "showMap";
private static final int REQUEST_CODE_FILE_PICKER = 1000;
......@@ -372,6 +373,11 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
mAdapter.setPrimaryColor(color);
}
@Override
public void setConversationSymbol(CharSequence symbol) {
binding.emojiSend.setText(symbol);
}
@Override
public void onDestroyView() {
if (mPreferences != null)
......@@ -898,8 +904,8 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
mPreferences = requireActivity().getSharedPreferences(path.getAccountId() + "_" + uri.getUri(), Context.MODE_PRIVATE);
mPreferences.registerOnSharedPreferenceChangeListener(this);
presenter.setConversationColor(mPreferences.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light)));
presenter.setConversationSymbol(mPreferences.getString(KEY_PREFERENCE_CONVERSATION_SYMBOL, getResources().getText(R.string.conversation_default_emoji).toString()));
mLastRead = mPreferences.getString(KEY_PREFERENCE_CONVERSATION_LAST_READ, null);
Log.w(TAG, "Loaded last read " + mLastRead);
} catch (Exception e) {
Log.e(TAG, "Can't load conversation preferences");
}
......@@ -940,6 +946,9 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
case KEY_PREFERENCE_CONVERSATION_COLOR:
presenter.setConversationColor(prefs.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light)));
break;
case KEY_PREFERENCE_CONVERSATION_SYMBOL:
presenter.setConversationSymbol(prefs.getString(KEY_PREFERENCE_CONVERSATION_SYMBOL, getResources().getText(R.string.conversation_default_emoji).toString()));
break;
}
}
......
......@@ -682,6 +682,11 @@ public class TvConversationFragment extends BaseSupportFragment<ConversationPres
}
@Override
public void setConversationSymbol(CharSequence symbol) {
}
@Override
public void startShareLocation(String accountId, String contactId) {
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/call_entry"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?android:attr/selectableItemBackground"
android:descendantFocusability="blocksDescendants"
android:paddingLeft="16dp"
android:paddingTop="8dp"
android:paddingRight="16dp"
android:paddingBottom="8dp">
<data />
<TextView
android:id="@+id/action_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_centerVertical="true"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="4dp"
android:backgroundTint="@color/colorPrimary"
android:gravity="center"
android:scaleType="fitCenter"
android:text=""
android:textSize="24dp"
android:textColor="@color/black"
app:tint="@color/colorPrimary"
tools:background="@drawable/baseline_call_24" />
<RelativeLayout
android:id="@+id/call_entry"
<TextView
android:id="@+id/action_title"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?android:attr/selectableItemBackground"
android:descendantFocusability="blocksDescendants"
android:paddingLeft="16dp"
android:paddingTop="8dp"
android:paddingRight="16dp"
android:paddingBottom="8dp">
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/action_icon"
android:ellipsize="middle"
android:gravity="start"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAlignment="viewStart"
android:textColor="@color/textColorPrimary"
android:textSize="16sp"
tools:text="Start Audio Call" />
<ImageView
android:id="@+id/action_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:background="@null"
android:padding="4dp"
android:scaleType="fitCenter"
android:tint="@color/colorPrimary"
tools:src="@drawable/baseline_call_24" />
<TextView
android:id="@+id/action_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/action_icon"
android:ellipsize="middle"
android:gravity="start"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAlignment="viewStart"
android:textColor="@color/textColorPrimary"
android:textSize="16sp"
tools:text="Start Audio Call" />
</RelativeLayout>
</layout>
\ No newline at end of file
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="16dp"
android:text="@string/conversation_default_emoji"
android:textAlignment="center"
android:textSize="24dp"
android:textColor="@color/text_color"/>
......@@ -56,6 +56,19 @@ along with this program; if not, write to the Free Software
<item>1080</item>
<item>2160</item>
</string-array>
<string-array name="conversation_emojis">
<item>👍</item>
<item>❤️</item>
<item>😂</item>
<item>💩</item>
<item>👻</item>
<item>😃</item>
<item></item>
<item>😍</item>
<item>🙏</item>
</string-array>
<string translatable="false" name="video_resolution_default">480</string>
<string translatable="false" name="video_resolution_default_tv">720</string>
</resources>
......@@ -262,6 +262,9 @@ public class ConversationPresenter extends RootPresenter<ConversationView> {
mConversationDisposable.add(c.getColor()
.observeOn(mUiScheduler)
.subscribe(view::setConversationColor, e -> Log.e(TAG, "Can't update conversation color", e)));
mConversationDisposable.add(c.getSymbol()
.observeOn(mUiScheduler)
.subscribe(view::setConversationSymbol, e -> Log.e(TAG, "Can't update conversation color", e)));
Log.e(TAG, "getLocationUpdates subscribe");
mConversationDisposable.add(account
......@@ -440,6 +443,11 @@ public class ConversationPresenter extends RootPresenter<ConversationView> {
.firstElement()
.subscribe(conversation -> conversation.setColor(color)));
}
public void setConversationSymbol(CharSequence symbol) {
mCompositeDisposable.add(mConversationSubject
.firstElement()
.subscribe(conversation -> conversation.setSymbol(symbol)));
}
public void cameraPermissionChanged(boolean isGranted) {
if (isGranted && mHardwareService.isVideoAvailable()) {
......
......@@ -83,6 +83,7 @@ public interface ConversationView extends BaseView {
void setLastDisplayed(Interaction interaction);
void setConversationColor(int integer);
void setConversationSymbol(CharSequence symbol);
void startSaveFile(DataTransfer currentFile, String fileAbsolutePath);
......
......@@ -60,6 +60,7 @@ public class Conversation extends ConversationHistory {
private final Subject<List<Conference>> callsSubject = BehaviorSubject.create();
private final Subject<Account.ComposingStatus> composingStatusSubject = BehaviorSubject.createDefault(Account.ComposingStatus.Idle);
private final Subject<Integer> color = BehaviorSubject.create();
private final Subject<CharSequence> symbol = BehaviorSubject.create();
private final Subject<List<CallContact>> mContactSubject = BehaviorSubject.create();
private Single<Conversation> isLoaded = null;
......@@ -648,9 +649,17 @@ public class Conversation extends ConversationHistory {
color.onNext(c);
}
public void setSymbol(CharSequence s) {
symbol.onNext(s);
}
public Observable<Integer> getColor() {
return color;
}
public Observable<CharSequence> getSymbol() {
return symbol;
}
public String getAccountId() {
return mAccountId;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment