| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- import type { ColorScheme } from '@growi/core';
- import { getForcedColorScheme } from '@growi/core/dist/utils';
- import {
- DefaultThemeMetadata,
- manifestPath,
- PresetThemesMetadatas,
- } from '@growi/preset-themes';
- import path from 'path';
- import uglifycss from 'uglifycss';
- import { growiPluginService } from '~/features/growi-plugin/server/services';
- import loggerFactory from '~/utils/logger';
- import type Crowi from '../crowi';
- import S2sMessage from '../models/vo/s2s-message';
- import { configManager } from './config-manager';
- import type { S2sMessageHandlable } from './s2s-messaging/handlable';
- const logger = loggerFactory('growi:service:CustomizeService');
- /**
- * the service class of CustomizeService
- */
- export class CustomizeService implements S2sMessageHandlable {
- s2sMessagingService: any;
- appService: any;
- lastLoadedAt?: Date;
- customCss?: string;
- customTitleTemplate!: string;
- theme: string;
- themeHref: string | undefined;
- forcedColorScheme?: ColorScheme;
- constructor(crowi: Crowi) {
- this.s2sMessagingService = crowi.s2sMessagingService;
- this.appService = crowi.appService;
- }
- /**
- * @inheritdoc
- */
- shouldHandleS2sMessage(s2sMessage) {
- const { eventName, updatedAt } = s2sMessage;
- if (eventName !== 'customizeServiceUpdated' || updatedAt == null) {
- return false;
- }
- return (
- this.lastLoadedAt == null ||
- this.lastLoadedAt < new Date(s2sMessage.updatedAt)
- );
- }
- /**
- * @inheritdoc
- */
- async handleS2sMessage(s2sMessage) {
- logger.info('Reset customized value by pubsub notification');
- await configManager.loadConfigs();
- this.initCustomCss();
- this.initCustomTitle();
- this.initGrowiTheme();
- }
- async publishUpdatedMessage() {
- const { s2sMessagingService } = this;
- if (s2sMessagingService != null) {
- const s2sMessage = new S2sMessage('customizeServiceUpdated', {
- updatedAt: new Date(),
- });
- try {
- await s2sMessagingService.publish(s2sMessage);
- } catch (e) {
- logger.error(
- 'Failed to publish update message with S2sMessagingService: ',
- e.message,
- );
- }
- }
- }
- /**
- * initialize custom css strings
- */
- initCustomCss() {
- const rawCss = configManager.getConfig('customize:css') || '';
- // uglify and store
- this.customCss = uglifycss.processString(rawCss);
- this.lastLoadedAt = new Date();
- }
- getCustomCss() {
- return this.customCss;
- }
- getCustomScript() {
- return configManager.getConfig('customize:script');
- }
- getCustomNoscript() {
- return configManager.getConfig('customize:noscript');
- }
- initCustomTitle() {
- let configValue = configManager.getConfig('customize:title');
- if (configValue == null || configValue.trim().length === 0) {
- configValue = '{{pagename}} - {{sitename}}';
- }
- this.customTitleTemplate = configValue;
- this.lastLoadedAt = new Date();
- }
- async initGrowiTheme(): Promise<void> {
- const theme = configManager.getConfig('customize:theme');
- this.theme = theme;
- const resultForThemePlugin =
- await growiPluginService.findThemePlugin(theme);
- if (resultForThemePlugin != null) {
- this.forcedColorScheme = getForcedColorScheme(
- resultForThemePlugin.themeMetadata.schemeType,
- );
- this.themeHref = resultForThemePlugin.themeHref;
- }
- // retrieve preset theme
- else {
- // import preset-themes manifest
- const presetThemesManifest = await import(
- path.join('@growi/preset-themes', manifestPath)
- ).then((imported) => imported.default);
- const themeMetadata = PresetThemesMetadatas.find((p) => p.name === theme);
- this.forcedColorScheme = getForcedColorScheme(themeMetadata?.schemeType);
- const manifestKey =
- themeMetadata?.manifestKey ?? DefaultThemeMetadata.manifestKey;
- if (
- themeMetadata == null ||
- !(themeMetadata.manifestKey in presetThemesManifest)
- ) {
- logger.warn(
- `Use default theme because the key for '${theme} does not exist in preset-themes manifest`,
- );
- }
- this.themeHref = `/static/preset-themes/${presetThemesManifest[manifestKey].file}`; // configured by express.static
- }
- }
- }
|