use of it.niedermann.nextcloud.deck.model.full.FullCard in project nextcloud-deck by stefan-niedermann.
the class SyncManager method updateAttachmentForCard.
@AnyThread
public WrappedLiveData<Attachment> updateAttachmentForCard(long accountId, @NonNull Attachment existing, @NonNull String mimeType, @NonNull File file) {
WrappedLiveData<Attachment> liveData = new WrappedLiveData<>();
executor.submit(() -> {
Attachment attachment = populateAttachmentEntityForFile(existing, existing.getCardId(), mimeType, file);
attachment.setLastModifiedLocal(Instant.now());
if (serverAdapter.hasInternetConnection()) {
FullCard card = dataBaseAdapter.getFullCardByLocalIdDirectly(accountId, existing.getCardId());
Stack stack = dataBaseAdapter.getStackByLocalIdDirectly(card.getCard().getStackId());
Board board = dataBaseAdapter.getBoardByLocalIdDirectly(stack.getBoardId());
Account account = dataBaseAdapter.getAccountByIdDirectly(card.getAccountId());
new DataPropagationHelper(serverAdapter, dataBaseAdapter, executor).updateEntity(new AttachmentDataProvider(null, board, stack, card, Collections.singletonList(attachment)), attachment, new ResponseCallback<>(account) {
@Override
public void onResponse(Attachment response) {
liveData.postValue(response);
}
@SuppressLint("MissingSuperCall")
@Override
public void onError(Throwable throwable) {
liveData.postError(throwable);
}
});
}
});
return liveData;
}
use of it.niedermann.nextcloud.deck.model.full.FullCard in project nextcloud-deck by stefan-niedermann.
the class SyncManager method cloneBoard.
/**
* Creates a new {@link Board} and adds the same {@link Label} and {@link Stack} as in the origin {@link Board}.
* Owner of the target {@link Board} will be the {@link User} with the {@link Account} of {@param targetAccountId}.
*
* @param cloneCards determines whether or not the cards in this {@link Board} shall be cloned or not
* Does <strong>not</strong> clone any {@link Card} or {@link AccessControl} from the origin {@link Board}.
*/
@AnyThread
public void cloneBoard(long originAccountId, long originBoardLocalId, long targetAccountId, @ColorInt int targetBoardColor, boolean cloneCards, @NonNull IResponseCallback<FullBoard> callback) {
executor.submit(() -> {
Account originAccount = dataBaseAdapter.getAccountByIdDirectly(originAccountId);
User newOwner = dataBaseAdapter.getUserByUidDirectly(originAccountId, originAccount.getUserName());
if (newOwner == null) {
callback.onError(new DeckException(DeckException.Hint.UNKNOWN_ACCOUNT_USER_ID, "User with Account-UID \"" + originAccount.getUserName() + "\" not found."));
return;
}
FullBoard originalBoard = dataBaseAdapter.getFullBoardByLocalIdDirectly(originAccountId, originBoardLocalId);
String newBoardTitleBaseName = originalBoard.getBoard().getTitle().trim();
int newBoardTitleCopyIndex = 0;
// already a copy?
String regex = " \\(copy [0-9]+\\)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(originalBoard.getBoard().getTitle());
if (matcher.find()) {
String found = matcher.group();
newBoardTitleBaseName = newBoardTitleBaseName.substring(0, newBoardTitleBaseName.length() - found.length());
Matcher indexMatcher = Pattern.compile("[0-9]+").matcher(found);
// noinspection ResultOfMethodCallIgnored
indexMatcher.find();
String oldIndexString = indexMatcher.group();
newBoardTitleCopyIndex = Integer.parseInt(oldIndexString);
}
String newBoardTitle;
do {
newBoardTitleCopyIndex++;
newBoardTitle = newBoardTitleBaseName + " (copy " + newBoardTitleCopyIndex + ")";
} while (dataBaseAdapter.getBoardForAccountByNameDirectly(targetAccountId, newBoardTitle) != null);
originalBoard.setAccountId(targetAccountId);
originalBoard.setId(null);
originalBoard.setLocalId(null);
originalBoard.getBoard().setTitle(newBoardTitle);
originalBoard.getBoard().setColor(String.format("%06X", 0xFFFFFF & targetBoardColor));
originalBoard.getBoard().setOwnerId(newOwner.getLocalId());
originalBoard.setStatusEnum(DBStatus.LOCAL_EDITED);
originalBoard.setOwner(newOwner);
long newBoardId = dataBaseAdapter.createBoardDirectly(originAccountId, originalBoard.getBoard());
originalBoard.setLocalId(newBoardId);
boolean isSameAccount = targetAccountId == originAccountId;
if (isSameAccount) {
List<AccessControl> aclList = originalBoard.getParticipants();
for (AccessControl acl : aclList) {
acl.setLocalId(null);
acl.setId(null);
acl.setBoardId(newBoardId);
dataBaseAdapter.createAccessControl(targetAccountId, acl);
}
}
Map<Long, Long> oldToNewLabelIdsDictionary = new HashMap<>();
for (Label label : originalBoard.getLabels()) {
Long oldLocalId = label.getLocalId();
label.setLocalId(null);
label.setId(null);
label.setAccountId(targetAccountId);
label.setStatusEnum(DBStatus.LOCAL_EDITED);
label.setBoardId(newBoardId);
long newLocalId = dataBaseAdapter.createLabelDirectly(targetAccountId, label);
oldToNewLabelIdsDictionary.put(oldLocalId, newLocalId);
}
List<Stack> oldStacks = originalBoard.getStacks();
for (Stack stack : oldStacks) {
Long oldStackId = stack.getLocalId();
stack.setLocalId(null);
stack.setId(null);
stack.setStatusEnum(DBStatus.LOCAL_EDITED);
stack.setAccountId(targetAccountId);
stack.setBoardId(newBoardId);
long createdStackId = dataBaseAdapter.createStack(targetAccountId, stack);
if (cloneCards) {
List<FullCard> oldCards = dataBaseAdapter.getFullCardsForStackDirectly(originAccountId, oldStackId, null);
for (FullCard oldCard : oldCards) {
Card newCard = oldCard.getCard();
newCard.setId(null);
newCard.setUserId(newOwner.getLocalId());
newCard.setLocalId(null);
newCard.setStackId(createdStackId);
newCard.setAccountId(targetAccountId);
newCard.setStatusEnum(DBStatus.LOCAL_EDITED);
long createdCardId = dataBaseAdapter.createCardDirectly(targetAccountId, newCard);
if (oldCard.getLabels() != null) {
for (Label oldLabel : oldCard.getLabels()) {
Long newLabelId = oldToNewLabelIdsDictionary.get(oldLabel.getLocalId());
if (newLabelId != null) {
dataBaseAdapter.createJoinCardWithLabel(newLabelId, createdCardId, DBStatus.LOCAL_EDITED);
} else
DeckLog.error("ID of created Label is null! Skipping assignment of ", oldLabel.getTitle(), "…");
}
}
if (isSameAccount && oldCard.getAssignedUsers() != null) {
for (User assignedUser : oldCard.getAssignedUsers()) {
dataBaseAdapter.createJoinCardWithUser(assignedUser.getLocalId(), createdCardId, DBStatus.LOCAL_EDITED);
}
}
}
}
}
if (serverAdapter.hasInternetConnection()) {
Account targetAccount = dataBaseAdapter.getAccountByIdDirectly(targetAccountId);
ServerAdapter serverAdapterToUse = this.serverAdapter;
if (originAccountId != targetAccountId) {
serverAdapterToUse = new ServerAdapter(appContext, targetAccount.getName());
}
syncHelperFactory.create(serverAdapterToUse, dataBaseAdapter, null).setResponseCallback(new ResponseCallback<>(targetAccount) {
@Override
public void onResponse(Boolean response) {
callback.onResponse(dataBaseAdapter.getFullBoardByLocalIdDirectly(targetAccountId, newBoardId));
}
@SuppressLint("MissingSuperCall")
@Override
public void onError(Throwable throwable) {
callback.onError(throwable);
}
}).doUpSyncFor(new BoardWithStacksAndLabelsUpSyncDataProvider(dataBaseAdapter.getFullBoardByLocalIdDirectly(targetAccountId, newBoardId)));
} else {
callback.onResponse(dataBaseAdapter.getFullBoardByLocalIdDirectly(targetAccountId, newBoardId));
}
});
}
use of it.niedermann.nextcloud.deck.model.full.FullCard in project nextcloud-deck by stefan-niedermann.
the class CardDataProvider method goDeeperForUpSync.
@Override
public void goDeeperForUpSync(SyncHelper syncHelper, ServerAdapter serverAdapter, DataBaseAdapter dataBaseAdapter, ResponseCallback<Boolean> callback) {
FullStack stack;
Board board;
List<JoinCardWithLabel> changedLabels;
if (this.stack == null) {
changedLabels = dataBaseAdapter.getAllChangedLabelJoins();
} else {
changedLabels = dataBaseAdapter.getAllChangedLabelJoinsForStack(this.stack.getLocalId());
}
Account account = callback.getAccount();
for (JoinCardWithLabel changedLabelLocal : changedLabels) {
Card card = dataBaseAdapter.getCardByLocalIdDirectly(account.getId(), changedLabelLocal.getCardId());
if (card == null) {
// https://github.com/stefan-niedermann/nextcloud-deck/issues/683#issuecomment-759116820
continue;
}
if (this.stack == null) {
stack = dataBaseAdapter.getFullStackByLocalIdDirectly(card.getStackId());
} else {
stack = this.stack;
}
if (this.board == null) {
board = dataBaseAdapter.getBoardByLocalIdDirectly(stack.getStack().getBoardId());
} else {
board = this.board;
}
JoinCardWithLabel changedLabel = dataBaseAdapter.getAllChangedLabelJoinsWithRemoteIDs(changedLabelLocal.getCardId(), changedLabelLocal.getLabelId());
if (changedLabel.getStatusEnum() == DBStatus.LOCAL_DELETED) {
if (changedLabel.getLabelId() == null || changedLabel.getCardId() == null) {
dataBaseAdapter.deleteJoinedLabelForCardPhysicallyByRemoteIDs(account.getId(), changedLabel.getCardId(), changedLabel.getLabelId());
} else {
serverAdapter.unassignLabelFromCard(board.getId(), stack.getId(), changedLabel.getCardId(), changedLabel.getLabelId(), new ResponseCallback<>(account) {
@Override
public void onResponse(Void response) {
dataBaseAdapter.deleteJoinedLabelForCardPhysicallyByRemoteIDs(account.getId(), changedLabel.getCardId(), changedLabel.getLabelId());
}
});
}
} else if (changedLabel.getStatusEnum() == DBStatus.LOCAL_EDITED) {
if (changedLabel.getLabelId() == null || changedLabel.getCardId() == null) {
// Sync next time, the card should be available on server then.
continue;
} else {
serverAdapter.assignLabelToCard(board.getId(), stack.getId(), changedLabel.getCardId(), changedLabel.getLabelId(), new ResponseCallback<>(account) {
@Override
public void onResponse(Void response) {
Label label = dataBaseAdapter.getLabelByRemoteIdDirectly(account.getId(), changedLabel.getLabelId());
dataBaseAdapter.setStatusForJoinCardWithLabel(card.getLocalId(), label.getLocalId(), DBStatus.UP_TO_DATE.getId());
}
});
}
}
}
List<JoinCardWithUser> changedUsers;
if (this.stack == null) {
changedUsers = dataBaseAdapter.getAllChangedUserJoinsWithRemoteIDs();
} else {
changedUsers = dataBaseAdapter.getAllChangedUserJoinsWithRemoteIDsForStack(this.stack.getLocalId());
}
for (JoinCardWithUser changedUser : changedUsers) {
// not already known to server?
if (changedUser.getCardId() == null) {
// skip for now
continue;
}
Card card = dataBaseAdapter.getCardByRemoteIdDirectly(account.getId(), changedUser.getCardId());
if (card == null) {
// this shouldn't actually happen, but does as it seems. the card cant be found by remote id (exists!) and account-ID.
continue;
}
if (this.stack == null) {
stack = dataBaseAdapter.getFullStackByLocalIdDirectly(card.getStackId());
} else {
stack = this.stack;
}
if (this.board == null) {
board = dataBaseAdapter.getBoardByLocalIdDirectly(stack.getStack().getBoardId());
} else {
board = this.board;
}
User user = dataBaseAdapter.getUserByLocalIdDirectly(changedUser.getUserId());
if (changedUser.getStatusEnum() == DBStatus.LOCAL_DELETED) {
serverAdapter.unassignUserFromCard(board.getId(), stack.getId(), changedUser.getCardId(), user.getUid(), new ResponseCallback<>(account) {
@Override
public void onResponse(Void response) {
dataBaseAdapter.deleteJoinedUserForCardPhysicallyByRemoteIDs(account.getId(), changedUser.getCardId(), user.getUid());
}
});
} else if (changedUser.getStatusEnum() == DBStatus.LOCAL_EDITED) {
serverAdapter.assignUserToCard(board.getId(), stack.getId(), changedUser.getCardId(), user.getUid(), new ResponseCallback<>(account) {
@Override
public void onResponse(Void response) {
dataBaseAdapter.setStatusForJoinCardWithUser(card.getLocalId(), user.getLocalId(), DBStatus.UP_TO_DATE.getId());
}
});
}
}
List<Attachment> attachments;
if (this.stack == null) {
attachments = dataBaseAdapter.getLocallyChangedAttachmentsDirectly(account.getId());
} else {
attachments = dataBaseAdapter.getLocallyChangedAttachmentsForStackDirectly(this.stack.getLocalId());
}
for (Attachment attachment : attachments) {
FullCard card = dataBaseAdapter.getFullCardByLocalIdDirectly(account.getId(), attachment.getCardId());
stack = dataBaseAdapter.getFullStackByLocalIdDirectly(card.getCard().getStackId());
board = dataBaseAdapter.getBoardByLocalIdDirectly(stack.getStack().getBoardId());
syncHelper.doUpSyncFor(new AttachmentDataProvider(this, board, stack.getStack(), card, Collections.singletonList(attachment)));
}
List<Card> cardsWithChangedComments;
if (this.stack == null) {
cardsWithChangedComments = dataBaseAdapter.getCardsWithLocallyChangedCommentsDirectly(account.getId());
} else {
cardsWithChangedComments = dataBaseAdapter.getCardsWithLocallyChangedCommentsForStackDirectly(this.stack.getLocalId());
}
for (Card card : cardsWithChangedComments) {
syncHelper.doUpSyncFor(new DeckCommentsDataProvider(this, card));
}
callback.onResponse(Boolean.TRUE);
}
use of it.niedermann.nextcloud.deck.model.full.FullCard in project nextcloud-deck by stefan-niedermann.
the class CardDataProvider method updateOnServer.
@Override
public void updateOnServer(ServerAdapter serverAdapter, DataBaseAdapter dataBaseAdapter, long accountId, ResponseCallback<FullCard> callback, FullCard entity) {
CardUpdate update = toCardUpdate(entity);
update.setStackId(stack.getId());
// https://github.com/stefan-niedermann/nextcloud-deck/issues/787 resolve archiving-conflict
serverAdapter.updateCard(board.getId(), stack.getId(), update, new ResponseCallback<>(callback.getAccount()) {
@Override
public void onResponse(FullCard response) {
callback.onResponse(response);
}
@SuppressLint("MissingSuperCall")
@Override
public void onError(Throwable throwable) {
if (throwable.getClass() == NextcloudHttpRequestFailedException.class && throwable.getCause() != null && throwable.getCause().getClass() == IllegalStateException.class && throwable.getCause().getMessage() != null && throwable.getCause().getMessage().contains(ALREADY_ARCHIVED_INDICATOR)) {
callback.onResponse(entity);
} else {
callback.onError(throwable);
}
}
});
}
use of it.niedermann.nextcloud.deck.model.full.FullCard in project nextcloud-deck by stefan-niedermann.
the class SyncManager method reorder.
/**
* @see <a href="https://github.com/stefan-niedermann/nextcloud-deck/issues/360">reenable reorder</a>
*/
@AnyThread
public void reorder(long accountId, @NonNull FullCard movedCard, long newStackId, int newIndex) {
executor.submit(() -> {
// read cards of new stack
List<FullCard> cardsOfNewStack = dataBaseAdapter.getFullCardsForStackDirectly(accountId, newStackId, null);
int newOrder = newIndex;
if (cardsOfNewStack.size() > newIndex) {
newOrder = cardsOfNewStack.get(newIndex).getCard().getOrder();
}
boolean orderIsCorrect = true;
if (newOrder == movedCard.getCard().getOrder() && newStackId == movedCard.getCard().getStackId()) {
int lastOrder = Integer.MIN_VALUE;
for (FullCard fullCard : cardsOfNewStack) {
int currentOrder = fullCard.getCard().getOrder();
if (currentOrder > lastOrder) {
lastOrder = currentOrder;
} else {
// the order is messed up. this could happen for a while,
// because the new cards by the app had all the same order: 0
orderIsCorrect = false;
break;
}
}
if (orderIsCorrect) {
return;
} else {
// we need to fix the order.
cardsOfNewStack.remove(movedCard);
cardsOfNewStack.add(newIndex, movedCard);
for (int i = 0; i < cardsOfNewStack.size(); i++) {
Card card = cardsOfNewStack.get(i).getCard();
card.setOrder(i);
dataBaseAdapter.updateCard(card, true);
}
}
}
// } else {
if (orderIsCorrect) {
reorderLocally(cardsOfNewStack, movedCard, newStackId, newOrder);
}
// FIXME: remove the sync-block, when commentblock up there is activated. (waiting for deck server bugfix)
if (hasInternetConnection()) {
Stack stack = dataBaseAdapter.getStackByLocalIdDirectly(movedCard.getCard().getStackId());
FullBoard board = dataBaseAdapter.getFullBoardByLocalIdDirectly(accountId, stack.getBoardId());
Account account = dataBaseAdapter.getAccountByIdDirectly(movedCard.getCard().getAccountId());
syncHelperFactory.create(serverAdapter, dataBaseAdapter, Instant.now()).setResponseCallback(new ResponseCallback<>(account) {
@Override
public void onResponse(Boolean response) {
// doNothing();
}
}).doUpSyncFor(new StackDataProvider(null, board));
}
// }
});
}
Aggregations