package com.kelin.mvvmlight.zhihu.newsdetail;
import android.app.Activity;
import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import com.kelin.mvvmlight.base.ViewModel;
import com.kelin.mvvmlight.command.ReplyCommand;
import com.kelin.mvvmlight.zhihu.retrofit.RetrofitProvider;
import com.kelin.mvvmlight.zhihu.retrofit.ToStringConverter;
import com.trello.rxlifecycle.ActivityLifecycleProvider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import rx.Notification;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Created by kelin on 16-4-28.
*/
public class NewsDetailViewModel implements ViewModel {
//context
private Activity activity;
/**
* Model
* data source for ViewModel
*/
private NewsDetailService.NewsDetail newsDetail;
/**
* ViewStyle
* collection of view style
*/
public class ViewStyle {
public final ObservableBoolean isRefreshing = new ObservableBoolean(true);
public final ObservableBoolean progressRefreshing = new ObservableBoolean(true);
}
//data
public final ObservableField<String> imageUrl = new ObservableField<>();
public final ObservableField<String> html = new ObservableField<>();
public final ObservableField<String> title = new ObservableField<>();
public final ViewStyle viewStyle = new ViewStyle();
//command
public final ReplyCommand onRefreshCommand = new ReplyCommand<>(() -> {
viewStyle.isRefreshing.set(true);
viewStyle.progressRefreshing.set(false);
loadData(newsDetail.getId());
});
public NewsDetailViewModel(Activity activity, long id) {
this.activity = activity;
loadData(id);
}
private void loadData(long id) {
Observable<Notification<NewsDetailService.NewsDetail>> newsDetailOb =
RetrofitProvider.getInstance().create(NewsDetailService.class)
.getNewsDetail(id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(((ActivityLifecycleProvider) activity).bindToLifecycle())
.materialize().share();
newsDetailOb.filter(Notification::isOnNext)
.map(n -> n.getValue())
.doOnNext(m -> newsDetail = m)
.subscribe(m -> loadHtmlCss(m.getCss()));
}
private void loadHtmlCss(List<String> urls) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://news-at.zhihu.com/")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(new Converter.Factory() {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new ToStringConverter();
}
}).build();
Observable.from(urls)
.flatMap(s -> retrofit
.create(NewsDetailCssService.class)
.getNewsDetailCss(s)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(((ActivityLifecycleProvider) activity).bindToLifecycle())
.materialize().share().filter(Notification::isOnNext).map(n -> n.getValue()))
.scan((s1, s2) -> s1 + s2)
.last()
.doOnNext(s -> newsDetail.setCssStr(s))
.doAfterTerminate(() -> viewStyle.progressRefreshing.set(false))
.subscribe(s -> initViewModelField());
}
private void initViewModelField() {
viewStyle.isRefreshing.set(false);
imageUrl.set(newsDetail.getImage());
Observable.just(newsDetail.getBody())
.map(s -> s + "<style type=\"text/css\">" + newsDetail.getCssStr())
.map(s -> s + "</style>")
.subscribe(s -> html.set(s));
title.set(newsDetail.getTitle());
}
}