Merge pull request #2999 from crazyserver/MOBILE-3914

Mobile 3914
main
Dani Palou 2021-11-17 11:12:59 +01:00 committed by GitHub
commit fb909f63a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 62 deletions

View File

@ -1,3 +1,3 @@
<ion-button (click)="openBlocks()" [attr.aria-label]="'core.block.opendrawerblocks' | translate">
<ion-icon name="fas-cubes" slot="icon-only" aria-hidden="true"></ion-icon>
<ion-icon name="fas-chevron-left" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>

View File

@ -20,7 +20,7 @@
</ng-container>
</ion-list>
<core-empty-box *ngIf="blocks.length == 0" icon="fas-cubes" [message]="'core.block.noblocks' | translate">
<core-empty-box *ngIf="blocks.length == 0" icon="fas-th-large" [message]="'core.block.noblocks' | translate">
</core-empty-box>
</core-loading>
</ion-content>

View File

@ -1 +1,4 @@
<core-dynamic-component [component]="componentClass" [data]="data"></core-dynamic-component>
<core-block-side-blocks-button *ngIf="course && hasBlocks" [courseId]="course.id" [downloadEnabled]="downloadEnabled">
</core-block-side-blocks-button>

View File

@ -20,6 +20,8 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { IonRefresher } from '@ionic/angular';
import { CoreCourseModuleCompletionData, CoreCourseSectionWithStatus } from '@features/course/services/course-helper';
import { CoreBlockHelper } from '@features/block/services/block-helper';
import { CoreCourse } from '@features/course/services/course';
/**
* Component to display single activity format. It will determine the right component to use and instantiate it.
@ -44,12 +46,13 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
componentClass?: Type<unknown>; // The class of the component to render.
data: Record<string | number, unknown> = {}; // Data to pass to the component.
hasBlocks = false;
/**
* Detect changes on input properties.
* @inheritdoc
*/
async ngOnChanges(changes: { [name: string]: SimpleChange }): Promise<void> {
if (!changes.course || !changes.sections) {
if (!changes.course && !changes.sections) {
return;
}
@ -57,6 +60,8 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
return;
}
this.hasBlocks = await CoreBlockHelper.hasCourseBlocks(this.course.id);
// In single activity the module should only have 1 section and 1 module. Get the module.
const module = this.sections?.[0].modules?.[0];
@ -85,6 +90,15 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
}
await this.dynamicComponent?.callComponentFunction('doRefresh', [refresher, done]);
if (this.course) {
const courseId = this.course.id;
await CoreCourse.invalidateCourseBlocks(courseId).then(async () => {
this.hasBlocks = await CoreBlockHelper.hasCourseBlocks(courseId);
return;
});
}
}
/**

View File

@ -31,43 +31,28 @@ export class CoreCourseFormatSingleActivityHandlerService implements CoreCourseF
format = 'singleactivity';
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* Whether it allows seeing all sections at the same time. Defaults to true.
*
* @param course The course to check.
* @return Whether it can view all sections.
* @inheritdoc
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
canViewAllSections(course: CoreCourseAnyCourseData): boolean {
canViewAllSections(): boolean {
return false;
}
/**
* Whether the option blocks should be displayed. Defaults to true.
*
* @param course The course to check.
* @return Whether it can display blocks.
* @inheritdoc
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
displayBlocks(course: CoreCourseAnyCourseData): boolean {
return false;
displayBlocks(): boolean {
return true;
}
/**
* Get the title to use in course page. If not defined, course displayname or fullname.
* This function will be called without sections first, and then call it again when the sections are retrieved.
*
* @param course The course.
* @param sections List of sections.
* @return Title.
* @inheritdoc
*/
getCourseTitle(course: CoreCourseAnyCourseData, sections?: CoreCourseWSSection[]): string {
if (sections?.[0]?.modules?.[0]) {
@ -84,34 +69,21 @@ export class CoreCourseFormatSingleActivityHandlerService implements CoreCourseF
}
/**
* Whether the option to enable section/module download should be displayed. Defaults to true.
*
* @param course The course to check.
* @return Whether the option to enable section/module download should be displayed
* @inheritdoc
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
displayEnableDownload(course: CoreCourseAnyCourseData): boolean {
displayEnableDownload(): boolean {
return false;
}
/**
* Whether the default section selector should be displayed. Defaults to true.
*
* @param course The course to check.
* @return Whether the default section selector should be displayed.
* @inheritdoc
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
displaySectionSelector(course: CoreCourseAnyCourseData): boolean {
displaySectionSelector(): boolean {
return false;
}
/**
* Whether the course refresher should be displayed. If it returns false, a refresher must be included in the course format,
* and the doRefresh method of CoreCourseSectionPage must be called on refresh. Defaults to true.
*
* @param course The course to check.
* @param sections List of course sections.
* @return Whether the refresher should be displayed.
* @inheritdoc
*/
displayRefresher(course: CoreCourseAnyCourseData, sections: CoreCourseWSSection[]): boolean {
if (sections?.[0]?.modules?.[0]) {
@ -122,28 +94,16 @@ export class CoreCourseFormatSingleActivityHandlerService implements CoreCourseF
}
/**
* Return the Component to use to display the course format instead of using the default one.
* Use it if you want to display a format completely different from the default one.
* If you want to customize the default format there are several methods to customize parts of it.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param course The course to render.
* @return The component (or promise resolved with component) to use, undefined if not found.
* @inheritdoc
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async getCourseFormatComponent(course: CoreCourseAnyCourseData): Promise<Type<unknown>> {
async getCourseFormatComponent(): Promise<Type<unknown>> {
return CoreCourseFormatSingleActivityComponent;
}
/**
* Whether the view should be refreshed when completion changes. If your course format doesn't display
* activity completion then you should return false.
*
* @param course The course.
* @return Whether course view should be refreshed when an activity completion changes.
* @inheritdoc
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async shouldRefreshWhenCompletionChanges(course: CoreCourseAnyCourseData): Promise<boolean> {
async shouldRefreshWhenCompletionChanges(): Promise<boolean> {
return false;
}

View File

@ -18,6 +18,7 @@ import { CoreSharedModule } from '@/core/shared.module';
import { CoreCourseFormatDelegate } from '@features/course/services/format-delegate';
import { CoreCourseFormatSingleActivityComponent } from './components/singleactivity';
import { CoreCourseFormatSingleActivityHandler } from './services/handlers/singleactivity-format';
import { CoreBlockComponentsModule } from '@features/block/components/components.module';
@NgModule({
declarations: [
@ -25,6 +26,7 @@ import { CoreCourseFormatSingleActivityHandler } from './services/handlers/singl
],
imports: [
CoreSharedModule,
CoreBlockComponentsModule,
],
providers: [
{

View File

@ -183,8 +183,13 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
return;
}
const numItems = CoreMainMenu.getNumItems();
this.moreBadge = this.allHandlers.some((handler, index) => (handler.onlyInMore || index >= numItems) && !!handler.badge);
// Calculate the main handlers not to display them in this view.
const mainHandlers = this.allHandlers
.filter((handler) => !handler.onlyInMore)
.slice(0, CoreMainMenu.getNumItems());
// Use only the handlers that don't appear in the main view.
this.moreBadge = this.allHandlers.some((handler) => mainHandlers.indexOf(handler) == -1 && !!handler.badge);
}
/**