Vmeda.Online/src/core/classes/items-management/swipe-navigation-items-manager.ts

122 lines
3.3 KiB
TypeScript
Raw Normal View History

// (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 { ActivatedRoute, ActivatedRouteSnapshot, UrlSegment } from '@angular/router';
import { CoreNavigator } from '@services/navigator';
import { CoreRoutedItemsManager } from './routed-items-manager';
import { CoreRoutedItemsManagerSource } from './routed-items-manager-source';
/**
* Helper class to manage the state and routing of a swipeable page.
*/
2021-12-16 12:29:13 +01:00
export class CoreSwipeNavigationItemsManager<
Item = unknown,
Source extends CoreRoutedItemsManagerSource<Item> = CoreRoutedItemsManagerSource<Item>
>
extends CoreRoutedItemsManager<Item, Source> {
/**
* Process page started operations.
*/
async start(): Promise<void> {
this.updateSelectedItem();
}
/**
* Navigate to the next item.
*/
async navigateToNextItem(): Promise<void> {
await this.navigateToItemBy(-1, 'back');
}
/**
* Navigate to the previous item.
*/
async navigateToPreviousItem(): Promise<void> {
await this.navigateToItemBy(1, 'forward');
}
/**
* @inheritdoc
*/
protected getCurrentPageRoute(): ActivatedRoute | null {
return CoreNavigator.getCurrentRoute();
}
/**
* @inheritdoc
*/
protected getSelectedItemPathFromRoute(route: ActivatedRouteSnapshot): string | null {
const segments: UrlSegment[] = [];
while (route) {
segments.push(...route.url);
if (!route.firstChild) {
break;
}
route = route.firstChild;
}
return segments.map(segment => segment.path).join('/').replace(/\/+/, '/').trim() || null;
}
/**
* Navigate to an item by an offset.
*
* @param delta Index offset.
* @param animationDirection Animation direction.
*/
protected async navigateToItemBy(delta: number, animationDirection: 'forward' | 'back'): Promise<void> {
const item = await this.getItemBy(delta);
if (!item) {
return;
}
await this.navigateToItem(item, { animationDirection, replace: true });
}
/**
* Get item by an offset.
*
* @param delta Index offset.
*/
protected async getItemBy(delta: number): Promise<Item | null> {
const items = this.getSource().getItems();
2021-12-16 12:29:13 +01:00
// Get selected item.
const index = (this.selectedItem && items?.indexOf(this.selectedItem)) ?? -1;
if (index === -1) {
return null;
}
// Get item by delta.
const item = items?.[index + delta] ?? null;
if (!item && !this.getSource().isCompleted()) {
await this.getSource().load();
return this.getItemBy(delta);
}
return item;
}
}