MOBILE-1486 course: Log view when course is viewed

main
Pau Ferrer Ocaña 2018-11-16 10:55:32 +01:00
parent dbf3c85f73
commit cfb6ac4f86
7 changed files with 124 additions and 24 deletions

View File

@ -66,18 +66,21 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges {
* Set fields from user.
*/
protected setFields(): void {
if (this.user) {
this.profileUrl = this.profileUrl || this.user.profileimageurl || this.user.userprofileimageurl ||
this.user.userpictureurl || this.user.profileimageurlsmall;
this.profileUrl = this.profileUrl || (this.user && (this.user.profileimageurl || this.user.userprofileimageurl ||
this.user.userpictureurl || this.user.profileimageurlsmall));
this.fullname = this.fullname || this.user.fullname || this.user.userfullname;
this.userId = this.userId || this.user.userid;
this.courseId = this.courseId || this.user.courseid;
// If not available we cannot ensure the avatar is from the current user.
this.myUser = this.userId && this.userId == this.currentUserId;
if (typeof this.profileUrl != 'string') {
this.profileUrl = '';
}
this.fullname = this.fullname || (this.user && (this.user.fullname || this.user.userfullname));
this.userId = this.userId || (this.user && this.user.userid);
this.courseId = this.courseId || (this.user && this.user.courseid);
// If not available we cannot ensure the avatar is from the current user.
this.myUser = this.userId && this.userId == this.currentUserId;
}
/**
@ -95,7 +98,6 @@ export class CoreUserAvatarComponent implements OnInit, OnChanges {
* Function executed image clicked.
*/
gotoProfile(event: any): void {
// If the event prevented default action, do nothing.
if (this.linkProfile && this.userId) {
event.preventDefault();
event.stopPropagation();

View File

@ -13,7 +13,9 @@
// limitations under the License.
import { NgModule } from '@angular/core';
import { Platform } from 'ionic-angular';
import { CoreCronDelegate } from '@providers/cron';
import { CoreEventsProvider } from '@providers/events';
import { CoreCourseProvider } from './providers/course';
import { CoreCourseHelperProvider } from './providers/helper';
import { CoreCourseFormatDelegate } from './providers/format-delegate';
@ -29,6 +31,7 @@ import { CoreCourseFormatTopicsModule } from './formats/topics/topics.module';
import { CoreCourseFormatWeeksModule } from './formats/weeks/weeks.module';
import { CoreCourseSyncProvider } from './providers/sync';
import { CoreCourseSyncCronHandler } from './providers/sync-cron-handler';
import { CoreCourseLogCronHandler } from './providers/log-cron-handler';
// List of providers (without handlers).
export const CORE_COURSE_PROVIDERS: any[] = [
@ -61,12 +64,29 @@ export const CORE_COURSE_PROVIDERS: any[] = [
CoreCourseSyncProvider,
CoreCourseFormatDefaultHandler,
CoreCourseModuleDefaultHandler,
CoreCourseSyncCronHandler
CoreCourseSyncCronHandler,
CoreCourseLogCronHandler
],
exports: []
})
export class CoreCourseModule {
constructor(cronDelegate: CoreCronDelegate, syncHandler: CoreCourseSyncCronHandler) {
constructor(cronDelegate: CoreCronDelegate, syncHandler: CoreCourseSyncCronHandler, logHandler: CoreCourseLogCronHandler,
platform: Platform, eventsProvider: CoreEventsProvider) {
cronDelegate.register(syncHandler);
cronDelegate.register(logHandler);
platform.resume.subscribe(() => {
// Log the app is open to keep user in online status.
setTimeout(() => {
cronDelegate.forceCronHandlerExecution(logHandler.name);
}, 1000);
});
eventsProvider.on(CoreEventsProvider.LOGIN, () => {
// Log the app is open to keep user in online status.
setTimeout(() => {
cronDelegate.forceCronHandlerExecution(logHandler.name);
}, 1000);
});
}
}

View File

@ -202,6 +202,11 @@ export class CoreCourseSectionPage implements OnDestroy {
}).then((sections) => {
let promise;
// Add log in Moodle.
this.courseProvider.logView(this.course.id, this.sectionNumber).catch(() => {
// Ignore errors.
});
// Get the completion status.
if (this.course.enablecompletion === false) {
// Completion not enabled.

View File

@ -0,0 +1,59 @@
// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreCronHandler } from '@providers/cron';
import { CoreSitesProvider } from '@providers/sites';
import { CoreCourseProvider } from '@core/course/providers/course';
/**
* Log cron handler. It will update last access of the user while app is open.
*/
@Injectable()
export class CoreCourseLogCronHandler implements CoreCronHandler {
name = 'CoreCourseLogCronHandler';
constructor(private coreProvider: CoreCourseProvider, private sitesProvider: CoreSitesProvider) {}
/**
* Execute the process.
* Receives the ID of the site affected, undefined for the current site.
*
* @param {string} [siteId] ID of the site affected, undefined for the current site.
* @return {Promise<any>} Promise resolved when done, rejected if failure.
*/
execute(siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return this.coreProvider.logView(site.getSiteHomeId(), undefined, site.getId());
});
}
/**
* Check whether it's a synchronization process or not.
*
* @return {boolean} Whether it's a synchronization process or not.
*/
isSync(): boolean {
return false;
}
/**
* Get the time between consecutive executions.
*
* @return {number} Time between consecutive executions (in ms).
*/
getInterval(): number {
return 240000; // 4 minutes. By default platform will see the user as online if lastaccess is less than 5 minutes.
}
}

View File

@ -10,7 +10,7 @@
<core-loading [hideUntil]="userLoaded">
<ion-list *ngIf="user && !isDeleted">
<ion-item text-center>
<ion-avatar class="user-avatar item-avatar-center" [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="true">
<ion-avatar core-user-avatar class="item-avatar-center" [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="true">
<ion-icon name="create" class="core-icon-foreground" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"></ion-icon>
</ion-avatar>
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>

View File

@ -11,7 +11,7 @@ ion-app.app-root page-core-user-profile {
border-radius: 50%;
background-color: white;
}
.user-avatar.item-avatar-center {
[core-user-avatar].item-avatar-center {
display: inline-block;
img {
margin: 0;

View File

@ -236,23 +236,37 @@ export class CoreCronDelegate {
const promises = [];
for (const name in this.handlers) {
const handler = this.handlers[name];
if (this.isHandlerManualSync(name)) {
// Mark the handler as running (it might be running already).
handler.running = true;
// Cancel pending timeout.
clearTimeout(handler.timeout);
delete handler.timeout;
// Now force the execution of the handler.
promises.push(this.checkAndExecuteHandler(name, true, siteId));
promises.push(this.forceCronHandlerExecution(name, siteId));
}
}
return this.utils.allPromises(promises);
}
/**
* Force execution of a cron tasks without waiting for the scheduled time.
* Please notice that some tasks may not be executed depending on the network connection and sync settings.
*
* @param {string} [name] If provided, the name of the handler.
* @param {string} [siteId] Site ID. If not defined, all sites.
* @return {Promise<any>} Promise resolved if handler has been executed successfully, rejected otherwise.
*/
forceCronHandlerExecution(name?: string, siteId?: string): Promise<any> {
const handler = this.handlers[name];
// Mark the handler as running (it might be running already).
handler.running = true;
// Cancel pending timeout.
clearTimeout(handler.timeout);
delete handler.timeout;
// Now force the execution of the handler.
return this.checkAndExecuteHandler(name, true, siteId);
}
/**
* Get a handler's interval.
*