summaryrefslogtreecommitdiff
path: root/src/web
diff options
context:
space:
mode:
authorsyuilo⭐️ <Syuilotan@yahoo.co.jp>2017-02-22 02:18:57 +0900
committerGitHub <noreply@github.com>2017-02-22 02:18:57 +0900
commit82a28f4c052e9c931c4844f0f330ec301c111366 (patch)
tree321f492a7ad024e568786b831dfc864adeb77aea /src/web
parentUpdate README.md (diff)
parentFix bugs (diff)
downloadmisskey-82a28f4c052e9c931c4844f0f330ec301c111366.tar.gz
misskey-82a28f4c052e9c931c4844f0f330ec301c111366.tar.bz2
misskey-82a28f4c052e9c931c4844f0f330ec301c111366.zip
Merge pull request #193 from syuilo/no-tag-ls
No tag ls
Diffstat (limited to 'src/web')
-rw-r--r--src/web/app/auth/tags/form.tag30
-rw-r--r--src/web/app/auth/tags/index.tag82
-rw-r--r--src/web/app/boot.js5
-rw-r--r--src/web/app/common/scripts/contains.js8
-rw-r--r--src/web/app/common/tags/api-info.tag2
-rw-r--r--src/web/app/common/tags/authorized-apps.tag21
-rw-r--r--src/web/app/common/tags/copyright.tag8
-rw-r--r--src/web/app/common/tags/core-error.tag14
-rw-r--r--src/web/app/common/tags/ellipsis.tag5
-rw-r--r--src/web/app/common/tags/file-type-icon.tag2
-rw-r--r--src/web/app/common/tags/index.js2
-rw-r--r--src/web/app/common/tags/introduction.tag4
-rw-r--r--src/web/app/common/tags/messaging/form.tag97
-rw-r--r--src/web/app/common/tags/messaging/index.tag138
-rw-r--r--src/web/app/common/tags/messaging/message.tag36
-rw-r--r--src/web/app/common/tags/messaging/room.tag170
-rw-r--r--src/web/app/common/tags/number.tag16
-rw-r--r--src/web/app/common/tags/poll-editor.tag33
-rw-r--r--src/web/app/common/tags/poll.tag51
-rw-r--r--src/web/app/common/tags/raw.tag2
-rw-r--r--src/web/app/common/tags/ripple-string.tag26
-rw-r--r--src/web/app/common/tags/signin-history.tag38
-rw-r--r--src/web/app/common/tags/signin.tag68
-rw-r--r--src/web/app/common/tags/signup.tag186
-rw-r--r--src/web/app/common/tags/special-message.tag6
-rw-r--r--src/web/app/common/tags/stream-indicator.tag65
-rw-r--r--src/web/app/common/tags/time.tag73
-rw-r--r--src/web/app/common/tags/twitter-setting.tag2
-rw-r--r--src/web/app/common/tags/uploader.tag77
-rw-r--r--src/web/app/common/tags/url-preview.tag30
-rw-r--r--src/web/app/common/tags/url.tag23
-rw-r--r--src/web/app/desktop/tags/analog-clock.tag160
-rw-r--r--src/web/app/desktop/tags/autocomplete-suggestion.tag176
-rw-r--r--src/web/app/desktop/tags/big-follow-button.tag110
-rw-r--r--src/web/app/desktop/tags/contextmenu.tag72
-rw-r--r--src/web/app/desktop/tags/crop-window.tag48
-rw-r--r--src/web/app/desktop/tags/dialog.tag105
-rw-r--r--src/web/app/desktop/tags/donation.tag27
-rw-r--r--src/web/app/desktop/tags/drive/base-contextmenu.tag38
-rw-r--r--src/web/app/desktop/tags/drive/browser-window.tag23
-rw-r--r--src/web/app/desktop/tags/drive/browser.tag709
-rw-r--r--src/web/app/desktop/tags/drive/file-contextmenu.tag91
-rw-r--r--src/web/app/desktop/tags/drive/file.tag112
-rw-r--r--src/web/app/desktop/tags/drive/folder-contextmenu.tag68
-rw-r--r--src/web/app/desktop/tags/drive/folder.tag235
-rw-r--r--src/web/app/desktop/tags/drive/nav-folder.tag145
-rw-r--r--src/web/app/desktop/tags/ellipsis-icon.tag4
-rw-r--r--src/web/app/desktop/tags/follow-button.tag110
-rw-r--r--src/web/app/desktop/tags/following-setuper.tag74
-rw-r--r--src/web/app/desktop/tags/go-top.tag14
-rw-r--r--src/web/app/desktop/tags/home-widgets/calendar.tag60
-rw-r--r--src/web/app/desktop/tags/home-widgets/donation.tag2
-rw-r--r--src/web/app/desktop/tags/home-widgets/mentions.tag110
-rw-r--r--src/web/app/desktop/tags/home-widgets/nav.tag4
-rw-r--r--src/web/app/desktop/tags/home-widgets/notifications.tag7
-rw-r--r--src/web/app/desktop/tags/home-widgets/photo-stream.tag47
-rw-r--r--src/web/app/desktop/tags/home-widgets/profile.tag18
-rw-r--r--src/web/app/desktop/tags/home-widgets/rss-reader.tag46
-rw-r--r--src/web/app/desktop/tags/home-widgets/timeline.tag131
-rw-r--r--src/web/app/desktop/tags/home-widgets/tips.tag61
-rw-r--r--src/web/app/desktop/tags/home-widgets/user-recommendation.tag66
-rw-r--r--src/web/app/desktop/tags/home.tag51
-rw-r--r--src/web/app/desktop/tags/image-dialog.tag47
-rw-r--r--src/web/app/desktop/tags/images-viewer.tag28
-rw-r--r--src/web/app/desktop/tags/index.js2
-rw-r--r--src/web/app/desktop/tags/input-dialog.tag88
-rw-r--r--src/web/app/desktop/tags/list-user.tag2
-rw-r--r--src/web/app/desktop/tags/messaging/room-window.tag10
-rw-r--r--src/web/app/desktop/tags/messaging/window.tag15
-rw-r--r--src/web/app/desktop/tags/notifications.tag56
-rw-r--r--src/web/app/desktop/tags/pages/entrance.tag26
-rw-r--r--src/web/app/desktop/tags/pages/entrance/signin.tag14
-rw-r--r--src/web/app/desktop/tags/pages/entrance/signup.tag4
-rw-r--r--src/web/app/desktop/tags/pages/home.tag62
-rw-r--r--src/web/app/desktop/tags/pages/not-found.tag45
-rw-r--r--src/web/app/desktop/tags/pages/post.tag19
-rw-r--r--src/web/app/desktop/tags/pages/search.tag13
-rw-r--r--src/web/app/desktop/tags/pages/user.tag20
-rw-r--r--src/web/app/desktop/tags/post-detail-sub.tag61
-rw-r--r--src/web/app/desktop/tags/post-detail.tag186
-rw-r--r--src/web/app/desktop/tags/post-form-window.tag35
-rw-r--r--src/web/app/desktop/tags/post-form.tag247
-rw-r--r--src/web/app/desktop/tags/post-preview.tag8
-rw-r--r--src/web/app/desktop/tags/progress-dialog.tag29
-rw-r--r--src/web/app/desktop/tags/repost-form-window.tag37
-rw-r--r--src/web/app/desktop/tags/repost-form.tag48
-rw-r--r--src/web/app/desktop/tags/search-posts.tag99
-rw-r--r--src/web/app/desktop/tags/search.tag10
-rw-r--r--src/web/app/desktop/tags/select-file-from-drive-window.tag45
-rw-r--r--src/web/app/desktop/tags/set-avatar-suggestion.tag18
-rw-r--r--src/web/app/desktop/tags/set-banner-suggestion.tag18
-rw-r--r--src/web/app/desktop/tags/settings-window.tag13
-rw-r--r--src/web/app/desktop/tags/settings.tag78
-rw-r--r--src/web/app/desktop/tags/stream-indicator.tag54
-rw-r--r--src/web/app/desktop/tags/sub-post-content.tag30
-rw-r--r--src/web/app/desktop/tags/timeline-post-sub.tag16
-rw-r--r--src/web/app/desktop/tags/timeline-post.tag189
-rw-r--r--src/web/app/desktop/tags/timeline.tag63
-rw-r--r--src/web/app/desktop/tags/ui-header-account.tag80
-rw-r--r--src/web/app/desktop/tags/ui-header-clock.tag46
-rw-r--r--src/web/app/desktop/tags/ui-header-nav.tag194
-rw-r--r--src/web/app/desktop/tags/ui-header-notifications.tag56
-rw-r--r--src/web/app/desktop/tags/ui-header-post-button.tag5
-rw-r--r--src/web/app/desktop/tags/ui-header-search.tag9
-rw-r--r--src/web/app/desktop/tags/ui-header.tag5
-rw-r--r--src/web/app/desktop/tags/ui-notification.tag34
-rw-r--r--src/web/app/desktop/tags/ui.tag34
-rw-r--r--src/web/app/desktop/tags/user-followers-window.tag2
-rw-r--r--src/web/app/desktop/tags/user-followers.tag19
-rw-r--r--src/web/app/desktop/tags/user-following-window.tag2
-rw-r--r--src/web/app/desktop/tags/user-following.tag19
-rw-r--r--src/web/app/desktop/tags/user-graphs.tag5
-rw-r--r--src/web/app/desktop/tags/user-header.tag55
-rw-r--r--src/web/app/desktop/tags/user-home.tag10
-rw-r--r--src/web/app/desktop/tags/user-photos.tag50
-rw-r--r--src/web/app/desktop/tags/user-preview.tag77
-rw-r--r--src/web/app/desktop/tags/user-profile.tag24
-rw-r--r--src/web/app/desktop/tags/user-timeline.tag150
-rw-r--r--src/web/app/desktop/tags/user.tag29
-rw-r--r--src/web/app/desktop/tags/users-list.tag85
-rw-r--r--src/web/app/desktop/tags/window.tag542
-rw-r--r--src/web/app/dev/tags/new-app-form.tag109
-rw-r--r--src/web/app/dev/tags/pages/app.tag22
-rw-r--r--src/web/app/dev/tags/pages/apps.tag21
-rw-r--r--src/web/app/dev/tags/pages/index.tag5
-rw-r--r--src/web/app/mobile/tags/drive-selector.tag27
-rw-r--r--src/web/app/mobile/tags/drive.tag426
-rw-r--r--src/web/app/mobile/tags/drive/file-viewer.tag29
-rw-r--r--src/web/app/mobile/tags/drive/file.tag18
-rw-r--r--src/web/app/mobile/tags/drive/folder.tag9
-rw-r--r--src/web/app/mobile/tags/follow-button.tag110
-rw-r--r--src/web/app/mobile/tags/home-timeline.tag62
-rw-r--r--src/web/app/mobile/tags/home.tag8
-rw-r--r--src/web/app/mobile/tags/images-viewer.tag9
-rw-r--r--src/web/app/mobile/tags/index.js1
-rw-r--r--src/web/app/mobile/tags/notification-preview.tag4
-rw-r--r--src/web/app/mobile/tags/notification.tag4
-rw-r--r--src/web/app/mobile/tags/notifications.tag55
-rw-r--r--src/web/app/mobile/tags/notify.tag34
-rw-r--r--src/web/app/mobile/tags/page/drive.tag80
-rw-r--r--src/web/app/mobile/tags/page/entrance.tag26
-rw-r--r--src/web/app/mobile/tags/page/entrance/signup.tag4
-rw-r--r--src/web/app/mobile/tags/page/home.tag56
-rw-r--r--src/web/app/mobile/tags/page/messaging-room.tag29
-rw-r--r--src/web/app/mobile/tags/page/messaging.tag17
-rw-r--r--src/web/app/mobile/tags/page/new-post.tag5
-rw-r--r--src/web/app/mobile/tags/page/notifications.tag18
-rw-r--r--src/web/app/mobile/tags/page/post.tag25
-rw-r--r--src/web/app/mobile/tags/page/search.tag21
-rw-r--r--src/web/app/mobile/tags/page/settings.tag9
-rw-r--r--src/web/app/mobile/tags/page/settings/api.tag9
-rw-r--r--src/web/app/mobile/tags/page/settings/authorized-apps.tag9
-rw-r--r--src/web/app/mobile/tags/page/settings/signin.tag9
-rw-r--r--src/web/app/mobile/tags/page/settings/twitter.tag9
-rw-r--r--src/web/app/mobile/tags/page/user-followers.tag42
-rw-r--r--src/web/app/mobile/tags/page/user-following.tag42
-rw-r--r--src/web/app/mobile/tags/page/user.tag22
-rw-r--r--src/web/app/mobile/tags/post-detail.tag182
-rw-r--r--src/web/app/mobile/tags/post-form.tag162
-rw-r--r--src/web/app/mobile/tags/post-preview.tag2
-rw-r--r--src/web/app/mobile/tags/search-posts.tag38
-rw-r--r--src/web/app/mobile/tags/search.tag11
-rw-r--r--src/web/app/mobile/tags/stream-indicator.tag54
-rw-r--r--src/web/app/mobile/tags/sub-post-content.tag20
-rw-r--r--src/web/app/mobile/tags/timeline-post-sub.tag2
-rw-r--r--src/web/app/mobile/tags/timeline-post.tag117
-rw-r--r--src/web/app/mobile/tags/timeline.tag79
-rw-r--r--src/web/app/mobile/tags/ui-header.tag20
-rw-r--r--src/web/app/mobile/tags/ui-nav.tag16
-rw-r--r--src/web/app/mobile/tags/ui.tag47
-rw-r--r--src/web/app/mobile/tags/user-followers.tag27
-rw-r--r--src/web/app/mobile/tags/user-following.tag27
-rw-r--r--src/web/app/mobile/tags/user-preview.tag2
-rw-r--r--src/web/app/mobile/tags/user-timeline.tag34
-rw-r--r--src/web/app/mobile/tags/user.tag85
-rw-r--r--src/web/app/mobile/tags/users-list.tag73
176 files changed, 5192 insertions, 4702 deletions
diff --git a/src/web/app/auth/tags/form.tag b/src/web/app/auth/tags/form.tag
index 99212febfc..4a236f7594 100644
--- a/src/web/app/auth/tags/form.tag
+++ b/src/web/app/auth/tags/form.tag
@@ -106,21 +106,25 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @session = @opts.session
- @app = @session.app
+ this.session = this.opts.session;
+ this.app = this.session.app;
- @cancel = ~>
- @api \auth/deny do
- token: @session.token
- .then ~>
- @trigger \denied
+ this.cancel = () => {
+ this.api('auth/deny', {
+ token: this.session.token
+ }).then(() => {
+ this.trigger('denied');
+ });
+ };
- @accept = ~>
- @api \auth/accept do
- token: @session.token
- .then ~>
- @trigger \accepted
+ this.accept = () => {
+ this.api('auth/accept', {
+ token: this.session.token
+ }).then(() => {
+ this.trigger('accepted');
+ });
+ };
</script>
</mk-form>
diff --git a/src/web/app/auth/tags/index.tag b/src/web/app/auth/tags/index.tag
index b17d857db2..f80e9dd1bc 100644
--- a/src/web/app/auth/tags/index.tag
+++ b/src/web/app/auth/tags/index.tag
@@ -88,50 +88,60 @@
</style>
<script>
- @mixin \i
- @mixin \api
+ this.mixin('i');
+ this.mixin('api');
- @state = null
- @fetching = true
+ this.state = null;
+ this.fetching = true;
- @token = window.location.href.split \/ .pop!
+ this.token = window.location.href.split('/').pop();
- @on \mount ~>
- if not @SIGNIN then return
+ this.on('mount', () => {
+ if (!this.SIGNIN) return;
- # Fetch session
- @api \auth/session/show do
- token: @token
- .then (session) ~>
- @session = session
- @fetching = false
+ // Fetch session
+ this.api('auth/session/show', {
+ token: this.token
+ }).then(session => {
+ this.session = session;
+ this.fetching = false;
- # 既に連携していた場合
- if @session.app.is_authorized
- @api \auth/accept do
- token: @session.token
- .then ~>
- @accepted!
- else
- @state = \waiting
- @update!
+ // 既に連携していた場合
+ if (this.session.app.is_authorized) {
+ this.api('auth/accept', {
+ token: this.session.token
+ }).then(() => {
+ this.accepted();
+ });
+ } else {
+ this.update({
+ state: 'waiting'
+ });
- @refs.form.on \denied ~>
- @state = \denied
- @update!
+ this.refs.form.on('denied', () => {
+ this.update({
+ state: 'denied'
+ });
+ });
- @refs.form.on \accepted @accepted
+ this.refs.form.on('accepted', this.accepted);
+ }
+ }).catch(error => {
+ this.update({
+ fetching: false,
+ state: 'fetch-session-error'
+ });
+ });
+ });
- .catch (error) ~>
- @fetching = false
- @state = \fetch-session-error
- @update!
+ this.accepted = () => {
+ this.update({
+ state: 'accepted'
+ });
- @accepted = ~>
- @state = \accepted
- @update!
-
- if @session.app.callback_url
- location.href = @session.app.callback_url + '?token=' + @session.token
+ if (this.session.app.callback_url) {
+ location.href = this.session.app.callback_url + '?token=' + this.session.token;
+ }
+ };
</script>
</mk-index>
diff --git a/src/web/app/boot.js b/src/web/app/boot.js
index ab147eb562..06e457e2b3 100644
--- a/src/web/app/boot.js
+++ b/src/web/app/boot.js
@@ -27,13 +27,16 @@ riot.mixin({
// ↓ iOS待ちPolyfill (SEE: http://caniuse.com/#feat=fetch)
require('whatwg-fetch');
-// ↓ NodeList、HTMLCollectionで forEach を使えるようにする
+// ↓ NodeList、HTMLCollection、FileListで forEach を使えるようにする
if (NodeList.prototype.forEach === undefined) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
if (HTMLCollection.prototype.forEach === undefined) {
HTMLCollection.prototype.forEach = Array.prototype.forEach;
}
+if (FileList.prototype.forEach === undefined) {
+ FileList.prototype.forEach = Array.prototype.forEach;
+}
// ↓ iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする
try {
diff --git a/src/web/app/common/scripts/contains.js b/src/web/app/common/scripts/contains.js
new file mode 100644
index 0000000000..fe73666193
--- /dev/null
+++ b/src/web/app/common/scripts/contains.js
@@ -0,0 +1,8 @@
+module.exports = function(parent, child) {
+ let node = child.parentNode;
+ while (node) {
+ if (node == parent) return true;
+ node = node.parentNode;
+ }
+ return false;
+}
diff --git a/src/web/app/common/tags/api-info.tag b/src/web/app/common/tags/api-info.tag
index f3cef26509..d3b1e4c25d 100644
--- a/src/web/app/common/tags/api-info.tag
+++ b/src/web/app/common/tags/api-info.tag
@@ -21,6 +21,6 @@
text-decoration underline
</style>
<script>
- @mixin \i
+ this.mixin('i');
</script>
</mk-api-info>
diff --git a/src/web/app/common/tags/authorized-apps.tag b/src/web/app/common/tags/authorized-apps.tag
index 16e9d9c0c1..14795e49da 100644
--- a/src/web/app/common/tags/authorized-apps.tag
+++ b/src/web/app/common/tags/authorized-apps.tag
@@ -17,18 +17,17 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @apps = []
- @fetching = true
+ this.apps = [];
+ this.fetching = true;
- @on \mount ~>
- @api \i/authorized_apps
- .then (apps) ~>
- @apps = apps
- @fetching = false
- @update!
- .catch (err) ~>
- console.error err
+ this.on('mount', () => {
+ this.api('i/authorized_apps').then(apps => {
+ this.apps = apps;
+ this.fetching = false;
+ this.update();
+ });
+ });
</script>
</mk-authorized-apps>
diff --git a/src/web/app/common/tags/copyright.tag b/src/web/app/common/tags/copyright.tag
index 368c4e3196..9c3f1f648b 100644
--- a/src/web/app/common/tags/copyright.tag
+++ b/src/web/app/common/tags/copyright.tag
@@ -1,11 +1,7 @@
-<mk-copyright><span>(c) syuilo 2014-2017</span>
+<mk-copyright>
+ <span>(c) syuilo 2014-2017</span>
<style>
:scope
display block
-
-
-
-
-
</style>
</mk-copyright>
diff --git a/src/web/app/common/tags/core-error.tag b/src/web/app/common/tags/core-error.tag
index 5b5d163600..feac70fbea 100644
--- a/src/web/app/common/tags/core-error.tag
+++ b/src/web/app/common/tags/core-error.tag
@@ -1,8 +1,7 @@
<mk-core-error>
- <!--i: i.fa.fa-times-circle--><img src="/_/resources/error.jpg" alt=""/>
- <h1>
- <mk-ripple-string>サーバーに接続できません</mk-ripple-string>
- </h1>
+ <!--i: i.fa.fa-times-circle-->
+ <img src="/_/resources/error.jpg" alt=""/>
+ <h1>サーバーに接続できません</h1>
<p class="text">インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから<a onclick={ retry }>再度お試し</a>ください。</p>
<p class="thanks">いつもMisskeyをご利用いただきありがとうございます。</p>
<style>
@@ -57,8 +56,9 @@
</style>
<script>
- @retry = ~>
- @unmount!
- @opts.retry!
+ this.retry = () => {
+ this.unmount();
+ this.opts.retry();
+ }
</script>
</mk-core-error>
diff --git a/src/web/app/common/tags/ellipsis.tag b/src/web/app/common/tags/ellipsis.tag
index 58f1083954..97ef745d02 100644
--- a/src/web/app/common/tags/ellipsis.tag
+++ b/src/web/app/common/tags/ellipsis.tag
@@ -20,10 +20,5 @@
opacity 1
40%
opacity 0
-
-
-
-
-
</style>
</mk-ellipsis>
diff --git a/src/web/app/common/tags/file-type-icon.tag b/src/web/app/common/tags/file-type-icon.tag
index 37cae49993..55c473bcd4 100644
--- a/src/web/app/common/tags/file-type-icon.tag
+++ b/src/web/app/common/tags/file-type-icon.tag
@@ -5,6 +5,6 @@
display inline
</style>
<script>
- @kind = @opts.type.split \/ .0
+ this.kind = this.opts.type.split('/')[0];
</script>
</mk-file-type-icon>
diff --git a/src/web/app/common/tags/index.js b/src/web/app/common/tags/index.js
index 21d817dbd2..90f03825e2 100644
--- a/src/web/app/common/tags/index.js
+++ b/src/web/app/common/tags/index.js
@@ -1,7 +1,6 @@
require('./core-error.tag');
require('./url.tag');
require('./url-preview.tag');
-require('./ripple-string.tag');
require('./time.tag');
require('./file-type-icon.tag');
require('./uploader.tag');
@@ -24,3 +23,4 @@ require('./messaging/room.tag');
require('./messaging/message.tag');
require('./messaging/index.tag');
require('./messaging/form.tag');
+require('./stream-indicator.tag');
diff --git a/src/web/app/common/tags/introduction.tag b/src/web/app/common/tags/introduction.tag
index 24fe86e997..fda011efff 100644
--- a/src/web/app/common/tags/introduction.tag
+++ b/src/web/app/common/tags/introduction.tag
@@ -21,9 +21,5 @@
margin 0
text-align center
-
-
-
-
</style>
</mk-introduction>
diff --git a/src/web/app/common/tags/messaging/form.tag b/src/web/app/common/tags/messaging/form.tag
index d6750fb9ec..4e5f5262af 100644
--- a/src/web/app/common/tags/messaging/form.tag
+++ b/src/web/app/common/tags/messaging/form.tag
@@ -2,9 +2,15 @@
<textarea ref="text" onkeypress={ onkeypress } onpaste={ onpaste } placeholder="ここにメッセージを入力"></textarea>
<div class="files"></div>
<mk-uploader ref="uploader"></mk-uploader>
- <button class="send" onclick={ send } disabled={ sending } title="メッセージを送信"><i class="fa fa-paper-plane" if={ !sending }></i><i class="fa fa-spinner fa-spin" if={ sending }></i></button>
- <button class="attach-from-local" type="button" title="PCから画像を添付する"><i class="fa fa-upload"></i></button>
- <button class="attach-from-drive" type="button" title="アルバムから画像を添付する"><i class="fa fa-folder-open"></i></button>
+ <button class="send" onclick={ send } disabled={ sending } title="メッセージを送信">
+ <i class="fa fa-paper-plane" if={ !sending }></i><i class="fa fa-spinner fa-spin" if={ sending }></i>
+ </button>
+ <button class="attach-from-local" type="button" title="PCから画像を添付する">
+ <i class="fa fa-upload"></i>
+ </button>
+ <button class="attach-from-drive" type="button" title="アルバムから画像を添付する">
+ <i class="fa fa-folder-open"></i>
+ </button>
<input name="file" type="file" accept="image/*"/>
<style>
:scope
@@ -111,49 +117,60 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @onpaste = (e) ~>
- data = e.clipboard-data
- items = data.items
- for i from 0 to items.length - 1
- item = items[i]
- switch (item.kind)
- | \file =>
- @upload item.get-as-file!
+ this.onpaste = (e) => {
+ const data = e.clipboardData;
+ const items = data.items;
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ if (item.kind == 'file') {
+ this.upload(item.getAsFile());
+ }
+ }
+ };
- @onkeypress = (e) ~>
- if (e.which == 10 || e.which == 13) && e.ctrl-key
- @send!
+ this.onkeypress = (e) => {
+ if ((e.which == 10 || e.which == 13) && e.ctrlKey) {
+ this.send();
+ }
+ };
- @select-file = ~>
- @refs.file.click!
+ this.selectFile = () => {
+ this.refs.file.click();
+ };
- @select-file-from-drive = ~>
- browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
- event = riot.observable!
- riot.mount browser, do
- multiple: true
+ this.selectFileFromDrive = () => {
+ const browser = document.body.appendChild(document.createElement('mk-select-file-from-drive-window'));
+ const event = riot.observable();
+ riot.mount(browser, {
+ multiple: true,
event: event
- event.one \selected (files) ~>
- files.for-each @add-file
+ });
+ event.one('selected', files => {
+ files.forEach(this.addFile);
+ });
+ };
- @send = ~>
- @sending = true
- @api \messaging/messages/create do
- user_id: @opts.user.id
- text: @refs.text.value
- .then (message) ~>
- @clear!
- .catch (err) ~>
- console.error err
- .then ~>
- @sending = false
- @update!
+ this.send = () => {
+ this.sending = true;
+ this.api('messaging/messages/create', {
+ user_id: this.opts.user.id,
+ text: this.refs.text.value
+ }).then(message => {
+ this.clear();
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.sending = false;
+ this.update();
+ });
+ };
- @clear = ~>
- @refs.text.value = ''
- @files = []
- @update!
+ this.clear = () => {
+ this.refs.text.value = '';
+ this.files = [];
+ this.update();
+ };
</script>
</mk-messaging-form>
diff --git a/src/web/app/common/tags/messaging/index.tag b/src/web/app/common/tags/messaging/index.tag
index 69f78ba8e3..2dbf76bd9a 100644
--- a/src/web/app/common/tags/messaging/index.tag
+++ b/src/web/app/common/tags/messaging/index.tag
@@ -286,72 +286,88 @@
</style>
<script>
- @mixin \i
- @mixin \api
+ this.mixin('i');
+ this.mixin('api');
- @search-result = []
+ this.searchResult = [];
- @on \mount ~>
- @api \messaging/history
- .then (history) ~>
- @is-loading = false
- history.for-each (message) ~>
- message.is_me = message.user_id == @I.id
- message._click = ~>
- if message.is_me
- @trigger \navigate-user message.recipient
- else
- @trigger \navigate-user message.user
- @history = history
- @update!
- .catch (err) ~>
- console.error err
+ this.on('mount', () => {
+ this.api('messaging/history').then(history => {
+ this.isLoading = false;
+ history.forEach(message => {
+ message.is_me = message.user_id == this.I.id
+ message._click = () => {
+ this.trigger('navigate-user', message.is_me ? message.recipient : message.user);
+ };
+ });
+ this.history = history;
+ this.update();
+ });
+ });
- @search = ~>
- q = @refs.search.value
- if q == ''
- @search-result = []
- else
- @api \users/search do
- query: q
- max: 5
- .then (users) ~>
- users.for-each (user) ~>
- user._click = ~>
- @trigger \navigate-user user
- @search-result = []
- @search-result = users
- @update!
- .catch (err) ~>
- console.error err
+ this.search = () => {
+ const q = this.refs.search.value;
+ if (q == '') {
+ this.searchResult = [];
+ return;
+ }
+ this.api('users/search', {
+ query: q,
+ max: 5
+ }).then(users => {
+ users.forEach(user => {
+ user._click = () => {
+ this.trigger('navigate-user', user);
+ this.searchResult = [];
+ };
+ });
+ this.update({
+ searchResult: users
+ });
+ });
+ };
- @on-search-keydown = (e) ~>
- key = e.which
- switch (key)
- | 9, 40 => # Key[TAB] or Key[↓]
- e.prevent-default!
- e.stop-propagation!
- @refs.search-result.child-nodes[0].focus!
+ this.onSearchKeydown = e => {
+ switch (e.which) {
+ case 9: // [TAB]
+ case 40: // [↓]
+ e.preventDefault();
+ e.stopPropagation();
+ this.refs.searchResult.childNodes[0].focus();
+ break;
+ }
+ };
- @on-search-result-keydown = (i, e) ~>
- key = e.which
- switch (key)
- | 10, 13 => # Key[ENTER]
- e.prevent-default!
- e.stop-propagation!
- @search-result[i]._click!
- | 27 => # Key[ESC]
- e.prevent-default!
- e.stop-propagation!
- @refs.search.focus!
- | 38 => # Key[↑]
- e.prevent-default!
- e.stop-propagation!
- (@refs.search-result.child-nodes[i].previous-element-sibling || @refs.search-result.child-nodes[@search-result.length - 1]).focus!
- | 9, 40 => # Key[TAB] or Key[↓]
- e.prevent-default!
- e.stop-propagation!
- (@refs.search-result.child-nodes[i].next-element-sibling || @refs.search-result.child-nodes[0]).focus!
+ this.onSearchResultKeydown = (i, e) => {
+ const cancel = () => {
+ e.preventDefault();
+ e.stopPropagation();
+ };
+ switch (true) {
+ case e.which == 10: // [ENTER]
+ case e.which == 13: // [ENTER]
+ cancel();
+ this.searchResult[i]._click();
+ break;
+
+ case e.which == 27: // [ESC]
+ cancel();
+ this.refs.search.focus();
+ break;
+
+ case e.which == 9 && e.shiftKey: // [TAB] + [Shift]
+ case e.which == 38: // [↑]
+ cancel();
+ (this.refs.searchResult.childNodes[i].previousElementSibling || this.refs.searchResult.childNodes[this.searchResult.length - 1]).focus();
+ break;
+
+ case e.which == 9: // [TAB]
+ case e.which == 40: // [↓]
+ cancel();
+ (this.refs.searchResult.childNodes[i].nextElementSibling || this.refs.searchResult.childNodes[0]).focus();
+ break;
+ }
+ };
</script>
</mk-messaging>
diff --git a/src/web/app/common/tags/messaging/message.tag b/src/web/app/common/tags/messaging/message.tag
index 5765ffa6c8..de763c779a 100644
--- a/src/web/app/common/tags/messaging/message.tag
+++ b/src/web/app/common/tags/messaging/message.tag
@@ -203,28 +203,32 @@
</style>
<script>
- @mixin \i
- @mixin \text
+ this.mixin('i');
+ this.mixin('text');
- @message = @opts.message
- @message.is_me = @message.user.id == @I.id
+ this.message = this.opts.message;
+ this.message.is_me = this.message.user.id == this.I.id;
- @on \mount ~>
- if @message.text?
- tokens = @analyze @message.text
+ this.on('mount', () => {
+ if (this.message.text) {
+ const tokens = this.analyze(this.message.text);
- @refs.text.innerHTML = @compile tokens
+ this.refs.text.innerHTML = this.compile(tokens);
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
- # URLをプレビュー
+ // URLをプレビュー
tokens
- .filter (t) -> t.type == \link
- .map (t) ~>
- @preview = @refs.text.append-child document.create-element \mk-url-preview
- riot.mount @preview, do
+ .filter(t => t.type == 'link')
+ .map(t => {
+ const el = this.refs.text.appendChild(document.createElement('mk-url-preview'));
+ riot.mount(el, {
url: t.content
+ });
+ });
+ }
+ });
</script>
</mk-messaging-message>
diff --git a/src/web/app/common/tags/messaging/room.tag b/src/web/app/common/tags/messaging/room.tag
index 5882a7fa40..c7fed91db3 100644
--- a/src/web/app/common/tags/messaging/room.tag
+++ b/src/web/app/common/tags/messaging/room.tag
@@ -124,101 +124,117 @@
</style>
<script>
- @mixin \i
- @mixin \api
- @mixin \messaging-stream
+ this.mixin('i');
+ this.mixin('api');
+ this.mixin('messaging-stream');
- @user = @opts.user
- @init = true
- @sending = false
- @messages = []
+ this.user = this.opts.user;
+ this.init = true;
+ this.sending = false;
+ this.messages = [];
- @connection = new @MessagingStreamConnection @I, @user.id
+ this.connection = new this.MessagingStreamConnection(this.I, this.user.id);
- @on \mount ~>
- @connection.event.on \message @on-message
- @connection.event.on \read @on-read
+ this.on('mount', () => {
+ this.connection.event.on('message', this.onMessage);
+ this.connection.event.on('read', this.onRead);
- document.add-event-listener \visibilitychange @on-visibilitychange
+ document.addEventListener('visibilitychange', this.onVisibilitychange);
- @api \messaging/messages do
- user_id: @user.id
- .then (messages) ~>
- @init = false
- @messages = messages.reverse!
- @update!
- @scroll-to-bottom!
- .catch (err) ~>
- console.error err
+ this.api('messaging/messages', {
+ user_id: this.user.id
+ }).then(messages => {
+ this.init = false;
+ this.messages = messages.reverse();
+ this.update();
+ this.scrollToBottom();
+ });
+ });
- @on \unmount ~>
- @connection.event.off \message @on-message
- @connection.event.off \read @on-read
- @connection.close!
+ this.on('unmount', () => {
+ this.connection.event.off('message', this.onMessage);
+ this.connection.event.off('read', this.onRead);
+ this.connection.close();
- document.remove-event-listener \visibilitychange @on-visibilitychange
+ document.removeEventListener('visibilitychange', this.onVisibilitychange);
+ });
- @on \update ~>
- @messages.for-each (message) ~>
- date = (new Date message.created_at).get-date!
- month = (new Date message.created_at).get-month! + 1
- message._date = date
- message._datetext = month + '月 ' + date + '日'
+ this.on('update', () => {
+ this.messages.forEach(message => {
+ const date = (new Date(message.created_at)).getDate();
+ const month = (new Date(message.created_at)).getMonth() + 1;
+ message._date = date;
+ message._datetext = month + '月 ' + date + '日';
+ });
+ });
- @on-message = (message) ~>
- is-bottom = @is-bottom!
+ this.onMessage = (message) => {
+ const isbottom = this.isBottom();
- @messages.push message
- if message.user_id != @I.id and not document.hidden
- @connection.socket.send JSON.stringify do
- type: \read
+ this.messages.push(message);
+ if (message.user_id != this.I.id && !document.hidden) {
+ this.connection.socket.send(JSON.stringify({
+ type: 'read',
id: message.id
- @update!
+ }));
+ }
+ this.update();
- if is-bottom
- # Scroll to bottom
- @scroll-to-bottom!
- else if message.user_id != @I.id
- # Notify
- @notify '新しいメッセージがあります'
+ if (isBottom) {
+ // Scroll to bottom
+ this.scrollToBottom();
+ } else if (message.user_id != this.I.id) {
+ // Notify
+ this.notify('新しいメッセージがあります');
+ }
+ };
- @on-read = (ids) ~>
- if not Array.isArray ids then ids = [ids]
- ids.for-each (id) ~>
- if (@messages.some (x) ~> x.id == id)
- exist = (@messages.map (x) -> x.id).index-of id
- @messages[exist].is_read = true
- @update!
+ this.onRead = ids => {
+ if (!Array.isArray(ids)) ids = [ids];
+ ids.forEach(id => {
+ if (this.messages.some(x => x.id == id)) {
+ const exist = this.messages.map(x => x.id).indexOf(id);
+ this.messages[exist].is_read = true;
+ this.update();
+ }
+ });
+ };
- @is-bottom = ~>
- current = @root.scroll-top + @root.offset-height
- max = @root.scroll-height
- current > (max - 32)
+ this.isBottom = () => {
+ const current = this.root.scrollTop + this.root.offsetHeight;
+ const max = this.root.scrollHeight;
+ return current > (max - 32);
+ };
- @scroll-to-bottom = ~>
- @root.scroll-top = @root.scroll-height
+ this.scrollToBottom = () => {
+ this.root.scrollTop = this.root.scrollHeight;
+ };
- @notify = (message) ~>
- n = document.create-element \p
- n.inner-HTML = '<i class="fa fa-arrow-circle-down"></i>' + message
- n.onclick = ~>
- @scroll-to-bottom!
- n.parent-node.remove-child n
- @refs.notifications.append-child n
+ this.notify = message => {
+ const n = document.createElement('p');
+ n.innerHTML = '<i class="fa fa-arrow-circle-down"></i>' + message;
+ n.onclick = () => {
+ this.scrollToBottom();
+ n.parentNode.removeChild(n);
+ };
+ this.refs.notifications.appendChild(n);
- set-timeout ~>
- n.style.opacity = 0
- set-timeout ~>
- n.parent-node.remove-child n
- , 1000ms
- , 4000ms
+ setTimeout(() => {
+ n.style.opacity = 0;
+ setTimeout(() => n.parentNode.removeChild(n), 1000);
+ }, 4000);
+ };
- @on-visibilitychange = ~>
- if document.hidden then return
- @messages.for-each (message) ~>
- if message.user_id != @I.id and not message.is_read
- @connection.socket.send JSON.stringify do
- type: \read
+ this.onVisibilitychange = () => {
+ if (document.hidden) return;
+ this.messages.forEach(message => {
+ if (message.user_id !== this.I.id && !message.is_read) {
+ this.connection.socket.send(JSON.stringify({
+ type: 'read',
id: message.id
+ }));
+ }
+ });
+ };
</script>
</mk-messaging-room>
diff --git a/src/web/app/common/tags/number.tag b/src/web/app/common/tags/number.tag
index c878c842e2..7dcbceba6a 100644
--- a/src/web/app/common/tags/number.tag
+++ b/src/web/app/common/tags/number.tag
@@ -2,17 +2,17 @@
<style>
:scope
display inline
-
</style>
<script>
- @on \mount ~>
- # バグ? https://github.com/riot/riot/issues/2103
- #value = @opts.value
- value = @opts.riot-value
- max = @opts.max
+ this.on('mount', () => {
+ // https://github.com/riot/riot/issues/2103
+ //value = this.opts.value
+ let value = this.opts.riotValue;
+ const max = this.opts.max;
- if max? then if value > max then value = max
+ if (max != null && value > max) value = max;
- @root.innerHTML = value.to-locale-string!
+ this.root.innerHTML = value.toLocaleString();
+ });
</script>
</mk-number>
diff --git a/src/web/app/common/tags/poll-editor.tag b/src/web/app/common/tags/poll-editor.tag
index 1c9c668f0b..9d9b28c763 100644
--- a/src/web/app/common/tags/poll-editor.tag
+++ b/src/web/app/common/tags/poll-editor.tag
@@ -86,26 +86,31 @@
</style>
<script>
- @choices = ['', '']
+ this.choices = ['', ''];
- @oninput = (i, e) ~>
- @choices[i] = e.target.value
+ this.oninput = (i, e) => {
+ this.choices[i] = e.target.value;
+ }
- @add = ~>
- @choices.push ''
- @update!
- @refs.choices.child-nodes[@choices.length - 1].child-nodes[0].focus!
+ this.add = () => {
+ this.choices.push('');
+ this.update();
+ this.refs.choices.childNodes[this.choices.length - 1].childNodes[0].focus();
+ }
- @remove = (i) ~>
- @choices = @choices.filter((_, _i) -> _i != i)
- @update!
+ this.remove = (i) => {
+ this.choices = this.choices.filter((_, _i) => _i != i);
+ this.update();
+ }
- @destroy = ~>
- @opts.ondestroy!
+ this.destroy = () => {
+ this.opts.ondestroy();
+ }
- @get = ~>
+ this.get = () => {
return {
- choices: @choices.filter (choice) -> choice != ''
+ choices: this.choices.filter(choice => choice != '')
}
+ }
</script>
</mk-poll-editor>
diff --git a/src/web/app/common/tags/poll.tag b/src/web/app/common/tags/poll.tag
index 426bb44281..6ddaf77595 100644
--- a/src/web/app/common/tags/poll.tag
+++ b/src/web/app/common/tags/poll.tag
@@ -68,32 +68,37 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @post = @opts.post
- @poll = @post.poll
- @total = @poll.choices.reduce ((a, b) -> a + b.votes), 0
- @is-voted = @poll.choices.some (c) -> c.is_voted
- @result = @is-voted
+ this.post = this.opts.post;
+ this.poll = this.post.poll;
+ this.total = this.poll.choices.reduce((a, b) => a + b.votes, 0);
+ this.isVoted = this.poll.choices.some(c => c.is_voted);
+ this.result = this.isVoted;
- @toggle-result = ~>
- @result = !@result
+ this.toggleResult = () => {
+ this.result = !this.result;
+ }
- @vote = (id) ~>
- if (@poll.choices.some (c) -> c.is_voted) then return
- @api \posts/polls/vote do
- post_id: @post.id
+ this.vote = (id) => {
+ if (this.poll.choices.some(c => c.is_voted)) return;
+ this.api('posts/polls/vote', {
+ post_id: this.post.id,
choice: id
- .then ~>
- @poll.choices.for-each (c) ->
- if c.id == id
- c.votes++
- c.is_voted = true
- @update do
- poll: @poll
- is-voted: true
- result: true
- total: @total + 1
-
+ }).then(() => {
+ this.poll.choices.forEach(c => {
+ if (c.id == id) {
+ c.votes++;
+ c.is_voted = true;
+ }
+ });
+ this.update({
+ poll: this.poll,
+ isVoted: true,
+ result: true,
+ total: this.total + 1
+ });
+ });
+ }
</script>
</mk-poll>
diff --git a/src/web/app/common/tags/raw.tag b/src/web/app/common/tags/raw.tag
index 609c53e7e9..0637675c45 100644
--- a/src/web/app/common/tags/raw.tag
+++ b/src/web/app/common/tags/raw.tag
@@ -4,5 +4,5 @@
display inline
</style>
- <script>@root.innerHTML = @opts.content</script>
+ <script>this.root.innerHTML = this.opts.content</script>
</mk-raw>
diff --git a/src/web/app/common/tags/ripple-string.tag b/src/web/app/common/tags/ripple-string.tag
deleted file mode 100644
index d3303e6ba6..0000000000
--- a/src/web/app/common/tags/ripple-string.tag
+++ /dev/null
@@ -1,26 +0,0 @@
-<mk-ripple-string><yield/>
- <style>
- :scope
- display inline
-
- > span
- animation ripple-string 5s infinite ease-in-out both
-
- @keyframes ripple-string
- 0%, 50%, 100%
- opacity 1
- 25%
- opacity 0.5
-
- </style>
- <script>
- @on \mount ~>
- text = @root.innerHTML
- @root.innerHTML = ''
- (text.split '').for-each (c, i) ~>
- ce = document.create-element \span
- ce.innerHTML = c
- ce.style.animation-delay = (i / 10) + 's'
- @root.append-child ce
- </script>
-</mk-ripple-string>
diff --git a/src/web/app/common/tags/signin-history.tag b/src/web/app/common/tags/signin-history.tag
index ffc837891d..3868980058 100644
--- a/src/web/app/common/tags/signin-history.tag
+++ b/src/web/app/common/tags/signin-history.tag
@@ -48,28 +48,30 @@
</style>
<script>
- @mixin \api
- @mixin \stream
+ this.mixin('api');
+ this.mixin('stream');
- @history = []
- @fetching = true
+ this.history = [];
+ this.fetching = true;
- @on \mount ~>
- @api \i/signin_history
- .then (history) ~>
- @history = history
- @fetching = false
- @update!
- .catch (err) ~>
- console.error err
+ this.on('mount', () => {
+ this.api('i/signin_history').then(history => {
+ this.update({
+ fetching: false,
+ history: history
+ });
+ });
- @stream.on \signin @on-signin
+ this.stream.on('signin', this.onSignin);
+ });
- @on \unmount ~>
- @stream.off \signin @on-signin
+ this.on('unmount', () => {
+ this.stream.off('signin', this.onSignin);
+ });
- @on-signin = (signin) ~>
- @history.unshift signin
- @update!
+ this.onSignin = signin => {
+ this.history.unshift(signin);
+ this.update();
+ };
</script>
</mk-signin-history>
diff --git a/src/web/app/common/tags/signin.tag b/src/web/app/common/tags/signin.tag
index 28d73b037f..c44ae3d6ee 100644
--- a/src/web/app/common/tags/signin.tag
+++ b/src/web/app/common/tags/signin.tag
@@ -97,42 +97,50 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @user = null
- @signing = false
+ this.user = null;
+ this.signing = false;
- @oninput = ~>
- @api \users/show do
- username: @refs.username.value
- .then (user) ~>
- @user = user
- @trigger \user user
- @update!
+ this.oninput = () => {
+ this.api('users/show', {
+ username: this.refs.username.value
+ }).then(user => {
+ this.user = user;
+ this.trigger('user', user);
+ this.update();
+ });
+ };
- @onsubmit = (e) ~>
- e.prevent-default!
+ this.onsubmit = e => {
+ e.preventDefault();
- if @refs.username.value == ''
- @refs.username.focus!
- return false
- if @refs.password.value == ''
- @refs.password.focus!
- return false
+ if (this.refs.username.value == '') {
+ this.refs.username.focus();
+ return false;
+ }
+ if (this.refs.password.value == '') {
+ this.refs.password.focus();
+ return false;
+ }
- @signing = true
- @update!
+ this.update({
+ signing: true
+ });
- @api \signin do
- username: @refs.username.value
- password: @refs.password.value
- .then ~>
- location.reload!
- .catch ~>
- alert 'something happened'
- @signing = false
- @update!
+ this.api('signin', {
+ username: this.refs.username.value,
+ password: this.refs.password.value
+ }).then(() => {
+ location.reload();
+ }).catch(() => {
+ alert('something happened');
+ this.update({
+ signing: false
+ });
+ });
- false
+ return false;
+ };
</script>
</mk-signin>
diff --git a/src/web/app/common/tags/signup.tag b/src/web/app/common/tags/signup.tag
index 7af72807a5..f0358e2328 100644
--- a/src/web/app/common/tags/signup.tag
+++ b/src/web/app/common/tags/signup.tag
@@ -174,120 +174,126 @@
</style>
<script>
- @mixin \api
- @mixin \get-password-strength
+ this.mixin('api');
+ this.mixin('get-password-strength');
- @username-state = null
- @password-strength = ''
- @password-retype-state = null
- @recaptchaed = false
+ this.usernameState = null;
+ this.passwordStrength = '';
+ this.passwordRetypeState = null;
+ this.recaptchaed = false;
- window.on-recaptchaed = ~>
- @recaptchaed = true
- @update!
+ window.onEecaptchaed = () => {
+ this.recaptchaed = true;
+ this.update();
+ };
- window.on-recaptcha-expired = ~>
- @recaptchaed = false
- @update!
+ window.onRecaptchaExpired = () => {
+ this.recaptchaed = false;
+ this.update();
+ };
- @on \mount ~>
- head = (document.get-elements-by-tag-name \head).0
- script = document.create-element \script
- ..set-attribute \src \https://www.google.com/recaptcha/api.js
- head.append-child script
+ this.on('mount', () => {
+ const head = document.getElementsByTagName('head')[0];
+ const script = document.createElement('script');
+ script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
+ head.appendChild(script);
+ });
- @on-change-username = ~>
- username = @refs.username.value
+ this.onChangeUsername = () => {
+ const username = this.refs.username.value;
- if username == ''
- @username-state = null
- @update!
- return
+ if (username == '') {
+ this.update({
+ usernameState: null
+ });
+ return;
+ }
- err = switch
- | not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
- | username.length < 3chars => \min-range
- | username.length > 20chars => \max-range
- | _ => null
+ const err =
+ !username.match(/^[a-zA-Z0-9\-]+$/) ? 'invalid-format' :
+ username.length < 3 ? 'min-range' :
+ username.length > 20 ? 'max-range' :
+ null;
- if err?
- @username-state = err
- @update!
- else
- @username-state = \wait
- @update!
+ if (err) {
+ this.update({
+ usernameState: err
+ });
+ return;
+ }
- @api \username/available do
- username: username
- .then (result) ~>
- if result.available
- @username-state = \ok
- else
- @username-state = \unavailable
- @update!
- .catch (err) ~>
- @username-state = \error
- @update!
+ this.update({
+ usernameState: 'wait'
+ });
- @on-change-password = ~>
- password = @refs.password.value
-
- if password == ''
- @password-strength = ''
- return
-
- strength = @get-password-strength password
+ this.api('username/available', {
+ username: username
+ }).then(result => {
+ this.update({
+ usernameState: result.available ? 'ok' : 'unavailable'
+ });
+ }).catch(err => {
+ this.update({
+ usernameState: 'error'
+ });
+ });
+ };
- if strength > 0.3
- @password-strength = \medium
- if strength > 0.7
- @password-strength = \high
- else
- @password-strength = \low
+ this.onChangePassword = () => {
+ const password = this.refs.password.value;
- @update!
+ if (password == '') {
+ this.passwordStrength = '';
+ return;
+ }
- @refs.password-metar.style.width = (strength * 100) + \%
+ const strength = this.getPasswordStrength(password);
+ this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
+ this.update();
+ this.refs.passwordMetar.style.width = `${strength * 100}%`;
+ };
- @on-change-password-retype = ~>
- password = @refs.password.value
- retyped-password = @refs.password-retype.value
+ this.onChangePasswordRetype = () => {
+ const password = this.refs.password.value;
+ const retypedPassword = this.refs.passwordRetype.value;
- if retyped-password == ''
- @password-retype-state = null
- return
+ if (retypedPassword == '') {
+ this.passwordRetypeState = null;
+ return;
+ }
- if password == retyped-password
- @password-retype-state = \match
- else
- @password-retype-state = \not-match
+ this.passwordRetypeState = password == retypedPassword ? 'match' : 'not-match';
+ };
- @onsubmit = (e) ~>
- e.prevent-default!
+ this.onsubmit = e => {
+ e.preventDefault();
- username = @refs.username.value
- password = @refs.password.value
+ const username = this.refs.username.value;
+ const password = this.refs.password.value;
- locker = document.body.append-child document.create-element \mk-locker
+ const locker = document.body.appendChild(document.createElement('mk-locker'));
- @api \signup do
- username: username
- password: password
- 'g-recaptcha-response': grecaptcha.get-response!
- .then ~>
- @api \signin do
- username: username
+ this.api('signup', {
+ username: username,
+ password: password,
+ 'g-recaptcha-response': grecaptcha.getResponse()
+ }).then(() => {
+ this.api('signin', {
+ username: username,
password: password
- .then ~>
+ }).then(() => {
location.href = CONFIG.url
- .catch ~>
- alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
+ });
+ }).catch(() => {
+ alert('何らかの原因によりアカウントの作成に失敗しました。再度お試しください。');
- grecaptcha.reset!
- @recaptchaed = false
+ grecaptcha.reset();
+ this.recaptchaed = false;
- locker.parent-node.remove-child locker
+ locker.parentNode.removeChild(locker);
+ });
- false
+ return false;
+ };
</script>
</mk-signup>
diff --git a/src/web/app/common/tags/special-message.tag b/src/web/app/common/tags/special-message.tag
index 53c54c9816..41bd5fe32a 100644
--- a/src/web/app/common/tags/special-message.tag
+++ b/src/web/app/common/tags/special-message.tag
@@ -20,8 +20,8 @@
</style>
<script>
- now = new Date!
- @d = now.get-date!
- @m = now.get-month! + 1
+ const now = new Date();
+ this.d = now.getDate();
+ this.m = now.getMonth() + 1;
</script>
</mk-special-message>
diff --git a/src/web/app/common/tags/stream-indicator.tag b/src/web/app/common/tags/stream-indicator.tag
new file mode 100644
index 0000000000..7d343a438a
--- /dev/null
+++ b/src/web/app/common/tags/stream-indicator.tag
@@ -0,0 +1,65 @@
+<mk-stream-indicator>
+ <p if={ state == 'initializing' }>
+ <i class="fa fa-spinner fa-spin"></i>
+ <span>接続中<mk-ellipsis></mk-ellipsis></span>
+ </p>
+ <p if={ state == 'reconnecting' }>
+ <i class="fa fa-spinner fa-spin"></i>
+ <span>切断されました 接続中<mk-ellipsis></mk-ellipsis></span>
+ </p>
+ <p if={ state == 'connected' }>
+ <i class="fa fa-check"></i>
+ <span>接続完了</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)
+
+ > p
+ display block
+ margin 0
+
+ > i
+ margin-right 0.25em
+
+ </style>
+ <script>
+ this.mixin('stream');
+
+ this.on('before-mount', () => {
+ this.state = this.getStreamState();
+
+ if (this.state == 'connected') {
+ this.root.style.opacity = 0;
+ }
+ });
+
+ this.streamStateEv.on('connected', () => {
+ this.state = this.getStreamState();
+ this.update();
+ setTimeout(() => {
+ Velocity(this.root, {
+ opacity: 0
+ }, 200, 'linear');
+ }, 1000);
+ });
+
+ this.streamStateEv.on('closed', () => {
+ this.state = this.getStreamState();
+ this.update();
+ Velocity(this.root, {
+ opacity: 1
+ }, 0);
+ });
+ </script>
+</mk-stream-indicator>
diff --git a/src/web/app/common/tags/time.tag b/src/web/app/common/tags/time.tag
index 0c9a6d6f90..ad34115f60 100644
--- a/src/web/app/common/tags/time.tag
+++ b/src/web/app/common/tags/time.tag
@@ -1,41 +1,50 @@
<mk-time>
- <time datetime={ opts.time }><span if={ mode == 'relative' }>{ relative }</span><span if={ mode == 'absolute' }>{ absolute }</span><span if={ mode == 'detail' }>{ absolute } ({ relative })</span></time>
+ <time datetime={ opts.time }>
+ <span if={ mode == 'relative' }>{ relative }</span>
+ <span if={ mode == 'absolute' }>{ absolute }</span>
+ <span if={ mode == 'detail' }>{ absolute } ({ relative })</span>
+ </time>
<script>
- @time = new Date @opts.time
- @mode = @opts.mode || \relative
- @tickid = null
+ this.time = new Date(this.opts.time);
+ this.mode = this.opts.mode || 'relative';
+ this.tickid = null;
- @absolute =
- @time.get-full-year! + \年 +
- @time.get-month! + 1 + \月 +
- @time.get-date! + \日 +
+ this.absolute =
+ this.time.getFullYear() + '年' +
+ this.time.getMonth() + 1 + '月' +
+ this.time.getDate() + '日' +
' ' +
- @time.get-hours! + \時 +
- @time.get-minutes! + \分
+ this.time.getHours() + '時' +
+ this.time.getMinutes() + '分';
- @on \mount ~>
- if @mode == \relative or @mode == \detail
- @tick!
- @tickid = set-interval @tick, 1000ms
+ this.on('mount', () => {
+ if (this.mode == 'relative' || this.mode == 'detail') {
+ this.tick();
+ this.tickid = setInterval(this.tick, 1000);
+ }
+ });
- @on \unmount ~>
- if @mode == \relative or @mode == \detail
- clear-interval @tickid
+ this.on('unmount', () => {
+ if (this.mode === 'relative' || this.mode === 'detail') {
+ clearInterval(this.tickid);
+ }
+ });
- @tick = ~>
- now = new Date!
- ago = (now - @time) / 1000ms
- @relative = switch
- | ago >= 31536000s => ~~(ago / 31536000s) + '年前'
- | ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月前'
- | ago >= 604800s => ~~(ago / 604800s) + '週間前'
- | ago >= 86400s => ~~(ago / 86400s) + '日前'
- | ago >= 3600s => ~~(ago / 3600s) + '時間前'
- | ago >= 60s => ~~(ago / 60s) + '分前'
- | ago >= 10s => ~~(ago % 60s) + '秒前'
- | ago >= 0s => 'たった今'
- | ago < 0s => '未来'
- | _ => 'なぞのじかん'
- @update!
+ this.tick = () => {
+ const now = new Date();
+ const ago = (now - this.time) / 1000/*ms*/;
+ this.relative =
+ ago >= 31536000 ? ~~(ago / 31536000) + '年前' :
+ ago >= 2592000 ? ~~(ago / 2592000) + 'ヶ月前' :
+ ago >= 604800 ? ~~(ago / 604800) + '週間前' :
+ ago >= 86400 ? ~~(ago / 86400) + '日前' :
+ ago >= 3600 ? ~~(ago / 3600) + '時間前' :
+ ago >= 60 ? ~~(ago / 60) + '分前' :
+ ago >= 10 ? ~~(ago % 60) + '秒前' :
+ ago >= 0 ? 'たった今' :
+ ago < 0 ? '未来' :
+ 'なぞのじかん';
+ this.update();
+ };
</script>
</mk-time>
diff --git a/src/web/app/common/tags/twitter-setting.tag b/src/web/app/common/tags/twitter-setting.tag
index 162ccd2928..6996c45b4d 100644
--- a/src/web/app/common/tags/twitter-setting.tag
+++ b/src/web/app/common/tags/twitter-setting.tag
@@ -24,6 +24,6 @@
color #8899a6
</style>
<script>
- @mixin \i
+ this.mixin('i');
</script>
</mk-twitter-setting>
diff --git a/src/web/app/common/tags/uploader.tag b/src/web/app/common/tags/uploader.tag
index 275a26c019..51520d9abd 100644
--- a/src/web/app/common/tags/uploader.tag
+++ b/src/web/app/common/tags/uploader.tag
@@ -140,56 +140,59 @@
</style>
<script>
- @mixin \i
+ this.mixin('i');
- @uploads = []
+ this.uploads = [];
-
- @upload = (file, folder) ~>
- id = Math.random!
+ this.upload = (file, folder) => {
+ const id = Math.random();
- ctx =
- id: id
- name: file.name || \untitled
+ const ctx = {
+ id: id,
+ name: file.name || 'untitled',
progress: undefined
+ };
- @uploads.push ctx
- @trigger \change-uploads @uploads
- @update!
+ this.uploads.push(ctx);
+ this.trigger('change-uploads', this.uploads);
+ this.update();
- reader = new FileReader!
- reader.onload = (e) ~>
- ctx.img = e.target.result
- @update!
- reader.read-as-data-URL file
+ const reader = new FileReader();
+ reader.onload = e => {
+ ctx.img = e.target.result;
+ this.update();
+ };
+ reader.readAsDataURL(file);
- data = new FormData!
- data.append \i @I.token
- data.append \file file
+ const data = new FormData();
+ data.append('i', this.I.token);
+ data.append('file', file);
- if folder?
- data.append \folder_id folder
+ if (folder) data.append('folder_id', folder);
- xhr = new XMLHttpRequest!
- xhr.open \POST CONFIG.apiUrl + '/drive/files/create' true
- xhr.onload = (e) ~>
- drive-file = JSON.parse e.target.response
+ const xhr = new XMLHttpRequest();
+ xhr.open('POST', CONFIG.apiUrl + '/drive/files/create', true);
+ xhr.onload = e => {
+ const driveFile = JSON.parse(e.target.response);
- @trigger \uploaded drive-file
+ this.trigger('uploaded', driveFile);
- @uploads = @uploads.filter (x) -> x.id != id
- @trigger \change-uploads @uploads
+ this.uploads = this.uploads.filter(x => x.id != id);
+ this.trigger('change-uploads', this.uploads);
- @update!
+ this.update();
+ };
- xhr.upload.onprogress = (e) ~>
- if e.length-computable
- if ctx.progress == undefined
- ctx.progress = {}
- ctx.progress.max = e.total
- ctx.progress.value = e.loaded
- @update!
+ xhr.upload.onprogress = e => {
+ if (e.lengthComputable) {
+ if (ctx.progress == undefined) ctx.progress = {};
+ ctx.progress.max = e.total;
+ ctx.progress.value = e.loaded;
+ this.update();
+ }
+ };
- xhr.send data
+ xhr.send(data);
+ };
</script>
</mk-uploader>
diff --git a/src/web/app/common/tags/url-preview.tag b/src/web/app/common/tags/url-preview.tag
index 7aab9d94e0..6daed4dbdf 100644
--- a/src/web/app/common/tags/url-preview.tag
+++ b/src/web/app/common/tags/url-preview.tag
@@ -91,22 +91,24 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @url = @opts.url
- @loading = true
+ this.url = this.opts.url;
+ this.loading = true;
- @on \mount ~>
- fetch CONFIG.url + '/api:url?url=' + @url
- .then (res) ~>
- info <~ res.json!.then
- @title = info.title
- @description = info.description
- @thumbnail = info.thumbnail
- @icon = info.icon
- @sitename = info.sitename
+ this.on('mount', () => {
+ fetch(CONFIG.url + '/api:url?url=' + this.url).then(res => {
+ res.json().then(info => {
+ this.title = info.title;
+ this.description = info.description;
+ this.thumbnail = info.thumbnail;
+ this.icon = info.icon;
+ this.sitename = info.sitename;
- @loading = false
- @update!
+ this.loading = false;
+ this.update();
+ });
+ });
+ });
</script>
</mk-url-preview>
diff --git a/src/web/app/common/tags/url.tag b/src/web/app/common/tags/url.tag
index d4284b61bf..0ad9e72b5d 100644
--- a/src/web/app/common/tags/url.tag
+++ b/src/web/app/common/tags/url.tag
@@ -30,19 +30,20 @@
</style>
<script>
- @url = @opts.href
+ this.url = this.opts.href;
- @on \before-mount ~>
- parser = document.create-element \a
- parser.href = @url
+ this.on('before-mount', () => {
+ parser = document.createElement('a');
+ parser.href = this.url;
- @schema = parser.protocol
- @hostname = parser.hostname
- @port = parser.port
- @pathname = parser.pathname
- @query = parser.search
- @hash = parser.hash
+ this.schema = parser.protocol;
+ this.hostname = parser.hostname;
+ this.port = parser.port;
+ this.pathname = parser.pathname;
+ this.query = parser.search;
+ this.hash = parser.hash;
- @update!
+ this.update();
+ });
</script>
</mk-url>
diff --git a/src/web/app/desktop/tags/analog-clock.tag b/src/web/app/desktop/tags/analog-clock.tag
index d2458a7789..dcf4acaff8 100644
--- a/src/web/app/desktop/tags/analog-clock.tag
+++ b/src/web/app/desktop/tags/analog-clock.tag
@@ -6,100 +6,90 @@
display block
width 256px
height 256px
-
</style>
<script>
- @on \mount ~>
- @draw!
- @clock = set-interval @draw, 1000ms
+ const Vec2 = function(x, y) {
+ this.x = x;
+ this.y = y;
+ };
- @on \unmount ~>
- clear-interval @clock
+ this.on('mount', () => {
+ this.draw()
+ this.clock = setInterval(this.draw, 1000);
+ });
- @draw = ~>
- now = new Date!
- s = now.get-seconds!
- m = now.get-minutes!
- h = now.get-hours!
+ this.on('unmount', () => {
+ clearInterval(this.clock);
+ });
- vec2 = (x, y) ->
- @x = x
- @y = y
+ this.draw = () => {
+ const now = new Date();
+ const s = now.getSeconds();
+ const m = now.getMinutes();
+ const h = now.getHours();
- ctx = @refs.canvas.get-context \2d
- canv-w = @refs.canvas.width
- canv-h = @refs.canvas.height
- ctx.clear-rect 0, 0, canv-w, canv-h
+ const ctx = this.refs.canvas.getContext('2d');
+ const canvW = this.refs.canvas.width;
+ const canvH = this.refs.canvas.height;
+ ctx.clearRect(0, 0, canvW, canvH);
- # 背景
- center = (Math.min (canv-w / 2), (canv-h / 2))
- line-start = center * 0.90
- line-end-short = center * 0.87
- line-end-long = center * 0.84
- for i from 0 to 59 by 1
- angle = Math.PI * i / 30
- uv = new vec2 (Math.sin angle), (-Math.cos angle)
- ctx.begin-path!
- ctx.line-width = 1
- ctx.move-to do
- (canv-w / 2) + uv.x * line-start
- (canv-h / 2) + uv.y * line-start
- if i % 5 == 0
- ctx.stroke-style = 'rgba(255, 255, 255, 0.2)'
- ctx.line-to do
- (canv-w / 2) + uv.x * line-end-long
- (canv-h / 2) + uv.y * line-end-long
- else
- ctx.stroke-style = 'rgba(255, 255, 255, 0.1)'
- ctx.line-to do
- (canv-w / 2) + uv.x * line-end-short
- (canv-h / 2) + uv.y * line-end-short
- ctx.stroke!
+ { // 背景
+ const center = Math.min((canvW / 2), (canvH / 2));
+ const lineStart = center * 0.90;
+ const shortLineEnd = center * 0.87;
+ const longLineEnd = center * 0.84;
+ for (let i = 0; i < 60; i++) {
+ const angle = Math.PI * i / 30;
+ const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
+ ctx.beginPath();
+ ctx.lineWidth = 1;
+ ctx.moveTo((canvW / 2) + uv.x * lineStart, (canvH / 2) + uv.y * lineStart);
+ if (i % 5 == 0) {
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
+ ctx.lineTo((canvW / 2) + uv.x * longLineEnd, (canvH / 2) + uv.y * longLineEnd);
+ } else {
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
+ ctx.lineTo((canvW / 2) + uv.x * shortLineEnd, (canvH / 2) + uv.y * shortLineEnd);
+ }
+ ctx.stroke();
+ }
+ }
- # 分
- angle = Math.PI * (m + s / 60) / 30
- length = (Math.min canv-w, canv-h) / 2.6
- uv = new vec2 (Math.sin angle), (-Math.cos angle)
- ctx.begin-path!
- ctx.stroke-style = \#ffffff
- ctx.line-width = 2
- ctx.move-to do
- (canv-w / 2) - uv.x * length / 5
- (canv-h / 2) - uv.y * length / 5
- ctx.line-to do
- (canv-w / 2) + uv.x * length
- (canv-h / 2) + uv.y * length
- ctx.stroke!
+ { // 分
+ const angle = Math.PI * (m + s / 60) / 30;
+ const length = Math.min(canvW, canvH) / 2.6;
+ const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
+ ctx.beginPath();
+ ctx.strokeStyle = '#ffffff';
+ ctx.lineWidth = 2;
+ ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
+ ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
+ ctx.stroke();
+ }
- # 時
- angle = Math.PI * (h % 12 + m / 60) / 6
- length = (Math.min canv-w, canv-h) / 4
- uv = new vec2 (Math.sin angle), (-Math.cos angle)
- ctx.begin-path!
- #ctx.stroke-style = \#ffffff
- ctx.stroke-style = CONFIG.theme-color
- ctx.line-width = 2
- ctx.move-to do
- (canv-w / 2) - uv.x * length / 5
- (canv-h / 2) - uv.y * length / 5
- ctx.line-to do
- (canv-w / 2) + uv.x * length
- (canv-h / 2) + uv.y * length
- ctx.stroke!
+ { // 時
+ const angle = Math.PI * (h % 12 + m / 60) / 6;
+ const length = Math.min(canvW, canvH) / 4;
+ const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
+ ctx.beginPath();
+ ctx.strokeStyle = CONFIG.themeColor;
+ ctx.lineWidth = 2;
+ ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
+ ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
+ ctx.stroke();
+ }
- # 秒
- angle = Math.PI * s / 30
- length = (Math.min canv-w, canv-h) / 2.6
- uv = new vec2 (Math.sin angle), (-Math.cos angle)
- ctx.begin-path!
- ctx.stroke-style = 'rgba(255, 255, 255, 0.5)'
- ctx.line-width = 1
- ctx.move-to do
- (canv-w / 2) - uv.x * length / 5
- (canv-h / 2) - uv.y * length / 5
- ctx.line-to do
- (canv-w / 2) + uv.x * length
- (canv-h / 2) + uv.y * length
- ctx.stroke!
+ { // 秒
+ const angle = Math.PI * s / 30;
+ const length = Math.min(canvW, canvH) / 2.6;
+ const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
+ ctx.beginPath();
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
+ ctx.lineWidth = 1;
+ ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
+ ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
+ ctx.stroke();
+ }
+ };
</script>
</mk-analog-clock>
diff --git a/src/web/app/desktop/tags/autocomplete-suggestion.tag b/src/web/app/desktop/tags/autocomplete-suggestion.tag
index 4aea8d8881..c7cc29dc19 100644
--- a/src/web/app/desktop/tags/autocomplete-suggestion.tag
+++ b/src/web/app/desktop/tags/autocomplete-suggestion.tag
@@ -80,108 +80,118 @@
</style>
<script>
- @mixin \api
+ const contains = require('../../common/scripts/contains');
- @q = @opts.q
- @textarea = @opts.textarea
- @loading = true
- @users = []
- @select = -1
+ this.mixin('api');
- @on \mount ~>
- @textarea.add-event-listener \keydown @on-keydown
+ this.q = this.opts.q;
+ this.textarea = this.opts.textarea;
+ this.fetching = true;
+ this.users = [];
+ this.select = -1;
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
+ this.on('mount', () => {
+ this.textarea.addEventListener('keydown', this.onKeydown);
- @api \users/search_by_username do
- query: @q
- limit: 30users
- .then (users) ~>
- @users = users
- @loading = false
- @update!
- .catch (err) ~>
- console.error err
+ document.querySelectorAll('body *').forEach(el => {
+ el.addEventListener('mousedown', this.mousedown);
+ });
- @on \unmount ~>
- @textarea.remove-event-listener \keydown @on-keydown
+ this.api('users/search_by_username', {
+ query: this.q,
+ limit: 30
+ }).then(users => {
+ this.update({
+ fetching: false,
+ users: users
+ });
+ });
+ });
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
+ this.on('unmount', () => {
+ this.textarea.removeEventListener('keydown', this.onKeydown);
- @mousedown = (e) ~>
- if (!contains @root, e.target) and (@root != e.target)
- @close!
+ document.querySelectorAll('body *').forEach(el => {
+ el.removeEventListener('mousedown', this.mousedown);
+ });
+ });
- @on-click = (e) ~>
- @complete e.item
+ this.mousedown = e => {
+ if (!contains(this.root, e.target) && (this.root != e.target)) this.close();
+ };
- @on-keydown = (e) ~>
- key = e.which
- switch (key)
- | 10, 13 => # Key[ENTER]
- if @select != -1
- e.prevent-default!
- e.stop-propagation!
- @complete @users[@select]
- else
- @close!
- | 27 => # Key[ESC]
- e.prevent-default!
- e.stop-propagation!
- @close!
- | 38 => # Key[↑]
- if @select != -1
- e.prevent-default!
- e.stop-propagation!
- @select-prev!
- else
- @close!
- | 9, 40 => # Key[TAB] or Key[↓]
- e.prevent-default!
- e.stop-propagation!
- @select-next!
- | _ =>
- @close!
+ this.onClick = e => {
+ this.complete(e.item);
+ };
- @select-next = ~>
- @select++
+ this.onKeydown = e => {
+ const cancel = () => {
+ e.preventDefault();
+ e.stopPropagation();
+ };
- if @select >= @users.length
- @select = 0
+ switch (e.which) {
+ case 10: // [ENTER]
+ case 13: // [ENTER]
+ if (this.select !== -1) {
+ cancel();
+ this.complete(this.users[this.select]);
+ } else {
+ this.close();
+ }
+ break;
- @apply-select!
+ case 27: // [ESC]
+ cancel();
+ this.close();
+ break;
- @select-prev = ~>
- @select--
+ case 38: // [↑]
+ if (this.select !== -1) {
+ cancel();
+ this.selectPrev();
+ } else {
+ this.close();
+ }
+ break;
- if @select < 0
- @select = @users.length - 1
+ case 9: // [TAB]
+ case 40: // [↓]
+ cancel();
+ this.selectNext();
+ break;
- @apply-select!
+ default:
+ this.close();
+ }
+ };
- @apply-select = ~>
- @refs.users.children.for-each (el) ~>
- el.remove-attribute \data-selected
+ this.selectNext = () => {
+ if (++this.select >= this.users.length) this.select = 0;
+ this.applySelect();
+ };
- @refs.users.children[@select].set-attribute \data-selected \true
- @refs.users.children[@select].focus!
+ this.selectPrev = () => {
+ if (--this.select < 0) this.select = this.users.length - 1;
+ this.applySelect();
+ };
- @complete = (user) ~>
- @opts.complete user
+ this.applySelect = () => {
+ this.refs.users.children.forEach(el => {
+ el.removeAttribute('data-selected');
+ });
- @close = ~>
- @opts.close!
+ this.refs.users.children[this.select].setAttribute('data-selected', 'true');
+ this.refs.users.children[this.select].focus();
+ };
+
+ this.complete = user => {
+ this.opts.complete(user);
+ };
+
+ this.close = () => {
+ this.opts.close();
+ };
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
</script>
</mk-autocomplete-suggestion>
diff --git a/src/web/app/desktop/tags/big-follow-button.tag b/src/web/app/desktop/tags/big-follow-button.tag
index dfee12b2a0..9d12b5a53e 100644
--- a/src/web/app/desktop/tags/big-follow-button.tag
+++ b/src/web/app/desktop/tags/big-follow-button.tag
@@ -70,58 +70,74 @@
</style>
<script>
- @mixin \api
- @mixin \is-promise
- @mixin \stream
+ this.mixin('api');
+ this.mixin('is-promise');
+ this.mixin('stream');
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @init = true
- @wait = false
+ this.user = null;
+ this.userPromise = this.isPromise(this.opts.user)
+ ? this.opts.user
+ : Promise.resolve(this.opts.user);
+ this.init = true;
+ this.wait = false;
- @on \mount ~>
- @user-promise.then (user) ~>
- @user = user
- @init = false
- @update!
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ this.on('mount', () => {
+ this.userPromise.then(user => {
+ this.update({
+ init: false,
+ user: user
+ });
+ this.stream.on('follow', this.onStreamFollow);
+ this.stream.on('unfollow', this.onStreamUnfollow);
+ });
+ });
- @on \unmount ~>
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ this.on('unmount', () => {
+ this.stream.off('follow', this.onStreamFollow);
+ this.stream.off('unfollow', this.onStreamUnfollow);
+ });
- @on-stream-follow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ this.onStreamFollow = user => {
+ if (user.id == this.user.id) {
+ this.update({
+ user: user
+ });
+ }
+ };
- @on-stream-unfollow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ this.onStreamUnfollow = user => {
+ if (user.id == this.user.id) {
+ this.update({
+ user: user
+ });
+ }
+ };
- @onclick = ~>
- @wait = true
- if @user.is_following
- @api \following/delete do
- user_id: @user.id
- .then ~>
- @user.is_following = false
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
- @update!
- else
- @api \following/create do
- user_id: @user.id
- .then ~>
- @user.is_following = true
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
- @update!
+ this.onclick = () => {
+ this.wait = true;
+ if (this.user.is_following) {
+ this.api('following/delete', {
+ user_id: this.user.id
+ }).then(() => {
+ this.user.is_following = false;
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.wait = false;
+ this.update();
+ });
+ } else {
+ this.api('following/create', {
+ user_id: this.user.id
+ }).then(() => {
+ this.user.is_following = true;
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.wait = false;
+ this.update();
+ });
+ }
+ };
</script>
</mk-big-follow-button>
diff --git a/src/web/app/desktop/tags/contextmenu.tag b/src/web/app/desktop/tags/contextmenu.tag
index b22948b7d4..8df11c3819 100644
--- a/src/web/app/desktop/tags/contextmenu.tag
+++ b/src/web/app/desktop/tags/contextmenu.tag
@@ -1,4 +1,5 @@
-<mk-contextmenu><yield />
+<mk-contextmenu>
+ <yield />
<style>
:scope
$width = 240px
@@ -94,46 +95,45 @@
</style>
<script>
- @root.add-event-listener \contextmenu (e) ~>
- e.prevent-default!
+ const contains = require('../../common/scripts/contains');
- @mousedown = (e) ~>
- e.prevent-default!
- if (!contains @root, e.target) and (@root != e.target)
- @close!
- return false
+ this.root.addEventListener('contextmenu', e => {
+ e.preventDefault();
+ });
- @open = (pos) ~>
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
- @root.style.display = \block
- @root.style.left = pos.x + \px
- @root.style.top = pos.y + \px
+ this.mousedown = e => {
+ e.preventDefault();
+ if (!contains(this.root, e.target) && (this.root != e.target)) this.close();
+ return false;
+ };
- Velocity @root, \finish true
- Velocity @root, { opacity: 0 } 0ms
- Velocity @root, {
+ this.open = pos => {
+ document.querySelectorAll('body *').forEach(el => {
+ el.addEventListener('mousedown', this.mousedown);
+ });
+
+ this.root.style.display = 'block';
+ this.root.style.left = pos.x + 'px';
+ this.root.style.top = pos.y + 'px';
+
+ Velocity(this.root, 'finish', true);
+ Velocity(this.root, { opacity: 0 }, 0);
+ Velocity(this.root, {
opacity: 1
- } {
- queue: false
- duration: 100ms
- easing: \linear
- }
+ }, {
+ queue: false,
+ duration: 100,
+ easing: 'linear'
+ });
+ };
- @close = ~>
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
- @trigger \closed
- @unmount!
+ this.close = () => {
+ document.querySelectorAll('body *').forEach(el => {
+ el.removeEventListener('mousedown', this.mousedown);
+ });
- function contains(parent, child)
- node = child.parent-node
- while (node != null)
- if (node == parent)
- return true
- node = node.parent-node
- return false
+ this.trigger('closed');
+ this.unmount();
+ };
</script>
</mk-contextmenu>
diff --git a/src/web/app/desktop/tags/crop-window.tag b/src/web/app/desktop/tags/crop-window.tag
index 8d27f4c512..2cadc29948 100644
--- a/src/web/app/desktop/tags/crop-window.tag
+++ b/src/web/app/desktop/tags/crop-window.tag
@@ -158,31 +158,37 @@
</style>
<script>
- @mixin \cropper
+ this.mixin('cropper');
- @image = @opts.file
- @title = @opts.title
- @aspect-ratio = @opts.aspect-ratio
- @cropper = null
+ this.image = this.opts.file;
+ this.title = this.opts.title;
+ this.aspectRatio = this.opts.aspectRatio;
+ this.cropper = null;
- @on \mount ~>
- @img = @refs.window.refs.img
- @cropper = new @Cropper @img, do
- aspect-ratio: @aspect-ratio
- highlight: no
- view-mode: 1
+ this.on('mount', () => {
+ this.img = this.refs.window.refs.img;
+ this.cropper = new this.Cropper(this.img, {
+ aspectRatio: this.aspectRatio,
+ highlight: false,
+ viewMode: 1
+ });
+ });
- @ok = ~>
- @cropper.get-cropped-canvas!.to-blob (blob) ~>
- @trigger \cropped blob
- @refs.window.close!
+ this.ok = () => {
+ this.cropper.getCroppedCanvas().toBlob(blob => {
+ this.trigger('cropped', blob);
+ this.refs.window.close();
+ });
+ };
- @skip = ~>
- @trigger \skiped
- @refs.window.close!
+ this.skip = () => {
+ this.trigger('skiped');
+ this.refs.window.close();
+ };
- @cancel = ~>
- @trigger \canceled
- @refs.window.close!
+ this.cancel = () => {
+ this.trigger('canceled');
+ this.refs.window.close();
+ };
</script>
</mk-crop-window>
diff --git a/src/web/app/desktop/tags/dialog.tag b/src/web/app/desktop/tags/dialog.tag
index 528779242e..c0df0b330f 100644
--- a/src/web/app/desktop/tags/dialog.tag
+++ b/src/web/app/desktop/tags/dialog.tag
@@ -79,69 +79,72 @@
</style>
<script>
- @can-through = if opts.can-through? then opts.can-through else true
- @opts.buttons.for-each (button) ~>
- button._onclick = ~>
- if button.onclick?
- button.onclick!
- @close!
+ this.canThrough = opts.canThrough != null ? opts.canThrough : true;
+ this.opts.buttons.forEach(button => {
+ button._onclick = () => {
+ if (button.onclick) button.onclick();
+ this.close();
+ };
+ });
- @on \mount ~>
- @refs.header.innerHTML = @opts.title
- @refs.body.innerHTML = @opts.text
+ this.on('mount', () => {
+ this.refs.header.innerHTML = this.opts.title;
+ this.refs.body.innerHTML = this.opts.text;
- @refs.bg.style.pointer-events = \auto
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
+ this.refs.bg.style.pointerEvents = 'auto';
+ Velocity(this.refs.bg, 'finish', true);
+ Velocity(this.refs.bg, {
opacity: 1
- } {
- queue: false
- duration: 100ms
- easing: \linear
- }
+ }, {
+ queue: false,
+ duration: 100,
+ easing: 'linear'
+ });
- Velocity @refs.main, {
- opacity: 0
+ Velocity(this.refs.main, {
+ opacity: 0,
scale: 1.2
- } {
+ }, {
duration: 0
- }
- Velocity @refs.main, {
- opacity: 1
+ });
+ Velocity(this.refs.main, {
+ opacity: 1,
scale: 1
- } {
- duration: 300ms
+ }, {
+ duration: 300,
easing: [ 0, 0.5, 0.5, 1 ]
- }
+ });
+ });
- @close = ~>
- @refs.bg.style.pointer-events = \none
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
+ this.close = () => {
+ this.refs.bg.style.pointerEvents = 'none';
+ Velocity(this.refs.bg, 'finish', true);
+ Velocity(this.refs.bg, {
opacity: 0
- } {
- queue: false
- duration: 300ms
- easing: \linear
- }
+ }, {
+ queue: false,
+ duration: 300,
+ easing: 'linear'
+ });
- @refs.main.style.pointer-events = \none
- Velocity @refs.main, \finish true
- Velocity @refs.main, {
- opacity: 0
+ this.refs.main.style.pointerEvents = 'none';
+ Velocity(this.refs.main, 'finish', true);
+ Velocity(this.refs.main, {
+ opacity: 0,
scale: 0.8
- } {
- queue: false
- duration: 300ms
- easing: [ 0.5, -0.5, 1, 0.5 ]
- complete: ~>
- @unmount!
- }
+ }, {
+ queue: false,
+ duration: 300,
+ easing: [ 0.5, -0.5, 1, 0.5 ],
+ complete: () => this.unmount()
+ });
+ };
- @bg-click = ~>
- if @can-through
- if @opts.on-through?
- @opts.on-through!
- @close!
+ this.bgClick = () => {
+ if (this.canThrough) {
+ if (this.opts.onThrough) this.opts.onThrough();
+ this.close();
+ }
+ };
</script>
</mk-dialog>
diff --git a/src/web/app/desktop/tags/donation.tag b/src/web/app/desktop/tags/donation.tag
index 7d0056d36f..e313188f24 100644
--- a/src/web/app/desktop/tags/donation.tag
+++ b/src/web/app/desktop/tags/donation.tag
@@ -47,21 +47,22 @@
</style>
<script>
- @mixin \api
- @mixin \i
+ this.mixin('api');
+ this.mixin('i');
- @close = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ this.close = e => {
+ e.preventDefault();
+ e.stopPropagation();
- @I.data.no_donation = true
- @I.update!
- @api \i/appdata/set do
- data: JSON.stringify do
- no_donation: @I.data.no_donation
+ this.I.data.no_donation = true;
+ this.I.update();
+ this.api('i/appdata/set', {
+ data: JSON.stringify({
+ no_donation: this.I.data.no_donation
+ })
+ });
- @unmount!
-
- @parent.parent.set-root-layout!
+ this.unmount();
+ };
</script>
</mk-donation>
diff --git a/src/web/app/desktop/tags/drive/base-contextmenu.tag b/src/web/app/desktop/tags/drive/base-contextmenu.tag
index c3a613d32b..2a95de0cd5 100644
--- a/src/web/app/desktop/tags/drive/base-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/base-contextmenu.tag
@@ -13,26 +13,32 @@
</ul>
</mk-contextmenu>
<script>
- @browser = @opts.browser
+ this.browser = this.opts.browser;
- @on \mount ~>
- @refs.ctx.on \closed ~>
- @trigger \closed
- @unmount!
+ this.on('mount', () => {
+ this.refs.ctx.on('closed', () => {
+ this.trigger('closed');
+ this.unmount();
+ });
+ });
- @open = (pos) ~>
- @refs.ctx.open pos
+ this.open = pos => {
+ this.refs.ctx.open(pos);
+ };
- @create-folder = ~>
- @browser.create-folder!
- @refs.ctx.close!
+ this.createFolder = () => {
+ this.browser.createFolder();
+ this.refs.ctx.close();
+ };
- @upload = ~>
- @browser.select-local-file!
- @refs.ctx.close!
+ this.upload = () => {
+ this.browser.selectLocalFile();
+ this.refs.ctx.close();
+ };
- @url-upload = ~>
- @browser.url-upload!
- @refs.ctx.close!
+ this.urlUpload = () => {
+ this.browser.urlUpload();
+ this.refs.ctx.close();
+ };
</script>
</mk-drive-browser-base-contextmenu>
diff --git a/src/web/app/desktop/tags/drive/browser-window.tag b/src/web/app/desktop/tags/drive/browser-window.tag
index c975427893..a658e36063 100644
--- a/src/web/app/desktop/tags/drive/browser-window.tag
+++ b/src/web/app/desktop/tags/drive/browser-window.tag
@@ -28,19 +28,24 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @folder = if @opts.folder? then @opts.folder else null
+ this.folder = this.opts.folder ? this.opts.folder : null;
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ this.on('mount', () => {
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
- @api \drive .then (info) ~>
- @update do
+ this.api('drive').then(info => {
+ this.update({
usage: info.usage / info.capacity * 100
+ });
+ });
+ });
- @close = ~>
- @refs.window.close!
+ this.close = () => {
+ this.refs.window.close();
+ };
</script>
</mk-drive-browser-window>
diff --git a/src/web/app/desktop/tags/drive/browser.tag b/src/web/app/desktop/tags/drive/browser.tag
index 1e8448dab2..1e8b17cfcd 100644
--- a/src/web/app/desktop/tags/drive/browser.tag
+++ b/src/web/app/desktop/tags/drive/browser.tag
@@ -8,7 +8,7 @@
</div>
<input class="search" type="search" placeholder="&#xf002; 検索"/>
</nav>
- <div class="main { uploading: uploads.length > 0, loading: loading }" ref="main" onmousedown={ onmousedown } ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop } oncontextmenu={ oncontextmenu }>
+ <div class="main { uploading: uploads.length > 0, fetching: fetching }" ref="main" onmousedown={ onmousedown } ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop } oncontextmenu={ oncontextmenu }>
<div class="selection" ref="selection"></div>
<div class="contents" ref="contents">
<div class="folders" ref="foldersContainer" if={ folders.length > 0 }>
@@ -23,13 +23,13 @@
</virtual>
<button if={ moreFiles }>もっと読み込む</button>
</div>
- <div class="empty" if={ files.length == 0 && folders.length == 0 && !loading }>
+ <div class="empty" if={ files.length == 0 && folders.length == 0 && !fetching }>
<p if={ draghover }>ドロップですか?いいですよ、ボクはカワイイですからね</p>
<p if={ !draghover && folder == null }><strong>ドライブには何もありません。</strong><br/>右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。</p>
<p if={ !draghover && folder != null }>このフォルダーは空です</p>
</div>
</div>
- <div class="loading" if={ loading }>
+ <div class="loading" if={ fetching }>
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
@@ -133,7 +133,7 @@
&, *
user-select none
- &.loading
+ &.fetching
cursor wait !important
*
@@ -184,7 +184,7 @@
> p
margin 0
- > .loading
+ > .fetching
.spinner
margin 100px auto
width 40px
@@ -238,418 +238,439 @@
</style>
<script>
- @mixin \api
- @mixin \dialog
- @mixin \input-dialog
- @mixin \stream
+ const contains = require('../../../common/scripts/contains');
- @files = []
- @folders = []
- @hierarchy-folders = []
+ this.mixin('api');
+ this.mixin('dialog');
+ this.mixin('input-dialog');
+ this.mixin('stream');
- @uploads = []
+ this.files = [];
+ this.folders = [];
+ this.hierarchyFolders = [];
- # 現在の階層(フォルダ)
- # * null でルートを表す
- @folder = null
+ this.uploads = [];
- @multiple = if @opts.multiple? then @opts.multiple else false
+ // 現在の階層(フォルダ)
+ // * null でルートを表す
+ this.folder = null;
- # ドロップされようとしているか
- @draghover = false
+ this.multiple = this.opts.multiple != null ? this.opts.multiple : false;
- # 自信の所有するアイテムがドラッグをスタートさせたか
- # (自分自身の階層にドロップできないようにするためのフラグ)
- @is-drag-source = false
+ // ドロップされようとしているか
+ this.draghover = false;
- @on \mount ~>
- @refs.uploader.on \uploaded (file) ~>
- @add-file file, true
+ // 自信の所有するアイテムがドラッグをスタートさせたか
+ // (自分自身の階層にドロップできないようにするためのフラグ)
+ this.isDragSource = false;
- @refs.uploader.on \change-uploads (uploads) ~>
- @uploads = uploads
- @update!
+ this.on('mount', () => {
+ this.refs.uploader.on('uploaded', file => {
+ this.addFile(file, true);
+ });
- @stream.on \drive_file_created @on-stream-drive-file-created
- @stream.on \drive_file_updated @on-stream-drive-file-updated
- @stream.on \drive_folder_created @on-stream-drive-folder-created
- @stream.on \drive_folder_updated @on-stream-drive-folder-updated
+ this.refs.uploader.on('change-uploads', uploads => {
+ this.update({
+ uploads: uploads
+ });
+ });
- # Riotのバグでnullを渡しても""になる
- # https://github.com/riot/riot/issues/2080
- #if @opts.folder?
- if @opts.folder? and @opts.folder != ''
- @move @opts.folder
- else
- @load!
+ this.stream.on('drive_file_created', this.onStreamDriveFileCreated);
+ this.stream.on('drive_file_updated', this.onStreamDriveFileUpdated);
+ this.stream.on('drive_folder_created', this.onStreamDriveFolderCreated);
+ this.stream.on('drive_folder_updated', this.onStreamDriveFolderUpdated);
- @on \unmount ~>
- @stream.off \drive_file_created @on-stream-drive-file-created
- @stream.off \drive_file_updated @on-stream-drive-file-updated
- @stream.off \drive_folder_created @on-stream-drive-folder-created
- @stream.off \drive_folder_updated @on-stream-drive-folder-updated
+ // Riotのバグでnullを渡しても""になる
+ // https://github.com/riot/riot/issues/2080
+ //if (this.opts.folder)
+ if (this.opts.folder && this.opts.folder != '') {
+ this.move(this.opts.folder);
+ } else {
+ this.load();
+ }
+ });
- @on-stream-drive-file-created = (file) ~>
- @add-file file, true
+ this.on('unmount', () => {
+ this.stream.off('drive_file_created', this.onStreamDriveFileCreated);
+ this.stream.off('drive_file_updated', this.onStreamDriveFileUpdated);
+ this.stream.off('drive_folder_created', this.onStreamDriveFolderCreated);
+ this.stream.off('drive_folder_updated', this.onStreamDriveFolderUpdated);
+ });
- @on-stream-drive-file-updated = (file) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- @remove-file file
- else
- @add-file file, true
+ this.onStreamDriveFileCreated = file => {
+ this.addFile(file, true);
+ };
- @on-stream-drive-folder-created = (folder) ~>
- @add-folder folder, true
+ this.onStreamDriveFileUpdated = file => {
+ const current = this.folder ? this.folder.id : null;
+ if (current != file.folder_id) {
+ this.removeFile(file);
+ } else {
+ this.addFile(file, true);
+ }
+ };
- @on-stream-drive-folder-updated = (folder) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- @remove-folder folder
- else
- @add-folder folder, true
+ this.onStreamDriveFolderCreated = folder => {
+ this.addFolder(folder, true);
+ };
- @onmousedown = (e) ~>
- if (contains @refs.folders-container, e.target) or (contains @refs.files-container, e.target)
- return true
+ this.onStreamDriveFolderUpdated = folder => {
+ const current = this.folder ? this.folder.id : null;
+ if (current != folder.parent_id) {
+ this.removeFolder(folder);
+ } else {
+ this.addFolder(folder, true);
+ }
+ };
- rect = @refs.main.get-bounding-client-rect!
+ this.onmousedown = e => {
+ if (contains(this.refs.foldersContainer, e.target) || contains(this.refs.filesContainer, e.target)) return true;
- left = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset
- top = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset
+ const rect = this.refs.main.getBoundingClientRect();
- move = (e) ~>
- @refs.selection.style.display = \block
+ const left = e.pageX + this.refs.main.scrollLeft - rect.left - window.pageXOffset
+ const top = e.pageY + this.refs.main.scrollTop - rect.top - window.pageYOffset
- cursor-x = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset
- cursor-y = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset
- w = cursor-x - left
- h = cursor-y - top
+ const move = e => {
+ this.refs.selection.style.display = 'block';
- if w > 0
- @refs.selection.style.width = w + \px
- @refs.selection.style.left = left + \px
- else
- @refs.selection.style.width = -w + \px
- @refs.selection.style.left = cursor-x + \px
+ const cursorX = e.pageX + this.refs.main.scrollLeft - rect.left - window.pageXOffset;
+ const cursorY = e.pageY + this.refs.main.scrollTop - rect.top - window.pageYOffset;
+ const w = cursorX - left;
+ const h = cursorY - top;
- if h > 0
- @refs.selection.style.height = h + \px
- @refs.selection.style.top = top + \px
- else
- @refs.selection.style.height = -h + \px
- @refs.selection.style.top = cursor-y + \px
+ if (w > 0) {
+ this.refs.selection.style.width = w + 'px';
+ this.refs.selection.style.left = left + 'px';
+ } else {
+ this.refs.selection.style.width = -w + 'px';
+ this.refs.selection.style.left = cursorX + 'px';
+ }
- up = (e) ~>
- document.document-element.remove-event-listener \mousemove move
- document.document-element.remove-event-listener \mouseup up
+ if (h > 0) {
+ this.refs.selection.style.height = h + 'px';
+ this.refs.selection.style.top = top + 'px';
+ } else {
+ this.refs.selection.style.height = -h + 'px';
+ this.refs.selection.style.top = cursorY + 'px';
+ }
+ };
- @refs.selection.style.display = \none
+ up = e => {
+ document.documentElement.removeEventListener('mousemove', move);
+ document.documentElement.removeEventListener('mouseup', up);
- document.document-element.add-event-listener \mousemove move
- document.document-element.add-event-listener \mouseup up
+ this.refs.selection.style.display = 'none';
+ };
- @path-oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
- return false
+ document.documentElement.addEventListener('mousemove', move);
+ document.documentElement.addEventListener('mouseup', up);
+ };
- @ondragover = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ this.pathOncontextmenu = e => {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ return false;
+ };
- # ドラッグ元が自分自身の所有するアイテムかどうか
- if !@is-drag-source
- # ドラッグされてきたものがファイルだったら
- if e.data-transfer.effect-allowed == \all
- e.data-transfer.drop-effect = \copy
- else
- e.data-transfer.drop-effect = \move
- @draghover = true
- else
- # 自分自身にはドロップさせない
- e.data-transfer.drop-effect = \none
- return false
+ this.ondragover = e => {
+ e.preventDefault();
+ e.stopPropagation();
- @ondragenter = (e) ~>
- e.prevent-default!
- if !@is-drag-source
- @draghover = true
+ // ドラッグ元が自分自身の所有するアイテムかどうか
+ if (!this.isDragSource) {
+ // ドラッグされてきたものがファイルだったら
+ e.dataTransfer.dropEffect = e.dataTransfer.effectAllowed == 'all' ? 'copy' : 'move';
+ this.draghover = true;
+ } else {
+ // 自分自身にはドロップさせない
+ e.dataTransfer.dropEffect = 'none';
+ return false;
+ }
+ };
- @ondragleave = (e) ~>
- @draghover = false
+ this.ondragenter = e => {
+ e.preventDefault();
+ if (!this.isDragSource) this.draghover = true;
+ };
- @ondrop = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ this.ondragleave = e => {
+ this.draghover = false;
+ };
- @draghover = false
+ this.ondrop = e => {
+ e.preventDefault();
+ e.stopPropagation();
- # ドロップされてきたものがファイルだったら
- if e.data-transfer.files.length > 0
- Array.prototype.for-each.call e.data-transfer.files, (file) ~>
- @upload file, @folder
- return false
+ this.draghover = false;
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
- return false
+ // ドロップされてきたものがファイルだったら
+ if (e.dataTransfer.files.length > 0) {
+ e.dataTransfer.files.forEach(file => {
+ this.upload(file, this.folder);
+ });
+ return false;
+ }
- # パース
- obj = JSON.parse data
+ // データ取得
+ const data = e.dataTransfer.getData('text');
+ if (data == null) return false;
- # (ドライブの)ファイルだったら
- if obj.type == \file
- file = obj.id
- if (@files.some (f) ~> f.id == file)
- return false
- @remove-file file
- @api \drive/files/update do
- file_id: file
- folder_id: if @folder? then @folder.id else null
- .then ~>
- # something
- .catch (err, text-status) ~>
- console.error err
+ // パース
+ // TODO: JSONじゃなかったら中断
+ const obj = JSON.parse(data);
- # (ドライブの)フォルダーだったら
- else if obj.type == \folder
- folder = obj.id
- # 移動先が自分自身ならreject
- if @folder? and folder == @folder.id
- return false
- if (@folders.some (f) ~> f.id == folder)
- return false
- @remove-folder folder
- @api \drive/folders/update do
- folder_id: folder
- parent_id: if @folder? then @folder.id else null
- .then ~>
- # something
- .catch (err) ~>
- if err == 'detected-circular-definition'
- @dialog do
- '<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
- '移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
- [
- text: \OK
- ]
-
- return false
-
- @oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
+ // (ドライブの)ファイルだったら
+ if (obj.type == 'file') {
+ const file = obj.id;
+ if (this.files.some(f => f.id == file)) return false;
+ this.removeFile(file);
+ this.api('drive/files/update', {
+ file_id: file,
+ folder_id: this.folder ? this.folder.id : null
+ });
+ // (ドライブの)フォルダーだったら
+ } else if (obj.type == 'folder') {
+ const folder = obj.id;
+ // 移動先が自分自身ならreject
+ if (this.folder && folder == this.folder.id) return false;
+ if (this.folders.some(f => f.id == folder)) return false;
+ this.removeFolder(folder);
+ this.api('drive/folders/update', {
+ folder_id: folder,
+ parent_id: this.folder ? this.folder.id : null
+ }).then(() => {
+ // something
+ }).catch(err => {
+ switch (err) {
+ case 'detected-circular-definition':
+ this.dialog('<i class="fa fa-exclamation-triangle"></i>操作を完了できません',
+ '移動先のフォルダーは、移動するフォルダーのサブフォルダーです。', [{
+ text: 'OK'
+ }]);
+ break;
+ default:
+ alert('不明なエラー' + err);
+ }
+ });
+ }
- ctx = document.body.append-child document.create-element \mk-drive-browser-base-contextmenu
- ctx = riot.mount ctx, do
- browser: @
- ctx = ctx.0
- ctx.open do
- x: e.page-x - window.page-x-offset
- y: e.page-y - window.page-y-offset
+ return false;
+ };
- return false
+ this.oncontextmenu = e => {
+ e.preventDefault();
+ e.stopImmediatePropagation();
- @select-local-file = ~>
- @refs.file-input.click!
+ const ctx = riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-base-contextmenu')), {
+ browser: this
+ })[0];
+ ctx.open({
+ x: e.pageX - window.pageXOffset,
+ y: e.pageY - window.pageYOffset
+ });
- @url-upload = ~>
- url <~ @input-dialog do
- 'URLアップロード'
- 'アップロードしたいファイルのURL'
- null
+ return false;
+ };
- if url? and url != ''
- @api \drive/files/upload_from_url do
- url: url
- folder_id: if @folder? then @folder.id else undefined
+ this.selectLocalFile = () => {
+ this.refs.fileInput.click();
+ };
- @dialog do
- '<i class="fa fa-check"></i>アップロードをリクエストしました'
- 'アップロードが完了するまで時間がかかる場合があります。'
- [
- text: \OK
- ]
+ this.urlUpload = () => {
+ this.inputDialog('URLアップロード', 'アップロードしたいファイルのURL', null, url => {
+ this.api('drive/files/upload_from_url', {
+ url: url,
+ folder_id: this.folder ? this.folder.id : undefined
+ });
- @create-folder = ~>
- name <~ @input-dialog do
- 'フォルダー作成'
- 'フォルダー名'
- null
+ this.dialog('<i class="fa fa-check"></i>アップロードをリクエストしました',
+ 'アップロードが完了するまで時間がかかる場合があります。', [{
+ text: 'OK'
+ }]);
+ });
+ };
- @api \drive/folders/create do
- name: name
- folder_id: if @folder? then @folder.id else undefined
- .then (folder) ~>
- @add-folder folder, true
- @update!
- .catch (err) ~>
- console.error err
+ this.createFolder = () => {
+ this.inputDialog('フォルダー作成', 'フォルダー名', null, name => {
+ this.api('drive/folders/create', {
+ name: name,
+ folder_id: this.folder ? this.folder.id : undefined
+ }).then(folder => {
+ this.addFolder(folder, true);
+ this.update();
+ });
+ });
+ };
- @change-file-input = ~>
- files = @refs.file-input.files
- for i from 0 to files.length - 1
- file = files.item i
- @upload file, @folder
+ this.changeFileInput = () => {
+ this.refs.fileInput.files.forEach(file => {
+ this.upload(file, this.folder);
+ });
+ };
- @upload = (file, folder) ~>
- if folder? and typeof folder == \object
- folder = folder.id
- @refs.uploader.upload file, folder
+ this.upload = (file, folder) => {
+ if (folder && typeof folder == 'object') folder = folder.id;
+ this.refs.uploader.upload(file, folder);
+ };
- @get-selection = ~>
- @files.filter (file) -> file._selected
+ this.getSelection = () => {
+ this.files.filter(file => file._selected);
+ };
- @new-window = (folder-id) ~>
- browser = document.body.append-child document.create-element \mk-drive-browser-window
- riot.mount browser, do
- folder: folder-id
+ this.newWindow = folderId => {
+ riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-window')), {
+ folder: folderId
+ });
+ };
- @move = (target-folder) ~>
- if target-folder? and typeof target-folder == \object
- target-folder = target-folder.id
+ this.move = target => {
+ if (target == null) {
+ this.goRoot();
+ return;
+ } else if (typeof target == 'object') {
+ target = target.id;
+ }
- if target-folder == null
- @go-root!
- return
+ this.update({
+ fetching: true
+ });
- @loading = true
- @update!
+ this.api('drive/folders/show', {
+ folder_id: target
+ }).then(folder => {
+ this.folder = folder;
+ this.hierarchyFolders = [];
- @api \drive/folders/show do
- folder_id: target-folder
- .then (folder) ~>
- @folder = folder
- @hierarchy-folders = []
+ const dive = folder => {
+ this.hierarchyFolders.unshift(folder);
+ if (folder.parent) dive(folder.parent);
+ };
- x = (f) ~>
- @hierarchy-folders.unshift f
- if f.parent?
- x f.parent
+ if (folder.parent) dive(folder.parent);
- if folder.parent?
- x folder.parent
+ this.update();
+ this.load();
+ });
+ };
- @update!
- @load!
- .catch (err, text-status) ->
- console.error err
+ this.addFolder = (folder, unshift = false) => {
+ const current = this.folder ? this.folder.id : null;
+ if (current != folder.parent_id) return;
- @add-folder = (folder, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- return
+ if (this.folders.some(f => f.id == folder.id)) {
+ const exist = this.folders.map(f => f.id).indexOf(folder.id);
+ this.folders[exist] = folder;
+ this.update();
+ return;
+ }
- if (@folders.some (f) ~> f.id == folder.id)
- exist = (@folders.map (f) -> f.id).index-of folder.id
- @folders[exist] = folder
- @update!
- return
+ if (unshift) {
+ this.folders.unshift(folder);
+ } else {
+ this.folders.push(folder);
+ }
- if unshift
- @folders.unshift folder
- else
- @folders.push folder
+ this.update();
+ };
- @update!
+ this.addFile = (file, unshift = false) => {
+ const current = this.folder ? this.folder.id : null;
+ if (current != file.folder_id) return;
- @add-file = (file, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- return
+ if (this.files.some(f => f.id == file.id)) {
+ const exist = this.files.map(f => f.id).indexOf(file.id);
+ this.files[exist] = file;
+ this.update();
+ return;
+ }
- if (@files.some (f) ~> f.id == file.id)
- exist = (@files.map (f) -> f.id).index-of file.id
- @files[exist] = file
- @update!
- return
+ if (unshift) {
+ this.files.unshift(file);
+ } else {
+ this.files.push(file);
+ }
- if unshift
- @files.unshift file
- else
- @files.push file
+ this.update();
+ };
- @update!
+ this.removeFolder = folder => {
+ if (typeof folder == 'object') folder = folder.id;
+ this.folders = this.folders.filter(f => f.id != folder);
+ this.update();
+ };
- @remove-folder = (folder) ~>
- if typeof folder == \object
- folder = folder.id
- @folders = @folders.filter (f) -> f.id != folder
- @update!
+ this.removeFile = file => {
+ if (typeof file == 'object') file = file.id;
+ this.files = this.files.filter(f => f.id != file);
+ this.update();
+ };
- @remove-file = (file) ~>
- if typeof file == \object
- file = file.id
- @files = @files.filter (f) -> f.id != file
- @update!
+ this.goRoot = () => {
+ // 既にrootにいるなら何もしない
+ if (this.folder == null) return;
- @go-root = ~>
- if @folder != null
- @folder = null
- @hierarchy-folders = []
- @update!
- @load!
+ this.update({
+ folder: null,
+ hierarchyFolders: []
+ });
+ this.load();
+ };
- @load = ~>
- @folders = []
- @files = []
- @more-folders = false
- @more-files = false
- @loading = true
- @update!
+ this.load = () => {
+ this.update({
+ folders: [],
+ files: [],
+ moreFolders: false,
+ moreFiles: false,
+ fetching: true
+ });
- load-folders = null
- load-files = null
+ let fetchedFolders = null;
+ let fetchedFiles = null;
- folders-max = 30
- files-max = 30
+ const foldersMax = 30;
+ const filesMax = 30;
- # フォルダ一覧取得
- @api \drive/folders do
- folder_id: if @folder? then @folder.id else null
- limit: folders-max + 1
- .then (folders) ~>
- if folders.length == folders-max + 1
- @more-folders = true
- folders.pop!
- load-folders := folders
- complete!
- .catch (err, text-status) ~>
- console.error err
+ // フォルダ一覧取得
+ this.api('drive/folders', {
+ folder_id: this.folder ? this.folder.id : null,
+ limit: foldersMax + 1
+ }).then(folders => {
+ if (folders.length == foldersMax + 1) {
+ this.moreFolders = true;
+ folders.pop();
+ }
+ fetchedFolders = folders;
+ complete();
+ });
- # ファイル一覧取得
- @api \drive/files do
- folder_id: if @folder? then @folder.id else null
- limit: files-max + 1
- .then (files) ~>
- if files.length == files-max + 1
- @more-files = true
- files.pop!
- load-files := files
- complete!
- .catch (err, text-status) ~>
- console.error err
+ // ファイル一覧取得
+ this.api('drive/files', {
+ folder_id: this.folder ? this.folder.id : null,
+ limit: filesMax + 1
+ }).then(files => {
+ if (files.length == filesMax + 1) {
+ this.moreFiles = true;
+ files.pop();
+ }
+ fetchedFiles = files;
+ complete();
+ });
- flag = false
- complete = ~>
- if flag
- load-folders.for-each (folder) ~>
- @add-folder folder
- load-files.for-each (file) ~>
- @add-file file
- @loading = false
- @update!
- else
- flag := true
+ let flag = false;
+ const complete = () => {
+ if (flag) {
+ fetchedFolders.forEach(this.addFolder);
+ fetchedFiles.forEach(this.addFile);
+ this.update({
+ fetching: false
+ });
+ } else {
+ flag = true;
+ }
+ };
+ };
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
</script>
</mk-drive-browser>
diff --git a/src/web/app/desktop/tags/drive/file-contextmenu.tag b/src/web/app/desktop/tags/drive/file-contextmenu.tag
index a2c9eb3f4e..29f1befc44 100644
--- a/src/web/app/desktop/tags/drive/file-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/file-contextmenu.tag
@@ -22,9 +22,6 @@
<li onclick={ parent.setBanner }>
<p>バナーに設定</p>
</li>
- <li onclick={ parent.setWallpaper }>
- <p>壁紙に設定</p>
- </li>
</ul>
</li>
<li class="has-child">
@@ -38,60 +35,58 @@
</ul>
</mk-contextmenu>
<script>
- @mixin \api
- @mixin \i
- @mixin \update-avatar
- @mixin \update-banner
- @mixin \update-wallpaper
- @mixin \input-dialog
- @mixin \NotImplementedException
-
- @browser = @opts.browser
- @file = @opts.file
-
- @on \mount ~>
- @refs.ctx.on \closed ~>
- @trigger \closed
- @unmount!
+ this.mixin('api');
+ this.mixin('i');
+ this.mixin('update-avatar');
+ this.mixin('update-banner');
+ this.mixin('input-dialog');
+ this.mixin('NotImplementedException');
- @open = (pos) ~>
- @refs.ctx.open pos
+ this.browser = this.opts.browser;
+ this.file = this.opts.file;
- @rename = ~>
- @refs.ctx.close!
+ this.on('mount', () => {
+ this.refs.ctx.on('closed', () => {
+ this.trigger('closed');
+ this.unmount();
+ });
+ });
- name <~ @input-dialog do
- 'ファイル名の変更'
- '新しいファイル名を入力してください'
- @file.name
+ this.open = pos => {
+ this.refs.ctx.open(pos);
+ };
- @api \drive/files/update do
- file_id: @file.id
- name: name
- .then ~>
- # something
- .catch (err) ~>
- console.error err
+ this.rename = () => {
+ this.refs.ctx.close();
- @copy-url = ~>
- @NotImplementedException!
+ this.inputDialog('ファイル名の変更', '新しいファイル名を入力してください', this.file.name, name => {
+ this.api('drive/files/update', {
+ file_id: this.file.id,
+ name: name
+ })
+ });
+ };
- @download = ~>
- @refs.ctx.close!
+ this.copyUrl = () => {
+ this.NotImplementedException();
+ };
- @set-avatar = ~>
- @refs.ctx.close!
- @update-avatar @I, null, @file
+ this.download = () => {
+ this.refs.ctx.close();
+ };
- @set-banner = ~>
- @refs.ctx.close!
- @update-banner @I, null, @file
+ this.setAvatar = () => {
+ this.refs.ctx.close();
+ this.updateAvatar(this.I, null, this.file);
+ };
- @set-wallpaper = ~>
- @refs.ctx.close!
- @update-wallpaper @I, null, @file
+ this.setBanner = () => {
+ this.refs.ctx.close();
+ this.updateBanner(this.I, null, this.file);
+ };
- @add-app = ~>
- @NotImplementedException!
+ this.addApp = () => {
+ this.NotImplementedException();
+ };
</script>
</mk-drive-browser-file-contextmenu>
diff --git a/src/web/app/desktop/tags/drive/file.tag b/src/web/app/desktop/tags/drive/file.tag
index 252e5ab1de..d92d4bbaf1 100644
--- a/src/web/app/desktop/tags/drive/file.tag
+++ b/src/web/app/desktop/tags/drive/file.tag
@@ -144,66 +144,76 @@
</style>
<script>
- @bytes-to-size = require '../../../common/scripts/bytes-to-size.js'
+ this.bytesToSize = require('../../../common/scripts/bytes-to-size');
- @mixin \i
+ this.mixin('i');
- @file = @opts.file
- @browser = @parent
+ this.file = this.opts.file;
+ this.browser = this.parent;
- @title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
+ this.title = `${this.file.name}\n${this.file.type} ${this.bytesToSize(this.file.datasize)}`;
- @is-contextmenu-showing = false
+ this.isContextmenuShowing = false;
- @onclick = ~>
- if @browser.multiple
- if @file._selected?
- @file._selected = !@file._selected
- else
- @file._selected = true
- @browser.trigger \change-selection @browser.get-selection!
- else
- if @file._selected
- @browser.trigger \selected @file
- else
- @browser.files.for-each (file) ~>
- file._selected = false
- @file._selected = true
- @browser.trigger \change-selection @file
+ this.onclick = () => {
+ if (this.browser.multiple) {
+ if (this.file._selected != null) {
+ this.file._selected = !this.file._selected;
+ } else {
+ this.file._selected = true;
+ }
+ this.browser.trigger('change-selection', this.browser.getSelection());
+ } else {
+ if (this.file._selected) {
+ this.browser.trigger('selected', this.file);
+ } else {
+ this.browser.files.forEach(file => file._selected = false);
+ this.file._selected = true;
+ this.browser.trigger('change-selection', this.file);
+ }
+ }
+ };
- @oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
+ this.oncontextmenu = e => {
+ e.preventDefault();
+ e.stopImmediatePropagation();
- @is-contextmenu-showing = true
- @update!
- ctx = document.body.append-child document.create-element \mk-drive-browser-file-contextmenu
- ctx = riot.mount ctx, do
- browser: @browser
- file: @file
- ctx = ctx.0
- ctx.open do
- x: e.page-x - window.page-x-offset
- y: e.page-y - window.page-y-offset
- ctx.on \closed ~>
- @is-contextmenu-showing = false
- @update!
- return false
+ this.update({
+ isContextmenuShowing: true
+ });
+ const ctx = riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-file-contextmenu')), {
+ browser: this.browser,
+ file: this.file
+ })[0];
+ ctx.open({
+ x: e.pageX - window.pageXOffset,
+ y: e.pageY - window.pageYOffset
+ });
+ ctx.on('closed', () => {
+ this.update({
+ isContextmenuShowing: false
+ });
+ });
+ return false;
+ };
- @ondragstart = (e) ~>
- e.data-transfer.effect-allowed = \move
- e.data-transfer.set-data 'text' JSON.stringify do
- type: \file
- id: @file.id
- file: @file
- @is-dragging = true
+ this.ondragstart = e => {
+ e.dataTransfer.effectAllowed = 'move';
+ e.dataTransfer.setData('text', JSON.stringify({
+ type: 'file',
+ id: this.file.id,
+ file: this.file
+ }));
+ this.isDragging = true;
- # 親ブラウザに対して、ドラッグが開始されたフラグを立てる
- # (=あなたの子供が、ドラッグを開始しましたよ)
- @browser.is-drag-source = true
+ // 親ブラウザに対して、ドラッグが開始されたフラグを立てる
+ // (=あなたの子供が、ドラッグを開始しましたよ)
+ this.browser.isDragSource = true;
+ };
- @ondragend = (e) ~>
- @is-dragging = false
- @browser.is-drag-source = false
+ this.ondragend = e => {
+ this.isDragging = false;
+ this.browser.isDragSource = false;
+ };
</script>
</mk-drive-browser-file>
diff --git a/src/web/app/desktop/tags/drive/folder-contextmenu.tag b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
index aea0904aa9..51e131f448 100644
--- a/src/web/app/desktop/tags/drive/folder-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
@@ -18,49 +18,45 @@
</ul>
</mk-contextmenu>
<script>
- @mixin \api
- @mixin \input-dialog
+ this.mixin('api');
+ this.mixin('input-dialog');
- @browser = @opts.browser
- @folder = @opts.folder
+ this.browser = this.opts.browser;
+ this.folder = this.opts.folder;
- @open = (pos) ~>
- @refs.ctx.open pos
+ this.open = pos => {
+ this.refs.ctx.open(pos);
- @refs.ctx.on \closed ~>
- @trigger \closed
- @unmount!
+ this.refs.ctx.on('closed', () => {
+ this.trigger('closed');
+ this.unmount();
+ });
+ };
- @move = ~>
- @browser.move @folder.id
- @refs.ctx.close!
+ this.move = () => {
+ this.browser.move(this.folder.id);
+ this.refs.ctx.close();
+ };
- @new-window = ~>
- @browser.new-window @folder.id
- @refs.ctx.close!
+ this.newWindow = () => {
+ this.browser.newWindow(this.folder.id);
+ this.refs.ctx.close();
+ };
- @create-folder = ~>
- @browser.create-folder!
- @refs.ctx.close!
+ this.createFolder = () => {
+ this.browser.createFolder();
+ this.refs.ctx.close();
+ };
- @upload = ~>
- @browser.select-lcoal-file!
- @refs.ctx.close!
+ this.rename = () => {
+ this.refs.ctx.close();
- @rename = ~>
- @refs.ctx.close!
-
- name <~ @input-dialog do
- 'フォルダ名の変更'
- '新しいフォルダ名を入力してください'
- @folder.name
-
- @api \drive/folders/update do
- folder_id: @folder.id
- name: name
- .then ~>
- # something
- .catch (err) ~>
- console.error err
+ this.inputialog('フォルダ名の変更', '新しいフォルダ名を入力してください', this.folder.name, name => {
+ this.api('drive/folders/update', {
+ folder_id: this.folder.id,
+ name: name
+ });
+ });
+ };
</script>
</mk-drive-browser-folder-contextmenu>
diff --git a/src/web/app/desktop/tags/drive/folder.tag b/src/web/app/desktop/tags/drive/folder.tag
index b6d52f19e6..1b804e97a1 100644
--- a/src/web/app/desktop/tags/drive/folder.tag
+++ b/src/web/app/desktop/tags/drive/folder.tag
@@ -50,135 +50,152 @@
</style>
<script>
- @mixin \api
- @mixin \dialog
+ this.mixin('api');
+ this.mixin('dialog');
- @folder = @opts.folder
- @browser = @parent
+ this.folder = this.opts.folder;
+ this.browser = this.parent;
- @title = @folder.name
- @hover = false
- @draghover = false
- @is-contextmenu-showing = false
+ this.title = this.folder.name;
+ this.hover = false;
+ this.draghover = false;
+ this.isContextmenuShowing = false;
- @onclick = ~>
- @browser.move @folder
+ this.onclick = () => {
+ this.browser.move(this.folder);
+ };
- @onmouseover = ~>
- @hover = true
+ this.onmouseover = () => {
+ this.hover = true;
+ };
- @onmouseout = ~>
- @hover = false
+ this.onmouseout = () => {
+ this.hover = false
+ };
- @ondragover = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ this.ondragover = e => {
+ e.preventDefault();
+ e.stopPropagation();
- # 自分自身がドラッグされていない場合
- if !@is-dragging
- # ドラッグされてきたものがファイルだったら
- if e.data-transfer.effect-allowed == \all
- e.data-transfer.drop-effect = \copy
- else
- e.data-transfer.drop-effect = \move
- else
- # 自分自身にはドロップさせない
- e.data-transfer.drop-effect = \none
- return false
+ // 自分自身がドラッグされていない場合
+ if (!this.isDragging) {
+ // ドラッグされてきたものがファイルだったら
+ if (e.dataTransfer.effectAllowed === 'all') {
+ e.dataTransfer.dropEffect = 'copy';
+ } else {
+ e.dataTransfer.dropEffect = 'move';
+ }
+ } else {
+ // 自分自身にはドロップさせない
+ e.dataTransfer.dropEffect = 'none';
+ }
+ return false;
+ };
- @ondragenter = ~>
- if !@is-dragging
- @draghover = true
+ this.ondragenter = () => {
+ if (!this.isDragging) this.draghover = true;
+ };
- @ondragleave = ~>
- @draghover = false
+ this.ondragleave = () => {
+ this.draghover = false;
+ };
- @ondrop = (e) ~>
- e.stop-propagation!
- @draghover = false
+ this.ondrop = e => {
+ e.stopPropagation();
+ this.draghover = false;
- # ファイルだったら
- if e.data-transfer.files.length > 0
- Array.prototype.for-each.call e.data-transfer.files, (file) ~>
- @browser.upload file, @folder
- return false
+ // ファイルだったら
+ if (e.dataTransfer.files.length > 0) {
+ e.dataTransfer.files.forEach(file => {
+ this.browser.upload(file, this.folder);
+ });
+ return false;
+ };
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
- return false
+ // データ取得
+ const data = e.dataTransfer.getData('text');
+ if (data == null) return false;
- # パース
- obj = JSON.parse data
+ // パース
+ // TODO: Validate JSON
+ const obj = JSON.parse(data);
- # (ドライブの)ファイルだったら
- if obj.type == \file
- file = obj.id
- @browser.remove-file file
- @api \drive/files/update do
- file_id: file
- folder_id: @folder.id
- .then ~>
- # something
- .catch (err, text-status) ~>
- console.error err
+ // (ドライブの)ファイルだったら
+ if (obj.type == 'file') {
+ const file = obj.id;
+ this.browser.removeFile(file);
+ this.api('drive/files/update', {
+ file_id: file,
+ folder_id: this.folder.id
+ });
+ // (ドライブの)フォルダーだったら
+ } else if (obj.type == 'folder') {
+ const folder = obj.id;
+ // 移動先が自分自身ならreject
+ if (folder == this.folder.id) return false;
+ this.browser.removeFolder(folder);
+ this.api('drive/folders/update', {
+ folder_id: folder,
+ parent_id: this.folder.id
+ }).then(() => {
+ // something
+ }).catch(err => {
+ switch (err) {
+ case 'detected-circular-definition':
+ this.dialog('<i class="fa fa-exclamation-triangle"></i>操作を完了できません',
+ '移動先のフォルダーは、移動するフォルダーのサブフォルダーです。', [{
+ text: 'OK'
+ }]);
+ break;
+ default:
+ alert('不明なエラー' + err);
+ }
+ });
+ }
- # (ドライブの)フォルダーだったら
- else if obj.type == \folder
- folder = obj.id
- # 移動先が自分自身ならreject
- if folder == @folder.id
- return false
- @browser.remove-folder folder
- @api \drive/folders/update do
- folder_id: folder
- parent_id: @folder.id
- .then ~>
- # something
- .catch (err) ~>
- if err == 'detected-circular-definition'
- @dialog do
- '<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
- '移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
- [
- text: \OK
- ]
+ return false;
+ };
- return false
+ this.ondragstart = e => {
+ e.dataTransfer.effectAllowed = 'move';
+ e.dataTransfer.setData('text', JSON.stringify({
+ type: 'folder',
+ id: this.folder.id
+ }));
+ this.isDragging = true;
- @ondragstart = (e) ~>
- e.data-transfer.effect-allowed = \move
- e.data-transfer.set-data 'text' JSON.stringify do
- type: \folder
- id: @folder.id
- @is-dragging = true
+ // 親ブラウザに対して、ドラッグが開始されたフラグを立てる
+ // (=あなたの子供が、ドラッグを開始しましたよ)
+ this.browser.isDragSource = true;
+ };
- # 親ブラウザに対して、ドラッグが開始されたフラグを立てる
- # (=あなたの子供が、ドラッグを開始しましたよ)
- @browser.is-drag-source = true
+ this.ondragend = e => {
+ this.isDragging = false;
+ this.browser.isDragSource = false;
+ };
- @ondragend = (e) ~>
- @is-dragging = false
- @browser.is-drag-source = false
+ this.oncontextmenu = e => {
+ e.preventDefault();
+ e.stopImmediatePropagation();
- @oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
+ this.update({
+ isContextmenuShowing: true
+ });
+ const ctx = riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-folder-contextmenu')), {
+ browser: this.browser,
+ folder: this.folder
+ })[0];
+ ctx.open({
+ x: e.pageX - window.pageXOffset,
+ y: e.pageY - window.pageYOffset
+ });
+ ctx.on('closed', () => {
+ this.update({
+ isContextmenuShowing: false
+ });
+ });
- @is-contextmenu-showing = true
- @update!
- ctx = document.body.append-child document.create-element \mk-drive-browser-folder-contextmenu
- ctx = riot.mount ctx, do
- browser: @browser
- folder: @folder
- ctx = ctx.0
- ctx.open do
- x: e.page-x - window.page-x-offset
- y: e.page-y - window.page-y-offset
- ctx.on \closed ~>
- @is-contextmenu-showing = false
- @update!
-
- return false
+ return false;
+ };
</script>
</mk-drive-browser-folder>
diff --git a/src/web/app/desktop/tags/drive/nav-folder.tag b/src/web/app/desktop/tags/drive/nav-folder.tag
index 632783d20b..e961ac491b 100644
--- a/src/web/app/desktop/tags/drive/nav-folder.tag
+++ b/src/web/app/desktop/tags/drive/nav-folder.tag
@@ -6,92 +6,93 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- # Riotのバグでnullを渡しても""になる
- # https://github.com/riot/riot/issues/2080
- #@folder = @opts.folder
- @folder = if @opts.folder? and @opts.folder != '' then @opts.folder else null
- @browser = @parent
+ // Riotのバグでnullを渡しても""になる
+ // https://github.com/riot/riot/issues/2080
+ //this.folder = this.opts.folder
+ this.folder = this.opts.folder && this.opts.folder != '' ? this.opts.folder : null;
+ this.browser = this.parent;
- @hover = false
+ this.hover = false;
- @onclick = ~>
- @browser.move @folder
+ this.onclick = () => {
+ this.browser.move(this.folder);
+ };
- @onmouseover = ~>
- @hover = true
+ this.onmouseover = () => {
+ this.hover = true
+ };
- @onmouseout = ~>
- @hover = false
+ this.onmouseout = () => {
+ this.hover = false
+ };
- @ondragover = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ this.ondragover = e => {
+ e.preventDefault();
+ e.stopPropagation();
- # このフォルダがルートかつカレントディレクトリならドロップ禁止
- if @folder == null and @browser.folder == null
- e.data-transfer.drop-effect = \none
- # ドラッグされてきたものがファイルだったら
- else if e.data-transfer.effect-allowed == \all
- e.data-transfer.drop-effect = \copy
- else
- e.data-transfer.drop-effect = \move
- return false
+ // このフォルダがルートかつカレントディレクトリならドロップ禁止
+ if (this.folder == null && this.browser.folder == null) {
+ e.dataTransfer.dropEffect = 'none';
+ // ドラッグされてきたものがファイルだったら
+ } else if (e.dataTransfer.effectAllowed == 'all') {
+ e.dataTransfer.dropEffect = 'copy';
+ } else {
+ e.dataTransfer.dropEffect = 'move';
+ }
+ return false;
+ };
- @ondragenter = ~>
- if @folder != null or @browser.folder != null
- @draghover = true
+ this.ondragenter = () => {
+ if (this.folder || this.browser.folder) this.draghover = true;
+ };
- @ondragleave = ~>
- if @folder != null or @browser.folder != null
- @draghover = false
+ this.ondragleave = () => {
+ if (this.folder || this.browser.folder) this.draghover = false;
+ };
- @ondrop = (e) ~>
- e.stop-propagation!
- @draghover = false
+ this.ondrop = e => {
+ e.stopPropagation();
+ this.draghover = false;
- # ファイルだったら
- if e.data-transfer.files.length > 0
- Array.prototype.for-each.call e.data-transfer.files, (file) ~>
- @browser.upload file, @folder
- return false
+ // ファイルだったら
+ if (e.dataTransfer.files.length > 0) {
+ e.dataTransfer.files.forEach(file => {
+ this.browser.upload(file, this.folder);
+ });
+ return false;
+ };
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
- return false
+ // データ取得
+ const data = e.dataTransfer.getData('text');
+ if (data == null) return false;
- # パース
- obj = JSON.parse data
+ // パース
+ // TODO: Validate JSON
+ const obj = JSON.parse(data);
- # (ドライブの)ファイルだったら
- if obj.type == \file
- file = obj.id
- @browser.remove-file file
- @api \drive/files/update do
- file_id: file
- folder_id: if @folder? then @folder.id else null
- .then ~>
- # something
- .catch (err, text-status) ~>
- console.error err
+ // (ドライブの)ファイルだったら
+ if (obj.type == 'file') {
+ const file = obj.id;
+ this.browser.removeFile(file);
+ this.api('drive/files/update', {
+ file_id: file,
+ folder_id: this.folder ? this.folder.id : null
+ });
+ // (ドライブの)フォルダーだったら
+ } else if (obj.type == 'folder') {
+ const folder = obj.id;
+ // 移動先が自分自身ならreject
+ if (this.folder && folder == this.folder.id) return false;
+ this.browser.removeFolder(folder);
+ this.api('drive/folders/update', {
+ folder_id: folder,
+ parent_id: this.folder ? this.folder.id : null
+ });
+ }
- # (ドライブの)フォルダーだったら
- else if obj.type == \folder
- folder = obj.id
- # 移動先が自分自身ならreject
- if @folder? and folder == @folder.id
- return false
- @browser.remove-folder folder
- @api \drive/folders/update do
- folder_id: folder
- parent_id: if @folder? then @folder.id else null
- .then ~>
- # something
- .catch (err, text-status) ~>
- console.error err
-
- return false
+ return false;
+ };
</script>
</mk-drive-browser-nav-folder>
diff --git a/src/web/app/desktop/tags/ellipsis-icon.tag b/src/web/app/desktop/tags/ellipsis-icon.tag
index 731c2525f1..8462bfc4af 100644
--- a/src/web/app/desktop/tags/ellipsis-icon.tag
+++ b/src/web/app/desktop/tags/ellipsis-icon.tag
@@ -33,9 +33,5 @@
40%
transform scale(1)
-
-
-
-
</style>
</mk-ellipsis-icon>
diff --git a/src/web/app/desktop/tags/follow-button.tag b/src/web/app/desktop/tags/follow-button.tag
index 1e82b5ed1a..1877e4a53f 100644
--- a/src/web/app/desktop/tags/follow-button.tag
+++ b/src/web/app/desktop/tags/follow-button.tag
@@ -67,58 +67,74 @@
</style>
<script>
- @mixin \api
- @mixin \is-promise
- @mixin \stream
+ this.mixin('api');
+ this.mixin('is-promise');
+ this.mixin('stream');
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @init = true
- @wait = false
+ this.user = null;
+ this.userPromise = this.isPromise(this.opts.user)
+ ? this.opts.user
+ : Promise.resolve(this.opts.user);
+ this.init = true;
+ this.wait = false;
- @on \mount ~>
- @user-promise.then (user) ~>
- @user = user
- @init = false
- @update!
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ this.on('mount', () => {
+ this.userPromise.then(user => {
+ this.update({
+ init: false,
+ user: user
+ });
+ this.stream.on('follow', this.onStreamFollow);
+ this.stream.on('unfollow', this.onStreamUnfollow);
+ });
+ });
- @on \unmount ~>
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ this.on('unmount', () => {
+ this.stream.off('follow', this.onStreamFollow);
+ this.stream.off('unfollow', this.onStreamUnfollow);
+ });
- @on-stream-follow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ this.onStreamFollow = user => {
+ if (user.id == this.user.id) {
+ this.update({
+ user: user
+ });
+ }
+ };
- @on-stream-unfollow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ this.onStreamUnfollow = user => {
+ if (user.id == this.user.id) {
+ this.update({
+ user: user
+ });
+ }
+ };
- @onclick = ~>
- @wait = true
- if @user.is_following
- @api \following/delete do
- user_id: @user.id
- .then ~>
- @user.is_following = false
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
- @update!
- else
- @api \following/create do
- user_id: @user.id
- .then ~>
- @user.is_following = true
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
- @update!
+ this.onclick = () => {
+ this.wait = true;
+ if (this.user.is_following) {
+ this.api('following/delete', {
+ user_id: this.user.id
+ }).then(() => {
+ this.user.is_following = false;
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.wait = false;
+ this.update();
+ });
+ } else {
+ this.api('following/create', {
+ user_id: this.user.id
+ }).then(() => {
+ this.user.is_following = true;
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.wait = false;
+ this.update();
+ });
+ }
+ };
</script>
</mk-follow-button>
diff --git a/src/web/app/desktop/tags/following-setuper.tag b/src/web/app/desktop/tags/following-setuper.tag
index 1b2e5aafa0..3dc8fb54c7 100644
--- a/src/web/app/desktop/tags/following-setuper.tag
+++ b/src/web/app/desktop/tags/following-setuper.tag
@@ -1,6 +1,6 @@
<mk-following-setuper>
<p class="title">気になるユーザーをフォロー:</p>
- <div class="users" if={ !loading && users.length > 0 }>
+ <div class="users" if={ !fetching && users.length > 0 }>
<div class="user" each={ users }><a class="avatar-anchor" href={ CONFIG.url + '/' + username }><img class="avatar" src={ avatar_url + '?thumbnail&size=42' } alt="" data-user-preview={ id }/></a>
<div class="body"><a class="name" href={ CONFIG.url + '/' + username } target="_blank" data-user-preview={ id }>{ name }</a>
<p class="username">@{ username }</p>
@@ -8,8 +8,8 @@
<mk-follow-button user={ this }></mk-follow-button>
</div>
</div>
- <p class="empty" if={ !loading && users.length == 0 }>おすすめのユーザーは見つかりませんでした。</p>
- <p class="loading" if={ loading }><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <p class="empty" if={ !fetching && users.length == 0 }>おすすめのユーザーは見つかりませんでした。</p>
+ <p class="fetching" if={ fetching }><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
<mk-ellipsis></mk-ellipsis>
</p><a class="refresh" onclick={ refresh }>もっと見る</a>
<button class="close" onclick={ close } title="閉じる"><i class="fa fa-times"></i></button>
@@ -81,7 +81,7 @@
text-align center
color #aaa
- > .loading
+ > .fetching
margin 0
padding 16px
text-align center
@@ -123,41 +123,49 @@
</style>
<script>
- @mixin \api
- @mixin \user-preview
+ this.mixin('api');
+ this.mixin('user-preview');
- @users = null
- @loading = true
+ this.users = null;
+ this.fetching = true;
- @limit = 6users
- @page = 0
+ this.limit = 6;
+ this.page = 0;
- @on \mount ~>
- @load!
+ this.on('mount', () => {
+ this.fetch();
+ });
- @load = ~>
- @loading = true
- @users = null
- @update!
+ this.fetch = () => {
+ this.update({
+ fetching: true,
+ users: null
+ });
- @api \users/recommendation do
- limit: @limit
- offset: @limit * @page
- .then (users) ~>
- @loading = false
- @users = users
- @update!
- .catch (err, text-status) ->
- console.error err
+ this.api('users/recommendation', {
+ limit: this.limit,
+ offset: this.limit * this.page
+ }).then(users => {
+ this.fetching = false
+ this.users = users
+ this.update({
+ fetching: false,
+ users: users
+ });
+ });
+ };
- @refresh = ~>
- if @users.length < @limit
- @page = 0
- else
- @page++
- @load!
+ this.refresh = () => {
+ if (this.users.length < this.limit) {
+ this.page = 0;
+ } else {
+ this.page++;
+ }
+ this.fetch();
+ };
- @close = ~>
- @unmount!
+ this.close = () => {
+ this.unmount();
+ };
</script>
</mk-following-setuper>
diff --git a/src/web/app/desktop/tags/go-top.tag b/src/web/app/desktop/tags/go-top.tag
deleted file mode 100644
index d43e68ea90..0000000000
--- a/src/web/app/desktop/tags/go-top.tag
+++ /dev/null
@@ -1,14 +0,0 @@
-<mk-go-top>
- <button class="hidden" title="一番上へ"><i class="fa fa-angle-up"></i></button>
- <script>
- window.add-event-listener \load @on-scroll
- window.add-event-listener \scroll @on-scroll
- window.add-event-listener \resize @on-scroll
-
- @on-scroll = ~>
- if $ window .scroll-top! > 500px
- @remove-class \hidden
- else
- @add-class \hidden
- </script>
-</mk-go-top>
diff --git a/src/web/app/desktop/tags/home-widgets/calendar.tag b/src/web/app/desktop/tags/home-widgets/calendar.tag
index 3d62dc60c5..9aa4ac6326 100644
--- a/src/web/app/desktop/tags/home-widgets/calendar.tag
+++ b/src/web/app/desktop/tags/home-widgets/calendar.tag
@@ -106,43 +106,45 @@
</style>
<script>
- @draw = ~>
- now = new Date!
- nd = now.get-date!
- nm = now.get-month!
- ny = now.get-full-year!
+ this.draw = () => {
+ const now = new Date();
+ const nd = now.getDate();
+ const nm = now.getMonth();
+ const ny = now.getFullYear();
- @year = ny
- @month = nm + 1
- @day = nd
- @week-day = [\日 \月 \火 \水 \木 \金 \土][now.get-day!]
+ this.year = ny;
+ this.month = nm + 1;
+ this.day = nd;
+ this.weekDay = ['日', '月', '火', '水', '木', '金', '土'][now.getDay()];
- @day-numer = (now - (new Date ny, nm, nd))
- @day-denom = 1000ms * 60s * 60m * 24h
- @month-numer = (now - (new Date ny, nm, 1))
- @month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1)
- @year-numer = (now - (new Date ny, 0, 1))
- @year-denom = (new Date ny + 1, 0, 1) - (new Date ny, 0, 1)
+ this.dayNumer = now - new Date(ny, nm, nd);
+ this.dayDenom = 1000/*ms*/ * 60/*s*/ * 60/*m*/ * 24/*h*/;
+ this.monthNumer = now - new Date(ny, nm, 1);
+ this.monthDenom = new Date(ny, nm + 1, 1) - new Date(ny, nm, 1);
+ this.yearNumer = now - new Date(ny, 0, 1);
+ this.yearDenom = new Date(ny + 1, 0, 1) - new Date(ny, 0, 1);
- @day-p = @day-numer / @day-denom * 100
- @month-p = @month-numer / @month-denom * 100
- @year-p = @year-numer / @year-denom * 100
+ this.dayP = this.dayNumer / this.dayDenom * 100;
+ this.monthP = this.monthNumer / this.monthDenom * 100;
+ this.yearP = this.yearNumer / this.yearDenom * 100;
- @is-holiday =
- (now.get-day! == 0 or now.get-day! == 6)
+ this.isHoliday = now.getDay() == 0 || now.getDay() == 6;
- @special =
- | nm == 0 and nd == 1 => \on-new-years-day
- | _ => false
+ this.special =
+ nm == 0 && nd == 1 ? 'on-new-years-day' :
+ false;
- @update!
+ this.update();
+ };
- @draw!
+ this.draw();
- @on \mount ~>
- @clock = set-interval @draw, 1000ms
+ this.on('mount', () => {
+ this.clock = setInterval(this.draw, 1000);
+ });
- @on \unmount ~>
- clear-interval @clock
+ this.on('unmount', () => {
+ clearInterval(this.clock);
+ });
</script>
</mk-calendar-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 047ea5011d..57c86a8751 100644
--- a/src/web/app/desktop/tags/home-widgets/donation.tag
+++ b/src/web/app/desktop/tags/home-widgets/donation.tag
@@ -32,5 +32,5 @@
color #999
</style>
- <script>@mixin \user-preview</script>
+ <script>this.mixin('user-preview');</script>
</mk-donation-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/mentions.tag b/src/web/app/desktop/tags/home-widgets/mentions.tag
index d683b0817b..6e6d891cbf 100644
--- a/src/web/app/desktop/tags/home-widgets/mentions.tag
+++ b/src/web/app/desktop/tags/home-widgets/mentions.tag
@@ -46,67 +46,73 @@
</style>
<script>
- @mixin \i
- @mixin \api
+ this.mixin('i');
+ this.mixin('api');
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @mode = \all
+ this.isLoading = true;
+ this.isEmpty = false;
+ this.moreLoading = false;
+ this.mode = 'all';
- @on \mount ~>
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ this.on('mount', () => {
+ document.addEventListener('keydown', this.onDocumentKeydown);
+ window.addEventListener('scroll', this.onScroll);
- @fetch ~>
- @trigger \loaded
+ this.fetch(() => this.trigger('loaded'));
+ });
- @on \unmount ~>
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ this.on('unmount', () => {
+ document.removeEventListener('keydown', this.onDocumentKeydown);
+ window.removeEventListener('scroll', this.onScroll);
+ });
- @on-document-keydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 84 # t
- @refs.timeline.focus!
+ this.onDocumentKeydown = e => {
+ if (e.target.tagName != 'INPUT' && tag != 'TEXTAREA') {
+ if (e.which == 84) { // t
+ this.refs.timeline.focus();
+ }
+ }
+ };
- @fetch = (cb) ~>
- @api \posts/mentions do
- following: @mode == \following
- .then (posts) ~>
- @is-loading = false
- @is-empty = posts.length == 0
- @update!
- @refs.timeline.set-posts posts
- if cb? then cb!
- .catch (err) ~>
- console.error err
- if cb? then cb!
+ this.fetch = cb => {
+ this.api('posts/mentions', {
+ following: this.mode == 'following'
+ }).then(posts => {
+ this.update({
+ isLoading: false,
+ isEmpty: posts.length == 0
+ });
+ this.refs.timeline.setPosts(posts);
+ if (cb) cb();
+ });
+ };
- @more = ~>
- if @more-loading or @is-loading or @refs.timeline.posts.length == 0
- return
- @more-loading = true
- @update!
- @api \posts/mentions do
- following: @mode == \following
- max_id: @refs.timeline.tail!.id
- .then (posts) ~>
- @more-loading = false
- @update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
+ this.more = () => {
+ if (this.moreLoading || this.isLoading || this.refs.timeline.posts.length == 0) return;
+ this.update({
+ moreLoading: true
+ });
+ this.api('posts/mentions', {
+ following: this.mode == 'following',
+ max_id: this.refs.timeline.tail().id
+ }).then(posts => {
+ this.update({
+ moreLoading: false
+ });
+ this.refs.timeline.prependPosts(posts);
+ });
+ };
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 8
- @more!
+ this.onScroll = () => {
+ const current = window.scrollY + window.innerHeight;
+ if (current > document.body.offsetHeight - 8) this.more();
+ };
- @set-mode = (mode) ~>
- @update do
+ this.setMode = mode => {
+ this.update({
mode: mode
- @fetch!
+ });
+ this.fetch();
+ };
</script>
</mk-mentions-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 a792299a53..67affc75f9 100644
--- a/src/web/app/desktop/tags/home-widgets/nav.tag
+++ b/src/web/app/desktop/tags/home-widgets/nav.tag
@@ -13,9 +13,5 @@
i
color #ccc
-
-
-
-
</style>
</mk-nav-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/notifications.tag b/src/web/app/desktop/tags/home-widgets/notifications.tag
index b09ae976eb..5d71407b45 100644
--- a/src/web/app/desktop/tags/home-widgets/notifications.tag
+++ b/src/web/app/desktop/tags/home-widgets/notifications.tag
@@ -43,8 +43,9 @@
</style>
<script>
- @settings = ~>
- w = riot.mount document.body.append-child document.create-element \mk-settings-window .0
- w.switch \notification
+ this.settings = () => {
+ const w = riot.mount(document.body.appendChild(document.createElement('mk-settings-window')))[0];
+ w.switch('notification');
+ };
</script>
</mk-notifications-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/photo-stream.tag b/src/web/app/desktop/tags/home-widgets/photo-stream.tag
index 6ce0fd33f7..7cbb07b4de 100644
--- a/src/web/app/desktop/tags/home-widgets/photo-stream.tag
+++ b/src/web/app/desktop/tags/home-widgets/photo-stream.tag
@@ -57,31 +57,36 @@
</style>
<script>
- @mixin \api
- @mixin \stream
+ this.mixin('api');
+ this.mixin('stream');
- @images = []
- @initializing = true
+ this.images = [];
+ this.initializing = true;
- @on \mount ~>
- @stream.on \drive_file_created @on-stream-drive-file-created
+ this.on('mount', () => {
+ this.stream.on('drive_file_created', this.onStreamDriveFileCreated);
- @api \drive/stream do
- type: 'image/*'
- limit: 9images
- .then (images) ~>
- @initializing = false
- @images = images
- @update!
+ this.api('drive/stream', {
+ type: 'image/*',
+ limit: 9
+ }).then(images => {
+ this.update({
+ initializing: false,
+ images: images
+ });
+ });
+ });
- @on \unmount ~>
- @stream.off \drive_file_created @on-stream-drive-file-created
+ this.on('unmount', () => {
+ this.stream.off('drive_file_created', this.onStreamDriveFileCreated);
+ });
- @on-stream-drive-file-created = (file) ~>
- if /^image\/.+$/.test file.type
- @images.unshift file
- if @images.length > 9
- @images.pop!
- @update!
+ this.onStreamDriveFileCreated = file => {
+ if (/^image\/.+$/.test(file.type)) {
+ this.images.unshift(file);
+ if (this.images.length > 9) this.images.pop();
+ this.update();
+ }
+ };
</script>
</mk-photo-stream-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/profile.tag b/src/web/app/desktop/tags/home-widgets/profile.tag
index 9f11072b7a..8ee2186149 100644
--- a/src/web/app/desktop/tags/home-widgets/profile.tag
+++ b/src/web/app/desktop/tags/home-widgets/profile.tag
@@ -41,15 +41,17 @@
</style>
<script>
- @mixin \i
- @mixin \user-preview
- @mixin \update-avatar
- @mixin \update-banner
+ this.mixin('i');
+ this.mixin('user-preview');
+ this.mixin('update-avatar');
+ this.mixin('update-banner');
- @set-avatar = ~>
- @update-avatar @I
+ this.setAvatar = () => {
+ this.updateAvatar(this.I);
+ };
- @set-banner = ~>
- @update-banner @I
+ this.setBanner = () => {
+ this.updateBanner(this.I);
+ };
</script>
</mk-profile-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/rss-reader.tag b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
index 0efd5cbecc..c8700a8b63 100644
--- a/src/web/app/desktop/tags/home-widgets/rss-reader.tag
+++ b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
@@ -64,31 +64,35 @@
</style>
<script>
- @mixin \api
- @mixin \NotImplementedException
+ this.mixin('api');
+ this.mixin('NotImplementedException');
- @url = 'http://news.yahoo.co.jp/pickup/rss.xml'
- @items = []
- @initializing = true
+ this.url = 'http://news.yahoo.co.jp/pickup/rss.xml';
+ this.items = [];
+ this.initializing = true;
- @on \mount ~>
- @fetch!
- @clock = set-interval @fetch, 60000ms
+ this.on('mount', () => {
+ this.fetch();
+ this.clock = setInterval(this.fetch, 60000);
+ });
- @on \unmount ~>
- clear-interval @clock
+ this.on('unmount', () => {
+ clearInterval(this.clock);
+ });
- @fetch = ~>
- @api CONFIG.url + '/api:rss' do
- url: @url
- .then (feed) ~>
- @items = feed.rss.channel.item
- @initializing = false
- @update!
- .catch (err) ->
- console.error err
+ this.fetch = () => {
+ this.api(CONFIG.url + '/api:rss', {
+ url: this.url
+ }).then(feed => {
+ this.update({
+ initializing: false,
+ items: feed.rss.channel.item
+ });
+ });
+ };
- @settings = ~>
- @NotImplementedException!
+ this.settings = () => {
+ this.NotImplementedException();
+ };
</script>
</mk-rss-reader-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/timeline.tag b/src/web/app/desktop/tags/home-widgets/timeline.tag
index 9f5bb3890e..a0a8790eaa 100644
--- a/src/web/app/desktop/tags/home-widgets/timeline.tag
+++ b/src/web/app/desktop/tags/home-widgets/timeline.tag
@@ -32,80 +32,87 @@
</style>
<script>
- @mixin \i
- @mixin \api
- @mixin \stream
+ this.mixin('i');
+ this.mixin('api');
+ this.mixin('stream');
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @no-following = @I.following_count == 0
+ this.isLoading = true;
+ this.isEmpty = false;
+ this.moreLoading = false;
+ this.noFollowing = this.I.following_count == 0;
- @on \mount ~>
- @stream.on \post @on-stream-post
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ this.on('mount', () => {
+ this.stream.on('post', this.onStreamPost);
+ this.stream.on('follow', this.onStreamFollow);
+ this.stream.on('unfollow', this.onStreamUnfollow);
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ document.addEventListener('keydown', this.onDocumentKeydown);
+ window.addEventListener('scroll', this.onScroll);
- @load ~>
- @trigger \loaded
+ this.load(() => this.trigger('loaded'));
+ });
- @on \unmount ~>
- @stream.off \post @on-stream-post
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ this.on('unmount', () => {
+ this.stream.off('post', this.onStreamPost);
+ this.stream.off('follow', this.onStreamFollow);
+ this.stream.off('unfollow', this.onStreamUnfollow);
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ document.removeEventListener('keydown', this.onDocumentKeydown);
+ window.removeEventListener('scroll', this.onScroll);
+ });
- @on-document-keydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 84 # t
- @refs.timeline.focus!
+ this.onDocumentKeydown = e => {
+ if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
+ if (e.which == 84) { // t
+ this.refs.timeline.focus();
+ }
+ }
+ };
- @load = (cb) ~>
- @api \posts/timeline
- .then (posts) ~>
- @is-loading = false
- @is-empty = posts.length == 0
- @update!
- @refs.timeline.set-posts posts
- if cb? then cb!
- .catch (err) ~>
- console.error err
- if cb? then cb!
+ this.load = (cb) => {
+ this.api('posts/timeline').then(posts => {
+ this.update({
+ isLoading: false,
+ isEmpty: posts.length == 0
+ });
+ this.refs.timeline.setPosts(posts);
+ if (cb) cb();
+ });
+ };
- @more = ~>
- if @more-loading or @is-loading or @refs.timeline.posts.length == 0
- return
- @more-loading = true
- @update!
- @api \posts/timeline do
- max_id: @refs.timeline.tail!.id
- .then (posts) ~>
- @more-loading = false
- @update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
+ this.more = () => {
+ if (this.moreLoading || this.isLoading || this.refs.timeline.posts.length == 0) return;
+ this.update({
+ moreLoading: true
+ });
+ this.api('posts/timeline', {
+ max_id: this.refs.timeline.tail().id
+ }).then(posts => {
+ this.update({
+ moreLoading: false
+ });
+ this.refs.timeline.prependPosts(posts);
+ });
+ };
- @on-stream-post = (post) ~>
- @is-empty = false
- @update!
- @refs.timeline.add-post post
+ this.onStreamPost = post => {
+ this.update({
+ isEmpty: false
+ });
+ this.refs.timeline.addPost(post);
+ };
- @on-stream-follow = ~>
- @load!
+ this.onStreamFollow = () => {
+ this.load();
+ };
- @on-stream-unfollow = ~>
- @load!
+ this.onStreamUnfollow = () => {
+ this.load();
+ };
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 8
- @more!
+ this.onScroll = () => {
+ const current = window.scrollY + window.innerHeight;
+ if (current > document.body.offsetHeight - 8) this.more();
+ };
</script>
</mk-timeline-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 2552c266d7..27268f3ed3 100644
--- a/src/web/app/desktop/tags/home-widgets/tips.tag
+++ b/src/web/app/desktop/tags/home-widgets/tips.tag
@@ -29,43 +29,46 @@
</style>
<script>
- @tips = [
- '<kbd>t</kbd>でタイムラインにフォーカスできます'
- '<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます'
- '投稿フォームにはファイルをドラッグ&ドロップできます'
- '投稿フォームにクリップボードにある画像データをペーストできます'
- 'ドライブにファイルをドラッグ&ドロップしてアップロードできます'
- 'ドライブでファイルをドラッグしてフォルダ移動できます'
- 'ドライブでフォルダをドラッグしてフォルダ移動できます'
- 'ホームをカスタマイズできます(準備中)'
+ this.tips = [
+ '<kbd>t</kbd>でタイムラインにフォーカスできます',
+ '<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます',
+ '投稿フォームにはファイルをドラッグ&ドロップできます',
+ '投稿フォームにクリップボードにある画像データをペーストできます',
+ 'ドライブにファイルをドラッグ&ドロップしてアップロードできます',
+ 'ドライブでファイルをドラッグしてフォルダ移動できます',
+ 'ドライブでフォルダをドラッグしてフォルダ移動できます',
+ 'ホームをカスタマイズできます(準備中)',
'MisskeyはMIT Licenseです'
]
- @on \mount ~>
- @set!
- @clock = set-interval @change, 20000ms
+ this.on('mount', () => {
+ this.set();
+ this.clock = setInterval(this.change, 20000);
+ });
- @on \unmount ~>
- clear-interval @clock
+ this.on('unmount', () => {
+ clearInterval(this.clock);
+ });
- @set = ~>
- @refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
- @update!
+ this.set = () => {
+ this.refs.text.innerHTML = this.tips[Math.floor(Math.random() * this.tips.length)];
+ };
- @change = ~>
- Velocity @refs.tip, {
+ this.change = () => {
+ Velocity(this.refs.tip, {
opacity: 0
- } {
- duration: 500ms
- easing: \linear
- complete: @set
- }
+ }, {
+ duration: 500,
+ easing: 'linear',
+ complete: this.set
+ });
- Velocity @refs.tip, {
+ Velocity(this.refs.tip, {
opacity: 1
- } {
- duration: 500ms
- easing: \linear
- }
+ }, {
+ duration: 500,
+ easing: 'linear'
+ });
+ };
</script>
</mk-tips-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
index 8e94090dc9..517d206a4d 100644
--- a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
+++ b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
@@ -109,44 +109,42 @@
</style>
<script>
- @mixin \api
- @mixin \user-preview
+ this.mixin('api');
+ this.mixin('user-preview');
- @users = null
- @loading = true
+ this.users = null;
+ this.loading = true;
- @limit = 3users
- @page = 0
+ this.limit = 3;
+ this.page = 0;
- @on \mount ~>
- @fetch!
- @clock = set-interval ~>
- if @users.length < @limit
- @fetch true
- , 60000ms
+ this.on('mount', () => {
+ this.fetch();
+ });
- @on \unmount ~>
- clear-interval @clock
+ this.fetch = () => {
+ this.update({
+ loading: true,
+ users: null
+ });
+ this.api('users/recommendation', {
+ limit: this.limit,
+ offset: this.limit * this.page
+ }).then(users => {
+ this.update({
+ loading: false,
+ users: users
+ });
+ });
+ };
- @fetch = (quiet = false) ~>
- @loading = true
- @users = null
- if not quiet then @update!
- @api \users/recommendation do
- limit: @limit
- offset: @limit * @page
- .then (users) ~>
- @loading = false
- @users = users
- @update!
- .catch (err, text-status) ->
- console.error err
-
- @refresh = ~>
- if @users.length < @limit
- @page = 0
- else
- @page++
- @fetch!
+ this.refresh = () => {
+ if (this.users.length < this.limit) {
+ this.page = 0;
+ } else {
+ this.page++;
+ }
+ this.fetch();
+ };
</script>
</mk-user-recommendation-home-widget>
diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag
index b2ba4e2806..7a148d123c 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -58,33 +58,40 @@
</style>
<script>
- @mixin \i
- @mode = @opts.mode || \timeline
+ this.mixin('i');
- # https://github.com/riot/riot/issues/2080
- if @mode == '' then @mode = \timeline
+ this.mode = this.opts.mode || 'timeline';
+ // https://github.com/riot/riot/issues/2080
+ if (this.mode == '') this.mode = 'timeline';
- @home = []
+ this.home = [];
- @on \mount ~>
- @refs.tl.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.tl.on('loaded', () => {
+ this.trigger('loaded');
+ });
- @I.data.home.for-each (widget) ~>
- try
- el = document.create-element \mk- + widget.name + \-home-widget
- switch widget.place
- | \left => @refs.left.append-child el
- | \right => @refs.right.append-child el
- @home.push (riot.mount el, do
- id: widget.id
+ this.I.data.home.forEach(widget => {
+ try {
+ const el = document.createElement(`mk-${widget.name}-home-widget`);
+ switch (widget.place) {
+ case 'left': this.refs.left.appendChild(el); break;
+ case 'right': this.refs.right.appendChild(el); break;
+ }
+ this.home.push(riot.mount(el, {
+ id: widget.id,
data: widget.data
- .0)
- catch e
- # noop
+ })[0]);
+ } catch (e) {
+ // noop
+ }
+ });
+ });
- @on \unmount ~>
- @home.for-each (widget) ~>
- widget.unmount!
+ this.on('unmount', () => {
+ this.home.forEach(widget => {
+ widget.unmount();
+ });
+ });
</script>
</mk-home>
diff --git a/src/web/app/desktop/tags/image-dialog.tag b/src/web/app/desktop/tags/image-dialog.tag
index d7660bb953..91245dac95 100644
--- a/src/web/app/desktop/tags/image-dialog.tag
+++ b/src/web/app/desktop/tags/image-dialog.tag
@@ -35,41 +35,26 @@
</style>
<script>
- @image = @opts.image
+ this.image = this.opts.image;
- @on \mount ~>
- Velocity @root, {
+ this.on('mount', () => {
+ Velocity(this.root, {
opacity: 1
- } {
- duration: 100ms
- easing: \linear
- }
+ }, {
+ duration: 100,
+ easing: 'linear'
+ });
+ });
- #Velocity @img, {
- # scale: 1
- # opacity: 1
- #} {
- # duration: 200ms
- # easing: \ease-out
- #}
-
- @close = ~>
- Velocity @root, {
+ this.close = () => {
+ Velocity(this.root, {
opacity: 0
- } {
- duration: 100ms
- easing: \linear
- complete: ~> @unmount!
- }
+ }, {
+ duration: 100,
+ easing: 'linear',
+ complete: () => this.unmount()
+ });
+ };
- #Velocity @img, {
- # scale: 0.9
- # opacity: 0
- #} {
- # duration: 200ms
- # easing: \ease-in
- # complete: ~>
- # @unmount!
- #}
</script>
</mk-image-dialog>
diff --git a/src/web/app/desktop/tags/images-viewer.tag b/src/web/app/desktop/tags/images-viewer.tag
index 017395e7b4..83bce7bf4e 100644
--- a/src/web/app/desktop/tags/images-viewer.tag
+++ b/src/web/app/desktop/tags/images-viewer.tag
@@ -26,20 +26,22 @@
</style>
<script>
- @images = @opts.images
- @image = @images.0
+ this.images = this.opts.images;
+ this.image = this.images[0];
- @mousemove = (e) ~>
- rect = @refs.view.get-bounding-client-rect!
- mouse-x = e.client-x - rect.left
- mouse-y = e.client-y - rect.top
- xp = mouse-x / @refs.view.offset-width * 100
- yp = mouse-y / @refs.view.offset-height * 100
- @refs.view.style.background-position = xp + '% ' + yp + '%'
+ this.mousemove = e => {
+ const rect = this.refs.view.getBoundingClientRect();
+ const mouseX = e.clientX - rect.left;
+ const mouseY = e.clientY - rect.top;
+ const xp = mouseX / this.refs.view.offsetWidth * 100;
+ const yp = mouseY / this.refs.view.offsetHeight * 100;
+ this.refs.view.style.backgroundPosition = xp + '% ' + yp + '%';
+ };
- @click = ~>
- dialog = document.body.append-child document.create-element \mk-image-dialog
- riot.mount dialog, do
- image: @image
+ this.click = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-image-dialog')), {
+ image: this.image
+ });
+ };
</script>
</mk-images-viewer>
diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js
index ed100ef75c..6bbb774ee7 100644
--- a/src/web/app/desktop/tags/index.js
+++ b/src/web/app/desktop/tags/index.js
@@ -16,7 +16,6 @@ require('./crop-window.tag');
require('./settings.tag');
require('./settings-window.tag');
require('./analog-clock.tag');
-require('./go-top.tag');
require('./ui-header.tag');
require('./ui-header-account.tag');
require('./ui-header-notifications.tag');
@@ -42,7 +41,6 @@ require('./home-widgets/notifications.tag');
require('./home-widgets/rss-reader.tag');
require('./home-widgets/photo-stream.tag');
require('./home-widgets/broadcast.tag');
-require('./stream-indicator.tag');
require('./timeline.tag');
require('./messaging/window.tag');
require('./messaging/room-window.tag');
diff --git a/src/web/app/desktop/tags/input-dialog.tag b/src/web/app/desktop/tags/input-dialog.tag
index d9f4ae3f41..f343c4625a 100644
--- a/src/web/app/desktop/tags/input-dialog.tag
+++ b/src/web/app/desktop/tags/input-dialog.tag
@@ -1,13 +1,17 @@
<mk-input-dialog>
- <mk-window ref="window" is-modal={ true } width={ '500px' }><yield to="header"><i class="fa fa-i-cursor"></i>{ parent.title }</yield>
-<yield to="content">
- <div class="body">
- <input ref="text" oninput={ parent.update } onkeydown={ parent.onKeydown } placeholder={ parent.placeholder }/>
- </div>
- <div class="action">
- <button class="cancel" onclick={ parent.cancel }>キャンセル</button>
- <button class="ok" disabled={ !parent.allowEmpty && refs.text.value.length == 0 } onclick={ parent.ok }>決定</button>
- </div></yield>
+ <mk-window ref="window" is-modal={ true } width={ '500px' }>
+ <yield to="header">
+ <i class="fa fa-i-cursor"></i>{ parent.title }
+ </yield>
+ <yield to="content">
+ <div class="body">
+ <input ref="text" oninput={ parent.update } onkeydown={ parent.onKeydown } placeholder={ parent.placeholder }/>
+ </div>
+ <div class="action">
+ <button class="cancel" onclick={ parent.cancel }>キャンセル</button>
+ <button class="ok" disabled={ !parent.allowEmpty && refs.text.value.length == 0 } onclick={ parent.ok }>決定</button>
+ </div>
+ </yield>
</mk-window>
<style>
:scope
@@ -116,42 +120,48 @@
</style>
<script>
- @done = false
+ this.done = false;
- @title = @opts.title
- @placeholder = @opts.placeholder
- @default = @opts.default
- @allow-empty = if @opts.allow-empty? then @opts.allow-empty else true
+ this.title = this.opts.title;
+ this.placeholder = this.opts.placeholder;
+ this.default = this.opts.default;
+ this.allowEmpty = this.opts.allowEmpty != null ? this.opts.allowEmpty : true;
- @on \mount ~>
- @text = @refs.window.refs.text
- if @default?
- @text.value = @default
- @text.focus!
+ this.on('mount', () => {
+ this.text = this.refs.window.refs.text;
+ if (this.default) this.text.value = this.default;
+ this.text.focus();
- @refs.window.on \closing ~>
- if @done
- @opts.on-ok @text.value
- else
- if @opts.on-cancel?
- @opts.on-cancel!
+ this.refs.window.on('closing', () => {
+ if (this.done) {
+ this.opts.onOk(this.text.value);
+ } else {
+ if (this.opts.onCancel) this.opts.onCancel();
+ }
+ });
- @refs.window.on \closed ~>
- @unmount!
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
+ });
- @cancel = ~>
- @done = false
- @refs.window.close!
+ this.cancel = () => {
+ this.done = false;
+ this.refs.window.close();
+ };
- @ok = ~>
- if not @allow-empty and @text.value == '' then return
- @done = true
- @refs.window.close!
+ this.ok = () => {
+ if (!this.allowEmpty && this.text.value == '') return;
+ this.done = true;
+ this.refs.window.close();
+ };
- @on-keydown = (e) ~>
- if e.which == 13 # Enter
- e.prevent-default!
- e.stop-propagation!
- @ok!
+ this.onKeydown = e => {
+ if (e.which == 13) { // Enter
+ e.preventDefault();
+ e.stopPropagation();
+ this.ok();
+ }
+ };
</script>
</mk-input-dialog>
diff --git a/src/web/app/desktop/tags/list-user.tag b/src/web/app/desktop/tags/list-user.tag
index 03dda494aa..133efd2d1e 100644
--- a/src/web/app/desktop/tags/list-user.tag
+++ b/src/web/app/desktop/tags/list-user.tag
@@ -93,5 +93,5 @@
right 16px
</style>
- <script>@user = @opts.user</script>
+ <script>this.user = this.opts.user</script>
</mk-list-user>
diff --git a/src/web/app/desktop/tags/messaging/room-window.tag b/src/web/app/desktop/tags/messaging/room-window.tag
index a7eddb591e..e8a9ed6acd 100644
--- a/src/web/app/desktop/tags/messaging/room-window.tag
+++ b/src/web/app/desktop/tags/messaging/room-window.tag
@@ -19,10 +19,12 @@
</style>
<script>
- @user = @opts.user
+ this.user = this.opts.user;
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ this.on('mount', () => {
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
+ });
</script>
</mk-messaging-room-window>
diff --git a/src/web/app/desktop/tags/messaging/window.tag b/src/web/app/desktop/tags/messaging/window.tag
index f81fd6681b..c7af1dc2a2 100644
--- a/src/web/app/desktop/tags/messaging/window.tag
+++ b/src/web/app/desktop/tags/messaging/window.tag
@@ -19,13 +19,16 @@
</style>
<script>
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ this.on('mount', () => {
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
- @refs.window.refs.index.on \navigate-user (user) ~>
- w = document.body.append-child document.create-element \mk-messaging-room-window
- riot.mount w, do
+ this.refs.window.refs.index.on('navigate-user', user => {
+ riot.mount(document.body.appendChild(document.createElement('mk-messaging-room-window')), {
user: user
+ });
+ });
+ });
</script>
</mk-messaging-window>
diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag
index 58851786b6..7ba74412ea 100644
--- a/src/web/app/desktop/tags/notifications.tag
+++ b/src/web/app/desktop/tags/notifications.tag
@@ -177,37 +177,41 @@
</style>
<script>
- @mixin \api
- @mixin \stream
- @mixin \user-preview
- @mixin \get-post-summary
+ this.mixin('api');
+ this.mixin('stream');
+ this.mixin('user-preview');
+ this.mixin('get-post-summary');
- @notifications = []
- @loading = true
+ this.notifications = [];
+ this.loading = true;
- @on \mount ~>
- @api \i/notifications
- .then (notifications) ~>
- @notifications = notifications
- @loading = false
- @update!
- .catch (err, text-status) ->
- console.error err
+ this.on('mount', () => {
+ this.api('i/notifications').then(notifications => {
+ this.update({
+ loading: false,
+ notifications: notifications
+ });
+ });
- @stream.on \notification @on-notification
+ this.stream.on('notification', this.onNotification);
+ });
- @on \unmount ~>
- @stream.off \notification @on-notification
+ this.on('unmount', () => {
+ this.stream.off('notification', this.onNotification);
+ });
- @on-notification = (notification) ~>
- @notifications.unshift notification
- @update!
+ this.onNotification = notification => {
+ this.notifications.unshift(notification);
+ this.update();
+ };
- @on \update ~>
- @notifications.for-each (notification) ~>
- date = (new Date notification.created_at).get-date!
- month = (new Date notification.created_at).get-month! + 1
- notification._date = date
- notification._datetext = month + '月 ' + date + '日'
+ this.on('update', () => {
+ this.notifications.forEach(notification => {
+ const date = new Date(notification.created_at).getDate();
+ const month = new Date(notification.created_at).getMonth() + 1;
+ notification._date = date;
+ notification._datetext = `${month}月 ${date}日`;
+ });
+ });
</script>
</mk-notifications>
diff --git a/src/web/app/desktop/tags/pages/entrance.tag b/src/web/app/desktop/tags/pages/entrance.tag
index 57d11217cc..82ac8539ca 100644
--- a/src/web/app/desktop/tags/pages/entrance.tag
+++ b/src/web/app/desktop/tags/pages/entrance.tag
@@ -63,18 +63,24 @@
</style>
<script>
- @mode = \signin
+ this.mode = 'signin';
- @signup = ~>
- @mode = \signup
- @update!
+ this.signup = () => {
+ this.update({
+ mode: 'signup'
+ });
+ };
- @signin = ~>
- @mode = \signin
- @update!
+ this.signin = () => {
+ this.update({
+ mode: 'signin'
+ });
+ };
- @introduction = ~>
- @mode = \introduction
- @update!
+ this.introduction = () => {
+ this.update({
+ mode: 'introduction'
+ });
+ };
</script>
</mk-entrance>
diff --git a/src/web/app/desktop/tags/pages/entrance/signin.tag b/src/web/app/desktop/tags/pages/entrance/signin.tag
index 1a5baac67e..bd4b47c7df 100644
--- a/src/web/app/desktop/tags/pages/entrance/signin.tag
+++ b/src/web/app/desktop/tags/pages/entrance/signin.tag
@@ -119,12 +119,16 @@
</style>
<script>
- @on \mount ~>
- @refs.signin.on \user (user) ~>
- @update do
+ this.on('mount', () => {
+ this.refs.signin.on('user', user => {
+ this.update({
user: user
+ });
+ });
+ });
- @introduction = ~>
- @parent.introduction!
+ this.introduction = () => {
+ this.parent.introduction();
+ };
</script>
</mk-entrance-signin>
diff --git a/src/web/app/desktop/tags/pages/entrance/signup.tag b/src/web/app/desktop/tags/pages/entrance/signup.tag
index 1a777fe965..7ab53759c9 100644
--- a/src/web/app/desktop/tags/pages/entrance/signup.tag
+++ b/src/web/app/desktop/tags/pages/entrance/signup.tag
@@ -43,9 +43,5 @@
> i
padding 14px
-
-
-
-
</style>
</mk-entrance-signup>
diff --git a/src/web/app/desktop/tags/pages/home.tag b/src/web/app/desktop/tags/pages/home.tag
index 51e5767704..e988cbc76e 100644
--- a/src/web/app/desktop/tags/pages/home.tag
+++ b/src/web/app/desktop/tags/pages/home.tag
@@ -5,43 +5,45 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \i
- @mixin \api
- @mixin \ui-progress
- @mixin \stream
- @mixin \get-post-summary
-
- @unread-count = 0
+ this.mixin('i');
+ this.mixin('api');
+ this.mixin('ui-progress');
+ this.mixin('stream');
+ this.mixin('get-post-summary');
- @page = switch @opts.mode
- | \timelie => \home
- | \mentions => \mentions
- | _ => \home
+ this.unreadCount = 0;
- @on \mount ~>
- @refs.ui.refs.home.on \loaded ~>
- @Progress.done!
+ this.page = this.opts.mode || 'timeline';
- document.title = 'Misskey'
- @Progress.start!
- @stream.on \post @on-stream-post
- document.add-event-listener \visibilitychange @window-on-visibilitychange, false
+ this.on('mount', () => {
+ this.refs.ui.refs.home.on('loaded', () => {
+ this.Progress.done();
+ });
+ document.title = 'Misskey';
+ this.Progress.start();
+ this.stream.on('post', this.onStreamPost);
+ document.addEventListener('visibilitychange', this.windowOnVisibilitychange, false);
+ });
- @on \unmount ~>
- @stream.off \post @on-stream-post
- document.remove-event-listener \visibilitychange @window-on-visibilitychange
+ this.on('unmount', () => {
+ this.stream.off('post', this.onStreamPost);
+ document.removeEventListener('visibilitychange', this.windowOnVisibilitychange);
+ });
- @on-stream-post = (post) ~>
- if document.hidden and post.user_id !== @I.id
- @unread-count++
- document.title = '(' + @unread-count + ') ' + @get-post-summary post
+ this.onStreamPost = post => {
+ if (document.hidden && post.user_id != this.I.id) {
+ this.unreadCount++;
+ document.title = `(${this.unreadCount}) ${this.getPostSummary(post)}`;
+ }
+ };
- @window-on-visibilitychange = ~>
- if !document.hidden
- @unread-count = 0
- document.title = 'Misskey'
+ this.windowOnVisibilitychange = () => {
+ if (!document.hidden) {
+ this.unreadCount = 0;
+ document.title = 'Misskey';
+ }
+ };
</script>
</mk-home-page>
diff --git a/src/web/app/desktop/tags/pages/not-found.tag b/src/web/app/desktop/tags/pages/not-found.tag
index a7cbad0b82..e62ea11008 100644
--- a/src/web/app/desktop/tags/pages/not-found.tag
+++ b/src/web/app/desktop/tags/pages/not-found.tag
@@ -1,54 +1,11 @@
<mk-not-found>
<mk-ui>
<main>
- <h1>Not Found</h1><img src="/_/resources/rogge.jpg" alt=""/>
- <div class="mask"></div>
+ <h1>Not Found</h1>
</main>
</mk-ui>
<style>
:scope
display block
-
- main
- display block
- width 600px
- margin 32px auto
-
- > img
- display block
- width 600px
- height 459px
- pointer-events none
- user-select none
- border-radius 16px
- box-shadow 0 0 16px rgba(0, 0, 0, 0.1)
-
- > h1
- display block
- margin 0
- padding 0
- position absolute
- top 260px
- left 225px
- transform rotate(-12deg)
- z-index 2
- color #444
- font-size 24px
- line-height 20px
-
- > .mask
- position absolute
- top 262px
- left 217px
- width 126px
- height 18px
- transform rotate(-12deg)
- background #D6D5DA
- border-radius 2px 6px 7px 6px
-
-
-
-
-
</style>
</mk-not-found>
diff --git a/src/web/app/desktop/tags/pages/post.tag b/src/web/app/desktop/tags/pages/post.tag
index fddc21deab..b04ba69dc5 100644
--- a/src/web/app/desktop/tags/pages/post.tag
+++ b/src/web/app/desktop/tags/pages/post.tag
@@ -16,17 +16,20 @@
</style>
<script>
- @mixin \ui-progress
+ this.mixin('ui-progress');
- @post = @opts.post
+ this.post = this.opts.post;
- @on \mount ~>
- @Progress.start!
+ this.on('mount', () => {
+ this.Progress.start();
- @refs.ui.refs.detail.on \post-fetched ~>
- @Progress.set 0.5
+ this.refs.ui.refs.detail.on('post-fetched', () => {
+ this.Progress.set(0.5);
+ });
- @refs.ui.refs.detail.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.detail.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
</script>
</mk-post-page>
diff --git a/src/web/app/desktop/tags/pages/search.tag b/src/web/app/desktop/tags/pages/search.tag
index 0c5a23c795..ace9e27ab9 100644
--- a/src/web/app/desktop/tags/pages/search.tag
+++ b/src/web/app/desktop/tags/pages/search.tag
@@ -5,15 +5,16 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \ui-progress
+ this.mixin('ui-progress');
- @on \mount ~>
- @Progress.start!
+ this.on('mount', () => {
+ this.Progress.start();
- @refs.ui.refs.search.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.search.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
</script>
</mk-search-page>
diff --git a/src/web/app/desktop/tags/pages/user.tag b/src/web/app/desktop/tags/pages/user.tag
index be0501e045..767af31e9a 100644
--- a/src/web/app/desktop/tags/pages/user.tag
+++ b/src/web/app/desktop/tags/pages/user.tag
@@ -5,21 +5,23 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \ui-progress
+ this.mixin('ui-progress');
- @user = @opts.user
+ this.user = this.opts.user;
- @on \mount ~>
- @Progress.start!
+ this.on('mount', () => {
+ this.Progress.start();
- @refs.ui.refs.user.on \user-fetched (user) ~>
- @Progress.set 0.5
+ this.refs.ui.refs.user.on('user-fetched', user => {
+ this.Progress.set(0.5);
document.title = user.name + ' | Misskey'
+ });
- @refs.ui.refs.user.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.user.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
</script>
</mk-user-page>
diff --git a/src/web/app/desktop/tags/post-detail-sub.tag b/src/web/app/desktop/tags/post-detail-sub.tag
index c4a651e371..f1b3c915cb 100644
--- a/src/web/app/desktop/tags/post-detail-sub.tag
+++ b/src/web/app/desktop/tags/post-detail-sub.tag
@@ -103,38 +103,45 @@
</style>
<script>
- @mixin \api
- @mixin \text
- @mixin \date-stringify
- @mixin \user-preview
+ this.mixin('api');
+ this.mixin('text');
+ this.mixin('date-stringify');
+ this.mixin('user-preview');
- @post = @opts.post
+ this.post = this.opts.post;
- @url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
+ this.url = CONFIG.url + '/' + this.post.user.username + '/' + this.post.id;
- @title = @date-stringify @post.created_at
+ this.title = this.dateStringify(this.post.created_at);
- @on \mount ~>
- if @post.text?
- tokens = @analyze @post.text
- @refs.text.innerHTML = @compile tokens
+ this.on('mount', () => {
+ if (this.p.text) {
+ const tokens = this.analyze(this.p.text);
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ this.refs.text.innerHTML = this.refs.text.innerHTML.replace('<p class="dummy"></p>', this.compile(tokens));
- @like = ~>
- if @post.is_liked
- @api \posts/likes/delete do
- post_id: @post.id
- .then ~>
- @post.is_liked = false
- @update!
- else
- @api \posts/likes/create do
- post_id: @post.id
- .then ~>
- @post.is_liked = true
- @update!
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
+ }
+ });
+
+ this.like = () => {
+ if (this.post.is_liked) {
+ this.api('posts/likes/delete', {
+ post_id: this.post.id
+ }).then(() => {
+ this.post.is_liked = false;
+ this.update();
+ });
+ } else {
+ this.api('posts/likes/create', {
+ post_id: this.post.id
+ }).then(() => {
+ this.post.is_liked = true;
+ this.update();
+ });
+ }
+ };
</script>
</mk-post-detail-sub>
diff --git a/src/web/app/desktop/tags/post-detail.tag b/src/web/app/desktop/tags/post-detail.tag
index 3c99babaaa..cc5fbeed88 100644
--- a/src/web/app/desktop/tags/post-detail.tag
+++ b/src/web/app/desktop/tags/post-detail.tag
@@ -329,108 +329,126 @@
</style>
<script>
- @mixin \api
- @mixin \text
- @mixin \user-preview
- @mixin \date-stringify
- @mixin \NotImplementedException
+ this.mixin('api');
+ this.mixin('text');
+ this.mixin('user-preview');
+ this.mixin('date-stringify');
+ this.mixin('NotImplementedException');
- @fetching = true
- @loading-context = false
- @content = null
- @post = null
+ this.fetching = true;
+ this.loadingContext = false;
+ this.content = null;
+ this.post = null;
- @on \mount ~>
+ this.on('mount', () => {
+ this.api('posts/show', {
+ post_id: this.opts.post
+ }).then(post => {
+ const isRepost = post.repost != null;
+ const p = isRepost ? post.repost : post;
+ this.update({
+ fetching: false,
+ post: post,
+ isRepost: isRepost,
+ p: p,
+ title: this.dateStringify(p.created_at)
+ });
- @api \posts/show do
- post_id: @opts.post
- .then (post) ~>
- @fetching = false
- @post = post
- @trigger \loaded
+ this.trigger('loaded');
- @is-repost = @post.repost?
- @p = if @is-repost then @post.repost else @post
+ if (this.p.text) {
+ const tokens = this.analyze(this.p.text);
- @title = @date-stringify @p.created_at
+ this.refs.text.innerHTML = this.compile(tokens);
- @update!
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
- if @p.text?
- tokens = @analyze @p.text
- @refs.text.innerHTML = @compile tokens
-
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
-
- # URLをプレビュー
+ // URLをプレビュー
tokens
- .filter (t) -> t.type == \link
- .map (t) ~>
- @preview = @refs.text.append-child document.create-element \mk-url-preview
- riot.mount @preview, do
- url: t.content
+ .filter(t => t.type == 'link')
+ .map(t => {
+ riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
+ url: t.content
+ });
+ });
+ }
- # Get likes
- @api \posts/likes do
- post_id: @p.id
+ // Get likes
+ this.api('posts/likes', {
+ post_id: this.p.id,
limit: 8
- .then (likes) ~>
- @likes = likes
- @update!
+ }).then(likes => {
+ this.update({
+ likes: likes
+ });
+ });
- # Get reposts
- @api \posts/reposts do
- post_id: @p.id
+ // Get reposts
+ this.api('posts/reposts', {
+ post_id: this.p.id,
limit: 8
- .then (reposts) ~>
- @reposts = reposts
- @update!
+ }).then(reposts => {
+ this.update({
+ reposts: reposts
+ });
+ });
- # Get replies
- @api \posts/replies do
- post_id: @p.id
+ // Get replies
+ this.api('posts/replies', {
+ post_id: this.p.id,
limit: 8
- .then (replies) ~>
- @replies = replies
- @update!
-
- @update!
+ }).then(replies => {
+ this.update({
+ replies: replies
+ });
+ });
+ });
+ });
- @reply = ~>
- form = document.body.append-child document.create-element \mk-post-form-window
- riot.mount form, do
- reply: @p
+ this.reply = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
+ reply: this.p
+ });
+ };
- @repost = ~>
- form = document.body.append-child document.create-element \mk-repost-form-window
- riot.mount form, do
- post: @p
+ this.repost = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-repost-form-window')), {
+ post: this.p
+ });
+ };
- @like = ~>
- if @p.is_liked
- @api \posts/likes/delete do
- post_id: @p.id
- .then ~>
- @p.is_liked = false
- @update!
- else
- @api \posts/likes/create do
- post_id: @p.id
- .then ~>
- @p.is_liked = true
- @update!
+ this.like = () => {
+ if (this.p.is_liked) {
+ this.api('posts/likes/delete', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = false;
+ this.update();
+ });
+ } else {
+ this.api('posts/likes/create', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = true;
+ this.update();
+ });
+ }
+ };
- @load-context = ~>
- @loading-context = true
+ this.loadContext = () => {
+ this.loadingContext = true;
- # Get context
- @api \posts/context do
- post_id: @p.reply_to_id
- .then (context) ~>
- @context = context.reverse!
- @loading-context = false
- @update!
+ // Fetch context
+ this.api('posts/context', {
+ post_id: this.p.reply_to_id
+ }).then(context => {
+ this.update({
+ loadContext: false,
+ content: context.reverse()
+ });
+ });
+ };
</script>
</mk-post-detail>
diff --git a/src/web/app/desktop/tags/post-form-window.tag b/src/web/app/desktop/tags/post-form-window.tag
index fc1a254e20..4f2ea25389 100644
--- a/src/web/app/desktop/tags/post-form-window.tag
+++ b/src/web/app/desktop/tags/post-form-window.tag
@@ -32,24 +32,31 @@
</style>
<script>
- @uploading-files = []
- @files = []
+ this.uploadingFiles = [];
+ this.files = [];
- @on \mount ~>
- @refs.window.refs.form.focus!
+ this.on('mount', () => {
+ this.refs.window.refs.form.focus();
- @refs.window.on \closed ~>
- @unmount!
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
- @refs.window.refs.form.on \post ~>
- @refs.window.close!
+ this.refs.window.refs.form.on('post', () => {
+ this.refs.window.close();
+ });
- @refs.window.refs.form.on \change-uploading-files (files) ~>
- @uploading-files = files
- @update!
+ this.refs.window.refs.form.on('change-uploading-files', files => {
+ this.update({
+ uploadingFiles: files
+ });
+ });
- @refs.window.refs.form.on \change-files (files) ~>
- @files = files
- @update!
+ this.refs.window.refs.form.on('change-files', files => {
+ this.update({
+ files: files
+ });
+ });
+ });
</script>
</mk-post-form-window>
diff --git a/src/web/app/desktop/tags/post-form.tag b/src/web/app/desktop/tags/post-form.tag
index a0b6ea7d07..3b80eee5d5 100644
--- a/src/web/app/desktop/tags/post-form.tag
+++ b/src/web/app/desktop/tags/post-form.tag
@@ -305,161 +305,160 @@
</style>
<script>
- get-cat = require '../../common/scripts/get-cat'
+ const getCat = require('../../common/scripts/get-cat');
- @mixin \api
- @mixin \notify
- @mixin \autocomplete
+ this.mixin('api');
+ this.mixin('notify');
+ this.mixin('autocomplete');
- @wait = false
- @uploadings = []
- @files = []
- @autocomplete = null
- @poll = false
+ this.wait = false;
+ this.uploadings = [];
+ this.files = [];
+ this.autocomplete = null;
+ this.poll = false;
- @in-reply-to-post = @opts.reply
+ this.inReplyToPost = this.opts.reply;
- # https://github.com/riot/riot/issues/2080
- if @in-reply-to-post == '' then @in-reply-to-post = null
+ // https://github.com/riot/riot/issues/2080
+ if (this.inReplyToPost == '') this.inReplyToPost = null;
- @on \mount ~>
- @refs.uploader.on \uploaded (file) ~>
- @add-file file
+ this.on('mount', () => {
+ this.refs.uploader.on('uploaded', file => {
+ this.addFile(file);
+ });
- @refs.uploader.on \change-uploads (uploads) ~>
- @trigger \change-uploading-files uploads
+ this.refs.uploader.on('change-uploads', uploads => {
+ this.trigger('change-uploading-files', uploads);
+ });
- @autocomplete = new @Autocomplete @refs.text
- @autocomplete.attach!
+ this.autocomplete = new this.Autocomplete(this.refs.text);
+ this.autocomplete.attach();
+ });
- @on \unmount ~>
- @autocomplete.detach!
+ this.on('unmount', () => {
+ this.autocomplete.detach();
+ });
- @focus = ~>
- @refs.text.focus!
+ this.focus = () => {
+ this.refs.text.focus();
+ };
- @clear = ~>
- @refs.text.value = ''
- @files = []
- @trigger \change-files
- @update!
+ this.clear = () => {
+ this.refs.text.value = '';
+ this.files = [];
+ this.trigger('change-files');
+ this.update();
+ };
- @ondragover = (e) ~>
- e.stop-propagation!
- @draghover = true
- # ドラッグされてきたものがファイルだったら
- if e.data-transfer.effect-allowed == \all
- e.data-transfer.drop-effect = \copy
- else
- e.data-transfer.drop-effect = \move
- return false
+ this.ondragover = e => {
+ e.stopPropagation();
+ this.draghover = true;
+ e.dataTransfer.dropEffect = e.dataTransfer.effectAllowed == 'all' ? 'copy' : 'move';
+ return false;
+ };
- @ondragenter = (e) ~>
- @draghover = true
+ this.ondragenter = e => {
+ this.draghover = true;
+ };
- @ondragleave = (e) ~>
- @draghover = false
+ this.ondragleave = e => {
+ this.draghover = false;
+ };
- @ondrop = (e) ~>
- e.prevent-default!
- e.stop-propagation!
- @draghover = false
+ this.ondrop = e => {
+ e.preventDefault();
+ e.stopPropagation();
+ this.draghover = false;
- # ファイルだったら
- if e.data-transfer.files.length > 0
- Array.prototype.for-each.call e.data-transfer.files, (file) ~>
- @upload file
- return false
+ // ファイルだったら
+ if (e.dataTransfer.files.length > 0) {
+ e.dataTransfer.files.forEach(this.upload);
+ }
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
- return false
+ return false;
+ };
- try
- # パース
- obj = JSON.parse data
+ this.onkeydown = e => {
+ if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey)) this.post();
+ };
- # (ドライブの)ファイルだったら
- if obj.type == \file
- @add-file obj.file
- catch
- # ignore
+ this.onpaste = e => {
+ e.clipboardData.items.forEach(item => {
+ if (item.kind == 'file') {
+ this.upload(item.getAsFile());
+ }
+ });
+ };
- return false
+ this.selectFile = () => {
+ this.refs.file.click();
+ };
- @onkeydown = (e) ~>
- if (e.which == 10 || e.which == 13) && (e.ctrl-key || e.meta-key)
- @post!
-
- @onpaste = (e) ~>
- data = e.clipboard-data
- items = data.items
- for i from 0 to items.length - 1
- item = items[i]
- switch (item.kind)
- | \file =>
- @upload item.get-as-file!
-
- @select-file = ~>
- @refs.file.click!
-
- @select-file-from-drive = ~>
- browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
- i = riot.mount browser, do
+ this.selectFileFromDrive = () => {
+ const i = riot.mount(document.body.appendChild(document.createElement('mk-select-file-from-drive-window')), {
multiple: true
- i[0].one \selected (files) ~>
- files.for-each @add-file
+ })[0];
+ i.one('selected', files => {
+ files.forEach(this.addFile);
+ });
+ };
- @change-file = ~>
- files = @refs.file.files
- for i from 0 to files.length - 1
- file = files.item i
- @upload file
+ this.changeFile = () => {
+ this.refs.file.files.forEach(this.upload);
+ };
- @upload = (file) ~>
- @refs.uploader.upload file
+ this.upload = file => {
+ this.refs.uploader.upload(file);
+ };
- @add-file = (file) ~>
- file._remove = ~>
- @files = @files.filter (x) -> x.id != file.id
- @trigger \change-files @files
- @update!
+ this.addFile = file => {
+ file._remove = () => {
+ this.files = this.files.filter(x => x.id != file.id);
+ this.trigger('change-files', this.files);
+ this.update();
+ };
- @files.push file
- @trigger \change-files @files
- @update!
+ this.files.push(file);
+ this.trigger('change-files', this.files);
+ this.update();
+ };
- @add-poll = ~>
- @poll = true
+ this.addPoll = () => {
+ this.poll = true;
+ };
- @on-poll-destroyed = ~>
- @update do
+ this.onPollDestroyed = () => {
+ this.update({
poll: false
+ });
+ };
- @post = (e) ~>
- @wait = true
+ this.post = e => {
+ this.wait = true;
- files = if @files? and @files.length > 0
- then @files.map (f) -> f.id
- else undefined
+ const files = this.files && this.files.length > 0
+ ? this.files.map(f => f.id)
+ : undefined;
- @api \posts/create do
- text: @refs.text.value
- media_ids: files
- reply_to_id: if @in-reply-to-post? then @in-reply-to-post.id else undefined
- poll: if @poll then @refs.poll.get! else undefined
- .then (data) ~>
- @trigger \post
- @notify if @in-reply-to-post? then '返信しました!' else '投稿しました!'
- .catch (err) ~>
- console.error err
- @notify '投稿できませんでした'
- .then ~>
- @wait = false
- @update!
+ this.api('posts/create', {
+ text: this.refs.text.value,
+ media_ids: files,
+ reply_to_id: this.inReplyToPost ? this.inReplyToPost.id : undefined,
+ poll: this.poll ? this.refs.poll.get() : undefined
+ }).then(data => {
+ this.trigger('post');
+ this.notify(this.inReplyToPost ? '返信しました!' : '投稿しました!');
+ }).catch(err => {
+ this.notify('投稿できませんでした');
+ }).then(() => {
+ this.update({
+ wait: false
+ });
+ });
+ };
- @cat = ~>
- @refs.text.value = @refs.text.value + get-cat!
+ this.cat = () => {
+ this.refs.text.value += getCat();
+ };
</script>
</mk-post-form>
diff --git a/src/web/app/desktop/tags/post-preview.tag b/src/web/app/desktop/tags/post-preview.tag
index c0514c323e..458a6f83f2 100644
--- a/src/web/app/desktop/tags/post-preview.tag
+++ b/src/web/app/desktop/tags/post-preview.tag
@@ -83,11 +83,11 @@
</style>
<script>
- @mixin \date-stringify
- @mixin \user-preview
+ this.mixin('date-stringify');
+ this.mixin('user-preview');
- @post = @opts.post
+ this.post = this.opts.post;
- @title = @date-stringify @post.created_at
+ this.title = this.dateStringify(this.post.created_at);
</script>
</mk-post-preview>
diff --git a/src/web/app/desktop/tags/progress-dialog.tag b/src/web/app/desktop/tags/progress-dialog.tag
index c60746257b..760f869f6e 100644
--- a/src/web/app/desktop/tags/progress-dialog.tag
+++ b/src/web/app/desktop/tags/progress-dialog.tag
@@ -75,20 +75,25 @@
</style>
<script>
- @title = @opts.title
- @value = parse-int @opts.value, 10
- @max = parse-int @opts.max, 10
+ this.title = this.opts.title;
+ this.value = parseInt(this.opts.value, 10);
+ this.max = parseInt(this.opts.max, 10);
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ this.on('mount', () => {
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
+ });
- @update-progress = (value, max) ~>
- @value = parse-int value, 10
- @max = parse-int max, 10
- @update!
+ this.updateProgress = (value, max) => {
+ this.update({
+ value: parseInt(value, 10),
+ max: parseInt(max, 10)
+ });
+ };
- @close = ~>
- @refs.window.close!
+ this.close = () => {
+ this.refs.window.close();
+ };
</script>
</mk-progress-dialog>
diff --git a/src/web/app/desktop/tags/repost-form-window.tag b/src/web/app/desktop/tags/repost-form-window.tag
index 45a0cdae6d..75fe9f4829 100644
--- a/src/web/app/desktop/tags/repost-form-window.tag
+++ b/src/web/app/desktop/tags/repost-form-window.tag
@@ -12,25 +12,32 @@
</style>
<script>
- @on-document-keydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 27 # Esc
- @refs.window.close!
+ this.onDocumentKeydown = e => {
+ if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
+ if (e.which == 27) { // Esc
+ this.refs.window.close();
+ }
+ }
+ };
- @on \mount ~>
- @refs.window.refs.form.on \cancel ~>
- @refs.window.close!
+ this.on('mount', () => {
+ this.refs.window.refs.form.on('cancel', () => {
+ this.refs.window.close();
+ });
- @refs.window.refs.form.on \posted ~>
- @refs.window.close!
+ this.refs.window.refs.form.on('posted', () => {
+ this.refs.window.close();
+ });
- document.add-event-listener \keydown @on-document-keydown
+ document.addEventListener('keydown', this.onDocumentKeydown);
- @refs.window.on \closed ~>
- @unmount!
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
+ });
- @on \unmount ~>
- document.remove-event-listener \keydown @on-document-keydown
+ this.on('unmount', () => {
+ document.removeEventListener('keydown', this.onDocumentKeydown);
+ });
</script>
</mk-repost-form-window>
diff --git a/src/web/app/desktop/tags/repost-form.tag b/src/web/app/desktop/tags/repost-form.tag
index 2c07ff4b16..e5101d9f2c 100644
--- a/src/web/app/desktop/tags/repost-form.tag
+++ b/src/web/app/desktop/tags/repost-form.tag
@@ -114,31 +114,35 @@
</style>
<script>
- @mixin \api
- @mixin \notify
+ this.mixin('api');
+ this.mixin('notify');
- @wait = false
- @quote = false
+ this.wait = false;
+ this.quote = false;
- @cancel = ~>
- @trigger \cancel
+ this.cancel = () => {
+ this.trigger('cancel');
+ };
- @ok = ~>
- @wait = true
- @api \posts/create do
- repost_id: @opts.post.id
- text: if @quote then @refs.text.value else undefined
- .then (data) ~>
- @trigger \posted
- @notify 'Repostしました!'
- .catch (err) ~>
- console.error err
- @notify 'Repostできませんでした'
- .then ~>
- @wait = false
- @update!
+ this.ok = () => {
+ this.wait = true;
+ this.api('posts/create', {
+ repost_id: this.opts.post.id,
+ text: this.quote ? this.refs.text.value : undefined
+ }).then(data => {
+ this.trigger('posted');
+ this.notify('Repostしました!');
+ }).catch(err => {
+ this.notify('Repostできませんでした');
+ }).then(() => {
+ this.update({
+ wait: false
+ });
+ });
+ };
- @onquote = ~>
- @quote = true
+ this.onquote = () => {
+ this.quote = true;
+ };
</script>
</mk-repost-form>
diff --git a/src/web/app/desktop/tags/search-posts.tag b/src/web/app/desktop/tags/search-posts.tag
index 2cc9b788ae..95ee33a5a4 100644
--- a/src/web/app/desktop/tags/search-posts.tag
+++ b/src/web/app/desktop/tags/search-posts.tag
@@ -28,59 +28,64 @@
</style>
<script>
- @mixin \api
- @mixin \get-post-summary
+ this.mixin('api');
+ this.mixin('get-post-summary');
- @query = @opts.query
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @page = 0
+ this.query = this.opts.query;
+ this.isLoading = true;
+ this.isEmpty = false;
+ this.moreLoading = false;
+ this.page = 0;
- @on \mount ~>
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ this.on('mount', () => {
+ document.addEventListener('keydown', this.onDocumentKeydown);
+ window.addEventListener('scroll', this.onScroll);
- @api \posts/search do
- query: @query
- .then (posts) ~>
- @is-loading = false
- @is-empty = posts.length == 0
- @update!
- @refs.timeline.set-posts posts
- @trigger \loaded
- .catch (err) ~>
- console.error err
+ this.api('posts/search', {
+ query: this.query
+ }).then(posts => {
+ this.update({
+ isLoading: false,
+ isEmpty: posts.length == 0
+ });
+ this.refs.timeline.setPosts(posts);
+ this.trigger('loaded');
+ });
+ });
- @on \unmount ~>
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ this.on('unmount', () => {
+ document.removeEventListener('keydown', this.onDocumentKeydown);
+ window.removeEventListener('scroll', this.onScroll);
+ });
- @on-document-keydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 84 # t
- @refs.timeline.focus!
+ this.onDocumentKeydown = e => {
+ if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
+ if (e.which == 84) { // t
+ this.refs.timeline.focus();
+ }
+ }
+ };
- @more = ~>
- if @more-loading or @is-loading or @timeline.posts.length == 0
- return
- @more-loading = true
- @update!
- @api \posts/search do
- query: @query
- page: @page + 1
- .then (posts) ~>
- @more-loading = false
- @page++
- @update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
+ this.more = () => {
+ if (this.moreLoading || this.isLoading || this.timeline.posts.length == 0) return;
+ this.update({
+ moreLoading: true
+ });
+ this.api('posts/search', {
+ query: this.query,
+ page: this.page + 1
+ }).then(posts => {
+ this.update({
+ moreLoading: false,
+ page: page + 1
+ });
+ this.refs.timeline.prependPosts(posts);
+ });
+ };
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 16 # 遊び
- @more!
+ this.onScroll = () => {
+ const current = window.scrollY + window.innerHeight;
+ if (current > document.body.offsetHeight - 16) this.more();
+ };
</script>
</mk-search-posts>
diff --git a/src/web/app/desktop/tags/search.tag b/src/web/app/desktop/tags/search.tag
index d2561dfdca..681b4c8aed 100644
--- a/src/web/app/desktop/tags/search.tag
+++ b/src/web/app/desktop/tags/search.tag
@@ -23,10 +23,12 @@
</style>
<script>
- @query = @opts.query
+ this.query = this.opts.query;
- @on \mount ~>
- @refs.posts.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.posts.on('loaded', () => {
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-search>
diff --git a/src/web/app/desktop/tags/select-file-from-drive-window.tag b/src/web/app/desktop/tags/select-file-from-drive-window.tag
index f9ba9e3cc0..777073583f 100644
--- a/src/web/app/desktop/tags/select-file-from-drive-window.tag
+++ b/src/web/app/desktop/tags/select-file-from-drive-window.tag
@@ -131,31 +131,38 @@
</style>
<script>
- @file = []
+ this.file = [];
- @multiple = if @opts.multiple? then @opts.multiple else false
- @title = @opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
+ this.multiple = this.opts.multiple != null ? this.opts.multiple : false;
+ this.title = this.opts.title || '<i class="fa fa-file-o"></i>ファイルを選択';
- @on \mount ~>
- @refs.window.refs.browser.on \selected (file) ~>
- @file = file
- @ok!
+ this.on('mount', () => {
+ this.refs.window.refs.browser.on('selected', file => {
+ this.file = file;
+ this.ok();
+ });
- @refs.window.refs.browser.on \change-selection (files) ~>
- @file = files
- @update!
+ this.refs.window.refs.browser.on('change-selection', files => {
+ this.file = files;
+ this.update();
+ });
- @refs.window.on \closed ~>
- @unmount!
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
+ });
- @close = ~>
- @refs.window.close!
+ this.close = () => {
+ this.refs.window.close();
+ };
- @upload = ~>
- @refs.window.refs.browser.select-local-file!
+ this.upload = () => {
+ this.refs.window.refs.browser.selectLocalFile();
+ };
- @ok = ~>
- @trigger \selected @file
- @refs.window.close!
+ this.ok = () => {
+ this.trigger('selected', this.file);
+ this.refs.window.close();
+ };
</script>
</mk-select-file-from-drive-window>
diff --git a/src/web/app/desktop/tags/set-avatar-suggestion.tag b/src/web/app/desktop/tags/set-avatar-suggestion.tag
index 22a0de0f3a..335148ea5d 100644
--- a/src/web/app/desktop/tags/set-avatar-suggestion.tag
+++ b/src/web/app/desktop/tags/set-avatar-suggestion.tag
@@ -31,15 +31,17 @@
</style>
<script>
- @mixin \i
- @mixin \update-avatar
+ this.mixin('i');
+ this.mixin('update-avatar');
- @set = ~>
- @update-avatar @I
+ this.set = () => {
+ this.updateAvatar(this.I);
+ };
- @close = (e) ~>
- e.prevent-default!
- e.stop-propagation!
- @unmount!
+ this.close = e => {
+ e.preventDefault();
+ e.stopPropagation();
+ this.unmount();
+ };
</script>
</mk-set-avatar-suggestion>
diff --git a/src/web/app/desktop/tags/set-banner-suggestion.tag b/src/web/app/desktop/tags/set-banner-suggestion.tag
index 3ccaab108d..deddc478cc 100644
--- a/src/web/app/desktop/tags/set-banner-suggestion.tag
+++ b/src/web/app/desktop/tags/set-banner-suggestion.tag
@@ -31,15 +31,17 @@
</style>
<script>
- @mixin \i
- @mixin \update-banner
+ this.mixin('i');
+ this.mixin('update-banner');
- @set = ~>
- @update-banner @I
+ this.set = () => {
+ this.updateBanner(this.I);
+ };
- @close = (e) ~>
- e.prevent-default!
- e.stop-propagation!
- @unmount!
+ this.close = e => {
+ e.preventDefault();
+ e.stopPropagation();
+ this.unmount();
+ };
</script>
</mk-set-banner-suggestion>
diff --git a/src/web/app/desktop/tags/settings-window.tag b/src/web/app/desktop/tags/settings-window.tag
index 10bb48de76..cb78921d42 100644
--- a/src/web/app/desktop/tags/settings-window.tag
+++ b/src/web/app/desktop/tags/settings-window.tag
@@ -15,11 +15,14 @@
</style>
<script>
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ this.on('mount', () => {
+ this.refs.window.on('closed', () => {
+ this.unmount();
+ });
+ });
- @close = ~>
- @refs.window.close!
+ this.close = () => {
+ this.refs.window.close();
+ };
</script>
</mk-settings-window>
diff --git a/src/web/app/desktop/tags/settings.tag b/src/web/app/desktop/tags/settings.tag
index 1c14514ac0..544e41c256 100644
--- a/src/web/app/desktop/tags/settings.tag
+++ b/src/web/app/desktop/tags/settings.tag
@@ -48,11 +48,6 @@
<p>API通信時に新鮮なユーザー情報をキャッシュすることでフェッチのオーバーヘッドを無くします。(実験的)</p>
</label>
<label class="checkbox">
- <input type="checkbox" checked={ I.data.debug } onclick={ updateDebug }/>
- <p>開発者モード</p>
- <p>デバッグ等の開発者モードを有効にします。</p>
- </label>
- <label class="checkbox">
<input type="checkbox" checked={ I.data.nya } onclick={ updateNya }/>
<p><i>な</i>を<i>にゃ</i>に変換する</p>
<p>攻撃的な投稿が多少和らぐ可能性があります。</p>
@@ -198,46 +193,49 @@
</style>
<script>
- @mixin \i
- @mixin \api
- @mixin \dialog
- @mixin \update-avatar
-
- @page = \account
+ this.mixin('i');
+ this.mixin('api');
+ this.mixin('notify');
+ this.mixin('dialog');
+ this.mixin('update-avatar');
- @set-page = (page) ~>
- @page = page
+ this.page = 'account';
- @avatar = ~>
- @update-avatar @I
+ this.setPage = page => {
+ this.page = page;
+ };
- @update-account = ~>
- @api \i/update do
- name: @refs.account-name.value
- location: @refs.account-location.value
- bio: @refs.account-bio.value
- birthday: @refs.account-birthday.value
- .then (i) ~>
- alert \ok
- .catch (err) ~>
- console.error err
+ this.avatar = () => {
+ this.updateAvatar(this.I);
+ };
- @update-cache = ~>
- @I.data.cache = !@I.data.cache
- @api \i/appdata/set do
- data: JSON.stringify do
- cache: @I.data.cache
+ this.updateAccount = () => {
+ this.api('i/update', {
+ name: this.refs.accountName.value,
+ location: this.refs.accountLocation.value,
+ bio: this.refs.accountBio.value,
+ birthday: this.refs.accountBirthday.value
+ }).then(() => {
+ this.notify('プロフィールを更新しました');
+ });
+ };
- @update-debug = ~>
- @I.data.debug = !@I.data.debug
- @api \i/appdata/set do
- data: JSON.stringify do
- debug: @I.data.debug
+ this.updateCache = () => {
+ this.I.data.cache = !this.I.data.cache;
+ this.api('i/appdata/set', {
+ data: JSON.stringify({
+ cache: this.I.data.cache
+ })
+ });
+ };
- @update-nya = ~>
- @I.data.nya = !@I.data.nya
- @api \i/appdata/set do
- data: JSON.stringify do
- nya: @I.data.nya
+ this.updateNya = () => {
+ this.I.data.nya = !this.I.data.nya;
+ this.api('i/appdata/set', {
+ data: JSON.stringify({
+ nya: this.I.data.nya
+ })
+ });
+ };
</script>
</mk-settings>
diff --git a/src/web/app/desktop/tags/stream-indicator.tag b/src/web/app/desktop/tags/stream-indicator.tag
deleted file mode 100644
index d2ab34574d..0000000000
--- a/src/web/app/desktop/tags/stream-indicator.tag
+++ /dev/null
@@ -1,54 +0,0 @@
-<mk-stream-indicator>
- <p if={ state == 'initializing' }><i class="fa fa-spinner fa-spin"></i><span>接続中
- <mk-ellipsis></mk-ellipsis></span></p>
- <p if={ state == 'reconnecting' }><i class="fa fa-spinner fa-spin"></i><span>切断されました 接続中
- <mk-ellipsis></mk-ellipsis></span></p>
- <p if={ state == 'connected' }><i class="fa fa-check"></i><span>接続完了</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)
-
- > p
- display block
- margin 0
-
- > i
- margin-right 0.25em
-
- </style>
- <script>
- @mixin \stream
-
- @on \before-mount ~>
- @state = @get-stream-state!
-
- if @state == \connected
- @root.style.opacity = 0
-
- @stream-state-ev.on \connected ~>
- @state = @get-stream-state!
- @update!
- set-timeout ~>
- Velocity @root, {
- opacity: 0
- } 200ms \linear
- , 1000ms
-
- @stream-state-ev.on \closed ~>
- @state = @get-stream-state!
- @update!
- Velocity @root, {
- opacity: 1
- } 0ms
- </script>
-</mk-stream-indicator>
diff --git a/src/web/app/desktop/tags/sub-post-content.tag b/src/web/app/desktop/tags/sub-post-content.tag
index 72f570dd6a..e0509ab7d4 100644
--- a/src/web/app/desktop/tags/sub-post-content.tag
+++ b/src/web/app/desktop/tags/sub-post-content.tag
@@ -1,5 +1,11 @@
<mk-sub-post-content>
- <div class="body"><a class="reply" if={ post.reply_to_id }><i class="fa fa-reply"></i></a><span ref="text"></span><a class="quote" if={ post.repost_id } href={ '/post:' + post.repost_id }>RP: ...</a></div>
+ <div class="body">
+ <a class="reply" if={ post.reply_to_id }>
+ <i class="fa fa-reply"></i>
+ </a>
+ <span ref="text"></span>
+ <a class="quote" if={ post.repost_id } href={ '/post:' + post.repost_id }>RP: ...</a>
+ </div>
<details if={ post.media }>
<summary>({ post.media.length }つのメディア)</summary>
<mk-images-viewer images={ post.media }></mk-images-viewer>
@@ -28,18 +34,20 @@
</style>
<script>
- @mixin \text
- @mixin \user-preview
+ this.mixin('text');
+ this.mixin('user-preview');
- @post = @opts.post
+ this.post = this.opts.post;
- @on \mount ~>
- if @post.text?
- tokens = @analyze @post.text
- @refs.text.innerHTML = @compile tokens, false
+ this.on('mount', () => {
+ if (this.post.text) {
+ const tokens = this.analyze(this.post.text);
+ this.refs.text.innerHTML = this.compile(tokens, false);
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
+ }
+ });
</script>
</mk-sub-post-content>
diff --git a/src/web/app/desktop/tags/timeline-post-sub.tag b/src/web/app/desktop/tags/timeline-post-sub.tag
index 5884927d75..905bc7aacf 100644
--- a/src/web/app/desktop/tags/timeline-post-sub.tag
+++ b/src/web/app/desktop/tags/timeline-post-sub.tag
@@ -8,15 +8,6 @@
</div>
</div>
</article>
- <script>
- @mixin \date-stringify
- @mixin \user-preview
-
- @post = @opts.post
-
- @title = @date-stringify @post.created_at
-
- </script>
<style>
:scope
display block
@@ -97,4 +88,11 @@
font-size 80%
</style>
+ <script>
+ this.mixin('date-stringify');
+ this.mixin('user-preview');
+
+ this.post = this.opts.post;
+ this.title = this.dateStringify(this.post.created_at);
+ </script>
</mk-timeline-post-sub>
diff --git a/src/web/app/desktop/tags/timeline-post.tag b/src/web/app/desktop/tags/timeline-post.tag
index 1549151fdb..440d5d9f42 100644
--- a/src/web/app/desktop/tags/timeline-post.tag
+++ b/src/web/app/desktop/tags/timeline-post.tag
@@ -55,8 +55,13 @@
<button class={ liked: p.is_liked } onclick={ like } title="善哉"><i class="fa fa-thumbs-o-up"></i>
<p class="count" if={ p.likes_count > 0 }>{ p.likes_count }</p>
</button>
- <button onclick={ NotImplementedException }><i class="fa fa-ellipsis-h"></i></button>
- <button onclick={ toggleDetail } title="詳細"><i class="fa fa-caret-down" if={ !isDetailOpened }></i><i class="fa fa-caret-up" if={ isDetailOpened }></i></button>
+ <button onclick={ NotImplementedException }>
+ <i class="fa fa-ellipsis-h"></i>
+ </button>
+ <button onclick={ toggleDetail } title="詳細">
+ <i class="fa fa-caret-down" if={ !isDetailOpened }></i>
+ <i class="fa fa-caret-up" if={ isDetailOpened }></i>
+ </button>
</footer>
</div>
</article>
@@ -312,96 +317,124 @@
</style>
<script>
- @mixin \api
- @mixin \text
- @mixin \date-stringify
- @mixin \user-preview
- @mixin \NotImplementedException
+ this.mixin('api');
+ this.mixin('text');
+ this.mixin('date-stringify');
+ this.mixin('user-preview');
+ this.mixin('NotImplementedException');
- @post = @opts.post
- @is-repost = @post.repost? and !@post.text?
- @p = if @is-repost then @post.repost else @post
+ this.post = this.opts.post;
+ this.isRepost = this.post.repost && this.post.text == null;
+ this.p = this.isRepost ? this.post.repost : this.post;
- @title = @date-stringify @p.created_at
+ this.title = this.dateStringify(this.p.created_at);
- @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
- @is-detail-opened = false
+ this.url = CONFIG.url + '/' + this.p.user.username + '/' + this.p.id;
+ this.isDetailOpened = false;
- @on \mount ~>
- if @p.text?
- tokens = if @p._highlight?
- then @analyze @p._highlight
- else @analyze @p.text
+ this.on('mount', () => {
+ if (this.p.text) {
+ const tokens = this.analyze(this.p.text);
- @refs.text.innerHTML = @refs.text.innerHTML.replace '<p class="dummy"></p>' if @p._highlight?
- then @compile tokens, true, false
- else @compile tokens
+ this.refs.text.innerHTML = this.refs.text.innerHTML.replace('<p class="dummy"></p>', this.compile(tokens));
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
- # URLをプレビュー
+ // URLをプレビュー
tokens
- .filter (t) -> t.type == \link
- .map (t) ~>
- @preview = @refs.text.append-child document.create-element \mk-url-preview
- riot.mount @preview, do
- url: t.content
+ .filter(t => t.type == 'link')
+ .map(t => {
+ riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
+ url: t.content
+ });
+ });
+ }
+ });
+
+ this.reply = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
+ reply: this.p
+ });
+ };
+
+ this.repost = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-repost-form-window')), {
+ post: this.p
+ });
+ };
+
+ this.like = () => {
+ if (this.p.is_liked) {
+ this.api('posts/likes/delete', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = false;
+ this.update();
+ });
+ } else {
+ this.api('posts/likes/create', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = true;
+ this.update();
+ });
+ }
+ };
+
+ this.toggleDetail = () => {
+ this.update({
+ isDetailOpened: !this.isDetailOpened
+ });
+ };
+
+ this.onKeyDown = e => {
+ let shouldBeCancel = true;
- @reply = ~>
- form = document.body.append-child document.create-element \mk-post-form-window
- riot.mount form, do
- reply: @p
+ switch (true) {
+ case e.which == 38: // [↑]
+ case e.which == 74: // [j]
+ case e.which == 9 && e.shiftKey: // [Shift] + [Tab]
+ focus(this.root, e => e.previousElementSibling);
+ break;
- @repost = ~>
- form = document.body.append-child document.create-element \mk-repost-form-window
- riot.mount form, do
- post: @p
+ case e.which == 40: // [↓]
+ case e.which == 75: // [k]
+ case e.which == 9: // [Tab]
+ focus(this.root, e => e.nextElementSibling);
+ break;
- @like = ~>
- if @p.is_liked
- @api \posts/likes/delete do
- post_id: @p.id
- .then ~>
- @p.is_liked = false
- @update!
- else
- @api \posts/likes/create do
- post_id: @p.id
- .then ~>
- @p.is_liked = true
- @update!
+ case e.which == 81: // [q]
+ case e.which == 69: // [e]
+ this.repost();
+ break;
- @toggle-detail = ~>
- @is-detail-opened = !@is-detail-opened
- @update!
+ case e.which == 70: // [f]
+ case e.which == 76: // [l]
+ this.like();
+ break;
- @on-key-down = (e) ~>
- should-be-cancel = true
- switch
- | e.which == 38 or e.which == 74 or (e.which == 9 and e.shift-key) => # ↑, j or Shift+Tab
- focus @root, (e) -> e.previous-element-sibling
- | e.which == 40 or e.which == 75 or e.which == 9 => # ↓, k or Tab
- focus @root, (e) -> e.next-element-sibling
- | e.which == 81 or e.which == 69 => # q or e
- @repost!
- | e.which == 70 or e.which == 76 => # f or l
- @like!
- | e.which == 82 => # r
- @reply!
- | _ =>
- should-be-cancel = false
+ case e.which == 82: // [r]
+ this.reply();
+ break;
+
+ default:
+ shouldBeCancel = false;
+ }
- if should-be-cancel
- e.prevent-default!
+ if (shouldBeCancel) e.preventDefault();
+ };
- function focus(el, fn)
- target = fn el
- if target?
- if target.has-attribute \tabindex
- target.focus!
- else
- focus target, fn
+ function focus(el, fn) {
+ const target = fn(el);
+ if (target) {
+ if (target.hasAttribute('tabindex')) {
+ target.focus();
+ } else {
+ focus(target, fn);
+ }
+ }
+ }
</script>
</mk-timeline-post>
diff --git a/src/web/app/desktop/tags/timeline.tag b/src/web/app/desktop/tags/timeline.tag
index 3439a426e3..a589adf5a0 100644
--- a/src/web/app/desktop/tags/timeline.tag
+++ b/src/web/app/desktop/tags/timeline.tag
@@ -3,7 +3,9 @@
<mk-timeline-post post={ post }></mk-timeline-post>
<p class="date" if={ i != posts.length - 1 && post._date != posts[i + 1]._date }><span><i class="fa fa-angle-up"></i>{ post._datetext }</span><span><i class="fa fa-angle-down"></i>{ posts[i + 1]._datetext }</span></p>
</virtual>
- <footer data-yield="footer"><yield from="footer"/></footer>
+ <footer data-yield="footer">
+ <yield from="footer"/>
+ </footer>
<style>
:scope
display block
@@ -44,36 +46,47 @@
</style>
<script>
- @posts = []
+ this.posts = [];
- @set-posts = (posts) ~>
- @posts = posts
- @update!
+ this.on('update', () => {
+ this.posts.forEach(post => {
+ const date = new Date(post.created_at).getDate();
+ const month = new Date(post.created_at).getMonth() + 1;
+ post._date = date;
+ post._datetext = `${month}月 ${date}日`;
+ });
+ });
- @prepend-posts = (posts) ~>
- posts.for-each (post) ~>
- @posts.push post
- @update!
+ this.setPosts = posts => {
+ this.update({
+ posts: posts
+ });
+ };
- @add-post = (post) ~>
- @posts.unshift post
- @update!
+ this.prependPosts = posts => {
+ posts.forEach(post => {
+ this.posts.push(post);
+ this.update();
+ });
+ }
- @clear = ~>
- @posts = []
- @update!
+ this.addPost = post => {
+ this.posts.unshift(post);
+ this.update();
+ };
- @focus = ~>
- @root.children.0.focus!
+ this.tail = () => {
+ return this.posts[this.posts.length - 1];
+ };
- @on \update ~>
- @posts.for-each (post) ~>
- date = (new Date post.created_at).get-date!
- month = (new Date post.created_at).get-month! + 1
- post._date = date
- post._datetext = month + '月 ' + date + '日'
+ this.clear = () => {
+ this.posts = [];
+ this.update();
+ };
+
+ this.focus = () => {
+ this.root.children[0].focus();
+ };
- @tail = ~>
- @posts[@posts.length - 1]
</script>
</mk-timeline>
diff --git a/src/web/app/desktop/tags/ui-header-account.tag b/src/web/app/desktop/tags/ui-header-account.tag
index 6071995cec..c035529f79 100644
--- a/src/web/app/desktop/tags/ui-header-account.tag
+++ b/src/web/app/desktop/tags/ui-header-account.tag
@@ -159,54 +159,54 @@
</style>
<script>
- @mixin \i
- @mixin \signout
+ const contains = require('../../common/scripts/contains');
- @is-open = false
+ this.mixin('i');
+ this.mixin('signout');
- @on \before-unmount ~>
- @close!
+ this.isOpen = false;
- @toggle = ~>
- if @is-open
- @close!
- else
- @open!
+ this.on('before-unmount', () => {
+ this.close();
+ });
- @open = ~>
- @is-open = true
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
+ this.toggle = () => {
+ this.isOpen ? this.close() : this.open();
+ };
- @close = ~>
- @is-open = false
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
+ this.open = () => {
+ this.update({
+ isOpen: true
+ });
+ document.querySelectorAll('body *').forEach(el => {
+ el.addEventListener('mousedown', this.mousedown);
+ });
+ };
- @mousedown = (e) ~>
- e.prevent-default!
- if (!contains @root, e.target) and (@root != e.target)
- @close!
- return false
+ this.close = () => {
+ this.update({
+ isOpen: false
+ });
+ document.querySelectorAll('body *').forEach(el => {
+ el.removeEventListener('mousedown', this.mousedown);
+ });
+ };
- @drive = ~>
- @close!
- riot.mount document.body.append-child document.create-element \mk-drive-browser-window
+ this.mousedown = e => {
+ e.preventDefault();
+ if (!contains(this.root, e.target) && this.root != e.target) this.close();
+ return false;
+ };
- @settings = ~>
- @close!
- riot.mount document.body.append-child document.create-element \mk-settings-window
+ this.drive = () => {
+ this.close();
+ riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-window')));
+ };
+
+ this.settings = () => {
+ this.close();
+ riot.mount(document.body.appendChild(document.createElement('mk-settings-window')));
+ };
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
</script>
</mk-ui-header-account>
diff --git a/src/web/app/desktop/tags/ui-header-clock.tag b/src/web/app/desktop/tags/ui-header-clock.tag
index 50536705bc..48b142509a 100644
--- a/src/web/app/desktop/tags/ui-header-clock.tag
+++ b/src/web/app/desktop/tags/ui-header-clock.tag
@@ -1,6 +1,10 @@
<mk-ui-header-clock>
<div class="header">
- <time ref="time"></time>
+ <time ref="time">
+ <span class="yyyymmdd">{ yyyy }/{ mm }/{ dd }</span>
+ <br>
+ <span class="hhnn">{ hh }<span style="visibility:{ now.getSeconds() % 2 == 0 ? 'visible' : 'hidden' }">:</span>{ nn }</span>
+ </time>
</div>
<div class="content">
<mk-analog-clock></mk-analog-clock>
@@ -13,7 +17,7 @@
> .header
padding 0 12px
text-align center
- font-size 0.5em
+ font-size 10px
&, *
cursor: default
@@ -58,30 +62,24 @@
</style>
<script>
- @draw = ~>
- now = new Date!
+ this.now = new Date();
- yyyy = now.get-full-year!
- mm = (\0 + (now.get-month! + 1)).slice -2
- dd = (\0 + now.get-date!).slice -2
- yyyymmdd = "<span class='yyyymmdd'>#yyyy/#mm/#dd</span>"
+ this.draw = () => {
+ const now = this.now = new Date();
+ this.yyyy = now.getFullYear();
+ this.mm = ('0' + (now.getMonth() + 1)).slice(-2);
+ this.dd = ('0' + now.getDate()).slice(-2);
+ this.hh = ('0' + now.getHours()).slice(-2);
+ this.nn = ('0' + now.getMinutes()).slice(-2);
+ };
- hh = (\0 + now.get-hours!).slice -2
- mm = (\0 + now.get-minutes!).slice -2
- hhmm = "<span class='hhmm'>#hh:#mm</span>"
+ this.on('mount', () => {
+ this.draw();
+ this.clock = setInterval(this.draw, 1000);
+ });
- if now.get-seconds! % 2 == 0
- hhmm .= replace \: '<span style=\'visibility:visible\'>:</span>'
- else
- hhmm .= replace \: '<span style=\'visibility:hidden\'>:</span>'
-
- @refs.time.innerHTML = "#yyyymmdd<br>#hhmm"
-
- @on \mount ~>
- @draw!
- @clock = set-interval @draw, 1000ms
-
- @on \unmount ~>
- clear-interval @clock
+ this.on('unmount', () => {
+ clearInterval(this.clock);
+ });
</script>
</mk-ui-header-clock>
diff --git a/src/web/app/desktop/tags/ui-header-nav.tag b/src/web/app/desktop/tags/ui-header-nav.tag
index 707a9366e8..9be1edea8c 100644
--- a/src/web/app/desktop/tags/ui-header-nav.tag
+++ b/src/web/app/desktop/tags/ui-header-nav.tag
@@ -1,113 +1,139 @@
<mk-ui-header-nav>
<ul if={ SIGNIN }>
- <li class="home { active: page == 'home' }"><a href={ CONFIG.url }><i class="fa fa-home"></i>
- <p>ホーム</p></a></li>
- <li class="messaging"><a onclick={ messaging }><i class="fa fa-comments"></i>
- <p>メッセージ</p><i class="fa fa-circle" if={ hasUnreadMessagingMessages }></i></a></li>
- <li class="info"><a href="https://twitter.com/misskey_xyz" target="_blank"><i class="fa fa-info"></i>
- <p>お知らせ</p></a></li>
- <li class="tv"><a href="https://misskey.tk" target="_blank"><i class="fa fa-television"></i>
- <p>MisskeyTV™</p></a></li>
- <style>
- :scope
+ <li class="home { active: page == 'home' }">
+ <a href={ CONFIG.url }>
+ <i class="fa fa-home"></i>
+ <p>ホーム</p>
+ </a>
+ </li>
+ <li class="messaging">
+ <a onclick={ messaging }>
+ <i class="fa fa-comments"></i>
+ <p>メッセージ</p>
+ <i class="fa fa-circle" if={ hasUnreadMessagingMessages }></i>
+ </a>
+ </li>
+ <li class="info">
+ <a href="https://twitter.com/misskey_xyz" target="_blank">
+ <i class="fa fa-info"></i>
+ <p>お知らせ</p>
+ </a>
+ </li>
+ <li class="tv">
+ <a href="https://misskey.tk" target="_blank">
+ <i class="fa fa-television"></i>
+ <p>MisskeyTV™</p>
+ </a>
+ </li>
+ </ul>
+ <style>
+ :scope
+ display inline-block
+ margin 0
+ padding 0
+ line-height 3rem
+ vertical-align top
+
+ > ul
display inline-block
margin 0
padding 0
- line-height 3rem
vertical-align top
+ line-height 3rem
+ list-style none
- > ul
+ > li
display inline-block
- margin 0
- padding 0
vertical-align top
- line-height 3rem
- list-style none
+ height 48px
+ line-height 48px
+
+ &.active
+ > a
+ border-bottom solid 3px $theme-color
- > li
+ > a
display inline-block
- vertical-align top
- height 48px
- line-height 48px
+ z-index 1
+ height 100%
+ padding 0 24px
+ font-size 1em
+ font-variant small-caps
+ color #9eaba8
+ text-decoration none
+ transition none
+ cursor pointer
- &.active
- > a
- border-bottom solid 3px $theme-color
+ *
+ pointer-events none
- > a
- display inline-block
- z-index 1
- height 100%
- padding 0 24px
- font-size 1em
- font-variant small-caps
- color #9eaba8
+ &:hover
+ color darken(#9eaba8, 20%)
text-decoration none
- transition none
- cursor pointer
-
- *
- pointer-events none
- &:hover
- color darken(#9eaba8, 20%)
- text-decoration none
+ > i:first-child
+ margin-right 8px
- > i:first-child
- margin-right 8px
+ > i:last-child
+ margin-left 5px
+ vertical-align super
+ font-size 10px
+ color $theme-color
- > i:last-child
- margin-left 5px
- vertical-align super
- font-size 10px
- color $theme-color
+ @media (max-width 1100px)
+ margin-left -5px
- @media (max-width 1100px)
- margin-left -5px
+ > p
+ display inline
+ margin 0
- > p
- display inline
- margin 0
+ @media (max-width 1100px)
+ display none
- @media (max-width 1100px)
- display none
+ @media (max-width 700px)
+ padding 0 12px
- @media (max-width 700px)
- padding 0 12px
+ </style>
+ <script>
+ this.mixin('i');
+ this.mixin('api');
+ this.mixin('stream');
- </style>
- <script>
- @mixin \i
- @mixin \api
- @mixin \stream
+ this.page = this.opts.page;
- @page = @opts.page
+ this.on('mount', () => {
+ this.stream.on('read_all_messaging_messages', this.onReadAllMessagingMessages);
+ this.stream.on('unread_messaging_message', this.onUnreadMessagingMessage);
- @on \mount ~>
- @stream.on \read_all_messaging_messages @on-read-all-messaging-messages
- @stream.on \unread_messaging_message @on-unread-messaging-message
+ // Fetch count of unread messaging messages
+ this.api('messaging/unread').then(res => {
+ if (res.count > 0) {
+ this.update({
+ hasUnreadMessagingMessages: true
+ });
+ }
+ });
+ });
- # Fetch count of unread messaging messages
- @api \messaging/unread
- .then (count) ~>
- if count.count > 0
- @has-unread-messaging-messages = true
- @update!
+ this.on('unmount', () => {
+ this.stream.off('read_all_messaging_messages', this.onReadAllMessagingMessages);
+ this.stream.off('unread_messaging_message', this.onUnreadMessagingMessage);
+ });
- @on \unmount ~>
- @stream.off \read_all_messaging_messages @on-read-all-messaging-messages
- @stream.off \unread_messaging_message @on-unread-messaging-message
+ this.onReadAllMessagingMessages = () => {
+ this.update({
+ hasUnreadMessagingMessages: false
+ });
+ };
- @on-read-all-messaging-messages = ~>
- @has-unread-messaging-messages = false
- @update!
+ this.onUnreadMessagingMessage = () => {
+ this.update({
+ hasUnreadMessagingMessages: true
+ });
+ };
- @on-unread-messaging-message = ~>
- @has-unread-messaging-messages = true
- @update!
-
- @messaging = ~>
- riot.mount document.body.append-child document.create-element \mk-messaging-window
- </script>
- </ul>
+ this.messaging = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-messaging-window')));
+ };
+ </script>
</mk-ui-header-nav>
diff --git a/src/web/app/desktop/tags/ui-header-notifications.tag b/src/web/app/desktop/tags/ui-header-notifications.tag
index 65330a14e3..05a9e6d772 100644
--- a/src/web/app/desktop/tags/ui-header-notifications.tag
+++ b/src/web/app/desktop/tags/ui-header-notifications.tag
@@ -75,40 +75,36 @@
</style>
<script>
- @is-open = false
+ const contains = require('../../common/scripts/contains');
- @toggle = ~>
- if @is-open
- @close!
- else
- @open!
+ this.isOpen = false;
- @open = ~>
- @is-open = true
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
+ this.toggle = () => {
+ this.isOpen ? this.close() : this.open();
+ };
- @close = ~>
- @is-open = false
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
+ this.open = () => {
+ this.update({
+ isOpen: true
+ });
+ document.querySelectorAll('body *').forEach(el => {
+ el.addEventListener('mousedown', this.mousedown);
+ });
+ };
- @mousedown = (e) ~>
- e.prevent-default!
- if (!contains @root, e.target) and (@root != e.target)
- @close!
- return false
+ this.close = () => {
+ this.update({
+ isOpen: false
+ });
+ document.querySelectorAll('body *').forEach(el => {
+ el.removeEventListener('mousedown', this.mousedown);
+ });
+ };
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
+ this.mousedown = e => {
+ e.preventDefault();
+ if (!contains(this.root, e.target) && this.root != e.target) this.close();
+ return false;
+ };
</script>
</mk-ui-header-notifications>
diff --git a/src/web/app/desktop/tags/ui-header-post-button.tag b/src/web/app/desktop/tags/ui-header-post-button.tag
index 071af0a158..ca380b06ea 100644
--- a/src/web/app/desktop/tags/ui-header-post-button.tag
+++ b/src/web/app/desktop/tags/ui-header-post-button.tag
@@ -35,7 +35,8 @@
</style>
<script>
- @post = (e) ~>
- @parent.parent.open-post-form!
+ this.post = e => {
+ this.parent.parent.openPostForm();
+ };
</script>
</mk-ui-header-post-button>
diff --git a/src/web/app/desktop/tags/ui-header-search.tag b/src/web/app/desktop/tags/ui-header-search.tag
index 10ebe1da98..ff1a313cec 100644
--- a/src/web/app/desktop/tags/ui-header-search.tag
+++ b/src/web/app/desktop/tags/ui-header-search.tag
@@ -32,10 +32,11 @@
</style>
<script>
- @mixin \page
+ this.mixin('page');
- @onsubmit = (e) ~>
- e.prevent-default!
- @page '/search:' + @refs.q.value
+ this.onsubmit = e => {
+ e.preventDefault();
+ this.page('/search:' + this.refs.q.value);
+ };
</script>
</mk-ui-header-search>
diff --git a/src/web/app/desktop/tags/ui-header.tag b/src/web/app/desktop/tags/ui-header.tag
index 41b74181f9..4ab1789309 100644
--- a/src/web/app/desktop/tags/ui-header.tag
+++ b/src/web/app/desktop/tags/ui-header.tag
@@ -21,7 +21,7 @@
<style>
:scope
display block
- position fixed
+ position sticky
top 0
z-index 1024
width 100%
@@ -80,6 +80,5 @@
display none
</style>
-
- <script>@mixin \i</script>
+ <script>this.mixin('i');</script>
</mk-ui-header>
diff --git a/src/web/app/desktop/tags/ui-notification.tag b/src/web/app/desktop/tags/ui-notification.tag
index 5f8583a391..34f310844e 100644
--- a/src/web/app/desktop/tags/ui-notification.tag
+++ b/src/web/app/desktop/tags/ui-notification.tag
@@ -22,23 +22,23 @@
</style>
<script>
- @on \mount ~>
- Velocity @root, {
- top: \0px
- } {
- duration: 500ms
- easing: \ease-out
- }
+ this.on('mount', () => {
+ Velocity(this.root, {
+ top: '0px'
+ }, {
+ duration: 500,
+ easing: 'ease-out'
+ })
- set-timeout ~>
- Velocity @root, {
- top: \-64px
- } {
- duration: 500ms
- easing: \ease-out
- complete: ~>
- @unmount!
- }
- , 6000ms
+ setTimeout(() => {
+ Velocity(this.root, {
+ top: '-64px'
+ }, {
+ duration: 500,
+ easing: 'ease-out',
+ complete: () => this.unmount()
+ });
+ }, 6000);
+ });
</script>
</mk-ui-notification>
diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag
index e40e5c88e2..0669d252af 100644
--- a/src/web/app/desktop/tags/ui.tag
+++ b/src/web/app/desktop/tags/ui.tag
@@ -9,29 +9,29 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \i
+ this.mixin('i');
- @open-post-form = ~>
- riot.mount document.body.append-child document.create-element \mk-post-form-window
+ this.openPostForm = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')));
+ };
- @set-root-layout = ~>
- @root.style.padding-top = @refs.header.root.client-height + \px
+ this.on('mount', () => {
+ document.addEventListener('keydown', this.onkeydown);
+ });
- @on \mount ~>
- @set-root-layout!
- document.add-event-listener \keydown @onkeydown
+ this.on('unmount', () => {
+ document.removeEventListener('keydown', this.onkeydown);
+ });
- @on \unmount ~>
- document.remove-event-listener \keydown @onkeydown
+ this.onkeydown = e => {
+ if (e.target.tagName == 'input' || e.target.tagName == 'textarea') return;
- @onkeydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 80 or e.which == 78 # p or n
- e.prevent-default!
- @open-post-form!
+ if (e.which == 80 || e.which == 78) { // p or n
+ e.preventDefault();
+ this.openPostForm();
+ }
+ };
</script>
</mk-ui>
diff --git a/src/web/app/desktop/tags/user-followers-window.tag b/src/web/app/desktop/tags/user-followers-window.tag
index e70682c19a..a4a24d6673 100644
--- a/src/web/app/desktop/tags/user-followers-window.tag
+++ b/src/web/app/desktop/tags/user-followers-window.tag
@@ -15,5 +15,5 @@
border-radius 4px
</style>
- <script>@user = @opts.user</script>
+ <script>this.user = this.opts.user</script>
</mk-user-followers-window>
diff --git a/src/web/app/desktop/tags/user-followers.tag b/src/web/app/desktop/tags/user-followers.tag
index 14f20b831e..f43e87de8a 100644
--- a/src/web/app/desktop/tags/user-followers.tag
+++ b/src/web/app/desktop/tags/user-followers.tag
@@ -7,16 +7,17 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @user = @opts.user
+ this.user = this.opts.user;
- @fetch = (iknow, limit, cursor, cb) ~>
- @api \users/followers do
- user_id: @user.id
- iknow: iknow
- limit: limit
- cursor: if cursor? then cursor else undefined
- .then cb
+ this.fetch = (iknow, limit, cursor, cb) => {
+ this.api('users/followers', {
+ user_id: this.user.id,
+ iknow: iknow,
+ limit: limit,
+ cursor: cursor ? cursor : undefined
+ }).then(cb);
+ };
</script>
</mk-user-followers>
diff --git a/src/web/app/desktop/tags/user-following-window.tag b/src/web/app/desktop/tags/user-following-window.tag
index 4e25e8a3ca..6dbf3b05e9 100644
--- a/src/web/app/desktop/tags/user-following-window.tag
+++ b/src/web/app/desktop/tags/user-following-window.tag
@@ -15,5 +15,5 @@
border-radius 4px
</style>
- <script>@user = @opts.user</script>
+ <script>this.user = this.opts.user</script>
</mk-user-following-window>
diff --git a/src/web/app/desktop/tags/user-following.tag b/src/web/app/desktop/tags/user-following.tag
index e21d391d4d..f2d21b3fed 100644
--- a/src/web/app/desktop/tags/user-following.tag
+++ b/src/web/app/desktop/tags/user-following.tag
@@ -7,16 +7,17 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @user = @opts.user
+ this.user = this.opts.user;
- @fetch = (iknow, limit, cursor, cb) ~>
- @api \users/following do
- user_id: @user.id
- iknow: iknow
- limit: limit
- cursor: if cursor? then cursor else undefined
- .then cb
+ this.fetch = (iknow, limit, cursor, cb) => {
+ this.api('users/following', {
+ user_id: this.user.id,
+ iknow: iknow,
+ limit: limit,
+ cursor: cursor ? cursor : undefined
+ }).then(cb);
+ };
</script>
</mk-user-following>
diff --git a/src/web/app/desktop/tags/user-graphs.tag b/src/web/app/desktop/tags/user-graphs.tag
index 6d49c990ae..e673f7700b 100644
--- a/src/web/app/desktop/tags/user-graphs.tag
+++ b/src/web/app/desktop/tags/user-graphs.tag
@@ -34,7 +34,8 @@
</style>
<script>
- @on \mount ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.trigger('loaded');
+ });
</script>
</mk-user-graphs>
diff --git a/src/web/app/desktop/tags/user-header.tag b/src/web/app/desktop/tags/user-header.tag
index d49b6498b5..c265357169 100644
--- a/src/web/app/desktop/tags/user-header.tag
+++ b/src/web/app/desktop/tags/user-header.tag
@@ -104,39 +104,42 @@
</style>
<script>
- @mixin \i
- @mixin \update-banner
- @mixin \NotImplementedException
+ this.mixin('i');
+ this.mixin('update-banner');
+ this.mixin('NotImplementedException');
- @user = @opts.user
+ this.user = this.opts.user;
- @on \mount ~>
- window.add-event-listener \load @scroll
- window.add-event-listener \scroll @scroll
- window.add-event-listener \resize @scroll
+ this.on('mount', () => {
+ window.addEventListener('load', this.scroll);
+ window.addEventListener('scroll', this.scroll);
+ window.addEventListener('resize', this.scroll);
+ });
- @on \unmount ~>
- window.remove-event-listener \load @scroll
- window.remove-event-listener \scroll @scroll
- window.remove-event-listener \resize @scroll
+ this.on('unmount', () => {
+ window.removeEventListener('load', this.scroll);
+ window.removeEventListener('scroll', this.scroll);
+ window.removeEventListener('resize', this.scroll);
+ });
- @scroll = ~>
- top = window.scroll-y
- height = 280px
+ this.scroll = () => {
+ const top = window.scrollY;
+ const height = 280/*px*/;
- pos = 50 - ((top / height) * 50)
- @refs.banner.style.background-position = 'center ' + pos + '%'
+ const pos = 50 - ((top / height) * 50);
+ this.refs.banner.style.backgroundPosition = `center ${pos}%`;
- blur = top / 32
- if blur <= 10
- @refs.banner.style.filter = 'blur(' + blur + 'px)'
+ const blur = top / 32
+ if (blur <= 10) this.refs.banner.style.filter = `blur(${blur}px)`;
+ };
- @on-update-banner = ~>
- if not @SIGNIN or @I.id != @user.id
- return
+ this.onUpdateBanner = () => {
+ if (!this.SIGNIN || this.I.id != this.user.id) return;
- @update-banner @I, (i) ~>
- @user.banner_url = i.banner_url
- @update!
+ this.updateBanner(this.I, i => {
+ this.user.banner_url = i.banner_url;
+ this.update();
+ });
+ };
</script>
</mk-user-header>
diff --git a/src/web/app/desktop/tags/user-home.tag b/src/web/app/desktop/tags/user-home.tag
index 50fe1cbfad..759a57581d 100644
--- a/src/web/app/desktop/tags/user-home.tag
+++ b/src/web/app/desktop/tags/user-home.tag
@@ -35,10 +35,12 @@
</style>
<script>
- @user = @opts.user
+ this.user = this.opts.user;
- @on \mount ~>
- @refs.tl.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.tl.on('loaded', () => {
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-user-home>
diff --git a/src/web/app/desktop/tags/user-photos.tag b/src/web/app/desktop/tags/user-photos.tag
index 3d24422dea..86f12aceb9 100644
--- a/src/web/app/desktop/tags/user-photos.tag
+++ b/src/web/app/desktop/tags/user-photos.tag
@@ -57,30 +57,36 @@
</style>
<script>
- @mixin \api
- @mixin \is-promise
+ this.mixin('api');
+ this.mixin('is-promise');
- @images = []
- @initializing = true
+ this.images = [];
+ this.initializing = true;
+ this.user = null;
+ this.userPromise = this.isPromise(this.opts.user)
+ ? this.opts.user
+ : Promise.resolve(this.opts.user);
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ this.on('mount', () => {
+ this.userPromise.then(user => {
+ this.update({
+ user: user
+ });
- @on \mount ~>
- @user-promise.then (user) ~>
- @user = user
- @update!
-
- @api \users/posts do
- user_id: @user.id
- with_media: true
- limit: 9posts
- .then (posts) ~>
- @initializing = false
- posts.for-each (post) ~>
- post.media.for-each (image) ~>
- if @images.length < 9
- @images.push image
- @update!
+ this.api('users/posts', {
+ user_id: this.user.id,
+ with_media: true,
+ limit: 9
+ }).then(posts => {
+ this.initializing = false;
+ posts.forEach(post => {
+ post.media.forEach(media => {
+ if (this.images.length < 9) this.images.push(media);
+ });
+ });
+ this.update();
+ });
+ });
+ });
</script>
</mk-user-photos>
diff --git a/src/web/app/desktop/tags/user-preview.tag b/src/web/app/desktop/tags/user-preview.tag
index 7d140c0957..f9806534e2 100644
--- a/src/web/app/desktop/tags/user-preview.tag
+++ b/src/web/app/desktop/tags/user-preview.tag
@@ -97,47 +97,50 @@
</style>
<script>
- @mixin \i
- @mixin \api
+ this.mixin('i');
+ this.mixin('api');
- @u = @opts.user
- @user = null
- @user-promise =
- if typeof @u == \string
- new Promise (resolve, reject) ~>
- @api \users/show do
- user_id: if @u.0 == \@ then undefined else @u
- username: if @u.0 == \@ then @u.substr 1 else undefined
- .then (user) ~>
- resolve user
- else
- Promise.resolve @u
+ this.u = this.opts.user;
+ this.user = null;
+ this.userPromise =
+ typeof this.u == 'string' ?
+ new Promise((resolve, reject) => {
+ this.api('users/show', {
+ user_id: this.u[0] == '@' ? undefined : this.u,
+ username: this.u[0] == '@' ? this.u.substr(1) : undefined
+ }).then(resolve);
+ })
+ : Promise.resolve(this.u);
- @on \mount ~>
- @user-promise.then (user) ~>
- @user = user
- @update!
+ this.on('mount', () => {
+ this.userPromise.then(user => {
+ this.update({
+ user: user
+ });
+ });
- Velocity @root, {
- opacity: 0
- 'margin-top': \-8px
- } 0ms
- Velocity @root, {
- opacity: 1
+ Velocity(this.root, {
+ opacity: 0,
+ 'margin-top': '-8px'
+ }, 0);
+ Velocity(this.root, {
+ opacity: 1,
'margin-top': 0
- } {
- duration: 200ms
- easing: \ease-out
- }
+ }, {
+ duration: 200,
+ easing: 'ease-out'
+ });
+ });
- @close = ~>
- Velocity @root, {
- opacity: 0
- 'margin-top': \-8px
- } {
- duration: 200ms
- easing: \ease-out
- complete: ~> @unmount!
- }
+ this.close = () => {
+ Velocity(this.root, {
+ opacity: 0,
+ 'margin-top': '-8px'
+ }, {
+ duration: 200,
+ easing: 'ease-out',
+ complete: () => this.unmount()
+ });
+ };
</script>
</mk-user-preview>
diff --git a/src/web/app/desktop/tags/user-profile.tag b/src/web/app/desktop/tags/user-profile.tag
index d8984e971d..03697fd5f3 100644
--- a/src/web/app/desktop/tags/user-profile.tag
+++ b/src/web/app/desktop/tags/user-profile.tag
@@ -80,20 +80,22 @@
</style>
<script>
- @age = require \s-age
+ this.age = require('s-age');
- @mixin \i
+ this.mixin('i');
- @user = @opts.user
+ this.user = this.opts.user;
- @show-following = ~>
- window = document.body.append-child document.create-element \mk-user-following-window
- riot.mount window, do
- user: @user
+ this.showFollowing = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-user-following-window')), {
+ user: this.user
+ });
+ };
- @show-followers = ~>
- window = document.body.append-child document.create-element \mk-user-followers-window
- riot.mount window, do
- user: @user
+ this.showFollowers = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-user-followers-window')), {
+ user: this.user
+ });
+ };
</script>
</mk-user-profile>
diff --git a/src/web/app/desktop/tags/user-timeline.tag b/src/web/app/desktop/tags/user-timeline.tag
index b0ed542a43..4851eb0a18 100644
--- a/src/web/app/desktop/tags/user-timeline.tag
+++ b/src/web/app/desktop/tags/user-timeline.tag
@@ -46,93 +46,89 @@
</style>
<script>
- @mixin \api
- @mixin \is-promise
- @mixin \get-post-summary
+ this.mixin('api');
+ this.mixin('is-promise');
+ this.mixin('get-post-summary');
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @unread-count = 0
- @mode = \default
+ this.user = null;
+ this.userPromise = this.isPromise(this.opts.user)
+ ? this.opts.user
+ : Promise.resolve(this.opts.user);
+ this.isLoading = true;
+ this.isEmpty = false;
+ this.moreLoading = false;
+ this.unreadCount = 0;
+ this.mode = 'default';
- @on \mount ~>
- document.add-event-listener \visibilitychange @window-on-visibilitychange, false
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ this.on('mount', () => {
+ document.addEventListener('keydown', this.onDocumentKeydown);
+ window.addEventListener('scroll', this.onScroll);
- @user-promise.then (user) ~>
- @user = user
- @update!
+ this.userPromise.then(user => {
+ this.update({
+ user: user
+ });
- @fetch ~>
- @trigger \loaded
+ this.fetch(() => this.trigger('loaded'));
+ });
+ });
- @on \unmount ~>
- document.remove-event-listener \visibilitychange @window-on-visibilitychange
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ this.on('unmount', () => {
+ document.removeEventListener('keydown', this.onDocumentKeydown);
+ window.removeEventListener('scroll', this.onScroll);
+ });
- @on-document-keydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 84 # t
- @refs.timeline.focus!
+ this.onDocumentKeydown = e => {
+ if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') {
+ if (e.which == 84) { // [t]
+ this.refs.timeline.focus();
+ }
+ }
+ };
- @fetch = (cb) ~>
- @api \users/posts do
- user_id: @user.id
- with_replies: @mode == \with-replies
- .then (posts) ~>
- @is-loading = false
- @is-empty = posts.length == 0
- @update!
- @refs.timeline.set-posts posts
- if cb? then cb!
- .catch (err) ~>
- console.error err
- if cb? then cb!
+ this.fetch = cb => {
+ this.api('users/posts', {
+ user_id: this.user.id,
+ with_replies: this.mode == 'with-replies'
+ }).then(posts => {
+ this.update({
+ isLoading: false,
+ isEmpty: posts.length == 0
+ });
+ this.refs.timeline.setPosts(posts);
+ if (cb) cb();
+ });
+ };
- @more = ~>
- if @more-loading or @is-loading or @refs.timeline.posts.length == 0
- return
- @more-loading = true
- @update!
- @api \users/posts do
- user_id: @user.id
- with_replies: @mode == \with-replies
- max_id: @refs.timeline.tail!.id
- .then (posts) ~>
- @more-loading = false
- @update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
+ this.more = () => {
+ if (this.moreLoading || this.isLoading || this.refs.timeline.posts.length == 0) return;
+ this.update({
+ moreLoading: true
+ });
+ this.api('users/posts', {
+ user_id: this.user.id,
+ with_replies: this.mode == 'with-replies',
+ max_id: this.refs.timeline.tail().id
+ }).then(posts => {
+ this.update({
+ moreLoading: false
+ });
+ this.refs.timeline.prependPosts(posts);
+ });
+ };
- @on-stream-post = (post) ~>
- @is-empty = false
- @update!
- @refs.timeline.add-post post
+ this.onScroll = () => {
+ const current = window.scrollY + window.innerHeight;
+ if (current > document.body.offsetHeight - 16/*遊び*/) {
+ this.more();
+ }
+ };
- if document.hidden
- @unread-count++
- document.title = '(' + @unread-count + ') ' + @get-post-summary post
-
- @window-on-visibilitychange = ~>
- if !document.hidden
- @unread-count = 0
- document.title = 'Misskey'
-
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 16 # 遊び
- @more!
-
- @set-mode = (mode) ~>
- @update do
+ this.setMode = mode => {
+ this.update({
mode: mode
- @fetch!
+ });
+ this.fetch();
+ };
</script>
</mk-user-timeline>
diff --git a/src/web/app/desktop/tags/user.tag b/src/web/app/desktop/tags/user.tag
index 24f2e958a3..c128736183 100644
--- a/src/web/app/desktop/tags/user.tag
+++ b/src/web/app/desktop/tags/user.tag
@@ -32,20 +32,23 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @username = @opts.user
- @page = if @opts.page? then @opts.page else \home
- @fetching = true
- @user = null
+ this.username = this.opts.user;
+ this.page = this.opts.page ? this.opts.page : 'home';
+ this.fetching = true;
+ this.user = null;
- @on \mount ~>
- @api \users/show do
- username: @username
- .then (user) ~>
- @fetching = false
- @user = user
- @update!
- @trigger \loaded
+ this.on('mount', () => {
+ this.api('users/show', {
+ username: this.username
+ }).then(user => {
+ this.update({
+ fetching: false,
+ user: user
+ });
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-user>
diff --git a/src/web/app/desktop/tags/users-list.tag b/src/web/app/desktop/tags/users-list.tag
index 51edd2ee30..c94d0e228d 100644
--- a/src/web/app/desktop/tags/users-list.tag
+++ b/src/web/app/desktop/tags/users-list.tag
@@ -1,7 +1,9 @@
<mk-users-list>
<nav>
- <div><span data-is-active={ mode == 'all' } onclick={ setMode.bind(this, 'all') }>すべて<span>{ opts.count }</span></span>
- <!-- ↓ https://github.com/riot/riot/issues/2080--><span if={ SIGNIN && opts.youKnowCount != '' } data-is-active={ mode == 'iknow' } onclick={ setMode.bind(this, 'iknow') }>知り合い<span>{ opts.youKnowCount }</span></span>
+ <div>
+ <span data-is-active={ mode == 'all' } onclick={ setMode.bind(this, 'all') }>すべて<span>{ opts.count }</span></span>
+ <!-- ↓ https://github.com/riot/riot/issues/2080-->
+ <span if={ SIGNIN && opts.youKnowCount != '' } data-is-active={ mode == 'iknow' } onclick={ setMode.bind(this, 'iknow') }>知り合い<span>{ opts.youKnowCount }</span></span>
</div>
</nav>
<div class="users" if={ !fetching && users.length != 0 }>
@@ -9,8 +11,10 @@
<mk-list-user user={ this }></mk-list-user>
</div>
</div>
- <button class="more" if={ !fetching && next != null } onclick={ more } disabled={ moreFetching }><span if={ !moreFetching }>もっと</span><span if={ moreFetching }>読み込み中
- <mk-ellipsis></mk-ellipsis></span></button>
+ <button class="more" if={ !fetching && next != null } onclick={ more } disabled={ moreFetching }>
+ <span if={ !moreFetching }>もっと</span>
+ <span if={ moreFetching }>読み込み中<mk-ellipsis></mk-ellipsis></span>
+ </button>
<p class="no" if={ !fetching && users.length == 0 }>{ opts.noUsers }</p>
<p class="fetching" if={ fetching }><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
<mk-ellipsis></mk-ellipsis>
@@ -88,47 +92,50 @@
</style>
<script>
- @mixin \i
+ this.mixin('i');
- @limit = 30users
- @mode = \all
+ this.limit = 30;
+ this.mode = 'all';
- @fetching = true
- @more-fetching = false
+ this.fetching = true;
+ this.moreFetching = false;
- @on \mount ~>
- @fetch ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.fetch(() => this.trigger('loaded'));
+ });
- @fetch = (cb) ~>
- @fetching = true
- @update!
- obj <~ @opts.fetch do
- @mode == \iknow
- @limit
- null
- @users = obj.users
- @next = obj.next
- @fetching = false
- @update!
- if cb? then cb!
+ this.fetch = cb => {
+ this.update({
+ fetching: true
+ });
+ this.opts.fetch(this.mode == 'iknow', this.limit, null, obj => {
+ this.update({
+ fetching: false,
+ users: obj.users,
+ next: obj.next
+ });
+ if (cb) cb();
+ });
+ };
- @more = ~>
- @more-fetching = true
- @update!
- obj <~ @opts.fetch do
- @mode == \iknow
- @limit
- @cursor
- @users = @users.concat obj.users
- @next = obj.next
- @more-fetching = false
- @update!
+ this.more = () => {
+ this.update({
+ moreFetching: true
+ });
+ this.opts.fetch(this.mode == 'iknow', this.limit, this.cursor, obj => {
+ this.update({
+ moreFetching: false,
+ users: this.users.concat(obj.users),
+ next: obj.next
+ });
+ });
+ };
- @set-mode = (mode) ~>
- @update do
+ this.setMode = mode => {
+ this.update({
mode: mode
-
- @fetch!
+ });
+ this.fetch();
+ };
</script>
</mk-users-list>
diff --git a/src/web/app/desktop/tags/window.tag b/src/web/app/desktop/tags/window.tag
index 323c294c2c..3e7da90769 100644
--- a/src/web/app/desktop/tags/window.tag
+++ b/src/web/app/desktop/tags/window.tag
@@ -192,328 +192,354 @@
</style>
<script>
- @min-height = 40px
- @min-width = 200px
+ const contains = require('../../common/scripts/contains');
- @is-modal = if @opts.is-modal? then @opts.is-modal else false
- @can-close = if @opts.can-close? then @opts.can-close else true
- @is-flexible = !@opts.height?
- @can-resize = not @is-flexible
+ this.minHeight = 40;
+ this.minWidth = 200;
- @on \mount ~>
- @refs.main.style.width = @opts.width || \530px
- @refs.main.style.height = @opts.height || \auto
+ this.isModal = this.opts.isModal != null ? this.opts.isModal : false;
+ this.canClose = this.opts.canClose != null ? this.opts.canClose : true;
+ this.isFlexible = this.opts.height == null;
+ this.canResize = !this.isFlexible;
- @refs.main.style.top = \15%
- @refs.main.style.left = (window.inner-width / 2) - (@refs.main.offset-width / 2) + \px
+ this.on('mount', () => {
+ this.refs.main.style.width = this.opts.width || '530px';
+ this.refs.main.style.height = this.opts.height || 'auto';
- @refs.header.add-event-listener \contextmenu (e) ~>
- e.prevent-default!
+ this.refs.main.style.top = '15%';
+ this.refs.main.style.left = (window.innerWidth / 2) - (this.refs.main.offsetWidth / 2) + 'px';
- window.add-event-listener \resize @on-browser-resize
+ this.refs.header.addEventListener('contextmenu', e => {
+ e.preventDefault();
+ });
- @open!
+ window.addEventListener('resize', this.onBrowserResize);
- @on \unmount ~>
- window.remove-event-listener \resize @on-browser-resize
+ this.open();
+ });
- @on-browser-resize = ~>
- position = @refs.main.get-bounding-client-rect!
- browser-width = window.inner-width
- browser-height = window.inner-height
- window-width = @refs.main.offset-width
- window-height = @refs.main.offset-height
+ this.on('unmount', () => {
+ window.removeEventListener('resize', this.onBrowserResize);
+ });
- if position.left < 0
- @refs.main.style.left = 0
+ this.onBrowserResize = () => {
+ const position = this.refs.main.getBoundingClientRect();
+ const browserWidth = window.innerWidth;
+ const browserHeight = window.innerHeight;
+ const windowWidth = this.refs.main.offsetWidth;
+ const windowHeight = this.refs.main.offsetHeight;
+ if (position.left < 0) this.refs.main.style.left = 0;
+ if (position.top < 0) this.refs.main.style.top = 0;
+ if (position.left + windowWidth > browserWidth) this.refs.main.style.left = browserWidth - windowWidth + 'px';
+ if (position.top + windowHeight > browserHeight) this.refs.main.style.top = browserHeight - windowHeight + 'px';
+ };
- if position.top < 0
- @refs.main.style.top = 0
+ this.open = () => {
+ this.trigger('opening');
- if position.left + window-width > browser-width
- @refs.main.style.left = browser-width - window-width + \px
+ this.top();
- if position.top + window-height > browser-height
- @refs.main.style.top = browser-height - window-height + \px
-
- @open = ~>
- @trigger \opening
-
- @top!
-
- if @is-modal
- @refs.bg.style.pointer-events = \auto
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
+ if (this.isModal) {
+ this.refs.bg.style.pointerEvents = 'auto';
+ Velocity(this.refs.bg, 'finish', true);
+ Velocity(this.refs.bg, {
opacity: 1
- } {
- queue: false
- duration: 100ms
- easing: \linear
- }
+ }, {
+ queue: false,
+ duration: 100,
+ easing: 'linear'
+ });
+ }
- @refs.main.style.pointer-events = \auto
- Velocity @refs.main, \finish true
- Velocity @refs.main, {scale: 1.1} 0ms
- Velocity @refs.main, {
- opacity: 1
+ this.refs.main.style.pointerEvents = 'auto';
+ Velocity(this.refs.main, 'finish', true);
+ Velocity(this.refs.main, { scale: 1.1 }, 0);
+ Velocity(this.refs.main, {
+ opacity: 1,
scale: 1
- } {
- queue: false
- duration: 200ms
- easing: \ease-out
- }
+ }, {
+ queue: false,
+ duration: 200,
+ easing: 'ease-out'
+ });
- #@refs.main.focus!
+ //this.refs.main.focus();
- set-timeout ~>
- @trigger \opened
- , 300ms
+ setTimeout(() => {
+ this.trigger('opened');
+ }, 300);
+ };
- @close = ~>
- @trigger \closing
+ this.close = () => {
+ this.trigger('closing');
- if @is-modal
- @refs.bg.style.pointer-events = \none
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
+ if (this.isModal) {
+ this.refs.bg.style.pointerEvents = 'none';
+ Velocity(this.refs.bg, 'finish', true);
+ Velocity(this.refs.bg, {
opacity: 0
- } {
- queue: false
- duration: 300ms
- easing: \linear
- }
+ }, {
+ queue: false,
+ duration: 300,
+ easing: 'linear'
+ });
+ }
- @refs.main.style.pointer-events = \none
- Velocity @refs.main, \finish true
- Velocity @refs.main, {
- opacity: 0
+ this.refs.main.style.pointerEvents = 'none';
+ Velocity(this.refs.main, 'finish', true);
+ Velocity(this.refs.main, {
+ opacity: 0,
scale: 0.8
- } {
- queue: false
- duration: 300ms
+ }, {
+ queue: false,
+ duration: 300,
easing: [ 0.5, -0.5, 1, 0.5 ]
- }
+ });
- set-timeout ~>
- @trigger \closed
- , 300ms
+ setTimeout(() => {
+ this.trigger('closed');
+ }, 300);
+ };
- # 最前面へ移動します
- @top = ~>
- z = 0
+ // 最前面へ移動します
+ this.top = () => {
+ let z = 0;
- ws = document.query-selector-all \mk-window
- ws.for-each (w) !~>
- if w == @root then return
- m = w.query-selector ':scope > .main'
- mz = Number(document.default-view.get-computed-style m, null .z-index)
- if mz > z then z := mz
+ const ws = document.querySelectorAll('mk-window');
+ ws.forEach(w => {
+ if (w == this.root) return;
+ const m = w.querySelector(':scope > .main');
+ const mz = Number(document.defaultView.getComputedStyle(m, null).zIndex);
+ if (mz > z) z = mz;
+ });
- if z > 0
- @refs.main.style.z-index = z + 1
- if @is-modal then @refs.bg.style.z-index = z + 1
+ if (z > 0) {
+ this.refs.main.style.zIndex = z + 1;
+ if (this.isModal) this.refs.bg.style.zIndex = z + 1;
+ }
+ };
- @repel-move = (e) ~>
- e.stop-propagation!
- return true
+ this.repelMove = e => {
+ e.stopPropagation();
+ return true;
+ };
- @bg-click = ~>
- if @can-close
- @close!
+ this.bgClick = () => {
+ if (this.canClose) this.close();
+ };
- @on-body-mousedown = (e) ~>
- @top!
- true
+ this.onBodyMousedown = () => {
+ this.top();
+ };
- # ヘッダー掴み時
- @on-header-mousedown = (e) ~>
- e.prevent-default!
+ // ヘッダー掴み時
+ this.onHeaderMousedown = e => {
+ e.preventDefault();
- if not contains @refs.main, document.active-element
- @refs.main.focus!
+ if (!contains(this.refs.main, document.activeElement)) this.refs.main.focus();
- position = @refs.main.get-bounding-client-rect!
+ const position = this.refs.main.getBoundingClientRect();
- click-x = e.client-x
- click-y = e.client-y
- move-base-x = click-x - position.left
- move-base-y = click-y - position.top
- browser-width = window.inner-width
- browser-height = window.inner-height
- window-width = @refs.main.offset-width
- window-height = @refs.main.offset-height
+ const clickX = e.clientX;
+ const clickY = e.clientY;
+ const moveBaseX = clickX - position.left;
+ const moveBaseY = clickY - position.top;
+ const browserWidth = window.innerWidth;
+ const browserHeight = window.innerHeight;
+ const windowWidth = this.refs.main.offsetWidth;
+ const windowHeight = this.refs.main.offsetHeight;
- # 動かした時
- drag-listen (me) ~>
- move-left = me.client-x - move-base-x
- move-top = me.client-y - move-base-y
+ // 動かした時
+ dragListen(me => {
+ let moveLeft = me.clientX - moveBaseX;
+ let moveTop = me.clientY - moveBaseY;
- # 上はみ出し
- if move-top < 0
- move-top = 0
+ // 上はみ出し
+ if (moveTop < 0) moveTop = 0;
- # 左はみ出し
- if move-left < 0
- move-left = 0
+ // 左はみ出し
+ if (moveLeft < 0) moveLeft = 0;
- # 下はみ出し
- if move-top + window-height > browser-height
- move-top = browser-height - window-height
+ // 下はみ出し
+ if (moveTop + windowHeight > browserHeight) moveTop = browserHeight - windowHeight;
- # 右はみ出し
- if move-left + window-width > browser-width
- move-left = browser-width - window-width
+ // 右はみ出し
+ if (moveLeft + windowWidth > browserWidth) moveLeft = browserWidth - windowWidth;
- @refs.main.style.left = move-left + \px
- @refs.main.style.top = move-top + \px
+ this.refs.main.style.left = moveLeft + 'px';
+ this.refs.main.style.top = moveTop + 'px';
+ });
+ };
- # 上ハンドル掴み時
- @on-top-handle-mousedown = (e) ~>
- e.prevent-default!
+ // 上ハンドル掴み時
+ this.onTopHandleMousedown = e => {
+ e.preventDefault();
- base = e.client-y
- height = parse-int((get-computed-style @refs.main, '').height, 10)
- top = parse-int((get-computed-style @refs.main, '').top, 10)
+ const base = e.clientY;
+ const height = parseInt(getComputedStyle(this.refs.main, '').height, 10);
+ const top = parseInt(getComputedStyle(this.refs.main, '').top, 10);
- # 動かした時
- drag-listen (me) ~>
- move = me.client-y - base
- if top + move > 0
- if height + -move > @min-height
- @apply-transform-height height + -move
- @apply-transform-top top + move
- else # 最小の高さより小さくなろうとした時
- @apply-transform-height @min-height
- @apply-transform-top top + (height - @min-height)
- else # 上のはみ出し時
- @apply-transform-height top + height
- @apply-transform-top 0
+ // 動かした時
+ dragListen(me => {
+ const move = me.clientY - base;
+ if (top + move > 0) {
+ if (height + -move > this.minHeight) {
+ this.applyTransformHeight(height + -move);
+ this.applyTransformTop(top + move);
+ } else { // 最小の高さより小さくなろうとした時
+ this.applyTransformHeight(this.minHeight);
+ this.applyTransformTop(top + (height - this.minHeight));
+ }
+ } else { // 上のはみ出し時
+ this.applyTransformHeight(top + height);
+ this.applyTransformTop(0);
+ }
+ });
+ };
- # 右ハンドル掴み時
- @on-right-handle-mousedown = (e) ~>
- e.prevent-default!
+ // 右ハンドル掴み時
+ this.onRightHandleMousedown = e => {
+ e.preventDefault();
- base = e.client-x
- width = parse-int((get-computed-style @refs.main, '').width, 10)
- left = parse-int((get-computed-style @refs.main, '').left, 10)
- browser-width = window.inner-width
+ const base = e.clientX;
+ const width = parseInt(getComputedStyle(this.refs.main, '').width, 10);
+ const left = parseInt(getComputedStyle(this.refs.main, '').left, 10);
+ const browserWidth = window.innerWidth;
- # 動かした時
- drag-listen (me) ~>
- move = me.client-x - base
- if left + width + move < browser-width
- if width + move > @min-width
- @apply-transform-width width + move
- else # 最小の幅より小さくなろうとした時
- @apply-transform-width @min-width
- else # 右のはみ出し時
- @apply-transform-width browser-width - left
+ // 動かした時
+ dragListen(me => {
+ const move = me.clientX - base;
+ if (left + width + move < browserWidth) {
+ if (width + move > this.minWidth) {
+ this.applyTransformWidth(width + move);
+ } else { // 最小の幅より小さくなろうとした時
+ this.applyTransformWidth(this.minWidth);
+ }
+ } else { // 右のはみ出し時
+ this.applyTransformWidth(browserWidth - left);
+ }
+ });
+ };
- # 下ハンドル掴み時
- @on-bottom-handle-mousedown = (e) ~>
- e.prevent-default!
+ // 下ハンドル掴み時
+ this.onBottomHandleMousedown = e => {
+ e.preventDefault();
- base = e.client-y
- height = parse-int((get-computed-style @refs.main, '').height, 10)
- top = parse-int((get-computed-style @refs.main, '').top, 10)
- browser-height = window.inner-height
+ const base = e.clientY;
+ const height = parseInt(getComputedStyle(this.refs.main, '').height, 10);
+ const top = parseInt(getComputedStyle(this.refs.main, '').top, 10);
+ const browserHeight = window.innerHeight;
- # 動かした時
- drag-listen (me) ~>
- move = me.client-y - base
- if top + height + move < browser-height
- if height + move > @min-height
- @apply-transform-height height + move
- else # 最小の高さより小さくなろうとした時
- @apply-transform-height @min-height
- else # 下のはみ出し時
- @apply-transform-height browser-height - top
+ // 動かした時
+ dragListen(me => {
+ const move = me.clientY - base;
+ if (top + height + move < browserHeight) {
+ if (height + move > this.minHeight) {
+ this.applyTransformHeight(height + move);
+ } else { // 最小の高さより小さくなろうとした時
+ this.applyTransformHeight(this.minHeight);
+ }
+ } else { // 下のはみ出し時
+ this.applyTransformHeight(browserHeight - top);
+ }
+ });
+ };
- # 左ハンドル掴み時
- @on-left-handle-mousedown = (e) ~>
- e.prevent-default!
+ // 左ハンドル掴み時
+ this.onLeftHandleMousedown = e => {
+ e.preventDefault();
- base = e.client-x
- width = parse-int((get-computed-style @refs.main, '').width, 10)
- left = parse-int((get-computed-style @refs.main, '').left, 10)
+ const base = e.clientX;
+ const width = parseInt(getComputedStyle(this.refs.main, '').width, 10);
+ const left = parseInt(getComputedStyle(this.refs.main, '').left, 10);
- # 動かした時
- drag-listen (me) ~>
- move = me.client-x - base
- if left + move > 0
- if width + -move > @min-width
- @apply-transform-width width + -move
- @apply-transform-left left + move
- else # 最小の幅より小さくなろうとした時
- @apply-transform-width @min-width
- @apply-transform-left left + (width - @min-width)
- else # 左のはみ出し時
- @apply-transform-width left + width
- @apply-transform-left 0
+ // 動かした時
+ dragListen(me => {
+ const move = me.clientX - base;
+ if (left + move > 0) {
+ if (width + -move > this.minWidth) {
+ this.applyTransformWidth(width + -move);
+ this.applyTransformLeft(left + move);
+ } else { // 最小の幅より小さくなろうとした時
+ this.applyTransformWidth(this.minWidth);
+ this.applyTransformLeft(left + (width - this.minWidth));
+ }
+ } else { // 左のはみ出し時
+ this.applyTransformWidth(left + width);
+ this.applyTransformLeft(0);
+ }
+ });
+ };
- # 左上ハンドル掴み時
- @on-top-left-handle-mousedown = (e) ~>
- @on-top-handle-mousedown e
- @on-left-handle-mousedown e
+ // 左上ハンドル掴み時
+ this.onTopLeftHandleMousedown = e => {
+ this.onTopHandleMousedown(e);
+ this.onLeftHandleMousedown(e);
+ };
- # 右上ハンドル掴み時
- @on-top-right-handle-mousedown = (e) ~>
- @on-top-handle-mousedown e
- @on-right-handle-mousedown e
+ // 右上ハンドル掴み時
+ this.onTopRightHandleMousedown = e => {
+ this.onTopHandleMousedown(e);
+ this.onRightHandleMousedown(e);
+ };
- # 右下ハンドル掴み時
- @on-bottom-right-handle-mousedown = (e) ~>
- @on-bottom-handle-mousedown e
- @on-right-handle-mousedown e
+ // 右下ハンドル掴み時
+ this.onBottomRightHandleMousedown = e => {
+ this.onBottomHandleMousedown(e);
+ this.onRightHandleMousedown(e);
+ };
- # 左下ハンドル掴み時
- @on-bottom-left-handle-mousedown = (e) ~>
- @on-bottom-handle-mousedown e
- @on-left-handle-mousedown e
+ // 左下ハンドル掴み時
+ this.onBottomLeftHandleMousedown = e => {
+ this.onBottomHandleMousedown(e);
+ this.onLeftHandleMousedown(e);
+ };
- # 高さを適用
- @apply-transform-height = (height) ~>
- @refs.main.style.height = height + \px
+ // 高さを適用
+ this.applyTransformHeight = height => {
+ this.refs.main.style.height = height + 'px';
+ };
- # 幅を適用
- @apply-transform-width = (width) ~>
- @refs.main.style.width = width + \px
+ // 幅を適用
+ this.applyTransformWidth = width => {
+ this.refs.main.style.width = width + 'px';
+ };
- # Y座標を適用
- @apply-transform-top = (top) ~>
- @refs.main.style.top = top + \px
+ // Y座標を適用
+ this.applyTransformTop = top => {
+ this.refs.main.style.top = top + 'px';
+ };
- # X座標を適用
- @apply-transform-left = (left) ~>
- @refs.main.style.left = left + \px
+ // X座標を適用
+ this.applyTransformLeft = left => {
+ this.refs.main.style.left = left + 'px';
+ };
- function drag-listen fn
- window.add-event-listener \mousemove fn
- window.add-event-listener \mouseleave drag-clear.bind null fn
- window.add-event-listener \mouseup drag-clear.bind null fn
+ function dragListen(fn) {
+ window.addEventListener('mousemove', fn);
+ window.addEventListener('mouseleave', dragClear.bind(null, fn));
+ window.addEventListener('mouseup', dragClear.bind(null, fn));
+ }
- function drag-clear fn
- window.remove-event-listener \mousemove fn
- window.remove-event-listener \mouseleave drag-clear
- window.remove-event-listener \mouseup drag-clear
+ function dragClear(fn) {
+ window.removeEventListener('mousemove', fn);
+ window.removeEventListener('mouseleave', dragClear);
+ window.removeEventListener('mouseup', dragClear);
+ }
- @ondragover = (e) ~>
- e.data-transfer.drop-effect = \none
+ this.ondragover = e => {
+ e.dataTransfer.dropEffect = 'none';
+ };
- @on-keydown = (e) ~>
- if e.which == 27 # Esc
- if @can-close
- e.prevent-default!
- e.stop-propagation!
- @close!
+ this.onKeydown = e => {
+ if (e.which == 27) { // Esc
+ if (this.canClose) {
+ e.preventDefault();
+ e.stopPropagation();
+ this.close();
+ }
+ }
+ };
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
</script>
</mk-window>
diff --git a/src/web/app/dev/tags/new-app-form.tag b/src/web/app/dev/tags/new-app-form.tag
index 86e694e94e..e01be512fb 100644
--- a/src/web/app/dev/tags/new-app-form.tag
+++ b/src/web/app/dev/tags/new-app-form.tag
@@ -178,66 +178,75 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @nid-state = null
+ this.nidState = null;
- @on-change-nid = ~>
- nid = @refs.nid.value
+ this.onChangeNid = () => {
+ const nid = this.refs.nid.value;
- if nid == ''
- @nid-state = null
- @update!
- return
+ if (nid == '') {
+ this.update({
+ nidState: null
+ });
+ return;
+ }
- err = switch
- | not nid.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
- | nid.length < 3chars => \min-range
- | nid.length > 30chars => \max-range
- | _ => null
+ const err =
+ !nid.match(/^[a-zA-Z0-9\-]+$/) ? 'invalid-format' :
+ nid.length < 3 ? 'min-range' :
+ nid.length > 30 ? 'max-range' :
+ null;
- if err?
- @nid-state = err
- @update!
- else
- @nid-state = \wait
- @update!
+ if (err) {
+ this.update({
+ nidState: err
+ });
+ return;
+ }
- @api \app/name_id/available do
- name_id: nid
- .then (result) ~>
- if result.available
- @nid-state = \ok
- else
- @nid-state = \unavailable
- @update!
- .catch (err) ~>
- @nid-state = \error
- @update!
+ this.update({
+ nidState: 'wait'
+ });
- @onsubmit = ~>
- name = @refs.name.value
- nid = @refs.nid.value
- description = @refs.description.value
- cb = @refs.cb.value
- permission = []
+ this.api('app/name_id/available', {
+ name_id: nid
+ }).then(result => {
+ this.update({
+ nidState: result.available ? 'ok' : 'unavailable'
+ });
+ }).catch(err => {
+ this.update({
+ nidState: 'error'
+ });
+ });
+ };
- @refs.permission.query-selector-all \input .for-each (el) ~>
- if el.checked then permission.push el.value
+ this.onsubmit = () => {
+ const name = this.refs.name.value;
+ const nid = this.refs.nid.value;
+ const description = this.refs.description.value;
+ const cb = this.refs.cb.value;
+ const permission = [];
- locker = document.body.append-child document.create-element \mk-locker
+ this.refs.permission.querySelectorAll('input').forEach(el => {
+ if (el.checked) permission.push(el.value);
+ });
- @api \app/create do
- name: name
- name_id: nid
- description: description
- callback_url: cb
- permission: permission.join \,
- .then ~>
- location.href = '/apps'
- .catch ~>
- alert 'アプリの作成に失敗しました。再度お試しください。'
+ const locker = document.body.appendChild(document.createElement('mk-locker'));
- locker.parent-node.remove-child locker
+ this.api('app/create', {
+ name: name,
+ name_id: nid,
+ description: description,
+ callback_url: cb,
+ permission: permission.join(',')
+ }).then(() => {
+ location.href = '/apps';
+ }).catch(() => {
+ alert('アプリの作成に失敗しました。再度お試しください。');
+ locker.parentNode.removeChild(locker);
+ });
+ };
</script>
</mk-new-app-form>
diff --git a/src/web/app/dev/tags/pages/app.tag b/src/web/app/dev/tags/pages/app.tag
index 7eaf9decf6..b25e0d8595 100644
--- a/src/web/app/dev/tags/pages/app.tag
+++ b/src/web/app/dev/tags/pages/app.tag
@@ -12,19 +12,21 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @fetching = true
+ this.fetching = true;
- @on \mount ~>
- @api \app/show do
- app_id: @opts.app
- .then (app) ~>
- @app = app
- @fetching = false
- @update!
+ this.on('mount', () => {
+ this.api('app/show', {
+ app_id: this.opts.app
+ }).then(app => {
+ this.update({
+ fetching: false,
+ app: app
+ });
+ });
+ });
</script>
</mk-app-page>
diff --git a/src/web/app/dev/tags/pages/apps.tag b/src/web/app/dev/tags/pages/apps.tag
index 03806c6da5..43db70fcf2 100644
--- a/src/web/app/dev/tags/pages/apps.tag
+++ b/src/web/app/dev/tags/pages/apps.tag
@@ -13,18 +13,21 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @fetching = true
+ this.fetching = true;
- @on \mount ~>
- @api \my/apps
- .then (apps) ~>
- @fetching = false
- @apps = apps
- @update!
+ this.on('mount', () => {
+ this.api('my/apps').then(apps => {
+ this.fetching = false
+ this.apps = apps
+ this.update({
+ fetching: false,
+ apps: apps
+ });
+ });
+ });
</script>
</mk-apps-page>
diff --git a/src/web/app/dev/tags/pages/index.tag b/src/web/app/dev/tags/pages/index.tag
index ff2494212c..f863876fa7 100644
--- a/src/web/app/dev/tags/pages/index.tag
+++ b/src/web/app/dev/tags/pages/index.tag
@@ -2,10 +2,5 @@
<style>
:scope
display block
-
-
-
-
-
</style>
</mk-index>
diff --git a/src/web/app/mobile/tags/drive-selector.tag b/src/web/app/mobile/tags/drive-selector.tag
index 7039ac26a3..753a2c3a9b 100644
--- a/src/web/app/mobile/tags/drive-selector.tag
+++ b/src/web/app/mobile/tags/drive-selector.tag
@@ -56,19 +56,24 @@
</style>
<script>
- @files = []
+ this.files = [];
- @on \mount ~>
- @refs.browser.on \change-selected (files) ~>
- @files = files
- @update!
+ this.on('mount', () => {
+ this.refs.browser.on('change-selected', files => {
+ this.update({
+ files: files
+ });
+ });
+ });
- @cancel = ~>
- @trigger \canceled
- @unmount!
+ this.cancel = () => {
+ this.trigger('canceled');
+ this.unmount();
+ };
- @ok = ~>
- @trigger \selected @files
- @unmount!
+ this.ok = () => {
+ this.trigger('selected', this.files);
+ this.unmount();
+ };
</script>
</mk-drive-selector>
diff --git a/src/web/app/mobile/tags/drive.tag b/src/web/app/mobile/tags/drive.tag
index 06ed54e762..35b9b65417 100644
--- a/src/web/app/mobile/tags/drive.tag
+++ b/src/web/app/mobile/tags/drive.tag
@@ -3,7 +3,7 @@
<p onclick={ goRoot }><i class="fa fa-cloud"></i>ドライブ</p>
<virtual each={ folder in hierarchyFolders }>
<span><i class="fa fa-angle-right"></i></span>
- <p onclick={ _move }>{ folder.name }</p>
+ <p onclick={ move }>{ folder.name }</p>
</virtual>
<virtual if={ folder != null }>
<span><i class="fa fa-angle-right"></i></span>
@@ -14,7 +14,7 @@
<p>{ file.name }</p>
</virtual>
</nav>
- <div class="browser { loading: loading }" if={ file == null }>
+ <div class="browser { loading: fetching }" if={ file == null }>
<div class="folders" if={ folders.length > 0 }>
<virtual each={ folder in folders }>
<mk-drive-folder folder={ folder }></mk-drive-folder>
@@ -27,11 +27,11 @@
</virtual>
<p if={ moreFiles }>もっと読み込む</p>
</div>
- <div class="empty" if={ files.length == 0 && folders.length == 0 && !loading }>
+ <div class="empty" if={ files.length == 0 && folders.length == 0 && !fetching }>
<p if={ !folder == null }>ドライブには何もありません。</p>
<p if={ folder != null }>このフォルダーは空です</p>
</div>
- <div class="loading" if={ loading }>
+ <div class="loading" if={ fetching }>
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
@@ -128,250 +128,266 @@
</style>
<script>
- @mixin \api
- @mixin \stream
+ this.mixin('api');
+ this.mixin('stream');
- @files = []
- @folders = []
- @hierarchy-folders = []
- @selected-files = []
+ this.files = [];
+ this.folders = [];
+ this.hierarchyFolders = [];
+ this.selectedFiles = [];
- # 現在の階層(フォルダ)
- # * null でルートを表す
- @folder = null
+ // 現在の階層(フォルダ)
+ // * null でルートを表す
+ this.folder = null;
- @file = null
+ this.file = null;
- @is-select-mode = @opts.select? and @opts.select
- @multiple = if @opts.multiple? then @opts.multiple else false
+ this.isSelectMode = this.opts.select;
+ this.multiple =this.opts.multiple;
- @on \mount ~>
- @stream.on \drive_file_created @on-stream-drive-file-created
- @stream.on \drive_file_updated @on-stream-drive-file-updated
- @stream.on \drive_folder_created @on-stream-drive-folder-created
- @stream.on \drive_folder_updated @on-stream-drive-folder-updated
+ this.on('mount', () => {
+ this.stream.on('drive_file_created', this.onStreamDriveFileCreated);
+ this.stream.on('drive_file_updated', this.onStreamDriveFileUpdated);
+ this.stream.on('drive_folder_created', this.onStreamDriveFolderCreated);
+ this.stream.on('drive_folder_updated', this.onStreamDriveFolderUpdated);
- # Riotのバグでnullを渡しても""になる
- # https://github.com/riot/riot/issues/2080
- #if @opts.folder?
- if @opts.folder? and @opts.folder != ''
- @cd @opts.folder, true
- else if @opts.file? and @opts.file != ''
- @cf @opts.file, true
- else
- @load!
+ // Riotのバグでnullを渡しても""になる
+ // https://github.com/riot/riot/issues/2080
+ //if (this.opts.folder)
+ //if (this.opts.file)
+ if (this.opts.folder && this.opts.folder != '') {
+ this.cd(this.opts.folder, true);
+ } else if (this.opts.file && this.opts.file != '') {
+ this.cf(this.opts.file, true);
+ } else {
+ this.load();
+ }
+ });
- @on \unmount ~>
- @stream.off \drive_file_created @on-stream-drive-file-created
- @stream.off \drive_file_updated @on-stream-drive-file-updated
- @stream.off \drive_folder_created @on-stream-drive-folder-created
- @stream.off \drive_folder_updated @on-stream-drive-folder-updated
+ this.on('unmount', () => {
+ this.stream.off('drive_file_created', this.onStreamDriveFileCreated);
+ this.stream.off('drive_file_updated', this.onStreamDriveFileUpdated);
+ this.stream.off('drive_folder_created', this.onStreamDriveFolderCreated);
+ this.stream.off('drive_folder_updated', this.onStreamDriveFolderUpdated);
+ });
- @on-stream-drive-file-created = (file) ~>
- @add-file file, true
+ this.onStreamDriveFileCreated = file => {
+ this.addFile(file, true);
+ };
- @on-stream-drive-file-updated = (file) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- @remove-file file
- else
- @add-file file, true
+ this.onStreamDriveFileUpdated = file => {
+ const current = this.folder ? this.folder.id : null;
+ if (current != file.folder_id) {
+ this.removeFile(file);
+ } else {
+ this.addFile(file, true);
+ }
+ };
- @on-stream-drive-folder-created = (folder) ~>
- @add-folder folder, true
+ this.onStreamDriveFolderCreated = folder => {
+ this.addFolder(folder, true);
+ };
- @on-stream-drive-folder-updated = (folder) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- @remove-folder folder
- else
- @add-folder folder, true
+ this.onStreamDriveFolderUpdated = folder => {
+ const current = this.folder ? this.folder.id : null;
+ if (current != folder.parent_id) {
+ this.removeFolder(folder);
+ } else {
+ this.addFolder(folder, true);
+ }
+ };
- @_move = (ev) ~>
- @move ev.item.folder
+ this.move = ev => {
+ this.cd(ev.item.folder);
+ };
- @move = (target-folder) ~>
- @cd target-folder
+ this.cd = (target, silent = false) => {
+ this.file = null;
- @cd = (target-folder, silent = false) ~>
- @file = null
+ if (target == null) {
+ this.goRoot();
+ return;
+ } else if (typeof target == 'object') target = target.id;
- if target-folder? and typeof target-folder == \object
- target-folder = target-folder.id
+ this.update({
+ fetching: true
+ });
- if target-folder == null
- @go-root!
- return
+ this.api('drive/folders/show', {
+ folder_id: target
+ }).then(folder => {
+ this.folder = folder;
+ this.hierarchyFolders = [];
- @loading = true
- @update!
+ if (folder.parent) dive(folder.parent);
- @api \drive/folders/show do
- folder_id: target-folder
- .then (folder) ~>
- @folder = folder
- @hierarchy-folders = []
+ this.update();
+ this.trigger('open-folder', this.folder, silent);
+ this.load();
+ });
+ };
- x = (f) ~>
- @hierarchy-folders.unshift f
- if f.parent?
- x f.parent
+ this.addFolder = (folder, unshift = false) => {
+ const current = this.folder ? this.folder.id : null;
+ // 追加しようとしているフォルダが、今居る階層とは違う階層のものだったら中断
+ if (current != folder.parent_id) return;
- if folder.parent?
- x folder.parent
+ // 追加しようとしているフォルダを既に所有してたら中断
+ if (this.folders.some(f => f.id == folder.id)) return;
- @update!
- @trigger \open-folder @folder, silent
- @load!
- .catch (err, text-status) ->
- console.error err
+ if (unshift) {
+ this.folders.unshift(folder);
+ } else {
+ this.folders.push(folder);
+ }
- @add-folder = (folder, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- return
+ this.update();
+ };
- if (@folders.some (f) ~> f.id == folder.id)
- return
+ this.addFile = (file, unshift = false) => {
+ const current = this.folder ? this.folder.id : null;
+ // 追加しようとしているファイルが、今居る階層とは違う階層のものだったら中断
+ if (current != file.folder_id) return;
- if unshift
- @folders.unshift folder
- else
- @folders.push folder
+ if (this.files.some(f => f.id == file.id)) {
+ const exist = this.files.map(f => f.id).indexOf(file.id);
+ this.files[exist] = file;
+ this.update();
+ return;
+ }
- @update!
+ if (unshift) {
+ this.files.unshift(file);
+ } else {
+ this.files.push(file);
+ }
- @add-file = (file, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- return
+ this.update();
+ };
- if (@files.some (f) ~> f.id == file.id)
- exist = (@files.map (f) -> f.id).index-of file.id
- @files[exist] = file
- @update!
- return
+ this.removeFolder = folder => {
+ if (typeof folder == 'object') folder = folder.id;
+ this.folders = this.folders.filter(f => f.id != folder);
+ this.update();
+ };
- if unshift
- @files.unshift file
- else
- @files.push file
+ this.removeFile = file => {
+ if (typeof file == 'object') file = file.id;
+ this.files = this.files.filter(f => f.id != file);
+ this.update();
+ };
- @update!
+ this.goRoot = () => {
+ if (this.folder || this.file) {
+ this.update({
+ file: null,
+ folder: null,
+ hierarchyFolders: []
+ });
+ this.trigger('move-root');
+ this.load();
+ }
+ };
- @remove-folder = (folder) ~>
- if typeof folder == \object
- folder = folder.id
- @folders = @folders.filter (f) -> f.id != folder
- @update!
+ this.load = () => {
+ this.update({
+ folders: [],
+ files: [],
+ moreFolders: false,
+ moreFiles: false,
+ fetching: true
+ });
- @remove-file = (file) ~>
- if typeof file == \object
- file = file.id
- @files = @files.filter (f) -> f.id != file
- @update!
+ this.trigger('begin-load');
- @go-root = ~>
- if @folder != null or @file != null
- @file = null
- @folder = null
- @hierarchy-folders = []
- @update!
- @trigger \move-root
- @load!
+ let fetchedFolders = null;
+ let fetchedFiles = null;
- @load = ~>
- @folders = []
- @files = []
- @more-folders = false
- @more-files = false
- @loading = true
- @update!
+ const foldersMax = 20;
+ const filesMax = 20;
- @trigger \begin-load
+ // フォルダ一覧取得
+ this.api('drive/folders', {
+ folder_id: this.folder ? this.folder.id : null,
+ limit: foldersMax + 1
+ }).then(folders => {
+ if (folders.length == foldersMax + 1) {
+ this.moreFolders = true;
+ folders.pop();
+ }
+ fetchedFolders = folders;
+ complete();
+ });
- load-folders = null
- load-files = null
+ // ファイル一覧取得
+ this.api('drive/files', {
+ folder_id: this.folder ? this.folder.id : null,
+ limit: filesMax + 1
+ }).then(files => {
+ if (files.length == filesMax + 1) {
+ this.moreFiles = true;
+ files.pop();
+ }
+ fetchedFiles = files;
+ complete();
+ });
- folders-max = 20
- files-max = 20
+ let flag = false;
+ const complete = () => {
+ if (flag) {
+ fetchedFolders.forEach(this.addFolder);
+ fetchedFiles.forEach(this.addFile);
+ this.update({
+ fetching: false
+ });
+ // 一連の読み込みが完了したイベントを発行
+ this.trigger('loaded');
+ } else {
+ flag = true;
+ // 一連の読み込みが半分完了したイベントを発行
+ this.trigger('load-mid');
+ }
+ };
+ };
- # フォルダ一覧取得
- @api \drive/folders do
- folder_id: if @folder? then @folder.id else null
- limit: folders-max + 1
- .then (folders) ~>
- if folders.length == folders-max + 1
- @more-folders = true
- folders.pop!
- load-folders := folders
- complete!
- .catch (err, text-status) ~>
- console.error err
+ this.chooseFile = file => {
+ if (this.isSelectMode) {
+ if (this.selectedFiles.some(f => f.id == file.id)) {
+ this.selectedFiles = this.selectedFiles.filter(f => f.id != file.id);
+ } else {
+ this.selectedFiles.push(file);
+ }
+ this.update();
+ this.trigger('change-selected', this.selectedFiles);
+ } else {
+ this.cf(file);
+ }
+ };
- # ファイル一覧取得
- @api \drive/files do
- folder_id: if @folder? then @folder.id else null
- limit: files-max + 1
- .then (files) ~>
- if files.length == files-max + 1
- @more-files = true
- files.pop!
- load-files := files
- complete!
- .catch (err, text-status) ~>
- console.error err
+ this.cf = (file, silent = false) => {
+ if (typeof file == 'object') file = file.id;
- flag = false
- complete = ~>
- if flag
- load-folders.for-each (folder) ~>
- @add-folder folder
- load-files.for-each (file) ~>
- @add-file file
- @loading = false
- @update!
+ this.update({
+ fetching: true
+ });
- @trigger \loaded
- else
- flag := true
- @trigger \load-mid
-
- @choose-file = (file) ~>
- if @is-select-mode
- exist = @selected-files.some (f) ~> f.id == file.id
- if exist
- @selected-files = (@selected-files.filter (f) ~> f.id != file.id)
- else
- @selected-files.push file
- @update!
- @trigger \change-selected @selected-files
- else
- @cf file
-
- @cf = (file, silent = false) ~>
- if typeof file == \object
- file = file.id
-
- @loading = true
- @update!
-
- @api \drive/files/show do
+ this.api('drive/files/show', {
file_id: file
- .then (file) ~>
- @file = file
- @folder = null
- @hierarchy-folders = []
+ }).then(file => {
+ this.file = file;
+ this.folder = null;
+ this.hierarchyFolders = [];
- x = (f) ~>
- @hierarchy-folders.unshift f
- if f.parent?
- x f.parent
+ if (file.folder) dive(file.folder);
- if file.folder?
- x file.folder
+ this.update();
+ this.trigger('open-file', this.file, silent);
+ });
+ };
- @update!
- @trigger \open-file @file, silent
+ const dive = folder => {
+ this.hierarchyFolders.unshift(folder);
+ if (folder.parent) dive(folder.parent);
+ };
</script>
</mk-drive>
diff --git a/src/web/app/mobile/tags/drive/file-viewer.tag b/src/web/app/mobile/tags/drive/file-viewer.tag
index a0d4c44453..78a10b83b4 100644
--- a/src/web/app/mobile/tags/drive/file-viewer.tag
+++ b/src/web/app/mobile/tags/drive/file-viewer.tag
@@ -180,22 +180,23 @@
</style>
<script>
- @bytes-to-size = require '../../../common/scripts/bytes-to-size.js'
- @get-gcd = require '../../../common/scripts/gcd.js'
+ this.bytesToSize = require('../../../common/scripts/bytes-to-size.js');
+ this.getGcd = require('../../../common/scripts/gcd.js');
- @mixin \api
+ this.mixin('api');
- @file = @opts.file
- @kind = @file.type.split \/ .0
-
- @rename = ~>
- name = window.prompt '名前を変更' @file.name
- if name? and name != '' and name != @file.name
- @api \drive/files/update do
- file_id: @file.id
- name: name
- .then ~>
- @parent.cf @file, true
+ this.file = this.opts.file;
+ this.kind = this.file.type.split('/')[0];
+ this.rename = () => {
+ const name = window.prompt('名前を変更', this.file.name);
+ if (name == null || name == '' || name == this.file.name) return;
+ this.api('drive/files/update', {
+ file_id: this.file.id,
+ name: name
+ }).then(() => {
+ this.parent.cf(this.file, true);
+ });
+ };
</script>
</mk-drive-file-viewer>
diff --git a/src/web/app/mobile/tags/drive/file.tag b/src/web/app/mobile/tags/drive/file.tag
index 95f91e5ebc..4b8216219b 100644
--- a/src/web/app/mobile/tags/drive/file.tag
+++ b/src/web/app/mobile/tags/drive/file.tag
@@ -122,16 +122,18 @@
</style>
<script>
- @bytes-to-size = require '../../../common/scripts/bytes-to-size.js'
+ this.bytesToSize = require('../../../common/scripts/bytes-to-size');
- @browser = @parent
- @file = @opts.file
- @is-selected = @browser.selected-files.some (f) ~> f.id == @file.id
+ this.browser = this.parent;
+ this.file = this.opts.file;
+ this.isSelected = this.browser.selectedFiles.some(f => f.id == this.file.id);
- @browser.on \change-selected (selects) ~>
- @is-selected = selects.some (f) ~> f.id == @file.id
+ this.browser.on('change-selected', selections => {
+ this.isSelected = selections.some(f => f.id == this.file.id);
+ });
- @onclick = ~>
- @browser.choose-file @file
+ this.onclick = () => {
+ this.browser.chooseFile(this.file);
+ };
</script>
</mk-drive-file>
diff --git a/src/web/app/mobile/tags/drive/folder.tag b/src/web/app/mobile/tags/drive/folder.tag
index 82bef02625..27e86662c7 100644
--- a/src/web/app/mobile/tags/drive/folder.tag
+++ b/src/web/app/mobile/tags/drive/folder.tag
@@ -37,10 +37,11 @@
</style>
<script>
- @browser = @parent
- @folder = @opts.folder
+ this.browser = this.parent;
+ this.folder = this.opts.folder;
- @onclick = ~>
- @browser.move @folder
+ this.onclick = () => {
+ this.browser.cd(this.folder);
+ };
</script>
</mk-drive-folder>
diff --git a/src/web/app/mobile/tags/follow-button.tag b/src/web/app/mobile/tags/follow-button.tag
index ac7058aebd..ae6d19f593 100644
--- a/src/web/app/mobile/tags/follow-button.tag
+++ b/src/web/app/mobile/tags/follow-button.tag
@@ -48,58 +48,74 @@
</style>
<script>
- @mixin \api
- @mixin \is-promise
- @mixin \stream
+ this.mixin('api');
+ this.mixin('is-promise');
+ this.mixin('stream');
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @init = true
- @wait = false
+ this.user = null;
+ this.userPromise = this.isPromise(this.opts.user)
+ ? this.opts.user
+ : Promise.resolve(this.opts.user);
+ this.init = true;
+ this.wait = false;
- @on \mount ~>
- @user-promise.then (user) ~>
- @user = user
- @init = false
- @update!
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ this.on('mount', () => {
+ this.userPromise.then(user => {
+ this.update({
+ init: false,
+ user: user
+ });
+ this.stream.on('follow', this.onStreamFollow);
+ this.stream.on('unfollow', this.onStreamUnfollow);
+ });
+ });
- @on \unmount ~>
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ this.on('unmount', () => {
+ this.stream.off('follow', this.onStreamFollow);
+ this.stream.off('unfollow', this.onStreamUnfollow);
+ });
- @on-stream-follow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ this.onStreamFollow = user => {
+ if (user.id == this.user.id) {
+ this.update({
+ user: user
+ });
+ }
+ };
- @on-stream-unfollow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ this.onStreamUnfollow = user => {
+ if (user.id == this.user.id) {
+ this.update({
+ user: user
+ });
+ }
+ };
- @onclick = ~>
- @wait = true
- if @user.is_following
- @api \following/delete do
- user_id: @user.id
- .then ~>
- @user.is_following = false
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
- @update!
- else
- @api \following/create do
- user_id: @user.id
- .then ~>
- @user.is_following = true
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
- @update!
+ this.onclick = () => {
+ this.wait = true;
+ if (this.user.is_following) {
+ this.api('following/delete', {
+ user_id: this.user.id
+ }).then(() => {
+ this.user.is_following = false;
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.wait = false;
+ this.update();
+ });
+ } else {
+ this.api('following/create', {
+ user_id: this.user.id
+ }).then(() => {
+ this.user.is_following = true;
+ }).catch(err => {
+ console.error(err);
+ }).then(() => {
+ this.wait = false;
+ this.update();
+ });
+ }
+ };
</script>
</mk-follow-button>
diff --git a/src/web/app/mobile/tags/home-timeline.tag b/src/web/app/mobile/tags/home-timeline.tag
index 2aa9127144..2cb051f32a 100644
--- a/src/web/app/mobile/tags/home-timeline.tag
+++ b/src/web/app/mobile/tags/home-timeline.tag
@@ -3,41 +3,49 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \api
- @mixin \stream
+ this.mixin('api');
+ this.mixin('stream');
- @init = new Promise (res, rej) ~>
- @api \posts/timeline
- .then (posts) ~>
- res posts
- @trigger \loaded
+ this.init = new Promise((res, rej) => {
+ this.api('posts/timeline').then(posts => {
+ res(posts);
+ this.trigger('loaded');
+ });
+ });
- @on \mount ~>
- @stream.on \post @on-stream-post
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ this.on('mount', () => {
+ this.stream.on('post', this.onStreamPost);
+ this.stream.on('follow', this.onStreamFollow);
+ this.stream.on('unfollow', this.onStreamUnfollow);
+ });
- @on \unmount ~>
- @stream.off \post @on-stream-post
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ this.on('unmount', () => {
+ this.stream.off('post', this.onStreamPost);
+ this.stream.off('follow', this.onStreamFollow);
+ this.stream.off('unfollow', this.onStreamUnfollow);
+ });
- @more = ~>
- @api \posts/timeline do
- max_id: @refs.timeline.tail!.id
+ this.more = () => {
+ this.api('posts/timeline', {
+ max_id: this.refs.timeline.tail().id
+ });
+ };
- @on-stream-post = (post) ~>
- @is-empty = false
- @update!
- @refs.timeline.add-post post
+ this.onStreamPost = post => {
+ this.update({
+ isEmpty: false
+ });
+ this.refs.timeline.addPost(post);
+ };
- @on-stream-follow = ~>
- @fetch!
+ this.onStreamFollow = () => {
+ this.fetch();
+ };
- @on-stream-unfollow = ~>
- @fetch!
+ this.onStreamUnfollow = () => {
+ this.fetch();
+ };
</script>
</mk-home-timeline>
diff --git a/src/web/app/mobile/tags/home.tag b/src/web/app/mobile/tags/home.tag
index 78141ca9a7..2edfd656e4 100644
--- a/src/web/app/mobile/tags/home.tag
+++ b/src/web/app/mobile/tags/home.tag
@@ -13,8 +13,10 @@
</style>
<script>
- @on \mount ~>
- @refs.tl.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.tl.on('loaded', () => {
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-home>
diff --git a/src/web/app/mobile/tags/images-viewer.tag b/src/web/app/mobile/tags/images-viewer.tag
index 05dc744cdb..f3724f21b6 100644
--- a/src/web/app/mobile/tags/images-viewer.tag
+++ b/src/web/app/mobile/tags/images-viewer.tag
@@ -18,10 +18,11 @@
</style>
<script>
- @images = @opts.images
- @image = @images.0
+ this.images = this.opts.images;
+ this.image = this.images[0];
- @click = ~>
- window.open @image.url
+ this.click = () => {
+ window.open(this.image.url);
+ };
</script>
</mk-images-viewer>
diff --git a/src/web/app/mobile/tags/index.js b/src/web/app/mobile/tags/index.js
index 2a8f2161c2..dec2be3325 100644
--- a/src/web/app/mobile/tags/index.js
+++ b/src/web/app/mobile/tags/index.js
@@ -1,7 +1,6 @@
require('./ui.tag');
require('./ui-header.tag');
require('./ui-nav.tag');
-require('./stream-indicator.tag');
require('./page/entrance.tag');
require('./page/entrance/signin.tag');
require('./page/entrance/signup.tag');
diff --git a/src/web/app/mobile/tags/notification-preview.tag b/src/web/app/mobile/tags/notification-preview.tag
index c146c6f0f7..b93b92d919 100644
--- a/src/web/app/mobile/tags/notification-preview.tag
+++ b/src/web/app/mobile/tags/notification-preview.tag
@@ -107,7 +107,7 @@
</style>
<script>
- @mixin \get-post-summary
- @notification = @opts.notification
+ this.mixin('get-post-summary');
+ this.notification = this.opts.notification;
</script>
</mk-notification-preview>
diff --git a/src/web/app/mobile/tags/notification.tag b/src/web/app/mobile/tags/notification.tag
index b619c66980..d32e6b40ae 100644
--- a/src/web/app/mobile/tags/notification.tag
+++ b/src/web/app/mobile/tags/notification.tag
@@ -167,7 +167,7 @@
</style>
<script>
- @mixin \get-post-summary
- @notification = @opts.notification
+ this.mixin('get-post-summary');
+ this.notification = this.opts.notification;
</script>
</mk-notification>
diff --git a/src/web/app/mobile/tags/notifications.tag b/src/web/app/mobile/tags/notifications.tag
index 8207495795..e73877266e 100644
--- a/src/web/app/mobile/tags/notifications.tag
+++ b/src/web/app/mobile/tags/notifications.tag
@@ -57,37 +57,40 @@
</style>
<script>
- @mixin \api
- @mixin \stream
- @mixin \get-post-summary
+ this.mixin('api');
+ this.mixin('stream');
+ this.mixin('get-post-summary');
- @notifications = []
- @loading = true
+ this.notifications = [];
+ this.loading = true;
- @on \mount ~>
- @api \i/notifications
- .then (notifications) ~>
- @notifications = notifications
- @loading = false
- @update!
- @trigger \loaded
- .catch (err, text-status) ->
- console.error err
+ this.on('mount', () => {
+ this.api('i/notifications').then(notifications => {
+ this.update({
+ loading: false,
+ notifications: notifications
+ });
+ });
- @stream.on \notification @on-notification
+ this.stream.on('notification', this.onNotification);
+ });
- @on \unmount ~>
- @stream.off \notification @on-notification
+ this.on('unmount', () => {
+ this.stream.off('notification', this.onNotification);
+ });
- @on-notification = (notification) ~>
- @notifications.unshift notification
- @update!
+ this.onNotification = notification => {
+ this.notifications.unshift(notification);
+ this.update();
+ };
- @on \update ~>
- @notifications.for-each (notification) ~>
- date = (new Date notification.created_at).get-date!
- month = (new Date notification.created_at).get-month! + 1
- notification._date = date
- notification._datetext = month + '月 ' + date + '日'
+ this.on('update', () => {
+ this.notifications.forEach(notification => {
+ const date = new Date(notification.created_at).getDate();
+ const month = new Date(notification.created_at).getMonth() + 1;
+ notification._date = date;
+ notification._datetext = `${month}月 ${date}日`;
+ });
+ });
</script>
</mk-notifications>
diff --git a/src/web/app/mobile/tags/notify.tag b/src/web/app/mobile/tags/notify.tag
index aa45ce0cff..c97e70696c 100644
--- a/src/web/app/mobile/tags/notify.tag
+++ b/src/web/app/mobile/tags/notify.tag
@@ -16,23 +16,23 @@
</style>
<script>
- @on \mount ~>
- Velocity @root, {
- bottom: \0px
- } {
- duration: 500ms
- easing: \ease-out
- }
+ this.on('mount', () => {
+ Velocity(this.root, {
+ bottom: '0px'
+ }, {
+ duration: 500,
+ easing: 'ease-out'
+ });
- set-timeout ~>
- Velocity @root, {
- bottom: \-64px
- } {
- duration: 500ms
- easing: \ease-out
- complete: ~>
- @unmount!
- }
- , 6000ms
+ setTimeout(() => {
+ Velocity(this.root, {
+ bottom: '-64px'
+ }, {
+ duration: 500,
+ easing: 'ease-out',
+ complete: () => this.unmount()
+ });
+ }, 6000);
+ });
</script>
</mk-notify>
diff --git a/src/web/app/mobile/tags/page/drive.tag b/src/web/app/mobile/tags/page/drive.tag
index ef83e4d5ba..a064a05598 100644
--- a/src/web/app/mobile/tags/page/drive.tag
+++ b/src/web/app/mobile/tags/page/drive.tag
@@ -5,57 +5,65 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
+ this.mixin('ui');
+ this.mixin('ui-progress');
- @on \mount ~>
- document.title = 'Misskey Drive'
- @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
+ this.on('mount', () => {
+ document.title = 'Misskey Drive';
+ this.ui.trigger('title', '<i class="fa fa-cloud"></i>ドライブ');
- @refs.ui.refs.browser.on \begin-load ~>
- @Progress.start!
+ this.refs.ui.refs.browser.on('begin-load', () => {
+ this.Progress.start();
+ });
- @refs.ui.refs.browser.on \loaded-mid ~>
- @Progress.set 0.5
+ this.refs.ui.refs.browser.on('loaded-mid', () => {
+ this.Progress.set(0.5);
+ });
- @refs.ui.refs.browser.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.browser.on('loaded', () => {
+ this.Progress.done();
+ });
- @refs.ui.refs.browser.on \move-root ~>
- title = 'Misskey Drive'
+ this.refs.ui.refs.browser.on('move-root', () => {
+ const title = 'Misskey Drive';
- # Rewrite URL
- history.push-state null, title, '/i/drive'
+ // Rewrite URL
+ history.pushState(null, title, '/i/drive');
- document.title = title
- @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
+ document.title = title;
+ this.ui.trigger('title', '<i class="fa fa-cloud"></i>ドライブ');
+ });
- @refs.ui.refs.browser.on \open-folder (folder, silent) ~>
- title = folder.name + ' | Misskey Drive'
+ this.refs.ui.refs.browser.on('open-folder', (folder, silent) => {
+ const title = folder.name + ' | Misskey Drive';
- if !silent
- # Rewrite URL
- history.push-state null, title, '/i/drive/folder/' + folder.id
+ if (!silent) {
+ // Rewrite URL
+ history.pushState(null, title, '/i/drive/folder/' + folder.id);
+ }
- document.title = title
- # TODO: escape html characters in folder.name
- @ui.trigger \title '<i class="fa fa-folder-open"></i>' + folder.name
+ document.title = title;
+ // TODO: escape html characters in folder.name
+ this.ui.trigger('title', '<i class="fa fa-folder-open"></i>' + folder.name);
+ });
- @refs.ui.refs.browser.on \open-file (file, silent) ~>
- title = file.name + ' | Misskey Drive'
+ this.refs.ui.refs.browser.on('open-file', (file, silent) => {
+ const title = file.name + ' | Misskey Drive';
- if !silent
- # Rewrite URL
- history.push-state null, title, '/i/drive/file/' + file.id
+ if (!silent) {
+ // Rewrite URL
+ history.pushState(null, title, '/i/drive/file/' + file.id);
+ }
- document.title = title
- # TODO: escape html characters in file.name
- @ui.trigger \title '<mk-file-type-icon class="icon"></mk-file-type-icon>' + file.name
- riot.mount \mk-file-type-icon do
+ document.title = title;
+ // TODO: escape html characters in file.name
+ this.ui.trigger('title', '<mk-file-type-icon class="icon"></mk-file-type-icon>' + file.name);
+ riot.mount('mk-file-type-icon', {
type: file.type
-
+ });
+ });
+ });
</script>
</mk-drive-page>
diff --git a/src/web/app/mobile/tags/page/entrance.tag b/src/web/app/mobile/tags/page/entrance.tag
index 424c58da5d..452dff992e 100644
--- a/src/web/app/mobile/tags/page/entrance.tag
+++ b/src/web/app/mobile/tags/page/entrance.tag
@@ -43,18 +43,24 @@
</style>
<script>
- @mode = \signin
+ this.mode = 'signin';
- @signup = ~>
- @mode = \signup
- @update!
+ this.signup = () => {
+ this.update({
+ mode: 'signup'
+ });
+ };
- @signin = ~>
- @mode = \signin
- @update!
+ this.signin = () => {
+ this.update({
+ mode: 'signin'
+ });
+ };
- @introduction = ~>
- @mode = \introduction
- @update!
+ this.introduction = () => {
+ this.update({
+ mode: 'introduction'
+ });
+ };
</script>
</mk-entrance>
diff --git a/src/web/app/mobile/tags/page/entrance/signup.tag b/src/web/app/mobile/tags/page/entrance/signup.tag
index 5209543886..c4b3ee9f38 100644
--- a/src/web/app/mobile/tags/page/entrance/signup.tag
+++ b/src/web/app/mobile/tags/page/entrance/signup.tag
@@ -34,9 +34,5 @@
> i
padding 14px
-
-
-
-
</style>
</mk-entrance-signup>
diff --git a/src/web/app/mobile/tags/page/home.tag b/src/web/app/mobile/tags/page/home.tag
index 947e119b09..c93803fb02 100644
--- a/src/web/app/mobile/tags/page/home.tag
+++ b/src/web/app/mobile/tags/page/home.tag
@@ -5,41 +5,47 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \i
- @mixin \ui
- @mixin \ui-progress
- @mixin \stream
- @mixin \get-post-summary
+ this.mixin('i');
+ this.mixin('ui');
+ this.mixin('ui-progress');
+ this.mixin('stream');
+ this.mixin('get-post-summary');
- @unread-count = 0
+ this.unreadCount = 0;
- @on \mount ~>
+ this.on('mount', () => {
document.title = 'Misskey'
- @ui.trigger \title '<i class="fa fa-home"></i>ホーム'
+ this.ui.trigger('title', '<i class="fa fa-home"></i>ホーム');
- @Progress.start!
+ this.Progress.start();
- @stream.on \post @on-stream-post
- document.add-event-listener \visibilitychange @window-on-visibilitychange, false
+ this.stream.on('post', this.onStreamPost);
+ document.addEventListener('visibilitychange', this.onVisibilitychange, false);
- @refs.ui.refs.home.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.home.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
- @on \unmount ~>
- @stream.off \post @on-stream-post
- document.remove-event-listener \visibilitychange @window-on-visibilitychange
+ this.on('unmount', () => {
+ this.stream.off('post', this.onStreamPost);
+ document.removeEventListener('visibilitychange', this.onVisibilitychange);
+ });
- @on-stream-post = (post) ~>
- if document.hidden and post.user_id !== @I.id
- @unread-count++
- document.title = '(' + @unread-count + ') ' + @get-post-summary post
+ this.onStreamPost = post => {
+ if (document.hidden && post.user_id !== this.I.id) {
+ this.unreadCount++;
+ document.title = `(${this.unreadCount}) ${this.getPostSummary(post)}`;
+ }
+ };
- @window-on-visibilitychange = ~>
- if !document.hidden
- @unread-count = 0
- document.title = 'Misskey'
+ this.onVisibilitychange = () => {
+ if (!document.hidden) {
+ this.unreadCount = 0;
+ document.title = 'Misskey';
+ }
+ };
</script>
</mk-home-page>
diff --git a/src/web/app/mobile/tags/page/messaging-room.tag b/src/web/app/mobile/tags/page/messaging-room.tag
index 2216d0c460..29657802a6 100644
--- a/src/web/app/mobile/tags/page/messaging-room.tag
+++ b/src/web/app/mobile/tags/page/messaging-room.tag
@@ -7,21 +7,24 @@
display block
</style>
<script>
- @mixin \api
- @mixin \ui
+ this.mixin('api');
+ this.mixin('ui');
- @fetching = true
+ this.fetching = true;
- @on \mount ~>
- @api \users/show do
- username: @opts.username
- .then (user) ~>
- @fetching = false
- @user = user
- @update!
+ this.on('mount', () => {
+ this.api('users/show', {
+ username: this.opts.username
+ }).then(user => {
+ this.update({
+ fetching: false,
+ user: user
+ });
- document.title = 'メッセージ: ' + user.name + ' | Misskey'
- # TODO: ユーザー名をエスケープ
- @ui.trigger \title '<i class="fa fa-comments-o"></i>' + user.name
+ document.title = `メッセージ: ${user.name} | Misskey`;
+ // TODO: ユーザー名をエスケープ
+ this.ui.trigger('title', '<i class="fa fa-comments-o"></i>' + user.name);
+ });
+ });
</script>
</mk-messaging-room-page>
diff --git a/src/web/app/mobile/tags/page/messaging.tag b/src/web/app/mobile/tags/page/messaging.tag
index dd277f46e9..fd94cbfa4a 100644
--- a/src/web/app/mobile/tags/page/messaging.tag
+++ b/src/web/app/mobile/tags/page/messaging.tag
@@ -7,15 +7,16 @@
display block
</style>
<script>
- @mixin \ui
- @mixin \page
+ this.mixin('ui');
+ this.mixin('page');
- @on \mount ~>
- document.title = 'Misskey | メッセージ'
- @ui.trigger \title '<i class="fa fa-comments-o"></i>メッセージ'
-
- @refs.ui.refs.index.on \navigate-user (user) ~>
- @page '/i/messaging/' + user.username
+ this.on('mount', () => {
+ document.title = 'Misskey | メッセージ';
+ this.ui.trigger('title', '<i class="fa fa-comments-o"></i>メッセージ');
+ this.refs.ui.refs.index.on('navigate-user', user => {
+ this.page('/i/messaging/' + user.username);
+ });
+ });
</script>
</mk-messaging-page>
diff --git a/src/web/app/mobile/tags/page/new-post.tag b/src/web/app/mobile/tags/page/new-post.tag
index e323f0d955..3ba549c8dc 100644
--- a/src/web/app/mobile/tags/page/new-post.tag
+++ b/src/web/app/mobile/tags/page/new-post.tag
@@ -3,10 +3,5 @@
<style>
:scope
display block
-
-
-
-
-
</style>
</mk-new-post-page>
diff --git a/src/web/app/mobile/tags/page/notifications.tag b/src/web/app/mobile/tags/page/notifications.tag
index 18b6cc2834..1d35d79edc 100644
--- a/src/web/app/mobile/tags/page/notifications.tag
+++ b/src/web/app/mobile/tags/page/notifications.tag
@@ -8,16 +8,18 @@
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
+ this.mixin('ui');
+ this.mixin('ui-progress');
- @on \mount ~>
- document.title = 'Misskey | 通知'
- @ui.trigger \title '<i class="fa fa-bell-o"></i>通知'
+ this.on('mount', () => {
+ document.title = 'Misskey | 通知';
+ this.ui.trigger('title', '<i class="fa fa-bell-o"></i>通知');
- @Progress.start!
+ this.Progress.start();
- @refs.ui.refs.notifications.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.notifications.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
</script>
</mk-notifications-page>
diff --git a/src/web/app/mobile/tags/page/post.tag b/src/web/app/mobile/tags/page/post.tag
index a8ffb1c3c7..2c4eba37a0 100644
--- a/src/web/app/mobile/tags/page/post.tag
+++ b/src/web/app/mobile/tags/page/post.tag
@@ -18,21 +18,24 @@
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
+ this.mixin('ui');
+ this.mixin('ui-progress');
- @post = @opts.post
+ this.post = this.opts.post;
- @on \mount ~>
- document.title = 'Misskey'
- @ui.trigger \title '<i class="fa fa-sticky-note-o"></i>投稿'
+ this.on('mount', () => {
+ document.title = 'Misskey';
+ this.ui.trigger('title', '<i class="fa fa-sticky-note-o"></i>投稿');
- @Progress.start!
+ this.Progress.start();
- @refs.ui.refs.post.on \post-fetched ~>
- @Progress.set 0.5
+ this.refs.ui.refs.post.on('post-fetched', () => {
+ this.Progress.set(0.5);
+ });
- @refs.ui.refs.post.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.post.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
</script>
</mk-post-page>
diff --git a/src/web/app/mobile/tags/page/search.tag b/src/web/app/mobile/tags/page/search.tag
index 31de7d9625..fbf741f2e6 100644
--- a/src/web/app/mobile/tags/page/search.tag
+++ b/src/web/app/mobile/tags/page/search.tag
@@ -5,20 +5,21 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
+ this.mixin('ui');
+ this.mixin('ui-progress');
- @on \mount ~>
- document.title = '検索: ' + @opts.query + ' | Misskey'
- # TODO: クエリをHTMLエスケープ
- @ui.trigger \title '<i class="fa fa-search"></i>' + @opts.query
+ this.on('mount', () => {
+ document.title = `検索: ${this.opts.query} | Misskey`
+ // TODO: クエリをHTMLエスケープ
+ this.ui.trigger('title', '<i class="fa fa-search"></i>' + this.opts.query);
- @Progress.start!
+ this.Progress.start();
- @refs.ui.refs.search.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.search.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
</script>
</mk-search-page>
diff --git a/src/web/app/mobile/tags/page/settings.tag b/src/web/app/mobile/tags/page/settings.tag
index 99e7569f5b..59974e8cb6 100644
--- a/src/web/app/mobile/tags/page/settings.tag
+++ b/src/web/app/mobile/tags/page/settings.tag
@@ -13,10 +13,11 @@
display block
</style>
<script>
- @mixin \ui
+ this.mixin('ui');
- @on \mount ~>
- document.title = 'Misskey | 設定'
- @ui.trigger \title '<i class="fa fa-cog"></i>設定'
+ this.on('mount', () => {
+ document.title = 'Misskey | 設定';
+ this.ui.trigger('title', '<i class="fa fa-cog"></i>設定');
+ });
</script>
</mk-settings-page>
diff --git a/src/web/app/mobile/tags/page/settings/api.tag b/src/web/app/mobile/tags/page/settings/api.tag
index 69f4a47db0..e4f954f51a 100644
--- a/src/web/app/mobile/tags/page/settings/api.tag
+++ b/src/web/app/mobile/tags/page/settings/api.tag
@@ -7,10 +7,11 @@
display block
</style>
<script>
- @mixin \ui
+ this.mixin('ui');
- @on \mount ~>
- document.title = 'Misskey | API'
- @ui.trigger \title '<i class="fa fa-key"></i>API'
+ this.on('mount', () => {
+ document.title = 'Misskey | API';
+ this.ui.trigger('title', '<i class="fa fa-key"></i>API');
+ });
</script>
</mk-api-info-page>
diff --git a/src/web/app/mobile/tags/page/settings/authorized-apps.tag b/src/web/app/mobile/tags/page/settings/authorized-apps.tag
index abb8ba0fc0..84904c91e5 100644
--- a/src/web/app/mobile/tags/page/settings/authorized-apps.tag
+++ b/src/web/app/mobile/tags/page/settings/authorized-apps.tag
@@ -7,10 +7,11 @@
display block
</style>
<script>
- @mixin \ui
+ this.mixin('ui');
- @on \mount ~>
- document.title = 'Misskey | アプリケーション'
- @ui.trigger \title '<i class="fa fa-puzzle-piece"></i>アプリケーション'
+ this.on('mount', () => {
+ document.title = 'Misskey | アプリケーション';
+ this.ui.trigger('title', '<i class="fa fa-puzzle-piece"></i>アプリケーション');
+ });
</script>
</mk-authorized-apps-page>
diff --git a/src/web/app/mobile/tags/page/settings/signin.tag b/src/web/app/mobile/tags/page/settings/signin.tag
index 5886b53f9a..874cdf4856 100644
--- a/src/web/app/mobile/tags/page/settings/signin.tag
+++ b/src/web/app/mobile/tags/page/settings/signin.tag
@@ -7,10 +7,11 @@
display block
</style>
<script>
- @mixin \ui
+ this.mixin('ui');
- @on \mount ~>
- document.title = 'Misskey | ログイン履歴'
- @ui.trigger \title '<i class="fa fa-sign-in"></i>ログイン履歴'
+ this.on('mount', () => {
+ document.title = 'Misskey | ログイン履歴';
+ this.ui.trigger('title', '<i class="fa fa-sign-in"></i>ログイン履歴');
+ });
</script>
</mk-signin-history-page>
diff --git a/src/web/app/mobile/tags/page/settings/twitter.tag b/src/web/app/mobile/tags/page/settings/twitter.tag
index f6cde2e5a5..2026ab7daf 100644
--- a/src/web/app/mobile/tags/page/settings/twitter.tag
+++ b/src/web/app/mobile/tags/page/settings/twitter.tag
@@ -7,10 +7,11 @@
display block
</style>
<script>
- @mixin \ui
+ this.mixin('ui');
- @on \mount ~>
- document.title = 'Misskey | Twitter連携'
- @ui.trigger \title '<i class="fa fa-twitter"></i>Twitter連携'
+ this.on('mount', () => {
+ document.title = 'Misskey | Twitter連携';
+ this.ui.trigger('title', '<i class="fa fa-twitter"></i>Twitter連携');
+ });
</script>
</mk-twitter-setting-page>
diff --git a/src/web/app/mobile/tags/page/user-followers.tag b/src/web/app/mobile/tags/page/user-followers.tag
index 5856e60e02..249897be2c 100644
--- a/src/web/app/mobile/tags/page/user-followers.tag
+++ b/src/web/app/mobile/tags/page/user-followers.tag
@@ -5,32 +5,34 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
- @mixin \api
-
- @fetching = true
- @user = null
+ this.mixin('ui');
+ this.mixin('ui-progress');
+ this.mixin('api');
- @on \mount ~>
- @Progress.start!
+ this.fetching = true;
+ this.user = null;
- @api \users/show do
- username: @opts.user
- .then (user) ~>
- @user = user
- @fetching = false
+ this.on('mount', () => {
+ this.Progress.start();
- document.title = user.name + 'のフォロワー | Misskey'
- # TODO: ユーザー名をエスケープ
- @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロワー'
+ this.api('users/show', {
+ username: this.opts.user
+ }).then(user => {
+ this.update({
+ fetching: false,
+ user: user
+ });
- @update!
+ document.title = user.name + 'のフォロワー | Misskey';
+ // TODO: ユーザー名をエスケープ
+ this.ui.trigger('title', '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロワー');
- @refs.ui.refs.list.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.list.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
+ });
</script>
</mk-user-followers-page>
diff --git a/src/web/app/mobile/tags/page/user-following.tag b/src/web/app/mobile/tags/page/user-following.tag
index 14b006d3f9..a682715a02 100644
--- a/src/web/app/mobile/tags/page/user-following.tag
+++ b/src/web/app/mobile/tags/page/user-following.tag
@@ -5,32 +5,34 @@
<style>
:scope
display block
-
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
- @mixin \api
-
- @fetching = true
- @user = null
+ this.mixin('ui');
+ this.mixin('ui-progress');
+ this.mixin('api');
- @on \mount ~>
- @Progress.start!
+ this.fetching = true;
+ this.user = null;
- @api \users/show do
- username: @opts.user
- .then (user) ~>
- @user = user
- @fetching = false
+ this.on('mount', () => {
+ this.Progress.start();
- document.title = user.name + 'のフォロー | Misskey'
- # TODO: ユーザー名をエスケープ
- @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロー'
+ this.api('users/show', {
+ username: this.opts.user
+ }).then(user => {
+ this.update({
+ fetching: false,
+ user: user
+ });
- @update!
+ document.title = user.name + 'のフォロー | Misskey';
+ // TODO: ユーザー名をエスケープ
+ this.ui.trigger('title', '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロー');
- @refs.ui.refs.list.on \loaded ~>
- @Progress.done!
+ this.refs.ui.refs.list.on('loaded', () => {
+ this.Progress.done();
+ });
+ });
+ });
</script>
</mk-user-following-page>
diff --git a/src/web/app/mobile/tags/page/user.tag b/src/web/app/mobile/tags/page/user.tag
index 0ac8ed4e25..2a0e48426f 100644
--- a/src/web/app/mobile/tags/page/user.tag
+++ b/src/web/app/mobile/tags/page/user.tag
@@ -8,18 +8,20 @@
</style>
<script>
- @mixin \ui
- @mixin \ui-progress
+ this.mixin('ui');
+ this.mixin('ui-progress');
- @user = @opts.user
+ this.user = this.opts.user;
- @on \mount ~>
- @Progress.start!
+ this.on('mount', () => {
+ this.Progress.start();
- @refs.ui.refs.user.on \loaded (user) ~>
- @Progress.done!
- document.title = user.name + ' | Misskey'
- # TODO: ユーザー名をエスケープ
- @ui.trigger \title '<i class="fa fa-user"></i>' + user.name
+ this.refs.ui.refs.user.on('loaded', user => {
+ this.Progress.done();
+ document.title = user.name + ' | Misskey';
+ // TODO: ユーザー名をエスケープ
+ this.ui.trigger('title', '<i class="fa fa-user"></i>' + user.name);
+ });
+ });
</script>
</mk-user-page>
diff --git a/src/web/app/mobile/tags/post-detail.tag b/src/web/app/mobile/tags/post-detail.tag
index 3856df0800..e8149e0982 100644
--- a/src/web/app/mobile/tags/post-detail.tag
+++ b/src/web/app/mobile/tags/post-detail.tag
@@ -329,102 +329,124 @@
</style>
<script>
- @mixin \api
- @mixin \text
- @mixin \get-post-summary
- @mixin \open-post-form
+ this.mixin('api');
+ this.mixin('text');
+ this.mixin('get-post-summary');
+ this.mixin('open-post-form');
- @fetching = true
- @loading-context = false
- @content = null
- @post = null
+ this.fetching = true;
+ this.loadingContext = false;
+ this.content = null;
+ this.post = null;
- @on \mount ~>
- @api \posts/show do
- post_id: @opts.post
- .then (post) ~>
- @post = post
- @is-repost = @post.repost?
- @p = if @is-repost then @post.repost else @post
- @summary = @get-post-summary @p
- @trigger \loaded
- @fetching = false
- @update!
+ this.on('mount', () => {
+ this.api('posts/show', {
+ post_id: this.opts.post
+ }).then(post => {
+ const isRepost = post.repost != null;
+ const p = isRepost ? post.repost : post;
+ this.update({
+ fetching: false,
+ post: post,
+ isRepost: isRepost,
+ p: p
+ });
- if @p.text?
- tokens = @analyze @p.text
- @refs.text.innerHTML = @compile tokens
+ this.trigger('loaded');
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ if (this.p.text) {
+ const tokens = this.analyze(this.p.text);
- # URLをプレビュー
+ this.refs.text.innerHTML = this.compile(tokens);
+
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
+
+ // URLをプレビュー
tokens
- .filter (t) -> t.type == \link
- .map (t) ~>
- @preview = @refs.text.append-child document.create-element \mk-url-preview
- riot.mount @preview, do
- url: t.content
+ .filter(t => t.type == 'link')
+ .map(t => {
+ riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
+ url: t.content
+ });
+ });
+ }
- # Get likes
- @api \posts/likes do
- post_id: @p.id
+ // Get likes
+ this.api('posts/likes', {
+ post_id: this.p.id,
limit: 8
- .then (likes) ~>
- @likes = likes
- @update!
+ }).then(likes => {
+ this.update({
+ likes: likes
+ });
+ });
- # Get reposts
- @api \posts/reposts do
- post_id: @p.id
+ // Get reposts
+ this.api('posts/reposts', {
+ post_id: this.p.id,
limit: 8
- .then (reposts) ~>
- @reposts = reposts
- @update!
+ }).then(reposts => {
+ this.update({
+ reposts: reposts
+ });
+ });
- # Get replies
- @api \posts/replies do
- post_id: @p.id
+ // Get replies
+ this.api('posts/replies', {
+ post_id: this.p.id,
limit: 8
- .then (replies) ~>
- @replies = replies
- @update!
+ }).then(replies => {
+ this.update({
+ replies: replies
+ });
+ });
+ });
+ });
- @reply = ~>
- @open-post-form do
- reply: @p
+ this.reply = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-post-form-window')), {
+ reply: this.p
+ });
+ };
- @repost = ~>
- text = window.prompt '「' + @summary + '」をRepost'
- if text?
- @api \posts/create do
- repost_id: @p.id
- text: if text == '' then undefined else text
+ this.repost = () => {
+ riot.mount(document.body.appendChild(document.createElement('mk-repost-form-window')), {
+ post: this.p
+ });
+ };
- @like = ~>
- if @p.is_liked
- @api \posts/likes/delete do
- post_id: @p.id
- .then ~>
- @p.is_liked = false
- @update!
- else
- @api \posts/likes/create do
- post_id: @p.id
- .then ~>
- @p.is_liked = true
- @update!
+ this.like = () => {
+ if (this.p.is_liked) {
+ this.api('posts/likes/delete', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = false;
+ this.update();
+ });
+ } else {
+ this.api('posts/likes/create', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = true;
+ this.update();
+ });
+ }
+ };
- @load-context = ~>
- @loading-context = true
+ this.loadContext = () => {
+ this.loadingContext = true;
- # Get context
- @api \posts/context do
- post_id: @p.reply_to_id
- .then (context) ~>
- @context = context.reverse!
- @loading-context = false
- @update!
+ // Fetch context
+ this.api('posts/context', {
+ post_id: this.p.reply_to_id
+ }).then(context => {
+ this.update({
+ loadContext: false,
+ content: context.reverse()
+ });
+ });
+ };
</script>
</mk-post-detail>
diff --git a/src/web/app/mobile/tags/post-form.tag b/src/web/app/mobile/tags/post-form.tag
index 3d98a9832f..353db01540 100644
--- a/src/web/app/mobile/tags/post-form.tag
+++ b/src/web/app/mobile/tags/post-form.tag
@@ -10,7 +10,7 @@
</header>
<div class="form">
<mk-post-preview if={ opts.reply } post={ opts.reply }></mk-post-preview>
- <textarea ref="text" disabled={ wait } oninput={ update } onkeypress={ onkeypress } onpaste={ onpaste } placeholder={ opts.reply ? 'この投稿への返信...' : 'いまどうしてる?' }></textarea>
+ <textarea ref="text" disabled={ wait } oninput={ update } onkeydown={ onkeydown } onpaste={ onpaste } placeholder={ opts.reply ? 'この投稿への返信...' : 'いまどうしてる?' }></textarea>
<div class="attaches" if={ files.length != 0 }>
<ul class="files" ref="attaches">
<li class="file" each={ files }>
@@ -182,103 +182,111 @@
</style>
<script>
- get-cat = require '../../common/scripts/get-cat'
+ const getCat = require('../../common/scripts/get-cat');
- @mixin \api
+ this.mixin('api');
- @wait = false
- @uploadings = []
- @files = []
- @poll = false
+ this.wait = false;
+ this.uploadings = [];
+ this.files = [];
+ this.poll = false;
- @on \mount ~>
- @refs.uploader.on \uploaded (file) ~>
- @add-file file
+ this.on('mount', () => {
+ this.refs.uploader.on('uploaded', file => {
+ this.addFile(file);
+ });
- @refs.uploader.on \change-uploads (uploads) ~>
- @trigger \change-uploading-files uploads
+ this.refs.uploader.on('change-uploads', uploads => {
+ this.trigger('change-uploading-files', uploads);
+ });
- @refs.text.focus!
+ this.refs.text.focus();
+ });
- @onkeypress = (e) ~>
- if (e.char-code == 10 || e.char-code == 13) && e.ctrl-key
- @post!
- else
- return true
+ this.onkeydown = e => {
+ if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey)) this.post();
+ };
- @onpaste = (e) ~>
- data = e.clipboard-data
- items = data.items
- for i from 0 to items.length - 1
- item = items[i]
- switch (item.kind)
- | \file =>
- @upload item.get-as-file!
- return true
+ this.onpaste = e => {
+ e.clipboardData.items.forEach(item => {
+ if (item.kind == 'file') {
+ this.upload(item.getAsFile());
+ }
+ });
+ };
- @select-file = ~>
- @refs.file.click!
+ this.selectFile = () => {
+ this.refs.file.click();
+ };
- @select-file-from-drive = ~>
- browser = document.body.append-child document.create-element \mk-drive-selector
- browser = riot.mount browser, do
+ this.selectFileFromDrive = () => {
+ const i = riot.mount(document.body.appendChild(document.createElement('mk-drive-selector')), {
multiple: true
- .0
- browser.on \selected (files) ~>
- files.for-each @add-file
+ })[0];
+ i.one('selected', files => {
+ files.forEach(this.addFile);
+ });
+ };
- @change-file = ~>
- files = @refs.file.files
- for i from 0 to files.length - 1
- file = files.item i
- @upload file
+ this.changeFile = () => {
+ this.refs.file.files.forEach(this.upload);
+ };
- @upload = (file) ~>
- @refs.uploader.upload file
+ this.upload = file => {
+ this.refs.uploader.upload(file);
+ };
- @add-file = (file) ~>
- file._remove = ~>
- @files = @files.filter (x) -> x.id != file.id
- @trigger \change-files @files
- @update!
+ this.addFile = file => {
+ file._remove = () => {
+ this.files = this.files.filter(x => x.id != file.id);
+ this.trigger('change-files', this.files);
+ this.update();
+ };
- @files.push file
- @trigger \change-files @files
- @update!
+ this.files.push(file);
+ this.trigger('change-files', this.files);
+ this.update();
+ };
- @add-poll = ~>
- @poll = true
+ this.addPoll = () => {
+ this.poll = true;
+ };
- @on-poll-destroyed = ~>
- @update do
+ this.onPollDestroyed = () => {
+ this.update({
poll: false
+ });
+ };
- @post = ~>
- @wait = true
+ this.post = () => {
+ this.wait = true;
- files = if @files? and @files.length > 0
- then @files.map (f) -> f.id
- else undefined
+ const files = this.files && this.files.length > 0
+ ? this.files.map(f => f.id)
+ : undefined;
- @api \posts/create do
- text: @refs.text.value
- media_ids: files
- reply_to_id: if @opts.reply? then @opts.reply.id else undefined
- poll: if @poll then @refs.poll.get! else undefined
- .then (data) ~>
- @trigger \post
- @unmount!
- .catch (err) ~>
- console.error err
- #@opts.ui.trigger \notification 'Error!'
- @wait = false
- @update!
+ this.api('posts/create', {
+ text: this.refs.text.value,
+ media_ids: files,
+ reply_to_id: this.inReplyToPost ? this.inReplyToPost.id : undefined,
+ poll: this.poll ? this.refs.poll.get() : undefined
+ }).then(data => {
+ this.trigger('post');
+ this.unmount();
+ }).catch(err => {
+ this.update({
+ wait: false
+ });
+ });
+ };
- @cancel = ~>
- @trigger \cancel
- @unmount!
+ this.cancel = () => {
+ this.trigger('cancel');
+ this.unmount();
+ };
- @cat = ~>
- @refs.text.value = @refs.text.value + get-cat!
+ this.cat = () => {
+ this.refs.text.value += getCat();
+ };
</script>
</mk-post-form>
diff --git a/src/web/app/mobile/tags/post-preview.tag b/src/web/app/mobile/tags/post-preview.tag
index d86ca86df6..aa1d5f9b29 100644
--- a/src/web/app/mobile/tags/post-preview.tag
+++ b/src/web/app/mobile/tags/post-preview.tag
@@ -90,5 +90,5 @@
color #717171
</style>
- <script>@post = @opts.post</script>
+ <script>this.post = this.opts.post</script>
</mk-post-preview>
diff --git a/src/web/app/mobile/tags/search-posts.tag b/src/web/app/mobile/tags/search-posts.tag
index 18d538c327..b0efe14636 100644
--- a/src/web/app/mobile/tags/search-posts.tag
+++ b/src/web/app/mobile/tags/search-posts.tag
@@ -7,26 +7,30 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @max = 30
- @offset = 0
+ this.max = 30;
+ this.offset = 0;
- @query = @opts.query
- @with-media = @opts.with-media
+ this.query = this.opts.query;
+ this.withMedia = this.opts.withMedia;
- @init = new Promise (res, rej) ~>
- @api \posts/search do
- query: @query
- .then (posts) ~>
- res posts
- @trigger \loaded
+ this.init = new Promise((res, rej) => {
+ this.api('posts/search', {
+ query: this.query
+ }).then(posts => {
+ res(posts);
+ this.trigger('loaded');
+ });
+ });
- @more = ~>
- @offset += @max
- @api \posts/search do
- query: @query
- max: @max
- offset: @offset
+ this.more = () => {
+ this.offset += this.max;
+ this.api('posts/search', {
+ query: this.query,
+ max: this.max,
+ offset: this.offset
+ });
+ };
</script>
</mk-search-posts>
diff --git a/src/web/app/mobile/tags/search.tag b/src/web/app/mobile/tags/search.tag
index 3cca973a26..831e5a3e34 100644
--- a/src/web/app/mobile/tags/search.tag
+++ b/src/web/app/mobile/tags/search.tag
@@ -3,13 +3,14 @@
<style>
:scope
display block
-
</style>
<script>
- @query = @opts.query
+ this.query = this.opts.query;
- @on \mount ~>
- @refs.posts.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.posts.on('loaded', () => {
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-search>
diff --git a/src/web/app/mobile/tags/stream-indicator.tag b/src/web/app/mobile/tags/stream-indicator.tag
deleted file mode 100644
index d2ab34574d..0000000000
--- a/src/web/app/mobile/tags/stream-indicator.tag
+++ /dev/null
@@ -1,54 +0,0 @@
-<mk-stream-indicator>
- <p if={ state == 'initializing' }><i class="fa fa-spinner fa-spin"></i><span>接続中
- <mk-ellipsis></mk-ellipsis></span></p>
- <p if={ state == 'reconnecting' }><i class="fa fa-spinner fa-spin"></i><span>切断されました 接続中
- <mk-ellipsis></mk-ellipsis></span></p>
- <p if={ state == 'connected' }><i class="fa fa-check"></i><span>接続完了</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)
-
- > p
- display block
- margin 0
-
- > i
- margin-right 0.25em
-
- </style>
- <script>
- @mixin \stream
-
- @on \before-mount ~>
- @state = @get-stream-state!
-
- if @state == \connected
- @root.style.opacity = 0
-
- @stream-state-ev.on \connected ~>
- @state = @get-stream-state!
- @update!
- set-timeout ~>
- Velocity @root, {
- opacity: 0
- } 200ms \linear
- , 1000ms
-
- @stream-state-ev.on \closed ~>
- @state = @get-stream-state!
- @update!
- Velocity @root, {
- opacity: 1
- } 0ms
- </script>
-</mk-stream-indicator>
diff --git a/src/web/app/mobile/tags/sub-post-content.tag b/src/web/app/mobile/tags/sub-post-content.tag
index 2256bb3486..5ff01c5020 100644
--- a/src/web/app/mobile/tags/sub-post-content.tag
+++ b/src/web/app/mobile/tags/sub-post-content.tag
@@ -28,17 +28,19 @@
</style>
<script>
- @mixin \text
+ this.mixin('text');
- @post = @opts.post
+ this.post = this.opts.post;
- @on \mount ~>
- if @post.text?
- tokens = @analyze @post.text
- @refs.text.innerHTML = @compile tokens, false
+ this.on('mount', () => {
+ if (this.post.text) {
+ const tokens = this.analyze(this.post.text);
+ this.refs.text.innerHTML = this.compile(tokens, false);
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
+ }
+ });
</script>
</mk-sub-post-content>
diff --git a/src/web/app/mobile/tags/timeline-post-sub.tag b/src/web/app/mobile/tags/timeline-post-sub.tag
index 8ffe84bbc9..5a944db733 100644
--- a/src/web/app/mobile/tags/timeline-post-sub.tag
+++ b/src/web/app/mobile/tags/timeline-post-sub.tag
@@ -97,5 +97,5 @@
font-size 80%
</style>
- <script>@post = @opts.post</script>
+ <script>this.post = this.opts.post</script>
</mk-timeline-post-sub>
diff --git a/src/web/app/mobile/tags/timeline-post.tag b/src/web/app/mobile/tags/timeline-post.tag
index 9ffa2c918c..8662eadb8c 100644
--- a/src/web/app/mobile/tags/timeline-post.tag
+++ b/src/web/app/mobile/tags/timeline-post.tag
@@ -3,10 +3,19 @@
<mk-timeline-post-sub post={ p.reply_to }></mk-timeline-post-sub>
</div>
<div class="repost" if={ isRepost }>
- <p><a class="avatar-anchor" href={ CONFIG.url + '/' + post.user.username }><img class="avatar" src={ post.user.avatar_url + '?thumbnail&size=64' } alt="avatar"/></a><i class="fa fa-retweet"></i><a class="name" href={ CONFIG.url + '/' + post.user.username }>{ post.user.name }</a>がRepost</p>
+ <p>
+ <a class="avatar-anchor" href={ CONFIG.url + '/' + post.user.username }>
+ <img class="avatar" src={ post.user.avatar_url + '?thumbnail&size=64' } alt="avatar"/>
+ </a>
+ <i class="fa fa-retweet"></i>
+ <a class="name" href={ CONFIG.url + '/' + post.user.username }>{ post.user.name }</a>がRepost
+ </p>
<mk-time time={ post.created_at }></mk-time>
</div>
- <article><a class="avatar-anchor" href={ CONFIG.url + '/' + p.user.username }><img class="avatar" src={ p.user.avatar_url + '?thumbnail&size=96' } alt="avatar"/></a>
+ <article>
+ <a class="avatar-anchor" href={ CONFIG.url + '/' + p.user.username }>
+ <img class="avatar" src={ p.user.avatar_url + '?thumbnail&size=96' } alt="avatar"/>
+ </a>
<div class="main">
<header>
<a class="name" href={ CONFIG.url + '/' + p.user.username }>{ p.user.name }</a>
@@ -286,62 +295,70 @@
</style>
<script>
- @mixin \api
- @mixin \text
- @mixin \get-post-summary
- @mixin \open-post-form
+ this.mixin('api');
+ this.mixin('text');
+ this.mixin('get-post-summary');
+ this.mixin('open-post-form');
- @post = @opts.post
- @is-repost = @post.repost? and !@post.text?
- @p = if @is-repost then @post.repost else @post
- @summary = @get-post-summary @p
- @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
+ this.post = this.opts.post;
+ this.isRepost = this.post.repost != null && this.post.text == null;
+ this.p = this.isRepost ? this.post.repost : this.post;
+ this.summary = this.getPostSummary(this.p);
+ this.url = CONFIG.url + '/' + this.p.user.username + '/' + this.p.id
- @on \mount ~>
- if @p.text?
- tokens = if @p._highlight?
- then @analyze @p._highlight
- else @analyze @p.text
+ this.on('mount', () => {
+ if (this.p.text) {
+ const tokens = this.analyze(this.p.text);
- @refs.text.innerHTML = @refs.text.innerHTML.replace '<p class="dummy"></p>' if @p._highlight?
- then @compile tokens, true, false
- else @compile tokens
+ this.refs.text.innerHTML = this.refs.text.innerHTML.replace('<p class="dummy"></p>', this.compile(tokens));
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ this.refs.text.children.forEach(e => {
+ if (e.tagName == 'MK-URL') riot.mount(e);
+ });
- # URLをプレビュー
+ // URLをプレビュー
tokens
- .filter (t) -> t.type == \link
- .map (t) ~>
- @preview = @refs.text.append-child document.create-element \mk-url-preview
- riot.mount @preview, do
- url: t.content
+ .filter(t => t.type == 'link')
+ .map(t => {
+ riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
+ url: t.content
+ });
+ });
+ }
+ });
- @reply = ~>
- @open-post-form do
- reply: @p
+ this.reply = () => {
+ this.openPostForm({
+ reply: this.p
+ });
+ };
- @repost = ~>
- text = window.prompt '「' + @summary + '」をRepost'
- if text?
- @api \posts/create do
- repost_id: @p.id
- text: if text == '' then undefined else text
+ this.repost = () => {
+ const text = window.prompt(`「${this.summary}」をRepost`);
+ if (text) {
+ this.api('posts/create', {
+ repost_id: this.p.id,
+ text: text == '' ? undefined : text
+ });
+ }
+ };
- @like = ~>
- if @p.is_liked
- @api \posts/likes/delete do
- post_id: @p.id
- .then ~>
- @p.is_liked = false
- @update!
- else
- @api \posts/likes/create do
- post_id: @p.id
- .then ~>
- @p.is_liked = true
- @update!
+ this.like = () => {
+ if (this.p.is_liked) {
+ this.api('posts/likes/delete', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = false;
+ this.update();
+ });
+ } else {
+ this.api('posts/likes/create', {
+ post_id: this.p.id
+ }).then(() => {
+ this.p.is_liked = true;
+ this.update();
+ });
+ }
+ };
</script>
</mk-timeline-post>
diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag
index c41016076e..421917d834 100644
--- a/src/web/app/mobile/tags/timeline.tag
+++ b/src/web/app/mobile/tags/timeline.tag
@@ -74,45 +74,58 @@
</style>
<script>
- @posts = []
- @init = true
- @fetching = false
- @can-fetch-more = true
+ this.posts = [];
+ this.init = true;
+ this.fetching = false;
+ this.canFetchMore = true;
- @on \mount ~>
- @opts.init.then (posts) ~>
- @init = false
- @set-posts posts
+ this.on('mount', () => {
+ this.opts.init.then(posts => {
+ this.init = false;
+ this.setPosts(posts);
+ });
+ });
- @on \update ~>
- @posts.for-each (post) ~>
- date = (new Date post.created_at).get-date!
- month = (new Date post.created_at).get-month! + 1
- post._date = date
- post._datetext = month + '月 ' + date + '日'
+ this.on('update', () => {
+ this.posts.forEach(post => {
+ const date = new Date(post.created_at).getDate();
+ const month = new Date(post.created_at).getMonth() + 1;
+ post._date = date;
+ post._datetext = `${month}月 ${date}日`;
+ });
+ });
- @more = ~>
- if @init or @fetching or @posts.length == 0 then return
- @fetching = true
- @update!
- @opts.more!.then (posts) ~>
- @fetching = false
- @prepend-posts posts
+ this.more = () => {
+ if (this.init || this.fetching || this.posts.length == 0) return;
+ this.update({
+ fetching: true
+ });
+ this.opts.more().then(posts => {
+ this.fetching = false;
+ this.prependPosts(posts);
+ });
+ };
- @set-posts = (posts) ~>
- @posts = posts
- @update!
+ this.setPosts = posts => {
+ this.update({
+ posts: posts
+ });
+ };
- @prepend-posts = (posts) ~>
- posts.for-each (post) ~>
- @posts.push post
- @update!
+ this.prependPosts = posts => {
+ posts.forEach(post => {
+ this.posts.push(post);
+ this.update();
+ });
+ }
- @add-post = (post) ~>
- @posts.unshift post
- @update!
+ this.addPost = post => {
+ this.posts.unshift(post);
+ this.update();
+ };
- @tail = ~>
- @posts[@posts.length - 1]
+ this.tail = () => {
+ return this.posts[this.posts.length - 1];
+ };
</script>
</mk-timeline>
diff --git a/src/web/app/mobile/tags/ui-header.tag b/src/web/app/mobile/tags/ui-header.tag
index d47c3610f9..30259ba911 100644
--- a/src/web/app/mobile/tags/ui-header.tag
+++ b/src/web/app/mobile/tags/ui-header.tag
@@ -13,7 +13,7 @@
$height = 48px
display block
- position fixed
+ position sticky
top 0
z-index 1024
width 100%
@@ -88,17 +88,15 @@
</style>
<script>
- @mixin \ui
- @mixin \open-post-form
+ this.mixin('ui');
+ this.mixin('open-post-form');
- @on \mount ~>
- @opts.ready!
+ this.ui.on('title', title => {
+ if (this.refs.title) this.refs.title.innerHTML = title;
+ });
- @ui.on \title (title) ~>
- if @refs.title?
- @refs.title.innerHTML = title
-
- @post = ~>
- @open-post-form!
+ this.post = () => {
+ this.openPostForm();
+ };
</script>
</mk-ui-header>
diff --git a/src/web/app/mobile/tags/ui-nav.tag b/src/web/app/mobile/tags/ui-nav.tag
index a5dbd4cbaf..23d07efdc4 100644
--- a/src/web/app/mobile/tags/ui-nav.tag
+++ b/src/web/app/mobile/tags/ui-nav.tag
@@ -117,15 +117,13 @@
</style>
<script>
- @mixin \i
- @mixin \page
+ this.mixin('i');
+ this.mixin('page');
- @on \mount ~>
- @opts.ready!
-
- @search = ~>
- query = window.prompt \検索
- if query? and query != ''
- @page '/search:' + query
+ this.search = () => {
+ const query = window.prompt('検索');
+ if (query == null || query == '') return;
+ this.page('/search:' + query);
+ };
</script>
</mk-ui-nav>
diff --git a/src/web/app/mobile/tags/ui.tag b/src/web/app/mobile/tags/ui.tag
index c3ffe90978..3b3c6823d0 100644
--- a/src/web/app/mobile/tags/ui.tag
+++ b/src/web/app/mobile/tags/ui.tag
@@ -1,7 +1,7 @@
<mk-ui>
<div class="global" ref="global">
- <mk-ui-header ref="header" ready={ ready }></mk-ui-header>
- <mk-ui-nav ref="nav" ready={ ready }></mk-ui-nav>
+ <mk-ui-header ref="header"></mk-ui-header>
+ <mk-ui-nav ref="nav"></mk-ui-nav>
<div class="content" ref="main"><yield /></div>
</div>
<mk-stream-indicator></mk-stream-indicator>
@@ -14,38 +14,27 @@
background #fff
</style>
<script>
- @mixin \stream
+ this.mixin('stream');
- @ready-count = 0
- @is-drawer-opening = false
+ this.isDrawerOpening = false;
- #@ui.on \notification (text) ~>
- # alert text
+ this.on('mount', () => {
+ this.stream.on('notification', this.onStreamNotification);
+ });
- @on \mount ~>
- @stream.on \notification @on-stream-notification
- @ready!
+ this.on('unmount', () => {
+ this.stream.off('notification', this.onStreamNotification);
+ });
- @on \unmount ~>
- @stream.off \notification @on-stream-notification
+ this.toggleDrawer = () => {
+ this.isDrawerOpening = !this.isDrawerOpening;
+ this.refs.nav.root.style.display = this.isDrawerOpening ? 'block' : 'none';
+ };
- @ready = ~>
- @ready-count++
-
- if @ready-count == 2
- @init-view-position!
-
- @init-view-position = ~>
- top = @refs.header.root.offset-height
- @refs.main.style.padding-top = top + \px
-
- @toggle-drawer = ~>
- @is-drawer-opening = !@is-drawer-opening
- @refs.nav.root.style.display = if @is-drawer-opening then \block else \none
-
- @on-stream-notification = (notification) ~>
- el = document.body.append-child document.create-element \mk-notify
- riot.mount el, do
+ this.onStreamNotification = notification => {
+ riot.mount(document.body.appendChild(document.createElement('mk-notify')), {
notification: notification
+ });
+ };
</script>
</mk-ui>
diff --git a/src/web/app/mobile/tags/user-followers.tag b/src/web/app/mobile/tags/user-followers.tag
index f328ab61de..e939da6c6e 100644
--- a/src/web/app/mobile/tags/user-followers.tag
+++ b/src/web/app/mobile/tags/user-followers.tag
@@ -6,20 +6,23 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @user = @opts.user
+ this.user = this.opts.user;
- @fetch = (iknow, limit, cursor, cb) ~>
- @api \users/followers do
- user_id: @user.id
- iknow: iknow
- limit: limit
- cursor: if cursor? then cursor else undefined
- .then cb
+ this.fetch = (iknow, limit, cursor, cb) => {
+ this.api('users/followers', {
+ user_id: this.user.id,
+ iknow: iknow,
+ limit: limit,
+ cursor: cursor ? cursor : undefined
+ }).then(cb);
+ };
- @on \mount ~>
- @refs.list.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.list.on('loaded', () => {
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-user-followers>
diff --git a/src/web/app/mobile/tags/user-following.tag b/src/web/app/mobile/tags/user-following.tag
index 29f3680b65..778eb08e1c 100644
--- a/src/web/app/mobile/tags/user-following.tag
+++ b/src/web/app/mobile/tags/user-following.tag
@@ -6,20 +6,23 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @user = @opts.user
+ this.user = this.opts.user;
- @fetch = (iknow, limit, cursor, cb) ~>
- @api \users/following do
- user_id: @user.id
- iknow: iknow
- limit: limit
- cursor: if cursor? then cursor else undefined
- .then cb
+ this.fetch = (iknow, limit, cursor, cb) => {
+ this.api('users/following', {
+ user_id: this.user.id,
+ iknow: iknow,
+ limit: limit,
+ cursor: cursor ? cursor : undefined
+ }).then(cb);
+ };
- @on \mount ~>
- @refs.list.on \loaded ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.refs.list.on('loaded', () => {
+ this.trigger('loaded');
+ });
+ });
</script>
</mk-user-following>
diff --git a/src/web/app/mobile/tags/user-preview.tag b/src/web/app/mobile/tags/user-preview.tag
index 2e600a8171..09cfeb49e7 100644
--- a/src/web/app/mobile/tags/user-preview.tag
+++ b/src/web/app/mobile/tags/user-preview.tag
@@ -85,5 +85,5 @@
color #717171
</style>
- <script>@user = @opts.user</script>
+ <script>this.user = this.opts.user</script>
</mk-user-preview>
diff --git a/src/web/app/mobile/tags/user-timeline.tag b/src/web/app/mobile/tags/user-timeline.tag
index 9646dda9e7..fb316dbdf9 100644
--- a/src/web/app/mobile/tags/user-timeline.tag
+++ b/src/web/app/mobile/tags/user-timeline.tag
@@ -9,23 +9,27 @@
</style>
<script>
- @mixin \api
+ this.mixin('api');
- @user = @opts.user
- @with-media = @opts.with-media
+ this.user = this.opts.user;
+ this.withMedia = this.opts.withMedia;
- @init = new Promise (res, rej) ~>
- @api \users/posts do
- user_id: @user.id
- with_media: @with-media
- .then (posts) ~>
- res posts
- @trigger \loaded
+ this.init = new Promise((res, rej) => {
+ this.api('users/posts', {
+ user_id: this.user.id,
+ with_media: this.withMedia
+ }).then(posts => {
+ res(posts);
+ this.trigger('loaded');
+ });
+ });
- @more = ~>
- @api \users/posts do
- user_id: @user.id
- with_media: @with-media
- max_id: @refs.timeline.tail!.id
+ this.more = () => {
+ this.api('users/posts', {
+ user_id: this.user.id,
+ with_media: this.withMedia,
+ max_id: this.refs.timeline.tail().id
+ });
+ };
</script>
</mk-user-timeline>
diff --git a/src/web/app/mobile/tags/user.tag b/src/web/app/mobile/tags/user.tag
index 37900bb617..9d95e99144 100644
--- a/src/web/app/mobile/tags/user.tag
+++ b/src/web/app/mobile/tags/user.tag
@@ -3,20 +3,43 @@
<header>
<div class="banner" style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }></div>
<div class="body">
- <div class="top"><a class="avatar"><img src={ user.avatar_url + '?thumbnail&size=160' } alt="avatar"/></a>
+ <div class="top">
+ <a class="avatar">
+ <img src={ user.avatar_url + '?thumbnail&size=160' } alt="avatar"/>
+ </a>
<mk-follow-button if={ SIGNIN && I.id != user.id } user={ user }></mk-follow-button>
</div>
<div class="title">
- <h1>{ user.name }</h1><span class="username">@{ user.username }</span><span class="followed" if={ user.is_followed }>フォローされています</span>
+ <h1>{ user.name }</h1>
+ <span class="username">@{ user.username }</span>
+ <span class="followed" if={ user.is_followed }>フォローされています</span>
</div>
<div class="bio">{ user.bio }</div>
<div class="info">
- <p class="location" if={ user.location }><i class="fa fa-map-marker"></i>{ user.location }</p>
- <p class="birthday" if={ user.birthday }><i class="fa fa-birthday-cake"></i>{ user.birthday.replace('-', '年').replace('-', '月') + '日' } ({ age(user.birthday) }歳)</p>
+ <p class="location" if={ user.location }>
+ <i class="fa fa-map-marker"></i>{ user.location }
+ </p>
+ <p class="birthday" if={ user.birthday }>
+ <i class="fa fa-birthday-cake"></i>{ user.birthday.replace('-', '年').replace('-', '月') + '日' } ({ age(user.birthday) }歳)
+ </p>
+ </div>
+ <div class="friends">
+ <a href="{ user.username }/following">
+ <b>{ user.following_count }</b>
+ <i>フォロー</i>
+ </a>
+ <a href="{ user.username }/followers">
+ <b>{ user.followers_count }</b>
+ <i>フォロワー</i>
+ </a>
</div>
- <div class="friends"><a href="{ user.username }/following"><b>{ user.following_count }</b><i>フォロー</i></a><a href="{ user.username }/followers"><b>{ user.followers_count }</b><i>フォロワー</i></a></div>
</div>
- <nav><a data-is-active={ page == 'posts' } onclick={ goPosts }>投稿</a><a data-is-active={ page == 'media' } onclick={ goMedia }>メディア</a><a data-is-active={ page == 'graphs' } onclick={ goGraphs }>グラフ</a><a data-is-active={ page == 'likes' } onclick={ goLikes }>いいね</a></nav>
+ <nav>
+ <a data-is-active={ page == 'posts' } onclick={ go.bind(null, 'posts') }>投稿</a>
+ <a data-is-active={ page == 'media' } onclick={ go.bind(null, 'media') }>メディア</a>
+ <a data-is-active={ page == 'graphs' } onclick={ go.bind(null, 'graphs') }>グラフ</a>
+ <a data-is-active={ page == 'likes' } onclick={ go.bind(null, 'likes') }>いいね</a>
+ </nav>
</header>
<div class="body">
<mk-user-timeline if={ page == 'posts' } user={ user }></mk-user-timeline>
@@ -154,38 +177,30 @@
</style>
<script>
- @age = require \s-age
-
- @mixin \i
- @mixin \api
-
- @username = @opts.user
- @page = if @opts.page? then @opts.page else \posts
- @fetching = true
-
- @on \mount ~>
- @api \users/show do
- username: @username
- .then (user) ~>
- @fetching = false
- @user = user
- @trigger \loaded user
- @update!
+ this.age = require('s-age');
- @go-posts = ~>
- @page = \posts
- @update!
+ this.mixin('i');
+ this.mixin('api');
- @go-media = ~>
- @page = \media
- @update!
+ this.username = this.opts.user;
+ this.page = this.opts.page ? this.opts.page : 'posts';
+ this.fetching = true;
- @go-graphs = ~>
- @page = \graphs
- @update!
+ this.on('mount', () => {
+ this.api('users/show', {
+ username: this.username
+ }).then(user => {
+ this.fetching = false;
+ this.user = user;
+ this.trigger('loaded', user);
+ this.update();
+ });
+ });
- @go-likes = ~>
- @page = \likes
- @update!
+ this.go = page => {
+ this.update({
+ page: page
+ });
+ };
</script>
</mk-user>
diff --git a/src/web/app/mobile/tags/users-list.tag b/src/web/app/mobile/tags/users-list.tag
index a45d2a9e07..82dfa3df45 100644
--- a/src/web/app/mobile/tags/users-list.tag
+++ b/src/web/app/mobile/tags/users-list.tag
@@ -70,47 +70,50 @@
</style>
<script>
- @mixin \i
+ this.mixin('i');
- @limit = 30users
- @mode = \all
+ this.limit = 30;
+ this.mode = 'all';
- @fetching = true
- @more-fetching = false
+ this.fetching = true;
+ this.moreFetching = false;
- @on \mount ~>
- @fetch ~>
- @trigger \loaded
+ this.on('mount', () => {
+ this.fetch(() => this.trigger('loaded'));
+ });
- @fetch = (cb) ~>
- @fetching = true
- @update!
- obj <~ @opts.fetch do
- @mode == \iknow
- @limit
- null
- @users = obj.users
- @next = obj.next
- @fetching = false
- @update!
- if cb? then cb!
+ this.fetch = cb => {
+ this.update({
+ fetching: true
+ });
+ this.opts.fetch(this.mode == 'iknow', this.limit, null, obj => {
+ this.update({
+ fetching: false,
+ users: obj.users,
+ next: obj.next
+ });
+ if (cb) cb();
+ });
+ };
- @more = ~>
- @more-fetching = true
- @update!
- obj <~ @opts.fetch do
- @mode == \iknow
- @limit
- @cursor
- @users = @users.concat obj.users
- @next = obj.next
- @more-fetching = false
- @update!
+ this.more = () => {
+ this.update({
+ moreFetching: true
+ });
+ this.opts.fetch(this.mode == 'iknow', this.limit, this.cursor, obj => {
+ this.update({
+ moreFetching: false,
+ users: this.users.concat(obj.users),
+ next: obj.next
+ });
+ });
+ };
- @set-mode = (mode) ~>
- @update do
+ this.setMode = mode => {
+ this.update({
mode: mode
-
- @fetch!
+ });
+ this.fetch();
+ };
</script>
</mk-users-list>