package com.piusvelte.sonet.fragment;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.Editable;
import android.text.TextUtils;
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.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.piusvelte.sonet.R;
import com.piusvelte.sonet.Sonet;
import com.piusvelte.sonet.loader.PhotoPathLoader;
import com.piusvelte.sonet.loader.SendPostLoader;
import com.piusvelte.sonet.provider.Accounts;
import com.piusvelte.sonet.provider.Widgets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import static com.piusvelte.sonet.Sonet.FACEBOOK;
/**
* Created by bemmanuel on 6/4/15.
*/
public class CreatePost extends Fragment implements TextWatcher, View.OnKeyListener, LoaderManager.LoaderCallbacks<Cursor> {
private static final int LOADER_ACCOUNT = 0;
private static final int LOADER_SEND_POST = 1;
private static final int LOADER_PHOTO = 2;
private static final String FRAGMENT_CHOOSE_POST_ACCOUNTS = "fragment:choose_post_accounts";
private static final String DIALOG_CHOOSE_LOCATION_ACCOUNT = "dialog:choose_location_account";
private static final String DIALOG_CHOOSE_LOCATION = "dialog:choose_location";
private static final String LOADER_ARG_ACCOUNT_ID = "account_id";
private static final String LOADER_ARG_PHOTO_URI = "photo_uri";
private static final String LOADER_ARG_ACCOUNTS = "accounts";
private static final String LOADER_ARG_MESSAGE = "message";
private static final int REQUEST_CHOOSE_POST_ACCOUNTS = 0;
private static final int REQUEST_CHOOSE_LOCATION = 1;
private static final int REQUEST_PHOTO = 2;
// private static final int REQUEST_TAGS = 3;
private static final String STATE_MESSAGE = "state:message";
// TODO move this to Client implementations
private static final List<Integer> sPhotoSupported = new ArrayList<>();
private static final List<Integer> sTaggingSupported = new ArrayList<>();
static {
sPhotoSupported.add(FACEBOOK);
sTaggingSupported.add(FACEBOOK);
}
private HashSet<ChoosePostAccounts.Account> mAccounts = new HashSet<>();
private EditText mMessage;
private TextView mCount;
private View mLoadingView;
private String mPhotoPath;
private SendPostLoaderCallbacks mSendPostLoaderCallbacks = new SendPostLoaderCallbacks(this);
private PhotoPathLoaderCallbacks mPhotoPathLoaderCallbacks = new PhotoPathLoaderCallbacks(this);
public static CreatePost newInstance(@Nullable Bundle extras) {
CreatePost createPost = new CreatePost();
Bundle args = new Bundle();
if (extras != null) {
args.putAll(extras);
}
createPost.setArguments(extras);
return createPost;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.post, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mMessage = (EditText) view.findViewById(R.id.message);
mCount = (TextView) view.findViewById(R.id.count);
mLoadingView = view.findViewById(R.id.loading);
mMessage.addTextChangedListener(this);
mMessage.setOnKeyListener(this);
if (savedInstanceState != null) {
mMessage.setText(savedInstanceState.getString(STATE_MESSAGE));
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
LoaderManager loaderManager = getLoaderManager();
if (loaderManager.hasRunningLoaders()) {
// TODO test this! >_<
if (loaderManager.getLoader(LOADER_SEND_POST) != null) {
loaderManager.initLoader(LOADER_SEND_POST, null, mSendPostLoaderCallbacks);
} else if (loaderManager.getLoader(LOADER_PHOTO) != null) {
loaderManager.initLoader(LOADER_PHOTO, null, mPhotoPathLoaderCallbacks);
} else if (loaderManager.getLoader(LOADER_ACCOUNT) != null) {
loaderManager.initLoader(LOADER_ACCOUNT, null, this);
}
}
}
@Override
public void onDestroyView() {
mMessage = null;
mCount = null;
mLoadingView = null;
super.onDestroyView();
}
// TODO support passing in arguments
private void handleIntent(@Nullable Intent intent) {
if (intent != null) {
String action = intent.getAction();
if ((action != null) && action.equals(Intent.ACTION_SEND)) {
if (intent.hasExtra(Intent.EXTRA_STREAM)) {
getPhoto((Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM));
}
if (intent.hasExtra(Intent.EXTRA_TEXT)) {
final String text = intent.getStringExtra(Intent.EXTRA_TEXT);
mMessage.setText(text);
mCount.setText(Integer.toString(text.length()));
}
chooseAccounts();
} else {
Uri data = intent.getData();
if ((data != null) && data.toString().contains(Accounts.getContentUri(getActivity()).toString())) {
Bundle args = new Bundle();
args.putString(LOADER_ARG_ACCOUNT_ID, data.getLastPathSegment());
getLoaderManager().restartLoader(LOADER_ACCOUNT, args, this);
mLoadingView.setVisibility(View.VISIBLE);
} else if (intent.hasExtra(Widgets.INSTANT_UPLOAD)) {
// check if a photo path was passed and prompt user to select the account
setPhoto(intent.getStringExtra(Widgets.INSTANT_UPLOAD));
chooseAccounts();
}
}
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_post, menu);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(STATE_MESSAGE, mMessage.getText().toString());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Fragment fragment;
switch (item.getItemId()) {
case android.R.id.home:
fragment = getFragmentManager().findFragmentByTag(FRAGMENT_CHOOSE_POST_ACCOUNTS);
if (fragment != null) {
getFragmentManager().popBackStack();
} else {
getActivity().finish();
}
return true;
case R.id.menu_post_accounts:
chooseAccounts();
return true;
case R.id.menu_post_photo:
boolean supported = false;
for (ChoosePostAccounts.Account account : mAccounts) {
supported = sPhotoSupported.contains(account.service);
if (supported) {
break;
}
}
if (supported) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), REQUEST_PHOTO);
} else {
unsupportedToast(sPhotoSupported);
}
return true;
case R.id.menu_send:
if (!mAccounts.isEmpty()) {
Bundle args = new Bundle();
args.putParcelableArrayList(LOADER_ARG_ACCOUNTS, new ArrayList<>(mAccounts));
args.putString(LOADER_ARG_MESSAGE, mMessage.getText().toString());
args.putString(LOADER_ARG_PHOTO_URI, mPhotoPath);
getLoaderManager().restartLoader(LOADER_SEND_POST, args, mSendPostLoaderCallbacks);
mLoadingView.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getActivity(), "no accounts selected", Toast.LENGTH_LONG).show();
}
return true;
// } else if (itemId == R.id.menu_post_tags) {
// if (mAccountsService.size() == 1) {
// if (sTaggingSupported.contains(mAccountsService.values().iterator().next()))
// selectFriends(mAccountsService.keySet().iterator().next());
// else
// unsupportedToast(sTaggingSupported);
// } else {
// // dialog to select an account
// Iterator<Long> accountIds = mAccountsService.keySet().iterator();
// HashMap<Long, String> accountEntries = new HashMap<Long, String>();
// while (accountIds.hasNext()) {
// Long accountId = accountIds.next();
// Cursor account = this.getContentResolver().query(Accounts.getContentUri(this), new String[]{Accounts._ID, ACCOUNTS_QUERY},
// Accounts._ID + "=?", new String[]{Long.toString(accountId)}, null);
// if (account.moveToFirst() && sTaggingSupported.contains(mAccountsService.get(accountId)))
// accountEntries.put(account.getLong(0), account.getString(1));
// }
// int size = accountEntries.size();
// if (size != 0) {
// final long[] accountIndexes = new long[size];
// final String[] accounts = new String[size];
// int i = 0;
// Iterator<Map.Entry<Long, String>> entries = accountEntries.entrySet().iterator();
// while (entries.hasNext()) {
// Map.Entry<Long, String> entry = entries.next();
// accountIndexes[i] = entry.getKey();
// accounts[i++] = entry.getValue();
// }
// mDialog = (new AlertDialog.Builder(this))
// .setTitle(R.string.accounts)
// .setSingleChoiceItems(accounts, -1, new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// selectFriends(accountIndexes[which]);
// dialog.dismiss();
// }
// })
// .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// dialog.dismiss();
// }
// })
// .create();
// mDialog.show();
// } else
// unsupportedToast(sTaggingSupported);
// }
default:
return super.onOptionsItemSelected(item);
}
}
protected void chooseAccounts() {
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
Fragment fragment = ChoosePostAccounts.newInstance(REQUEST_CHOOSE_POST_ACCOUNTS, mAccounts);
fragment.setTargetFragment(this, REQUEST_CHOOSE_POST_ACCOUNTS);
getFragmentManager().beginTransaction()
.add(R.id.fragment_container,
fragment,
FRAGMENT_CHOOSE_POST_ACCOUNTS)
.addToBackStack(null)
.commit();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// NO-OP
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// NO-OP
}
@Override
public void afterTextChanged(Editable s) {
mCount.setText(Integer.toString(s.toString().length()));
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
mCount.setText(Integer.toString(mMessage.getText().toString().length()));
return false;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_ACCOUNT:
return new CursorLoader(getActivity(),
Accounts.getContentUri(getActivity()),
new String[] { Accounts._ID, Accounts.SERVICE },
Accounts._ID + "=?",
new String[] { args.getString(LOADER_ARG_ACCOUNT_ID) },
null);
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
switch (loader.getId()) {
case LOADER_ACCOUNT:
mLoadingView.setVisibility(View.GONE);
if (cursor != null) {
if (cursor.moveToFirst()) {
ChoosePostAccounts.Account account = new ChoosePostAccounts.Account();
account.id = cursor.getLong(cursor.getColumnIndexOrThrow(Accounts._ID));
account.service = cursor.getInt(cursor.getColumnIndexOrThrow(Accounts.SERVICE));
mAccounts.add(account);
}
}
break;
default:
break;
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// NO-OP
}
private static class SendPostLoaderCallbacks implements LoaderManager.LoaderCallbacks<Boolean> {
private CreatePost mCreatePost;
public SendPostLoaderCallbacks(@NonNull CreatePost createPost) {
mCreatePost = createPost;
}
@Override
public Loader<Boolean> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_SEND_POST:
ArrayList<ChoosePostAccounts.Account> accounts = args.getParcelableArrayList(LOADER_ARG_ACCOUNTS);
return new SendPostLoader(mCreatePost.getActivity(),
accounts,
args.getString(LOADER_ARG_MESSAGE),
args.getString(LOADER_ARG_PHOTO_URI));
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<Boolean> loader, Boolean data) {
switch (loader.getId()) {
case LOADER_SEND_POST:
mCreatePost.onPostSendResult(data);
break;
}
}
@Override
public void onLoaderReset(Loader<Boolean> loader) {
// NO-OP
}
}
private void unsupportedToast(List<Integer> supportedServices) {
StringBuilder message = new StringBuilder();
message.append("This feature is currently supported only for ");
for (int i = 0, l = supportedServices.size(); i < l; i++) {
message.append(Sonet.getServiceName(getResources(), supportedServices.get(i)));
if (i == (l - 1)) {
message.append(".");
} else if (i == (l - 2)) {
message.append(", and ");
} else {
message.append(", ");
}
}
Toast.makeText(getActivity(), message.toString(), Toast.LENGTH_LONG).show();
}
protected void getPhoto(Uri uri) {
Bundle args = new Bundle();
args.putString(LOADER_ARG_PHOTO_URI, uri.toString());
getLoaderManager().restartLoader(LOADER_PHOTO, args, mPhotoPathLoaderCallbacks);
mLoadingView.setVisibility(View.VISIBLE);
}
protected void setPhoto(String path) {
mPhotoPath = path;
Toast.makeText(getActivity(), "Currently, the photo will only be uploaded Facebook accounts.", Toast.LENGTH_LONG).show();
}
private void setPhotoPath(String path) {
mLoadingView.setVisibility(View.GONE);
if (!TextUtils.isEmpty(path)) {
setPhoto(path);
} else {
Toast.makeText(getActivity(), "error retrieving the photo path", Toast.LENGTH_LONG).show();
}
}
private void onPostSendResult(Boolean result) {
mLoadingView.setVisibility(View.GONE);
if (Boolean.TRUE.equals(result)) {
Toast.makeText(getActivity(), R.string.success, Toast.LENGTH_LONG).show();
}
getActivity().finish();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_PHOTO:
if (resultCode == Activity.RESULT_OK) {
getPhoto(data.getData());
}
break;
// case REQUEST_TAGS:
// if (resultCode == Activity.RESULT_OK && data.hasExtra(Stags) && data.hasExtra(Accounts.SID)) {
// long id = data.getLongExtra(Accounts.SID, Sonet.INVALID_ACCOUNT_ID);
//
// for (ChoosePostAccounts.Account account : mAccounts) {
// if (account.id == id) {
// account.tags = Arrays.asList(data.getStringArrayExtra(Stags));
// break;
// }
// }
// }
// break;
case REQUEST_CHOOSE_POST_ACCOUNTS:
if (resultCode == Activity.RESULT_OK) {
mAccounts.clear();
List<ChoosePostAccounts.Account> selectedAccounts = ChoosePostAccounts.getAccounts(data);
if (selectedAccounts != null) {
mAccounts.addAll(selectedAccounts);
}
}
break;
case REQUEST_CHOOSE_LOCATION:
if (resultCode == Activity.RESULT_OK) {
long accountId = ChooseLocation.getAccountId(data);
String latitude = ChooseLocation.getLatitude(data);
String longitude = ChooseLocation.getLongitude(data);
String location = ChooseLocation.getLocation(data);
for (ChoosePostAccounts.Account account : mAccounts) {
if (account.id == accountId) {
account.latitude = latitude;
account.longitude = longitude;
account.location = location;
break;
}
}
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
private static class PhotoPathLoaderCallbacks implements LoaderManager.LoaderCallbacks<String> {
private CreatePost mCreatePost;
PhotoPathLoaderCallbacks(@NonNull CreatePost createPost) {
mCreatePost = createPost;
}
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_PHOTO:
return new PhotoPathLoader(mCreatePost.getActivity(), Uri.parse(args.getString(LOADER_ARG_PHOTO_URI)));
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
switch (loader.getId()) {
case LOADER_PHOTO:
mCreatePost.setPhotoPath(data);
break;
}
}
@Override
public void onLoaderReset(Loader<String> loader) {
// NO-OP
}
}
}