+ package="gr.thmmy.mthmmy"
+ android:installLocation="auto">
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
-
+
+
+ android:scheme="http" />
+ android:scheme="http" />
+ android:scheme="https" />
+ android:scheme="https" />
-
+
+ android:windowSoftInputMode="adjustPan" />
+ android:value=".activities.main.MainActivity" />
+ android:value=".activities.main.MainActivity" />
+ android:theme="@style/AppTheme.NoActionBar" />
+ android:value=".activities.main.MainActivity" />
+ android:value=".activities.main.MainActivity" />
+ android:value=".activities.main.MainActivity" />
+ android:resource="@xml/provider_paths" />
+ android:exported="false" />
-
-
+
+
diff --git a/app/src/main/assets/YouTube_light_color_icon.png b/app/src/main/assets/YouTube_light_color_icon.png
new file mode 100644
index 00000000..bfd6db39
Binary files /dev/null and b/app/src/main/assets/YouTube_light_color_icon.png differ
diff --git a/app/src/main/assets/apache_libraries.html b/app/src/main/assets/apache_libraries.html
index 2c0ceabc..45905fa2 100644
--- a/app/src/main/assets/apache_libraries.html
+++ b/app/src/main/assets/apache_libraries.html
@@ -39,25 +39,25 @@
diff --git a/app/src/main/assets/mit_libraries.html b/app/src/main/assets/mit_libraries.html
index 2c6cf3bb..42b46e78 100644
--- a/app/src/main/assets/mit_libraries.html
+++ b/app/src/main/assets/mit_libraries.html
@@ -42,7 +42,7 @@
jsoup v1.10.2 (Copyright ©2009-2017, Jonathan Hedley <jonathan@hedley.net>)
- android-gif-drawable v1.2.5 (Copyright ©2016 Karol Wrótniak, Droids on Roids)
+ android-gif-drawable v1.2.7 (Copyright ©2016 Karol Wrótniak, Droids on Roids)
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java
index ec0c2b25..d010eb8f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/BookmarkActivity.java
@@ -21,7 +21,12 @@ import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
+//TODO proper handling with adapter etc.
+//TODO better UI
+//TODO after clicking bookmark and then back button should return to this activity
public class BookmarkActivity extends BaseActivity {
+ private TextView boardsTitle;
+ private TextView topicsTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -43,93 +48,100 @@ public class BookmarkActivity extends BaseActivity {
LinearLayout bookmarksLinearView = (LinearLayout) findViewById(R.id.bookmarks_container);
LayoutInflater layoutInflater = getLayoutInflater();
- TextView tmp = new TextView(this);
- tmp.setLayoutParams(new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT
- , LinearLayout.LayoutParams.WRAP_CONTENT));
- tmp.setText(getString(R.string.board_bookmarks_title));
- tmp.setTypeface(tmp.getTypeface(), Typeface.BOLD);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- tmp.setTextColor(getColor(R.color.primary_text));
- } else {
- //noinspection deprecation
- tmp.setTextColor(getResources().getColor(R.color.primary_text));
- }
- tmp.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
- tmp.setTextSize(20f);
- bookmarksLinearView.addView(tmp);
+ if(!getBoardsBookmarked().isEmpty()) {
+ boardsTitle = new TextView(this);
+ boardsTitle.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT
+ , LinearLayout.LayoutParams.WRAP_CONTENT));
+ boardsTitle.setText(getString(R.string.board_bookmarks_title));
+ boardsTitle.setTypeface(boardsTitle.getTypeface(), Typeface.BOLD);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ boardsTitle.setTextColor(getColor(R.color.primary_text));
+ } else {
+ //noinspection deprecation
+ boardsTitle.setTextColor(getResources().getColor(R.color.primary_text));
+ }
+ boardsTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ boardsTitle.setTextSize(20f);
+ bookmarksLinearView.addView(boardsTitle);
- for (final Bookmark bookmarkedBoard : getBoardsBookmarked()) {
- if (bookmarkedBoard != null && bookmarkedBoard.getTitle() != null) {
- final LinearLayout row = (LinearLayout) layoutInflater.inflate(
- R.layout.activity_bookmark_row, bookmarksLinearView, false);
- row.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(BookmarkActivity.this, BoardActivity.class);
- Bundle extras = new Bundle();
- extras.putString(BUNDLE_BOARD_URL, "https://www.thmmy.gr/smf/index.php?board="
- + bookmarkedBoard.getId() + ".0");
- extras.putString(BUNDLE_BOARD_TITLE, bookmarkedBoard.getTitle());
- intent.putExtras(extras);
- startActivity(intent);
- finish();
- }
- });
- ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedBoard.getTitle());
- (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- removeBookmark(bookmarkedBoard);
- row.setVisibility(View.GONE);
- }
- });
- bookmarksLinearView.addView(row);
+ for (final Bookmark bookmarkedBoard : getBoardsBookmarked()) {
+ if (bookmarkedBoard != null && bookmarkedBoard.getTitle() != null) {
+ final LinearLayout row = (LinearLayout) layoutInflater.inflate(
+ R.layout.activity_bookmark_row, bookmarksLinearView, false);
+ row.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(BookmarkActivity.this, BoardActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_BOARD_URL, "https://www.thmmy.gr/smf/index.php?board="
+ + bookmarkedBoard.getId() + ".0");
+ extras.putString(BUNDLE_BOARD_TITLE, bookmarkedBoard.getTitle());
+ intent.putExtras(extras);
+ startActivity(intent);
+ finish();
+ }
+ });
+ ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedBoard.getTitle());
+ (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ removeBookmark(bookmarkedBoard);
+ row.setVisibility(View.GONE);
+ updateTitles();
+ }
+ });
+ bookmarksLinearView.addView(row);
+ }
}
}
- tmp = new TextView(this);
- tmp.setLayoutParams(new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT
- , LinearLayout.LayoutParams.WRAP_CONTENT));
- tmp.setText(getString(R.string.topic_bookmarks_title));
- tmp.setTypeface(tmp.getTypeface(), Typeface.BOLD);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- tmp.setTextColor(getColor(R.color.primary_text));
- } else {
- //noinspection deprecation
- tmp.setTextColor(getResources().getColor(R.color.primary_text));
- }
- tmp.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
- tmp.setTextSize(20f);
- bookmarksLinearView.addView(tmp);
- for (final Bookmark bookmarkedTopic : getTopicsBookmarked()) {
- if (bookmarkedTopic != null && bookmarkedTopic.getTitle() != null) {
- final LinearLayout row = (LinearLayout) layoutInflater.inflate(
- R.layout.activity_bookmark_row, bookmarksLinearView, false);
- row.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(BookmarkActivity.this, TopicActivity.class);
- Bundle extras = new Bundle();
- extras.putString(BUNDLE_TOPIC_URL, "https://www.thmmy.gr/smf/index.php?topic="
- + bookmarkedTopic.getId() + "." + 2147483647);
- extras.putString(BUNDLE_TOPIC_TITLE, bookmarkedTopic.getTitle());
- intent.putExtras(extras);
- startActivity(intent);
- finish();
- }
- });
- ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedTopic.getTitle());
- (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- removeBookmark(bookmarkedTopic);
- row.setVisibility(View.GONE);
- }
- });
- bookmarksLinearView.addView(row);
+ if(!getTopicsBookmarked().isEmpty()) {
+ topicsTitle = new TextView(this);
+ topicsTitle.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT
+ , LinearLayout.LayoutParams.WRAP_CONTENT));
+ topicsTitle.setText(getString(R.string.topic_bookmarks_title));
+ topicsTitle.setTypeface(topicsTitle.getTypeface(), Typeface.BOLD);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ topicsTitle.setTextColor(getColor(R.color.primary_text));
+ } else {
+ //noinspection deprecation
+ topicsTitle.setTextColor(getResources().getColor(R.color.primary_text));
+ }
+ topicsTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ topicsTitle.setTextSize(20f);
+ bookmarksLinearView.addView(topicsTitle);
+
+ for (final Bookmark bookmarkedTopic : getTopicsBookmarked()) {
+ if (bookmarkedTopic != null && bookmarkedTopic.getTitle() != null) {
+ final LinearLayout row = (LinearLayout) layoutInflater.inflate(
+ R.layout.activity_bookmark_row, bookmarksLinearView, false);
+ row.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(BookmarkActivity.this, TopicActivity.class);
+ Bundle extras = new Bundle();
+ extras.putString(BUNDLE_TOPIC_URL, "https://www.thmmy.gr/smf/index.php?topic="
+ + bookmarkedTopic.getId() + "." + 2147483647);
+ extras.putString(BUNDLE_TOPIC_TITLE, bookmarkedTopic.getTitle());
+ intent.putExtras(extras);
+ startActivity(intent);
+ finish();
+ }
+ });
+ ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmarkedTopic.getTitle());
+ (row.findViewById(R.id.remove_bookmark)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ removeBookmark(bookmarkedTopic);
+ row.setVisibility(View.GONE);
+ updateTitles();
+ }
+ });
+ bookmarksLinearView.addView(row);
+ }
}
}
}
@@ -139,4 +151,12 @@ public class BookmarkActivity extends BaseActivity {
drawer.setSelection(BOOKMARKS_ID);
super.onResume();
}
+
+ private void updateTitles()
+ {
+ if(getBoardsBookmarked().isEmpty()&&boardsTitle!=null)
+ boardsTitle.setVisibility(View.GONE);
+ if(getTopicsBookmarked().isEmpty()&&topicsTitle!=null)
+ topicsTitle.setVisibility(View.GONE);
+ }
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
index 39a770c2..460b0b0d 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
@@ -14,7 +14,6 @@ import android.widget.Toast;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.main.MainActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
-
import timber.log.Timber;
import static gr.thmmy.mthmmy.session.SessionManager.CONNECTION_ERROR;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
index 00dbb69a..633ab6ec 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
@@ -8,12 +8,12 @@ import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
+import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Toast;
-import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
@@ -21,17 +21,15 @@ import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.Objects;
-import javax.net.ssl.SSLHandshakeException;
-
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.Board;
import gr.thmmy.mthmmy.model.Bookmark;
import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.model.Topic;
+import gr.thmmy.mthmmy.utils.ParseTask;
+import gr.thmmy.mthmmy.utils.exceptions.ParseException;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-import okhttp3.Request;
-import okhttp3.Response;
import timber.log.Timber;
public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMoreListener {
@@ -164,6 +162,13 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
}
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ Log.d("Boardaa", "onResume called!");
+ refreshBoardBookmark((ImageButton) findViewById(R.id.bookmark));
+ }
+
@Override
public void onDestroy() {
super.onDestroy();
@@ -176,47 +181,15 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
* BoardTask's {@link AsyncTask#execute execute} method needs a boards's url as String
* parameter!
*/
- private class BoardTask extends AsyncTask {
+ private class BoardTask extends ParseTask {
@Override
protected void onPreExecute() {
if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE);
if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(false);
}
- @Override
- protected Void doInBackground(String... boardUrl) {
- Request request = new Request.Builder()
- .url(boardUrl[0])
- .build();
- try {
- Response response = client.newCall(request).execute();
- parseBoard(Jsoup.parse(response.body().string()));
- } catch (SSLHandshakeException e) {
- Timber.w("Certificate problem (please switch to unsafe connection).");
- } catch (Exception e) {
- Timber.e("ERROR", e);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void voids) {
- if (boardTitle == null || Objects.equals(boardTitle, "")
- || !Objects.equals(boardTitle, parsedTitle)) {
- boardTitle = parsedTitle;
- toolbar.setTitle(boardTitle);
- thisPageBookmark = new Bookmark(boardTitle, ThmmyPage.getBoardId(boardUrl));
- }
-
- //Parse was successful
- ++pagesLoaded;
- if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(true);
- progressBar.setVisibility(ProgressBar.INVISIBLE);
- boardAdapter.notifyDataSetChanged();
- isLoadingMore = false;
- }
-
- private void parseBoard(Document boardPage) {
+ @Override //TODO should throw ParseException
+ public void parse(Document boardPage) throws ParseException {
parsedTitle = boardPage.select("div.nav a.nav").last().text();
//Removes loading item
@@ -320,5 +293,23 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
}
}
}
+
+ @Override
+ protected void postParsing(ResultCode result) {
+ //TODO if (result == ResultCode.SUCCESS)...
+ if (boardTitle == null || Objects.equals(boardTitle, "")
+ || !Objects.equals(boardTitle, parsedTitle)) {
+ boardTitle = parsedTitle;
+ toolbar.setTitle(boardTitle);
+ thisPageBookmark = new Bookmark(boardTitle, ThmmyPage.getBoardId(boardUrl));
+ }
+
+ //Parse was successful
+ ++pagesLoaded;
+ if (newTopicFAB.getVisibility() != View.GONE) newTopicFAB.setEnabled(true);
+ progressBar.setVisibility(ProgressBar.INVISIBLE);
+ boardAdapter.notifyDataSetChanged();
+ isLoadingMore = false;
+ }
}
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java
index b4339f14..8c944f7f 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java
@@ -27,7 +27,6 @@ import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.Download;
import gr.thmmy.mthmmy.model.ThmmyPage;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-
import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
@@ -189,7 +188,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter.
} catch (SSLHandshakeException e) {
Timber.w("Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
- Timber.e("ERROR", e);
+ Timber.e(e, "Exception");
}
return null;
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
index ddc604b4..9e665182 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
@@ -8,15 +8,18 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
-import android.support.v7.widget.Toolbar;
import android.widget.Toast;
+import java.util.ArrayList;
+import java.util.List;
+
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.board.BoardActivity;
import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity;
import gr.thmmy.mthmmy.activities.main.forum.ForumFragment;
import gr.thmmy.mthmmy.activities.main.recent.RecentFragment;
+import gr.thmmy.mthmmy.activities.main.unread.UnreadFragment;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
@@ -34,11 +37,13 @@ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL;
-public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener {
+public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener, UnreadFragment.UnreadFragmentInteractionListener {
- //----------------------------------------CLASS VARIABLES-----------------------------------------
+//-----------------------------------------CLASS VARIABLES------------------------------------------
private static final int TIME_INTERVAL = 2000;
private long mBackPressed;
+ private SectionsPagerAdapter sectionsPagerAdapter;
+ private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -48,7 +53,6 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
setContentView(R.layout.activity_main);
if (sessionManager.isLoginScreenDefault())
-
{
//Go to login
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
@@ -57,25 +61,25 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
}
- //Initialize toolbar
- toolbar = (Toolbar)
-
- findViewById(R.id.toolbar);
-
- setSupportActionBar(toolbar);
-
//Initialize drawer
createDrawer();
//Create the adapter that will return a fragment for each section of the activity
- SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
+ sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
+ sectionsPagerAdapter.addFragment(RecentFragment.newInstance(1), "RECENT");
+ sectionsPagerAdapter.addFragment(ForumFragment.newInstance(2), "FORUM");
+ if(sessionManager.isLoggedIn())
+ sectionsPagerAdapter.addFragment(UnreadFragment.newInstance(3), "UNREAD");
+
//Set up the ViewPager with the sections adapter.
- ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
- mViewPager.setAdapter(mSectionsPagerAdapter);
+ viewPager = (ViewPager) findViewById(R.id.container);
+ viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
- tabLayout.setupWithViewPager(mViewPager);
+ tabLayout.setupWithViewPager(viewPager);
+
+ setMainActivity(this);
}
@Override
@@ -88,6 +92,7 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
@Override
protected void onResume() {
drawer.setSelection(HOME_ID);
+ updateTabs();
super.onResume();
}
@@ -122,6 +127,17 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
startActivity(i);
}
+ @Override
+ public void onUnreadFragmentInteraction(TopicSummary topicSummary) {
+ if (topicSummary.getLastUser() == null && topicSummary.getDateTimeModified() == null) {
+ return; //TODO!
+ }
+ Intent i = new Intent(MainActivity.this, TopicActivity.class);
+ i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl());
+ i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getSubject());
+ startActivity(i);
+ }
+
//---------------------------------FragmentPagerAdapter---------------------------------------------
/**
@@ -130,42 +146,57 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
* it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
- public class SectionsPagerAdapter extends FragmentPagerAdapter {
+ private class SectionsPagerAdapter extends FragmentPagerAdapter {
+ private final List fragmentList = new ArrayList<>();
+ private final List fragmentTitleList = new ArrayList<>();
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
+ void addFragment(Fragment fragment, String title) {
+ fragmentList.add(fragment);
+ fragmentTitleList.add(title);
+ notifyDataSetChanged();
+ }
+
+ void removeFragment(int position) {
+ fragmentList.remove(position);
+ fragmentTitleList.remove(position);
+ notifyDataSetChanged();
+ if(viewPager.getCurrentItem()==position)
+ viewPager.setCurrentItem(position-1);
+ }
+
@Override
public Fragment getItem(int position) {
- switch (position) {
- case 0:
- return RecentFragment.newInstance(position + 1);
- case 1:
- return ForumFragment.newInstance(position + 1);
- default:
- return RecentFragment.newInstance(position + 1); //temp (?)
- }
+ return fragmentList.get(position);
}
@Override
public int getCount() {
- // Show 2 total pages.
- return 2;
+ return fragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
- switch (position) {
- case 0:
- return "RECENT POSTS";
- case 1:
- return "FORUM";
- }
+ return fragmentTitleList.get(position);
+ }
- return null;
+ @Override
+ public int getItemPosition(Object object) {
+ int position = fragmentList.indexOf(object);
+ return position == -1 ? POSITION_NONE : position;
}
}
+
+ public void updateTabs()
+ {
+ if(!sessionManager.isLoggedIn()&§ionsPagerAdapter.getCount()==3)
+ sectionsPagerAdapter.removeFragment(2);
+ else if(sessionManager.isLoggedIn()&§ionsPagerAdapter.getCount()==2)
+ sectionsPagerAdapter.addFragment(UnreadFragment.newInstance(3), "UNREAD");
+ }
//-------------------------------FragmentPagerAdapter END-------------------------------------------
private void redirectToActivityFromIntent(Intent intent) {
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java
index 9f896b29..821c83a5 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java
@@ -26,7 +26,6 @@ import gr.thmmy.mthmmy.model.TopicSummary;
* specified {@link ForumFragment.ForumFragmentInteractionListener}.
*/
class ForumAdapter extends ExpandableRecyclerAdapter {
- private final Context context;
private final LayoutInflater layoutInflater;
private final List categories;
@@ -34,7 +33,6 @@ class ForumAdapter extends ExpandableRecyclerAdapter categories, BaseFragment.FragmentInteractionListener listener) {
super(categories);
- this.context = context;
this.categories = categories;
mListener = (ForumFragment.ForumFragmentInteractionListener) listener;
layoutInflater = LayoutInflater.from(context);
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
index 8bcecc25..75919925 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
@@ -2,24 +2,21 @@ package gr.thmmy.mthmmy.activities.main.forum;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
-import android.widget.Toast;
import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
-import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -29,11 +26,12 @@ import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.Board;
import gr.thmmy.mthmmy.model.Category;
import gr.thmmy.mthmmy.session.SessionManager;
+import gr.thmmy.mthmmy.utils.CustomRecyclerView;
+import gr.thmmy.mthmmy.utils.ParseTask;
+import gr.thmmy.mthmmy.utils.exceptions.ParseException;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-
import okhttp3.HttpUrl;
import okhttp3.Request;
-import okhttp3.Response;
import timber.log.Timber;
/**
@@ -44,12 +42,12 @@ import timber.log.Timber;
* Use the {@link ForumFragment#newInstance} factory method to
* create an instance of this fragment.
*/
-public class ForumFragment extends BaseFragment
-{
+public class ForumFragment extends BaseFragment {
private static final String TAG = "ForumFragment";
// Fragment initialization parameters, e.g. ARG_SECTION_NUMBER
private MaterialProgressBar progressBar;
+ private SwipeRefreshLayout swipeRefreshLayout;
private ForumAdapter forumAdapter;
private List categories;
@@ -57,11 +55,13 @@ public class ForumFragment extends BaseFragment
private ForumTask forumTask;
// Required empty public constructor
- public ForumFragment() {}
+ public ForumFragment() {
+ }
/**
* Use ONLY this factory method to create a new instance of
* this fragment using the provided parameters.
+ *
* @return A new instance of fragment Forum.
*/
public static ForumFragment newInstance(int sectionNumber) {
@@ -82,9 +82,8 @@ public class ForumFragment extends BaseFragment
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- if (categories.isEmpty())
- {
- forumTask =new ForumTask();
+ if (categories.isEmpty()) {
+ forumTask = new ForumTask();
forumTask.execute();
}
@@ -104,11 +103,10 @@ public class ForumFragment extends BaseFragment
forumAdapter.setExpandCollapseListener(new ExpandableRecyclerAdapter.ExpandCollapseListener() {
@Override
public void onParentExpanded(int parentPosition) {
- if(BaseActivity.getSessionManager().isLoggedIn())
- {
- if(forumTask.getStatus()== AsyncTask.Status.RUNNING)
+ if (BaseActivity.getSessionManager().isLoggedIn()) {
+ if (forumTask.getStatus() == AsyncTask.Status.RUNNING)
forumTask.cancel(true);
- forumTask =new ForumTask();
+ forumTask = new ForumTask();
forumTask.setUrl(categories.get(parentPosition).getCategoryURL());
forumTask.execute();
}
@@ -116,18 +114,17 @@ public class ForumFragment extends BaseFragment
@Override
public void onParentCollapsed(int parentPosition) {
- if(BaseActivity.getSessionManager().isLoggedIn())
- {
- if(forumTask.getStatus()== AsyncTask.Status.RUNNING)
+ if (BaseActivity.getSessionManager().isLoggedIn()) {
+ if (forumTask.getStatus() == AsyncTask.Status.RUNNING)
forumTask.cancel(true);
- forumTask =new ForumTask();
+ forumTask = new ForumTask();
forumTask.setUrl(categories.get(parentPosition).getCategoryURL());
forumTask.execute();
}
}
});
- RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.list);
+ CustomRecyclerView recyclerView = (CustomRecyclerView) rootView.findViewById(R.id.list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext());
recyclerView.setLayoutManager(linearLayoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
@@ -135,6 +132,20 @@ public class ForumFragment extends BaseFragment
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setAdapter(forumAdapter);
+ swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swiperefresh);
+ swipeRefreshLayout.setOnRefreshListener(
+ new SwipeRefreshLayout.OnRefreshListener() {
+ @Override
+ public void onRefresh() {
+ if (forumTask != null && forumTask.getStatus() != AsyncTask.Status.RUNNING) {
+ forumTask = new ForumTask();
+ forumTask.execute(SessionManager.indexUrl.toString());
+ }
+ }
+
+ }
+ );
+
}
return rootView;
}
@@ -142,19 +153,18 @@ public class ForumFragment extends BaseFragment
@Override
public void onDestroy() {
super.onDestroy();
- if(forumTask!=null&&forumTask.getStatus()!= AsyncTask.Status.RUNNING)
+ if (forumTask != null && forumTask.getStatus() != AsyncTask.Status.RUNNING)
forumTask.cancel(true);
}
- public interface ForumFragmentInteractionListener extends FragmentInteractionListener{
+ public interface ForumFragmentInteractionListener extends FragmentInteractionListener {
void onForumFragmentInteraction(Board board);
}
//---------------------------------------ASYNC TASK-----------------------------------
- private class ForumTask extends AsyncTask {
+ private class ForumTask extends ParseTask {
private HttpUrl forumUrl = SessionManager.forumUrl; //may change upon collapse/expand
- private Document document;
private final List fetchedCategories;
@@ -166,69 +176,52 @@ public class ForumFragment extends BaseFragment
progressBar.setVisibility(ProgressBar.VISIBLE);
}
- protected Integer doInBackground(Void... voids) {
- Request request = new Request.Builder()
+ @Override
+ protected Request prepareRequest(String... params) {
+ return new Request.Builder()
.url(forumUrl)
.build();
- try {
- Response response = client.newCall(request).execute();
- document = Jsoup.parse(response.body().string());
- parse(document);
- categories.clear();
- categories.addAll(fetchedCategories);
- fetchedCategories.clear();
- return 0;
- } catch (IOException e) {
- Timber.d("Network Error", e);
- return 1;
- } catch (Exception e) {
- Timber.d("Exception", e);
- return 2;
- }
-
}
- protected void onPostExecute(Integer result) {
-
- if (result == 0)
- forumAdapter.notifyParentDataSetChanged(false);
- else if (result == 1)
- Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show();
-
- progressBar.setVisibility(ProgressBar.INVISIBLE);
- }
-
- private void parse(Document document)
- {
+ @Override
+ public void parse(Document document) throws ParseException {
Elements categoryBlocks = document.select(".tborder:not([style])>table[cellpadding=5]");
if (categoryBlocks.size() != 0) {
- for(Element categoryBlock: categoryBlocks)
- {
+ for (Element categoryBlock : categoryBlocks) {
Element categoryElement = categoryBlock.select("td[colspan=2]>[name]").first();
String categoryUrl = categoryElement.attr("href");
Category category = new Category(categoryElement.text(), categoryUrl);
- if(categoryUrl.contains("sa=collapse")|| !BaseActivity.getSessionManager().isLoggedIn())
- {
+ if (categoryUrl.contains("sa=collapse") || !BaseActivity.getSessionManager().isLoggedIn()) {
category.setExpanded(true);
Elements boardsElements = categoryBlock.select("b [name]");
- for(Element boardElement: boardsElements) {
+ for (Element boardElement : boardsElements) {
Board board = new Board(boardElement.attr("href"), boardElement.text(), null, null, null, null);
category.getBoards().add(board);
}
- }
- else
+ } else
category.setExpanded(false);
fetchedCategories.add(category);
}
- }
- else
- Timber.e("Parsing failed!");
+ categories.clear();
+ categories.addAll(fetchedCategories);
+ fetchedCategories.clear();
+ } else
+ throw new ParseException("Parsing failed");
+ }
+
+ @Override
+ protected void postParsing(ParseTask.ResultCode result) {
+ if (result == ResultCode.SUCCESS)
+ forumAdapter.notifyParentDataSetChanged(false);
+
+ progressBar.setVisibility(ProgressBar.INVISIBLE);
+ swipeRefreshLayout.setRefreshing(false);
}
- public void setUrl(String string)
+ public void setUrl(String string) //TODO delete and simplify e.g. in prepareRequest possible?
{
forumUrl = HttpUrl.parse(string);
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
index 47f4678d..86e3a2d2 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java
@@ -10,13 +10,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
-import android.widget.Toast;
-import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@@ -27,14 +24,12 @@ import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.CustomRecyclerView;
+import gr.thmmy.mthmmy.utils.ParseTask;
import gr.thmmy.mthmmy.utils.exceptions.ParseException;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-
-import okhttp3.HttpUrl;
-import okhttp3.Request;
-import okhttp3.Response;
import timber.log.Timber;
+
/**
* A {@link BaseFragment} subclass.
* Activities that contain this fragment must implement the
@@ -56,11 +51,13 @@ public class RecentFragment extends BaseFragment {
private RecentTask recentTask;
// Required empty public constructor
- public RecentFragment() {}
+ public RecentFragment() {
+ }
/**
* Use ONLY this factory method to create a new instance of
* this fragment using the provided parameters.
+ *
* @return A new instance of fragment Recent.
*/
public static RecentFragment newInstance(int sectionNumber) {
@@ -81,10 +78,9 @@ public class RecentFragment extends BaseFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- if (topicSummaries.isEmpty())
- {
- recentTask =new RecentTask();
- recentTask.execute();
+ if (topicSummaries.isEmpty()) {
+ recentTask = new RecentTask();
+ recentTask.execute(SessionManager.indexUrl.toString());
}
Timber.d("onActivityCreated");
@@ -117,7 +113,7 @@ public class RecentFragment extends BaseFragment {
public void onRefresh() {
if (recentTask != null && recentTask.getStatus() != AsyncTask.Status.RUNNING) {
recentTask = new RecentTask();
- recentTask.execute();
+ recentTask.execute(SessionManager.indexUrl.toString());
}
}
@@ -131,7 +127,7 @@ public class RecentFragment extends BaseFragment {
@Override
public void onDestroy() {
super.onDestroy();
- if(recentTask!=null&&recentTask.getStatus()!= AsyncTask.Status.RUNNING)
+ if (recentTask != null && recentTask.getStatus() != AsyncTask.Status.RUNNING)
recentTask.cancel(true);
}
@@ -141,55 +137,16 @@ public class RecentFragment extends BaseFragment {
}
//---------------------------------------ASYNC TASK-----------------------------------
-
- private class RecentTask extends AsyncTask {
- private final HttpUrl thmmyUrl = SessionManager.indexUrl;
- private Document document;
-
+ private class RecentTask extends ParseTask {
protected void onPreExecute() {
-
progressBar.setVisibility(ProgressBar.VISIBLE);
}
- protected Integer doInBackground(Void... voids) {
- Request request = new Request.Builder()
- .url(thmmyUrl)
- .build();
- try {
- Response response = client.newCall(request).execute();
- document = Jsoup.parse(response.body().string());
- parse(document);
- return 0;
- } catch (ParseException e) {
- Timber.e("ParseException", e);
- return 1;
- } catch (IOException e) {
- Timber.i("Network Error", e);
- return 2;
- } catch (Exception e) {
- Timber.e("Exception", e);
- return 3;
- }
-
- }
-
-
- protected void onPostExecute(Integer result) {
-
- if (result == 0)
- recentAdapter.notifyDataSetChanged();
- else if (result == 2)
- Toast.makeText(getActivity(), "Network error", Toast.LENGTH_SHORT).show(); //Fixme, sometimes activity isn't ready
-
- progressBar.setVisibility(ProgressBar.INVISIBLE);
- swipeRefreshLayout.setRefreshing(false);
- }
-
- private void parse(Document document) throws ParseException {
+ @Override
+ public void parse(Document document) throws ParseException {
Elements recent = document.select("#block8 :first-child div");
if (!recent.isEmpty()) {
topicSummaries.clear();
-
for (int i = 0; i < recent.size(); i += 3) {
String link = recent.get(i).child(0).attr("href");
String title = recent.get(i).child(0).attr("title");
@@ -212,11 +169,18 @@ public class RecentFragment extends BaseFragment {
topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime));
}
-
return;
}
throw new ParseException("Parsing failed");
}
- }
+ @Override
+ protected void postParsing(ParseTask.ResultCode result) {
+ if (result == ResultCode.SUCCESS)
+ recentAdapter.notifyDataSetChanged();
+
+ progressBar.setVisibility(ProgressBar.INVISIBLE);
+ swipeRefreshLayout.setRefreshing(false);
+ }
+ }
}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java
new file mode 100644
index 00000000..73adc1e4
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java
@@ -0,0 +1,147 @@
+package gr.thmmy.mthmmy.activities.main.unread;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.List;
+
+import gr.thmmy.mthmmy.R;
+import gr.thmmy.mthmmy.base.BaseFragment;
+import gr.thmmy.mthmmy.model.TopicSummary;
+
+class UnreadAdapter extends RecyclerView.Adapter {
+ private final Context context;
+ private final List unreadList;
+ private final UnreadFragment.UnreadFragmentInteractionListener mListener;
+ private final MarkReadInteractionListener markReadListener;
+
+ private final int VIEW_TYPE_ITEM = 0;
+ private final int VIEW_TYPE_NADA = 1;
+ private final int VIEW_TYPE_MARK_READ = 2;
+
+ UnreadAdapter(Context context, @NonNull List topicSummaryList,
+ BaseFragment.FragmentInteractionListener listener,
+ MarkReadInteractionListener markReadInteractionListener) {
+ this.context = context;
+ this.unreadList = topicSummaryList;
+ mListener = (UnreadFragment.UnreadFragmentInteractionListener) listener;
+ markReadListener = markReadInteractionListener;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (unreadList.get(position).getDateTimeModified() == null) return VIEW_TYPE_MARK_READ;
+ return unreadList.get(position).getTopicUrl() == null ? VIEW_TYPE_NADA : VIEW_TYPE_ITEM;
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ if (viewType == VIEW_TYPE_ITEM) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.fragment_unread_row, parent, false);
+ return new ViewHolder(view);
+ } else if (viewType == VIEW_TYPE_NADA) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.fragment_unread_empty_row, parent, false);
+ return new EmptyViewHolder(view);
+ } else if (viewType == VIEW_TYPE_MARK_READ) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.fragment_unread_mark_read_row, parent, false);
+ return new MarkReadViewHolder(view);
+ }
+ return null;
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
+ if (holder instanceof UnreadAdapter.EmptyViewHolder) {
+ final UnreadAdapter.EmptyViewHolder emptyViewHolder = (UnreadAdapter.EmptyViewHolder) holder;
+ emptyViewHolder.text.setText(unreadList.get(position).getDateTimeModified());
+ } else if (holder instanceof UnreadAdapter.ViewHolder) {
+ final UnreadAdapter.ViewHolder viewHolder = (UnreadAdapter.ViewHolder) holder;
+
+ viewHolder.mTitleView.setText(unreadList.get(position).getSubject());
+ viewHolder.mDateTimeView.setText(unreadList.get(position).getDateTimeModified());
+ viewHolder.mUserView.setText(context.getString(R.string.byUser, unreadList.get(position).getLastUser()));
+
+ viewHolder.topic = unreadList.get(position);
+
+ viewHolder.mView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (null != mListener) {
+ // Notify the active callbacks interface (the activity, if the
+ // fragment is attached to one) that an item has been selected.
+ mListener.onUnreadFragmentInteraction(viewHolder.topic); //?
+ }
+ }
+ });
+ } else if (holder instanceof UnreadAdapter.MarkReadViewHolder) {
+ final UnreadAdapter.MarkReadViewHolder markReadViewHolder = (UnreadAdapter.MarkReadViewHolder) holder;
+ markReadViewHolder.text.setText(unreadList.get(position).getSubject());
+ markReadViewHolder.topic = unreadList.get(position);
+
+ markReadViewHolder.mView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (null != mListener) {
+ // Notify the active callbacks interface (the activity, if the
+ // fragment is attached to one) that an item has been selected.
+ markReadListener.onMarkReadInteraction(unreadList.get(position).getTopicUrl());
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return unreadList.size();
+ }
+
+ private static class ViewHolder extends RecyclerView.ViewHolder {
+ final View mView;
+ final TextView mTitleView;
+ final TextView mUserView;
+ final TextView mDateTimeView;
+ public TopicSummary topic;
+
+ ViewHolder(View view) {
+ super(view);
+ mView = view;
+ mTitleView = (TextView) view.findViewById(R.id.title);
+ mUserView = (TextView) view.findViewById(R.id.lastUser);
+ mDateTimeView = (TextView) view.findViewById(R.id.dateTime);
+ }
+ }
+
+ private static class EmptyViewHolder extends RecyclerView.ViewHolder {
+ final TextView text;
+
+ EmptyViewHolder(View view) {
+ super(view);
+ text = (TextView) view.findViewById(R.id.text);
+ }
+ }
+
+ private static class MarkReadViewHolder extends RecyclerView.ViewHolder {
+ final View mView;
+ final TextView text;
+ public TopicSummary topic;
+
+ MarkReadViewHolder(View view) {
+ super(view);
+ mView = view;
+ text = (TextView) view.findViewById(R.id.mark_read);
+ }
+ }
+
+ public interface MarkReadInteractionListener {
+ void onMarkReadInteraction(String markReadLinkUrl);
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
new file mode 100644
index 00000000..d1febe97
--- /dev/null
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
@@ -0,0 +1,251 @@
+package gr.thmmy.mthmmy.activities.main.unread;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.DividerItemDecoration;
+import android.support.v7.widget.LinearLayoutManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.Toast;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import gr.thmmy.mthmmy.R;
+import gr.thmmy.mthmmy.base.BaseFragment;
+import gr.thmmy.mthmmy.model.TopicSummary;
+import gr.thmmy.mthmmy.session.SessionManager;
+import gr.thmmy.mthmmy.utils.CustomRecyclerView;
+import gr.thmmy.mthmmy.utils.ParseTask;
+import gr.thmmy.mthmmy.utils.exceptions.ParseException;
+import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
+import okhttp3.Request;
+import timber.log.Timber;
+
+/**
+ * A {@link BaseFragment} subclass.
+ * Activities that contain this fragment must implement the
+ * {@link UnreadFragment.UnreadFragmentInteractionListener} interface
+ * to handle interaction events.
+ * Use the {@link UnreadFragment#newInstance} factory method to
+ * create an instance of this fragment.
+ */
+
+public class UnreadFragment extends BaseFragment {
+ private static final String TAG = "UnreadFragment";
+ // Fragment initialization parameters, e.g. ARG_SECTION_NUMBER
+
+ private MaterialProgressBar progressBar;
+ private SwipeRefreshLayout swipeRefreshLayout;
+ private UnreadAdapter unreadAdapter;
+
+ private List topicSummaries;
+
+ private UnreadTask unreadTask;
+ private MarkReadTask markReadTask;
+
+ // Required empty public constructor
+ public UnreadFragment() {
+ }
+
+ /**
+ * Use ONLY this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @return A new instance of fragment Unread.
+ */
+ public static UnreadFragment newInstance(int sectionNumber) {
+ UnreadFragment fragment = new UnreadFragment();
+ Bundle args = new Bundle();
+ args.putString(ARG_TAG, TAG);
+ args.putInt(ARG_SECTION_NUMBER, sectionNumber);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ topicSummaries = new ArrayList<>();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ if (topicSummaries.isEmpty()) {
+ unreadTask = new UnreadTask();
+ unreadTask.execute(SessionManager.unreadUrl.toString());
+ }
+ markReadTask = new MarkReadTask();
+ Timber.d("onActivityCreated");
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ final View rootView = inflater.inflate(R.layout.fragment_unread, container, false);
+
+ // Set the adapter
+ if (rootView instanceof RelativeLayout) {
+ progressBar = (MaterialProgressBar) rootView.findViewById(R.id.progressBar);
+ unreadAdapter = new UnreadAdapter(getActivity(), topicSummaries,
+ fragmentInteractionListener, new UnreadAdapter.MarkReadInteractionListener() {
+ @Override
+ public void onMarkReadInteraction(String markReadLinkUrl) {
+ if (markReadTask != null && markReadTask.getStatus() != AsyncTask.Status.RUNNING) {
+ markReadTask = new MarkReadTask();
+ markReadTask.execute(markReadLinkUrl);
+ }
+ }
+ });
+
+ CustomRecyclerView recyclerView = (CustomRecyclerView) rootView.findViewById(R.id.list);
+ LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext());
+ recyclerView.setLayoutManager(linearLayoutManager);
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
+ linearLayoutManager.getOrientation());
+ recyclerView.addItemDecoration(dividerItemDecoration);
+ recyclerView.setAdapter(unreadAdapter);
+
+ swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swiperefresh);
+ swipeRefreshLayout.setOnRefreshListener(
+ new SwipeRefreshLayout.OnRefreshListener() {
+ @Override
+ public void onRefresh() {
+ if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) {
+ unreadTask = new UnreadTask();
+ unreadTask.execute(SessionManager.unreadUrl.toString());
+ }
+ }
+
+ }
+ );
+ }
+
+ return rootView;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING)
+ unreadTask.cancel(true);
+ if (markReadTask != null && markReadTask.getStatus() != AsyncTask.Status.RUNNING)
+ markReadTask.cancel(true);
+ }
+
+ public interface UnreadFragmentInteractionListener extends FragmentInteractionListener {
+ void onUnreadFragmentInteraction(TopicSummary topicSummary);
+ }
+
+ //---------------------------------------ASYNC TASK-----------------------------------
+ private class UnreadTask extends ParseTask {
+ protected void onPreExecute() {
+ progressBar.setVisibility(ProgressBar.VISIBLE);
+ }
+
+ @Override
+ public void parse(Document document) throws ParseException {
+ Elements unread = document.select("table.bordercolor[cellspacing=1] tr:not(.titlebg)");
+ if (!unread.isEmpty()) {
+ topicSummaries.clear();
+ for (Element row : unread) {
+ Elements information = row.select("td");
+ String link = information.last().select("a").first().attr("href");
+ String title = information.get(2).select("a").first().text();
+
+ Element lastUserAndDate = information.get(6);
+ String lastUser = lastUserAndDate.select("a").text();
+ String dateTime = lastUserAndDate.select("span").html();
+ //dateTime = dateTime.replace(" ", "");
+ dateTime = dateTime.substring(0, dateTime.indexOf(" "));
+ dateTime = dateTime.replace("", "");
+ dateTime = dateTime.replace(" ", "");
+
+ topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime));
+ }
+ Element markRead = document.select("table:not(.bordercolor):not([width])").select("a")
+ .first();
+ if (markRead != null)
+ topicSummaries.add(new TopicSummary(markRead.attr("href"), markRead.text(), null,
+ null));
+ } else {
+ topicSummaries.clear();
+ String message = document.select("table.bordercolor[cellspacing=1]").first().text();
+ if (message.contains("No messages")) { //It's english
+ message = "No unread posts!";
+ } else { //It's greek
+ message = "Δεν υπάρχουν μη διαβασμένα μηνύματα!";
+ }
+ topicSummaries.add(new TopicSummary(null, null, null, message));
+ }
+ }
+
+ @Override
+ protected void postParsing(ParseTask.ResultCode result) {
+ if (result == ResultCode.SUCCESS)
+ unreadAdapter.notifyDataSetChanged();
+
+ progressBar.setVisibility(ProgressBar.INVISIBLE);
+ swipeRefreshLayout.setRefreshing(false);
+ }
+ }
+
+ private class MarkReadTask extends AsyncTask {
+ private static final int SUCCESS = 0;
+ private static final int NETWORK_ERROR = 1;
+ private static final int OTHER_ERROR = 2;
+
+ @Override
+ protected void onPreExecute() {
+ progressBar.setVisibility(ProgressBar.VISIBLE);
+ }
+
+ @Override
+ protected Integer doInBackground(String... strings) {
+ Request request = new Request.Builder()
+ .url(strings[0])
+ .build();
+ try {
+ client.newCall(request).execute();
+ return SUCCESS;
+ } catch (IOException e) {
+ Timber.i(e, "IO Exception");
+ return NETWORK_ERROR;
+ } catch (Exception e) {
+ Timber.e(e, "Exception");
+ return OTHER_ERROR;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Integer result) {
+ progressBar.setVisibility(ProgressBar.GONE);
+
+ if (result == NETWORK_ERROR) {
+ Toast.makeText(getContext()
+ , "Task was unsuccessful!\n Please check your internet conneciton.",
+ Toast.LENGTH_LONG).show();
+ } else if (result == OTHER_ERROR) {
+ Toast.makeText(getContext()
+ , "Fatal error!\n Task aborted...", Toast.LENGTH_LONG).show();
+ } else {
+ if (unreadTask != null && unreadTask.getStatus() != AsyncTask.Status.RUNNING) {
+ unreadTask = new UnreadTask();
+ unreadTask.execute(SessionManager.unreadUrl.toString());
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
index 08495dd9..f21a21eb 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
@@ -19,7 +19,6 @@ import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
-
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
@@ -50,7 +49,6 @@ import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.utils.CenterVerticalSpan;
import gr.thmmy.mthmmy.utils.CircleTransform;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-
import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
@@ -276,11 +274,12 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
} catch (SSLHandshakeException e) {
Timber.w("Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
- Timber.e("ERROR", e);
+ Timber.e(e, "Exception");
}
return false;
}
+ //TODO: better parse error handling (ParseException etc.)
protected void onPostExecute(Boolean result) {
if (!result) { //Parse failed! //TODO report as ParseException?
Timber.d("Parse failed!");
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
index 5c3f8d40..8f39f6c9 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
@@ -26,7 +26,6 @@ import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.utils.ParseHelpers;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-
import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
@@ -167,7 +166,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
} catch (SSLHandshakeException e) {
Timber.w("Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
- Timber.e("ERROR", e);
+ Timber.e(e, "Exception");
}
return false;
}
@@ -185,6 +184,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap
isLoadingMore = false;
}
+ //TODO: better parse error handling (ParseException etc.)
private boolean parseLatestPosts(Document latestPostsPage) {
Elements latestPostsRows = latestPostsPage.
select("td:has(table:Contains(Show Posts)):not([style]) > table");
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
index f573f3db..50c8c521 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java
@@ -41,7 +41,6 @@ import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
-
import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber;
@@ -141,11 +140,12 @@ public class StatsFragment extends Fragment {
} catch (SSLHandshakeException e) {
Timber.w("Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
- Timber.e("ERROR", e);
+ Timber.e(e, "Exception");
}
return false;
}
+ //TODO: better parse error handling (ParseException etc.)
@Override
protected void onPostExecute(Boolean result) {
if (!result) { //Parse failed!
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
index 70644bf4..fc3d4dd7 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
@@ -7,7 +7,6 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.method.LinkMovementMethod;
-
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -25,7 +24,6 @@ import java.util.Objects;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.utils.ParseHelpers;
-
import timber.log.Timber;
diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java
index 7c42b8cd..3fe99911 100644
--- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java
+++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java
@@ -11,12 +11,54 @@ import java.util.Map;
import java.util.regex.Matcher;
import okhttp3.Response;
+import timber.log.Timber;
+/**
+ * This is a utility class containing a collection of static methods to help with topic replying.
+ */
class Posting {
+ /**
+ * {@link REPLY_STATUS} enum defines the different possible outcomes of a topic reply request.
+ */
enum REPLY_STATUS {
- SUCCESSFUL, NO_SUBJECT, EMPTY_BODY, NEW_REPLY_WHILE_POSTING, NOT_FOUND, SESSION_ENDED, OTHER_ERROR
+ /**
+ * The request was successful
+ */
+ SUCCESSFUL,
+ /**
+ * Request was lacking a subject
+ */
+ NO_SUBJECT,
+ /**
+ * Request had empty body
+ */
+ EMPTY_BODY,
+ /**
+ * There were new topic replies while making the request
+ */
+ NEW_REPLY_WHILE_POSTING,
+ /**
+ * Error 404, page was not found
+ */
+ NOT_FOUND,
+ /**
+ * User session ended while posting the reply
+ */
+ SESSION_ENDED,
+ /**
+ * Other undefined of unidentified error
+ */
+ OTHER_ERROR
}
+ /**
+ * This method can be used to check whether a topic post request was successful or not and if
+ * not maybe get the reason why.
+ *
+ * @param response {@link okhttp3.Response} of the request
+ * @return a {@link REPLY_STATUS} that describes the response status
+ * @throws IOException method relies to {@link org.jsoup.Jsoup#parse(String)}
+ */
static REPLY_STATUS replyStatus(Response response) throws IOException {
if (response.code() == 404) return REPLY_STATUS.NOT_FOUND;
if (response.code() < 200 || response.code() >= 400) return REPLY_STATUS.OTHER_ERROR;
@@ -26,8 +68,8 @@ class Posting {
String[] errors = postErrorPage.select("tr[id=errors] div[id=error_list]").first()
.toString().split(" ");
for (int i = 0; i < errors.length; ++i) { //TODO test
- Log.d("TAG", String.valueOf(i));
- Log.d("TAG", errors[i]);
+ Timber.d(String.valueOf(i));
+ Timber.d(errors[i]);
}
for (String error : errors) {
if (error.contains("Your session timed out while posting") ||
@@ -45,10 +87,19 @@ class Posting {
return REPLY_STATUS.SUCCESSFUL;
}
+ /**
+ * This is a fucked up method.. Just don't waste your time here unless you have suicidal
+ * tendencies.
+ *
+ * @param html the html string to be transformed to BBcode
+ * @return the BBcode string
+ */
static String htmlToBBcode(String html) {
+ Log.d("Cancer", html);
Map bbMap = new HashMap<>();
Map smileysMap1 = new HashMap<>();
Map smileysMap2 = new HashMap<>();
+
smileysMap1.put("Smiley", ":)");
smileysMap1.put("Wink", ";)");
smileysMap1.put("Cheesy", ":D");
@@ -171,64 +222,66 @@ class Posting {
//html stuff on the beginning
bbMap.put(" \n ", "");
//quotes and code headers
- bbMap.put("\n\\s+?", "");
- bbMap.put("\n\\s+?", "");
- bbMap.put("\n\\s+?\n (.+?)\n
", "");
- bbMap.put(" ", "\n");
+ bbMap.put("\\s*?