Browse Source

ProfileActivity improvements/fixes

pull/70/head
Ezerous 4 years ago
parent
commit
dad4fa8ccd
  1. 31
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
  2. 59
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java
  3. 60
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
  4. 23
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
  5. 6
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
  6. 6
      app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java
  7. 16
      app/src/main/res/layout/fragment_profile_latest_posts.xml
  8. 12
      app/src/main/res/layout/fragment_profile_stats.xml

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

@ -67,7 +67,7 @@ import static gr.thmmy.mthmmy.utils.ui.PhotoViewUtils.displayPhotoViewImage;
* this user's avatar url using the key {@link #BUNDLE_PROFILE_THUMBNAIL_URL} and a <b>String</b> containing * this user's avatar url using the key {@link #BUNDLE_PROFILE_THUMBNAIL_URL} and a <b>String</b> containing
* the username using the key {@link #BUNDLE_PROFILE_USERNAME}. * the username using the key {@link #BUNDLE_PROFILE_USERNAME}.
*/ */
public class ProfileActivity extends BaseActivity implements LatestPostsFragment.LatestPostsFragmentInteractionListener { public class ProfileActivity extends BaseActivity implements LatestPostsFragment.LatestPostsFragmentInteractionListener, LatestPostsFragment.OnLoadingListener, StatsFragment.OnLoadingListener{
/** /**
* 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.
*/ */
@ -209,6 +209,24 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
startActivity(i); startActivity(i);
} }
@Override
public void onLoadingLatestPosts(boolean loading) {
setBarVisibility(loading);
}
@Override
public void onLoadingStats(boolean loading) {
setBarVisibility(loading);
}
private void setBarVisibility (boolean visible){
if(visible)
progressBar.setVisibility(ProgressBar.VISIBLE);
else
progressBar.setVisibility(ProgressBar.INVISIBLE);
}
public void onProfileTaskStarted() { public void onProfileTaskStarted() {
progressBar.setVisibility(ProgressBar.VISIBLE); progressBar.setVisibility(ProgressBar.VISIBLE);
if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(false); if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(false);
@ -233,7 +251,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
.into(avatarView); .into(avatarView);
} }
else else
Timber.d("Will not load Glide image (invalid context)"); Timber.i("Will not load Glide image (invalid context)");
} }
/** /**
@ -336,7 +354,6 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
, Toast.LENGTH_LONG).show(); , Toast.LENGTH_LONG).show();
finish(); finish();
} else { } else {
Timber.d("Parse failed!");
Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Fatal error!\n Aborting..." Toast.makeText(BaseApplication.getInstance().getApplicationContext(), "Fatal error!\n Aborting..."
, Toast.LENGTH_LONG).show(); , Toast.LENGTH_LONG).show();
finish(); finish();
@ -358,8 +375,12 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
private void setupViewPager(ViewPager viewPager, Document profilePage) { private void setupViewPager(ViewPager viewPager, Document profilePage) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(SummaryFragment.newInstance(profilePage), "SUMMARY"); adapter.addFrag(SummaryFragment.newInstance(profilePage), "SUMMARY");
adapter.addFrag(LatestPostsFragment.newInstance(profileUrl), "LATEST POSTS"); LatestPostsFragment latestPostsFragment = LatestPostsFragment.newInstance(profileUrl);
adapter.addFrag(StatsFragment.newInstance(profileUrl), "STATS"); latestPostsFragment.setOnLoadingListener(this);
adapter.addFrag(latestPostsFragment, "LATEST POSTS");
StatsFragment statsFragment = StatsFragment.newInstance(profileUrl);
statsFragment.setOnLoadingListener(this);
adapter.addFrag(statsFragment, "STATS");
viewPager.setAdapter(adapter); viewPager.setAdapter(adapter);
} }

59
app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java

@ -19,7 +19,6 @@ import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.model.TopicSummary; import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.views.ReactiveWebView; import gr.thmmy.mthmmy.views.ReactiveWebView;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
/** /**
* {@link RecyclerView.Adapter} that can display a {@link TopicSummary} and makes a call to the * {@link RecyclerView.Adapter} that can display a {@link TopicSummary} and makes a call to the
@ -28,7 +27,6 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_EMPTY = -1; private static final int VIEW_TYPE_EMPTY = -1;
private static final int VIEW_TYPE_ITEM = 0; private static final int VIEW_TYPE_ITEM = 0;
private static final int VIEW_TYPE_LOADING = 1;
private final Context context; private final Context context;
private final LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener; private final LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener;
private final ArrayList<PostSummary> parsedTopicSummaries; private final ArrayList<PostSummary> parsedTopicSummaries;
@ -40,14 +38,10 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
this.parsedTopicSummaries = parsedTopicSummaries; this.parsedTopicSummaries = parsedTopicSummaries;
} }
interface OnLoadMoreListener {
void onLoadMore();
}
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (parsedTopicSummaries.get(position) == null && position == 0) return VIEW_TYPE_EMPTY; if (parsedTopicSummaries.get(position) == null && position == 0) return VIEW_TYPE_EMPTY;
return parsedTopicSummaries.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM; return VIEW_TYPE_ITEM;
} }
@NonNull @NonNull
@ -57,10 +51,6 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
View view = LayoutInflater.from(parent.getContext()). View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.fragment_profile_latest_posts_row, parent, false); inflate(R.layout.fragment_profile_latest_posts_row, parent, false);
return new LatestPostViewHolder(view); return new LatestPostViewHolder(view);
} else if (viewType == VIEW_TYPE_LOADING) {
View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.recycler_loading_item, parent, false);
return new LoadingViewHolder(view);
} else { // viewType == VIEW_TYPE_EMPTY } else { // viewType == VIEW_TYPE_EMPTY
View view = LayoutInflater.from(parent.getContext()). View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.fragment_profile_latest_posts_empty_message, parent, false); inflate(R.layout.fragment_profile_latest_posts_empty_message, parent, false);
@ -71,28 +61,22 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@Override @Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof LatestPostViewHolder) { PostSummary topic = parsedTopicSummaries.get(position);
PostSummary topic = parsedTopicSummaries.get(position); final LatestPostViewHolder latestPostViewHolder = (LatestPostViewHolder) holder;
final LatestPostViewHolder latestPostViewHolder = (LatestPostViewHolder) holder; latestPostViewHolder.postTitle.setText(topic.getSubject());
latestPostViewHolder.postDate.setText(topic.getDateTime());
latestPostViewHolder.postTitle.setText(topic.getSubject()); latestPostViewHolder.post.setBackgroundColor(Color.argb(1, 255, 255, 255));
latestPostViewHolder.postDate.setText(topic.getDateTime()); latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/"
latestPostViewHolder.post.setBackgroundColor(Color.argb(1, 255, 255, 255)); , topic.getPost(), "text/html", "UTF-8", null);
latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/"
, topic.getPost(), "text/html", "UTF-8", null); latestPostViewHolder.latestPostsRow.setOnClickListener(v -> {
if (interactionListener != null) {
latestPostViewHolder.latestPostsRow.setOnClickListener(v -> { // Notify the active callbacks interface (the activity, if the
if (interactionListener != null) { // fragment is attached to one) that a post has been selected.
// Notify the active callbacks interface (the activity, if the interactionListener.onLatestPostsFragmentInteraction(
// fragment is attached to one) that a post has been selected. parsedTopicSummaries.get(holder.getAdapterPosition()));
interactionListener.onLatestPostsFragmentInteraction( }
parsedTopicSummaries.get(holder.getAdapterPosition())); });
}
});
} else if (holder instanceof LoadingViewHolder) {
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
} }
@Override @Override
@ -114,13 +98,4 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
post = itemView.findViewById(R.id.post); post = itemView.findViewById(R.id.post);
} }
} }
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
final MaterialProgressBar progressBar;
LoadingViewHolder(View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.recycler_progress_bar);
}
}
} }

60
app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java

@ -5,7 +5,6 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ProgressBar;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
@ -27,7 +26,6 @@ import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.utils.parsing.ParseException; import gr.thmmy.mthmmy.utils.parsing.ParseException;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
@ -35,7 +33,7 @@ import timber.log.Timber;
/** /**
* Use the {@link LatestPostsFragment#newInstance} factory method to create an instance of this fragment. * Use the {@link LatestPostsFragment#newInstance} factory method to create an instance of this fragment.
*/ */
public class LatestPostsFragment extends BaseFragment implements LatestPostsAdapter.OnLoadMoreListener { public class LatestPostsFragment extends BaseFragment {
/** /**
* The key to use when putting profile's url String to {@link LatestPostsFragment}'s Bundle. * The key to use when putting profile's url String to {@link LatestPostsFragment}'s Bundle.
*/ */
@ -50,12 +48,13 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
private int pagesLoaded = 0; private int pagesLoaded = 0;
private String profileUrl; private String profileUrl;
private LatestPostsTask profileLatestPostsTask; private LatestPostsTask profileLatestPostsTask;
private MaterialProgressBar progressBar;
private boolean isLoadingMore; private boolean isLoadingMore;
private boolean userHasPosts = true; private boolean userHasPosts = true;
private static final int visibleThreshold = 5; private static final int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount; private int lastVisibleItem, totalItemCount;
private OnLoadingListener onLoadingListener;
public LatestPostsFragment() { public LatestPostsFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -87,16 +86,16 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
Bundle savedInstanceState) { Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_profile_latest_posts, container, false); final View rootView = inflater.inflate(R.layout.fragment_profile_latest_posts, container, false);
latestPostsAdapter = new LatestPostsAdapter(this.getContext(), fragmentInteractionListener, parsedTopicSummaries); latestPostsAdapter = new LatestPostsAdapter(this.getContext(), fragmentInteractionListener, parsedTopicSummaries);
RecyclerView mainContent = rootView.findViewById(R.id.profile_latest_posts_recycler); RecyclerView recyclerView = rootView.findViewById(R.id.profile_latest_posts_recycler);
mainContent.setAdapter(latestPostsAdapter); recyclerView.setAdapter(latestPostsAdapter);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mainContent.setLayoutManager(layoutManager); recyclerView.setLayoutManager(layoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mainContent.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
layoutManager.getOrientation()); layoutManager.getOrientation());
mainContent.addItemDecoration(dividerItemDecoration); recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setItemViewCacheSize(15);
//latestPostsAdapter.setOnLoadMoreListener(); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
mainContent.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy); super.onScrolled(recyclerView, dx, dy);
@ -110,20 +109,15 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
} }
} }
}); });
progressBar = rootView.findViewById(R.id.progressBar);
return rootView; return rootView;
} }
@Override
public void onLoadMore() { public void onLoadMore() {
if (pagesLoaded < numberOfPages) { if (pagesLoaded < numberOfPages) {
parsedTopicSummaries.add(null);
latestPostsAdapter.notifyItemInserted(parsedTopicSummaries.size() - 1);
//Load data //Load data
profileLatestPostsTask = new LatestPostsTask(); profileLatestPostsTask = new LatestPostsTask();
profileLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileUrl + ";sa=showPosts;start=" + pagesLoaded * 15); profileLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileUrl + ";sa=showPosts;start=" + pagesLoaded * 15);
++pagesLoaded; pagesLoaded++;
} }
} }
@ -148,6 +142,14 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
void onLatestPostsFragmentInteraction(PostSummary postSummary); void onLatestPostsFragmentInteraction(PostSummary postSummary);
} }
public interface OnLoadingListener {
void onLoadingLatestPosts(boolean loading);
}
public void setOnLoadingListener(OnLoadingListener onLoadingListener) {
this.onLoadingListener = onLoadingListener;
}
/** /**
* An {@link AsyncTask} that handles asynchronous fetching of a profile page and parsing this * An {@link AsyncTask} that handles asynchronous fetching of a profile page and parsing this
* user's latest posts. * user's latest posts.
@ -155,8 +157,16 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
* parameter!</p> * parameter!</p>
*/ */
private class LatestPostsTask extends AsyncTask<String, Void, Boolean> { private class LatestPostsTask extends AsyncTask<String, Void, Boolean> {
private ArrayList<PostSummary> fetchedParsedTopicSummaries;
@Override
protected void onPreExecute() { protected void onPreExecute() {
if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE); onLoadingListener.onLoadingLatestPosts(true);
}
public LatestPostsTask() {
super();
fetchedParsedTopicSummaries = new ArrayList<>();
} }
protected Boolean doInBackground(String... profileUrl) { protected Boolean doInBackground(String... profileUrl) {
@ -177,10 +187,12 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
protected void onPostExecute(Boolean result) { protected void onPostExecute(Boolean result) {
if (Boolean.FALSE.equals(result)) if (Boolean.FALSE.equals(result))
Timber.e(new ParseException("Parsing failed (latest posts)"),"ParseException"); //TODO: This is inaccurate (e.g. can also have an I/O cause) Timber.e(new ParseException("Parsing failed (latest posts)"),"ParseException"); //TODO: This is inaccurate (e.g. can also have an I/O cause)
int prevSize = parsedTopicSummaries.size();
progressBar.setVisibility(ProgressBar.INVISIBLE); parsedTopicSummaries.addAll(fetchedParsedTopicSummaries);
latestPostsAdapter.notifyItemRangeInserted(prevSize, parsedTopicSummaries.size() - prevSize);
latestPostsAdapter.notifyDataSetChanged(); latestPostsAdapter.notifyDataSetChanged();
isLoadingMore = false; isLoadingMore = false;
onLoadingListener.onLoadingLatestPosts(false);
} }
//TODO: better parse error handling (ParseException etc.) //TODO: better parse error handling (ParseException etc.)
@ -192,14 +204,10 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
latestPostsRows = latestPostsPage. latestPostsRows = latestPostsPage.
select("td:has(table:Contains(Εμφάνιση μηνυμάτων)):not([style]) > table"); select("td:has(table:Contains(Εμφάνιση μηνυμάτων)):not([style]) > table");
//Removes loading item
if (isLoadingMore)
parsedTopicSummaries.remove(parsedTopicSummaries.size() - 1);
if (!latestPostsRows.select("td:contains(Sorry, no matches were found)").isEmpty() || if (!latestPostsRows.select("td:contains(Sorry, no matches were found)").isEmpty() ||
!latestPostsRows.select("td:contains(Δυστυχώς δεν βρέθηκε τίποτα)").isEmpty()){ !latestPostsRows.select("td:contains(Δυστυχώς δεν βρέθηκε τίποτα)").isEmpty()){
userHasPosts = false; userHasPosts = false;
parsedTopicSummaries.add(null); fetchedParsedTopicSummaries.add(null);
return true; return true;
} }
@ -228,7 +236,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
//style.css //style.css
pPost = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />" + pPost); pPost = ("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />" + pPost);
parsedTopicSummaries.add(new PostSummary(pTopicUrl, pTopicTitle, pDateTime, pPost)); fetchedParsedTopicSummaries.add(new PostSummary(pTopicUrl, pTopicTitle, pDateTime, pPost));
} }
} }
return true; return true;

23
app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java

@ -8,7 +8,6 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -43,7 +42,6 @@ import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.utils.parsing.ParseException; import gr.thmmy.mthmmy.utils.parsing.ParseException;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
@ -56,7 +54,6 @@ public class StatsFragment extends Fragment {
private String profileUrl; private String profileUrl;
private ProfileStatsTask profileStatsTask; private ProfileStatsTask profileStatsTask;
private LinearLayout mainContent; private LinearLayout mainContent;
private MaterialProgressBar progressBar;
private boolean userHasPosts = true; private boolean userHasPosts = true;
private String generalStatisticsTitle = "", generalStatistics = "", postingActivityByTimeTitle = "", mostPopularBoardsByPostsTitle = "", mostPopularBoardsByActivityTitle = ""; private String generalStatisticsTitle = "", generalStatistics = "", postingActivityByTimeTitle = "", mostPopularBoardsByPostsTitle = "", mostPopularBoardsByActivityTitle = "";
@ -64,6 +61,8 @@ public class StatsFragment extends Fragment {
private final List<BarEntry> mostPopularBoardsByPosts = new ArrayList<>(), mostPopularBoardsByActivity = new ArrayList<>(); private final List<BarEntry> mostPopularBoardsByPosts = new ArrayList<>(), mostPopularBoardsByActivity = new ArrayList<>();
private final ArrayList<String> mostPopularBoardsByPostsLabels = new ArrayList<>(), mostPopularBoardsByActivityLabels = new ArrayList<>(); private final ArrayList<String> mostPopularBoardsByPostsLabels = new ArrayList<>(), mostPopularBoardsByActivityLabels = new ArrayList<>();
private OnLoadingListener onLoadingListener;
public StatsFragment() { public StatsFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -94,7 +93,6 @@ public class StatsFragment extends Fragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_profile_stats, container, false); final View rootView = inflater.inflate(R.layout.fragment_profile_stats, container, false);
mainContent = rootView.findViewById(R.id.main_content); mainContent = rootView.findViewById(R.id.main_content);
progressBar = rootView.findViewById(R.id.progressBar);
if (profileStatsTask!=null && profileStatsTask.getStatus() == AsyncTask.Status.FINISHED) if (profileStatsTask!=null && profileStatsTask.getStatus() == AsyncTask.Status.FINISHED)
populateLayout(); populateLayout();
return rootView; return rootView;
@ -117,6 +115,14 @@ public class StatsFragment extends Fragment {
profileStatsTask.cancel(true); profileStatsTask.cancel(true);
} }
public interface OnLoadingListener {
void onLoadingStats(boolean loading);
}
public void setOnLoadingListener(OnLoadingListener onLoadingListener) {
this.onLoadingListener = onLoadingListener;
}
/** /**
* An {@link AsyncTask} that handles asynchronous parsing of a profile page's data. * An {@link AsyncTask} that handles asynchronous parsing of a profile page's data.
* {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #()} * {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link #()}
@ -129,7 +135,7 @@ public class StatsFragment extends Fragment {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
progressBar.setVisibility(ProgressBar.VISIBLE); onLoadingListener.onLoadingStats(true);
} }
@Override @Override
@ -150,7 +156,7 @@ public class StatsFragment extends Fragment {
@Override @Override
protected void onPostExecute(Boolean result) { protected void onPostExecute(Boolean result) {
progressBar.setVisibility(ProgressBar.INVISIBLE); onLoadingListener.onLoadingStats(false);
if (!result) if (!result)
Timber.e(new ParseException("Parsing failed (user stats)"),"ParseException"); //TODO: This is inaccurate (e.g. can also have an I/O cause) Timber.e(new ParseException("Parsing failed (user stats)"),"ParseException"); //TODO: This is inaccurate (e.g. can also have an I/O cause)
else else
@ -221,7 +227,7 @@ public class StatsFragment extends Fragment {
} }
private void populateLayout() { private void populateLayout() {
progressBar.setVisibility(ProgressBar.VISIBLE); onLoadingListener.onLoadingStats(true);;
((TextView) mainContent.findViewById(R.id.general_statistics_title)) ((TextView) mainContent.findViewById(R.id.general_statistics_title))
.setText(generalStatisticsTitle); .setText(generalStatisticsTitle);
((TextView) mainContent.findViewById(R.id.general_statistics)) ((TextView) mainContent.findViewById(R.id.general_statistics))
@ -229,6 +235,7 @@ public class StatsFragment extends Fragment {
if (!userHasPosts) { if (!userHasPosts) {
mainContent.removeViews(2, mainContent.getChildCount() - 2); mainContent.removeViews(2, mainContent.getChildCount() - 2);
onLoadingListener.onLoadingStats(false);
return; return;
} }
@ -346,7 +353,7 @@ public class StatsFragment extends Fragment {
mostPopularBoardsByActivityData.setValueTextColor(Color.WHITE); mostPopularBoardsByActivityData.setValueTextColor(Color.WHITE);
mostPopularBoardsByActivityChart.setData(mostPopularBoardsByActivityData); mostPopularBoardsByActivityChart.setData(mostPopularBoardsByActivityData);
mostPopularBoardsByActivityChart.invalidate(); mostPopularBoardsByActivityChart.invalidate();
progressBar.setVisibility(ProgressBar.INVISIBLE); onLoadingListener.onLoadingStats(false);
} }
private class MyXAxisValueFormatter implements IAxisValueFormatter { private class MyXAxisValueFormatter implements IAxisValueFormatter {

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

@ -25,7 +25,6 @@ import java.util.Objects;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.views.ReactiveWebView; import gr.thmmy.mthmmy.views.ReactiveWebView;
import timber.log.Timber;
/** /**
* 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.
@ -69,7 +68,7 @@ public class SummaryFragment extends Fragment {
@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)); profileSummaryDocument = Jsoup.parse(requireArguments().getString(PROFILE_DOCUMENT));
parsedProfileSummaryData = new ArrayList<>(); parsedProfileSummaryData = new ArrayList<>();
} }
@ -90,7 +89,6 @@ public class SummaryFragment extends Fragment {
summaryTask = new SummaryTask(); summaryTask = new SummaryTask();
summaryTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileSummaryDocument); summaryTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, profileSummaryDocument);
} }
Timber.d("onActivityCreated");
} }
@Override @Override
@ -189,13 +187,11 @@ public class SummaryFragment extends Fragment {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
entry.setTextColor(getResources().getColor(R.color.primary_text, null)); entry.setTextColor(getResources().getColor(R.color.primary_text, null));
else else
//noinspection deprecation
entry.setTextColor(getResources().getColor(R.color.primary_text)); entry.setTextColor(getResources().getColor(R.color.primary_text));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY)); entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY));
} else { } else {
//noinspection deprecation
entry.setText(Html.fromHtml(profileSummaryRow)); entry.setText(Html.fromHtml(profileSummaryRow));
} }

6
app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java

@ -28,13 +28,11 @@ public abstract class BaseFragment extends Fragment {
@Override @Override
public void onAttach(Context context) { public void onAttach(Context context) {
super.onAttach(context); super.onAttach(context);
if (context instanceof FragmentInteractionListener) { if (context instanceof FragmentInteractionListener)
fragmentInteractionListener = (FragmentInteractionListener) context; fragmentInteractionListener = (FragmentInteractionListener) context;
else
} else {
throw new RuntimeException(context.toString() throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener"); + " must implement OnFragmentInteractionListener");
}
} }
@Override @Override

16
app/src/main/res/layout/fragment_profile_latest_posts.xml

@ -1,26 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
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:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="@color/background_light">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/profile_latest_posts_recycler" android:id="@+id/profile_latest_posts_recycler"
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:scrollbars="none"> android:scrollbars="none">
</androidx.recyclerview.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progressBar"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
android:layout_width="match_parent"
android:layout_height="@dimen/progress_bar_height"
android:layout_alignParentTop="true"
android:indeterminate="true"
android:visibility="invisible"
app:mpb_indeterminateTint="@color/accent"
app:mpb_progressStyle="horizontal"/>
</RelativeLayout> </RelativeLayout>

12
app/src/main/res/layout/fragment_profile_stats.xml

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
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:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/background_light"> android:background="@color/background_light">
@ -87,15 +86,4 @@
android:layout_marginBottom="14dp"/> android:layout_marginBottom="14dp"/>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.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_height="@dimen/progress_bar_height"
android:layout_alignParentTop="true"
android:indeterminate="true"
android:visibility="invisible"
app:mpb_indeterminateTint="@color/accent"
app:mpb_progressStyle="horizontal"/>
</RelativeLayout> </RelativeLayout>
Loading…
Cancel
Save