Merge pull request #148 from nextcloud/contactListHeaders

extract new call item to layout
This commit is contained in:
Mario Đanić 2018-04-27 11:02:24 +02:00 committed by GitHub
commit aaf18b57a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 105 additions and 149 deletions

View file

@ -63,7 +63,7 @@ android {
} }
ext { ext {
supportLibraryVersion = '27.1.0' supportLibraryVersion = '27.1.1'
} }
@ -83,7 +83,7 @@ dependencies {
implementation 'com.android.support:multidex:1.0.3' implementation 'com.android.support:multidex:1.0.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation "io.reactivex.rxjava2:rxjava:2.1.4" implementation "io.reactivex.rxjava2:rxjava:2.1.7"
implementation 'com.bluelinelabs:conductor:2.1.4' implementation 'com.bluelinelabs:conductor:2.1.4'
implementation 'com.bluelinelabs:conductor-support:2.1.4' implementation 'com.bluelinelabs:conductor-support:2.1.4'
@ -99,17 +99,19 @@ dependencies {
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.github.aurae.retrofit2:converter-logansquare:1.4.1' implementation 'com.github.aurae.retrofit2:converter-logansquare:1.4.1'
implementation 'com.google.dagger:dagger:2.8' implementation 'com.google.dagger:dagger:2.9'
annotationProcessor 'com.google.dagger:dagger-compiler:2.8' annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
implementation 'com.github.lukaspili.autodagger2:autodagger2:1.1' implementation 'com.github.lukaspili.autodagger2:autodagger2:1.1'
annotationProcessor 'com.github.lukaspili.autodagger2:autodagger2-compiler:1.1' annotationProcessor 'com.github.lukaspili.autodagger2:autodagger2-compiler:1.1'
compileOnly 'javax.annotation:jsr250-api:1.0' // Android only
implementation 'org.greenrobot:eventbus:3.0.0' implementation 'org.greenrobot:eventbus:3.0.0'
implementation 'io.requery:requery:1.5.0' implementation 'io.requery:requery:1.5.1'
implementation 'io.requery:requery-android:1.5.0' implementation 'io.requery:requery-android:1.5.1'
implementation 'net.zetetic:android-database-sqlcipher:3.5.9' implementation 'net.zetetic:android-database-sqlcipher:3.5.9'
annotationProcessor 'io.requery:requery-processor:1.5.0' annotationProcessor 'io.requery:requery-processor:1.5.1'
implementation 'org.parceler:parceler-api:1.1.9' implementation 'org.parceler:parceler-api:1.1.9'
annotationProcessor 'org.parceler:parceler:1.1.9' annotationProcessor 'org.parceler:parceler:1.1.9'
@ -125,8 +127,6 @@ dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4' debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4' releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
debugImplementation "javax.transaction:transaction-api:1.1-rev-1"
implementation 'com.github.HITGIF:TextFieldBoxes:1.4.3' implementation 'com.github.HITGIF:TextFieldBoxes:1.4.3'
implementation 'eu.davidea:flexible-adapter:5.0.3' implementation 'eu.davidea:flexible-adapter:5.0.3'

View file

@ -1,101 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.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/>.
*/
package com.nextcloud.talk.adapters.items;
import android.view.View;
import android.widget.RelativeLayout;
import com.nextcloud.talk.R;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.items.AbstractHeaderItem;
import eu.davidea.flexibleadapter.items.IFlexible;
import eu.davidea.flexibleadapter.items.IHeader;
import eu.davidea.viewholders.FlexibleViewHolder;
public class NewCallHeaderItem extends AbstractHeaderItem<NewCallHeaderItem.HeaderViewHolder>
implements IHeader<NewCallHeaderItem.HeaderViewHolder> {
HeaderViewHolder headerViewHolder;
public NewCallHeaderItem() {
super();
setSelectable(true);
}
@Override
public boolean equals(Object o) {
return false;
}
@Override
public int getLayoutRes() {
return R.layout.rv_item_call_header;
}
@Override
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, HeaderViewHolder holder, int position, List<Object> payloads) {
headerViewHolder = holder;
if (holder.secondaryRelativeLayout.getVisibility() == View.GONE && adapter.isSelected(position)) {
togglePublicCall(true);
} else if (holder.initialRelativeLayout.getVisibility() == View.GONE && !adapter.isSelected(position)) {
togglePublicCall(false);
}
}
@Override
public HeaderViewHolder createViewHolder(View view, FlexibleAdapter adapter) {
headerViewHolder = new HeaderViewHolder(view, adapter);
return headerViewHolder;
}
public void togglePublicCall(boolean showDescription) {
if (!showDescription) {
headerViewHolder.secondaryRelativeLayout.setVisibility(View.GONE);
headerViewHolder.initialRelativeLayout.setVisibility(View.VISIBLE);
} else {
headerViewHolder.initialRelativeLayout.setVisibility(View.GONE);
headerViewHolder.secondaryRelativeLayout.setVisibility(View.VISIBLE);
}
}
static class HeaderViewHolder extends FlexibleViewHolder {
@BindView(R.id.initial_relative_layout)
public RelativeLayout initialRelativeLayout;
@BindView(R.id.secondary_relative_layout)
public RelativeLayout secondaryRelativeLayout;
/**
* Default constructor.
*/
HeaderViewHolder(View view, FlexibleAdapter adapter) {
super(view, adapter, true);
ButterKnife.bind(this, view);
}
}
}

View file

@ -44,6 +44,7 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.Button; import android.widget.Button;
import android.widget.RelativeLayout;
import com.bluelinelabs.conductor.RouterTransaction; import com.bluelinelabs.conductor.RouterTransaction;
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler; import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
@ -51,7 +52,6 @@ import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler;
import com.kennyc.bottomsheet.BottomSheet; import com.kennyc.bottomsheet.BottomSheet;
import com.nextcloud.talk.R; import com.nextcloud.talk.R;
import com.nextcloud.talk.activities.CallActivity; import com.nextcloud.talk.activities.CallActivity;
import com.nextcloud.talk.adapters.items.NewCallHeaderItem;
import com.nextcloud.talk.adapters.items.UserHeaderItem; import com.nextcloud.talk.adapters.items.UserHeaderItem;
import com.nextcloud.talk.adapters.items.UserItem; import com.nextcloud.talk.adapters.items.UserItem;
import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.api.NcApi;
@ -110,16 +110,16 @@ public class ContactsController extends BaseController implements SearchView.OnQ
public static final String TAG = "ContactsController"; public static final String TAG = "ContactsController";
private static final String KEY_SEARCH_QUERY = "ContactsController.searchQuery"; private static final String KEY_SEARCH_QUERY = "ContactsController.searchQuery";
@Nullable @BindView(R.id.initial_relative_layout)
public RelativeLayout initialRelativeLayout;
@Nullable @BindView(R.id.secondary_relative_layout)
public RelativeLayout secondaryRelativeLayout;
@Inject @Inject
UserUtils userUtils; UserUtils userUtils;
@Inject @Inject
NcApi ncApi; NcApi ncApi;
@Inject @Inject
EventBus eventBus; EventBus eventBus;
@BindView(R.id.recycler_view) @BindView(R.id.recycler_view)
RecyclerView recyclerView; RecyclerView recyclerView;
@ -153,7 +153,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
private boolean isNewConversationView; private boolean isNewConversationView;
private boolean isPublicCall; private boolean isPublicCall;
private HashMap<String, UserHeaderItem> userHeaderItems = new HashMap<String, UserHeaderItem>(); private HashMap<String, UserHeaderItem> userHeaderItems = new HashMap<>();
public ContactsController() { public ContactsController() {
super(); super();
@ -170,7 +170,11 @@ public class ContactsController extends BaseController implements SearchView.OnQ
@Override @Override
protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) { protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
return inflater.inflate(R.layout.controller_generic_rv, container, false); if (isNewConversationView) {
return inflater.inflate(R.layout.controller_contacts_rv, container, false);
} else {
return inflater.inflate(R.layout.controller_generic_rv, container, false);
}
} }
@Override @Override
@ -179,6 +183,8 @@ public class ContactsController extends BaseController implements SearchView.OnQ
eventBus.register(this); eventBus.register(this);
if (isNewConversationView) { if (isNewConversationView) {
toggleNewCallHeaderVisibility(!isPublicCall);
checkAndHandleBottomButtons(); checkAndHandleBottomButtons();
if (getActionBar() != null) { if (getActionBar() != null) {
@ -465,10 +471,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
return firstName.compareToIgnoreCase(secondName); return firstName.compareToIgnoreCase(secondName);
}); });
if (isNewConversationView) {
contactItems.add(0, new NewCallHeaderItem());
}
adapter.updateDataSet(contactItems, true); adapter.updateDataSet(contactItems, true);
searchItem.setVisible(contactItems.size() > 0); searchItem.setVisible(contactItems.size() > 0);
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
@ -610,7 +612,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
bottomButtonsLinearLayout.setVisibility(View.VISIBLE); bottomButtonsLinearLayout.setVisibility(View.VISIBLE);
} }
if (isPublicCall && adapter.getSelectedItemCount() < 2) { if (adapter.getSelectedItemCount() == 0) {
clearButton.setVisibility(View.GONE); clearButton.setVisibility(View.GONE);
} else { } else {
clearButton.setVisibility(View.VISIBLE); clearButton.setVisibility(View.VISIBLE);
@ -743,12 +745,25 @@ public class ContactsController extends BaseController implements SearchView.OnQ
checkAndHandleBottomButtons(); checkAndHandleBottomButtons();
} }
} else if (adapter.getItem(position) instanceof NewCallHeaderItem) {
adapter.toggleSelection(position);
isPublicCall = adapter.isSelected(position);
((NewCallHeaderItem) adapter.getItem(position)).togglePublicCall(isPublicCall);
checkAndHandleBottomButtons();
} }
return true; return true;
} }
@Optional
@OnClick(R.id.call_header_layout)
void toggleCallHeader() {
toggleNewCallHeaderVisibility(isPublicCall);
isPublicCall = !isPublicCall;
checkAndHandleBottomButtons();
}
private void toggleNewCallHeaderVisibility(boolean showInitialLayout) {
if (showInitialLayout) {
initialRelativeLayout.setVisibility(View.VISIBLE);
secondaryRelativeLayout.setVisibility(View.GONE);
} else {
initialRelativeLayout.setVisibility(View.GONE);
secondaryRelativeLayout.setVisibility(View.VISIBLE);
}
}
} }

View file

@ -45,6 +45,7 @@ import autodagger.AutoInjector;
import io.reactivex.CompletableObserver; import io.reactivex.CompletableObserver;
import io.reactivex.Observer; import io.reactivex.Observer;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.JavaNetCookieJar; import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import retrofit2.Retrofit; import retrofit2.Retrofit;
@ -83,6 +84,7 @@ public class AccountRemovalJob extends Job {
ncApi.unregisterDeviceForNotificationsWithNextcloud(ApiUtils.getCredentials(userEntity.getUsername(), ncApi.unregisterDeviceForNotificationsWithNextcloud(ApiUtils.getCredentials(userEntity.getUsername(),
userEntity.getToken()), ApiUtils.getUrlNextcloudPush(userEntity.getBaseUrl())) userEntity.getToken()), ApiUtils.getUrlNextcloudPush(userEntity.getBaseUrl()))
.subscribeOn(Schedulers.newThread())
.subscribe(new Observer<GenericOverall>() { .subscribe(new Observer<GenericOverall>() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {
@ -102,6 +104,7 @@ public class AccountRemovalJob extends Job {
ncApi.unregisterDeviceForNotificationsWithProxy ncApi.unregisterDeviceForNotificationsWithProxy
(ApiUtils.getCredentials(userEntity.getUsername(), (ApiUtils.getCredentials(userEntity.getUsername(),
userEntity.getToken()), ApiUtils.getUrlPushProxy(), queryMap) userEntity.getToken()), ApiUtils.getUrlPushProxy(), queryMap)
.subscribeOn(Schedulers.newThread())
.subscribe(new Observer<Void>() { .subscribe(new Observer<Void>() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {
@ -154,7 +157,9 @@ public class AccountRemovalJob extends Job {
}); });
} else { } else {
userUtils.deleteUser(userEntity.getUsername(), userUtils.deleteUser(userEntity.getUsername(),
userEntity.getBaseUrl()).subscribe(new CompletableObserver() { userEntity.getBaseUrl())
.subscribeOn(Schedulers.newThread())
.subscribe(new CompletableObserver() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {
@ -174,7 +179,9 @@ public class AccountRemovalJob extends Job {
} catch (IOException e) { } catch (IOException e) {
Log.d(TAG, "Something went wrong while removing job at parsing PushConfigurationState"); Log.d(TAG, "Something went wrong while removing job at parsing PushConfigurationState");
userUtils.deleteUser(userEntity.getUsername(), userUtils.deleteUser(userEntity.getUsername(),
userEntity.getBaseUrl()).subscribe(new CompletableObserver() { userEntity.getBaseUrl())
.subscribeOn(Schedulers.newThread())
.subscribe(new CompletableObserver() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Nextcloud Talk application
~
~ @author Andy Scherzinger
~ Copyright (C) 2018 Andy Scherzinger
~
~ 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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/rv_item_call_header"/>
<include layout="@layout/controller_generic_rv" />
</LinearLayout>

View file

@ -20,10 +20,11 @@
--> -->
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:id="@+id/generic_rv_layout"
android:layout_height="match_parent" android:layout_width="match_parent"
android:background="@color/nc_white_color"> android:layout_height="match_parent"
android:background="@color/nc_white_color">
<android.support.v4.widget.SwipeRefreshLayout <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout" android:id="@+id/swipe_refresh_layout"

View file

@ -20,10 +20,11 @@
--> -->
<RelativeLayout 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:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:id="@+id/call_header_layout"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:orientation="vertical"> android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout <RelativeLayout
android:id="@+id/initial_relative_layout" android:id="@+id/initial_relative_layout"
@ -32,25 +33,28 @@
<ImageView <ImageView
android:id="@+id/public_call_link" android:id="@+id/public_call_link"
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_marginStart="24dp" android:layout_marginEnd="8dp"
android:src="@drawable/ic_group_black_24px"/> android:layout_marginStart="@dimen/activity_horizontal_margin"
android:contentDescription="@null"
android:src="@drawable/ic_group_black_24px"
android:tint="@color/colorPrimary" />
<TextView <TextView
android:id="@+id/description_text" android:id="@+id/description_text"
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_marginEnd="24dp" android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginStart="8dp" android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_toEndOf="@id/public_call_link" android:layout_toEndOf="@id/public_call_link"
android:ellipsize="middle" android:ellipsize="middle"
android:singleLine="true" android:singleLine="true"
android:text="@string/nc_public_call" android:text="@string/nc_public_call"
android:textAppearance="?android:attr/textAppearanceListItem" android:textAppearance="?android:attr/textAppearanceListItem"
tools:text="@string/nc_public_call"/> tools:text="@string/nc_public_call" />
</RelativeLayout> </RelativeLayout>
@ -72,7 +76,7 @@
android:text="@string/nc_public_call_explanation" android:text="@string/nc_public_call_explanation"
android:textAlignment="center" android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceListItem" android:textAppearance="?android:attr/textAppearanceListItem"
tools:text="@string/nc_public_call_explanation"/> tools:text="@string/nc_public_call_explanation" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -10,7 +10,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.android.tools.build:gradle:3.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View file

@ -1,6 +1,6 @@
#Tue Sep 19 12:04:53 CEST 2017 #Thu Apr 26 16:49:12 CEST 2018
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

1
lombok.config Normal file
View file

@ -0,0 +1 @@
lombok.addGeneratedAnnotation = false