From d058ecc4ea0bb2b242ba5cc525dc9442964b5939 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 20 Sep 2018 17:21:16 +0900
Subject: [PATCH] Resolve #2698

---
 .../views/pages/admin/admin.dashboard.vue     | 14 +++++++++-
 .../app/desktop/views/pages/welcome.vue       | 24 +++++++++++++++++
 src/client/app/mobile/views/pages/welcome.vue | 26 ++++++++++++++++++-
 src/models/meta.ts                            |  1 +
 src/server/api/endpoints/admin/update-meta.ts | 10 +++++++
 src/server/api/endpoints/meta.ts              |  3 ++-
 6 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/src/client/app/desktop/views/pages/admin/admin.dashboard.vue b/src/client/app/desktop/views/pages/admin/admin.dashboard.vue
index c86c30db17..5d0f6d451e 100644
--- a/src/client/app/desktop/views/pages/admin/admin.dashboard.vue
+++ b/src/client/app/desktop/views/pages/admin/admin.dashboard.vue
@@ -14,6 +14,14 @@
 	</div>
 
 	<div class="form">
+		<div>
+			<label>
+				<p>%i18n:@banner-url%</p>
+				<input v-model="bannerUrl">
+			</label>
+			<button class="ui" @click="updateMeta">%i18n:@save%</button>
+		</div>
+
 		<div>
 			<label>
 				<input type="checkbox" v-model="disableRegistration" @change="updateMeta">
@@ -46,6 +54,7 @@ export default Vue.extend({
 			stats: null,
 			disableRegistration: false,
 			disableLocalTimeline: false,
+			bannerUrl: null,
 			inviteCode: null,
 			connection: null,
 			connectionId: null
@@ -58,6 +67,7 @@ export default Vue.extend({
 		(this as any).os.getMeta().then(meta => {
 			this.disableRegistration = meta.disableRegistration;
 			this.disableLocalTimeline = meta.disableLocalTimeline;
+			this.bannerUrl = meta.bannerUrl;
 		});
 
 		(this as any).api('stats').then(stats => {
@@ -76,7 +86,8 @@ export default Vue.extend({
 		updateMeta() {
 			(this as any).api('admin/update-meta', {
 				disableRegistration: this.disableRegistration,
-				disableLocalTimeline: this.disableLocalTimeline
+				disableLocalTimeline: this.disableLocalTimeline,
+				bannerUrl: this.bannerUrl
 			});
 		}
 	}
@@ -114,6 +125,7 @@ export default Vue.extend({
 
 	> .form
 		> div
+			padding 16px
 			border-bottom solid 1px #eee
 
 </style>
diff --git a/src/client/app/desktop/views/pages/welcome.vue b/src/client/app/desktop/views/pages/welcome.vue
index ea1734f8c7..913fa6b21b 100644
--- a/src/client/app/desktop/views/pages/welcome.vue
+++ b/src/client/app/desktop/views/pages/welcome.vue
@@ -1,5 +1,7 @@
 <template>
 <div class="mk-welcome">
+	<div class="banner" :style="{ backgroundImage: banner ? `url(${banner})` : null }"></div>
+
 	<button @click="dark">
 		<template v-if="$store.state.device.darkmode">%fa:moon%</template>
 		<template v-else>%fa:R moon%</template>
@@ -154,6 +156,7 @@ export default Vue.extend({
 		return {
 			meta: null,
 			stats: null,
+			banner: null,
 			copyright,
 			host,
 			name: 'Misskey',
@@ -169,6 +172,7 @@ export default Vue.extend({
 			this.name = meta.name;
 			this.description = meta.description;
 			this.announcements = meta.broadcasts;
+			this.banner = meta.bannerUrl;
 		});
 
 		(this as any).api('stats').then(stats => {
@@ -308,6 +312,26 @@ root(isDark)
 	//background-position center
 	//background-size cover
 
+	> .banner
+		position absolute
+		top 0
+		left 0
+		width 100%
+		height 400px
+		background-position center
+		background-size cover
+		opacity 0.7
+
+		&:after
+			content ""
+			display block
+			position absolute
+			bottom 0
+			left 0
+			width 100%
+			height 100px
+			background linear-gradient(transparent, isDark ? #191b22 : #f7f7f7)
+
 	> .forkit
 		position absolute
 		top 0
diff --git a/src/client/app/mobile/views/pages/welcome.vue b/src/client/app/mobile/views/pages/welcome.vue
index 74f43f2c71..65a7af93a9 100644
--- a/src/client/app/mobile/views/pages/welcome.vue
+++ b/src/client/app/mobile/views/pages/welcome.vue
@@ -1,5 +1,7 @@
 <template>
 <div class="wgwfgvvimdjvhjfwxropcwksnzftjqes">
+	<div class="banner" :style="{ backgroundImage: banner ? `url(${banner})` : null }"></div>
+
 	<div>
 		<img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" :alt="name">
 		<p class="host">{{ host }}</p>
@@ -80,6 +82,7 @@ export default Vue.extend({
 			meta: null,
 			copyright,
 			stats: null,
+			banner: null,
 			host,
 			name: 'Misskey',
 			description: '',
@@ -93,6 +96,7 @@ export default Vue.extend({
 			this.name = meta.name;
 			this.description = meta.description;
 			this.announcements = meta.broadcasts;
+			this.banner = meta.bannerUrl;
 		});
 
 		(this as any).api('stats').then(stats => {
@@ -121,7 +125,27 @@ root(isDark)
 	text-align center
 	//background #fff
 
-	> div
+	> .banner
+		position absolute
+		top 0
+		left 0
+		width 100%
+		height 300px
+		background-position center
+		background-size cover
+		opacity 0.7
+
+		&:after
+			content ""
+			display block
+			position absolute
+			bottom 0
+			left 0
+			width 100%
+			height 100px
+			background linear-gradient(transparent, isDark ? #191b22 : #f7f7f7)
+
+	> div:not(.banner)
 		padding 32px
 		margin 0 auto
 		max-width 500px
diff --git a/src/models/meta.ts b/src/models/meta.ts
index 8ca68416f8..3c0347485c 100644
--- a/src/models/meta.ts
+++ b/src/models/meta.ts
@@ -14,4 +14,5 @@ export type IMeta = {
 	disableRegistration?: boolean;
 	disableLocalTimeline?: boolean;
 	hidedTags?: string[];
+	bannerUrl?: string;
 };
diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts
index 3f5cd56b2f..f0ebfbe936 100644
--- a/src/server/api/endpoints/admin/update-meta.ts
+++ b/src/server/api/endpoints/admin/update-meta.ts
@@ -34,6 +34,12 @@ export const meta = {
 				'ja-JP': '統計などで無視するハッシュタグ'
 			}
 		}),
+
+		bannerUrl: $.str.optional.nullable.note({
+			desc: {
+				'ja-JP': 'インスタンスのバナー画像URL'
+			}
+		}),
 	}
 };
 
@@ -59,6 +65,10 @@ export default (params: any) => new Promise(async (res, rej) => {
 		set.hidedTags = ps.hidedTags;
 	}
 
+	if (ps.bannerUrl !== undefined) {
+		set.bannerUrl = ps.bannerUrl;
+	}
+
 	await Meta.update({}, {
 		$set: set
 	}, { upsert: true });
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index 18b0882f76..6c585d2c3a 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -38,6 +38,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 		driveCapacityPerLocalUserMb: config.localDriveCapacityMb,
 		recaptchaSitekey: config.recaptcha ? config.recaptcha.site_key : null,
 		swPublickey: config.sw ? config.sw.public_key : null,
-		hidedTags: (me && me.isAdmin) ? meta.hidedTags : undefined
+		hidedTags: (me && me.isAdmin) ? meta.hidedTags : undefined,
+		bannerUrl: meta.bannerUrl
 	});
 });