mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Compare commits
11 Commits
beta-0.16.
...
beta-0.16.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3800cd5e4f | ||
|
|
259f2cd419 | ||
|
|
20eb022c36 | ||
|
|
531e555b52 | ||
|
|
a9024aa34b | ||
|
|
d4e3b7842c | ||
|
|
167fddfbcc | ||
|
|
a48d642648 | ||
|
|
9a70f054c7 | ||
|
|
ca43d13bd6 | ||
|
|
5b71004179 |
@@ -54,6 +54,7 @@ public class BrambleCoreModule {
|
|||||||
c.inject(new IdentityModule.EagerSingletons());
|
c.inject(new IdentityModule.EagerSingletons());
|
||||||
c.inject(new LifecycleModule.EagerSingletons());
|
c.inject(new LifecycleModule.EagerSingletons());
|
||||||
c.inject(new PluginModule.EagerSingletons());
|
c.inject(new PluginModule.EagerSingletons());
|
||||||
|
c.inject(new PropertiesModule.EagerSingletons());
|
||||||
c.inject(new SyncModule.EagerSingletons());
|
c.inject(new SyncModule.EagerSingletons());
|
||||||
c.inject(new SystemModule.EagerSingletons());
|
c.inject(new SystemModule.EagerSingletons());
|
||||||
c.inject(new TransportModule.EagerSingletons());
|
c.inject(new TransportModule.EagerSingletons());
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 22
|
targetSdkVersion 22
|
||||||
versionCode 1602
|
versionCode 1604
|
||||||
versionName "0.16.2"
|
versionName "0.16.4"
|
||||||
applicationId "org.briarproject.briar.beta"
|
applicationId "org.briarproject.briar.beta"
|
||||||
resValue "string", "app_package", "org.briarproject.briar.beta"
|
resValue "string", "app_package", "org.briarproject.briar.beta"
|
||||||
buildConfigField "String", "GitHash", "\"${getGitHash()}\""
|
buildConfigField "String", "GitHash", "\"${getGitHash()}\""
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ abstract class BasePostFragment extends BaseFragment {
|
|||||||
false);
|
false);
|
||||||
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
|
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
ui = new BlogPostViewHolder(view);
|
ui = new BlogPostViewHolder(view, true, new OnBlogPostClickListener() {
|
||||||
ui.setOnBlogPostClickListener(new OnBlogPostClickListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlogPostClick(BlogPostItem post) {
|
public void onBlogPostClick(BlogPostItem post) {
|
||||||
// We're already there
|
// We're already there
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
BlogInvitationResponseReceivedEvent b =
|
BlogInvitationResponseReceivedEvent b =
|
||||||
(BlogInvitationResponseReceivedEvent) e;
|
(BlogInvitationResponseReceivedEvent) e;
|
||||||
InvitationResponse r = b.getResponse();
|
InvitationResponse r = b.getResponse();
|
||||||
if (r.getGroupId().equals(groupId) && r.wasAccepted()) {
|
if (r.getShareableId().equals(groupId) && r.wasAccepted()) {
|
||||||
LOG.info("Blog invitation accepted");
|
LOG.info("Blog invitation accepted");
|
||||||
onBlogInvitationAccepted(b.getContactId());
|
onBlogInvitationAccepted(b.getContactId());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ class BlogPostAdapter
|
|||||||
int viewType) {
|
int viewType) {
|
||||||
View v = LayoutInflater.from(ctx).inflate(
|
View v = LayoutInflater.from(ctx).inflate(
|
||||||
R.layout.list_item_blog_post, parent, false);
|
R.layout.list_item_blog_post, parent, false);
|
||||||
BlogPostViewHolder ui = new BlogPostViewHolder(v);
|
BlogPostViewHolder ui = new BlogPostViewHolder(v, false, listener);
|
||||||
ui.setOnBlogPostClickListener(listener);
|
|
||||||
return ui;
|
return ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.ActivityOptionsCompat;
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
@@ -47,12 +48,16 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
private final ImageView reblogButton;
|
private final ImageView reblogButton;
|
||||||
private final TextView body;
|
private final TextView body;
|
||||||
private final ViewGroup commentContainer;
|
private final ViewGroup commentContainer;
|
||||||
|
private final boolean fullText;
|
||||||
|
|
||||||
@Nullable
|
@NonNull
|
||||||
private OnBlogPostClickListener listener;
|
private final OnBlogPostClickListener listener;
|
||||||
|
|
||||||
BlogPostViewHolder(View v) {
|
BlogPostViewHolder(View v, boolean fullText,
|
||||||
|
@NonNull OnBlogPostClickListener listener) {
|
||||||
super(v);
|
super(v);
|
||||||
|
this.fullText = fullText;
|
||||||
|
this.listener = listener;
|
||||||
|
|
||||||
ctx = v.getContext();
|
ctx = v.getContext();
|
||||||
layout = (ViewGroup) v.findViewById(R.id.postLayout);
|
layout = (ViewGroup) v.findViewById(R.id.postLayout);
|
||||||
@@ -64,10 +69,6 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
(ViewGroup) v.findViewById(R.id.commentContainer);
|
(ViewGroup) v.findViewById(R.id.commentContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOnBlogPostClickListener(OnBlogPostClickListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setVisibility(int visibility) {
|
void setVisibility(int visibility) {
|
||||||
layout.setVisibility(visibility);
|
layout.setVisibility(visibility);
|
||||||
}
|
}
|
||||||
@@ -92,7 +93,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
|
|
||||||
setTransitionName(item.getId());
|
setTransitionName(item.getId());
|
||||||
if (listener != null) {
|
if (!fullText) {
|
||||||
layout.setClickable(true);
|
layout.setClickable(true);
|
||||||
layout.setOnClickListener(new OnClickListener() {
|
layout.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -111,7 +112,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
author.setPersona(
|
author.setPersona(
|
||||||
item.isRssFeed() ? AuthorView.RSS_FEED : AuthorView.NORMAL);
|
item.isRssFeed() ? AuthorView.RSS_FEED : AuthorView.NORMAL);
|
||||||
// TODO make author clickable more often #624
|
// TODO make author clickable more often #624
|
||||||
if (listener != null && item.getHeader().getType() == POST) {
|
if (!fullText && item.getHeader().getType() == POST) {
|
||||||
author.setAuthorClickable(new OnClickListener() {
|
author.setAuthorClickable(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -124,7 +125,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
|
|
||||||
// post body
|
// post body
|
||||||
Spanned bodyText = getSpanned(item.getBody());
|
Spanned bodyText = getSpanned(item.getBody());
|
||||||
if (listener == null) {
|
if (fullText) {
|
||||||
body.setText(bodyText);
|
body.setText(bodyText);
|
||||||
body.setTextIsSelectable(true);
|
body.setTextIsSelectable(true);
|
||||||
makeLinksClickable(body);
|
makeLinksClickable(body);
|
||||||
@@ -170,7 +171,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
reblogger.setAuthor(item.getAuthor());
|
reblogger.setAuthor(item.getAuthor());
|
||||||
reblogger.setAuthorStatus(item.getAuthorStatus());
|
reblogger.setAuthorStatus(item.getAuthorStatus());
|
||||||
reblogger.setDate(item.getTimestamp());
|
reblogger.setDate(item.getTimestamp());
|
||||||
if (listener != null) {
|
if (!fullText) {
|
||||||
reblogger.setAuthorClickable(new OnClickListener() {
|
reblogger.setAuthorClickable(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -200,7 +201,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
|
|||||||
// TODO make author clickable #624
|
// TODO make author clickable #624
|
||||||
|
|
||||||
body.setText(c.getComment());
|
body.setText(c.getComment());
|
||||||
if (listener == null) body.setTextIsSelectable(true);
|
if (fullText) body.setTextIsSelectable(true);
|
||||||
|
|
||||||
commentContainer.addView(v);
|
commentContainer.addView(v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,7 +161,18 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
|
|||||||
private ViewHolder(View v) {
|
private ViewHolder(View v) {
|
||||||
scrollView = (ScrollView) v.findViewById(R.id.scrollView);
|
scrollView = (ScrollView) v.findViewById(R.id.scrollView);
|
||||||
progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
|
progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
|
||||||
post = new BlogPostViewHolder(v.findViewById(R.id.postLayout));
|
post = new BlogPostViewHolder(v.findViewById(R.id.postLayout),
|
||||||
|
true, new OnBlogPostClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onBlogPostClick(BlogPostItem post) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAuthorClick(BlogPostItem post) {
|
||||||
|
// probably don't want to allow author clicks here
|
||||||
|
}
|
||||||
|
});
|
||||||
input = (TextInputView) v.findViewById(R.id.inputText);
|
input = (TextInputView) v.findViewById(R.id.inputText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.forum;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@@ -43,10 +44,10 @@ public class CreateForumActivity extends BriarActivity {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(CreateForumActivity.class.getName());
|
Logger.getLogger(CreateForumActivity.class.getName());
|
||||||
|
|
||||||
|
private TextInputLayout nameEntryLayout;
|
||||||
private EditText nameEntry;
|
private EditText nameEntry;
|
||||||
private Button createForumButton;
|
private Button createForumButton;
|
||||||
private ProgressBar progress;
|
private ProgressBar progress;
|
||||||
private TextView feedback;
|
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
// Fields that are accessed from background threads must be volatile
|
||||||
@Inject
|
@Inject
|
||||||
@@ -58,6 +59,8 @@ public class CreateForumActivity extends BriarActivity {
|
|||||||
|
|
||||||
setContentView(R.layout.activity_create_forum);
|
setContentView(R.layout.activity_create_forum);
|
||||||
|
|
||||||
|
nameEntryLayout =
|
||||||
|
(TextInputLayout) findViewById(R.id.createForumNameLayout);
|
||||||
nameEntry = (EditText) findViewById(R.id.createForumNameEntry);
|
nameEntry = (EditText) findViewById(R.id.createForumNameEntry);
|
||||||
nameEntry.addTextChangedListener(new TextWatcher() {
|
nameEntry.addTextChangedListener(new TextWatcher() {
|
||||||
|
|
||||||
@@ -85,8 +88,6 @@ public class CreateForumActivity extends BriarActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
feedback = (TextView) findViewById(R.id.createForumFeedback);
|
|
||||||
|
|
||||||
createForumButton = (Button) findViewById(R.id.createForumButton);
|
createForumButton = (Button) findViewById(R.id.createForumButton);
|
||||||
createForumButton.setOnClickListener(new OnClickListener() {
|
createForumButton.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -118,10 +119,10 @@ public class CreateForumActivity extends BriarActivity {
|
|||||||
String name = nameEntry.getText().toString();
|
String name = nameEntry.getText().toString();
|
||||||
int length = StringUtils.toUtf8(name).length;
|
int length = StringUtils.toUtf8(name).length;
|
||||||
if (length > MAX_FORUM_NAME_LENGTH) {
|
if (length > MAX_FORUM_NAME_LENGTH) {
|
||||||
feedback.setText(R.string.name_too_long);
|
nameEntryLayout.setError(getString(R.string.name_too_long));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
feedback.setText("");
|
nameEntryLayout.setError(null);
|
||||||
return length > 0;
|
return length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class ForumControllerImpl extends
|
|||||||
(ForumInvitationResponseReceivedEvent) e;
|
(ForumInvitationResponseReceivedEvent) e;
|
||||||
ForumInvitationResponse r =
|
ForumInvitationResponse r =
|
||||||
(ForumInvitationResponse) f.getResponse();
|
(ForumInvitationResponse) f.getResponse();
|
||||||
if (r.getGroupId().equals(getGroupId()) && r.wasAccepted()) {
|
if (r.getShareableId().equals(getGroupId()) && r.wasAccepted()) {
|
||||||
LOG.info("Forum invitation was accepted");
|
LOG.info("Forum invitation was accepted");
|
||||||
onForumInvitationAccepted(r.getContactId());
|
onForumInvitationAccepted(r.getContactId());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class GroupControllerImpl extends
|
|||||||
(GroupInvitationResponseReceivedEvent) e;
|
(GroupInvitationResponseReceivedEvent) e;
|
||||||
final GroupInvitationResponse r =
|
final GroupInvitationResponse r =
|
||||||
(GroupInvitationResponse) g.getResponse();
|
(GroupInvitationResponse) g.getResponse();
|
||||||
if (getGroupId().equals(r.getGroupId()) && r.wasAccepted()) {
|
if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
|
||||||
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.privategroup.creation;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@@ -11,6 +12,7 @@ import android.view.View.OnClickListener;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.TextView.OnEditorActionListener;
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
|
|
||||||
@@ -19,6 +21,8 @@ import org.briarproject.briar.R;
|
|||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
|
||||||
|
import static android.view.View.GONE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
|
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
|
||||||
|
|
||||||
public class CreateGroupFragment extends BaseFragment {
|
public class CreateGroupFragment extends BaseFragment {
|
||||||
@@ -28,7 +32,8 @@ public class CreateGroupFragment extends BaseFragment {
|
|||||||
private CreateGroupListener listener;
|
private CreateGroupListener listener;
|
||||||
private EditText nameEntry;
|
private EditText nameEntry;
|
||||||
private Button createGroupButton;
|
private Button createGroupButton;
|
||||||
private TextView feedback;
|
private TextInputLayout nameLayout;
|
||||||
|
private ProgressBar progress;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
@@ -69,7 +74,7 @@ public class CreateGroupFragment extends BaseFragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
feedback = (TextView) v.findViewById(R.id.feedback);
|
nameLayout = (TextInputLayout) v.findViewById(R.id.nameLayout);
|
||||||
|
|
||||||
createGroupButton = (Button) v.findViewById(R.id.button);
|
createGroupButton = (Button) v.findViewById(R.id.button);
|
||||||
createGroupButton.setOnClickListener(new OnClickListener() {
|
createGroupButton.setOnClickListener(new OnClickListener() {
|
||||||
@@ -79,6 +84,8 @@ public class CreateGroupFragment extends BaseFragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
progress = (ProgressBar) v.findViewById(R.id.progressBar);
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,16 +114,18 @@ public class CreateGroupFragment extends BaseFragment {
|
|||||||
String name = nameEntry.getText().toString();
|
String name = nameEntry.getText().toString();
|
||||||
int length = StringUtils.toUtf8(name).length;
|
int length = StringUtils.toUtf8(name).length;
|
||||||
if (length > MAX_GROUP_NAME_LENGTH) {
|
if (length > MAX_GROUP_NAME_LENGTH) {
|
||||||
feedback.setText(R.string.name_too_long);
|
nameLayout.setError(getString(R.string.name_too_long));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
feedback.setText("");
|
nameLayout.setError(null);
|
||||||
return length > 0;
|
return length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createGroup() {
|
private void createGroup() {
|
||||||
if (!validateName()) return;
|
if (!validateName()) return;
|
||||||
listener.hideSoftKeyboard(nameEntry);
|
listener.hideSoftKeyboard(nameEntry);
|
||||||
|
createGroupButton.setVisibility(GONE);
|
||||||
|
progress.setVisibility(VISIBLE);
|
||||||
listener.onGroupNameChosen(nameEntry.getText().toString());
|
listener.onGroupNameChosen(nameEntry.getText().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,42 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_margin="@dimen/margin_large">
|
android:padding="@dimen/margin_large">
|
||||||
|
|
||||||
<EditText
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/createForumNameLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/createForumNameEntry"
|
app:errorEnabled="true">
|
||||||
android:maxLines="1"
|
|
||||||
android:inputType="text|textCapSentences"
|
|
||||||
android:hint="@string/choose_forum_hint" />
|
|
||||||
|
|
||||||
<TextView
|
<EditText
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/createForumNameEntry"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:id="@+id/createForumFeedback"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center" />
|
android:hint="@string/choose_forum_hint"
|
||||||
|
android:inputType="text|textCapSentences"
|
||||||
|
android:maxLines="1"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/BriarButton"
|
|
||||||
android:id="@+id/createForumButton"
|
android:id="@+id/createForumButton"
|
||||||
|
style="@style/BriarButton"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/create_forum_button" />
|
android:text="@string/create_forum_button"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/createForumProgressBar"
|
android:id="@+id/createForumProgressBar"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
android:indeterminate="true"
|
android:indeterminate="true"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -1,30 +1,42 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_margin="@dimen/margin_large">
|
android:padding="@dimen/margin_large">
|
||||||
|
|
||||||
<EditText
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/name"
|
android:id="@+id/nameLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1"
|
app:errorEnabled="true">
|
||||||
android:inputType="text|textCapSentences"
|
|
||||||
android:hint="@string/groups_create_group_hint"/>
|
|
||||||
|
|
||||||
<TextView
|
<EditText
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/name"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:id="@+id/feedback"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center" />
|
android:hint="@string/groups_create_group_hint"
|
||||||
|
android:inputType="text|textCapSentences"
|
||||||
|
android:maxLines="1"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/BriarButton"
|
|
||||||
android:id="@+id/button"
|
android:id="@+id/button"
|
||||||
|
style="@style/BriarButton"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/groups_create_group_button"/>
|
android:text="@string/groups_create_group_button"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -433,7 +433,6 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
|
|||||||
|
|
||||||
// build post body
|
// build post body
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
b.append("<h3>").append(feed.getTitle()).append("</h3>");
|
|
||||||
|
|
||||||
if (!StringUtils.isNullOrEmpty(entry.getTitle())) {
|
if (!StringUtils.isNullOrEmpty(entry.getTitle())) {
|
||||||
b.append("<h1>").append(entry.getTitle()).append("</h1>");
|
b.append("<h1>").append(entry.getTitle()).append("</h1>");
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import net.jodah.concurrentunit.Waiter;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
@@ -493,26 +492,6 @@ public class BlogSharingIntegrationTest
|
|||||||
// 1 can again share blog 1 with 0
|
// 1 can again share blog 1 with 0
|
||||||
assertTrue(
|
assertTrue(
|
||||||
blogSharingManager1.canBeShared(blog1.getId(), contact0From1));
|
blogSharingManager1.canBeShared(blog1.getId(), contact0From1));
|
||||||
|
|
||||||
// re-create local state (simulates sign-out and sign-in)
|
|
||||||
Transaction txn0 = db0.startTransaction(false);
|
|
||||||
((BlogSharingManagerImpl) blogSharingManager0).createLocalState(txn0);
|
|
||||||
db0.commitTransaction(txn0);
|
|
||||||
db0.endTransaction(txn0);
|
|
||||||
Transaction txn1 = db1.startTransaction(false);
|
|
||||||
((BlogSharingManagerImpl) blogSharingManager1).createLocalState(txn1);
|
|
||||||
db1.commitTransaction(txn1);
|
|
||||||
db1.endTransaction(txn1);
|
|
||||||
|
|
||||||
// ensure there's no error with the sessions by checking shareability
|
|
||||||
assertFalse(
|
|
||||||
blogSharingManager0.canBeShared(blog1.getId(), contact1From0));
|
|
||||||
assertTrue(
|
|
||||||
blogSharingManager1.canBeShared(blog1.getId(), contact0From1));
|
|
||||||
|
|
||||||
// contacts should still be able to remove each other without errors
|
|
||||||
contactManager0.removeContact(contactId1From0);
|
|
||||||
contactManager1.removeContact(contactId0From1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -0,0 +1,253 @@
|
|||||||
|
package org.briarproject.briar.sharing;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
|
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||||
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
|
import org.briarproject.bramble.api.data.BdfEntry;
|
||||||
|
import org.briarproject.bramble.api.data.MetadataParser;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
|
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||||
|
import org.briarproject.briar.api.blog.BlogManager;
|
||||||
|
import org.briarproject.briar.api.client.MessageTracker;
|
||||||
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
|
import org.jmock.Expectations;
|
||||||
|
import org.jmock.Mockery;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
|
import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID;
|
||||||
|
import static org.briarproject.briar.sharing.SharingConstants.GROUP_KEY_CONTACT_ID;
|
||||||
|
|
||||||
|
public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
|
private final Mockery context = new Mockery();
|
||||||
|
private final BlogSharingManagerImpl blogSharingManager;
|
||||||
|
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||||
|
private final IdentityManager identityManager =
|
||||||
|
context.mock(IdentityManager.class);
|
||||||
|
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||||
|
private final SessionEncoder sessionEncoder =
|
||||||
|
context.mock(SessionEncoder.class);
|
||||||
|
private final SessionParser sessionParser =
|
||||||
|
context.mock(SessionParser.class);
|
||||||
|
private final ContactGroupFactory contactGroupFactory =
|
||||||
|
context.mock(ContactGroupFactory.class);
|
||||||
|
private final BlogManager blogManager = context.mock(BlogManager.class);
|
||||||
|
|
||||||
|
private final AuthorId localAuthorId = new AuthorId(getRandomId());
|
||||||
|
private final ContactId contactId = new ContactId(0);
|
||||||
|
private final AuthorId authorId = new AuthorId(getRandomId());
|
||||||
|
private final Author author = new Author(authorId, "Author",
|
||||||
|
getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||||
|
private final Contact contact =
|
||||||
|
new Contact(contactId, author, localAuthorId, true, true);
|
||||||
|
private final Collection<Contact> contacts =
|
||||||
|
Collections.singletonList(contact);
|
||||||
|
private final Group contactGroup =
|
||||||
|
new Group(new GroupId(getRandomId()), CLIENT_ID,
|
||||||
|
getRandomBytes(42));
|
||||||
|
private final Group blogGroup =
|
||||||
|
new Group(new GroupId(getRandomId()), BlogManager.CLIENT_ID,
|
||||||
|
getRandomBytes(42));
|
||||||
|
private final Blog blog = new Blog(blogGroup, author, false);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private final ProtocolEngine<Blog> engine =
|
||||||
|
context.mock(ProtocolEngine.class);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BlogSharingManagerImplTest() {
|
||||||
|
MetadataParser metadataParser = context.mock(MetadataParser.class);
|
||||||
|
MessageTracker messageTracker = context.mock(MessageTracker.class);
|
||||||
|
MessageParser<Blog> messageParser = context.mock(MessageParser.class);
|
||||||
|
InvitationFactory<Blog, BlogInvitationResponse> invitationFactory =
|
||||||
|
context.mock(InvitationFactory.class);
|
||||||
|
blogSharingManager =
|
||||||
|
new BlogSharingManagerImpl(db, clientHelper, metadataParser,
|
||||||
|
messageParser, sessionEncoder, sessionParser,
|
||||||
|
messageTracker, contactGroupFactory,
|
||||||
|
engine, invitationFactory, identityManager,
|
||||||
|
blogManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddingContactFreshState() throws Exception {
|
||||||
|
Map<MessageId, BdfDictionary> sessions =
|
||||||
|
new HashMap<MessageId, BdfDictionary>(0);
|
||||||
|
testAddingContact(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddingContactExistingState() throws Exception {
|
||||||
|
Map<MessageId, BdfDictionary> sessions =
|
||||||
|
new HashMap<MessageId, BdfDictionary>(1);
|
||||||
|
sessions.put(new MessageId(getRandomId()), new BdfDictionary());
|
||||||
|
testAddingContact(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DbException.class)
|
||||||
|
public void testAddingContactMultipleSessions() throws Exception {
|
||||||
|
Map<MessageId, BdfDictionary> sessions =
|
||||||
|
new HashMap<MessageId, BdfDictionary>(2);
|
||||||
|
sessions.put(new MessageId(getRandomId()), new BdfDictionary());
|
||||||
|
sessions.put(new MessageId(getRandomId()), new BdfDictionary());
|
||||||
|
testAddingContact(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemovingBlogFreshState() throws Exception {
|
||||||
|
Map<MessageId, BdfDictionary> sessions =
|
||||||
|
new HashMap<MessageId, BdfDictionary>(0);
|
||||||
|
testRemovingBlog(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemovingBlogExistingState() throws Exception {
|
||||||
|
Map<MessageId, BdfDictionary> sessions =
|
||||||
|
new HashMap<MessageId, BdfDictionary>(1);
|
||||||
|
sessions.put(new MessageId(getRandomId()), new BdfDictionary());
|
||||||
|
testRemovingBlog(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DbException.class)
|
||||||
|
public void testRemovingBlogMultipleSessions() throws Exception {
|
||||||
|
Map<MessageId, BdfDictionary> sessions =
|
||||||
|
new HashMap<MessageId, BdfDictionary>(2);
|
||||||
|
sessions.put(new MessageId(getRandomId()), new BdfDictionary());
|
||||||
|
sessions.put(new MessageId(getRandomId()), new BdfDictionary());
|
||||||
|
testRemovingBlog(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testAddingContact(final Map<MessageId, BdfDictionary> sessions)
|
||||||
|
throws Exception {
|
||||||
|
final Transaction txn = new Transaction(null, false);
|
||||||
|
final LocalAuthor localAuthor =
|
||||||
|
new LocalAuthor(localAuthorId, "Local Author",
|
||||||
|
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||||
|
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||||
|
System.currentTimeMillis());
|
||||||
|
final BdfDictionary meta = BdfDictionary
|
||||||
|
.of(new BdfEntry(GROUP_KEY_CONTACT_ID, contactId.getInt()));
|
||||||
|
final Group localBlogGroup =
|
||||||
|
new Group(new GroupId(getRandomId()), BlogManager.CLIENT_ID,
|
||||||
|
getRandomBytes(42));
|
||||||
|
final Blog localBlog = new Blog(localBlogGroup, localAuthor, false);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(db).getContacts(txn);
|
||||||
|
will(returnValue(contacts));
|
||||||
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||||
|
will(returnValue(contactGroup));
|
||||||
|
oneOf(db).containsGroup(txn, contactGroup.getId());
|
||||||
|
will(returnValue(false));
|
||||||
|
oneOf(db).addGroup(txn, contactGroup);
|
||||||
|
oneOf(db).setGroupVisibility(txn, contactId, contactGroup.getId(),
|
||||||
|
SHARED);
|
||||||
|
oneOf(clientHelper)
|
||||||
|
.mergeGroupMetadata(txn, contactGroup.getId(), meta);
|
||||||
|
oneOf(identityManager).getLocalAuthor(txn);
|
||||||
|
will(returnValue(localAuthor));
|
||||||
|
oneOf(blogManager).getPersonalBlog(localAuthor);
|
||||||
|
will(returnValue(localBlog));
|
||||||
|
oneOf(blogManager).getPersonalBlog(author);
|
||||||
|
will(returnValue(blog));
|
||||||
|
}});
|
||||||
|
expectPreShareShareable(txn, contact, localBlog, sessions);
|
||||||
|
expectPreShareShareable(txn, contact, blog, sessions);
|
||||||
|
|
||||||
|
blogSharingManager.createLocalState(txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expectPreShareShareable(final Transaction txn,
|
||||||
|
final Contact contact, final Blog blog,
|
||||||
|
final Map<MessageId, BdfDictionary> sessions) throws Exception {
|
||||||
|
final Group contactGroup =
|
||||||
|
new Group(new GroupId(getRandomId()), CLIENT_ID,
|
||||||
|
getRandomBytes(42));
|
||||||
|
final BdfDictionary sessionDict = new BdfDictionary();
|
||||||
|
final Message message =
|
||||||
|
new Message(new MessageId(getRandomId()), contactGroup.getId(),
|
||||||
|
42L, getRandomBytes(1337));
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(contactGroupFactory)
|
||||||
|
.createContactGroup(CLIENT_ID, contact);
|
||||||
|
will(returnValue(contactGroup));
|
||||||
|
oneOf(sessionParser)
|
||||||
|
.getSessionQuery(new SessionId(blog.getId().getBytes()));
|
||||||
|
will(returnValue(sessionDict));
|
||||||
|
oneOf(clientHelper)
|
||||||
|
.getMessageMetadataAsDictionary(txn, contactGroup.getId(),
|
||||||
|
sessionDict);
|
||||||
|
will(returnValue(sessions));
|
||||||
|
if (sessions.size() == 0) {
|
||||||
|
oneOf(db).addGroup(txn, blog.getGroup());
|
||||||
|
oneOf(db).setGroupVisibility(txn, contact.getId(),
|
||||||
|
blog.getGroup().getId(), SHARED);
|
||||||
|
oneOf(clientHelper)
|
||||||
|
.createMessageForStoringMetadata(contactGroup.getId());
|
||||||
|
will(returnValue(message));
|
||||||
|
oneOf(db).addLocalMessage(txn, message, new Metadata(), false);
|
||||||
|
oneOf(sessionEncoder).encodeSession(with(any(Session.class)));
|
||||||
|
will(returnValue(sessionDict));
|
||||||
|
oneOf(clientHelper).mergeMessageMetadata(txn, message.getId(),
|
||||||
|
sessionDict);
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testRemovingBlog(final Map<MessageId, BdfDictionary> sessions)
|
||||||
|
throws Exception {
|
||||||
|
final Transaction txn = new Transaction(null, false);
|
||||||
|
final BdfDictionary sessionDict = new BdfDictionary();
|
||||||
|
final Session session = new Session(contactGroup.getId(), blog.getId());
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(db).getContacts(txn);
|
||||||
|
will(returnValue(contacts));
|
||||||
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||||
|
will(returnValue(contactGroup));
|
||||||
|
oneOf(sessionParser)
|
||||||
|
.getSessionQuery(new SessionId(blog.getId().getBytes()));
|
||||||
|
will(returnValue(sessionDict));
|
||||||
|
oneOf(clientHelper)
|
||||||
|
.getMessageMetadataAsDictionary(txn, contactGroup.getId(),
|
||||||
|
sessionDict);
|
||||||
|
will(returnValue(sessions));
|
||||||
|
if (sessions.size() == 1) {
|
||||||
|
oneOf(sessionParser)
|
||||||
|
.parseSession(contactGroup.getId(), sessionDict);
|
||||||
|
will(returnValue(session));
|
||||||
|
oneOf(engine).onLeaveAction(txn, session);
|
||||||
|
will(returnValue(session));
|
||||||
|
oneOf(sessionEncoder).encodeSession(session);
|
||||||
|
will(returnValue(sessionDict));
|
||||||
|
oneOf(clientHelper).mergeMessageMetadata(txn,
|
||||||
|
sessions.keySet().iterator().next(), sessionDict);
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
blogSharingManager.removingBlog(txn, blog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user