package treehou.se.habit.ui.servers; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; 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.View; import android.view.ViewGroup; import android.widget.TextView; import com.trello.rxlifecycle.RxLifecycle; import com.trello.rxlifecycle.components.support.RxFragment; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; import io.realm.Realm; import se.treehou.ng.ohcommunicator.connector.models.OHServer; import se.treehou.ng.ohcommunicator.services.IScanner; import se.treehou.ng.ohcommunicator.services.Scanner; import se.treehou.ng.ohcommunicator.services.callbacks.OHCallback; import se.treehou.ng.ohcommunicator.services.callbacks.OHResponse; import treehou.se.habit.R; import treehou.se.habit.core.db.model.ServerDB; import treehou.se.habit.util.RxUtil; public class ScanServersFragment extends RxFragment { private static final String TAG = "ScanServersFragment"; @BindView(R.id.empty) View viwEmpty; @BindView(R.id.list) RecyclerView lstServer; private ServersAdapter serversAdapter; private OHCallback<List<OHServer>> discoveryListener; private Unbinder unbinder; private IScanner scanner; public static ScanServersFragment newInstance() { ScanServersFragment fragment = new ScanServersFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } public ScanServersFragment() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); scanner = new Scanner(getContext()); serversAdapter = new ServersAdapter(getActivity()); // TODO serversAdapter.addAll(OHServer.loadAll()); serversAdapter.setItemListener(new ServersAdapter.ItemListener() { @Override public void onItemClickListener(ServersAdapter.ServerHolder serverHolder) { final OHServer server = serversAdapter.getItem(serverHolder.getAdapterPosition()); saveServer(server); getFragmentManager().popBackStack(); } @Override public void itemCountUpdated(int itemCount) { updateEmptyView(itemCount); } }); } private void saveServer(OHServer server){ Realm realm = Realm.getDefaultInstance(); realm.beginTransaction(); ServerDB serverDB = ServerDB.fromGeneric(server); realm.copyToRealmOrUpdate(serverDB); realm.commitTransaction(); realm.close(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_scan_servers, container, false); unbinder = ButterKnife.bind(this, rootView); ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); if(actionBar != null) { actionBar.setTitle(R.string.scan_for_server); } lstServer.setAdapter(serversAdapter); GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1); lstServer.setLayoutManager(gridLayoutManager); lstServer.setItemAnimator(new DefaultItemAnimator()); return rootView; } @Override public void onResume() { super.onResume(); serversAdapter.clear(); discoveryListener = new OHCallback<List<OHServer>>() { @Override public void onUpdate(final OHResponse<List<OHServer>> response) { if(isAdded()){ getActivity().runOnUiThread(() -> { for (OHServer server : response.body()) { serversAdapter.addItem(server); } }); } } @Override public void onError() {} }; scanner.registerRx().compose(RxUtil.newToMainSchedulers()) .compose(RxLifecycle.bindFragment(this.lifecycle())) .subscribe(server -> { serversAdapter.addItem(server); }); } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); } /** * Show empty view if no controllers exist */ private void updateEmptyView(int itemCount){ viwEmpty.setVisibility(itemCount <= 0 ? View.VISIBLE : View.GONE); } public static class ServersAdapter extends RecyclerView.Adapter<ServersAdapter.ServerHolder>{ private List<OHServer> items = new ArrayList<>(); private Context context; private ItemListener itemListener = new DummyItemListener(); public class ServerHolder extends RecyclerView.ViewHolder { public final TextView lblName; public final TextView lblHost; public ServerHolder(View view) { super(view); lblName = (TextView) view.findViewById(R.id.lbl_server); lblHost = (TextView) view.findViewById(R.id.lbl_host); } } public ServersAdapter(Context context) { this.context = context; } @Override public ServerHolder onCreateViewHolder(ViewGroup viewGroup, int position) { LayoutInflater inflater = LayoutInflater.from(context); View itemView = inflater.inflate(R.layout.item_scan_server, null); return new ServerHolder(itemView); } @Override public void onBindViewHolder(final ServerHolder serverHolder, final int position) { OHServer server = items.get(position); serverHolder.lblName.setText(server.getDisplayName()); serverHolder.lblHost.setText(server.getLocalUrl()); serverHolder.itemView.setOnClickListener(v -> itemListener.onItemClickListener(serverHolder)); } @Override public int getItemCount() { return items.size(); } public OHServer getItem(int position) { return items.get(position); } interface ItemListener{ void onItemClickListener(ServerHolder serverHolder); void itemCountUpdated(int itemCount); } public class DummyItemListener implements ItemListener { @Override public void onItemClickListener(ServerHolder serverHolder) {} @Override public void itemCountUpdated(int itemCount) {} } public void setItemListener(ItemListener itemListener) { if(itemListener == null){ this.itemListener = new DummyItemListener(); return; } this.itemListener = itemListener; } public void addItem(OHServer item) { if(items.contains(item)){ return; } items.add(0, item); notifyItemInserted(0); itemListener.itemCountUpdated(items.size()); } public void addAll(List<OHServer> items) { Iterator<OHServer> serverIterator = items.iterator(); while (serverIterator.hasNext()) { OHServer serverDB = serverIterator.next(); if(this.items.contains(serverDB)){ serverIterator.remove(); } } for(OHServer item : items) { this.items.add(0, item); } notifyItemRangeInserted(0, items.size()); itemListener.itemCountUpdated(items.size()); } public void removeItem(int position) { Log.d(TAG, "removeItem: " + position); items.remove(position); notifyItemRemoved(position); itemListener.itemCountUpdated(items.size()); } public void removeItem(OHServer item) { int position = items.indexOf(item); items.remove(position); itemListener.itemCountUpdated(items.size()); } public void clear() { this.items.clear(); notifyDataSetChanged(); itemListener.itemCountUpdated(items.size()); } } }