package com.seafile.seadroid2.ui.activity;
import android.content.*;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.widget.*;
import android.view.MenuItem;
import com.google.common.collect.Lists;
import com.seafile.seadroid2.util.ConcurrentAsyncTask;
import com.seafile.seadroid2.R;
import com.seafile.seadroid2.SeafException;
import com.seafile.seadroid2.account.Account;
import com.seafile.seadroid2.account.AccountManager;
import com.seafile.seadroid2.data.DataManager;
import com.seafile.seadroid2.data.SeafRepo;
import com.seafile.seadroid2.data.SearchedFile;
import com.seafile.seadroid2.transfer.TransferService;
import com.seafile.seadroid2.ui.WidgetUtils;
import com.seafile.seadroid2.ui.adapter.SearchAdapter;
import com.seafile.seadroid2.util.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Search Activity
*
*/
public class SearchActivity extends BaseActivity implements View.OnClickListener, Toolbar.OnMenuItemClickListener {
private static final String DEBUG_TAG = "SearchActivity";
private static final String STATE_SEARCHED_RESULT = "searched_result";
private String mSearchedRlt;
private EditText mTextField;
private View mSearchContent;
private ImageButton mTextClearBtn;
private View mSearchBtn;
private ListView mListView;
private LinearLayout mProgressContainer;
private LinearLayout mMessageContainer;
private ImageView mEmptyText;
private ImageView mErrorText;
private SearchAdapter mAdapter;
private List<SearchedFile> mSearchedFiles = Lists.newArrayList();
private DataManager dataManager;
private TransferService txService = null;
private Account account;
public static final int DOWNLOAD_FILE_REQUEST = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
mSearchBtn = findViewById(R.id.btn_search);
mSearchBtn.setOnClickListener(this);
mTextClearBtn = (ImageButton) findViewById(R.id.btn_clear);
mTextClearBtn.setOnClickListener(this);
mTextField = (EditText) findViewById(R.id.et_content);
mTextField.setOnClickListener(this);
mTextField.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
mTextField.addTextChangedListener(new SearchTextWatcher());
mTextField.setOnEditorActionListener(new EditorActionListener());
mTextField.requestFocus();
mSearchContent = findViewById(R.id.search_content);
mListView = (ListView) findViewById(R.id.lv_search);
mProgressContainer = (LinearLayout) findViewById(R.id.progressContainer);
mMessageContainer = (LinearLayout) findViewById(R.id.ll_message_content);
mEmptyText = (ImageView) findViewById(R.id.iv_empty_txt);
mErrorText = (ImageView) findViewById(R.id.iv_error_txt);
mAdapter = new SearchAdapter(this);
mAdapter.setItems(mSearchedFiles);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(new SearchListClickListener());
//TODO mListView load more data
setSupportActionBar(getActionBarToolbar());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.search_menu_item);
initData();
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the searched result
savedInstanceState.putString(STATE_SEARCHED_RESULT, mSearchedRlt);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mSearchedRlt = savedInstanceState.getString(STATE_SEARCHED_RESULT);
// update ui
if (dataManager != null) {
mSearchContent.setVisibility(View.VISIBLE);
mMessageContainer.setVisibility(View.GONE);
mEmptyText.setVisibility(View.GONE);
mErrorText.setVisibility(View.GONE);
ArrayList<SearchedFile> files = dataManager.parseSearchResult(mSearchedRlt);
if(files != null) {
mAdapter.setItems(files);
mAdapter.notifyChanged();
}
}
}
@Override
protected void onDestroy() {
Log.d(DEBUG_TAG, "onDestroy is called");
if (txService != null) {
unbindService(mConnection);
txService = null;
}
super.onDestroy();
}
private void initData() {
AccountManager accountManager = new AccountManager(this);
account = accountManager.getCurrentAccount();
dataManager = new DataManager(account);
// bind transfer service
Intent bIntent = new Intent(this, TransferService.class);
bindService(bIntent, mConnection, Context.BIND_AUTO_CREATE);
Log.d(DEBUG_TAG, "try bind TransferService");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getActionBarToolbar().setOnMenuItemClickListener(this);
return true;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
if (mSearchedFiles.isEmpty()) {
mMessageContainer.setVisibility(View.VISIBLE);
} else {
mMessageContainer.setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
final int id = v.getId();
if (id == R.id.btn_search) {
// pass 0 to disable page loading
handleSearch(0);
} else if (id == R.id.btn_clear) {
mTextField.getText().clear();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case DOWNLOAD_FILE_REQUEST:
if (resultCode == RESULT_OK) {
File file = new File(data.getStringExtra("path"));
WidgetUtils.showFile(this, file);
}
default:
break;
}
}
private void handleSearch(int page) {
// TODO page loading instead of only display top 100 search result
page = 100;
if (!Utils.isNetworkOn()) {
showShortToast(this, R.string.network_down);
mMessageContainer.setVisibility(View.VISIBLE);
return;
} else
mMessageContainer.setVisibility(View.GONE);
String searchText = mTextField.getText().toString().trim();
if (!TextUtils.isEmpty(searchText)) {
// mSearchedFiles.clear();
search(searchText, page);
Utils.hideSoftKeyboard(mTextField);
} else {
showShortToast(this, R.string.search_txt_empty);
}
}
private void search(String content, int page) {
// start asynctask
ConcurrentAsyncTask.execute(new SearchLibrariesTask(dataManager, content, page));
}
class SearchLibrariesTask extends AsyncTask<Void, Void, ArrayList<SearchedFile>> {
private DataManager dataManager;
private String query;
private int page;
private SeafException seafException;
@Override
protected void onPreExecute() {
// show loading view
showLoading(true);
mSearchBtn.setEnabled(false);
mMessageContainer.setVisibility(View.GONE);
}
public SearchLibrariesTask(DataManager dataManager, String query, int page) {
this.dataManager = dataManager;
this.query = query;
this.page = page;
}
@Override
protected ArrayList<SearchedFile> doInBackground(Void... params) {
try {
mSearchedRlt = dataManager.search(query, page);
return dataManager.parseSearchResult(mSearchedRlt);
} catch (SeafException e) {
seafException = e;
return null;
}
}
@Override
protected void onPostExecute(ArrayList<SearchedFile> result) {
// stop loading view
showLoading(false);
mSearchBtn.setEnabled(true);
if (result == null) {
if (seafException != null) {
mMessageContainer.setVisibility(View.VISIBLE);
mEmptyText.setVisibility(View.GONE);
mErrorText.setVisibility(View.VISIBLE);
if (seafException.getCode() == 404)
showShortToast(SearchActivity.this, R.string.search_server_not_support);
Log.d(DEBUG_TAG, seafException.getMessage() + " code " + seafException.getCode());
} else {
mEmptyText.setVisibility(View.VISIBLE);
mErrorText.setVisibility(View.GONE);
}
return;
}
if (result.size() == 0) {
mMessageContainer.setVisibility(View.VISIBLE);
showShortToast(SearchActivity.this, R.string.search_content_empty);
return;
}
// update ui
mSearchContent.setVisibility(View.VISIBLE);
mMessageContainer.setVisibility(View.GONE);
mSearchedFiles = result;
mAdapter.setItems(mSearchedFiles);
mAdapter.notifyChanged();
}
}
public DataManager getDataManager() {
if (dataManager == null) {
AccountManager accountManager = new AccountManager(this);
account = accountManager.getCurrentAccount();
dataManager = new DataManager(account);
}
return dataManager;
}
private void showLoading(boolean show) {
if (show) {
mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
this, android.R.anim.fade_in));
mListView.startAnimation(AnimationUtils.loadAnimation(
this, android.R.anim.fade_out));
mProgressContainer.setVisibility(View.VISIBLE);
mListView.setVisibility(View.INVISIBLE);
} else {
mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
this, android.R.anim.fade_out));
mListView.startAnimation(AnimationUtils.loadAnimation(
this, android.R.anim.fade_in));
mProgressContainer.setVisibility(View.GONE);
mListView.setVisibility(View.VISIBLE);
}
}
class SearchListClickListener implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final SearchedFile searchedFile = (SearchedFile) mAdapter.getItem(position);
onSearchedFileSelected(searchedFile);
}
}
class SearchTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (mTextField.getText().toString().length() > 0) {
mTextClearBtn.setVisibility(View.VISIBLE);
mSearchBtn.setVisibility(View.VISIBLE);
} else {
mTextClearBtn.setVisibility(View.GONE);
mSearchBtn.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable s) {}
}
class EditorActionListener implements TextView.OnEditorActionListener {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
// pass 0 to disable page loading
handleSearch(0);
return true;
}
return false;
}
}
public void onSearchedFileSelected(SearchedFile searchedFile) {
final String repoID = searchedFile.getRepoID();
final SeafRepo repo = dataManager.getCachedRepoByID(repoID);
final String repoName = repo.getName();
final String filePath = searchedFile.getPath();
if (searchedFile.isDir()) {
if (repo == null) {
showShortToast(this, R.string.search_library_not_found);
return;
}
WidgetUtils.showRepo(this, repoID, repoName, filePath, null);
return;
}
// Encrypted repo doesn\`t support gallery,
// because pic thumbnail under encrypted repo was not supported at the server side
if (Utils.isViewableImage(searchedFile.getTitle())
&& repo != null && !repo.encrypted) {
WidgetUtils.startGalleryActivity(this, repoName, repoID, Utils.getParentPath(filePath), searchedFile.getTitle(), account);
return;
}
final File localFile = dataManager.getLocalCachedFile(repoName, repoID, filePath, null);
if (localFile != null) {
WidgetUtils.showFile(this, localFile);
return;
}
startFileActivity(repoName, repoID, filePath);
}
private void startFileActivity(String repoName, String repoID, String filePath) {
final int taskID = txService.addDownloadTask(account, repoName, repoID, filePath);
Intent intent = new Intent(this, FileActivity.class);
intent.putExtra("repoName", repoName);
intent.putExtra("repoID", repoID);
intent.putExtra("filePath", filePath);
intent.putExtra("account", account);
intent.putExtra("taskID", taskID);
startActivityForResult(intent, DOWNLOAD_FILE_REQUEST);
}
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
TransferService.TransferBinder binder = (TransferService.TransferBinder) service;
txService = binder.getService();
Log.d(DEBUG_TAG, "bind TransferService");
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
txService = null;
}
};
}