/*
This file is part of RateBeer For Android.
RateBeer for Android 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.
RateBeer for Android 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 RateBeer for Android. If not, see
<http://www.gnu.org/licenses/>.
*/
package com.ratebeer.android.gui.fragments;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.commonsware.cwac.merge.MergeAdapter;
import com.googlecode.androidannotations.annotations.AfterViews;
import com.googlecode.androidannotations.annotations.EFragment;
import com.googlecode.androidannotations.annotations.FragmentArg;
import com.googlecode.androidannotations.annotations.InstanceState;
import com.googlecode.androidannotations.annotations.OptionsItem;
import com.googlecode.androidannotations.annotations.OptionsMenu;
import com.googlecode.androidannotations.annotations.OrmLiteDao;
import com.googlecode.androidannotations.annotations.ViewById;
import com.j256.ormlite.dao.Dao;
import com.ratebeer.android.R;
import com.ratebeer.android.api.ApiMethod;
import com.ratebeer.android.api.CommandFailureResult;
import com.ratebeer.android.api.CommandSuccessResult;
import com.ratebeer.android.api.command.DeleteBeerMailCommand;
import com.ratebeer.android.api.command.GetBeerMailPartCommand;
import com.ratebeer.android.api.command.GetBeerMailPartCommand.MailPart;
import com.ratebeer.android.app.persistance.BeerMail;
import com.ratebeer.android.app.persistance.DatabaseHelper;
import com.ratebeer.android.gui.components.BeermailService;
import com.ratebeer.android.gui.components.RateBeerFragment;
import com.ratebeer.android.gui.components.helpers.ArrayAdapter;
import com.ratebeer.android.gui.fragments.ConfirmDialogFragment.OnDialogResult;
@EFragment(R.layout.fragment_mailview)
@OptionsMenu({ R.menu.refresh, R.menu.mailview })
public class MailViewFragment extends RateBeerFragment {
@FragmentArg
@InstanceState
protected BeerMail mail;
@ViewById
protected ListView parts;
private TextView originalBody;
private MailPartAdapter repliesAdapter;
private DateFormat dateFormat;
@OrmLiteDao(helper = DatabaseHelper.class, model = BeerMail.class)
Dao<BeerMail, Long> beerMailDao;
public MailViewFragment() {
}
public static MailViewFragment buildFromExtras(Bundle extras) {
// Assume there is an extra containing the BeerMail object
return MailViewFragment_.builder().mail((BeerMail) extras.getParcelable(BeermailService.EXTRA_MAIL)).build();
}
@AfterViews
public void init() {
if (mail == null)
return;
dateFormat = android.text.format.DateFormat.getDateFormat(getActivity());
parts.setAdapter(new MailViewAdapter());
parts.setItemsCanFocus(true);
// If the body text was already loaded earlier, then it was stored in the database and we can show it now
if (mail.getBody() != null) {
updateBodyText();
}
// Load the body text (original message) from the server, even when it was stored because this call also markes
// the message as read
execute(new GetBeerMailPartCommand(getUser(), mail.getMessageId(), false));
// Always retrieve the replies from the server; these are not stored in the database
execute(new GetBeerMailPartCommand(getUser(), mail.getMessageId(), true));
// Also set this mail to read (which should already be done on the server by now)
mail.setIsRead(true);
try {
beerMailDao.update(mail);
} catch (SQLException e) {
Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME,
"Cannot write to database; wanted to save the read status of beer mail " + mail.getMessageId());
}
}
@OptionsItem(R.id.menu_reply)
protected void onReply() {
load(SendMailFragment_.buildReplyFromExisting(mail));
}
@OptionsItem(R.id.menu_delete)
protected void onDelete() {
// ASk to confirm the removal of this mail
new ConfirmDialogFragment(new OnDialogResult() {
@Override
public void onConfirmed() {
if (getActivity() != null) {
execute(new DeleteBeerMailCommand(getUser(), mail));
}
}
}, R.string.mail_confirmdelete, mail.getSenderName()).show(getFragmentManager(), "dialog");
}
@OptionsItem(R.id.menu_refresh)
protected void onRefreshScreen() {
// See if there are new replies to this beer mail
execute(new GetBeerMailPartCommand(getUser(), mail.getMessageId(), true));
}
protected OnClickListener onSenderClick = new OnClickListener() {
@Override
public void onClick(View v) {
load(UserViewFragment_.builder().userId(mail.getSenderId()).userName(mail.getSenderName()).build());
}
};
private void updateBodyText() {
originalBody.setMovementMethod(LinkMovementMethod.getInstance());
try {
originalBody.setText(Html.fromHtml(mail.getBody().replace("\n", "<br />")));
} catch (Exception e) {
// This can happen if the mail is very long, in which case Html.fromHtml throws a RuntimeException
// As a fallback, don't parse the body as HTML but print the plain text instead
originalBody.setText(mail.getBody().replace("<br />", "\n"));
}
}
private void updateReplies(List<MailPart> parts) {
repliesAdapter.replace(parts);
}
@Override
public void onTaskSuccessResult(CommandSuccessResult result) {
if (result.getCommand().getMethod() == ApiMethod.DeleteBeerMail) {
DeleteBeerMailCommand dbmCommand = (DeleteBeerMailCommand) result.getCommand();
// Remove the mail from the database and close the screen
try {
beerMailDao.delete(dbmCommand.getMail());
getFragmentManager().popBackStack();
} catch (SQLException e) {
publishException(null, getString(R.string.mail_notavailable));
}
} else if (result.getCommand().getMethod() == ApiMethod.GetBeerMailPart) {
GetBeerMailPartCommand gbmpCommand = (GetBeerMailPartCommand) result.getCommand();
if (gbmpCommand.fetchReplies()) {
// We performed this command to get the replies to an original beer mail
updateReplies(gbmpCommand.getParts());
} else {
// We performed this command to get the mail body text (the first message)
try {
// Update the database and show the received body text
if (gbmpCommand.getParts().size() == 1)
mail.updateBody(gbmpCommand.getParts().get(0).body);
beerMailDao.update(mail);
updateBodyText();
} catch (SQLException e) {
Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME,
"Cannot write to database; wanted to save the body text of beer mail "
+ mail.getMessageId());
}
}
}
}
@Override
public void onTaskFailureResult(CommandFailureResult result) {
publishException(null, result.getException());
}
private class MailViewAdapter extends MergeAdapter {
public MailViewAdapter() {
// Add the mail header
TextView subjectText = (TextView) getActivity().getLayoutInflater().inflate(R.layout.list_item_mailheader,
null);
addView(subjectText);
subjectText.setText(mail.getSubject());
// Add the original, first message and show the sender text on its button
View original = getActivity().getLayoutInflater().inflate(R.layout.list_item_mailpart, null);
addView(original);
Button originalSender = (Button) original.findViewById(R.id.sender);
originalBody = (TextView) original.findViewById(R.id.body);
String dateText = "";
try {
if (mail.getSent() != null) {
dateText = "\n" + dateFormat.format(mail.getSent());
}
} catch (Exception e) {
// Cannot format date; ignore and don't show instead
}
originalSender.setText(getString(R.string.app_by, mail.getSenderName()) + dateText);
originalSender.setOnClickListener(onSenderClick);
// Set the list of replies
repliesAdapter = new MailPartAdapter(getActivity(), new ArrayList<MailPart>());
addAdapter(repliesAdapter);
}
}
private class MailPartAdapter extends ArrayAdapter<MailPart> {
public MailPartAdapter(Context context, List<MailPart> objects) {
super(context, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the right view, using a ViewHolder
ViewHolder holder;
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_mailpart, null);
holder = new ViewHolder();
holder.sender = (TextView) convertView.findViewById(R.id.sender);
holder.body = (TextView) convertView.findViewById(R.id.body);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Bind the data
<<<<<<< HEAD
MailPart item = getItem(position);
=======
final MailPart item = getItem(position);
>>>>>>> 9cb2b20cee7ae90e7a5ea61c0ebff4e0c86a6dd6
if (getActivity() != null) {
String dateText = "";
try {
if (mail.getSent() != null) {
dateText = "\n" + dateFormat.format(item.sent);
}
} catch (Exception e) {
// Cannot format date; ignore and don't show instead
}
<<<<<<< HEAD
holder.sender.setText(getString(R.string.app_by, mail.getSenderName()) + dateText);
holder.body.setText(item.body);
// TODO: Add click listener
=======
holder.sender.setText(getString(R.string.app_by, item.userName) + dateText);
holder.body.setText(item.body);
holder.sender.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
load(UserViewFragment_.builder().userId(item.sourceUserId).userName(item.userName)
.build());
}
});
>>>>>>> 9cb2b20cee7ae90e7a5ea61c0ebff4e0c86a6dd6
}
return convertView;
}
}
protected static class ViewHolder {
TextView sender, body;
}
}