MOBILE-3320 database: Fix issues adding offline entries

main
Dani Palou 2021-06-21 09:11:51 +02:00
parent 7ace30fa80
commit ce4f4356c4
9 changed files with 41 additions and 15 deletions

View File

@ -71,7 +71,7 @@ export class AddonModDataSearchComponent implements OnInit {
this.search.advanced?.forEach((field) => { this.search.advanced?.forEach((field) => {
if (typeof field != 'undefined') { if (typeof field != 'undefined') {
this.advancedIndexed[field.name] = field.value this.advancedIndexed[field.name] = field.value
? CoreTextUtils.parseJSON(field.value) ? CoreTextUtils.parseJSON(field.value, '')
: ''; : '';
} }
}); });

View File

@ -112,7 +112,8 @@ export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHan
offlineContent: CoreFormFields, offlineContent: CoreFormFields,
offlineFiles?: FileEntry[], offlineFiles?: FileEntry[],
): AddonModDataEntryField { ): AddonModDataEntryField {
const uploadedFilesResult: CoreFileUploaderStoreFilesResult = <CoreFileUploaderStoreFilesResult>offlineContent?.file; const uploadedFilesResult: CoreFileUploaderStoreFilesResult | undefined =
<CoreFileUploaderStoreFilesResult | undefined> offlineContent?.file;
if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) { if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
originalContent.content = offlineFiles[0].name; originalContent.content = offlineFiles[0].name;

View File

@ -121,8 +121,8 @@ export class AddonModDataFieldLatlongHandlerService implements AddonModDataField
* @inheritdoc * @inheritdoc
*/ */
overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField { overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
originalContent.content = offlineContent[0] || ''; originalContent.content = offlineContent['0'] || '';
originalContent.content1 = offlineContent[1] || ''; originalContent.content1 = offlineContent['1'] || '';
return originalContent; return originalContent;
} }

View File

@ -155,7 +155,8 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
offlineContent: CoreFormFields, offlineContent: CoreFormFields,
offlineFiles?: FileEntry[], offlineFiles?: FileEntry[],
): AddonModDataEntryField { ): AddonModDataEntryField {
const uploadedFilesResult: CoreFileUploaderStoreFilesResult = <CoreFileUploaderStoreFilesResult>offlineContent?.file; const uploadedFilesResult: CoreFileUploaderStoreFilesResult | undefined =
<CoreFileUploaderStoreFilesResult | undefined> offlineContent?.file;
if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) { if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
originalContent.content = offlineFiles[0].name; originalContent.content = offlineFiles[0].name;
@ -165,7 +166,7 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
originalContent.files = [uploadedFilesResult.online[0]]; originalContent.files = [uploadedFilesResult.online[0]];
} }
originalContent.content1 = <string>offlineContent.alttext || ''; originalContent.content1 = <string> offlineContent.alttext || '';
return originalContent; return originalContent;
} }

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data'; import { AddonModDataEntryField, AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { Translate, makeSingleton } from '@singletons'; import { Translate, makeSingleton } from '@singletons';
@ -59,5 +59,14 @@ export class AddonModDataFieldUrlHandlerService extends AddonModDataFieldTextHan
} }
} }
/**
* @inheritdoc
*/
overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
originalContent.content = offlineContent['0'] || '';
return originalContent;
}
} }
export const AddonModDataFieldUrlHandler = makeSingleton(AddonModDataFieldUrlHandlerService); export const AddonModDataFieldUrlHandler = makeSingleton(AddonModDataFieldUrlHandlerService);

View File

@ -92,9 +92,9 @@ export class AddonModDataHelperProvider {
if (offlineContent.subfield) { if (offlineContent.subfield) {
offlineContents[offlineContent.fieldid][offlineContent.subfield] = offlineContents[offlineContent.fieldid][offlineContent.subfield] =
CoreTextUtils.parseJSON(offlineContent.value); CoreTextUtils.parseJSON(offlineContent.value, '');
} else { } else {
offlineContents[offlineContent.fieldid][''] = CoreTextUtils.parseJSON(offlineContent.value); offlineContents[offlineContent.fieldid][''] = CoreTextUtils.parseJSON(offlineContent.value, '');
} }
}); });
@ -632,7 +632,7 @@ export class AddonModDataHelperProvider {
const folderPath = await AddonModDataOffline.getEntryFieldFolder(dataId, entryId, fieldId, siteId); const folderPath = await AddonModDataOffline.getEntryFieldFolder(dataId, entryId, fieldId, siteId);
try { try {
return CoreFileUploader.getStoredFiles(folderPath); return await CoreFileUploader.getStoredFiles(folderPath);
} catch { } catch {
// Ignore not found files. // Ignore not found files.
return []; return [];

View File

@ -88,9 +88,9 @@ export class AddonModDataOfflineProvider {
const promises: Promise<void>[] = []; const promises: Promise<void>[] = [];
entry.fields.forEach((field) => { entry.fields.forEach((field) => {
const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult>(field.value); const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult | null>(field.value, null);
if (!value.offline) { if (!value || !value.offline) {
return; return;
} }

View File

@ -345,8 +345,8 @@ export class AddonModDataSyncProvider extends CoreCourseActivitySyncBaseProvider
try { try {
await Promise.all(editAction.fields.map(async (field) => { await Promise.all(editAction.fields.map(async (field) => {
// Upload Files if asked. // Upload Files if asked.
const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult>(field.value || ''); const value = CoreTextUtils.parseJSON<CoreFileUploaderStoreFilesResult | null>(field.value || '', null);
if (value.online || value.offline) { if (value && (value.online || value.offline)) {
let files: CoreFileEntry[] = value.online || []; let files: CoreFileEntry[] = value.online || [];
const offlineFiles = value.offline const offlineFiles = value.offline

View File

@ -277,7 +277,10 @@ export class CoreUtilsProvider {
return source; return source;
} }
if (Array.isArray(source)) { if (this.valueIsFileEntry(source)) {
// Don't clone FileEntry. It has a lot of depth and they shouldn't be modified.
return source;
} else if (Array.isArray(source)) {
// Clone the array and all the entries. // Clone the array and all the entries.
const newArray = [] as unknown as T; const newArray = [] as unknown as T;
for (let i = 0; i < source.length; i++) { for (let i = 0; i < source.length; i++) {
@ -750,6 +753,18 @@ export class CoreUtilsProvider {
return 'isFile' in file; return 'isFile' in file;
} }
/**
* Check if an unknown value is a FileEntry.
*
* @param value Value to check.
* @return Type guard indicating if the file is a FileEntry.
*/
valueIsFileEntry(file: unknown): file is FileEntry {
// We cannot use instanceof because FileEntry is a type. Check some of the properties.
return !!(file && typeof file == 'object' && 'isFile' in file && 'filesystem' in file &&
'toInternalURL' in file && 'copyTo' in file);
}
/** /**
* Check if a value is an object. * Check if a value is an object.
* *