Merge pull request #2890 from NoelDeMartin/MOBILE-3320

MOBILE-3320: Forum & Split view improvements
main
Dani Palou 2021-07-13 09:20:06 +02:00 committed by GitHub
commit ad976e2b2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 9 deletions

View File

@ -29,6 +29,7 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { Network, NgZone, Translate } from '@singletons'; import { Network, NgZone, Translate } from '@singletons';
import { CoreArray } from '@singletons/array';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { import {
@ -771,7 +772,9 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
* @return Array containing all the posts of the discussion. * @return Array containing all the posts of the discussion.
*/ */
protected getAllPosts(): Post[] { protected getAllPosts(): Post[] {
return this.posts.map(this.flattenPostHierarchy.bind(this)); const allPosts = this.posts.map(post => this.flattenPostHierarchy(post));
return CoreArray.flatten(allPosts);
} }
/** /**

View File

@ -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 { ActivatedRouteSnapshot, Params, UrlSegment } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot, Params, UrlSegment } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
@ -29,12 +29,12 @@ export abstract class CorePageItemsListManager<Item> {
protected itemsMap: Record<string, Item> | null = null; protected itemsMap: Record<string, Item> | null = null;
protected hasMoreItems = true; protected hasMoreItems = true;
protected selectedItem: Item | null = null; protected selectedItem: Item | null = null;
protected pageComponent: unknown; protected pageRouteLocator?: unknown | ActivatedRoute;
protected splitView?: CoreSplitViewComponent; protected splitView?: CoreSplitViewComponent;
protected splitViewOutletSubscription?: Subscription; protected splitViewOutletSubscription?: Subscription;
constructor(pageComponent: unknown) { constructor(pageRouteLocator: unknown | ActivatedRoute) {
this.pageComponent = pageComponent; this.pageRouteLocator = pageRouteLocator;
} }
get items(): Item[] { get items(): Item[] {
@ -62,7 +62,7 @@ export abstract class CorePageItemsListManager<Item> {
this.watchSplitViewOutlet(splitView); this.watchSplitViewOutlet(splitView);
// Calculate current selected item. // Calculate current selected item.
const route = CoreNavigator.getCurrentRoute({ pageComponent: this.pageComponent }); const route = this.getCurrentPageRoute();
this.updateSelectedItem(route?.snapshot ?? null); this.updateSelectedItem(route?.snapshot ?? null);
// Select default item if none is selected on a non-mobile layout. // Select default item if none is selected on a non-mobile layout.
@ -138,7 +138,7 @@ export abstract class CorePageItemsListManager<Item> {
*/ */
async select(item: Item): Promise<void> { async select(item: Item): Promise<void> {
// Get current route in the page. // Get current route in the page.
const route = CoreNavigator.getCurrentRoute({ pageComponent: this.pageComponent }); const route = this.getCurrentPageRoute();
if (route === null) { if (route === null) {
return; return;
@ -208,7 +208,7 @@ export abstract class CorePageItemsListManager<Item> {
return false; return false;
} }
return !this.splitView?.isNested; return !!this.splitView && !this.splitView?.isNested;
} }
/** /**
@ -253,6 +253,19 @@ export abstract class CorePageItemsListManager<Item> {
return segments.map(segment => segment.path).join('/').replace(/\/+/, '/').trim() || null; return segments.map(segment => segment.path).join('/').replace(/\/+/, '/').trim() || null;
} }
/**
* Get page route.
*
* @returns Current page route, if any.
*/
private getCurrentPageRoute(): ActivatedRoute | null {
if (this.pageRouteLocator instanceof ActivatedRoute) {
return CoreNavigator.isRouteActive(this.pageRouteLocator) ? this.pageRouteLocator : null;
}
return CoreNavigator.getCurrentRoute({ pageComponent: this.pageRouteLocator });
}
/** /**
* Get the page route given a child route on the splitview outlet. * Get the page route given a child route on the splitview outlet.
* *
@ -260,11 +273,28 @@ export abstract class CorePageItemsListManager<Item> {
* @return Page route. * @return Page route.
*/ */
private getPageRouteFromSplitViewOutlet(route: ActivatedRouteSnapshot | null): ActivatedRouteSnapshot | null { private getPageRouteFromSplitViewOutlet(route: ActivatedRouteSnapshot | null): ActivatedRouteSnapshot | null {
while (route && route.component !== this.pageComponent) { const isPageRoute = this.buildRouteMatcher();
while (route && !isPageRoute(route)) {
route = route.parent; route = route.parent;
} }
return route; return route;
} }
/**
* Build a function to check whether the given snapshot belongs to the page.
*
* @returns Route matcher.
*/
private buildRouteMatcher(): (route: ActivatedRouteSnapshot) => boolean {
if (this.pageRouteLocator instanceof ActivatedRoute) {
const pageRoutePath = CoreNavigator.getRouteFullPath(this.pageRouteLocator.snapshot);
return route => CoreNavigator.getRouteFullPath(route) === pageRoutePath;
}
return route => route.component === this.pageRouteLocator;
}
} }

View File

@ -398,6 +398,27 @@ export class CoreNavigatorService {
return pageComponent || routeData ? null : route; return pageComponent || routeData ? null : route;
} }
/**
* Check whether a route is active within the current stack.
*
* @param route Route to check.
* @return Whether the route is active or not.
*/
isRouteActive(route: ActivatedRoute): boolean {
const routePath = this.getRouteFullPath(route.snapshot);
let activeRoute: ActivatedRoute | null = Router.routerState.root;
while (activeRoute) {
if (this.getRouteFullPath(activeRoute.snapshot) === routePath) {
return true;
}
activeRoute = activeRoute.firstChild;
}
return false;
}
/** /**
* Increase the number of times a route is repeated on the navigation stack. * Increase the number of times a route is repeated on the navigation stack.
* *