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

Supports Issuing Estimates #15

Merged
merged 8 commits into from
Nov 17, 2017
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.learningmachine.android.app.data.error.IssuerAnalyticsException;
import com.learningmachine.android.app.data.model.IssuerRecord;
import com.learningmachine.android.app.data.model.IssuingEstimate;
import com.learningmachine.android.app.data.store.IssuerStore;
import com.learningmachine.android.app.data.webservice.IssuerService;
import com.learningmachine.android.app.data.webservice.request.IssuerAnalytic;
Expand Down Expand Up @@ -56,6 +57,10 @@ public Observable<IssuerResponse> fetchIssuer(String url) {
return mIssuerService.getIssuer(url);
}

public Observable<List<IssuingEstimate>> getIssuingEstimates(String issuingEstimateURL, String key) {
return mIssuerService.getIssuingEstimates(issuingEstimateURL, key);
}

public Observable<String> addIssuer(IssuerIntroductionRequest request) {
IssuerResponse issuer = request.getIssuerResponse();
return mIssuerService.postIntroduction(issuer.getIntroUrl(), request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ public class IssuerRecord {

private String mRecipientPubKey;

public IssuerRecord(String name, String email, String uuid, String certsUrl, String introUrl, String introducedOn, String analyticsUrlString, String recipientPubKey) {
public IssuerRecord(String name,
String email,
String uuid,
String certsUrl,
String introUrl,
String introducedOn,
String analyticsUrlString,
String recipientPubKey) {
mName = name;
mEmail = email;
mUuid = uuid;
Expand Down Expand Up @@ -98,7 +105,6 @@ public void setRevocationKeys(List<KeyRotation> revocationKeys) {
mRevocationKeys = revocationKeys;
}


/** Image filename, created with the md5 of mUuid*/
public String getImageFilename() {
return ImageUtils.getImageFilename(mUuid);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.learningmachine.android.app.data.model;

import com.google.gson.annotations.SerializedName;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

import java.text.SimpleDateFormat;
import java.util.AbstractMap;

/**
* Created by chris on 11/16/17.
*/

public class IssuingEstimate {
@SerializedName("title")
private String mTitle;

@SerializedName("willIssueOn")
private String mWillIssueOn;

public String getTitle() { return mTitle; }
public String getWillIssueOn() { return mWillIssueOn; }
public String getEstimateDescription() {
DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime();
DateTime estimateDate = dateTimeFormatter.parseDateTime(mWillIssueOn);

SimpleDateFormat format = new SimpleDateFormat("MMMM dd, yyyy");
return "📅 Scheduled for " + format.format(estimateDate.toDate());
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.learningmachine.android.app.data.webservice;

import com.learningmachine.android.app.data.model.IssuingEstimate;
import com.learningmachine.android.app.data.webservice.request.IssuerAnalytic;
import com.learningmachine.android.app.data.webservice.request.IssuerIntroductionRequest;
import com.learningmachine.android.app.data.webservice.response.IssuerResponse;

import java.util.List;

import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.http.Url;
import rx.Observable;

Expand All @@ -19,4 +23,7 @@ public interface IssuerService {

@POST
Observable<Void> postIssuerAnalytics(@Url String url, @Body IssuerAnalytic issuerAnalytic);

@GET
Observable<List<IssuingEstimate>> getIssuingEstimates(@Url String url, @Query("key") String key);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

public class IssuerResponse extends IssuerRecord {
private static final String WEB_AUTH_METHOD = "web";
private static final String ISSUING_ESTIMATE_UNSIGNED = "unsigned";

@SerializedName("image")
private String mImageData;
Expand All @@ -20,6 +21,11 @@ public class IssuerResponse extends IssuerRecord {
@SerializedName("introductionErrorURL")
private String mIntroductionErrorUrlString;

@SerializedName("issuingEstimateURL")
private String mIssuingEstimateUrlString;
@SerializedName("issuingEstimateAuth")
private String mIssuingEstimateAuth;

public IssuerResponse(String name, String email, String uuid, String certsUrl, String introUrl, String introducedOn, String imageData, String analyticsUrlString) {
super(name, email, uuid, certsUrl, introUrl, introducedOn, analyticsUrlString, null);
mImageData = imageData;
Expand Down Expand Up @@ -58,4 +64,8 @@ public String getIntroductionSuccessUrlString() {
public String getIntroductionErrorUrlString() {
return mIntroductionErrorUrlString;
}

public String getIssuingEstimateUrlString() { return mIssuingEstimateUrlString; }

public boolean usesUnsignedIssuingEstimateRequests() { return ISSUING_ESTIMATE_UNSIGNED.equals(mIssuingEstimateAuth); }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,49 @@
import android.databinding.Bindable;

import com.learningmachine.android.app.data.model.CertificateRecord;
import com.learningmachine.android.app.data.model.IssuingEstimate;

public class CertificateListItemViewModel extends BaseObservable {

private CertificateRecord mCertificate;
private IssuingEstimate mEstimate;

@Bindable
public String getTitle() {
if (mCertificate == null) {
return null;
if (mEstimate == null) {
return null;
}
return mEstimate.getTitle();
}
return mCertificate.getName();
}

@Bindable
public String getDescription() {
if (mCertificate == null) {
return null;
if (mEstimate == null) {
return null;
}
return mEstimate.getEstimateDescription();
}
return mCertificate.getDescription();
}

public void bindCertificate(CertificateRecord certificate) {
mCertificate = certificate;
mEstimate = null;
notifyChange();
}

public void bindEstimate(IssuingEstimate estimate) {
mCertificate = null;
mEstimate = estimate;
notifyChange();
}

public CertificateRecord getCertificate() {
return mCertificate;
}
public IssuingEstimate getIssuingEstimate() { return mEstimate; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.view.View;

import com.learningmachine.android.app.data.model.CertificateRecord;
import com.learningmachine.android.app.data.model.IssuingEstimate;
import com.learningmachine.android.app.databinding.ListItemCertificateBinding;
import com.learningmachine.android.app.ui.cert.CertificateActivity;

Expand All @@ -28,6 +29,10 @@ public CertificateViewHolder(ListItemCertificateBinding binding) {
@Override
public void onClick(View v) {
CertificateRecord certificate = mViewModel.getCertificate();
if (certificate == null) {
return;
}

Context context = mBinding.getRoot()
.getContext();
String certUuid = certificate.getUuid();
Expand All @@ -39,4 +44,9 @@ public void bind(CertificateRecord certificate) {
mViewModel.bindCertificate(certificate);
mBinding.executePendingBindings();
}

public void bind(IssuingEstimate estimate) {
mViewModel.bindEstimate(estimate);
mBinding.executePendingBindings();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
Expand All @@ -16,8 +17,12 @@

import com.learningmachine.android.app.R;
import com.learningmachine.android.app.data.CertificateManager;
import com.learningmachine.android.app.data.IssuerManager;
import com.learningmachine.android.app.data.inject.Injector;
import com.learningmachine.android.app.data.model.CertificateRecord;
import com.learningmachine.android.app.data.model.IssuerRecord;
import com.learningmachine.android.app.data.model.IssuingEstimate;
import com.learningmachine.android.app.data.webservice.response.IssuerResponse;
import com.learningmachine.android.app.databinding.FragmentIssuerBinding;
import com.learningmachine.android.app.databinding.ListItemCertificateBinding;
import com.learningmachine.android.app.ui.LMFragment;
Expand All @@ -28,17 +33,21 @@

import javax.inject.Inject;

import rx.Observable;
import timber.log.Timber;

public class IssuerFragment extends LMFragment {

private static final String ARG_ISSUER_UUID = "IssuerFragment.IssuerUuid";

@Inject protected CertificateManager mCertificateManager;
@Inject protected IssuerManager mIssuerManager;

private String mIssuerUuid;
private FragmentIssuerBinding mBinding;

private List<CertificateRecord> mCertificateList;
private List<IssuingEstimate> mEstimateList;

public static IssuerFragment newInstance(String issuerUuid) {
Bundle args = new Bundle();
Expand All @@ -59,6 +68,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {

mIssuerUuid = getArguments().getString(ARG_ISSUER_UUID);
mCertificateList = new ArrayList<>();
mEstimateList = new ArrayList<>();
}

@Nullable
Expand Down Expand Up @@ -101,10 +111,24 @@ public void onResume() {
mCertificateManager.getCertificatesForIssuer(mIssuerUuid)
.compose(bindToMainThread())
.subscribe(this::updateRecyclerView, throwable -> Timber.e(throwable, "Unable to load certificates"));

Observable.zip(mIssuerManager.getIssuer(mIssuerUuid),
mIssuerManager.fetchIssuer(mIssuerUuid),
(record, response) -> {
response.setRecipientPubKey(record.getRecipientPubKey());
return response;
})
.subscribe(this::fetchIssuingEstimates);
}

private void fetchIssuingEstimates(IssuerResponse issuerResponse) {
mIssuerManager.getIssuingEstimates(issuerResponse.getIssuingEstimateUrlString(), issuerResponse.getRecipientPubKey())
.compose(bindToMainThread())
.subscribe(this::updateRecyclerViewWithEstimates);
}

private void setupRecyclerView() {
CertificateAdapter adapter = new CertificateAdapter(mCertificateList);
CertificateAdapter adapter = new CertificateAdapter(mCertificateList, mEstimateList);
mBinding.certificateRecyclerView.setAdapter(adapter);

RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
Expand All @@ -118,12 +142,19 @@ private void updateRecyclerView(List<CertificateRecord> certificateList) {
.notifyDataSetChanged();
}

private class CertificateAdapter extends RecyclerView.Adapter<CertificateViewHolder> {
private void updateRecyclerViewWithEstimates(List<IssuingEstimate> estimateList) {
mEstimateList.clear();
mEstimateList.addAll(estimateList);
mBinding.certificateRecyclerView.getAdapter().notifyDataSetChanged();
}

private class CertificateAdapter extends RecyclerView.Adapter<CertificateViewHolder> {
private List<CertificateRecord> mCertificateList;
private List<IssuingEstimate> mEstimateList;

CertificateAdapter(List<CertificateRecord> certificateList) {
CertificateAdapter(List<CertificateRecord> certificateList, List<IssuingEstimate> estimateList) {
mCertificateList = certificateList;
mEstimateList = estimateList;
}

@Override
Expand All @@ -139,13 +170,19 @@ public CertificateViewHolder onCreateViewHolder(ViewGroup parent, int viewType)

@Override
public void onBindViewHolder(CertificateViewHolder holder, int position) {
CertificateRecord certificate = mCertificateList.get(position);
holder.bind(certificate);
if (position < mEstimateList.size()) {
IssuingEstimate estimate = mEstimateList.get(position);
holder.bind(estimate);
} else {
position -= mEstimateList.size();
CertificateRecord certificate = mCertificateList.get(position);
holder.bind(certificate);
}
}

@Override
public int getItemCount() {
return mCertificateList.size();
return mEstimateList.size() + mCertificateList.size();
}
}
}