Add --hide parameter to removeContact command

This commit is contained in:
AsamK 2023-11-11 11:35:23 +01:00
parent 9f4a2b3e26
commit 7b0744ec75
14 changed files with 96 additions and 35 deletions

View file

@ -193,6 +193,8 @@ public interface Manager extends Closeable {
SendMessageResults sendEndSessionMessage(Set<RecipientIdentifier.Single> recipients) throws IOException;
void hideRecipient(RecipientIdentifier.Single recipient);
void deleteRecipient(RecipientIdentifier.Single recipient);
void deleteContact(RecipientIdentifier.Single recipient);

View file

@ -9,7 +9,8 @@ public record Contact(
int messageExpirationTime,
boolean isBlocked,
boolean isArchived,
boolean isProfileSharingEnabled
boolean isProfileSharingEnabled,
boolean isHidden
) {
private Contact(final Builder builder) {
@ -17,9 +18,10 @@ public record Contact(
builder.familyName,
builder.color,
builder.messageExpirationTime,
builder.blocked,
builder.archived,
builder.profileSharingEnabled);
builder.isBlocked,
builder.isArchived,
builder.isProfileSharingEnabled,
builder.isHidden);
}
public static Builder newBuilder() {
@ -32,9 +34,10 @@ public record Contact(
builder.familyName = copy.familyName();
builder.color = copy.color();
builder.messageExpirationTime = copy.messageExpirationTime();
builder.blocked = copy.isBlocked();
builder.archived = copy.isArchived();
builder.profileSharingEnabled = copy.isProfileSharingEnabled();
builder.isBlocked = copy.isBlocked();
builder.isArchived = copy.isArchived();
builder.isProfileSharingEnabled = copy.isProfileSharingEnabled();
builder.isHidden = copy.isHidden();
return builder;
}
@ -59,13 +62,18 @@ public record Contact(
private String familyName;
private String color;
private int messageExpirationTime;
private boolean blocked;
private boolean archived;
private boolean profileSharingEnabled;
private boolean isBlocked;
private boolean isArchived;
private boolean isProfileSharingEnabled;
private boolean isHidden;
private Builder() {
}
public static Builder newBuilder() {
return new Builder();
}
public Builder withGivenName(final String val) {
givenName = val;
return this;
@ -86,18 +94,23 @@ public record Contact(
return this;
}
public Builder withBlocked(final boolean val) {
blocked = val;
public Builder withIsBlocked(final boolean val) {
isBlocked = val;
return this;
}
public Builder withArchived(final boolean val) {
archived = val;
public Builder withIsArchived(final boolean val) {
isArchived = val;
return this;
}
public Builder withProfileSharingEnabled(final boolean val) {
profileSharingEnabled = val;
public Builder withIsProfileSharingEnabled(final boolean val) {
isProfileSharingEnabled = val;
return this;
}
public Builder withIsHidden(final boolean val) {
isHidden = val;
return this;
}

View file

@ -20,6 +20,7 @@ public class ContactHelper {
public void setContactName(final RecipientId recipientId, final String givenName, final String familyName) {
var contact = account.getContactStore().getContact(recipientId);
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
builder.withIsHidden(false);
if (givenName != null) {
builder.withGivenName(givenName);
}
@ -43,8 +44,14 @@ public class ContactHelper {
var contact = account.getContactStore().getContact(recipientId);
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
if (blocked) {
builder.withProfileSharingEnabled(false);
builder.withIsProfileSharingEnabled(false);
}
account.getContactStore().storeContact(recipientId, builder.withBlocked(blocked).build());
account.getContactStore().storeContact(recipientId, builder.withIsBlocked(blocked).build());
}
public void setContactHidden(RecipientId recipientId, boolean hidden) {
var contact = account.getContactStore().getContact(recipientId);
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
account.getContactStore().storeContact(recipientId, builder.withIsHidden(hidden).build());
}
}

View file

@ -78,9 +78,9 @@ public class SendHelper {
Optional<Long> editTargetTimestamp
) {
var contact = account.getContactStore().getContact(recipientId);
if (contact == null || !contact.isProfileSharingEnabled()) {
if (contact == null || !contact.isProfileSharingEnabled() || contact.isHidden()) {
final var contactBuilder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
contact = contactBuilder.withProfileSharingEnabled(true).build();
contact = contactBuilder.withIsProfileSharingEnabled(true).withIsHidden(false).build();
account.getContactStore().storeContact(recipientId, contact);
}

View file

@ -116,11 +116,13 @@ public class StorageHelper {
final var blocked = contact != null && contact.isBlocked();
final var profileShared = contact != null && contact.isProfileSharingEnabled();
final var archived = contact != null && contact.isArchived();
final var hidden = contact != null && contact.isHidden();
final var contactGivenName = contact == null ? null : contact.givenName();
final var contactFamilyName = contact == null ? null : contact.familyName();
if (blocked != contactRecord.isBlocked()
|| profileShared != contactRecord.isProfileSharingEnabled()
|| archived != contactRecord.isArchived()
|| hidden != contactRecord.isHidden()
|| (
contactRecord.getSystemGivenName().isPresent() && !contactRecord.getSystemGivenName()
.get()
@ -133,9 +135,10 @@ public class StorageHelper {
)) {
logger.debug("Storing new or updated contact {}", recipientId);
final var contactBuilder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
final var newContact = contactBuilder.withBlocked(contactRecord.isBlocked())
.withProfileSharingEnabled(contactRecord.isProfileSharingEnabled())
.withArchived(contactRecord.isArchived());
final var newContact = contactBuilder.withIsBlocked(contactRecord.isBlocked())
.withIsProfileSharingEnabled(contactRecord.isProfileSharingEnabled())
.withIsArchived(contactRecord.isArchived())
.withIsHidden(contactRecord.isHidden());
if (contactRecord.getSystemGivenName().isPresent() || contactRecord.getSystemFamilyName().isPresent()) {
newContact.withGivenName(contactRecord.getSystemGivenName().orElse(null))
.withFamilyName(contactRecord.getSystemFamilyName().orElse(null));

View file

@ -339,8 +339,8 @@ public class SyncHelper {
if (c.getExpirationTimer().isPresent()) {
builder.withMessageExpirationTime(c.getExpirationTimer().get());
}
builder.withBlocked(c.isBlocked());
builder.withArchived(c.isArchived());
builder.withIsBlocked(c.isBlocked());
builder.withIsArchived(c.isArchived());
account.getContactStore().storeContact(recipientId, builder.build());
if (c.getAvatar().isPresent()) {

View file

@ -840,6 +840,15 @@ public class ManagerImpl implements Manager {
}
}
@Override
public void hideRecipient(final RecipientIdentifier.Single recipient) {
final var recipientIdOptional = context.getRecipientHelper().resolveRecipientOptional(recipient);
if (recipientIdOptional.isPresent()) {
context.getContactHelper().setContactHidden(recipientIdOptional.get(), true);
account.removeRecipient(recipientIdOptional.get());
}
}
@Override
public void deleteRecipient(final RecipientIdentifier.Single recipient) {
final var recipientIdOptional = context.getRecipientHelper().resolveRecipientOptional(recipient);

View file

@ -32,7 +32,7 @@ import java.util.UUID;
public class AccountDatabase extends Database {
private static final Logger logger = LoggerFactory.getLogger(AccountDatabase.class);
private static final long DATABASE_VERSION = 18;
private static final long DATABASE_VERSION = 19;
private AccountDatabase(final HikariDataSource dataSource) {
super(logger, DATABASE_VERSION, dataSource);
@ -531,5 +531,13 @@ public class AccountDatabase extends Database {
""");
}
}
if (oldVersion < 19) {
logger.debug("Updating database: Adding contact hidden column");
try (final var statement = connection.createStatement()) {
statement.executeUpdate("""
ALTER TABLE recipient ADD COLUMN hidden INTEGER NOT NULL DEFAULT FALSE;
""");
}
}
}
}

View file

@ -826,6 +826,7 @@ public class SignalAccount implements Closeable {
contact.messageExpirationTime,
contact.blocked,
contact.archived,
false,
false));
// Store profile keys only in profile store

View file

@ -44,7 +44,8 @@ public class LegacyRecipientStore2 {
r.contact.messageExpirationTime,
r.contact.blocked,
r.contact.archived,
r.contact.profileSharingEnabled);
r.contact.profileSharingEnabled,
false);
}
ProfileKey profileKey = null;

View file

@ -70,6 +70,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
blocked INTEGER NOT NULL DEFAULT FALSE,
archived INTEGER NOT NULL DEFAULT FALSE,
profile_sharing INTEGER NOT NULL DEFAULT FALSE,
hidden INTEGER NOT NULL DEFAULT FALSE,
profile_last_update_timestamp INTEGER NOT NULL DEFAULT 0,
profile_given_name TEXT,
@ -318,9 +319,9 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
public List<Pair<RecipientId, Contact>> getContacts() {
final var sql = (
"""
SELECT r._id, r.given_name, r.family_name, r.expiration_time, r.profile_sharing, r.color, r.blocked, r.archived
SELECT r._id, r.given_name, r.family_name, r.expiration_time, r.profile_sharing, r.color, r.blocked, r.archived, r.hidden
FROM %s r
WHERE (r.number IS NOT NULL OR r.uuid IS NOT NULL) AND %s
WHERE (r.number IS NOT NULL OR r.uuid IS NOT NULL) AND %s AND r.hidden = FALSE
"""
).formatted(TABLE_RECIPIENT, SQL_IS_CONTACT);
try (final var connection = database.getConnection()) {
@ -342,6 +343,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
final var sqlWhere = new ArrayList<String>();
if (onlyContacts) {
sqlWhere.add("(" + SQL_IS_CONTACT + ")");
sqlWhere.add("r.hidden = FALSE");
}
if (blocked.isPresent()) {
sqlWhere.add("r.blocked = ?");
@ -357,7 +359,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
SELECT r._id,
r.number, r.uuid, r.pni, r.username,
r.profile_key, r.profile_key_credential,
r.given_name, r.family_name, r.expiration_time, r.profile_sharing, r.color, r.blocked, r.archived,
r.given_name, r.family_name, r.expiration_time, r.profile_sharing, r.color, r.blocked, r.archived, r.hidden,
r.profile_last_update_timestamp, r.profile_given_name, r.profile_family_name, r.profile_about, r.profile_about_emoji, r.profile_avatar_url_path, r.profile_mobile_coin_address, r.profile_unidentified_access_mode, r.profile_capabilities
FROM %s r
WHERE (r.number IS NOT NULL OR r.uuid IS NOT NULL) AND %s
@ -962,7 +964,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
private Contact getContact(final Connection connection, final RecipientId recipientId) throws SQLException {
final var sql = (
"""
SELECT r.given_name, r.family_name, r.expiration_time, r.profile_sharing, r.color, r.blocked, r.archived
SELECT r.given_name, r.family_name, r.expiration_time, r.profile_sharing, r.color, r.blocked, r.archived, r.hidden
FROM %s r
WHERE r._id = ? AND (%s)
"""
@ -1053,7 +1055,8 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
resultSet.getInt("expiration_time"),
resultSet.getBoolean("blocked"),
resultSet.getBoolean("archived"),
resultSet.getBoolean("profile_sharing"));
resultSet.getBoolean("profile_sharing"),
resultSet.getBoolean("hidden"));
}
private Profile getProfileFromResultSet(ResultSet resultSet) throws SQLException {

View file

@ -613,6 +613,9 @@ Remove the info of a given contact
NUMBER::
Specify the contact phone number.
*--hide*::
Hide the contact in the contact list, but keep the data.
*--forget*::
Delete all data associated with this contact, including identity keys and sessions.

View file

@ -20,7 +20,11 @@ public class RemoveContactCommand implements JsonRpcLocalCommand {
public void attachToSubparser(final Subparser subparser) {
subparser.help("Remove the details of a given contact");
subparser.addArgument("recipient").help("Contact number");
subparser.addArgument("--forget")
final var mut = subparser.addMutuallyExclusiveGroup();
mut.addArgument("--hide")
.action(Arguments.storeTrue())
.help("Hide the contact in the contact list, but keep the data.");
mut.addArgument("--forget")
.action(Arguments.storeTrue())
.help("Delete all data associated with this contact, including identity keys and sessions.");
}
@ -32,8 +36,11 @@ public class RemoveContactCommand implements JsonRpcLocalCommand {
var recipientString = ns.getString("recipient");
var recipient = CommandUtil.getSingleRecipientIdentifier(recipientString, m.getSelfNumber());
var hide = Boolean.TRUE == ns.getBoolean("hide");
var forget = Boolean.TRUE == ns.getBoolean("forget");
if (forget) {
if (hide) {
m.hideRecipient(recipient);
} else if (forget) {
m.deleteRecipient(recipient);
} else {
m.deleteContact(recipient);

View file

@ -452,6 +452,10 @@ public class DbusManagerImpl implements Manager {
return new SendMessageResults(0, Map.of());
}
public void hideRecipient(final RecipientIdentifier.Single recipient) {
throw new UnsupportedOperationException();
}
@Override
public void deleteRecipient(final RecipientIdentifier.Single recipient) {
signal.deleteRecipient(recipient.getIdentifier());
@ -653,7 +657,7 @@ public class DbusManagerImpl implements Manager {
}
return Recipient.newBuilder()
.withAddress(new RecipientAddress(null, n))
.withContact(new Contact(contactName, null, null, 0, contactBlocked, false, false))
.withContact(new Contact(contactName, null, null, 0, contactBlocked, false, false, false))
.build();
}).filter(Objects::nonNull).toList();
}