/**
* Copyright 2014-present Liquid Data Intelligence S.A.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.lqd.sdk.visual;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.lang.reflect.Method;
import io.lqd.sdk.LQLog;
import io.lqd.sdk.Liquid;
import io.lqd.sdk.R;
import io.lqd.sdk.model.LQInAppMessage;
public class Modal implements InappMessage {
private LQInAppMessage mModalModel;
private PopupWindow mPopupWindow;
private ViewGroup container;
private View mRoot;
private TextView mViewMessage;
private Context mContext;
public Modal(Context context, View root, LQInAppMessage modalModel) {
mRoot = root;
mModalModel = modalModel;
mContext = context;
setUpModal();
setUpButtons();
}
public void show() {
show(0);
}
public void show(final int milliseconds){
mRoot.postDelayed(new Runnable() {
@Override
public void run() {
mPopupWindow.showAtLocation(mRoot, Gravity.CENTER, 0, 0);
}
}, milliseconds);
}
private void setUpModal() {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
container = (ViewGroup) layoutInflater.inflate(R.layout.activity_modal, null);
TextView mViewTitle = (TextView) container.findViewById(R.id.inAppMessage);
mViewMessage = (TextView) container.findViewById(R.id.textView);
Typeface HeavyLato = Typeface.createFromAsset(mContext.getAssets(), "fonts/Lato-Heavy.ttf");
Typeface RegularLato = Typeface.createFromAsset(mContext.getAssets(), "fonts/Lato-Regular.ttf");
// Set font
mViewTitle.setTypeface(HeavyLato);
mViewMessage.setTypeface(RegularLato);
// Set the background Color
((GradientDrawable) container.findViewById(R.id.modal_linear_bg_color).getBackground()).
setColor(Color.parseColor(mModalModel.getBgColor()));
// Set the text
mViewTitle.setText(mModalModel.getTitle());
mViewMessage.setText(mModalModel.getMessage());
// Set Text Color
mViewTitle.setTextColor(Color.parseColor(mModalModel.getTitleColor()));
mViewMessage.setTextColor(Color.parseColor(mModalModel.getMessageColor()));
mPopupWindow = new PopupWindow(container, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
mPopupWindow.setAnimationStyle(R.style.FadeInOutAnimation);
mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
Liquid.getInstance().showInAppMessages();
}
});
}
private void setUpButtons() {
final Button xClose = (Button) container.findViewById(R.id.xClose);
xClose.setTransformationMethod(null);
LinearLayout ctasContainer = (LinearLayout) container.findViewById(R.id.modal_buttons_container);
LinearLayout.LayoutParams layout_params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layout_params.setMargins(px(), px(), px(), px());
ctasContainer.setLayoutParams(layout_params);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
// Buttons parameters
params.weight = 1.0f;
params.width = 0;
params.height = Math.round(mViewMessage.getTextSize() * 2.66F) ;
params.setMargins(Math.round(mViewMessage.getTextSize() * 0.66F), Math.round(mViewMessage.getTextSize() * 0.66F), Math.round(mViewMessage.getTextSize() * 0.66F), Math.round(mViewMessage.getTextSize() * 0.66F));
Typeface boldLato = Typeface.createFromAsset(mContext.getAssets(), "fonts/Lato-Bold.ttf");
for(final LQInAppMessage.Cta cta : mModalModel.getCtas()) {
final Button ctaBtn = new Button(mContext);
ctaBtn.setBackgroundResource(R.drawable.buttonshape);
ctaBtn.setLayoutParams(params);
// Set button font
ctaBtn.setTypeface(boldLato);
ctaBtn.setTransformationMethod(null);
// Character Limit
if(cta.getButtonText().length() > 14)
ctaBtn.setText(cta.getButtonText().substring(0, 14));
else
ctaBtn.setText(cta.getButtonText());
// Button text size
ctaBtn.setTextSize(TypedValue.COMPLEX_UNIT_PX, getButtonTextSize());
// Button background color
ctaBtn.getBackground().setColorFilter(Color.parseColor(cta.getButtonColor()), PorterDuff.Mode.SRC_IN);
// Button text color
ctaBtn.setTextColor(Color.parseColor(cta.getButtonTextColor()));
if (Build.VERSION.SDK_INT > 15) {
ctaBtn.setOnTouchListener(new View.OnTouchListener() {
Rect mRect;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mRect = new Rect(ctaBtn.getLeft(), ctaBtn.getTop(), ctaBtn.getRight(), ctaBtn.getBottom());
ViewHelper.setAlpha(ctaBtn, 0.7F);
}
if (event.getAction() == MotionEvent.ACTION_UP) {
ViewHelper.setAlpha(ctaBtn, 1);
}
if (event.getAction() == MotionEvent.ACTION_MOVE &&
!mRect.contains(ctaBtn.getLeft() + (int) event.getX(), ctaBtn.getTop() + (int) event.getY())) {
ViewHelper.setAlpha(ctaBtn, 1);
}
return false;
}
});
}
ctaBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent mIntent = new Intent(Intent.ACTION_VIEW);
if (cta.getDeepLink() != null) {
try {
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mIntent.setData(Uri.parse(cta.getDeepLink()));
Liquid.getInstance().trackCta(cta);
mContext.startActivity(mIntent);
} catch (Exception e) {
LQLog.infoVerbose("Canceled or not properly assigned to deeplink or URL");
}
}
mPopupWindow.dismiss();
}
});
ctasContainer.addView(ctaBtn);
}
// Change x button color
xClose.setTextColor(Color.parseColor(mModalModel.getTitleColor()));
xClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Liquid.getInstance().trackDismiss(mModalModel);
mPopupWindow.dismiss();
}
});
}
private int px() {
return Math.round(getRealDimensions() * 0.013F);
}
private float getButtonTextSize() {
return mViewMessage.getTextSize();
}
private float getRealDimensions(){
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int realWidth;
int realHeight;
if (Build.VERSION.SDK_INT >= 17){
// New way to get real metrics
DisplayMetrics realMetrics = new DisplayMetrics();
display.getRealMetrics(realMetrics);
realWidth = realMetrics.widthPixels;
realHeight = realMetrics.heightPixels;
} else if (Build.VERSION.SDK_INT >= 14) {
// Reflection for this weird in-between time
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
realWidth = (Integer) mGetRawW.invoke(display);
realHeight = (Integer) mGetRawH.invoke(display);
} catch (Exception e) {
realWidth = display.getWidth();
realHeight = display.getHeight();
Log.e("Display Info", "Couldn't use reflection to get the real display metrics.");
}
} else {
// This should be close, as lower API devices should not have window navigation bars
realWidth = display.getWidth();
realHeight = display.getHeight();
}
if (realHeight < realWidth) {
realWidth = realHeight;
}
if (realWidth == 480)
realWidth = 700;
return realWidth;
}
}