package com.cygnusa.hyperm; import android.annotation.SuppressLint; import android.content.ContentValues; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.RecyclerView; import androidx.appcompat.widget.Toolbar; import androidx.recyclerview.widget.ItemTouchHelper; import android.view.MenuItem; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.reflect.TypeToken; import com.cygnusa.hyperm.adapter.NotificationAdapter; import com.cygnusa.hyperm.fancyshowcase.DismissListener; import com.cygnusa.hyperm.fancyshowcase.FancyShowCaseView; import com.cygnusa.hyperm.fancyshowcase.FocusShape; import com.cygnusa.hyperm.util.ApiService; import com.cygnusa.hyperm.util.GlobalData; import com.cygnusa.hyperm.util.MainApplication; import com.cygnusa.hyperm.util.MyCallback; import com.cygnusa.hyperm.util.PositionUpdateListener; import com.cygnusa.hyperm.util.TransparentProgressDialog; import com.cygnusa.hyperm.util.UtilService; import com.cygnusa.hyperm.util.WrapContentLinearLayoutManager; import com.cygnusa.hyperm.wrappers.AssessmentList; import com.cygnusa.hyperm.wrappers.ErrorResponse; import com.cygnusa.hyperm.wrappers.Notification; import com.cygnusa.hyperm.wrappers.NotificationResponse; import com.tylersuehr.esr.EmptyStateRecyclerView; import com.tylersuehr.esr.TextStateDisplay; import java.util.ArrayList; import java.util.HashMap; import jp.wasabeef.recyclerview.animators.SlideInLeftAnimator; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class NotificationActivity extends AppCompatActivity implements PositionUpdateListener, DismissListener { ApiService restService; EmptyStateRecyclerView notificationList; TransparentProgressDialog progressDialog; int PAGE = 0; int LIMIT = 10; WrapContentLinearLayoutManager linearLayoutManager; int TOTAL_RECORD = 0; ProgressBar progressBar; ArrayList MY_NOTIFICATIONS = new ArrayList<>(); NotificationAdapter adapter; private Paint p = new Paint(); public static Handler.Callback notificationCallback; ArrayList ASSESSMENT_LIST = new ArrayList<>(); ArrayList OFFLINE_ASSESSMENT_LIST = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notification); setupWindowAnimations(); restService = ((MainApplication) getApplication()).getClient(); GlobalData.openDatabase(NotificationActivity.this); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); toolbar.setContentInsetStartWithNavigation(0); toolbar.setTitle(""); getSupportActionBar().setTitle(""); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); @SuppressLint("PrivateResource") Drawable backArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_material); backArrow.setColorFilter(getResources().getColor(R.color.btn_bg_color), PorterDuff.Mode.SRC_ATOP); getSupportActionBar().setHomeAsUpIndicator(backArrow); notificationList = findViewById(R.id.notificationList); notificationList.setHasFixedSize(true); notificationList.setItemAnimator(new SlideInLeftAnimator()); linearLayoutManager = new WrapContentLinearLayoutManager(getBaseContext()); notificationList.setLayoutManager(linearLayoutManager); notificationList.addOnScrollListener(recyclerViewOnScrollListener); progressBar = findViewById(R.id.progressBar); notificationList.setStateDisplay(EmptyStateRecyclerView.STATE_EMPTY, new TextStateDisplay(this, "No data available", "")); notificationList.post(new Runnable() { @Override public void run() { getNotifications(true); } }); initSwipe(); findViewById(R.id.helpIcon).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showHelpScreen(); } }); notificationCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { PAGE = 0; getNotifications(false); return false; } }; } private void showHelpScreen() { try { View view; // if (adapter != null && adapter.getItemCount() > 0) { // view = notificationList.findViewHolderForAdapterPosition(linearLayoutManager.findFirstVisibleItemPosition()).itemView; // } else { // view = notificationList; // } new FancyShowCaseView.Builder(this) .focusOn(notificationList) .title("Tap here to view notification") .titleSize(22, 1) .titleGravity(1) .closeOnTouch(true) .fitSystemWindows(false) .dismissListener(this) .focusShape(FocusShape.ROUNDED_RECTANGLE) .backgroundColor(Color.parseColor("#99000000")) .build() .show(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onDismiss(String id) { try { View view; if (adapter != null && adapter.getItemCount() > 0) { view = notificationList.findViewHolderForAdapterPosition(linearLayoutManager.findFirstVisibleItemPosition()).itemView; } else { view = notificationList; } new FancyShowCaseView.Builder(this) .focusOn(view) .title("Swipe right to left delete notification") .titleSize(22, 1) .closeOnTouch(true) .fitSystemWindows(false) .focusShape(FocusShape.ROUNDED_RECTANGLE) .backgroundColor(Color.parseColor("#99000000")) .build() .show(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onSkipped(String id) { } private void initSwipe() { ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { return false; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); if (direction == ItemTouchHelper.LEFT) { try { notificationList.setEnabled(false); deleteNotification(position); notificationList.setEnabled(true); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { Bitmap icon; if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { View itemView = viewHolder.itemView; float height = (float) itemView.getBottom() - (float) itemView.getTop(); float width = height / 3; if (dX < 0) { p.setColor(Color.RED); RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(), (float) itemView.getRight(), (float) itemView.getBottom()); c.drawRect(background, p); icon = BitmapFactory.decodeResource(getResources(), R.mipmap.delete_icon); RectF icon_dest = new RectF((float) itemView.getRight() - 2 * width, (float) itemView.getTop() + width, (float) itemView.getRight() - width, (float) itemView.getBottom() - width); c.drawBitmap(icon, null, icon_dest, p); } } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } }; ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); itemTouchHelper.attachToRecyclerView(notificationList); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { finish(); this.overridePendingTransition(R.anim.animation_f_enter, R.anim.animation_f_leave); } return super.onOptionsItemSelected(item); } @Override public void onBackPressed() { super.onBackPressed(); this.overridePendingTransition(R.anim.animation_f_enter, R.anim.animation_f_leave); } private void setupWindowAnimations() { this.overridePendingTransition(R.anim.animation_enter, R.anim.animation_leave); } @Override protected void onResume() { super.onResume(); if (GlobalData.canLogout) { finish(); } } private void getNotifications(boolean canLoadProgress) { if (new UtilService().isNetworkAvailable(NotificationActivity.this)) { if (canLoadProgress) { progressDialog = new TransparentProgressDialog(NotificationActivity.this); progressDialog.show(); progressBar.setVisibility(View.GONE); } else { progressBar.setVisibility(View.VISIBLE); } restService.getNotifications(PAGE, LIMIT).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } progressBar.setVisibility(View.GONE); if (response.body() != null && response.body().getStatus() == 200) { TOTAL_RECORD = Integer.parseInt(response.body().getTotal()); if (adapter == null) { MY_NOTIFICATIONS = response.body().getData(); adapter = new NotificationAdapter(NotificationActivity.this, MY_NOTIFICATIONS, NotificationActivity.this, restService); notificationList.setAdapter(adapter); } else { MY_NOTIFICATIONS.addAll(response.body().getData()); adapter.notifyDataSetChanged(); } if (MY_NOTIFICATIONS.size() == 0) { notificationList.invokeState(EmptyStateRecyclerView.STATE_EMPTY); } else { notificationList.invokeState(EmptyStateRecyclerView.STATE_OK); } GlobalData.sdb.delete("notifications", null, null); Gson gson = new Gson(); JsonElement jsonElement = gson.toJsonTree( MY_NOTIFICATIONS, new TypeToken>() { }.getType()); ContentValues values = new ContentValues(); values.put("notifications", jsonElement.toString()); GlobalData.sdb.insert("notifications", null, values); } else if (response.body() != null && response.body().getStatus() == 401) { GlobalData.canLogout = true; finish(); } else if (response.body() != null) { GlobalData.showToast(getBaseContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show(); } else if (response.errorBody() != null) { Gson gson = new Gson(); ErrorResponse message = gson.fromJson(response.errorBody().charStream(), ErrorResponse.class); GlobalData.showToast(getBaseContext(), message.getMessage(), Toast.LENGTH_SHORT).show(); if (message.getStatus() == 401) { GlobalData.canLogout = true; finish(); } } new Handler().postDelayed(new Runnable() { @Override public void run() { if (getPreferences(MODE_PRIVATE).getBoolean("NotificationActivity", true)) { showHelpScreen(); getPreferences(MODE_PRIVATE).edit().putBoolean("NotificationActivity", false).apply(); } } }, 1000); } @Override public void onFailure(Call call, Throwable t) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } progressBar.setVisibility(View.GONE); GlobalData.showToast(getBaseContext(), "Connection Failure, try again!", Toast.LENGTH_SHORT).show(); } }); } else { if (adapter == null) { Cursor cursor = GlobalData.sdb.rawQuery("select * from notifications", null); if (cursor.getCount() > 0) { cursor.moveToFirst(); Gson gson = new Gson(); MY_NOTIFICATIONS = gson.fromJson( cursor.getString(cursor.getColumnIndex("notifications")), new TypeToken>() { }.getType()); TOTAL_RECORD = MY_NOTIFICATIONS.size(); adapter = new NotificationAdapter(NotificationActivity.this, MY_NOTIFICATIONS, NotificationActivity.this, restService); notificationList.setAdapter(adapter); } else { GlobalData.showToast(getBaseContext(), "Please check your internet connection", Toast.LENGTH_SHORT).show(); } } else { GlobalData.showToast(getBaseContext(), "Please check your internet connection", Toast.LENGTH_SHORT).show(); } } } private RecyclerView.OnScrollListener recyclerViewOnScrollListener = new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int visibleItemCount = linearLayoutManager.getChildCount(); int totalItemCount = linearLayoutManager.getItemCount(); int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition(); if (progressBar.getVisibility() != View.VISIBLE) { if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0 && totalItemCount < TOTAL_RECORD && MY_NOTIFICATIONS.size() < TOTAL_RECORD) { PAGE++; getNotifications(false); } } } }; @Override public void onPositionUpdate(int position) { } private void deleteNotification(int id) { Cursor cursor = GlobalData.sdb.rawQuery("select * from notification_deleted", null); String ids; if (cursor.getCount() > 0) { cursor.moveToFirst(); ids = cursor.getString(cursor.getColumnIndex("notification_deleted")); ids = ids + "," + MY_NOTIFICATIONS.get(id).getId().trim(); } else { ids = MY_NOTIFICATIONS.get(id).getId().trim(); } adapter.remove(id); if (MY_NOTIFICATIONS.size() == 0) { notificationList.invokeState(EmptyStateRecyclerView.STATE_EMPTY); } GlobalData.sdb.delete("notification_deleted", null, null); ContentValues values1 = new ContentValues(); values1.put("notification_deleted", ids); GlobalData.sdb.insert("notification_deleted", null, values1); GlobalData.sdb.delete("notifications", null, null); Gson gson = new Gson(); JsonElement jsonElement = gson.toJsonTree( MY_NOTIFICATIONS, new TypeToken>() { }.getType()); ContentValues values = new ContentValues(); values.put("notifications", jsonElement.toString()); GlobalData.sdb.insert("notifications", null, values); if (new UtilService().isNetworkAvailable(NotificationActivity.this)) { HashMap map = new HashMap<>(); map.put("notificationid", ids); restService.updateDeleteNotifications(map) .enqueue(new MyCallback(ids) { @Override public void onResponse(Call call, Response response) { if (response.body() != null && response.body().getStatus() == 200) { GlobalData.sdb.delete("notification_deleted", null, null); } try { new android.os.Handler(HomeActivity.badgeUpdateCallback).sendEmptyMessage(0); } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(Call call, Throwable t) { GlobalData.showToast(NotificationActivity.this, "Connection Failure, try again!", Toast.LENGTH_SHORT).show(); } }); } else { try { new android.os.Handler(HomeActivity.badgeUpdateCallback).sendEmptyMessage(0); } catch (Exception e) { e.printStackTrace(); } } } }