commit
019c7ab73f
|
@ -56,6 +56,16 @@
|
|||
"addon.block_timeline.pluginname": "block_timeline",
|
||||
"addon.block_timeline.sortbycourses": "block_timeline",
|
||||
"addon.block_timeline.sortbydates": "block_timeline",
|
||||
"addon.blog.blog": "blog",
|
||||
"addon.blog.blogentries": "blog",
|
||||
"addon.blog.errorloadentries": "local_moodlemobileapp",
|
||||
"addon.blog.linktooriginalentry": "blog",
|
||||
"addon.blog.noentriesyet": "blog",
|
||||
"addon.blog.publishtonoone": "blog",
|
||||
"addon.blog.publishtosite": "blog",
|
||||
"addon.blog.publishtoworld": "blog",
|
||||
"addon.blog.showonlyyourentries": "local_moodlemobileapp",
|
||||
"addon.blog.siteblogheading": "blog",
|
||||
"addon.calendar.calendar": "calendar",
|
||||
"addon.calendar.calendarevents": "local_moodlemobileapp",
|
||||
"addon.calendar.defaultnotificationtime": "local_moodlemobileapp",
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
|
||||
import { CoreUserDelegate } from '@core/user/providers/user-delegate';
|
||||
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
|
||||
import { AddonBlogProvider } from './providers/blog';
|
||||
import { AddonBlogMainMenuHandler } from './providers/mainmenu-handler';
|
||||
import { AddonBlogUserHandler } from './providers/user-handler';
|
||||
import { AddonBlogCourseOptionHandler } from './providers/course-option-handler';
|
||||
import { AddonBlogComponentsModule } from './components/components.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
],
|
||||
imports: [
|
||||
AddonBlogComponentsModule
|
||||
],
|
||||
providers: [
|
||||
AddonBlogProvider,
|
||||
AddonBlogMainMenuHandler,
|
||||
AddonBlogUserHandler,
|
||||
AddonBlogCourseOptionHandler
|
||||
]
|
||||
})
|
||||
export class AddonBlogModule {
|
||||
constructor(mainMenuDelegate: CoreMainMenuDelegate, menuHandler: AddonBlogMainMenuHandler,
|
||||
userHandler: AddonBlogUserHandler, userDelegate: CoreUserDelegate,
|
||||
courseOptionHandler: AddonBlogCourseOptionHandler, courseOptionsDelegate: CoreCourseOptionsDelegate) {
|
||||
mainMenuDelegate.registerHandler(menuHandler);
|
||||
userDelegate.registerHandler(userHandler);
|
||||
courseOptionsDelegate.registerHandler(courseOptionHandler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
import { CorePipesModule } from '@pipes/pipes.module';
|
||||
import { CoreCommentsComponentsModule } from '@core/comments/components/components.module';
|
||||
import { AddonBlogEntriesComponent } from './entries/entries';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonBlogEntriesComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
CorePipesModule,
|
||||
CoreCommentsComponentsModule
|
||||
],
|
||||
providers: [
|
||||
],
|
||||
exports: [
|
||||
AddonBlogEntriesComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonBlogEntriesComponent
|
||||
]
|
||||
})
|
||||
export class AddonBlogComponentsModule {}
|
|
@ -0,0 +1,49 @@
|
|||
<ion-content>
|
||||
<ion-refresher [enabled]="loaded" (ionRefresh)="refresh($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="loaded" class="core-loading-center">
|
||||
<div class="safe-padding-horizontal">
|
||||
<ion-item *ngIf="showMyIssuesToggle">
|
||||
<ion-label>{{ 'addon.blog.showonlyyourentries' | translate }}</ion-label>
|
||||
<ion-toggle [(ngModel)]="onlyMyEntries"></ion-toggle>
|
||||
</ion-item>
|
||||
</div>
|
||||
<core-empty-box *ngIf="entries && entries.length == 0" icon="fa-newspaper-o" [message]="'addon.blog.noentriesyet' | translate"></core-empty-box>
|
||||
<ng-container *ngFor="let entry of entries">
|
||||
<ion-card *ngIf="!onlyMyEntries || entry.userid == currentUserId">
|
||||
<ion-item text-wrap>
|
||||
<ion-avatar core-user-avatar [user]="entry.user" item-start [courseId]="entry.courseid"></ion-avatar>
|
||||
<h2>
|
||||
<core-format-text [text]="entry.subject"></core-format-text>
|
||||
<ion-note float-end padding-left text-end>
|
||||
{{ 'addon.blog.' + entry.publishTranslated | translate}}
|
||||
</ion-note>
|
||||
</h2>
|
||||
<p>
|
||||
<ion-note float-end padding-left text-end>
|
||||
{{entry.created | coreDateDayOrTime}}
|
||||
</ion-note>
|
||||
{{entry.user && entry.user.fullname}}
|
||||
</p>
|
||||
</ion-item>
|
||||
<ion-card-content>
|
||||
<core-format-text [text]="entry.summary" [component]="this.component" [componentId]="entry.id"></core-format-text>
|
||||
<ion-item>
|
||||
<core-comments [component]="this.component" [itemId]="entry.id" area="format_blog" [instanceId]="entry.userid" contextLevel="user"></core-comments>
|
||||
</ion-item>
|
||||
<core-file *ngFor="let file of entry.attachmentfiles" [file]="file" [component]="this.component" [componentId]="entry.id"></core-file>
|
||||
<a ion-item *ngIf="entry.uniquehash" [href]="entry.uniquehash" core-link>{{ 'addon.blog.linktooriginalentry' | translate }}</a>
|
||||
</ion-card-content>
|
||||
<ion-row text-center>
|
||||
<ion-col *ngIf="entry.lastmodified > entry.created">
|
||||
<ion-note>
|
||||
<ion-icon name="time"></ion-icon> {{entry.lastmodified | coreTimeAgo}}
|
||||
</ion-note>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-card>
|
||||
</ng-container>
|
||||
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMore($event)" [error]="loadMoreError"></core-infinite-loading>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -0,0 +1,163 @@
|
|||
// (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 { Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import { Content } from 'ionic-angular';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreUserProvider } from '@core/user/providers/user';
|
||||
import { AddonBlogProvider } from '../../providers/blog';
|
||||
|
||||
/**
|
||||
* Component that displays the blog entries.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-blog-entries',
|
||||
templateUrl: 'addon-blog-entries.html',
|
||||
})
|
||||
export class AddonBlogEntriesComponent implements OnInit {
|
||||
@Input() userId?: number;
|
||||
@Input() courseId?: number;
|
||||
@Input() cmId?: number;
|
||||
|
||||
protected filter = {};
|
||||
protected pageLoaded = 0;
|
||||
|
||||
@ViewChild(Content) content: Content;
|
||||
|
||||
loaded = false;
|
||||
canLoadMore = false;
|
||||
loadMoreError = false;
|
||||
entries = [];
|
||||
currentUserId: number;
|
||||
showMyIssuesToggle = false;
|
||||
onlyMyEntries = false;
|
||||
component = AddonBlogProvider.COMPONENT;
|
||||
|
||||
constructor(protected blogProvider: AddonBlogProvider, protected domUtils: CoreDomUtilsProvider,
|
||||
protected userProvider: CoreUserProvider, sitesProvider: CoreSitesProvider) {
|
||||
this.currentUserId = sitesProvider.getCurrentSiteUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.userId) {
|
||||
this.filter['userid'] = this.userId;
|
||||
}
|
||||
|
||||
if (this.courseId) {
|
||||
this.filter['courseid'] = this.courseId;
|
||||
}
|
||||
|
||||
if (this.cmId) {
|
||||
this.filter['cmid'] = this.cmId;
|
||||
}
|
||||
|
||||
this.fetchEntries().then(() => {
|
||||
this.blogProvider.logView(this.filter).catch(() => {
|
||||
// Ignore errors.
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch blog entries.
|
||||
*
|
||||
* @param {boolean} [refresh] Empty events array first.
|
||||
* @return {Promise<any>} Promise with the entries.
|
||||
*/
|
||||
private fetchEntries(refresh: boolean = false): Promise<any> {
|
||||
this.loadMoreError = false;
|
||||
|
||||
if (refresh) {
|
||||
this.pageLoaded = 0;
|
||||
}
|
||||
|
||||
return this.blogProvider.getEntries(this.filter, this.pageLoaded).then((result) => {
|
||||
const promises = result.entries.map((entry) => {
|
||||
switch (entry.publishstate) {
|
||||
case 'draft':
|
||||
entry.publishTranslated = 'publishtonoone';
|
||||
break;
|
||||
case 'site':
|
||||
entry.publishTranslated = 'publishtosite';
|
||||
break;
|
||||
case 'public':
|
||||
entry.publishTranslated = 'publishtoworld';
|
||||
break;
|
||||
default:
|
||||
entry.publishTranslated = 'privacy:unknown';
|
||||
break;
|
||||
}
|
||||
|
||||
return this.userProvider.getProfile(entry.userid, entry.courseid, true).then((user) => {
|
||||
entry.user = user;
|
||||
}).catch(() => {
|
||||
// Ignore errors.
|
||||
});
|
||||
});
|
||||
|
||||
if (refresh) {
|
||||
this.showMyIssuesToggle = false;
|
||||
this.entries = result.entries;
|
||||
} else {
|
||||
this.entries = this.entries.concat(result.entries);
|
||||
}
|
||||
|
||||
this.canLoadMore = result.totalentries > this.entries.length;
|
||||
this.pageLoaded++;
|
||||
|
||||
this.showMyIssuesToggle = !this.userId && (this.showMyIssuesToggle || this.entries.some((entry) => {
|
||||
return entry.userid == this.currentUserId;
|
||||
}));
|
||||
|
||||
return Promise.all(promises);
|
||||
}).catch((message) => {
|
||||
this.domUtils.showErrorModalDefault(message, 'addon.blog.errorloadentries', true);
|
||||
this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading.
|
||||
}).finally(() => {
|
||||
this.loaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to load more entries.
|
||||
*
|
||||
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||
* @return {Promise<any>} Resolved when done.
|
||||
*/
|
||||
loadMore(infiniteComplete?: any): Promise<any> {
|
||||
return this.fetchEntries().finally(() => {
|
||||
infiniteComplete && infiniteComplete();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh blog entries on PTR.
|
||||
*
|
||||
* @param {any} refresher Refresher instance.
|
||||
*/
|
||||
refresh(refresher?: any): void {
|
||||
this.blogProvider.invalidateEntries(this.filter).finally(() => {
|
||||
this.fetchEntries(true).finally(() => {
|
||||
if (refresher) {
|
||||
refresher.complete();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"blog": "Blog",
|
||||
"blogentries": "Blog entries",
|
||||
"errorloadentries": "Error loading blog entries.",
|
||||
"linktooriginalentry": "Link to original blog entry",
|
||||
"noentriesyet": "No visible entries here",
|
||||
"publishtonoone": "Yourself (draft)",
|
||||
"publishtosite": "Anyone on this site",
|
||||
"publishtoworld": "Anyone in the world",
|
||||
"showonlyyourentries": "Show only your entries",
|
||||
"siteblogheading": "Site blog"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<ion-header>
|
||||
<ion-navbar core-back-button>
|
||||
<ion-title>{{ title | translate }}</ion-title>
|
||||
<ion-buttons end></ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<addon-blog-entries class="core-avoid-header" [courseId]="courseId" [userId]="userId" [cmId]="cmId"></addon-blog-entries>
|
|
@ -0,0 +1,33 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
import { AddonBlogEntriesPage } from './entries';
|
||||
import { AddonBlogComponentsModule } from '../../components/components.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonBlogEntriesPage,
|
||||
],
|
||||
imports: [
|
||||
CoreDirectivesModule,
|
||||
AddonBlogComponentsModule,
|
||||
IonicPageModule.forChild(AddonBlogEntriesPage),
|
||||
TranslateModule.forChild()
|
||||
],
|
||||
})
|
||||
export class AddonBlogEntriesPageModule {}
|
|
@ -0,0 +1,43 @@
|
|||
// (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 { Component } from '@angular/core';
|
||||
import { IonicPage, NavParams } from 'ionic-angular';
|
||||
|
||||
/**
|
||||
* Page that displays the list of blog entries.
|
||||
*/
|
||||
@IonicPage({ segment: 'addon-blog-entries' })
|
||||
@Component({
|
||||
selector: 'page-addon-blog-entries',
|
||||
templateUrl: 'entries.html',
|
||||
})
|
||||
export class AddonBlogEntriesPage {
|
||||
userId: number;
|
||||
courseId: number;
|
||||
cmId: number;
|
||||
title: string;
|
||||
|
||||
constructor(params: NavParams) {
|
||||
this.userId = params.get('userId');
|
||||
this.courseId = params.get('courseId');
|
||||
this.cmId = params.get('cmId');
|
||||
|
||||
if (!this.userId && !this.courseId && !this.cmId) {
|
||||
this.title = 'addon.blog.siteblogheading';
|
||||
} else {
|
||||
this.title = 'addon.blog.blogentries';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
// (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 { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
|
||||
/**
|
||||
* Service to handle blog entries.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonBlogProvider {
|
||||
static ENTRIES_PER_PAGE = 10;
|
||||
static COMPONENT = 'blog';
|
||||
protected ROOT_CACHE_KEY = 'addonBlog:';
|
||||
protected logger;
|
||||
|
||||
constructor(logger: CoreLoggerProvider, protected sitesProvider: CoreSitesProvider, protected utils: CoreUtilsProvider) {
|
||||
this.logger = logger.getInstance('AddonBlogProvider');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the blog plugin is enabled for a certain site.
|
||||
*
|
||||
* This method is called quite often and thus should only perform a quick
|
||||
* check, we should not be calling WS from here.
|
||||
*
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<boolean>} Promise resolved with true if enabled, resolved with false or rejected otherwise.
|
||||
*/
|
||||
isPluginEnabled(siteId?: string): Promise<boolean> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
return site.wsAvailable('core_blog_get_entries') &&
|
||||
site.canUseAdvancedFeature('enableblogs');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache key for the blog entries.
|
||||
*
|
||||
* @param {any} [filter] Filter to apply on search.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
getEntriesCacheKey(filter: any = {}): string {
|
||||
return this.ROOT_CACHE_KEY + this.utils.sortAndStringify(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blog entries.
|
||||
*
|
||||
* @param {any} [filter] Filter to apply on search.
|
||||
* @param {any} [page=0] Page of the blog entries to fetch.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the entries are retrieved.
|
||||
*/
|
||||
getEntries(filter: any = {}, page: number = 0, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const data = {
|
||||
filters: this.utils.objectToArrayOfObjects(filter, 'name', 'value'),
|
||||
page: page,
|
||||
perpage: AddonBlogProvider.ENTRIES_PER_PAGE
|
||||
};
|
||||
|
||||
const preSets = {
|
||||
cacheKey: this.getEntriesCacheKey(filter)
|
||||
};
|
||||
|
||||
return site.read('core_blog_get_entries', data, preSets);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate blog entries WS call.
|
||||
*
|
||||
* @param {any} [filter] Filter to apply on search
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when data is invalidated.
|
||||
*/
|
||||
invalidateEntries(filter: any = {}, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
return site.invalidateWsCacheForKey(this.getEntriesCacheKey(filter));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the blog_entries_viewed event.
|
||||
*
|
||||
* @param {any} [filter] Filter to apply on search.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when done.
|
||||
*/
|
||||
logView(filter: any = {}, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const data = {
|
||||
filters: this.utils.objectToArrayOfObjects(filter, 'name', 'value')
|
||||
};
|
||||
|
||||
return site.write('core_blog_view_entries', data);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
// (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, Injector } from '@angular/core';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreFilepoolProvider } from '@providers/filepool';
|
||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
|
||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
|
||||
import { AddonBlogEntriesComponent } from '../components/entries/entries';
|
||||
import { AddonBlogProvider } from './blog';
|
||||
|
||||
/**
|
||||
* Course nav handler.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonBlogCourseOptionHandler implements CoreCourseOptionsHandler {
|
||||
name = 'AddonBlog';
|
||||
priority = 100;
|
||||
|
||||
constructor(protected coursesProvider: CoreCoursesProvider, protected blogProvider: AddonBlogProvider,
|
||||
protected courseHelper: CoreCourseHelperProvider, protected courseProvider: CoreCourseProvider,
|
||||
protected sitesProvider: CoreSitesProvider, protected filepoolProvider: CoreFilepoolProvider) {}
|
||||
|
||||
/**
|
||||
* Should invalidate the data to determine if the handler is enabled for a certain course.
|
||||
*
|
||||
* @param {number} courseId The course ID.
|
||||
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
|
||||
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
invalidateEnabledForCourse(courseId: number, navOptions?: any, admOptions?: any): Promise<any> {
|
||||
return this.courseProvider.invalidateCourseBlocks(courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean} Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return this.blogProvider.isPluginEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled for a certain course.
|
||||
*
|
||||
* @param {number} courseId The course ID.
|
||||
* @param {any} accessData Access type and data. Default, guest, ...
|
||||
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
|
||||
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabledForCourse(courseId: number, accessData: any, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
|
||||
return this.courseHelper.hasABlockNamed(courseId, 'blog_menu').then((enabled) => {
|
||||
if (enabled && navOptions && typeof navOptions.blogs != 'undefined') {
|
||||
return navOptions.blogs;
|
||||
}
|
||||
|
||||
return enabled;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {number} courseId The course ID.
|
||||
* @return {CoreCourseOptionsHandlerData|Promise<CoreCourseOptionsHandlerData>} Data or promise resolved with the data.
|
||||
*/
|
||||
getDisplayData(injector: Injector, courseId: number): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> {
|
||||
return {
|
||||
title: 'addon.blog.blog',
|
||||
class: 'addon-blog-handler',
|
||||
component: AddonBlogEntriesComponent
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a course is downloaded. It should prefetch all the data to be able to see the addon in offline.
|
||||
*
|
||||
* @param {any} course The course.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
prefetch(course: any): Promise<any> {
|
||||
const siteId = this.sitesProvider.getCurrentSiteId();
|
||||
|
||||
return this.blogProvider.getEntries({courseid: course.id}).then((result) => {
|
||||
return result.entries.map((entry) => {
|
||||
let files = [];
|
||||
|
||||
if (entry.attachmentfiles && entry.attachmentfiles.length) {
|
||||
files = entry.attachmentfiles;
|
||||
}
|
||||
if (entry.summaryfiles && entry.summaryfiles.length) {
|
||||
files = files.concat(entry.summaryfiles);
|
||||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
return this.filepoolProvider.addFilesToQueue(siteId, files, entry.module, entry.id);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// (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 { AddonBlogProvider } from './blog';
|
||||
import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@core/mainmenu/providers/delegate';
|
||||
|
||||
/**
|
||||
* Handler to inject an option into main menu.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonBlogMainMenuHandler implements CoreMainMenuHandler {
|
||||
name = 'AddonBlog';
|
||||
priority = 450;
|
||||
|
||||
constructor(private blogProvider: AddonBlogProvider) { }
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean} Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return this.blogProvider.isPluginEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return {CoreMainMenuHandlerData} Data needed to render the handler.
|
||||
*/
|
||||
getDisplayData(): CoreMainMenuHandlerData {
|
||||
return {
|
||||
icon: 'fa-newspaper-o',
|
||||
title: 'addon.blog.siteblogheading',
|
||||
page: 'AddonBlogEntriesPage',
|
||||
class: 'addon-blog-handler'
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// (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 { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate';
|
||||
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||
import { AddonBlogProvider } from './blog';
|
||||
|
||||
/**
|
||||
* Profile item handler.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonBlogUserHandler implements CoreUserProfileHandler {
|
||||
name = 'AddonBlog:blogs';
|
||||
priority = 300;
|
||||
type = CoreUserDelegate.TYPE_NEW_PAGE;
|
||||
|
||||
constructor(protected linkHelper: CoreContentLinksHelperProvider, protected blogProvider: AddonBlogProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
* @return {boolean|Promise<boolean>} Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return this.blogProvider.isPluginEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if handler is enabled for this user in this context.
|
||||
*
|
||||
* @param {any} user User to check.
|
||||
* @param {number} courseId Course ID.
|
||||
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
|
||||
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
||||
* @return {boolean|Promise<boolean>} Promise resolved with true if enabled, resolved with false otherwise.
|
||||
*/
|
||||
isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return {CoreUserProfileHandlerData} Data needed to render the handler.
|
||||
*/
|
||||
getDisplayData(user: any, courseId: number): CoreUserProfileHandlerData {
|
||||
return {
|
||||
icon: 'fa-newspaper-o',
|
||||
title: 'addon.blog.blogentries',
|
||||
class: 'addon-blog-handler',
|
||||
action: (event, navCtrl, user, courseId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||
this.linkHelper.goInSite(navCtrl, 'AddonBlogEntriesPage', { userId: user.id, courseId: courseId });
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="assign && (description || (assign.introattachments && assign.introattachments.length))" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
</core-context-menu>
|
||||
</core-navbar-buttons>
|
||||
|
|
|
@ -35,7 +35,7 @@ export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
protected title: string;
|
||||
|
||||
constructor(injector: Injector, private chatProvider: AddonModChatProvider, private timeUtils: CoreTimeUtilsProvider,
|
||||
private navCtrl: NavController) {
|
||||
protected navCtrl: NavController) {
|
||||
super(injector);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="500" *ngIf="canAdd" [content]="'addon.mod_data.addentries' | translate" [iconAction]="'add'" (action)="gotoAddEntries($event)"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -70,7 +70,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
|
|||
|
||||
constructor(injector: Injector, private feedbackProvider: AddonModFeedbackProvider, @Optional() content: Content,
|
||||
private feedbackOffline: AddonModFeedbackOfflineProvider, private groupsProvider: CoreGroupsProvider,
|
||||
private feedbackSync: AddonModFeedbackSyncProvider, private navCtrl: NavController,
|
||||
private feedbackSync: AddonModFeedbackSyncProvider, protected navCtrl: NavController,
|
||||
private feedbackHelper: AddonModFeedbackHelperProvider, private timeUtils: CoreTimeUtilsProvider) {
|
||||
super(injector, content);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'addon.mod_forum.refreshdiscussions' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="650" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="canAdd" [priority]="600" [content]="'addon.mod_glossary.addentry' | translate" (action)="openNewEntry()" iconAction="add"></core-context-menu-item>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
</core-context-menu>
|
||||
</core-navbar-buttons>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
</core-context-menu>
|
||||
</core-navbar-buttons>
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline && !pageIsOffline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && isOnline && (hasOffline || pageIsOffline)" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="canEdit && (isOnline || pageIsOffline)" [priority]="590" [content]="'core.edit' | translate" iconAction="create" (action)="goToEditPage()"></core-context-menu-item>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||
|
|
|
@ -67,7 +67,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
|
|||
|
||||
constructor(injector: Injector, private workshopProvider: AddonModWorkshopProvider, @Optional() content: Content,
|
||||
private workshopOffline: AddonModWorkshopOfflineProvider, private groupsProvider: CoreGroupsProvider,
|
||||
private navCtrl: NavController, private modalCtrl: ModalController, private utils: CoreUtilsProvider,
|
||||
protected navCtrl: NavController, private modalCtrl: ModalController, private utils: CoreUtilsProvider,
|
||||
platform: Platform, private workshopHelper: AddonModWorkshopHelperProvider,
|
||||
private workshopSync: AddonModWorkshopSyncProvider) {
|
||||
super(injector, content);
|
||||
|
|
|
@ -79,7 +79,7 @@ export class AddonNotesUserHandler implements CoreUserProfileHandler {
|
|||
return this.noteEnabledCache[courseId];
|
||||
}
|
||||
|
||||
return this.notesProvider.isPluginAddNoteEnabledForCourse(courseId).then((enabled) => {
|
||||
return this.notesProvider.isPluginViewNotesEnabledForCourse(courseId).then((enabled) => {
|
||||
this.noteEnabledCache[courseId] = enabled;
|
||||
|
||||
return enabled;
|
||||
|
|
|
@ -81,6 +81,7 @@ import { CoreBlockModule } from '@core/block/block.module';
|
|||
|
||||
// Addon modules.
|
||||
import { AddonBadgesModule } from '@addon/badges/badges.module';
|
||||
import { AddonBlogModule } from '@addon/blog/blog.module';
|
||||
import { AddonCalendarModule } from '@addon/calendar/calendar.module';
|
||||
import { AddonCompetencyModule } from '@addon/competency/competency.module';
|
||||
import { AddonCourseCompletionModule } from '@addon/coursecompletion/coursecompletion.module';
|
||||
|
@ -198,6 +199,7 @@ export const CORE_PROVIDERS: any[] = [
|
|||
CoreCommentsModule,
|
||||
CoreBlockModule,
|
||||
AddonBadgesModule,
|
||||
AddonBlogModule,
|
||||
AddonCalendarModule,
|
||||
AddonCompetencyModule,
|
||||
AddonCourseCompletionModule,
|
||||
|
|
|
@ -990,7 +990,9 @@ details summary {
|
|||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.icon.fa-graduation-cap{
|
||||
.icon.fa-graduation-cap,
|
||||
.item > .icon.fa,
|
||||
.item-inner > .icon.fa {
|
||||
font-size: 21px;
|
||||
width: 21px;
|
||||
line-height: 28px;
|
||||
|
|
|
@ -56,6 +56,16 @@
|
|||
"addon.block_timeline.pluginname": "Timeline",
|
||||
"addon.block_timeline.sortbycourses": "Sort by courses",
|
||||
"addon.block_timeline.sortbydates": "Sort by dates",
|
||||
"addon.blog.blog": "Blog",
|
||||
"addon.blog.blogentries": "Blog entries",
|
||||
"addon.blog.errorloadentries": "Error loading blog entries.",
|
||||
"addon.blog.linktooriginalentry": "Link to original blog entry",
|
||||
"addon.blog.noentriesyet": "No visible entries here",
|
||||
"addon.blog.publishtonoone": "Yourself (draft)",
|
||||
"addon.blog.publishtosite": "Anyone on this site",
|
||||
"addon.blog.publishtoworld": "Anyone in the world",
|
||||
"addon.blog.showonlyyourentries": "Show only your entries",
|
||||
"addon.blog.siteblogheading": "Site blog",
|
||||
"addon.calendar.calendar": "Calendar",
|
||||
"addon.calendar.calendarevents": "Calendar events",
|
||||
"addon.calendar.defaultnotificationtime": "Default notification time",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { OnInit, OnDestroy, Input, Output, EventEmitter, Injector } from '@angular/core';
|
||||
import { NavController } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
|
@ -20,6 +21,8 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
|
|||
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
|
||||
import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
|
||||
import { CoreCourseSectionPage } from '@core/course/pages/section/section.ts';
|
||||
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||
import { AddonBlogProvider } from '@addon/blog/providers/blog';
|
||||
|
||||
/**
|
||||
* Template class to easily create CoreCourseModuleMainComponent of resources (or activities without syncing).
|
||||
|
@ -32,6 +35,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
loaded: boolean; // If the component has been loaded.
|
||||
component: string; // Component name.
|
||||
componentId: number; // Component ID.
|
||||
blog: boolean; // If blog is avalaible.
|
||||
|
||||
// Data for context menu.
|
||||
externalUrl: string; // External URL to open in browser.
|
||||
|
@ -54,6 +58,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
protected domUtils: CoreDomUtilsProvider;
|
||||
protected moduleDelegate: CoreCourseModuleDelegate;
|
||||
protected courseSectionPage: CoreCourseSectionPage;
|
||||
protected linkHelper: CoreContentLinksHelperProvider;
|
||||
protected navCtrl: NavController;
|
||||
protected blogProvider: AddonBlogProvider;
|
||||
|
||||
protected logger;
|
||||
|
||||
|
@ -64,6 +71,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
this.domUtils = injector.get(CoreDomUtilsProvider);
|
||||
this.moduleDelegate = injector.get(CoreCourseModuleDelegate);
|
||||
this.courseSectionPage = injector.get(CoreCourseSectionPage, null);
|
||||
this.linkHelper = injector.get(CoreContentLinksHelperProvider);
|
||||
this.navCtrl = injector.get(NavController, null);
|
||||
this.blogProvider = injector.get(AddonBlogProvider, null);
|
||||
this.dataRetrieved = new EventEmitter();
|
||||
|
||||
const loggerProvider = injector.get(CoreLoggerProvider);
|
||||
|
@ -79,6 +89,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
this.externalUrl = this.module.url;
|
||||
this.loaded = false;
|
||||
this.refreshIcon = 'spinner';
|
||||
this.blogProvider.isPluginEnabled().then((enabled) => {
|
||||
this.blog = enabled;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -216,6 +229,16 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
this.textUtils.expandText(this.translate.instant('core.description'), this.description, this.component, this.module.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to blog posts.
|
||||
*
|
||||
* @param {any} event Event.
|
||||
*/
|
||||
gotoBlog(event: any): void {
|
||||
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||
this.linkHelper.goInSite(this.navCtrl, 'AddonBlogEntriesPage', { cmId: this.module.id });
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch the module.
|
||||
*/
|
||||
|
|
|
@ -753,6 +753,25 @@ export class CoreCourseHelperProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the course has a block with that name.
|
||||
*
|
||||
* @param {number} courseId Course ID.
|
||||
* @param {string} name Block name to search.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<boolean>} Promise resolved with true if the block exists or false otherwise.
|
||||
* @since 3.3
|
||||
*/
|
||||
hasABlockNamed(courseId: number, name: string, siteId?: string): Promise<boolean> {
|
||||
return this.courseProvider.getCourseBlocks(courseId, siteId).then((blocks) => {
|
||||
return blocks.some((block) => {
|
||||
return block.name == name;
|
||||
});
|
||||
}).catch(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the prefetch icon for selected courses.
|
||||
*
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
|
@ -27,39 +27,43 @@ export class CoreCourseLogHelperProvider {
|
|||
|
||||
// Variables for database.
|
||||
static ACTIVITY_LOG_TABLE = 'course_activity_log';
|
||||
protected tablesSchema = [
|
||||
{
|
||||
name: CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
|
||||
columns: [
|
||||
{
|
||||
name: 'component',
|
||||
type: 'TEXT'
|
||||
},
|
||||
{
|
||||
name: 'componentid',
|
||||
type: 'INTEGER'
|
||||
},
|
||||
{
|
||||
name: 'ws',
|
||||
type: 'TEXT'
|
||||
},
|
||||
{
|
||||
name: 'data',
|
||||
type: 'TEXT'
|
||||
},
|
||||
{
|
||||
name: 'time',
|
||||
type: 'INTEGER'
|
||||
}
|
||||
],
|
||||
primaryKeys: ['component', 'componentid', 'ws', 'time']
|
||||
}
|
||||
];
|
||||
protected siteSchema: CoreSiteSchema = {
|
||||
name: 'CoreCourseOfflineProvider',
|
||||
version: 1,
|
||||
tables: [
|
||||
{
|
||||
name: CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
|
||||
columns: [
|
||||
{
|
||||
name: 'component',
|
||||
type: 'TEXT'
|
||||
},
|
||||
{
|
||||
name: 'componentid',
|
||||
type: 'INTEGER'
|
||||
},
|
||||
{
|
||||
name: 'ws',
|
||||
type: 'TEXT'
|
||||
},
|
||||
{
|
||||
name: 'data',
|
||||
type: 'TEXT'
|
||||
},
|
||||
{
|
||||
name: 'time',
|
||||
type: 'INTEGER'
|
||||
}
|
||||
],
|
||||
primaryKeys: ['component', 'componentid', 'ws', 'time']
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
constructor(protected sitesProvider: CoreSitesProvider, protected timeUtils: CoreTimeUtilsProvider,
|
||||
protected textUtils: CoreTextUtilsProvider, protected utils: CoreUtilsProvider,
|
||||
protected appProvider: CoreAppProvider) {
|
||||
this.sitesProvider.createTablesFromSchema(this.tablesSchema);
|
||||
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue