package github.daneren2005.dsub.fragments;
import android.content.Context;
import android.content.SharedPreferences;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
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 android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.ChatMessage;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
import github.daneren2005.dsub.util.BackgroundTask;
import github.daneren2005.dsub.util.TabBackgroundTask;
import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.adapter.ChatAdapter;
import github.daneren2005.dsub.util.Constants;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author Joshua Bahnsen
*/
public class ChatFragment extends SubsonicFragment {
private static final String TAG = ChatFragment.class.getSimpleName();
private ListView chatListView;
private EditText messageEditText;
private ImageButton sendButton;
private Long lastChatMessageTime = (long) 0;
private ArrayList<ChatMessage> messageList;
private ScheduledExecutorService executorService;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
if(bundle != null) {
List<ChatMessage> abstractList = (List<ChatMessage>) bundle.getSerializable(Constants.FRAGMENT_LIST);
messageList = new ArrayList<ChatMessage>(abstractList);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) messageList);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
rootView = inflater.inflate(R.layout.chat, container, false);
messageEditText = (EditText) rootView.findViewById(R.id.chat_edittext);
sendButton = (ImageButton) rootView.findViewById(R.id.chat_send);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendMessage();
}
});
chatListView = (ListView) rootView.findViewById(R.id.chat_entries);
chatListView.setStackFromBottom(true);
messageEditText.setImeActionLabel("Send", KeyEvent.KEYCODE_ENTER);
messageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
sendButton.setEnabled(!Util.isNullOrWhiteSpace(editable.toString()));
}
});
messageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE || (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN)) {
sendMessage();
return true;
}
return false;
}
});
if(messageList == null) {
messageList = new ArrayList<ChatMessage>();
refresh(true);
} else {
for (ChatMessage message : messageList) {
if (message.getTime() > lastChatMessageTime) {
lastChatMessageTime = message.getTime();
}
}
ChatAdapter chatAdapter = new ChatAdapter(context, messageList, getImageLoader());
chatListView.setAdapter(chatAdapter);
}
setTitle(R.string.button_bar_chat);
refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout);
refreshLayout.setOnRefreshListener(this);
setupScrollList(chatListView);
return rootView;
}
@Override
public void onStart() {
super.onStart();
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
if(primaryFragment) {
load(false);
} else {
invalidated = true;
}
}
});
}
};
SharedPreferences prefs = Util.getPreferences(context);
long refreshRate = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_CHAT_REFRESH, "30"));
if(refreshRate > 0) {
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(runnable, refreshRate * 1000L, refreshRate * 1000L, TimeUnit.MILLISECONDS);
}
}
@Override
public void onStop() {
super.onStop();
if(executorService != null) {
executorService.shutdown();
executorService = null;
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.abstract_top_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
protected void refresh(boolean refresh) {
load(refresh);
}
private synchronized void load(final boolean refresh) {
BackgroundTask<List<ChatMessage>> task = new TabBackgroundTask<List<ChatMessage>>(this) {
@Override
protected List<ChatMessage> doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
return musicService.getChatMessages(refresh ? 0L : lastChatMessageTime, context, this);
}
@Override
protected void done(List<ChatMessage> result) {
if (result != null && !result.isEmpty()) {
if(refresh) {
messageList.clear();
}
// Reset lastChatMessageTime if we have a newer message
for (ChatMessage message : result) {
if (message.getTime() > lastChatMessageTime) {
lastChatMessageTime = message.getTime();
}
}
// Reverse results to show them on the bottom
Collections.reverse(result);
messageList.addAll(result);
ChatAdapter chatAdapter = new ChatAdapter(context, messageList, getImageLoader());
chatListView.setAdapter(chatAdapter);
}
}
};
task.execute();
}
private void sendMessage() {
final String message = messageEditText.getText().toString();
if (!Util.isNullOrWhiteSpace(message)) {
messageEditText.setText("");
InputMethodManager mgr = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
BackgroundTask<Void> task = new TabBackgroundTask<Void>(this) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
musicService.addChatMessage(message, context, this);
return null;
}
@Override
protected void done(Void result) {
load(false);
}
};
task.execute();
}
}
}