/**
* 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.pages.extendedcursor;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import com.waz.api.EphemeralExpiration;
import com.waz.zclient.R;
import com.waz.zclient.controllers.globallayout.KeyboardHeightObserver;
import com.waz.zclient.controllers.globallayout.KeyboardVisibilityObserver;
import com.waz.zclient.pages.extendedcursor.emoji.EmojiKeyboardLayout;
import com.waz.zclient.pages.extendedcursor.ephemeral.EphemeralLayout;
import com.waz.zclient.pages.extendedcursor.image.CursorImagesLayout;
import com.waz.zclient.pages.extendedcursor.voicefilter.VoiceFilterLayout;
import com.waz.zclient.ui.animation.interpolators.penner.Expo;
import com.waz.zclient.ui.utils.KeyboardUtils;
import com.waz.zclient.utils.ViewUtils;
import java.util.List;
import java.util.Set;
public class ExtendedCursorContainer extends FrameLayout implements KeyboardHeightObserver,
KeyboardVisibilityObserver {
private static final String PREF__NAME = "PREF__NAME";
private static final String PREF__KEY__KEYBOARD_HEIGHT = "PREF__KEY__KEYBOARD_HEIGHT";
private static final String PREF__KEY__KEYBOARD_HEIGHT_LANDSCAPE = "PREF__KEY__KEYBOARD_HEIGHT_LANDSCAPE";
private Callback callback;
public enum Type {
NONE,
VOICE_FILTER_RECORDING,
IMAGES,
EMOJIS,
EPHEMERAL
}
private final SharedPreferences sharedPreferences;
private int defaultExtendedContainerHeight;
private Type type;
private int accentColor;
private boolean isExpanded;
private VoiceFilterLayout voiceFilterLayout;
private EmojiKeyboardLayout emojiKeyboardLayout;
private EphemeralLayout ephemeralLayout;
private int keyboardHeightLandscape;
private int keyboardHeight;
private CursorImagesLayout cursorImagesLayout;
public ExtendedCursorContainer(Context context) {
this(context, null);
}
public ExtendedCursorContainer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExtendedCursorContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
sharedPreferences = getContext().getSharedPreferences(PREF__NAME, Context.MODE_PRIVATE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//noinspection deprecation
accentColor = getResources().getColor(R.color.accent_blue);
} else {
accentColor = getResources().getColor(R.color.accent_blue, context.getTheme());
}
isExpanded = false;
type = Type.NONE;
initKeyboardHeight();
}
public void setKeyboardHeight(int height) {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (height > keyboardHeightLandscape && height > defaultExtendedContainerHeight) {
keyboardHeightLandscape = height;
sharedPreferences.edit().putInt(PREF__KEY__KEYBOARD_HEIGHT_LANDSCAPE, height).apply();
}
} else {
if (height > keyboardHeight && height > defaultExtendedContainerHeight) {
keyboardHeight = height;
sharedPreferences.edit().putInt(PREF__KEY__KEYBOARD_HEIGHT_LANDSCAPE, height).apply();
}
}
updateHeight();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateHeight();
}
public void openVoiceFilter(VoiceFilterLayout.Callback callback) {
openWithType(Type.VOICE_FILTER_RECORDING);
voiceFilterLayout.setCallback(callback);
}
public void openCursorImages(CursorImagesLayout.Callback callback) {
openWithType(Type.IMAGES);
cursorImagesLayout.setCallback(callback);
}
public void openEmojis(List<String> recent,
Set<String> unsupported,
EmojiKeyboardLayout.Callback callback) {
openWithType(Type.EMOJIS);
emojiKeyboardLayout.setCallback(callback);
emojiKeyboardLayout.setEmojis(recent, unsupported);
}
public void openEphemeral(EphemeralLayout.Callback callback, EphemeralExpiration expiration) {
openWithType(Type.EPHEMERAL);
ephemeralLayout.setSelectedExpiration(expiration);
ephemeralLayout.setCallback(callback);
}
public void setAccentColor(int accentColor) {
this.accentColor = accentColor;
switch (type) {
case NONE:
break;
case VOICE_FILTER_RECORDING:
voiceFilterLayout.setAccentColor(accentColor);
break;
}
}
@Override
public void onKeyboardHeightChanged(int keyboardHeight) {
setKeyboardHeight(keyboardHeight);
}
@Override
public void onKeyboardVisibilityChanged(boolean keyboardIsVisible, int keyboardHeight, View currentFocus) {
if (keyboardIsVisible) {
close(true);
}
}
public void close(boolean immediate) {
Type lastType = type;
type = Type.NONE;
if (!isExpanded) {
return;
}
if (callback != null) {
callback.onExtendedCursorClosed(lastType);
}
isExpanded = false;
closeCursorImages();
closeVoiceFilter();
if (immediate) {
setVisibility(View.GONE);
removeAllViews();
return;
}
setTranslationY(0);
animate()
.translationY(ViewUtils.toPx(getContext(), 160))
.setDuration(150)
.setInterpolator(new Expo.EaseOut())
.withEndAction(new Runnable() {
@Override
public void run() {
setVisibility(View.GONE);
removeAllViews();
}
});
}
public boolean isExpanded() {
return isExpanded;
}
public Type getType() {
return type;
}
private void openWithType(Type type) {
if (this.type == type) {
return;
}
this.type = type;
removeAllViews();
switch (type) {
case VOICE_FILTER_RECORDING:
closeCursorImages();
voiceFilterLayout = (VoiceFilterLayout) LayoutInflater.from(getContext()).inflate(R.layout.voice_filter_layout,
this,
false);
voiceFilterLayout.setAccentColor(accentColor);
addView(voiceFilterLayout);
break;
case IMAGES:
closeVoiceFilter();
cursorImagesLayout = (CursorImagesLayout) LayoutInflater.from(getContext()).inflate(R.layout.cursor_images_layout,
this,
false);
addView(cursorImagesLayout);
break;
case EMOJIS:
closeVoiceFilter();
closeCursorImages();
emojiKeyboardLayout = (EmojiKeyboardLayout) LayoutInflater.from(getContext()).inflate(R.layout.emoji_keyboard_layout,
this,
false);
addView(emojiKeyboardLayout);
break;
case EPHEMERAL:
closeVoiceFilter();
closeCursorImages();
ephemeralLayout = (EphemeralLayout) LayoutInflater.from(getContext()).inflate(R.layout.ephemeral_keyboard_layout, this, false);
addView(ephemeralLayout);
break;
}
if (KeyboardUtils.isKeyboardVisible(getContext())) {
KeyboardUtils.closeKeyboardIfShown((Activity) getContext());
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
animateUp();
}
}, getResources().getInteger(R.integer.animation_delay_short));
} else if (!isExpanded) {
animateUp();
}
}
private void closeVoiceFilter() {
if (voiceFilterLayout != null) {
voiceFilterLayout.onClose();
voiceFilterLayout = null;
}
}
private void closeCursorImages() {
if (cursorImagesLayout != null) {
cursorImagesLayout.onClose();
cursorImagesLayout = null;
}
}
private void animateUp() {
setTranslationY(ViewUtils.toPx(getContext(), 160));
animate()
.translationY(0)
.setDuration(150)
.setInterpolator(new Expo.EaseOut())
.withStartAction(new Runnable() {
@Override
public void run() {
setVisibility(View.VISIBLE);
}
})
.withEndAction(new Runnable() {
@Override
public void run() {
isExpanded = true;
}
});
}
private void initKeyboardHeight() {
defaultExtendedContainerHeight = getResources().getDimensionPixelSize(R.dimen.extend_container_height);
if (sharedPreferences.contains(PREF__KEY__KEYBOARD_HEIGHT)) {
keyboardHeight = sharedPreferences.getInt(PREF__KEY__KEYBOARD_HEIGHT,
getResources().getDimensionPixelSize(R.dimen.extend_container_height));
} else {
keyboardHeight = -1;
}
if (sharedPreferences.contains(PREF__KEY__KEYBOARD_HEIGHT_LANDSCAPE)) {
keyboardHeightLandscape = sharedPreferences.getInt(PREF__KEY__KEYBOARD_HEIGHT_LANDSCAPE,
getResources().getDimensionPixelSize(R.dimen.extend_container_height));
} else {
keyboardHeightLandscape = -1;
}
}
private void updateHeight() {
int newHeight = defaultExtendedContainerHeight;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (keyboardHeightLandscape != -1) {
newHeight = keyboardHeightLandscape;
}
} else {
if (keyboardHeight != -1) {
newHeight = keyboardHeight;
}
}
getLayoutParams().height = newHeight;
}
public void setCallback(Callback callback) {
this.callback = callback;
}
public interface Callback {
void onExtendedCursorClosed(ExtendedCursorContainer.Type lastType);
}
}