/*
* The MIT License (MIT)
*
* Copyright � 2013 Clover Studio Ltd. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.cloverstudio.spikademo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.cloverstudio.spikademo.R;
import com.cloverstudio.spikademo.adapters.UsersAdapter;
import com.cloverstudio.spikademo.couchdb.CouchDB;
import com.cloverstudio.spikademo.couchdb.model.Notification;
import com.cloverstudio.spikademo.couchdb.model.RecentActivity;
import com.cloverstudio.spikademo.couchdb.model.User;
import com.cloverstudio.spikademo.couchdb.model.UserSearch;
import com.cloverstudio.spikademo.dialog.HookUpProgressDialog;
import com.cloverstudio.spikademo.extendables.SpikaAsync;
import com.cloverstudio.spikademo.extendables.SubMenuActivity;
import com.cloverstudio.spikademo.management.UsersManagement;
import com.cloverstudio.spikademo.utils.Const;
import com.cloverstudio.spikademo.view.GenderButton;
import com.cloverstudio.spikademo.view.GenderButton.ButtonType;
/**
* UsersActivity
*
* Shows a list of users that are added to login user's contacts by default; also contains a submenu with
* options for searching and exploring users.
*/
public class UsersActivity extends SubMenuActivity {
private ListView mLvUsers;
private List<User> mUsers;
private List<Notification> mUserNotifications;
private UsersAdapter mUserListAdapter;
private RelativeLayout mLayoutUserSearch;
private RelativeLayout mLayoutUserExplore;
private RelativeLayout mRlMyContacts;
private RelativeLayout mRlSearch;
private String mSearchGender;
private RelativeLayout mRlExplore;
private TextView mTvNoUsers;
private TextView mTvFromAge;
private TextView mTvToAge;
private int mFullWidth;
private boolean firstMeasure = true;
private static final int FROM_AGE = 0;
private static final int TO_AGE = 100;
private boolean mOnlineUsersChecked;
public static final int REQUEST_UPDATE_USERS = 8;
private static final String ALL_USERS = "all_users";
private static final String CONTACTS = "contacts";
private static final String SEARCH_USERS = "search_users";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
setSideBar(getString(R.string.USERS));
initialization();
initUserSearch();
initUserExplore();
showTutorial(getString(R.string.tutorial_users));
}
@Override
protected void enableViews() {
super.enableViews();
mLvUsers.setEnabled(true);
}
@Override
protected void disableViews() {
super.disableViews();
mLvUsers.setEnabled(false);
}
private void initialization() {
super.setSubMenu();
mOnlineUsersChecked = false;
mLvUsers = (ListView) findViewById(R.id.lvUsers);
mLayoutUserSearch = (RelativeLayout) findViewById(R.id.rlSearchUsers);
mLayoutUserExplore = (RelativeLayout) findViewById(R.id.rlExploreUsers);
mRlMyContacts = (RelativeLayout) findViewById(R.id.rlMyContacts);
mRlMyContacts.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTvNoUsers.setVisibility(View.GONE);
mTvTitle.setText(getString(R.string.MY_CONTACTS));
closeSubMenu();
if (SpikaApp.hasNetworkConnection()) {
new GetUsersAsync(UsersActivity.this).execute(CONTACTS);
}
mLayoutUserSearch.setVisibility(View.GONE);
mLayoutUserExplore.setVisibility(View.GONE);
}
});
mRlSearch = (RelativeLayout) findViewById(R.id.rlSearch);
mRlSearch.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTvNoUsers.setVisibility(View.GONE);
mTvTitle.setText(getString(R.string.USERS));
closeSubMenu();
mLayoutUserExplore.setVisibility(View.GONE);
mLayoutUserSearch.setVisibility(View.VISIBLE);
clearListView();
}
});
mRlExplore = (RelativeLayout) findViewById(R.id.rlExplore);
mRlExplore.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTvNoUsers.setVisibility(View.GONE);
mTvTitle.setText(getString(R.string.USERS));
closeSubMenu();
mLayoutUserSearch.setVisibility(View.GONE);
mLayoutUserExplore.setVisibility(View.VISIBLE);
clearListView();
}
});
mTvNoUsers = (TextView) findViewById(R.id.tvNoUsers);
mTvNoUsers.setVisibility(View.GONE);
mTvTitle.setText(getString(R.string.MY_CONTACTS));
closeSubMenu();
if (SpikaApp.hasNetworkConnection()) {
// XXX Delete this if no error accures
//new GetLoginUserAsync(this).execute();
new GetUsersAsync(UsersActivity.this).execute(CONTACTS);
}
mLayoutUserSearch.setVisibility(View.GONE);
mLayoutUserExplore.setVisibility(View.GONE);
}
private void initUserSearch() {
final EditText etSearchName = (EditText) findViewById(R.id.etSearchName);
etSearchName.setTypeface(SpikaApp.getTfMyriadPro());
final Button btnSearch = (Button) findViewById(R.id.btnSearch);
btnSearch.setTypeface(SpikaApp.getTfMyriadPro(), Typeface.BOLD);
btnSearch.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
UserSearch userSearch = new UserSearch();
userSearch.setName(etSearchName.getText().toString());
etSearchName.setText("");
new SearchUsersAsync(UsersActivity.this).execute(userSearch);
}
});
etSearchName.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
UserSearch userSearch = new UserSearch();
userSearch.setName(etSearchName.getText().toString());
etSearchName.setText("");
hideKeyboard();
new SearchUsersAsync(UsersActivity.this)
.execute(userSearch);
return true;
}
return false;
}
});
}
private void initUserExplore() {
final GenderButton btnMale = (GenderButton) findViewById(R.id.btnMale);
btnMale.setType(ButtonType.LEFT);
btnMale.setChecked(false);
final GenderButton btnFemale = (GenderButton) findViewById(R.id.btnFemale);
btnFemale.setType(ButtonType.MIDDLE);
btnFemale.setChecked(false);
final GenderButton btnAll = (GenderButton) findViewById(R.id.btnAll);
btnAll.setType(ButtonType.RIGHT);
btnAll.setChecked(true);
btnMale.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
btnMale.setChecked(true);
mSearchGender = Const.MALE;
btnFemale.setChecked(false);
btnAll.setChecked(false);
}
});
btnFemale.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
btnMale.setChecked(false);
mSearchGender = Const.FEMALE;
btnFemale.setChecked(true);
btnAll.setChecked(false);
}
});
btnAll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
btnMale.setChecked(false);
mSearchGender = null;
btnFemale.setChecked(false);
btnAll.setChecked(true);
}
});
final Button btnExplore = (Button) findViewById(R.id.btnUserExplore);
btnExplore.setTypeface(SpikaApp.getTfMyriadPro(), Typeface.BOLD);
btnExplore.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
UserSearch userSearch = new UserSearch();
userSearch.setGender(mSearchGender);
if (mTvFromAge.getText().toString()
.equals(String.valueOf(FROM_AGE))) {
userSearch.setFromAge(null);
} else {
userSearch.setFromAge(mTvFromAge.getText().toString());
}
if (mTvFromAge.getText().toString()
.equals(String.valueOf(FROM_AGE))) {
userSearch.setToAge(null);
} else {
userSearch.setToAge(mTvToAge.getText().toString());
}
if (mOnlineUsersChecked) {
userSearch.setOnlineStatus(Const.ONLINE);
} else {
userSearch.setOnlineStatus("");
}
new SearchUsersAsync(UsersActivity.this).execute(userSearch);
}
});
firstMeasure = true;
final View seekBar = (View) findViewById(R.id.seekBar);
final RelativeLayout rlSeekBar = (RelativeLayout) findViewById(R.id.rlSeekBar);
final int MARGIN_SIZE = (int) getResources().getDimension(
R.dimen.seekBar_margin) + 1;
mTvFromAge = (TextView) findViewById(R.id.tvFromAge);
mTvFromAge.setText(String.valueOf(FROM_AGE));
mTvToAge = (TextView) findViewById(R.id.tvToAge);
mTvToAge.setText(String.valueOf(TO_AGE));
rlSeekBar.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE
|| event.getAction() == MotionEvent.ACTION_DOWN) {
int xPointTouch = Math.round(event.getX());
if (firstMeasure) {
mFullWidth = seekBar.getWidth();
firstMeasure = false;
}
final RelativeLayout.LayoutParams layoutParams = new LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
layoutParams
.addRule(RelativeLayout.RIGHT_OF, R.id.viewLeft);
layoutParams
.addRule(RelativeLayout.LEFT_OF, R.id.viewRight);
RelativeLayout.LayoutParams currentParams = (RelativeLayout.LayoutParams) seekBar
.getLayoutParams();
Rect rectSeekBar = new Rect();
seekBar.getLocalVisibleRect(rectSeekBar);
int xPointLeft = MARGIN_SIZE + currentParams.leftMargin;
int xPointRight = MARGIN_SIZE + mFullWidth
- currentParams.rightMargin;
int distanceLeft = Math.abs(xPointTouch - xPointLeft);
int distanceRight = Math.abs(xPointTouch - xPointRight);
int leftMargin = currentParams.leftMargin;
int rightMargin = currentParams.rightMargin;
if (distanceLeft < distanceRight) {
leftMargin = 0;
if (xPointTouch >= MARGIN_SIZE) {
leftMargin = xPointTouch - MARGIN_SIZE;
}
if (xPointTouch >= MARGIN_SIZE + mFullWidth) {
leftMargin = mFullWidth;
}
int fromAge = (int) Math.round((leftMargin * 1.0)
/ mFullWidth * (TO_AGE - FROM_AGE));
mTvFromAge.setText(String.valueOf(fromAge));
} else {
rightMargin = MARGIN_SIZE + mFullWidth - xPointTouch;
if (xPointTouch >= MARGIN_SIZE + mFullWidth) {
rightMargin = 0;
}
int toAge = (int) Math
.round(((mFullWidth - rightMargin) * 1.0)
/ mFullWidth * (TO_AGE - FROM_AGE));
mTvToAge.setText(String.valueOf(toAge));
}
layoutParams.leftMargin = leftMargin;
layoutParams.rightMargin = rightMargin;
seekBar.setLayoutParams(layoutParams);
seekBar.invalidate();
}
return true;
}
});
final CheckBox checkBoxOnlineUsers = (CheckBox) findViewById(R.id.checkboxOnlineUsers);
checkBoxOnlineUsers.setTypeface(SpikaApp.getTfMyriadPro());
}
public void onCheckboxClicked(View view) {
// Is the view now checked?
boolean checked = ((CheckBox) view).isChecked();
// Check which checkbox was clicked
switch (view.getId()) {
case R.id.checkboxOnlineUsers:
if (checked)
mOnlineUsersChecked = true;
else
mOnlineUsersChecked = false;
break;
default:
break;
}
}
private class GetUsersAsync extends SpikaAsync<String, Void, List<User>> {
String searchType = "";
protected GetUsersAsync(Context context) {
super(context);
}
HookUpProgressDialog progressDialog = new HookUpProgressDialog(
UsersActivity.this);
@Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute();
}
@Override
protected List<User> doInBackground(String... params) {
searchType = params[0];
if (params[0].equals(ALL_USERS)) {
return CouchDB.findAllUsers();
} else if (params[0].equals(SEARCH_USERS)) {
return CouchDB.findUsersByName(params[1]);
} else if (params[0].equals(CONTACTS)) {
return CouchDB.findUserContacts(UsersManagement.getLoginUser()
.getId());
} else {
return CouchDB.findAllUsers();
}
}
@Override
protected void onPostExecute(List<User> result) {
if (searchType.equals(CONTACTS)
&& (result == null || result.size() == 0)) {
UsersActivity.this
.showTutorialOnceAfterBoot(getString(R.string.tutorial_nocontact));
}
if (UsersManagement.getLoginUser().getActivitySummary() != null) {
for (RecentActivity recentActivity : UsersManagement
.getLoginUser().getActivitySummary()
.getRecentActivityList()) {
if (recentActivity.getTargetType().equals(Const.USER)) {
mUserNotifications = recentActivity.getNotifications();
}
}
}
mUsers = (ArrayList<User>) result;
if (mUsers.size() == 0) {
mTvNoUsers.setVisibility(View.VISIBLE);
mTvNoUsers.setText(getString(R.string.no_users_in_contacts));
} else {
mTvNoUsers.setVisibility(View.GONE);
}
// sorting users by name
Collections.sort(mUsers, new Comparator<User>() {
@Override
public int compare(User lhs, User rhs) {
return lhs.getName().compareToIgnoreCase(rhs.getName());
}
});
if (mUserListAdapter == null) {
mUserListAdapter = new UsersAdapter(UsersActivity.this, mUsers,
mUserNotifications);
mLvUsers.setAdapter(mUserListAdapter);
mLvUsers.setOnItemClickListener(mUserListAdapter);
} else {
mUserListAdapter.setItems(mUsers, mUserNotifications);
}
progressDialog.dismiss();
}
}
private void clearListView() {
mUserListAdapter = new UsersAdapter(UsersActivity.this,
new ArrayList<User>(), new ArrayList<Notification>());
mLvUsers.setAdapter(mUserListAdapter);
}
private class SearchUsersAsync extends
SpikaAsync<UserSearch, Void, List<User>> {
protected SearchUsersAsync(Context context) {
super(context);
}
HookUpProgressDialog progressDialog = new HookUpProgressDialog(
UsersActivity.this);
@Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute();
}
@Override
protected List<User> doInBackground(UserSearch... params) {
return CouchDB.searchUsers(params[0]);
}
@Override
protected void onPostExecute(List<User> result) {
if (result != null) {
if (UsersManagement.getLoginUser().getActivitySummary() != null) {
for (RecentActivity recentActivity : UsersManagement
.getLoginUser().getActivitySummary()
.getRecentActivityList()) {
if (recentActivity.getTargetType().equals(Const.USER)) {
mUserNotifications = recentActivity
.getNotifications();
}
}
}
mUsers = (ArrayList<User>) result;
if (mUsers.size() == 0) {
mTvNoUsers.setVisibility(View.VISIBLE);
mTvNoUsers.setText(getString(R.string.no_users_found));
} else {
mTvNoUsers.setVisibility(View.GONE);
}
// sorting users by name
Collections.sort(mUsers, new Comparator<User>() {
@Override
public int compare(User lhs, User rhs) {
return lhs.getName().compareToIgnoreCase(rhs.getName());
}
});
if (mUserListAdapter == null) {
mUserListAdapter = new UsersAdapter(UsersActivity.this,
mUsers, mUserNotifications);
mLvUsers.setAdapter(mUserListAdapter);
mLvUsers.setOnItemClickListener(mUserListAdapter);
} else {
mUserListAdapter.setItems(mUsers, mUserNotifications);
}
}
progressDialog.dismiss();
}
}
@Override
public void onBackPressed() {
if (mLayoutUserSearch.getVisibility() == View.VISIBLE) {
mLayoutUserSearch.setVisibility(View.GONE);
if (SpikaApp.hasNetworkConnection()) {
new GetUsersAsync(UsersActivity.this).execute(CONTACTS);
}
} else if (mLayoutUserExplore.getVisibility() == View.VISIBLE) {
mLayoutUserExplore.setVisibility(View.GONE);
if (SpikaApp.hasNetworkConnection()) {
new GetUsersAsync(UsersActivity.this).execute(CONTACTS);
}
} else {
super.onBackPressed();
}
}
@Override
protected void refreshActivitySummaryViews() {
super.refreshActivitySummaryViews();
if (UsersManagement.getLoginUser().getActivitySummary() != null) {
for (RecentActivity recentActivity : UsersManagement.getLoginUser()
.getActivitySummary().getRecentActivityList()) {
if (recentActivity.getTargetType().equals(Const.USER)) {
mUserNotifications = recentActivity.getNotifications();
}
}
}
if (mUserListAdapter != null) {
mUserListAdapter.setItems(mUsers, mUserNotifications);
}
}
@Override
protected void setObjectsNull() {
mLvUsers.setAdapter(null);
mLvUsers = null;
mLayoutUserSearch = null;
mUserListAdapter = null;
super.setObjectsNull();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check which request we're responding to
if (requestCode == REQUEST_UPDATE_USERS) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
mTvNoUsers.setVisibility(View.GONE);
mTvTitle.setText(getString(R.string.MY_CONTACTS));
if (SpikaApp.hasNetworkConnection()) {
new GetUsersAsync(UsersActivity.this).execute(CONTACTS);
}
mLayoutUserSearch.setVisibility(View.GONE);
mLayoutUserExplore.setVisibility(View.GONE);
}
}
}
}