diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..ecd817f
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..3b31283
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 71e50ab..afe79ae 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -4,6 +4,8 @@
+
+
diff --git a/.travis.yml b/.travis.yml
index 70085e5..3538182 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,8 +4,8 @@ android:
components:
- tools
- platform-tools
- - build-tools-24.0.1
- - android-24
+ - build-tools-26.0.0
+ - android-26
- extra-android-support
- extra-android-m2repository
- extra-google-m2repository
diff --git a/app/build.gradle b/app/build.gradle
index 8d11f08..7ca4beb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,15 +1,15 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 24
- buildToolsVersion "24.0.1"
+ compileSdkVersion versions.compileSdk
+ buildToolsVersion versions.buildTools
defaultConfig {
applicationId "com.afollestad.nocknock"
- minSdkVersion 21
- targetSdkVersion 24
- versionCode 14
- versionName "0.1.3.1"
+ minSdkVersion versions.minSdk
+ targetSdkVersion versions.compileSdk
+ versionCode versions.publishVersionCode
+ versionName versions.publishVersion
lintOptions {
abortOnError false
@@ -33,11 +33,11 @@ android {
}
dependencies {
- compile 'com.android.support:appcompat-v7:24.2.0'
- compile 'com.android.support:design:24.2.0'
- compile 'com.afollestad.material-dialogs:core:0.9.0.1'
- compile 'com.afollestad.material-dialogs:commons:0.9.0.1'
- compile 'com.afollestad:bridge:3.2.5'
- compile 'com.afollestad:inquiry:3.2.1'
+ compile 'com.android.support:appcompat-v7:' + versions.supportLib
+ compile 'com.android.support:design:' + versions.supportLib
+ compile 'com.afollestad.material-dialogs:core:' + versions.materialDialogs
+ compile 'com.afollestad.material-dialogs:commons:' + versions.materialDialogs
+ compile 'com.afollestad:bridge:' + versions.bridge
+ compile 'com.afollestad:inquiry:' + versions.inquiry
compile files('libs/rhino-1.7.7.1.jar')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/afollestad/nocknock/adapter/ServerAdapter.java b/app/src/main/java/com/afollestad/nocknock/adapter/ServerAdapter.java
index b4da56b..0de2c5b 100644
--- a/app/src/main/java/com/afollestad/nocknock/adapter/ServerAdapter.java
+++ b/app/src/main/java/com/afollestad/nocknock/adapter/ServerAdapter.java
@@ -5,167 +5,165 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-
import com.afollestad.nocknock.R;
import com.afollestad.nocknock.api.ServerModel;
import com.afollestad.nocknock.api.ServerStatus;
import com.afollestad.nocknock.util.TimeUtil;
import com.afollestad.nocknock.views.StatusImageView;
-
import java.util.ArrayList;
import java.util.Collections;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class ServerAdapter extends RecyclerView.Adapter {
- private final Object LOCK = new Object();
- private ArrayList mServers;
- private ClickListener mListener;
+ private final Object LOCK = new Object();
+ private ArrayList mServers;
+ private ClickListener mListener;
- public interface ClickListener {
- void onSiteSelected(int index, ServerModel model, boolean longClick);
+ public interface ClickListener {
+ void onSiteSelected(int index, ServerModel model, boolean longClick);
+ }
+
+ public void performClick(int index, boolean longClick) {
+ if (mListener != null) {
+ mListener.onSiteSelected(index, mServers.get(index), longClick);
}
+ }
- public void performClick(int index, boolean longClick) {
- if (mListener != null) {
- mListener.onSiteSelected(index, mServers.get(index), longClick);
+ public ServerAdapter(ClickListener listener) {
+ mListener = listener;
+ mServers = new ArrayList<>(2);
+ }
+
+ public void add(ServerModel model) {
+ mServers.add(model);
+ notifyItemInserted(mServers.size() - 1);
+ }
+
+ public void update(int index, ServerModel model) {
+ mServers.set(index, model);
+ notifyItemChanged(index);
+ }
+
+ public void update(ServerModel model) {
+ synchronized (LOCK) {
+ for (int i = 0; i < mServers.size(); i++) {
+ if (mServers.get(i).id == model.id) {
+ update(i, model);
+ break;
}
+ }
}
+ }
- public ServerAdapter(ClickListener listener) {
- mListener = listener;
- mServers = new ArrayList<>(2);
- }
+ public void remove(int index) {
+ mServers.remove(index);
+ notifyItemRemoved(index);
+ }
- public void add(ServerModel model) {
- mServers.add(model);
- notifyItemInserted(mServers.size() - 1);
- }
-
- public void update(int index, ServerModel model) {
- mServers.set(index, model);
- notifyItemChanged(index);
- }
-
- public void update(ServerModel model) {
- synchronized (LOCK) {
- for (int i = 0; i < mServers.size(); i++) {
- if (mServers.get(i).id == model.id) {
- update(i, model);
- break;
- }
- }
+ public void remove(ServerModel model) {
+ synchronized (LOCK) {
+ for (int i = 0; i < mServers.size(); i++) {
+ if (mServers.get(i).id == model.id) {
+ remove(i);
+ break;
}
+ }
+ }
+ }
+
+ public void set(ServerModel[] models) {
+ if (models == null || models.length == 0) {
+ mServers.clear();
+ return;
+ }
+ mServers = new ArrayList<>(models.length);
+ Collections.addAll(mServers, models);
+ notifyDataSetChanged();
+ }
+
+ public void clear() {
+ mServers.clear();
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public ServerAdapter.ServerVH onCreateViewHolder(ViewGroup parent, int viewType) {
+ final View v =
+ LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_server, parent, false);
+ return new ServerVH(v, this);
+ }
+
+ @Override
+ public void onBindViewHolder(ServerAdapter.ServerVH holder, int position) {
+ final ServerModel model = mServers.get(position);
+
+ holder.textName.setText(model.name);
+ holder.textUrl.setText(model.url);
+ holder.iconStatus.setStatus(model.status);
+
+ switch (model.status) {
+ case ServerStatus.OK:
+ holder.textStatus.setText(R.string.everything_checks_out);
+ break;
+ case ServerStatus.WAITING:
+ holder.textStatus.setText(R.string.waiting);
+ break;
+ case ServerStatus.CHECKING:
+ holder.textStatus.setText(R.string.checking_status);
+ break;
+ case ServerStatus.ERROR:
+ holder.textStatus.setText(model.reason);
+ break;
}
- public void remove(int index) {
- mServers.remove(index);
- notifyItemRemoved(index);
+ if (model.checkInterval <= 0) {
+ holder.textInterval.setText("");
+ } else {
+ final long now = System.currentTimeMillis();
+ final long nextCheck = model.lastCheck + model.checkInterval;
+ final long difference = nextCheck - now;
+ holder.textInterval.setText(TimeUtil.str(difference));
}
+ }
- public void remove(ServerModel model) {
- synchronized (LOCK) {
- for (int i = 0; i < mServers.size(); i++) {
- if (mServers.get(i).id == model.id) {
- remove(i);
- break;
- }
- }
- }
- }
+ @Override
+ public int getItemCount() {
+ return mServers.size();
+ }
- public void set(ServerModel[] models) {
- if (models == null || models.length == 0) {
- mServers.clear();
- return;
- }
- mServers = new ArrayList<>(models.length);
- Collections.addAll(mServers, models);
- notifyDataSetChanged();
- }
+ public static class ServerVH extends RecyclerView.ViewHolder
+ implements View.OnClickListener, View.OnLongClickListener {
- public void clear() {
- mServers.clear();
- notifyDataSetChanged();
+ final StatusImageView iconStatus;
+ final TextView textName;
+ final TextView textInterval;
+ final TextView textUrl;
+ final TextView textStatus;
+ final ServerAdapter adapter;
+
+ public ServerVH(View itemView, ServerAdapter adapter) {
+ super(itemView);
+ iconStatus = (StatusImageView) itemView.findViewById(R.id.iconStatus);
+ textName = (TextView) itemView.findViewById(R.id.textName);
+ textInterval = (TextView) itemView.findViewById(R.id.textInterval);
+ textUrl = (TextView) itemView.findViewById(R.id.textUrl);
+ textStatus = (TextView) itemView.findViewById(R.id.textStatus);
+ this.adapter = adapter;
+
+ itemView.setOnClickListener(this);
+ itemView.setOnLongClickListener(this);
}
@Override
- public ServerAdapter.ServerVH onCreateViewHolder(ViewGroup parent, int viewType) {
- final View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_server, parent, false);
- return new ServerVH(v, this);
+ public void onClick(View view) {
+ adapter.performClick(getAdapterPosition(), false);
}
@Override
- public void onBindViewHolder(ServerAdapter.ServerVH holder, int position) {
- final ServerModel model = mServers.get(position);
-
- holder.textName.setText(model.name);
- holder.textUrl.setText(model.url);
- holder.iconStatus.setStatus(model.status);
-
- switch (model.status) {
- case ServerStatus.OK:
- holder.textStatus.setText(R.string.everything_checks_out);
- break;
- case ServerStatus.WAITING:
- holder.textStatus.setText(R.string.waiting);
- break;
- case ServerStatus.CHECKING:
- holder.textStatus.setText(R.string.checking_status);
- break;
- case ServerStatus.ERROR:
- holder.textStatus.setText(model.reason);
- break;
- }
-
- if (model.checkInterval <= 0) {
- holder.textInterval.setText("");
- } else {
- final long now = System.currentTimeMillis();
- final long nextCheck = model.lastCheck + model.checkInterval;
- final long difference = nextCheck - now;
- holder.textInterval.setText(TimeUtil.str(difference));
- }
- }
-
- @Override
- public int getItemCount() {
- return mServers.size();
- }
-
- public static class ServerVH extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
-
- final StatusImageView iconStatus;
- final TextView textName;
- final TextView textInterval;
- final TextView textUrl;
- final TextView textStatus;
- final ServerAdapter adapter;
-
- public ServerVH(View itemView, ServerAdapter adapter) {
- super(itemView);
- iconStatus = (StatusImageView) itemView.findViewById(R.id.iconStatus);
- textName = (TextView) itemView.findViewById(R.id.textName);
- textInterval = (TextView) itemView.findViewById(R.id.textInterval);
- textUrl = (TextView) itemView.findViewById(R.id.textUrl);
- textStatus = (TextView) itemView.findViewById(R.id.textStatus);
- this.adapter = adapter;
-
- itemView.setOnClickListener(this);
- itemView.setOnLongClickListener(this);
- }
-
- @Override
- public void onClick(View view) {
- adapter.performClick(getAdapterPosition(), false);
- }
-
- @Override
- public boolean onLongClick(View view) {
- adapter.performClick(getAdapterPosition(), true);
- return false;
- }
+ public boolean onLongClick(View view) {
+ adapter.performClick(getAdapterPosition(), true);
+ return false;
}
+ }
}
diff --git a/app/src/main/java/com/afollestad/nocknock/api/ServerModel.java b/app/src/main/java/com/afollestad/nocknock/api/ServerModel.java
index 1e3b6df..6fe6bc3 100644
--- a/app/src/main/java/com/afollestad/nocknock/api/ServerModel.java
+++ b/app/src/main/java/com/afollestad/nocknock/api/ServerModel.java
@@ -1,36 +1,23 @@
package com.afollestad.nocknock.api;
import com.afollestad.inquiry.annotations.Column;
-
import java.io.Serializable;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class ServerModel implements Serializable {
- public ServerModel() {
- }
+ public ServerModel() {}
- @Column(name = "_id", primaryKey = true, notNull = true, autoIncrement = true)
- public long id;
- @Column
- public String name;
- @Column
- public String url;
- @Column
- @ServerStatus.Enum
- public int status;
- @Column
- public long checkInterval;
- @Column
- public long lastCheck;
- @Column
- public String reason;
+ @Column(name = "_id", primaryKey = true, notNull = true, autoIncrement = true)
+ public long id;
- @Column
- @ValidationMode.Enum
- public int validationMode;
- @Column
- public String validationContent;
-}
\ No newline at end of file
+ @Column public String name;
+ @Column public String url;
+ @Column @ServerStatus.Enum public int status;
+ @Column public long checkInterval;
+ @Column public long lastCheck;
+ @Column public String reason;
+
+ @Column @ValidationMode.Enum public int validationMode;
+ @Column public String validationContent;
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/api/ServerStatus.java b/app/src/main/java/com/afollestad/nocknock/api/ServerStatus.java
index f7f98fe..93bf2c8 100644
--- a/app/src/main/java/com/afollestad/nocknock/api/ServerStatus.java
+++ b/app/src/main/java/com/afollestad/nocknock/api/ServerStatus.java
@@ -1,21 +1,18 @@
package com.afollestad.nocknock.api;
import android.support.annotation.IntDef;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public final class ServerStatus {
- public final static int OK = 1;
- public final static int WAITING = 2;
- public final static int CHECKING = 3;
- public final static int ERROR = 4;
+ public static final int OK = 1;
+ public static final int WAITING = 2;
+ public static final int CHECKING = 3;
+ public static final int ERROR = 4;
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({OK, WAITING, CHECKING, ERROR})
- public @interface Enum {}
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({OK, WAITING, CHECKING, ERROR})
+ public @interface Enum {}
}
diff --git a/app/src/main/java/com/afollestad/nocknock/api/ValidationMode.java b/app/src/main/java/com/afollestad/nocknock/api/ValidationMode.java
index 2606635..bf1a524 100644
--- a/app/src/main/java/com/afollestad/nocknock/api/ValidationMode.java
+++ b/app/src/main/java/com/afollestad/nocknock/api/ValidationMode.java
@@ -1,21 +1,17 @@
package com.afollestad.nocknock.api;
import android.support.annotation.IntDef;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public final class ValidationMode {
- public final static int STATUS_CODE = 1;
- public final static int TERM_SEARCH = 2;
- public final static int JAVASCRIPT = 3;
+ public static final int STATUS_CODE = 1;
+ public static final int TERM_SEARCH = 2;
+ public static final int JAVASCRIPT = 3;
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({STATUS_CODE, TERM_SEARCH, JAVASCRIPT})
- public @interface Enum {
- }
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATUS_CODE, TERM_SEARCH, JAVASCRIPT})
+ public @interface Enum {}
}
diff --git a/app/src/main/java/com/afollestad/nocknock/dialogs/AboutDialog.java b/app/src/main/java/com/afollestad/nocknock/dialogs/AboutDialog.java
index 3eeed80..e61ed75 100644
--- a/app/src/main/java/com/afollestad/nocknock/dialogs/AboutDialog.java
+++ b/app/src/main/java/com/afollestad/nocknock/dialogs/AboutDialog.java
@@ -6,28 +6,25 @@ import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
-
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.nocknock.R;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class AboutDialog extends DialogFragment {
- public static void show(AppCompatActivity context) {
- AboutDialog dialog = new AboutDialog();
- dialog.show(context.getSupportFragmentManager(), "[ABOUT_DIALOG]");
- }
+ public static void show(AppCompatActivity context) {
+ AboutDialog dialog = new AboutDialog();
+ dialog.show(context.getSupportFragmentManager(), "[ABOUT_DIALOG]");
+ }
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return new MaterialDialog.Builder(getActivity())
- .title(R.string.about)
- .positiveText(R.string.dismiss)
- .content(Html.fromHtml(getString(R.string.about_body)))
- .contentLineSpacing(1.6f)
- .build();
- }
-}
\ No newline at end of file
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new MaterialDialog.Builder(getActivity())
+ .title(R.string.about)
+ .positiveText(R.string.dismiss)
+ .content(Html.fromHtml(getString(R.string.about_body)))
+ .contentLineSpacing(1.6f)
+ .build();
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/receivers/BootReceiver.java b/app/src/main/java/com/afollestad/nocknock/receivers/BootReceiver.java
index 7bb96e5..31729e2 100644
--- a/app/src/main/java/com/afollestad/nocknock/receivers/BootReceiver.java
+++ b/app/src/main/java/com/afollestad/nocknock/receivers/BootReceiver.java
@@ -3,26 +3,21 @@ package com.afollestad.nocknock.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-
import com.afollestad.inquiry.Inquiry;
import com.afollestad.nocknock.api.ServerModel;
import com.afollestad.nocknock.ui.MainActivity;
import com.afollestad.nocknock.util.AlarmUtil;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class BootReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
- final Inquiry inq = Inquiry.newInstance(context, MainActivity.DB_NAME).build(false);
- ServerModel[] models = inq
- .selectFrom(MainActivity.SITES_TABLE_NAME, ServerModel.class)
- .all();
- AlarmUtil.setSiteChecks(context, models);
- inq.destroyInstance();
- }
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
+ final Inquiry inq = Inquiry.newInstance(context, MainActivity.DB_NAME).build(false);
+ ServerModel[] models = inq.selectFrom(MainActivity.SITES_TABLE_NAME, ServerModel.class).all();
+ AlarmUtil.setSiteChecks(context, models);
+ inq.destroyInstance();
}
+ }
}
diff --git a/app/src/main/java/com/afollestad/nocknock/receivers/ConnectivityReceiver.java b/app/src/main/java/com/afollestad/nocknock/receivers/ConnectivityReceiver.java
index 7ceed62..3417ce3 100644
--- a/app/src/main/java/com/afollestad/nocknock/receivers/ConnectivityReceiver.java
+++ b/app/src/main/java/com/afollestad/nocknock/receivers/ConnectivityReceiver.java
@@ -4,22 +4,19 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
-
import com.afollestad.nocknock.services.CheckService;
import com.afollestad.nocknock.util.NetworkUtil;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class ConnectivityReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- final boolean hasInternet = NetworkUtil.hasInternet(context);
- Log.v("ConnectivityReceiver", "Connectivity state changed... has internet? " + hasInternet);
- if (hasInternet) {
- context.startService(new Intent(context, CheckService.class)
- .putExtra(CheckService.ONLY_WAITING, true));
- }
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final boolean hasInternet = NetworkUtil.hasInternet(context);
+ Log.v("ConnectivityReceiver", "Connectivity state changed... has internet? " + hasInternet);
+ if (hasInternet) {
+ context.startService(
+ new Intent(context, CheckService.class).putExtra(CheckService.ONLY_WAITING, true));
}
+ }
}
diff --git a/app/src/main/java/com/afollestad/nocknock/services/CheckService.java b/app/src/main/java/com/afollestad/nocknock/services/CheckService.java
index 2b9ab94..ad87568 100644
--- a/app/src/main/java/com/afollestad/nocknock/services/CheckService.java
+++ b/app/src/main/java/com/afollestad/nocknock/services/CheckService.java
@@ -3,7 +3,6 @@ package com.afollestad.nocknock.services;
import android.app.IntentService;
import android.app.Notification;
import android.app.PendingIntent;
-import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
@@ -13,8 +12,6 @@ import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
-import android.widget.Toast;
-
import com.afollestad.bridge.Bridge;
import com.afollestad.bridge.BridgeException;
import com.afollestad.bridge.Response;
@@ -29,213 +26,210 @@ import com.afollestad.nocknock.ui.MainActivity;
import com.afollestad.nocknock.ui.ViewSiteActivity;
import com.afollestad.nocknock.util.JsUtil;
import com.afollestad.nocknock.util.NetworkUtil;
-
import java.util.Locale;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
@SuppressWarnings("CheckResult")
public class CheckService extends IntentService {
- public static String ACTION_CHECK_UPDATE = BuildConfig.APPLICATION_ID + ".CHECK_UPDATE";
- public static String ACTION_RUNNING = BuildConfig.APPLICATION_ID + ".CHECK_RUNNING";
- public static String MODEL_ID = "model_id";
- public static String ONLY_WAITING = "only_waiting";
- public static int NOTI_ID = 3456;
+ public static String ACTION_CHECK_UPDATE = BuildConfig.APPLICATION_ID + ".CHECK_UPDATE";
+ public static String ACTION_RUNNING = BuildConfig.APPLICATION_ID + ".CHECK_RUNNING";
+ public static String MODEL_ID = "model_id";
+ public static String ONLY_WAITING = "only_waiting";
+ public static int NOTI_ID = 3456;
- public CheckService() {
- super("NockNockCheckService");
+ public CheckService() {
+ super("NockNockCheckService");
+ }
+
+ private static void LOG(String msg, Object... format) {
+ if (format != null) msg = String.format(Locale.getDefault(), msg, format);
+ Log.v("NockNockService", msg);
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ Inquiry.newInstance(this, MainActivity.DB_NAME).build();
+ isRunning(true);
+ Bridge.config().defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
+
+ final Query query =
+ Inquiry.get(this).selectFrom(MainActivity.SITES_TABLE_NAME, ServerModel.class);
+ if (intent != null && intent.hasExtra(MODEL_ID)) {
+ query.where("_id = ?", intent.getLongExtra(MODEL_ID, -1));
+ } else if (intent != null && intent.getBooleanExtra(ONLY_WAITING, false)) {
+ query.where("status = ?", ServerStatus.WAITING);
+ }
+ final ServerModel[] sites = query.all();
+
+ if (sites == null || sites.length == 0) {
+ LOG("No sites added to check, service will terminate.");
+ isRunning(false);
+ stopSelf();
+ return;
}
- private static void LOG(String msg, Object... format) {
- if (format != null)
- msg = String.format(Locale.getDefault(), msg, format);
- Log.v("NockNockService", msg);
+ LOG("Checking %d sites...", sites.length);
+ sendBroadcast(new Intent(ACTION_RUNNING));
+
+ for (ServerModel site : sites) {
+ LOG("Updating %s (%s) status to WAITING...", site.name, site.url);
+ site.status = ServerStatus.WAITING;
+ updateStatus(site);
}
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
+ if (NetworkUtil.hasInternet(this)) {
+ for (ServerModel site : sites) {
+ LOG("Checking %s (%s)...", site.name, site.url);
+ site.status = ServerStatus.CHECKING;
+ site.lastCheck = System.currentTimeMillis();
+ updateStatus(site);
- @Override
- protected void onHandleIntent(Intent intent) {
- Inquiry.newInstance(this, MainActivity.DB_NAME).build();
- isRunning(true);
- Bridge.config()
- .defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
-
- final Query query = Inquiry.get(this)
- .selectFrom(MainActivity.SITES_TABLE_NAME, ServerModel.class);
- if (intent != null && intent.hasExtra(MODEL_ID)) {
- query.where("_id = ?", intent.getLongExtra(MODEL_ID, -1));
- } else if (intent != null && intent.getBooleanExtra(ONLY_WAITING, false)) {
- query.where("status = ?", ServerStatus.WAITING);
- }
- final ServerModel[] sites = query.all();
-
- if (sites == null || sites.length == 0) {
- LOG("No sites added to check, service will terminate.");
- isRunning(false);
- stopSelf();
- return;
- }
-
- LOG("Checking %d sites...", sites.length);
- sendBroadcast(new Intent(ACTION_RUNNING));
-
- for (ServerModel site : sites) {
- LOG("Updating %s (%s) status to WAITING...", site.name, site.url);
- site.status = ServerStatus.WAITING;
- updateStatus(site);
- }
-
- if (NetworkUtil.hasInternet(this)) {
- for (ServerModel site : sites) {
- LOG("Checking %s (%s)...", site.name, site.url);
- site.status = ServerStatus.CHECKING;
- site.lastCheck = System.currentTimeMillis();
- updateStatus(site);
-
- try {
- final Response response = Bridge.get(site.url)
- .throwIfNotSuccess()
- .cancellable(false)
- .request()
- .response();
-
- site.reason = null;
- site.status = ServerStatus.OK;
-
- if (site.validationMode == ValidationMode.TERM_SEARCH) {
- final String body = response.asString();
- if (body == null || !body.contains(site.validationContent)) {
- site.status = ServerStatus.ERROR;
- site.reason = "Term \"" + site.validationContent + "\" not found in response body.";
- }
- } else if (site.validationMode == ValidationMode.JAVASCRIPT) {
- final String body = response.asString();
- site.reason = JsUtil.exec(site.validationContent, body);
- if (site.reason != null && !site.toString().isEmpty())
- site.status = ServerStatus.ERROR;
- }
-
- if (site.status == ServerStatus.ERROR)
- showNotification(this, site);
- } catch (BridgeException e) {
- processError(e, site);
- }
- updateStatus(site);
- }
- } else {
- LOG("No internet connection, waiting.");
- }
-
- isRunning(false);
- LOG("Service is finished!");
- }
-
- private void processError(BridgeException e, ServerModel site) {
- site.status = ServerStatus.OK;
- site.reason = null;
-
- switch (e.reason()) {
- case BridgeException.REASON_REQUEST_CANCELLED:
- // Shouldn't happen
- break;
- case BridgeException.REASON_REQUEST_FAILED:
- case BridgeException.REASON_RESPONSE_UNPARSEABLE:
- case BridgeException.REASON_RESPONSE_UNSUCCESSFUL:
- case BridgeException.REASON_RESPONSE_IOERROR:
- //noinspection ConstantConditions
- if (e.response() != null && e.response().code() == 401) {
- // Don't consider 401 unsuccessful here
- site.reason = null;
- } else {
- site.status = ServerStatus.ERROR;
- site.reason = e.getMessage();
- }
- break;
- case BridgeException.REASON_REQUEST_TIMEOUT:
- site.status = ServerStatus.ERROR;
- site.reason = getString(R.string.timeout);
- break;
- case BridgeException.REASON_RESPONSE_VALIDATOR_ERROR:
- case BridgeException.REASON_RESPONSE_VALIDATOR_FALSE:
- // Not used
- break;
- }
-
- if (site.status != ServerStatus.OK) {
- LOG("%s error: %s", site.name, site.reason);
- showNotification(this, site);
- }
- }
-
- private void updateStatus(ServerModel site) {
- Inquiry.get(this)
- .update(MainActivity.SITES_TABLE_NAME, ServerModel.class)
- .where("_id = ?", site.id)
- .values(site)
- .run();
- sendBroadcast(new Intent(ACTION_CHECK_UPDATE)
- .putExtra("model", site));
- }
-
- private void isRunning(boolean running) {
- PreferenceManager.getDefaultSharedPreferences(this)
- .edit().putBoolean("check_service_running", running).commit();
- }
-
- public static boolean isRunning(Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context)
- .getBoolean("check_service_running", false);
- }
-
- public static void isAppOpen(Context context, boolean open) {
- PreferenceManager.getDefaultSharedPreferences(context)
- .edit().putBoolean("is_app_open", open).commit();
- }
-
- public static boolean isAppOpen(Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context)
- .getBoolean("is_app_open", false);
- }
-
- private static void showNotification(Context context, ServerModel site) {
- if (isAppOpen(context)) {
- // Don't show notifications while the app is open
- return;
- }
-
- final NotificationManagerCompat nm = NotificationManagerCompat.from(context);
- final PendingIntent openIntent = PendingIntent.getActivity(context, 9669,
- new Intent(context, ViewSiteActivity.class)
- .putExtra("model", site)
- .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
- PendingIntent.FLAG_CANCEL_CURRENT);
- final Notification noti = new NotificationCompat.Builder(context)
- .setContentTitle(site.name)
- .setContentText(context.getString(R.string.something_wrong))
- .setContentIntent(openIntent)
- .setSmallIcon(R.drawable.ic_notification)
- .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
- .setPriority(Notification.PRIORITY_HIGH)
- .setAutoCancel(true)
- .setDefaults(Notification.DEFAULT_VIBRATE)
- .build();
- nm.notify(site.url, NOTI_ID, noti);
- }
-
- @Override
- public void onDestroy() {
try {
- Inquiry.destroy(this);
- } catch (Throwable t2) {
- t2.printStackTrace();
+ final Response response =
+ Bridge.get(site.url).throwIfNotSuccess().cancellable(false).request().response();
+
+ site.reason = null;
+ site.status = ServerStatus.OK;
+
+ if (site.validationMode == ValidationMode.TERM_SEARCH) {
+ final String body = response.asString();
+ if (body == null || !body.contains(site.validationContent)) {
+ site.status = ServerStatus.ERROR;
+ site.reason = "Term \"" + site.validationContent + "\" not found in response body.";
+ }
+ } else if (site.validationMode == ValidationMode.JAVASCRIPT) {
+ final String body = response.asString();
+ site.reason = JsUtil.exec(site.validationContent, body);
+ if (site.reason != null && !site.toString().isEmpty()) site.status = ServerStatus.ERROR;
+ }
+
+ if (site.status == ServerStatus.ERROR) showNotification(this, site);
+ } catch (BridgeException e) {
+ processError(e, site);
}
- super.onDestroy();
+ updateStatus(site);
+ }
+ } else {
+ LOG("No internet connection, waiting.");
}
+
+ isRunning(false);
+ LOG("Service is finished!");
+ }
+
+ private void processError(BridgeException e, ServerModel site) {
+ site.status = ServerStatus.OK;
+ site.reason = null;
+
+ switch (e.reason()) {
+ case BridgeException.REASON_REQUEST_CANCELLED:
+ // Shouldn't happen
+ break;
+ case BridgeException.REASON_REQUEST_FAILED:
+ case BridgeException.REASON_RESPONSE_UNPARSEABLE:
+ case BridgeException.REASON_RESPONSE_UNSUCCESSFUL:
+ case BridgeException.REASON_RESPONSE_IOERROR:
+ //noinspection ConstantConditions
+ if (e.response() != null && e.response().code() == 401) {
+ // Don't consider 401 unsuccessful here
+ site.reason = null;
+ } else {
+ site.status = ServerStatus.ERROR;
+ site.reason = e.getMessage();
+ }
+ break;
+ case BridgeException.REASON_REQUEST_TIMEOUT:
+ site.status = ServerStatus.ERROR;
+ site.reason = getString(R.string.timeout);
+ break;
+ case BridgeException.REASON_RESPONSE_VALIDATOR_ERROR:
+ case BridgeException.REASON_RESPONSE_VALIDATOR_FALSE:
+ // Not used
+ break;
+ }
+
+ if (site.status != ServerStatus.OK) {
+ LOG("%s error: %s", site.name, site.reason);
+ showNotification(this, site);
+ }
+ }
+
+ private void updateStatus(ServerModel site) {
+ Inquiry.get(this)
+ .update(MainActivity.SITES_TABLE_NAME, ServerModel.class)
+ .where("_id = ?", site.id)
+ .values(site)
+ .run();
+ sendBroadcast(new Intent(ACTION_CHECK_UPDATE).putExtra("model", site));
+ }
+
+ private void isRunning(boolean running) {
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .edit()
+ .putBoolean("check_service_running", running)
+ .commit();
+ }
+
+ public static boolean isRunning(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean("check_service_running", false);
+ }
+
+ public static void isAppOpen(Context context, boolean open) {
+ PreferenceManager.getDefaultSharedPreferences(context)
+ .edit()
+ .putBoolean("is_app_open", open)
+ .commit();
+ }
+
+ public static boolean isAppOpen(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("is_app_open", false);
+ }
+
+ private static void showNotification(Context context, ServerModel site) {
+ if (isAppOpen(context)) {
+ // Don't show notifications while the app is open
+ return;
+ }
+
+ final NotificationManagerCompat nm = NotificationManagerCompat.from(context);
+ final PendingIntent openIntent =
+ PendingIntent.getActivity(
+ context,
+ 9669,
+ new Intent(context, ViewSiteActivity.class)
+ .putExtra("model", site)
+ .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ final Notification noti =
+ new NotificationCompat.Builder(context)
+ .setContentTitle(site.name)
+ .setContentText(context.getString(R.string.something_wrong))
+ .setContentIntent(openIntent)
+ .setSmallIcon(R.drawable.ic_notification)
+ .setLargeIcon(
+ BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setAutoCancel(true)
+ .setDefaults(Notification.DEFAULT_VIBRATE)
+ .build();
+ nm.notify(site.url, NOTI_ID, noti);
+ }
+
+ @Override
+ public void onDestroy() {
+ try {
+ Inquiry.destroy(this);
+ } catch (Throwable t2) {
+ t2.printStackTrace();
+ }
+ super.onDestroy();
+ }
}
diff --git a/app/src/main/java/com/afollestad/nocknock/ui/AddSiteActivity.java b/app/src/main/java/com/afollestad/nocknock/ui/AddSiteActivity.java
index cb54ece..ba1b7fd 100644
--- a/app/src/main/java/com/afollestad/nocknock/ui/AddSiteActivity.java
+++ b/app/src/main/java/com/afollestad/nocknock/ui/AddSiteActivity.java
@@ -20,236 +20,254 @@ import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
-
import com.afollestad.nocknock.R;
import com.afollestad.nocknock.api.ServerModel;
import com.afollestad.nocknock.api.ServerStatus;
import com.afollestad.nocknock.api.ValidationMode;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class AddSiteActivity extends AppCompatActivity implements View.OnClickListener {
- private View rootLayout;
- private Toolbar toolbar;
+ private View rootLayout;
+ private Toolbar toolbar;
- private TextInputLayout nameTiLayout;
- private EditText inputName;
- private TextInputLayout urlTiLayout;
- private EditText inputUrl;
- private EditText inputInterval;
- private Spinner spinnerInterval;
- private TextView textUrlWarning;
- private Spinner responseValidationSpinner;
+ private TextInputLayout nameTiLayout;
+ private EditText inputName;
+ private TextInputLayout urlTiLayout;
+ private EditText inputUrl;
+ private EditText inputInterval;
+ private Spinner spinnerInterval;
+ private TextView textUrlWarning;
+ private Spinner responseValidationSpinner;
- private boolean isClosing;
+ private boolean isClosing;
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_addsite);
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_addsite);
- rootLayout = findViewById(R.id.rootView);
- nameTiLayout = (TextInputLayout) findViewById(R.id.nameTiLayout);
- inputName = (EditText) findViewById(R.id.inputName);
- urlTiLayout = (TextInputLayout) findViewById(R.id.urlTiLayout);
- inputUrl = (EditText) findViewById(R.id.inputUrl);
- textUrlWarning = (TextView) findViewById(R.id.textUrlWarning);
- inputInterval = (EditText) findViewById(R.id.checkIntervalInput);
- spinnerInterval = (Spinner) findViewById(R.id.checkIntervalSpinner);
- responseValidationSpinner = (Spinner) findViewById(R.id.responseValidationMode);
+ rootLayout = findViewById(R.id.rootView);
+ nameTiLayout = (TextInputLayout) findViewById(R.id.nameTiLayout);
+ inputName = (EditText) findViewById(R.id.inputName);
+ urlTiLayout = (TextInputLayout) findViewById(R.id.urlTiLayout);
+ inputUrl = (EditText) findViewById(R.id.inputUrl);
+ textUrlWarning = (TextView) findViewById(R.id.textUrlWarning);
+ inputInterval = (EditText) findViewById(R.id.checkIntervalInput);
+ spinnerInterval = (Spinner) findViewById(R.id.checkIntervalSpinner);
+ responseValidationSpinner = (Spinner) findViewById(R.id.responseValidationMode);
- toolbar = (Toolbar) findViewById(R.id.toolbar);
- toolbar.setNavigationOnClickListener(view -> closeActivityWithReveal());
+ toolbar = (Toolbar) findViewById(R.id.toolbar);
+ toolbar.setNavigationOnClickListener(view -> closeActivityWithReveal());
- if (savedInstanceState == null) {
- rootLayout.setVisibility(View.INVISIBLE);
- ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver();
- if (viewTreeObserver.isAlive()) {
- viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- circularRevealActivity();
- rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
- }
- });
- }
- }
-
- ArrayAdapter intervalOptionsAdapter = new ArrayAdapter<>(this, R.layout.list_item_spinner,
- getResources().getStringArray(R.array.interval_options));
- intervalOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
- spinnerInterval.setAdapter(intervalOptionsAdapter);
-
- inputUrl.setOnFocusChangeListener((view, hasFocus) -> {
- if (!hasFocus) {
- final String inputStr = inputUrl.getText().toString().trim();
- if (inputStr.isEmpty()) return;
- final Uri uri = Uri.parse(inputStr);
- if (uri.getScheme() == null) {
- inputUrl.setText("http://" + inputStr);
- textUrlWarning.setVisibility(View.GONE);
- } else if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
- textUrlWarning.setVisibility(View.VISIBLE);
- textUrlWarning.setText(R.string.warning_http_url);
- } else {
- textUrlWarning.setVisibility(View.GONE);
- }
- }
- });
-
- ArrayAdapter validationOptionsAdapter = new ArrayAdapter<>(this, R.layout.list_item_spinner,
- getResources().getStringArray(R.array.response_validation_options));
- validationOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
- responseValidationSpinner.setAdapter(validationOptionsAdapter);
- responseValidationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {
- final View searchTerm = findViewById(R.id.responseValidationSearchTerm);
- final View javascript = findViewById(R.id.responseValidationScript);
- final TextView modeDesc = (TextView) findViewById(R.id.validationModeDescription);
-
- searchTerm.setVisibility(i == 1 ? View.VISIBLE : View.GONE);
- javascript.setVisibility(i == 2 ? View.VISIBLE : View.GONE);
-
- switch (i) {
- case 0:
- modeDesc.setText(R.string.validation_mode_status_desc);
- break;
- case 1:
- modeDesc.setText(R.string.validation_mode_term_desc);
- break;
- case 2:
- modeDesc.setText(R.string.validation_mode_javascript_desc);
- break;
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> adapterView) {
- }
- });
-
- findViewById(R.id.doneBtn).setOnClickListener(this);
+ if (savedInstanceState == null) {
+ rootLayout.setVisibility(View.INVISIBLE);
+ ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver();
+ if (viewTreeObserver.isAlive()) {
+ viewTreeObserver.addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ circularRevealActivity();
+ rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ }
+ });
+ }
}
- @Override
- public void onBackPressed() {
- closeActivityWithReveal();
- }
+ ArrayAdapter intervalOptionsAdapter =
+ new ArrayAdapter<>(
+ this,
+ R.layout.list_item_spinner,
+ getResources().getStringArray(R.array.interval_options));
+ intervalOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
+ spinnerInterval.setAdapter(intervalOptionsAdapter);
- private void closeActivityWithReveal() {
- if (isClosing) return;
- isClosing = true;
- final int fabSize = getIntent().getIntExtra("fab_size", toolbar.getMeasuredHeight());
- final int cx = (int) getIntent().getFloatExtra("fab_x", rootLayout.getMeasuredWidth() / 2) + (fabSize / 2);
- final int cy = (int) getIntent().getFloatExtra("fab_y", rootLayout.getMeasuredHeight() / 2) + toolbar.getMeasuredHeight() + (fabSize / 2);
- float initialRadius = Math.max(cx, cy);
-
- final Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, initialRadius, 0);
- circularReveal.setDuration(300);
- circularReveal.setInterpolator(new AccelerateInterpolator());
- circularReveal.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- rootLayout.setVisibility(View.INVISIBLE);
- finish();
- overridePendingTransition(0, 0);
- }
- });
-
- circularReveal.start();
- }
-
- private void circularRevealActivity() {
- final int cx = rootLayout.getMeasuredWidth() / 2;
- final int cy = rootLayout.getMeasuredHeight() / 2;
- final float finalRadius = Math.max(cx, cy);
- final Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, 0, finalRadius);
-
- circularReveal.setDuration(300);
- circularReveal.setInterpolator(new DecelerateInterpolator());
-
- rootLayout.setVisibility(View.VISIBLE);
- circularReveal.start();
- }
-
- // Done button
- @Override
- public void onClick(View view) {
- isClosing = true;
-
- ServerModel model = new ServerModel();
- model.name = inputName.getText().toString().trim();
- model.url = inputUrl.getText().toString().trim();
- model.status = ServerStatus.WAITING;
-
- if (model.name.isEmpty()) {
- nameTiLayout.setError(getString(R.string.please_enter_name));
- isClosing = false;
- return;
- } else {
- nameTiLayout.setError(null);
- }
-
- if (model.url.isEmpty()) {
- urlTiLayout.setError(getString(R.string.please_enter_url));
- isClosing = false;
- return;
- } else {
- urlTiLayout.setError(null);
- if (!Patterns.WEB_URL.matcher(model.url).find()) {
- urlTiLayout.setError(getString(R.string.please_enter_valid_url));
- isClosing = false;
- return;
+ inputUrl.setOnFocusChangeListener(
+ (view, hasFocus) -> {
+ if (!hasFocus) {
+ final String inputStr = inputUrl.getText().toString().trim();
+ if (inputStr.isEmpty()) return;
+ final Uri uri = Uri.parse(inputStr);
+ if (uri.getScheme() == null) {
+ inputUrl.setText("http://" + inputStr);
+ textUrlWarning.setVisibility(View.GONE);
+ } else if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
+ textUrlWarning.setVisibility(View.VISIBLE);
+ textUrlWarning.setText(R.string.warning_http_url);
} else {
- final Uri uri = Uri.parse(model.url);
- if (uri.getScheme() == null)
- model.url = "http://" + model.url;
+ textUrlWarning.setVisibility(View.GONE);
}
- }
+ }
+ });
- String intervalStr = inputInterval.getText().toString().trim();
- if (intervalStr.isEmpty()) intervalStr = "0";
- model.checkInterval = Integer.parseInt(intervalStr);
+ ArrayAdapter validationOptionsAdapter =
+ new ArrayAdapter<>(
+ this,
+ R.layout.list_item_spinner,
+ getResources().getStringArray(R.array.response_validation_options));
+ validationOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
+ responseValidationSpinner.setAdapter(validationOptionsAdapter);
+ responseValidationSpinner.setOnItemSelectedListener(
+ new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {
+ final View searchTerm = findViewById(R.id.responseValidationSearchTerm);
+ final View javascript = findViewById(R.id.responseValidationScript);
+ final TextView modeDesc = (TextView) findViewById(R.id.validationModeDescription);
- switch (spinnerInterval.getSelectedItemPosition()) {
- case 0: // minutes
- model.checkInterval *= (60 * 1000);
- break;
- case 1: // hours
- model.checkInterval *= (60 * 60 * 1000);
- break;
- case 2: // days
- model.checkInterval *= (60 * 60 * 24 * 1000);
- break;
- default: // weeks
- model.checkInterval *= (60 * 60 * 24 * 7 * 1000);
- break;
- }
+ searchTerm.setVisibility(i == 1 ? View.VISIBLE : View.GONE);
+ javascript.setVisibility(i == 2 ? View.VISIBLE : View.GONE);
- model.lastCheck = System.currentTimeMillis() - model.checkInterval;
+ switch (i) {
+ case 0:
+ modeDesc.setText(R.string.validation_mode_status_desc);
+ break;
+ case 1:
+ modeDesc.setText(R.string.validation_mode_term_desc);
+ break;
+ case 2:
+ modeDesc.setText(R.string.validation_mode_javascript_desc);
+ break;
+ }
+ }
- switch (responseValidationSpinner.getSelectedItemPosition()) {
- case 0:
- model.validationMode = ValidationMode.STATUS_CODE;
- model.validationContent = null;
- break;
- case 1:
- model.validationMode = ValidationMode.TERM_SEARCH;
- model.validationContent = ((EditText) findViewById(R.id.responseValidationSearchTerm)).getText().toString().trim();
- break;
- case 2:
- model.validationMode = ValidationMode.JAVASCRIPT;
- model.validationContent = ((EditText) findViewById(R.id.responseValidationScriptInput)).getText().toString().trim();
- break;
- }
+ @Override
+ public void onNothingSelected(AdapterView> adapterView) {}
+ });
- setResult(RESULT_OK, new Intent()
- .putExtra("model", model));
- finish();
- overridePendingTransition(R.anim.fade_out, R.anim.fade_out);
+ findViewById(R.id.doneBtn).setOnClickListener(this);
+ }
+
+ @Override
+ public void onBackPressed() {
+ closeActivityWithReveal();
+ }
+
+ private void closeActivityWithReveal() {
+ if (isClosing) return;
+ isClosing = true;
+ final int fabSize = getIntent().getIntExtra("fab_size", toolbar.getMeasuredHeight());
+ final int cx =
+ (int) getIntent().getFloatExtra("fab_x", rootLayout.getMeasuredWidth() / 2) + (fabSize / 2);
+ final int cy =
+ (int) getIntent().getFloatExtra("fab_y", rootLayout.getMeasuredHeight() / 2)
+ + toolbar.getMeasuredHeight()
+ + (fabSize / 2);
+ float initialRadius = Math.max(cx, cy);
+
+ final Animator circularReveal =
+ ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, initialRadius, 0);
+ circularReveal.setDuration(300);
+ circularReveal.setInterpolator(new AccelerateInterpolator());
+ circularReveal.addListener(
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ rootLayout.setVisibility(View.INVISIBLE);
+ finish();
+ overridePendingTransition(0, 0);
+ }
+ });
+
+ circularReveal.start();
+ }
+
+ private void circularRevealActivity() {
+ final int cx = rootLayout.getMeasuredWidth() / 2;
+ final int cy = rootLayout.getMeasuredHeight() / 2;
+ final float finalRadius = Math.max(cx, cy);
+ final Animator circularReveal =
+ ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, 0, finalRadius);
+
+ circularReveal.setDuration(300);
+ circularReveal.setInterpolator(new DecelerateInterpolator());
+
+ rootLayout.setVisibility(View.VISIBLE);
+ circularReveal.start();
+ }
+
+ // Done button
+ @Override
+ public void onClick(View view) {
+ isClosing = true;
+
+ ServerModel model = new ServerModel();
+ model.name = inputName.getText().toString().trim();
+ model.url = inputUrl.getText().toString().trim();
+ model.status = ServerStatus.WAITING;
+
+ if (model.name.isEmpty()) {
+ nameTiLayout.setError(getString(R.string.please_enter_name));
+ isClosing = false;
+ return;
+ } else {
+ nameTiLayout.setError(null);
}
-}
\ No newline at end of file
+
+ if (model.url.isEmpty()) {
+ urlTiLayout.setError(getString(R.string.please_enter_url));
+ isClosing = false;
+ return;
+ } else {
+ urlTiLayout.setError(null);
+ if (!Patterns.WEB_URL.matcher(model.url).find()) {
+ urlTiLayout.setError(getString(R.string.please_enter_valid_url));
+ isClosing = false;
+ return;
+ } else {
+ final Uri uri = Uri.parse(model.url);
+ if (uri.getScheme() == null) model.url = "http://" + model.url;
+ }
+ }
+
+ String intervalStr = inputInterval.getText().toString().trim();
+ if (intervalStr.isEmpty()) intervalStr = "0";
+ model.checkInterval = Integer.parseInt(intervalStr);
+
+ switch (spinnerInterval.getSelectedItemPosition()) {
+ case 0: // minutes
+ model.checkInterval *= (60 * 1000);
+ break;
+ case 1: // hours
+ model.checkInterval *= (60 * 60 * 1000);
+ break;
+ case 2: // days
+ model.checkInterval *= (60 * 60 * 24 * 1000);
+ break;
+ default: // weeks
+ model.checkInterval *= (60 * 60 * 24 * 7 * 1000);
+ break;
+ }
+
+ model.lastCheck = System.currentTimeMillis() - model.checkInterval;
+
+ switch (responseValidationSpinner.getSelectedItemPosition()) {
+ case 0:
+ model.validationMode = ValidationMode.STATUS_CODE;
+ model.validationContent = null;
+ break;
+ case 1:
+ model.validationMode = ValidationMode.TERM_SEARCH;
+ model.validationContent =
+ ((EditText) findViewById(R.id.responseValidationSearchTerm))
+ .getText()
+ .toString()
+ .trim();
+ break;
+ case 2:
+ model.validationMode = ValidationMode.JAVASCRIPT;
+ model.validationContent =
+ ((EditText) findViewById(R.id.responseValidationScriptInput))
+ .getText()
+ .toString()
+ .trim();
+ break;
+ }
+
+ setResult(RESULT_OK, new Intent().putExtra("model", model));
+ finish();
+ overridePendingTransition(R.anim.fade_out, R.anim.fade_out);
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/ui/MainActivity.java b/app/src/main/java/com/afollestad/nocknock/ui/MainActivity.java
index 88f8ba8..1e84a40 100644
--- a/app/src/main/java/com/afollestad/nocknock/ui/MainActivity.java
+++ b/app/src/main/java/com/afollestad/nocknock/ui/MainActivity.java
@@ -27,7 +27,6 @@ import android.view.MenuItem;
import android.view.View;
import android.view.animation.PathInterpolator;
import android.widget.TextView;
-
import com.afollestad.bridge.Bridge;
import com.afollestad.inquiry.Inquiry;
import com.afollestad.materialdialogs.MaterialDialog;
@@ -41,286 +40,299 @@ import com.afollestad.nocknock.util.AlarmUtil;
import com.afollestad.nocknock.util.MathUtil;
import com.afollestad.nocknock.views.DividerItemDecoration;
-public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener, View.OnClickListener, ServerAdapter.ClickListener {
+public class MainActivity extends AppCompatActivity
+ implements SwipeRefreshLayout.OnRefreshListener,
+ View.OnClickListener,
+ ServerAdapter.ClickListener {
- private final static int ADD_SITE_RQ = 6969;
- private final static int VIEW_SITE_RQ = 6923;
- public final static String DB_NAME = "nock_nock";
- public final static String SITES_TABLE_NAME_OLD = "sites";
- public final static String SITES_TABLE_NAME = "site_models";
+ private static final int ADD_SITE_RQ = 6969;
+ private static final int VIEW_SITE_RQ = 6923;
+ public static final String DB_NAME = "nock_nock";
+ public static final String SITES_TABLE_NAME_OLD = "sites";
+ public static final String SITES_TABLE_NAME = "site_models";
- private FloatingActionButton mFab;
- private RecyclerView mList;
- private ServerAdapter mAdapter;
- private TextView mEmptyText;
- private SwipeRefreshLayout mRefreshLayout;
+ private FloatingActionButton mFab;
+ private RecyclerView mList;
+ private ServerAdapter mAdapter;
+ private TextView mEmptyText;
+ private SwipeRefreshLayout mRefreshLayout;
- private ObjectAnimator mFabAnimator;
- private float mOrigFabX;
- private float mOrigFabY;
+ private ObjectAnimator mFabAnimator;
+ private float mOrigFabX;
+ private float mOrigFabY;
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mReceiver =
+ new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.v("MainActivity", "Received " + intent.getAction());
- if (CheckService.ACTION_RUNNING.equals(intent.getAction())) {
- if (mRefreshLayout != null)
- mRefreshLayout.setRefreshing(false);
- } else {
- final ServerModel model = (ServerModel) intent.getSerializableExtra("model");
- if (mAdapter != null && mList != null && model != null) {
- mList.post(() -> mAdapter.update(model));
- }
+ Log.v("MainActivity", "Received " + intent.getAction());
+ if (CheckService.ACTION_RUNNING.equals(intent.getAction())) {
+ if (mRefreshLayout != null) mRefreshLayout.setRefreshing(false);
+ } else {
+ final ServerModel model = (ServerModel) intent.getSerializableExtra("model");
+ if (mAdapter != null && mList != null && model != null) {
+ mList.post(() -> mAdapter.update(model));
}
+ }
}
- };
+ };
- @SuppressLint("CommitPrefEdits")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
+ @SuppressLint("CommitPrefEdits")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
- mAdapter = new ServerAdapter(this);
- mEmptyText = (TextView) findViewById(R.id.emptyText);
+ mAdapter = new ServerAdapter(this);
+ mEmptyText = (TextView) findViewById(R.id.emptyText);
- mList = (RecyclerView) findViewById(R.id.list);
- mList.setLayoutManager(new LinearLayoutManager(this));
- mList.setAdapter(mAdapter);
- mList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
+ mList = (RecyclerView) findViewById(R.id.list);
+ mList.setLayoutManager(new LinearLayoutManager(this));
+ mList.setAdapter(mAdapter);
+ mList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
- mRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
- mRefreshLayout.setOnRefreshListener(this);
- mRefreshLayout.setColorSchemeColors(ContextCompat.getColor(this, R.color.md_green),
- ContextCompat.getColor(this, R.color.md_yellow),
- ContextCompat.getColor(this, R.color.md_red));
+ mRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
+ mRefreshLayout.setOnRefreshListener(this);
+ mRefreshLayout.setColorSchemeColors(
+ ContextCompat.getColor(this, R.color.md_green),
+ ContextCompat.getColor(this, R.color.md_yellow),
+ ContextCompat.getColor(this, R.color.md_red));
- mFab = (FloatingActionButton) findViewById(R.id.fab);
- mFab.setOnClickListener(this);
+ mFab = (FloatingActionButton) findViewById(R.id.fab);
+ mFab.setOnClickListener(this);
- Inquiry.newInstance(this, DB_NAME).build();
- Bridge.config()
- .defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
+ Inquiry.newInstance(this, DB_NAME).build();
+ Bridge.config().defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
- final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
- if (!sp.getBoolean("migrated_db", false)) {
- final Inquiry mdb = Inquiry.newInstance(this, DB_NAME)
- .instanceName("migrate_db")
- .build(false);
- final ServerModel[] models = Inquiry.get(this)
- .selectFrom(SITES_TABLE_NAME_OLD, ServerModel.class)
- .projection("_id", "name", "url", "status", "checkInterval", "lastCheck", "reason")
- .all();
- if (models != null) {
- Log.d("SiteMigration", "Migrating " + models.length + " sites to the new table.");
- for (ServerModel model : models) {
- model.validationMode = ValidationMode.STATUS_CODE;
- model.validationContent = null;
- }
- //noinspection CheckResult
- mdb.insertInto(SITES_TABLE_NAME, ServerModel.class)
- .values(models)
- .run();
- mdb.dropTable(SITES_TABLE_NAME_OLD);
- }
- sp.edit().putBoolean("migrated_db", true).commit();
+ final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ if (!sp.getBoolean("migrated_db", false)) {
+ final Inquiry mdb =
+ Inquiry.newInstance(this, DB_NAME).instanceName("migrate_db").build(false);
+ final ServerModel[] models =
+ Inquiry.get(this)
+ .selectFrom(SITES_TABLE_NAME_OLD, ServerModel.class)
+ .projection("_id", "name", "url", "status", "checkInterval", "lastCheck", "reason")
+ .all();
+ if (models != null) {
+ Log.d("SiteMigration", "Migrating " + models.length + " sites to the new table.");
+ for (ServerModel model : models) {
+ model.validationMode = ValidationMode.STATUS_CODE;
+ model.validationContent = null;
}
+ //noinspection CheckResult
+ mdb.insertInto(SITES_TABLE_NAME, ServerModel.class).values(models).run();
+ mdb.dropTable(SITES_TABLE_NAME_OLD);
+ }
+ sp.edit().putBoolean("migrated_db", true).commit();
+ }
+ }
+
+ private void showRefreshTutorial() {
+ if (mAdapter.getItemCount() == 0) return;
+ final SharedPreferences pr = PreferenceManager.getDefaultSharedPreferences(this);
+ if (pr.getBoolean("shown_swipe_refresh_tutorial", false)) return;
+
+ mFab.hide();
+ final View tutorialView = findViewById(R.id.swipeRefreshTutorial);
+ tutorialView.setVisibility(View.VISIBLE);
+ tutorialView.setAlpha(0f);
+ tutorialView.animate().cancel();
+ tutorialView.animate().setDuration(300).alpha(1f).start();
+
+ findViewById(R.id.understoodBtn)
+ .setOnClickListener(
+ view -> {
+ view.setOnClickListener(null);
+ findViewById(R.id.swipeRefreshTutorial).setVisibility(View.GONE);
+ pr.edit().putBoolean("shown_swipe_refresh_tutorial", true).commit();
+ mFab.show();
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ CheckService.isAppOpen(this, true);
+
+ try {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(CheckService.ACTION_CHECK_UPDATE);
+ filter.addAction(CheckService.ACTION_RUNNING);
+ registerReceiver(mReceiver, filter);
+ } catch (Throwable t) {
+ t.printStackTrace();
}
- private void showRefreshTutorial() {
- if (mAdapter.getItemCount() == 0) return;
- final SharedPreferences pr = PreferenceManager.getDefaultSharedPreferences(this);
- if (pr.getBoolean("shown_swipe_refresh_tutorial", false)) return;
+ refreshModels();
+ }
- mFab.hide();
- final View tutorialView = findViewById(R.id.swipeRefreshTutorial);
- tutorialView.setVisibility(View.VISIBLE);
- tutorialView.setAlpha(0f);
- tutorialView.animate().cancel();
- tutorialView.animate().setDuration(300).alpha(1f).start();
+ @Override
+ protected void onPause() {
+ super.onPause();
+ CheckService.isAppOpen(this, false);
- findViewById(R.id.understoodBtn).setOnClickListener(view -> {
- view.setOnClickListener(null);
- findViewById(R.id.swipeRefreshTutorial).setVisibility(View.GONE);
- pr.edit().putBoolean("shown_swipe_refresh_tutorial", true).commit();
- mFab.show();
+ if (isFinishing()) {
+ Inquiry.destroy(this);
+ }
+
+ NotificationManagerCompat.from(this).cancel(CheckService.NOTI_ID);
+ try {
+ unregisterReceiver(mReceiver);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ private void refreshModels() {
+ mAdapter.clear();
+ mEmptyText.setVisibility(View.VISIBLE);
+ Inquiry.get(this).selectFrom(SITES_TABLE_NAME, ServerModel.class).all(this::setModels);
+ }
+
+ private void setModels(ServerModel[] models) {
+ mAdapter.set(models);
+ mEmptyText.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
+ AlarmUtil.setSiteChecks(this, models);
+ showRefreshTutorial();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.about) {
+ AboutDialog.show(this);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onRefresh() {
+ if (CheckService.isRunning(this)) {
+ mRefreshLayout.setRefreshing(false);
+ return;
+ }
+ startService(new Intent(this, CheckService.class));
+ }
+
+ // FAB clicked
+ @Override
+ public void onClick(View view) {
+ mOrigFabX = mFab.getX();
+ mOrigFabY = mFab.getY();
+ final Path curve = MathUtil.bezierCurve(mFab, mList);
+ if (mFabAnimator != null) mFabAnimator.cancel();
+ mFabAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, curve);
+ mFabAnimator.setInterpolator(new PathInterpolator(.5f, .5f));
+ mFabAnimator.setDuration(300);
+ mFabAnimator.addListener(
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ startActivityForResult(
+ new Intent(MainActivity.this, AddSiteActivity.class)
+ .putExtra("fab_x", mOrigFabX)
+ .putExtra("fab_y", mOrigFabY)
+ .putExtra("fab_size", mFab.getMeasuredWidth())
+ .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION),
+ ADD_SITE_RQ);
+ mFab.postDelayed(
+ () -> {
+ mFab.setX(mOrigFabX);
+ mFab.setY(mOrigFabY);
+ },
+ 600);
+ }
});
- }
+ mFabAnimator.start();
+ }
- @Override
- protected void onResume() {
- super.onResume();
- CheckService.isAppOpen(this, true);
-
- try {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(CheckService.ACTION_CHECK_UPDATE);
- filter.addAction(CheckService.ACTION_RUNNING);
- registerReceiver(mReceiver, filter);
- } catch (Throwable t) {
- t.printStackTrace();
- }
-
- refreshModels();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- CheckService.isAppOpen(this, false);
-
- if (isFinishing()) {
- Inquiry.destroy(this);
- }
-
- NotificationManagerCompat.from(this).cancel(CheckService.NOTI_ID);
- try {
- unregisterReceiver(mReceiver);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private void refreshModels() {
- mAdapter.clear();
- mEmptyText.setVisibility(View.VISIBLE);
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (resultCode == RESULT_OK) {
+ final ServerModel model = (ServerModel) data.getSerializableExtra("model");
+ if (requestCode == ADD_SITE_RQ) {
+ mAdapter.add(model);
+ mEmptyText.setVisibility(View.GONE);
Inquiry.get(this)
- .selectFrom(SITES_TABLE_NAME, ServerModel.class)
- .all(this::setModels);
+ .insertInto(SITES_TABLE_NAME, ServerModel.class)
+ .values(model)
+ .run(
+ inserted -> {
+ AlarmUtil.setSiteChecks(MainActivity.this, model);
+ checkSite(MainActivity.this, model);
+ });
+ } else if (requestCode == VIEW_SITE_RQ) {
+ mAdapter.update(model);
+ AlarmUtil.setSiteChecks(MainActivity.this, model);
+ checkSite(MainActivity.this, model);
+ }
}
+ }
- private void setModels(ServerModel[] models) {
- mAdapter.set(models);
- mEmptyText.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
- AlarmUtil.setSiteChecks(this, models);
- showRefreshTutorial();
- }
+ public static void removeSite(
+ final Context context, final ServerModel model, final Runnable onRemoved) {
+ new MaterialDialog.Builder(context)
+ .title(R.string.remove_site)
+ .content(Html.fromHtml(context.getString(R.string.remove_site_prompt, model.name)))
+ .positiveText(R.string.remove)
+ .negativeText(android.R.string.cancel)
+ .onPositive(
+ (dialog, which) -> {
+ AlarmUtil.cancelSiteChecks(context, model);
+ final NotificationManagerCompat nm = NotificationManagerCompat.from(context);
+ nm.cancel(model.url, CheckService.NOTI_ID);
+ //noinspection CheckResult
+ final Inquiry rinq =
+ Inquiry.newInstance(context, DB_NAME).instanceName("remove_site").build(false);
+ //noinspection CheckResult
+ rinq.deleteFrom(SITES_TABLE_NAME, ServerModel.class).where("_id = ?", model.id).run();
+ rinq.destroyInstance();
+ if (onRemoved != null) onRemoved.run();
+ })
+ .show();
+ }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return super.onCreateOptionsMenu(menu);
- }
+ public static void checkSite(Context context, ServerModel model) {
+ context.startService(
+ new Intent(context, CheckService.class).putExtra(CheckService.MODEL_ID, model.id));
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.about) {
- AboutDialog.show(this);
- return true;
- }
- return super.onOptionsItemSelected(item);
+ @Override
+ public void onSiteSelected(final int index, final ServerModel model, boolean longClick) {
+ if (longClick) {
+ new MaterialDialog.Builder(this)
+ .title(R.string.options)
+ .items(R.array.site_long_options)
+ .negativeText(android.R.string.cancel)
+ .itemsCallback(
+ (dialog, itemView, which, text) -> {
+ if (which == 0) {
+ checkSite(MainActivity.this, model);
+ } else {
+ removeSite(
+ MainActivity.this,
+ model,
+ () -> {
+ mAdapter.remove(index);
+ mEmptyText.setVisibility(
+ mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
+ });
+ }
+ })
+ .show();
+ } else {
+ startActivityForResult(
+ new Intent(this, ViewSiteActivity.class).putExtra("model", model),
+ VIEW_SITE_RQ,
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
}
-
- @Override
- public void onRefresh() {
- if (CheckService.isRunning(this)) {
- mRefreshLayout.setRefreshing(false);
- return;
- }
- startService(new Intent(this, CheckService.class));
- }
-
- // FAB clicked
- @Override
- public void onClick(View view) {
- mOrigFabX = mFab.getX();
- mOrigFabY = mFab.getY();
- final Path curve = MathUtil.bezierCurve(mFab, mList);
- if (mFabAnimator != null)
- mFabAnimator.cancel();
- mFabAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, curve);
- mFabAnimator.setInterpolator(new PathInterpolator(.5f, .5f));
- mFabAnimator.setDuration(300);
- mFabAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- startActivityForResult(new Intent(MainActivity.this, AddSiteActivity.class)
- .putExtra("fab_x", mOrigFabX)
- .putExtra("fab_y", mOrigFabY)
- .putExtra("fab_size", mFab.getMeasuredWidth())
- .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION), ADD_SITE_RQ);
- mFab.postDelayed(() -> {
- mFab.setX(mOrigFabX);
- mFab.setY(mOrigFabY);
- }, 600);
- }
- });
- mFabAnimator.start();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (resultCode == RESULT_OK) {
- final ServerModel model = (ServerModel) data.getSerializableExtra("model");
- if (requestCode == ADD_SITE_RQ) {
- mAdapter.add(model);
- mEmptyText.setVisibility(View.GONE);
- Inquiry.get(this).insertInto(SITES_TABLE_NAME, ServerModel.class)
- .values(model)
- .run(inserted -> {
- AlarmUtil.setSiteChecks(MainActivity.this, model);
- checkSite(MainActivity.this, model);
- });
- } else if (requestCode == VIEW_SITE_RQ) {
- mAdapter.update(model);
- AlarmUtil.setSiteChecks(MainActivity.this, model);
- checkSite(MainActivity.this, model);
- }
- }
- }
-
- public static void removeSite(final Context context, final ServerModel model, final Runnable onRemoved) {
- new MaterialDialog.Builder(context)
- .title(R.string.remove_site)
- .content(Html.fromHtml(context.getString(R.string.remove_site_prompt, model.name)))
- .positiveText(R.string.remove)
- .negativeText(android.R.string.cancel)
- .onPositive((dialog, which) -> {
- AlarmUtil.cancelSiteChecks(context, model);
- final NotificationManagerCompat nm = NotificationManagerCompat.from(context);
- nm.cancel(model.url, CheckService.NOTI_ID);
- //noinspection CheckResult
- final Inquiry rinq = Inquiry.newInstance(context, DB_NAME)
- .instanceName("remove_site")
- .build(false);
- //noinspection CheckResult
- rinq.deleteFrom(SITES_TABLE_NAME, ServerModel.class)
- .where("_id = ?", model.id)
- .run();
- rinq.destroyInstance();
- if (onRemoved != null)
- onRemoved.run();
- }).show();
- }
-
- public static void checkSite(Context context, ServerModel model) {
- context.startService(new Intent(context, CheckService.class)
- .putExtra(CheckService.MODEL_ID, model.id));
- }
-
- @Override
- public void onSiteSelected(final int index, final ServerModel model, boolean longClick) {
- if (longClick) {
- new MaterialDialog.Builder(this)
- .title(R.string.options)
- .items(R.array.site_long_options)
- .negativeText(android.R.string.cancel)
- .itemsCallback((dialog, itemView, which, text) -> {
- if (which == 0) {
- checkSite(MainActivity.this, model);
- } else {
- removeSite(MainActivity.this, model, () -> {
- mAdapter.remove(index);
- mEmptyText.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
- });
- }
- }).show();
- } else {
- startActivityForResult(new Intent(this, ViewSiteActivity.class)
- .putExtra("model", model), VIEW_SITE_RQ,
- ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
- }
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/ui/ViewSiteActivity.java b/app/src/main/java/com/afollestad/nocknock/ui/ViewSiteActivity.java
index 5edbef3..71d4bc5 100644
--- a/app/src/main/java/com/afollestad/nocknock/ui/ViewSiteActivity.java
+++ b/app/src/main/java/com/afollestad/nocknock/ui/ViewSiteActivity.java
@@ -19,7 +19,6 @@ import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
-
import com.afollestad.bridge.Bridge;
import com.afollestad.inquiry.Inquiry;
import com.afollestad.nocknock.R;
@@ -29,312 +28,333 @@ import com.afollestad.nocknock.api.ValidationMode;
import com.afollestad.nocknock.services.CheckService;
import com.afollestad.nocknock.util.TimeUtil;
import com.afollestad.nocknock.views.StatusImageView;
-
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
-/**
- * @author Aidan Follestad (afollestad)
- */
-public class ViewSiteActivity extends AppCompatActivity implements View.OnClickListener, Toolbar.OnMenuItemClickListener {
+/** @author Aidan Follestad (afollestad) */
+public class ViewSiteActivity extends AppCompatActivity
+ implements View.OnClickListener, Toolbar.OnMenuItemClickListener {
- private StatusImageView iconStatus;
- private EditText inputName;
- private EditText inputUrl;
- private EditText inputCheckInterval;
- private Spinner checkIntervalSpinner;
- private TextView textLastCheckResult;
- private TextView textNextCheck;
- private TextView textUrlWarning;
- private Spinner responseValidationSpinner;
+ private StatusImageView iconStatus;
+ private EditText inputName;
+ private EditText inputUrl;
+ private EditText inputCheckInterval;
+ private Spinner checkIntervalSpinner;
+ private TextView textLastCheckResult;
+ private TextView textNextCheck;
+ private TextView textUrlWarning;
+ private Spinner responseValidationSpinner;
- private ServerModel mModel;
+ private ServerModel mModel;
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mReceiver =
+ new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.v("ViewSiteActivity", "Received " + intent.getAction());
- final ServerModel model = (ServerModel) intent.getSerializableExtra("model");
- if (model != null) {
- mModel = model;
- update();
- }
- }
- };
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_viewsite);
-
- final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- toolbar.setNavigationOnClickListener(view -> finish());
- toolbar.inflateMenu(R.menu.menu_viewsite);
- toolbar.setOnMenuItemClickListener(this);
-
- iconStatus = (StatusImageView) findViewById(R.id.iconStatus);
- inputName = (EditText) findViewById(R.id.inputName);
- inputUrl = (EditText) findViewById(R.id.inputUrl);
- textUrlWarning = (TextView) findViewById(R.id.textUrlWarning);
- inputCheckInterval = (EditText) findViewById(R.id.checkIntervalInput);
- checkIntervalSpinner = (Spinner) findViewById(R.id.checkIntervalSpinner);
- textLastCheckResult = (TextView) findViewById(R.id.textLastCheckResult);
- textNextCheck = (TextView) findViewById(R.id.textNextCheck);
- responseValidationSpinner = (Spinner) findViewById(R.id.responseValidationMode);
-
- ArrayAdapter intervalOptionsAdapter = new ArrayAdapter<>(this, R.layout.list_item_spinner,
- getResources().getStringArray(R.array.interval_options));
- intervalOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
- checkIntervalSpinner.setAdapter(intervalOptionsAdapter);
-
- inputUrl.setOnFocusChangeListener((view, hasFocus) -> {
- if (!hasFocus) {
- final String inputStr = inputUrl.getText().toString().trim();
- if (inputStr.isEmpty()) return;
- final Uri uri = Uri.parse(inputStr);
- if (uri.getScheme() == null) {
- inputUrl.setText("http://" + inputStr);
- textUrlWarning.setVisibility(View.GONE);
- } else if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
- textUrlWarning.setVisibility(View.VISIBLE);
- textUrlWarning.setText(R.string.warning_http_url);
- } else {
- textUrlWarning.setVisibility(View.GONE);
- }
- }
- });
-
- ArrayAdapter validationOptionsAdapter = new ArrayAdapter<>(this, R.layout.list_item_spinner,
- getResources().getStringArray(R.array.response_validation_options));
- validationOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
- responseValidationSpinner.setAdapter(validationOptionsAdapter);
- responseValidationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {
- final View searchTerm = findViewById(R.id.responseValidationSearchTerm);
- final View javascript = findViewById(R.id.responseValidationScript);
- final TextView modeDesc = (TextView) findViewById(R.id.validationModeDescription);
-
- searchTerm.setVisibility(i == 1 ? View.VISIBLE : View.GONE);
- javascript.setVisibility(i == 2 ? View.VISIBLE : View.GONE);
-
- switch (i) {
- case 0:
- modeDesc.setText(R.string.validation_mode_status_desc);
- break;
- case 1:
- modeDesc.setText(R.string.validation_mode_term_desc);
- break;
- case 2:
- modeDesc.setText(R.string.validation_mode_javascript_desc);
- break;
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> adapterView) {
- }
- });
-
- mModel = (ServerModel) getIntent().getSerializableExtra("model");
- update();
-
- Bridge.config()
- .defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- if (intent != null && intent.hasExtra("model")) {
- mModel = (ServerModel) intent.getSerializableExtra("model");
+ Log.v("ViewSiteActivity", "Received " + intent.getAction());
+ final ServerModel model = (ServerModel) intent.getSerializableExtra("model");
+ if (model != null) {
+ mModel = model;
update();
+ }
}
- }
+ };
- @SuppressLint({"SetTextI18n", "SwitchIntDef"})
- private void update() {
- final SimpleDateFormat df = new SimpleDateFormat("MMMM dd, hh:mm:ss a", Locale.getDefault());
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_viewsite);
- iconStatus.setStatus(mModel.status);
- inputName.setText(mModel.name);
- inputUrl.setText(mModel.url);
+ final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ toolbar.setNavigationOnClickListener(view -> finish());
+ toolbar.inflateMenu(R.menu.menu_viewsite);
+ toolbar.setOnMenuItemClickListener(this);
- if (mModel.lastCheck == 0) {
- textLastCheckResult.setText(R.string.none);
- } else {
- switch (mModel.status) {
- case ServerStatus.CHECKING:
- textLastCheckResult.setText(R.string.checking_status);
- break;
- case ServerStatus.ERROR:
- textLastCheckResult.setText(mModel.reason);
- break;
- case ServerStatus.OK:
- textLastCheckResult.setText(R.string.everything_checks_out);
- break;
- case ServerStatus.WAITING:
- textLastCheckResult.setText(R.string.waiting);
- break;
- }
- }
+ iconStatus = (StatusImageView) findViewById(R.id.iconStatus);
+ inputName = (EditText) findViewById(R.id.inputName);
+ inputUrl = (EditText) findViewById(R.id.inputUrl);
+ textUrlWarning = (TextView) findViewById(R.id.textUrlWarning);
+ inputCheckInterval = (EditText) findViewById(R.id.checkIntervalInput);
+ checkIntervalSpinner = (Spinner) findViewById(R.id.checkIntervalSpinner);
+ textLastCheckResult = (TextView) findViewById(R.id.textLastCheckResult);
+ textNextCheck = (TextView) findViewById(R.id.textNextCheck);
+ responseValidationSpinner = (Spinner) findViewById(R.id.responseValidationMode);
- if (mModel.checkInterval == 0) {
- textNextCheck.setText(R.string.none_turned_off);
- inputCheckInterval.setText("");
- checkIntervalSpinner.setSelection(0);
- } else {
- long lastCheck = mModel.lastCheck;
- if (lastCheck == 0) lastCheck = System.currentTimeMillis();
- textNextCheck.setText(df.format(new Date(lastCheck + mModel.checkInterval)));
+ ArrayAdapter intervalOptionsAdapter =
+ new ArrayAdapter<>(
+ this,
+ R.layout.list_item_spinner,
+ getResources().getStringArray(R.array.interval_options));
+ intervalOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
+ checkIntervalSpinner.setAdapter(intervalOptionsAdapter);
- if (mModel.checkInterval >= TimeUtil.WEEK) {
- inputCheckInterval.setText(Integer.toString((int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.WEEK))));
- checkIntervalSpinner.setSelection(3);
- } else if (mModel.checkInterval >= TimeUtil.DAY) {
- inputCheckInterval.setText(Integer.toString((int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.DAY))));
- checkIntervalSpinner.setSelection(2);
- } else if (mModel.checkInterval >= TimeUtil.HOUR) {
- inputCheckInterval.setText(Integer.toString((int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.HOUR))));
- checkIntervalSpinner.setSelection(1);
- } else if (mModel.checkInterval >= TimeUtil.MINUTE) {
- inputCheckInterval.setText(Integer.toString((int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.MINUTE))));
- checkIntervalSpinner.setSelection(0);
+ inputUrl.setOnFocusChangeListener(
+ (view, hasFocus) -> {
+ if (!hasFocus) {
+ final String inputStr = inputUrl.getText().toString().trim();
+ if (inputStr.isEmpty()) return;
+ final Uri uri = Uri.parse(inputStr);
+ if (uri.getScheme() == null) {
+ inputUrl.setText("http://" + inputStr);
+ textUrlWarning.setVisibility(View.GONE);
+ } else if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
+ textUrlWarning.setVisibility(View.VISIBLE);
+ textUrlWarning.setText(R.string.warning_http_url);
} else {
- inputCheckInterval.setText("0");
- checkIntervalSpinner.setSelection(0);
+ textUrlWarning.setVisibility(View.GONE);
}
- }
+ }
+ });
- responseValidationSpinner.setSelection(mModel.validationMode - 1);
- switch (mModel.validationMode) {
- case ValidationMode.TERM_SEARCH:
- ((TextView) findViewById(R.id.responseValidationSearchTerm)).setText(mModel.validationContent);
+ ArrayAdapter validationOptionsAdapter =
+ new ArrayAdapter<>(
+ this,
+ R.layout.list_item_spinner,
+ getResources().getStringArray(R.array.response_validation_options));
+ validationOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown);
+ responseValidationSpinner.setAdapter(validationOptionsAdapter);
+ responseValidationSpinner.setOnItemSelectedListener(
+ new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {
+ final View searchTerm = findViewById(R.id.responseValidationSearchTerm);
+ final View javascript = findViewById(R.id.responseValidationScript);
+ final TextView modeDesc = (TextView) findViewById(R.id.validationModeDescription);
+
+ searchTerm.setVisibility(i == 1 ? View.VISIBLE : View.GONE);
+ javascript.setVisibility(i == 2 ? View.VISIBLE : View.GONE);
+
+ switch (i) {
+ case 0:
+ modeDesc.setText(R.string.validation_mode_status_desc);
break;
- case ValidationMode.JAVASCRIPT:
- ((TextView) findViewById(R.id.responseValidationScriptInput)).setText(mModel.validationContent);
+ case 1:
+ modeDesc.setText(R.string.validation_mode_term_desc);
+ break;
+ case 2:
+ modeDesc.setText(R.string.validation_mode_javascript_desc);
break;
- }
-
- findViewById(R.id.doneBtn).setOnClickListener(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- try {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(CheckService.ACTION_CHECK_UPDATE);
- // filter.addAction(CheckService.ACTION_RUNNING);
- registerReceiver(mReceiver, filter);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- try {
- unregisterReceiver(mReceiver);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private void performSave(boolean withValidation) {
- mModel.name = inputName.getText().toString().trim();
- mModel.url = inputUrl.getText().toString().trim();
- mModel.status = ServerStatus.WAITING;
-
- if (withValidation && mModel.name.isEmpty()) {
- inputName.setError(getString(R.string.please_enter_name));
- return;
- } else {
- inputName.setError(null);
- }
-
- if (withValidation && mModel.url.isEmpty()) {
- inputUrl.setError(getString(R.string.please_enter_url));
- return;
- } else {
- inputUrl.setError(null);
- if (withValidation && !Patterns.WEB_URL.matcher(mModel.url).find()) {
- inputUrl.setError(getString(R.string.please_enter_valid_url));
- return;
- } else {
- final Uri uri = Uri.parse(mModel.url);
- if (uri.getScheme() == null)
- mModel.url = "http://" + mModel.url;
}
- }
+ }
- String intervalStr = inputCheckInterval.getText().toString().trim();
- if (intervalStr.isEmpty()) intervalStr = "0";
- mModel.checkInterval = Integer.parseInt(intervalStr);
+ @Override
+ public void onNothingSelected(AdapterView> adapterView) {}
+ });
- switch (checkIntervalSpinner.getSelectedItemPosition()) {
- case 0: // minutes
- mModel.checkInterval *= (60 * 1000);
- break;
- case 1: // hours
- mModel.checkInterval *= (60 * 60 * 1000);
- break;
- case 2: // days
- mModel.checkInterval *= (60 * 60 * 24 * 1000);
- break;
- default: // weeks
- mModel.checkInterval *= (60 * 60 * 24 * 7 * 1000);
- break;
- }
+ mModel = (ServerModel) getIntent().getSerializableExtra("model");
+ update();
- mModel.lastCheck = System.currentTimeMillis() - mModel.checkInterval;
+ Bridge.config().defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
+ }
- switch (responseValidationSpinner.getSelectedItemPosition()) {
- case 0:
- mModel.validationMode = ValidationMode.STATUS_CODE;
- mModel.validationContent = null;
- break;
- case 1:
- mModel.validationMode = ValidationMode.TERM_SEARCH;
- mModel.validationContent = ((EditText) findViewById(R.id.responseValidationSearchTerm)).getText().toString().trim();
- break;
- case 2:
- mModel.validationMode = ValidationMode.JAVASCRIPT;
- mModel.validationContent = ((EditText) findViewById(R.id.responseValidationScriptInput)).getText().toString().trim();
- break;
- }
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ if (intent != null && intent.hasExtra("model")) {
+ mModel = (ServerModel) intent.getSerializableExtra("model");
+ update();
+ }
+ }
- final Inquiry inq = Inquiry.newInstance(this, MainActivity.DB_NAME)
- .build(false);
- //noinspection CheckResult
- inq.update(MainActivity.SITES_TABLE_NAME, ServerModel.class)
- .where("_id = ?", mModel.id)
- .values(mModel)
- .run();
- inq.destroyInstance();
+ @SuppressLint({"SetTextI18n", "SwitchIntDef"})
+ private void update() {
+ final SimpleDateFormat df = new SimpleDateFormat("MMMM dd, hh:mm:ss a", Locale.getDefault());
+
+ iconStatus.setStatus(mModel.status);
+ inputName.setText(mModel.name);
+ inputUrl.setText(mModel.url);
+
+ if (mModel.lastCheck == 0) {
+ textLastCheckResult.setText(R.string.none);
+ } else {
+ switch (mModel.status) {
+ case ServerStatus.CHECKING:
+ textLastCheckResult.setText(R.string.checking_status);
+ break;
+ case ServerStatus.ERROR:
+ textLastCheckResult.setText(mModel.reason);
+ break;
+ case ServerStatus.OK:
+ textLastCheckResult.setText(R.string.everything_checks_out);
+ break;
+ case ServerStatus.WAITING:
+ textLastCheckResult.setText(R.string.waiting);
+ break;
+ }
}
- // Save button
- @Override
- public void onClick(View view) {
- performSave(true);
- setResult(RESULT_OK, new Intent().putExtra("model", mModel));
- finish();
+ if (mModel.checkInterval == 0) {
+ textNextCheck.setText(R.string.none_turned_off);
+ inputCheckInterval.setText("");
+ checkIntervalSpinner.setSelection(0);
+ } else {
+ long lastCheck = mModel.lastCheck;
+ if (lastCheck == 0) lastCheck = System.currentTimeMillis();
+ textNextCheck.setText(df.format(new Date(lastCheck + mModel.checkInterval)));
+
+ if (mModel.checkInterval >= TimeUtil.WEEK) {
+ inputCheckInterval.setText(
+ Integer.toString(
+ (int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.WEEK))));
+ checkIntervalSpinner.setSelection(3);
+ } else if (mModel.checkInterval >= TimeUtil.DAY) {
+ inputCheckInterval.setText(
+ Integer.toString(
+ (int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.DAY))));
+ checkIntervalSpinner.setSelection(2);
+ } else if (mModel.checkInterval >= TimeUtil.HOUR) {
+ inputCheckInterval.setText(
+ Integer.toString(
+ (int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.HOUR))));
+ checkIntervalSpinner.setSelection(1);
+ } else if (mModel.checkInterval >= TimeUtil.MINUTE) {
+ inputCheckInterval.setText(
+ Integer.toString(
+ (int) Math.ceil(((float) mModel.checkInterval / (float) TimeUtil.MINUTE))));
+ checkIntervalSpinner.setSelection(0);
+ } else {
+ inputCheckInterval.setText("0");
+ checkIntervalSpinner.setSelection(0);
+ }
}
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.refresh:
- performSave(false);
- MainActivity.checkSite(this, mModel);
- return true;
- case R.id.remove:
- MainActivity.removeSite(this, mModel, this::finish);
- return true;
- }
- return false;
+ responseValidationSpinner.setSelection(mModel.validationMode - 1);
+ switch (mModel.validationMode) {
+ case ValidationMode.TERM_SEARCH:
+ ((TextView) findViewById(R.id.responseValidationSearchTerm))
+ .setText(mModel.validationContent);
+ break;
+ case ValidationMode.JAVASCRIPT:
+ ((TextView) findViewById(R.id.responseValidationScriptInput))
+ .setText(mModel.validationContent);
+ break;
}
+
+ findViewById(R.id.doneBtn).setOnClickListener(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ try {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(CheckService.ACTION_CHECK_UPDATE);
+ // filter.addAction(CheckService.ACTION_RUNNING);
+ registerReceiver(mReceiver, filter);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ try {
+ unregisterReceiver(mReceiver);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ private void performSave(boolean withValidation) {
+ mModel.name = inputName.getText().toString().trim();
+ mModel.url = inputUrl.getText().toString().trim();
+ mModel.status = ServerStatus.WAITING;
+
+ if (withValidation && mModel.name.isEmpty()) {
+ inputName.setError(getString(R.string.please_enter_name));
+ return;
+ } else {
+ inputName.setError(null);
+ }
+
+ if (withValidation && mModel.url.isEmpty()) {
+ inputUrl.setError(getString(R.string.please_enter_url));
+ return;
+ } else {
+ inputUrl.setError(null);
+ if (withValidation && !Patterns.WEB_URL.matcher(mModel.url).find()) {
+ inputUrl.setError(getString(R.string.please_enter_valid_url));
+ return;
+ } else {
+ final Uri uri = Uri.parse(mModel.url);
+ if (uri.getScheme() == null) mModel.url = "http://" + mModel.url;
+ }
+ }
+
+ String intervalStr = inputCheckInterval.getText().toString().trim();
+ if (intervalStr.isEmpty()) intervalStr = "0";
+ mModel.checkInterval = Integer.parseInt(intervalStr);
+
+ switch (checkIntervalSpinner.getSelectedItemPosition()) {
+ case 0: // minutes
+ mModel.checkInterval *= (60 * 1000);
+ break;
+ case 1: // hours
+ mModel.checkInterval *= (60 * 60 * 1000);
+ break;
+ case 2: // days
+ mModel.checkInterval *= (60 * 60 * 24 * 1000);
+ break;
+ default: // weeks
+ mModel.checkInterval *= (60 * 60 * 24 * 7 * 1000);
+ break;
+ }
+
+ mModel.lastCheck = System.currentTimeMillis() - mModel.checkInterval;
+
+ switch (responseValidationSpinner.getSelectedItemPosition()) {
+ case 0:
+ mModel.validationMode = ValidationMode.STATUS_CODE;
+ mModel.validationContent = null;
+ break;
+ case 1:
+ mModel.validationMode = ValidationMode.TERM_SEARCH;
+ mModel.validationContent =
+ ((EditText) findViewById(R.id.responseValidationSearchTerm))
+ .getText()
+ .toString()
+ .trim();
+ break;
+ case 2:
+ mModel.validationMode = ValidationMode.JAVASCRIPT;
+ mModel.validationContent =
+ ((EditText) findViewById(R.id.responseValidationScriptInput))
+ .getText()
+ .toString()
+ .trim();
+ break;
+ }
+
+ final Inquiry inq = Inquiry.newInstance(this, MainActivity.DB_NAME).build(false);
+ //noinspection CheckResult
+ inq.update(MainActivity.SITES_TABLE_NAME, ServerModel.class)
+ .where("_id = ?", mModel.id)
+ .values(mModel)
+ .run();
+ inq.destroyInstance();
+ }
+
+ // Save button
+ @Override
+ public void onClick(View view) {
+ performSave(true);
+ setResult(RESULT_OK, new Intent().putExtra("model", mModel));
+ finish();
+ }
+
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.refresh:
+ performSave(false);
+ MainActivity.checkSite(this, mModel);
+ return true;
+ case R.id.remove:
+ MainActivity.removeSite(this, mModel, this::finish);
+ return true;
+ }
+ return false;
+ }
}
diff --git a/app/src/main/java/com/afollestad/nocknock/util/AlarmUtil.java b/app/src/main/java/com/afollestad/nocknock/util/AlarmUtil.java
index 7effdb4..a527898 100644
--- a/app/src/main/java/com/afollestad/nocknock/util/AlarmUtil.java
+++ b/app/src/main/java/com/afollestad/nocknock/util/AlarmUtil.java
@@ -5,55 +5,57 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
-
import com.afollestad.nocknock.api.ServerModel;
import com.afollestad.nocknock.services.CheckService;
-
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class AlarmUtil {
- private final static int BASE_RQC = 69;
+ private static final int BASE_RQC = 69;
- public static PendingIntent getSiteIntent(Context context, ServerModel site) {
- return PendingIntent.getService(context,
- BASE_RQC + (int) site.id,
- new Intent(context, CheckService.class)
- .putExtra(CheckService.MODEL_ID, site.id),
- PendingIntent.FLAG_UPDATE_CURRENT);
- }
+ public static PendingIntent getSiteIntent(Context context, ServerModel site) {
+ return PendingIntent.getService(
+ context,
+ BASE_RQC + (int) site.id,
+ new Intent(context, CheckService.class).putExtra(CheckService.MODEL_ID, site.id),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ }
- private static AlarmManager am(Context context) {
- return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- }
+ private static AlarmManager am(Context context) {
+ return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ }
- public static void cancelSiteChecks(Context context, ServerModel site) {
- PendingIntent pi = getSiteIntent(context, site);
- am(context).cancel(pi);
- }
+ public static void cancelSiteChecks(Context context, ServerModel site) {
+ PendingIntent pi = getSiteIntent(context, site);
+ am(context).cancel(pi);
+ }
- public static void setSiteChecks(Context context, ServerModel site) {
- cancelSiteChecks(context, site);
- if (site.checkInterval <= 0) return;
- if (site.lastCheck <= 0)
- site.lastCheck = System.currentTimeMillis();
- final long nextCheck = site.lastCheck + site.checkInterval;
- final AlarmManager aMgr = am(context);
- final PendingIntent serviceIntent = getSiteIntent(context, site);
- aMgr.setRepeating(AlarmManager.RTC_WAKEUP, nextCheck, site.checkInterval, serviceIntent);
- final SimpleDateFormat df = new SimpleDateFormat("EEE MMM dd hh:mm:ssa z yyyy", Locale.getDefault());
- Log.d("AlarmUtil", String.format(Locale.getDefault(), "Set site check alarm for %s (%s), check interval: %d, next check: %s",
- site.name, site.url, site.checkInterval, df.format(new Date(nextCheck))));
- }
+ public static void setSiteChecks(Context context, ServerModel site) {
+ cancelSiteChecks(context, site);
+ if (site.checkInterval <= 0) return;
+ if (site.lastCheck <= 0) site.lastCheck = System.currentTimeMillis();
+ final long nextCheck = site.lastCheck + site.checkInterval;
+ final AlarmManager aMgr = am(context);
+ final PendingIntent serviceIntent = getSiteIntent(context, site);
+ aMgr.setRepeating(AlarmManager.RTC_WAKEUP, nextCheck, site.checkInterval, serviceIntent);
+ final SimpleDateFormat df =
+ new SimpleDateFormat("EEE MMM dd hh:mm:ssa z yyyy", Locale.getDefault());
+ Log.d(
+ "AlarmUtil",
+ String.format(
+ Locale.getDefault(),
+ "Set site check alarm for %s (%s), check interval: %d, next check: %s",
+ site.name,
+ site.url,
+ site.checkInterval,
+ df.format(new Date(nextCheck))));
+ }
- public static void setSiteChecks(Context context, ServerModel[] sites) {
- if (sites == null || sites.length == 0) return;
- for (ServerModel site : sites)
- setSiteChecks(context, site);
- }
-}
\ No newline at end of file
+ public static void setSiteChecks(Context context, ServerModel[] sites) {
+ if (sites == null || sites.length == 0) return;
+ for (ServerModel site : sites) setSiteChecks(context, site);
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/util/JsUtil.java b/app/src/main/java/com/afollestad/nocknock/util/JsUtil.java
index 160927b..3c7c462 100644
--- a/app/src/main/java/com/afollestad/nocknock/util/JsUtil.java
+++ b/app/src/main/java/com/afollestad/nocknock/util/JsUtil.java
@@ -1,72 +1,68 @@
package com.afollestad.nocknock.util;
import android.util.Log;
-
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class JsUtil {
- public static String exec(String code, String response) {
- try {
- final String func = String.format(
- "function validate(response) { " +
- "try { " +
- "%s " +
- "} catch(e) { " +
- "return e; " +
- "} " +
- "}", code.replace("\n", " "));
+ public static String exec(String code, String response) {
+ try {
+ final String func =
+ String.format(
+ "function validate(response) { "
+ + "try { "
+ + "%s "
+ + "} catch(e) { "
+ + "return e; "
+ + "} "
+ + "}",
+ code.replace("\n", " "));
- // Every Rhino VM begins with the enter()
- // This Context is not Android's Context
- Context rhino = Context.enter();
+ // Every Rhino VM begins with the enter()
+ // This Context is not Android's Context
+ Context rhino = Context.enter();
- // Turn off optimization to make Rhino Android compatible
- rhino.setOptimizationLevel(-1);
- try {
- Scriptable scope = rhino.initStandardObjects();
+ // Turn off optimization to make Rhino Android compatible
+ rhino.setOptimizationLevel(-1);
+ try {
+ Scriptable scope = rhino.initStandardObjects();
- // Note the forth argument is 1, which means the JavaScript source has
- // been compressed to only one line using something like YUI
- rhino.evaluateString(scope, func, "JavaScript", 1, null);
+ // Note the forth argument is 1, which means the JavaScript source has
+ // been compressed to only one line using something like YUI
+ rhino.evaluateString(scope, func, "JavaScript", 1, null);
- // Get the functionName defined in JavaScriptCode
- Function jsFunction = (Function) scope.get("validate", scope);
+ // Get the functionName defined in JavaScriptCode
+ Function jsFunction = (Function) scope.get("validate", scope);
- // Call the function with params
- Object jsResult = jsFunction.call(rhino, scope, scope, new Object[]{response});
-
- // Parse the jsResult object to a String
- String result = Context.toString(jsResult);
-
- boolean success = result != null && result.equals("true");
- String message = "The script returned a value other than true!";
- if (!success && result != null && !result.equals("false")) {
- if (result.equals("undefined")) {
- message = "The script did not return or throw anything!";
- } else {
- message = result;
- }
- }
-
- Log.d("JsUtil", "Evaluated to " + message + " (" + success + "): " + code);
- return !success ? message : null;
- } finally {
- Context.exit();
- }
- } catch (EvaluatorException e) {
- return e.getMessage();
+ // Call the function with params
+ Object jsResult = jsFunction.call(rhino, scope, scope, new Object[] {response});
+ // Parse the jsResult object to a String
+ String result = Context.toString(jsResult);
+ boolean success = result != null && result.equals("true");
+ String message = "The script returned a value other than true!";
+ if (!success && result != null && !result.equals("false")) {
+ if (result.equals("undefined")) {
+ message = "The script did not return or throw anything!";
+ } else {
+ message = result;
+ }
}
- }
- private JsUtil() {
+ Log.d("JsUtil", "Evaluated to " + message + " (" + success + "): " + code);
+ return !success ? message : null;
+ } finally {
+ Context.exit();
+ }
+ } catch (EvaluatorException e) {
+ return e.getMessage();
}
+ }
+
+ private JsUtil() {}
}
diff --git a/app/src/main/java/com/afollestad/nocknock/util/MathUtil.java b/app/src/main/java/com/afollestad/nocknock/util/MathUtil.java
index 6cb885b..efe418b 100644
--- a/app/src/main/java/com/afollestad/nocknock/util/MathUtil.java
+++ b/app/src/main/java/com/afollestad/nocknock/util/MathUtil.java
@@ -4,29 +4,27 @@ import android.graphics.Path;
import android.support.design.widget.FloatingActionButton;
import android.view.View;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public final class MathUtil {
- public static Path bezierCurve(FloatingActionButton fab, View rootView) {
- final int fabCenterX = (int) (fab.getX() + fab.getMeasuredWidth() / 2);
- final int fabCenterY = (int) (fab.getY() + fab.getMeasuredHeight() / 2);
+ public static Path bezierCurve(FloatingActionButton fab, View rootView) {
+ final int fabCenterX = (int) (fab.getX() + fab.getMeasuredWidth() / 2);
+ final int fabCenterY = (int) (fab.getY() + fab.getMeasuredHeight() / 2);
- final int endCenterX = (rootView.getMeasuredWidth() / 2) - (fab.getMeasuredWidth() / 2);
- final int endCenterY = (rootView.getMeasuredHeight() / 2) - (fab.getMeasuredHeight() / 2);
+ final int endCenterX = (rootView.getMeasuredWidth() / 2) - (fab.getMeasuredWidth() / 2);
+ final int endCenterY = (rootView.getMeasuredHeight() / 2) - (fab.getMeasuredHeight() / 2);
- final int halfX = (fabCenterX - endCenterX) / 2;
- final int halfY = (fabCenterY - endCenterY) / 2;
- int mControlX = endCenterX + halfX;
- int mControlY = endCenterY + halfY;
- mControlY -= halfY;
- mControlX += halfX;
+ final int halfX = (fabCenterX - endCenterX) / 2;
+ final int halfY = (fabCenterY - endCenterY) / 2;
+ int mControlX = endCenterX + halfX;
+ int mControlY = endCenterY + halfY;
+ mControlY -= halfY;
+ mControlX += halfX;
- Path path = new Path();
- path.moveTo(fab.getX(), fab.getY());
- path.quadTo(mControlX, mControlY, endCenterX, endCenterY);
+ Path path = new Path();
+ path.moveTo(fab.getX(), fab.getY());
+ path.quadTo(mControlX, mControlY, endCenterX, endCenterY);
- return path;
- }
-}
\ No newline at end of file
+ return path;
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/util/NetworkUtil.java b/app/src/main/java/com/afollestad/nocknock/util/NetworkUtil.java
index 3680f26..c67e57a 100644
--- a/app/src/main/java/com/afollestad/nocknock/util/NetworkUtil.java
+++ b/app/src/main/java/com/afollestad/nocknock/util/NetworkUtil.java
@@ -4,15 +4,13 @@ import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class NetworkUtil {
- public static boolean hasInternet(Context context) {
- final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- final NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
- return activeNetwork != null &&
- activeNetwork.isConnectedOrConnecting();
- }
-}
\ No newline at end of file
+ public static boolean hasInternet(Context context) {
+ final ConnectivityManager cm =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ final NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/util/TimeUtil.java b/app/src/main/java/com/afollestad/nocknock/util/TimeUtil.java
index 3a65b73..bc0b604 100644
--- a/app/src/main/java/com/afollestad/nocknock/util/TimeUtil.java
+++ b/app/src/main/java/com/afollestad/nocknock/util/TimeUtil.java
@@ -1,32 +1,30 @@
package com.afollestad.nocknock.util;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class TimeUtil {
- public final static long SECOND = 1000;
- public final static long MINUTE = SECOND * 60;
- public final static long HOUR = MINUTE * 60;
- public final static long DAY = HOUR * 24;
- public final static long WEEK = DAY * 7;
- public final static long MONTH = WEEK * 4;
+ public static final long SECOND = 1000;
+ public static final long MINUTE = SECOND * 60;
+ public static final long HOUR = MINUTE * 60;
+ public static final long DAY = HOUR * 24;
+ public static final long WEEK = DAY * 7;
+ public static final long MONTH = WEEK * 4;
- public static String str(long duration) {
- if (duration <= 0) {
- return "";
- } else if (duration >= MONTH) {
- return (int) Math.ceil(((float) duration / (float) MONTH)) + "mo";
- } else if (duration >= WEEK) {
- return (int) Math.ceil(((float) duration / (float) WEEK)) + "w";
- } else if (duration >= DAY) {
- return (int) Math.ceil(((float) duration / (float) DAY)) + "d";
- } else if (duration >= HOUR) {
- return (int) Math.ceil(((float) duration / (float) HOUR)) + "h";
- } else if (duration >= MINUTE) {
- return (int) Math.ceil(((float) duration / (float) MINUTE)) + "m";
- } else {
- return "<1m";
- }
+ public static String str(long duration) {
+ if (duration <= 0) {
+ return "";
+ } else if (duration >= MONTH) {
+ return (int) Math.ceil(((float) duration / (float) MONTH)) + "mo";
+ } else if (duration >= WEEK) {
+ return (int) Math.ceil(((float) duration / (float) WEEK)) + "w";
+ } else if (duration >= DAY) {
+ return (int) Math.ceil(((float) duration / (float) DAY)) + "d";
+ } else if (duration >= HOUR) {
+ return (int) Math.ceil(((float) duration / (float) HOUR)) + "h";
+ } else if (duration >= MINUTE) {
+ return (int) Math.ceil(((float) duration / (float) MINUTE)) + "m";
+ } else {
+ return "<1m";
}
+ }
}
diff --git a/app/src/main/java/com/afollestad/nocknock/views/DividerItemDecoration.java b/app/src/main/java/com/afollestad/nocknock/views/DividerItemDecoration.java
index cc4396a..5000d4c 100644
--- a/app/src/main/java/com/afollestad/nocknock/views/DividerItemDecoration.java
+++ b/app/src/main/java/com/afollestad/nocknock/views/DividerItemDecoration.java
@@ -26,79 +26,75 @@ import android.view.View;
*/
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
- private static final int[] ATTRS = new int[]{
- android.R.attr.listDivider
- };
+ private static final int[] ATTRS = new int[] {android.R.attr.listDivider};
- public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
+ public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
- public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
+ public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
- private Drawable mDivider;
+ private Drawable mDivider;
- private int mOrientation;
+ private int mOrientation;
- public DividerItemDecoration(Context context, int orientation) {
- final TypedArray a = context.obtainStyledAttributes(ATTRS);
- mDivider = a.getDrawable(0);
- a.recycle();
- setOrientation(orientation);
+ public DividerItemDecoration(Context context, int orientation) {
+ final TypedArray a = context.obtainStyledAttributes(ATTRS);
+ mDivider = a.getDrawable(0);
+ a.recycle();
+ setOrientation(orientation);
+ }
+
+ public void setOrientation(int orientation) {
+ if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
+ throw new IllegalArgumentException("invalid orientation");
}
+ mOrientation = orientation;
+ }
- public void setOrientation(int orientation) {
- if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
- throw new IllegalArgumentException("invalid orientation");
- }
- mOrientation = orientation;
+ @Override
+ public void onDraw(Canvas c, RecyclerView parent) {
+ if (mOrientation == VERTICAL_LIST) {
+ drawVertical(c, parent);
+ } else {
+ drawHorizontal(c, parent);
}
+ }
- @Override
- public void onDraw(Canvas c, RecyclerView parent) {
- if (mOrientation == VERTICAL_LIST) {
- drawVertical(c, parent);
- } else {
- drawHorizontal(c, parent);
- }
+ public void drawVertical(Canvas c, RecyclerView parent) {
+ final int left = parent.getPaddingLeft();
+ final int right = parent.getWidth() - parent.getPaddingRight();
+
+ final int childCount = parent.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = parent.getChildAt(i);
+ final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
+ final int top = child.getBottom() + params.bottomMargin;
+ final int bottom = top + mDivider.getIntrinsicHeight();
+ mDivider.setBounds(left, top, right, bottom);
+ mDivider.draw(c);
}
+ }
- public void drawVertical(Canvas c, RecyclerView parent) {
- final int left = parent.getPaddingLeft();
- final int right = parent.getWidth() - parent.getPaddingRight();
+ public void drawHorizontal(Canvas c, RecyclerView parent) {
+ final int top = parent.getPaddingTop();
+ final int bottom = parent.getHeight() - parent.getPaddingBottom();
- final int childCount = parent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- final View child = parent.getChildAt(i);
- final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
- .getLayoutParams();
- final int top = child.getBottom() + params.bottomMargin;
- final int bottom = top + mDivider.getIntrinsicHeight();
- mDivider.setBounds(left, top, right, bottom);
- mDivider.draw(c);
- }
+ final int childCount = parent.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = parent.getChildAt(i);
+ final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
+ final int left = child.getRight() + params.rightMargin;
+ final int right = left + mDivider.getIntrinsicHeight();
+ mDivider.setBounds(left, top, right, bottom);
+ mDivider.draw(c);
}
+ }
- public void drawHorizontal(Canvas c, RecyclerView parent) {
- final int top = parent.getPaddingTop();
- final int bottom = parent.getHeight() - parent.getPaddingBottom();
-
- final int childCount = parent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- final View child = parent.getChildAt(i);
- final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
- .getLayoutParams();
- final int left = child.getRight() + params.rightMargin;
- final int right = left + mDivider.getIntrinsicHeight();
- mDivider.setBounds(left, top, right, bottom);
- mDivider.draw(c);
- }
+ @Override
+ public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
+ if (mOrientation == VERTICAL_LIST) {
+ outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
+ } else {
+ outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
-
- @Override
- public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
- if (mOrientation == VERTICAL_LIST) {
- outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
- } else {
- outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
- }
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/app/src/main/java/com/afollestad/nocknock/views/StatusImageView.java b/app/src/main/java/com/afollestad/nocknock/views/StatusImageView.java
index ac8cf13..4aa41a7 100644
--- a/app/src/main/java/com/afollestad/nocknock/views/StatusImageView.java
+++ b/app/src/main/java/com/afollestad/nocknock/views/StatusImageView.java
@@ -3,45 +3,42 @@ package com.afollestad.nocknock.views;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
-
import com.afollestad.nocknock.R;
import com.afollestad.nocknock.api.ServerStatus;
-/**
- * @author Aidan Follestad (afollestad)
- */
+/** @author Aidan Follestad (afollestad) */
public class StatusImageView extends ImageView {
- public StatusImageView(Context context) {
- super(context);
- setStatus(ServerStatus.OK);
- }
+ public StatusImageView(Context context) {
+ super(context);
+ setStatus(ServerStatus.OK);
+ }
- public StatusImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setStatus(ServerStatus.OK);
- }
+ public StatusImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setStatus(ServerStatus.OK);
+ }
- public StatusImageView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- setStatus(ServerStatus.OK);
- }
+ public StatusImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setStatus(ServerStatus.OK);
+ }
- public void setStatus(@ServerStatus.Enum int status) {
- switch (status) {
- case ServerStatus.CHECKING:
- case ServerStatus.WAITING:
- setImageResource(R.drawable.status_progress);
- setBackgroundResource(R.drawable.yellow_circle);
- break;
- case ServerStatus.ERROR:
- setImageResource(R.drawable.status_error);
- setBackgroundResource(R.drawable.red_circle);
- break;
- case ServerStatus.OK:
- setImageResource(R.drawable.status_ok);
- setBackgroundResource(R.drawable.green_circle);
- break;
- }
+ public void setStatus(@ServerStatus.Enum int status) {
+ switch (status) {
+ case ServerStatus.CHECKING:
+ case ServerStatus.WAITING:
+ setImageResource(R.drawable.status_progress);
+ setBackgroundResource(R.drawable.yellow_circle);
+ break;
+ case ServerStatus.ERROR:
+ setImageResource(R.drawable.status_error);
+ setBackgroundResource(R.drawable.red_circle);
+ break;
+ case ServerStatus.OK:
+ setImageResource(R.drawable.status_ok);
+ setBackgroundResource(R.drawable.green_circle);
+ break;
}
+ }
}
diff --git a/build.gradle b/build.gradle
index 75c86f6..d68c028 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,14 +1,14 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply from: './dependencies.gradle'
buildscript {
+ apply from: './dependencies.gradle'
+
repositories {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.3'
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
+ classpath 'com.android.tools.build:gradle:' + versions.gradlePlugin
+ classpath "com.diffplug.spotless:spotless-plugin-gradle:" + versions.spotlessPlugin
}
}
@@ -17,6 +17,22 @@ allprojects {
jcenter()
maven { url "https://jitpack.io" }
}
+
+ buildscript {
+ repositories {
+ maven { url "https://plugins.gradle.org/m2/" }
+ }
+ }
+ apply plugin: "com.diffplug.gradle.spotless"
+ spotless {
+ java {
+ target "**/*.java"
+ trimTrailingWhitespace()
+ removeUnusedImports()
+ googleJavaFormat()
+ endWithNewline()
+ }
+ }
}
task clean(type: Delete) {
diff --git a/dependencies.gradle b/dependencies.gradle
new file mode 100644
index 0000000..2ddd7c7
--- /dev/null
+++ b/dependencies.gradle
@@ -0,0 +1,13 @@
+ext.versions = [
+ minSdk : 21,
+ compileSdk : 26,
+ buildTools : '26.0.0',
+ publishVersion : '0.1.3.1',
+ publishVersionCode: 14,
+ gradlePlugin : '2.3.2',
+ spotlessPlugin : '3.4.0',
+ supportLib : '25.3.1',
+ materialDialogs : '0.9.4.5',
+ bridge : '5.1.2',
+ inquiry : '5.0.0'
+]
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index cf2d737..41f2737 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip