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');