From f770525c762809154610784f3de3e03e02985b09 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 7 Jun 2018 05:14:37 +0900
Subject: [PATCH] nanka iroiro

---
 .../app/desktop/views/components/settings.vue     | 10 ++++++++++
 src/client/app/desktop/views/components/ui.vue    | 14 +++++++++++++-
 .../app/desktop/views/pages/deck/deck.column.vue  |  1 +
 src/client/app/desktop/views/pages/deck/deck.vue  |  8 +++++++-
 src/models/user.ts                                |  5 +++++
 src/server/api/endpoints/i/update.ts              | 15 +++++++++++++++
 6 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/client/app/desktop/views/components/settings.vue b/src/client/app/desktop/views/components/settings.vue
index 1bfff8cc8..e0d578c33 100644
--- a/src/client/app/desktop/views/components/settings.vue
+++ b/src/client/app/desktop/views/components/settings.vue
@@ -40,6 +40,7 @@
 				<button class="ui button" @click="customizeHome" style="margin-bottom: 16px">%i18n:@customize%</button>
 			</div>
 			<div class="div">
+				<button class="ui" @click="updateWallpaper">%i18n:@choose-wallpaper%</button>
 				<mk-switch v-model="darkmode" text="%i18n:@dark-mode%"/>
 				<mk-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons" text="%i18n:@circle-icons%"/>
 				<mk-switch v-model="$store.state.settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="%i18n:@gradient-window-header%"/>
@@ -293,6 +294,15 @@ export default Vue.extend({
 			this.$router.push('/i/customize-home');
 			this.$emit('done');
 		},
+		updateWallpaper() {
+			(this as any).apis.chooseDriveFile({
+				multiple: false
+			}).then(file => {
+				(this as any).api('i/update', {
+					wallpaperId: file.id
+				});
+			});
+		},
 		onChangeFetchOnScroll(v) {
 			this.$store.dispatch('settings/set', {
 				key: 'fetchOnScroll',
diff --git a/src/client/app/desktop/views/components/ui.vue b/src/client/app/desktop/views/components/ui.vue
index 34769b52b..351deafde 100644
--- a/src/client/app/desktop/views/components/ui.vue
+++ b/src/client/app/desktop/views/components/ui.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="mk-ui">
+<div class="mk-ui" :style="style">
 	<x-header class="header"/>
 	<div class="content">
 		<slot></slot>
@@ -16,6 +16,15 @@ export default Vue.extend({
 	components: {
 		XHeader
 	},
+	computed: {
+		style(): any {
+			if (!this.$store.getters.isSignedIn || this.$store.state.i.wallpaperUrl == null) return {};
+			return {
+				backgroundColor: this.$store.state.i.wallpaperColor && this.$store.state.i.wallpaperColor.length == 3 ? `rgb(${ this.$store.state.i.wallpaperColor.join(',') })` : null,
+				backgroundImage: `url(${ this.$store.state.i.wallpaperUrl })`
+			};
+		}
+	},
 	mounted() {
 		document.addEventListener('keydown', this.onKeydown);
 	},
@@ -40,6 +49,9 @@ export default Vue.extend({
 	display flex
 	flex-direction column
 	flex 1
+	background-size cover
+	background-position center
+	background-attachment fixed
 
 	> .header
 		@media (max-width 1000px)
diff --git a/src/client/app/desktop/views/pages/deck/deck.column.vue b/src/client/app/desktop/views/pages/deck/deck.column.vue
index 458732fa7..f71503d5c 100644
--- a/src/client/app/desktop/views/pages/deck/deck.column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.column.vue
@@ -140,6 +140,7 @@ root(isDark)
 		z-index 1
 		line-height $header-height
 		padding 0 16px
+		font-size 14px
 		color isDark ? #e3e5e8 : #888
 		background isDark ? #313543 : #fff
 		box-shadow 0 1px rgba(#000, 0.15)
diff --git a/src/client/app/desktop/views/pages/deck/deck.vue b/src/client/app/desktop/views/pages/deck/deck.vue
index d6cbf7396..369874ec6 100644
--- a/src/client/app/desktop/views/pages/deck/deck.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.vue
@@ -150,7 +150,6 @@ export default Vue.extend({
 root(isDark)
 	display flex
 	flex 1
-	justify-content center
 	padding 16px 0 16px 16px
 	overflow auto
 
@@ -160,6 +159,13 @@ root(isDark)
 		&:last-of-type
 			margin-right 0
 
+	> *
+		&:first-child
+			margin-left auto
+
+		&:last-child
+			margin-right auto
+
 	> button
 		padding 0 16px
 		color isDark ? #93a0a5 : #888
diff --git a/src/models/user.ts b/src/models/user.ts
index 0e06512da..2d4d7dc18 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -48,6 +48,7 @@ type IUserBase = {
 	usernameLower: string;
 	avatarId: mongo.ObjectID;
 	bannerId: mongo.ObjectID;
+	wallpaperId: mongo.ObjectID;
 	data: any;
 	description: string;
 	pinnedNoteId: mongo.ObjectID;
@@ -412,6 +413,10 @@ export const pack = (
 		? `${config.drive_url}/${_user.bannerId}`
 		: null;
 
+	_user.wallpaperUrl = _user.wallpaperId != null
+		? `${config.drive_url}/${_user.wallpaperId}`
+		: null;
+
 	if (!meId || !meId.equals(_user.id) || !opts.detail) {
 		delete _user.avatarId;
 		delete _user.bannerId;
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index b94f073d2..1a1da997c 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -45,6 +45,11 @@ module.exports = async (params, user, app) => new Promise(async (res, rej) => {
 	if (bannerIdErr) return rej('invalid bannerId param');
 	if (bannerId !== undefined) updates.bannerId = bannerId;
 
+	// Get 'wallpaperId' parameter
+	const [wallpaperId, wallpaperIdErr] = $.type(ID).optional().nullable().get(params.wallpaperId);
+	if (wallpaperIdErr) return rej('invalid wallpaperId param');
+	if (wallpaperId !== undefined) updates.wallpaperId = wallpaperId;
+
 	// Get 'isLocked' parameter
 	const [isLocked, isLockedErr] = $.bool.optional().get(params.isLocked);
 	if (isLockedErr) return rej('invalid isLocked param');
@@ -85,6 +90,16 @@ module.exports = async (params, user, app) => new Promise(async (res, rej) => {
 		}
 	}
 
+	if (wallpaperId) {
+		const wallpaper = await DriveFile.findOne({
+			_id: wallpaperId
+		});
+
+		if (wallpaper != null && wallpaper.metadata.properties.avgColor) {
+			updates.wallpaperColor = wallpaper.metadata.properties.avgColor;
+		}
+	}
+
 	await User.update(user._id, {
 		$set: updates
 	});