MOBILE-4482 forum: Avoid reuploading files when editing post
parent
ec5c8d6cad
commit
3d51b17e33
|
@ -39,7 +39,7 @@ import {
|
||||||
} from '../../services/forum';
|
} from '../../services/forum';
|
||||||
import { CoreTag } from '@features/tag/services/tag';
|
import { CoreTag } from '@features/tag/services/tag';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
|
import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
|
||||||
import { AddonModForumSync } from '../../services/forum-sync';
|
import { AddonModForumSync } from '../../services/forum-sync';
|
||||||
import { CoreSync } from '@services/sync';
|
import { CoreSync } from '@services/sync';
|
||||||
import { CoreText } from '@singletons/text';
|
import { CoreText } from '@singletons/text';
|
||||||
|
@ -57,6 +57,7 @@ import { CoreToasts } from '@services/toasts';
|
||||||
import { toBoolean } from '@/core/transforms/boolean';
|
import { toBoolean } from '@/core/transforms/boolean';
|
||||||
import { CorePopovers } from '@services/popovers';
|
import { CorePopovers } from '@services/popovers';
|
||||||
import { CoreLoadings } from '@services/loadings';
|
import { CoreLoadings } from '@services/loadings';
|
||||||
|
import { CoreWSFile } from '@services/ws';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.).
|
* Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.).
|
||||||
|
@ -214,7 +215,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
this.formData.isEditing = !!isEditing;
|
this.formData.isEditing = !!isEditing;
|
||||||
this.formData.subject = subject || this.defaultReplySubject || '';
|
this.formData.subject = subject || this.defaultReplySubject || '';
|
||||||
this.formData.message = message || null;
|
this.formData.message = message || null;
|
||||||
this.formData.files = files || [];
|
this.formData.files = (files ?? []).slice(); // Make a copy to avoid modifying the original array.
|
||||||
this.formData.isprivatereply = !!isPrivate;
|
this.formData.isprivatereply = !!isPrivate;
|
||||||
this.formData.id = postId;
|
this.formData.id = postId;
|
||||||
|
|
||||||
|
@ -392,10 +393,9 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let saveOffline = false;
|
|
||||||
let message = this.formData.message;
|
let message = this.formData.message;
|
||||||
const subject = this.formData.subject;
|
const subject = this.formData.subject;
|
||||||
const replyingTo = this.formData.replyingTo!;
|
const replyingTo = this.formData.replyingTo ?? 0;
|
||||||
const files = this.formData.files || [];
|
const files = this.formData.files || [];
|
||||||
const isEditOnline = this.formData.id && this.formData.id > 0;
|
const isEditOnline = this.formData.id && this.formData.id > 0;
|
||||||
const modal = await CoreLoadings.show('core.sending', true);
|
const modal = await CoreLoadings.show('core.sending', true);
|
||||||
|
@ -413,73 +413,56 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
// Add some HTML to the message if needed.
|
// Add some HTML to the message if needed.
|
||||||
message = CoreText.formatHtmlLines(message);
|
message = CoreText.formatHtmlLines(message);
|
||||||
|
|
||||||
// Upload attachments first if any.
|
|
||||||
let attachments;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (files.length) {
|
|
||||||
try {
|
|
||||||
attachments = await AddonModForumHelper.uploadOrStoreReplyFiles(
|
|
||||||
this.forum.id,
|
|
||||||
isEditOnline ? this.formData.id! : replyingTo,
|
|
||||||
files,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
// Cannot upload them in online, save them in offline.
|
|
||||||
if (!this.forum.id || isEditOnline || CoreUtils.isWebServiceError(error)) {
|
|
||||||
// Cannot store them in offline. Reject.
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveOffline = true;
|
|
||||||
attachments = await AddonModForumHelper.uploadOrStoreReplyFiles(this.forum.id, replyingTo, files, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let sent = false;
|
let sent = false;
|
||||||
|
|
||||||
if (isEditOnline) {
|
if (this.formData.id && this.formData.id > 0) {
|
||||||
sent = await AddonModForum.updatePost(this.formData.id!, subject, message, {
|
const attachments = await this.uploadAttachmentsForEditOnline(this.formData.id);
|
||||||
|
|
||||||
|
sent = await AddonModForum.updatePost(this.formData.id, subject, message, {
|
||||||
attachmentsid: attachments,
|
attachmentsid: attachments,
|
||||||
inlineattachmentsid: this.preparePostData?.draftitemid,
|
inlineattachmentsid: this.preparePostData?.draftitemid,
|
||||||
});
|
});
|
||||||
} else if (saveOffline) {
|
|
||||||
// Save post in offline.
|
|
||||||
await AddonModForumOffline.replyPost(
|
|
||||||
replyingTo,
|
|
||||||
this.discussionId,
|
|
||||||
this.forum.id,
|
|
||||||
this.forum.name,
|
|
||||||
this.courseId,
|
|
||||||
subject,
|
|
||||||
message,
|
|
||||||
{
|
|
||||||
attachmentsid: attachments,
|
|
||||||
private: !!this.formData.isprivatereply,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set sent to false since it wasn't sent to server.
|
|
||||||
sent = false;
|
|
||||||
} else {
|
} else {
|
||||||
// Try to send it to server.
|
const { attachments, saveOffline } = await this.uploadAttachmentsForReply(replyingTo);
|
||||||
// Don't allow offline if there are attachments since they were uploaded fine.
|
|
||||||
sent = await AddonModForum.replyPost(
|
if (saveOffline) {
|
||||||
replyingTo,
|
// Save post in offline.
|
||||||
this.discussionId,
|
await AddonModForumOffline.replyPost(
|
||||||
this.forum.id,
|
replyingTo,
|
||||||
this.forum.name,
|
this.discussionId,
|
||||||
this.courseId,
|
this.forum.id,
|
||||||
subject,
|
this.forum.name,
|
||||||
message,
|
this.courseId,
|
||||||
{
|
subject,
|
||||||
attachmentsid: attachments,
|
message,
|
||||||
private: !!this.formData.isprivatereply,
|
{
|
||||||
},
|
attachmentsid: attachments,
|
||||||
undefined,
|
private: !!this.formData.isprivatereply,
|
||||||
!files.length,
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set sent to false since it wasn't sent to server.
|
||||||
|
sent = false;
|
||||||
|
} else {
|
||||||
|
// Try to send it to server.
|
||||||
|
// Don't allow offline if there are attachments since they were uploaded fine.
|
||||||
|
sent = await AddonModForum.replyPost(
|
||||||
|
replyingTo,
|
||||||
|
this.discussionId,
|
||||||
|
this.forum.id,
|
||||||
|
this.forum.name,
|
||||||
|
this.courseId,
|
||||||
|
subject,
|
||||||
|
message,
|
||||||
|
{
|
||||||
|
attachmentsid: attachments,
|
||||||
|
private: !!this.formData.isprivatereply,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
!files.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sent && this.forum.id) {
|
if (sent && this.forum.id) {
|
||||||
|
@ -506,6 +489,81 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload attachments when editing an online post.
|
||||||
|
*
|
||||||
|
* @param postId Post ID being edited.
|
||||||
|
* @returns Draft area id (if any attachment has changed).
|
||||||
|
*/
|
||||||
|
protected async uploadAttachmentsForEditOnline(postId: number): Promise<number | undefined> {
|
||||||
|
const files = this.formData.files || [];
|
||||||
|
const previousAttachments = (this.post.attachments ?? []) as CoreWSFile[];
|
||||||
|
|
||||||
|
if (!CoreFileUploader.areFileListDifferent(files, previousAttachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use prepare post for edition to avoid re-uploading all files.
|
||||||
|
let filesToKeep = files.filter((file): file is CoreWSFile => !CoreUtils.isFileEntry(file));
|
||||||
|
let removedFiles: { filepath: string; filename: string }[] | undefined;
|
||||||
|
|
||||||
|
if (previousAttachments.length && !filesToKeep.length) {
|
||||||
|
// Post had attachments but they were all removed. We cannot use the filesToKeep option because it doesn't allow
|
||||||
|
// removing all files. In this case we'll just keep 1 file and remove it later.
|
||||||
|
filesToKeep = [previousAttachments[0]];
|
||||||
|
removedFiles = [{
|
||||||
|
filename: previousAttachments[0].filename ?? '',
|
||||||
|
filepath: previousAttachments[0].filepath ?? '',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
const preparePostData = await AddonModForum.preparePostForEdition(postId, 'attachment', { filesToKeep });
|
||||||
|
|
||||||
|
if (removedFiles?.length) {
|
||||||
|
await CoreFileUploader.deleteDraftFiles(preparePostData.draftitemid, removedFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
await CoreFileUploader.uploadFiles(preparePostData.draftitemid, files);
|
||||||
|
|
||||||
|
return preparePostData.draftitemid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload attachments for a reply that isn't an online post being edited.
|
||||||
|
*
|
||||||
|
* @param replyingTo Replying to post ID.
|
||||||
|
* @returns Draft area id (if any attachment was uploaded) and whether data should be saved offline.
|
||||||
|
*/
|
||||||
|
async uploadAttachmentsForReply(
|
||||||
|
replyingTo: number,
|
||||||
|
): Promise<{ attachments: CoreFileUploaderStoreFilesResult | number | undefined; saveOffline: boolean }> {
|
||||||
|
const files = this.formData.files || [];
|
||||||
|
if (!files.length) {
|
||||||
|
return { attachments: undefined, saveOffline: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const attachments = await AddonModForumHelper.uploadOrStoreReplyFiles(
|
||||||
|
this.forum.id,
|
||||||
|
replyingTo,
|
||||||
|
files,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
return { attachments, saveOffline: false };
|
||||||
|
} catch (error) {
|
||||||
|
// Cannot upload them in online, save them in offline.
|
||||||
|
if (!this.forum.id || CoreUtils.isWebServiceError(error)) {
|
||||||
|
// Cannot store them in offline. Reject.
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachments = await AddonModForumHelper.uploadOrStoreReplyFiles(this.forum.id, replyingTo, files, true);
|
||||||
|
|
||||||
|
return { attachments, saveOffline: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel reply.
|
* Cancel reply.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue