From ca26fc736308e0bc17465c97396fd67eedb7af8f Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sun, 12 Nov 2017 18:23:33 +0900
Subject: [PATCH] :v:

---
 locales/en.yml                                |   5 +
 locales/ja.yml                                |   5 +
 src/web/app/desktop/mixins/widget.js          |   9 +-
 .../desktop/tags/home-widgets/broadcast.tag   |   7 +-
 .../desktop/tags/home-widgets/donation.tag    |   5 +-
 src/web/app/desktop/tags/home-widgets/nav.tag |   3 +
 .../desktop/tags/home-widgets/post-form.tag   | 101 ++++++++++++++++++
 .../app/desktop/tags/home-widgets/tips.tag    |   2 +
 .../app/desktop/tags/home-widgets/version.tag |   2 +
 src/web/app/desktop/tags/home.tag             |  55 ++++++++--
 src/web/app/desktop/tags/index.js             |   1 +
 11 files changed, 179 insertions(+), 16 deletions(-)
 create mode 100644 src/web/app/desktop/tags/home-widgets/post-form.tag

diff --git a/locales/en.yml b/locales/en.yml
index 2845eec6a1..574af26a68 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -385,6 +385,11 @@ desktop:
       next: "Next month"
       go: "Click to travel"
 
+    mk-post-form-home-widget:
+      title: "Post"
+      post: "Post"
+      placeholder: "What's happening?"
+
     mk-repost-form:
       quote: "Quote..."
       cancel: "Cancel"
diff --git a/locales/ja.yml b/locales/ja.yml
index 2d9aceb2db..9e6251d0d7 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -385,6 +385,11 @@ desktop:
       next: "来月"
       go: "クリックして時間遡行"
 
+    mk-post-form-home-widget:
+      title: "投稿"
+      post: "投稿"
+      placeholder: "いまどうしてる?"
+
     mk-repost-form:
       quote: "引用する..."
       cancel: "キャンセル"
diff --git a/src/web/app/desktop/mixins/widget.js b/src/web/app/desktop/mixins/widget.js
index 2bf858ebe6..cb04295fc5 100644
--- a/src/web/app/desktop/mixins/widget.js
+++ b/src/web/app/desktop/mixins/widget.js
@@ -9,10 +9,13 @@ riot.mixin('widget', {
 		this.mixin('api');
 
 		this.id = this.opts.id;
+		this.place = this.opts.place;
 
-		Object.keys(this.data).forEach(prop => {
-			this.data[prop] = this.opts.data.hasOwnProperty(prop) ? this.opts.data[prop] : this.data[prop];
-		});
+		if (this.data) {
+			Object.keys(this.data).forEach(prop => {
+				this.data[prop] = this.opts.data.hasOwnProperty(prop) ? this.opts.data[prop] : this.data[prop];
+			});
+		}
 	},
 
 	save: function() {
diff --git a/src/web/app/desktop/tags/home-widgets/broadcast.tag b/src/web/app/desktop/tags/home-widgets/broadcast.tag
index 1102e22c7f..c33c5f367b 100644
--- a/src/web/app/desktop/tags/home-widgets/broadcast.tag
+++ b/src/web/app/desktop/tags/home-widgets/broadcast.tag
@@ -75,9 +75,8 @@
 				a
 					color #555
 
-			
-
-			
-
 	</style>
+	<script>
+		this.mixin('widget');
+	</script>
 </mk-broadcast-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/donation.tag b/src/web/app/desktop/tags/home-widgets/donation.tag
index d533e82831..9d56d12f04 100644
--- a/src/web/app/desktop/tags/home-widgets/donation.tag
+++ b/src/web/app/desktop/tags/home-widgets/donation.tag
@@ -28,5 +28,8 @@
 					color #999
 
 	</style>
-	<script>this.mixin('user-preview');</script>
+	<script>
+		this.mixin('widget');
+		this.mixin('user-preview');
+	</script>
 </mk-donation-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/nav.tag b/src/web/app/desktop/tags/home-widgets/nav.tag
index 54bfb87a11..1061b36f41 100644
--- a/src/web/app/desktop/tags/home-widgets/nav.tag
+++ b/src/web/app/desktop/tags/home-widgets/nav.tag
@@ -14,4 +14,7 @@
 				color #ccc
 
 	</style>
+	<script>
+		this.mixin('widget');
+	</script>
 </mk-nav-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/post-form.tag b/src/web/app/desktop/tags/home-widgets/post-form.tag
new file mode 100644
index 0000000000..2aa3cda502
--- /dev/null
+++ b/src/web/app/desktop/tags/home-widgets/post-form.tag
@@ -0,0 +1,101 @@
+<mk-post-form-home-widget>
+	<mk-post-form if={ place == 'main' }/>
+	<virtual if={ place != 'main' }>
+		<virtual if={ data.design == 0 }>
+			<p class="title"><i class="fa fa-pencil"></i>%i18n:desktop.tags.mk-post-form-home-widget.title%</p>
+		</virtual>
+		<textarea disabled={ posting } ref="text" onkeydown={ onkeydown } placeholder="%i18n:desktop.tags.mk-post-form-home-widget.placeholder%"></textarea>
+		<button onclick={ post } disabled={ posting }>%i18n:desktop.tags.mk-post-form-home-widget.post%</button>
+	</virtual>
+	<style>
+		:scope
+			display block
+			background #fff
+			overflow hidden
+
+			> .title
+				z-index 1
+				margin 0
+				padding 0 16px
+				line-height 42px
+				font-size 0.9em
+				font-weight bold
+				color #888
+				box-shadow 0 1px rgba(0, 0, 0, 0.07)
+
+				> i
+					margin-right 4px
+
+			> textarea
+				display block
+				width 100%
+				max-width 100%
+				min-width 100%
+				padding 16px
+				margin-bottom 28px + 16px
+				border none
+				border-bottom solid 1px #eee
+
+			> button
+				display block
+				position absolute
+				bottom 8px
+				right 8px
+				margin 0
+				padding 0 10px
+				height 28px
+				color $theme-color-foreground
+				background $theme-color !important
+				outline none
+				border none
+				border-radius 4px
+				transition background 0.1s ease
+				cursor pointer
+
+				&:hover
+					background lighten($theme-color, 10%) !important
+
+				&:active
+					background darken($theme-color, 10%) !important
+					transition background 0s ease
+
+	</style>
+	<script>
+		this.data = {
+			design: 0
+		};
+
+		this.mixin('widget');
+
+		this.func = () => {
+			if (++this.data.design == 2) this.data.design = 0;
+			this.save();
+		};
+
+		this.onkeydown = e => {
+			if (e.which == 10 || e.which == 13) this.post();
+		};
+
+		this.post = () => {
+			this.update({
+				posting: true
+			});
+
+			this.api('posts/create', {
+				text: this.refs.text.value
+			}).then(data => {
+				this.clear();
+			}).catch(err => {
+				alert('失敗した');
+			}).then(() => {
+				this.update({
+					posting: false
+				});
+			});
+		};
+
+		this.clear = () => {
+			this.refs.text.value = '';
+		};
+	</script>
+</mk-post-form-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/tips.tag b/src/web/app/desktop/tags/home-widgets/tips.tag
index 5a535099ab..fd5ec801f5 100644
--- a/src/web/app/desktop/tags/home-widgets/tips.tag
+++ b/src/web/app/desktop/tags/home-widgets/tips.tag
@@ -31,6 +31,8 @@
 	<script>
 		import anime from 'animejs';
 
+		this.mixin('widget');
+
 		this.tips = [
 			'<kbd>t</kbd>でタイムラインにフォーカスできます',
 			'<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます',
diff --git a/src/web/app/desktop/tags/home-widgets/version.tag b/src/web/app/desktop/tags/home-widgets/version.tag
index ea5307061c..ec14f9c79b 100644
--- a/src/web/app/desktop/tags/home-widgets/version.tag
+++ b/src/web/app/desktop/tags/home-widgets/version.tag
@@ -17,6 +17,8 @@
 
 	</style>
 	<script>
+		this.mixin('widget');
+
 		this.version = VERSION;
 	</script>
 </mk-version-home-widget>
diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag
index 60625bde64..8da58eb51c 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -16,6 +16,7 @@
 				<option value="notifications">通知</option>
 				<option value="user-recommendation">おすすめユーザー</option>
 				<option value="recommended-polls">投票</option>
+				<option value="post-form">投稿フォーム</option>
 				<option value="channel">チャンネル</option>
 				<option value="server">サーバー情報</option>
 				<option value="donation">寄付のお願い</option>
@@ -32,12 +33,13 @@
 		</div>
 	</div>
 	<div class="main">
-		<div class="left" ref="left"></div>
-		<main>
+		<div class="left" ref="left" data-place="left"></div>
+		<main ref="main">
+			<div class="maintop" ref="maintop" data-place="main" if={ opts.customize }></div>
 			<mk-timeline-home-widget ref="tl" if={ mode == 'timeline' }/>
 			<mk-mentions-home-widget ref="tl" if={ mode == 'mentions' }/>
 		</main>
-		<div class="right" ref="right"></div>
+		<div class="right" ref="right" data-place="right"></div>
 	</div>
 	<style>
 		:scope
@@ -46,6 +48,12 @@
 			&[data-customize]
 				background-image url('/assets/desktop/grid.svg')
 
+				> .main > main > *:not(.maintop)
+					cursor not-allowed
+
+					> *
+						pointer-events none
+
 			&:not([data-customize])
 				> .main > *:empty
 					display none
@@ -91,30 +99,39 @@
 				max-width 1200px
 
 				> *
-					> *:not(.customize-container)
+					> *:not(.customize-container):not(.maintop)
+					> .maintop > .customize-container > *
 					> .customize-container > *
 						display block
 						border solid 1px rgba(0, 0, 0, 0.075)
 						border-radius 6px
 
-					> *:not(.customize-container)
+					> *:not(.customize-container):not(.maintop)
 					> .customize-container
 						&:not(:last-child)
 							margin-bottom 16px
 
+					> .maintop > .customize-container
+						margin-bottom 16px
+
 				> main
 					padding 16px
 					width calc(100% - 275px * 2)
 
-				> *:not(main)
-					width 275px
+					> .maintop
+						min-height 64px
 
+				> *
 					> .customize-container
+					> .maintop > .customize-container
 						cursor move
 
 						> *
 							pointer-events none
 
+				> *:not(main)
+					width 275px
+
 				> .left
 					padding 16px 0 16px 16px
 
@@ -160,11 +177,18 @@
 				const sortableOption = {
 					group: 'kyoppie',
 					animation: 150,
-					onSort: this.saveHome
+					onMove: evt => {
+						const id = evt.dragged.getAttribute('data-widget-id');
+						this.home.find(tag => tag.id == id).update({ place: evt.to.getAttribute('data-place') });
+					},
+					onSort: () => {
+						this.saveHome();
+					}
 				};
 
 				new Sortable(this.refs.left, sortableOption);
 				new Sortable(this.refs.right, sortableOption);
+				new Sortable(this.refs.maintop, sortableOption);
 				new Sortable(this.refs.trash, Object.assign({}, sortableOption, {
 					onAdd: evt => {
 						const el = evt.item;
@@ -213,11 +237,19 @@
 						this.refs.right.appendChild(actualEl);
 					}
 					break;
+				case 'main':
+					if (this.opts.customize) {
+						this.refs.maintop.appendChild(actualEl);
+					} else {
+						this.refs.main.insertBefore(actualEl, this.refs.tl.root);
+					}
+					break;
 			}
 
 			const tag = riot.mount(el, {
 				id: widget.id,
 				data: widget.data,
+				place: widget.place,
 				tl: this.refs.tl
 			})[0];
 
@@ -265,6 +297,13 @@
 				data.push(widget);
 			});
 
+			Array.from(this.refs.maintop.children).forEach(el => {
+				const id = el.getAttribute('data-widget-id');
+				const widget = this.I.client_settings.home.find(w => w.id == id);
+				widget.place = 'main';
+				data.push(widget);
+			});
+
 			this.api('i/update_home', {
 				home: data
 			}).then(() => {
diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js
index 865c3d3e06..e48ba9744b 100644
--- a/src/web/app/desktop/tags/index.js
+++ b/src/web/app/desktop/tags/index.js
@@ -42,6 +42,7 @@ require('./home-widgets/server.tag');
 require('./home-widgets/slideshow.tag');
 require('./home-widgets/channel.tag');
 require('./home-widgets/timemachine.tag');
+require('./home-widgets/post-form.tag');
 require('./timeline.tag');
 require('./messaging/window.tag');
 require('./messaging/room-window.tag');