Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
66f82f26d5
|
|||
6cb2aa00fb
|
|||
96a236803e
|
|||
9d24044eb3
|
|||
90248bcb54
|
|||
a3b2a1b14f
|
|||
b21b159b95
|
|||
93ec261dc0
|
|||
ae246e9219
|
|||
3f18fdd35a
|
|||
faf5207478
|
|||
71f003dd66
|
|||
3f85ab514e
|
|||
9eb5a6b1b9
|
|||
8e26cd6078
|
|||
36b9263730
|
|||
3d29fecaec
|
|||
![]() |
92ac05f1e3 |
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
<uses-permission android:name="com.android.vending.BILLING" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
@@ -116,6 +116,10 @@ public class SCNApp extends Application implements LifecycleObserver
|
|||||||
|
|
||||||
[X] - perhaps response codes in api (?)
|
[X] - perhaps response codes in api (?)
|
||||||
|
|
||||||
|
[X] - verify recieve
|
||||||
|
|
||||||
|
[ ] - Android O repeat sound
|
||||||
|
|
||||||
[ ] - test notification channels
|
[ ] - test notification channels
|
||||||
|
|
||||||
[ ] - publish (+ HN post ?)
|
[ ] - publish (+ HN post ?)
|
||||||
|
@@ -9,6 +9,7 @@ import java.util.TimeZone;
|
|||||||
|
|
||||||
public class CMessage
|
public class CMessage
|
||||||
{
|
{
|
||||||
|
public final long SCN_ID;
|
||||||
public final long Timestamp;
|
public final long Timestamp;
|
||||||
public final String Title;
|
public final String Title;
|
||||||
public final String Content;
|
public final String Content;
|
||||||
@@ -21,8 +22,9 @@ public class CMessage
|
|||||||
_format.setTimeZone(TimeZone.getDefault());
|
_format.setTimeZone(TimeZone.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
public CMessage(long t, String mt, String mc, PriorityEnum p)
|
public CMessage(long id, long t, String mt, String mc, PriorityEnum p)
|
||||||
{
|
{
|
||||||
|
SCN_ID = id;
|
||||||
Timestamp = t;
|
Timestamp = t;
|
||||||
Title = mt;
|
Title = mt;
|
||||||
Content = mc;
|
Content = mc;
|
||||||
|
@@ -38,14 +38,15 @@ public class CMessageList
|
|||||||
String title = sharedPref.getString("message["+i+"].title", "");
|
String title = sharedPref.getString("message["+i+"].title", "");
|
||||||
String content = sharedPref.getString("message["+i+"].content", "");
|
String content = sharedPref.getString("message["+i+"].content", "");
|
||||||
PriorityEnum prio = PriorityEnum.parseAPI(sharedPref.getInt("message["+i+"].priority", 1));
|
PriorityEnum prio = PriorityEnum.parseAPI(sharedPref.getInt("message["+i+"].priority", 1));
|
||||||
|
long scnid = sharedPref.getLong("message["+i+"].scnid", 0);
|
||||||
|
|
||||||
Messages.add(new CMessage(time, title, content, prio));
|
Messages.add(new CMessage(scnid, time, title, content, prio));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CMessage add(final long time, final String title, final String content, final PriorityEnum pe)
|
public CMessage add(final long scnid, final long time, final String title, final String content, final PriorityEnum pe)
|
||||||
{
|
{
|
||||||
CMessage msg = new CMessage(time, title, content, pe);
|
CMessage msg = new CMessage(scnid, time, title, content, pe);
|
||||||
|
|
||||||
boolean run = SCNApp.runOnUiThread(() ->
|
boolean run = SCNApp.runOnUiThread(() ->
|
||||||
{
|
{
|
||||||
@@ -63,6 +64,7 @@ public class CMessageList
|
|||||||
e.putString("message["+count+"].title", title);
|
e.putString("message["+count+"].title", title);
|
||||||
e.putString("message["+count+"].content", content);
|
e.putString("message["+count+"].content", content);
|
||||||
e.putInt( "message["+count+"].priority", pe.ID);
|
e.putInt( "message["+count+"].priority", pe.ID);
|
||||||
|
e.putLong( "message["+count+"].scnid", scnid);
|
||||||
|
|
||||||
e.apply();
|
e.apply();
|
||||||
|
|
||||||
@@ -77,7 +79,7 @@ public class CMessageList
|
|||||||
|
|
||||||
if (!run)
|
if (!run)
|
||||||
{
|
{
|
||||||
Messages.add(new CMessage(time, title, content, pe));
|
Messages.add(new CMessage(scnid, time, title, content, pe));
|
||||||
fullSave();
|
fullSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +115,7 @@ public class CMessageList
|
|||||||
e.putString("message["+i+"].title", Messages.get(i).Title);
|
e.putString("message["+i+"].title", Messages.get(i).Title);
|
||||||
e.putString("message["+i+"].content", Messages.get(i).Content);
|
e.putString("message["+i+"].content", Messages.get(i).Content);
|
||||||
e.putInt( "message["+i+"].priority", Messages.get(i).Priority.ID);
|
e.putInt( "message["+i+"].priority", Messages.get(i).Priority.ID);
|
||||||
|
e.putLong( "message["+i+"].scnid", Messages.get(i).SCN_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.apply();
|
e.apply();
|
||||||
|
@@ -1,17 +1,29 @@
|
|||||||
package com.blackforestbytes.simplecloudnotifier.model;
|
package com.blackforestbytes.simplecloudnotifier.model;
|
||||||
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.media.RingtoneManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
public class NotificationSettings
|
public class NotificationSettings
|
||||||
{
|
{
|
||||||
public boolean EnableSound = false;
|
public boolean EnableSound;
|
||||||
public String SoundName = "";
|
public String SoundName;
|
||||||
public String SoundSource = Uri.EMPTY.toString();
|
public String SoundSource;
|
||||||
public boolean RepeatSound = false;
|
public boolean RepeatSound;
|
||||||
|
|
||||||
public boolean EnableLED = false;
|
public boolean EnableLED;
|
||||||
public int LEDColor = Color.BLUE;
|
public int LEDColor;
|
||||||
|
|
||||||
public boolean EnableVibration = false;
|
public boolean EnableVibration;
|
||||||
|
|
||||||
|
public NotificationSettings(PriorityEnum p)
|
||||||
|
{
|
||||||
|
EnableSound = (p == PriorityEnum.HIGH);
|
||||||
|
SoundName = (p == PriorityEnum.HIGH) ? "Default" : "";
|
||||||
|
SoundSource = (p == PriorityEnum.HIGH) ? RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION).toString() : Uri.EMPTY.toString();
|
||||||
|
RepeatSound = false;
|
||||||
|
EnableLED = (p == PriorityEnum.HIGH) || (p == PriorityEnum.NORMAL);
|
||||||
|
LEDColor = Color.BLUE;
|
||||||
|
EnableVibration = (p == PriorityEnum.HIGH) || (p == PriorityEnum.NORMAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import android.view.View;
|
|||||||
|
|
||||||
import com.android.billingclient.api.Purchase;
|
import com.android.billingclient.api.Purchase;
|
||||||
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
||||||
import com.blackforestbytes.simplecloudnotifier.service.IABService;
|
import com.blackforestbytes.simplecloudnotifier.service.IABService;
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
import com.google.firebase.iid.FirebaseInstanceId;
|
||||||
|
|
||||||
@@ -47,9 +48,9 @@ public class SCNSettings
|
|||||||
public boolean Enabled = true;
|
public boolean Enabled = true;
|
||||||
public int LocalCacheSize = 500;
|
public int LocalCacheSize = 500;
|
||||||
|
|
||||||
public final NotificationSettings PriorityLow = new NotificationSettings();
|
public final NotificationSettings PriorityLow = new NotificationSettings(PriorityEnum.LOW);
|
||||||
public final NotificationSettings PriorityNorm = new NotificationSettings();
|
public final NotificationSettings PriorityNorm = new NotificationSettings(PriorityEnum.NORMAL);
|
||||||
public final NotificationSettings PriorityHigh = new NotificationSettings();
|
public final NotificationSettings PriorityHigh = new NotificationSettings(PriorityEnum.HIGH);
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -195,10 +196,10 @@ public class SCNSettings
|
|||||||
if (isConnected())
|
if (isConnected())
|
||||||
{
|
{
|
||||||
ServerCommunication.info(user_id, user_key, loader);
|
ServerCommunication.info(user_id, user_key, loader);
|
||||||
if (promode_server != promode_local)
|
|
||||||
{
|
if (promode_server != promode_local) updateProState(loader);
|
||||||
updateProState(loader);
|
|
||||||
}
|
if (!Str.equals(fcm_token_local, fcm_token_server)) work(a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -4,7 +4,9 @@ import android.util.Log;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.json.JSONTokener;
|
import org.json.JSONTokener;
|
||||||
|
|
||||||
@@ -39,7 +41,7 @@ public class ServerCommunication
|
|||||||
@Override
|
@Override
|
||||||
public void onFailure(Call call, IOException e)
|
public void onFailure(Call call, IOException e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:register", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
|
SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
|
||||||
}
|
}
|
||||||
@@ -57,25 +59,25 @@ public class ServerCommunication
|
|||||||
|
|
||||||
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
||||||
|
|
||||||
if (!json.getBoolean("success"))
|
if (!json_bool(json, "success"))
|
||||||
{
|
{
|
||||||
SCNApp.showToast(json.getString("message"), 4000);
|
SCNApp.showToast(json_str(json, "message"), 4000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCNSettings.inst().user_id = json.getInt("user_id");
|
SCNSettings.inst().user_id = json_int(json, "user_id");
|
||||||
SCNSettings.inst().user_key = json.getString("user_key");
|
SCNSettings.inst().user_key = json_str(json, "user_key");
|
||||||
SCNSettings.inst().fcm_token_server = token;
|
SCNSettings.inst().fcm_token_server = token;
|
||||||
SCNSettings.inst().quota_curr = json.getInt("quota");
|
SCNSettings.inst().quota_curr = json_int(json, "quota");
|
||||||
SCNSettings.inst().quota_max = json.getInt("quota_max");
|
SCNSettings.inst().quota_max = json_int(json, "quota_max");
|
||||||
SCNSettings.inst().promode_server = json.getBoolean("is_pro");
|
SCNSettings.inst().promode_server = json_bool(json, "is_pro");
|
||||||
SCNSettings.inst().save();
|
SCNSettings.inst().save();
|
||||||
|
|
||||||
SCNApp.refreshAccountTab();
|
SCNApp.refreshAccountTab();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:register", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -87,7 +89,7 @@ public class ServerCommunication
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:register", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +107,7 @@ public class ServerCommunication
|
|||||||
@Override
|
@Override
|
||||||
public void onFailure(Call call, IOException e)
|
public void onFailure(Call call, IOException e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:update_1", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
|
SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
|
||||||
}
|
}
|
||||||
@@ -123,25 +125,25 @@ public class ServerCommunication
|
|||||||
|
|
||||||
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
||||||
|
|
||||||
if (!json.getBoolean("success"))
|
if (!json_bool(json, "success"))
|
||||||
{
|
{
|
||||||
SCNApp.showToast(json.getString("message"), 4000);
|
SCNApp.showToast(json_str(json, "message"), 4000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCNSettings.inst().user_id = json.getInt("user_id");
|
SCNSettings.inst().user_id = json_int(json, "user_id");
|
||||||
SCNSettings.inst().user_key = json.getString("user_key");
|
SCNSettings.inst().user_key = json_str(json, "user_key");
|
||||||
SCNSettings.inst().fcm_token_server = token;
|
SCNSettings.inst().fcm_token_server = token;
|
||||||
SCNSettings.inst().quota_curr = json.getInt("quota");
|
SCNSettings.inst().quota_curr = json_int(json, "quota");
|
||||||
SCNSettings.inst().quota_max = json.getInt("quota_max");
|
SCNSettings.inst().quota_max = json_int(json, "quota_max");
|
||||||
SCNSettings.inst().promode_server = json.getBoolean("is_pro");
|
SCNSettings.inst().promode_server = json_bool(json, "is_pro");
|
||||||
SCNSettings.inst().save();
|
SCNSettings.inst().save();
|
||||||
|
|
||||||
SCNApp.refreshAccountTab();
|
SCNApp.refreshAccountTab();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:update_1", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -153,7 +155,7 @@ public class ServerCommunication
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:update_1", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +171,7 @@ public class ServerCommunication
|
|||||||
client.newCall(request).enqueue(new Callback() {
|
client.newCall(request).enqueue(new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call call, IOException e) {
|
public void onFailure(Call call, IOException e) {
|
||||||
e.printStackTrace();
|
Log.e("SC:update_2", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,21 +187,21 @@ public class ServerCommunication
|
|||||||
|
|
||||||
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
||||||
|
|
||||||
if (!json.getBoolean("success")) {
|
if (!json_bool(json, "success")) {
|
||||||
SCNApp.showToast(json.getString("message"), 4000);
|
SCNApp.showToast(json_str(json, "message"), 4000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCNSettings.inst().user_id = json.getInt("user_id");
|
SCNSettings.inst().user_id = json_int(json, "user_id");
|
||||||
SCNSettings.inst().user_key = json.getString("user_key");
|
SCNSettings.inst().user_key = json_str(json, "user_key");
|
||||||
SCNSettings.inst().quota_curr = json.getInt("quota");
|
SCNSettings.inst().quota_curr = json_int(json, "quota");
|
||||||
SCNSettings.inst().quota_max = json.getInt("quota_max");
|
SCNSettings.inst().quota_max = json_int(json, "quota_max");
|
||||||
SCNSettings.inst().promode_server = json.getBoolean("is_pro");
|
SCNSettings.inst().promode_server = json_bool(json, "is_pro");
|
||||||
SCNSettings.inst().save();
|
SCNSettings.inst().save();
|
||||||
|
|
||||||
SCNApp.refreshAccountTab();
|
SCNApp.refreshAccountTab();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Log.e("SC:update_2", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
} finally {
|
} finally {
|
||||||
SCNApp.runOnUiThread(() -> {
|
SCNApp.runOnUiThread(() -> {
|
||||||
@@ -211,7 +213,7 @@ public class ServerCommunication
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:update_2", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,7 +229,7 @@ public class ServerCommunication
|
|||||||
client.newCall(request).enqueue(new Callback() {
|
client.newCall(request).enqueue(new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call call, IOException e) {
|
public void onFailure(Call call, IOException e) {
|
||||||
e.printStackTrace();
|
Log.e("SC:info", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
SCNApp.runOnUiThread(() -> {
|
SCNApp.runOnUiThread(() -> {
|
||||||
if (loader != null) loader.setVisibility(View.GONE);
|
if (loader != null) loader.setVisibility(View.GONE);
|
||||||
@@ -246,20 +248,40 @@ public class ServerCommunication
|
|||||||
|
|
||||||
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
||||||
|
|
||||||
if (!json.getBoolean("success")) {
|
if (!json_bool(json, "success"))
|
||||||
SCNApp.showToast(json.getString("message"), 4000);
|
{
|
||||||
|
SCNApp.showToast(json_str(json, "message"), 4000);
|
||||||
|
|
||||||
|
int errid = json.optInt("errid", 0);
|
||||||
|
|
||||||
|
if (errid == 201 || errid == 202 || errid == 203 || errid == 204)
|
||||||
|
{
|
||||||
|
// user not found or auth failed
|
||||||
|
|
||||||
|
SCNSettings.inst().user_id = -1;
|
||||||
|
SCNSettings.inst().user_key = "";
|
||||||
|
SCNSettings.inst().quota_curr = 0;
|
||||||
|
SCNSettings.inst().quota_max = 0;
|
||||||
|
SCNSettings.inst().promode_server = false;
|
||||||
|
SCNSettings.inst().fcm_token_server = "";
|
||||||
|
SCNSettings.inst().save();
|
||||||
|
|
||||||
|
SCNApp.refreshAccountTab();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCNSettings.inst().user_id = json.getInt("user_id");
|
SCNSettings.inst().user_id = json_int(json, "user_id");
|
||||||
SCNSettings.inst().quota_curr = json.getInt("quota");
|
SCNSettings.inst().quota_curr = json_int(json, "quota");
|
||||||
SCNSettings.inst().quota_max = json.getInt("quota_max");
|
SCNSettings.inst().quota_max = json_int(json, "quota_max");
|
||||||
SCNSettings.inst().promode_server = json.getBoolean("is_pro");
|
SCNSettings.inst().promode_server = json_bool(json, "is_pro");
|
||||||
|
if (!json_bool(json, "fcm_token_set")) SCNSettings.inst().fcm_token_server = "";
|
||||||
SCNSettings.inst().save();
|
SCNSettings.inst().save();
|
||||||
|
|
||||||
SCNApp.refreshAccountTab();
|
SCNApp.refreshAccountTab();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Log.e("SC:info", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
} finally {
|
} finally {
|
||||||
SCNApp.runOnUiThread(() -> {
|
SCNApp.runOnUiThread(() -> {
|
||||||
@@ -271,7 +293,7 @@ public class ServerCommunication
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
Log.e("SC:info", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +311,7 @@ public class ServerCommunication
|
|||||||
client.newCall(request).enqueue(new Callback() {
|
client.newCall(request).enqueue(new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call call, IOException e) {
|
public void onFailure(Call call, IOException e) {
|
||||||
e.printStackTrace();
|
Log.e("SC:upgrade", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,21 +327,20 @@ public class ServerCommunication
|
|||||||
|
|
||||||
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
|
||||||
|
|
||||||
if (!json.getBoolean("success")) {
|
if (!json_bool(json, "success")) {
|
||||||
SCNApp.showToast(json.getString("message"), 4000);
|
SCNApp.showToast(json_str(json, "message"), 4000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCNSettings.inst().user_id = json.getInt("user_id");
|
SCNSettings.inst().user_id = json_int(json, "user_id");
|
||||||
SCNSettings.inst().user_key = json.getString("user_key");
|
SCNSettings.inst().quota_curr = json_int(json, "quota");
|
||||||
SCNSettings.inst().quota_curr = json.getInt("quota");
|
SCNSettings.inst().quota_max = json_int(json, "quota_max");
|
||||||
SCNSettings.inst().quota_max = json.getInt("quota_max");
|
SCNSettings.inst().promode_server = json_bool(json, "is_pro");
|
||||||
SCNSettings.inst().promode_server = json.getBoolean("is_pro");
|
|
||||||
SCNSettings.inst().save();
|
SCNSettings.inst().save();
|
||||||
|
|
||||||
SCNApp.refreshAccountTab();
|
SCNApp.refreshAccountTab();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Log.e("SC:upgrade", e.toString());
|
||||||
SCNApp.showToast("Communication with server failed", 4000);
|
SCNApp.showToast("Communication with server failed", 4000);
|
||||||
} finally {
|
} finally {
|
||||||
SCNApp.runOnUiThread(() -> { if (loader != null) loader.setVisibility(View.GONE); });
|
SCNApp.runOnUiThread(() -> { if (loader != null) loader.setVisibility(View.GONE); });
|
||||||
@@ -334,4 +355,49 @@ public class ServerCommunication
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ack(int id, String key, CMessage msg)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(BASE_URL + "ack.php?user_id=" + id + "&user_key=" + key + "&scn_msg_id=" + msg.SCN_ID)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.newCall(request).enqueue(new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, IOException e) {
|
||||||
|
Log.e("SC:ack", e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call call, Response response) {
|
||||||
|
// ????
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.e("SC:ack", e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean json_bool(JSONObject o, String key) throws JSONException
|
||||||
|
{
|
||||||
|
Object v = o.get(key);
|
||||||
|
if (v instanceof Integer) return ((int)v) != 0;
|
||||||
|
if (v instanceof Boolean) return ((boolean)v);
|
||||||
|
if (v instanceof String) return !Str.equals(((String)v), "0") && !Str.equals(((String)v), "false");
|
||||||
|
|
||||||
|
return o.getBoolean(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int json_int(JSONObject o, String key) throws JSONException
|
||||||
|
{
|
||||||
|
return o.getInt(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String json_str(JSONObject o, String key) throws JSONException
|
||||||
|
{
|
||||||
|
return o.getString(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import com.blackforestbytes.simplecloudnotifier.model.CMessage;
|
|||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.PriorityEnum;
|
import com.blackforestbytes.simplecloudnotifier.model.PriorityEnum;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
import com.google.firebase.messaging.RemoteMessage;
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
@@ -36,9 +37,9 @@ public class FBMService extends FirebaseMessagingService
|
|||||||
String title = remoteMessage.getData().get("title");
|
String title = remoteMessage.getData().get("title");
|
||||||
String content = remoteMessage.getData().get("body");
|
String content = remoteMessage.getData().get("body");
|
||||||
PriorityEnum prio = PriorityEnum.parseAPI(remoteMessage.getData().get("priority"));
|
PriorityEnum prio = PriorityEnum.parseAPI(remoteMessage.getData().get("priority"));
|
||||||
|
long scn_id = Long.parseLong(remoteMessage.getData().get("scn_msg_id"));
|
||||||
|
|
||||||
CMessage msg = CMessageList.inst().add(time, title, content, prio);
|
CMessage msg = CMessageList.inst().add(scn_id, time, title, content, prio);
|
||||||
|
|
||||||
|
|
||||||
if (SCNApp.isBackground())
|
if (SCNApp.isBackground())
|
||||||
{
|
{
|
||||||
@@ -48,6 +49,8 @@ public class FBMService extends FirebaseMessagingService
|
|||||||
{
|
{
|
||||||
NotificationService.inst().showForeground(msg);
|
NotificationService.inst().showForeground(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerCommunication.ack(SCNSettings.inst().user_id, SCNSettings.inst().user_key, msg);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@@ -6,9 +6,14 @@ import android.app.NotificationManager;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.media.AudioAttributes;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.media.Ringtone;
|
||||||
|
import android.media.RingtoneManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.VibrationEffect;
|
||||||
|
import android.os.Vibrator;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.blackforestbytes.simplecloudnotifier.R;
|
import com.blackforestbytes.simplecloudnotifier.R;
|
||||||
@@ -23,9 +28,7 @@ import androidx.core.app.NotificationCompat;
|
|||||||
|
|
||||||
public class NotificationService
|
public class NotificationService
|
||||||
{
|
{
|
||||||
private final static String CHANNEL_ID_LOW = "CHAN_BFB_SCN_MESSAGES_LOW";
|
private final static String CHANNEL_ID = "CHAN_BFB_SCN_MESSAGES";
|
||||||
private final static String CHANNEL_ID_NORM = "CHAN_BFB_SCN_MESSAGES_NORM";
|
|
||||||
private final static String CHANNEL_ID_HIGH = "CHAN_BFB_SCN_MESSAGES_HIGH";
|
|
||||||
|
|
||||||
private final static Object _lock = new Object();
|
private final static Object _lock = new Object();
|
||||||
private static NotificationService _inst = null;
|
private static NotificationService _inst = null;
|
||||||
@@ -51,72 +54,86 @@ public class NotificationService
|
|||||||
NotificationManager notifman = ctxt.getSystemService(NotificationManager.class);
|
NotificationManager notifman = ctxt.getSystemService(NotificationManager.class);
|
||||||
if (notifman == null) return;
|
if (notifman == null) return;
|
||||||
|
|
||||||
NotificationChannel channelLow = notifman.getNotificationChannel(CHANNEL_ID_LOW);
|
NotificationChannel channel = notifman.getNotificationChannel(CHANNEL_ID);
|
||||||
if (channelLow == null) notifman.createNotificationChannel(channelLow = new NotificationChannel(CHANNEL_ID_LOW, "Push notifications (low priority)", NotificationManager.IMPORTANCE_LOW));
|
if (channel == null)
|
||||||
NotificationChannel channelNorm = notifman.getNotificationChannel(CHANNEL_ID_NORM);
|
{
|
||||||
if (channelNorm == null) notifman.createNotificationChannel(channelNorm = new NotificationChannel(CHANNEL_ID_NORM, "Push notifications (normal priority)", NotificationManager.IMPORTANCE_DEFAULT));
|
channel = new NotificationChannel(CHANNEL_ID, "Push notifications", NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
NotificationChannel channelHigh = notifman.getNotificationChannel(CHANNEL_ID_HIGH);
|
channel.setDescription("Push notifications from the server");
|
||||||
if (channelHigh == null) notifman.createNotificationChannel(channelHigh = new NotificationChannel(CHANNEL_ID_HIGH, "Push notifications (high priority)", NotificationManager.IMPORTANCE_HIGH));
|
channel.setSound(null, null);
|
||||||
|
channel.setVibrationPattern(null);
|
||||||
channelLow.setDescription("Messages from the API with priority set to low");
|
notifman.createNotificationChannel(channel);
|
||||||
channelLow.enableLights(SCNSettings.inst().PriorityLow.EnableLED);
|
}
|
||||||
channelLow.setLightColor(SCNSettings.inst().PriorityLow.LEDColor);
|
|
||||||
channelLow.enableVibration(SCNSettings.inst().PriorityLow.EnableVibration);
|
|
||||||
channelLow.setVibrationPattern(new long[]{200});
|
|
||||||
|
|
||||||
channelNorm.setDescription("Messages from the API with priority set to normal");
|
|
||||||
channelNorm.enableLights(SCNSettings.inst().PriorityNorm.EnableLED);
|
|
||||||
channelNorm.setLightColor(SCNSettings.inst().PriorityNorm.LEDColor);
|
|
||||||
channelNorm.enableVibration(SCNSettings.inst().PriorityNorm.EnableVibration);
|
|
||||||
channelNorm.setVibrationPattern(new long[]{200});
|
|
||||||
|
|
||||||
channelHigh.setDescription("Messages from the API with priority set to high");
|
|
||||||
channelHigh.enableLights(SCNSettings.inst().PriorityHigh.EnableLED);
|
|
||||||
channelHigh.setLightColor(SCNSettings.inst().PriorityHigh.LEDColor);
|
|
||||||
channelHigh.enableVibration(SCNSettings.inst().PriorityHigh.EnableVibration);
|
|
||||||
channelHigh.setVibrationPattern(new long[]{200});
|
|
||||||
channelLow.setBypassDnd(true);
|
|
||||||
channelLow.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showForeground(CMessage msg)
|
public void showForeground(CMessage msg)
|
||||||
{
|
{
|
||||||
SCNApp.showToast("Message recieved: " + msg.Title, Toast.LENGTH_LONG);
|
SCNApp.showToast("Message recieved: " + msg.Title, Toast.LENGTH_LONG);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NotificationSettings ns = SCNSettings.inst().PriorityNorm;
|
||||||
|
switch (msg.Priority)
|
||||||
|
{
|
||||||
|
case LOW: ns = SCNSettings.inst().PriorityLow; break;
|
||||||
|
case NORMAL: ns = SCNSettings.inst().PriorityNorm; break;
|
||||||
|
case HIGH: ns = SCNSettings.inst().PriorityHigh; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns.EnableSound && !ns.SoundSource.isEmpty())
|
||||||
|
{
|
||||||
|
Ringtone rt = RingtoneManager.getRingtone(SCNApp.getContext(), Uri.parse(ns.SoundSource));
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) rt.setLooping(false);
|
||||||
|
rt.play();
|
||||||
|
new Thread(() -> { try { Thread.sleep(5*1000); } catch (InterruptedException e) { /* */ } rt.stop(); }).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns.EnableVibration)
|
||||||
|
{
|
||||||
|
Vibrator v = (Vibrator) SCNApp.getContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
v.vibrate(VibrationEffect.createOneShot(1500, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||||
|
} else {
|
||||||
|
v.vibrate(1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showBackground(CMessage msg)
|
public void showBackground(CMessage msg)
|
||||||
{
|
{
|
||||||
Context ctxt = SCNApp.getContext();
|
Context ctxt = SCNApp.getContext();
|
||||||
|
|
||||||
String channel = CHANNEL_ID_NORM;
|
|
||||||
NotificationSettings ns = SCNSettings.inst().PriorityNorm;
|
NotificationSettings ns = SCNSettings.inst().PriorityNorm;
|
||||||
switch (msg.Priority)
|
switch (msg.Priority)
|
||||||
{
|
{
|
||||||
case LOW: ns = SCNSettings.inst().PriorityLow; channel = CHANNEL_ID_LOW; break;
|
case LOW: ns = SCNSettings.inst().PriorityLow; break;
|
||||||
case NORMAL: ns = SCNSettings.inst().PriorityNorm; channel = CHANNEL_ID_NORM; break;
|
case NORMAL: ns = SCNSettings.inst().PriorityNorm; break;
|
||||||
case HIGH: ns = SCNSettings.inst().PriorityHigh; channel = CHANNEL_ID_HIGH; break;
|
case HIGH: ns = SCNSettings.inst().PriorityHigh; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctxt, channel);
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
||||||
|
{
|
||||||
|
// old
|
||||||
|
|
||||||
|
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctxt, CHANNEL_ID);
|
||||||
mBuilder.setSmallIcon(R.drawable.ic_bfb);
|
mBuilder.setSmallIcon(R.drawable.ic_bfb);
|
||||||
mBuilder.setContentTitle(msg.Title);
|
mBuilder.setContentTitle(msg.Title);
|
||||||
mBuilder.setContentText(msg.Content);
|
mBuilder.setContentText(msg.Content);
|
||||||
mBuilder.setShowWhen(true);
|
mBuilder.setShowWhen(true);
|
||||||
mBuilder.setWhen(msg.Timestamp);
|
mBuilder.setWhen(msg.Timestamp * 1000);
|
||||||
mBuilder.setAutoCancel(true);
|
mBuilder.setAutoCancel(true);
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
|
||||||
{
|
|
||||||
if (msg.Priority == PriorityEnum.LOW) mBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
|
if (msg.Priority == PriorityEnum.LOW) mBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
|
||||||
if (msg.Priority == PriorityEnum.NORMAL) mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
|
if (msg.Priority == PriorityEnum.NORMAL) mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
|
||||||
if (msg.Priority == PriorityEnum.HIGH) mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
|
if (msg.Priority == PriorityEnum.HIGH) mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||||
if (ns.EnableVibration) mBuilder.setVibrate(new long[]{200});
|
if (ns.EnableVibration) mBuilder.setVibrate(new long[]{500});
|
||||||
if (ns.EnableLED) mBuilder.setLights(ns.LEDColor, 500, 500);
|
if (ns.EnableLED) mBuilder.setLights(ns.LEDColor, 500, 500);
|
||||||
}
|
|
||||||
|
|
||||||
if (ns.EnableSound && !ns.SoundSource.isEmpty())
|
if (ns.EnableSound && !ns.SoundSource.isEmpty()) mBuilder.setSound(Uri.parse(ns.SoundSource), AudioManager.STREAM_NOTIFICATION);
|
||||||
{
|
|
||||||
mBuilder.setSound(Uri.parse(ns.SoundSource), AudioManager.STREAM_ALARM);
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = new Intent(ctxt, MainActivity.class);
|
Intent intent = new Intent(ctxt, MainActivity.class);
|
||||||
PendingIntent pi = PendingIntent.getActivity(ctxt, 0, intent, 0);
|
PendingIntent pi = PendingIntent.getActivity(ctxt, 0, intent, 0);
|
||||||
@@ -128,4 +145,48 @@ public class NotificationService
|
|||||||
|
|
||||||
if (mNotificationManager != null) mNotificationManager.notify(0, n);
|
if (mNotificationManager != null) mNotificationManager.notify(0, n);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new
|
||||||
|
|
||||||
|
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctxt, CHANNEL_ID);
|
||||||
|
mBuilder.setSmallIcon(R.drawable.ic_bfb);
|
||||||
|
mBuilder.setContentTitle(msg.Title);
|
||||||
|
mBuilder.setContentText(msg.Content);
|
||||||
|
mBuilder.setShowWhen(true);
|
||||||
|
mBuilder.setWhen(msg.Timestamp * 1000);
|
||||||
|
mBuilder.setAutoCancel(true);
|
||||||
|
|
||||||
|
if (ns.EnableLED) mBuilder.setLights(ns.LEDColor, 500, 500);
|
||||||
|
|
||||||
|
if (msg.Priority == PriorityEnum.LOW) mBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
|
||||||
|
if (msg.Priority == PriorityEnum.NORMAL) mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
|
||||||
|
if (msg.Priority == PriorityEnum.HIGH) mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||||
|
|
||||||
|
Intent intent = new Intent(ctxt, MainActivity.class);
|
||||||
|
PendingIntent pi = PendingIntent.getActivity(ctxt, 0, intent, 0);
|
||||||
|
mBuilder.setContentIntent(pi);
|
||||||
|
NotificationManager mNotificationManager = (NotificationManager) ctxt.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
if (mNotificationManager == null) return;
|
||||||
|
|
||||||
|
Notification n = mBuilder.build();
|
||||||
|
n.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||||
|
|
||||||
|
mNotificationManager.notify(0, n);
|
||||||
|
|
||||||
|
if (ns.EnableSound && !ns.SoundSource.isEmpty())
|
||||||
|
{
|
||||||
|
Ringtone rt = RingtoneManager.getRingtone(SCNApp.getContext(), Uri.parse(ns.SoundSource));
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) rt.setLooping(false);
|
||||||
|
rt.play();
|
||||||
|
new Thread(() -> { try { Thread.sleep(5*1000); } catch (InterruptedException e) { /* */ } rt.stop(); }).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns.EnableVibration)
|
||||||
|
{
|
||||||
|
Vibrator v = (Vibrator) SCNApp.getContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
|
v.vibrate(VibrationEffect.createOneShot(1500, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
package com.blackforestbytes.simplecloudnotifier.view;
|
package com.blackforestbytes.simplecloudnotifier.view;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -21,6 +23,7 @@ import net.glxn.qrgen.android.QRCode;
|
|||||||
import net.glxn.qrgen.core.image.ImageType;
|
import net.glxn.qrgen.core.image.ImageType;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import static android.content.Context.CLIPBOARD_SERVICE;
|
import static android.content.Context.CLIPBOARD_SERVICE;
|
||||||
@@ -55,15 +58,47 @@ public class AccountFragment extends Fragment
|
|||||||
|
|
||||||
v.findViewById(R.id.btnAccountReset).setOnClickListener(cv ->
|
v.findViewById(R.id.btnAccountReset).setOnClickListener(cv ->
|
||||||
{
|
{
|
||||||
|
Activity a = getActivity();
|
||||||
|
if (a == null) return;
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(a);
|
||||||
|
|
||||||
|
builder.setTitle("Confirm");
|
||||||
|
builder.setMessage("Reset account key?");
|
||||||
|
|
||||||
|
builder.setPositiveButton("YES", (dialog, which) -> {
|
||||||
View lpnl = v.findViewById(R.id.loadingPanel);
|
View lpnl = v.findViewById(R.id.loadingPanel);
|
||||||
lpnl.setVisibility(View.VISIBLE);
|
lpnl.setVisibility(View.VISIBLE);
|
||||||
SCNSettings.inst().reset(lpnl);
|
SCNSettings.inst().reset(lpnl);
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNegativeButton("NO", (dialog, which) -> dialog.dismiss());
|
||||||
|
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
v.findViewById(R.id.btnClearLocalStorage).setOnClickListener(cv ->
|
v.findViewById(R.id.btnClearLocalStorage).setOnClickListener(cv ->
|
||||||
{
|
{
|
||||||
|
Activity a = getActivity();
|
||||||
|
if (a == null) return;
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(a);
|
||||||
|
|
||||||
|
builder.setTitle("Confirm");
|
||||||
|
builder.setMessage("Clear local messages?");
|
||||||
|
|
||||||
|
builder.setPositiveButton("YES", (dialog, which) -> {
|
||||||
CMessageList.inst().clear();
|
CMessageList.inst().clear();
|
||||||
SCNApp.showToast("Notifications cleared", 1000);
|
SCNApp.showToast("Notifications cleared", 1000);
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNegativeButton("NO", (dialog, which) -> dialog.dismiss());
|
||||||
|
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
v.findViewById(R.id.btnQR).setOnClickListener(cv ->
|
v.findViewById(R.id.btnQR).setOnClickListener(cv ->
|
||||||
|
@@ -45,6 +45,6 @@ public class NotificationsFragment extends Fragment
|
|||||||
|
|
||||||
public void updateProState()
|
public void updateProState()
|
||||||
{
|
{
|
||||||
adView.setVisibility(IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE) != null ? View.GONE : View.VISIBLE);
|
if (adView != null) adView.setVisibility(IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE) != null ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -201,7 +201,6 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
|
|||||||
{
|
{
|
||||||
SCNSettings.inst().save();
|
SCNSettings.inst().save();
|
||||||
updateUI();
|
updateUI();
|
||||||
NotificationService.inst().updateChannels();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onUpgradeAccount()
|
private void onUpgradeAccount()
|
||||||
@@ -213,9 +212,9 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
|
|||||||
{
|
{
|
||||||
Purchase p = IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE);
|
Purchase p = IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE);
|
||||||
|
|
||||||
prefUpgradeAccount.setVisibility( p != null ? View.GONE : View.VISIBLE);
|
if (prefUpgradeAccount != null) prefUpgradeAccount.setVisibility( p != null ? View.GONE : View.VISIBLE);
|
||||||
prefUpgradeAccount_info.setVisibility(p != null ? View.GONE : View.VISIBLE);
|
if (prefUpgradeAccount_info != null) prefUpgradeAccount_info.setVisibility(p != null ? View.GONE : View.VISIBLE);
|
||||||
prefUpgradeAccount_msg.setVisibility( p != null ? View.VISIBLE : View.GONE );
|
if (prefUpgradeAccount_msg != null) prefUpgradeAccount_msg.setVisibility( p != null ? View.VISIBLE : View.GONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCacheSizeIndex(int value)
|
private int getCacheSizeIndex(int value)
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:ignore="TooManyViews"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".view.SettingsFragment">
|
tools:context=".view.SettingsFragment">
|
||||||
@@ -33,23 +32,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<Switch
|
||||||
android:layout_marginStart="4dp"
|
android:layout_marginStart="4dp"
|
||||||
android:layout_marginEnd="4dp"
|
android:layout_marginEnd="4dp"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/prefAppEnabled"
|
android:id="@+id/prefAppEnabled"
|
||||||
android:text="@string/str_enabled"
|
android:text="@string/str_enabled"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:minHeight="48dp" />
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -102,6 +92,7 @@
|
|||||||
android:layout_marginEnd="4dp"
|
android:layout_marginEnd="4dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center|center"
|
||||||
android:minHeight="48dp">
|
android:minHeight="48dp">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -151,23 +142,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgLowEnableSound"
|
android:id="@+id/prefMsgLowEnableSound"
|
||||||
android:text="@string/str_msg_enablesound"
|
android:text="@string/str_msg_enablesound"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"/>
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -176,20 +158,15 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/prefMsgLowRingtone_container"
|
android:id="@+id/prefMsgLowRingtone_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
android:layout_marginEnd="4dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvMsgLowRingtone"
|
android:id="@+id/tvMsgLowRingtone"
|
||||||
@@ -206,9 +183,8 @@
|
|||||||
android:spinnerMode="dialog"
|
android:spinnerMode="dialog"
|
||||||
android:text="Whatever"
|
android:text="Whatever"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -217,23 +193,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgLowRepeatSound"
|
android:id="@+id/prefMsgLowRepeatSound"
|
||||||
android:text="@string/str_repeatnotificationsound"
|
android:text="@string/str_repeatnotificationsound"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -242,23 +209,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgLowEnableLED"
|
android:id="@+id/prefMsgLowEnableLED"
|
||||||
android:text="@string/str_enable_led"
|
android:text="@string/str_enable_led"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -308,23 +266,15 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgLowEnableVibrations"
|
android:id="@+id/prefMsgLowEnableVibrations"
|
||||||
android:text="@string/str_enable_vibration"
|
android:text="@string/str_enable_vibration"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -349,23 +299,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgNormEnableSound"
|
android:id="@+id/prefMsgNormEnableSound"
|
||||||
android:text="@string/str_msg_enablesound"
|
android:text="@string/str_msg_enablesound"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -374,20 +315,15 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/prefMsgNormRingtone_container"
|
android:id="@+id/prefMsgNormRingtone_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
android:layout_marginEnd="4dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvMsgNormRingtone"
|
android:id="@+id/tvMsgNormRingtone"
|
||||||
@@ -406,8 +342,6 @@
|
|||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
@@ -415,23 +349,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgNormRepeatSound"
|
android:id="@+id/prefMsgNormRepeatSound"
|
||||||
android:text="@string/str_repeatnotificationsound"
|
android:text="@string/str_repeatnotificationsound"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -440,23 +365,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgNormEnableLED"
|
android:id="@+id/prefMsgNormEnableLED"
|
||||||
android:text="@string/str_enable_led"
|
android:text="@string/str_enable_led"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -506,23 +422,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgNormEnableVibrations"
|
android:id="@+id/prefMsgNormEnableVibrations"
|
||||||
android:text="@string/str_enable_vibration"
|
android:text="@string/str_enable_vibration"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -547,23 +454,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgHighEnableSound"
|
android:id="@+id/prefMsgHighEnableSound"
|
||||||
android:text="@string/str_msg_enablesound"
|
android:text="@string/str_msg_enablesound"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -572,18 +470,15 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/prefMsgHighRingtone_container"
|
android:id="@+id/prefMsgHighRingtone_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
@@ -604,8 +499,6 @@
|
|||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
@@ -613,23 +506,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgHighRepeatSound"
|
android:id="@+id/prefMsgHighRepeatSound"
|
||||||
android:text="@string/str_repeatnotificationsound"
|
android:text="@string/str_repeatnotificationsound"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -638,23 +522,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgHighEnableLED"
|
android:id="@+id/prefMsgHighEnableLED"
|
||||||
android:text="@string/str_enable_led"
|
android:text="@string/str_enable_led"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -704,23 +579,14 @@
|
|||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:background="#c0c0c0"/>
|
android:background="#c0c0c0"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp">
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/prefMsgHighEnableVibrations"
|
android:id="@+id/prefMsgHighEnableVibrations"
|
||||||
android:text="@string/str_enable_vibration"
|
android:text="@string/str_enable_vibration"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="4dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_marginEnd="4dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:minHeight="48dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -18,9 +18,9 @@
|
|||||||
<string name="str_common_settings">Common Settings</string>
|
<string name="str_common_settings">Common Settings</string>
|
||||||
<string name="str_enabled">Enabled</string>
|
<string name="str_enabled">Enabled</string>
|
||||||
<string name="str_localcachesize">Remember the last x notifications locally</string>
|
<string name="str_localcachesize">Remember the last x notifications locally</string>
|
||||||
<string name="str_header_prio0">Notifications (low priority)</string>
|
<string name="str_header_prio0">Notifications (priority 0 - Low)</string>
|
||||||
<string name="str_header_prio1">Notifications (normal priority)</string>
|
<string name="str_header_prio1">Notifications (priority 1 - Normal)</string>
|
||||||
<string name="str_header_prio2">Notifications (high priority)</string>
|
<string name="str_header_prio2">Notifications (priority 2 - High)</string>
|
||||||
<string name="str_msg_enablesound">Enable notification sound</string>
|
<string name="str_msg_enablesound">Enable notification sound</string>
|
||||||
<string name="str_notificationsound">Notification sound</string>
|
<string name="str_notificationsound">Notification sound</string>
|
||||||
<string name="str_repeatnotificationsound">Repeat notification sound</string>
|
<string name="str_repeatnotificationsound">Repeat notification sound</string>
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
#Sun Nov 11 19:37:57 CET 2018
|
#Mon Nov 12 13:06:09 CET 2018
|
||||||
VERSION_NAME=0.0.5
|
VERSION_NAME=0.0.6
|
||||||
VERSION_CODE=5
|
VERSION_CODE=6
|
||||||
|
BIN
data/icon_web.pdn
Normal file
BIN
data/icon_web.pdn
Normal file
Binary file not shown.
47
web/ack.php
Normal file
47
web/ack.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
include_once 'model.php';
|
||||||
|
|
||||||
|
$INPUT = array_merge($_GET, $_POST);
|
||||||
|
|
||||||
|
|
||||||
|
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'errid'=>101, 'message' => 'Missing parameter [[user_id]]']));
|
||||||
|
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'errid'=>102, 'message' => 'Missing parameter [[user_key]]']));
|
||||||
|
if (!isset($INPUT['scn_msg_id'])) die(json_encode(['success' => false, 'errid'=>103, 'message' => 'Missing parameter [[scn_msg_id]]']));
|
||||||
|
|
||||||
|
$user_id = $INPUT['user_id'];
|
||||||
|
$user_key = $INPUT['user_key'];
|
||||||
|
$scn_msg_id = $INPUT['scn_msg_id'];
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
|
||||||
|
$pdo = getDatabase();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day, fcm_token FROM users WHERE user_id = :uid LIMIT 1');
|
||||||
|
$stmt->execute(['uid' => $user_id]);
|
||||||
|
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>201, 'message' => 'User not found']));
|
||||||
|
$data = $datas[0];
|
||||||
|
|
||||||
|
if ($data === null) die(json_encode(['success' => false, 'errid'=>202, 'message' => 'User not found']));
|
||||||
|
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found']));
|
||||||
|
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed']));
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('SELECT ack FROM messages WHERE scn_message_id=:smid AND sender_user_id=:uid LIMIT 1');
|
||||||
|
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
|
||||||
|
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>301, 'message' => 'Message not found']));
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('UPDATE messages SET ack=1 WHERE scn_message_id=:smid AND sender_user_id=:uid');
|
||||||
|
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
|
||||||
|
|
||||||
|
echo json_encode(
|
||||||
|
[
|
||||||
|
'success' => true,
|
||||||
|
'prev_ack' => $datas[0]['ack'],
|
||||||
|
'new_ack' => 1,
|
||||||
|
'message' => 'ok'
|
||||||
|
]);
|
||||||
|
return 0;
|
@@ -193,6 +193,11 @@ input::-webkit-inner-spin-button {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fullcenterflex .card
|
||||||
|
{
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
a.card,
|
a.card,
|
||||||
a.card:active,
|
a.card:active,
|
||||||
a.card:visited,
|
a.card:visited,
|
||||||
|
BIN
web/favicon.ico
Normal file
BIN
web/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
BIN
web/favicon.png
Normal file
BIN
web/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
@@ -9,6 +9,8 @@
|
|||||||
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
||||||
<link rel="stylesheet" href="/css/style.css">
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.ico"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form id="mainpnl">
|
<form id="mainpnl">
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
||||||
<link rel="stylesheet" href="/css/style.css">
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.ico"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mainpnl">
|
<div id="mainpnl">
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
||||||
<link rel="stylesheet" href="/css/style.css">
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.ico"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mainpnl">
|
<div id="mainpnl">
|
||||||
@@ -100,6 +102,10 @@
|
|||||||
<td data-label="Statuscode">403 (Forbidden)</td>
|
<td data-label="Statuscode">403 (Forbidden)</td>
|
||||||
<td data-label="Explanation">The user has exceeded its daily quota - wait 24 hours or upgrade your account</td>
|
<td data-label="Explanation">The user has exceeded its daily quota - wait 24 hours or upgrade your account</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td data-label="Statuscode">412 (Precondition Failed)</td>
|
||||||
|
<td data-label="Explanation">There is no device connected with this account - open the app and press the refresh button in the account tab</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td data-label="Statuscode">500 (Internal Server Error)</td>
|
<td data-label="Statuscode">500 (Internal Server Error)</td>
|
||||||
<td data-label="Explanation">There was an internal error while sending your data - try again later</td>
|
<td data-label="Explanation">There was an internal error while sending your data - try again later</td>
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
<!--<link rel="stylesheet" href="/css/mini-dark.min.css">-->
|
||||||
<link rel="stylesheet" href="/css/style.css">
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.ico"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ $user_key = $INPUT['user_key'];
|
|||||||
|
|
||||||
$pdo = getDatabase();
|
$pdo = getDatabase();
|
||||||
|
|
||||||
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day FROM users WHERE user_id = :uid LIMIT 1');
|
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day, fcm_token FROM users WHERE user_id = :uid LIMIT 1');
|
||||||
$stmt->execute(['uid' => $user_id]);
|
$stmt->execute(['uid' => $user_id]);
|
||||||
|
|
||||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
@@ -38,6 +38,7 @@ echo json_encode(
|
|||||||
'quota' => $quota,
|
'quota' => $quota,
|
||||||
'quota_max' => Statics::quota_max($is_pro),
|
'quota_max' => Statics::quota_max($is_pro),
|
||||||
'is_pro' => $is_pro,
|
'is_pro' => $is_pro,
|
||||||
|
'fcm_token_set' => ($data['fcm_token'] != null),
|
||||||
'message' => 'ok'
|
'message' => 'ok'
|
||||||
]);
|
]);
|
||||||
return 0;
|
return 0;
|
@@ -123,7 +123,7 @@ function sendPOST($url, $body, $header)
|
|||||||
|
|
||||||
if ($response->code != 200) throw new Exception("Repsponse code: " . $response->code);
|
if ($response->code != 200) throw new Exception("Repsponse code: " . $response->code);
|
||||||
|
|
||||||
return $response->body;
|
return $response->raw_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyOrderToken($tok)
|
function verifyOrderToken($tok)
|
||||||
@@ -136,26 +136,25 @@ function verifyOrderToken($tok)
|
|||||||
$product = getConfig()['verify_api']['product_id'];
|
$product = getConfig()['verify_api']['product_id'];
|
||||||
$acctoken = getConfig()['verify_api']['accesstoken'];
|
$acctoken = getConfig()['verify_api']['accesstoken'];
|
||||||
|
|
||||||
if ($acctoken == '') $acctoken = refreshVerifyToken();
|
if ($acctoken == '' || $acctoken == null || $acctoken == false) $acctoken = refreshVerifyToken();
|
||||||
|
|
||||||
$url = 'https://www.googleapis.com/androidpublisher/v3/applications/'.$package.'/purchases/products/'.$product.'/tokens/'.$tok.'?access_token='.$acctoken;
|
$url = 'https://www.googleapis.com/androidpublisher/v3/applications/'.$package.'/purchases/products/'.$product.'/tokens/'.$tok.'?access_token='.$acctoken;
|
||||||
|
$response = $builder = \Httpful\Request::get($url)->send();
|
||||||
|
$obj = json_decode($response->raw_body, true);
|
||||||
|
|
||||||
$json = sendPOST($url, "", []);
|
if ($response->code != 401 && ($obj === null || $obj === false))
|
||||||
$obj = json_decode($json);
|
|
||||||
|
|
||||||
if ($obj === null || $obj === false)
|
|
||||||
{
|
{
|
||||||
reportError('verify-token returned NULL');
|
reportError('verify-token returned NULL');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($obj['error']) && isset($obj['error']['code']) && $obj['error']['code'] == 401) // "Invalid Credentials" -- refresh acces_token
|
if ($response->code == 401 || isset($obj['error']) && isset($obj['error']['code']) && $obj['error']['code'] == 401) // "Invalid Credentials" -- refresh acces_token
|
||||||
{
|
{
|
||||||
$acctoken = refreshVerifyToken();
|
$acctoken = refreshVerifyToken();
|
||||||
|
|
||||||
$url = 'https://www.googleapis.com/androidpublisher/v3/applications/'.$package.'/purchases/products/'.$product.'/tokens/'.$tok.'?access_token='.$acctoken;
|
$url = 'https://www.googleapis.com/androidpublisher/v3/applications/'.$package.'/purchases/products/'.$product.'/tokens/'.$tok.'?access_token='.$acctoken;
|
||||||
$json = sendPOST($url, "", []);
|
$response = $builder = \Httpful\Request::get($url)->send();
|
||||||
$obj = json_decode($json);
|
$obj = json_decode($response->raw_body, true);
|
||||||
|
|
||||||
if ($obj === null || $obj === false)
|
if ($obj === null || $obj === false)
|
||||||
{
|
{
|
||||||
@@ -185,10 +184,10 @@ function refreshVerifyToken()
|
|||||||
'&client_secret='.getConfig()['verify_api']['clientsecret'];
|
'&client_secret='.getConfig()['verify_api']['clientsecret'];
|
||||||
|
|
||||||
$json = sendPOST($url, "", []);
|
$json = sendPOST($url, "", []);
|
||||||
$obj = json_decode($json);
|
$obj = json_decode($json, true);
|
||||||
file_put_contents('.verify_accesstoken', $obj['access_token']);
|
file_put_contents('.verify_accesstoken', $obj['access_token']);
|
||||||
|
|
||||||
return $obj->access_token;
|
return $obj['access_token'];
|
||||||
}
|
}
|
||||||
|
|
||||||
function api_return($http_code, $message)
|
function api_return($http_code, $message)
|
||||||
@@ -201,12 +200,13 @@ function api_return($http_code, $message)
|
|||||||
/**
|
/**
|
||||||
* @param String $str
|
* @param String $str
|
||||||
* @param String[] $path
|
* @param String[] $path
|
||||||
|
* @return mixed|null
|
||||||
*/
|
*/
|
||||||
function try_json($str, $path)
|
function try_json($str, $path)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$o = json_decode($str);
|
$o = json_decode($str, true);
|
||||||
foreach ($path as $p) $o = $o[$p];
|
foreach ($path as $p) $o = $o[$p];
|
||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
@@ -215,3 +215,15 @@ function try_json($str, $path)
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#################################################################################################################
|
||||||
|
|
||||||
|
if (getConfig()['global']['prod']) {
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
ini_set('log_errors', 1);
|
||||||
|
} else {
|
||||||
|
error_reporting(E_STRICT);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#################################################################################################################
|
||||||
|
@@ -15,15 +15,29 @@ $user_key = generateRandomAuthKey();
|
|||||||
|
|
||||||
$pdo = getDatabase();
|
$pdo = getDatabase();
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
if ($ispro)
|
if ($ispro)
|
||||||
{
|
{
|
||||||
if (!verifyOrderToken($pro_token)) die(json_encode(['success' => false, 'message' => 'Purchase token could not be verified']));
|
if (!verifyOrderToken($pro_token))
|
||||||
|
{
|
||||||
|
$pdo->rollBack();
|
||||||
|
die(json_encode(['success' => false, 'message' => 'Purchase token could not be verified']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('UPDATE users SET is_pro=0, pro_token=NULL WHERE user_id <> :uid AND pro_token = :ptk');
|
||||||
|
$stmt->execute(['uid' => $user_id, 'ptk' => $pro_token]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare('INSERT INTO users (user_key, fcm_token, is_pro, pro_token, timestamp_accessed) VALUES (:key, :token, :bpro, :spro, NOW())');
|
$stmt = $pdo->prepare('INSERT INTO users (user_key, fcm_token, is_pro, pro_token, timestamp_accessed) VALUES (:key, :token, :bpro, :spro, NOW())');
|
||||||
$stmt->execute(['key' => $user_key, 'token' => $fcmtoken, 'bpro' => $ispro, 'spro' => $ispro ? $pro_token : null]);
|
$stmt->execute(['key' => $user_key, 'token' => $fcmtoken, 'bpro' => $ispro, 'spro' => $ispro ? $pro_token : null]);
|
||||||
$user_id = $pdo->lastInsertId('user_id');
|
$user_id = $pdo->lastInsertId('user_id');
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('UPDATE users SET fcm_token=NULL WHERE user_id <> :uid AND fcm_token=:ft');
|
||||||
|
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]);
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
echo json_encode(
|
echo json_encode(
|
||||||
[
|
[
|
||||||
'success' => true,
|
'success' => true,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
DROP TABLE IF EXISTS `users`;
|
||||||
CREATE TABLE `users`
|
CREATE TABLE `users`
|
||||||
(
|
(
|
||||||
`user_id` INT(11) NOT NULL AUTO_INCREMENT,
|
`user_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
@@ -16,19 +17,21 @@ CREATE TABLE `users`
|
|||||||
PRIMARY KEY (`user_id`)
|
PRIMARY KEY (`user_id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `messages`;
|
||||||
CREATE TABLE `messages`
|
CREATE TABLE `messages`
|
||||||
(
|
(
|
||||||
`scn_message_id` INT(11) NOT NULL AUTO_INCREMENT,
|
`scn_message_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
`sender_user_id` INT(11) NOT NULL,
|
`sender_user_id` INT(11) NOT NULL,
|
||||||
|
|
||||||
`timestamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`timestamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`ack` BIT NOT NULL DEFAULT 0,
|
||||||
|
|
||||||
`title` VARCHAR(256) NOT NULL,
|
`title` VARCHAR(256) NOT NULL,
|
||||||
`content` VARCHAR(12288) NULL,
|
`content` VARCHAR(12288) NULL,
|
||||||
`priority` INT(11) NOT NULL,
|
`priority` INT(11) NOT NULL,
|
||||||
|
|
||||||
`fcn_message_id` VARCHAR(256) NOT NULL,
|
`fcm_message_id` VARCHAR(256) NULL,
|
||||||
`usr_message_id` VARCHAR(256) NULL,
|
`usr_message_id` VARCHAR(256) NULL,
|
||||||
|
|
||||||
PRIMARY KEY (`scn_message_id`)
|
PRIMARY KEY (`scn_message_id`)
|
||||||
)
|
);
|
46
web/send.php
46
web/send.php
@@ -32,6 +32,7 @@ try
|
|||||||
if (strlen(trim($message)) == 0) api_return(400, json_encode(['success' => false, 'error' => 1201, 'errhighlight' => 103, 'message' => 'No title specified']));
|
if (strlen(trim($message)) == 0) api_return(400, json_encode(['success' => false, 'error' => 1201, 'errhighlight' => 103, 'message' => 'No title specified']));
|
||||||
if (strlen($message) > 120) api_return(400, json_encode(['success' => false, 'error' => 1202, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)']));
|
if (strlen($message) > 120) api_return(400, json_encode(['success' => false, 'error' => 1202, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)']));
|
||||||
if (strlen($content) > 10000) api_return(400, json_encode(['success' => false, 'error' => 1203, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)']));
|
if (strlen($content) > 10000) api_return(400, json_encode(['success' => false, 'error' => 1203, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)']));
|
||||||
|
if ($usrmsgid != null && strlen($usrmsgid) > 64) api_return(400, json_encode(['success' => false, 'error' => 1204, 'errhighlight' => -1, 'message' => 'MessageID too long (64 characters)']));
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -54,6 +55,11 @@ try
|
|||||||
if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $new_quota=1;
|
if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $new_quota=1;
|
||||||
if ($new_quota > Statics::quota_max($data['is_pro'])) api_return(403, json_encode(['success' => false, 'error' => 2101, 'errhighlight' => -1, 'message' => 'Daily quota reached ('.Statics::quota_max($data['is_pro']).')']));
|
if ($new_quota > Statics::quota_max($data['is_pro'])) api_return(403, json_encode(['success' => false, 'error' => 2101, 'errhighlight' => -1, 'message' => 'Daily quota reached ('.Statics::quota_max($data['is_pro']).')']));
|
||||||
|
|
||||||
|
if ($fcm == null || $fcm == '' || $fcm == false)
|
||||||
|
{
|
||||||
|
api_return(412, json_encode(['success' => false, 'error' => 1401, 'errhighlight' => -1, 'message' => 'No device linked with this account']));
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
if ($usrmsgid != null)
|
if ($usrmsgid != null)
|
||||||
@@ -79,6 +85,22 @@ try
|
|||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('INSERT INTO messages (sender_user_id, title, content, priority, fcm_message_id, usr_message_id) VALUES (:suid, :t, :c, :p, :fmid, :umid)');
|
||||||
|
$stmt->execute(
|
||||||
|
[
|
||||||
|
'suid' => $user_id,
|
||||||
|
't' => $message,
|
||||||
|
'c' => $content,
|
||||||
|
'p' => $priority,
|
||||||
|
'fmid' => null,
|
||||||
|
'umid' => $usrmsgid,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$scn_msg_id = $pdo->lastInsertId();
|
||||||
|
|
||||||
$url = "https://fcm.googleapis.com/fcm/send";
|
$url = "https://fcm.googleapis.com/fcm/send";
|
||||||
$payload = json_encode(
|
$payload = json_encode(
|
||||||
[
|
[
|
||||||
@@ -97,6 +119,7 @@ try
|
|||||||
'priority' => $priority,
|
'priority' => $priority,
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'usr_msg_id' => $usrmsgid,
|
'usr_msg_id' => $usrmsgid,
|
||||||
|
'scn_msg_id' => $scn_msg_id,
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
$header=
|
$header=
|
||||||
@@ -112,28 +135,24 @@ try
|
|||||||
if (try_json($httpresult, ['success']) != 1)
|
if (try_json($httpresult, ['success']) != 1)
|
||||||
{
|
{
|
||||||
reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult);
|
reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult);
|
||||||
api_return(403, json_encode(['success' => false, 'error' => 9902, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.']));
|
$pdo->rollBack();
|
||||||
|
api_return(500, json_encode(['success' => false, 'error' => 9902, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
{
|
{
|
||||||
reportError("FCM communication failed", $e);
|
reportError("FCM communication failed", $e);
|
||||||
api_return(403, json_encode(['success' => false, 'error' => 9901, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()]));
|
$pdo->rollBack();
|
||||||
|
api_return(500, json_encode(['success' => false, 'error' => 9901, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), messages_sent=messages_sent+1, quota_today=:q, quota_day=NOW() WHERE user_id = :uid');
|
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), messages_sent=messages_sent+1, quota_today=:q, quota_day=NOW() WHERE user_id = :uid');
|
||||||
$stmt->execute(['uid' => $user_id, 'q' => $new_quota]);
|
$stmt->execute(['uid' => $user_id, 'q' => $new_quota]);
|
||||||
|
|
||||||
$stmt = $pdo->prepare('INSERT INTO messages (sender_user_id, title, content, priority, fcn_message_id, usr_message_id) VALUES (:suid, :t, :c, :p, :fmid, :umid)');
|
$stmt = $pdo->prepare('UPDATE messages SET fcm_message_id=:fmid WHERE scn_message_id=:smid');
|
||||||
$stmt->execute(
|
$stmt->execute([ 'fmid' => try_json($httpresult, ['results', 0, 'message_id']), 'smid' => $scn_msg_id ]);
|
||||||
[
|
|
||||||
'suid' => $user_id,
|
$pdo->commit();
|
||||||
't' => $message,
|
|
||||||
'c' => $content,
|
|
||||||
'p' => $priority,
|
|
||||||
'fmid' => try_json($httpresult, ['results', 'message_id']),
|
|
||||||
'umid' => $usrmsgid,
|
|
||||||
]);
|
|
||||||
|
|
||||||
api_return(200, json_encode(
|
api_return(200, json_encode(
|
||||||
[
|
[
|
||||||
@@ -145,9 +164,12 @@ try
|
|||||||
'quota' => $new_quota,
|
'quota' => $new_quota,
|
||||||
'is_pro' => $data['is_pro'],
|
'is_pro' => $data['is_pro'],
|
||||||
'quota_max' => Statics::quota_max($data['is_pro']),
|
'quota_max' => Statics::quota_max($data['is_pro']),
|
||||||
|
'scn_msg_id' => $scn_msg_id,
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
catch (Exception $mex)
|
catch (Exception $mex)
|
||||||
{
|
{
|
||||||
reportError("Root try-catch triggered", $mex);
|
reportError("Root try-catch triggered", $mex);
|
||||||
|
if ($pdo->inTransaction()) $pdo->rollBack();
|
||||||
|
api_return(500, json_encode(['success' => false, 'error' => 9903, 'errhighlight' => -1, 'message' => 'PHP script threw exception.'."\n\n".'Exception: ' . $e->getMessage()]));
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,8 @@ $new_userkey = generateRandomAuthKey();
|
|||||||
|
|
||||||
if ($fcm_token === null)
|
if ($fcm_token === null)
|
||||||
{
|
{
|
||||||
|
// only gen new user_secret
|
||||||
|
|
||||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), user_key=:at WHERE user_id = :uid');
|
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), user_key=:at WHERE user_id = :uid');
|
||||||
$stmt->execute(['uid' => $user_id, 'at' => $new_userkey]);
|
$stmt->execute(['uid' => $user_id, 'at' => $new_userkey]);
|
||||||
|
|
||||||
@@ -51,9 +53,14 @@ if ($fcm_token === null)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// update fcm and gen new user_secret
|
||||||
|
|
||||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), fcm_token=:ft, user_key=:at WHERE user_id = :uid');
|
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), fcm_token=:ft, user_key=:at WHERE user_id = :uid');
|
||||||
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token, 'at' => $new_userkey]);
|
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token, 'at' => $new_userkey]);
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('UPDATE users SET fcm_token=NULL WHERE user_id <> :uid AND fcm_token=:ft');
|
||||||
|
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]);
|
||||||
|
|
||||||
echo json_encode(
|
echo json_encode(
|
||||||
[
|
[
|
||||||
'success' => true,
|
'success' => true,
|
||||||
|
@@ -49,8 +49,7 @@ if ($ispro)
|
|||||||
[
|
[
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'user_key' => $new_userkey,
|
'quota' => $data['quota_today'],
|
||||||
'quota' => $data['quota'],
|
|
||||||
'quota_max'=> Statics::quota_max(true),
|
'quota_max'=> Statics::quota_max(true),
|
||||||
'is_pro' => true,
|
'is_pro' => true,
|
||||||
'message' => 'user updated'
|
'message' => 'user updated'
|
||||||
@@ -68,8 +67,7 @@ else
|
|||||||
[
|
[
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'user_key' => $new_userkey,
|
'quota' => $data['quota_today'],
|
||||||
'quota' => $data['quota'],
|
|
||||||
'quota_max'=> Statics::quota_max(false),
|
'quota_max'=> Statics::quota_max(false),
|
||||||
'is_pro' => false,
|
'is_pro' => false,
|
||||||
'message' => 'user updated'
|
'message' => 'user updated'
|
||||||
|
Reference in New Issue
Block a user