NotificationActivity.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. package com.cygnusa.hyperm;
  2. import android.annotation.SuppressLint;
  3. import android.content.ContentValues;
  4. import android.database.Cursor;
  5. import android.graphics.Bitmap;
  6. import android.graphics.BitmapFactory;
  7. import android.graphics.Canvas;
  8. import android.graphics.Color;
  9. import android.graphics.Paint;
  10. import android.graphics.PorterDuff;
  11. import android.graphics.RectF;
  12. import android.graphics.drawable.Drawable;
  13. import android.os.Bundle;
  14. import android.os.Handler;
  15. import android.os.Message;
  16. import androidx.appcompat.app.AppCompatActivity;
  17. import androidx.recyclerview.widget.RecyclerView;
  18. import androidx.appcompat.widget.Toolbar;
  19. import androidx.recyclerview.widget.ItemTouchHelper;
  20. import android.view.MenuItem;
  21. import android.view.View;
  22. import android.widget.ProgressBar;
  23. import android.widget.Toast;
  24. import com.google.gson.Gson;
  25. import com.google.gson.JsonElement;
  26. import com.google.gson.reflect.TypeToken;
  27. import com.cygnusa.hyperm.adapter.NotificationAdapter;
  28. import com.cygnusa.hyperm.fancyshowcase.DismissListener;
  29. import com.cygnusa.hyperm.fancyshowcase.FancyShowCaseView;
  30. import com.cygnusa.hyperm.fancyshowcase.FocusShape;
  31. import com.cygnusa.hyperm.util.ApiService;
  32. import com.cygnusa.hyperm.util.GlobalData;
  33. import com.cygnusa.hyperm.util.MainApplication;
  34. import com.cygnusa.hyperm.util.MyCallback;
  35. import com.cygnusa.hyperm.util.PositionUpdateListener;
  36. import com.cygnusa.hyperm.util.TransparentProgressDialog;
  37. import com.cygnusa.hyperm.util.UtilService;
  38. import com.cygnusa.hyperm.util.WrapContentLinearLayoutManager;
  39. import com.cygnusa.hyperm.wrappers.AssessmentList;
  40. import com.cygnusa.hyperm.wrappers.ErrorResponse;
  41. import com.cygnusa.hyperm.wrappers.Notification;
  42. import com.cygnusa.hyperm.wrappers.NotificationResponse;
  43. import com.tylersuehr.esr.EmptyStateRecyclerView;
  44. import com.tylersuehr.esr.TextStateDisplay;
  45. import java.util.ArrayList;
  46. import java.util.HashMap;
  47. import jp.wasabeef.recyclerview.animators.SlideInLeftAnimator;
  48. import retrofit2.Call;
  49. import retrofit2.Callback;
  50. import retrofit2.Response;
  51. public class NotificationActivity extends AppCompatActivity implements PositionUpdateListener, DismissListener {
  52. ApiService restService;
  53. EmptyStateRecyclerView notificationList;
  54. TransparentProgressDialog progressDialog;
  55. int PAGE = 0;
  56. int LIMIT = 10;
  57. WrapContentLinearLayoutManager linearLayoutManager;
  58. int TOTAL_RECORD = 0;
  59. ProgressBar progressBar;
  60. ArrayList<Notification> MY_NOTIFICATIONS = new ArrayList<>();
  61. NotificationAdapter adapter;
  62. private Paint p = new Paint();
  63. public static Handler.Callback notificationCallback;
  64. ArrayList<AssessmentList> ASSESSMENT_LIST = new ArrayList<>();
  65. ArrayList<AssessmentList> OFFLINE_ASSESSMENT_LIST = new ArrayList<>();
  66. @Override
  67. protected void onCreate(Bundle savedInstanceState) {
  68. super.onCreate(savedInstanceState);
  69. setContentView(R.layout.activity_notification);
  70. setupWindowAnimations();
  71. restService = ((MainApplication) getApplication()).getClient();
  72. GlobalData.openDatabase(NotificationActivity.this);
  73. Toolbar toolbar = findViewById(R.id.toolbar);
  74. setSupportActionBar(toolbar);
  75. toolbar.setContentInsetStartWithNavigation(0);
  76. toolbar.setTitle("");
  77. getSupportActionBar().setTitle("");
  78. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  79. getSupportActionBar().setDisplayShowHomeEnabled(true);
  80. @SuppressLint("PrivateResource")
  81. Drawable backArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_material);
  82. backArrow.setColorFilter(getResources().getColor(R.color.btn_bg_color), PorterDuff.Mode.SRC_ATOP);
  83. getSupportActionBar().setHomeAsUpIndicator(backArrow);
  84. notificationList = findViewById(R.id.notificationList);
  85. notificationList.setHasFixedSize(true);
  86. notificationList.setItemAnimator(new SlideInLeftAnimator());
  87. linearLayoutManager = new WrapContentLinearLayoutManager(getBaseContext());
  88. notificationList.setLayoutManager(linearLayoutManager);
  89. notificationList.addOnScrollListener(recyclerViewOnScrollListener);
  90. progressBar = findViewById(R.id.progressBar);
  91. notificationList.setStateDisplay(EmptyStateRecyclerView.STATE_EMPTY,
  92. new TextStateDisplay(this, "No data available", ""));
  93. notificationList.post(new Runnable() {
  94. @Override
  95. public void run() {
  96. getNotifications(true);
  97. }
  98. });
  99. initSwipe();
  100. findViewById(R.id.helpIcon).setOnClickListener(new View.OnClickListener() {
  101. @Override
  102. public void onClick(View v) {
  103. showHelpScreen();
  104. }
  105. });
  106. notificationCallback = new Handler.Callback() {
  107. @Override
  108. public boolean handleMessage(Message msg) {
  109. PAGE = 0;
  110. getNotifications(false);
  111. return false;
  112. }
  113. };
  114. }
  115. private void showHelpScreen() {
  116. try {
  117. View view;
  118. // if (adapter != null && adapter.getItemCount() > 0) {
  119. // view = notificationList.findViewHolderForAdapterPosition(linearLayoutManager.findFirstVisibleItemPosition()).itemView;
  120. // } else {
  121. // view = notificationList;
  122. // }
  123. new FancyShowCaseView.Builder(this)
  124. .focusOn(notificationList)
  125. .title("Tap here to view notification")
  126. .titleSize(22, 1)
  127. .titleGravity(1)
  128. .closeOnTouch(true)
  129. .fitSystemWindows(false)
  130. .dismissListener(this)
  131. .focusShape(FocusShape.ROUNDED_RECTANGLE)
  132. .backgroundColor(Color.parseColor("#99000000"))
  133. .build()
  134. .show();
  135. } catch (Exception e) {
  136. e.printStackTrace();
  137. }
  138. }
  139. @Override
  140. public void onDismiss(String id) {
  141. try {
  142. View view;
  143. if (adapter != null && adapter.getItemCount() > 0) {
  144. view = notificationList.findViewHolderForAdapterPosition(linearLayoutManager.findFirstVisibleItemPosition()).itemView;
  145. } else {
  146. view = notificationList;
  147. }
  148. new FancyShowCaseView.Builder(this)
  149. .focusOn(view)
  150. .title("Swipe right to left delete notification")
  151. .titleSize(22, 1)
  152. .closeOnTouch(true)
  153. .fitSystemWindows(false)
  154. .focusShape(FocusShape.ROUNDED_RECTANGLE)
  155. .backgroundColor(Color.parseColor("#99000000"))
  156. .build()
  157. .show();
  158. } catch (Exception e) {
  159. e.printStackTrace();
  160. }
  161. }
  162. @Override
  163. public void onSkipped(String id) {
  164. }
  165. private void initSwipe() {
  166. ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
  167. @Override
  168. public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
  169. return false;
  170. }
  171. @Override
  172. public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
  173. int position = viewHolder.getAdapterPosition();
  174. if (direction == ItemTouchHelper.LEFT) {
  175. try {
  176. notificationList.setEnabled(false);
  177. deleteNotification(position);
  178. notificationList.setEnabled(true);
  179. } catch (Exception e) {
  180. e.printStackTrace();
  181. }
  182. }
  183. }
  184. @Override
  185. public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
  186. Bitmap icon;
  187. if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
  188. View itemView = viewHolder.itemView;
  189. float height = (float) itemView.getBottom() - (float) itemView.getTop();
  190. float width = height / 3;
  191. if (dX < 0) {
  192. p.setColor(Color.RED);
  193. RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),
  194. (float) itemView.getRight(), (float) itemView.getBottom());
  195. c.drawRect(background, p);
  196. icon = BitmapFactory.decodeResource(getResources(), R.mipmap.delete_icon);
  197. RectF icon_dest = new RectF((float) itemView.getRight() - 2 * width,
  198. (float) itemView.getTop() + width, (float) itemView.getRight() - width,
  199. (float) itemView.getBottom() - width);
  200. c.drawBitmap(icon, null, icon_dest, p);
  201. }
  202. }
  203. super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
  204. }
  205. };
  206. ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
  207. itemTouchHelper.attachToRecyclerView(notificationList);
  208. }
  209. @Override
  210. public boolean onOptionsItemSelected(MenuItem item) {
  211. if (item.getItemId() == android.R.id.home) {
  212. finish();
  213. this.overridePendingTransition(R.anim.animation_f_enter,
  214. R.anim.animation_f_leave);
  215. }
  216. return super.onOptionsItemSelected(item);
  217. }
  218. @Override
  219. public void onBackPressed() {
  220. super.onBackPressed();
  221. this.overridePendingTransition(R.anim.animation_f_enter,
  222. R.anim.animation_f_leave);
  223. }
  224. private void setupWindowAnimations() {
  225. this.overridePendingTransition(R.anim.animation_enter,
  226. R.anim.animation_leave);
  227. }
  228. @Override
  229. protected void onResume() {
  230. super.onResume();
  231. if (GlobalData.canLogout) {
  232. finish();
  233. }
  234. }
  235. private void getNotifications(boolean canLoadProgress) {
  236. if (new UtilService().isNetworkAvailable(NotificationActivity.this)) {
  237. if (canLoadProgress) {
  238. progressDialog = new TransparentProgressDialog(NotificationActivity.this);
  239. progressDialog.show();
  240. progressBar.setVisibility(View.GONE);
  241. } else {
  242. progressBar.setVisibility(View.VISIBLE);
  243. }
  244. restService.getNotifications(PAGE, LIMIT).enqueue(new Callback<NotificationResponse>() {
  245. @Override
  246. public void onResponse(Call<NotificationResponse> call, Response<NotificationResponse> response) {
  247. if (progressDialog != null && progressDialog.isShowing()) {
  248. progressDialog.dismiss();
  249. }
  250. progressBar.setVisibility(View.GONE);
  251. if (response.body() != null && response.body().getStatus() == 200) {
  252. TOTAL_RECORD = Integer.parseInt(response.body().getTotal());
  253. if (adapter == null) {
  254. MY_NOTIFICATIONS = response.body().getData();
  255. adapter = new NotificationAdapter(NotificationActivity.this, MY_NOTIFICATIONS,
  256. NotificationActivity.this, restService);
  257. notificationList.setAdapter(adapter);
  258. } else {
  259. MY_NOTIFICATIONS.addAll(response.body().getData());
  260. adapter.notifyDataSetChanged();
  261. }
  262. if (MY_NOTIFICATIONS.size() == 0) {
  263. notificationList.invokeState(EmptyStateRecyclerView.STATE_EMPTY);
  264. } else {
  265. notificationList.invokeState(EmptyStateRecyclerView.STATE_OK);
  266. }
  267. GlobalData.sdb.delete("notifications", null, null);
  268. Gson gson = new Gson();
  269. JsonElement jsonElement = gson.toJsonTree(
  270. MY_NOTIFICATIONS, new TypeToken<ArrayList<Notification>>() {
  271. }.getType());
  272. ContentValues values = new ContentValues();
  273. values.put("notifications", jsonElement.toString());
  274. GlobalData.sdb.insert("notifications", null, values);
  275. } else if (response.body() != null && response.body().getStatus() == 401) {
  276. GlobalData.canLogout = true;
  277. finish();
  278. } else if (response.body() != null) {
  279. GlobalData.showToast(getBaseContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
  280. } else if (response.errorBody() != null) {
  281. Gson gson = new Gson();
  282. ErrorResponse message = gson.fromJson(response.errorBody().charStream(), ErrorResponse.class);
  283. GlobalData.showToast(getBaseContext(), message.getMessage(), Toast.LENGTH_SHORT).show();
  284. if (message.getStatus() == 401) {
  285. GlobalData.canLogout = true;
  286. finish();
  287. }
  288. }
  289. new Handler().postDelayed(new Runnable() {
  290. @Override
  291. public void run() {
  292. if (getPreferences(MODE_PRIVATE).getBoolean("NotificationActivity", true)) {
  293. showHelpScreen();
  294. getPreferences(MODE_PRIVATE).edit().putBoolean("NotificationActivity", false).apply();
  295. }
  296. }
  297. }, 1000);
  298. }
  299. @Override
  300. public void onFailure(Call<NotificationResponse> call, Throwable t) {
  301. if (progressDialog != null && progressDialog.isShowing()) {
  302. progressDialog.dismiss();
  303. }
  304. progressBar.setVisibility(View.GONE);
  305. GlobalData.showToast(getBaseContext(), "Connection Failure, try again!", Toast.LENGTH_SHORT).show();
  306. }
  307. });
  308. } else {
  309. if (adapter == null) {
  310. Cursor cursor = GlobalData.sdb.rawQuery("select * from notifications", null);
  311. if (cursor.getCount() > 0) {
  312. cursor.moveToFirst();
  313. Gson gson = new Gson();
  314. MY_NOTIFICATIONS = gson.fromJson(
  315. cursor.getString(cursor.getColumnIndex("notifications")),
  316. new TypeToken<ArrayList<Notification>>() {
  317. }.getType());
  318. TOTAL_RECORD = MY_NOTIFICATIONS.size();
  319. adapter = new NotificationAdapter(NotificationActivity.this, MY_NOTIFICATIONS,
  320. NotificationActivity.this, restService);
  321. notificationList.setAdapter(adapter);
  322. } else {
  323. GlobalData.showToast(getBaseContext(), "Please check your internet connection", Toast.LENGTH_SHORT).show();
  324. }
  325. } else {
  326. GlobalData.showToast(getBaseContext(), "Please check your internet connection", Toast.LENGTH_SHORT).show();
  327. }
  328. }
  329. }
  330. private RecyclerView.OnScrollListener recyclerViewOnScrollListener = new RecyclerView.OnScrollListener() {
  331. @Override
  332. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  333. super.onScrollStateChanged(recyclerView, newState);
  334. }
  335. @Override
  336. public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  337. super.onScrolled(recyclerView, dx, dy);
  338. int visibleItemCount = linearLayoutManager.getChildCount();
  339. int totalItemCount = linearLayoutManager.getItemCount();
  340. int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
  341. if (progressBar.getVisibility() != View.VISIBLE) {
  342. if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
  343. && firstVisibleItemPosition >= 0
  344. && totalItemCount < TOTAL_RECORD && MY_NOTIFICATIONS.size() < TOTAL_RECORD) {
  345. PAGE++;
  346. getNotifications(false);
  347. }
  348. }
  349. }
  350. };
  351. @Override
  352. public void onPositionUpdate(int position) {
  353. }
  354. private void deleteNotification(int id) {
  355. Cursor cursor = GlobalData.sdb.rawQuery("select * from notification_deleted", null);
  356. String ids;
  357. if (cursor.getCount() > 0) {
  358. cursor.moveToFirst();
  359. ids = cursor.getString(cursor.getColumnIndex("notification_deleted"));
  360. ids = ids + "," + MY_NOTIFICATIONS.get(id).getId().trim();
  361. } else {
  362. ids = MY_NOTIFICATIONS.get(id).getId().trim();
  363. }
  364. adapter.remove(id);
  365. if (MY_NOTIFICATIONS.size() == 0) {
  366. notificationList.invokeState(EmptyStateRecyclerView.STATE_EMPTY);
  367. }
  368. GlobalData.sdb.delete("notification_deleted", null, null);
  369. ContentValues values1 = new ContentValues();
  370. values1.put("notification_deleted", ids);
  371. GlobalData.sdb.insert("notification_deleted", null, values1);
  372. GlobalData.sdb.delete("notifications", null, null);
  373. Gson gson = new Gson();
  374. JsonElement jsonElement = gson.toJsonTree(
  375. MY_NOTIFICATIONS, new TypeToken<ArrayList<Notification>>() {
  376. }.getType());
  377. ContentValues values = new ContentValues();
  378. values.put("notifications", jsonElement.toString());
  379. GlobalData.sdb.insert("notifications", null, values);
  380. if (new UtilService().isNetworkAvailable(NotificationActivity.this)) {
  381. HashMap<String, String> map = new HashMap<>();
  382. map.put("notificationid", ids);
  383. restService.updateDeleteNotifications(map)
  384. .enqueue(new MyCallback<ErrorResponse>(ids) {
  385. @Override
  386. public void onResponse(Call<ErrorResponse> call, Response<ErrorResponse> response) {
  387. if (response.body() != null && response.body().getStatus() == 200) {
  388. GlobalData.sdb.delete("notification_deleted", null, null);
  389. }
  390. try {
  391. new android.os.Handler(HomeActivity.badgeUpdateCallback).sendEmptyMessage(0);
  392. } catch (Exception e) {
  393. e.printStackTrace();
  394. }
  395. }
  396. @Override
  397. public void onFailure(Call<ErrorResponse> call, Throwable t) {
  398. GlobalData.showToast(NotificationActivity.this, "Connection Failure, try again!", Toast.LENGTH_SHORT).show();
  399. }
  400. });
  401. } else {
  402. try {
  403. new android.os.Handler(HomeActivity.badgeUpdateCallback).sendEmptyMessage(0);
  404. } catch (Exception e) {
  405. e.printStackTrace();
  406. }
  407. }
  408. }
  409. }