Browse Source

Board implementation adn other fixes

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
3774b06096
  1. 207
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
  2. 180
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java
  3. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
  4. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java
  5. 3
      app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java
  6. 8
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
  7. 18
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java
  8. 51
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java
  9. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  10. 33
      app/src/main/java/gr/thmmy/mthmmy/data/Board.java
  11. 30
      app/src/main/java/gr/thmmy/mthmmy/data/PostSummary.java
  12. 42
      app/src/main/java/gr/thmmy/mthmmy/data/Topic.java
  13. 30
      app/src/main/java/gr/thmmy/mthmmy/data/TopicSummary.java
  14. 14
      app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java
  15. 2
      app/src/main/res/layout-v21/activity_profile.xml
  16. 8
      app/src/main/res/layout-v21/activity_topic_post_row.xml
  17. 57
      app/src/main/res/layout/activity_board.xml
  18. 48
      app/src/main/res/layout/activity_board_sub_board.xml
  19. 60
      app/src/main/res/layout/activity_board_topic.xml
  20. 2
      app/src/main/res/layout/activity_profile.xml
  21. 10
      app/src/main/res/layout/activity_topic.xml
  22. 8
      app/src/main/res/layout/activity_topic_post_row.xml
  23. 6
      app/src/main/res/layout/fragment_recent_row.xml
  24. 83
      app/src/main/res/values/strings.xml

207
app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java

@ -1,16 +1,39 @@
package gr.thmmy.mthmmy.activities.board; package gr.thmmy.mthmmy.activities.board;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
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.support.v7.widget.Toolbar;
import android.util.Log;
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;
import java.util.ArrayList;
import java.util.Objects;
import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.base.BaseActivity;
import gr.thmmy.mthmmy.data.Board;
import gr.thmmy.mthmmy.data.Topic;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mthmmy.utils.Report;
import okhttp3.Request;
import okhttp3.Response;
public class BoardActivity extends BaseActivity { public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMoreListener{
/** /**
* Debug Tag for logging debug output to LogCat * Debug Tag for logging debug output to LogCat
*/ */
@SuppressWarnings("unused")
private static final String TAG = "BoardActivity"; private static final String TAG = "BoardActivity";
/** /**
* The key to use when putting board's url String to {@link BoardActivity}'s Bundle. * The key to use when putting board's url String to {@link BoardActivity}'s Bundle.
@ -22,7 +45,17 @@ public class BoardActivity extends BaseActivity {
public static final String BUNDLE_BOARD_TITLE = "BOARD_TITLE"; public static final String BUNDLE_BOARD_TITLE = "BOARD_TITLE";
private MaterialProgressBar progressBar; private MaterialProgressBar progressBar;
private String boardTitle; private BoardTask boardTask;
private RecyclerView mainContent;
private BoardAdapter boardAdapter;
private final ArrayList<Board> parsedSubBoards = new ArrayList<>();
private final ArrayList<Topic> parsedTopics = new ArrayList<>();
private String boardUrl;
private int numberOfPages = -1;
private int pagesLoaded = 0;
private boolean isLoadingMore;
private static final int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -30,7 +63,8 @@ public class BoardActivity extends BaseActivity {
setContentView(R.layout.activity_board); setContentView(R.layout.activity_board);
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
boardTitle = extras.getString("BOARD_TITLE"); final String boardTitle = extras.getString(BUNDLE_BOARD_TITLE);
boardUrl = extras.getString(BUNDLE_BOARD_URL);
//Initializes graphics //Initializes graphics
toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar = (Toolbar) findViewById(R.id.toolbar);
@ -43,6 +77,173 @@ public class BoardActivity extends BaseActivity {
createDrawer(); createDrawer();
boardAdapter = new BoardAdapter(getApplicationContext(), parsedSubBoards, parsedTopics);
mainContent = (RecyclerView) findViewById(R.id.board_recycler_view);
mainContent.setAdapter(boardAdapter);
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mainContent.setLayoutManager(layoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mainContent.getContext(),
layoutManager.getOrientation());
mainContent.addItemDecoration(dividerItemDecoration);
mainContent.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = layoutManager.getItemCount();
lastVisibleItem = layoutManager.findLastVisibleItemPosition();
if (!isLoadingMore && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
isLoadingMore = true;
onLoadMore();
}
}
});
progressBar = (MaterialProgressBar) findViewById(R.id.progressBar); progressBar = (MaterialProgressBar) findViewById(R.id.progressBar);
boardTask = new BoardTask();
boardTask.execute(boardUrl);
}
@Override
public void onLoadMore() {
if (pagesLoaded < numberOfPages) {
parsedTopics.add(null);
boardAdapter.notifyItemInserted(parsedSubBoards.size() + parsedTopics.size() - 1);
//Load data
boardTask = new BoardTask();
boardTask.execute(boardUrl.substring(0, boardUrl.lastIndexOf(".")) + "." + pagesLoaded * 20);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (boardTask != null && boardTask.getStatus() != AsyncTask.Status.RUNNING)
boardTask.cancel(true);
}
/**
* An {@link AsyncTask} that handles asynchronous fetching of a board page and parsing it's content.
* <p>BoardTask's {@link AsyncTask#execute execute} method needs a boards's url as String
* parameter!</p>
*/
public class BoardTask extends AsyncTask<String, Void, Boolean> {
//Class variables
/**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "BoardTask"; //Separate tag for AsyncTask
protected void onPreExecute() {
if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE);
}
@Override
protected Boolean doInBackground(String... boardUrl) {
Log.d(TAG, boardUrl[0]);
Request request = new Request.Builder()
.url(boardUrl[0])
.build();
try {
Response response = BaseActivity.getClient().newCall(request).execute();
return parseBoard(Jsoup.parse(response.body().string()));
} catch (SSLHandshakeException e) {
Report.w(TAG, "Certificate problem (please switch to unsafe connection).");
} catch (Exception e) {
Report.e("TAG", "ERROR", e);
}
return false;
}
protected void onPostExecute(Boolean result) {
if (!result) { //Parse failed!
Report.d(TAG, "Parse failed!");
Toast.makeText(getApplicationContext()
, "Fatal error!\n Aborting...", Toast.LENGTH_LONG).show();
finish();
}
++pagesLoaded;
//Parse was successful
progressBar.setVisibility(ProgressBar.INVISIBLE);
boardAdapter = new BoardAdapter(getApplicationContext(), parsedSubBoards, parsedTopics);
mainContent.swapAdapter(boardAdapter, false);
isLoadingMore = false;
}
private boolean parseBoard(Document boardPage) {
//Removes loading item
if (isLoadingMore) {
parsedTopics.remove(parsedTopics.size() - 1);
}
//Finds number of pages
if (numberOfPages == -1) {
Elements pages = boardPage.select("table.tborder td.catbg[height=30]").first()
.select("a.navPages");
numberOfPages = 1;
if (pages != null && !pages.isEmpty()) {
for (Element page : pages) {
if (Integer.parseInt(page.text()) > numberOfPages)
numberOfPages = Integer.parseInt(page.text());
}
}
}
{ //Finds sub boards
Elements subBoardRows = boardPage.select("div.tborder>table>tbody>tr");
if (subBoardRows != null && !subBoardRows.isEmpty()) {
for (Element subBoardRow : subBoardRows) {
if (!Objects.equals(subBoardRow.className(), "titlebg")) {
String pUrl = "", pTitle = "", pMods = "", pStats = "", pLastPost = "";
Elements subBoardColumns = subBoardRow.select(">td");
for (Element subBoardCol : subBoardColumns) {
if (Objects.equals(subBoardCol.className(), "windowbg"))
pStats = subBoardCol.text();
else if (Objects.equals(subBoardCol.className(), "smalltext"))
pLastPost = subBoardCol.text();
else {
pUrl = subBoardCol.select("a").first().attr("href");
pTitle = subBoardCol.select("a").first().text();
pMods = subBoardCol.select("div.smalltext").first().text();
}
}
parsedSubBoards.add(new Board(pUrl, pTitle, pMods, pStats, pLastPost));
}
}
}
}
{ //Finds topics
Elements topicRows = boardPage.select("table.bordercolor>tbody>tr");
if (topicRows != null && !topicRows.isEmpty()) {
for (Element topicRow : topicRows) {
if (!Objects.equals(topicRow.className(), "titlebg")) {
String pTopicUrl, pSubject, pStartedBy, pLastPost, pStats;
boolean pLocked = false, pSticky = false;
Elements topicColumns = topicRow.select(">td");
if (topicColumns.size() != 7) return false;
{
Element column = topicColumns.get(2);
Element tmp = column.select("span[id^=msg_] a").first();
pTopicUrl = tmp.attr("href");
pSubject = tmp.text();
if (topicColumns.get(1).select("img[id^=stickyicon]").first() != null)
pSticky = true;
if (topicColumns.get(1).select("img[id^=lockicon]").first() != null)
pLocked = true;
}
pStartedBy = topicColumns.get(3).text();
pStats = "Replies " + topicColumns.get(4).text() + ", Views " + topicColumns.get(5).text();
pLastPost = topicColumns.last().text();
parsedTopics.add(new Topic(pTopicUrl, pSubject, pStartedBy, pLastPost,
pStats, pLocked, pSticky));
}
}
}
}
return true;
}
} }
} }

180
app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java

@ -0,0 +1,180 @@
package gr.thmmy.mthmmy.activities.board;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.data.Board;
import gr.thmmy.mthmmy.data.Topic;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE;
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;
/**
* {@link RecyclerView.Adapter} that can display a {@link gr.thmmy.mthmmy.data.Board}.
*/
class BoardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = "BoardAdapter";
private final int VIEW_TYPE_SUB_BOARD = 0;
private final int VIEW_TYPE_TOPIC = 1;
private final int VIEW_TYPE_LOADING = 2;
private final Context context;
private ArrayList<Board> parsedSubBoards = new ArrayList<>();
private ArrayList<Topic> parsedTopics = new ArrayList<>();
BoardAdapter(Context context, ArrayList<Board> parsedSubBoards, ArrayList<Topic> parsedTopics) {
this.context = context;
this.parsedSubBoards = parsedSubBoards;
this.parsedTopics = parsedTopics;
}
interface OnLoadMoreListener {
void onLoadMore();
}
@Override
public int getItemViewType(int position) {
if (position < parsedSubBoards.size())
return VIEW_TYPE_SUB_BOARD;
else if (parsedTopics.get(position - parsedSubBoards.size()) != null)
return VIEW_TYPE_TOPIC;
else return VIEW_TYPE_LOADING;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_SUB_BOARD) {
View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_board_sub_board, parent, false);
return new SubBoardViewHolder(view);
} else if (viewType == VIEW_TYPE_TOPIC) {
View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_board_topic, parent, false);
return new TopicViewHolder(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);
}
return null;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof SubBoardViewHolder) {
Board subBoard = parsedSubBoards.get(position);
final SubBoardViewHolder subBoardViewHolder = (SubBoardViewHolder) holder;
subBoardViewHolder.boardRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, BoardActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_BOARD_URL, parsedSubBoards.get(holder.
getAdapterPosition()).getUrl());
extras.putString(BUNDLE_BOARD_TITLE, parsedSubBoards.get(holder.
getAdapterPosition()).getTitle());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
subBoardViewHolder.boardTitle.setText(subBoard.getTitle());
subBoardViewHolder.boardMods.setText(context.getString(R.string.child_board_mods, subBoard.getMods()));
subBoardViewHolder.boardStats.setText(subBoard.getStats());
subBoardViewHolder.boardLastPost.setText(subBoard.getLastPost());
} else if (holder instanceof TopicViewHolder) {
Topic topic = parsedTopics.get(position - parsedSubBoards.size());
final TopicViewHolder topicViewHolder = (TopicViewHolder) holder;
topicViewHolder.topicRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, TopicActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_TOPIC_URL, parsedTopics.get(holder.
getAdapterPosition()).getUrl());
extras.putString(BUNDLE_TOPIC_TITLE, parsedTopics.get(holder.
getAdapterPosition()).getSubject());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
topicViewHolder.topicSubject.setText(topic.getSubject());
String lockedSticky = "";
if (topic.isLocked())
lockedSticky += context.getResources().getString(R.string.fa_lock);
if (topic.isSticky())
lockedSticky += context.getResources().getString(R.string.fa_sticky);
topicViewHolder.topicLockedSticky.setText(lockedSticky);
topicViewHolder.topicStartedBy.setText(context.getString(R.string.topic_started_by, topic.getStarter()));
topicViewHolder.topicStats.setText(topic.getStats());
topicViewHolder.topicLastPost.setText(context.getString(R.string.topic_last_post, topic.getLastPost()));
} else if (holder instanceof LoadingViewHolder) {
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
@Override
public int getItemCount() {
if (parsedSubBoards == null && parsedTopics == null) return 0;
else if (parsedSubBoards == null) return parsedTopics.size();
else if (parsedTopics == null) return parsedSubBoards.size();
else return parsedSubBoards.size() + parsedTopics.size();
}
private static class SubBoardViewHolder extends RecyclerView.ViewHolder {
final LinearLayout boardRow;
final TextView boardTitle, boardMods, boardStats, boardLastPost;
SubBoardViewHolder(View itemView) {
super(itemView);
boardRow = (LinearLayout) itemView.findViewById(R.id.child_board_row);
boardTitle = (TextView) itemView.findViewById(R.id.child_board_title);
boardMods = (TextView) itemView.findViewById(R.id.child_board_mods);
boardStats = (TextView) itemView.findViewById(R.id.child_board_stats);
boardLastPost = (TextView) itemView.findViewById(R.id.child_board_last_post);
}
}
private static class TopicViewHolder extends RecyclerView.ViewHolder {
final LinearLayout topicRow;
final TextView topicSubject, topicLockedSticky, topicStartedBy, topicStats, topicLastPost;
TopicViewHolder(View itemView) {
super(itemView);
topicRow = (LinearLayout) itemView.findViewById(R.id.topic_row_linear);
topicSubject = (TextView) itemView.findViewById(R.id.topic_subject);
topicLockedSticky = (TextView) itemView.findViewById(R.id.topic_locked_sticky);
topicStartedBy = (TextView) itemView.findViewById(R.id.topic_started_by);
topicStats = (TextView) itemView.findViewById(R.id.topic_stats);
topicLastPost = (TextView) itemView.findViewById(R.id.topic_last_post);
}
}
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
final MaterialProgressBar progressBar;
LoadingViewHolder(View itemView) {
super(itemView);
progressBar = (MaterialProgressBar) itemView.findViewById(R.id.recycler_progress_bar);
}
}
}

4
app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java

@ -89,14 +89,14 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
public void onRecentFragmentInteraction(TopicSummary topicSummary) { public void onRecentFragmentInteraction(TopicSummary topicSummary) {
Intent i = new Intent(MainActivity.this, TopicActivity.class); Intent i = new Intent(MainActivity.this, TopicActivity.class);
i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl()); i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl());
i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getTitle()); i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getSubject());
startActivity(i); startActivity(i);
} }
@Override @Override
public void onForumFragmentInteraction(Board board) { public void onForumFragmentInteraction(Board board) {
Intent i = new Intent(MainActivity.this, BoardActivity.class); Intent i = new Intent(MainActivity.this, BoardActivity.class);
i.putExtra(BUNDLE_BOARD_URL, board.getBoardURL()); i.putExtra(BUNDLE_BOARD_URL, board.getUrl());
i.putExtra(BUNDLE_BOARD_TITLE, board.getTitle()); i.putExtra(BUNDLE_BOARD_TITLE, board.getTitle());
startActivity(i); startActivity(i);
} }

4
app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java

@ -156,7 +156,7 @@ public class ForumFragment extends BaseFragment
private HttpUrl forumUrl = SessionManager.forumUrl; //may change upon collapse/expand private HttpUrl forumUrl = SessionManager.forumUrl; //may change upon collapse/expand
private Document document; private Document document;
private List<Category> fetchedCategories; private final List<Category> fetchedCategories;
ForumTask() { ForumTask() {
fetchedCategories = new ArrayList<>(); fetchedCategories = new ArrayList<>();
@ -214,7 +214,7 @@ public class ForumFragment extends BaseFragment
category.setExpanded(true); category.setExpanded(true);
Elements boardsElements = categoryBlock.select("b [name]"); Elements boardsElements = categoryBlock.select("b [name]");
for(Element boardElement: boardsElements) { for(Element boardElement: boardsElements) {
Board board = new Board(boardElement.text(), boardElement.attr("href")); Board board = new Board(boardElement.attr("href"), boardElement.text(), null, null, null);
category.getBoards().add(board); category.getBoards().add(board);
} }
} }

3
app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java

@ -41,8 +41,7 @@ class RecentAdapter extends RecyclerView.Adapter<RecentAdapter.ViewHolder> {
@Override @Override
public void onBindViewHolder(final ViewHolder holder, final int position) { public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mTitleView.setText(recentList.get(position).getSubject());
holder.mTitleView.setText(recentList.get(position).getTitle());
holder.mDateTimeView.setText(recentList.get(position).getDateTimeModified()); holder.mDateTimeView.setText(recentList.get(position).getDateTimeModified());
holder.mUserView.setText(context.getString(R.string.byUser, recentList.get(position).getLastUser())); holder.mUserView.setText(context.getString(R.string.byUser, recentList.get(position).getLastUser()));

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

@ -38,7 +38,7 @@ import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment;
import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment; import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment;
import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment; import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment;
import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.data.TopicSummary; import gr.thmmy.mthmmy.data.PostSummary;
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;
@ -169,10 +169,10 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment
} }
@Override @Override
public void onLatestPostsFragmentInteraction(TopicSummary topicSummary) { public void onLatestPostsFragmentInteraction(PostSummary postSummary) {
Intent i = new Intent(ProfileActivity.this, TopicActivity.class); Intent i = new Intent(ProfileActivity.this, TopicActivity.class);
i.putExtra(BUNDLE_TOPIC_URL, topicSummary.getTopicUrl()); i.putExtra(BUNDLE_TOPIC_URL, postSummary.getTopicUrl());
i.putExtra(BUNDLE_TOPIC_TITLE, topicSummary.getTitle().substring(topicSummary.getTitle(). i.putExtra(BUNDLE_TOPIC_TITLE, postSummary.getTitle().substring(postSummary.getTitle().
lastIndexOf("/ ") + 2)); lastIndexOf("/ ") + 2));
startActivity(i); startActivity(i);
} }

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

@ -8,25 +8,33 @@ import android.webkit.WebView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import java.util.ArrayList;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.base.BaseFragment; import gr.thmmy.mthmmy.activities.base.BaseFragment;
import gr.thmmy.mthmmy.data.PostSummary;
import gr.thmmy.mthmmy.data.TopicSummary; import gr.thmmy.mthmmy.data.TopicSummary;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import static gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment.parsedTopicSummaries;
/** /**
* {@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
* specified {@link LatestPostsFragment.LatestPostsFragmentInteractionListener}. * specified {@link LatestPostsFragment.LatestPostsFragmentInteractionListener}.
*/ */
class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
/**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "LatestPostsAdapter"; private static final String TAG = "LatestPostsAdapter";
private final int VIEW_TYPE_ITEM = 0; private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1; private final int VIEW_TYPE_LOADING = 1;
final private LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener; final private LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener;
private final ArrayList<PostSummary> parsedTopicSummaries;
LatestPostsAdapter(BaseFragment.FragmentInteractionListener interactionListener){ LatestPostsAdapter(BaseFragment.FragmentInteractionListener interactionListener,
ArrayList<PostSummary> parsedTopicSummaries) {
this.interactionListener = (LatestPostsFragment.LatestPostsFragmentInteractionListener) interactionListener; this.interactionListener = (LatestPostsFragment.LatestPostsFragmentInteractionListener) interactionListener;
this.parsedTopicSummaries = parsedTopicSummaries;
} }
interface OnLoadMoreListener { interface OnLoadMoreListener {
@ -55,11 +63,11 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override @Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof LatestPostViewHolder) { if (holder instanceof LatestPostViewHolder) {
TopicSummary topic = parsedTopicSummaries.get(position); PostSummary topic = parsedTopicSummaries.get(position);
final LatestPostViewHolder latestPostViewHolder = (LatestPostViewHolder) holder; final LatestPostViewHolder latestPostViewHolder = (LatestPostViewHolder) holder;
latestPostViewHolder.postTitle.setText(topic.getTitle()); latestPostViewHolder.postTitle.setText(topic.getTitle());
latestPostViewHolder.postDate.setText(topic.getDateTimeModified()); latestPostViewHolder.postDate.setText(topic.getDateTime());
latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/" latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/"
, topic.getPost(), "text/html", "UTF-8", null); , topic.getPost(), "text/html", "UTF-8", null);

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

@ -23,7 +23,7 @@ import javax.net.ssl.SSLHandshakeException;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.base.BaseActivity;
import gr.thmmy.mthmmy.activities.base.BaseFragment; import gr.thmmy.mthmmy.activities.base.BaseFragment;
import gr.thmmy.mthmmy.data.TopicSummary; import gr.thmmy.mthmmy.data.PostSummary;
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;
@ -32,7 +32,7 @@ import okhttp3.Response;
/** /**
* 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 { public class LatestPostsFragment extends BaseFragment implements LatestPostsAdapter.OnLoadMoreListener{
/** /**
* Debug Tag for logging debug output to LogCat * Debug Tag for logging debug output to LogCat
*/ */
@ -43,10 +43,11 @@ public class LatestPostsFragment extends BaseFragment {
*/ */
private static final String PROFILE_URL = "PROFILE_URL"; private static final String PROFILE_URL = "PROFILE_URL";
/** /**
* {@link ArrayList} of {@link TopicSummary} objects used to hold profile's latest posts. Data * {@link ArrayList} of {@link PostSummary} objects used to hold profile's latest posts. Data
* are added in {@link LatestPostsTask}. * are added in {@link LatestPostsTask}.
*/ */
static ArrayList<TopicSummary> parsedTopicSummaries; private ArrayList<PostSummary> parsedTopicSummaries;
private RecyclerView mainContent;
private LatestPostsAdapter latestPostsAdapter; private LatestPostsAdapter latestPostsAdapter;
private int numberOfPages = -1; private int numberOfPages = -1;
private int pagesLoaded = 0; private int pagesLoaded = 0;
@ -87,8 +88,8 @@ public class LatestPostsFragment 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_latest_posts, container, false); final View rootView = inflater.inflate(R.layout.profile_fragment_latest_posts, container, false);
latestPostsAdapter = new LatestPostsAdapter(fragmentInteractionListener); latestPostsAdapter = new LatestPostsAdapter(fragmentInteractionListener, parsedTopicSummaries);
RecyclerView mainContent = (RecyclerView) rootView.findViewById(R.id.profile_latest_posts_recycler); mainContent = (RecyclerView) rootView.findViewById(R.id.profile_latest_posts_recycler);
mainContent.setAdapter(latestPostsAdapter); mainContent.setAdapter(latestPostsAdapter);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mainContent.setLayoutManager(layoutManager); mainContent.setLayoutManager(layoutManager);
@ -96,21 +97,6 @@ public class LatestPostsFragment extends BaseFragment {
layoutManager.getOrientation()); layoutManager.getOrientation());
mainContent.addItemDecoration(dividerItemDecoration); mainContent.addItemDecoration(dividerItemDecoration);
final LatestPostsAdapter.OnLoadMoreListener onLoadMoreListener = new LatestPostsAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
if (pagesLoaded < numberOfPages) {
parsedTopicSummaries.add(null);
latestPostsAdapter.notifyItemInserted(parsedTopicSummaries.size() - 1);
//Load data
profileLatestPostsTask = new LatestPostsTask();
profileLatestPostsTask.execute(profileUrl + ";sa=showPosts;start=" + pagesLoaded * 15);
++pagesLoaded;
}
}
};
//latestPostsAdapter.setOnLoadMoreListener(); //latestPostsAdapter.setOnLoadMoreListener();
mainContent.addOnScrollListener(new RecyclerView.OnScrollListener() { mainContent.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
@ -121,7 +107,7 @@ public class LatestPostsFragment extends BaseFragment {
if (!isLoadingMore && totalItemCount <= (lastVisibleItem + visibleThreshold)) { if (!isLoadingMore && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
isLoadingMore = true; isLoadingMore = true;
onLoadMoreListener.onLoadMore(); onLoadMore();
} }
} }
}); });
@ -129,6 +115,19 @@ public class LatestPostsFragment extends BaseFragment {
return rootView; return rootView;
} }
@Override
public void onLoadMore() {
if (pagesLoaded < numberOfPages) {
parsedTopicSummaries.add(null);
latestPostsAdapter.notifyItemInserted(parsedTopicSummaries.size() - 1);
//Load data
profileLatestPostsTask = new LatestPostsTask();
profileLatestPostsTask.execute(profileUrl + ";sa=showPosts;start=" + pagesLoaded * 15);
++pagesLoaded;
}
}
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
@ -148,7 +147,7 @@ public class LatestPostsFragment extends BaseFragment {
} }
public interface LatestPostsFragmentInteractionListener extends FragmentInteractionListener { public interface LatestPostsFragmentInteractionListener extends FragmentInteractionListener {
void onLatestPostsFragmentInteraction(TopicSummary topicSummary); void onLatestPostsFragmentInteraction(PostSummary postSummary);
} }
/** /**
@ -193,7 +192,9 @@ public class LatestPostsFragment extends BaseFragment {
} }
//Parse was successful //Parse was successful
progressBar.setVisibility(ProgressBar.INVISIBLE); progressBar.setVisibility(ProgressBar.INVISIBLE);
latestPostsAdapter.notifyDataSetChanged(); latestPostsAdapter = new LatestPostsAdapter(fragmentInteractionListener, parsedTopicSummaries);
mainContent.swapAdapter(latestPostsAdapter, false);
//latestPostsAdapter.notifyDataSetChanged();
isLoadingMore = false; isLoadingMore = false;
} }
@ -259,7 +260,7 @@ public class LatestPostsFragment extends BaseFragment {
//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 TopicSummary(pTopicUrl, pTopicTitle, "", pDateTime, pPost)); parsedTopicSummaries.add(new PostSummary(pTopicUrl, pTopicTitle, pDateTime, pPost));
} }
} }
return true; return true;

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

@ -319,7 +319,6 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
public void onClick(View v) { public void onClick(View v) {
//Clicking an expanded header starts profile activity //Clicking an expanded header starts profile activity
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 extras = new Bundle(); Bundle extras = new Bundle();
extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL()); extras.putString(BUNDLE_PROFILE_URL, currentPost.getProfileURL());

33
app/src/main/java/gr/thmmy/mthmmy/data/Board.java

@ -1,34 +1,33 @@
package gr.thmmy.mthmmy.data; package gr.thmmy.mthmmy.data;
import java.util.ArrayList;
public class Board { public class Board {
private final String title; private final String url, title, mods, stats, lastPost;
private final String boardURL;
private ArrayList <Board> subBoards;
private ArrayList <TopicSummary> topicSummaries;
public Board(String title, String boardURL) { public Board(String url, String title, String mods, String stats, String lastPost) {
this.url = url;
this.title = title; this.title = title;
this.boardURL = boardURL; this.mods = mods;
subBoards = new ArrayList<>(); this.stats = stats;
topicSummaries = new ArrayList<>(); this.lastPost = lastPost;
}
public String getUrl() {
return url;
} }
public String getTitle() { public String getTitle() {
return title; return title;
} }
public String getBoardURL() { public String getMods() {
return boardURL; return mods;
} }
public ArrayList<Board> getSubBoards() { public String getStats() {
return subBoards; return stats;
} }
public ArrayList<TopicSummary> getTopicSummaries() { public String getLastPost() {
return topicSummaries; return lastPost;
} }
} }

30
app/src/main/java/gr/thmmy/mthmmy/data/PostSummary.java

@ -0,0 +1,30 @@
package gr.thmmy.mthmmy.data;
public class PostSummary {
private final String topicUrl;
private final String title;
private final String dateTime;
private final String post;
public PostSummary(String topicUrl, String title, String dateTime,
String post) {
this.topicUrl = topicUrl;
this.title = title;
this.dateTime = dateTime;
this.post = post;
}
public String getTopicUrl() {
return topicUrl;
}
public String getTitle() {
return title;
}
public String getDateTime() {
return dateTime;
}
public String getPost(){ return post;}
}

42
app/src/main/java/gr/thmmy/mthmmy/data/Topic.java

@ -0,0 +1,42 @@
package gr.thmmy.mthmmy.data;
public class Topic extends TopicSummary {
private final String stats;
private final boolean locked, sticky;
public Topic(String topicUrl, String subject, String starter, String lastPost,
String stats, boolean locked, boolean sticky) {
super(topicUrl, subject, starter, lastPost);
this.stats = stats;
this.locked = locked;
this.sticky = sticky;
}
public String getSubject() {
return subject;
}
public String getStarter() {
return lastUser;
}
public boolean isLocked() {
return locked;
}
public boolean isSticky() {
return sticky;
}
public String getUrl() {
return topicUrl;
}
public String getLastPost() {
return dateTimeModified;
}
public String getStats() {
return stats;
}
}

30
app/src/main/java/gr/thmmy/mthmmy/data/TopicSummary.java

@ -1,36 +1,24 @@
package gr.thmmy.mthmmy.data; package gr.thmmy.mthmmy.data;
public class TopicSummary { public class TopicSummary {
private final String topicUrl; final String topicUrl;
private final String title; final String subject;
private final String lastUser; final String lastUser;
private final String dateTimeModified; final String dateTimeModified;
private final String post;
public TopicSummary(String topicUrl, String subject, String lastUser, String dateTimeModified) {
public TopicSummary(String topicUrl, String title, String lastUser, String dateTimeModified) {
this.topicUrl = topicUrl; this.topicUrl = topicUrl;
this.title = title; this.subject = subject;
this.lastUser = lastUser; this.lastUser = lastUser;
this.dateTimeModified = dateTimeModified; this.dateTimeModified = dateTimeModified;
this.post = "";
}
public TopicSummary(String topicUrl, String title, String username, String dateTimeModified,
String post) {
this.topicUrl = topicUrl;
this.title = title;
this.lastUser = username;
this.dateTimeModified = dateTimeModified;
this.post = post;
} }
public String getTopicUrl() { public String getTopicUrl() {
return topicUrl; return topicUrl;
} }
public String getTitle() { public String getSubject() {
return title; return subject;
} }
public String getLastUser() { public String getLastUser() {
@ -40,6 +28,4 @@ public class TopicSummary {
public String getDateTimeModified() { public String getDateTimeModified() {
return dateTimeModified; return dateTimeModified;
} }
public String getPost(){ return post;}
} }

14
app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java

@ -21,17 +21,13 @@ import static gr.thmmy.mthmmy.activities.base.BaseActivity.getClient;
* <p>Class has one constructor: <ul><li>{@link #ThmmyFile(URL, String, String)}</li></ul> * <p>Class has one constructor: <ul><li>{@link #ThmmyFile(URL, String, String)}</li></ul>
* and the methods:<ul><li>getters</li> * and the methods:<ul><li>getters</li>
* <li>{@link #download()}</li> * <li>{@link #download()}</li>
* <li>{@link #download(String)}</li></ul></p> * <li>{@link #download()}</li></ul></p>
*/ */
public class ThmmyFile { public class ThmmyFile {
/** /**
* Debug Tag for logging debug output to LogCat * Debug Tag for logging debug output to LogCat
*/ */
private static final String TAG = "ThmmyFile"; private static final String TAG = "ThmmyFile";
/**
* Folder name used when downloading files without a package name.
*/
private static final String NO_PACKAGE_FOLDER_NAME = "Other";
private final URL fileUrl; private final URL fileUrl;
private final String filename, fileInfo; private final String filename, fileInfo;
private String extension, filePath; private String extension, filePath;
@ -39,7 +35,7 @@ public class ThmmyFile {
/** /**
* This constructor only creates a ThmmyFile object and <b>does not download</b> the file. To download * This constructor only creates a ThmmyFile object and <b>does not download</b> the file. To download
* the file use {@link #download(String)} or {@link #download()}! * the file use {@link #download()} or {@link #download()}!
* *
* @param fileUrl {@link URL} object with file's url * @param fileUrl {@link URL} object with file's url
* @param filename {@link String} with desired file name * @param filename {@link String} with desired file name
@ -67,7 +63,7 @@ public class ThmmyFile {
} }
/** /**
* This is null until {@link #download(String)} or {@link #download()} is called and has succeeded. * This is null until {@link #download()} or {@link #download()} is called and has succeeded.
* *
* @return String with file's extension or null * @return String with file's extension or null
*/ */
@ -77,7 +73,7 @@ public class ThmmyFile {
} }
/** /**
* This is null until {@link #download(String)} or {@link #download()} is called and has succeeded. * This is null until {@link #download()} or {@link #download()} is called and has succeeded.
* *
* @return String with file's path or null * @return String with file's path or null
*/ */
@ -87,7 +83,7 @@ public class ThmmyFile {
} }
/** /**
* This is null until {@link #download(String)} or {@link #download()} is called and has succeeded. * This is null until {@link #download()} or {@link #download()} is called and has succeeded.
* *
* @return {@link File} or null * @return {@link File} or null
*/ */

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

@ -39,7 +39,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:contentDescription="@string/thumbnail" android:contentDescription="@string/post_thumbnail"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:src="@drawable/ic_default_user_thumbnail" android:src="@drawable/ic_default_user_thumbnail"
android:transitionName="user_thumbnail" android:transitionName="user_thumbnail"

8
app/src/main/res/layout-v21/activity_topic_post_row.xml

@ -89,7 +89,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:contentDescription="@string/thumbnail" android:contentDescription="@string/post_thumbnail"
android:maxHeight="@dimen/thumbnail_size" android:maxHeight="@dimen/thumbnail_size"
android:maxWidth="@dimen/thumbnail_size" android:maxWidth="@dimen/thumbnail_size"
android:src="@drawable/ic_default_user_thumbnail" android:src="@drawable/ic_default_user_thumbnail"
@ -104,7 +104,7 @@
android:layout_toEndOf="@+id/thumbnail_holder" android:layout_toEndOf="@+id/thumbnail_holder"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:text="@string/username" android:text="@string/post_author"
android:textColor="@color/primary_text" android:textColor="@color/primary_text"
android:textStyle="bold"/> android:textStyle="bold"/>
@ -116,7 +116,7 @@
android:layout_toEndOf="@+id/thumbnail_holder" android:layout_toEndOf="@+id/thumbnail_holder"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:text="@string/subject" android:text="@string/post_subject"
/> />
</RelativeLayout> </RelativeLayout>
@ -128,7 +128,7 @@
android:layout_marginTop="9dp" android:layout_marginTop="9dp"
android:background="@color/card_background" android:background="@color/card_background"
android:clickable="true" android:clickable="true"
android:contentDescription="@string/quote" android:contentDescription="@string/post_quote_button"
android:src="@drawable/ic_format_quote_unchecked"/> android:src="@drawable/ic_format_quote_unchecked"/>
</LinearLayout> </LinearLayout>

57
app/src/main/res/layout/activity_board.xml

@ -36,60 +36,6 @@
tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity"> tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity">
</android.support.v7.widget.RecyclerView> </android.support.v7.widget.RecyclerView>
<LinearLayout
android:id="@+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom|end"
android:background="@color/primary"
app:elevation="8dp"
app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareLinearBehavior">
<ImageButton
android:id="@+id/page_first_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:contentDescription="@string/text_first"
app:srcCompat="@drawable/page_first"/>
<ImageButton
android:id="@+id/page_previous_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:contentDescription="@string/text_previous"
app:srcCompat="@drawable/page_previous"/>
<TextView
android:id="@+id/page_indicator"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:hint="@string/text_page"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="22sp"/>
<ImageButton
android:id="@+id/page_next_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:contentDescription="@string/text_next"
app:srcCompat="@drawable/page_next"/>
<ImageButton
android:id="@+id/page_last_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:contentDescription="@string/text_last"
app:srcCompat="@drawable/page_last"/>
</LinearLayout>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar <me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding" style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
@ -107,8 +53,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginBottom="50dp" android:layout_margin="@dimen/fab_margins"
android:layout_marginEnd="@dimen/fab_margins"
app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior" app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior"
app:srcCompat="@drawable/ic_add_fab"/> app:srcCompat="@drawable/ic_add_fab"/>
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

48
app/src/main/res/layout/activity_board_sub_board.xml

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/child_board_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/card_background"
android:clickable="true"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<TextView
android:id="@+id/child_board_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_board_title"
android:textColor="@color/accent"
android:textStyle="bold"/>
<TextView
android:id="@+id/child_board_mods"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:text="@string/child_board_mods"
android:textColor="@color/secondary_text"/>
<TextView
android:id="@+id/child_board_stats"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:text="@string/child_board_stats"
android:textColor="@color/secondary_text"/>
<TextView
android:id="@+id/child_board_last_post"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:text="@string/child_board_last_post"
android:textColor="@color/secondary_text"/>
</LinearLayout>

60
app/src/main/res/layout/activity_board_topic.xml

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topic_row_linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/topic_subject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/topic_subject"
android:textColor="@color/primary_text"
android:textStyle="bold"/>
<TextView
android:id="@+id/topic_locked_sticky"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/topic_locked_sticky"
android:textColor="@color/accent"/>
</LinearLayout>
<TextView
android:id="@+id/topic_started_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:text="@string/topic_started_by"
android:textColor="@color/secondary_text"/>
<TextView
android:id="@+id/topic_stats"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:text="@string/topic_stats"
android:textColor="@color/secondary_text"/>
<TextView
android:id="@+id/topic_last_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:text="@string/topic_last_post"
android:textColor="@color/secondary_text"/>
</LinearLayout>

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

@ -39,7 +39,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:contentDescription="@string/thumbnail" android:contentDescription="@string/post_thumbnail"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:src="@drawable/ic_default_user_thumbnail" android:src="@drawable/ic_default_user_thumbnail"
app:layout_collapseMode="parallax"/> app:layout_collapseMode="parallax"/>

10
app/src/main/res/layout/activity_topic.xml

@ -50,7 +50,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.8" android:layout_weight="0.8"
android:contentDescription="@string/text_first" android:contentDescription="@string/button_first"
app:srcCompat="@drawable/page_first"/> app:srcCompat="@drawable/page_first"/>
<ImageButton <ImageButton
@ -58,7 +58,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.8" android:layout_weight="0.8"
android:contentDescription="@string/text_previous" android:contentDescription="@string/button_previous"
app:srcCompat="@drawable/page_previous"/> app:srcCompat="@drawable/page_previous"/>
<TextView <TextView
@ -68,7 +68,7 @@
android:layout_gravity="center" android:layout_gravity="center"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:hint="@string/text_page" android:hint="@string/button_page"
android:maxLines="1" android:maxLines="1"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="22sp"/> android:textSize="22sp"/>
@ -78,7 +78,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.8" android:layout_weight="0.8"
android:contentDescription="@string/text_next" android:contentDescription="@string/button_next"
app:srcCompat="@drawable/page_next"/> app:srcCompat="@drawable/page_next"/>
<ImageButton <ImageButton
@ -86,7 +86,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.8" android:layout_weight="0.8"
android:contentDescription="@string/text_last" android:contentDescription="@string/button_last"
app:srcCompat="@drawable/page_last"/> app:srcCompat="@drawable/page_last"/>
</LinearLayout> </LinearLayout>

8
app/src/main/res/layout/activity_topic_post_row.xml

@ -88,7 +88,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:contentDescription="@string/thumbnail" android:contentDescription="@string/post_thumbnail"
android:maxHeight="@dimen/thumbnail_size" android:maxHeight="@dimen/thumbnail_size"
android:maxWidth="@dimen/thumbnail_size" android:maxWidth="@dimen/thumbnail_size"
android:src="@drawable/ic_default_user_thumbnail"/> android:src="@drawable/ic_default_user_thumbnail"/>
@ -102,7 +102,7 @@
android:layout_toEndOf="@+id/thumbnail_holder" android:layout_toEndOf="@+id/thumbnail_holder"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:text="@string/username" android:text="@string/post_author"
android:textColor="@color/primary_text" android:textColor="@color/primary_text"
android:textStyle="bold"/> android:textStyle="bold"/>
@ -114,7 +114,7 @@
android:layout_toEndOf="@+id/thumbnail_holder" android:layout_toEndOf="@+id/thumbnail_holder"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:text="@string/subject" android:text="@string/post_subject"
/> />
</RelativeLayout> </RelativeLayout>
@ -126,7 +126,7 @@
android:layout_marginTop="9dp" android:layout_marginTop="9dp"
android:background="@color/card_background" android:background="@color/card_background"
android:clickable="true" android:clickable="true"
android:contentDescription="@string/quote" android:contentDescription="@string/post_quote_button"
android:src="@drawable/ic_format_quote_unchecked"/> android:src="@drawable/ic_format_quote_unchecked"/>
</LinearLayout> </LinearLayout>

6
app/src/main/res/layout/fragment_recent_row.xml

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

83
app/src/main/res/values/strings.xml

@ -1,32 +1,68 @@
<resources> <resources>
<string name="app_name">mTHMMY</string> <string name="app_name">mTHMMY</string>
<!--Base Activity-->
<string name="login">Login</string>
<string name="login_spinner">Authenticating&#8230;</string>
<string name="logout">Logout</string>
<string name="home">Home</string>
<!--Login Activity-->
<string name="thmmy_img_description">thmmy.gr</string> <string name="thmmy_img_description">thmmy.gr</string>
<string name="hint_username">Username</string> <string name="hint_username">Username</string>
<string name="hint_password">Password</string> <string name="hint_password">Password</string>
<string name="btn_login">LOGIN</string> <string name="btn_login">LOGIN</string>
<string name="btn_continue_as_guest">Don\'t have an account? Continue as guest!</string> <string name="btn_continue_as_guest">Don\'t have an account? Continue as guest!</string>
<!--Main Activity-->
<string name="byUser">by %1$s</string>
<!--Board Activity-->
<string name="child_board_title">Child Board</string>
<string name="child_board_mods">Moderators: %1$s</string>
<string name="child_board_stats">Stats</string>
<string name="child_board_last_post">Last post</string>
<string name="topic_subject">Subject</string>
<string name="topic_locked_sticky">Locked/Sticky</string>
<string name="topic_started_by">Started By: %1$s</string>
<string name="topic_stats">Stats</string>
<string name="topic_last_post">Last post on: %1$s</string>
<!--Topic Activity-->
<string name="post_author">Post author</string>
<string name="post_subject">Post subject</string>
<string name="post">Post</string>
<string name="post_thumbnail">Thumbnail</string>
<string name="post_quote_button">Quote button</string>
<string name="user_number_of_posts">#%1$d</string>
<string name="button_first">first</string>
<string name="button_previous">previous</string>
<string name="button_page">Page</string>
<string name="button_next">next</string>
<string name="button_last">last</string>
<!--Profile Activity-->
<string name="general_statistics_title">General Statistics</string>
<string name="general_statistics">Statistics</string>
<string name="posting_activity_by_time_title">Posting Activity</string>
<string name="most_popular_boards_by_posts_title">Most Popular Boards By Posts</string>
<string name="most_popular_boards_by_activity_title">Most Popular Boards By Activity</string>
<!--About Activity-->
<string name="about">About</string> <string name="about">About</string>
<string name="version">v%1$s</string> <string name="version">v%1$s</string>
<string name="logo">Logo</string> <string name="logo">Logo</string>
<string name="trollPic">You should watch a funny pic!</string> <string name="trollPic">You should watch a funny pic!</string>
<string name="login">Login</string>
<string name="login_spinner">Authenticating&#8230;</string>
<string name="logout">Logout</string>
<string name="username">Username should be here&#8230;</string> <!--Licences-->
<string name="subject">Subject should be here&#8230;</string> <string name="libraries">Libraries</string>
<string name="post">Post should be here&#8230;</string> <string name="libraries_text">mTHMMY uses the following open-source libraries:</string>
<string name="thumbnail">Thumbnail should be here&#8230;</string> <string name="apache_v2_0_libraries"><u>Apache v2.0 License libraries</u></string>
<string name="quote">Quote button should be here&#8230;</string> <string name="the_mit_libraries"><u>The MIT License libraries</u></string>
<string name="text_first">first</string> <string name="contact">Contact</string>
<string name="text_previous">previous</string> <string name="contact_text">Do not hesitate to contact us for any matter either by email at thmmynolife@gmail.com, or by joining our discord server at https://discord.gg/CVt3yrn.</string>
<string name="text_page">Page</string>
<string name="text_next">next</string>
<string name="text_last">last</string>
<string name="home">Home</string>
<!--FontAwesome strings-->
<string name="fa_icon_star">&#xf005;</string> <string name="fa_icon_star">&#xf005;</string>
<string name="fa_file">&#xf15b;</string> <string name="fa_file">&#xf15b;</string>
<string name="fa_file_image_o">&#xf1c5;</string> <string name="fa_file_image_o">&#xf1c5;</string>
@ -37,21 +73,6 @@
<string name="fa_file_powerpoint_o">&#xf1c4;</string> <string name="fa_file_powerpoint_o">&#xf1c4;</string>
<string name="fa_file_excel_o">&#xf1c3;</string> <string name="fa_file_excel_o">&#xf1c3;</string>
<string name="fa_file_video_o">&#xf1c8;</string> <string name="fa_file_video_o">&#xf1c8;</string>
<string name="fa_info_circle">&#xf05a;</string> <string name="fa_lock">&#xf023;</string>
<string name="fa_sticky">&#xf249;</string>
<string name="user_number_of_posts">#%1$d</string>
<string name="byUser">by %1$s</string>
<string name="general_statistics_title">General Statistics</string>
<string name="general_statistics">Statistics</string>
<string name="posting_activity_by_time_title">Posting Activity</string>
<string name="most_popular_boards_by_posts_title">Most Popular Boards By Posts</string>
<string name="most_popular_boards_by_activity_title">Most Popular Boards By Activity</string>
<string name="libraries">Libraries</string>
<string name="libraries_text">mTHMMY uses the following open-source libraries:</string>
<string name="apache_v2_0_libraries"><u>Apache v2.0 License libraries</u></string>
<string name="the_mit_libraries"><u>The MIT License libraries</u></string>
<string name="contact">Contact</string>
<string name="contact_text">Do not hesitate to contact us for any matter either by email at thmmynolife@gmail.com, or by joining our discord server at https://discord.gg/CVt3yrn.</string>
</resources> </resources>

Loading…
Cancel
Save