diff --git a/app/src/main/java/in/testpress/testpress/network/AppService.kt b/app/src/main/java/in/testpress/testpress/network/AppService.kt index c772d9173..16c1cd3f1 100644 --- a/app/src/main/java/in/testpress/testpress/network/AppService.kt +++ b/app/src/main/java/in/testpress/testpress/network/AppService.kt @@ -5,10 +5,11 @@ import `in`.testpress.network.TestpressApiClient import `in`.testpress.testpress.BuildConfig import `in`.testpress.testpress.core.Constants import `in`.testpress.testpress.models.InstituteSettings +import `in`.testpress.testpress.models.pojo.DashboardResponse import `in`.testpress.testpress.models.pojo.GenerateOTPResponse import `in`.testpress.testpress.models.pojo.OTPLoginResponse import android.content.Context -import retrofit.http.GET +import retrofit2.http.GET import retrofit2.http.Body import retrofit2.http.POST import kotlin.collections.HashMap @@ -17,6 +18,10 @@ const val OTP_URL = "/api/v2.5/auth/generate-otp/" const val VERIFY_OTP_URL = "/api/v2.5/auth/otp-login/" interface AppService { + + @GET("/api/v2.4/dashboard/") + fun getDashBoardData():RetrofitCall + @GET(Constants.Http.URL_INSTITUTE_SETTINGS_FRAG) fun getInstituteSettings(): RetrofitCall @@ -31,6 +36,10 @@ interface AppService { class AppNetwork(context: Context) : TestpressApiClient(BuildConfig.BASE_URL, context) { private fun getAppService() = retrofit.create(AppService::class.java) + fun getDashBoardData():RetrofitCall{ + return getAppService().getDashBoardData() + } + fun getInstituteSettings(): RetrofitCall { return getAppService().getInstituteSettings() } diff --git a/app/src/main/java/in/testpress/testpress/repository/DashBoardRepository.kt b/app/src/main/java/in/testpress/testpress/repository/DashBoardRepository.kt new file mode 100644 index 000000000..95950fb54 --- /dev/null +++ b/app/src/main/java/in/testpress/testpress/repository/DashBoardRepository.kt @@ -0,0 +1,46 @@ +package `in`.testpress.testpress.repository + +import `in`.testpress.network.NetworkBoundResource +import `in`.testpress.network.Resource +import `in`.testpress.network.RetrofitCall +import `in`.testpress.testpress.models.pojo.DashboardResponse +import `in`.testpress.testpress.network.AppNetwork +import `in`.testpress.testpress.util.PreferenceManager +import android.content.Context +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.google.gson.GsonBuilder + +class DashBoardRepository( + val context: Context +) { + private val service = AppNetwork(context) + + fun loadData(): LiveData> { + return object : NetworkBoundResource() { + + override fun loadFromDb(): LiveData { + val liveData = MutableLiveData() + liveData.postValue( + PreferenceManager.getDashboardDataPreferences(context) + ) + return liveData + } + + override fun saveNetworkResponseToDB(item: DashboardResponse) { + val gson = GsonBuilder().setPrettyPrinting().create() + val json = gson.toJson(item) + PreferenceManager.setDashboardData(context, json) + } + + override fun shouldFetch(data: DashboardResponse?): Boolean { + return true + } + + override fun createCall(): RetrofitCall { + return service.getDashBoardData() + } + }.asLiveData() + } + +} \ No newline at end of file diff --git a/app/src/main/java/in/testpress/testpress/ui/fragments/DashboardFragment.java b/app/src/main/java/in/testpress/testpress/ui/fragments/DashboardFragment.java index ce7482cd5..b728bb6c9 100644 --- a/app/src/main/java/in/testpress/testpress/ui/fragments/DashboardFragment.java +++ b/app/src/main/java/in/testpress/testpress/ui/fragments/DashboardFragment.java @@ -1,18 +1,12 @@ package in.testpress.testpress.ui.fragments; +import static in.testpress.testpress.BuildConfig.APPLICATION_ID; +import static in.testpress.testpress.util.PreferenceManager.getDashboardDataPreferences; + import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.loader.app.LoaderManager; -import androidx.loader.content.Loader; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -20,14 +14,19 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.loader.content.Loader; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.facebook.shimmer.ShimmerFrameLayout; -import com.github.kevinsawicki.wishlist.Toaster; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import javax.inject.Inject; @@ -40,18 +39,15 @@ import in.testpress.testpress.models.DaoSession; import in.testpress.testpress.models.pojo.DashboardResponse; import in.testpress.testpress.models.pojo.DashboardSection; +import in.testpress.testpress.repository.DashBoardRepository; import in.testpress.testpress.ui.ThrowableLoader; import in.testpress.testpress.ui.adapters.DashboardAdapter; +import in.testpress.testpress.viewmodel.DashBoardViewModel; import io.sentry.Sentry; import io.sentry.protocol.User; -import static in.testpress.testpress.BuildConfig.APPLICATION_ID; -import static in.testpress.testpress.util.PreferenceManager.getDashboardDataPreferences; -import static in.testpress.testpress.util.PreferenceManager.setDashboardData; - -public class DashboardFragment extends Fragment implements - LoaderManager.LoaderCallbacks { +public class DashboardFragment extends Fragment { private ArrayList sections = new ArrayList<>(); @InjectView(R.id.recycler_View) @@ -77,16 +73,23 @@ public class DashboardFragment extends Fragment implements private DaoSession daoSession; protected Exception exception; DashboardResponse dashboardResponse; - + private DashBoardViewModel viewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { Injector.inject(this); super.onCreate(savedInstanceState); - initLoader(); + initViewModel(); setUsernameInSentry(); } + private void initViewModel() { + viewModel = DashBoardViewModel.Companion.initializeViewModel( + this, + new DashBoardRepository(requireContext()) + ); + } + private void setUsernameInSentry() { AccountManager manager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE); Account[] account = manager.getAccountsByType(APPLICATION_ID); @@ -97,6 +100,14 @@ private void setUsernameInSentry() { } } + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Injector.inject(this); + getActivity().invalidateOptionsMenu(); + return inflater.inflate(R.layout.dashboard_view, null); + + } + @Override public void onViewCreated(final View view, final Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -106,6 +117,7 @@ public void onViewCreated(final View view, final Bundle savedInstanceState) { recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); swipeRefreshLayout.setEnabled(true); + showDataFromCacheIfAvailable(); addOnClickListeners(); } @@ -114,28 +126,10 @@ private void showDataFromCacheIfAvailable() { if (!getSections().isEmpty()) { adapter.setResponse(getDashboardDataPreferences(requireContext())); } else { - showLoading(); + loadData(); } } - private void showLoading() { - loadingPlaceholder.setVisibility(View.VISIBLE); - loadingPlaceholder.startShimmer(); - } - - private void hideShimmer() { - loadingPlaceholder.stopShimmer(); - loadingPlaceholder.setVisibility(View.GONE); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Injector.inject(this); - getActivity().invalidateOptionsMenu(); - return inflater.inflate(R.layout.dashboard_view, null); - - } - private void addOnClickListeners() { swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override @@ -157,46 +151,46 @@ public void onClick(View v) { public void refresh() { if (getActivity() != null) { - getLoaderManager().restartLoader(0, null, this); + loadData(); } } - private List getSections() { - return getDashboardDataPreferences(getContext()).getAvailableSections(); + private void loadData() { + viewModel.loadData().observe(getViewLifecycleOwner(), dashboard -> { + showLoadingImage(); + switch (dashboard.getStatus()) { + case SUCCESS: { + swipeRefreshLayout.setRefreshing(false); + adapter.setResponse(Objects.requireNonNull(dashboard.getData())); + hideShimmer(); + break; + } + case ERROR: { + hideShimmer(); + setEmptyText(); + break; + } + } + }); } - @NonNull - @Override - public Loader onCreateLoader(int id, @Nullable Bundle args) { - return new ThrowableLoader(getContext(), dashboardResponse) { + private void showLoadingImage() { + loadingPlaceholder.setVisibility(View.VISIBLE); + loadingPlaceholder.startShimmer(); + } - @Override - public DashboardResponse loadData() throws Exception { - try { - return serviceProvider.getService(getActivity()).getDashboardData(); - } catch (Exception exception) { - throw exception; - } - } - }; + private void hideShimmer() { + loadingPlaceholder.stopShimmer(); + loadingPlaceholder.setVisibility(View.GONE); } - @Override - public void onLoadFinished(@NonNull Loader loader, DashboardResponse data) { - final Exception exception = getException(loader); - swipeRefreshLayout.setRefreshing(false); - hideShimmer(); - if (exception != null) { - this.exception = exception; - getLoaderManager().destroyLoader(loader.getId()); - adapter.setResponse(getDashboardDataPreferences(getContext())); - return; - } - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String json = gson.toJson(data); - setDashboardData(getContext(), json); - adapter.setResponse(data); - adapter.notifyDataSetChanged(); + private void setEmptyText() { + setEmptyText(R.string.no_data_available, R.string.try_after_some_time, + R.drawable.ic_error_outline_black_18dp); + } + + private List getSections() { + return getDashboardDataPreferences(getContext()).getAvailableSections(); } @Override @@ -205,10 +199,6 @@ public void onResume() { refresh(); } - private void setEmptyText() { - setEmptyText(R.string.no_data_available, R.string.try_after_some_time, - R.drawable.ic_error_outline_black_18dp); - } protected int getErrorMessage(Exception exception) { if (exception instanceof IOException) { @@ -243,16 +233,4 @@ private void setEmptyText(final int title, final int description, final int icon retryButton.setVisibility(View.VISIBLE); } - @Override - public void onLoaderReset(@NonNull Loader loader) { - - } - - private void initLoader() { - if (firstCallback) { - getLoaderManager().initLoader(0, null, this); - firstCallback = false; - } - } - } diff --git a/app/src/main/java/in/testpress/testpress/viewmodel/DashBoardViewModel.kt b/app/src/main/java/in/testpress/testpress/viewmodel/DashBoardViewModel.kt new file mode 100644 index 000000000..c7b073647 --- /dev/null +++ b/app/src/main/java/in/testpress/testpress/viewmodel/DashBoardViewModel.kt @@ -0,0 +1,31 @@ +package `in`.testpress.testpress.viewmodel + +import `in`.testpress.network.Resource +import `in`.testpress.testpress.models.pojo.DashboardResponse +import `in`.testpress.testpress.repository.DashBoardRepository +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelStoreOwner + + +class DashBoardViewModel( + private val dashBoardRepository: DashBoardRepository +) : ViewModel() { + + fun loadData(): LiveData> { + return dashBoardRepository.loadData() + } + + companion object { + fun initializeViewModel(owner: ViewModelStoreOwner, repository: DashBoardRepository):DashBoardViewModel{ + return ViewModelProvider(owner, object : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + return DashBoardViewModel(repository) as T + } + }).get(DashBoardViewModel::class.java) + } + } + +} +