MOBILE-3592 user: Implement user tag area handler
parent
90bd583147
commit
36d03d27c5
|
@ -86,7 +86,7 @@ export class CoreDelegate<HandlerType extends CoreDelegateHandler> {
|
||||||
* @param delegateName Delegate name used for logging purposes.
|
* @param delegateName Delegate name used for logging purposes.
|
||||||
* @param listenSiteEvents Whether to update the handler when a site event occurs (login, site updated, ...).
|
* @param listenSiteEvents Whether to update the handler when a site event occurs (login, site updated, ...).
|
||||||
*/
|
*/
|
||||||
constructor(delegateName: string, listenSiteEvents?: boolean) {
|
constructor(delegateName: string, listenSiteEvents: boolean = true) {
|
||||||
this.logger = CoreLogger.getInstance(delegateName);
|
this.logger = CoreLogger.getInstance(delegateName);
|
||||||
|
|
||||||
this.handlersInitPromise = new Promise((resolve): void => {
|
this.handlersInitPromise = new Promise((resolve): void => {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, Type } from '@angular/core';
|
||||||
import { IonInfiniteScroll, IonRefresher } from '@ionic/angular';
|
import { IonInfiniteScroll, IonRefresher } from '@ionic/angular';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTag } from '@features/tag/services/tag';
|
import { CoreTag } from '@features/tag/services/tag';
|
||||||
|
@ -20,6 +20,7 @@ import { CoreTagFeedElement } from '../../services/tag-helper';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { CoreTagAreaDelegate } from '../../services/tag-area-delegate';
|
import { CoreTagAreaDelegate } from '../../services/tag-area-delegate';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the tag index area.
|
* Page that displays the tag index area.
|
||||||
|
@ -47,7 +48,7 @@ export class CoreTagIndexAreaPage implements OnInit {
|
||||||
items: CoreTagFeedElement[] = [];
|
items: CoreTagFeedElement[] = [];
|
||||||
nextPage = 0;
|
nextPage = 0;
|
||||||
canLoadMore = false;
|
canLoadMore = false;
|
||||||
areaComponent: any; // @todo
|
areaComponent?: Type<unknown>;
|
||||||
loadMoreError = false;
|
loadMoreError = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -59,7 +60,7 @@ export class CoreTagIndexAreaPage implements OnInit {
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
|
||||||
const navParams = this.route.snapshot.queryParamMap;
|
const navParams = this.route.snapshot.queryParams;
|
||||||
|
|
||||||
this.tagId = navParams['tagId'] ? parseInt(navParams['tagId'], 10) : this.tagId;
|
this.tagId = navParams['tagId'] ? parseInt(navParams['tagId'], 10) : this.tagId;
|
||||||
this.tagName = navParams['tagName'] || this.tagName;
|
this.tagName = navParams['tagName'] || this.tagName;
|
||||||
|
@ -74,8 +75,8 @@ export class CoreTagIndexAreaPage implements OnInit {
|
||||||
this.componentName = navParams['componentName'];
|
this.componentName = navParams['componentName'];
|
||||||
this.itemType = navParams['itemType'];
|
this.itemType = navParams['itemType'];
|
||||||
this.items = []; // @todo navParams['items'] || [];
|
this.items = []; // @todo navParams['items'] || [];
|
||||||
this.nextPage = navParams.has('nextPage') ? parseInt(navParams['nextPage']!, 10) : 0;
|
this.nextPage = typeof navParams['nextPage'] != 'undefined' ? parseInt(navParams['nextPage'], 10) : 0;
|
||||||
this.canLoadMore = !!navParams['canLoadMore'];
|
this.canLoadMore = CoreUtils.instance.isTrueOrOne(navParams['canLoadMore']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!this.componentName || !this.itemType || !this.items.length || this.nextPage == 0) {
|
if (!this.componentName || !this.itemType || !this.items.length || this.nextPage == 0) {
|
||||||
|
|
|
@ -168,8 +168,11 @@ export class CoreTagIndexPage implements OnInit {
|
||||||
canLoadMore: area.canLoadMore,
|
canLoadMore: area.canLoadMore,
|
||||||
nextPage: 1,
|
nextPage: 1,
|
||||||
};
|
};
|
||||||
// this.splitviewCtrl.push('core-tag-index-area', params);
|
// this.splitviewCtrl.push('index-area', params);
|
||||||
this.router.navigate(['core-tag-index-area'], { queryParams: params });
|
this.router.navigate(['../index-area'], {
|
||||||
|
queryParams: params,
|
||||||
|
relativeTo: this.route,
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ export class CoreTagAreaDelegateService extends CoreDelegate<CoreTagAreaHandler>
|
||||||
protected handlerNameProperty = 'type';
|
protected handlerNameProperty = 'type';
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super('CoreTagAreaDelegate');
|
super('CoreTagAreaDelegate', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { CoreUserProfileField } from '@features/user/services/user';
|
||||||
@Component({
|
@Component({
|
||||||
template: '',
|
template: '',
|
||||||
})
|
})
|
||||||
export class CoreUserProfileFieldBaseComponent implements OnInit {
|
export abstract class CoreUserProfileFieldBaseComponent implements OnInit {
|
||||||
|
|
||||||
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
@Input() field?: AuthEmailSignupProfileField | CoreUserProfileField; // The profile field to be rendered.
|
||||||
@Input() edit = false; // True if editing the field. Defaults to false.
|
@Input() edit = false; // True if editing the field. Defaults to false.
|
||||||
|
|
|
@ -21,10 +21,12 @@ import { CoreComponentsModule } from '@components/components.module';
|
||||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||||
import { CorePipesModule } from '@pipes/pipes.module';
|
import { CorePipesModule } from '@pipes/pipes.module';
|
||||||
import { CoreUserProfileFieldComponent } from './user-profile-field/user-profile-field';
|
import { CoreUserProfileFieldComponent } from './user-profile-field/user-profile-field';
|
||||||
|
import { CoreUserTagAreaComponent } from './tag-area/tag-area';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
CoreUserProfileFieldComponent,
|
CoreUserProfileFieldComponent,
|
||||||
|
CoreUserTagAreaComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
@ -38,6 +40,7 @@ import { CoreUserProfileFieldComponent } from './user-profile-field/user-profile
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
CoreUserProfileFieldComponent,
|
CoreUserProfileFieldComponent,
|
||||||
|
CoreUserTagAreaComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CoreUserComponentsModule {}
|
export class CoreUserComponentsModule {}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<ion-item class="ion-text-wrap" *ngFor="let item of items" core-user-link [userId]="item.user.id">
|
||||||
|
<core-user-avatar [user]="item.user" slot="start"></core-user-avatar>
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ item.heading }}</h2>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
|
@ -0,0 +1,30 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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 } from '@angular/core';
|
||||||
|
|
||||||
|
import { CoreUserTagFeedElement } from '@features/user/services/handlers/tag-area-handler';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to render the user tag area.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'core-user-tag-area',
|
||||||
|
templateUrl: 'core-user-tag-area.html',
|
||||||
|
})
|
||||||
|
export class CoreUserTagAreaComponent {
|
||||||
|
|
||||||
|
@Input() items?: CoreUserTagFeedElement[]; // Area items to render.
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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, Type } from '@angular/core';
|
||||||
|
|
||||||
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate';
|
||||||
|
import { CoreUserTagAreaComponent } from '@features/user/components/tag-area/tag-area';
|
||||||
|
import { CoreTagFeedElement } from '@features/tag/services/tag-helper';
|
||||||
|
import { CoreUserBasicData } from '../user';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to support tags.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class CoreUserTagAreaHandlerService implements CoreTagAreaHandler {
|
||||||
|
|
||||||
|
name = 'CoreUserTagAreaHandler';
|
||||||
|
type = 'core/user';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the handler is enabled on a site level.
|
||||||
|
*
|
||||||
|
* @return Whether or not the handler is enabled on a site level.
|
||||||
|
*/
|
||||||
|
async isEnabled(): Promise<boolean> {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the rendered content of a tag index and returns the items.
|
||||||
|
*
|
||||||
|
* @param content Rendered content.
|
||||||
|
* @return Area items (or promise resolved with the items).
|
||||||
|
*/
|
||||||
|
parseContent(content: string): CoreUserTagFeedElement[] {
|
||||||
|
const items: CoreUserTagFeedElement[] = [];
|
||||||
|
const element = CoreDomUtils.instance.convertToElement(content);
|
||||||
|
|
||||||
|
Array.from(element.querySelectorAll('div.user-box')).forEach((userbox: HTMLElement) => {
|
||||||
|
const avatarLink = userbox.querySelector('a:first-child');
|
||||||
|
if (!avatarLink) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const profileUrl = avatarLink.getAttribute('href') || '';
|
||||||
|
const match = profileUrl.match(/.*\/user\/(?:profile|view)\.php\?id=(\d+)/);
|
||||||
|
if (!match) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const avatarImg = avatarLink.querySelector('img.userpicture');
|
||||||
|
const avatarUrl = avatarImg ? avatarImg.getAttribute('src') : '';
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
avatarUrl,
|
||||||
|
heading: userbox.innerText,
|
||||||
|
details: [],
|
||||||
|
user: {
|
||||||
|
id: Number(match[1]),
|
||||||
|
profileimageurl: avatarUrl || '',
|
||||||
|
fullname: userbox.innerText,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the component to use to display items.
|
||||||
|
*
|
||||||
|
* @param injector Injector.
|
||||||
|
* @return The component (or promise resolved with component) to use, undefined if not found.
|
||||||
|
*/
|
||||||
|
getComponent(): Type<unknown> | Promise<Type<unknown>> {
|
||||||
|
return CoreUserTagAreaComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CoreUserTagAreaHandler extends makeSingleton(CoreUserTagAreaHandlerService) {}
|
||||||
|
|
||||||
|
export type CoreUserTagFeedElement = CoreTagFeedElement & {
|
||||||
|
user: CoreUserBasicData;
|
||||||
|
};
|
|
@ -25,6 +25,8 @@ import { CoreContentLinksDelegate } from '@features/contentlinks/services/conten
|
||||||
import { CoreUserProfileLinkHandler } from './services/handlers/profile-link';
|
import { CoreUserProfileLinkHandler } from './services/handlers/profile-link';
|
||||||
import { CoreCronDelegate } from '@services/cron';
|
import { CoreCronDelegate } from '@services/cron';
|
||||||
import { CoreUserSyncCronHandler } from './services/handlers/sync-cron';
|
import { CoreUserSyncCronHandler } from './services/handlers/sync-cron';
|
||||||
|
import { CoreUserTagAreaHandler } from './services/handlers/tag-area-handler';
|
||||||
|
import { CoreTagAreaDelegate } from '@features/tag/services/tag-area-delegate';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -55,6 +57,7 @@ const routes: Routes = [
|
||||||
CoreUserDelegate.instance.registerHandler(CoreUserProfileMailHandler.instance);
|
CoreUserDelegate.instance.registerHandler(CoreUserProfileMailHandler.instance);
|
||||||
CoreContentLinksDelegate.instance.registerHandler(CoreUserProfileLinkHandler.instance);
|
CoreContentLinksDelegate.instance.registerHandler(CoreUserProfileLinkHandler.instance);
|
||||||
CoreCronDelegate.instance.register(CoreUserSyncCronHandler.instance);
|
CoreCronDelegate.instance.register(CoreUserSyncCronHandler.instance);
|
||||||
|
CoreTagAreaDelegate.instance.registerHandler(CoreUserTagAreaHandler.instance);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue