MOBILE-2386 blog: Add blog entries page

main
Pau Ferrer Ocaña 2019-02-14 16:14:57 +01:00
parent cc9ba9204c
commit f11892f93c
42 changed files with 846 additions and 5 deletions

View File

@ -56,6 +56,16 @@
"addon.block_timeline.pluginname": "block_timeline", "addon.block_timeline.pluginname": "block_timeline",
"addon.block_timeline.sortbycourses": "block_timeline", "addon.block_timeline.sortbycourses": "block_timeline",
"addon.block_timeline.sortbydates": "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.calendar": "calendar",
"addon.calendar.calendarevents": "local_moodlemobileapp", "addon.calendar.calendarevents": "local_moodlemobileapp",
"addon.calendar.defaultnotificationtime": "local_moodlemobileapp", "addon.calendar.defaultnotificationtime": "local_moodlemobileapp",

View File

@ -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);
}
}

View File

@ -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 {}

View File

@ -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>

View File

@ -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();
}
});
});
}
}

View File

@ -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"
}

View File

@ -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>

View File

@ -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 {}

View File

@ -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';
}
}
}

View File

@ -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);
});
}
}

View File

@ -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();
});
});
}
}

View File

@ -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'
};
}
}

View File

@ -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 });
}
};
}
}

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -6,6 +6,7 @@
<core-context-menu> <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="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="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 [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="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> <core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -35,7 +35,7 @@ export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComp
protected title: string; protected title: string;
constructor(injector: Injector, private chatProvider: AddonModChatProvider, private timeUtils: CoreTimeUtilsProvider, constructor(injector: Injector, private chatProvider: AddonModChatProvider, private timeUtils: CoreTimeUtilsProvider,
private navCtrl: NavController) { protected navCtrl: NavController) {
super(injector); super(injector);
} }

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -6,6 +6,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item [priority]="500" *ngIf="canAdd" [content]="'addon.mod_data.addentries' | translate" [iconAction]="'add'" (action)="gotoAddEntries($event)"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -70,7 +70,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
constructor(injector: Injector, private feedbackProvider: AddonModFeedbackProvider, @Optional() content: Content, constructor(injector: Injector, private feedbackProvider: AddonModFeedbackProvider, @Optional() content: Content,
private feedbackOffline: AddonModFeedbackOfflineProvider, private groupsProvider: CoreGroupsProvider, private feedbackOffline: AddonModFeedbackOfflineProvider, private groupsProvider: CoreGroupsProvider,
private feedbackSync: AddonModFeedbackSyncProvider, private navCtrl: NavController, private feedbackSync: AddonModFeedbackSyncProvider, protected navCtrl: NavController,
private feedbackHelper: AddonModFeedbackHelperProvider, private timeUtils: CoreTimeUtilsProvider) { private feedbackHelper: AddonModFeedbackHelperProvider, private timeUtils: CoreTimeUtilsProvider) {
super(injector, content); super(injector, content);

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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 [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="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> <core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -6,6 +6,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="canAdd" [priority]="600" [content]="'addon.mod_glossary.addentry' | translate" (action)="openNewEntry()" iconAction="add"></core-context-menu-item>

View File

@ -6,6 +6,7 @@
<core-context-menu> <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="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="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 [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="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> <core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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-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-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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 [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="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> <core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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 [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="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> <core-context-menu-item *ngIf="size" [priority]="500" [content]="size" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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 [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -13,6 +13,7 @@
<core-context-menu> <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="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="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 && !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="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> <core-context-menu-item *ngIf="canEdit && (isOnline || pageIsOffline)" [priority]="590" [content]="'core.edit' | translate" iconAction="create" (action)="goToEditPage()"></core-context-menu-item>

View File

@ -3,6 +3,7 @@
<core-context-menu> <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="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="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]="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="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> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>

View File

@ -67,7 +67,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
constructor(injector: Injector, private workshopProvider: AddonModWorkshopProvider, @Optional() content: Content, constructor(injector: Injector, private workshopProvider: AddonModWorkshopProvider, @Optional() content: Content,
private workshopOffline: AddonModWorkshopOfflineProvider, private groupsProvider: CoreGroupsProvider, 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, platform: Platform, private workshopHelper: AddonModWorkshopHelperProvider,
private workshopSync: AddonModWorkshopSyncProvider) { private workshopSync: AddonModWorkshopSyncProvider) {
super(injector, content); super(injector, content);

View File

@ -79,7 +79,7 @@ export class AddonNotesUserHandler implements CoreUserProfileHandler {
return this.noteEnabledCache[courseId]; return this.noteEnabledCache[courseId];
} }
return this.notesProvider.isPluginAddNoteEnabledForCourse(courseId).then((enabled) => { return this.notesProvider.isPluginViewNotesEnabledForCourse(courseId).then((enabled) => {
this.noteEnabledCache[courseId] = enabled; this.noteEnabledCache[courseId] = enabled;
return enabled; return enabled;

View File

@ -81,6 +81,7 @@ import { CoreBlockModule } from '@core/block/block.module';
// Addon modules. // Addon modules.
import { AddonBadgesModule } from '@addon/badges/badges.module'; import { AddonBadgesModule } from '@addon/badges/badges.module';
import { AddonBlogModule } from '@addon/blog/blog.module';
import { AddonCalendarModule } from '@addon/calendar/calendar.module'; import { AddonCalendarModule } from '@addon/calendar/calendar.module';
import { AddonCompetencyModule } from '@addon/competency/competency.module'; import { AddonCompetencyModule } from '@addon/competency/competency.module';
import { AddonCourseCompletionModule } from '@addon/coursecompletion/coursecompletion.module'; import { AddonCourseCompletionModule } from '@addon/coursecompletion/coursecompletion.module';
@ -198,6 +199,7 @@ export const CORE_PROVIDERS: any[] = [
CoreCommentsModule, CoreCommentsModule,
CoreBlockModule, CoreBlockModule,
AddonBadgesModule, AddonBadgesModule,
AddonBlogModule,
AddonCalendarModule, AddonCalendarModule,
AddonCompetencyModule, AddonCompetencyModule,
AddonCourseCompletionModule, AddonCourseCompletionModule,

View File

@ -990,7 +990,9 @@ details summary {
pointer-events: auto; pointer-events: auto;
} }
.icon.fa-graduation-cap{ .icon.fa-graduation-cap,
.item > .icon.fa,
.item-inner > .icon.fa {
font-size: 21px; font-size: 21px;
width: 21px; width: 21px;
line-height: 28px; line-height: 28px;

View File

@ -56,6 +56,16 @@
"addon.block_timeline.pluginname": "Timeline", "addon.block_timeline.pluginname": "Timeline",
"addon.block_timeline.sortbycourses": "Sort by courses", "addon.block_timeline.sortbycourses": "Sort by courses",
"addon.block_timeline.sortbydates": "Sort by dates", "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.calendar": "Calendar",
"addon.calendar.calendarevents": "Calendar events", "addon.calendar.calendarevents": "Calendar events",
"addon.calendar.defaultnotificationtime": "Default notification time", "addon.calendar.defaultnotificationtime": "Default notification time",

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
import { OnInit, OnDestroy, Input, Output, EventEmitter, Injector } from '@angular/core'; import { OnInit, OnDestroy, Input, Output, EventEmitter, Injector } from '@angular/core';
import { NavController } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
@ -20,6 +21,8 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate'; import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
import { CoreCourseSectionPage } from '@core/course/pages/section/section.ts'; 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). * 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. loaded: boolean; // If the component has been loaded.
component: string; // Component name. component: string; // Component name.
componentId: number; // Component ID. componentId: number; // Component ID.
blog: boolean; // If blog is avalaible.
// Data for context menu. // Data for context menu.
externalUrl: string; // External URL to open in browser. externalUrl: string; // External URL to open in browser.
@ -54,6 +58,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
protected domUtils: CoreDomUtilsProvider; protected domUtils: CoreDomUtilsProvider;
protected moduleDelegate: CoreCourseModuleDelegate; protected moduleDelegate: CoreCourseModuleDelegate;
protected courseSectionPage: CoreCourseSectionPage; protected courseSectionPage: CoreCourseSectionPage;
protected linkHelper: CoreContentLinksHelperProvider;
protected navCtrl: NavController;
protected blogProvider: AddonBlogProvider;
protected logger; protected logger;
@ -64,6 +71,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
this.domUtils = injector.get(CoreDomUtilsProvider); this.domUtils = injector.get(CoreDomUtilsProvider);
this.moduleDelegate = injector.get(CoreCourseModuleDelegate); this.moduleDelegate = injector.get(CoreCourseModuleDelegate);
this.courseSectionPage = injector.get(CoreCourseSectionPage, null); 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(); this.dataRetrieved = new EventEmitter();
const loggerProvider = injector.get(CoreLoggerProvider); const loggerProvider = injector.get(CoreLoggerProvider);
@ -79,6 +89,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
this.externalUrl = this.module.url; this.externalUrl = this.module.url;
this.loaded = false; this.loaded = false;
this.refreshIcon = 'spinner'; 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); 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. * Prefetch the module.
*/ */

View File

@ -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. * Initialize the prefetch icon for selected courses.
* *