forked from EVOgeek/Vmeda.Online
		
	MOBILE-3592 user: Implement user tag area handler
This commit is contained in:
		
							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> | ||||||
							
								
								
									
										30
									
								
								src/core/features/user/components/tag-area/tag-area.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/core/features/user/components/tag-area/tag-area.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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.
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								src/core/features/user/services/handlers/tag-area-handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/core/features/user/services/handlers/tag-area-handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user