use of org.thoughtcrime.securesms.database.DraftDatabase in project Signal-Android by WhisperSystems.
the class ConversationParentFragment method saveDraft.
protected ListenableFuture<Long> saveDraft() {
final SettableFuture<Long> future = new SettableFuture<>();
if (this.recipient == null) {
future.set(threadId);
return future;
}
final Context context = requireContext().getApplicationContext();
final Drafts drafts = getDraftsForCurrentState();
final long thisThreadId = this.threadId;
final RecipientId recipientId = this.recipient.getId();
final int thisDistributionType = this.distributionType;
final ListenableFuture<VoiceNoteDraft> voiceNoteDraftFuture = draftViewModel.consumeVoiceNoteDraftFuture();
new AsyncTask<Long, Void, Long>() {
@Override
protected Long doInBackground(Long... params) {
if (voiceNoteDraftFuture != null) {
try {
Draft voiceNoteDraft = voiceNoteDraftFuture.get().asDraft();
draftViewModel.setVoiceNoteDraft(recipientId, voiceNoteDraft);
drafts.add(voiceNoteDraft);
} catch (ExecutionException | InterruptedException e) {
Log.w(TAG, "Could not extract voice note draft data.", e);
}
}
ThreadDatabase threadDatabase = SignalDatabase.threads();
DraftDatabase draftDatabase = SignalDatabase.drafts();
long threadId = params[0];
if (drafts.size() > 0) {
if (threadId == -1)
threadId = threadDatabase.getOrCreateThreadIdFor(getRecipient(), thisDistributionType);
draftDatabase.replaceDrafts(threadId, drafts);
threadDatabase.updateSnippet(threadId, drafts.getSnippet(context), drafts.getUriSnippet(), System.currentTimeMillis(), Types.BASE_DRAFT_TYPE, true);
} else if (threadId > 0) {
threadDatabase.update(threadId, false);
}
if (drafts.isEmpty()) {
draftDatabase.clearDrafts(threadId);
}
return threadId;
}
@Override
protected void onPostExecute(Long result) {
future.set(result);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, thisThreadId);
return future;
}
use of org.thoughtcrime.securesms.database.DraftDatabase in project Signal-Android by WhisperSystems.
the class ConversationActivity method saveDraft.
protected ListenableFuture<Long> saveDraft() {
final SettableFuture<Long> future = new SettableFuture<>();
if (this.recipients == null || this.recipients.isEmpty()) {
future.set(threadId);
return future;
}
final Drafts drafts = getDraftsForCurrentState();
final long thisThreadId = this.threadId;
final MasterSecret thisMasterSecret = this.masterSecret.parcelClone();
final int thisDistributionType = this.distributionType;
new AsyncTask<Long, Void, Long>() {
@Override
protected Long doInBackground(Long... params) {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(ConversationActivity.this);
DraftDatabase draftDatabase = DatabaseFactory.getDraftDatabase(ConversationActivity.this);
long threadId = params[0];
if (drafts.size() > 0) {
if (threadId == -1)
threadId = threadDatabase.getThreadIdFor(getRecipients(), thisDistributionType);
draftDatabase.insertDrafts(new MasterCipher(thisMasterSecret), threadId, drafts);
threadDatabase.updateSnippet(threadId, drafts.getSnippet(ConversationActivity.this), drafts.getUriSnippet(ConversationActivity.this), System.currentTimeMillis(), Types.BASE_DRAFT_TYPE, true);
} else if (threadId > 0) {
threadDatabase.update(threadId, false);
}
return threadId;
}
@Override
protected void onPostExecute(Long result) {
future.set(result);
}
}.execute(thisThreadId);
return future;
}
use of org.thoughtcrime.securesms.database.DraftDatabase in project Signal-Android by signalapp.
the class ConversationActivity method saveDraft.
protected ListenableFuture<Long> saveDraft() {
final SettableFuture<Long> future = new SettableFuture<>();
if (this.recipient == null) {
future.set(threadId);
return future;
}
final Drafts drafts = getDraftsForCurrentState();
final long thisThreadId = this.threadId;
final int thisDistributionType = this.distributionType;
new AsyncTask<Long, Void, Long>() {
@Override
protected Long doInBackground(Long... params) {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(ConversationActivity.this);
DraftDatabase draftDatabase = DatabaseFactory.getDraftDatabase(ConversationActivity.this);
long threadId = params[0];
if (drafts.size() > 0) {
if (threadId == -1)
threadId = threadDatabase.getThreadIdFor(getRecipient(), thisDistributionType);
draftDatabase.insertDrafts(threadId, drafts);
threadDatabase.updateSnippet(threadId, drafts.getSnippet(ConversationActivity.this), drafts.getUriSnippet(), System.currentTimeMillis(), Types.BASE_DRAFT_TYPE, true);
} else if (threadId > 0) {
threadDatabase.update(threadId, false);
}
return threadId;
}
@Override
protected void onPostExecute(Long result) {
future.set(result);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, thisThreadId);
return future;
}
use of org.thoughtcrime.securesms.database.DraftDatabase in project Signal-Android by WhisperSystems.
the class BlobProvider method deleteOrphanedDraftFiles.
private static void deleteOrphanedDraftFiles(@NonNull Context context) {
File directory = getOrCreateDirectory(context, DRAFT_ATTACHMENTS_DIRECTORY);
File[] files = directory.listFiles();
if (files == null || files.length == 0) {
Log.d(TAG, "No attachment drafts exist. Skipping.");
return;
}
DraftDatabase draftDatabase = SignalDatabase.drafts();
DraftDatabase.Drafts voiceNoteDrafts = draftDatabase.getAllVoiceNoteDrafts();
@SuppressWarnings("ConstantConditions") List<String> draftFileNames = voiceNoteDrafts.stream().map(VoiceNoteDraft::fromDraft).map(VoiceNoteDraft::getUri).map(BlobProvider::getId).filter(Objects::nonNull).map(BlobProvider::buildFileName).collect(Collectors.toList());
for (final File file : files) {
if (!draftFileNames.contains(file.getName())) {
if (file.delete()) {
Log.d(TAG, "Deleted orphaned attachment draft: " + file.getName());
} else {
Log.d(TAG, "Failed to delete orphaned attachment draft: " + file.getName());
}
}
}
}
use of org.thoughtcrime.securesms.database.DraftDatabase in project Signal-Android by WhisperSystems.
the class ConversationParentFragment method initializeDraftFromDatabase.
private ListenableFuture<Boolean> initializeDraftFromDatabase() {
SettableFuture<Boolean> future = new SettableFuture<>();
final Context context = requireContext().getApplicationContext();
new AsyncTask<Void, Void, Pair<Drafts, CharSequence>>() {
@Override
protected Pair<Drafts, CharSequence> doInBackground(Void... params) {
DraftDatabase draftDatabase = SignalDatabase.drafts();
Drafts results = draftDatabase.getDrafts(threadId);
Draft mentionsDraft = results.getDraftOfType(Draft.MENTION);
Spannable updatedText = null;
if (mentionsDraft != null) {
String text = results.getDraftOfType(Draft.TEXT).getValue();
List<Mention> mentions = MentionUtil.bodyRangeListToMentions(context, Base64.decodeOrThrow(mentionsDraft.getValue()));
UpdatedBodyAndMentions updated = MentionUtil.updateBodyAndMentionsWithDisplayNames(context, text, mentions);
updatedText = new SpannableString(updated.getBody());
MentionAnnotation.setMentionAnnotations(updatedText, updated.getMentions());
}
draftDatabase.clearDrafts(threadId);
return new Pair<>(results, updatedText);
}
@Override
protected void onPostExecute(Pair<Drafts, CharSequence> draftsWithUpdatedMentions) {
Drafts drafts = Objects.requireNonNull(draftsWithUpdatedMentions.first());
CharSequence updatedText = draftsWithUpdatedMentions.second();
if (drafts.isEmpty()) {
future.set(false);
updateToggleButtonState();
return;
}
AtomicInteger draftsRemaining = new AtomicInteger(drafts.size());
AtomicBoolean success = new AtomicBoolean(false);
ListenableFuture.Listener<Boolean> listener = new AssertedSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean result) {
success.compareAndSet(false, result);
if (draftsRemaining.decrementAndGet() <= 0) {
future.set(success.get());
}
}
};
for (Draft draft : drafts) {
try {
switch(draft.getType()) {
case Draft.TEXT:
composeText.setText(updatedText == null ? draft.getValue() : updatedText);
listener.onSuccess(true);
break;
case Draft.LOCATION:
attachmentManager.setLocation(SignalPlace.deserialize(draft.getValue()), getCurrentMediaConstraints()).addListener(listener);
break;
case Draft.IMAGE:
setMedia(Uri.parse(draft.getValue()), MediaType.IMAGE).addListener(listener);
break;
case Draft.AUDIO:
setMedia(Uri.parse(draft.getValue()), MediaType.AUDIO).addListener(listener);
break;
case Draft.VIDEO:
setMedia(Uri.parse(draft.getValue()), MediaType.VIDEO).addListener(listener);
break;
case Draft.QUOTE:
SettableFuture<Boolean> quoteResult = new SettableFuture<>();
new QuoteRestorationTask(draft.getValue(), quoteResult).execute();
quoteResult.addListener(listener);
break;
case Draft.VOICE_NOTE:
draftViewModel.setVoiceNoteDraft(recipient.getId(), draft);
break;
}
} catch (IOException e) {
Log.w(TAG, e);
}
}
updateToggleButtonState();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return future;
}
Aggregations