package treehou.se.habit.ui.servers; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import com.trello.rxlifecycle.components.support.RxFragment; import javax.inject.Inject; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import butterknife.Unbinder; import io.realm.Realm; import io.realm.RealmResults; import rx.functions.Action1; import treehou.se.habit.HabitApplication; import treehou.se.habit.R; import treehou.se.habit.core.db.model.ServerDB; import treehou.se.habit.ui.inbox.InboxListFragment; import treehou.se.habit.ui.adapter.ServersAdapter; import treehou.se.habit.ui.bindings.BindingsFragment; import treehou.se.habit.util.Settings; public class ServersFragment extends RxFragment { private static final String TAG = "ServersFragment"; private ViewGroup container; @BindView(R.id.list) RecyclerView lstServer; @BindView(R.id.empty) View viwEmpty; @BindView(R.id.fab_add) FloatingActionButton fabAdd; @Inject Settings settings; private ServersAdapter serversAdapter; private RealmResults<ServerDB> servers; private Unbinder unbinder; private Realm realm; public static ServersFragment newInstance() { ServersFragment fragment = new ServersFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } public ServersFragment() {} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getApplicationComponent().inject(this); realm = Realm.getDefaultInstance(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { this.container = container; View rootView = inflater.inflate(R.layout.fragment_servers, container, false); unbinder = ButterKnife.bind(this, rootView); GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1); lstServer.setLayoutManager(gridLayoutManager); lstServer.setItemAnimator(new DefaultItemAnimator()); setupActionbar(); return rootView; } protected HabitApplication.ApplicationComponent getApplicationComponent() { return ((HabitApplication) getContext().getApplicationContext()).component(); } @Override public void onResume() { super.onResume(); setupAdapter(); } @Override public void onPause() { super.onPause(); lstServer.setAdapter(null); } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); } @Override public void onDestroy() { super.onDestroy(); realm.close(); } /** * Hookup actionbar */ private void setupActionbar(){ ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); if(actionBar != null) { actionBar.setTitle(R.string.servers); } setHasOptionsMenu(true); } /** * Hookup server list, listening for server updates. */ private void setupAdapter(){ realm.where(ServerDB.class).findAllAsync().asObservable() .compose(this.bindToLifecycle()) .subscribe(servers1 -> { Log.d(TAG, "Loaded " + servers1.size() + " servers"); ServersFragment.this.servers = servers1; updateEmptyView(servers1.size()); serversAdapter = new ServersAdapter(getContext(), servers1); serversAdapter.setItemListener(serverListener); lstServer.setAdapter(serversAdapter); }); if(!settings.getServerSetupAsked()){ showScanServerFlow(); } } /** * Launch flow for opening server scanning. */ private void showScanServerFlow() { settings.setServerSetupAsked(true); new AlertDialog.Builder(getActivity()) .setMessage(R.string.start_scan_question) .setNeutralButton(R.string.new_server, (dialog, which) -> startNewServerFlow()) .setPositiveButton(R.string.scan, (dialog, which) -> openServerScan()) .setNegativeButton(R.string.cancel, null) .show(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.servers, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_scan_for_server: openServerScan(); break; } return super.onOptionsItemSelected(item); } private ServersAdapter.ItemListener serverListener = new ServersAdapter.ItemListener() { @Override public void onItemClickListener(ServersAdapter.ServerHolder serverHolder) { final ServerDB server = serversAdapter.getItem(serverHolder.getAdapterPosition()); openServerPage(server); } /** * Open page for editing server. * @param server the server to open page for. */ private void openServerPage(ServerDB server){ getActivity().getSupportFragmentManager().beginTransaction() .replace(R.id.page_container, ServerMenuFragment.newInstance(server.getId())) .addToBackStack(null) .commit(); } @Override public boolean onItemLongClickListener(final ServersAdapter.ServerHolder serverHolder) { final ServerDB server = serversAdapter.getItem(serverHolder.getAdapterPosition()); showRemoveDialog(serverHolder, server); return true; } }; /** * Launch flow for creating new server. */ @OnClick({R.id.empty, R.id.fab_add}) public void startNewServerFlow(){ getActivity().getSupportFragmentManager().beginTransaction() .replace(R.id.page_container, SetupServerFragment.newInstance()) .addToBackStack(null) .commit(); } /** * Launch flow used to scan for server on network. */ private void openServerScan(){ getActivity().getSupportFragmentManager().beginTransaction() .replace(R.id.page_container, ScanServersFragment.newInstance()) .addToBackStack(null) .commit(); } /** * Launchs flow asking user to remove or keep server. * @param serverHolder holder that triggered flow. * @param server the server to remove. */ private void showRemoveDialog(final ServersAdapter.ServerHolder serverHolder, final ServerDB server){ new AlertDialog.Builder(getActivity()) .setMessage(R.string.remove_server_question) .setPositiveButton(R.string.ok, (dialog, which) -> { realm.beginTransaction(); int position = serverHolder.getAdapterPosition(); int i = servers.indexOf(server); if(i >= 0) { servers.deleteFromRealm(i);} realm.commitTransaction(); serversAdapter.notifyItemRemoved(position); }) .setNegativeButton(R.string.cancel, null) .show(); } /** * Show empty view if no controllers exist */ private void updateEmptyView(int itemCount){ viwEmpty.setVisibility(itemCount <= 0 ? View.VISIBLE : View.GONE); } }