/* * Copyright (C) 2022 Kristóf Marussy * * This file is part of Sophie. * * Sophie is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * * SPDX-License-Identifier: AGPL-3.0-only */ import type { UnreadCount } from '@sophie/service-shared'; import { Service as ServiceBase } from '@sophie/shared'; import { Instance, getSnapshot, ReferenceIdentifier } from 'mobx-state-tree'; import generateId from '../utils/generateId'; import overrideProps from '../utils/overrideProps'; import { ProfileSettingsSnapshotWithId } from './Profile'; import ServiceSettings, { ServiceSettingsSnapshotIn } from './ServiceSettings'; export interface ServiceConfig extends Omit { id?: string | undefined; profile?: ReferenceIdentifier | undefined; } const Service = overrideProps(ServiceBase, { settings: ServiceSettings, }) .views((self) => ({ get config(): ServiceConfig { const { id, settings } = self; return { ...getSnapshot(settings), id }; }, })) .actions((self) => ({ setLocation({ url, canGoBack, canGoForward, }: { url: string; canGoBack: boolean; canGoForward: boolean; }): void { self.currentUrl = url; self.canGoBack = canGoBack; self.canGoForward = canGoForward; }, setTitle(title: string): void { self.title = title; }, startedLoading(): void { self.state = 'loading'; }, finishedLoading(): void { if (self.state === 'loading') { // Do not overwrite crashed state if the service haven't been reloaded yet. self.state = 'loaded'; } }, crashed(): void { self.state = 'crashed'; }, setUnreadCount({ direct, indirect }: UnreadCount): void { if (direct !== undefined) { self.directMessageCount = direct; } if (indirect !== undefined) { self.indirectMessageCount = indirect; } }, })); /* eslint-disable-next-line @typescript-eslint/no-redeclare -- Intentionally naming the type the same as the store definition. */ interface Service extends Instance {} export default Service; export type ServiceSettingsSnapshotWithId = [string, ServiceSettingsSnapshotIn]; export function addMissingServiceIdsAndProfiles( serviceConfigs: ServiceConfig[] | undefined, profiles: ProfileSettingsSnapshotWithId[], ): ServiceSettingsSnapshotWithId[] { return (serviceConfigs ?? []).map((serviceConfig) => { const { id, ...settings } = serviceConfig; const { name } = settings; let { profile: profileId } = settings; if (profileId === undefined) { profileId = generateId(name); profiles.push([profileId, { name }]); } return [ id === undefined ? generateId(name) : id, { ...settings, profile: profileId }, ]; }); }