Browse Source

Work in progress: summary tab completed

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
cfd19618d7
  1. 172
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
  2. 143
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileParser.java
  3. 59
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
  4. 15
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  5. 2
      app/src/main/res/layout-v21/activity_profile.xml
  6. 2
      app/src/main/res/layout/activity_profile.xml
  7. 7
      app/src/main/res/layout/profile_fragment_latest_posts_row.xml
  8. 43
      app/src/main/res/layout/profile_fragment_summary.xml

172
app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java

@ -2,21 +2,19 @@ package gr.thmmy.mthmmy.activities.profile;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.res.ResourcesCompat; import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.util.Log;
import android.view.View; import android.view.View;
import android.webkit.WebView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -25,64 +23,65 @@ import com.squareup.picasso.Picasso;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.base.BaseActivity;
import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment;
import gr.thmmy.mthmmy.utils.CircleTransform; import gr.thmmy.mthmmy.utils.CircleTransform;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mthmmy.utils.Report; import mthmmy.utils.Report;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.PERSONAL_TEXT_INDEX;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.THUMBNAIL_URL_INDEX;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.USERNAME_INDEX;
import static gr.thmmy.mthmmy.activities.profile.ProfileParser.parseProfileSummary;
import static gr.thmmy.mthmmy.session.SessionManager.LOGGED_IN;
/** /**
* Activity for user's profile. When creating an Intent of this activity you need to bundle a <b>String</b> * Activity for user profile. When creating an Intent of this activity you need to bundle a <b>String</b>
* containing this user's profile url using the key {@link #EXTRAS_PROFILE_URL}. * containing this user's profile url using the key {@link #BUNDLE_PROFILE_URL}, a <b>String</b> containing
* this user's avatar url and a <b>String</b> containing the username.
*/ */
public class ProfileActivity extends BaseActivity { public class ProfileActivity extends BaseActivity {
//Graphic element variables //Graphics
private ImageView userThumbnail; private TextView personalTextView;
private TextView userName;
private TextView personalText;
private MaterialProgressBar progressBar; private MaterialProgressBar progressBar;
private FloatingActionButton replyFAB; private FloatingActionButton replyFAB;
private ViewPager viewPager; private ViewPager viewPager;
//Other variables and constants
//Other variables
/** /**
* Debug Tag for logging debug output to LogCat * Debug Tag for logging debug output to LogCat
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static final String TAG = "ProfileActivity"; private static final String TAG = "ProfileActivity";
static String PACKAGE_NAME;
/** /**
* The key to use when putting profile's url String to {@link ProfileActivity}'s Bundle. * The key to use when putting profile's url String to {@link ProfileActivity}'s Bundle.
*/ */
public static final String EXTRAS_PROFILE_URL = "PROFILE_URL"; public static final String BUNDLE_PROFILE_URL = "PROFILE_URL";
/** /**
* {@link ArrayList} of Strings used to hold profile's information. Data are added in {@link ProfileTask}. * The key to use when putting user's thumbnail url String to {@link ProfileActivity}'s Bundle.
* If user doesn't have a thumbnail put an empty string.
*/ */
private ArrayList<String> parsedProfileData; public static final String BUNDLE_THUMBNAIL_URL = "THUMBNAIL_URL";
private ProfileTask profileTask; /**
* The key to use when putting username String to {@link ProfileActivity}'s Bundle.
*/
public static final String BUNDLE_USERNAME = "USERNAME";
private static final int THUMBNAIL_SIZE = 200; private static final int THUMBNAIL_SIZE = 200;
private ProfileTask profileTask;
private String personalText;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile); setContentView(R.layout.activity_profile);
PACKAGE_NAME = getApplicationContext().getPackageName();
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
String thumbnailUrl = extras.getString(BUNDLE_THUMBNAIL_URL);
String username = extras.getString(BUNDLE_USERNAME);
//Initializes graphic elements //Initializes graphic elements
toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar = (Toolbar) findViewById(R.id.toolbar);
@ -97,9 +96,24 @@ public class ProfileActivity extends BaseActivity {
progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar);
userThumbnail = (ImageView) findViewById(R.id.user_thumbnail); ImageView thumbnailView = (ImageView) findViewById(R.id.user_thumbnail);
userName = (TextView) findViewById(R.id.profile_activity_username); if (thumbnailUrl != null)
personalText = (TextView) findViewById(R.id.profile_activity_personal_text); //noinspection ConstantConditions
Picasso.with(this)
.load(thumbnailUrl)
.resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE)
.centerCrop()
.error(ResourcesCompat.getDrawable(this.getResources()
, R.drawable.ic_default_user_thumbnail, null))
.placeholder(ResourcesCompat.getDrawable(this.getResources()
, R.drawable.ic_default_user_thumbnail, null))
.transform(new CircleTransform())
.into(thumbnailView);
TextView usernameView = (TextView) findViewById(R.id.profile_activity_username);
usernameView.setText(username);
personalTextView = (TextView) findViewById(R.id.profile_activity_personal_text);
viewPager = (ViewPager) findViewById(R.id.profile_tab_container);
replyFAB = (FloatingActionButton) findViewById(R.id.profile_fab); //TODO hide fab while logged out replyFAB = (FloatingActionButton) findViewById(R.id.profile_fab); //TODO hide fab while logged out
replyFAB.setEnabled(false); replyFAB.setEnabled(false);
@ -131,10 +145,8 @@ public class ProfileActivity extends BaseActivity {
} }
}); });
//Gets info
parsedProfileData = new ArrayList<>();
profileTask = new ProfileTask(); profileTask = new ProfileTask();
profileTask.execute(extras.getString(EXTRAS_PROFILE_URL)); //Attempt data parsing profileTask.execute(extras.getString(BUNDLE_PROFILE_URL)); //Attempt data parsing
} }
@Override @Override
@ -145,19 +157,19 @@ public class ProfileActivity extends BaseActivity {
} }
/** /**
* An {@link AsyncTask} that handles asynchronous fetching of a profile page and parsing it's * An {@link AsyncTask} that handles asynchronous fetching of a profile page and parsing this
* data. {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #populateLayout()} * user's personal text.
* to build graphics. * <p>ProfileTask's {@link AsyncTask#execute execute} method needs a profile's url as String
* <p> * parameter!</p>
* <p>Calling ProfileSummaryTask's {@link AsyncTask#execute execute} method needs to have profile's url
* as String parameter!</p>
*/ */
public class ProfileTask extends AsyncTask<String, Void, Boolean> { public class ProfileTask extends AsyncTask<String, Void, Boolean> {
//Class variables //Class variables
/** /**
* Debug Tag for logging debug output to LogCat * Debug Tag for logging debug output to LogCat
*/ */
private static final String TAG = "TopicTask"; //Separate tag for AsyncTask @SuppressWarnings("unused")
private static final String TAG = "ProfileTask"; //Separate tag for AsyncTask
Document profilePage;
protected void onPreExecute() { protected void onPreExecute() {
progressBar.setVisibility(ProgressBar.VISIBLE); progressBar.setVisibility(ProgressBar.VISIBLE);
@ -165,7 +177,6 @@ public class ProfileActivity extends BaseActivity {
} }
protected Boolean doInBackground(String... profileUrl) { protected Boolean doInBackground(String... profileUrl) {
Document document;
String pageUrl = profileUrl[0] + ";wap"; //Profile's page wap url String pageUrl = profileUrl[0] + ";wap"; //Profile's page wap url
Request request = new Request.Builder() Request request = new Request.Builder()
@ -173,10 +184,18 @@ public class ProfileActivity extends BaseActivity {
.build(); .build();
try { try {
Response response = client.newCall(request).execute(); Response response = client.newCall(request).execute();
document = Jsoup.parse(response.body().string()); profilePage = Jsoup.parse(response.body().string());
//long parseStartTime = System.nanoTime(); { //Finds personal text
parsedProfileData = parseProfileSummary(document); Element tmpEl = profilePage.select("td.windowbg:nth-child(2)").first();
//long parseEndTime = System.nanoTime(); if (tmpEl != null) {
personalText = tmpEl.text().trim();
} else {
//Should never get here!
//Something is wrong.
Report.e(TAG, "An error occurred while trying to find profile's personal text.");
personalText = null;
}
}
return true; return true;
} catch (SSLHandshakeException e) { } catch (SSLHandshakeException e) {
Report.w(TAG, "Certificate problem (please switch to unsafe connection)."); Report.w(TAG, "Certificate problem (please switch to unsafe connection).");
@ -194,36 +213,55 @@ public class ProfileActivity extends BaseActivity {
} }
//Parse was successful //Parse was successful
progressBar.setVisibility(ProgressBar.INVISIBLE); progressBar.setVisibility(ProgressBar.INVISIBLE);
populateLayout();
if (personalText != null) {
personalTextView.setVisibility(View.VISIBLE);
personalTextView.setText(personalText);
} else {
personalTextView.setVisibility(View.GONE);
}
setupViewPager(viewPager, profilePage);
TabLayout tabLayout = (TabLayout) findViewById(R.id.profile_tabs);
tabLayout.setupWithViewPager(viewPager);
} }
} }
/** /**
* Simple method that builds the UI of a {@link ProfileActivity}. * Simple method that sets up the {@link ViewPager} of a {@link ProfileActivity}
* <p>Use this method <b>only after</b> parsing profile's data with {@link ProfileTask} as it * @param viewPager the ViewPager to be setup
* reads from {@link #parsedProfileData}</p> * @param profilePage this profile's parsed page
*/ */
private void populateLayout() { private void setupViewPager(ViewPager viewPager, Document profilePage) {
if (parsedProfileData.get(THUMBNAIL_URL_INDEX) != null) ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
//noinspection ConstantConditions adapter.addFrag(SummaryFragment.newInstance(profilePage), "SUMMARY");
Picasso.with(this) //adapter.addFrag(new );
.load(parsedProfileData.get(THUMBNAIL_URL_INDEX)) //adapter.addFrag(new );
.resize(THUMBNAIL_SIZE, THUMBNAIL_SIZE) viewPager.setAdapter(adapter);
.centerCrop() }
.error(ResourcesCompat.getDrawable(this.getResources()
, R.drawable.ic_default_user_thumbnail, null))
.placeholder(ResourcesCompat.getDrawable(this.getResources()
, R.drawable.ic_default_user_thumbnail, null))
.transform(new CircleTransform())
.into(userThumbnail);
userName.setText(parsedProfileData.get(USERNAME_INDEX)); class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
if (parsedProfileData.get(PERSONAL_TEXT_INDEX) != null) { ViewPagerAdapter(FragmentManager manager) {
personalText.setVisibility(View.VISIBLE); super(manager);
personalText.setText(parsedProfileData.get(PERSONAL_TEXT_INDEX)); }
} else { @Override
personalText.setVisibility(View.GONE); public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
} }
} }
} }

143
app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileParser.java

@ -1,143 +0,0 @@
package gr.thmmy.mthmmy.activities.profile;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.Objects;
import mthmmy.utils.Report;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.PACKAGE_NAME;
/**
* Singleton used for parsing user's profile.
* <p>Class contains the methods:<ul><li>{@link #parseProfileSummary(Document)}</li>
* </ul></p>
*/
class ProfileParser {
/**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "ProfileParser";
/**
* Index of user's thumbnail url in parsed information ArrayList
* <p><b>Not the url itself!</b></p>
*/
static final int THUMBNAIL_URL_INDEX = 0;
/**
* Index of user's username in parsed information ArrayList
* <p><b>Not the username itself!</b></p>
*/
static final int USERNAME_INDEX = 1;
/**
* Index of user's personal text in parsed information ArrayList
* <p><b>Not the text itself!</b></p>
*/
static final int PERSONAL_TEXT_INDEX = 2;
/**
* Returns an {@link ArrayList} of {@link String}s. This method is used to parse all available
* information in a user profile.
* <p>
* User's thumbnail image url, username and personal text are placed at Array's indexes defined
* by public constants THUMBNAIL_URL_INDEX, USERNAME_INDEX and PERSONAL_TEXT_INDEX respectively.
*
* @param profile {@link Document} object containing this profile's source code
* @return ArrayList containing this profile's parsed information
* @see org.jsoup.Jsoup Jsoup
*/
static ArrayList<String> parseProfileSummary(Document profile) {
//Method's variables
ArrayList<String> parsedInformation = new ArrayList<>();
//Contains all summary's rows
Elements summaryRows = profile.select(".bordercolor > tbody:nth-child(1) > tr:nth-child(2) tr");
{ //Finds thumbnail's url
Element tmpEl = profile.select(".bordercolor img.avatar").first();
if (tmpEl != null)
parsedInformation.add(THUMBNAIL_URL_INDEX, tmpEl.attr("abs:src"));
else //User doesn't have an avatar
parsedInformation.add(THUMBNAIL_URL_INDEX, null);
}
{ //Finds username
Element tmpEl = summaryRows.first();
if (tmpEl != null) {
parsedInformation.add(USERNAME_INDEX, tmpEl.select("td").get(1).text());
} else {
//Should never get here!
//Something is wrong.
Report.e(PACKAGE_NAME + "." + TAG, "An error occurred while trying to find profile's username.");
parsedInformation.add(USERNAME_INDEX, null);
}
}
{ //Finds personal text
Element tmpEl = profile.select("td.windowbg:nth-child(2)").first();
if (tmpEl != null) {
String tmpPersonalText = tmpEl.text().trim();
parsedInformation.add(PERSONAL_TEXT_INDEX, tmpPersonalText);
} else {
//Should never get here!
//Something is wrong.
Report.e(PACKAGE_NAME + "." + TAG, "An error occurred while trying to find profile's personal text.");
parsedInformation.add(PERSONAL_TEXT_INDEX, null);
}
}
for (Element row : summaryRows) {
String rowText = row.text(), pHtml = "";
//Horizontal rule rows
if (row.select("td").size() == 1)
pHtml = "";
else if (rowText.contains("Signature") || rowText.contains("Υπογραφή")) {
//This needs special handling since it may have css
{ //Fix embedded videos
Elements noembedTag = row.select("noembed");
ArrayList<String> embededVideosUrls = new ArrayList<>();
for (Element _noembed : noembedTag) {
embededVideosUrls.add(_noembed.text().substring(_noembed.text()
.indexOf("href=\"https://www.youtube.com/watch?") + 38
, _noembed.text().indexOf("target") - 2));
}
pHtml = row.html();
int tmp_counter = 0;
while (pHtml.contains("<embed")) {
if (tmp_counter > embededVideosUrls.size())
break;
pHtml = pHtml.replace(
pHtml.substring(pHtml.indexOf("<embed"), pHtml.indexOf("/noembed>") + 9)
, "<div class=\"embedded-video\">"
+ "<a href=\"https://www.youtube.com/"
+ embededVideosUrls.get(tmp_counter) + "\" target=\"_blank\">"
+ "<img src=\"https://img.youtube.com/vi/"
+ embededVideosUrls.get(tmp_counter) + "/default.jpg\" alt=\"\" border=\"0\">"
+ "</a>"
//+ "<img class=\"embedded-video-play\" src=\"http://www.youtube.com/yt/brand/media/image/YouTube_light_color_icon.png\">"
+ "</div>");
}
}
//Add stuff to make it work in WebView
//style.css
pHtml = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />" + pHtml);
} else if (!rowText.contains("Name") && !rowText.contains("Όνομα")) { //Don't add username twice
if (Objects.equals(row.select("td").get(1).text(), ""))
continue;
//Style parsed information with html
pHtml = "<b>" + row.select("td").first().text() + "</b> "
+ row.select("td").get(1).text();
}
parsedInformation.add(pHtml);
}
return parsedInformation;
}
}

59
app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java

@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.activities.profile.summary;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Html; import android.text.Html;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -21,45 +22,48 @@ import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.base.BaseFragment;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mthmmy.utils.Report; import mthmmy.utils.Report;
/** /**
* A {@link BaseFragment} subclass. * Use the {@link SummaryFragment#newInstance} factory method to create an instance of this fragment.
* Use the {@link SummaryFragment#newInstance} factory method to
* create an instance of this fragment.
*/ */
public class SummaryFragment extends BaseFragment { public class SummaryFragment extends Fragment {
static final String PROFILE_DOCUMENT = "PROFILE_DOCUMENT"; /**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "SummaryFragment"; private static final String TAG = "SummaryFragment";
/**
* The key to use when putting profile's source code String to {@link SummaryFragment}'s Bundle.
*/
static final String PROFILE_DOCUMENT = "PROFILE_DOCUMENT";
/** /**
* {@link ArrayList} of Strings used to hold profile's information. Data are added in {@link ProfileActivity.ProfileTask}. * {@link ArrayList} of Strings used to hold profile's information. Data are added in {@link ProfileActivity.ProfileTask}.
*/ */
private ArrayList<String> parsedProfileSummaryData;
/**
* A {@link Document} holding this profile's source code.
*/
private Document profileSummaryDocument; private Document profileSummaryDocument;
private ProfileSummaryTask profileSummaryTask; private ProfileSummaryTask profileSummaryTask;
private ArrayList<String> parsedProfileSummaryData;
private LinearLayout mainContent; private LinearLayout mainContent;
private MaterialProgressBar progressBar;
public SummaryFragment() { public SummaryFragment() {
// Required empty public constructor // Required empty public constructor
this.profileSummaryDocument = Jsoup.parse(getArguments().getString(PROFILE_DOCUMENT));
} }
/** /**
* Use ONLY this factory method to create a new instance of * Use ONLY this factory method to create a new instance of this fragment using the provided
* this fragment using the provided parameters. * parameters.
* *
* @param profileSummaryDocument a {@link Document} containing this profile's parsed page
* @return A new instance of fragment Summary. * @return A new instance of fragment Summary.
*/ */
public static SummaryFragment newInstance(int sectionNumber, Document profileSummaryDocument) { public static SummaryFragment newInstance(Document profileSummaryDocument) {
SummaryFragment fragment = new SummaryFragment(); SummaryFragment fragment = new SummaryFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ARG_TAG, TAG);
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putString(PROFILE_DOCUMENT, profileSummaryDocument.toString()); args.putString(PROFILE_DOCUMENT, profileSummaryDocument.toString());
fragment.setArguments(args); fragment.setArguments(args);
return fragment; return fragment;
@ -68,6 +72,7 @@ public class SummaryFragment extends BaseFragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
profileSummaryDocument = Jsoup.parse(getArguments().getString(PROFILE_DOCUMENT));
parsedProfileSummaryData = new ArrayList<>(); parsedProfileSummaryData = new ArrayList<>();
} }
@ -77,7 +82,6 @@ public class SummaryFragment extends BaseFragment {
if (parsedProfileSummaryData.isEmpty()) { if (parsedProfileSummaryData.isEmpty()) {
profileSummaryTask = new ProfileSummaryTask(); profileSummaryTask = new ProfileSummaryTask();
profileSummaryTask.execute(profileSummaryDocument); profileSummaryTask.execute(profileSummaryDocument);
} }
Report.d(TAG, "onActivityCreated"); Report.d(TAG, "onActivityCreated");
} }
@ -93,15 +97,13 @@ public class SummaryFragment extends BaseFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.profile_fragment_summary, container, false); final View rootView = inflater.inflate(R.layout.profile_fragment_summary, container, false);
progressBar = (MaterialProgressBar) rootView.findViewById(R.id.progressBar);
mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content); mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content);
populateLayout();
return rootView; return rootView;
} }
/** /**
* An {@link AsyncTask} that handles asynchronous fetching of a profile page and parsing it's * An {@link AsyncTask} that handles asynchronous parsing of a profile page's data.
* data. {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #populateLayout()} * {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #populateLayout()}
* to build graphics. * to build graphics.
* <p> * <p>
* <p>Calling ProfileSummaryTask's {@link AsyncTask#execute execute} method needs to have profile's url * <p>Calling ProfileSummaryTask's {@link AsyncTask#execute execute} method needs to have profile's url
@ -112,28 +114,20 @@ public class SummaryFragment extends BaseFragment {
/** /**
* Debug Tag for logging debug output to LogCat * Debug Tag for logging debug output to LogCat
*/ */
@SuppressWarnings("unused")
private static final String TAG = "TopicTask"; //Separate tag for AsyncTask private static final String TAG = "TopicTask"; //Separate tag for AsyncTask
protected void onPreExecute() {
progressBar.setVisibility(MaterialProgressBar.VISIBLE);
}
protected Void doInBackground(Document... profileSummaryPage) { protected Void doInBackground(Document... profileSummaryPage) {
parsedProfileSummaryData = parseProfileSummary(profileSummaryPage[0]); parsedProfileSummaryData = parseProfileSummary(profileSummaryPage[0]);
return null; return null;
} }
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
progressBar.setVisibility(MaterialProgressBar.INVISIBLE);
populateLayout(); populateLayout();
} }
/** /**
* Returns an {@link ArrayList} of {@link String}s. This method is used to parse all available * This method is used to parse all available information in a user profile.
* information in a user profile.
* <p>
* User's thumbnail image url, username and personal text are placed at Array's indexes defined
* by public constants THUMBNAIL_URL_INDEX, USERNAME_INDEX and PERSONAL_TEXT_INDEX respectively.
* *
* @param profile {@link Document} object containing this profile's source code * @param profile {@link Document} object containing this profile's source code
* @return ArrayList containing this profile's parsed information * @return ArrayList containing this profile's parsed information
@ -200,7 +194,7 @@ public class SummaryFragment extends BaseFragment {
} }
/** /**
* Simple method that builds the UI of a {@link ProfileActivity}. * Simple method that builds the UI of a {@link SummaryFragment}.
* <p>Use this method <b>only after</b> parsing profile's data with * <p>Use this method <b>only after</b> parsing profile's data with
* {@link gr.thmmy.mthmmy.activities.profile.ProfileActivity.ProfileTask} as it reads from * {@link gr.thmmy.mthmmy.activities.profile.ProfileActivity.ProfileTask} as it reads from
* {@link #parsedProfileSummaryData}</p> * {@link #parsedProfileSummaryData}</p>
@ -210,7 +204,8 @@ public class SummaryFragment extends BaseFragment {
if (profileSummaryRow.contains("Signature") if (profileSummaryRow.contains("Signature")
|| profileSummaryRow.contains("Υπογραφή")) { || profileSummaryRow.contains("Υπογραφή")) {
WebView signatureEntry = new WebView(this.getContext()); WebView signatureEntry = new WebView(this.getContext());
signatureEntry.loadDataWithBaseURL("file:///android_asset/", profileSummaryRow, "text/html", "UTF-8", null); signatureEntry.loadDataWithBaseURL("file:///android_asset/", profileSummaryRow,
"text/html", "UTF-8", null);
} }
TextView entry = new TextView(this.getContext()); TextView entry = new TextView(this.getContext());

15
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java

@ -50,7 +50,9 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mthmmy.utils.Report; import mthmmy.utils.Report;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.EXTRAS_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.base_url; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.base_url;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList;
@ -310,9 +312,14 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
if (viewProperties.get(holder.getAdapterPosition())[isUserExtraInfoVisibile]) { if (viewProperties.get(holder.getAdapterPosition())[isUserExtraInfoVisibile]) {
Intent intent = new Intent(context, ProfileActivity.class); Intent intent = new Intent(context, ProfileActivity.class);
Bundle b = new Bundle(); Bundle extras = new Bundle();
b.putString(EXTRAS_PROFILE_URL, currentPost.getProfileURL()); extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL());
intent.putExtras(b); if(currentPost.getThumbnailUrl() == null)
extras.putString(BUNDLE_THUMBNAIL_URL, "");
else
extras.putString(BUNDLE_THUMBNAIL_URL, currentPost.getThumbnailUrl());
extras.putString(BUNDLE_USERNAME, currentPost.getAuthor());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK); intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent); context.startActivity(intent);
} }

2
app/src/main/res/layout-v21/activity_profile.xml

@ -95,7 +95,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:visibility="invisible" android:visibility="invisible"
app:layout_anchor="@id/nested_scroll" app:layout_anchor="@id/profile_tab_container"
app:layout_anchorGravity="top|center" app:layout_anchorGravity="top|center"
app:mpb_indeterminateTint="@color/accent" app:mpb_indeterminateTint="@color/accent"
app:mpb_progressStyle="horizontal"/> app:mpb_progressStyle="horizontal"/>

2
app/src/main/res/layout/activity_profile.xml

@ -97,7 +97,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:visibility="invisible" android:visibility="invisible"
app:layout_anchor="@id/nested_scroll" app:layout_anchor="@id/profile_tab_container"
app:layout_anchorGravity="top|center" app:layout_anchorGravity="top|center"
app:mpb_indeterminateTint="@color/accent" app:mpb_indeterminateTint="@color/accent"
app:mpb_progressStyle="horizontal"/> app:mpb_progressStyle="horizontal"/>

7
app/src/main/res/layout/profile_fragment_latest_posts_row.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

43
app/src/main/res/layout/profile_fragment_summary.xml

@ -1,36 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nested_scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="@color/background"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:scrollbars="none">
<android.support.v4.widget.NestedScrollView <LinearLayout
android:id="@+id/nested_scroll" android:id="@+id/profile_activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/profile_activity_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progressBar"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:gravity="center"
android:indeterminate="true" android:orientation="vertical">
android:visibility="invisible" </LinearLayout>
app:mpb_indeterminateTint="@color/accent" </android.support.v4.widget.NestedScrollView>
app:mpb_progressStyle="horizontal"/>
</RelativeLayout>
Loading…
Cancel
Save