Files
outline/app/models/User.ts
Tom Moor db73879918 Assorted cleanup, minor bug fixes, styling fixes, eslint rules (#5165
* fix: Logic error in toast
fix: Remove useless component

* fix: Logout not clearing all stores

* Add icons to notification settings

* Add eslint rule to enforce spaced comment

* Add eslint rule for arrow-body-style

* Add eslint rule to enforce self-closing components

* Add menu to api key settings
Fix: Deleting webhook subscription does not remove from UI
Split webhook subscriptions into active and inactive
Styling updates
2023-04-08 05:25:20 -07:00

151 lines
3.2 KiB
TypeScript

import { subMinutes } from "date-fns";
import { computed, action, observable } from "mobx";
import { now } from "mobx-utils";
import {
NotificationEventDefaults,
NotificationEventType,
UserPreference,
UserPreferences,
} from "@shared/types";
import type { Role, NotificationSettings } from "@shared/types";
import { client } from "~/utils/ApiClient";
import ParanoidModel from "./ParanoidModel";
import Field from "./decorators/Field";
class User extends ParanoidModel {
@Field
@observable
id: string;
@Field
@observable
avatarUrl: string;
@Field
@observable
name: string;
@Field
@observable
color: string;
@Field
@observable
language: string;
@Field
@observable
preferences: UserPreferences | null;
@Field
@observable
notificationSettings: NotificationSettings;
email: string;
isAdmin: boolean;
isViewer: boolean;
lastActiveAt: string;
isSuspended: boolean;
@computed
get initial(): string {
return this.name ? this.name[0] : "?";
}
@computed
get isInvited(): boolean {
return !this.lastActiveAt;
}
/**
* Whether the user has been recently active. Recently is currently defined
* as within the last 5 minutes.
*
* @returns true if the user has been active recently
*/
@computed
get isRecentlyActive(): boolean {
return new Date(this.lastActiveAt) > subMinutes(now(10000), 5);
}
@computed
get role(): Role {
if (this.isAdmin) {
return "admin";
} else if (this.isViewer) {
return "viewer";
} else {
return "member";
}
}
/**
* Returns the current preference for the given notification event type taking
* into account the default system value.
*
* @param type The type of notification event
* @returns The current preference
*/
public subscribedToEventType = (type: NotificationEventType) =>
this.notificationSettings[type] ?? NotificationEventDefaults[type] ?? false;
/**
* Sets a preference for the users notification settings on the model and
* saves the change to the server.
*
* @param type The type of notification event
* @param value Set the preference to true/false
*/
@action
setNotificationEventType = async (
eventType: NotificationEventType,
value: boolean
) => {
this.notificationSettings = {
...this.notificationSettings,
[eventType]: value,
};
if (value) {
await client.post(`/users.notificationsSubscribe`, {
eventType,
});
} else {
await client.post(`/users.notificationsUnsubscribe`, {
eventType,
});
}
};
/**
* Get the value for a specific preference key, or return the fallback if
* none is set.
*
* @param key The UserPreference key to retrieve
* @param fallback An optional fallback value, defaults to false.
* @returns The value
*/
getPreference(key: UserPreference, fallback = false): boolean {
return this.preferences?.[key] ?? fallback;
}
/**
* Set the value for a specific preference key.
*
* @param key The UserPreference key to retrieve
* @param value The value to set
*/
setPreference(key: UserPreference, value: boolean) {
this.preferences = {
...this.preferences,
[key]: value,
};
}
}
export default User;