Added some qol improvements
This commit is contained in:
@@ -49,10 +49,10 @@ public class UnitsController : ControllerBase {
|
|||||||
Desc = 7
|
Desc = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 1; i < substitutions.ChildNodes.Count; i++) {
|
for (int i = 2; i < substitutions.ChildNodes.Count; i++) {
|
||||||
var node = substitutions.ChildNodes[i];
|
var node = substitutions.ChildNodes[i];
|
||||||
if (node.ChildNodes.Count < 8) continue;
|
if (node.ChildNodes.Count < 8) continue;
|
||||||
if (!node.ChildNodes[cols.Times].InnerText.Contains("-")) continue;
|
if (node.ChildNodes[cols.Times].InnerText.Contains("//")) continue;
|
||||||
|
|
||||||
var substitution = new Substitution {
|
var substitution = new Substitution {
|
||||||
Times = node.ChildNodes[cols.Times].InnerText.Split(" - ").Select(int.Parse).ToArray(),
|
Times = node.ChildNodes[cols.Times].InnerText.Split(" - ").Select(int.Parse).ToArray(),
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {HttpClient} from "@angular/common/http";
|
import {HttpClient} from "@angular/common/http";
|
||||||
import {firstValueFrom} from "rxjs";
|
import {firstValueFrom, Observable} from "rxjs";
|
||||||
import {environment} from "../../environments/environment";
|
import {environment} from "../../environments/environment";
|
||||||
import {IServService} from "./iserv.service";
|
import {IServService} from "./iserv.service";
|
||||||
|
import {Lesson} from "../entities/course";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -11,23 +12,56 @@ export class StorageService {
|
|||||||
|
|
||||||
constructor(private client: HttpClient) {}
|
constructor(private client: HttpClient) {}
|
||||||
|
|
||||||
public async getItem<T>(item: string, isJson: boolean = true): Promise<T> {
|
public async getItem<T>(item: string, isJson: boolean = true, defaultValue: T = undefined): Promise<T> {
|
||||||
try {
|
try {
|
||||||
const data = await firstValueFrom(this.client.get<{value: string}>(environment.backend + `/storage?user=${IServService.userdata.username}&item=${item}`));
|
const data = await firstValueFrom(this.client.get<{value: string}>(environment.backend + `/storage?user=${IServService.userdata.username}&item=${item}`));
|
||||||
|
|
||||||
if (isJson) return JSON.parse(data.value) as T;
|
if (isJson) return JSON.parse(data.value) as T;
|
||||||
return data.value as T;
|
else return data.value as T;
|
||||||
}catch {
|
}catch {
|
||||||
return undefined;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getItemLocal<T>(item: string, isJson: boolean = true, defaultValue: T = undefined): Observable<T> {
|
||||||
|
return new Observable<T>((result) => {
|
||||||
|
const local = localStorage.getItem(item);
|
||||||
|
|
||||||
|
if (local != undefined) {
|
||||||
|
if (isJson) result.next(JSON.parse(local) as T);
|
||||||
|
else result.next(local as T);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
const response = await this.getItem<T>(item, isJson, defaultValue);
|
||||||
|
localStorage.setItem(item, isJson ? JSON.stringify(response) : response as string);
|
||||||
|
result.next(response);
|
||||||
|
result.complete();
|
||||||
|
}, 0);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public async setItem(item: string, value: any) {
|
public async setItem(item: string, value: any) {
|
||||||
|
localStorage.setItem(item, value);
|
||||||
await firstValueFrom(this.client.post(environment.backend + `/storage?user=${IServService.userdata.username}&item=${item}`, value));
|
await firstValueFrom(this.client.post(environment.backend + `/storage?user=${IServService.userdata.username}&item=${item}`, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async clear() {
|
public isLessonThisWeek(lesson: Lesson): boolean {
|
||||||
await firstValueFrom(this.client.delete(environment.backend + `/storage?user=${IServService.userdata.username}`));
|
const week = this.getWeek(new Date()) % 2;
|
||||||
|
const label = week == 0 ? "a" : "b";
|
||||||
|
return (lesson != undefined && (lesson.week == "all" || lesson.week == label));
|
||||||
|
}
|
||||||
|
|
||||||
|
private getWeek(orig: Date): number {
|
||||||
|
const date = new Date(orig.getTime());
|
||||||
|
date.setHours(0, 0, 0, 0);
|
||||||
|
// Thursday in current week decides the year.
|
||||||
|
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
|
||||||
|
// January 4 is always in week 1.
|
||||||
|
const week1 = new Date(date.getFullYear(), 0, 4);
|
||||||
|
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
|
||||||
|
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000
|
||||||
|
- 3 + (week1.getDay() + 6) % 7) / 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class AppComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async logout() {
|
public async logout() {
|
||||||
await this.storage.clear();
|
localStorage.clear();
|
||||||
this.iserv.logout();
|
this.iserv.logout();
|
||||||
await this.router.navigate(["login"]);
|
await this.router.navigate(["login"]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,14 +42,15 @@ export class HomePage implements OnInit {
|
|||||||
const classPromise = this.iserv.getCoursesAndClass();
|
const classPromise = this.iserv.getCoursesAndClass();
|
||||||
const subsPromise = this.units.getSubstitutionPlan("today");
|
const subsPromise = this.units.getSubstitutionPlan("today");
|
||||||
const timetablePromise = this.storage.getItem<Timetable>("timetable");
|
const timetablePromise = this.storage.getItem<Timetable>("timetable");
|
||||||
await Promise.all([classPromise, subsPromise, timetablePromise]);
|
await Promise.all([classPromise, subsPromise]);
|
||||||
|
|
||||||
this.classData = await classPromise;
|
this.classData = await classPromise;
|
||||||
let unitsData = await subsPromise;
|
let unitsData = await subsPromise;
|
||||||
|
|
||||||
const timetable = await timetablePromise;
|
const timetable = await timetablePromise;
|
||||||
|
|
||||||
if (scheduleDay != undefined && timetable != undefined) {
|
if (scheduleDay != undefined && timetable != undefined) {
|
||||||
this.lessons = timetable[scheduleDay].filter(lesson => lesson != undefined);
|
this.lessons = timetable[scheduleDay].filter(lesson => lesson != undefined && this.storage.isLessonThisWeek(lesson));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.dateIsPast(unitsData.date, this.today)) {
|
if (this.dateIsPast(unitsData.date, this.today)) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title>BetterIServ</ion-title>
|
<ion-title>BetterIServ</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
|
<ion-progress-bar type="indeterminate" *ngIf="showLoading" />
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content [fullscreen]="true">
|
<ion-content [fullscreen]="true">
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import {Router} from "@angular/router";
|
|||||||
})
|
})
|
||||||
export class LoginPage implements OnInit {
|
export class LoginPage implements OnInit {
|
||||||
|
|
||||||
|
public showLoading: boolean = false;
|
||||||
|
|
||||||
constructor(private iservApi: IServService, private router: Router, private alerts: AlertController) { }
|
constructor(private iservApi: IServService, private router: Router, private alerts: AlertController) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@@ -21,12 +23,16 @@ export class LoginPage implements OnInit {
|
|||||||
|
|
||||||
public async onLogin(email?: string, password?: string) {
|
public async onLogin(email?: string, password?: string) {
|
||||||
if (email == undefined || password == undefined) return;
|
if (email == undefined || password == undefined) return;
|
||||||
|
if (this.showLoading) return;
|
||||||
|
this.showLoading = true;
|
||||||
|
|
||||||
if (await this.iservApi.login(email, password)) {
|
if (await this.iservApi.login(email, password)) {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
|
this.showLoading = false;
|
||||||
await this.router.navigate(['home']);
|
await this.router.navigate(['home']);
|
||||||
}, 500);
|
}, 500);
|
||||||
}else {
|
}else {
|
||||||
|
this.showLoading = false;
|
||||||
const alert = await this.alerts.create({
|
const alert = await this.alerts.create({
|
||||||
header: "Fehler",
|
header: "Fehler",
|
||||||
message: "Die angegebenen Logindaten sind nicht korrekt!",
|
message: "Die angegebenen Logindaten sind nicht korrekt!",
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
<ion-label *ngIf="day == 'thu'">Do</ion-label>
|
<ion-label *ngIf="day == 'thu'">Do</ion-label>
|
||||||
<ion-label *ngIf="day == 'fri'">Fr</ion-label>
|
<ion-label *ngIf="day == 'fri'">Fr</ion-label>
|
||||||
|
|
||||||
<lesson *ngFor="let lesson of timetable[day] | week; let i = index" [ngClass]="{'hide': lesson == undefined}" (click)="onEditOrAdd(undefined, {lesson, day, time: i})" [lesson]="lesson" [courses]="courses" />
|
<lesson *ngFor="let lesson of timetable[day]; let i = index" [ngClass]="{'hide': lesson == undefined, 'off-week': !storage.isLessonThisWeek(lesson)}" (click)="onEditOrAdd(undefined, {lesson, day, time: i})" [lesson]="lesson" [courses]="courses" />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|||||||
@@ -38,5 +38,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hide {
|
.hide {
|
||||||
opacity: 0;
|
opacity: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.off-week {
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import {Component, ElementRef, NgZone, OnInit, ViewChild} from '@angular/core';
|
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import {IonicModule, IonModal} from '@ionic/angular';
|
import {IonicModule, IonModal} from '@ionic/angular';
|
||||||
import {IServService} from "../../api/iserv.service";
|
import {IServService} from "../../api/iserv.service";
|
||||||
import {Course, Lesson, Timetable} from "../../entities/course";
|
import {Course, Lesson, Timetable} from "../../entities/course";
|
||||||
import {WeekPipe} from "../../pipes/week.pipe";
|
|
||||||
import {LessonComponent} from "../../components/lesson/lesson.component";
|
import {LessonComponent} from "../../components/lesson/lesson.component";
|
||||||
import {StorageService} from "../../api/storage.service";
|
import {StorageService} from "../../api/storage.service";
|
||||||
|
|
||||||
@@ -13,7 +12,7 @@ import {StorageService} from "../../api/storage.service";
|
|||||||
templateUrl: './schedule.page.html',
|
templateUrl: './schedule.page.html',
|
||||||
styleUrls: ['./schedule.page.scss'],
|
styleUrls: ['./schedule.page.scss'],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [IonicModule, CommonModule, FormsModule, WeekPipe, LessonComponent]
|
imports: [IonicModule, CommonModule, FormsModule, LessonComponent]
|
||||||
})
|
})
|
||||||
export class SchedulePage implements OnInit {
|
export class SchedulePage implements OnInit {
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ export class SchedulePage implements OnInit {
|
|||||||
@ViewChild('courseModal') courseModal: IonModal;
|
@ViewChild('courseModal') courseModal: IonModal;
|
||||||
@ViewChild('tableModal') tableModal: IonModal;
|
@ViewChild('tableModal') tableModal: IonModal;
|
||||||
|
|
||||||
constructor(public iserv: IServService, private storage: StorageService) { }
|
constructor(public iserv: IServService, public storage: StorageService) { }
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.courses = (await this.iserv.getCoursesAndClass()).courses;
|
this.courses = (await this.iserv.getCoursesAndClass()).courses;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
<section *ngIf="showNews">
|
<section *ngIf="showNews">
|
||||||
<ion-card *ngFor="let info of data?.notifications">
|
<ion-card *ngFor="let info of data?.notifications">
|
||||||
<ion-card-content>
|
<ion-card-content>
|
||||||
<ion-label [innerHtml]="info" style="color: #FFF"/>
|
<ion-label [innerHtml]="info" style="color: var(--ion-text-color)"/>
|
||||||
</ion-card-content>
|
</ion-card-content>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core';
|
|
||||||
import {Lesson} from "../entities/course";
|
|
||||||
|
|
||||||
@Pipe({
|
|
||||||
name: 'week',
|
|
||||||
standalone: true
|
|
||||||
})
|
|
||||||
export class WeekPipe implements PipeTransform {
|
|
||||||
|
|
||||||
transform(objects: Lesson[]): Lesson[] {
|
|
||||||
if (objects == undefined) return [];
|
|
||||||
|
|
||||||
const week = this.getWeek(new Date()) % 2;
|
|
||||||
const label = week == 0 ? "a" : "b";
|
|
||||||
const result = [];
|
|
||||||
for (let lesson of objects) {
|
|
||||||
if (lesson != undefined && (lesson.week == "all" || lesson.week == label))
|
|
||||||
result.push(lesson);
|
|
||||||
else result.push(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getWeek(orig: Date): number {
|
|
||||||
const date = new Date(orig.getTime());
|
|
||||||
date.setHours(0, 0, 0, 0);
|
|
||||||
// Thursday in current week decides the year.
|
|
||||||
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
|
|
||||||
// January 4 is always in week 1.
|
|
||||||
const week1 = new Date(date.getFullYear(), 0, 4);
|
|
||||||
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
|
|
||||||
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000
|
|
||||||
- 3 + (week1.getDay() + 6) % 7) / 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user