Merge pull request #3014 from crazyserver/MOBILE-3940

MOBILE-3940 my: Use new mypage param when retrieving dashboard blocks
main
Dani Palou 2021-12-03 14:39:52 +01:00 committed by GitHub
commit ad321c1fbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 108 additions and 55 deletions

View File

@ -19,7 +19,7 @@ import { CoreCourses } from '@features/courses/services/courses';
import { AddonBlockTimelineComponent } from '@addons/block/timeline/components/timeline/timeline';
import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler';
import { makeSingleton } from '@singletons';
import { AddonBlockTimeline } from './timeline';
import { CoreCoursesDashboard } from '@features/courses/services/dashboard';
/**
* Block handler.
@ -36,7 +36,7 @@ export class AddonBlockTimelineHandlerService extends CoreBlockBaseHandler {
* @return Whether or not the handler is enabled on a site level.
*/
async isEnabled(): Promise<boolean> {
const enabled = await AddonBlockTimeline.isAvailable();
const enabled = !CoreCoursesDashboard.isDisabledInSite();
const currentSite = CoreSites.getCurrentSite();
return enabled && ((currentSite && currentSite.isVersionGreaterEqualThan('3.6')) ||

View File

@ -14,7 +14,6 @@
import { Injectable } from '@angular/core';
import { CoreSites } from '@services/sites';
import { CoreCoursesDashboard } from '@features/courses/services/dashboard';
import {
AddonCalendarEvents,
AddonCalendarEventsGroupedByCourse,
@ -251,19 +250,6 @@ export class AddonBlockTimelineProvider {
await site.invalidateWsCacheForKeyStartingWith(this.getActionEventsByTimesortPrefixCacheKey());
}
/**
* Returns whether or not My Overview is available for a certain site.
*
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with true if available, resolved with false or rejected otherwise.
*/
async isAvailable(siteId?: string): Promise<boolean> {
const site = await CoreSites.getSite(siteId);
// Check if dashboard is disabled.
return !CoreCoursesDashboard.isDisabledInSite(site);
}
/**
* Handles course events, filtering and treating if more can be loaded.
*

View File

@ -85,8 +85,9 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy {
*/
protected async loadContent(): Promise<void> {
const available = await CoreCoursesDashboard.isAvailable();
const disabled = await CoreCoursesDashboard.isDisabled();
if (available) {
if (available && !disabled) {
this.userId = CoreSites.getCurrentSiteUserId();
try {
@ -101,7 +102,7 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy {
// Cannot get the blocks, just show dashboard if needed.
this.loadFallbackBlocks();
}
} else if (!CoreCoursesDashboard.isDisabledInSite()) {
} else if (!available) {
// Not available, but not disabled either. Use fallback.
this.loadFallbackBlocks();
} else {

View File

@ -26,13 +26,16 @@
</ion-toolbar>
</ion-header>
<ion-content>
<ion-refresher slot="fixed" (ionRefresh)="refresh($event.target)">
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refresh($event.target)">
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="loaded">
<ion-list>
<!-- My courses blocks. -->
<core-block [block]="{name: 'myoverview', visible: true}" contextLevel="user" [instanceId]="userId"
[extraData]="{'downloadEnabled': true}">
</core-block>
<core-block *ngIf="loadedBlock?.visible" [block]="loadedBlock" contextLevel="user" [instanceId]="userId"
[extraData]="{'downloadEnabled': true}"></core-block>
</ion-list>
<core-empty-box *ngIf="!loadedBlock" icon="fas-cubes" [message]="'core.course.nocontentavailable' | translate">
</core-empty-box>
</core-loading>
</ion-content>

View File

@ -15,6 +15,8 @@
import { AddonBlockMyOverviewComponent } from '@addons/block/myoverview/components/myoverview/myoverview';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { CoreBlockComponent } from '@features/block/components/block/block';
import { CoreCourseBlock } from '@features/course/services/course';
import { CoreCoursesDashboard, CoreCoursesDashboardProvider } from '@features/courses/services/dashboard';
import { IonRefresher } from '@ionic/angular';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
@ -37,7 +39,9 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
searchEnabled = false;
downloadCoursesEnabled = false;
userId: number;
loadedBlock?: Partial<CoreCourseBlock>;
myOverviewBlock?: AddonBlockMyOverviewComponent;
loaded = false;
protected updateSiteObserver: CoreEventObserver;
@ -58,21 +62,49 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
this.loadBlock();
this.loadContent();
}
/**
* Load my overview block instance.
*/
protected loadBlock(): void {
setTimeout(() => {
if (!this.block) {
return this.loadBlock();
}
protected async loadContent(): Promise<void> {
const available = await CoreCoursesDashboard.isAvailable();
const disabled = await CoreCourses.isMyCoursesDisabled();
if (available && !disabled) {
try {
const blocks = await CoreCoursesDashboard.getDashboardBlocksFromWS(CoreCoursesDashboardProvider.MY_PAGE_COURSES);
this.loadedBlock = blocks.find((block) => block.name == 'myoverview');
await CoreUtils.nextTicks(2);
this.myOverviewBlock = this.block?.dynamicComponent?.instance as AddonBlockMyOverviewComponent;
}, 500);
} catch {
// Cannot get the blocks, just show the block if needed.
this.loadFallbackBlock();
}
} else if (!available) {
// WS not available, or my courses page not available. show fallback block.
this.loadFallbackBlock();
} else {
// Disabled.
this.loadedBlock = undefined;
}
this.loaded = true;
}
/**
* Load fallback blocks.
*/
protected loadFallbackBlock(): void {
this.loadedBlock = {
name: 'myoverview',
visible: true,
};
}
/**
@ -95,11 +127,21 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
* @param refresher Refresher.
*/
async refresh(refresher?: IonRefresher): Promise<void> {
if (this.block) {
await CoreUtils.ignoreErrors(this.block.doRefresh());
const promises: Promise<void>[] = [];
promises.push(CoreCoursesDashboard.invalidateDashboardBlocks(CoreCoursesDashboardProvider.MY_PAGE_COURSES));
// Invalidate the blocks.
if (this.myOverviewBlock) {
promises.push(CoreUtils.ignoreErrors(this.myOverviewBlock.doRefresh()));
}
Promise.all(promises).finally(() => {
this.loadContent().finally(() => {
refresher?.complete();
});
});
}
/**

View File

@ -18,6 +18,7 @@ import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
import { CoreCourseBlock } from '@features/course/services/course';
import { CoreStatusWithWarningsWSResponse } from '@services/ws';
import { makeSingleton } from '@singletons';
import { CoreError } from '@classes/errors/error';
const ROOT_CACHE_KEY = 'CoreCoursesDashboard:';
@ -27,32 +28,47 @@ const ROOT_CACHE_KEY = 'CoreCoursesDashboard:';
@Injectable({ providedIn: 'root' })
export class CoreCoursesDashboardProvider {
static readonly MY_PAGE_DEFAULT = '__default';
static readonly MY_PAGE_COURSES = '__courses';
/**
* Get cache key for dashboard blocks WS calls.
*
* @param myPage What my page to return blocks of. Default MY_PAGE_DEFAULT.
* @param userId User ID. Default, 0 means current user.
* @return Cache key.
*/
protected getDashboardBlocksCacheKey(userId: number = 0): string {
return ROOT_CACHE_KEY + 'blocks:' + userId;
protected getDashboardBlocksCacheKey(myPage = CoreCoursesDashboardProvider.MY_PAGE_DEFAULT, userId: number = 0): string {
return ROOT_CACHE_KEY + 'blocks:' + myPage + ':' + userId;
}
/**
* Get dashboard blocks from WS.
*
* @param myPage What my page to return blocks of. Default MY_PAGE_DEFAULT.
* @param userId User ID. Default, current user.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the list of blocks.
* @since 3.6
*/
protected async getDashboardBlocksFromWS(userId?: number, siteId?: string): Promise<CoreCourseBlock[]> {
async getDashboardBlocksFromWS(
myPage = CoreCoursesDashboardProvider.MY_PAGE_DEFAULT,
userId?: number,
siteId?: string,
): Promise<CoreCourseBlock[]> {
const site = await CoreSites.getSite(siteId);
const params: CoreBlockGetDashboardBlocksWSParams = {
returncontents: true,
};
if (CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('4.0')) {
params.mypage = myPage;
} else if (myPage != CoreCoursesDashboardProvider.MY_PAGE_DEFAULT) {
throw new CoreError('mypage param is no accessible on core_block_get_dashboard_blocks');
}
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getDashboardBlocksCacheKey(userId),
cacheKey: this.getDashboardBlocksCacheKey(myPage, userId),
updateFrequency: CoreSite.FREQUENCY_RARELY,
};
if (userId) {
@ -71,7 +87,7 @@ export class CoreCoursesDashboardProvider {
* @return Promise resolved with the list of blocks.
*/
async getDashboardBlocks(userId?: number, siteId?: string): Promise<CoreCoursesDashboardBlocks> {
const blocks = await CoreCoursesDashboard.getDashboardBlocksFromWS(userId, siteId);
const blocks = await this.getDashboardBlocksFromWS(CoreCoursesDashboardProvider.MY_PAGE_DEFAULT, userId, siteId);
let mainBlocks: CoreCourseBlock[] = [];
let sideBlocks: CoreCourseBlock[] = [];
@ -104,14 +120,19 @@ export class CoreCoursesDashboardProvider {
/**
* Invalidates dashboard blocks WS call.
*
* @param myPage What my page to return blocks of. Default MY_PAGE_DEFAULT.
* @param userId User ID. Default, current user.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when the data is invalidated.
*/
async invalidateDashboardBlocks(userId?: number, siteId?: string): Promise<void> {
async invalidateDashboardBlocks(
myPage = CoreCoursesDashboardProvider.MY_PAGE_DEFAULT,
userId?: number,
siteId?: string,
): Promise<void> {
const site = await CoreSites.getSite(siteId);
return await site.invalidateWsCacheForKey(this.getDashboardBlocksCacheKey(userId));
return await site.invalidateWsCacheForKey(this.getDashboardBlocksCacheKey(myPage, userId));
}
/**
@ -124,11 +145,6 @@ export class CoreCoursesDashboardProvider {
async isAvailable(siteId?: string): Promise<boolean> {
const site = await CoreSites.getSite(siteId);
// First check if it's disabled.
if (this.isDisabledInSite(site)) {
return false;
}
return site.wsAvailable('core_block_get_dashboard_blocks');
}
@ -171,6 +187,7 @@ export type CoreCoursesDashboardBlocks = {
type CoreBlockGetDashboardBlocksWSParams = {
userid?: number; // User id (optional), default is current user.
returncontents?: boolean; // Whether to return the block contents.
mypage?: string; // @since 4.0. What my page to return blocks of. Default MY_PAGE_DEFAULT.
};
/**

View File

@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { AddonBlockTimeline } from '@addons/block/timeline/services/timeline';
import { Injectable } from '@angular/core';
import { CoreBlockDelegate } from '@features/block/services/block-delegate';
import { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerToDisplay } from '@features/mainmenu/services/home-delegate';
@ -49,6 +48,7 @@ export class CoreDashboardHomeHandlerService implements CoreMainMenuHomeHandler
const promises: Promise<void>[] = [];
let blocksEnabled = false;
let dashboardAvailable = false;
let dashboardEnabled = false;
// Check if blocks and 3.6 dashboard is enabled.
promises.push(CoreBlockDelegate.areBlocksDisabled(siteId).then((disabled) => {
@ -57,7 +57,13 @@ export class CoreDashboardHomeHandlerService implements CoreMainMenuHomeHandler
return;
}));
promises.push(CoreCoursesDashboard.isAvailable().then((available) => {
promises.push(CoreCoursesDashboard.isDisabled(siteId).then((disabled) => {
dashboardEnabled = !disabled;
return;
}));
promises.push(CoreCoursesDashboard.isAvailable(siteId).then((available) => {
dashboardAvailable = available;
return;
@ -65,16 +71,14 @@ export class CoreDashboardHomeHandlerService implements CoreMainMenuHomeHandler
await Promise.all(promises);
if (dashboardAvailable && blocksEnabled) {
if (dashboardAvailable && dashboardEnabled && blocksEnabled) {
const blocks = await CoreCoursesDashboard.getDashboardBlocks(undefined, siteId);
return CoreBlockDelegate.hasSupportedBlock(blocks.mainBlocks) || CoreBlockDelegate.hasSupportedBlock(blocks.sideBlocks);
}
// Check if my overview is enabled. If it's enabled we will fake enabled blocks.
const timelineEnabled = await AddonBlockTimeline.isAvailable();
return timelineEnabled && blocksEnabled;
// Dashboard is enabled but not available, we will fake blocks.
return dashboardEnabled && blocksEnabled;
}
/**