/*
* Mr.Mantou - On the importance of taste
* Copyright (C) 2015-2016 XiNGRZ <xxx@oxo.ooo>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ooo.oxo.mr;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.SharedElementCallback;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;
import com.jakewharton.rxbinding.support.v4.widget.RxSwipeRefreshLayout;
import com.trello.rxlifecycle.components.support.RxAppCompatActivity;
import com.umeng.analytics.MobclickAgent;
import java.util.List;
import java.util.Map;
import ooo.oxo.mr.databinding.MainActivityBinding;
import ooo.oxo.mr.model.Image;
import ooo.oxo.mr.rx.RxAVQuery;
import ooo.oxo.mr.rx.RxList;
import ooo.oxo.mr.util.ToastUtil;
import ooo.oxo.mr.util.UpdateUtil;
import ooo.oxo.mr.view.MiuiStatusBarCompat;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MainActivity extends RxAppCompatActivity implements MainAdapter.Listener {
private static final String TAG = "MainActivity";
private ObservableArrayList<Image> images;
private MainActivityBinding binding;
private Bundle reenterState;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MiuiStatusBarCompat.enableLightStatusBar(getWindow());
binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
setSupportActionBar(binding.toolbar);
images = MrSharedState.getInstance().getImages();
Glide.get(this).setMemoryCategory(MemoryCategory.HIGH);
binding.content.setAdapter(new MainAdapter(this, images, Glide.with(this), this));
setExitSharedElementCallback(new SharedElementCallback() {
@Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
if (reenterState != null) {
int index = reenterState.getInt("index", 0);
Image image = images.get(index);
MainAdapter.ViewHolder holder = (MainAdapter.ViewHolder) binding.content
.findViewHolderForLayoutPosition(index);
sharedElements.clear();
if (holder != null && holder.binding != null) {
sharedElements.put(String.format("%s.image", image.getObjectId()), holder.binding.image);
}
reenterState = null;
}
}
});
Observable<List<Image>> load = Observable.just(images)
.doOnSubscribe(() -> binding.refresher.setRefreshing(true))
.doOnCompleted(() -> binding.refresher.setRefreshing(false))
.map(whatever -> images.isEmpty() ? Image.all() : Image.since(images.get(0)))
.observeOn(Schedulers.io())
.flatMap(RxAVQuery::find)
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(RxList.prependTo(images));
RxSwipeRefreshLayout.refreshes(binding.refresher)
.compose(bindToLifecycle())
.flatMap(whatever -> load)
.retry((count, tr) -> {
Log.e(TAG, "An error occurred while fetching images", tr);
ToastUtil.shorts(this, tr.getMessage());
binding.refresher.setRefreshing(false);
return true;
})
.filter(loaded -> !loaded.isEmpty())
.subscribe(loaded -> binding.content.smoothScrollToPosition(0));
load.compose(bindToLifecycle())
.onErrorReturn(tr -> {
Log.e(TAG, "An error occurred while fetching images", tr);
ToastUtil.shorts(this, tr.getMessage());
binding.refresher.setRefreshing(false);
return null;
})
.subscribe();
UpdateUtil.checkForUpdate(version -> UpdateUtil.promptUpdate(this, version));
}
@Override
protected void onDestroy() {
super.onDestroy();
binding.content.setAdapter(null);
}
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
@Override
public void onImageClick(MainAdapter.ViewHolder holder) {
final Image image = images.get(holder.getLayoutPosition());
final Intent intent = new Intent(this, ViewerActivity.class);
intent.putExtra("index", holder.getAdapterPosition());
intent.putExtra("thumbnail", image.getUrl(holder.binding.image.getWidth()));
final ActivityOptionsCompat options;
if (Build.VERSION.SDK_INT >= 21) {
options = ActivityOptionsCompat.makeSceneTransitionAnimation(
this, holder.binding.image, String.format("%s.image", image.getObjectId()));
} else {
options = ActivityOptionsCompat.makeScaleUpAnimation(
holder.itemView, 0, 0, holder.itemView.getWidth(), holder.itemView.getHeight());
}
startActivity(intent, options.toBundle());
}
@Override
public void onActivityReenter(int resultCode, Intent data) {
super.onActivityReenter(resultCode, data);
supportPostponeEnterTransition();
reenterState = new Bundle(data.getExtras());
binding.content.scrollToPosition(reenterState.getInt("index", 0));
binding.content.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
binding.content.getViewTreeObserver().removeOnPreDrawListener(this);
supportStartPostponedEnterTransition();
return true;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
startActivity(new Intent(this, AboutActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}