package net.krautchan.android.activity;
/*
* Copyright (C) 2011 Johannes Jander (johannes@jandermail.de)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.StreamCorruptedException;
import java.util.Timer;
import java.util.TimerTask;
import net.krautchan.R;
import net.krautchan.android.Defaults;
import net.krautchan.android.Eisenheinrich;
import net.krautchan.android.dialog.BannedDialog;
import net.krautchan.android.dialog.GoToThreadDialog;
import net.krautchan.android.helpers.ActivityHelpers;
import net.krautchan.android.helpers.CustomExceptionHandler;
import net.krautchan.android.widget.CommandBar;
import net.krautchan.android.widget.ThreadListAdapter;
import net.krautchan.data.KCBoard;
import net.krautchan.data.KCThread;
import net.krautchan.data.KODataListener;
import net.krautchan.parser.KCPageParser;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
public class KCThreadListActivity extends Activity implements ProvidesBoards, ProvidesThreads {
protected static final String TAG = "KCThreadListActivity";
private ListView list = null;
private CommandBar cmdBar;
private ThreadListAdapter adapter = null;
private KCBoard curBoard;
private String token;
private Timer siteReachableWatchdog = new Timer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(
"eisenheinrich", "http://eisenheinrich.datensalat.net:8080/Eisenweb/upload/logfile/test", this));
setContentView(R.layout.thread_list);
list = (ListView)findViewById(R.id.thread_listview);
adapter = new ThreadListAdapter(this, this, this, R.layout.thread_list_item);
Bundle bndl;
if (null != savedInstanceState) {
bndl = savedInstanceState;
curBoard = Eisenheinrich.GLOBALS.getBoardCache().get(bndl.getLong("boardId"));
if (null == curBoard) {
throw new NullPointerException ("Cache returned null for BoardID "+bndl.getLong("boardId"));
}
Log.i("THREADLIST", "onCreate. Board: "+curBoard.shortName +" - "+curBoard.name);
Thread t = new Thread (new KCPageParser(curBoard.uri, curBoard.dbId)
.setBasePath(Defaults.BASE_URL)
.setThreadHandler(Eisenheinrich.getInstance().getThreadListener())
.setPostingHandler(Eisenheinrich.getInstance().getPostListener())
);
t.start();
} else {
bndl = getIntent().getExtras();
byte[] boardS = bndl.getByteArray("board");
ByteArrayInputStream bitch = new ByteArrayInputStream(boardS);
ObjectInputStream in;
try {
in = new ObjectInputStream(bitch);
curBoard = (KCBoard)in.readObject();
} catch (StreamCorruptedException e) {
Toast toast = Toast.makeText(this, "KCThreadListActivity::onCreate failed: "+e.getMessage(), Toast.LENGTH_LONG);
toast.show();
} catch (IOException e) {
Toast toast = Toast.makeText(this, "KCThreadListActivity::onCreate failed: "+e.getMessage(), Toast.LENGTH_LONG);
toast.show();
} catch (ClassNotFoundException e) {
Toast toast = Toast.makeText(this, "KCThreadListActivity::onCreate failed: "+e.getMessage(), Toast.LENGTH_LONG);
toast.show();
}
}
cmdBar = (CommandBar) findViewById(R.id.command_bar);
/*
final Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
if (0 == msg.arg1) {
cmdBar.hideProgressBar();
} else if (1 == msg.arg1) {
cmdBar.incrementProgressBy(10);
}
}
};*/
token = bndl.getString("token");
Timer tm = new Timer();
tm.schedule(new TimerTask() {
@Override
public void run() {
KCThreadListActivity.this.runOnUiThread(new Runnable () {
@Override
public void run() {
adjustTitle ();
}
});
}
}, 5000);
list.setAdapter(adapter);
Eisenheinrich.getInstance().addThreadListener(new KODataListener<KCThread>() {
@Override
public void notifyAdded(final KCThread item, Object token) {
if (KCThreadListActivity.this.token.equals(token)) {
siteReachableWatchdog.cancel();
// cannot add to the collection backing the adapter from a thread that is
// not the UI thread. Therefore, post a runnable to UI thread to handle this
runOnUiThread(new Runnable() {
public void run() {
//threads.add(item);
adapter.add(item);
adapter.notifyDataSetChanged();
cmdBar.incrementProgressBy(10);
}
});
}
}
@Override
public void notifyDone(Object token) {
Message msg = cmdBar.getProgressHandler().obtainMessage();
msg.arg1 = 0;
cmdBar.getProgressHandler().sendMessage(msg);
}
@Override
public void notifyError(Exception ex, Object token) {
KCThreadListActivity.this.finish();
}
});
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
if (null != siteReachableWatchdog) {
siteReachableWatchdog.cancel();
}
KCThread curThread = KCThreadListActivity.this.getThread(id);
if (null != curThread) {
ActivityHelpers.switchToThread (curThread, KCThreadListActivity.this);
}
}
});
registerForContextMenu(list);
list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
Eisenheinrich.getInstance();
KCThread curThread = Eisenheinrich.GLOBALS.getThreadCache().get(id);
if (null != curThread) {
list.setTag(curThread);
}
openContextMenu(list);
return true; // avoid extra click events
}
});
}
@Override
public KCThread getThread(long dbId) {
return Eisenheinrich.GLOBALS.getThreadCache().get(dbId);
}
@Override
public KCBoard getBoard(long dbId) {
return Eisenheinrich.GLOBALS.getBoardCache().get(dbId);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Context Menu");
menu.add(0, v.getId(), 0, R.string.option_bookmark);
menu.add(0, v.getId(), 0, R.string.option_hide);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
View v = this.findViewById(item.getItemId());
KCThread thread = (KCThread) v.getTag();
String title = (String)item.getTitle();
if (title.equals(getString(R.string.option_bookmark))){
Eisenheinrich.getInstance().dbHelper.bookmarkThread(thread);
} else if (title.equals(getString(R.string.option_hide))){
adapter.hide(thread);
thread.hidden = true;
Eisenheinrich.getInstance().dbHelper.persistThread(thread);
} else {
return false;
}
return true;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if ((newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) || (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)) {
adapter.notifyDataSetChanged();
}
}
@Override
protected void onStop() {
super.onStop();
list.setVisibility(View.GONE);
Eisenheinrich.getInstance();
Eisenheinrich.GLOBALS.getThreadCache().freeze();
}
@Override
protected void onRestart() {
super.onRestart();
list.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
adjustTitle ();
}
@Override
protected void onRestoreInstanceState(Bundle inState) {
super.onRestoreInstanceState(inState);
curBoard = Eisenheinrich.GLOBALS.getBoardCache().get(inState.getLong("boardId"));
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("boardId", curBoard.dbId);
outState.putString("token", token);
Eisenheinrich.GLOBALS.getThreadCache().freeze();
}
private void adjustTitle () {
KCBoard board = Eisenheinrich.GLOBALS.getBoardCache().get(curBoard.dbId);
if (null == board) {
return;
}
String title = "/"+curBoard.shortName+"/ - "+curBoard.name;
if (board.banned) {
cmdBar.setTitle(title + " ("+this.getString(R.string.banned)+")");
} else {
cmdBar.setTitle(title);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu_threadlist, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.go_thread:
new GoToThreadDialog (this, curBoard, Eisenheinrich.getInstance().getHttpClient()).showDialog();
return true;
case R.id.bookmark:
return true;
case R.id.reload: {
//threads.clear();
adapter.clear();
adapter.notifyDataSetInvalidated();
new Thread (new KCPageParser(curBoard.uri, curBoard.dbId)
.setBasePath("http://krautchan.net/")
.setThreadHandler(Eisenheinrich.getInstance().getThreadListener())
.setPostingHandler(Eisenheinrich.getInstance().getPostListener())
).start();
cmdBar.showProgressBar();
return true;
}
case R.id.new_thread: {
KCBoard board = Eisenheinrich.GLOBALS.getBoardCache().get(curBoard.dbId);
if ((board.banned) && (null == Eisenheinrich.GLOBALS.getKomturCode())) {
new BannedDialog (this).show();
Toast.makeText(KCThreadListActivity.this, R.string.banned_message, Toast.LENGTH_LONG).show();
} else {
ActivityHelpers.createThreadMask (null, curBoard.dbId, "", this);
}
return true;
}
case R.id.prefs:
return true;
case R.id.forward:
return true;
case R.id.home:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}