MOBILE-3817 filter: Apply update in background to filters
parent
01df501cad
commit
979e995166
|
@ -2409,7 +2409,7 @@ export function chainRequests<T, O extends ObservableInput<any>>(
|
||||||
|
|
||||||
return source.subscribe({
|
return source.subscribe({
|
||||||
next: async (value) => {
|
next: async (value) => {
|
||||||
if (readingStrategy !== CoreSitesReadingStrategy.UPDATE_IN_BACKGROUND) {
|
if (readingStrategy !== CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE) {
|
||||||
// Just use same strategy.
|
// Just use same strategy.
|
||||||
subscriber.next({ data: value, readingStrategy });
|
subscriber.next({ data: value, readingStrategy });
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-pr
|
||||||
import { SQLiteDB } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreTime } from '@singletons/time';
|
import { CoreTime } from '@singletons/time';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { asyncObservable, firstValueFrom } from '@/core/utils/rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
const ROOT_CACHE_KEY = 'mmCourse:';
|
const ROOT_CACHE_KEY = 'mmCourse:';
|
||||||
|
|
||||||
|
@ -402,19 +405,36 @@ export class CoreCourseProvider {
|
||||||
* @return Promise resolved with the list of blocks.
|
* @return Promise resolved with the list of blocks.
|
||||||
* @since 3.7
|
* @since 3.7
|
||||||
*/
|
*/
|
||||||
async getCourseBlocks(courseId: number, siteId?: string): Promise<CoreCourseBlock[]> {
|
getCourseBlocks(courseId: number, siteId?: string): Promise<CoreCourseBlock[]> {
|
||||||
const site = await CoreSites.getSite(siteId);
|
return firstValueFrom(this.getCourseBlocksObservable(courseId, { siteId }));
|
||||||
const params: CoreBlockGetCourseBlocksWSParams = {
|
}
|
||||||
courseid: courseId,
|
|
||||||
returncontents: true,
|
|
||||||
};
|
|
||||||
const preSets: CoreSiteWSPreSets = {
|
|
||||||
cacheKey: this.getCourseBlocksCacheKey(courseId),
|
|
||||||
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
|
||||||
};
|
|
||||||
const result = await site.read<CoreCourseBlocksWSResponse>('core_block_get_course_blocks', params, preSets);
|
|
||||||
|
|
||||||
return result.blocks || [];
|
/**
|
||||||
|
* Get course blocks.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @param options Options.
|
||||||
|
* @return Observable that returns the blocks.
|
||||||
|
* @since 3.7
|
||||||
|
*/
|
||||||
|
getCourseBlocksObservable(courseId: number, options: CoreSitesCommonWSOptions = {}): Observable<CoreCourseBlock[]> {
|
||||||
|
return asyncObservable(async () => {
|
||||||
|
const site = await CoreSites.getSite(options.siteId);
|
||||||
|
|
||||||
|
const params: CoreBlockGetCourseBlocksWSParams = {
|
||||||
|
courseid: courseId,
|
||||||
|
returncontents: true,
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getCourseBlocksCacheKey(courseId),
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
|
||||||
|
};
|
||||||
|
|
||||||
|
return site.readObservable<CoreCourseBlocksWSResponse>('core_block_get_course_blocks', params, preSets).pipe(
|
||||||
|
map(result => result.blocks),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -908,7 +928,7 @@ export class CoreCourseProvider {
|
||||||
* @param includeStealthModules Whether to include stealth modules. Defaults to true.
|
* @param includeStealthModules Whether to include stealth modules. Defaults to true.
|
||||||
* @return The reject contains the error message, else contains the sections.
|
* @return The reject contains the error message, else contains the sections.
|
||||||
*/
|
*/
|
||||||
async getSections(
|
getSections(
|
||||||
courseId: number,
|
courseId: number,
|
||||||
excludeModules: boolean = false,
|
excludeModules: boolean = false,
|
||||||
excludeContents: boolean = false,
|
excludeContents: boolean = false,
|
||||||
|
@ -916,63 +936,83 @@ export class CoreCourseProvider {
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
includeStealthModules: boolean = true,
|
includeStealthModules: boolean = true,
|
||||||
): Promise<CoreCourseWSSection[]> {
|
): Promise<CoreCourseWSSection[]> {
|
||||||
|
return firstValueFrom(this.getSectionsObservable(courseId, {
|
||||||
const site = await CoreSites.getSite(siteId);
|
excludeModules,
|
||||||
preSets = preSets || {};
|
excludeContents,
|
||||||
preSets.cacheKey = this.getSectionsCacheKey(courseId);
|
includeStealthModules,
|
||||||
preSets.updateFrequency = preSets.updateFrequency || CoreSite.FREQUENCY_RARELY;
|
preSets,
|
||||||
|
siteId,
|
||||||
const params: CoreCourseGetContentsParams = {
|
|
||||||
courseid: courseId,
|
|
||||||
};
|
|
||||||
params.options = [
|
|
||||||
{
|
|
||||||
name: 'excludemodules',
|
|
||||||
value: excludeModules,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'excludecontents',
|
|
||||||
value: excludeContents,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (this.canRequestStealthModules(site)) {
|
|
||||||
params.options.push({
|
|
||||||
name: 'includestealthmodules',
|
|
||||||
value: includeStealthModules,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let sections: CoreCourseGetContentsWSSection[];
|
|
||||||
try {
|
|
||||||
sections = await site.read('core_course_get_contents', params, preSets);
|
|
||||||
} catch {
|
|
||||||
// Error getting the data, it could fail because we added a new parameter and the call isn't cached.
|
|
||||||
// Retry without the new parameter and forcing cache.
|
|
||||||
preSets.omitExpires = true;
|
|
||||||
params.options.splice(-1, 1);
|
|
||||||
sections = await site.read('core_course_get_contents', params, preSets);
|
|
||||||
}
|
|
||||||
|
|
||||||
const siteHomeId = site.getSiteHomeId();
|
|
||||||
let showSections = true;
|
|
||||||
if (courseId == siteHomeId) {
|
|
||||||
const storedNumSections = site.getStoredConfig('numsections');
|
|
||||||
showSections = storedNumSections !== undefined && !!storedNumSections;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showSections !== undefined && !showSections && sections.length > 0) {
|
|
||||||
// Get only the last section (Main menu block section).
|
|
||||||
sections.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add course to all modules.
|
|
||||||
return sections.map((section) => ({
|
|
||||||
...section,
|
|
||||||
modules: section.modules.map((module) => this.addAdditionalModuleData(module, courseId, section.id)),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the course sections.
|
||||||
|
*
|
||||||
|
* @param courseId The course ID.
|
||||||
|
* @param options Options.
|
||||||
|
* @return Observable that returns the sections.
|
||||||
|
*/
|
||||||
|
getSectionsObservable(
|
||||||
|
courseId: number,
|
||||||
|
options: CoreCourseGetSectionsOptions = {},
|
||||||
|
): Observable<CoreCourseWSSection[]> {
|
||||||
|
options.includeStealthModules = options.includeStealthModules ?? true;
|
||||||
|
|
||||||
|
return asyncObservable(async () => {
|
||||||
|
const site = await CoreSites.getSite(options.siteId);
|
||||||
|
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
...options.preSets,
|
||||||
|
cacheKey: this.getSectionsCacheKey(courseId),
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
|
||||||
|
};
|
||||||
|
|
||||||
|
const params: CoreCourseGetContentsParams = {
|
||||||
|
courseid: courseId,
|
||||||
|
};
|
||||||
|
params.options = [
|
||||||
|
{
|
||||||
|
name: 'excludemodules',
|
||||||
|
value: !!options.excludeModules,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'excludecontents',
|
||||||
|
value: !!options.excludeContents,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (this.canRequestStealthModules(site)) {
|
||||||
|
params.options.push({
|
||||||
|
name: 'includestealthmodules',
|
||||||
|
value: !!options.includeStealthModules,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return site.readObservable<CoreCourseGetContentsWSSection[]>('core_course_get_contents', params, preSets).pipe(
|
||||||
|
map(sections => {
|
||||||
|
const siteHomeId = site.getSiteHomeId();
|
||||||
|
let showSections = true;
|
||||||
|
if (courseId == siteHomeId) {
|
||||||
|
const storedNumSections = site.getStoredConfig('numsections');
|
||||||
|
showSections = storedNumSections !== undefined && !!storedNumSections;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSections !== undefined && !showSections && sections.length > 0) {
|
||||||
|
// Get only the last section (Main menu block section).
|
||||||
|
sections.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add course to all modules.
|
||||||
|
return sections.map((section) => ({
|
||||||
|
...section,
|
||||||
|
modules: section.modules.map((module) => this.addAdditionalModuleData(module, courseId, section.id)),
|
||||||
|
}));
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get cache key for section WS call.
|
* Get cache key for section WS call.
|
||||||
*
|
*
|
||||||
|
@ -1933,3 +1973,13 @@ export type CoreCourseStoreModuleViewedOptions = {
|
||||||
timeaccess?: number;
|
timeaccess?: number;
|
||||||
siteId?: string;
|
siteId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for getSections.
|
||||||
|
*/
|
||||||
|
export type CoreCourseGetSectionsOptions = CoreSitesCommonWSOptions & {
|
||||||
|
excludeModules?: boolean;
|
||||||
|
excludeContents?: boolean;
|
||||||
|
includeStealthModules?: boolean; // Defaults to true.
|
||||||
|
preSets?: CoreSiteWSPreSets;
|
||||||
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||||
import { CoreFilterDelegate } from './filter-delegate';
|
import { CoreFilterDelegate } from './filter-delegate';
|
||||||
import {
|
import {
|
||||||
CoreFilter,
|
CoreFilter,
|
||||||
|
@ -31,6 +31,7 @@ import { CoreEvents, CoreEventSiteData } from '@singletons/events';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreSite } from '@classes/site';
|
import { CoreSite } from '@classes/site';
|
||||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||||
|
import { firstValueFrom } from '@/core/utils/rxjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper service to provide filter functionalities.
|
* Helper service to provide filter functionalities.
|
||||||
|
@ -75,7 +76,11 @@ export class CoreFilterHelperProvider {
|
||||||
* @return Promise resolved with the contexts.
|
* @return Promise resolved with the contexts.
|
||||||
*/
|
*/
|
||||||
async getBlocksContexts(courseId: number, siteId?: string): Promise<CoreFiltersGetAvailableInContextWSParamContext[]> {
|
async getBlocksContexts(courseId: number, siteId?: string): Promise<CoreFiltersGetAvailableInContextWSParamContext[]> {
|
||||||
const blocks = await CoreCourse.getCourseBlocks(courseId, siteId);
|
// Use stale while revalidate, but always use the first value. If data is updated it will be stored in DB.
|
||||||
|
const blocks = await firstValueFrom(CoreCourse.getCourseBlocksObservable(courseId, {
|
||||||
|
readingStrategy: CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE,
|
||||||
|
siteId,
|
||||||
|
}));
|
||||||
|
|
||||||
const contexts: CoreFiltersGetAvailableInContextWSParamContext[] = [];
|
const contexts: CoreFiltersGetAvailableInContextWSParamContext[] = [];
|
||||||
|
|
||||||
|
@ -153,7 +158,12 @@ export class CoreFilterHelperProvider {
|
||||||
* @return Promise resolved with the contexts.
|
* @return Promise resolved with the contexts.
|
||||||
*/
|
*/
|
||||||
async getCourseModulesContexts(courseId: number, siteId?: string): Promise<CoreFiltersGetAvailableInContextWSParamContext[]> {
|
async getCourseModulesContexts(courseId: number, siteId?: string): Promise<CoreFiltersGetAvailableInContextWSParamContext[]> {
|
||||||
const sections = await CoreCourse.getSections(courseId, false, true, undefined, siteId);
|
// Use stale while revalidate, but always use the first value. If data is updated it will be stored in DB.
|
||||||
|
const sections = await firstValueFrom(CoreCourse.getSectionsObservable(courseId, {
|
||||||
|
excludeContents: true,
|
||||||
|
readingStrategy: CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE,
|
||||||
|
siteId,
|
||||||
|
}));
|
||||||
|
|
||||||
const contexts: CoreFiltersGetAvailableInContextWSParamContext[] = [];
|
const contexts: CoreFiltersGetAvailableInContextWSParamContext[] = [];
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||||
import { CoreSite } from '@classes/site';
|
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
import { CoreWSExternalWarning } from '@services/ws';
|
import { CoreWSExternalWarning } from '@services/ws';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreFilterDelegate } from './filter-delegate';
|
import { CoreFilterDelegate } from './filter-delegate';
|
||||||
|
@ -284,13 +284,15 @@ export class CoreFilterProvider {
|
||||||
const data: CoreFiltersGetAvailableInContextWSParams = {
|
const data: CoreFiltersGetAvailableInContextWSParams = {
|
||||||
contexts: contextsToSend,
|
contexts: contextsToSend,
|
||||||
};
|
};
|
||||||
const preSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getAvailableInContextsCacheKey(contextsToSend),
|
cacheKey: this.getAvailableInContextsCacheKey(contextsToSend),
|
||||||
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
splitRequest: {
|
splitRequest: {
|
||||||
param: 'contexts',
|
param: 'contexts',
|
||||||
maxLength: 300,
|
maxLength: 300,
|
||||||
},
|
},
|
||||||
|
// Use stale while revalidate, but always use the first value. If data is updated it will be stored in DB.
|
||||||
|
...CoreSites.getReadingStrategyPreSets(CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE),
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await site.read<CoreFilterGetAvailableInContextResult>(
|
const result = await site.read<CoreFilterGetAvailableInContextResult>(
|
||||||
|
|
|
@ -1796,7 +1796,7 @@ export class CoreSitesProvider {
|
||||||
getFromCache: false,
|
getFromCache: false,
|
||||||
emergencyCache: false,
|
emergencyCache: false,
|
||||||
};
|
};
|
||||||
case CoreSitesReadingStrategy.UPDATE_IN_BACKGROUND:
|
case CoreSitesReadingStrategy.STALE_WHILE_REVALIDATE:
|
||||||
return {
|
return {
|
||||||
updateInBackground: true,
|
updateInBackground: true,
|
||||||
getFromCache: true,
|
getFromCache: true,
|
||||||
|
@ -2023,7 +2023,7 @@ export const enum CoreSitesReadingStrategy {
|
||||||
PREFER_CACHE,
|
PREFER_CACHE,
|
||||||
ONLY_NETWORK,
|
ONLY_NETWORK,
|
||||||
PREFER_NETWORK,
|
PREFER_NETWORK,
|
||||||
UPDATE_IN_BACKGROUND,
|
STALE_WHILE_REVALIDATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue