package com.luorrak.ouroboros.reply;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
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.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.koushikdutta.ion.Ion;
import com.luorrak.ouroboros.R;
import com.luorrak.ouroboros.api.JsonParser;
import com.luorrak.ouroboros.util.InfiniteDbHelper;
import com.luorrak.ouroboros.util.NetworkHelper;
import com.luorrak.ouroboros.util.Reply;
import com.luorrak.ouroboros.util.SaveReplyText;
import com.luorrak.ouroboros.util.SettingsHelper;
import com.luorrak.ouroboros.util.Util;
import java.util.ArrayList;
/**
* Ouroboros - An 8chan browser
* Copyright (C) 2015 Luorrak
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
public class ReplyCommentFragment extends Fragment {
private static boolean isPosting;
private String resto;
private String boardName;
private String replyNo;
private SharedPreferences sharedPreferences;
private NetworkHelper networkHelper;
private final int FILE_SELECT_CODE = 1;
private Reply reply;
public ReplyCommentFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
isPosting = false;
View view = inflater.inflate(R.layout.fragment_post_comment_activity, container, false);
setActionBarTitle("Post a comment");
networkHelper = new NetworkHelper();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
reply = new Reply();
if (savedInstanceState == null){
reply.filePath = new ArrayList<>();
} else {
reply.filePath = savedInstanceState.getStringArrayList("filePath");
for (String file : reply.filePath){
addAttachmentPreview(file, view);
}
}
reply.fileName = new ArrayList<String>();
resto = getActivity().getIntent().getStringExtra(Util.INTENT_THREAD_NO);
boardName = getActivity().getIntent().getStringExtra(Util.INTENT_BOARD_NAME);
replyNo = getActivity().getIntent().getStringExtra(Util.INTENT_REPLY_NO);
EditText nameText = (EditText) view.findViewById(R.id.post_comment_editText_name);
final EditText emailText = (EditText) view.findViewById(R.id.post_comment_editText_email);
CheckBox sageBox = (CheckBox) view.findViewById(R.id.post_comment_checkBox_sage);
EditText subjetText = (EditText) view.findViewById(R.id.post_comment_editText_subject);
EditText commentText = (EditText) view.findViewById(R.id.post_comment_editText_comment);
String defaultName = SettingsHelper.getDefaultName(getActivity());
String defaultEmail = SettingsHelper.getDefaultEmail(getActivity());
nameText.setText(sharedPreferences.getString(SaveReplyText.nameEditTextKey, defaultName));
emailText.setText(sharedPreferences.getString(SaveReplyText.emailEditTextKey, defaultEmail));
subjetText.setText(sharedPreferences.getString(SaveReplyText.subjectEditTextKey, ""));
commentText.setText(sharedPreferences.getString(SaveReplyText.commentEditTextKey, ""));
nameText.addTextChangedListener(new SaveReplyText(sharedPreferences, SaveReplyText.nameEditTextKey));
emailText.addTextChangedListener(new SaveReplyText(sharedPreferences, SaveReplyText.emailEditTextKey));
subjetText.addTextChangedListener(new SaveReplyText(sharedPreferences, SaveReplyText.subjectEditTextKey));
commentText.addTextChangedListener(new SaveReplyText(sharedPreferences, SaveReplyText.commentEditTextKey));
sageBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
reply.sage = isChecked;
}
});
if (replyNo != null){
if (commentText.getText().toString().equals("")){
commentText.append(">>" + replyNo + "\n");
} else {
commentText.append("\n>>" + replyNo + "\n");
}
}
commentText.requestFocus();
setHasOptionsMenu(true);
return view;
}
private void setActionBarTitle(String title){
getActivity().setTitle(title);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.menu_post_comment_activity, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_attach_file){
if (reply.filePath.size() < 5) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Util.REQUEST_STORAGE_PERMISSION);
} else {
selectFile();
}
} else {
Snackbar.make(getView(), "Maximum amount of attachments reached", Snackbar.LENGTH_LONG).show();
}
}
if (id == R.id.action_submit && !isPosting){
isPosting = true;
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progress_bar);
progressBar.setVisibility(View.VISIBLE);
EditText nameText = (EditText) getActivity().findViewById(R.id.post_comment_editText_name);
EditText emailText = (EditText) getActivity().findViewById(R.id.post_comment_editText_email);
EditText subjectText = (EditText) getActivity().findViewById(R.id.post_comment_editText_subject);
EditText commentText = (EditText) getActivity().findViewById(R.id.post_comment_editText_comment);
EditText captchaText = (EditText) getActivity().findViewById(R.id.post_comment_captcha_editText);
ImageView captchaImage = (ImageView) getActivity().findViewById(R.id.post_comment_captcha_image);
reply.name = nameText.getText().toString();
reply.email = emailText.getText().toString();
reply.subject = subjectText.getText().toString();
reply.comment = commentText.getText().toString();
reply.captchaText = captchaText.getText().toString();
if (captchaImage.getTag() != null){
reply.captchaCookie = captchaImage.getTag().toString();
}
reply.resto = resto;
reply.board = boardName;
reply.password = SettingsHelper.getPostPassword(getContext());
networkHelper.postReply(getActivity(), reply, sharedPreferences, new JsonParser(), new InfiniteDbHelper(getActivity()), getView());
}
return super.onOptionsItemSelected(item);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("filePath", reply.filePath);
}
public static void finishedPosting(){
isPosting = false;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case Util.REQUEST_STORAGE_PERMISSION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
selectFile();
} else {
Snackbar.make(getView(), "Requires Permission", Snackbar.LENGTH_LONG).show();
}
break;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
private void removeFile() {
reply.filePath.clear();
}
private void selectFile() {
boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat) {
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,FILE_SELECT_CODE);
} else {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent,FILE_SELECT_CODE);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FILE_SELECT_CODE && resultCode == Activity.RESULT_OK) {
String filePath = getPath(getActivity(), data.getData());
if (filePath == null){
Snackbar.make(getView(), "Could not retrieve file", Snackbar.LENGTH_LONG).show();
} else {
reply.filePath.add(filePath);
addAttachmentPreview(filePath, getView());
}
}
}
private void addAttachmentPreview(final String filePath, View layout) {
final LinearLayout view = (LinearLayout) layout.findViewById(R.id.post_comment_container);
final View card = View.inflate(getActivity(), R.layout.card_reply_attachment, null);
ImageView imagePreview = (ImageView) card.findViewById(R.id.reply_attachment_image);
TextView filePathTextView = (TextView) card.findViewById(R.id.reply_attachment_path);
ImageButton deleteAttachment = (ImageButton) card.findViewById(R.id.reply_delete_attachment);
Ion.with(imagePreview)
.load(filePath)
.withBitmapInfo();
filePathTextView.setText(filePath);
deleteAttachment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
reply.filePath.remove(filePath);
view.removeView(card);
}
});
view.addView(card);
}
//https://stackoverflow.com/questions/20067508/get-real-path-from-uri-android-kitkat-new-storage-access-framework
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @author paulburke
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
private static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
private static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}