diff --git a/android/.idea/assetWizardSettings.xml b/android/.idea/assetWizardSettings.xml
index 2eb36a1..5aa074b 100644
--- a/android/.idea/assetWizardSettings.xml
+++ b/android/.idea/assetWizardSettings.xml
@@ -14,8 +14,8 @@
diff --git a/android/app/build.gradle b/android/app/build.gradle
index eafab24..026882d 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -15,6 +15,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ compileOptions {
+ targetCompatibility 1.8
+ sourceCompatibility 1.8
+ }
}
dependencies {
@@ -29,6 +33,9 @@ dependencies {
implementation 'com.google.firebase:firebase-core:16.0.3'
implementation 'com.google.firebase:firebase-messaging:17.3.2'
implementation 'com.android.support:support-v4:27.1.1'
+
+ implementation 'com.squareup.okhttp3:okhttp:3.10.0'
+ implementation 'com.github.kenglxn.QRGen:android:2.5.0'
}
apply plugin: 'com.google.gms.google-services'
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java
index 102f8eb..2f2c607 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java
@@ -4,7 +4,9 @@ import android.app.Application;
import android.content.Context;
import android.widget.Toast;
+import com.blackforestbytes.simplecloudnotifier.view.AccountFragment;
import com.blackforestbytes.simplecloudnotifier.view.MainActivity;
+import com.blackforestbytes.simplecloudnotifier.view.TabAdapter;
import java.lang.ref.WeakReference;
@@ -28,11 +30,7 @@ public class SCNApp extends Application
final MainActivity a = mainActivity.get();
if (a != null)
{
- a.runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(a, msg, duration).show();
- }
- });
+ a.runOnUiThread(() -> Toast.makeText(a, msg, duration).show());
}
}
@@ -43,6 +41,23 @@ public class SCNApp extends Application
return false;
}
+ public static void refreshAccountTab()
+ {
+ runOnUiThread(() ->
+ {
+ MainActivity a = mainActivity.get();
+ if (a == null) return;
+
+ TabAdapter ta = a.adpTabs;
+ if (ta == null) return;
+
+ AccountFragment tf = ta.tab2;
+ if (tf == null) return;
+
+ tf.updateUI();
+ });
+ }
+
public static void register(MainActivity a)
{
mainActivity = new WeakReference<>(a);
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java
index 693a86a..f8a9ff1 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java
@@ -65,7 +65,7 @@ public class CMessageList
{
MessageAdapter a = ref.get();
if (a == null) continue;
- a.notifyItemInserted(count);
+ a.customNotifyItemInserted(count);
}
CleanUpListener();
}
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/SCNSettings.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/SCNSettings.java
new file mode 100644
index 0000000..931a81d
--- /dev/null
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/SCNSettings.java
@@ -0,0 +1,126 @@
+package com.blackforestbytes.simplecloudnotifier.model;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+import android.view.View;
+
+import com.blackforestbytes.simplecloudnotifier.SCNApp;
+import com.google.firebase.iid.FirebaseInstanceId;
+
+public class SCNSettings
+{
+ private final static Object _lock = new Object();
+ private static SCNSettings _inst = null;
+ public static SCNSettings inst()
+ {
+ synchronized (_lock)
+ {
+ if (_inst != null) return _inst;
+ return _inst = new SCNSettings();
+ }
+ }
+
+ public int quota_curr;
+ public int quota_max;
+ public int user_id;
+ public String user_key;
+
+ public String fcm_token_local;
+ public String fcm_token_server;
+
+ public SCNSettings()
+ {
+ SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("Config", Context.MODE_PRIVATE);
+
+ quota_curr = sharedPref.getInt("quota_curr", 0);
+ quota_max = sharedPref.getInt("quota_max", 0);
+ user_id = sharedPref.getInt("user_id", -1);
+ user_key = sharedPref.getString("user_key", "");
+ fcm_token_local = sharedPref.getString("fcm_token_local", "");
+ fcm_token_server = sharedPref.getString("fcm_token_server", "");
+ }
+
+ public void save()
+ {
+ SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("Config", Context.MODE_PRIVATE);
+ SharedPreferences.Editor e = sharedPref.edit();
+
+ e.putInt("quota_curr", quota_curr);
+ e.putInt("quota_max", quota_max);
+ e.putInt("user_id", user_id);
+ e.putString("user_key", user_key);
+ e.putString("fcm_token_local", fcm_token_local);
+ e.putString("fcm_token_server", fcm_token_server);
+
+ e.apply();
+ }
+
+ public boolean isConnected()
+ {
+ return user_id>=0 && user_key != null && !user_key.isEmpty();
+ }
+
+ public String createOnlineURL()
+ {
+ if (!isConnected()) return ServerCommunication.BASE_URL + "index.php";
+ return ServerCommunication.BASE_URL + "index.php?preset_user_id="+user_id+"&preset_user_key="+user_key;
+ }
+
+ public void setServerToken(String token, View loader)
+ {
+ if (isConnected())
+ {
+ fcm_token_local = token;
+ save();
+ if (!fcm_token_local.equals(fcm_token_server)) ServerCommunication.update(user_id, user_key, fcm_token_local, loader);
+ }
+ else
+ {
+ fcm_token_local = token;
+ save();
+ ServerCommunication.register(fcm_token_local, loader);
+ }
+ }
+
+ public void work(Activity a)
+ {
+ FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(a, instanceIdResult ->
+ {
+ String newToken = instanceIdResult.getToken();
+ Log.e("FB::GetInstanceId", newToken);
+ SCNSettings.inst().setServerToken(newToken, null);
+ }).addOnCompleteListener(r ->
+ {
+ if (isConnected()) ServerCommunication.info(user_id, user_key, null);
+ });
+ }
+
+ public void reset(View loader)
+ {
+ if (!isConnected()) return;
+
+ ServerCommunication.update(user_id, user_key, loader);
+ }
+
+ public void refresh(View loader, Activity a)
+ {
+ if (isConnected())
+ {
+ ServerCommunication.info(user_id, user_key, loader);
+ }
+ else
+ {
+ FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(a, instanceIdResult ->
+ {
+ String newToken = instanceIdResult.getToken();
+ Log.e("FB::GetInstanceId", newToken);
+ SCNSettings.inst().setServerToken(newToken, loader);
+ }).addOnCompleteListener(r ->
+ {
+ if (isConnected()) ServerCommunication.info(user_id, user_key, null);
+ });
+ }
+ }
+}
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/ServerCommunication.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/ServerCommunication.java
new file mode 100644
index 0000000..5b691b1
--- /dev/null
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/ServerCommunication.java
@@ -0,0 +1,276 @@
+package com.blackforestbytes.simplecloudnotifier.model;
+
+import android.os.Build;
+import android.util.Log;
+import android.view.View;
+
+import com.blackforestbytes.simplecloudnotifier.BuildConfig;
+import com.blackforestbytes.simplecloudnotifier.SCNApp;
+
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+import java.io.IOException;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+
+public class ServerCommunication
+{
+ //public static final String BASE_URL = "https://simplecloudnotifier.blackforestbytes.com/";
+ public static final String BASE_URL = "http://10.0.2.2:1010/";
+
+ private static final OkHttpClient client = new OkHttpClient();
+
+ private ServerCommunication(){ throw new Error("no."); }
+
+ public static void register(String token, View loader)
+ {
+ try
+ {
+ Request request = new Request.Builder()
+ .url(BASE_URL + "register.php?fcm_token="+token)
+ .build();
+
+ client.newCall(request).enqueue(new Callback()
+ {
+ @Override
+ public void onFailure(Call call, IOException e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
+ }
+
+ @Override
+ public void onResponse(Call call, Response response)
+ {
+ try (ResponseBody responseBody = response.body())
+ {
+ if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
+ if (responseBody == null) throw new IOException("No response");
+
+ String r = responseBody.string();
+ Log.d("Server::Response", r);
+
+ JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
+
+ if (!json.getBoolean("success"))
+ {
+ SCNApp.showToast(json.getString("message"), 4000);
+ return;
+ }
+
+ SCNSettings.inst().user_id = json.getInt("user_id");
+ SCNSettings.inst().user_key = json.getString("user_key");
+ SCNSettings.inst().fcm_token_server = token;
+ SCNSettings.inst().quota_curr = json.getInt("quota");
+ SCNSettings.inst().quota_max = json.getInt("quota_max");
+ SCNSettings.inst().save();
+
+ SCNApp.refreshAccountTab();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+ finally
+ {
+ SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
+ }
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+ }
+
+ public static void update(int id, String key, String token, View loader)
+ {
+ try
+ {
+ Request request = new Request.Builder()
+ .url(BASE_URL + "update.php?user_id="+id+"&user_key="+key+"&fcm_token="+token)
+ .build();
+
+ client.newCall(request).enqueue(new Callback()
+ {
+ @Override
+ public void onFailure(Call call, IOException e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
+ }
+
+ @Override
+ public void onResponse(Call call, Response response)
+ {
+ try (ResponseBody responseBody = response.body())
+ {
+ if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
+ if (responseBody == null) throw new IOException("No response");
+
+ String r = responseBody.string();
+ Log.d("Server::Response", r);
+
+ JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
+
+ if (!json.getBoolean("success"))
+ {
+ SCNApp.showToast(json.getString("message"), 4000);
+ return;
+ }
+
+ SCNSettings.inst().user_id = json.getInt("user_id");
+ SCNSettings.inst().user_key = json.getString("user_key");
+ SCNSettings.inst().fcm_token_server = token;
+ SCNSettings.inst().quota_curr = json.getInt("quota");
+ SCNSettings.inst().quota_max = json.getInt("quota_max");
+ SCNSettings.inst().save();
+
+ SCNApp.refreshAccountTab();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+ finally
+ {
+ SCNApp.runOnUiThread(() -> { if (loader!=null)loader.setVisibility(View.GONE); });
+ }
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+ }
+
+ public static void update(int id, String key, View loader)
+ {
+ try
+ {
+ Request request = new Request.Builder()
+ .url(BASE_URL + "update.php?user_id=" + id + "&user_key=" + key)
+ .build();
+
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) {
+ try (ResponseBody responseBody = response.body()) {
+ if (!response.isSuccessful())
+ throw new IOException("Unexpected code " + response);
+ if (responseBody == null) throw new IOException("No response");
+
+ String r = responseBody.string();
+ Log.d("Server::Response", r);
+
+ JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
+
+ if (!json.getBoolean("success")) {
+ SCNApp.showToast(json.getString("message"), 4000);
+ return;
+ }
+
+ SCNSettings.inst().user_id = json.getInt("user_id");
+ SCNSettings.inst().user_key = json.getString("user_key");
+ SCNSettings.inst().quota_curr = json.getInt("quota");
+ SCNSettings.inst().quota_max = json.getInt("quota_max");
+ SCNSettings.inst().save();
+
+ SCNApp.refreshAccountTab();
+ } catch (Exception e) {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ } finally {
+ SCNApp.runOnUiThread(() -> {
+ if (loader != null) loader.setVisibility(View.GONE);
+ });
+ }
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+ }
+
+ public static void info(int id, String key, View loader)
+ {
+ try
+ {
+ Request request = new Request.Builder()
+ .url(BASE_URL + "info.php?user_id=" + id + "&user_key=" + key)
+ .build();
+
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ SCNApp.runOnUiThread(() -> {
+ if (loader != null) loader.setVisibility(View.GONE);
+ });
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) {
+ try (ResponseBody responseBody = response.body()) {
+ if (!response.isSuccessful())
+ throw new IOException("Unexpected code " + response);
+ if (responseBody == null) throw new IOException("No response");
+
+ String r = responseBody.string();
+ Log.d("Server::Response", r);
+
+ JSONObject json = (JSONObject) new JSONTokener(r).nextValue();
+
+ if (!json.getBoolean("success")) {
+ SCNApp.showToast(json.getString("message"), 4000);
+ return;
+ }
+
+ SCNSettings.inst().user_id = json.getInt("user_id");
+ SCNSettings.inst().quota_curr = json.getInt("quota");
+ SCNSettings.inst().quota_max = json.getInt("quota_max");
+ SCNSettings.inst().save();
+
+ SCNApp.refreshAccountTab();
+ } catch (Exception e) {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ } finally {
+ SCNApp.runOnUiThread(() -> {
+ if (loader != null) loader.setVisibility(View.GONE);
+ });
+ }
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ SCNApp.showToast("Communication with server failed", 4000);
+ }
+ }
+}
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java
index 2a78c79..79873dc 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java
@@ -5,6 +5,7 @@ import android.widget.Toast;
import com.blackforestbytes.simplecloudnotifier.SCNApp;
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
+import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
@@ -14,6 +15,7 @@ public class FBMService extends FirebaseMessagingService
public void onNewToken(String token)
{
Log.i("Firebase::NewToken", token);
+ SCNSettings.inst().setServerToken(token, null);
}
@Override
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java
index 4051949..eeb2418 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java
@@ -1,13 +1,33 @@
package com.blackforestbytes.simplecloudnotifier.view;
+import android.annotation.SuppressLint;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.VectorDrawable;
+import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
+import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.blackforestbytes.simplecloudnotifier.R;
+import com.blackforestbytes.simplecloudnotifier.SCNApp;
+import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
+import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
+import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
+
+import net.glxn.qrgen.android.QRCode;
+import net.glxn.qrgen.core.image.ImageType;
+
+import static android.content.Context.CLIPBOARD_SERVICE;
public class AccountFragment extends Fragment
{
@@ -19,7 +39,82 @@ public class AccountFragment extends Fragment
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
- return inflater.inflate(R.layout.fragment_account, container, false);
+ View v = inflater.inflate(R.layout.fragment_account, container, false);
+
+ updateUI(v);
+
+ v.findViewById(R.id.btnCopyUserID).setOnClickListener(cv ->
+ {
+ ClipboardManager clipboard = (ClipboardManager) cv.getContext().getSystemService(CLIPBOARD_SERVICE);
+ clipboard.setPrimaryClip(ClipData.newPlainText("UserID", String.valueOf(SCNSettings.inst().user_id)));
+ SCNApp.showToast("Copied userID to clipboard", 1000);
+ });
+
+ v.findViewById(R.id.btnCopyUserKey).setOnClickListener(cv ->
+ {
+ ClipboardManager clipboard = (ClipboardManager) cv.getContext().getSystemService(CLIPBOARD_SERVICE);
+ clipboard.setPrimaryClip(ClipData.newPlainText("UserKey", String.valueOf(SCNSettings.inst().user_key)));
+ SCNApp.showToast("Copied key to clipboard", 1000);
+ });
+
+ v.findViewById(R.id.btnAccountReset).setOnClickListener(cv ->
+ {
+ View lpnl = v.findViewById(R.id.loadingPanel);
+ lpnl.setVisibility(View.VISIBLE);
+ SCNSettings.inst().reset(lpnl);
+ });
+
+ v.findViewById(R.id.btnClearLocalStorage).setOnClickListener(cv ->
+ {
+ CMessageList.inst().Messages.clear();
+ CMessageList.inst().fullSave();
+ SCNApp.showToast("Notifications cleared", 1000);
+ });
+
+ v.findViewById(R.id.btnQR).setOnClickListener(cv ->
+ {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(SCNSettings.inst().createOnlineURL()));
+ startActivity(browserIntent);
+ });
+
+ v.findViewById(R.id.btnRefresh).setOnClickListener(cv ->
+ {
+ View lpnl = v.findViewById(R.id.loadingPanel);
+ lpnl.setVisibility(View.VISIBLE);
+ SCNSettings.inst().refresh(lpnl, getActivity());
+ });
+
+ return v;
}
+ public void updateUI()
+ {
+ updateUI(getView());
+ }
+
+ @SuppressLint("DefaultLocale")
+ public void updateUI(View v)
+ {
+ TextView tvUserID = v.findViewById(R.id.tvUserID);
+ TextView tvUserKey = v.findViewById(R.id.tvUserKey);
+ TextView tvQuota = v.findViewById(R.id.tvQuota);
+ ImageButton btnQR = v.findViewById(R.id.btnQR);
+
+ SCNSettings s = SCNSettings.inst();
+
+ if (s.isConnected())
+ {
+ tvUserID.setText(String.valueOf(s.user_id));
+ tvUserKey.setText(s.user_key);
+ tvQuota.setText(String.format("%d / %d", s.quota_curr, s.quota_max));
+ btnQR.setImageBitmap(QRCode.from(s.createOnlineURL()).to(ImageType.PNG).withSize(512, 512).bitmap());
+ }
+ else
+ {
+ tvUserID.setText(R.string.str_not_connected);
+ tvUserKey.setText(R.string.str_not_connected);
+ tvQuota.setText(R.string.str_not_connected);
+ btnQR.setImageResource(R.drawable.qr_default);
+ }
+ }
}
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java
index 50e4eee..33b0d38 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java
@@ -8,34 +8,40 @@ import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.blackforestbytes.simplecloudnotifier.R;
import com.blackforestbytes.simplecloudnotifier.SCNApp;
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
+import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
+import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
+import com.google.firebase.iid.FirebaseInstanceId;
public class MainActivity extends AppCompatActivity
{
+ public TabAdapter adpTabs;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- TabLayout tabLayout = findViewById(R.id.tab_layout);
- tabLayout.addTab(tabLayout.newTab().setText("Notifications"));
- tabLayout.addTab(tabLayout.newTab().setText("Account"));
- tabLayout.addTab(tabLayout.newTab().setText("Settings"));
- tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
-
- final ViewPager viewPager = findViewById(R.id.pager);
- final PagerAdapter adapter = new TabAdapter(getSupportFragmentManager());
+ ViewPager viewPager = findViewById(R.id.pager);
+ PagerAdapter adapter = adpTabs = new TabAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
- viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
+
+ TabLayout tabLayout = findViewById(R.id.tab_layout);
+ tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
+ tabLayout.setupWithViewPager(viewPager);
SCNApp.register(this);
+
+ SCNSettings.inst().work(this);
}
@Override
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java
index 401d3ab..03e850a 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java
@@ -15,8 +15,11 @@ import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
public class MessageAdapter extends RecyclerView.Adapter
{
- public MessageAdapter()
+ private final View vNoElements;
+
+ public MessageAdapter(View noElementsView)
{
+ vNoElements = noElementsView;
CMessageList.inst().register(this);
}
@@ -42,6 +45,18 @@ public class MessageAdapter extends RecyclerView.Adapter
return CMessageList.inst().size();
}
+ public void customNotifyItemInserted(int idx)
+ {
+ notifyItemInserted(idx);
+ vNoElements.setVisibility(getItemCount()>0 ? View.VISIBLE : View.GONE);
+ }
+
+ public void customNotifyDataSetChanged()
+ {
+ notifyDataSetChanged();
+ vNoElements.setVisibility(getItemCount()>0 ? View.VISIBLE : View.GONE);
+ }
+
private class MessagePresenter extends RecyclerView.ViewHolder implements View.OnClickListener
{
private TextView tvTimestamp;
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/NotificationsFragment.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/NotificationsFragment.java
index 70eb627..6824958 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/NotificationsFragment.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/NotificationsFragment.java
@@ -27,7 +27,7 @@ public class NotificationsFragment extends Fragment
RecyclerView rvMessages = v.findViewById(R.id.rvMessages);
rvMessages.setLayoutManager(new LinearLayoutManager(this.getContext(), RecyclerView.VERTICAL, true));
- rvMessages.setAdapter(new MessageAdapter());
+ rvMessages.setAdapter(new MessageAdapter(v.findViewById(R.id.tvNoElements)));
return v;
}
diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/TabAdapter.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/TabAdapter.java
index 6d69993..f0d851f 100644
--- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/TabAdapter.java
+++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/TabAdapter.java
@@ -6,6 +6,10 @@ import android.support.v4.app.FragmentStatePagerAdapter;
public class TabAdapter extends FragmentStatePagerAdapter {
+ public NotificationsFragment tab1 = new NotificationsFragment();
+ public AccountFragment tab2 = new AccountFragment();
+ public SettingsFragment tab3 = new SettingsFragment();
+
public TabAdapter(FragmentManager fm)
{
super(fm);
@@ -16,16 +20,28 @@ public class TabAdapter extends FragmentStatePagerAdapter {
switch (position) {
case 0:
- return new NotificationsFragment();
+ return tab1;
case 1:
- return new AccountFragment();
+ return tab2;
case 2:
- return new SettingsFragment();
+ return tab3;
default:
return null;
}
}
+ @Override
+ public CharSequence getPageTitle(int position)
+ {
+ switch (position)
+ {
+ case 0: return "Notifications";
+ case 1: return "Account";
+ case 2: return "Settings";
+ default: return null;
+ }
+ }
+
@Override
public int getCount() {
return 3;
diff --git a/android/app/src/main/res/drawable/ic_refresh.xml b/android/app/src/main/res/drawable/ic_refresh.xml
new file mode 100644
index 0000000..45dc20c
--- /dev/null
+++ b/android/app/src/main/res/drawable/ic_refresh.xml
@@ -0,0 +1,6 @@
+
+
+
diff --git a/android/app/src/main/res/drawable/qr_default.xml b/android/app/src/main/res/drawable/qr_default.xml
index d47e01b..344e92c 100644
--- a/android/app/src/main/res/drawable/qr_default.xml
+++ b/android/app/src/main/res/drawable/qr_default.xml
@@ -1,5 +1,5 @@
diff --git a/android/app/src/main/res/layout/fragment_account.xml b/android/app/src/main/res/layout/fragment_account.xml
index 16fcef8..d6bd560 100644
--- a/android/app/src/main/res/layout/fragment_account.xml
+++ b/android/app/src/main/res/layout/fragment_account.xml
@@ -1,197 +1,238 @@
-
+ android:layout_height="match_parent"
+ tools:context=".view.AccountFragment">
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ android:indeterminate="true"
+ android:indeterminateTint="#FFF"
+ tools:ignore="UnusedAttribute" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/android/app/src/main/res/layout/fragment_notifications.xml b/android/app/src/main/res/layout/fragment_notifications.xml
index 3623e93..75e4049 100644
--- a/android/app/src/main/res/layout/fragment_notifications.xml
+++ b/android/app/src/main/res/layout/fragment_notifications.xml
@@ -12,4 +12,11 @@
android:clipToPadding="false"
android:scrollbars="vertical" />
+
\ No newline at end of file
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 97a2445..1318ba0 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
- SimpleCloudNotifier
+ Simple Cloud Notifier
Hello blank fragment
Icon User
@@ -11,4 +11,7 @@
Icon Fuel
QR Code
Reset Account
+ No notifications
+ not connected
+ reload
diff --git a/android/build.gradle b/android/build.gradle
index 5898833..af5e896 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -18,6 +18,7 @@ allprojects {
repositories {
google()
jcenter()
+ maven { url "https://jitpack.io" }
}
}
diff --git a/web/info.php b/web/info.php
new file mode 100644
index 0000000..1c9bc8b
--- /dev/null
+++ b/web/info.php
@@ -0,0 +1,42 @@
+ 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]]']));
+
+$user_id = $INPUT['user_id'];
+$user_key = $INPUT['token'];
+
+//----------------------
+
+$pdo = getDatabase();
+
+$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, quota_max, quota_day 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' => 'No User 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']));
+
+$quota = $data['quota_today'];
+$quota_max = $data['quota_max'];
+
+if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $quota=0;
+
+echo json_encode(
+[
+ 'success' => true,
+ 'user_id' => $user_id,
+ 'quota' => $quota,
+ 'quota_max'=> $quota_max,
+ 'message' => 'ok'
+]);
+return 0;
\ No newline at end of file
diff --git a/web/register.php b/web/register.php
index f4fcebd..c089e3a 100644
--- a/web/register.php
+++ b/web/register.php
@@ -15,5 +15,14 @@ $stmt = $pdo->prepare('INSERT INTO users (user_key, fcm_token, timestamp_accesse
$stmt->execute(['key' => $user_key, 'token' => $fcmtoken]);
$user_id = $pdo->lastInsertId('user_id');
-echo json_encode(['success' => true, 'user_id' => $user_id, 'user_key' => $user_key, 'message' => 'new user registered']);
+echo json_encode(
+[
+ 'success' => true,
+ 'user_id' => $user_id,
+ 'user_key' => $user_key,
+ 'quota' => 0,
+ 'quota_max'=> 100,
+ 'message' => 'New user registered'
+]);
+
return 0;
\ No newline at end of file
diff --git a/web/update.php b/web/update.php
index 66e81bb..3ea19c6 100644
--- a/web/update.php
+++ b/web/update.php
@@ -7,17 +7,16 @@ $INPUT = array_merge($_GET, $_POST);
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[user_id]]']));
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[user_key]]']));
-if (!isset($INPUT['message'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[message]]']));
$user_id = $INPUT['user_id'];
-$user_key = $INPUT['token'];
-$fcm_token = isset($INPUT['token']) ? $INPUT['token'] : null;
+$user_key = $INPUT['user_key'];
+$fcm_token = isset($INPUT['fcm_token']) ? $INPUT['fcm_token'] : null;
//----------------------
$pdo = getDatabase();
-$stmt = $pdo->prepare('SELECT user_id, user_key FROM users WHERE user_id = :uid LIMIT 1');
+$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, quota_max, quota_day FROM users WHERE user_id = :uid LIMIT 1');
$stmt->execute(['uid' => $user_id]);
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
@@ -28,6 +27,9 @@ if ($data === null) die(json_encode(['success' => false, 'message' => 'User not
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'message' => 'UserID not found']));
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'message' => 'Authentification failed']));
+$quota = $data['quota_today'];
+$quota_max = $data['quota_max'];
+
$new_userkey = generateRandomAuthKey();
if ($fcm_token === null)
@@ -35,7 +37,15 @@ if ($fcm_token === null)
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), user_key=:at WHERE user_id = :uid');
$stmt->execute(['uid' => $user_id, 'at' => $new_userkey]);
- echo json_encode(['success' => true, 'user_id' => $user_id, 'user_key' => $new_userkey, 'message' => 'user updated']);
+ echo json_encode(
+ [
+ 'success' => true,
+ 'user_id' => $user_id,
+ 'user_key' => $new_userkey,
+ 'quota' => $quota,
+ 'quota_max'=> $quota_max,
+ 'message' => 'user updated'
+ ]);
return 0;
}
else
@@ -43,6 +53,14 @@ else
$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]);
- echo json_encode(['success' => true, 'user_id' => $user_id, 'user_key' => $new_userkey, 'message' => 'user updated']);
+ echo json_encode(
+ [
+ 'success' => true,
+ 'user_id' => $user_id,
+ 'user_key' => $new_userkey,
+ 'quota' => $quota,
+ 'quota_max'=> $quota_max,
+ 'message' => 'user updated'
+ ]);
return 0;
}
\ No newline at end of file