@eolme/vma-router
Version:
Router for VK Mini Apps
166 lines (129 loc) • 4.75 kB
text/typescript
import History from './History';
import Route from './Route';
import type { RouteList, RouteParams, RouterCache, Popout, Modal, Page, HistoryEvent } from '../types';
import { log } from '../utils/report';
class Router {
private static _name = '[Router]';
cache!: RouterCache;
history!: History;
constructor(routes: RouteList) {
this.cache = new Map();
this.history = new History(routes);
this.history.on('update', this._saveCache.bind(this));
this.history.on('reload', this._replaceFromLocation.bind(this));
}
private _saveCache(event: HistoryEvent) {
log(Router._name, 'Auto save cache.');
this.cache.set(event.next.view, event.next.panel);
this.cache.set(event.prev.view, event.prev.panel);
}
private _replaceFromLocation() {
log(Router._name, 'Auto replace from location.');
const nextRoute = Route.buildFromLocation(this.history.routes, this.history.location);
this.history.replace(nextRoute);
}
pushPage(page: Page, params: RouteParams = {}) {
log(Router._name, 'Call pushPage with', page);
const nextRoute = Route.buildFromPage(this.history.routes, page, params);
this.history.push(nextRoute);
}
replacePage(page: Page, params: RouteParams = {}) {
log(Router._name, 'Call replacePage with', page);
const nextRoute = Route.buildFromPage(this.history.routes, page, params);
this.history.replace(nextRoute);
}
popPage() {
log(Router._name, 'Call popPage.');
this.history.back();
}
pushPageAfterMove(prevPage: Page, nextPage: Page, params: RouteParams = {}) {
log(Router._name, 'Call pushPageAfterMove from', prevPage, 'to', nextPage);
const prevRoute = Route.buildFromPage(this.history.routes, prevPage);
const nextRoute = Route.buildFromPage(this.history.routes, nextPage, params);
this.history.pushAfterMove(prevRoute, nextRoute);
}
pushModal(modal: Modal, params: RouteParams = {}) {
log(Router._name, 'Call pushModal with', modal);
const currentRoute = this.history.route;
const nextRoute = currentRoute.clone();
nextRoute.modal = modal;
nextRoute.params = params;
nextRoute.compile(currentRoute.page);
this.history.push(nextRoute);
}
replaceModal(modal: Modal, params: RouteParams = {}) {
log(Router._name, 'Call replaceModal with', modal);
const currentRoute = this.history.route;
const nextRoute = currentRoute.clone();
nextRoute.modal = modal;
nextRoute.params = params;
nextRoute.compile(currentRoute.page);
if (currentRoute.hasModal) {
this.history.replace(nextRoute);
} else {
this.history.push(nextRoute);
}
}
pushPopup(popup: Popout, params: RouteParams = {}) {
log(Router._name, 'Call pushPopup with', popup);
const currentRoute = this.history.route;
const nextRoute = currentRoute.clone();
nextRoute.popout = popup;
nextRoute.params = params;
nextRoute.compile(currentRoute.page);
this.history.push(nextRoute);
}
replacePopup(popup: Popout, params: RouteParams = {}) {
log(Router._name, 'Call replacePopup with', popup);
const currentRoute = this.history.route;
const nextRoute = currentRoute.clone();
nextRoute.popout = popup;
nextRoute.params = params;
nextRoute.compile(currentRoute.page);
if (currentRoute.hasPopout) {
this.history.replace(nextRoute);
} else {
this.history.push(nextRoute);
}
}
popPageIfModal() {
log(Router._name, 'Call popPageIfModal.');
const currentRoute = this.history.route;
if (currentRoute.hasModal) {
this.history.back();
} else {
log(Router._name, 'No modal was found.');
}
}
popPageIfPopup() {
log(Router._name, 'Call popPageIfPopup.');
const currentRoute = this.history.route;
if (currentRoute.hasPopout) {
this.history.back();
} else {
log(Router._name, 'No popout was found.');
}
}
popPageIfModalOrPopup() {
log(Router._name, 'Call popPageIfModalOrPopup.');
const currentRoute = this.history.route;
if (currentRoute.hasModal || currentRoute.hasPopout) {
this.history.back();
} else {
log(Router._name, 'No modal or popup was found.');
}
}
canMoveTo(page: Page, params: RouteParams = {}) {
const route = Route.buildFromPage(this.history.routes, page, params);
const index = this.history.lastIndexOf(route);
return this.history.canMoveTo(index);
}
moveTo(page: Page, params: RouteParams = {}) {
log(Router._name, 'Call moveTo with', page);
const route = Route.buildFromPage(this.history.routes, page, params);
const index = this.history.lastIndexOf(route);
this.history.moveTo(index);
}
}
export { Router };
export default Router;