Fix duplicate contacts on rename

This commit is contained in:
Paul Schaub 2019-12-22 02:06:51 +01:00
parent 647695b081
commit 6504170d58
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
5 changed files with 73 additions and 73 deletions

View File

@ -44,31 +44,30 @@ public class LoginViewModel extends AndroidViewModel {
public void setUsername(String username) {
if (username == null || username.isEmpty()) {
this.username = null;
usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_field_required)));
this.username = null;
updateLoginEnabled();
return;
}
try {
this.username = JidCreate.entityBareFrom(username);
updateLoginEnabled();
} catch (XmppStringprepException e) {
usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_invalid_username)));
this.username = null;
updateLoginEnabled();
} else {
try {
this.username = JidCreate.entityBareFrom(username);
} catch (XmppStringprepException e) {
this.username = null;
usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_invalid_username)));
}
}
updateLoginButtonState();
}
public void setPassword(String password) {
this.password = password;
updateLoginEnabled();
if (password == null || password.isEmpty()) {
this.password = null;
passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_field_required)));
} else {
this.password = password;
}
updateLoginButtonState();
}
private void updateLoginEnabled() {
private void updateLoginButtonState() {
loginButtonEnabled.setValue(username != null && !(password == null || password.isEmpty()));
}
@ -81,15 +80,19 @@ public class LoginViewModel extends AndroidViewModel {
disposable.add(messenger.addAccount()
.setAddress(username.asEntityBareJidString())
.setPassword(password)
.loginAndStoreAccountIfSuccessful()
.execute()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> loginCompleted.setValue(true))
.doOnError(this::handleConnectionError)
.doOnComplete(this::signalLoginSuccessful)
.doOnError(this::signalLoginError)
.subscribe());
}
private void handleConnectionError(Throwable error) {
private void signalLoginSuccessful() {
loginCompleted.setValue(true);
}
private void signalLoginError(Throwable error) {
if (error instanceof SASLErrorException) {
passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_incorrect_password)));
loginButtonEnabled.setValue(true);
@ -99,12 +102,6 @@ public class LoginViewModel extends AndroidViewModel {
}
}
@Override
protected void onCleared() {
super.onCleared();
disposable.clear();
}
public LiveData<Error> getPasswordError() {
return passwordError;
}
@ -121,6 +118,12 @@ public class LoginViewModel extends AndroidViewModel {
return loginButtonEnabled;
}
@Override
protected void onCleared() {
super.onCleared();
disposable.clear();
}
public static class Error {
private String message;

View File

@ -11,6 +11,7 @@ import io.requery.Convert;
import io.requery.Entity;
import io.requery.ForeignKey;
import io.requery.Generated;
import io.requery.Index;
import io.requery.Key;
import io.requery.ManyToOne;
import io.requery.Persistable;
@ -19,17 +20,19 @@ import io.requery.Table;
import io.requery.converter.UUIDConverter;
@Entity
@Table(name = "contacts")
@Table(name = "contacts", uniqueIndexes = "unique_address")
public abstract class AbstractPeerModel implements Persistable {
@Key
@Convert(UUIDConverter.class)
UUID id;
@Index("unique_address")
@ManyToOne(cascade = CascadeAction.NONE)
@ForeignKey(referencedColumn = "id")
AccountModel account;
@Index("unique_address")
@Column(nullable = false)
String address;

View File

@ -107,11 +107,11 @@ public class XmppPeerRepository
public Single<Peer> getOrCreatePeer(Account account, String address) {
return getPeerByAddress(account, address)
.switchIfEmpty(Single
.just(new IPeer(){
{
setAccount(account);
setAddress(address);
}
.just(new IPeer())
.map(peer -> {
peer.setAccount(account);
peer.setAddress(address);
return peer;
})
.flatMap(this::insertPeer))
.subscribeOn(subscriberScheduler())
@ -121,6 +121,7 @@ public class XmppPeerRepository
@Override
public Observable<List<Peer>> observeAllPeers() {
return data().select(PeerModel.class)
.orderBy(PeerModel.ADDRESS)
.get().observableResult()
.map(ResultDelegate::toList)
.map(peerModels -> {

View File

@ -7,7 +7,6 @@ import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.data.repository.AccountRepository;
import org.mercury_im.messenger.data.repository.PeerRepository;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.entity.contact.IPeer;
import org.mercury_im.messenger.entity.contact.Peer;
import org.mercury_im.messenger.entity.contact.SubscriptionDirection;
@ -80,7 +79,7 @@ public class MercuryRosterStore implements RosterStore {
@Override
public RosterPacket.Item getEntry(Jid bareJid) {
return itemMap.get(bareJid);
return itemMap.get(bareJid.asUnescapedString());
}
@Override
@ -90,27 +89,30 @@ public class MercuryRosterStore implements RosterStore {
@Override
public boolean addEntry(RosterPacket.Item item, String version) {
LOGGER.log(Level.INFO, "Add entry " + item.toXML().toString());
// Update database
Peer contact = toEntity(item);
disposable.add(peerRepository.upsertPeer(contact)
.map(p -> {
LOGGER.log(Level.INFO, "Unserted Peer for account " + p.getAccount().getId());
return p;
})
writeEntryToDatabase(item);
writeRosterVersionToDatabase(version);
return true;
}
private void writeEntryToDatabase(RosterPacket.Item item) {
disposable.add(peerRepository.getOrCreatePeer(account, item.getJid().asUnescapedString())
.map(peer -> toEntity(item, peer))
.flatMap(peerRepository::updatePeer)
.subscribe(
success -> LOGGER.log(Level.FINE, "Upserted contact model " + success + " successfully"),
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + contact, error)
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + item.getJid().asUnescapedString(), error)
));
/*
}
private void writeRosterVersionToDatabase(String version) {
/*
disposable.add(peerRepository.updateRosterVersion(account, version)
.subscribe(
success -> LOGGER.log(Level.FINE, "Upserted roster version to " + rosterVersion + " successfully"),
error -> LOGGER.log(Level.WARNING, "An error occurred upserting roster version", error)
));
*/
return true;
}
@Override
@ -119,16 +121,7 @@ public class MercuryRosterStore implements RosterStore {
// Update database
// TODO: Delete other contacts
for (RosterPacket.Item item : items) {
Peer model = toEntity(item);
disposable.add(peerRepository.upsertPeer(model)
.map(p -> {
LOGGER.log(Level.INFO, "Unserted Peer for account " + p.getAccount().getId());
return p;
})
.subscribe(
success -> LOGGER.log(Level.FINE, "Upserted contact model " + success + " successfully"),
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + model, error)
));
writeEntryToDatabase(item);
}
/*
@ -191,8 +184,7 @@ public class MercuryRosterStore implements RosterStore {
return item;
}
public Peer toEntity(RosterPacket.Item item) {
Peer peer = new IPeer();
public Peer toEntity(RosterPacket.Item item, Peer peer) {
peer.setAccount(account);
peer.setAddress(item.getJid().asEntityBareJidOrThrow().asEntityBareJidString());
peer.setName(item.getName());

View File

@ -23,6 +23,13 @@ public class AddAccount {
private static final Logger LOGGER = Logger.getLogger(AddAccount.class.getName());
public enum ConnectionResult {
success,
credential_error,
server_error,
other_error
}
private Account account;
private MercuryConnection connection;
@ -42,22 +49,19 @@ public class AddAccount {
return this;
}
public boolean isAddressSet() {
return account.getAddress() != null;
}
public AddAccount setPassword(String password) {
this.account.setPassword(password);
return this;
}
public boolean isPasswordSet() {
return account.getPassword() != null;
public Completable execute() {
return loginAndStoreAccountIfSuccessful();
}
public Completable loginAndStoreAccountIfSuccessful() {
return login().andThen(insertEnabledAccountIntoDatabase()).ignoreElement()
.andThen(Completable.fromAction(() -> messenger.addConnection(connection)));
return logIntoAccount()
.andThen(insertEnabledAccountIntoDatabase()).ignoreElement()
.andThen(addConnectionToMessenger());
}
private Single<Account> insertEnabledAccountIntoDatabase() {
@ -66,6 +70,10 @@ public class AddAccount {
.map(this::updateAccount);
}
private Completable addConnectionToMessenger() {
return Completable.fromAction(() -> messenger.addConnection(connection));
}
private Account updateAccount(Account account) {
this.account = account;
updateAccountIdInConnection(account);
@ -78,7 +86,7 @@ public class AddAccount {
}
}
private Completable login() {
private Completable logIntoAccount() {
return Completable.fromAction(
() -> {
getOrCreateConnection();
@ -117,11 +125,4 @@ public class AddAccount {
((AbstractXMPPConnection) connection.getConnection()).connect().login();
}
}
public enum ConnectionResult {
success,
credential_error,
server_error,
other_error
}
}