account color selector

This commit is contained in:
kosyak 2024-09-02 00:12:42 +02:00
parent 4dab5156e1
commit 00817b79be
7 changed files with 107 additions and 22 deletions

View file

@ -83,6 +83,7 @@ dependencies {
implementation 'com.github.singpolyma:TokenAutoComplete:bfa93780e0' implementation 'com.github.singpolyma:TokenAutoComplete:bfa93780e0'
implementation 'com.github.kizitonwose.colorpreference:core:1.1.0'
implementation 'com.github.kizitonwose.colorpreference:support:1.1.0' implementation 'com.github.kizitonwose.colorpreference:support:1.1.0'
implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.caverock:androidsvg-aar:1.4'
implementation 'com.github.singpolyma:Better-Link-Movement-Method:4df081e1e4' implementation 'com.github.singpolyma:Better-Link-Movement-Method:4df081e1e4'

View file

@ -36,6 +36,7 @@ import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.ui.adapter.AccountAdapter; import eu.siacs.conversations.ui.adapter.AccountAdapter;
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.XmppConnection;
@ -44,8 +45,14 @@ import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView; import com.google.android.material.navigation.NavigationBarView;
import com.kizitonwose.colorpreference.ColorDialog;
import com.kizitonwose.colorpreference.ColorShape;
public class ManageAccountActivity extends XmppActivity implements OnAccountUpdate, KeyChainAliasCallback, XmppConnectionService.OnAccountCreated, AccountAdapter.OnTglAccountState { public class ManageAccountActivity extends XmppActivity implements OnAccountUpdate,
KeyChainAliasCallback,
XmppConnectionService.OnAccountCreated,
AccountAdapter.OnTglAccountState,
ColorDialog.OnColorSelectedListener {
private final String STATE_SELECTED_ACCOUNT = "selected_account"; private final String STATE_SELECTED_ACCOUNT = "selected_account";
@ -61,6 +68,18 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
protected Pair<Integer, Intent> mPostponedActivityResult = null; protected Pair<Integer, Intent> mPostponedActivityResult = null;
private AccountAdapter.ColorSelectorListener colorSelectorListener = new AccountAdapter.ColorSelectorListener() {
@Override
public void onColorPickerRequested(Jid accountJid, int currentColor) {
new ColorDialog.Builder(ManageAccountActivity.this)
.setColorShape(ColorShape.CIRCLE)
.setColorChoices(R.array.themeColorsOverride)
.setSelectedColor(currentColor)
.setTag(accountJid.asBareJid().toEscapedString())
.show();
}
};
@Override @Override
public void onAccountUpdate() { public void onAccountUpdate() {
refreshUi(); refreshUi();
@ -102,7 +121,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
} }
accountListView = findViewById(R.id.account_list); accountListView = findViewById(R.id.account_list);
this.mAccountAdapter = new AccountAdapter(this, accountList); this.mAccountAdapter = new AccountAdapter(this, accountList, colorSelectorListener);
accountListView.setAdapter(this.mAccountAdapter); accountListView.setAdapter(this.mAccountAdapter);
accountListView.setOnItemClickListener((arg0, view, position, arg3) -> switchToAccount(accountList.get(position))); accountListView.setOnItemClickListener((arg0, view, position, arg3) -> switchToAccount(accountList.get(position)));
registerForContextMenu(accountListView); registerForContextMenu(accountListView);
@ -158,6 +177,13 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
super.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState);
} }
@Override
protected void onDestroy() {
super.onDestroy();
colorSelectorListener = null;
mAccountAdapter.colorSelectorListener = null;
}
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
@ -349,6 +375,12 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
} }
} }
@Override
public void onColorSelected(int newColor, String tag) {
UIHelper.overrideAccountColor(this, tag, newColor);
refreshUiReal();
}
private void addAccountFromKey() { private void addAccountFromKey() {
try { try {
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null); KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);

View file

@ -9,6 +9,11 @@ import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import com.kizitonwose.colorpreference.ColorDialog;
import com.kizitonwose.colorpreference.ColorPreference;
import com.kizitonwose.colorpreference.ColorShape;
import com.kizitonwose.colorpreference.ColorUtils;
import java.util.List; import java.util.List;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
@ -19,22 +24,29 @@ import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.AvatarWorkerTask;
import eu.siacs.conversations.ui.util.StyledAttributes; import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.Jid;
public class AccountAdapter extends ArrayAdapter<Account> { public class AccountAdapter extends ArrayAdapter<Account> {
private final XmppActivity activity; private final XmppActivity activity;
private final boolean showStateButton; private final boolean showStateButton;
private final boolean showColorSelector;
public ColorSelectorListener colorSelectorListener = null;
public AccountAdapter(XmppActivity activity, List<Account> objects, boolean showStateButton) { public AccountAdapter(XmppActivity activity, List<Account> objects, boolean showStateButton) {
super(activity, 0, objects); super(activity, 0, objects);
this.activity = activity; this.activity = activity;
this.showStateButton = showStateButton; this.showStateButton = showStateButton;
this.showColorSelector = false;
} }
public AccountAdapter(XmppActivity activity, List<Account> objects) { public AccountAdapter(XmppActivity activity, List<Account> objects, ColorSelectorListener listener) {
super(activity, 0, objects); super(activity, 0, objects);
this.activity = activity; this.activity = activity;
this.showStateButton = true; this.showStateButton = true;
this.showColorSelector = true;
colorSelectorListener = listener;
} }
@Override @Override
@ -77,18 +89,27 @@ public class AccountAdapter extends ArrayAdapter<Account> {
} else { } else {
viewHolder.binding.tglAccountStatus.setVisibility(View.GONE); viewHolder.binding.tglAccountStatus.setVisibility(View.GONE);
} }
viewHolder.binding.tglAccountStatus.setOnCheckedChangeListener((compoundButton, b) -> { viewHolder.binding.tglAccountStatus.setOnCheckedChangeListener((compoundButton, b) -> {
if (b == isDisabled && activity instanceof OnTglAccountState) { if (b == isDisabled && activity instanceof OnTglAccountState) {
((OnTglAccountState) activity).onClickTglAccountState(account, b); ((OnTglAccountState) activity).onClickTglAccountState(account, b);
} }
}); });
if (activity.xmppConnectionService.getAccounts().size() > 1) { if (this.showColorSelector && activity.xmppConnectionService.getAccounts().size() > 1) {
viewHolder.binding.accountIndicator.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().getEscapedLocal())); int color = UIHelper.getAccountColor(activity, account.getJid());
viewHolder.binding.colorView.setVisibility(View.VISIBLE);
ColorUtils.setColorViewValue(viewHolder.binding.colorView, color, false, ColorShape.CIRCLE);
viewHolder.binding.colorView.setOnClickListener(v -> {
if (colorSelectorListener != null) {
colorSelectorListener.onColorPickerRequested(account.getJid(), color);
}
});
} else { } else {
viewHolder.binding.accountIndicator.setBackgroundColor(Color.TRANSPARENT); viewHolder.binding.colorView.setVisibility(View.GONE);
} }
return view; return view;
} }
@ -106,4 +127,7 @@ public class AccountAdapter extends ArrayAdapter<Account> {
void onClickTglAccountState(Account account, boolean state); void onClickTglAccountState(Account account, boolean state);
} }
public interface ColorSelectorListener {
void onColorPickerRequested(Jid accountJid, int currentColor);
}
} }

View file

@ -401,7 +401,7 @@ public class ConversationAdapter
Account account = conversation.getAccount(); Account account = conversation.getAccount();
if (account != null && activity.xmppConnectionService.getAccounts().size() > 1) { if (account != null && activity.xmppConnectionService.getAccounts().size() > 1) {
viewHolder.binding.accountIndicator.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().getEscapedLocal())); viewHolder.binding.accountIndicator.setBackgroundColor(UIHelper.getAccountColor(activity, account.getJid()));
} else { } else {
viewHolder.binding.accountIndicator.setBackgroundColor(Color.TRANSPARENT); viewHolder.binding.accountIndicator.setBackgroundColor(Color.TRANSPARENT);
} }

View file

@ -108,7 +108,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
} }
if (account != null && activity.xmppConnectionService.getAccounts().size() > 1) { if (account != null && activity.xmppConnectionService.getAccounts().size() > 1) {
viewHolder.accountIndicator.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().getEscapedLocal())); viewHolder.accountIndicator.setBackgroundColor(UIHelper.getAccountColor(activity, account.getJid()));
} else { } else {
viewHolder.accountIndicator.setBackgroundColor(Color.TRANSPARENT); viewHolder.accountIndicator.setBackgroundColor(Color.TRANSPARENT);
} }

View file

@ -1,6 +1,7 @@
package eu.siacs.conversations.utils; package eu.siacs.conversations.utils;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.text.format.DateUtils; import android.text.format.DateUtils;
@ -231,6 +232,23 @@ public class UIHelper {
return getColorForName(name, false); return getColorForName(name, false);
} }
public static int getAccountColor(Context context, Jid accountJid) {
SharedPreferences prefs = context.getSharedPreferences("accountColorsPrefs", Context.MODE_PRIVATE);
String name = accountJid.asBareJid().toEscapedString();
int overrideColor = prefs.getInt(name, -1);
if (overrideColor != -1) {
return overrideColor;
} else {
return getColorForName(name);
}
}
public static void overrideAccountColor(Context context, String accountName, int color) {
SharedPreferences prefs = context.getSharedPreferences("accountColorsPrefs", Context.MODE_PRIVATE);
prefs.edit().putInt(accountName, color).apply();
}
public static int getColorForName(String name, boolean safe) { public static int getColorForName(String name, boolean safe) {
if (Config.XEP_0392) { if (Config.XEP_0392) {
return XEP0392Helper.rgbFromNick(name); return XEP0392Helper.rgbFromNick(name);

View file

@ -6,17 +6,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:clipToPadding="false"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingBottom="8dp" android:paddingBottom="8dp"
android:paddingTop="8dp"> android:paddingTop="8dp">
<View
android:id="@+id/account_indicator"
android:layout_width="@dimen/account_indicator_width"
android:layout_marginStart="-4dp"
android:layout_height="48dp" />
<eu.siacs.conversations.ui.widget.AvatarView <eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/account_image" android:id="@+id/account_image"
android:layout_width="48dp" android:layout_width="48dp"
@ -31,8 +24,8 @@
android:layout_toEndOf="@+id/account_image" android:layout_toEndOf="@+id/account_image"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="@dimen/avatar_item_distance" android:paddingLeft="@dimen/avatar_item_distance"
android:layout_toLeftOf="@+id/tgl_account_status" android:layout_toLeftOf="@+id/controls"
android:layout_toStartOf="@+id/tgl_account_status"> android:layout_toStartOf="@+id/controls">
<TextView <TextView
android:id="@+id/account_jid" android:id="@+id/account_jid"
@ -50,14 +43,31 @@
android:textAppearance="@style/TextAppearance.Conversations.Body2" /> android:textAppearance="@style/TextAppearance.Conversations.Body2" />
</LinearLayout> </LinearLayout>
<androidx.appcompat.widget.SwitchCompat <LinearLayout
android:id="@+id/tgl_account_status" android:id="@+id/controls"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:orientation="horizontal"
android:layout_centerVertical="true" android:gravity="center_vertical"
android:padding="16dp" android:padding="16dp"
android:focusable="false" /> android:layout_alignParentRight="true"
android:layout_centerVertical="true">
<ImageView
android:id="@+id/color_view"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"
android:layout_marginEnd="12dp"
android:scaleType="fitXY" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/tgl_account_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false" />
</LinearLayout>
</RelativeLayout> </RelativeLayout>
</layout> </layout>