This commit is contained in:
syuilo 2018-02-07 15:16:01 +09:00
parent 18e1628e2a
commit 0c2b79aced
88 changed files with 474 additions and 460 deletions

View file

@ -3,12 +3,12 @@
<h1>%i18n:common.tags.mk-error.title%</h1>
<p class="text">{
'%i18n:common.tags.mk-error.description%'.substr(0, '%i18n:common.tags.mk-error.description%'.indexOf('{'))
}<a onclick={ reload }>{
}<a @click="reload">{
'%i18n:common.tags.mk-error.description%'.match(/\{(.+?)\}/)[1]
}</a>{
'%i18n:common.tags.mk-error.description%'.substr('%i18n:common.tags.mk-error.description%'.indexOf('}') + 1)
}</p>
<button if={ !troubleshooting } onclick={ troubleshoot }>%i18n:common.tags.mk-error.troubleshoot%</button>
<button if={ !troubleshooting } @click="troubleshoot">%i18n:common.tags.mk-error.troubleshoot%</button>
<mk-troubleshooter if={ troubleshooting }/>
<p class="thanks">%i18n:common.tags.mk-error.thanks%</p>
<style>

View file

@ -2,7 +2,7 @@
<textarea ref="text" onkeypress={ onkeypress } onpaste={ onpaste } placeholder="%i18n:common.input-message-here%"></textarea>
<div class="files"></div>
<mk-uploader ref="uploader"/>
<button class="send" onclick={ send } disabled={ sending } title="%i18n:common.send%">
<button class="send" @click="send" disabled={ sending } title="%i18n:common.send%">
<virtual if={ !sending }>%fa:paper-plane%</virtual><virtual if={ sending }>%fa:spinner .spin%</virtual>
</button>
<button class="attach-from-local" type="button" title="%i18n:common.tags.mk-messaging-form.attach-from-local%">

View file

@ -6,7 +6,7 @@
</div>
<div class="result">
<ol class="users" if={ searchResult.length > 0 } ref="searchResult">
<li each={ user, i in searchResult } onkeydown={ parent.onSearchResultKeydown.bind(null, i) } onclick={ user._click } tabindex="-1">
<li each={ user, i in searchResult } onkeydown={ parent.onSearchResultKeydown.bind(null, i) } @click="user._click" tabindex="-1">
<img class="avatar" src={ user.avatar_url + '?thumbnail&size=32' } alt=""/>
<span class="name">{ user.name }</span>
<span class="username">@{ user.username }</span>
@ -16,7 +16,7 @@
</div>
<div class="history" if={ history.length > 0 }>
<virtual each={ history }>
<a class="user" data-is-me={ is_me } data-is-read={ is_read } onclick={ _click }>
<a class="user" data-is-me={ is_me } data-is-read={ is_read } @click="_click">
<div>
<img class="avatar" src={ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' } alt=""/>
<header>

View file

@ -3,7 +3,7 @@
<p class="init" if={ init }>%fa:spinner .spin%%i18n:common.loading%</p>
<p class="empty" if={ !init && messages.length == 0 }>%fa:info-circle%%i18n:common.tags.mk-messaging-room.empty%</p>
<p class="no-history" if={ !init && messages.length > 0 && !moreMessagesIsInStock }>%fa:flag%%i18n:common.tags.mk-messaging-room.no-history%</p>
<button class="more { fetching: fetchingMoreMessages }" if={ moreMessagesIsInStock } onclick={ fetchMoreMessages } disabled={ fetchingMoreMessages }>
<button class="more { fetching: fetchingMoreMessages }" if={ moreMessagesIsInStock } @click="fetchMoreMessages" disabled={ fetchingMoreMessages }>
<virtual if={ fetchingMoreMessages }>%fa:spinner .pulse .fw%</virtual>{ fetchingMoreMessages ? '%i18n:common.loading%' : '%i18n:common.tags.mk-messaging-room.more%' }
</button>
<virtual each={ message, i in messages }>

View file

@ -5,13 +5,13 @@
<ul ref="choices">
<li each={ choice, i in choices }>
<input value={ choice } oninput={ oninput.bind(null, i) } placeholder={ '%i18n:common.tags.mk-poll-editor.choice-n%'.replace('{}', i + 1) }>
<button onclick={ remove.bind(null, i) } title="%i18n:common.tags.mk-poll-editor.remove%">
<button @click="remove.bind(null, i)" title="%i18n:common.tags.mk-poll-editor.remove%">
%fa:times%
</button>
</li>
</ul>
<button class="add" if={ choices.length < 10 } onclick={ add }>%i18n:common.tags.mk-poll-editor.add%</button>
<button class="destroy" onclick={ destroy } title="%i18n:common.tags.mk-poll-editor.destroy%">
<button class="add" if={ choices.length < 10 } @click="add">%i18n:common.tags.mk-poll-editor.add%</button>
<button class="destroy" @click="destroy" title="%i18n:common.tags.mk-poll-editor.destroy%">
%fa:times%
</button>
<style>

View file

@ -1,6 +1,6 @@
<mk-poll data-is-voted={ isVoted }>
<ul>
<li each={ poll.choices } onclick={ vote.bind(null, id) } class={ voted: voted } title={ !parent.isVoted ? '%i18n:common.tags.mk-poll.vote-to%'.replace('{}', text) : '' }>
<li each={ poll.choices } @click="vote.bind(null, id)" class={ voted: voted } title={ !parent.isVoted ? '%i18n:common.tags.mk-poll.vote-to%'.replace('{}', text) : '' }>
<div class="backdrop" style={ 'width:' + (parent.result ? (votes / parent.total * 100) : 0) + '%' }></div>
<span>
<virtual if={ is_voted }>%fa:check%</virtual>
@ -12,7 +12,7 @@
<p if={ total > 0 }>
<span>{ '%i18n:common.tags.mk-poll.total-users%'.replace('{}', total) }</span>
<a if={ !isVoted } onclick={ toggleResult }>{ result ? '%i18n:common.tags.mk-poll.vote%' : '%i18n:common.tags.mk-poll.show-result%' }</a>
<a if={ !isVoted } @click="toggleResult">{ result ? '%i18n:common.tags.mk-poll.vote%' : '%i18n:common.tags.mk-poll.show-result%' }</a>
<span if={ isVoted }>%i18n:common.tags.mk-poll.voted%</span>
</p>
<style>

View file

@ -1,7 +1,7 @@
<mk-post-menu>
<div class="backdrop" ref="backdrop" onclick={ close }></div>
<div class="backdrop" ref="backdrop" @click="close"></div>
<div class="popover { compact: opts.compact }" ref="popover">
<button if={ post.user_id === I.id } onclick={ pin }>%i18n:common.tags.mk-post-menu.pin%</button>
<button if={ post.user_id === I.id } @click="pin">%i18n:common.tags.mk-post-menu.pin%</button>
<div if={ I.is_pro && !post.is_category_verified }>
<select ref="categorySelect">
<option value="">%i18n:common.tags.mk-post-menu.select%</option>
@ -12,7 +12,7 @@
<option value="gadgets">%i18n:common.post_categories.gadgets%</option>
<option value="photography">%i18n:common.post_categories.photography%</option>
</select>
<button onclick={ categorize }>%i18n:common.tags.mk-post-menu.categorize%</button>
<button @click="categorize">%i18n:common.tags.mk-post-menu.categorize%</button>
</div>
</div>
<style>

View file

@ -1,184 +0,0 @@
<mk-reaction-picker>
<div class="backdrop" ref="backdrop" onclick={ close }></div>
<div class="popover { compact: opts.compact }" ref="popover">
<p if={ !opts.compact }>{ title }</p>
<div>
<button onclick={ react.bind(null, 'like') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="1" title="%i18n:common.reactions.like%"><mk-reaction-icon reaction='like'/></button>
<button onclick={ react.bind(null, 'love') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="2" title="%i18n:common.reactions.love%"><mk-reaction-icon reaction='love'/></button>
<button onclick={ react.bind(null, 'laugh') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="3" title="%i18n:common.reactions.laugh%"><mk-reaction-icon reaction='laugh'/></button>
<button onclick={ react.bind(null, 'hmm') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="4" title="%i18n:common.reactions.hmm%"><mk-reaction-icon reaction='hmm'/></button>
<button onclick={ react.bind(null, 'surprise') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="5" title="%i18n:common.reactions.surprise%"><mk-reaction-icon reaction='surprise'/></button>
<button onclick={ react.bind(null, 'congrats') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="6" title="%i18n:common.reactions.congrats%"><mk-reaction-icon reaction='congrats'/></button>
<button onclick={ react.bind(null, 'angry') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="4" title="%i18n:common.reactions.angry%"><mk-reaction-icon reaction='angry'/></button>
<button onclick={ react.bind(null, 'confused') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="5" title="%i18n:common.reactions.confused%"><mk-reaction-icon reaction='confused'/></button>
<button onclick={ react.bind(null, 'pudding') } onmouseover={ onmouseover } onmouseout={ onmouseout } tabindex="6" title="%i18n:common.reactions.pudding%"><mk-reaction-icon reaction='pudding'/></button>
</div>
</div>
<style>
$border-color = rgba(27, 31, 35, 0.15)
:scope
display block
position initial
> .backdrop
position fixed
top 0
left 0
z-index 10000
width 100%
height 100%
background rgba(0, 0, 0, 0.1)
opacity 0
> .popover
position absolute
z-index 10001
background #fff
border 1px solid $border-color
border-radius 4px
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
transform scale(0.5)
opacity 0
$balloon-size = 16px
&:not(.compact)
margin-top $balloon-size
transform-origin center -($balloon-size)
&:before
content ""
display block
position absolute
top -($balloon-size * 2)
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size $border-color
&:after
content ""
display block
position absolute
top -($balloon-size * 2) + 1.5px
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size #fff
> p
display block
margin 0
padding 8px 10px
font-size 14px
color #586069
border-bottom solid 1px #e1e4e8
> div
padding 4px
width 240px
text-align center
> button
width 40px
height 40px
font-size 24px
border-radius 2px
&:hover
background #eee
&:active
background $theme-color
box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
</style>
<script>
import anime from 'animejs';
this.mixin('api');
this.post = this.opts.post;
this.source = this.opts.source;
const placeholder = '%i18n:common.tags.mk-reaction-picker.choose-reaction%';
this.title = placeholder;
this.onmouseover = e => {
this.update({
title: e.target.title
});
};
this.onmouseout = () => {
this.update({
title: placeholder
});
};
this.on('mount', () => {
const rect = this.source.getBoundingClientRect();
const width = this.refs.popover.offsetWidth;
const height = this.refs.popover.offsetHeight;
if (this.opts.compact) {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
this.refs.popover.style.left = (x - (width / 2)) + 'px';
this.refs.popover.style.top = (y - (height / 2)) + 'px';
} else {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
this.refs.popover.style.left = (x - (width / 2)) + 'px';
this.refs.popover.style.top = y + 'px';
}
anime({
targets: this.refs.backdrop,
opacity: 1,
duration: 100,
easing: 'linear'
});
anime({
targets: this.refs.popover,
opacity: 1,
scale: [0.5, 1],
duration: 500
});
});
this.react = reaction => {
this.api('posts/reactions/create', {
post_id: this.post.id,
reaction: reaction
}).then(() => {
if (this.opts.cb) this.opts.cb();
this.unmount();
});
};
this.close = () => {
this.refs.backdrop.style.pointerEvents = 'none';
anime({
targets: this.refs.backdrop,
opacity: 0,
duration: 200,
easing: 'linear'
});
this.refs.popover.style.pointerEvents = 'none';
anime({
targets: this.refs.popover,
opacity: 0,
scale: 0.5,
duration: 200,
easing: 'easeInBack',
complete: () => this.unmount()
});
};
</script>
</mk-reaction-picker>

View file

@ -0,0 +1,202 @@
<template>
<div>
<div class="backdrop" ref="backdrop" @click="close"></div>
<div class="popover" :data-compact="compact" ref="popover">
<p if={ !opts.compact }>{ title }</p>
<div>
<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" title="%i18n:common.reactions.like%"><mk-reaction-icon reaction='like'/></button>
<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" title="%i18n:common.reactions.love%"><mk-reaction-icon reaction='love'/></button>
<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" title="%i18n:common.reactions.laugh%"><mk-reaction-icon reaction='laugh'/></button>
<button @click="react('hmm')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" title="%i18n:common.reactions.hmm%"><mk-reaction-icon reaction='hmm'/></button>
<button @click="react('surprise')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" title="%i18n:common.reactions.surprise%"><mk-reaction-icon reaction='surprise'/></button>
<button @click="react('congrats')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" title="%i18n:common.reactions.congrats%"><mk-reaction-icon reaction='congrats'/></button>
<button @click="react('angry')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" title="%i18n:common.reactions.angry%"><mk-reaction-icon reaction='angry'/></button>
<button @click="react('confused')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" title="%i18n:common.reactions.confused%"><mk-reaction-icon reaction='confused'/></button>
<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" title="%i18n:common.reactions.pudding%"><mk-reaction-icon reaction='pudding'/></button>
</div>
</div>
</div>
</template>
<script>
import anime from 'animejs';
import api from '../scripts/api';
export default {
props: ['post', 'cb'],
methods: {
react: function (reaction) {
api('posts/reactions/create', {
post_id: this.post.id,
reaction: reaction
}).then(() => {
if (this.cb) this.cb();
this.$destroy();
});
}
}
};
this.mixin('api');
this.post = this.opts.post;
this.source = this.opts.source;
const placeholder = '%i18n:common.tags.mk-reaction-picker.choose-reaction%';
this.title = placeholder;
this.onmouseover = e => {
this.update({
title: e.target.title
});
};
this.onmouseout = () => {
this.update({
title: placeholder
});
};
this.on('mount', () => {
const rect = this.source.getBoundingClientRect();
const width = this.refs.popover.offsetWidth;
const height = this.refs.popover.offsetHeight;
if (this.opts.compact) {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
this.refs.popover.style.left = (x - (width / 2)) + 'px';
this.refs.popover.style.top = (y - (height / 2)) + 'px';
} else {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
this.refs.popover.style.left = (x - (width / 2)) + 'px';
this.refs.popover.style.top = y + 'px';
}
anime({
targets: this.refs.backdrop,
opacity: 1,
duration: 100,
easing: 'linear'
});
anime({
targets: this.refs.popover,
opacity: 1,
scale: [0.5, 1],
duration: 500
});
});
this.react = reaction => {
};
this.close = () => {
this.refs.backdrop.style.pointerEvents = 'none';
anime({
targets: this.refs.backdrop,
opacity: 0,
duration: 200,
easing: 'linear'
});
this.refs.popover.style.pointerEvents = 'none';
anime({
targets: this.refs.popover,
opacity: 0,
scale: 0.5,
duration: 200,
easing: 'easeInBack',
complete: () => this.unmount()
});
};
</script>
<mk-reaction-picker>
<style>
$border-color = rgba(27, 31, 35, 0.15)
:scope
display block
position initial
> .backdrop
position fixed
top 0
left 0
z-index 10000
width 100%
height 100%
background rgba(0, 0, 0, 0.1)
opacity 0
> .popover
position absolute
z-index 10001
background #fff
border 1px solid $border-color
border-radius 4px
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
transform scale(0.5)
opacity 0
$balloon-size = 16px
&:not(.compact)
margin-top $balloon-size
transform-origin center -($balloon-size)
&:before
content ""
display block
position absolute
top -($balloon-size * 2)
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size $border-color
&:after
content ""
display block
position absolute
top -($balloon-size * 2) + 1.5px
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size #fff
> p
display block
margin 0
padding 8px 10px
font-size 14px
color #586069
border-bottom solid 1px #e1e4e8
> div
padding 4px
width 240px
text-align center
> button
width 40px
height 40px
font-size 24px
border-radius 2px
&:hover
background #eee
&:active
background $theme-color
box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
</style>
</mk-reaction-picker>

View file

@ -42,7 +42,7 @@
</mk-signin-history>
<mk-signin-record>
<header onclick={ toggle }>
<header @click="toggle">
<virtual if={ rec.success }>%fa:check%</virtual>
<virtual if={ !rec.success }>%fa:times%</virtual>
<span class="ip">{ rec.ip }</span>

View file

@ -36,7 +36,7 @@
<input name="agree-tou" type="checkbox" autocomplete="off" required="required"/>
<p><a href={ touUrl } target="_blank">利用規約</a>に同意する</p>
</label>
<button onclick={ onsubmit }>%i18n:common.tags.mk-signup.create%</button>
<button @click="onsubmit">%i18n:common.tags.mk-signup.create%</button>
</form>
<style>
:scope

View file

@ -1,78 +0,0 @@
<mk-stream-indicator>
<p if={ connection.state == 'initializing' }>
%fa:spinner .pulse%
<span>%i18n:common.tags.mk-stream-indicator.connecting%<mk-ellipsis/></span>
</p>
<p if={ connection.state == 'reconnecting' }>
%fa:spinner .pulse%
<span>%i18n:common.tags.mk-stream-indicator.reconnecting%<mk-ellipsis/></span>
</p>
<p if={ connection.state == 'connected' }>
%fa:check%
<span>%i18n:common.tags.mk-stream-indicator.connected%</span>
</p>
<style>
:scope
display block
pointer-events none
position fixed
z-index 16384
bottom 8px
right 8px
margin 0
padding 6px 12px
font-size 0.9em
color #fff
background rgba(0, 0, 0, 0.8)
border-radius 4px
> p
display block
margin 0
> [data-fa]
margin-right 0.25em
</style>
<script>
import anime from 'animejs';
this.mixin('i');
this.mixin('stream');
this.connection = this.stream.getConnection();
this.connectionId = this.stream.use();
this.on('before-mount', () => {
if (this.connection.state == 'connected') {
this.root.style.opacity = 0;
}
this.connection.on('_connected_', () => {
this.update();
setTimeout(() => {
anime({
targets: this.root,
opacity: 0,
easing: 'linear',
duration: 200
});
}, 1000);
});
this.connection.on('_closed_', () => {
this.update();
anime({
targets: this.root,
opacity: 1,
easing: 'linear',
duration: 100
});
});
});
this.on('unmount', () => {
this.stream.dispose(this.connectionId);
});
</script>
</mk-stream-indicator>

View file

@ -0,0 +1,74 @@
<template>
<div>
<p v-if=" stream.state == 'initializing' ">
%fa:spinner .pulse%
<span>%i18n:common.tags.mk-stream-indicator.connecting%<mk-ellipsis/></span>
</p>
<p v-if=" stream.state == 'reconnecting' ">
%fa:spinner .pulse%
<span>%i18n:common.tags.mk-stream-indicator.reconnecting%<mk-ellipsis/></span>
</p>
<p v-if=" stream.state == 'connected' ">
%fa:check%
<span>%i18n:common.tags.mk-stream-indicator.connected%</span>
</p>
</div>
</template>
<script>
import anime from 'animejs';
import Ellipsis from './ellipsis.vue';
export default {
props: ['stream'],
created: function() {
if (this.stream.state == 'connected') {
this.root.style.opacity = 0;
}
this.stream.on('_connected_', () => {
setTimeout(() => {
anime({
targets: this.root,
opacity: 0,
easing: 'linear',
duration: 200
});
}, 1000);
});
this.stream.on('_closed_', () => {
anime({
targets: this.root,
opacity: 1,
easing: 'linear',
duration: 100
});
});
}
};
</script>
<style lang="stylus">
> div
display block
pointer-events none
position fixed
z-index 16384
bottom 8px
right 8px
margin 0
padding 6px 12px
font-size 0.9em
color #fff
background rgba(0, 0, 0, 0.8)
border-radius 4px
> p
display block
margin 0
> [data-fa]
margin-right 0.25em
</style>

View file

@ -2,9 +2,9 @@
<p>%i18n:common.tags.mk-twitter-setting.description%<a href={ _DOCS_URL_ + '/link-to-twitter' } target="_blank">%i18n:common.tags.mk-twitter-setting.detail%</a></p>
<p class="account" if={ I.twitter } title={ 'Twitter ID: ' + I.twitter.user_id }>%i18n:common.tags.mk-twitter-setting.connected-to%: <a href={ 'https://twitter.com/' + I.twitter.screen_name } target="_blank">@{ I.twitter.screen_name }</a></p>
<p>
<a href={ _API_URL_ + '/connect/twitter' } target="_blank" onclick={ connect }>{ I.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }</a>
<a href={ _API_URL_ + '/connect/twitter' } target="_blank" @click="connect">{ I.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }</a>
<span if={ I.twitter }> or </span>
<a href={ _API_URL_ + '/disconnect/twitter' } target="_blank" if={ I.twitter } onclick={ disconnect }>%i18n:common.tags.mk-twitter-setting.disconnect%</a>
<a href={ _API_URL_ + '/disconnect/twitter' } target="_blank" if={ I.twitter } @click="disconnect">%i18n:common.tags.mk-twitter-setting.disconnect%</a>
</p>
<p class="id" if={ I.twitter }>Twitter ID: { I.twitter.user_id }</p>
<style>