update fork #128

Manually merged
tristan merged 181 commits from mirror/monocles_chat_clean:master into master 2026-01-23 14:02:38 +01:00
6 changed files with 152 additions and 12 deletions
Showing only changes of commit d263614cec - Show all commits

Allow deleting own stories

Arne 2025-12-30 11:47:55 +01:00

View file

@ -7911,4 +7911,19 @@ public class XmppConnectionService extends Service {
}
});
}
public void retractStory(Account account, String storyId, final UiCallback<Void> callback) {
Iq iq = getIqGenerator().deleteItem(Namespace.PUBSUB_STORIES, storyId);
this.sendIqPacket(account, iq, response -> {
if (response.getType() == Iq.Type.RESULT) {
if (callback != null) {
callback.success(null);
}
} else {
if (callback != null) {
callback.error(R.string.error_deleting_story, null);
}
}
});
}
}

View file

@ -2,11 +2,16 @@ package eu.siacs.conversations.ui;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;
import com.bumptech.glide.Glide;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.File;
import java.io.FileOutputStream;
@ -17,6 +22,7 @@ import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.xmpp.Jid;
import okhttp3.HttpUrl;
public class StoryViewActivity extends XmppActivity {
@ -24,19 +30,47 @@ public class StoryViewActivity extends XmppActivity {
public static final String EXTRA_URL = "url";
public static final String EXTRA_ACCOUNT = "account";
public static final String EXTRA_TITLE = "title";
public static final String EXTRA_STORY_ID = "story_id";
public static final String EXTRA_CONTACT = "contact";
private ImageView imageView;
private TextView titleView;
private String storyId;
private Jid contact;
private Account mAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_story_view);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
imageView = findViewById(R.id.story_image_view);
titleView = findViewById(R.id.story_title_view);
final String title = getIntent().getStringExtra(EXTRA_TITLE);
if (title != null) {
titleView.setText(title);
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(title);
}
} else {
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(R.string.story);
}
}
storyId = getIntent().getStringExtra(EXTRA_STORY_ID);
try {
contact = Jid.of(getIntent().getStringExtra(EXTRA_CONTACT));
} catch (final Exception e) {
//ignore
}
}
@ -45,6 +79,56 @@ public class StoryViewActivity extends XmppActivity {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_story_view, menu);
MenuItem deleteButton = menu.findItem(R.id.action_delete_story);
if (mAccount != null && contact != null && mAccount.getJid().asBareJid().equals(contact)) {
deleteButton.setVisible(true);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
if (item.getItemId() == R.id.action_delete_story) {
new MaterialAlertDialogBuilder(this)
.setTitle(R.string.delete_story_dialog_title)
.setMessage(R.string.delete_story_dialog_message)
.setPositiveButton(R.string.delete, (dialog, which) -> {
xmppConnectionService.retractStory(mAccount, storyId, new UiCallback<Void>() {
@Override
public void success(Void aVoid) {
runOnUiThread(() -> {
Toast.makeText(StoryViewActivity.this, R.string.story_deleted, Toast.LENGTH_SHORT).show();
finish();
});
}
@Override
public void error(int errorCode, Void object) {
runOnUiThread(() -> Toast.makeText(StoryViewActivity.this, errorCode, Toast.LENGTH_SHORT).show());
}
@Override
public void userInputRequired(android.app.PendingIntent pi, Void object) {
}
});
})
.setNegativeButton(R.string.cancel, null)
.create()
.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackendConnected() {
String url = getIntent().getStringExtra(EXTRA_URL);
@ -55,13 +139,15 @@ public class StoryViewActivity extends XmppActivity {
return;
}
Account account = xmppConnectionService.findAccountByUuid(accountUuid);
if (account == null) {
mAccount = xmppConnectionService.findAccountByUuid(accountUuid);
if (mAccount == null) {
Toast.makeText(this, R.string.no_active_account, Toast.LENGTH_SHORT).show();
finish();
return;
}
invalidateOptionsMenu();
final HttpUrl httpUrl;
try {
httpUrl = HttpUrl.get(url);
@ -71,8 +157,8 @@ public class StoryViewActivity extends XmppActivity {
return;
}
final boolean useTor = xmppConnectionService.useTorToConnect() || account.isOnion();
final boolean useI2p = xmppConnectionService.useI2PToConnect() || account.isI2P();
final boolean useTor = xmppConnectionService.useTorToConnect() || mAccount.isOnion();
final boolean useI2p = xmppConnectionService.useI2PToConnect() || mAccount.isI2P();
new Thread(() -> {
File tempFile = null;

View file

@ -38,15 +38,28 @@ public class StoryAdapter extends RecyclerView.Adapter<StoryAdapter.StoryViewHol
public void onBindViewHolder(@NonNull StoryViewHolder holder, int position) {
final Story story = stories.get(position);
final Jid jid = story.getContact();
Contact contact = null;
Account storyAccount = null;
for (Account account : activity.xmppConnectionService.getAccounts()) {
contact = account.getRoster().getContact(jid);
if (contact != null) {
storyAccount = account;
break;
Contact contact;
Account storyAccount;
// Check if the story author is one of our own accounts
storyAccount = activity.xmppConnectionService.findAccountByJid(jid);
if (storyAccount != null) {
// It's our own story
contact = storyAccount.getSelfContact();
} else {
// It's from someone else. Find which of our accounts knows them.
contact = null;
storyAccount = null;
for (Account account : activity.xmppConnectionService.getAccounts()) {
contact = account.getRoster().getContact(jid);
if (contact != null) {
storyAccount = account; // The account that has this contact in its roster
break;
}
}
}
if (contact != null) {
holder.storyTitle.setText(contact.getDisplayName());
holder.storyImage.setImageDrawable(activity.xmppConnectionService.getAvatarService().get(contact, activity.getResources().getDimensionPixelSize(R.dimen.avatar_story_size)));
@ -62,6 +75,8 @@ public class StoryAdapter extends RecyclerView.Adapter<StoryAdapter.StoryViewHol
intent.putExtra(StoryViewActivity.EXTRA_ACCOUNT, finalStoryAccount.getUuid());
}
intent.putExtra(StoryViewActivity.EXTRA_TITLE, story.getTitle());
intent.putExtra(StoryViewActivity.EXTRA_STORY_ID, story.getUuid());
intent.putExtra(StoryViewActivity.EXTRA_CONTACT, story.getContact().asBareJid().toString());
activity.startActivity(intent);
});
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
@ -11,11 +12,19 @@
android:layout_height="match_parent"
android:scaleType="fitCenter" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#80000000"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<TextView
android:id="@+id/story_title_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_gravity="bottom"
android:background="#80000000"
android:padding="16dp"
android:textColor="@android:color/white"

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_delete_story"
android:title="@string/delete_story"
android:icon="@drawable/ic_delete_24dp"
app:showAsAction="ifRoom"
android:visible="false" />
</menu>

View file

@ -1580,4 +1580,9 @@
<string name="story">Story</string>
<string name="add_story_title">Add a title</string>
<string name="title_optional">Title (optional)</string>
<string name="error_deleting_story">Could not delete story</string>
<string name="delete_story">Delete story</string>
<string name="delete_story_dialog_title">Delete story</string>
<string name="delete_story_dialog_message">Do you really want to delete this story</string>
<string name="story_deleted">Story deleted</string>
</resources>