/**
* Copyright (C) 2016 eBusiness Information
*
* This file is part of OSM Contributor.
*
* OSM Contributor 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.
*
* OSM Contributor 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 OSM Contributor. If not, see <http://www.gnu.org/licenses/>.
*/
package io.jawg.osmcontributor.ui.activities;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.jawg.osmcontributor.OsmTemplateApplication;
import io.jawg.osmcontributor.R;
import io.jawg.osmcontributor.model.events.PleaseLoadPoisToUpdateEvent;
import io.jawg.osmcontributor.model.events.PleaseRevertPoiEvent;
import io.jawg.osmcontributor.model.events.PleaseRevertPoiNodeRefEvent;
import io.jawg.osmcontributor.model.events.PoisToUpdateLoadedEvent;
import io.jawg.osmcontributor.rest.events.PleaseUploadPoiChangesByIdsEvent;
import io.jawg.osmcontributor.rest.events.SyncFinishUploadPoiEvent;
import io.jawg.osmcontributor.rest.events.error.SyncConflictingNodeErrorEvent;
import io.jawg.osmcontributor.rest.events.error.SyncConnectionLostErrorEvent;
import io.jawg.osmcontributor.rest.events.error.SyncNewNodeErrorEvent;
import io.jawg.osmcontributor.rest.events.error.SyncUnauthorizedEvent;
import io.jawg.osmcontributor.rest.events.error.SyncUploadNoteRetrofitErrorEvent;
import io.jawg.osmcontributor.rest.events.error.SyncUploadRetrofitErrorEvent;
import io.jawg.osmcontributor.ui.adapters.PoisAdapter;
import io.jawg.osmcontributor.ui.managers.tutorial.SyncTutoManager;
import io.jawg.osmcontributor.ui.managers.tutorial.TutorialManager;
import io.jawg.osmcontributor.utils.OsmAnswers;
import io.jawg.osmcontributor.utils.helper.SwipeItemTouchHelperCallback;
import io.jawg.osmcontributor.utils.upload.PoiUpdateWrapper;
public class UploadActivity extends AppCompatActivity implements PoisAdapter.OnItemRemovedListener {
/*=========================================*/
/*---------------INJECTIONS----------------*/
/*=========================================*/
@BindView(R.id.comment_edit_text)
EditText editTextComment;
@BindView(R.id.no_value_text)
TextView noValues;
@BindView(R.id.poi_list)
RecyclerView poisListView;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.coordinatorLayout)
CoordinatorLayout coordinatorLayout;
@Inject
EventBus eventBus;
/*=========================================*/
/*---------------ATTRIBUTES----------------*/
/*=========================================*/
private List<PoiUpdateWrapper> poisWrapper = new ArrayList<>();
private PoisAdapter adapter;
private ProgressDialog ringProgressDialog;
private boolean isCanceled;
private SyncTutoManager syncTutoManager;
/*=========================================*/
/*----------------OVERRIDE-----------------*/
/*=========================================*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload);
((OsmTemplateApplication) getApplication()).getOsmTemplateComponent().inject(this);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
OsmAnswers.visitedActivity("Page de synchronisation");
adapter = new PoisAdapter(this, poisWrapper);
adapter.setOnStartSwipeListener(this);
poisListView.setAdapter(adapter);
poisListView.setLayoutManager(new LinearLayoutManager(this));
syncTutoManager = new SyncTutoManager(this, TutorialManager.forceDisplaySyncTuto);
ItemTouchHelper.Callback callback = new SwipeItemTouchHelperCallback(adapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(poisListView);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
syncTutoManager.launchTuto(poisListView.getChildAt(0).findViewById(R.id.revert), findViewById(R.id.comment_edit_text), findViewById(R.id.action_confirm));
}
}, 500);
}
@Override
protected void onResume() {
super.onResume();
eventBus.register(this);
eventBus.post(new PleaseLoadPoisToUpdateEvent());
}
@Override
protected void onPause() {
eventBus.unregister(this);
super.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_upload, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
return true;
}
if (id == R.id.action_confirm) {
if (poisWrapper.size() == 0) {
Toast.makeText(this, R.string.nothing_to_update, Toast.LENGTH_SHORT).show();
return true;
}
if (!adapter.changedSelected()) {
Toast.makeText(this, R.string.nothing_selected, Toast.LENGTH_SHORT).show();
return true;
}
String comment = editTextComment.getText().toString();
if (!comment.isEmpty()) {
eventBus.post(new PleaseUploadPoiChangesByIdsEvent(comment, adapter.getPoiToUpload(), adapter.getPoiNodeRefToUpload()));
ringProgressDialog = ProgressDialog.show(this, null, getString(R.string.saving), true);
ringProgressDialog.setCancelable(true);
} else {
Toast.makeText(this, R.string.need_a_comment, Toast.LENGTH_SHORT).show();
}
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onItemRemoved(final PoiUpdateWrapper removedItem, final int position) {
final Snackbar snackbar = Snackbar.make(coordinatorLayout, getString(R.string.revert_snack_bar), Snackbar.LENGTH_SHORT);
snackbar.setAction(getString(R.string.undo_snack_bar), new View.OnClickListener() {
@Override
public void onClick(View v) {
isCanceled = true;
snackbar.dismiss();
adapter.insert(position, removedItem);
poisListView.smoothScrollToPosition(position);
}
});
snackbar.setCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar snackbar, int action) {
super.onDismissed(snackbar, action);
if (!isCanceled && (action == DISMISS_EVENT_TIMEOUT || action == DISMISS_EVENT_CONSECUTIVE || action == DISMISS_EVENT_SWIPE || action == DISMISS_EVENT_MANUAL)) {
if (removedItem.getIsPoi()) {
eventBus.post(new PleaseRevertPoiEvent(removedItem.getId()));
} else {
eventBus.post(new PleaseRevertPoiNodeRefEvent(removedItem.getId()));
}
}
}
});
snackbar.show();
}
/*=========================================*/
/*-----------------EVENTS------------------*/
/*=========================================*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void onPoisToUpdateLoadedEvent(PoisToUpdateLoadedEvent event) {
poisWrapper.clear();
poisWrapper.addAll(event.getPoiUpdateWrappers());
adapter.notifyDataSetChanged();
if (event.getPoiUpdateWrappers().size() == 0) {
poisListView.setVisibility(View.GONE);
noValues.setVisibility(View.VISIBLE);
finish();
} else {
poisListView.setVisibility(View.VISIBLE);
noValues.setVisibility(View.GONE);
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncFinishUploadPoiEvent(SyncFinishUploadPoiEvent event) {
String result;
if (event.getSuccessfullyAddedPoisCount() > 0) {
result = getResources().getQuantityString(R.plurals.add_done,
event.getSuccessfullyAddedPoisCount(), event.getSuccessfullyAddedPoisCount());
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
resultReceived();
}
if (event.getSuccessfullyUpdatedPoisCount() > 0) {
result = getResources().getQuantityString(R.plurals.update_done,
event.getSuccessfullyUpdatedPoisCount(), event.getSuccessfullyUpdatedPoisCount());
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
resultReceived();
}
if (event.getSuccessfullyDeletedPoisCount() > 0) {
result = getResources().getQuantityString(R.plurals.delete_done,
event.getSuccessfullyDeletedPoisCount(), event.getSuccessfullyDeletedPoisCount());
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
resultReceived();
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncUnauthorizedEvent(SyncUnauthorizedEvent event) {
Toast.makeText(this, R.string.couldnt_connect_retrofit, Toast.LENGTH_LONG).show();
resultReceived();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncConflictingNodeErrorEvent(SyncConflictingNodeErrorEvent event) {
Toast.makeText(this, R.string.couldnt_update_node, Toast.LENGTH_LONG).show();
resultReceived();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncNewNodeErrorEvent(SyncNewNodeErrorEvent event) {
Toast.makeText(this, R.string.couldnt_create_node, Toast.LENGTH_LONG).show();
resultReceived();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncUploadRetrofitErrorEvent(SyncUploadRetrofitErrorEvent event) {
Toast.makeText(this, R.string.couldnt_upload_retrofit, Toast.LENGTH_SHORT).show();
resultReceived();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncUploadNoteRetrofitErrorEvent(SyncUploadNoteRetrofitErrorEvent event) {
Toast.makeText(this, R.string.couldnt_upload_retrofit, Toast.LENGTH_SHORT).show();
resultReceived();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncConnectionLostErrorEvent(SyncConnectionLostErrorEvent event) {
Toast.makeText(this, R.string.couldnt_save_connectivity, Toast.LENGTH_SHORT).show();
resultReceived();
}
/*=========================================*/
/*--------------PRIVATE CODE---------------*/
/*=========================================*/
private void resultReceived() {
ringProgressDialog.cancel();
//get all pois not updated
eventBus.post(new PleaseLoadPoisToUpdateEvent());
editTextComment.setText("");
}
}