/*
* Copyright (c) 2015 Jarrad Hope
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package io.syng.util;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Patterns;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.afollestad.materialdialogs.MaterialDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import io.syng.R;
import io.syng.adapter.BackgroundArrayAdapter;
import io.syng.entity.Dapp;
import io.syng.entity.Profile;
public final class GeneralUtil {
public static void hideKeyBoard(View view, Context context) {
if (view == null) return;
InputMethodManager imm = (InputMethodManager)
context.getApplicationContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public static void showKeyBoard(View view, Context context) {
if (view == null) return;
InputMethodManager imm = (InputMethodManager) context.getApplicationContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
public static void createHomeScreenIcon(final Context context, final String name, final String url) {
Intent shortcutIntent = new Intent(Intent.ACTION_VIEW);
shortcutIntent.setData(Uri.parse(url));
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(context.getApplicationContext(), R.mipmap.ic_launcher));
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
context.sendBroadcast(addIntent);
}
public static void showWarningDialogIfNeed(final Context context) {
if (PrefsUtil.isFirstLaunch()) {
PrefsUtil.setFirstLaunch(false);
new AlertDialogWrapper.Builder(context)
.setTitle(R.string.warning_title)
.setMessage(R.string.warning_message)
.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
}
public static boolean processCreateDialog(Context context, MaterialDialog dialog) {
EditText name = (EditText) dialog.findViewById(R.id.et_profile_name);
EditText pass1 = (EditText) dialog.findViewById(R.id.et_profile_pass_1);
EditText pass2 = (EditText) dialog.findViewById(R.id.et_profile_pass_2);
String nameString = name.getText().toString();
String pass1String = pass1.getText().toString();
String pass2String = pass2.getText().toString();
if (TextUtils.isEmpty(nameString)) {
Toast.makeText(context, "Profile name can't be empty", Toast.LENGTH_SHORT).show();
return false;
}
if (TextUtils.isEmpty(pass1String) || TextUtils.isEmpty(pass2String)) {
Toast.makeText(context, "Password name can't be empty", Toast.LENGTH_SHORT).show();
return false;
}
if (!pass1.getText().toString().equals(pass2.getText().toString())) {
Toast.makeText(context, "Passwords should be the same!", Toast.LENGTH_SHORT).show();
return false;
} else {
Profile profile = new Profile();
profile.setName(name.getText().toString());
profile.setPassword(pass1String);
ProfileManager.addProfile(profile);
ProfileManager.setCurrentProfile(profile, pass1String);
GeneralUtil.hideKeyBoard(name, context);
GeneralUtil.hideKeyBoard(pass1, context);
GeneralUtil.hideKeyBoard(pass2, context);
return true;
}
}
public static void showProfileCreateDialog(final Context context, boolean cancelable, MaterialDialog.ButtonCallback callback) {
if (callback == null) {
callback = new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
if (processCreateDialog(context, dialog)) {
dialog.dismiss();
}
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.dismiss();
}
};
}
MaterialDialog dialog = new MaterialDialog.Builder(context)
.title("New profile")
.positiveText(R.string.dialog_button_create)
.negativeText(R.string.dialog_button_cancel)
.customView(R.layout.profile_create_dialog, true)
.autoDismiss(false)
.cancelable(cancelable)
.callback(callback)
.show();
EditText name = (EditText) dialog.findViewById(R.id.et_profile_name);
GeneralUtil.showKeyBoard(name, context);
}
public static void showProfilePasswordRequestDialog(final Context context, String profileName, MaterialDialog.ButtonCallback callback) {
if (callback == null) {
callback = new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
dialog.dismiss();
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.dismiss();
}
};
}
MaterialDialog dialog = new MaterialDialog.Builder(context)
.title((profileName != null ? profileName + " " : "") + context.getResources().getString(R.string.request_profile_password))
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.customView(R.layout.profile_password, true)
.callback(callback)
.autoDismiss(false)
.show();
EditText name = (EditText) dialog.findViewById(R.id.et_pass);
GeneralUtil.showKeyBoard(name, context);
}
public static void showDAppEditDialog(final Dapp dapp, final Context context) {
MaterialDialog dialog = new MaterialDialog.Builder(context)
.title("Edit")
.customView(R.layout.dapp_form, true)
.positiveText(R.string.save)
.negativeText(R.string.cancel)
.neutralText("Remove")
.neutralColorRes(android.R.color.holo_red_dark)
.callback(new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
EditText dappNameEdit = (EditText) dialog.findViewById(R.id.dapp_name);
EditText dappUrlEdit = (EditText) dialog.findViewById(R.id.dapp_url);
CheckBox checkBox = (CheckBox) dialog.findViewById(R.id.dapp_home_icon);
boolean homeScreenIcon = checkBox.isChecked();
String url = dappUrlEdit.getText().toString();
String name = dappNameEdit.getText().toString();
if (Patterns.WEB_URL.matcher(url.replace("dapp://", "http://")).matches()) {
dapp.setName(name);
dapp.setUrl(url);
System.out.println(url);
ProfileManager.updateDAppInProfile(ProfileManager.getCurrentProfile(), dapp);
if (homeScreenIcon) {
GeneralUtil.createHomeScreenIcon(context, name, url);
}
dialog.hide();
} else {
Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.hide();
}
@Override
public void onNeutral(MaterialDialog dialog) {
ProfileManager.removeDAppInProfile(ProfileManager.getCurrentProfile(), dapp);
dialog.hide();
}
})
.autoDismiss(false)
.build();
EditText dappNameEdit = (EditText) dialog.findViewById(R.id.dapp_name);
dappNameEdit.setText(dapp.getName());
EditText dappUrlEdit = (EditText) dialog.findViewById(R.id.dapp_url);
dappUrlEdit.setText(dapp.getUrl());
dialog.show();
}
public static void showDAppCreateDialog(final Context context) {
Dialog dialog = new MaterialDialog.Builder(context)
.title("Add new DApp")
.customView(R.layout.dapp_form, true)
.positiveText(R.string.save)
.negativeText(R.string.cancel)
.callback(new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
EditText dappNameEdit = (EditText) dialog.findViewById(R.id.dapp_name);
EditText dappUrlEdit = (EditText) dialog.findViewById(R.id.dapp_url);
CheckBox checkBox = (CheckBox) dialog.findViewById(R.id.dapp_home_icon);
boolean homeScreenIcon = checkBox.isChecked();
String url = dappUrlEdit.getText().toString();
String name = dappNameEdit.getText().toString();
if (Patterns.WEB_URL.matcher(url.replace("dapp://", "http://")).matches()) {
Dapp dapp = new Dapp(name);
dapp.setUrl(url);
ProfileManager.addDAppToProfile(ProfileManager.getCurrentProfile(), dapp);
if (homeScreenIcon) {
GeneralUtil.createHomeScreenIcon(context, name, url);
}
dialog.hide();
} else {
Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.hide();
}
})
.autoDismiss(false)
.show();
EditText dappNameEdit = (EditText) dialog.findViewById(R.id.dapp_name);
GeneralUtil.showKeyBoard(dappNameEdit, context);
}
public static void showProfileImportDialog(final Context context) {
new MaterialDialog.Builder(context)
.title(R.string.wallet_title)
.customView(R.layout.wallet_import, true)
.positiveText(R.string.sImport)
.negativeText(R.string.cancel)
.callback(new MaterialDialog.ButtonCallback() {
@SuppressWarnings("TryFinallyCanBeTryWithResources")
@Override
public void onPositive(MaterialDialog dialog) {
Logger logger = LoggerFactory.getLogger("SyngApplication");
RadioButton importJsonRadio = (RadioButton) dialog.findViewById(R.id.radio_import_json);
EditText importPathEdit = (EditText) dialog.findViewById(R.id.wallet_import_path);
EditText walletPasswordEdit = (EditText) dialog.findViewById(R.id.wallet_password);
EditText currentWalletPasswordEdit = (EditText) dialog.findViewById(R.id.current_wallet_password);
String importPath = importPathEdit.getText().toString();
String password = walletPasswordEdit.getText().toString();
String currentPassword = currentWalletPasswordEdit.getText().toString();
String fileContents = null;
try {
File walletFile = new File(importPath);
if (walletFile.exists()) {
FileInputStream stream = new FileInputStream(walletFile);
try {
FileChannel fileChannel = stream.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
fileContents = Charset.defaultCharset().decode(buffer).toString();
} finally {
stream.close();
}
} else {
Toast.makeText(context, R.string.file_not_found, Toast.LENGTH_SHORT).show();
logger.warn("Wallet file not found: " + importPath);
return;
}
} catch (Exception e) {
Toast.makeText(context, R.string.error_reading_file, Toast.LENGTH_SHORT).show();
logger.error("Error reading wallet file", e);
}
if (importJsonRadio.isChecked()) {
Profile profile = ProfileManager.getCurrentProfile();
if (profile.importWallet(fileContents, password, currentPassword)) {
ProfileManager.updateProfile(profile);
ProfileManager.setCurrentProfile(profile, currentPassword);
} else {
Toast.makeText(context, R.string.invalid_wallet_password, Toast.LENGTH_SHORT).show();
}
} else {
Profile profile = ProfileManager.getCurrentProfile();
profile.importPrivateKey(fileContents, password, currentPassword);
ProfileManager.updateProfile(profile);
}
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.hide();
}
})
.build().show();
}
public static void showHeaderBackgroundDialog(final Context context) {
new MaterialDialog.Builder(context)
.adapter(new BackgroundArrayAdapter(context),
new MaterialDialog.ListCallback() {
@SuppressWarnings("ConstantConditions")
@Override
public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
BackgroundArrayAdapter adapter = (BackgroundArrayAdapter) dialog.getListView().getAdapter();
int imageResourceId = adapter.getImageResourceIdByPosition(which);
ProfileManager.setCurrentProfileBackgroundResourceId(imageResourceId);
dialog.dismiss();
}
})
.show();
}
}