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; ...@@ -50,7 +50,7 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import androidx.core.widget.ImageViewCompat; import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import cx.ring.R; import cx.ring.R;
...@@ -100,6 +100,7 @@ public class ContactDetailsActivity extends AppCompatActivity { ...@@ -100,6 +100,7 @@ public class ContactDetailsActivity extends AppCompatActivity {
final IContactAction callback; final IContactAction callback;
int iconTint; int iconTint;
CharSequence iconSymbol;
ContactAction(@DrawableRes int i, int tint, CharSequence t, IContactAction cb) { ContactAction(@DrawableRes int i, int tint, CharSequence t, IContactAction cb) {
icon = i; icon = i;
...@@ -118,6 +119,10 @@ public class ContactDetailsActivity extends AppCompatActivity { ...@@ -118,6 +119,10 @@ public class ContactDetailsActivity extends AppCompatActivity {
void setIconTint(int tint) { void setIconTint(int tint) {
iconTint = tint; iconTint = tint;
} }
void setSymbol(CharSequence t) {
iconSymbol = t;
}
} }
static class ContactActionView extends RecyclerView.ViewHolder { static class ContactActionView extends RecyclerView.ViewHolder {
...@@ -152,9 +157,10 @@ public class ContactDetailsActivity extends AppCompatActivity { ...@@ -152,9 +157,10 @@ public class ContactDetailsActivity extends AppCompatActivity {
@Override @Override
public void onBindViewHolder(@NonNull ContactActionView holder, int position) { public void onBindViewHolder(@NonNull ContactActionView holder, int position) {
ContactAction action = actions.get(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) 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.binding.actionTitle.setText(action.title);
holder.callback = action.callback; holder.callback = action.callback;
} }
...@@ -169,8 +175,10 @@ public class ContactDetailsActivity extends AppCompatActivity { ...@@ -169,8 +175,10 @@ public class ContactDetailsActivity extends AppCompatActivity {
private final CompositeDisposable mDisposableBag = new CompositeDisposable(); private final CompositeDisposable mDisposableBag = new CompositeDisposable();
private ContactAction colorAction; private ContactAction colorAction;
private ContactAction symbolAction;
private ContactAction contactAction; private ContactAction contactAction;
private int colorActionPosition; private int colorActionPosition;
private int symbolActionPosition;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
...@@ -193,6 +201,7 @@ public class ContactDetailsActivity extends AppCompatActivity { ...@@ -193,6 +201,7 @@ public class ContactDetailsActivity extends AppCompatActivity {
fab.setOnClickListener(view -> goToConversationActivity(mConversation.getAccountId(), mConversation.getUri())); fab.setOnClickListener(view -> goToConversationActivity(mConversation.getAccountId(), mConversation.getUri()));
colorActionPosition = 1; colorActionPosition = 1;
symbolActionPosition = 2;
mDisposableBag.add(mConversationFacade mDisposableBag.add(mConversationFacade
.startConversation(path.getAccountId(), path.getConversationUri()) .startConversation(path.getAccountId(), path.getConversationUri())
...@@ -240,6 +249,18 @@ public class ContactDetailsActivity extends AppCompatActivity { ...@@ -240,6 +249,18 @@ public class ContactDetailsActivity extends AppCompatActivity {
collapsingToolbarLayout.setStatusBarScrimColor(color); collapsingToolbarLayout.setStatusBarScrimColor(color);
adapter.actions.add(colorAction); 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) { if (mConversation.getContacts().size() <= 2) {
CallContact contact = mConversation.getContact(); CallContact contact = mConversation.getContact();
adapter.actions.add(new ContactAction(R.drawable.baseline_call_24, getText(R.string.ab_action_audio_call), () -> 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 ...@@ -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_PENDING_MESSAGE = "pendingMessage";
public static final String KEY_PREFERENCE_CONVERSATION_COLOR = "color"; 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_LAST_READ = "lastRead";
public static final String KEY_PREFERENCE_CONVERSATION_SYMBOL = "symbol";
public static final String EXTRA_SHOW_MAP = "showMap"; public static final String EXTRA_SHOW_MAP = "showMap";
private static final int REQUEST_CODE_FILE_PICKER = 1000; private static final int REQUEST_CODE_FILE_PICKER = 1000;
...@@ -372,6 +373,11 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen ...@@ -372,6 +373,11 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
mAdapter.setPrimaryColor(color); mAdapter.setPrimaryColor(color);
} }
@Override
public void setConversationSymbol(CharSequence symbol) {
binding.emojiSend.setText(symbol);
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
if (mPreferences != null) if (mPreferences != null)
...@@ -898,8 +904,8 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen ...@@ -898,8 +904,8 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
mPreferences = requireActivity().getSharedPreferences(path.getAccountId() + "_" + uri.getUri(), Context.MODE_PRIVATE); mPreferences = requireActivity().getSharedPreferences(path.getAccountId() + "_" + uri.getUri(), Context.MODE_PRIVATE);
mPreferences.registerOnSharedPreferenceChangeListener(this); mPreferences.registerOnSharedPreferenceChangeListener(this);
presenter.setConversationColor(mPreferences.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light))); 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); mLastRead = mPreferences.getString(KEY_PREFERENCE_CONVERSATION_LAST_READ, null);
Log.w(TAG, "Loaded last read " + mLastRead);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "Can't load conversation preferences"); Log.e(TAG, "Can't load conversation preferences");
} }
...@@ -940,6 +946,9 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen ...@@ -940,6 +946,9 @@ public class ConversationFragment extends BaseSupportFragment<ConversationPresen
case KEY_PREFERENCE_CONVERSATION_COLOR: case KEY_PREFERENCE_CONVERSATION_COLOR:
presenter.setConversationColor(prefs.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light))); presenter.setConversationColor(prefs.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light)));
break; 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 ...@@ -682,6 +682,11 @@ public class TvConversationFragment extends BaseSupportFragment<ConversationPres
} }
@Override
public void setConversationSymbol(CharSequence symbol) {
}
@Override @Override
public void startShareLocation(String accountId, String contactId) { public void startShareLocation(String accountId, String contactId) {
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<data />
<RelativeLayout
android:id="@+id/call_entry" android:id="@+id/call_entry"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
...@@ -15,23 +12,28 @@ ...@@ -15,23 +12,28 @@
android:paddingRight="16dp" android:paddingRight="16dp"
android:paddingBottom="8dp"> android:paddingBottom="8dp">
<ImageView <TextView
android:id="@+id/action_icon" android:id="@+id/action_icon"
android:layout_width="40dp" android:layout_width="32dp"
android:layout_height="40dp" android:layout_height="32dp"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="16dp" android:layout_marginStart="4dp"
android:background="@null" android:layout_marginTop="4dp"
android:padding="4dp" android:layout_marginEnd="20dp"
android:layout_marginBottom="4dp"
android:backgroundTint="@color/colorPrimary"
android:gravity="center"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:tint="@color/colorPrimary" android:text=""
tools:src="@drawable/baseline_call_24" /> android:textSize="24dp"
android:textColor="@color/black"
app:tint="@color/colorPrimary"
tools:background="@drawable/baseline_call_24" />
<TextView <TextView
android:id="@+id/action_title" android:id="@+id/action_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_toEndOf="@id/action_icon" android:layout_toEndOf="@id/action_icon"
android:ellipsize="middle" android:ellipsize="middle"
...@@ -44,6 +46,4 @@ ...@@ -44,6 +46,4 @@
android:textSize="16sp" android:textSize="16sp"
tools:text="Start Audio Call" /> tools:text="Start Audio Call" />
</RelativeLayout> </RelativeLayout>
</layout>
\ No newline at end of file
<?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 ...@@ -56,6 +56,19 @@ along with this program; if not, write to the Free Software
<item>1080</item> <item>1080</item>
<item>2160</item> <item>2160</item>
</string-array> </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">480</string>
<string translatable="false" name="video_resolution_default_tv">720</string> <string translatable="false" name="video_resolution_default_tv">720</string>
</resources> </resources>
...@@ -262,6 +262,9 @@ public class ConversationPresenter extends RootPresenter<ConversationView> { ...@@ -262,6 +262,9 @@ public class ConversationPresenter extends RootPresenter<ConversationView> {
mConversationDisposable.add(c.getColor() mConversationDisposable.add(c.getColor()
.observeOn(mUiScheduler) .observeOn(mUiScheduler)
.subscribe(view::setConversationColor, e -> Log.e(TAG, "Can't update conversation color", e))); .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"); Log.e(TAG, "getLocationUpdates subscribe");
mConversationDisposable.add(account mConversationDisposable.add(account
...@@ -440,6 +443,11 @@ public class ConversationPresenter extends RootPresenter<ConversationView> { ...@@ -440,6 +443,11 @@ public class ConversationPresenter extends RootPresenter<ConversationView> {
.firstElement() .firstElement()
.subscribe(conversation -> conversation.setColor(color))); .subscribe(conversation -> conversation.setColor(color)));
} }
public void setConversationSymbol(CharSequence symbol) {
mCompositeDisposable.add(mConversationSubject
.firstElement()
.subscribe(conversation -> conversation.setSymbol(symbol)));
}
public void cameraPermissionChanged(boolean isGranted) { public void cameraPermissionChanged(boolean isGranted) {
if (isGranted && mHardwareService.isVideoAvailable()) { if (isGranted && mHardwareService.isVideoAvailable()) {
......
...@@ -83,6 +83,7 @@ public interface ConversationView extends BaseView { ...@@ -83,6 +83,7 @@ public interface ConversationView extends BaseView {
void setLastDisplayed(Interaction interaction); void setLastDisplayed(Interaction interaction);
void setConversationColor(int integer); void setConversationColor(int integer);
void setConversationSymbol(CharSequence symbol);
void startSaveFile(DataTransfer currentFile, String fileAbsolutePath); void startSaveFile(DataTransfer currentFile, String fileAbsolutePath);
......
...@@ -60,6 +60,7 @@ public class Conversation extends ConversationHistory { ...@@ -60,6 +60,7 @@ public class Conversation extends ConversationHistory {
private final Subject<List<Conference>> callsSubject = BehaviorSubject.create(); private final Subject<List<Conference>> callsSubject = BehaviorSubject.create();
private final Subject<Account.ComposingStatus> composingStatusSubject = BehaviorSubject.createDefault(Account.ComposingStatus.Idle); private final Subject<Account.ComposingStatus> composingStatusSubject = BehaviorSubject.createDefault(Account.ComposingStatus.Idle);
private final Subject<Integer> color = BehaviorSubject.create(); private final Subject<Integer> color = BehaviorSubject.create();
private final Subject<CharSequence> symbol = BehaviorSubject.create();
private final Subject<List<CallContact>> mContactSubject = BehaviorSubject.create(); private final Subject<List<CallContact>> mContactSubject = BehaviorSubject.create();
private Single<Conversation> isLoaded = null; private Single<Conversation> isLoaded = null;
...@@ -648,9 +649,17 @@ public class Conversation extends ConversationHistory { ...@@ -648,9 +649,17 @@ public class Conversation extends ConversationHistory {
color.onNext(c); color.onNext(c);
} }
public void setSymbol(CharSequence s) {
symbol.onNext(s);
}
public Observable<Integer> getColor() { public Observable<Integer> getColor() {
return color; return color;
} }
public Observable<CharSequence> getSymbol() {
return symbol;
}
public String getAccountId() { public String getAccountId() {
return mAccountId; return mAccountId;
......
Supports Markdown
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