feat: PWA Support (#1488)

This commit is contained in:
sct
2021-04-25 20:44:12 +09:00
committed by GitHub
parent e6e5ad221a
commit 28830d4ef8
88 changed files with 2022 additions and 650 deletions

View File

@@ -29,6 +29,7 @@ import { getSettings } from '../lib/settings';
import logger from '../logger';
import { MediaRequest } from './MediaRequest';
import SeasonRequest from './SeasonRequest';
import { UserPushSubscription } from './UserPushSubscription';
import { UserSettings } from './UserSettings';
@Entity()
@@ -105,6 +106,9 @@ export class User {
})
public settings?: UserSettings;
@OneToMany(() => UserPushSubscription, (pushSub) => pushSub.user)
public pushSubscriptions: UserPushSubscription[];
@CreateDateColumn()
public createdAt: Date;

View File

@@ -0,0 +1,27 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { User } from './User';
@Entity()
export class UserPushSubscription {
@PrimaryGeneratedColumn()
public id: number;
@ManyToOne(() => User, (user) => user.pushSubscriptions, {
eager: true,
onDelete: 'CASCADE',
})
public user: User;
@Column()
public endpoint: string;
@Column()
public p256dh: string;
@Column({ unique: true })
public auth: string;
constructor(init?: Partial<UserPushSubscription>) {
Object.assign(this, init);
}
}

View File

@@ -5,12 +5,15 @@ import {
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import {
hasNotificationAgentEnabled,
NotificationAgentType,
} from '../lib/notifications/agenttypes';
import { NotificationAgentTypes } from '../interfaces/api/userSettingsInterfaces';
import { hasNotificationType, Notification } from '../lib/notifications';
import { NotificationAgentKey } from '../lib/settings';
import { User } from './User';
export const ALL_NOTIFICATIONS = Object.values(Notification)
.filter((v) => !isNaN(Number(v)))
.reduce((a, v) => a + Number(v), 0);
@Entity()
export class UserSettings {
constructor(init?: Partial<UserSettings>) {
@@ -24,15 +27,15 @@ export class UserSettings {
@JoinColumn()
public user: User;
@Column({ default: 'en' })
public locale?: string;
@Column({ nullable: true })
public region?: string;
@Column({ nullable: true })
public originalLanguage?: string;
@Column({ type: 'integer', default: NotificationAgentType.EMAIL })
public notificationAgents = NotificationAgentType.EMAIL;
@Column({ nullable: true })
public pgpKey?: string;
@@ -45,7 +48,63 @@ export class UserSettings {
@Column({ nullable: true })
public telegramSendSilently?: boolean;
public hasNotificationAgentEnabled(agent: NotificationAgentType): boolean {
return !!hasNotificationAgentEnabled(agent, this.notificationAgents);
@Column({
type: 'text',
nullable: true,
transformer: {
from: (value: string | null): Partial<NotificationAgentTypes> => {
const defaultTypes = {
email: ALL_NOTIFICATIONS,
discord: 0,
pushbullet: 0,
pushover: 0,
slack: 0,
telegram: 0,
webhook: 0,
webpush: ALL_NOTIFICATIONS,
};
if (!value) {
return defaultTypes;
}
const values = JSON.parse(value) as Partial<NotificationAgentTypes>;
// Something with the migration to this field has caused some issue where
// the value pre-populates with just a raw "2"? Here we check if that's the case
// and return the default notification types if so
if (typeof values !== 'object') {
return defaultTypes;
}
if (values.email == null) {
values.email = ALL_NOTIFICATIONS;
}
if (values.webpush == null) {
values.webpush = ALL_NOTIFICATIONS;
}
return values;
},
to: (value: Partial<NotificationAgentTypes>): string => {
const allowedKeys = Object.values(NotificationAgentKey);
// Remove any unknown notification agent keys before saving to db
(Object.keys(value) as (keyof NotificationAgentTypes)[]).forEach(
(key) => {
if (!allowedKeys.includes(key)) {
delete value[key];
}
}
);
return JSON.stringify(value);
},
},
})
public notificationTypes: Partial<NotificationAgentTypes>;
public hasNotificationType(key: NotificationAgentKey, type: Notification) {
return hasNotificationType(type, this.notificationTypes[key] ?? 0);
}
}