mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-18 23:52:52 +00:00
176 lines
4.9 KiB
TypeScript
176 lines
4.9 KiB
TypeScript
/*
|
|
* Copyright (C) 2023 StApps
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation, version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
import {AfterViewInit, Component, HostListener, Input, OnInit, ViewChild} from '@angular/core';
|
|
import {Location} from '@angular/common';
|
|
import {ActivatedRoute, Router} from '@angular/router';
|
|
import {AnimationController, IonRouterOutlet} from '@ionic/angular';
|
|
import {SharedAxisChoreographer} from '../../../animation/animation-choreographer';
|
|
import {materialSharedAxisX} from '../../../animation/material-motion';
|
|
import {ScheduleResponsiveBreakpoint} from './schema/schema';
|
|
import {CalendarService} from '../../calendar/calendar.service';
|
|
import moment from 'moment';
|
|
import {fabExpand} from '../../../animation/fab-expand';
|
|
|
|
/**
|
|
* This needs to be sorted by break point low -> high
|
|
*
|
|
* Last entry must have `until: Infinity`
|
|
*/
|
|
const responsiveConfig: ScheduleResponsiveBreakpoint[] = [
|
|
{
|
|
until: 768,
|
|
days: 3,
|
|
startOf: 'day',
|
|
},
|
|
{
|
|
until: 1700,
|
|
days: 3,
|
|
startOf: 'day',
|
|
},
|
|
{
|
|
until: Number.POSITIVE_INFINITY,
|
|
days: 7,
|
|
startOf: 'week',
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Component that displays the schedule
|
|
*/
|
|
@Component({
|
|
selector: 'stapps-schedule-page',
|
|
templateUrl: 'schedule-page.html',
|
|
styleUrls: ['schedule-page.scss'],
|
|
animations: [materialSharedAxisX],
|
|
})
|
|
export class SchedulePageComponent implements OnInit, AfterViewInit {
|
|
/**
|
|
* Current width of the window
|
|
*/
|
|
private currentWindowWidth: number = window.innerWidth;
|
|
|
|
/**
|
|
* Actual Segment Tab
|
|
*/
|
|
actualSegmentValue?: string | null;
|
|
|
|
/**
|
|
* Trigger event to go to today in calendar component
|
|
*/
|
|
|
|
/**
|
|
* Layout
|
|
*/
|
|
layout: ScheduleResponsiveBreakpoint = SchedulePageComponent.getDaysToDisplay(this.currentWindowWidth);
|
|
|
|
@ViewChild('segment') segmentView!: HTMLIonSegmentElement;
|
|
|
|
/**
|
|
* Show the navigation drawer
|
|
*/
|
|
@Input() showDrawer = true;
|
|
|
|
/**
|
|
* Search value from search bar
|
|
*/
|
|
queryText: string;
|
|
|
|
/**
|
|
* Choreographer for the tab switching
|
|
*/
|
|
tabChoreographer: SharedAxisChoreographer<string | null | undefined>;
|
|
|
|
isModalOpen = false;
|
|
|
|
fabAnimation = fabExpand(this.animationController);
|
|
|
|
/**
|
|
* Amount of days that should be shown according to current display width
|
|
*/
|
|
static getDaysToDisplay(width: number): ScheduleResponsiveBreakpoint {
|
|
// the search could be optimized, but probably would have little
|
|
// actual effect with five entries.
|
|
// we can be sure we get an hit when the last value.until is infinity
|
|
// (unless someone has a display that reaches across the universe)
|
|
return (
|
|
responsiveConfig.find(value => width < value.until) ?? responsiveConfig[responsiveConfig.length - 1]
|
|
);
|
|
}
|
|
|
|
constructor(
|
|
private readonly activatedRoute: ActivatedRoute,
|
|
private calendarService: CalendarService,
|
|
readonly routerOutlet: IonRouterOutlet,
|
|
private router: Router,
|
|
private animationController: AnimationController,
|
|
private location: Location,
|
|
) {}
|
|
|
|
ngOnInit() {
|
|
this.onInit();
|
|
}
|
|
|
|
/**
|
|
* ngOnInit is not reliably called after first navigation to app/schedule. This leads to URL and segmentView being out of sync.
|
|
* ionViewWillEnter is called on second, third, ... navigation to app/schedule
|
|
*/
|
|
ionViewWillEnter() {
|
|
this.onInit();
|
|
this.segmentView.value = this.tabChoreographer.currentValue;
|
|
}
|
|
|
|
ngAfterViewInit() {
|
|
this.segmentView.value = this.tabChoreographer.currentValue;
|
|
}
|
|
|
|
onInit() {
|
|
this.tabChoreographer = new SharedAxisChoreographer(this.activatedRoute.snapshot.paramMap.get('mode'), [
|
|
'calendar',
|
|
'recurring',
|
|
'single',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Resize callback
|
|
*
|
|
* Note: this may not fire when the browser transfers from full screen to windowed
|
|
* (Firefox & Chrome tested)
|
|
*/
|
|
@HostListener('window:resize', ['$event'])
|
|
onResize(_: UIEvent) {
|
|
const current = SchedulePageComponent.getDaysToDisplay(this.currentWindowWidth);
|
|
const next = SchedulePageComponent.getDaysToDisplay(window.innerWidth);
|
|
this.currentWindowWidth = window.innerWidth;
|
|
|
|
if (current.days === next.days) {
|
|
this.layout = next;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When the segment changes
|
|
*/
|
|
onSegmentChange() {
|
|
const url = this.router.createUrlTree(['schedule', this.segmentView.value]).toString();
|
|
this.location.go(url);
|
|
this.tabChoreographer.changeViewForState(this.segmentView.value);
|
|
}
|
|
|
|
onTodayClick() {
|
|
this.calendarService.emitGoToDate(moment().startOf('day'));
|
|
}
|
|
}
|