mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
All text that can be generated by users will show emoji from the shipped sprites. For all messages and posts, the custom emoji keyboard is now available. This also disables menu actions rather than hiding them and thus closes #677 Included is a fix for a regression that was not showing the keyboard automatically in forums and thus closes #676
353 lines
10 KiB
Java
353 lines
10 KiB
Java
package org.briarproject.android.blogs;
|
|
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.design.widget.Snackbar;
|
|
import android.support.v4.app.ActivityOptionsCompat;
|
|
import android.support.v4.content.ContextCompat;
|
|
import android.support.v7.app.AlertDialog;
|
|
import android.support.v7.widget.LinearLayoutManager;
|
|
import android.view.LayoutInflater;
|
|
import android.view.Menu;
|
|
import android.view.MenuInflater;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.Toast;
|
|
|
|
import org.briarproject.R;
|
|
import org.briarproject.android.ActivityComponent;
|
|
import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
|
|
import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener;
|
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
|
import org.briarproject.android.fragment.BaseFragment;
|
|
import org.briarproject.android.sharing.ShareBlogActivity;
|
|
import org.briarproject.android.sharing.SharingStatusBlogActivity;
|
|
import org.briarproject.android.view.BriarRecyclerView;
|
|
import org.briarproject.api.blogs.BlogPostHeader;
|
|
import org.briarproject.api.db.DbException;
|
|
import org.briarproject.api.identity.Author;
|
|
import org.briarproject.api.sync.GroupId;
|
|
|
|
import java.util.Collection;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import static android.app.Activity.RESULT_OK;
|
|
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
|
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
|
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
|
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
|
import static android.widget.Toast.LENGTH_SHORT;
|
|
import static org.briarproject.android.BriarActivity.GROUP_ID;
|
|
import static org.briarproject.android.blogs.BlogActivity.BLOG_NAME;
|
|
import static org.briarproject.android.blogs.BlogActivity.IS_NEW_BLOG;
|
|
import static org.briarproject.android.blogs.BlogActivity.REQUEST_SHARE;
|
|
import static org.briarproject.android.blogs.BlogActivity.REQUEST_WRITE_POST;
|
|
|
|
public class BlogFragment extends BaseFragment implements
|
|
OnBlogPostAddedListener {
|
|
|
|
public final static String TAG = BlogFragment.class.getName();
|
|
|
|
@Inject
|
|
BlogController blogController;
|
|
|
|
private GroupId groupId;
|
|
private String blogName;
|
|
private BlogPostAdapter adapter;
|
|
private BriarRecyclerView list;
|
|
private MenuItem writeButton, deleteButton;
|
|
private boolean isMyBlog = false, canDeleteBlog = false;
|
|
|
|
static BlogFragment newInstance(GroupId groupId, String name,
|
|
boolean isNew) {
|
|
|
|
BlogFragment f = new BlogFragment();
|
|
|
|
Bundle bundle = new Bundle();
|
|
bundle.putByteArray(GROUP_ID, groupId.getBytes());
|
|
bundle.putString(BLOG_NAME, name);
|
|
bundle.putBoolean(IS_NEW_BLOG, isNew);
|
|
|
|
f.setArguments(bundle);
|
|
return f;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
Bundle savedInstanceState) {
|
|
|
|
setHasOptionsMenu(true);
|
|
|
|
Bundle args = getArguments();
|
|
byte[] b = args.getByteArray(GROUP_ID);
|
|
if (b == null) throw new IllegalStateException("No group ID in args");
|
|
groupId = new GroupId(b);
|
|
blogName = args.getString(BLOG_NAME);
|
|
boolean isNew = args.getBoolean(IS_NEW_BLOG);
|
|
|
|
View v = inflater.inflate(R.layout.fragment_blog, container, false);
|
|
|
|
adapter = new BlogPostAdapter(getActivity(),
|
|
(OnBlogPostClickListener) getActivity());
|
|
list = (BriarRecyclerView) v.findViewById(R.id.postList);
|
|
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
|
list.setAdapter(adapter);
|
|
list.showProgressBar();
|
|
list.setEmptyText(getString(R.string.blogs_other_blog_empty_state));
|
|
|
|
// show snackbar if this blog was just created
|
|
if (isNew) {
|
|
Snackbar s = Snackbar.make(list, R.string.blogs_my_blogs_created,
|
|
LENGTH_LONG);
|
|
s.getView().setBackgroundResource(R.color.briar_primary);
|
|
s.show();
|
|
|
|
// show only once
|
|
args.putBoolean(IS_NEW_BLOG, false);
|
|
}
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public void injectFragment(ActivityComponent component) {
|
|
component.inject(this);
|
|
blogController.setOnBlogPostAddedListener(this);
|
|
}
|
|
|
|
@Override
|
|
public void onStart() {
|
|
super.onStart();
|
|
loadBlog();
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
loadBlogPosts(false);
|
|
list.startPeriodicUpdate();
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
list.stopPeriodicUpdate();
|
|
}
|
|
|
|
@Override
|
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
inflater.inflate(R.menu.blogs_blog_actions, menu);
|
|
writeButton = menu.findItem(R.id.action_write_blog_post);
|
|
if (isMyBlog) writeButton.setVisible(true);
|
|
deleteButton = menu.findItem(R.id.action_blog_delete);
|
|
if (canDeleteBlog) deleteButton.setEnabled(true);
|
|
|
|
super.onCreateOptionsMenu(menu, inflater);
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
|
ActivityOptionsCompat options =
|
|
makeCustomAnimation(getActivity(),
|
|
android.R.anim.slide_in_left,
|
|
android.R.anim.slide_out_right);
|
|
switch (item.getItemId()) {
|
|
case android.R.id.home:
|
|
getActivity().onBackPressed();
|
|
return true;
|
|
case R.id.action_write_blog_post:
|
|
Intent i =
|
|
new Intent(getActivity(), WriteBlogPostActivity.class);
|
|
i.putExtra(GROUP_ID, groupId.getBytes());
|
|
i.putExtra(BLOG_NAME, blogName);
|
|
startActivityForResult(i, REQUEST_WRITE_POST,
|
|
options.toBundle());
|
|
return true;
|
|
case R.id.action_blog_share:
|
|
Intent i2 = new Intent(getActivity(), ShareBlogActivity.class);
|
|
i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
|
i2.putExtra(GROUP_ID, groupId.getBytes());
|
|
startActivityForResult(i2, REQUEST_SHARE, options.toBundle());
|
|
return true;
|
|
case R.id.action_blog_sharing_status:
|
|
Intent i3 = new Intent(getActivity(),
|
|
SharingStatusBlogActivity.class);
|
|
i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
|
i3.putExtra(GROUP_ID, groupId.getBytes());
|
|
startActivity(i3, options.toBundle());
|
|
return true;
|
|
case R.id.action_blog_delete:
|
|
showDeleteDialog();
|
|
return true;
|
|
default:
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(int request, int result, Intent data) {
|
|
super.onActivityResult(request, result, data);
|
|
|
|
if (request == REQUEST_WRITE_POST && result == RESULT_OK) {
|
|
displaySnackbar(R.string.blogs_blog_post_created, true);
|
|
loadBlogPosts(true);
|
|
} else if (request == REQUEST_SHARE && result == RESULT_OK) {
|
|
displaySnackbar(R.string.blogs_sharing_snackbar, false);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getUniqueTag() {
|
|
return TAG;
|
|
}
|
|
|
|
@Override
|
|
public void onBlogPostAdded(BlogPostHeader header, final boolean local) {
|
|
blogController.loadBlogPost(header,
|
|
new UiResultExceptionHandler<BlogPostItem, DbException>(
|
|
listener) {
|
|
@Override
|
|
public void onResultUi(BlogPostItem post) {
|
|
adapter.add(post);
|
|
if (local) {
|
|
list.scrollToPosition(0);
|
|
displaySnackbar(R.string.blogs_blog_post_created, false);
|
|
} else {
|
|
displaySnackbar(R.string.blogs_blog_post_received, true);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onExceptionUi(DbException exception) {
|
|
// TODO: Decide how to handle errors in the UI
|
|
getActivity().finish();
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
void loadBlogPosts(final boolean reload) {
|
|
blogController.loadBlogPosts(
|
|
new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
|
|
listener) {
|
|
@Override
|
|
public void onResultUi(Collection<BlogPostItem> posts) {
|
|
if (posts.size() > 0) {
|
|
adapter.addAll(posts);
|
|
if (reload) list.scrollToPosition(0);
|
|
} else {
|
|
list.showData();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onExceptionUi(DbException exception) {
|
|
// TODO: Decide how to handle errors in the UI
|
|
finish();
|
|
}
|
|
});
|
|
}
|
|
|
|
private void loadBlog() {
|
|
blogController.loadBlog(
|
|
new UiResultExceptionHandler<BlogItem, DbException>(listener) {
|
|
@Override
|
|
public void onResultUi(BlogItem blog) {
|
|
setToolbarTitle(blog.getBlog().getAuthor());
|
|
if (blog.isOurs())
|
|
showWriteButton();
|
|
if (blog.canBeRemoved())
|
|
enableDeleteButton();
|
|
}
|
|
|
|
@Override
|
|
public void onExceptionUi(DbException exception) {
|
|
// TODO: Decide how to handle errors in the UI
|
|
finish();
|
|
}
|
|
});
|
|
}
|
|
|
|
private void setToolbarTitle(Author a) {
|
|
String title = getString(R.string.blogs_personal_blog, a.getName());
|
|
getActivity().setTitle(title);
|
|
|
|
// safe title in intent, so it can be restored automatically
|
|
Intent intent = getActivity().getIntent();
|
|
intent.putExtra(BLOG_NAME, title);
|
|
}
|
|
|
|
private void showWriteButton() {
|
|
isMyBlog = true;
|
|
if (writeButton != null)
|
|
writeButton.setVisible(true);
|
|
}
|
|
|
|
private void enableDeleteButton() {
|
|
canDeleteBlog = true;
|
|
if (deleteButton != null)
|
|
deleteButton.setEnabled(true);
|
|
}
|
|
|
|
private void displaySnackbar(int stringId, boolean scroll) {
|
|
Snackbar snackbar =
|
|
Snackbar.make(list, stringId, Snackbar.LENGTH_LONG);
|
|
snackbar.getView().setBackgroundResource(R.color.briar_primary);
|
|
if (scroll) {
|
|
View.OnClickListener onClick = new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
list.smoothScrollToPosition(0);
|
|
}
|
|
};
|
|
snackbar.setActionTextColor(ContextCompat
|
|
.getColor(getContext(),
|
|
R.color.briar_button_positive));
|
|
snackbar.setAction(R.string.blogs_blog_post_scroll_to, onClick);
|
|
}
|
|
snackbar.show();
|
|
}
|
|
|
|
private void showDeleteDialog() {
|
|
DialogInterface.OnClickListener okListener =
|
|
new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
deleteBlog();
|
|
}
|
|
};
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
|
|
R.style.BriarDialogTheme);
|
|
builder.setTitle(getString(R.string.blogs_remove_blog));
|
|
builder.setMessage(
|
|
getString(R.string.blogs_remove_blog_dialog_message));
|
|
builder.setPositiveButton(R.string.cancel, null);
|
|
builder.setNegativeButton(R.string.blogs_remove_blog_ok, okListener);
|
|
builder.show();
|
|
}
|
|
|
|
private void deleteBlog() {
|
|
blogController.deleteBlog(
|
|
new UiResultExceptionHandler<Void, DbException>(listener) {
|
|
@Override
|
|
public void onResultUi(Void result) {
|
|
Toast.makeText(getActivity(),
|
|
R.string.blogs_blog_removed, LENGTH_SHORT)
|
|
.show();
|
|
getActivity().supportFinishAfterTransition();
|
|
}
|
|
|
|
@Override
|
|
public void onExceptionUi(DbException exception) {
|
|
// TODO: Decide how to handle errors in the UI
|
|
finish();
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|