Commit 2ed1e7b3 authored by Adrien Béraud's avatar Adrien Béraud Committed by Sébastien Blin

account spinner: use full layout, fix logic

Change-Id: I41d77a4280fc33a738ab3af9776067adb541a2c4
parent dba9c9fd
......@@ -122,7 +122,7 @@ public class AccountWizardActivity extends BaseActivity<AccountWizardPresenter>
File filedir = getFilesDir();
return accountCreationModel.toVCard()
.flatMap(vcard -> {
account.setProfile(vcard);
account.resetProfile();
return VCardUtils.saveLocalProfileToDisk(vcard, account.getAccountID(), filedir);
})
.subscribeOn(Schedulers.io());
......
......@@ -29,11 +29,13 @@ import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.jami.model.Account;
import java.util.List;
import cx.ring.R;
import cx.ring.databinding.ItemToolbarSelectedBinding;
import cx.ring.databinding.ItemToolbarSpinnerBinding;
import net.jami.model.Account;
import cx.ring.views.AvatarDrawable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
......@@ -57,30 +59,26 @@ public class AccountSpinnerAdapter extends ArrayAdapter<Account> {
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
int type = getItemViewType(position);
ViewHolder holder;
ViewHolderHeader holder;
if (convertView == null) {
holder = new ViewHolder();
holder.binding = ItemToolbarSpinnerBinding.inflate(mInflater, parent, false);
holder = new ViewHolderHeader();
holder.binding = ItemToolbarSelectedBinding.inflate(mInflater, parent, false);
convertView = holder.binding.getRoot();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder = (ViewHolderHeader) convertView.getTag();
holder.loader.clear();
}
holder.binding.logo.setVisibility(View.GONE);
holder.binding.subtitle.setVisibility(View.GONE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.binding.title.getLayoutParams();
params.leftMargin = 0;
holder.binding.title.setLayoutParams(params);
if (type == TYPE_ACCOUNT) {
Account account = getItem(position);
holder.loader.add(AvatarDrawable.load(getContext(), account)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(avatar -> holder.binding.logo.setImageDrawable(avatar), e -> Log.e(TAG, "Error loading avatar", e)));
holder.loader.add(account.getAccountAlias()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(alias -> holder.binding.title.setText(alias)));
.subscribe(alias -> holder.binding.title.setText(alias), e -> Log.e(TAG, "Error loading title", e)));
}
return convertView;
}
......@@ -165,6 +163,10 @@ public class AccountSpinnerAdapter extends ArrayAdapter<Account> {
ItemToolbarSpinnerBinding binding;
final CompositeDisposable loader = new CompositeDisposable();
}
private static class ViewHolderHeader {
ItemToolbarSelectedBinding binding;
final CompositeDisposable loader = new CompositeDisposable();
}
private String getUri(Account account, CharSequence defaultNameSip) {
if (account.isIP2IP()) {
......
......@@ -22,7 +22,6 @@ package cx.ring.client;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
......@@ -43,7 +42,6 @@ import androidx.core.content.ContextCompat;
import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat;
import androidx.core.util.Pair;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
......@@ -51,6 +49,12 @@ import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import net.jami.model.Account;
import net.jami.model.AccountConfig;
import net.jami.model.Conversation;
import net.jami.services.AccountService;
import net.jami.services.NotificationService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
......@@ -72,14 +76,7 @@ import cx.ring.fragments.ConversationFragment;
import cx.ring.fragments.SmartListFragment;
import cx.ring.interfaces.BackHandlerInterface;
import cx.ring.interfaces.Colorable;
import net.jami.model.Account;
import net.jami.model.AccountConfig;
import cx.ring.service.DRingService;
import net.jami.model.Contact;
import net.jami.model.Conversation;
import net.jami.services.AccountService;
import net.jami.services.NotificationService;
import cx.ring.settings.SettingsFragment;
import cx.ring.settings.VideoSettingsFragment;
import cx.ring.settings.pluginssettings.PluginDetails;
......@@ -302,14 +299,6 @@ public class HomeActivity extends AppCompatActivity implements BottomNavigationV
mBinding.spinnerToolbar.setVisibility(View.VISIBLE);
mBinding.mainToolbar.setTitle(null);
mBinding.mainToolbar.setSubtitle(null);
int targetSize = (int) (AvatarFactory.SIZE_AB * getResources().getDisplayMetrics().density);
mDisposable.add(mAccountService.getCurrentAccountSubject()
.switchMapSingle(account -> AvatarFactory.getBitmapAvatar(HomeActivity.this, account, targetSize)
.map(avatar -> new Pair<>(account, avatar)))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(d -> mBinding.mainToolbar.setLogo(new BitmapDrawable(getResources(), d.second)),
e -> Log.e(TAG, "Error loading avatar", e)));
}
@Override
......@@ -329,11 +318,11 @@ public class HomeActivity extends AppCompatActivity implements BottomNavigationV
}
}));
mDisposable.add(mAccountService.getProfileAccountList()
mDisposable.add(mAccountService.getObservableAccountList()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(accounts -> {
if (mAccountAdapter == null) {
mAccountAdapter = new AccountSpinnerAdapter(HomeActivity.this, accounts);
mAccountAdapter = new AccountSpinnerAdapter(HomeActivity.this, new ArrayList<>(accounts));
mAccountAdapter.setNotifyOnChange(false);
mBinding.spinnerToolbar.setAdapter(mAccountAdapter);
} else {
......@@ -449,7 +438,7 @@ public class HomeActivity extends AppCompatActivity implements BottomNavigationV
fContent = getSupportFragmentManager().findFragmentById(R.id.main_frame);
if (fContent instanceof SmartListFragment) {
mBinding.navigationView.getMenu().getItem(NAVIGATION_CONVERSATIONS).setChecked(true);
showProfileInfo();
//showProfileInfo();
showToolbarSpinner();
hideTabletToolbar();
}
......@@ -513,69 +502,61 @@ public class HomeActivity extends AppCompatActivity implements BottomNavigationV
return false;
Bundle bundle = new Bundle();
switch (item.getItemId()) {
case R.id.navigation_requests:
if (fContent instanceof ContactRequestsFragment) {
((ContactRequestsFragment) fContent).presentForAccount(null);
break;
}
popCustomBackStack();
fContent = new ContactRequestsFragment();
getSupportFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.main_frame, fContent, CONTACT_REQUESTS_TAG)
.setReorderingAllowed(true)
.addToBackStack(CONTACT_REQUESTS_TAG)
.commit();
showProfileInfo();
showToolbarSpinner();
break;
case R.id.navigation_home:
if (fContent instanceof SmartListFragment) {
break;
int itemId = item.getItemId();
if (itemId == R.id.navigation_requests) {
if (fContent instanceof ContactRequestsFragment) {
((ContactRequestsFragment) fContent).presentForAccount(null);
return true;
}
popCustomBackStack();
fContent = new ContactRequestsFragment();
getSupportFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.main_frame, fContent, CONTACT_REQUESTS_TAG)
.setReorderingAllowed(true)
.addToBackStack(CONTACT_REQUESTS_TAG)
.commit();
//showProfileInfo();
showToolbarSpinner();
} else if (itemId == R.id.navigation_home) {
if (fContent instanceof SmartListFragment) {
return true;
}
popCustomBackStack();
fContent = new SmartListFragment();
getSupportFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.main_frame, fContent, HOME_TAG)
.setReorderingAllowed(true)
.commit();
//showProfileInfo();
showToolbarSpinner();
} else if (itemId == R.id.navigation_settings) {
if (account.needsMigration()) {
Log.d(TAG, "launchAccountMigrationActivity: Launch account migration activity");
Intent intent = new Intent()
.setClass(this, AccountWizardActivity.class)
.setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, account.getAccountID()));
startActivityForResult(intent, 1);
} else {
Log.d(TAG, "launchAccountEditFragment: Launch account edit fragment");
bundle.putString(AccountEditionFragment.ACCOUNT_ID, account.getAccountID());
if (fContent instanceof AccountEditionFragment) {
return true;
}
popCustomBackStack();
fContent = new SmartListFragment();
fContent = new AccountEditionFragment();
fContent.setArguments(bundle);
getSupportFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.main_frame, fContent, HOME_TAG)
.setReorderingAllowed(true)
.replace(getFragmentContainerId(), fContent, ACCOUNTS_TAG)
.addToBackStack(ACCOUNTS_TAG)
.commit();
showProfileInfo();
//showProfileInfo();
showToolbarSpinner();
break;
case R.id.navigation_settings:
if (account.needsMigration()) {
Log.d(TAG, "launchAccountMigrationActivity: Launch account migration activity");
Intent intent = new Intent()
.setClass(this, AccountWizardActivity.class)
.setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, account.getAccountID()));
startActivityForResult(intent, 1);
} else {
Log.d(TAG, "launchAccountEditFragment: Launch account edit fragment");
bundle.putString(AccountEditionFragment.ACCOUNT_ID, account.getAccountID());
if (fContent instanceof AccountEditionFragment) {
break;
}
popCustomBackStack();
fContent = new AccountEditionFragment();
fContent.setArguments(bundle);
getSupportFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(getFragmentContainerId(), fContent, ACCOUNTS_TAG)
.addToBackStack(ACCOUNTS_TAG)
.commit();
showProfileInfo();
showToolbarSpinner();
break;
}
break;
default:
break;
}
}
return true;
......
......@@ -594,7 +594,7 @@ public class NotificationServiceImpl implements NotificationService {
unreadConvBuilder.addMessage(last.getBody());
} else {
Account account = mAccountService.getAccount(accountId);
Tuple<String, Object> profile = account == null ? null : VCardServiceImpl.loadProfile(account).blockingGet();
Tuple<String, Object> profile = account == null ? null : VCardServiceImpl.loadProfile(mContext, account).blockingGet();
Bitmap myPic = account == null ? null : getContactPicture(account);
Person userPerson = new Person.Builder()
.setKey(accountId)
......
......@@ -50,11 +50,12 @@ public class VCardServiceImpl extends VCardService {
this.mContext = context;
}
public static Single<Tuple<String, Object>> loadProfile(@NonNull Account account) {
public static Single<Tuple<String, Object>> loadProfile(@NonNull Context context, @NonNull Account account) {
synchronized (account) {
Single<Tuple<String, Object>> ret = account.getLoadedProfile();
if (ret == null) {
ret = Single.fromCallable(() -> readData(account.getProfile()))
ret = VCardUtils.loadLocalProfileFromDiskWithDefault(context.getFilesDir(), account.getAccountID())
.map(VCardServiceImpl::readData)
.subscribeOn(Schedulers.computation())
.cache();
account.setLoadedProfile(ret);
......@@ -63,6 +64,11 @@ public class VCardServiceImpl extends VCardService {
}
}
@Override
public Single<Tuple<String, Object>> loadProfile(@NonNull Account account) {
return loadProfile(mContext, account);
}
@Override
public Maybe<VCard> loadSmallVCard(String accountId, int maxSize) {
return VCardUtils.loadLocalProfileFromDisk(mContext.getFilesDir(), accountId)
......
......@@ -177,7 +177,7 @@ public class TVAccountWizard
File filedir = getFilesDir();
return accountCreationModel.toVCard()
.flatMap(vcard -> {
account.setProfile(vcard);
account.resetProfile();
return VCardUtils.saveLocalProfileToDisk(vcard, account.getAccountID(), filedir);
})
.subscribeOn(Schedulers.io());
......
......@@ -91,7 +91,7 @@ public class TVShareFragment extends BaseSupportFragment<SharePresenter> impleme
private void getUserAvatar(Account account) {
disposable.add(VCardServiceImpl
.loadProfile(account)
.loadProfile(requireContext(), account)
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess(profile -> {
if (binding != null) {
......
......@@ -392,7 +392,7 @@ public class MainFragment extends BaseBrowseFragment<MainPresenter> implements M
String address = account.getDisplayUsername();
mDisposable.clear();
mDisposable.add(VCardServiceImpl
.loadProfile(account)
.loadProfile(context, account)
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess(profile -> {
if (profile.first != null && !profile.first.isEmpty()) {
......
......@@ -97,11 +97,10 @@ public class MainPresenter extends RootPresenter<MainView> {
}
public void reloadAccountInfos() {
mCompositeDisposable.add(mAccountService.getProfileAccountList()
mCompositeDisposable.add(mAccountService.getCurrentAccountSubject()
.observeOn(mUiScheduler)
.subscribe(
accounts -> getView().displayAccountInfos(
new HomeNavigationViewModel(accounts.isEmpty() ? null : accounts.get(0), null)),
account -> getView().displayAccountInfos(new HomeNavigationViewModel(account, null)),
e-> Log.d(TAG, "reloadAccountInfos getProfileAccountList onError", e)));
mCompositeDisposable.add(mAccountService.getObservableAccounts()
.observeOn(mUiScheduler)
......
......@@ -253,7 +253,7 @@ public class AvatarDrawable extends Drawable {
}
public static Single<AvatarDrawable> load(Context context, Account account, boolean crop) {
return VCardServiceImpl.loadProfile(account)
return VCardServiceImpl.loadProfile(context, account)
.map(data -> new Builder()
.withPhoto((Bitmap) data.second)
.withNameData(data.first, account.getRegisteredName())
......
......@@ -24,7 +24,7 @@
<Spinner
android:id="@+id/spinner_toolbar"
android:layout_width="264dp"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:dropDownWidth="320dp"
......
......@@ -38,8 +38,6 @@ along with this program; if not, write to the Free Software
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
android:clipChildren="false"
android:clipToPadding="false"
app:contentInsetStart="16dp">
<cx.ring.views.SwitchButton
......@@ -59,51 +57,11 @@ along with this program; if not, write to the Free Software
<Spinner
android:id="@+id/spinner_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:dropDownWidth="260dp"
android:paddingStart="-60dp" />
<!--
<RelativeLayout
android:id="@+id/tablet_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="100dp"
android:visibility="gone">
<ImageView
android:id="@+id/contact_image"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
tools:src="@drawable/ic_contact_picture_fallback" />
<TextView
android:id="@+id/contact_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/contact_image"
android:layout_marginStart="16dp"
android:layout_toEndOf="@+id/contact_image"
android:singleLine="true"
android:textColor="@color/textColorPrimary"
android:textSize="16sp"
tools:text="Thomas" />
<TextView
android:id="@+id/contact_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_title"
android:layout_alignStart="@id/contact_title"
android:layout_toEndOf="@+id/contact_image"
android:textColor="@color/textColorPrimary"
android:textSize="14sp"
tools:text="tom" />
</RelativeLayout>-->
android:paddingStart="-60dp"
tools:listitem="@layout/item_toolbar_selected"/>
</com.google.android.material.appbar.MaterialToolbar>
......
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2018-2021 Savoir-faire Linux Inc.
Author: Adrien Beraud <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, see <http://www.gnu.org/licenses/>.
-->
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clipToPadding="false"
android:paddingBottom="8dp">
<TextView
style="@style/Subheader"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center_vertical"
android:paddingEnd="72dp"
android:paddingStart="72dp"
android:text="@string/normal_accounts_titles" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/colorBackground"
android:clipToPadding="false"
android:elevation="2dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/accounts_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dividerHeight="1px"
android:focusable="false"
android:nestedScrollingEnabled="false"
android:visibility="visible"
tools:listitem="@layout/item_account_pref" />
<TextView
android:id="@+id/empty_account_list"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/empty_account_list"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/textColorSecondary"
android:visibility="gone" />
</FrameLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="72dp"
android:minHeight="72dp"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/account_photo"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_alignParentStart="true"
tools:src="@drawable/ic_contact_picture_fallback" />
<TextView
android:id="@+id/account_alias"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="16dp"
android:layout_toEndOf="@id/account_photo"
android:layout_toStartOf="@id/error_indicator"
android:focusable="false"
android:gravity="start"
android:textAlignment="viewStart"
android:textAppearance="@style/ListPrimary"
tools:text="Jami account" />
<TextView
android:id="@+id/account_host"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/account_alias"
android:layout_toEndOf="@id/account_photo"
android:layout_toStartOf="@id/error_indicator"
android:ellipsize="middle"
android:focusable="false"
android:gravity="start"
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/ListSecondary"
tools:text="testaccount" />
<ImageView
android:id="@+id/error_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="16dp"
android:layout_toStartOf="@id/account_checked"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:tint="@color/colorError"
android:visibility="gone"
app:srcCompat="@drawable/baseline_error_24" />
<ProgressBar
android:id="@+id/loading_indicator"
style="?android:attr/progressBarStyleSmall"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"