Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Used repository pattern in dashboard fragment #218

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion app/src/main/java/in/testpress/testpress/network/AppService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<DashboardResponse>

@GET(Constants.Http.URL_INSTITUTE_SETTINGS_FRAG)
fun getInstituteSettings(): RetrofitCall<InstituteSettings>

Expand All @@ -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<DashboardResponse>{
return getAppService().getDashBoardData()
}

fun getInstituteSettings(): RetrofitCall<InstituteSettings> {
return getAppService().getInstituteSettings()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Resource<DashboardResponse>> {
return object : NetworkBoundResource<DashboardResponse, DashboardResponse>() {

override fun loadFromDb(): LiveData<DashboardResponse> {
val liveData = MutableLiveData<DashboardResponse>()
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<DashboardResponse> {
return service.getDashBoardData()
}
}.asLiveData()
}

}
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
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;
import android.widget.Button;
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;

Expand All @@ -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<DashboardResponse> {
public class DashboardFragment extends Fragment {

private ArrayList<String> sections = new ArrayList<>();
@InjectView(R.id.recycler_View)
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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();
}
Expand All @@ -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
Expand All @@ -157,46 +151,46 @@ public void onClick(View v) {

public void refresh() {
if (getActivity() != null) {
getLoaderManager().restartLoader(0, null, this);
loadData();
}
}

private List<DashboardSection> 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<DashboardResponse> onCreateLoader(int id, @Nullable Bundle args) {
return new ThrowableLoader<DashboardResponse>(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<DashboardResponse> 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<DashboardSection> getSections() {
return getDashboardDataPreferences(getContext()).getAvailableSections();
}

@Override
Expand All @@ -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) {
Expand Down Expand Up @@ -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<DashboardResponse> loader) {

}

private void initLoader() {
if (firstCallback) {
getLoaderManager().initLoader(0, null, this);
firstCallback = false;
}
}

}
Original file line number Diff line number Diff line change
@@ -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<Resource<DashboardResponse>> {
return dashBoardRepository.loadData()
}

companion object {
fun initializeViewModel(owner: ViewModelStoreOwner, repository: DashBoardRepository):DashBoardViewModel{
return ViewModelProvider(owner, object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return DashBoardViewModel(repository) as T
}
}).get(DashBoardViewModel::class.java)
}
}

}