ViewThreadFragment.java 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Copyright 2017 Andrew Dawson
  2. *
  3. * This file is a part of Tusky.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it under the terms of the
  6. * GNU General Public License as published by the Free Software Foundation; either version 3 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
  10. * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  11. * Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with Tusky; if not,
  14. * see <http://www.gnu.org/licenses>. */
  15. package com.keylesspalace.tusky;
  16. import android.content.Context;
  17. import android.graphics.drawable.Drawable;
  18. import android.os.Bundle;
  19. import android.support.annotation.Nullable;
  20. import android.support.design.widget.Snackbar;
  21. import android.support.v4.content.ContextCompat;
  22. import android.support.v7.widget.DividerItemDecoration;
  23. import android.support.v7.widget.LinearLayoutManager;
  24. import android.support.v7.widget.RecyclerView;
  25. import android.view.LayoutInflater;
  26. import android.view.View;
  27. import android.view.ViewGroup;
  28. import com.keylesspalace.tusky.entity.Status;
  29. import com.keylesspalace.tusky.entity.StatusContext;
  30. import retrofit2.Call;
  31. import retrofit2.Callback;
  32. public class ViewThreadFragment extends SFragment implements StatusActionListener {
  33. private static final String TAG = "ViewThreadFragment";
  34. private RecyclerView recyclerView;
  35. private ThreadAdapter adapter;
  36. private String thisThreadsStatusId;
  37. public static ViewThreadFragment newInstance(String id) {
  38. Bundle arguments = new Bundle();
  39. ViewThreadFragment fragment = new ViewThreadFragment();
  40. arguments.putString("id", id);
  41. fragment.setArguments(arguments);
  42. return fragment;
  43. }
  44. @Nullable
  45. @Override
  46. public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
  47. @Nullable Bundle savedInstanceState) {
  48. View rootView = inflater.inflate(R.layout.fragment_view_thread, container, false);
  49. Context context = getContext();
  50. recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
  51. recyclerView.setHasFixedSize(true);
  52. LinearLayoutManager layoutManager = new LinearLayoutManager(context);
  53. recyclerView.setLayoutManager(layoutManager);
  54. DividerItemDecoration divider = new DividerItemDecoration(
  55. context, layoutManager.getOrientation());
  56. Drawable drawable = ThemeUtils.getDrawable(context, R.attr.status_divider_drawable,
  57. R.drawable.status_divider_dark);
  58. divider.setDrawable(drawable);
  59. recyclerView.addItemDecoration(divider);
  60. recyclerView.addItemDecoration(new ConversationLineItemDecoration(context, ContextCompat.getDrawable(context, R.drawable.conversation_divider_dark)));
  61. adapter = new ThreadAdapter(this);
  62. recyclerView.setAdapter(adapter);
  63. String id = getArguments().getString("id");
  64. sendStatusRequest(id);
  65. sendThreadRequest(id);
  66. thisThreadsStatusId = id;
  67. return rootView;
  68. }
  69. private void sendStatusRequest(final String id) {
  70. MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
  71. Call<Status> call = api.status(id);
  72. call.enqueue(new Callback<Status>() {
  73. @Override
  74. public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
  75. if (response.isSuccessful()) {
  76. int position = adapter.insertStatus(response.body());
  77. recyclerView.scrollToPosition(position);
  78. } else {
  79. onThreadRequestFailure(id);
  80. }
  81. }
  82. @Override
  83. public void onFailure(Call<Status> call, Throwable t) {
  84. onThreadRequestFailure(id);
  85. }
  86. });
  87. callList.add(call);
  88. }
  89. private void sendThreadRequest(final String id) {
  90. MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
  91. Call<StatusContext> call = api.statusContext(id);
  92. call.enqueue(new Callback<StatusContext>() {
  93. @Override
  94. public void onResponse(Call<StatusContext> call, retrofit2.Response<StatusContext> response) {
  95. if (response.isSuccessful()) {
  96. StatusContext context = response.body();
  97. adapter.addAncestors(context.ancestors);
  98. adapter.addDescendants(context.descendants);
  99. } else {
  100. onThreadRequestFailure(id);
  101. }
  102. }
  103. @Override
  104. public void onFailure(Call<StatusContext> call, Throwable t) {
  105. onThreadRequestFailure(id);
  106. }
  107. });
  108. callList.add(call);
  109. }
  110. private void onThreadRequestFailure(final String id) {
  111. View view = getView();
  112. if (view != null) {
  113. Snackbar.make(view, R.string.error_generic, Snackbar.LENGTH_LONG)
  114. .setAction(R.string.action_retry, new View.OnClickListener() {
  115. @Override
  116. public void onClick(View v) {
  117. sendThreadRequest(id);
  118. sendStatusRequest(id);
  119. }
  120. })
  121. .show();
  122. } else {
  123. Log.e(TAG, "Couldn't display thread fetch error message");
  124. }
  125. }
  126. public void onReply(int position) {
  127. super.reply(adapter.getItem(position));
  128. }
  129. public void onReblog(boolean reblog, int position) {
  130. super.reblog(adapter.getItem(position), reblog, adapter, position);
  131. }
  132. public void onFavourite(boolean favourite, int position) {
  133. super.favourite(adapter.getItem(position), favourite, adapter, position);
  134. }
  135. public void onMore(View view, int position) {
  136. super.more(adapter.getItem(position), view, adapter, position);
  137. }
  138. public void onViewMedia(String url, Status.MediaAttachment.Type type) {
  139. super.viewMedia(url, type);
  140. }
  141. public void onViewThread(int position) {
  142. Status status = adapter.getItem(position);
  143. if (thisThreadsStatusId.equals(status.id)) {
  144. // If already viewing this thread, don't reopen it.
  145. return;
  146. }
  147. super.viewThread(status);
  148. }
  149. public void onViewTag(String tag) {
  150. super.viewTag(tag);
  151. }
  152. public void onViewAccount(String id) {
  153. super.viewAccount(id);
  154. }
  155. }