forked from mirror/monocles_chat_clean
update fork #128
8 changed files with 272 additions and 79 deletions
Add support for attachments in posts
commit
b9f87e830a
|
|
@ -16,14 +16,16 @@ public class Post {
|
|||
private final Jid author;
|
||||
private final Date published;
|
||||
private final String commentsNode;
|
||||
private final String attachmentUrl;
|
||||
|
||||
public Post(String id, String title, String content, Jid author, Date published, String commentsNode) {
|
||||
public Post(String id, String title, String content, Jid author, Date published, String commentsNode, String attachmentUrl) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
this.author = author;
|
||||
this.published = published;
|
||||
this.commentsNode = commentsNode;
|
||||
this.attachmentUrl = attachmentUrl;
|
||||
}
|
||||
|
||||
public static Post fromElement(Element entry) {
|
||||
|
|
@ -51,12 +53,21 @@ public class Post {
|
|||
// ignore
|
||||
}
|
||||
}
|
||||
Element link = entry.findChild("link", Namespace.ATOM);
|
||||
|
||||
String commentsNode = null;
|
||||
if (link != null && "replies".equals(link.getAttribute("rel"))) {
|
||||
commentsNode = link.getAttribute("href");
|
||||
String attachmentUrl = null;
|
||||
for (Element link : entry.getChildren()) {
|
||||
if ("link".equals(link.getName()) && Namespace.ATOM.equals(link.getNamespace())) {
|
||||
String rel = link.getAttribute("rel");
|
||||
if ("replies".equals(rel)) {
|
||||
commentsNode = link.getAttribute("href");
|
||||
} else if ("enclosure".equals(rel)) {
|
||||
attachmentUrl = link.getAttribute("href");
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Post(id, title, content, author, published, commentsNode);
|
||||
|
||||
return new Post(id, title, content, author, published, commentsNode, attachmentUrl);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
|
|
@ -82,4 +93,8 @@ public class Post {
|
|||
public String getCommentsNode() {
|
||||
return commentsNode;
|
||||
}
|
||||
}
|
||||
|
||||
public String getAttachmentUrl() {
|
||||
return attachmentUrl;
|
||||
}
|
||||
}
|
||||
|
|
@ -830,7 +830,7 @@ public class IqGenerator extends AbstractGenerator {
|
|||
return iq;
|
||||
}
|
||||
|
||||
public Iq publishPost(final Account account, final String node, final String title, final String content, final String inReplyToId, final String postId) {
|
||||
public Iq publishPost(final Account account, final String node, final String title, final String content, final String inReplyToId, final String postId, final String attachmentUrl, final String attachmentType) {
|
||||
final Iq iq = new Iq(Iq.Type.SET);
|
||||
final boolean isComment = inReplyToId != null;
|
||||
final String fullNode = isComment ? "urn:xmpp:microblog:0:comments/" + inReplyToId : node;
|
||||
|
|
@ -839,18 +839,31 @@ public class IqGenerator extends AbstractGenerator {
|
|||
final Element publish = pubsub.addChild("publish");
|
||||
publish.setAttribute("node", fullNode);
|
||||
final Element item = publish.addChild("item");
|
||||
final String id = postId != null ? postId : "tag:" + account.getServer() + "," + AbstractGenerator.getTimestamp(System.currentTimeMillis()) + ":" + UUID.randomUUID().toString(); item.setAttribute("id", id);
|
||||
final String id = postId != null ? postId : "tag:" + account.getServer() + "," + AbstractGenerator.getTimestamp(System.currentTimeMillis()) + ":" + UUID.randomUUID().toString();
|
||||
if (!isComment) {
|
||||
item.setAttribute("id", id);
|
||||
}
|
||||
final Element entry = item.addChild("entry", Namespace.ATOM);
|
||||
|
||||
if (!isComment) {
|
||||
entry.addChild("link")
|
||||
.setAttribute("rel", "replies")
|
||||
.setAttribute("type", "application/atom+xml")
|
||||
.setAttribute("href", "xmpp:" + account.getJid().asBareJid() + "?;node=urn:xmpp:microblog:0:comments/" + id);
|
||||
}
|
||||
|
||||
if (inReplyToId != null) {
|
||||
entry.setAttribute("xmlns:thr", "http://purl.org/syndication/thread/1.0");
|
||||
entry.addChild("thr:in-reply-to").setAttribute("ref", inReplyToId);
|
||||
}
|
||||
|
||||
if (attachmentUrl != null && attachmentType != null) {
|
||||
entry.addChild("link")
|
||||
.setAttribute("rel", "enclosure")
|
||||
.setAttribute("href", attachmentUrl)
|
||||
.setAttribute("type", attachmentType);
|
||||
}
|
||||
|
||||
entry.addChild("title").setContent(title);
|
||||
entry.addChild("content").setContent(content);
|
||||
final Element author = entry.addChild("author");
|
||||
|
|
|
|||
|
|
@ -8174,30 +8174,25 @@ public class XmppConnectionService extends Service {
|
|||
void onPubsubItemsFetchFailed();
|
||||
}
|
||||
|
||||
public void publishPost(final String node, final String title, final String content, final String inReplyToId, final String postId, final OnPostPublished callback) {
|
||||
Account account = null;
|
||||
for (Account acc : getAccounts()) {
|
||||
if (acc.isOnlineAndConnected()) {
|
||||
account = acc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void publishPost(final String node, final String title, final String content, final String inReplyToId, final String postId, final String attachmentUrl, final String attachmentType, final OnPostPublished callback) {
|
||||
Account account = AccountUtils.getFirstEnabled(getAccounts());
|
||||
if (account == null) {
|
||||
if (callback != null) {
|
||||
callback.onPostPublishFailed();
|
||||
}
|
||||
return;
|
||||
}
|
||||
final Iq request = getIqGenerator().publishPost(account, node, title, content, inReplyToId, postId);
|
||||
sendIqPacket(account, request, response -> { if (response.getType() == Iq.Type.RESULT) {
|
||||
if (callback != null) {
|
||||
callback.onPostPublished();
|
||||
final Iq request = getIqGenerator().publishPost(account, node, title, content, inReplyToId, postId, attachmentUrl, attachmentType);
|
||||
sendIqPacket(account, request, response -> {
|
||||
if (response.getType() == Iq.Type.RESULT) {
|
||||
if (callback != null) {
|
||||
callback.onPostPublished();
|
||||
}
|
||||
} else {
|
||||
if (callback != null) {
|
||||
callback.onPostPublishFailed();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (callback != null) {
|
||||
callback.onPostPublishFailed();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
package eu.siacs.conversations.ui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ActivityCreatePostBinding;
|
||||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.utils.FileUtils;
|
||||
|
||||
public class CreatePostActivity extends XmppActivity {
|
||||
|
||||
|
|
@ -18,6 +28,38 @@ public class CreatePostActivity extends XmppActivity {
|
|||
private String inReplyToId;
|
||||
private String inReplyToNode;
|
||||
private String postId;
|
||||
private Uri attachmentUri;
|
||||
private Uri mCameraUri;
|
||||
|
||||
private final ActivityResultLauncher<String> requestPermissionLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
||||
if (isGranted) {
|
||||
openCamera();
|
||||
} else {
|
||||
Toast.makeText(this, R.string.no_camera_permission, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
private final ActivityResultLauncher<Intent> takePictureLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||
if (result.getResultCode() == RESULT_OK) {
|
||||
attachmentUri = mCameraUri;
|
||||
binding.attachmentPreview.setImageURI(attachmentUri);
|
||||
binding.attachmentPreview.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
private final ActivityResultLauncher<String> attachFileLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.GetContent(),
|
||||
uri -> {
|
||||
if (uri != null) {
|
||||
this.attachmentUri = uri;
|
||||
binding.attachmentPreview.setImageURI(attachmentUri);
|
||||
binding.attachmentPreview.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
|
@ -39,6 +81,25 @@ public class CreatePostActivity extends XmppActivity {
|
|||
}
|
||||
|
||||
binding.publishButton.setOnClickListener(v -> publishPost());
|
||||
binding.attachFileButton.setOnClickListener(v -> attachFileLauncher.launch("*/*"));
|
||||
binding.attachImageButton.setOnClickListener(v -> {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
|
||||
openCamera();
|
||||
} else {
|
||||
requestPermissionLauncher.launch(Manifest.permission.CAMERA);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openCamera() {
|
||||
if (xmppConnectionService == null) {
|
||||
Toast.makeText(this, R.string.not_connected_try_again, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
mCameraUri = xmppConnectionService.getFileBackend().getTakePhotoUri();
|
||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraUri);
|
||||
takePictureLauncher.launch(takePictureIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -55,27 +116,53 @@ public class CreatePostActivity extends XmppActivity {
|
|||
String title = binding.postTitleEditText.getText().toString();
|
||||
String content = binding.postContentEditText.getText().toString();
|
||||
|
||||
if (title.isEmpty() && content.isEmpty()) {
|
||||
Toast.makeText(this, R.string.title_or_content_are_required, Toast.LENGTH_SHORT).show();
|
||||
if (title.isEmpty() && content.isEmpty() && attachmentUri == null) {
|
||||
Toast.makeText(this, R.string.title_or_content_or_attachment_required, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}if (xmppConnectionService != null) {
|
||||
xmppConnectionService.publishPost("urn:xmpp:microblog:0", title, content, inReplyToId, postId, new XmppConnectionService.OnPostPublished() {
|
||||
@Override
|
||||
public void onPostPublished() {
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(CreatePostActivity.this, R.string.post_published, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostPublishFailed() {
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(CreatePostActivity.this, R.string.error_publish_post, Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (xmppConnectionService != null) {
|
||||
if (attachmentUri != null) {
|
||||
final String mimeType = getContentResolver().getType(attachmentUri);
|
||||
xmppConnectionService.uploadFileForUrl(xmppConnectionService.getAccounts().get(0), attachmentUri, mimeType, new UiCallback<String>() {
|
||||
@Override
|
||||
public void success(String url) {
|
||||
publish(title, content, url, mimeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(int errorCode, String object) {
|
||||
runOnUiThread(() -> Toast.makeText(CreatePostActivity.this, errorCode, Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userInputRequired(android.app.PendingIntent pi, String object) {
|
||||
// Not handled
|
||||
}
|
||||
});
|
||||
} else {
|
||||
publish(title, content, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void publish(String title, String content, String attachmentUrl, String attachmentType) {
|
||||
xmppConnectionService.publishPost("urn:xmpp:microblog:0", title, content, inReplyToId, postId, attachmentUrl, attachmentType, new XmppConnectionService.OnPostPublished() {
|
||||
@Override
|
||||
public void onPostPublished() {
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(CreatePostActivity.this, R.string.post_published, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostPublishFailed() {
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(CreatePostActivity.this, R.string.error_publish_post, Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -91,4 +178,4 @@ public class CreatePostActivity extends XmppActivity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,27 @@
|
|||
package eu.siacs.conversations.ui.adapter;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DateFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ItemPostBinding;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
|
|
@ -64,10 +72,17 @@ public class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.PostViewHold
|
|||
}
|
||||
|
||||
void bind(Post post) {
|
||||
final boolean isExpanded = expandedPosts.contains(post);
|
||||
final boolean isExpanded = expandedPosts.contains(post);final boolean hasAttachment = post.getAttachmentUrl() != null;
|
||||
|
||||
binding.postContentSummary.setVisibility(isExpanded ? View.GONE : View.VISIBLE);
|
||||
binding.postContentFull.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
|
||||
binding.postActions.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
|
||||
binding.attachmentHint.setVisibility(hasAttachment && !isExpanded ? View.VISIBLE : View.GONE);
|
||||
binding.postImage.setVisibility(hasAttachment && isExpanded ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (hasAttachment && isExpanded) {
|
||||
Glide.with(mActivity).load(post.getAttachmentUrl()).into(binding.postImage);
|
||||
}
|
||||
|
||||
binding.postContentSummary.setText(post.getContent());
|
||||
binding.postContentFull.setText(post.getContent());
|
||||
|
|
@ -110,6 +125,7 @@ public class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.PostViewHold
|
|||
mActivity.startActivity(Intent.createChooser(intent, mActivity.getString(R.string.share_post_with)));
|
||||
});
|
||||
|
||||
|
||||
if (post.getAuthor() != null && mActivity.xmppConnectionService != null) {
|
||||
Account account = AccountUtils.getFirstEnabled(mActivity.xmppConnectionService.getAccounts());
|
||||
if (account != null && post.getAuthor().asBareJid().equals(account.getJid().asBareJid())) {
|
||||
|
|
@ -123,31 +139,32 @@ public class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.PostViewHold
|
|||
mActivity.startActivity(intent);
|
||||
});
|
||||
binding.deleteButton.setOnClickListener(v -> {
|
||||
new MaterialAlertDialogBuilder(mActivity)
|
||||
.setTitle(R.string.retract_post)
|
||||
.setMessage(R.string.retract_post_confirm)
|
||||
.setPositiveButton(R.string.retract, (dialog, which) -> {
|
||||
mActivity.xmppConnectionService.retractPost("urn:xmpp:microblog:0", post.getId(), new XmppConnectionService.OnPostRetracted() {
|
||||
@Override
|
||||
public void onPostRetracted() {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
int pos = getAdapterPosition();
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
posts.remove(pos);
|
||||
notifyItemRemoved(pos);
|
||||
}
|
||||
});
|
||||
}
|
||||
new AlertDialog.Builder(mActivity)
|
||||
.setTitle(R.string.retract_post)
|
||||
.setMessage(R.string.retract_post_confirm)
|
||||
.setPositiveButton(R.string.retract, (dialog, which) -> {
|
||||
mActivity.xmppConnectionService.retractPost("urn:xmpp:microblog:0", post.getId(), new XmppConnectionService.OnPostRetracted() {
|
||||
@Override
|
||||
public void onPostRetracted() {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
int pos = getAdapterPosition();
|
||||
if(pos != RecyclerView.NO_POSITION) {
|
||||
posts.remove(pos);
|
||||
notifyItemRemoved(pos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostRetractionFailed() {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
Toast.makeText(mActivity, R.string.error_retract_post, Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
}); })
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
@Override
|
||||
public void onPostRetractionFailed() {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
Toast.makeText(mActivity, R.string.error_retract_post, Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
});
|
||||
} else {
|
||||
binding.editButton.setVisibility(View.GONE);
|
||||
|
|
@ -208,4 +225,4 @@ public class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.PostViewHold
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
app:layout_constraintBottom_toTopOf="@+id/post_title_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
|
|
@ -22,6 +22,18 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attachment_preview"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/app_bar"
|
||||
tools:src="@tools:sample/avatars"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/post_title_layout"
|
||||
android:layout_width="0dp"
|
||||
|
|
@ -29,7 +41,7 @@
|
|||
android:layout_margin="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/app_bar">
|
||||
app:layout_constraintTop_toBottomOf="@+id/attachment_preview">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/post_title_edit_text"
|
||||
|
|
@ -44,7 +56,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="16dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/publish_button"
|
||||
app:layout_constraintBottom_toTopOf="@+id/attachment_options"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_title_layout">
|
||||
|
|
@ -58,6 +70,32 @@
|
|||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/attachment_options"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/publish_button">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/attach_file_button"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_attach_file_24dp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/attach_image_button"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_camera_alt_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/publish_button"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -75,11 +75,38 @@
|
|||
android:layout_marginTop="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/attachment_hint"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_author_avatar"
|
||||
tools:text="This is a post title" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attachment_hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:src="@drawable/ic_attach_file_white_24dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/post_title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/post_title"
|
||||
app:layout_constraintTop_toTopOf="@+id/post_title"
|
||||
app:tint="?android:attr/textColorSecondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/post_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxHeight="400dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_title"
|
||||
tools:src="@tools:sample/backgrounds/scenic"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/post_content_summary"
|
||||
android:layout_width="0dp"
|
||||
|
|
@ -89,7 +116,7 @@
|
|||
android:maxLines="3"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_title"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_image"
|
||||
tools:text="This is the content of the post. It can be a long text spanning multiple lines." />
|
||||
|
||||
<TextView
|
||||
|
|
@ -102,7 +129,7 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_title"
|
||||
app:layout_constraintTop_toBottomOf="@+id/post_image"
|
||||
tools:text="This is the content of the post. It can be a long text spanning multiple lines." />
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
|||
|
|
@ -1613,6 +1613,7 @@
|
|||
<string name="retract_post_confirm">Do you really want to retract this post?</string>
|
||||
<string name="retract">Retract</string>
|
||||
<string name="error_retract_post">Could not retract post</string>
|
||||
<string name="title_or_content_or_attachment_required">Title, content or attachment required</string>
|
||||
<plurals name="publishing_to_x_contacts">
|
||||
<item quantity="one">Publishing to %d contact</item>
|
||||
<item quantity="other">Publishing to %d contacts</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue