/* * Created by Itzik Braun on 12/3/2015. * Copyright (c) 2015 deluge. All rights reserved. * * Last Modification at: 3/12/15 4:27 PM */ package com.braunster.chatsdk.Utils; import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; import android.content.Context; import android.graphics.Point; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Display; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageLoader; import com.braunster.chatsdk.R; import com.braunster.chatsdk.Utils.helper.ChatSDKUiHelper; import com.braunster.chatsdk.Utils.volley.VolleyUtils; import com.braunster.chatsdk.adapter.ChatSDKMessagesListAdapter; import com.braunster.chatsdk.dao.BMessage; import com.braunster.chatsdk.dao.core.DaoCore; import com.braunster.chatsdk.network.BDefines; import com.braunster.chatsdk.network.TwitterManager; import com.braunster.chatsdk.object.BError; import com.github.johnpersano.supertoasts.SuperToast; import com.ortiz.touch.TouchImageView; import org.apache.commons.lang3.StringUtils; import org.jdeferred.Deferred; import org.jdeferred.Promise; import org.jdeferred.impl.DeferredObject; import org.scribe.model.Token; import org.scribe.oauth.OAuthService; import java.io.File; import java.util.concurrent.Callable; import timber.log.Timber; public class DialogUtils { public static final String TAG = DialogUtils.class.getSimpleName(); public static final boolean DEBUG = Debug.DialogUtils; /** A dialog that contain editText, Response from dialog is received through the interface.*/ public static class ChatSDKEditTextDialog extends DialogFragment implements TextView.OnEditorActionListener { private EditText mEditText; private String dialogTitle = "Title"; private EditTextDialogInterface listener; private ChatSDKUiHelper chatSDKUiHelper; public static ChatSDKEditTextDialog getInstace(){ ChatSDKEditTextDialog f = new ChatSDKEditTextDialog(); return f; } public ChatSDKEditTextDialog() { // Empty constructor required for DialogFragment } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { chatSDKUiHelper = ChatSDKUiHelper.getInstance().get(getActivity()); View view = inflater.inflate(R.layout.chat_sdk_dialog_edit_text, container); mEditText = (EditText) view.findViewById(R.id.et_enter); getDialog().setTitle(dialogTitle); // Show soft keyboard automatically mEditText.requestFocus(); getDialog().getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); // Listen to Done press on the keyboard. mEditText.setOnEditorActionListener(this); return view; } public void setTitleAndListen(String title, EditTextDialogInterface listener){ this.dialogTitle = title; this.listener = listener; } /** Option to add more callbacks to the dialog.*/ public interface EditTextDialogInterface extends DialogInterface<String>{ } @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (EditorInfo.IME_ACTION_DONE == actionId) { if (mEditText.getText().toString().isEmpty()) { SuperToast toast = chatSDKUiHelper.getAlertToast(); toast.setGravity(Gravity.TOP, 0, 0); toast.setText("Please enter chat name"); toast.show(); return true; } InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0); // Return input text to activity listener.onFinished(mEditText.getText().toString()); this.dismiss(); return true; } return false; } } public static class ChatSDKTwitterLoginDialog extends DialogFragment { private static final String PROTECTED_RESOURCE_URL = "https://api.twitter.com/1.1/account/verify_credentials.json"; protected EditText etPin; private WebView webView; private OAuthService service; private Token requestToken; private LinearLayout progressBar; private Deferred<Object, BError, Void> deferred = new DeferredObject<>(); /** indicator that the login process has started, It is used to keep the webview hiding when the onPageFinished mehod is evoked.*/ private boolean loginIn = false; public static ChatSDKTwitterLoginDialog getInstance(){ ChatSDKTwitterLoginDialog dialog = new ChatSDKTwitterLoginDialog(); return dialog; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.chat_sdk_dialog_twitter_login, null); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); Display display = getActivity().getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x; int height = size.y; view.findViewById(R.id.content).setLayoutParams(new RelativeLayout.LayoutParams(width, height)); webView = (WebView) view.findViewById(R.id.webView); etPin = ((EditText)view.findViewById(R.id.chat_sdk_et_pin_code)); progressBar = (LinearLayout) view.findViewById(R.id.chat_sdk_progressbar); webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (DEBUG) Timber.v("shouldOverrideUrlLoading, Url: %s", url); if (url.startsWith(getString(R.string.twitter_callback_url) + "?denied")) { deferred.reject(BError.getError(BError.Code.OPERATION_FAILED, "Cancelled.")); dismiss(); return false; } if (!url.startsWith(getString(R.string.twitter_callback_url) + "?oauth_token")) return false; Uri uri = Uri.parse(url); String ver = uri.getQueryParameter("oauth_verifier"); TwitterManager.getVerifierThread(getActivity(), ver, deferred).start(); ((TextView) progressBar.findViewById(R.id.chat_sdk_progressbar_text)).setText(getActivity().getResources().getString(R.string.connecting)); webView.setVisibility(View.INVISIBLE); progressBar.setVisibility(View.VISIBLE); loginIn = true; return true; } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (DEBUG) Timber.v("onPageFinished, Url: %s", url ); if (loginIn) return; progressBar.setVisibility(View.INVISIBLE); webView.setVisibility(View.VISIBLE); } }); etPin.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { if (etPin.getText().toString().isEmpty()) return true; TwitterManager.getVerifierThread(getActivity(), etPin.getText().toString(), deferred).start(); } return false; } }); view.findViewById(R.id.chat_sdk_btn_done).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { TwitterManager.getVerifierThread(getActivity(), etPin.getText().toString(), deferred).start(); } }); TwitterManager.getAuthorizationURLThread(getActivity(), handler).start(); return view; } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case TwitterManager.ERROR: deferred.reject((BError) msg.obj); break; case TwitterManager.SUCCESS: webView.loadUrl((String) msg.obj); break; } } }; public Promise<Object, BError, Void> promise(){ return deferred.promise(); } } /** A popup to select the type of message to send, "Text", "Image", "Location".*/ public static PopupWindow getMenuOptionPopup(Context context, View.OnClickListener listener){ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View popupView = inflater.inflate(R.layout.chat_sdk_popup_options, null); PopupWindow optionPopup = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); popupView.findViewById(R.id.chat_sdk_btn_choose_picture).setOnClickListener(listener); popupView.findViewById(R.id.chat_sdk_btn_take_picture).setOnClickListener(listener); popupView.findViewById(R.id.chat_sdk_btn_location).setOnClickListener(listener); if (!BDefines.Options.LocationEnabled || context.getString(R.string.google_maps_api_key).isEmpty()){ popupView.findViewById(R.id.chat_sdk_btn_location).setVisibility(View.GONE); } popupView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); // TODO fix popup size to wrap view size. optionPopup.setContentView(popupView); optionPopup.setBackgroundDrawable(new BitmapDrawable()); optionPopup.setOutsideTouchable(true); optionPopup.setWidth(popupView.getMeasuredWidth()); optionPopup.setHeight(popupView.getMeasuredHeight()); return optionPopup; } /** Full screen popup for showing an image in greater size.*/ public static ImagePopupWindow getImageDialog(final Context context, String data, final ImagePopupWindow.LoadTypes loadingType){ return getImageDialog(context, data, loadingType, false, ""); } public static ImagePopupWindow getImageMessageDialog(final Context context, String data, final ImagePopupWindow.LoadTypes loadingType, ChatSDKMessagesListAdapter.MessageListItem message){ return getImageDialog(context, data, loadingType, true, message.entityId); } private static ImagePopupWindow getImageDialog(final Context context, String data, final ImagePopupWindow.LoadTypes loadingType, boolean saveAfterLoad, String imageName){ if (StringUtils.isEmpty(data)) return null; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View popupView = inflater.inflate(R.layout.chat_sdk_popup_touch_image, null); // Full screen popup. final ImagePopupWindow imagePopup = new ImagePopupWindow(context, popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true); imagePopup.setData(data); imagePopup.setImageName(imageName); imagePopup.setLoadingType(loadingType); imagePopup.saveToImageDir(saveAfterLoad); imagePopup.setContentView(popupView); imagePopup.setBackgroundDrawable(new BitmapDrawable()); imagePopup.setOutsideTouchable(true); imagePopup.setAnimationStyle(R.style.ImagePopupAnimation); imagePopup.load(); return imagePopup; } public static class ImagePopupWindow extends PopupWindow{ private boolean saveToDir =false; private LoadTypes loadingType; private Context context; private String data; private ChatSDKUiHelper chatSDKUiHelper; private String imageName = ""; private View popupView; /** Type indicate from where to load the file.*/ public enum LoadTypes{ LOAD_FROM_PATH, LOAD_FROM_URL, LOAD_FROM_LRU_CACHE; } public ImagePopupWindow(Context ctx, View popupView, int width, int height, boolean focusable) { super(popupView, width, height, focusable); this.context = ctx; this.popupView = popupView; chatSDKUiHelper = ChatSDKUiHelper.getInstance().get(context); } public void load(){ // Dismiss popup when clicked. popupView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); final TouchImageView imageView = (TouchImageView) popupView.findViewById(R.id.chat_sdk_popup_image_imageview); final ProgressBar progressBar = (ProgressBar) popupView.findViewById(R.id.chat_sdk_popup_image_progressbar); switch (loadingType) { case LOAD_FROM_URL: if (DEBUG) Timber.d("load from url"); VolleyUtils.getImageLoader().get(data, new ImageLoader.ImageListener() { @Override public void onResponse(final ImageLoader.ImageContainer response, boolean isImmediate) { if (isImmediate && response.getBitmap() == null) progressBar.setVisibility(View.VISIBLE); if (response.getBitmap() != null) { imageView.setImageBitmap(response.getBitmap()); if (saveToDir) { File file, dir = Utils.ImageSaver.getAlbumStorageDir(context, Utils.ImageSaver.IMAGE_DIR_NAME); if (dir != null) if(dir.exists()) { file = new File(dir, imageName + ".jpg"); if (!file.exists()) { ImageUtils.saveBitmapToFile(file, response.getBitmap()); ImageUtils.scanFilePathForGallery(context, file.getPath()); // If the message name is equal to a message entity id we // save the image path to the message object so we could use it instead of downloading images. BMessage message = DaoCore.fetchEntityWithEntityID(BMessage.class, imageName); if (message != null) { message.setResourcesPath(file.getPath()); DaoCore.updateEntity(message); } } else if (DEBUG) Timber.d("Image is already saved in image dir"); } } animateIn(imageView, progressBar); } } @Override public void onErrorResponse(VolleyError error) { progressBar.setVisibility(View.GONE); chatSDKUiHelper.showAlertToast(R.string.unable_to_fetch_image); dismiss(); } }); break; case LOAD_FROM_PATH: if (DEBUG) Timber.d("load from path"); imageView.setImageBitmap(ImageUtils.loadBitmapFromFile(data)); animateIn(imageView, progressBar); break; case LOAD_FROM_LRU_CACHE: if (DEBUG) Timber.d("load from cache"); imageView.setImageBitmap(VolleyUtils.getBitmapCache().getBitmap(data)); animateIn(imageView, progressBar); } } private void animateIn(final ImageView imageView, final ProgressBar progressBar){ imageView.startAnimation(AnimationUtils.loadAnimation(context, android.R.anim.fade_in)); imageView.getAnimation().setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { progressBar.setVisibility(View.GONE); } @Override public void onAnimationEnd(Animation animation) { imageView.setVisibility(View.VISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); } public void saveToImageDir(boolean saveToDir) { this.saveToDir = saveToDir; } public void setData(String data) { this.data = data; } public void setLoadingType(LoadTypes loadingType) { this.loadingType = loadingType; } public void setImageName(String imageName) { this.imageName = imageName; } } /** Basic interface for getting callback from the dialog.*/ public interface DialogInterface<T>{ public void onFinished(T t); } public static void showAlertDialog(Activity activity, String title, String alert, String p, String n, final Callable neg, final Callable pos){ final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity); // set title if not null if (title != null && !title.equals("")) alertDialogBuilder.setTitle(title); // set dialog message alertDialogBuilder .setMessage(alert) .setCancelable(false) .setPositiveButton(p, new android.content.DialogInterface.OnClickListener() { public void onClick(android.content.DialogInterface dialog, int id) { if (pos != null) try { pos.call(); } catch (Exception e) { e.printStackTrace(); } dialog.dismiss(); } }) .setNegativeButton(n, new android.content.DialogInterface.OnClickListener() { public void onClick(android.content.DialogInterface dialog, int id) { // if this button is clicked, just close // the dialog box and do nothing if (neg != null) try { neg.call(); } catch (Exception e) { e.printStackTrace(); } dialog.cancel(); } }); // create alert dialog AlertDialog alertDialog = alertDialogBuilder.create(); // show it alertDialog.show(); } }