diff options
author | Chocobozzz <me@florianbigard.com> | 2019-07-10 14:06:19 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-07-24 10:58:16 +0200 |
commit | ffb321bedca46d6987c7b31dd58e5dea96ea2ea2 (patch) | |
tree | 019f0427c1860ae0b00694c43f1be8d5fe1aa995 /server | |
parent | 7cd4d2ba10106c10602c86f74f55743ded588896 (diff) | |
download | PeerTube-ffb321bedca46d6987c7b31dd58e5dea96ea2ea2.tar.gz PeerTube-ffb321bedca46d6987c7b31dd58e5dea96ea2ea2.tar.zst PeerTube-ffb321bedca46d6987c7b31dd58e5dea96ea2ea2.zip |
WIP plugins: load theme on client side
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/config.ts | 5 | ||||
-rw-r--r-- | server/controllers/themes.ts | 10 | ||||
-rw-r--r-- | server/initializers/constants.ts | 6 | ||||
-rw-r--r-- | server/initializers/migrations/0400-user-theme.ts | 2 | ||||
-rw-r--r-- | server/lib/client-html.ts | 9 | ||||
-rw-r--r-- | server/lib/plugins/theme-utils.ts | 10 | ||||
-rw-r--r-- | server/models/account/user.ts | 6 |
7 files changed, 30 insertions, 18 deletions
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 088234074..81518bbb5 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts | |||
@@ -4,7 +4,7 @@ import { ServerConfig, UserRight } from '../../../shared' | |||
4 | import { About } from '../../../shared/models/server/about.model' | 4 | import { About } from '../../../shared/models/server/about.model' |
5 | import { CustomConfig } from '../../../shared/models/server/custom-config.model' | 5 | import { CustomConfig } from '../../../shared/models/server/custom-config.model' |
6 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup' | 6 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup' |
7 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' | 7 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME } from '../../initializers/constants' |
8 | import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares' | 8 | import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares' |
9 | import { customConfigUpdateValidator } from '../../middlewares/validators/config' | 9 | import { customConfigUpdateValidator } from '../../middlewares/validators/config' |
10 | import { ClientHtml } from '../../lib/client-html' | 10 | import { ClientHtml } from '../../lib/client-html' |
@@ -69,10 +69,11 @@ async function getConfig (req: express.Request, res: express.Response) { | |||
69 | name: t.name, | 69 | name: t.name, |
70 | version: t.version, | 70 | version: t.version, |
71 | description: t.description, | 71 | description: t.description, |
72 | css: t.css, | ||
72 | clientScripts: t.clientScripts | 73 | clientScripts: t.clientScripts |
73 | })) | 74 | })) |
74 | 75 | ||
75 | const defaultTheme = getThemeOrDefault(CONFIG.THEME.DEFAULT) | 76 | const defaultTheme = getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME) |
76 | 77 | ||
77 | const json: ServerConfig = { | 78 | const json: ServerConfig = { |
78 | instance: { | 79 | instance: { |
diff --git a/server/controllers/themes.ts b/server/controllers/themes.ts index 20e7062d0..104c285ad 100644 --- a/server/controllers/themes.ts +++ b/server/controllers/themes.ts | |||
@@ -1,13 +1,11 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { PLUGIN_GLOBAL_CSS_PATH } from '../initializers/constants' | ||
3 | import { join } from 'path' | 2 | import { join } from 'path' |
4 | import { RegisteredPlugin } from '../lib/plugins/plugin-manager' | 3 | import { RegisteredPlugin } from '../lib/plugins/plugin-manager' |
5 | import { servePluginStaticDirectoryValidator } from '../middlewares/validators/plugins' | ||
6 | import { serveThemeCSSValidator } from '../middlewares/validators/themes' | 4 | import { serveThemeCSSValidator } from '../middlewares/validators/themes' |
7 | 5 | ||
8 | const themesRouter = express.Router() | 6 | const themesRouter = express.Router() |
9 | 7 | ||
10 | themesRouter.get('/:themeName/:themeVersion/css/:staticEndpoint', | 8 | themesRouter.get('/:themeName/:themeVersion/css/:staticEndpoint(*)', |
11 | serveThemeCSSValidator, | 9 | serveThemeCSSValidator, |
12 | serveThemeCSSDirectory | 10 | serveThemeCSSDirectory |
13 | ) | 11 | ) |
@@ -24,5 +22,9 @@ function serveThemeCSSDirectory (req: express.Request, res: express.Response) { | |||
24 | const plugin: RegisteredPlugin = res.locals.registeredPlugin | 22 | const plugin: RegisteredPlugin = res.locals.registeredPlugin |
25 | const staticEndpoint = req.params.staticEndpoint | 23 | const staticEndpoint = req.params.staticEndpoint |
26 | 24 | ||
27 | return express.static(join(plugin.path, staticEndpoint), { fallthrough: false }) | 25 | if (plugin.css.includes(staticEndpoint) === false) { |
26 | return res.sendStatus(404) | ||
27 | } | ||
28 | |||
29 | return res.sendFile(join(plugin.path, staticEndpoint)) | ||
28 | } | 30 | } |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 9d61ed537..e5f88b71d 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -585,7 +585,8 @@ const P2P_MEDIA_LOADER_PEER_VERSION = 2 | |||
585 | const PLUGIN_GLOBAL_CSS_FILE_NAME = 'plugins-global.css' | 585 | const PLUGIN_GLOBAL_CSS_FILE_NAME = 'plugins-global.css' |
586 | const PLUGIN_GLOBAL_CSS_PATH = join(CONFIG.STORAGE.TMP_DIR, PLUGIN_GLOBAL_CSS_FILE_NAME) | 586 | const PLUGIN_GLOBAL_CSS_PATH = join(CONFIG.STORAGE.TMP_DIR, PLUGIN_GLOBAL_CSS_FILE_NAME) |
587 | 587 | ||
588 | const DEFAULT_THEME = 'default' | 588 | const DEFAULT_THEME_NAME = 'default' |
589 | const DEFAULT_USER_THEME_NAME = 'instance-default' | ||
589 | 590 | ||
590 | // --------------------------------------------------------------------------- | 591 | // --------------------------------------------------------------------------- |
591 | 592 | ||
@@ -660,6 +661,7 @@ export { | |||
660 | PREVIEWS_SIZE, | 661 | PREVIEWS_SIZE, |
661 | REMOTE_SCHEME, | 662 | REMOTE_SCHEME, |
662 | FOLLOW_STATES, | 663 | FOLLOW_STATES, |
664 | DEFAULT_USER_THEME_NAME, | ||
663 | SERVER_ACTOR_NAME, | 665 | SERVER_ACTOR_NAME, |
664 | PLUGIN_GLOBAL_CSS_FILE_NAME, | 666 | PLUGIN_GLOBAL_CSS_FILE_NAME, |
665 | PLUGIN_GLOBAL_CSS_PATH, | 667 | PLUGIN_GLOBAL_CSS_PATH, |
@@ -669,7 +671,7 @@ export { | |||
669 | HLS_STREAMING_PLAYLIST_DIRECTORY, | 671 | HLS_STREAMING_PLAYLIST_DIRECTORY, |
670 | FEEDS, | 672 | FEEDS, |
671 | JOB_TTL, | 673 | JOB_TTL, |
672 | DEFAULT_THEME, | 674 | DEFAULT_THEME_NAME, |
673 | NSFW_POLICY_TYPES, | 675 | NSFW_POLICY_TYPES, |
674 | STATIC_MAX_AGE, | 676 | STATIC_MAX_AGE, |
675 | STATIC_PATHS, | 677 | STATIC_PATHS, |
diff --git a/server/initializers/migrations/0400-user-theme.ts b/server/initializers/migrations/0400-user-theme.ts index 2c1763890..f74d76115 100644 --- a/server/initializers/migrations/0400-user-theme.ts +++ b/server/initializers/migrations/0400-user-theme.ts | |||
@@ -9,7 +9,7 @@ async function up (utils: { | |||
9 | const data = { | 9 | const data = { |
10 | type: Sequelize.STRING, | 10 | type: Sequelize.STRING, |
11 | allowNull: false, | 11 | allowNull: false, |
12 | defaultValue: 'default' | 12 | defaultValue: 'instance-default' |
13 | } | 13 | } |
14 | 14 | ||
15 | await utils.queryInterface.addColumn('user', 'theme', data) | 15 | await utils.queryInterface.addColumn('user', 'theme', data) |
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index 516827a05..ccc963514 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts | |||
@@ -92,6 +92,7 @@ export class ClientHtml { | |||
92 | let html = buffer.toString() | 92 | let html = buffer.toString() |
93 | 93 | ||
94 | html = ClientHtml.addCustomCSS(html) | 94 | html = ClientHtml.addCustomCSS(html) |
95 | html = ClientHtml.addPluginCSS(html) | ||
95 | 96 | ||
96 | ClientHtml.htmlCache[ path ] = html | 97 | ClientHtml.htmlCache[ path ] = html |
97 | 98 | ||
@@ -138,11 +139,17 @@ export class ClientHtml { | |||
138 | } | 139 | } |
139 | 140 | ||
140 | private static addCustomCSS (htmlStringPage: string) { | 141 | private static addCustomCSS (htmlStringPage: string) { |
141 | const styleTag = '<style class="custom-css-style">' + CONFIG.INSTANCE.CUSTOMIZATIONS.CSS + '</style>' | 142 | const styleTag = `<style class="custom-css-style">${CONFIG.INSTANCE.CUSTOMIZATIONS.CSS}</style>` |
142 | 143 | ||
143 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.CUSTOM_CSS, styleTag) | 144 | return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.CUSTOM_CSS, styleTag) |
144 | } | 145 | } |
145 | 146 | ||
147 | private static addPluginCSS (htmlStringPage: string) { | ||
148 | const linkTag = `<link rel="stylesheet" href="/plugins/global.css" />` | ||
149 | |||
150 | return htmlStringPage.replace('</head>', linkTag + '</head>') | ||
151 | } | ||
152 | |||
146 | private static addVideoOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) { | 153 | private static addVideoOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) { |
147 | const previewUrl = WEBSERVER.URL + video.getPreviewStaticPath() | 154 | const previewUrl = WEBSERVER.URL + video.getPreviewStaticPath() |
148 | const videoUrl = WEBSERVER.URL + video.getWatchStaticPath() | 155 | const videoUrl = WEBSERVER.URL + video.getWatchStaticPath() |
diff --git a/server/lib/plugins/theme-utils.ts b/server/lib/plugins/theme-utils.ts index 066339e65..76c671f1c 100644 --- a/server/lib/plugins/theme-utils.ts +++ b/server/lib/plugins/theme-utils.ts | |||
@@ -1,18 +1,18 @@ | |||
1 | import { DEFAULT_THEME } from '../../initializers/constants' | 1 | import { DEFAULT_THEME_NAME, DEFAULT_USER_THEME_NAME } from '../../initializers/constants' |
2 | import { PluginManager } from './plugin-manager' | 2 | import { PluginManager } from './plugin-manager' |
3 | import { CONFIG } from '../../initializers/config' | 3 | import { CONFIG } from '../../initializers/config' |
4 | 4 | ||
5 | function getThemeOrDefault (name: string) { | 5 | function getThemeOrDefault (name: string, defaultTheme: string) { |
6 | if (isThemeRegistered(name)) return name | 6 | if (isThemeRegistered(name)) return name |
7 | 7 | ||
8 | // Fallback to admin default theme | 8 | // Fallback to admin default theme |
9 | if (name !== CONFIG.THEME.DEFAULT) return getThemeOrDefault(CONFIG.THEME.DEFAULT) | 9 | if (name !== CONFIG.THEME.DEFAULT) return getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME) |
10 | 10 | ||
11 | return DEFAULT_THEME | 11 | return defaultTheme |
12 | } | 12 | } |
13 | 13 | ||
14 | function isThemeRegistered (name: string) { | 14 | function isThemeRegistered (name: string) { |
15 | if (name === DEFAULT_THEME) return true | 15 | if (name === DEFAULT_THEME_NAME || name === DEFAULT_USER_THEME_NAME) return true |
16 | 16 | ||
17 | return !!PluginManager.Instance.getRegisteredThemes() | 17 | return !!PluginManager.Instance.getRegisteredThemes() |
18 | .find(r => r.name === name) | 18 | .find(r => r.name === name) |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index b8ca1dd5c..6f0b0e00f 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -44,7 +44,7 @@ import { VideoChannelModel } from '../video/video-channel' | |||
44 | import { AccountModel } from './account' | 44 | import { AccountModel } from './account' |
45 | import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type' | 45 | import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type' |
46 | import { values } from 'lodash' | 46 | import { values } from 'lodash' |
47 | import { DEFAULT_THEME, NSFW_POLICY_TYPES } from '../../initializers/constants' | 47 | import { DEFAULT_THEME_NAME, DEFAULT_USER_THEME_NAME, NSFW_POLICY_TYPES } from '../../initializers/constants' |
48 | import { clearCacheByUserId } from '../../lib/oauth-model' | 48 | import { clearCacheByUserId } from '../../lib/oauth-model' |
49 | import { UserNotificationSettingModel } from './user-notification-setting' | 49 | import { UserNotificationSettingModel } from './user-notification-setting' |
50 | import { VideoModel } from '../video/video' | 50 | import { VideoModel } from '../video/video' |
@@ -190,7 +190,7 @@ export class UserModel extends Model<UserModel> { | |||
190 | videoQuotaDaily: number | 190 | videoQuotaDaily: number |
191 | 191 | ||
192 | @AllowNull(false) | 192 | @AllowNull(false) |
193 | @Default(DEFAULT_THEME) | 193 | @Default(DEFAULT_THEME_NAME) |
194 | @Is('UserTheme', value => throwIfNotValid(value, isThemeValid, 'theme')) | 194 | @Is('UserTheme', value => throwIfNotValid(value, isThemeValid, 'theme')) |
195 | @Column | 195 | @Column |
196 | theme: string | 196 | theme: string |
@@ -568,7 +568,7 @@ export class UserModel extends Model<UserModel> { | |||
568 | autoPlayVideo: this.autoPlayVideo, | 568 | autoPlayVideo: this.autoPlayVideo, |
569 | videoLanguages: this.videoLanguages, | 569 | videoLanguages: this.videoLanguages, |
570 | role: this.role, | 570 | role: this.role, |
571 | theme: getThemeOrDefault(this.theme), | 571 | theme: getThemeOrDefault(this.theme, DEFAULT_USER_THEME_NAME), |
572 | roleLabel: USER_ROLE_LABELS[ this.role ], | 572 | roleLabel: USER_ROLE_LABELS[ this.role ], |
573 | videoQuota: this.videoQuota, | 573 | videoQuota: this.videoQuota, |
574 | videoQuotaDaily: this.videoQuotaDaily, | 574 | videoQuotaDaily: this.videoQuotaDaily, |