diff --git a/client/src/components/Header.vue b/client/src/components/Header.vue
index 32a9c5c..ce9c5cb 100644
--- a/client/src/components/Header.vue
+++ b/client/src/components/Header.vue
@@ -3,7 +3,11 @@
- {{indexName}}
+
+ {{indexName}}
+
+
+
A search engine of PeerTube videos and channels
@@ -11,7 +15,7 @@
Developed by Framasoft
-
+
@@ -48,6 +52,10 @@
text-align: center;
}
+ .title-image {
+ max-width: 500px;
+ }
+
h4 {
font-weight: normal;
font-size: 14px;
@@ -78,14 +86,39 @@
diff --git a/client/src/views/Search.vue b/client/src/views/Search.vue
index d9bc869..2fb731b 100644
--- a/client/src/views/Search.vue
+++ b/client/src/views/Search.vue
@@ -420,7 +420,7 @@
import ChannelResult from '../components/ChannelResult.vue'
import { searchVideos, searchVideoChannels } from '../shared/search'
import { getConfig } from '../shared/config'
- import { pageToAPIParams, durationRangeToAPIParams, publishedDateRangeToAPIParams, extractTagsFromQuery } from '../shared/utils'
+ import { pageToAPIParams, durationRangeToAPIParams, publishedDateRangeToAPIParams, extractTagsFromQuery, buildApiUrl } from '../shared/utils'
import { SearchUrl } from '../models'
import { EnhancedVideo } from '../../../server/types/video.model'
import { EnhancedVideoChannel } from '../../../server/types/channel.model'
diff --git a/config/default.yaml b/config/default.yaml
index 088b739..3aa7a3d 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -7,7 +7,7 @@ webserver:
hostname: 'localhost'
port: 3234
-elastic_search:
+elastic-search:
hostname: 'localhost'
port: 9200
indexes:
@@ -19,8 +19,17 @@ log:
search-instance:
name: 'PeerTube Search Index'
+
+ # Set an image instead of displaying your website title in text at the top of the search page
+ # Must be a relative URL. For example if you use a theme: /theme/mytheme/img/title.svg
+ name_image: ''
+
+ # The image between the title and the search bar
+ search_image: ''
+
description: 'A search engine of PeerTube videos and channels, developed by Framasoft'
legal_notices_url: ''
+ theme: 'default'
instances-index:
# Contains PeerTube instance hosts the indexer will index
diff --git a/config/test.yaml b/config/test.yaml
index 699435f..3e5924e 100644
--- a/config/test.yaml
+++ b/config/test.yaml
@@ -1,8 +1,13 @@
-elastic_search:
+elastic-search:
indexes:
videos: 'peertube-index-videos-test1'
channels: 'peertube-index-channels-test1'
+search-instance:
+ name_image: '/theme/framasoft/img/title.svg'
+ search_image: '/theme/framasoft/img/sepia-search.svg'
+ theme: 'framasoft'
+
instances-index:
whitelist:
enabled: true
diff --git a/package.json b/package.json
index bef0513..29b741a 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"tsc": "tsc",
"eslint": "eslint",
"lint": "eslint --ext .ts \"server/**/*.ts\"",
- "build": "rm -r dist && tsc && cd ./client && npm run build",
+ "build": "rm -r dist && tsc && cp -r themes dist/ && cd ./client && npm run build",
"postinstall": "cd client/ && yarn install --pure-lockfile",
"start": "node dist/server.js",
"i18n:update": "cd client && git fetch weblate && git merge weblate/master && rm -f src/locale/en_US/LC_MESSAGES/app.po && make clean && make makemessages && make translations"
diff --git a/server.ts b/server.ts
index 87a98e0..e189e30 100644
--- a/server.ts
+++ b/server.ts
@@ -41,36 +41,51 @@ app.use(apiRoute, apiRouter)
app.use('/js/', express.static(join(__dirname, '../client/dist/js')))
app.use('/css/', express.static(join(__dirname, '../client/dist/css')))
app.use('/img/', express.static(join(__dirname, '../client/dist/img')))
-
-let indexHTML: string
+app.use('/theme/', express.static(join(__dirname, './themes')))
app.use('/opensearch.xml', async function (req, res) {
- return res.send(`
-
- ${CONFIG.SEARCH_INSTANCE.NAME}
- ${CONFIG.SEARCH_INSTANCE.DESCRIPTION}
- ${url}/img/favicon.png
- *
- peertube video
-
-
-
- open
- true
- UTF-8
- UTF-8
- Framasoft: contact.framasoft.org
-`).type('application/xml').status(200).end()
+ const data = `
+
+ ${CONFIG.SEARCH_INSTANCE.NAME}
+ ${CONFIG.SEARCH_INSTANCE.DESCRIPTION}
+ ${url}/img/favicon.png
+ *
+ peertube video
+
+
+
+ open
+ true
+ UTF-8
+ UTF-8
+ Framasoft: contact.framasoft.org
+ `
+
+ return res.type('application/xml').send(data).end()
})
+let indexHTML: string
+
app.use('/*', async function (req, res) {
res.set('Content-Type', 'text/html; charset=UTF-8')
if (indexHTML) return res.send(indexHTML)
- const buffer = await readFile(join(__dirname, '../client/dist/index.html'))
+ let bufferCSS: Buffer
+ if (CONFIG.SEARCH_INSTANCE.THEME !== 'default') {
+
+ try {
+ bufferCSS = await readFile(join(__dirname, 'themes', CONFIG.SEARCH_INSTANCE.THEME, 'index.css'))
+ } catch (err) {
+ logger.error({ err }, 'Cannot fetch CSS theme.')
+ }
+ }
+
const title = CONFIG.SEARCH_INSTANCE.NAME
const description = CONFIG.SEARCH_INSTANCE.DESCRIPTION
+ const styleCSS = bufferCSS
+ ? ``
+ : ''
const tags = `
${title}
@@ -89,7 +104,11 @@ app.use('/*', async function (req, res) {
- `
+
+
+ ${styleCSS}`
+
+ const buffer = await readFile(join(__dirname, '../client/dist/index.html'))
indexHTML = buffer.toString()
indexHTML = indexHTML.replace('', tags + '')
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 42dc5a6..66d01bd 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -18,6 +18,8 @@ export { configRouter }
async function getConfig (req: express.Request, res: express.Response) {
return res.json({
searchInstanceName: CONFIG.SEARCH_INSTANCE.NAME,
+ searchInstanceNameImage: CONFIG.SEARCH_INSTANCE.NAME_IMAGE,
+ searchInstanceSearchImage: CONFIG.SEARCH_INSTANCE.SEARCH_IMAGE,
legalNoticesUrl: CONFIG.SEARCH_INSTANCE.LEGAL_NOTICES_URL,
indexedHostsCount: VideosIndexer.Instance.getIndexedHosts().length,
indexedInstancesUrl: CONFIG.INSTANCES_INDEX.PUBLIC_URL
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 62c7b7f..af0f738 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -13,11 +13,11 @@ const CONFIG = {
PORT: config.get('webserver.port')
},
ELASTIC_SEARCH: {
- HOSTNAME: config.get('elastic_search.hostname'),
- PORT: config.get('elastic_search.port'),
+ HOSTNAME: config.get('elastic-search.hostname'),
+ PORT: config.get('elastic-search.port'),
INDEXES: {
- VIDEOS: config.get('elastic_search.indexes.videos'),
- CHANNELS: config.get('elastic_search.indexes.channels')
+ VIDEOS: config.get('elastic-search.indexes.videos'),
+ CHANNELS: config.get('elastic-search.indexes.channels')
}
},
LOG: {
@@ -25,8 +25,11 @@ const CONFIG = {
},
SEARCH_INSTANCE: {
NAME: config.get('search-instance.name'),
+ NAME_IMAGE: config.get('search-instance.name_image'),
+ SEARCH_IMAGE: config.get('search-instance.search_image'),
DESCRIPTION: config.get('search-instance.description'),
- LEGAL_NOTICES_URL: config.get('search-instance.legal_notices_url')
+ LEGAL_NOTICES_URL: config.get('search-instance.legal_notices_url'),
+ THEME: config.get('search-instance.theme')
},
INSTANCES_INDEX: {
URL: config.get('instances-index.url'),
diff --git a/shared/server-config.model.ts b/shared/server-config.model.ts
index ddd93bb..da7757c 100644
--- a/shared/server-config.model.ts
+++ b/shared/server-config.model.ts
@@ -1,5 +1,8 @@
export interface ServerConfig {
searchInstanceName: string
+ searchInstanceNameImage: string
+
+ searchInstanceSearchImage: string
indexedHostsCount: number
diff --git a/themes/framasoft/img/sepia-search.svg b/themes/framasoft/img/sepia-search.svg
new file mode 100644
index 0000000..991e5eb
--- /dev/null
+++ b/themes/framasoft/img/sepia-search.svg
@@ -0,0 +1,365 @@
+
+
diff --git a/themes/framasoft/img/title.svg b/themes/framasoft/img/title.svg
new file mode 100644
index 0000000..dabd323
--- /dev/null
+++ b/themes/framasoft/img/title.svg
@@ -0,0 +1,278 @@
+
+
diff --git a/themes/framasoft/index.css b/themes/framasoft/index.css
new file mode 100644
index 0000000..2f95089
--- /dev/null
+++ b/themes/framasoft/index.css
@@ -0,0 +1,22 @@
+header {
+ font-family: inherit !important;
+ margin-bottom: 0;
+}
+
+header h4 {
+ font-size: 16px;
+ color: #757575;
+}
+
+header h4 a {
+ color: #757575;
+}
+
+header .search-home {
+ margin: 50px 0 -7px 0 !important;
+ z-index: 100;
+}
+
+.search-container {
+ margin-top: 0;
+}