add option to selection popup to quote

open sitesetup in correct split controller
show empty view when the threadlayout wasn't touched yet
refactor-toolbar
Floens 8 years ago
parent 78f37e6b4a
commit 3c7f68e21d
  1. 34
      Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java
  2. 9
      Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java
  3. 11
      Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java
  4. 36
      Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java
  5. 2
      Clover/app/src/main/java/org/floens/chan/ui/cell/PostCellInterface.java
  6. 4
      Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java
  7. 14
      Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
  8. 20
      Clover/app/src/main/res/values/ids.xml

@ -280,26 +280,36 @@ public class ReplyPresenter implements AuthenticationLayoutCallback, ImagePickDe
} }
public void quote(Post post, boolean withText) { public void quote(Post post, boolean withText) {
handleQuote(post, withText ? post.comment.toString() : null);
}
public void quote(Post post, CharSequence text) {
handleQuote(null, text.toString());
}
private void handleQuote(Post post, String textQuote) {
callback.loadViewsIntoDraft(draft); callback.loadViewsIntoDraft(draft);
String textToInsert = ""; String extraNewline = "";
if (draft.selection - 1 >= 0 && draft.selection - 1 < draft.comment.length() && draft.comment.charAt(draft.selection - 1) != '\n') { if (draft.selection - 1 >= 0 && draft.selection - 1 < draft.comment.length() &&
textToInsert += "\n"; draft.comment.charAt(draft.selection - 1) != '\n') {
extraNewline = "\n";
} }
textToInsert += ">>" + post.no + "\n"; String postQuote = post != null ? ">>" + post.no + "\n" : "";
if (withText) { StringBuilder textQuoteResult = new StringBuilder();
String[] lines = post.comment.toString().split("\n+"); String[] lines = textQuote.split("\n+");
final Pattern quotePattern = Pattern.compile("^>>(>/[a-z0-9]+/)?\\d+.*$"); // matches for >>123, >>123 (OP), >>123 (You), >>>/fit/123 // matches for >>123, >>123 (OP), >>123 (You), >>>/fit/123
for (String line : lines) { final Pattern quotePattern = Pattern.compile("^>>(>/[a-z0-9]+/)?\\d+.*$");
if (!quotePattern.matcher(line).matches()) { // do not include post no from quoted post for (String line : lines) {
textToInsert += ">" + line + "\n"; // do not include post no from quoted post
} if (!quotePattern.matcher(line).matches()) {
textQuoteResult.append(">").append(line).append("\n");
} }
} }
commentInsert(textToInsert); commentInsert(extraNewline + postQuote + textQuoteResult.toString());
highlightQuotes(); highlightQuotes();
} }

@ -117,6 +117,8 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt
this.loadable = loadable; this.loadable = loadable;
chanLoader = chanLoaderFactory.obtain(loadable, this); chanLoader = chanLoaderFactory.obtain(loadable, this);
threadPresenterCallback.showLoading();
} }
} }
@ -554,6 +556,11 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt
threadPresenterCallback.quote(post, false); threadPresenterCallback.quote(post, false);
} }
@Override
public void onPostSelectionQuoted(Post post, CharSequence quoted) {
threadPresenterCallback.quote(post, quoted);
}
@Override @Override
public void onShowPostReplies(Post post) { public void onShowPostReplies(Post post) {
List<Post> posts = new ArrayList<>(); List<Post> posts = new ArrayList<>();
@ -757,6 +764,8 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt
void quote(Post post, boolean withText); void quote(Post post, boolean withText);
void quote(Post post, CharSequence text);
void confirmPostDelete(Post post); void confirmPostDelete(Post post);
void showDeleting(); void showDeleting();

@ -156,7 +156,15 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
private void restoreFresh() { private void restoreFresh() {
if (!siteManager.areSitesSetup()) { if (!siteManager.areSitesSetup()) {
mainNavigationController.pushController(new SitesSetupController(this), false); SitesSetupController setupController = new SitesSetupController(this);
if (drawerController.childControllers.get(0) instanceof DoubleNavigationController) {
DoubleNavigationController doubleNavigationController =
(DoubleNavigationController) drawerController.childControllers.get(0);
doubleNavigationController.pushController(setupController, false);
} else {
mainNavigationController.pushController(setupController, false);
}
} else { } else {
browseController.loadWithDefaultBoard(); browseController.loadWithDefaultBoard();
} }
@ -451,6 +459,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
// TODO: clear whole stack?
stackTop().onHide(); stackTop().onHide();
stackTop().onDestroy(); stackTop().onDestroy();
stack.clear(); stack.clear();

@ -41,6 +41,9 @@ import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan; import android.text.style.ClickableSpan;
import android.text.style.UnderlineSpan; import android.text.style.UnderlineSpan;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
@ -429,6 +432,39 @@ public class PostCell extends LinearLayout implements PostCellInterface {
comment.setTextIsSelectable(true); comment.setTextIsSelectable(true);
comment.setText(commentText, TextView.BufferType.SPANNABLE); comment.setText(commentText, TextView.BufferType.SPANNABLE);
comment.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
private MenuItem quoteMenuItem;
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
quoteMenuItem = menu.add(Menu.NONE, R.id.post_selection_action_quote,
0, R.string.post_quote);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item == quoteMenuItem) {
CharSequence selection = comment.getText().subSequence(
comment.getSelectionStart(), comment.getSelectionEnd());
callback.onPostSelectionQuoted(post, selection);
mode.finish();
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
} else { } else {
comment.setText(commentText); comment.setText(commentText);
} }

@ -58,5 +58,7 @@ public interface PostCellInterface {
void onPostLinkableClicked(Post post, PostLinkable linkable); void onPostLinkableClicked(Post post, PostLinkable linkable);
void onPostNoClicked(Post post); void onPostNoClicked(Post post);
void onPostSelectionQuoted(Post post, CharSequence quoted);
} }
} }

@ -115,6 +115,10 @@ public class ThemeSettingsController extends Controller implements View.OnClickL
@Override @Override
public void onPostNoClicked(Post post) { public void onPostNoClicked(Post post) {
} }
@Override
public void onPostSelectionQuoted(Post post, CharSequence quoted) {
}
}; };
private ChanParser.Callback parserCallback = new ChanParser.Callback() { private ChanParser.Callback parserCallback = new ChanParser.Callback() {

@ -72,7 +72,11 @@ import static org.floens.chan.utils.AndroidUtils.getString;
/** /**
* Wrapper around ThreadListLayout, so that it cleanly manages between a load bar and the list view. * Wrapper around ThreadListLayout, so that it cleanly manages between a load bar and the list view.
*/ */
public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.ThreadPresenterCallback, PostPopupHelper.PostPopupHelperCallback, View.OnClickListener, ThreadListLayout.ThreadListLayoutCallback { public class ThreadLayout extends CoordinatorLayout implements
ThreadPresenter.ThreadPresenterCallback,
PostPopupHelper.PostPopupHelperCallback,
View.OnClickListener,
ThreadListLayout.ThreadListLayoutCallback {
private enum Visible { private enum Visible {
LOADING, LOADING,
THREAD, THREAD,
@ -152,8 +156,6 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
} }
presenter.create(this); presenter.create(this);
switchVisible(Visible.LOADING);
} }
public void destroy() { public void destroy() {
@ -387,6 +389,12 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
threadListLayout.getReplyPresenter().quote(post, withText); threadListLayout.getReplyPresenter().quote(post, withText);
} }
@Override
public void quote(Post post, CharSequence text) {
threadListLayout.openReply(true);
threadListLayout.getReplyPresenter().quote(post, text);
}
@Override @Override
public void confirmPostDelete(final Post post) { public void confirmPostDelete(final Post post) {
@SuppressLint("InflateParams") final View view = LayoutInflater.from(getContext()) @SuppressLint("InflateParams") final View view = LayoutInflater.from(getContext())

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?><!--
Clover - 4chan browser https://github.com/Floens/Clover/
Copyright (C) 2014 Floens
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<item name="post_selection_action_quote" type="id" />
</resources>
Loading…
Cancel
Save