package me.ccrama.redditslide.Activities;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.wuman.jreadability.Readability;
import org.apache.commons.lang3.StringEscapeUtils;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.ccrama.redditslide.Constants;
import me.ccrama.redditslide.R;
import me.ccrama.redditslide.Reddit;
import me.ccrama.redditslide.SpoilerRobotoTextView;
import me.ccrama.redditslide.Visuals.Palette;
public class ReaderMode extends BaseActivityAnim {
public static final String EXTRA_URL = "url";
public static final String EXTRA_COLOR = "color";
public static String html;
SpoilerRobotoTextView v;
String url;
@Override
public void onCreate(Bundle savedInstanceState) {
overrideSwipeFromAnywhere();
super.onCreate(savedInstanceState);
applyColorTheme("");
setContentView(R.layout.activity_reader);
int subredditColor = getIntent().getExtras().getInt(EXTRA_COLOR, Palette.getDefaultColor());
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
setupAppBar(R.id.toolbar, "", true, subredditColor, R.id.appbar);
if (getIntent().hasExtra("url")) {
url = getIntent().getExtras().getString(EXTRA_URL, "");
((Toolbar) findViewById(R.id.toolbar)).setTitle(url);
}
v = (SpoilerRobotoTextView) findViewById(R.id.body);
final SwipeRefreshLayout mSwipeRefreshLayout =
((SwipeRefreshLayout) ReaderMode.this.findViewById(R.id.refresh));
mSwipeRefreshLayout.setColorSchemeColors(Palette.getColors("", this));
//If we use 'findViewById(R.id.header).getMeasuredHeight()', 0 is always returned.
//So, we estimate the height of the header in dp.
mSwipeRefreshLayout.setProgressViewOffset(false,
Constants.SINGLE_HEADER_VIEW_OFFSET - Constants.PTR_OFFSET_TOP,
Constants.SINGLE_HEADER_VIEW_OFFSET + Constants.PTR_OFFSET_BOTTOM);
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});
new AsyncGetArticle().execute();
}
private void display(String title, String web) {
v.setTextHtml(web, "nosub");
if (title != null && !title.isEmpty()) {
((Toolbar) findViewById(R.id.toolbar)).setTitle(title);
} else {
int index = v.getText().toString().indexOf("\n");
if (index < 0) {
index = 0;
}
((Toolbar) findViewById(R.id.toolbar)).setTitle(
v.getText().toString().substring(0, index));
}
}
public class AsyncGetArticle extends AsyncTask<Void, Void, Void> {
String articleText;
String title;
@Override
protected Void doInBackground(Void... params) {
try {
if (url != null) {
URL url = new URL(ReaderMode.this.url);
URLConnection con = url.openConnection();
Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
Matcher m = p.matcher(con.getContentType());
/* If Content-Type doesn't match this pre-conception, choose default and
* hope for the best. */
String charset = m.matches() ? m.group(1) : "ISO-8859-1";
Reader r = new InputStreamReader(con.getInputStream(), charset);
StringBuilder buf = new StringBuilder();
while (true) {
int ch = r.read();
if (ch < 0) break;
buf.append((char) ch);
}
html = buf.toString();
ReadabilityWrapper readability = new ReadabilityWrapper(html); // URL
readability.init();
title = readability.getArticleTitle().text();
articleText = readability.outerHtml();
} else {
Readability readability =
new Readability(StringEscapeUtils.unescapeJava(html)); // URL
readability.init();
articleText = readability.outerHtml();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
((SwipeRefreshLayout) ReaderMode.this.findViewById(R.id.refresh)).setRefreshing(false);
((SwipeRefreshLayout) ReaderMode.this.findViewById(R.id.refresh)).setEnabled(false);
if (articleText != null) {
display(title, articleText);
} else {
new AlertDialogWrapper.Builder(ReaderMode.this).setTitle(
R.string.internal_browser_extracting_error)
.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNeutralButton("Open in web view",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(ReaderMode.this, Website.class);
i.putExtra(Website.EXTRA_URL, url);
startActivity(i);
finish();
}
})
.setCancelable(false)
.show();
}
}
@Override
protected void onPreExecute() {
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
if (url != null) {
inflater.inflate(R.menu.menu_reader, menu);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.web:
Intent i = new Intent(this, Website.class);
i.putExtra(Website.EXTRA_URL, url);
ReaderMode.this.startActivity(i);
finish();
return true;
case R.id.share:
Reddit.defaultShareText(
((Toolbar) findViewById(R.id.toolbar)).getTitle().toString(), url,
ReaderMode.this);
return true;
}
return false;
}
public static class ReadabilityWrapper extends Readability {
public ReadabilityWrapper(String html) {
super(html);
}
public ReadabilityWrapper(String html, String baseUri) {
super(html, baseUri);
}
public ReadabilityWrapper(File in, String charsetName, String baseUri) throws IOException {
super(in, charsetName, baseUri);
}
public ReadabilityWrapper(URL url, int timeoutMillis) throws IOException {
super(url, timeoutMillis);
}
public ReadabilityWrapper(Document doc) {
super(doc);
}
@Override
public Element getArticleTitle() {
return super.getArticleTitle();
}
}
}