/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* 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.waz.zclient.views;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.waz.api.User;
import com.waz.zclient.R;
import com.waz.zclient.controllers.mentioning.MentioningObserver;
import com.waz.zclient.pages.BaseFragment;
import com.waz.zclient.ui.utils.MathUtils;
import com.waz.zclient.utils.ViewUtils;
import java.util.List;
public class MentioningFragment extends BaseFragment<MentioningFragment.Container> implements MentioningObserver,
MentioningAdapter.OnItemClickListener {
public static final String TAG = MentioningFragment.class.getSimpleName();
private RecyclerView recyclerView;
private MentioningAdapter mentioningAdapter;
private View markerView;
private View contentView;
private int totalWidth;
private int maxLeft;
private int maxRight;
private boolean visible;
public static Fragment getInstance() {
return new MentioningFragment();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
contentView = inflater.inflate(R.layout.mentioning_view, container, false);
recyclerView = ViewUtils.getView(contentView, R.id.rv__mentioning__list);
markerView = ViewUtils.getView(contentView, R.id.iv__mentioning__marker);
return contentView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
visible = true;
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), OrientationHelper.HORIZONTAL, false);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new SpacingItemDecorator(getResources().getDimensionPixelSize(R.dimen.mentioning__item__padding_outer)));
mentioningAdapter = new MentioningAdapter();
mentioningAdapter.setOnItemClickListener(this);
recyclerView.setAdapter(mentioningAdapter);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//noinspection deprecation
recyclerView.setBackground(ViewUtils.getRoundedRect(getResources().getDimensionPixelSize(R.dimen.mentioning__popover__height) / 2,
getResources().getColor(R.color.mentioning__popover__background)));
} else {
recyclerView.setBackground(ViewUtils.getRoundedRect(getResources().getDimensionPixelSize(R.dimen.mentioning__popover__height) / 2,
getResources().getColor(R.color.mentioning__popover__background, getContext().getTheme())));
}
recyclerView.post(new Runnable() {
@Override
public void run() {
if (getActivity() == null ||
getResources() == null ||
contentView == null) {
return;
}
maxLeft = getResources().getDimensionPixelSize(R.dimen.content__separator__avatar_container__width) -
getResources().getDimensionPixelSize(R.dimen.content__separator__chathead__size);
totalWidth = contentView.getMeasuredWidth();
maxRight = totalWidth - maxLeft;
}
});
hide();
}
@Override
public void onStart() {
super.onStart();
getControllerFactory().getMentioningController().addObserver(this);
}
@Override
public void onStop() {
getControllerFactory().getMentioningController().removeObserver(this);
super.onStop();
}
@Override
public void onDestroyView() {
mentioningAdapter = null;
if (recyclerView != null) {
recyclerView.setAdapter(null);
recyclerView = null;
}
contentView = null;
markerView = null;
super.onDestroyView();
}
@Override
public void onQueryResultChanged(@NonNull List<User> usersList) {
if (mentioningAdapter == null) {
return;
}
mentioningAdapter.setUsers(usersList);
if (usersList.size() == 0) {
hide();
} else {
show();
}
}
@Override
public void onMentionedUserSelected(@NonNull String query, @NonNull User user) {
hide();
}
@Override
public void onCursorPositionChanged(final float x, final float y) {
// TODO: Position relative to y as well
recyclerView.post(new Runnable() {
@Override
public void run() {
if (recyclerView == null) {
return;
}
final int recyclerViewWidth = recyclerView.getWidth();
final LinearLayout.LayoutParams recyclerViewLP = (LinearLayout.LayoutParams) recyclerView.getLayoutParams();
recyclerViewLP.leftMargin = (int) MathUtils.clamp(x - (recyclerViewWidth / 2),
maxLeft,
maxRight - recyclerViewWidth);
recyclerView.setLayoutParams(recyclerViewLP);
final int markerViewWidth = markerView.getWidth();
final LinearLayout.LayoutParams markerLP = (LinearLayout.LayoutParams) markerView.getLayoutParams();
markerLP.leftMargin = (int) (x - (markerViewWidth / 2));
markerView.setLayoutParams(markerLP);
final ViewGroup.LayoutParams contentLP = contentView.getLayoutParams();
if (contentLP instanceof ViewGroup.MarginLayoutParams) {
((ViewGroup.MarginLayoutParams) contentLP).bottomMargin =
getResources().getDimensionPixelSize(R.dimen.cursor__black_box__height);
contentView.setLayoutParams(contentLP);
}
if (visible && contentView.getVisibility() != View.VISIBLE) {
contentView.setVisibility(View.VISIBLE);
} else if (!visible && contentView.getVisibility() != View.GONE) {
contentView.setVisibility(View.GONE);
}
}
});
}
@Override
public void onItemClick(User user) {
if (user == null) {
return;
}
getControllerFactory().getMentioningController().completeUser(user);
}
private void show() {
if (contentView == null ||
(visible && contentView.getVisibility() == View.INVISIBLE) ||
contentView.getVisibility() == View.VISIBLE) {
return;
}
visible = true;
contentView.setVisibility(View.INVISIBLE);
}
private void hide() {
if (contentView == null || !visible) {
return;
}
visible = false;
contentView.setVisibility(View.GONE);
}
public interface Container {
}
private static class SpacingItemDecorator extends RecyclerView.ItemDecoration {
private final int space;
SpacingItemDecorator(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
final int position = params.getViewLayoutPosition();
final int itemCount = parent.getAdapter().getItemCount() - 1;
if (position > 0 && position < itemCount) {
outRect.left = space;
outRect.right = space;
} else if (position == 0) {
outRect.right = space;
} else if (position == itemCount) {
outRect.left = space;
}
}
}
}