summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2017-01-12 05:55:38 +0900
committersyuilo <syuilotan@yahoo.co.jp>2017-01-12 05:55:38 +0900
commit520299c2b47e6d446ee622657e4a987278b13d3e (patch)
tree2948994ff6425bb81b68568835ca5a6092f9516b /src
parent[Server] Fix bug (diff)
downloadsharkey-520299c2b47e6d446ee622657e4a987278b13d3e.tar.gz
sharkey-520299c2b47e6d446ee622657e4a987278b13d3e.tar.bz2
sharkey-520299c2b47e6d446ee622657e4a987278b13d3e.zip
#16
Diffstat (limited to 'src')
-rw-r--r--src/web/app/auth/tags/form.tag214
-rw-r--r--src/web/app/auth/tags/index.tag217
-rw-r--r--src/web/app/common/tags/copyright.tag14
-rw-r--r--src/web/app/common/tags/core-error.tag115
-rw-r--r--src/web/app/common/tags/ellipsis.tag42
-rw-r--r--src/web/app/common/tags/file-type-icon.tag18
-rw-r--r--src/web/app/common/tags/forkit.tag69
-rw-r--r--src/web/app/common/tags/introduction.tag43
-rw-r--r--src/web/app/common/tags/number.tag27
-rw-r--r--src/web/app/common/tags/raw.tag13
-rw-r--r--src/web/app/common/tags/ripple-string.tag44
-rw-r--r--src/web/app/common/tags/signin.tag225
-rw-r--r--src/web/app/common/tags/signup.tag529
-rw-r--r--src/web/app/common/tags/special-message.tag45
-rw-r--r--src/web/app/common/tags/time.tag76
-rw-r--r--src/web/app/common/tags/uploader.tag324
-rw-r--r--src/web/app/common/tags/url-preview.tag173
-rw-r--r--src/web/app/common/tags/url.tag78
-rw-r--r--src/web/app/desktop/tags/analog-clock.tag181
-rw-r--r--src/web/app/desktop/tags/autocomplete-suggestion.tag287
-rw-r--r--src/web/app/desktop/tags/big-follow-button.tag223
-rw-r--r--src/web/app/desktop/tags/contextmenu.tag233
-rw-r--r--src/web/app/desktop/tags/crop-window.tag305
-rw-r--r--src/web/app/desktop/tags/debugger.tag147
-rw-r--r--src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag102
-rw-r--r--src/web/app/desktop/tags/dialog.tag256
-rw-r--r--src/web/app/desktop/tags/donation.tag113
-rw-r--r--src/web/app/desktop/tags/drive/base-contextmenu.tag51
-rw-r--r--src/web/app/desktop/tags/drive/browser-window.tag49
-rw-r--r--src/web/app/desktop/tags/drive/browser.tag1031
-rw-r--r--src/web/app/desktop/tags/drive/file-contextmenu.tag176
-rw-r--r--src/web/app/desktop/tags/drive/file.tag351
-rw-r--r--src/web/app/desktop/tags/drive/folder-contextmenu.tag108
-rw-r--r--src/web/app/desktop/tags/drive/folder.tag301
-rw-r--r--src/web/app/desktop/tags/drive/nav-folder.tag157
-rw-r--r--src/web/app/desktop/tags/ellipsis-icon.tag63
-rw-r--r--src/web/app/desktop/tags/follow-button.tag215
-rw-r--r--src/web/app/desktop/tags/following-setuper.tag274
-rw-r--r--src/web/app/desktop/tags/go-top.tag27
-rw-r--r--src/web/app/desktop/tags/home-widgets/broadcast.tag138
-rw-r--r--src/web/app/desktop/tags/home-widgets/calendar.tag241
-rw-r--r--src/web/app/desktop/tags/home-widgets/donation.tag63
-rw-r--r--src/web/app/desktop/tags/home-widgets/mentions.tag193
-rw-r--r--src/web/app/desktop/tags/home-widgets/nav.tag38
-rw-r--r--src/web/app/desktop/tags/home-widgets/notifications.tag85
-rw-r--r--src/web/app/desktop/tags/home-widgets/photo-stream.tag149
-rw-r--r--src/web/app/desktop/tags/home-widgets/profile.tag97
-rw-r--r--src/web/app/desktop/tags/home-widgets/rss-reader.tag156
-rw-r--r--src/web/app/desktop/tags/home-widgets/timeline.tag184
-rw-r--r--src/web/app/desktop/tags/home-widgets/tips.tag123
-rw-r--r--src/web/app/desktop/tags/home-widgets/user-recommendation.tag256
-rw-r--r--src/web/app/desktop/tags/home.tag143
-rw-r--r--src/web/app/desktop/tags/image-dialog.tag134
-rw-r--r--src/web/app/desktop/tags/images-viewer.tag74
-rw-r--r--src/web/app/desktop/tags/input-dialog.tag263
-rw-r--r--src/web/app/desktop/tags/list-user.tag164
-rw-r--r--src/web/app/desktop/tags/messaging/form.tag277
-rw-r--r--src/web/app/desktop/tags/messaging/index.tag505
-rw-r--r--src/web/app/desktop/tags/messaging/message.tag375
-rw-r--r--src/web/app/desktop/tags/messaging/room-window.tag45
-rw-r--r--src/web/app/desktop/tags/messaging/room.tag380
-rw-r--r--src/web/app/desktop/tags/messaging/window.tag51
-rw-r--r--src/web/app/desktop/tags/notifications.tag359
-rw-r--r--src/web/app/desktop/tags/pages/entrance.tag125
-rw-r--r--src/web/app/desktop/tags/pages/entrance/signin.tag220
-rw-r--r--src/web/app/desktop/tags/pages/entrance/signup.tag81
-rw-r--r--src/web/app/desktop/tags/pages/home.tag89
-rw-r--r--src/web/app/desktop/tags/pages/not-found.tag90
-rw-r--r--src/web/app/desktop/tags/pages/post.tag43
-rw-r--r--src/web/app/desktop/tags/pages/search.tag27
-rw-r--r--src/web/app/desktop/tags/pages/user.tag35
-rw-r--r--src/web/app/desktop/tags/post-detail-sub.tag229
-rw-r--r--src/web/app/desktop/tags/post-detail.tag690
-rw-r--r--src/web/app/desktop/tags/post-form-window.tag95
-rw-r--r--src/web/app/desktop/tags/post-form.tag714
-rw-r--r--src/web/app/desktop/tags/post-preview.tag155
-rw-r--r--src/web/app/desktop/tags/post-status-graph.tag125
-rw-r--r--src/web/app/desktop/tags/progress-dialog.tag158
-rw-r--r--src/web/app/desktop/tags/repost-form-window.tag60
-rw-r--r--src/web/app/desktop/tags/repost-form.tag240
-rw-r--r--src/web/app/desktop/tags/search-posts.tag150
-rw-r--r--src/web/app/desktop/tags/search.tag52
-rw-r--r--src/web/app/desktop/tags/select-file-from-drive-window.tag269
-rw-r--r--src/web/app/desktop/tags/set-avatar-suggestion.tag76
-rw-r--r--src/web/app/desktop/tags/set-banner-suggestion.tag76
-rw-r--r--src/web/app/desktop/tags/settings-window.tag45
-rw-r--r--src/web/app/desktop/tags/settings.tag467
-rw-r--r--src/web/app/desktop/tags/signin-history.tag118
-rw-r--r--src/web/app/desktop/tags/stream-indicator.tag97
-rw-r--r--src/web/app/desktop/tags/sub-post-content.tag63
-rw-r--r--src/web/app/desktop/tags/timeline-post-sub.tag160
-rw-r--r--src/web/app/desktop/tags/timeline-post.tag598
-rw-r--r--src/web/app/desktop/tags/timeline.tag133
-rw-r--r--src/web/app/desktop/tags/ui-header-account.tag369
-rw-r--r--src/web/app/desktop/tags/ui-header-clock.tag135
-rw-r--r--src/web/app/desktop/tags/ui-header-nav.tag186
-rw-r--r--src/web/app/desktop/tags/ui-header-notifications.tag193
-rw-r--r--src/web/app/desktop/tags/ui-header-post-button.tag70
-rw-r--r--src/web/app/desktop/tags/ui-header-search.tag68
-rw-r--r--src/web/app/desktop/tags/ui-header.tag144
-rw-r--r--src/web/app/desktop/tags/ui-notification.tag71
-rw-r--r--src/web/app/desktop/tags/ui.tag62
-rw-r--r--src/web/app/desktop/tags/user-followers-window.tag39
-rw-r--r--src/web/app/desktop/tags/user-followers.tag35
-rw-r--r--src/web/app/desktop/tags/user-following-window.tag39
-rw-r--r--src/web/app/desktop/tags/user-following.tag35
-rw-r--r--src/web/app/desktop/tags/user-friends-graph.tag117
-rw-r--r--src/web/app/desktop/tags/user-graphs.tag68
-rw-r--r--src/web/app/desktop/tags/user-header.tag239
-rw-r--r--src/web/app/desktop/tags/user-home.tag73
-rw-r--r--src/web/app/desktop/tags/user-likes-graph.tag71
-rw-r--r--src/web/app/desktop/tags/user-photos.tag149
-rw-r--r--src/web/app/desktop/tags/user-posts-graph.tag123
-rw-r--r--src/web/app/desktop/tags/user-preview.tag253
-rw-r--r--src/web/app/desktop/tags/user-profile.tag139
-rw-r--r--src/web/app/desktop/tags/user-timeline.tag234
-rw-r--r--src/web/app/desktop/tags/user.tag84
-rw-r--r--src/web/app/desktop/tags/users-list.tag233
-rw-r--r--src/web/app/desktop/tags/window.tag828
-rw-r--r--src/web/app/dev/tags/new-app-form.tag435
-rw-r--r--src/web/app/dev/tags/pages/app.tag48
-rw-r--r--src/web/app/dev/tags/pages/apps.tag50
-rw-r--r--src/web/app/dev/tags/pages/index.tag14
-rw-r--r--src/web/app/dev/tags/pages/new-app.tag65
-rw-r--r--src/web/app/mobile/tags/drive-selector.tag131
-rw-r--r--src/web/app/mobile/tags/drive.tag550
-rw-r--r--src/web/app/mobile/tags/drive/file-viewer.tag15
-rw-r--r--src/web/app/mobile/tags/drive/file.tag223
-rw-r--r--src/web/app/mobile/tags/drive/folder.tag75
-rw-r--r--src/web/app/mobile/tags/follow-button.tag181
-rw-r--r--src/web/app/mobile/tags/home-timeline.tag67
-rw-r--r--src/web/app/mobile/tags/home.tag31
-rw-r--r--src/web/app/mobile/tags/images-viewer.tag44
-rw-r--r--src/web/app/mobile/tags/notification-preview.tag196
-rw-r--r--src/web/app/mobile/tags/notification.tag226
-rw-r--r--src/web/app/mobile/tags/notifications.tag157
-rw-r--r--src/web/app/mobile/tags/notify.tag61
-rw-r--r--src/web/app/mobile/tags/page/drive.tag73
-rw-r--r--src/web/app/mobile/tags/page/entrance.tag99
-rw-r--r--src/web/app/mobile/tags/page/entrance/signin.tag84
-rw-r--r--src/web/app/mobile/tags/page/entrance/signup.tag67
-rw-r--r--src/web/app/mobile/tags/page/home.tag67
-rw-r--r--src/web/app/mobile/tags/page/new-post.tag15
-rw-r--r--src/web/app/mobile/tags/page/notifications.tag33
-rw-r--r--src/web/app/mobile/tags/page/post.tag53
-rw-r--r--src/web/app/mobile/tags/page/search.tag35
-rw-r--r--src/web/app/mobile/tags/page/user-followers.tag53
-rw-r--r--src/web/app/mobile/tags/page/user-following.tag53
-rw-r--r--src/web/app/mobile/tags/page/user.tag37
-rw-r--r--src/web/app/mobile/tags/post-detail.tag694
-rw-r--r--src/web/app/mobile/tags/post-form.tag426
-rw-r--r--src/web/app/mobile/tags/post-preview.tag147
-rw-r--r--src/web/app/mobile/tags/search-posts.tag51
-rw-r--r--src/web/app/mobile/tags/search.tag23
-rw-r--r--src/web/app/mobile/tags/stream-indicator.tag97
-rw-r--r--src/web/app/mobile/tags/sub-post-content.tag61
-rw-r--r--src/web/app/mobile/tags/timeline-post-sub.tag161
-rw-r--r--src/web/app/mobile/tags/timeline-post.tag487
-rw-r--r--src/web/app/mobile/tags/timeline.tag206
-rw-r--r--src/web/app/mobile/tags/ui-header.tag173
-rw-r--r--src/web/app/mobile/tags/ui-nav.tag284
-rw-r--r--src/web/app/mobile/tags/ui.tag81
-rw-r--r--src/web/app/mobile/tags/user-followers.tag39
-rw-r--r--src/web/app/mobile/tags/user-following.tag39
-rw-r--r--src/web/app/mobile/tags/user-preview.tag149
-rw-r--r--src/web/app/mobile/tags/user-timeline.tag51
-rw-r--r--src/web/app/mobile/tags/user.tag326
-rw-r--r--src/web/app/mobile/tags/users-list.tag209
168 files changed, 13962 insertions, 13926 deletions
diff --git a/src/web/app/auth/tags/form.tag b/src/web/app/auth/tags/form.tag
index f5b1555554..21c2339bc7 100644
--- a/src/web/app/auth/tags/form.tag
+++ b/src/web/app/auth/tags/form.tag
@@ -1,126 +1,126 @@
-mk-form
- header
- h1
- i { app.name }
- | があなたの
- b アカウント
- | に
- b アクセス
- | することを
- b 許可
- | しますか?
- img(src={ app.icon_url + '?thumbnail&size=64' })
- div.app
- section
- h2 { app.name }
- p.nid { app.name_id }
- p.description { app.description }
- section
- h2 このアプリは次の権限を要求しています:
- ul
- virtual(each={ p in app.permission })
- li(if={ p == 'account-read' }) アカウントの情報を見る。
- li(if={ p == 'account-write' }) アカウントの情報を操作する。
- li(if={ p == 'post-write' }) 投稿する。
- li(if={ p == 'like-write' }) いいねしたりいいね解除する。
- li(if={ p == 'following-write' }) フォローしたりフォロー解除する。
- li(if={ p == 'drive-read' }) ドライブを見る。
- li(if={ p == 'drive-write' }) ドライブを操作する。
- li(if={ p == 'notification-read' }) 通知を見る。
- li(if={ p == 'notification-write' }) 通知を操作する。
-
- div.action
- button(onclick={ cancel }) キャンセル
- button(onclick={ accept }) アクセスを許可
+<mk-form>
+ <header>
+ <h1><i>{ app.name }</i>があなたの<b>アカウント</b>に<b>アクセス</b>することを<b>許可</b>しますか?</h1><img src="{ app.icon_url + '?thumbnail&amp;size=64' }"/>
+ </header>
+ <div class="app">
+ <section>
+ <h2>{ app.name }</h2>
+ <p class="nid">{ app.name_id }</p>
+ <p class="description">{ app.description }</p>
+ </section>
+ <section>
+ <h2>このアプリは次の権限を要求しています:</h2>
+ <ul>
+ <virtual each="{ p in app.permission }">
+ <li if="{ p == 'account-read' }">アカウントの情報を見る。</li>
+ <li if="{ p == 'account-write' }">アカウントの情報を操作する。</li>
+ <li if="{ p == 'post-write' }">投稿する。</li>
+ <li if="{ p == 'like-write' }">いいねしたりいいね解除する。</li>
+ <li if="{ p == 'following-write' }">フォローしたりフォロー解除する。</li>
+ <li if="{ p == 'drive-read' }">ドライブを見る。</li>
+ <li if="{ p == 'drive-write' }">ドライブを操作する。</li>
+ <li if="{ p == 'notification-read' }">通知を見る。</li>
+ <li if="{ p == 'notification-write' }">通知を操作する。</li>
+ </virtual>
+ </ul>
+ </section>
+ </div>
+ <div class="action">
+ <button onclick="{ cancel }">キャンセル</button>
+ <button onclick="{ accept }">アクセスを許可</button>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > header
+ > h1
+ margin 0
+ padding 32px 32px 20px 32px
+ font-size 24px
+ font-weight normal
+ color #777
- > header
- > h1
- margin 0
- padding 32px 32px 20px 32px
- font-size 24px
- font-weight normal
- color #777
+ i
+ color #77aeca
- i
- color #77aeca
+ &:before
+ content '「'
- &:before
- content '「'
+ &:after
+ content '」'
- &:after
- content '」'
+ b
+ color #666
- b
- color #666
+ > img
+ display block
+ z-index 1
+ width 84px
+ height 84px
+ margin 0 auto -38px auto
+ border solid 5px #fff
+ border-radius 100%
+ box-shadow 0 2px 2px rgba(0, 0, 0, 0.1)
- > img
- display block
- z-index 1
- width 84px
- height 84px
- margin 0 auto -38px auto
- border solid 5px #fff
- border-radius 100%
- box-shadow 0 2px 2px rgba(0, 0, 0, 0.1)
+ > .app
+ padding 44px 16px 0 16px
+ color #555
+ background #eee
+ box-shadow 0 2px 2px rgba(0, 0, 0, 0.1) inset
- > .app
- padding 44px 16px 0 16px
- color #555
- background #eee
- box-shadow 0 2px 2px rgba(0, 0, 0, 0.1) inset
-
- &:after
- content ''
- display block
- clear both
+ &:after
+ content ''
+ display block
+ clear both
- > section
- float left
- width 50%
- padding 8px
- text-align left
+ > section
+ float left
+ width 50%
+ padding 8px
+ text-align left
- > h2
- margin 0
- font-size 16px
- color #777
+ > h2
+ margin 0
+ font-size 16px
+ color #777
- > .action
- padding 16px
+ > .action
+ padding 16px
- > button
- margin 0 8px
+ > button
+ margin 0 8px
- @media (max-width 600px)
- > header
- > img
- box-shadow none
+ @media (max-width 600px)
+ > header
+ > img
+ box-shadow none
- > .app
- box-shadow none
+ > .app
+ box-shadow none
- @media (max-width 500px)
- > header
- > h1
- font-size 16px
+ @media (max-width 500px)
+ > header
+ > h1
+ font-size 16px
-script.
- @mixin \api
+ </style>
+ <script>
+ @mixin \api
- @session = @opts.session
- @app = @session.app
+ @session = @opts.session
+ @app = @session.app
- @cancel = ~>
- @api \auth/deny do
- token: @session.token
- .then ~>
- @trigger \denied
+ @cancel = ~>
+ @api \auth/deny do
+ token: @session.token
+ .then ~>
+ @trigger \denied
- @accept = ~>
- @api \auth/accept do
- token: @session.token
- .then ~>
- @trigger \accepted
+ @accept = ~>
+ @api \auth/accept do
+ token: @session.token
+ .then ~>
+ @trigger \accepted
+ </script>
+</mk-form>
diff --git a/src/web/app/auth/tags/index.tag b/src/web/app/auth/tags/index.tag
index b7017daec6..d4818b9bfd 100644
--- a/src/web/app/auth/tags/index.tag
+++ b/src/web/app/auth/tags/index.tag
@@ -1,129 +1,136 @@
-mk-index
- main(if={ SIGNIN })
- p.fetching(if={ fetching })
- | 読み込み中
- mk-ellipsis
- mk-form@form(if={ state == null && !fetching }, session={ session })
- div.denied(if={ state == 'denied' })
- h1 アプリケーションの連携をキャンセルしました。
- p このアプリがあなたのアカウントにアクセスすることはありません。
- div.accepted(if={ state == 'accepted' })
- h1 { session.app.is_authorized ? 'このアプリは既に連携済みです' : 'アプリケーションの連携を許可しました'}
- p(if={ session.app.callback_url })
- | アプリケーションに戻っています
- mk-ellipsis
- p(if={ !session.app.callback_url }) アプリケーションに戻って、やっていってください。
- div.error(if={ state == 'fetch-session-error' })
- p セッションが存在しません。
- main.signin(if={ !SIGNIN })
- h1 サインインしてください
- mk-signin
- footer
- img(src='/_/resources/auth/logo.svg', alt='Misskey')
+<mk-index>
+ <main if="{ SIGNIN }">
+ <p class="fetching" if="{ fetching }">読み込み中
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <mk-form ref="form" if="{ state == null &amp;&amp; !fetching }" session="{ session }"></mk-form>
+ <div class="denied" if="{ state == 'denied' }">
+ <h1>アプリケーションの連携をキャンセルしました。</h1>
+ <p>このアプリがあなたのアカウントにアクセスすることはありません。</p>
+ </div>
+ <div class="accepted" if="{ state == 'accepted' }">
+ <h1>{ session.app.is_authorized ? 'このアプリは既に連携済みです' : 'アプリケーションの連携を許可しました'}</h1>
+ <p if="{ session.app.callback_url }">アプリケーションに戻っています
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <p if="{ !session.app.callback_url }">アプリケーションに戻って、やっていってください。</p>
+ </div>
+ <div class="error" if="{ state == 'fetch-session-error' }">
+ <p>セッションが存在しません。</p>
+ </div>
+ </main>
+ <main class="signin" if="{ !SIGNIN }">
+ <h1>サインインしてください</h1>
+ <mk-signin></mk-signin>
+ </main>
+ <footer><img src="/_/resources/auth/logo.svg" alt="Misskey"/></footer>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > main
+ width 100%
+ max-width 500px
+ margin 0 auto
+ text-align center
+ background #fff
+ box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
- > main
- width 100%
- max-width 500px
- margin 0 auto
- text-align center
- background #fff
- box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
+ > .fetching
+ margin 0
+ padding 32px
+ color #555
- > .fetching
- margin 0
- padding 32px
- color #555
+ > div
+ padding 64px
- > div
- padding 64px
+ > h1
+ margin 0 0 8px 0
+ padding 0
+ font-size 20px
+ font-weight normal
- > h1
- margin 0 0 8px 0
- padding 0
- font-size 20px
- font-weight normal
+ > p
+ margin 0
+ color #555
- > p
- margin 0
- color #555
+ &.denied > h1
+ color #e65050
- &.denied > h1
- color #e65050
+ &.accepted > h1
+ color #50bbe6
- &.accepted > h1
- color #50bbe6
+ &.signin
+ padding 32px 32px 16px 32px
- &.signin
- padding 32px 32px 16px 32px
+ > h1
+ margin 0 0 22px 0
+ padding 0
+ font-size 20px
+ font-weight normal
+ color #555
- > h1
- margin 0 0 22px 0
- padding 0
- font-size 20px
- font-weight normal
- color #555
+ @media (max-width 600px)
+ max-width none
+ box-shadow none
- @media (max-width 600px)
- max-width none
- box-shadow none
+ @media (max-width 500px)
+ > div
+ > h1
+ font-size 16px
- @media (max-width 500px)
- > div
- > h1
- font-size 16px
+ > footer
+ > img
+ display block
+ width 64px
+ height 64px
+ margin 0 auto
- > footer
- > img
- display block
- width 64px
- height 64px
- margin 0 auto
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
-script.
- @mixin \i
- @mixin \api
+ @state = null
+ @fetching = true
- @state = null
- @fetching = true
+ @token = window.location.href.split \/ .pop!
- @token = window.location.href.split \/ .pop!
+ @on \mount ~>
+ if not @SIGNIN then return
- @on \mount ~>
- if not @SIGNIN then return
+ # Fetch session
+ @api \auth/session/show do
+ token: @token
+ .then (session) ~>
+ @session = session
+ @fetching = false
- # Fetch session
- @api \auth/session/show do
- token: @token
- .then (session) ~>
- @session = session
- @fetching = false
+ # 既に連携していた場合
+ if @session.app.is_authorized
+ @api \auth/accept do
+ token: @session.token
+ .then ~>
+ @accepted!
+ else
+ @update!
- # 既に連携していた場合
- if @session.app.is_authorized
- @api \auth/accept do
- token: @session.token
- .then ~>
- @accepted!
- else
- @update!
+ @refs.form.on \denied ~>
+ @state = \denied
+ @update!
- @refs.form.on \denied ~>
- @state = \denied
- @update!
+ @refs.form.on \accepted @accepted
- @refs.form.on \accepted @accepted
+ .catch (error) ~>
+ @fetching = false
+ @state = \fetch-session-error
+ @update!
- .catch (error) ~>
- @fetching = false
- @state = \fetch-session-error
+ @accepted = ~>
+ @state = \accepted
@update!
- @accepted = ~>
- @state = \accepted
- @update!
-
- if @session.app.callback_url
- location.href = @session.app.callback_url + '?token=' + @session.token
+ if @session.app.callback_url
+ location.href = @session.app.callback_url + '?token=' + @session.token
+ </script>
+</mk-index>
diff --git a/src/web/app/common/tags/copyright.tag b/src/web/app/common/tags/copyright.tag
index 0fccf375e8..c5041935f4 100644
--- a/src/web/app/common/tags/copyright.tag
+++ b/src/web/app/common/tags/copyright.tag
@@ -1,5 +1,11 @@
-mk-copyright
- span (c) syuilo 2014-2017
+<mk-copyright><span>(c) syuilo 2014-2017</span>
+ <style type="stylus">
+ :scope
+ display block
-style.
- 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 19ef68bea6..0473884497 100644
--- a/src/web/app/common/tags/core-error.tag
+++ b/src/web/app/common/tags/core-error.tag
@@ -1,63 +1,64 @@
-mk-core-error
- //i: i.fa.fa-times-circle
- img(src='/_/resources/error.jpg', alt='')
- h1: mk-ripple-string サーバーに接続できません
- p.text
- | インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから
- a(onclick={ retry }) 再度お試し
- | ください。
- p.thanks いつもMisskeyをご利用いただきありがとうございます。
+<mk-core-error>
+ <!--i: i.fa.fa-times-circle--><img src="/_/resources/error.jpg" alt=""/>
+ <h1>
+ <mk-ripple-string>サーバーに接続できません</mk-ripple-string>
+ </h1>
+ <p class="text">インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから<a onclick="{ retry }">再度お試し</a>ください。</p>
+ <p class="thanks">いつもMisskeyをご利用いただきありがとうございます。</p>
+ <style type="stylus">
+ :scope
+ position fixed
+ z-index 16385
+ top 0
+ left 0
+ width 100%
+ height 100%
+ text-align center
+ background #f8f8f8
-style.
- position fixed
- z-index 16385
- top 0
- left 0
- width 100%
- height 100%
- text-align center
- background #f8f8f8
+ > i
+ display block
+ margin-top 64px
+ font-size 5em
+ color #6998a0
- > i
- display block
- margin-top 64px
- font-size 5em
- color #6998a0
+ > img
+ display block
+ height 200px
+ margin 64px auto 0 auto
+ pointer-events none
+ -ms-user-select none
+ -moz-user-select none
+ -webkit-user-select none
+ user-select none
- > img
- display block
- height 200px
- margin 64px auto 0 auto
- pointer-events none
- -ms-user-select none
- -moz-user-select none
- -webkit-user-select none
- user-select none
+ > h1
+ display block
+ margin 32px auto 16px auto
+ font-size 1.5em
+ color #555
- > h1
- display block
- margin 32px auto 16px auto
- font-size 1.5em
- color #555
+ > .text
+ display block
+ margin 0 auto
+ max-width 600px
+ font-size 1em
+ color #666
- > .text
- display block
- margin 0 auto
- max-width 600px
- font-size 1em
- color #666
+ > .thanks
+ display block
+ margin 32px auto 0 auto
+ padding 32px 0 32px 0
+ max-width 600px
+ font-size 0.9em
+ font-style oblique
+ color #aaa
+ border-top solid 1px #eee
- > .thanks
- display block
- margin 32px auto 0 auto
- padding 32px 0 32px 0
- max-width 600px
- font-size 0.9em
- font-style oblique
- color #aaa
- border-top solid 1px #eee
-
-script.
- @retry = ~>
- @unmount!
- @opts.retry!
+ </style>
+ <script>
+ @retry = ~>
+ @unmount!
+ @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 47eca62acd..71755dd8f3 100644
--- a/src/web/app/common/tags/ellipsis.tag
+++ b/src/web/app/common/tags/ellipsis.tag
@@ -1,25 +1,29 @@
-mk-ellipsis
- span .
- span .
- span .
+<mk-ellipsis><span>.</span><span>.</span><span>.</span>
+ <style type="stylus">
+ :scope
+ display inline
-style.
- display inline
+ > span
+ animation ellipsis 1.4s infinite ease-in-out both
- > span
- animation ellipsis 1.4s infinite ease-in-out both
+ &:nth-child(1)
+ animation-delay 0s
- &:nth-child(1)
- animation-delay 0s
+ &:nth-child(2)
+ animation-delay 0.16s
- &:nth-child(2)
- animation-delay 0.16s
+ &:nth-child(3)
+ animation-delay 0.32s
- &:nth-child(3)
- animation-delay 0.32s
+ @keyframes ellipsis
+ 0%, 80%, 100%
+ opacity 1
+ 40%
+ opacity 0
- @keyframes ellipsis
- 0%, 80%, 100%
- 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 68b8f95ad7..4569fe81f1 100644
--- a/src/web/app/common/tags/file-type-icon.tag
+++ b/src/web/app/common/tags/file-type-icon.tag
@@ -1,9 +1,11 @@
-mk-file-type-icon
- i.fa.fa-file-image-o(if={ kind == 'image' })
+<mk-file-type-icon><i class="fa fa-file-image-o" if="{ kind == 'image' }"></i>
+ <style type="stylus">
+ :scope
+ display inline
-style.
- display inline
-
-script.
- @file = @opts.file
- @kind = @file.type.split \/ .0
+ </style>
+ <script>
+ @file = @opts.file
+ @kind = @file.type.split \/ .0
+ </script>
+</mk-file-type-icon>
diff --git a/src/web/app/common/tags/forkit.tag b/src/web/app/common/tags/forkit.tag
index 7205fbe76b..5e44055455 100644
--- a/src/web/app/common/tags/forkit.tag
+++ b/src/web/app/common/tags/forkit.tag
@@ -1,37 +1,44 @@
-mk-forkit
- a(href='https://github.com/syuilo/misskey', target='_blank', title='View source on Github', aria-label='View source on Github')
- svg(width='80', height='80', viewBox='0 0 250 250', aria-hidden)
- path(d='M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z')
- path.octo-arm(d='M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2', fill='currentColor')
- path(d='M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z', fill='currentColor')
+<mk-forkit><a href="https://github.com/syuilo/misskey" target="_blank" title="View source on Github" aria-label="View source on Github">
+ <svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="aria-hidden">
+ <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
+ <path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor"></path>
+ <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor"></path>
+ </svg></a>
+ <style type="stylus">
+ :scope
+ display block
+ position absolute
+ top 0
+ right 0
-style.
- display block
- position absolute
- top 0
- right 0
+ > a
+ display block
- > a
- display block
+ > svg
+ display block
+ //fill #151513
+ //color #fff
+ fill $theme-color
+ color $theme-color-foreground
- > svg
- display block
- //fill #151513
- //color #fff
- fill $theme-color
- color $theme-color-foreground
+ .octo-arm
+ transform-origin 130px 106px
+
+ &:hover
+ .octo-arm
+ animation octocat-wave 560ms ease-in-out
+
+ @keyframes octocat-wave
+ 0%, 100%
+ transform rotate(0)
+ 20%, 60%
+ transform rotate(-25deg)
+ 40%, 80%
+ transform rotate(10deg)
- .octo-arm
- transform-origin 130px 106px
+
- &:hover
- .octo-arm
- animation octocat-wave 560ms ease-in-out
+
- @keyframes octocat-wave
- 0%, 100%
- transform rotate(0)
- 20%, 60%
- transform rotate(-25deg)
- 40%, 80%
- transform rotate(10deg)
+ </style>
+</mk-forkit>
diff --git a/src/web/app/common/tags/introduction.tag b/src/web/app/common/tags/introduction.tag
index 99df485674..cfeeb24ace 100644
--- a/src/web/app/common/tags/introduction.tag
+++ b/src/web/app/common/tags/introduction.tag
@@ -1,22 +1,29 @@
-mk-introduction
- article
- h1 Misskeyとは?
- <p><ruby>Misskey<rt>みすきー</rt></ruby>は、<a href="http://syuilo.com" target="_blank">syuilo</a>が2014年くらいから<a href="https://github.com/syuilo/misskey" target="_blank">オープンソースで</a>開発・運営を行っている、ミニブログベースのSNSです。</p>
- <p>Twitter, Facebook, LINE, Google+ などを<del>パクって</del><i>参考にして</i>います。</p>
- <p>無料で誰でも利用でき、広告は一切掲載していません。</p>
- <p><a href={ CONFIG.urls.about } target="_blank">もっと知りたい方はこちら</a></p>
+<mk-introduction>
+ <article>
+ <h1>Misskeyとは?</h1><p><ruby>Misskey<rt>みすきー</rt></ruby>は、<a href="http://syuilo.com" target="_blank">syuilo</a>が2014年くらいから<a href="https://github.com/syuilo/misskey" target="_blank">オープンソースで</a>開発・運営を行っている、ミニブログベースのSNSです。</p>
+<p>Twitter, Facebook, LINE, Google+ などを<del>パクって</del><i>参考にして</i>います。</p>
+<p>無料で誰でも利用でき、広告は一切掲載していません。</p>
+<p><a href="{ CONFIG.urls.about }" target="_blank">もっと知りたい方はこちら</a></p>
+ </article>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ h1
+ margin 0
+ text-align center
+ font-size 1.2em
- h1
- margin 0
- text-align center
- font-size 1.2em
+ p
+ margin 16px 0
- p
- margin 16px 0
+ &:last-child
+ margin 0
+ text-align center
- &:last-child
- margin 0
- text-align center
+
+
+
+
+ </style>
+</mk-introduction>
diff --git a/src/web/app/common/tags/number.tag b/src/web/app/common/tags/number.tag
index 589c747b35..3b9879655e 100644
--- a/src/web/app/common/tags/number.tag
+++ b/src/web/app/common/tags/number.tag
@@ -1,15 +1,18 @@
-mk-number
+<mk-number>
+ <style type="stylus">
+ :scope
+ display inline
-style.
- display inline
+ </style>
+ <script>
+ @on \mount ~>
+ # バグ? https://github.com/riot/riot/issues/2103
+ #value = @opts.value
+ value = @opts.riot-value
+ max = @opts.max
-script.
- @on \mount ~>
- # バグ? https://github.com/riot/riot/issues/2103
- #value = @opts.value
- value = @opts.riot-value
- max = @opts.max
+ if max? then if value > max then value = max
- if max? then if value > max then value = max
-
- @root.innerHTML = value.to-locale-string!
+ @root.innerHTML = value.to-locale-string!
+ </script>
+</mk-number>
diff --git a/src/web/app/common/tags/raw.tag b/src/web/app/common/tags/raw.tag
index 131826e597..ee7318a9f2 100644
--- a/src/web/app/common/tags/raw.tag
+++ b/src/web/app/common/tags/raw.tag
@@ -1,7 +1,8 @@
-mk-raw
+<mk-raw>
+ <style type="stylus">
+ :scope
+ display inline
-style.
- display inline
-
-script.
- @root.innerHTML = @opts.content
+ </style>
+ <script>@root.innerHTML = @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
index 3be6903369..2afd2b9ff3 100644
--- a/src/web/app/common/tags/ripple-string.tag
+++ b/src/web/app/common/tags/ripple-string.tag
@@ -1,24 +1,26 @@
-mk-ripple-string
- <yield/>
+<mk-ripple-string><yield/>
+ <style type="stylus">
+ :scope
+ display inline
-style.
- display inline
+ > span
+ animation ripple-string 5s infinite ease-in-out both
- > span
- animation ripple-string 5s infinite ease-in-out both
+ @keyframes ripple-string
+ 0%, 50%, 100%
+ opacity 1
+ 25%
+ opacity 0.5
- @keyframes ripple-string
- 0%, 50%, 100%
- opacity 1
- 25%
- opacity 0.5
-
-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
+ </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.tag b/src/web/app/common/tags/signin.tag
index 6f4013b1cb..dc5faca08d 100644
--- a/src/web/app/common/tags/signin.tag
+++ b/src/web/app/common/tags/signin.tag
@@ -1,136 +1,131 @@
-mk-signin
- form(onsubmit={ onsubmit }, class={ signing: signing })
- label.user-name
- input@username(
- type='text'
- pattern='^[a-zA-Z0-9\-]+$'
- placeholder='ユーザー名'
- autofocus
- required
- oninput={ oninput })
- i.fa.fa-at
- label.password
- input@password(
- type='password'
- placeholder='パスワード'
- required)
- i.fa.fa-lock
- button(type='submit', disabled={ signing }) { signing ? 'やっています...' : 'サインイン' }
-
-style.
- display block
-
- > form
- display block
- z-index 2
-
- &.signing
- &, *
- cursor wait !important
-
- label
+<mk-signin>
+ <form class="{ signing: signing }" onsubmit="{ onsubmit }">
+ <label class="user-name">
+ <input ref="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="ユーザー名" autofocus="autofocus" required="required" oninput="{ oninput }"/><i class="fa fa-at"></i>
+ </label>
+ <label class="password">
+ <input ref="password" type="password" placeholder="パスワード" required="required"/><i class="fa fa-lock"></i>
+ </label>
+ <button type="submit" disabled="{ signing }">{ signing ? 'やっています...' : 'サインイン' }</button>
+ </form>
+ <style type="stylus">
+ :scope
display block
- margin 12px 0
- i
+ > form
display block
- pointer-events none
- position absolute
- bottom 0
- top 0
- left 0
- z-index 1
- margin auto
- padding 0 16px
- height 1em
- color #898786
+ z-index 2
- input[type=text]
- input[type=password]
- user-select text
- display inline-block
- cursor auto
- padding 0 0 0 38px
- margin 0
- width 100%
- line-height 44px
- font-size 1em
- color rgba(0, 0, 0, 0.7)
- background #fff
- outline none
- border solid 1px #eee
- border-radius 4px
+ &.signing
+ &, *
+ cursor wait !important
- &:hover
- background rgba(255, 255, 255, 0.7)
- border-color #ddd
+ label
+ display block
+ margin 12px 0
- & + i
- color #797776
+ i
+ display block
+ pointer-events none
+ position absolute
+ bottom 0
+ top 0
+ left 0
+ z-index 1
+ margin auto
+ padding 0 16px
+ height 1em
+ color #898786
- &:focus
- background #fff
- border-color #ccc
+ input[type=text]
+ input[type=password]
+ user-select text
+ display inline-block
+ cursor auto
+ padding 0 0 0 38px
+ margin 0
+ width 100%
+ line-height 44px
+ font-size 1em
+ color rgba(0, 0, 0, 0.7)
+ background #fff
+ outline none
+ border solid 1px #eee
+ border-radius 4px
- & + i
- color #797776
+ &:hover
+ background rgba(255, 255, 255, 0.7)
+ border-color #ddd
- [type=submit]
- cursor pointer
- padding 16px
- margin -6px 0 0 0
- width 100%
- font-size 1.2em
- color rgba(0, 0, 0, 0.5)
- outline none
- border none
- border-radius 0
- background transparent
- transition all .5s ease
+ & + i
+ color #797776
- &:hover
- color $theme-color
- transition all .2s ease
+ &:focus
+ background #fff
+ border-color #ccc
- &:focus
- color $theme-color
- transition all .2s ease
+ & + i
+ color #797776
- &:active
- color darken($theme-color, 30%)
- transition all .2s ease
+ [type=submit]
+ cursor pointer
+ padding 16px
+ margin -6px 0 0 0
+ width 100%
+ font-size 1.2em
+ color rgba(0, 0, 0, 0.5)
+ outline none
+ border none
+ border-radius 0
+ background transparent
+ transition all .5s ease
- &:disabled
- opacity 0.7
+ &:hover
+ color $theme-color
+ transition all .2s ease
-script.
- @mixin \api
+ &:focus
+ color $theme-color
+ transition all .2s ease
- @user = null
- @signing = false
+ &:active
+ color darken($theme-color, 30%)
+ transition all .2s ease
- @oninput = ~>
- @api \users/show do
- username: @refs.username.value
- .then (user) ~>
- @user = user
- @trigger \user user
- @update!
+ &:disabled
+ opacity 0.7
+
+ </style>
+ <script>
+ @mixin \api
- @onsubmit = (e) ~>
- e.prevent-default!
+ @user = null
+ @signing = false
- @signing = true
- @update!
+ @oninput = ~>
+ @api \users/show do
+ username: @refs.username.value
+ .then (user) ~>
+ @user = user
+ @trigger \user user
+ @update!
- @api \signin do
- username: @refs.username.value
- password: @refs.password.value
- .then ~>
- location.reload!
- .catch ~>
- alert 'something happened'
- @signing = false
+ @onsubmit = (e) ~>
+ e.prevent-default!
+
+ @signing = true
@update!
- false
+ @api \signin do
+ username: @refs.username.value
+ password: @refs.password.value
+ .then ~>
+ location.reload!
+ .catch ~>
+ alert 'something happened'
+ @signing = false
+ @update!
+
+ false
+ </script>
+</mk-signin>
diff --git a/src/web/app/common/tags/signup.tag b/src/web/app/common/tags/signup.tag
index 9b28d7d1ff..c07b27fb19 100644
--- a/src/web/app/common/tags/signup.tag
+++ b/src/web/app/common/tags/signup.tag
@@ -1,352 +1,293 @@
-mk-signup
- form(onsubmit={ onsubmit }, autocomplete='off')
- label.username
- p.caption
- i.fa.fa-at
- | ユーザー名
- input@username(
- type='text'
- pattern='^[a-zA-Z0-9\-]{3,20}$'
- placeholder='a~z、A~Z、0~9、-'
- autocomplete='off'
- required
- onkeyup={ on-change-username })
-
- p.profile-page-url-preview(if={ refs.username.value != '' && username-state != 'invalid-format' && username-state != 'min-range' && username-state != 'max-range' }) { CONFIG.url + '/' + refs.username.value }
-
- p.info(if={ username-state == 'wait' }, style='color:#999')
- i.fa.fa-fw.fa-spinner.fa-pulse
- | 確認しています...
- p.info(if={ username-state == 'ok' }, style='color:#3CB7B5')
- i.fa.fa-fw.fa-check
- | 利用できます
- p.info(if={ username-state == 'unavailable' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 既に利用されています
- p.info(if={ username-state == 'error' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 通信エラー
- p.info(if={ username-state == 'invalid-format' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | a~z、A~Z、0~9、-(ハイフン)が使えます
- p.info(if={ username-state == 'min-range' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 3文字以上でお願いします!
- p.info(if={ username-state == 'max-range' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 20文字以内でお願いします
-
- label.password
- p.caption
- i.fa.fa-lock
- | パスワード
- input@password(
- type='password'
- placeholder='8文字以上を推奨します'
- autocomplete='off'
- required
- onkeyup={ on-change-password })
-
- div.meter(if={ password-strength != '' }, data-strength={ password-strength })
- div.value@password-metar
-
- p.info(if={ password-strength == 'low' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 弱いパスワード
- p.info(if={ password-strength == 'medium' }, style='color:#3CB7B5')
- i.fa.fa-fw.fa-check
- | まあまあのパスワード
- p.info(if={ password-strength == 'high' }, style='color:#3CB7B5')
- i.fa.fa-fw.fa-check
- | 強いパスワード
-
- label.retype-password
- p.caption
- i.fa.fa-lock
- | パスワード(再入力)
- input@password-retype(
- type='password'
- placeholder='確認のため再入力してください'
- autocomplete='off'
- required
- onkeyup={ on-change-password-retype })
-
- p.info(if={ password-retype-state == 'match' }, style='color:#3CB7B5')
- i.fa.fa-fw.fa-check
- | 確認されました
- p.info(if={ password-retype-state == 'not-match' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 一致していません
-
- label.recaptcha
- p.caption
- i.fa.fa-toggle-on(if={ recaptchaed })
- i.fa.fa-toggle-off(if={ !recaptchaed })
- | 認証
- div.g-recaptcha(
- data-callback='onRecaptchaed'
- data-expired-callback='onRecaptchaExpired'
- data-sitekey={ CONFIG.recaptcha.site-key })
-
- label.agree-tou
- input(
- name='agree-tou',
- type='checkbox',
- autocomplete='off',
- required)
- p
- a(href={ CONFIG.urls.about + '/tou' }, target='_blank') 利用規約
- | に同意する
-
- button(onclick={ onsubmit })
- | アカウント作成
-
-style.
- display block
- min-width 302px
- overflow hidden
-
- > form
-
- label
+<mk-signup>
+ <form onsubmit="{ onsubmit }" autocomplete="off">
+ <label class="username">
+ <p class="caption"><i class="fa fa-at"></i>ユーザー名</p>
+ <input ref="username" type="text" pattern="^[a-zA-Z0-9-]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required="required" onkeyup="{ onChangeUsername }"/>
+ <p class="profile-page-url-preview" if="{ refs.username.value != '' &amp;&amp; username-state != 'invalidFormat' &amp;&amp; username-state != 'minRange' &amp;&amp; username-state != 'maxRange' }">{ CONFIG.url + '/' + refs.username.value }</p>
+ <p class="info" if="{ usernameState == 'wait' }" style="color:#999"><i class="fa fa-fw fa-spinner fa-pulse"></i>確認しています...</p>
+ <p class="info" if="{ usernameState == 'ok' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>利用できます</p>
+ <p class="info" if="{ usernameState == 'unavailable' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>既に利用されています</p>
+ <p class="info" if="{ usernameState == 'error' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>通信エラー</p>
+ <p class="info" if="{ usernameState == 'invalid-format' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>a~z、A~Z、0~9、-(ハイフン)が使えます</p>
+ <p class="info" if="{ usernameState == 'min-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>3文字以上でお願いします!</p>
+ <p class="info" if="{ usernameState == 'max-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>20文字以内でお願いします</p>
+ </label>
+ <label class="password">
+ <p class="caption"><i class="fa fa-lock"></i>パスワード</p>
+ <input ref="password" type="password" placeholder="8文字以上を推奨します" autocomplete="off" required="required" onkeyup="{ onChangePassword }"/>
+ <div class="meter" if="{ passwordStrength != '' }" data-strength="{ passwordStrength }">
+ <div class="value" ref="passwordMetar"></div>
+ </div>
+ <p class="info" if="{ passwordStrength == 'low' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>弱いパスワード</p>
+ <p class="info" if="{ passwordStrength == 'medium' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>まあまあのパスワード</p>
+ <p class="info" if="{ passwordStrength == 'high' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>強いパスワード</p>
+ </label>
+ <label class="retype-password">
+ <p class="caption"><i class="fa fa-lock"></i>パスワード(再入力)</p>
+ <input ref="passwordRetype" type="password" placeholder="確認のため再入力してください" autocomplete="off" required="required" onkeyup="{ onChangePasswordRetype }"/>
+ <p class="info" if="{ passwordRetypeState == 'match' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>確認されました</p>
+ <p class="info" if="{ passwordRetypeState == 'not-match' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>一致していません</p>
+ </label>
+ <label class="recaptcha">
+ <p class="caption"><i class="fa fa-toggle-on" if="{ recaptchaed }"></i><i class="fa fa-toggle-off" if="{ !recaptchaed }"></i>認証</p>
+ <div class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" data-sitekey="{ CONFIG.recaptcha.siteKey }"></div>
+ </label>
+ <label class="agree-tou">
+ <input name="agree-tou" type="checkbox" autocomplete="off" required="required"/>
+ <p><a href="{ CONFIG.urls.about + '/tou' }" target="_blank">利用規約</a>に同意する</p>
+ </label>
+ <button onclick="{ onsubmit }">アカウント作成</button>
+ </form>
+ <style type="stylus">
+ :scope
display block
- margin 16px 0
+ min-width 302px
+ overflow hidden
- > .caption
- margin 0 0 4px 0
- color #828888
- font-size 0.95em
+ > form
- > i
- margin-right 0.25em
- color #96adac
+ label
+ display block
+ margin 16px 0
- > .info
- display block
- margin 4px 0
- font-size 0.8em
+ > .caption
+ margin 0 0 4px 0
+ color #828888
+ font-size 0.95em
- > i
- margin-right 0.3em
+ > i
+ margin-right 0.25em
+ color #96adac
- &.username
- .profile-page-url-preview
- display block
- margin 4px 8px 0 4px
- font-size 0.8em
- color #888
+ > .info
+ display block
+ margin 4px 0
+ font-size 0.8em
- &:empty
- display none
+ > i
+ margin-right 0.3em
- &:not(:empty) + .info
- margin-top 0
+ &.username
+ .profile-page-url-preview
+ display block
+ margin 4px 8px 0 4px
+ font-size 0.8em
+ color #888
- &.password
- .meter
- display block
- margin-top 8px
- width 100%
- height 8px
+ &:empty
+ display none
- &[data-strength='']
- display none
+ &:not(:empty) + .info
+ margin-top 0
- &[data-strength='low']
- > .value
- background #d73612
+ &.password
+ .meter
+ display block
+ margin-top 8px
+ width 100%
+ height 8px
- &[data-strength='medium']
- > .value
- background #d7ca12
+ &[data-strength='']
+ display none
- &[data-strength='high']
- > .value
- background #61bb22
+ &[data-strength='low']
+ > .value
+ background #d73612
- > .value
- display block
- width 0%
- height 100%
- background transparent
- border-radius 4px
- transition all 0.1s ease
+ &[data-strength='medium']
+ > .value
+ background #d7ca12
- [type=text], [type=password]
- user-select text
- display inline-block
- cursor auto
- padding 0 12px
- margin 0
- width 100%
- line-height 44px
- font-size 1em
- color #333 !important
- background #fff !important
- outline none
- border solid 1px rgba(0, 0, 0, 0.1)
- border-radius 4px
- box-shadow 0 0 0 114514px #fff inset
- transition all .3s ease
+ &[data-strength='high']
+ > .value
+ background #61bb22
- &:hover
- border-color rgba(0, 0, 0, 0.2)
- transition all .1s ease
+ > .value
+ display block
+ width 0%
+ height 100%
+ background transparent
+ border-radius 4px
+ transition all 0.1s ease
- &:focus
- color $theme-color !important
- border-color $theme-color
- box-shadow 0 0 0 1024px #fff inset, 0 0 0 4px rgba($theme-color, 10%)
- transition all 0s ease
+ [type=text], [type=password]
+ user-select text
+ display inline-block
+ cursor auto
+ padding 0 12px
+ margin 0
+ width 100%
+ line-height 44px
+ font-size 1em
+ color #333 !important
+ background #fff !important
+ outline none
+ border solid 1px rgba(0, 0, 0, 0.1)
+ border-radius 4px
+ box-shadow 0 0 0 114514px #fff inset
+ transition all .3s ease
- &:disabled
- opacity 0.5
+ &:hover
+ border-color rgba(0, 0, 0, 0.2)
+ transition all .1s ease
- .agree-tou
- padding 4px
- border-radius 4px
+ &:focus
+ color $theme-color !important
+ border-color $theme-color
+ box-shadow 0 0 0 1024px #fff inset, 0 0 0 4px rgba($theme-color, 10%)
+ transition all 0s ease
- &:hover
- background #f4f4f4
+ &:disabled
+ opacity 0.5
- &:active
- background #eee
+ .agree-tou
+ padding 4px
+ border-radius 4px
- &, *
- cursor pointer
+ &:hover
+ background #f4f4f4
- p
- display inline
- color #555
+ &:active
+ background #eee
- button
- margin 0 0 32px 0
- padding 16px
- width 100%
- font-size 1em
- color #fff
- background $theme-color
- border-radius 3px
+ &, *
+ cursor pointer
- &:hover
- background lighten($theme-color, 5%)
+ p
+ display inline
+ color #555
- &:active
- background darken($theme-color, 5%)
+ button
+ margin 0 0 32px 0
+ padding 16px
+ width 100%
+ font-size 1em
+ color #fff
+ background $theme-color
+ border-radius 3px
-script.
- @mixin \api
- @mixin \get-password-strength
+ &:hover
+ background lighten($theme-color, 5%)
- @username-state = null
- @password-strength = ''
- @password-retype-state = null
- @recaptchaed = false
+ &:active
+ background darken($theme-color, 5%)
- window.on-recaptchaed = ~>
- @recaptchaed = true
- @update!
+ </style>
+ <script>
+ @mixin \api
+ @mixin \get-password-strength
- window.on-recaptcha-expired = ~>
+ @username-state = null
+ @password-strength = ''
+ @password-retype-state = null
@recaptchaed = false
- @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
-
- @on-change-username = ~>
- username = @refs.username.value
+ window.on-recaptchaed = ~>
+ @recaptchaed = true
+ @update!
- if username == ''
- @username-state = null
+ window.on-recaptcha-expired = ~>
+ @recaptchaed = false
@update!
- return
- err = switch
- | not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
- | username.length < 3chars => \min-range
- | username.length > 20chars => \max-range
- | _ => null
+ @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
- if err?
- @username-state = err
- @update!
- else
- @username-state = \wait
- @update!
+ @on-change-username = ~>
+ username = @refs.username.value
- @api \username/available do
- username: username
- .then (result) ~>
- if result.available
- @username-state = \ok
- else
- @username-state = \unavailable
+ if username == ''
+ @username-state = null
+ @update!
+ return
+
+ err = switch
+ | not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
+ | username.length < 3chars => \min-range
+ | username.length > 20chars => \max-range
+ | _ => null
+
+ if err?
+ @username-state = err
@update!
- .catch (err) ~>
- @username-state = \error
+ else
+ @username-state = \wait
@update!
- @on-change-password = ~>
- password = @refs.password.value
+ @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!
+
+ @on-change-password = ~>
+ password = @refs.password.value
- if password == ''
- @password-strength = ''
- return
+ if password == ''
+ @password-strength = ''
+ return
- strength = @get-password-strength password
+ strength = @get-password-strength password
- if strength > 0.3
- @password-strength = \medium
- if strength > 0.7
- @password-strength = \high
- else
- @password-strength = \low
+ if strength > 0.3
+ @password-strength = \medium
+ if strength > 0.7
+ @password-strength = \high
+ else
+ @password-strength = \low
- @update!
+ @update!
- @refs.password-metar.style.width = (strength * 100) + \%
+ @refs.password-metar.style.width = (strength * 100) + \%
- @on-change-password-retype = ~>
- password = @refs.password.value
- retyped-password = @refs.password-retype.value
+ @on-change-password-retype = ~>
+ password = @refs.password.value
+ retyped-password = @refs.password-retype.value
- if retyped-password == ''
- @password-retype-state = null
- return
+ if retyped-password == ''
+ @password-retype-state = null
+ return
- if password == retyped-password
- @password-retype-state = \match
- else
- @password-retype-state = \not-match
+ if password == retyped-password
+ @password-retype-state = \match
+ else
+ @password-retype-state = \not-match
- @onsubmit = (e) ~>
- e.prevent-default!
+ @onsubmit = (e) ~>
+ e.prevent-default!
- username = @refs.username.value
- password = @refs.password.value
+ username = @refs.username.value
+ password = @refs.password.value
- locker = document.body.append-child document.create-element \mk-locker
+ locker = document.body.append-child document.create-element \mk-locker
- @api \signup do
- username: username
- password: password
- 'g-recaptcha-response': grecaptcha.get-response!
- .then ~>
- @api \signin do
+ @api \signup do
username: username
password: password
+ 'g-recaptcha-response': grecaptcha.get-response!
.then ~>
- location.href = CONFIG.url
- .catch ~>
- alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
+ @api \signin do
+ username: username
+ password: password
+ .then ~>
+ location.href = CONFIG.url
+ .catch ~>
+ alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
- grecaptcha.reset!
- @recaptchaed = false
+ grecaptcha.reset!
+ @recaptchaed = false
- locker.parent-node.remove-child locker
+ locker.parent-node.remove-child locker
- false
+ 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 5a6d5787ea..ffba09c2da 100644
--- a/src/web/app/common/tags/special-message.tag
+++ b/src/web/app/common/tags/special-message.tag
@@ -1,24 +1,27 @@
-mk-special-message
- p(if={ m == 1 && d == 1 }) Happy New Year!
- p(if={ m == 12 && d == 25 }) Merry Christmas!
+<mk-special-message>
+ <p if="{ m == 1 &amp;&amp; d == 1 }">Happy New Year! </p>
+ <p if="{ m == 12 &amp;&amp; d == 25 }">Merry Christmas!</p>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ &:empty
+ display none
- &:empty
- display none
+ > p
+ margin 0
+ padding 4px
+ text-align center
+ font-size 14px
+ font-weight bold
+ text-transform uppercase
+ color #fff
+ background #ff1036
- > p
- margin 0
- padding 4px
- text-align center
- font-size 14px
- font-weight bold
- text-transform uppercase
- color #fff
- background #ff1036
-
-script.
- now = new Date!
- @d = now.get-date!
- @m = now.get-month! + 1
+ </style>
+ <script>
+ now = new Date!
+ @d = now.get-date!
+ @m = now.get-month! + 1
+ </script>
+</mk-special-message>
diff --git a/src/web/app/common/tags/time.tag b/src/web/app/common/tags/time.tag
index 52ad89a44f..5456adb0b6 100644
--- a/src/web/app/common/tags/time.tag
+++ b/src/web/app/common/tags/time.tag
@@ -1,43 +1,41 @@
-mk-time
- time(datetime={ opts.time })
- span(if={ mode == 'relative' }) { relative }
- span(if={ mode == 'absolute' }) { absolute }
- span(if={ mode == 'detail' }) { absolute } ({ relative })
+<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>
+ <script>
+ @time = new Date @opts.time
+ @mode = @opts.mode || \relative
+ @tickid = null
-script.
- @time = new Date @opts.time
- @mode = @opts.mode || \relative
- @tickid = null
+ @absolute =
+ @time.get-full-year! + \年 +
+ @time.get-month! + 1 + \月 +
+ @time.get-date! + \日 +
+ ' ' +
+ @time.get-hours! + \時 +
+ @time.get-minutes! + \分
- @absolute =
- @time.get-full-year! + \年 +
- @time.get-month! + 1 + \月 +
- @time.get-date! + \日 +
- ' ' +
- @time.get-hours! + \時 +
- @time.get-minutes! + \分
+ @on \mount ~>
+ if @mode == \relative or @mode == \detail
+ @tick!
+ @tickid = set-interval @tick, 1000ms
- @on \mount ~>
- if @mode == \relative or @mode == \detail
- @tick!
- @tickid = set-interval @tick, 1000ms
+ @on \unmount ~>
+ if @mode == \relative or @mode == \detail
+ clear-interval @tickid
- @on \unmount ~>
- if @mode == \relative or @mode == \detail
- clear-interval @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!
+ @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!
+ </script>
+</mk-time>
diff --git a/src/web/app/common/tags/uploader.tag b/src/web/app/common/tags/uploader.tag
index 6d4e9b6363..6a081ddaf0 100644
--- a/src/web/app/common/tags/uploader.tag
+++ b/src/web/app/common/tags/uploader.tag
@@ -1,201 +1,195 @@
-mk-uploader
- ol(if={ uploads.length > 0 })
- li(each={ uploads })
- div.img(style='background-image: url({ img })')
- p.name
- i.fa.fa-spinner.fa-pulse
- | { name }
- p.status
- span.initing(if={ progress == undefined })
- | 待機中
- mk-ellipsis
- span.kb(if={ progress != undefined })
- | { String(Math.floor(progress.value / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }
- i KB
- = ' / '
- | { String(Math.floor(progress.max / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }
- i KB
- span.percentage(if={ progress != undefined }) { Math.floor((progress.value / progress.max) * 100) }
- progress(if={ progress != undefined && progress.value != progress.max }, value={ progress.value }, max={ progress.max })
- div.progress.initing(if={ progress == undefined })
- div.progress.waiting(if={ progress != undefined && progress.value == progress.max })
-
-style.
- display block
- overflow auto
-
- &:empty
- display none
-
- > ol
- display block
- margin 0
- padding 0
- list-style none
-
- > li
+<mk-uploader>
+ <ol if="{ uploads.length &gt; 0 }">
+ <li each="{ uploads }">
+ <div class="img" style="background-image: url({ img })"></div>
+ <p class="name"><i class="fa fa-spinner fa-pulse"></i>{ name }</p>
+ <p class="status"><span class="initing" if="{ progress == undefined }">待機中
+ <mk-ellipsis></mk-ellipsis></span><span class="kb" if="{ progress != undefined }">{ String(Math.floor(progress.value / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }<i>KB</i> / { String(Math.floor(progress.max / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }<i>KB</i></span><span class="percentage" if="{ progress != undefined }">{ Math.floor((progress.value / progress.max) * 100) }</span></p>
+ <progress if="{ progress != undefined &amp;&amp; progress.value != progress.max }" value="{ progress.value }" max="{ progress.max }"></progress>
+ <div class="progress initing" if="{ progress == undefined }"></div>
+ <div class="progress waiting" if="{ progress != undefined &amp;&amp; progress.value == progress.max }"></div>
+ </li>
+ </ol>
+ <style type="stylus">
+ :scope
display block
- margin 8px 0 0 0
- padding 0
- height 36px
- box-shadow 0 -1px 0 rgba($theme-color, 0.1)
- border-top solid 8px transparent
+ overflow auto
- &:first-child
- margin 0
- box-shadow none
- border-top none
+ &:empty
+ display none
- > .img
+ > ol
display block
- position absolute
- top 0
- left 0
- width 36px
- height 36px
- background-size cover
- background-position center center
-
- > .name
- display block
- position absolute
- top 0
- left 44px
margin 0
padding 0
- max-width 256px
- font-size 0.8em
- color rgba($theme-color, 0.7)
- white-space nowrap
- text-overflow ellipsis
- overflow hidden
+ list-style none
- > i
- margin-right 4px
+ > li
+ display block
+ margin 8px 0 0 0
+ padding 0
+ height 36px
+ box-shadow 0 -1px 0 rgba($theme-color, 0.1)
+ border-top solid 8px transparent
- > .status
- display block
- position absolute
- top 0
- right 0
- margin 0
- padding 0
- font-size 0.8em
+ &:first-child
+ margin 0
+ box-shadow none
+ border-top none
- > .initing
- color rgba($theme-color, 0.5)
+ > .img
+ display block
+ position absolute
+ top 0
+ left 0
+ width 36px
+ height 36px
+ background-size cover
+ background-position center center
- > .kb
- color rgba($theme-color, 0.5)
+ > .name
+ display block
+ position absolute
+ top 0
+ left 44px
+ margin 0
+ padding 0
+ max-width 256px
+ font-size 0.8em
+ color rgba($theme-color, 0.7)
+ white-space nowrap
+ text-overflow ellipsis
+ overflow hidden
- > .percentage
- display inline-block
- width 48px
- text-align right
+ > i
+ margin-right 4px
- color rgba($theme-color, 0.7)
+ > .status
+ display block
+ position absolute
+ top 0
+ right 0
+ margin 0
+ padding 0
+ font-size 0.8em
- &:after
- content '%'
+ > .initing
+ color rgba($theme-color, 0.5)
- > progress
- display block
- position absolute
- bottom 0
- right 0
- margin 0
- width calc(100% - 44px)
- height 8px
- background transparent
- border none
- border-radius 4px
- overflow hidden
+ > .kb
+ color rgba($theme-color, 0.5)
- &::-webkit-progress-value
- background $theme-color
+ > .percentage
+ display inline-block
+ width 48px
+ text-align right
- &::-webkit-progress-bar
- background rgba($theme-color, 0.1)
+ color rgba($theme-color, 0.7)
- > .progress
- display block
- position absolute
- bottom 0
- right 0
- margin 0
- width calc(100% - 44px)
- height 8px
- border none
- border-radius 4px
- background linear-gradient(
- 45deg,
- lighten($theme-color, 30%) 25%,
- $theme-color 25%,
- $theme-color 50%,
- lighten($theme-color, 30%) 50%,
- lighten($theme-color, 30%) 75%,
- $theme-color 75%,
- $theme-color
- )
- background-size 32px 32px
- animation bg 1.5s linear infinite
+ &:after
+ content '%'
+
+ > progress
+ display block
+ position absolute
+ bottom 0
+ right 0
+ margin 0
+ width calc(100% - 44px)
+ height 8px
+ background transparent
+ border none
+ border-radius 4px
+ overflow hidden
+
+ &::-webkit-progress-value
+ background $theme-color
- &.initing
- opacity 0.3
+ &::-webkit-progress-bar
+ background rgba($theme-color, 0.1)
- @keyframes bg
- from {background-position: 0 0;}
- to {background-position: -64px 32px;}
+ > .progress
+ display block
+ position absolute
+ bottom 0
+ right 0
+ margin 0
+ width calc(100% - 44px)
+ height 8px
+ border none
+ border-radius 4px
+ background linear-gradient(
+ 45deg,
+ lighten($theme-color, 30%) 25%,
+ $theme-color 25%,
+ $theme-color 50%,
+ lighten($theme-color, 30%) 50%,
+ lighten($theme-color, 30%) 75%,
+ $theme-color 75%,
+ $theme-color
+ )
+ background-size 32px 32px
+ animation bg 1.5s linear infinite
-script.
- @mixin \i
+ &.initing
+ opacity 0.3
- @uploads = []
+ @keyframes bg
+ from {background-position: 0 0;}
+ to {background-position: -64px 32px;}
+ </style>
+ <script>
+ @mixin \i
- @upload = (file, folder) ~>
- id = Math.random!
+ @uploads = []
- ctx =
- id: id
- name: file.name || \untitled
- progress: undefined
+
+ @upload = (file, folder) ~>
+ id = Math.random!
- @uploads.push ctx
- @trigger \change-uploads @uploads
- @update!
+ ctx =
+ id: id
+ name: file.name || \untitled
+ progress: undefined
- reader = new FileReader!
- reader.onload = (e) ~>
- ctx.img = e.target.result
+ @uploads.push ctx
+ @trigger \change-uploads @uploads
@update!
- reader.read-as-data-URL file
- data = new FormData!
- data.append \i @I.token
- data.append \file file
+ reader = new FileReader!
+ reader.onload = (e) ~>
+ ctx.img = e.target.result
+ @update!
+ reader.read-as-data-URL file
- if folder?
- data.append \folder_id folder
+ data = new FormData!
+ data.append \i @I.token
+ data.append \file file
- xhr = new XMLHttpRequest!
- xhr.open \POST CONFIG.api.url + '/drive/files/create' true
- xhr.onload = (e) ~>
- drive-file = JSON.parse e.target.response
+ if folder?
+ data.append \folder_id folder
- @trigger \uploaded drive-file
+ xhr = new XMLHttpRequest!
+ xhr.open \POST CONFIG.api.url + '/drive/files/create' true
+ xhr.onload = (e) ~>
+ drive-file = JSON.parse e.target.response
- @uploads = @uploads.filter (x) -> x.id != id
- @trigger \change-uploads @uploads
+ @trigger \uploaded drive-file
- @update!
+ @uploads = @uploads.filter (x) -> x.id != id
+ @trigger \change-uploads @uploads
- 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.send data
+ 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.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 605d26bc67..860d4d547f 100644
--- a/src/web/app/common/tags/url-preview.tag
+++ b/src/web/app/common/tags/url-preview.tag
@@ -1,105 +1,110 @@
-mk-url-preview
- a(href={ url }, target='_blank', title={ url }, if={ !loading })
- div.thumbnail(if={ thumbnail }, style={ 'background-image: url(' + thumbnail + ')' })
- article
- header: h1 { title }
- p { description }
- footer
- img.icon(if={ icon }, src={ icon })
- p { sitename }
+<mk-url-preview><a href="{ url }" target="_blank" title="{ url }" if="{ !loading }">
+ <div class="thumbnail" if="{ thumbnail }" style="{ 'background-image: url(' + thumbnail + ')' }"></div>
+ <article>
+ <header>
+ <h1>{ title }</h1>
+ </header>
+ <p>{ description }</p>
+ <footer><img class="icon" if="{ icon }" src="{ icon }"/>
+ <p>{ sitename }</p>
+ </footer>
+ </article></a>
+ <style type="stylus">
+ :scope
+ display block
+ font-size 16px
-style.
- display block
- font-size 16px
+ > a
+ display block
+ border solid 1px #eee
+ border-radius 4px
+ overflow hidden
- > a
- display block
- border solid 1px #eee
- border-radius 4px
- overflow hidden
+ &:hover
+ text-decoration none
+ border-color #ddd
- &:hover
- text-decoration none
- border-color #ddd
+ > article > header > h1
+ text-decoration underline
- > article > header > h1
- text-decoration underline
+ > .thumbnail
+ position absolute
+ width 100px
+ height 100%
+ background-position center
+ background-size cover
- > .thumbnail
- position absolute
- width 100px
- height 100%
- background-position center
- background-size cover
+ & + article
+ left 100px
+ width calc(100% - 100px)
- & + article
- left 100px
- width calc(100% - 100px)
+ > article
+ padding 16px
- > article
- padding 16px
+ > header
+ margin-bottom 8px
- > header
- margin-bottom 8px
+ > h1
+ margin 0
+ font-size 1em
+ color #555
- > h1
- margin 0
- font-size 1em
- color #555
+ > p
+ margin 0
+ color #777
+ font-size 0.8em
- > p
- margin 0
- color #777
- font-size 0.8em
+ > footer
+ margin-top 8px
- > footer
- margin-top 8px
+ > img
+ display inline-block
+ width 16px
+ heigth 16px
+ margin-right 4px
+ vertical-align bottom
- > img
- display inline-block
- width 16px
- heigth 16px
- margin-right 4px
- vertical-align bottom
+ > p
+ display inline-block
+ margin 0
+ color #666
+ font-size 0.8em
+ line-height 16px
- > p
- display inline-block
- margin 0
- color #666
- font-size 0.8em
- line-height 16px
+ @media (max-width 500px)
+ font-size 8px
- @media (max-width 500px)
- font-size 8px
+ > a
+ border none
- > a
- border none
+ > .thumbnail
+ width 70px
- > .thumbnail
- width 70px
+ & + article
+ left 70px
+ width calc(100% - 70px)
- & + article
- left 70px
- width calc(100% - 70px)
+ > article
+ padding 8px
- > article
- padding 8px
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @url = @opts.url
+ @loading = true
- @url = @opts.url
- @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
- @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
-
- @loading = false
- @update!
+ @loading = false
+ @update!
+ </script>
+</mk-url-preview>
diff --git a/src/web/app/common/tags/url.tag b/src/web/app/common/tags/url.tag
index 18892e8108..be7db32c5f 100644
--- a/src/web/app/common/tags/url.tag
+++ b/src/web/app/common/tags/url.tag
@@ -1,50 +1,46 @@
-mk-url
- a(href={ url }, target={ opts.target })
- span.schema { schema }//
- span.hostname { hostname }
- span.port(if={ port != '' }) :{ port }
- span.pathname(if={ pathname != '' }) { pathname }
- span.query { query }
- span.hash { hash }
+<mk-url><a href="{ url }" target="{ opts.target }"><span class="schema">{ schema }//</span><span class="hostname">{ hostname }</span><span class="port" if="{ port != '' }">:{ port }</span><span class="pathname" if="{ pathname != '' }">{ pathname }</span><span class="query">{ query }</span><span class="hash">{ hash }</span></a>
+ <style type="stylus">
+ :scope
+ > a
+ &:after
+ content "\f14c"
+ display inline-block
+ padding-left 2px
+ font-family FontAwesome
+ font-size .9em
+ font-weight 400
+ font-style normal
-style.
- > a
- &:after
- content "\f14c"
- display inline-block
- padding-left 2px
- font-family FontAwesome
- font-size .9em
- font-weight 400
- font-style normal
+ > .schema
+ opacity 0.5
- > .schema
- opacity 0.5
+ > .hostname
+ font-weight bold
- > .hostname
- font-weight bold
+ > .pathname
+ opacity 0.8
- > .pathname
- opacity 0.8
+ > .query
+ opacity 0.5
- > .query
- opacity 0.5
+ > .hash
+ font-style italic
- > .hash
- font-style italic
+ </style>
+ <script>
+ @url = @opts.href
-script.
- @url = @opts.href
+ @on \before-mount ~>
+ parser = document.create-element \a
+ parser.href = @url
- @on \before-mount ~>
- parser = document.create-element \a
- parser.href = @url
+ @schema = parser.protocol
+ @hostname = parser.hostname
+ @port = parser.port
+ @pathname = parser.pathname
+ @query = parser.search
+ @hash = parser.hash
- @schema = parser.protocol
- @hostname = parser.hostname
- @port = parser.port
- @pathname = parser.pathname
- @query = parser.search
- @hash = parser.hash
-
- @update!
+ @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 a4cfe5726c..c84accb057 100644
--- a/src/web/app/desktop/tags/analog-clock.tag
+++ b/src/web/app/desktop/tags/analog-clock.tag
@@ -1,102 +1,105 @@
-mk-analog-clock
- canvas@canvas(width='256', height='256')
+<mk-analog-clock>
+ <canvas ref="canvas" width="256" height="256"></canvas>
+ <style type="stylus">
+ :scope
+ > canvas
+ display block
+ width 256px
+ height 256px
-style.
- > canvas
- display block
- width 256px
- height 256px
+ </style>
+ <script>
+ @on \mount ~>
+ @draw!
+ @clock = set-interval @draw, 1000ms
-script.
- @on \mount ~>
- @draw!
- @clock = set-interval @draw, 1000ms
+ @on \unmount ~>
+ clear-interval @clock
- @on \unmount ~>
- clear-interval @clock
+ @draw = ~>
+ now = new Date!
+ s = now.get-seconds!
+ m = now.get-minutes!
+ h = now.get-hours!
- @draw = ~>
- now = new Date!
- s = now.get-seconds!
- m = now.get-minutes!
- h = now.get-hours!
+ vec2 = (x, y) ->
+ @x = x
+ @y = y
- vec2 = (x, y) ->
- @x = x
- @y = y
+ 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
- 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
+ # 背景
+ 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!
- # 背景
- 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
+ # 分
+ 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.line-width = 1
+ ctx.stroke-style = \#ffffff
+ ctx.line-width = 2
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
+ (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!
- # 分
- 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!
-
- # 時
- 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!
+ # 時
+ 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!
- # 秒
- 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!
+ # 秒
+ 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!
+ </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 13d9df6914..ecebf26a32 100644
--- a/src/web/app/desktop/tags/autocomplete-suggestion.tag
+++ b/src/web/app/desktop/tags/autocomplete-suggestion.tag
@@ -1,182 +1,183 @@
-mk-autocomplete-suggestion
- ol.users@users(if={ users.length > 0 })
- li(each={ users }, onclick={ parent.on-click }, onkeydown={ parent.on-keydown }, tabindex='-1')
- img.avatar(src={ avatar_url + '?thumbnail&size=32' }, alt='')
- span.name { name }
- span.username @{ username }
-
-style.
- display block
- position absolute
- z-index 65535
- margin-top calc(1em + 8px)
- overflow hidden
- background #fff
- border solid 1px rgba(0, 0, 0, 0.1)
- border-radius 4px
-
- > .users
- display block
- margin 0
- padding 4px 0
- max-height 190px
- max-width 500px
- overflow auto
- list-style none
-
- > li
+<mk-autocomplete-suggestion>
+ <ol class="users" ref="users" if="{ users.length &gt; 0 }">
+ <li each="{ users }" onclick="{ parent.onClick }" onkeydown="{ parent.onKeydown }" tabindex="-1"><img class="avatar" src="{ avatar_url + '?thumbnail&amp;size=32' }" alt=""/><span class="name">{ name }</span><span class="username">@{ username }</span></li>
+ </ol>
+ <style type="stylus">
+ :scope
display block
- padding 4px 12px
- white-space nowrap
+ position absolute
+ z-index 65535
+ margin-top calc(1em + 8px)
overflow hidden
- font-size 0.9em
- color rgba(0, 0, 0, 0.8)
- cursor default
+ background #fff
+ border solid 1px rgba(0, 0, 0, 0.1)
+ border-radius 4px
+
+ > .users
+ display block
+ margin 0
+ padding 4px 0
+ max-height 190px
+ max-width 500px
+ overflow auto
+ list-style none
- &, *
- user-select none
+ > li
+ display block
+ padding 4px 12px
+ white-space nowrap
+ overflow hidden
+ font-size 0.9em
+ color rgba(0, 0, 0, 0.8)
+ cursor default
- &:hover
- &[data-selected='true']
- color #fff
- background $theme-color
+ &, *
+ user-select none
- .name
- color #fff
+ &:hover
+ &[data-selected='true']
+ color #fff
+ background $theme-color
- .username
- color #fff
+ .name
+ color #fff
- &:active
- color #fff
- background darken($theme-color, 10%)
+ .username
+ color #fff
- .name
- color #fff
+ &:active
+ color #fff
+ background darken($theme-color, 10%)
- .username
- color #fff
+ .name
+ color #fff
- .avatar
- vertical-align middle
- min-width 28px
- min-height 28px
- max-width 28px
- max-height 28px
- margin 0 8px 0 0
- border-radius 100%
+ .username
+ color #fff
- .name
- margin 0 8px 0 0
- /*font-weight bold*/
- font-weight normal
- color rgba(0, 0, 0, 0.8)
+ .avatar
+ vertical-align middle
+ min-width 28px
+ min-height 28px
+ max-width 28px
+ max-height 28px
+ margin 0 8px 0 0
+ border-radius 100%
- .username
- font-weight normal
- color rgba(0, 0, 0, 0.3)
+ .name
+ margin 0 8px 0 0
+ /*font-weight bold*/
+ font-weight normal
+ color rgba(0, 0, 0, 0.8)
-script.
- @mixin \api
+ .username
+ font-weight normal
+ color rgba(0, 0, 0, 0.3)
- @q = @opts.q
- @textarea = @opts.textarea
- @loading = true
- @users = []
- @select = -1
+ </style>
+ <script>
+ @mixin \api
- @on \mount ~>
- @textarea.add-event-listener \keydown @on-keydown
+ @q = @opts.q
+ @textarea = @opts.textarea
+ @loading = true
+ @users = []
+ @select = -1
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
+ @on \mount ~>
+ @textarea.add-event-listener \keydown @on-keydown
- @api \users/search_by_username do
- query: @q
- limit: 30users
- .then (users) ~>
- @users = users
- @loading = false
- @update!
- .catch (err) ~>
- console.error err
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.add-event-listener \mousedown @mousedown
- @on \unmount ~>
- @textarea.remove-event-listener \keydown @on-keydown
+ @api \users/search_by_username do
+ query: @q
+ limit: 30users
+ .then (users) ~>
+ @users = users
+ @loading = false
+ @update!
+ .catch (err) ~>
+ console.error err
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
+ @on \unmount ~>
+ @textarea.remove-event-listener \keydown @on-keydown
- @mousedown = (e) ~>
- if (!contains @root, e.target) and (@root != e.target)
- @close!
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.remove-event-listener \mousedown @mousedown
- @on-click = (e) ~>
- @complete e.item
+ @mousedown = (e) ~>
+ if (!contains @root, e.target) and (@root != e.target)
+ @close!
+
+ @on-click = (e) ~>
+ @complete e.item
- @on-keydown = (e) ~>
- key = e.which
- switch (key)
- | 10, 13 => # Key[ENTER]
- if @select != -1
+ @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!
- @complete @users[@select]
- else
@close!
- | 27 => # Key[ESC]
- e.prevent-default!
- e.stop-propagation!
- @close!
- | 38 => # Key[↑]
- if @select != -1
+ | 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-prev!
- else
+ @select-next!
+ | _ =>
@close!
- | 9, 40 => # Key[TAB] or Key[↓]
- e.prevent-default!
- e.stop-propagation!
- @select-next!
- | _ =>
- @close!
- @select-next = ~>
- @select++
+ @select-next = ~>
+ @select++
- if @select >= @users.length
- @select = 0
+ if @select >= @users.length
+ @select = 0
- @apply-select!
+ @apply-select!
- @select-prev = ~>
- @select--
+ @select-prev = ~>
+ @select--
- if @select < 0
- @select = @users.length - 1
+ if @select < 0
+ @select = @users.length - 1
- @apply-select!
+ @apply-select!
- @apply-select = ~>
- @refs.users.children.for-each (el) ~>
- el.remove-attribute \data-selected
+ @apply-select = ~>
+ @refs.users.children.for-each (el) ~>
+ el.remove-attribute \data-selected
- @refs.users.children[@select].set-attribute \data-selected \true
- @refs.users.children[@select].focus!
+ @refs.users.children[@select].set-attribute \data-selected \true
+ @refs.users.children[@select].focus!
- @complete = (user) ~>
- @opts.complete user
+ @complete = (user) ~>
+ @opts.complete user
- @close = ~>
- @opts.close!
+ @close = ~>
+ @opts.close!
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
+ 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 636853407c..37c67f07b2 100644
--- a/src/web/app/desktop/tags/big-follow-button.tag
+++ b/src/web/app/desktop/tags/big-follow-button.tag
@@ -1,134 +1,127 @@
-mk-big-follow-button
- button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following },
- onclick={ onclick },
- disabled={ wait },
- title={ user.is_following ? 'フォロー解除' : 'フォローする' })
- span(if={ !wait && user.is_following })
- i.fa.fa-minus
- | フォロー解除
- span(if={ !wait && !user.is_following })
- i.fa.fa-plus
- | フォロー
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ wait })
- div.init(if={ init }): i.fa.fa-spinner.fa-pulse.fa-fw
+<mk-big-follow-button>
+ <button class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }" if="{ !init }" onclick="{ onclick }" disabled="{ wait }" title="{ user.is_following ? 'フォロー解除' : 'フォローする' }"><span if="{ !wait &amp;&amp; user.is_following }"><i class="fa fa-minus"></i>フォロー解除</span><span if="{ !wait &amp;&amp; !user.is_following }"><i class="fa fa-plus"></i>フォロー</span><i class="fa fa-spinner fa-pulse fa-fw" if="{ wait }"></i></button>
+ <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > button
+ > .init
+ display block
+ cursor pointer
+ padding 0
+ margin 0
+ width 100%
+ line-height 38px
+ font-size 1em
+ outline none
+ border-radius 4px
- > button
- > .init
- display block
- cursor pointer
- padding 0
- margin 0
- width 100%
- line-height 38px
- font-size 1em
- outline none
- border-radius 4px
+ *
+ pointer-events none
- *
- pointer-events none
+ i
+ margin-right 8px
- i
- margin-right 8px
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- &:focus
- &:after
- content ""
- pointer-events none
- position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ &.follow
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
- &.follow
- color #888
- background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
- border solid 1px #e2e2e2
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
- &:hover
- background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
- border-color #dcdcdc
+ &:active
+ background #ececec
+ border-color #dcdcdc
- &:active
- background #ececec
- border-color #dcdcdc
+ &.unfollow
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
- &.unfollow
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- border solid 1px lighten($theme-color, 15%)
+ &:not(:disabled)
+ font-weight bold
- &:not(:disabled)
- font-weight bold
+ &:hover:not(:disabled)
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- &:hover:not(:disabled)
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:active:not(:disabled)
+ background $theme-color
+ border-color $theme-color
- &:active:not(:disabled)
- background $theme-color
- border-color $theme-color
+ &.wait
+ cursor wait !important
+ opacity 0.7
- &.wait
- cursor wait !important
- opacity 0.7
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
+ @mixin \stream
-script.
- @mixin \api
- @mixin \is-promise
- @mixin \stream
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ @init = true
+ @wait = false
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @init = true
- @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
-
- @on \unmount ~>
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
-
- @on-stream-follow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ @on \mount ~>
+ @user-promise.then (user) ~>
+ @user = user
+ @init = false
+ @update!
+ @stream.on \follow @on-stream-follow
+ @stream.on \unfollow @on-stream-unfollow
- @on-stream-unfollow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ @on \unmount ~>
+ @stream.off \follow @on-stream-follow
+ @stream.off \unfollow @on-stream-unfollow
- @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
+ @on-stream-follow = (user) ~>
+ if user.id == @user.id
+ @user = user
@update!
- else
- @api \following/create do
- user_id: @user.id
- .then ~>
- @user.is_following = true
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
+
+ @on-stream-unfollow = (user) ~>
+ if user.id == @user.id
+ @user = user
@update!
+
+ @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!
+ </script>
+</mk-big-follow-button>
diff --git a/src/web/app/desktop/tags/contextmenu.tag b/src/web/app/desktop/tags/contextmenu.tag
index 7c3c7b8a24..c82a1e1e3a 100644
--- a/src/web/app/desktop/tags/contextmenu.tag
+++ b/src/web/app/desktop/tags/contextmenu.tag
@@ -1,138 +1,139 @@
-mk-contextmenu
- | <yield />
+<mk-contextmenu><yield />
+ <style type="stylus">
+ :scope
+ $width = 240px
+ $item-height = 38px
+ $padding = 10px
-style.
- $width = 240px
- $item-height = 38px
- $padding = 10px
+ display none
+ position fixed
+ top 0
+ left 0
+ z-index 4096
+ width $width
+ font-size 0.8em
+ background #fff
+ border-radius 0 4px 4px 4px
+ box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
- display none
- position fixed
- top 0
- left 0
- z-index 4096
- width $width
- font-size 0.8em
- background #fff
- border-radius 0 4px 4px 4px
- box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
+ ul
+ display block
+ margin 0
+ padding $padding 0
+ list-style none
- ul
- display block
- margin 0
- padding $padding 0
- list-style none
+ li
+ display block
- li
- display block
+ &.separator
+ margin-top $padding
+ padding-top $padding
+ border-top solid 1px #eee
- &.separator
- margin-top $padding
- padding-top $padding
- border-top solid 1px #eee
+ &.has-child
+ > p
+ cursor default
- &.has-child
- > p
- cursor default
+ > i:last-child
+ position absolute
+ top 0
+ right 8px
+ line-height $item-height
- > i:last-child
- position absolute
- top 0
- right 8px
- line-height $item-height
+ &:hover > ul
+ visibility visible
- &:hover > ul
- visibility visible
+ &:active
+ > p, a
+ background $theme-color
- &:active
> p, a
- background $theme-color
-
- > p, a
- display block
- z-index 1
- margin 0
- padding 0 32px 0 38px
- line-height $item-height
- color #868C8C
- text-decoration none
- cursor pointer
-
- &:hover
- text-decoration none
+ display block
+ z-index 1
+ margin 0
+ padding 0 32px 0 38px
+ line-height $item-height
+ color #868C8C
+ text-decoration none
+ cursor pointer
- *
- pointer-events none
+ &:hover
+ text-decoration none
- > i
- width 28px
- margin-left -28px
- text-align center
+ *
+ pointer-events none
- &:hover
- > p, a
- text-decoration none
- background $theme-color
- color $theme-color-foreground
+ > i
+ width 28px
+ margin-left -28px
+ text-align center
- &:active
- > p, a
- text-decoration none
- background darken($theme-color, 10%)
- color $theme-color-foreground
+ &:hover
+ > p, a
+ text-decoration none
+ background $theme-color
+ color $theme-color-foreground
- li > ul
- visibility hidden
- position absolute
- top 0
- left $width
- margin-top -($padding)
- width $width
- background #fff
- border-radius 0 4px 4px 4px
- box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
- transition visibility 0s linear 0.2s
+ &:active
+ > p, a
+ text-decoration none
+ background darken($theme-color, 10%)
+ color $theme-color-foreground
-script.
+ li > ul
+ visibility hidden
+ position absolute
+ top 0
+ left $width
+ margin-top -($padding)
+ width $width
+ background #fff
+ border-radius 0 4px 4px 4px
+ box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
+ transition visibility 0s linear 0.2s
- @root.add-event-listener \contextmenu (e) ~>
- e.prevent-default!
+ </style>
+ <script>
+ @root.add-event-listener \contextmenu (e) ~>
+ e.prevent-default!
- @mousedown = (e) ~>
- e.prevent-default!
- if (!contains @root, e.target) and (@root != e.target)
- @close!
- return false
+ @mousedown = (e) ~>
+ e.prevent-default!
+ if (!contains @root, e.target) and (@root != e.target)
+ @close!
+ return false
- @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
+ @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
- Velocity @root, \finish true
- Velocity @root, { opacity: 0 } 0ms
- Velocity @root, {
- opacity: 1
- } {
- queue: false
- duration: 100ms
- easing: \linear
- }
+ Velocity @root, \finish true
+ Velocity @root, { opacity: 0 } 0ms
+ Velocity @root, {
+ opacity: 1
+ } {
+ queue: false
+ duration: 100ms
+ 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!
+ @close = ~>
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.remove-event-listener \mousedown @mousedown
+ @trigger \closed
+ @unmount!
- function contains(parent, child)
- node = child.parent-node
- while (node != null)
- if (node == parent)
- return true
- node = node.parent-node
- return false
+ function contains(parent, child)
+ node = child.parent-node
+ while (node != null)
+ if (node == parent)
+ return true
+ node = node.parent-node
+ return false
+ </script>
+</mk-contextmenu>
diff --git a/src/web/app/desktop/tags/crop-window.tag b/src/web/app/desktop/tags/crop-window.tag
index 16e1a72b3a..768c76d952 100644
--- a/src/web/app/desktop/tags/crop-window.tag
+++ b/src/web/app/desktop/tags/crop-window.tag
@@ -1,189 +1,188 @@
-mk-crop-window
- mk-window@window(is-modal={ true }, width={ '800px' })
- <yield to="header">
- i.fa.fa-crop
- | { parent.title }
- </yield>
- <yield to="content">
- div.body
- img@img(src={ parent.image.url + '?thumbnail&quality=80' }, alt='')
- div.action
- button.skip(onclick={ parent.skip }) クロップをスキップ
- button.cancel(onclick={ parent.cancel }) キャンセル
- button.ok(onclick={ parent.ok }) 決定
- </yield>
+<mk-crop-window>
+ <mk-window ref="window" is-modal="{ true }" width="{ '800px' }"><yield to="header"><i class="fa fa-crop"></i>{ parent.title }</yield>
+<yield to="content">
+ <div class="body"><img ref="img" src="{ parent.image.url + '?thumbnail&amp;quality=80' }" alt=""/></div>
+ <div class="action">
+ <button class="skip" onclick="{ parent.skip }">クロップをスキップ</button>
+ <button class="cancel" onclick="{ parent.cancel }">キャンセル</button>
+ <button class="ok" onclick="{ parent.ok }">決定</button>
+ </div></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
- [data-yield='content']
+ > .body
+ > img
+ width 100%
+ max-height 400px
- > .body
- > img
- width 100%
- max-height 400px
+ .cropper-modal {
+ opacity: 0.8;
+ }
- .cropper-modal {
- opacity: 0.8;
- }
+ .cropper-view-box {
+ outline-color: $theme-color;
+ }
- .cropper-view-box {
- outline-color: $theme-color;
- }
+ .cropper-line, .cropper-point {
+ background-color: $theme-color;
+ }
- .cropper-line, .cropper-point {
- background-color: $theme-color;
- }
+ .cropper-bg {
+ animation: cropper-bg 0.5s linear infinite;
+ }
- .cropper-bg {
- animation: cropper-bg 0.5s linear infinite;
- }
+ @-webkit-keyframes cropper-bg {
+ 0% {
+ background-position: 0 0;
+ }
- @-webkit-keyframes cropper-bg {
- 0% {
- background-position: 0 0;
- }
+ 100% {
+ background-position: -8px -8px;
+ }
+ }
- 100% {
- background-position: -8px -8px;
- }
- }
+ @-moz-keyframes cropper-bg {
+ 0% {
+ background-position: 0 0;
+ }
- @-moz-keyframes cropper-bg {
- 0% {
- background-position: 0 0;
- }
+ 100% {
+ background-position: -8px -8px;
+ }
+ }
- 100% {
- background-position: -8px -8px;
- }
- }
+ @-ms-keyframes cropper-bg {
+ 0% {
+ background-position: 0 0;
+ }
- @-ms-keyframes cropper-bg {
- 0% {
- background-position: 0 0;
- }
+ 100% {
+ background-position: -8px -8px;
+ }
+ }
- 100% {
- background-position: -8px -8px;
- }
- }
+ @keyframes cropper-bg {
+ 0% {
+ background-position: 0 0;
+ }
- @keyframes cropper-bg {
- 0% {
- background-position: 0 0;
- }
+ 100% {
+ background-position: -8px -8px;
+ }
+ }
- 100% {
- background-position: -8px -8px;
- }
- }
+ > .action
+ height 72px
+ background lighten($theme-color, 95%)
- > .action
- height 72px
- background lighten($theme-color, 95%)
+ .ok
+ .cancel
+ .skip
+ display block
+ position absolute
+ bottom 16px
+ cursor pointer
+ padding 0
+ margin 0
+ height 40px
+ font-size 1em
+ outline none
+ border-radius 4px
- .ok
- .cancel
- .skip
- display block
- position absolute
- bottom 16px
- cursor pointer
- padding 0
- margin 0
- height 40px
- font-size 1em
- outline none
- border-radius 4px
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- &:focus
- &:after
- content ""
- pointer-events none
- position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ &:disabled
+ opacity 0.7
+ cursor default
- &:disabled
- opacity 0.7
- cursor default
+ .ok
+ .cancel
+ width 120px
- .ok
- .cancel
- width 120px
+ .ok
+ right 16px
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
- .ok
- right 16px
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- border solid 1px lighten($theme-color, 15%)
+ &:not(:disabled)
+ font-weight bold
- &:not(:disabled)
- font-weight bold
+ &:hover:not(:disabled)
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- &:hover:not(:disabled)
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:active:not(:disabled)
+ background $theme-color
+ border-color $theme-color
- &:active:not(:disabled)
- background $theme-color
- border-color $theme-color
+ .cancel
+ .skip
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
- .cancel
- .skip
- color #888
- background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
- border solid 1px #e2e2e2
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
- &:hover
- background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
- border-color #dcdcdc
+ &:active
+ background #ececec
+ border-color #dcdcdc
- &:active
- background #ececec
- border-color #dcdcdc
+ .cancel
+ right 148px
- .cancel
- right 148px
+ .skip
+ left 16px
+ width 150px
- .skip
- left 16px
- width 150px
+ </style>
+ <script>
+ @mixin \cropper
-script.
- @mixin \cropper
+ @image = @opts.file
+ @title = @opts.title
+ @aspect-ratio = @opts.aspect-ratio
+ @cropper = null
- @image = @opts.file
- @title = @opts.title
- @aspect-ratio = @opts.aspect-ratio
- @cropper = null
+ @on \mount ~>
+ @img = @refs.window.refs.img
+ @cropper = new @Cropper @img, do
+ aspect-ratio: @aspect-ratio
+ highlight: no
+ view-mode: 1
- @on \mount ~>
- @img = @refs.window.refs.img
- @cropper = new @Cropper @img, do
- aspect-ratio: @aspect-ratio
- highlight: no
- view-mode: 1
+ @ok = ~>
+ @cropper.get-cropped-canvas!.to-blob (blob) ~>
+ @trigger \cropped blob
+ @refs.window.close!
- @ok = ~>
- @cropper.get-cropped-canvas!.to-blob (blob) ~>
- @trigger \cropped blob
+ @skip = ~>
+ @trigger \skiped
@refs.window.close!
- @skip = ~>
- @trigger \skiped
- @refs.window.close!
-
- @cancel = ~>
- @trigger \canceled
- @refs.window.close!
+ @cancel = ~>
+ @trigger \canceled
+ @refs.window.close!
+ </script>
+</mk-crop-window>
diff --git a/src/web/app/desktop/tags/debugger.tag b/src/web/app/desktop/tags/debugger.tag
index e2b522cb00..9f9ff2cc4b 100644
--- a/src/web/app/desktop/tags/debugger.tag
+++ b/src/web/app/desktop/tags/debugger.tag
@@ -1,87 +1,90 @@
-mk-debugger
- mk-window@window(is-modal={ false }, width={ '700px' }, height={ '550px' })
- <yield to="header">
- i.fa.fa-wrench
- | Debugger
- </yield>
- <yield to="content">
- section.progress-dialog
- h1 progress-dialog
- button.style-normal(onclick={ parent.progress-dialog }): i.fa.fa-play
- button.style-normal(onclick={ parent.progress-dialog-destroy }): i.fa.fa-stop
- label
- p TITLE:
- input@progress-title(value='Title')
- label
- p VAL:
- input@progress-value(type='number', oninput={ parent.progress-change }, value=0)
- label
- p MAX:
- input@progress-max(type='number', oninput={ parent.progress-change }, value=100)
- </yield>
+<mk-debugger>
+ <mk-window ref="window" is-modal="{ false }" width="{ '700px' }" height="{ '550px' }"><yield to="header"><i class="fa fa-wrench"></i>Debugger</yield>
+<yield to="content">
+ <section class="progress-dialog">
+ <h1>progress-dialog</h1>
+ <button class="style-normal" onclick="{ parent.progressDialog }"><i class="fa fa-play"></i></button>
+ <button class="style-normal" onclick="{ parent.progressDialogDestroy }"><i class="fa fa-stop"></i></button>
+ <label>
+ <p>TITLE:</p>
+ <input ref="progressTitle" value="Title"/>
+ </label>
+ <label>
+ <p>VAL:</p>
+ <input ref="progressValue" type="number" oninput="{ parent.progressChange }" value="0"/>
+ </label>
+ <label>
+ <p>MAX:</p>
+ <input ref="progressMax" type="number" oninput="{ parent.progressChange }" value="100"/>
+ </label>
+ </section></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
+ overflow auto
- [data-yield='content']
- overflow auto
+ > section
+ padding 32px
- > section
- padding 32px
+ // & + section
+ // margin-top 16px
- // & + section
- // margin-top 16px
+ > h1
+ display block
+ margin 0
+ padding 0 0 8px 0
+ font-size 1em
+ color #555
+ border-bottom solid 1px #eee
- > h1
- display block
- margin 0
- padding 0 0 8px 0
- font-size 1em
- color #555
- border-bottom solid 1px #eee
+ > label
+ display block
- > label
- display block
+ > p
+ display inline
+ margin 0
- > p
- display inline
- margin 0
+ > .progress-dialog
+ button
+ display inline-block
+ margin 8px
- > .progress-dialog
- button
- display inline-block
- margin 8px
+ </style>
+ <script>
+ @mixin \open-window
-script.
- @mixin \open-window
+ @on \mount ~>
+ @progress-title = @tags['mk-window'].progress-title
+ @progress-value = @tags['mk-window'].progress-value
+ @progress-max = @tags['mk-window'].progress-max
- @on \mount ~>
- @progress-title = @tags['mk-window'].progress-title
- @progress-value = @tags['mk-window'].progress-value
- @progress-max = @tags['mk-window'].progress-max
+ @refs.window.on \closed ~>
+ @unmount!
- @refs.window.on \closed ~>
- @unmount!
+ ################################
- ################################
+ @progress-controller = riot.observable!
- @progress-controller = riot.observable!
+ @progress-dialog = ~>
+ @open-window \mk-progress-dialog do
+ title: @progress-title.value
+ value: @progress-value.value
+ max: @progress-max.value
+ controller: @progress-controller
- @progress-dialog = ~>
- @open-window \mk-progress-dialog do
- title: @progress-title.value
- value: @progress-value.value
- max: @progress-max.value
- controller: @progress-controller
+ @progress-change = ~>
+ @progress-controller.trigger do
+ \update
+ @progress-value.value
+ @progress-max.value
- @progress-change = ~>
- @progress-controller.trigger do
- \update
- @progress-value.value
- @progress-max.value
-
- @progress-dialog-destroy = ~>
- @progress-controller.trigger \close
+ @progress-dialog-destroy = ~>
+ @progress-controller.trigger \close
+ </script>
+</mk-debugger>
diff --git a/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag b/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag
index f11a0c0857..09a746fb9b 100644
--- a/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag
+++ b/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag
@@ -1,56 +1,60 @@
-mk-detect-slow-internet-connection-notice
- i: i.fa.fa-exclamation
- div: p インターネット回線が遅いようです。
-
-style.
- display block
- pointer-events none
- position fixed
- z-index 16384
- top 64px
- right 16px
- margin 0
- padding 0
- width 298px
- font-size 0.9em
- background #fff
- box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
- opacity 0
+<mk-detect-slow-internet-connection-notice><i><i class="fa fa-exclamation"></i></i>
+ <div>
+ <p>インターネット回線が遅いようです。</p>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ pointer-events none
+ position fixed
+ z-index 16384
+ top 64px
+ right 16px
+ margin 0
+ padding 0
+ width 298px
+ font-size 0.9em
+ background #fff
+ box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
+ opacity 0
- > i
- display block
- width 48px
- line-height 48px
- margin-right 0.25em
- text-align center
- color $theme-color-foreground
- font-size 1.5em
- background $theme-color
+ > i
+ display block
+ width 48px
+ line-height 48px
+ margin-right 0.25em
+ text-align center
+ color $theme-color-foreground
+ font-size 1.5em
+ background $theme-color
- > div
- display block
- position absolute
- top 0
- left 48px
- margin 0
- width 250px
- height 48px
- color #666
+ > div
+ display block
+ position absolute
+ top 0
+ left 48px
+ margin 0
+ width 250px
+ height 48px
+ color #666
- > p
- display block
- margin 0
- padding 8px
+ > p
+ display block
+ margin 0
+ padding 8px
-script.
- @mixin \net
+ </style>
+ <script>
+ @mixin \net
- @net.on \detected-slow-network ~>
- Velocity @root, {
- opacity: 1
- } 200ms \linear
- set-timeout ~>
+ @net.on \detected-slow-network ~>
Velocity @root, {
- opacity: 0
+ opacity: 1
} 200ms \linear
- , 10000ms
+ set-timeout ~>
+ Velocity @root, {
+ opacity: 0
+ } 200ms \linear
+ , 10000ms
+ </script>
+</mk-detect-slow-internet-connection-notice>
diff --git a/src/web/app/desktop/tags/dialog.tag b/src/web/app/desktop/tags/dialog.tag
index 88a461db84..d0aab4995c 100644
--- a/src/web/app/desktop/tags/dialog.tag
+++ b/src/web/app/desktop/tags/dialog.tag
@@ -1,141 +1,147 @@
-mk-dialog
- div.bg@bg(onclick={ bg-click })
- div.main@main
- header@header
- div.body@body
- div.buttons
- virtual(each={ opts.buttons })
- button(onclick={ _onclick }) { text }
+<mk-dialog>
+ <div class="bg" ref="bg" onclick="{ bgClick }"></div>
+ <div class="main" ref="main">
+ <header ref="header"></header>
+ <div class="body" ref="body"></div>
+ <div class="buttons">
+ <virtual each="{ opts.buttons }">
+ <button onclick="{ _onclick }">{ text }</button>
+ </virtual>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > .bg
+ display block
+ position fixed
+ z-index 8192
+ top 0
+ left 0
+ width 100%
+ height 100%
+ background rgba(0, 0, 0, 0.7)
+ opacity 0
+ pointer-events none
- > .bg
- display block
- position fixed
- z-index 8192
- top 0
- left 0
- width 100%
- height 100%
- background rgba(0, 0, 0, 0.7)
- opacity 0
- pointer-events none
+ > .main
+ display block
+ position fixed
+ z-index 8192
+ top 20%
+ left 0
+ right 0
+ margin 0 auto 0 auto
+ padding 32px 42px
+ width 480px
+ background #fff
- > .main
- display block
- position fixed
- z-index 8192
- top 20%
- left 0
- right 0
- margin 0 auto 0 auto
- padding 32px 42px
- width 480px
- background #fff
-
- > header
- margin 1em 0
- color $theme-color
- // color #43A4EC
- font-weight bold
+ > header
+ margin 1em 0
+ color $theme-color
+ // color #43A4EC
+ font-weight bold
- > i
- margin-right 0.5em
+ > i
+ margin-right 0.5em
- > .body
- margin 1em 0
- color #888
+ > .body
+ margin 1em 0
+ color #888
- > .buttons
- > button
- display inline-block
- float right
- margin 0
- padding 10px 10px
- font-size 1.1em
- font-weight normal
- text-decoration none
- color #888
- background transparent
- outline none
- border none
- border-radius 0
- cursor pointer
- transition color 0.1s ease
+ > .buttons
+ > button
+ display inline-block
+ float right
+ margin 0
+ padding 10px 10px
+ font-size 1.1em
+ font-weight normal
+ text-decoration none
+ color #888
+ background transparent
+ outline none
+ border none
+ border-radius 0
+ cursor pointer
+ transition color 0.1s ease
- i
- margin 0 0.375em
+ i
+ margin 0 0.375em
- &:hover
- color $theme-color
+ &:hover
+ color $theme-color
- &:active
- color darken($theme-color, 10%)
- transition color 0s ease
+ &:active
+ color darken($theme-color, 10%)
+ transition color 0s ease
-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!
+ </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!
- @on \mount ~>
- @refs.header.innerHTML = @opts.title
- @refs.body.innerHTML = @opts.text
+ @on \mount ~>
+ @refs.header.innerHTML = @opts.title
+ @refs.body.innerHTML = @opts.text
- @refs.bg.style.pointer-events = \auto
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
- opacity: 1
- } {
- queue: false
- duration: 100ms
- easing: \linear
- }
+ @refs.bg.style.pointer-events = \auto
+ Velocity @refs.bg, \finish true
+ Velocity @refs.bg, {
+ opacity: 1
+ } {
+ queue: false
+ duration: 100ms
+ easing: \linear
+ }
- Velocity @refs.main, {
- opacity: 0
- scale: 1.2
- } {
- duration: 0
- }
- Velocity @refs.main, {
- opacity: 1
- scale: 1
- } {
- duration: 300ms
- easing: [ 0, 0.5, 0.5, 1 ]
- }
+ Velocity @refs.main, {
+ opacity: 0
+ scale: 1.2
+ } {
+ duration: 0
+ }
+ Velocity @refs.main, {
+ opacity: 1
+ scale: 1
+ } {
+ duration: 300ms
+ easing: [ 0, 0.5, 0.5, 1 ]
+ }
- @close = ~>
- @refs.bg.style.pointer-events = \none
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
- opacity: 0
- } {
- queue: false
- duration: 300ms
- easing: \linear
- }
+ @close = ~>
+ @refs.bg.style.pointer-events = \none
+ Velocity @refs.bg, \finish true
+ Velocity @refs.bg, {
+ opacity: 0
+ } {
+ queue: false
+ duration: 300ms
+ easing: \linear
+ }
- @refs.main.style.pointer-events = \none
- Velocity @refs.main, \finish true
- Velocity @refs.main, {
- opacity: 0
- scale: 0.8
- } {
- queue: false
- duration: 300ms
- easing: [ 0.5, -0.5, 1, 0.5 ]
- complete: ~>
- @unmount!
- }
+ @refs.main.style.pointer-events = \none
+ Velocity @refs.main, \finish true
+ Velocity @refs.main, {
+ opacity: 0
+ scale: 0.8
+ } {
+ queue: false
+ duration: 300ms
+ easing: [ 0.5, -0.5, 1, 0.5 ]
+ complete: ~>
+ @unmount!
+ }
- @bg-click = ~>
- if @can-through
- if @opts.on-through?
- @opts.on-through!
- @close!
+ @bg-click = ~>
+ if @can-through
+ if @opts.on-through?
+ @opts.on-through!
+ @close!
+ </script>
+</mk-dialog>
diff --git a/src/web/app/desktop/tags/donation.tag b/src/web/app/desktop/tags/donation.tag
index 9f8a1a6729..49ea8332d3 100644
--- a/src/web/app/desktop/tags/donation.tag
+++ b/src/web/app/desktop/tags/donation.tag
@@ -1,63 +1,68 @@
-mk-donation
- button.close(onclick={ close }) 閉じる x
- div.message
- p 利用者の皆さま、
- p
- | 今日は、日本の皆さまにお知らせがあります。
- | Misskeyの援助をお願いいたします。
- | 私は独立性を守るため、一切の広告を掲載いたしません。
- | 平均で約¥1,500の寄付をいただき、運営しております。
- | 援助をしてくださる利用者はほんの少数です。
- | お願いいたします。
- | 今日、利用者の皆さまが¥300ご援助くだされば、募金活動を一時間で終了することができます。
- | コーヒー1杯ほどの金額です。
- | Misskeyを活用しておられるのでしたら、広告を掲載せずにもう1年活動できるよう、どうか1分だけお時間をください。
- | 私は小さな非営利個人ですが、サーバー、プログラム、人件費など、世界でトップクラスのウェブサイト同等のコストがかかります。
- | 利用者は何億人といますが、他の大きなサイトに比べてほんの少額の費用で運営しているのです。
- | 人間の可能性、自由、そして機会。知識こそ、これらの基盤を成すものです。
- | 私は、誰もが無料かつ制限なく知識に触れられるべきだと信じています。
- | 募金活動を終了し、Misskeyの改善に戻れるようご援助ください。
- | よろしくお願いいたします。
-
-style.
- display block
- color #fff
- background #03072C
+<mk-donation>
+ <button class="close" onclick="{ close }">閉じる x</button>
+ <div class="message">
+ <p>利用者の皆さま、</p>
+ <p>
+ 今日は、日本の皆さまにお知らせがあります。
+ Misskeyの援助をお願いいたします。
+ 私は独立性を守るため、一切の広告を掲載いたしません。
+ 平均で約¥1,500の寄付をいただき、運営しております。
+ 援助をしてくださる利用者はほんの少数です。
+ お願いいたします。
+ 今日、利用者の皆さまが¥300ご援助くだされば、募金活動を一時間で終了することができます。
+ コーヒー1杯ほどの金額です。
+ Misskeyを活用しておられるのでしたら、広告を掲載せずにもう1年活動できるよう、どうか1分だけお時間をください。
+ 私は小さな非営利個人ですが、サーバー、プログラム、人件費など、世界でトップクラスのウェブサイト同等のコストがかかります。
+ 利用者は何億人といますが、他の大きなサイトに比べてほんの少額の費用で運営しているのです。
+ 人間の可能性、自由、そして機会。知識こそ、これらの基盤を成すものです。
+ 私は、誰もが無料かつ制限なく知識に触れられるべきだと信じています。
+ 募金活動を終了し、Misskeyの改善に戻れるようご援助ください。
+ よろしくお願いいたします。
+ </p>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ color #fff
+ background #03072C
- > .close
- position absolute
- top 16px
- right 16px
- z-index 1
+ > .close
+ position absolute
+ top 16px
+ right 16px
+ z-index 1
- > .message
- padding 32px
- font-size 1.4em
- font-family serif
+ > .message
+ padding 32px
+ font-size 1.4em
+ font-family serif
- > p
- display block
- margin 0 auto
- max-width 1200px
+ > p
+ display block
+ margin 0 auto
+ max-width 1200px
- > p:first-child
- margin-bottom 16px
+ > p:first-child
+ margin-bottom 16px
-script.
- @mixin \api
- @mixin \i
+ </style>
+ <script>
+ @mixin \api
+ @mixin \i
- @close = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ @close = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
- @I.data.no_donation = true
- @api \i/appdata/set do
- data: JSON.stringify do
- no_donation: @I.data.no_donation
- .then ~>
- @update-i!
+ @I.data.no_donation = true
+ @api \i/appdata/set do
+ data: JSON.stringify do
+ no_donation: @I.data.no_donation
+ .then ~>
+ @update-i!
- @unmount!
+ @unmount!
- @parent.parent.set-root-layout!
+ @parent.parent.set-root-layout!
+ </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 c8b51009ea..d3a85e9157 100644
--- a/src/web/app/desktop/tags/drive/base-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/base-contextmenu.tag
@@ -1,28 +1,31 @@
-mk-drive-browser-base-contextmenu
- mk-contextmenu@ctx
- ul
- li(onclick={ parent.create-folder }): p
- i.fa.fa-folder-o
- | フォルダーを作成
- li(onclick={ parent.upload }): p
- i.fa.fa-upload
- | ファイルをアップロード
+<mk-drive-browser-base-contextmenu>
+ <mk-contextmenu ref="ctx">
+ <ul>
+ <li onclick="{ parent.createFolder }">
+ <p><i class="fa fa-folder-o"></i>フォルダーを作成</p>
+ </li>
+ <li onclick="{ parent.upload }">
+ <p><i class="fa fa-upload"></i>ファイルをアップロード</p>
+ </li>
+ </ul>
+ </mk-contextmenu>
+ <script>
+ @browser = @opts.browser
-script.
- @browser = @opts.browser
+ @on \mount ~>
+ @refs.ctx.on \closed ~>
+ @trigger \closed
+ @unmount!
- @on \mount ~>
- @refs.ctx.on \closed ~>
- @trigger \closed
- @unmount!
+ @open = (pos) ~>
+ @refs.ctx.open pos
- @open = (pos) ~>
- @refs.ctx.open pos
+ @create-folder = ~>
+ @browser.create-folder!
+ @refs.ctx.close!
- @create-folder = ~>
- @browser.create-folder!
- @refs.ctx.close!
-
- @upload = ~>
- @browser.select-local-file!
- @refs.ctx.close!
+ @upload = ~>
+ @browser.select-local-file!
+ @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 b3a5fc9a47..c7447a3c21 100644
--- a/src/web/app/desktop/tags/drive/browser-window.tag
+++ b/src/web/app/desktop/tags/drive/browser-window.tag
@@ -1,29 +1,28 @@
-mk-drive-browser-window
- mk-window@window(is-modal={ false }, width={ '800px' }, height={ '500px' })
- <yield to="header">
- i.fa.fa-cloud
- | ドライブ
- </yield>
- <yield to="content">
- mk-drive-browser(multiple={ true }, folder={ parent.folder })
- </yield>
+<mk-drive-browser-window>
+ <mk-window ref="window" is-modal="{ false }" width="{ '800px' }" height="{ '500px' }"><yield to="header"><i class="fa fa-cloud"></i>ドライブ</yield>
+<yield to="content">
+ <mk-drive-browser multiple="{ true }" folder="{ parent.folder }"></mk-drive-browser></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
+ > mk-drive-browser
+ height 100%
- [data-yield='content']
- > mk-drive-browser
- height 100%
+ </style>
+ <script>
+ @folder = if @opts.folder? then @opts.folder else null
-script.
- @folder = if @opts.folder? then @opts.folder else null
+ @on \mount ~>
+ @refs.window.on \closed ~>
+ @unmount!
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
-
- @close = ~>
- @refs.window.close!
+ @close = ~>
+ @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 62e6425fe5..2bcb15f873 100644
--- a/src/web/app/desktop/tags/drive/browser.tag
+++ b/src/web/app/desktop/tags/drive/browser.tag
@@ -1,634 +1,637 @@
-mk-drive-browser
- nav
- div.path(oncontextmenu={ path-oncontextmenu })
- mk-drive-browser-nav-folder(class={ current: folder == null }, folder={ null })
- virtual(each={ folder in hierarchy-folders })
- span.separator: i.fa.fa-angle-right
- mk-drive-browser-nav-folder(folder={ folder })
- span.separator(if={ folder != null }): i.fa.fa-angle-right
- span.folder.current(if={ folder != null })
- | { folder.name }
- input.search(type='search', placeholder!='&#xf002; 検索')
- div.main@main(class={ uploading: uploads.length > 0, loading: loading }, onmousedown={ onmousedown }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop }, oncontextmenu={ oncontextmenu })
- div.selection@selection
- div.contents@contents
- div.folders@folders-container(if={ folders.length > 0 })
- virtual(each={ folder in folders })
- mk-drive-browser-folder.folder(folder={ folder })
- button(if={ more-folders })
- | もっと読み込む
- div.files@files-container(if={ files.length > 0 })
- virtual(each={ file in files })
- mk-drive-browser-file.file(file={ file })
- button(if={ more-files })
- | もっと読み込む
- div.empty(if={ files.length == 0 && folders.length == 0 && !loading })
- p(if={ draghover })
- | ドロップですか?いいですよ、ボクはカワイイですからね
- p(if={ !draghover && folder == null })
- strong ドライブには何もありません。
- br
- | 右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。
- p(if={ !draghover && folder != null })
- | このフォルダーは空です
- div.loading(if={ loading }).
+<mk-drive-browser>
+ <nav>
+ <div class="path" oncontextmenu="{ pathOncontextmenu }">
+ <mk-drive-browser-nav-folder class="{ current: folder == null }" folder="{ null }"></mk-drive-browser-nav-folder>
+ <virtual each="{ folder in hierarchyFolders }"><span class="separator"><i class="fa fa-angle-right"></i></span>
+ <mk-drive-browser-nav-folder folder="{ folder }"></mk-drive-browser-nav-folder>
+ </virtual><span class="separator" if="{ folder != null }"><i class="fa fa-angle-right"></i></span><span class="folder current" if="{ folder != null }">{ folder.name }</span>
+ </div>
+ <input class="search" type="search" placeholder="&#xf002; 検索"/>
+ </nav>
+ <div class="main { uploading: uploads.length &gt; 0, loading: loading }" 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 &gt; 0 }">
+ <virtual each="{ folder in folders }">
+ <mk-drive-browser-folder class="folder" folder="{ folder }"></mk-drive-browser-folder>
+ </virtual>
+ <button if="{ moreFolders }">もっと読み込む</button>
+ </div>
+ <div class="files" ref="filesContainer" if="{ files.length &gt; 0 }">
+ <virtual each="{ file in files }">
+ <mk-drive-browser-file class="file" file="{ file }"></mk-drive-browser-file>
+ </virtual>
+ <button if="{ moreFiles }">もっと読み込む</button>
+ </div>
+ <div class="empty" if="{ files.length == 0 &amp;&amp; folders.length == 0 &amp;&amp; !loading }">
+ <p if="{ draghover }">ドロップですか?いいですよ、ボクはカワイイですからね</p>
+ <p if="{ !draghover &amp;&amp; folder == null }"><strong>ドライブには何もありません。</strong><br/>右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。</p>
+ <p if="{ !draghover &amp;&amp; folder != null }">このフォルダーは空です</p>
+ </div>
+ </div>
+ <div class="loading" if="{ loading }">
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
</div>
- div.dropzone(if={ draghover })
- mk-uploader@uploader
- input@file-input(type='file', accept='*/*', multiple, tabindex='-1', onchange={ change-file-input })
+ </div>
+ </div>
+ <div class="dropzone" if="{ draghover }"></div>
+ <mk-uploader ref="uploader"></mk-uploader>
+ <input ref="fileInput" type="file" accept="*/*" multiple="multiple" tabindex="-1" onchange="{ changeFileInput }"/>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > nav
+ display block
+ z-index 2
+ width 100%
+ overflow auto
+ font-size 0.9em
+ color #555
+ background #fff
+ //border-bottom 1px solid #dfdfdf
+ box-shadow 0 1px 0 rgba(0, 0, 0, 0.05)
- > nav
- display block
- z-index 2
- width 100%
- overflow auto
- font-size 0.9em
- color #555
- background #fff
- //border-bottom 1px solid #dfdfdf
- box-shadow 0 1px 0 rgba(0, 0, 0, 0.05)
+ &, *
+ user-select none
- &, *
- user-select none
+ > .path
+ display inline-block
+ vertical-align bottom
+ margin 0
+ padding 0 8px
+ width calc(100% - 200px)
+ line-height 38px
+ white-space nowrap
- > .path
- display inline-block
- vertical-align bottom
- margin 0
- padding 0 8px
- width calc(100% - 200px)
- line-height 38px
- white-space nowrap
+ > *
+ display inline-block
+ margin 0
+ padding 0 8px
+ line-height 38px
+ cursor pointer
- > *
- display inline-block
- margin 0
- padding 0 8px
- line-height 38px
- cursor pointer
+ i
+ margin-right 4px
- i
- margin-right 4px
+ *
+ pointer-events none
- *
- pointer-events none
+ &:hover
+ text-decoration underline
+
+ &.current
+ font-weight bold
+ cursor default
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration none
- &.current
- font-weight bold
- cursor default
+ &.separator
+ margin 0
+ padding 0
+ opacity 0.5
+ cursor default
- &:hover
- text-decoration none
+ > i
+ margin 0
- &.separator
+ > .search
+ display inline-block
+ vertical-align bottom
+ user-select text
+ cursor auto
margin 0
- padding 0
- opacity 0.5
- cursor default
+ padding 0 18px
+ width 200px
+ font-size 1em
+ line-height 38px
+ background transparent
+ outline none
+ //border solid 1px #ddd
+ border none
+ border-radius 0
+ box-shadow none
+ transition color 0.5s ease, border 0.5s ease
+ font-family FontAwesome, sans-serif
- > i
- margin 0
+ &[data-active='true']
+ background #fff
- > .search
- display inline-block
- vertical-align bottom
- user-select text
- cursor auto
- margin 0
- padding 0 18px
- width 200px
- font-size 1em
- line-height 38px
- background transparent
- outline none
- //border solid 1px #ddd
- border none
- border-radius 0
- box-shadow none
- transition color 0.5s ease, border 0.5s ease
- font-family FontAwesome, sans-serif
+ &::-webkit-input-placeholder,
+ &:-ms-input-placeholder,
+ &:-moz-placeholder
+ color $ui-controll-foreground-color
- &[data-active='true']
- background #fff
+ > .main
+ padding 8px
+ height calc(100% - 38px)
+ overflow auto
- &::-webkit-input-placeholder,
- &:-ms-input-placeholder,
- &:-moz-placeholder
- color $ui-controll-foreground-color
+ &, *
+ user-select none
- > .main
- padding 8px
- height calc(100% - 38px)
- overflow auto
+ &.loading
+ cursor wait !important
- &, *
- user-select none
+ *
+ pointer-events none
- &.loading
- cursor wait !important
+ > .contents
+ opacity 0.5
- *
- pointer-events none
+ &.uploading
+ height calc(100% - 38px - 100px)
- > .contents
- opacity 0.5
+ > .selection
+ display none
+ position absolute
+ z-index 128
+ top 0
+ left 0
+ border solid 1px $theme-color
+ background rgba($theme-color, 0.5)
+ pointer-events none
- &.uploading
- height calc(100% - 38px - 100px)
+ > .contents
- > .selection
- display none
- position absolute
- z-index 128
- top 0
- left 0
- border solid 1px $theme-color
- background rgba($theme-color, 0.5)
- pointer-events none
+ > .folders
+ &:after
+ content ""
+ display block
+ clear both
- > .contents
+ > .folder
+ float left
- > .folders
- &:after
- content ""
- display block
- clear both
+ > .files
+ &:after
+ content ""
+ display block
+ clear both
- > .folder
- float left
+ > .file
+ float left
- > .files
- &:after
- content ""
- display block
- clear both
+ > .empty
+ padding 16px
+ text-align center
+ color #999
+ pointer-events none
- > .file
- float left
+ > p
+ margin 0
- > .empty
- padding 16px
- text-align center
- color #999
- pointer-events none
+ > .loading
+ .spinner
+ margin 100px auto
+ width 40px
+ height 40px
+ text-align center
- > p
- margin 0
+ animation sk-rotate 2.0s infinite linear
+
+ .dot1, .dot2
+ width 60%
+ height 60%
+ display inline-block
+ position absolute
+ top 0
+ background-color rgba(0, 0, 0, 0.3)
+ border-radius 100%
- > .loading
- .spinner
- margin 100px auto
- width 40px
- height 40px
- text-align center
+ animation sk-bounce 2.0s infinite ease-in-out
- animation sk-rotate 2.0s infinite linear
+ .dot2
+ top auto
+ bottom 0
+ animation-delay -1.0s
- .dot1, .dot2
- width 60%
- height 60%
- display inline-block
+ @keyframes sk-rotate { 100% { transform: rotate(360deg); }}
+
+ @keyframes sk-bounce {
+ 0%, 100% {
+ transform: scale(0.0);
+ } 50% {
+ transform: scale(1.0);
+ }
+ }
+
+ > .dropzone
position absolute
- top 0
- background-color rgba(0, 0, 0, 0.3)
- border-radius 100%
+ left 0
+ top 38px
+ width 100%
+ height calc(100% - 38px)
+ border dashed 2px rgba($theme-color, 0.5)
+ pointer-events none
- animation sk-bounce 2.0s infinite ease-in-out
+ > mk-uploader
+ height 100px
+ padding 16px
+ background #fff
- .dot2
- top auto
- bottom 0
- animation-delay -1.0s
+ > input
+ display none
- @keyframes sk-rotate { 100% { transform: rotate(360deg); }}
+ </style>
+ <script>
+ @mixin \api
+ @mixin \dialog
+ @mixin \input-dialog
+ @mixin \stream
- @keyframes sk-bounce {
- 0%, 100% {
- transform: scale(0.0);
- } 50% {
- transform: scale(1.0);
- }
- }
+ @files = []
+ @folders = []
+ @hierarchy-folders = []
- > .dropzone
- position absolute
- left 0
- top 38px
- width 100%
- height calc(100% - 38px)
- border dashed 2px rgba($theme-color, 0.5)
- pointer-events none
+ @uploads = []
- > mk-uploader
- height 100px
- padding 16px
- background #fff
+ # 現在の階層(フォルダ)
+ # * null でルートを表す
+ @folder = null
- > input
- display none
+ @multiple = if @opts.multiple? then @opts.multiple else false
-script.
- @mixin \api
- @mixin \dialog
- @mixin \input-dialog
- @mixin \stream
+ # ドロップされようとしているか
+ @draghover = false
- @files = []
- @folders = []
- @hierarchy-folders = []
+ # 自信の所有するアイテムがドラッグをスタートさせたか
+ # (自分自身の階層にドロップできないようにするためのフラグ)
+ @is-drag-source = false
- @uploads = []
+ @on \mount ~>
+ @refs.uploader.on \uploaded (file) ~>
+ @add-file file, true
- # 現在の階層(フォルダ)
- # * null でルートを表す
- @folder = null
+ @refs.uploader.on \change-uploads (uploads) ~>
+ @uploads = uploads
+ @update!
- @multiple = if @opts.multiple? then @opts.multiple else false
+ @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
- # ドロップされようとしているか
- @draghover = false
+ # Riotのバグでnullを渡しても""になる
+ # https://github.com/riot/riot/issues/2080
+ #if @opts.folder?
+ if @opts.folder? and @opts.folder != ''
+ @move @opts.folder
+ else
+ @load!
- # 自信の所有するアイテムがドラッグをスタートさせたか
- # (自分自身の階層にドロップできないようにするためのフラグ)
- @is-drag-source = false
+ @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
- @on \mount ~>
- @refs.uploader.on \uploaded (file) ~>
+ @on-stream-drive-file-created = (file) ~>
@add-file file, true
- @refs.uploader.on \change-uploads (uploads) ~>
- @uploads = uploads
- @update!
+ @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
- @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
+ @on-stream-drive-folder-created = (folder) ~>
+ @add-folder 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
- # Riotのバグでnullを渡しても""になる
- # https://github.com/riot/riot/issues/2080
- #if @opts.folder?
- if @opts.folder? and @opts.folder != ''
- @move @opts.folder
- else
- @load!
+ @onmousedown = (e) ~>
+ if (contains @refs.folders-container, e.target) or (contains @refs.files-container, e.target)
+ return true
- @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
+ rect = @refs.main.get-bounding-client-rect!
- @on-stream-drive-file-created = (file) ~>
- @add-file file, 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
- @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
+ move = (e) ~>
+ @refs.selection.style.display = \block
- @on-stream-drive-folder-created = (folder) ~>
- @add-folder folder, true
+ 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
- @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
+ 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
- @onmousedown = (e) ~>
- if (contains @refs.folders-container, e.target) or (contains @refs.files-container, e.target)
- return true
+ 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
- rect = @refs.main.get-bounding-client-rect!
+ up = (e) ~>
+ document.document-element.remove-event-listener \mousemove move
+ document.document-element.remove-event-listener \mouseup up
- 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
+ @refs.selection.style.display = \none
- move = (e) ~>
- @refs.selection.style.display = \block
+ document.document-element.add-event-listener \mousemove move
+ document.document-element.add-event-listener \mouseup up
- 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
+ @path-oncontextmenu = (e) ~>
+ e.prevent-default!
+ e.stop-immediate-propagation!
+ return false
- 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
+ @ondragover = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
- if h > 0
- @refs.selection.style.height = h + \px
- @refs.selection.style.top = top + \px
+ # ドラッグ元が自分自身の所有するアイテムかどうか
+ 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
- @refs.selection.style.height = -h + \px
- @refs.selection.style.top = cursor-y + \px
-
- up = (e) ~>
- document.document-element.remove-event-listener \mousemove move
- document.document-element.remove-event-listener \mouseup up
+ # 自分自身にはドロップさせない
+ e.data-transfer.drop-effect = \none
+ return false
- @refs.selection.style.display = \none
+ @ondragenter = (e) ~>
+ e.prevent-default!
+ if !@is-drag-source
+ @draghover = true
- document.document-element.add-event-listener \mousemove move
- document.document-element.add-event-listener \mouseup up
+ @ondragleave = (e) ~>
+ @draghover = false
- @path-oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
- return false
+ @ondrop = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
- @ondragover = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ @draghover = 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
+ # ドロップされてきたものがファイルだったら
+ if e.data-transfer.files.length > 0
+ Array.prototype.for-each.call e.data-transfer.files, (file) ~>
+ @upload file, @folder
+ return false
- @ondragenter = (e) ~>
- e.prevent-default!
- if !@is-drag-source
- @draghover = true
+ # データ取得
+ data = e.data-transfer.get-data 'text'
+ if !data?
+ return false
- @ondragleave = (e) ~>
- @draghover = false
+ # パース
+ obj = JSON.parse data
- @ondrop = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ # (ドライブの)ファイルだったら
+ 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
- @draghover = false
+ # (ドライブの)フォルダーだったら
+ 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
+ ]
- # ドロップされてきたものがファイルだったら
- if e.data-transfer.files.length > 0
- Array.prototype.for-each.call e.data-transfer.files, (file) ~>
- @upload file, @folder
return false
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
+ @oncontextmenu = (e) ~>
+ e.prevent-default!
+ e.stop-immediate-propagation!
+
+ 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
- # パース
- obj = JSON.parse data
+ @select-local-file = ~>
+ @refs.file-input.click!
- # (ドライブの)ファイルだったら
- 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
+ @create-folder = ~>
+ name <~ @input-dialog do
+ 'フォルダー作成'
+ 'フォルダー名'
+ null
- # (ドライブの)フォルダーだったら
- 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
+ @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) ~>
- if err == 'detected-circular-definition'
- @dialog do
- '<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
- '移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
- [
- text: \OK
- ]
+ console.error err
- return false
+ @change-file-input = ~>
+ files = @refs.file-input.files
+ for i from 0 to files.length - 1
+ file = files.item i
+ @upload file, @folder
- @oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
+ @upload = (file, folder) ~>
+ if folder? and typeof folder == \object
+ folder = folder.id
+ @refs.uploader.upload file, folder
- 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
+ @get-selection = ~>
+ @files.filter (file) -> file._selected
- return false
+ @new-window = (folder-id) ~>
+ browser = document.body.append-child document.create-element \mk-drive-browser-window
+ riot.mount browser, do
+ folder: folder-id
- @select-local-file = ~>
- @refs.file-input.click!
+ @move = (target-folder) ~>
+ if target-folder? and typeof target-folder == \object
+ target-folder = target-folder.id
- @create-folder = ~>
- name <~ @input-dialog do
- 'フォルダー作成'
- 'フォルダー名'
- null
+ if target-folder == null
+ @go-root!
+ return
- @api \drive/folders/create do
- name: name
- folder_id: if @folder? then @folder.id else undefined
- .then (folder) ~>
- @add-folder folder, true
+ @loading = true
@update!
- .catch (err) ~>
- console.error err
-
- @change-file-input = ~>
- files = @refs.file-input.files
- for i from 0 to files.length - 1
- file = files.item i
- @upload file, @folder
-
- @upload = (file, folder) ~>
- if folder? and typeof folder == \object
- folder = folder.id
- @refs.uploader.upload file, folder
- @get-selection = ~>
- @files.filter (file) -> file._selected
+ @api \drive/folders/show do
+ folder_id: target-folder
+ .then (folder) ~>
+ @folder = folder
+ @hierarchy-folders = []
- @new-window = (folder-id) ~>
- browser = document.body.append-child document.create-element \mk-drive-browser-window
- riot.mount browser, do
- folder: folder-id
+ x = (f) ~>
+ @hierarchy-folders.unshift f
+ if f.parent?
+ x f.parent
- @move = (target-folder) ~>
- if target-folder? and typeof target-folder == \object
- target-folder = target-folder.id
+ if folder.parent?
+ x folder.parent
- if target-folder == null
- @go-root!
- return
-
- @loading = true
- @update!
-
- @api \drive/folders/show do
- folder_id: target-folder
- .then (folder) ~>
- @folder = folder
- @hierarchy-folders = []
-
- x = (f) ~>
- @hierarchy-folders.unshift f
- if f.parent?
- x f.parent
+ @update!
+ @load!
+ .catch (err, text-status) ->
+ console.error err
- if folder.parent?
- x folder.parent
+ @add-folder = (folder, unshift = false) ~>
+ current = if @folder? then @folder.id else null
+ if current != folder.parent_id
+ return
- @update!
- @load!
- .catch (err, text-status) ->
- console.error err
+ if (@folders.some (f) ~> f.id == folder.id)
+ exist = (@folders.map (f) -> f.id).index-of folder.id
+ @folders[exist] = folder
+ @update!
+ return
- @add-folder = (folder, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- return
+ if unshift
+ @folders.unshift folder
+ else
+ @folders.push folder
- 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
- @folders.unshift folder
- else
- @folders.push folder
+ @add-file = (file, unshift = false) ~>
+ current = if @folder? then @folder.id else null
+ if current != file.folder_id
+ return
- @update!
+ if (@files.some (f) ~> f.id == file.id)
+ exist = (@files.map (f) -> f.id).index-of file.id
+ @files[exist] = file
+ @update!
+ return
- @add-file = (file, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- return
+ if unshift
+ @files.unshift file
+ else
+ @files.push file
- 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
- @files.unshift file
- else
- @files.push file
-
- @update!
+ @remove-folder = (folder) ~>
+ if typeof folder == \object
+ folder = folder.id
+ @folders = @folders.filter (f) -> f.id != folder
+ @update!
- @remove-folder = (folder) ~>
- if typeof folder == \object
- folder = folder.id
- @folders = @folders.filter (f) -> f.id != folder
- @update!
+ @remove-file = (file) ~>
+ if typeof file == \object
+ file = file.id
+ @files = @files.filter (f) -> f.id != file
+ @update!
- @remove-file = (file) ~>
- if typeof file == \object
- file = file.id
- @files = @files.filter (f) -> f.id != file
- @update!
+ @go-root = ~>
+ if @folder != null
+ @folder = null
+ @hierarchy-folders = []
+ @update!
+ @load!
- @go-root = ~>
- if @folder != null
- @folder = null
- @hierarchy-folders = []
+ @load = ~>
+ @folders = []
+ @files = []
+ @more-folders = false
+ @more-files = false
+ @loading = true
@update!
- @load!
-
- @load = ~>
- @folders = []
- @files = []
- @more-folders = false
- @more-files = false
- @loading = true
- @update!
- load-folders = null
- load-files = null
+ load-folders = null
+ load-files = null
- folders-max = 30
- files-max = 30
+ folders-max = 30
+ files-max = 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
+ # フォルダ一覧取得
+ @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
- # ファイル一覧取得
- @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
+ # ファイル一覧取得
+ @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
- 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
+ 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
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
+ 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 7d7dca6c92..96779601db 100644
--- a/src/web/app/desktop/tags/drive/file-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/file-contextmenu.tag
@@ -1,97 +1,103 @@
-mk-drive-browser-file-contextmenu
- mk-contextmenu@ctx: ul
- li(onclick={ parent.rename }): p
- i.fa.fa-i-cursor
- | 名前を変更
- li(onclick={ parent.copy-url }): p
- i.fa.fa-link
- | URLをコピー
- li: a(href={ parent.file.url + '?download' }, download={ parent.file.name }, onclick={ parent.download })
- i.fa.fa-download
- | ダウンロード
- li.separator
- li(onclick={ parent.delete }): p
- i.fa.fa-trash-o
- | 削除
- li.separator
- li.has-child
- p
- | その他...
- i.fa.fa-caret-right
- ul
- li(onclick={ parent.set-avatar }): p
- | アバターに設定
- li(onclick={ parent.set-banner }): p
- | バナーに設定
- li(onclick={ parent.set-wallpaper }): p
- | 壁紙に設定
- li.has-child
- p
- | アプリで開く...
- i.fa.fa-caret-right
- ul
- li(onclick={ parent.add-app }): p
- | アプリを追加...
+<mk-drive-browser-file-contextmenu>
+ <mk-contextmenu ref="ctx">
+ <ul>
+ <li onclick="{ parent.rename }">
+ <p><i class="fa fa-i-cursor"></i>名前を変更</p>
+ </li>
+ <li onclick="{ parent.copyUrl }">
+ <p><i class="fa fa-link"></i>URLをコピー</p>
+ </li>
+ <li><a href="{ parent.file.url + '?download' }" download="{ parent.file.name }" onclick="{ parent.download }"><i class="fa fa-download"></i>ダウンロード</a></li>
+ <li class="separator"></li>
+ <li onclick="{ parent.delete }">
+ <p><i class="fa fa-trash-o"></i>削除</p>
+ </li>
+ <li class="separator"></li>
+ <li class="has-child">
+ <p>その他...<i class="fa fa-caret-right"></i></p>
+ <ul>
+ <li onclick="{ parent.setAvatar }">
+ <p>アバターに設定</p>
+ </li>
+ <li onclick="{ parent.setBanner }">
+ <p>バナーに設定</p>
+ </li>
+ <li onclick="{ parent.setWallpaper }">
+ <p>壁紙に設定</p>
+ </li>
+ </ul>
+ </li>
+ <li class="has-child">
+ <p>アプリで開く...<i class="fa fa-caret-right"></i></p>
+ <ul>
+ <li onclick="{ parent.addApp }">
+ <p>アプリを追加...</p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </mk-contextmenu>
+ <script>
+ @mixin \api
+ @mixin \i
+ @mixin \update-avatar
+ @mixin \update-banner
+ @mixin \update-wallpaper
+ @mixin \input-dialog
+ @mixin \NotImplementedException
-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
- @browser = @opts.browser
- @file = @opts.file
+ @on \mount ~>
+ @refs.ctx.on \closed ~>
+ @trigger \closed
+ @unmount!
- @on \mount ~>
- @refs.ctx.on \closed ~>
- @trigger \closed
- @unmount!
+ @open = (pos) ~>
+ @refs.ctx.open pos
- @open = (pos) ~>
- @refs.ctx.open pos
+ @rename = ~>
+ @refs.ctx.close!
- @rename = ~>
- @refs.ctx.close!
+ name <~ @input-dialog do
+ 'ファイル名の変更'
+ '新しいファイル名を入力してください'
+ @file.name
- name <~ @input-dialog do
- 'ファイル名の変更'
- '新しいファイル名を入力してください'
- @file.name
+ @api \drive/files/update do
+ file_id: @file.id
+ name: name
+ .then ~>
+ # something
+ .catch (err) ~>
+ console.error err
- @api \drive/files/update do
- file_id: @file.id
- name: name
- .then ~>
- # something
- .catch (err) ~>
- console.error err
+ @copy-url = ~>
+ @NotImplementedException!
- @copy-url = ~>
- @NotImplementedException!
+ @download = ~>
+ @refs.ctx.close!
- @download = ~>
- @refs.ctx.close!
+ @set-avatar = ~>
+ @refs.ctx.close!
+ @update-avatar @I, (i) ~>
+ @update-i i
+ , @file
- @set-avatar = ~>
- @refs.ctx.close!
- @update-avatar @I, (i) ~>
- @update-i i
- , @file
+ @set-banner = ~>
+ @refs.ctx.close!
+ @update-banner @I, (i) ~>
+ @update-i i
+ , @file
- @set-banner = ~>
- @refs.ctx.close!
- @update-banner @I, (i) ~>
- @update-i i
- , @file
+ @set-wallpaper = ~>
+ @refs.ctx.close!
+ @update-wallpaper @I, (i) ~>
+ @update-i i
+ , @file
- @set-wallpaper = ~>
- @refs.ctx.close!
- @update-wallpaper @I, (i) ~>
- @update-i i
- , @file
-
- @add-app = ~>
- @NotImplementedException!
+ @add-app = ~>
+ @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 1702bb6501..8daa54983d 100644
--- a/src/web/app/desktop/tags/drive/file.tag
+++ b/src/web/app/desktop/tags/drive/file.tag
@@ -1,207 +1,208 @@
-mk-drive-browser-file(data-is-selected={ (file._selected || false).toString() }, data-is-contextmenu-showing={ is-contextmenu-showing.toString() }, onclick={ onclick }, oncontextmenu={ oncontextmenu }, draggable='true', ondragstart={ ondragstart }, ondragend={ ondragend }, title={ title })
- div.label(if={ I.avatar_id == file.id })
- img(src='/_/resources/label.svg')
- p アバター
- div.label(if={ I.banner_id == file.id })
- img(src='/_/resources/label.svg')
- p バナー
- div.label(if={ I.data.wallpaper == file.id })
- img(src='/_/resources/label.svg')
- p 壁紙
- div.thumbnail: img(src={ file.url + '?thumbnail&size=128' }, alt='')
- p.name
- span { file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }
- span.ext(if={ file.name.lastIndexOf('.') != -1 }) { file.name.substr(file.name.lastIndexOf('.')) }
-
-style.
- display block
- margin 4px
- padding 8px 0 0 0
- width 144px
- height 180px
- border-radius 4px
+<mk-drive-browser-file data-is-selected="{ (file._selected || false).toString() }" data-is-contextmenu-showing="{ isContextmenuShowing.toString() }" onclick="{ onclick }" oncontextmenu="{ oncontextmenu }" draggable="true" ondragstart="{ ondragstart }" ondragend="{ ondragend }" title="{ title }">
+ <div class="label" if="{ I.avatar_id == file.id }"><img src="/_/resources/label.svg"/>
+ <p>アバター</p>
+ </div>
+ <div class="label" if="{ I.banner_id == file.id }"><img src="/_/resources/label.svg"/>
+ <p>バナー</p>
+ </div>
+ <div class="label" if="{ I.data.wallpaper == file.id }"><img src="/_/resources/label.svg"/>
+ <p>壁紙</p>
+ </div>
+ <div class="thumbnail"><img src="{ file.url + '?thumbnail&amp;size=128' }" alt=""/></div>
+ <p class="name"><span>{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }</span><span class="ext" if="{ file.name.lastIndexOf('.') != -1 }">{ file.name.substr(file.name.lastIndexOf('.')) }</span></p>
+ <style type="stylus">
+ :scope
+ display block
+ margin 4px
+ padding 8px 0 0 0
+ width 144px
+ height 180px
+ border-radius 4px
- &, *
- cursor pointer
+ &, *
+ cursor pointer
- &:hover
- background rgba(0, 0, 0, 0.05)
+ &:hover
+ background rgba(0, 0, 0, 0.05)
- > .label
- &:before
- &:after
- background #0b65a5
+ > .label
+ &:before
+ &:after
+ background #0b65a5
- &:active
- background rgba(0, 0, 0, 0.1)
+ &:active
+ background rgba(0, 0, 0, 0.1)
- > .label
- &:before
- &:after
- background #0b588c
+ > .label
+ &:before
+ &:after
+ background #0b588c
- &[data-is-selected='true']
- background $theme-color
+ &[data-is-selected='true']
+ background $theme-color
- &:hover
- background lighten($theme-color, 10%)
+ &:hover
+ background lighten($theme-color, 10%)
- &:active
- background darken($theme-color, 10%)
+ &:active
+ background darken($theme-color, 10%)
- > .label
- &:before
- &:after
- display none
+ > .label
+ &:before
+ &:after
+ display none
- > .name
- color $theme-color-foreground
+ > .name
+ color $theme-color-foreground
- &[data-is-contextmenu-showing='true']
- &:after
- content ""
- pointer-events none
- position absolute
- top -4px
- right -4px
- bottom -4px
- left -4px
- border 2px dashed rgba($theme-color, 0.3)
- border-radius 4px
+ &[data-is-contextmenu-showing='true']
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -4px
+ right -4px
+ bottom -4px
+ left -4px
+ border 2px dashed rgba($theme-color, 0.3)
+ border-radius 4px
- > .label
- position absolute
- top 0
- left 0
- pointer-events none
+ > .label
+ position absolute
+ top 0
+ left 0
+ pointer-events none
- &:before
- content ""
- display block
- position absolute
- z-index 1
- top 0
- left 57px
- width 28px
- height 8px
- background #0c7ac9
+ &:before
+ content ""
+ display block
+ position absolute
+ z-index 1
+ top 0
+ left 57px
+ width 28px
+ height 8px
+ background #0c7ac9
- &:after
- content ""
- display block
- position absolute
- z-index 1
- top 57px
- left 0
- width 8px
- height 28px
- background #0c7ac9
+ &:after
+ content ""
+ display block
+ position absolute
+ z-index 1
+ top 57px
+ left 0
+ width 8px
+ height 28px
+ background #0c7ac9
- > img
- position absolute
- z-index 2
- top 0
- left 0
+ > img
+ position absolute
+ z-index 2
+ top 0
+ left 0
- > p
- position absolute
- z-index 3
- top 19px
- left -28px
- width 120px
- margin 0
- text-align center
- line-height 28px
- color #fff
- transform rotate(-45deg)
+ > p
+ position absolute
+ z-index 3
+ top 19px
+ left -28px
+ width 120px
+ margin 0
+ text-align center
+ line-height 28px
+ color #fff
+ transform rotate(-45deg)
- > .thumbnail
- width 128px
- height 128px
- left 8px
+ > .thumbnail
+ width 128px
+ height 128px
+ left 8px
- > img
- display block
- position absolute
- top 0
- left 0
- right 0
- bottom 0
- margin auto
- max-width 128px
- max-height 128px
- pointer-events none
+ > img
+ display block
+ position absolute
+ top 0
+ left 0
+ right 0
+ bottom 0
+ margin auto
+ max-width 128px
+ max-height 128px
+ pointer-events none
- > .name
- display block
- margin 4px 0 0 0
- font-size 0.8em
- text-align center
- word-break break-all
- color #444
- overflow hidden
+ > .name
+ display block
+ margin 4px 0 0 0
+ font-size 0.8em
+ text-align center
+ word-break break-all
+ color #444
+ overflow hidden
- > .ext
- opacity 0.5
+ > .ext
+ opacity 0.5
-script.
- @mixin \i
- @mixin \bytes-to-size
+ </style>
+ <script>
+ @mixin \i
+ @mixin \bytes-to-size
- @file = @opts.file
- @browser = @parent
+ @file = @opts.file
+ @browser = @parent
- @title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
+ @title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
- @is-contextmenu-showing = false
+ @is-contextmenu-showing = 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
+ @onclick = ~>
+ if @browser.multiple
+ if @file._selected?
+ @file._selected = !@file._selected
+ else
+ @file._selected = true
+ @browser.trigger \change-selection @browser.get-selection!
else
- @browser.files.for-each (file) ~>
- file._selected = false
- @file._selected = true
- @browser.trigger \change-selection @file
+ if @file._selected
+ @browser.trigger \selected @file
+ else
+ @browser.files.for-each (file) ~>
+ file._selected = false
+ @file._selected = true
+ @browser.trigger \change-selection @file
- @oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
+ @oncontextmenu = (e) ~>
+ e.prevent-default!
+ e.stop-immediate-propagation!
- @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
+ @is-contextmenu-showing = true
@update!
- return false
+ 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
- @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
+ @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
- # 親ブラウザに対して、ドラッグが開始されたフラグを立てる
- # (=あなたの子供が、ドラッグを開始しましたよ)
- @browser.is-drag-source = true
+ # 親ブラウザに対して、ドラッグが開始されたフラグを立てる
+ # (=あなたの子供が、ドラッグを開始しましたよ)
+ @browser.is-drag-source = true
- @ondragend = (e) ~>
- @is-dragging = false
- @browser.is-drag-source = false
+ @ondragend = (e) ~>
+ @is-dragging = false
+ @browser.is-drag-source = 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 67fb1047b7..eb50e51c68 100644
--- a/src/web/app/desktop/tags/drive/folder-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
@@ -1,62 +1,66 @@
-mk-drive-browser-folder-contextmenu
- mk-contextmenu@ctx: ul
- li(onclick={ parent.move }): p
- i.fa.fa-arrow-right
- | このフォルダへ移動
- li(onclick={ parent.new-window }): p
- i.fa.fa-share-square-o
- | 新しいウィンドウで表示
- li.separator
- li(onclick={ parent.rename }): p
- i.fa.fa-i-cursor
- | 名前を変更
- li.separator
- li(onclick={ parent.delete }): p
- i.fa.fa-trash-o
- | 削除
+<mk-drive-browser-folder-contextmenu>
+ <mk-contextmenu ref="ctx">
+ <ul>
+ <li onclick="{ parent.move }">
+ <p><i class="fa fa-arrow-right"></i>このフォルダへ移動</p>
+ </li>
+ <li onclick="{ parent.newWindow }">
+ <p><i class="fa fa-share-square-o"></i>新しいウィンドウで表示</p>
+ </li>
+ <li class="separator"></li>
+ <li onclick="{ parent.rename }">
+ <p><i class="fa fa-i-cursor"></i>名前を変更</p>
+ </li>
+ <li class="separator"></li>
+ <li onclick="{ parent.delete }">
+ <p><i class="fa fa-trash-o"></i>削除</p>
+ </li>
+ </ul>
+ </mk-contextmenu>
+ <script>
+ @mixin \api
+ @mixin \input-dialog
-script.
- @mixin \api
- @mixin \input-dialog
+ @browser = @opts.browser
+ @folder = @opts.folder
- @browser = @opts.browser
- @folder = @opts.folder
+ @open = (pos) ~>
+ @refs.ctx.open pos
- @open = (pos) ~>
- @refs.ctx.open pos
+ @refs.ctx.on \closed ~>
+ @trigger \closed
+ @unmount!
- @refs.ctx.on \closed ~>
- @trigger \closed
- @unmount!
+ @move = ~>
+ @browser.move @folder.id
+ @refs.ctx.close!
- @move = ~>
- @browser.move @folder.id
- @refs.ctx.close!
+ @new-window = ~>
+ @browser.new-window @folder.id
+ @refs.ctx.close!
- @new-window = ~>
- @browser.new-window @folder.id
- @refs.ctx.close!
+ @create-folder = ~>
+ @browser.create-folder!
+ @refs.ctx.close!
- @create-folder = ~>
- @browser.create-folder!
- @refs.ctx.close!
+ @upload = ~>
+ @browser.select-lcoal-file!
+ @refs.ctx.close!
- @upload = ~>
- @browser.select-lcoal-file!
- @refs.ctx.close!
+ @rename = ~>
+ @refs.ctx.close!
- @rename = ~>
- @refs.ctx.close!
+ name <~ @input-dialog do
+ 'フォルダ名の変更'
+ '新しいフォルダ名を入力してください'
+ @folder.name
- name <~ @input-dialog do
- 'フォルダ名の変更'
- '新しいフォルダ名を入力してください'
- @folder.name
-
- @api \drive/folders/update do
- folder_id: @folder.id
- name: name
- .then ~>
- # something
- .catch (err) ~>
- console.error err
+ @api \drive/folders/update do
+ folder_id: @folder.id
+ name: name
+ .then ~>
+ # something
+ .catch (err) ~>
+ console.error err
+ </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 0f3b06d543..ddeb21027b 100644
--- a/src/web/app/desktop/tags/drive/folder.tag
+++ b/src/web/app/desktop/tags/drive/folder.tag
@@ -1,183 +1,184 @@
-mk-drive-browser-folder(data-is-contextmenu-showing={ is-contextmenu-showing.toString() }, data-draghover={ draghover.toString() }, onclick={ onclick }, onmouseover={ onmouseover }, onmouseout={ onmouseout }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop }, oncontextmenu={ oncontextmenu }, draggable='true', ondragstart={ ondragstart }, ondragend={ ondragend }, title={ title })
- p.name
- i.fa.fa-fw(class={ fa-folder-o: !hover, fa-folder-open-o: hover })
- | { folder.name }
-
-style.
- display block
- margin 4px
- padding 8px
- width 144px
- height 64px
- background lighten($theme-color, 95%)
- border-radius 4px
+<mk-drive-browser-folder data-is-contextmenu-showing="{ isContextmenuShowing.toString() }" data-draghover="{ draghover.toString() }" onclick="{ onclick }" onmouseover="{ onmouseover }" onmouseout="{ onmouseout }" ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }" oncontextmenu="{ oncontextmenu }" draggable="true" ondragstart="{ ondragstart }" ondragend="{ ondragend }" title="{ title }">
+ <p class="name"><i class="fa fa-fw { fa-folder-o: !hover, fa-folder-open-o: hover }"></i>{ folder.name }</p>
+ <style type="stylus">
+ :scope
+ display block
+ margin 4px
+ padding 8px
+ width 144px
+ height 64px
+ background lighten($theme-color, 95%)
+ border-radius 4px
- &, *
- cursor pointer
+ &, *
+ cursor pointer
- *
- pointer-events none
+ *
+ pointer-events none
- &:hover
- background lighten($theme-color, 90%)
+ &:hover
+ background lighten($theme-color, 90%)
- &:active
- background lighten($theme-color, 85%)
+ &:active
+ background lighten($theme-color, 85%)
- &[data-is-contextmenu-showing='true']
- &[data-draghover='true']
- &:after
- content ""
- pointer-events none
- position absolute
- top -4px
- right -4px
- bottom -4px
- left -4px
- border 2px dashed rgba($theme-color, 0.3)
- border-radius 4px
+ &[data-is-contextmenu-showing='true']
+ &[data-draghover='true']
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -4px
+ right -4px
+ bottom -4px
+ left -4px
+ border 2px dashed rgba($theme-color, 0.3)
+ border-radius 4px
- &[data-draghover='true']
- background lighten($theme-color, 90%)
+ &[data-draghover='true']
+ background lighten($theme-color, 90%)
- > .name
- margin 0
- font-size 0.9em
- color darken($theme-color, 30%)
+ > .name
+ margin 0
+ font-size 0.9em
+ color darken($theme-color, 30%)
- > i
- margin-right 4px
- margin-left 2px
- text-align left
+ > i
+ margin-right 4px
+ margin-left 2px
+ text-align left
-script.
- @mixin \api
- @mixin \dialog
+ </style>
+ <script>
+ @mixin \api
+ @mixin \dialog
- @folder = @opts.folder
- @browser = @parent
+ @folder = @opts.folder
+ @browser = @parent
- @title = @folder.name
- @hover = false
- @draghover = false
- @is-contextmenu-showing = false
+ @title = @folder.name
+ @hover = false
+ @draghover = false
+ @is-contextmenu-showing = false
- @onclick = ~>
- @browser.move @folder
+ @onclick = ~>
+ @browser.move @folder
- @onmouseover = ~>
- @hover = true
+ @onmouseover = ~>
+ @hover = true
- @onmouseout = ~>
- @hover = false
+ @onmouseout = ~>
+ @hover = false
- @ondragover = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ @ondragover = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
- # 自分自身がドラッグされていない場合
- if !@is-dragging
- # ドラッグされてきたものがファイルだったら
- if e.data-transfer.effect-allowed == \all
- e.data-transfer.drop-effect = \copy
+ # 自分自身がドラッグされていない場合
+ 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 = \move
- else
- # 自分自身にはドロップさせない
- e.data-transfer.drop-effect = \none
- return false
+ # 自分自身にはドロップさせない
+ e.data-transfer.drop-effect = \none
+ return false
- @ondragenter = ~>
- if !@is-dragging
- @draghover = true
+ @ondragenter = ~>
+ if !@is-dragging
+ @draghover = true
- @ondragleave = ~>
- @draghover = false
+ @ondragleave = ~>
+ @draghover = false
- @ondrop = (e) ~>
- e.stop-propagation!
- @draghover = false
+ @ondrop = (e) ~>
+ e.stop-propagation!
+ @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.data-transfer.files.length > 0
+ Array.prototype.for-each.call e.data-transfer.files, (file) ~>
+ @browser.upload file, @folder
+ return false
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
- return false
+ # データ取得
+ data = e.data-transfer.get-data 'text'
+ if !data?
+ return false
- # パース
- obj = JSON.parse data
+ # パース
+ 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
+ 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
- # (ドライブの)フォルダーだったら
- 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
- ]
+ # (ドライブの)フォルダーだったら
+ 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
- @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
+ @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
- # 親ブラウザに対して、ドラッグが開始されたフラグを立てる
- # (=あなたの子供が、ドラッグを開始しましたよ)
- @browser.is-drag-source = true
+ # 親ブラウザに対して、ドラッグが開始されたフラグを立てる
+ # (=あなたの子供が、ドラッグを開始しましたよ)
+ @browser.is-drag-source = true
- @ondragend = (e) ~>
- @is-dragging = false
- @browser.is-drag-source = false
+ @ondragend = (e) ~>
+ @is-dragging = false
+ @browser.is-drag-source = false
- @oncontextmenu = (e) ~>
- e.prevent-default!
- e.stop-immediate-propagation!
+ @oncontextmenu = (e) ~>
+ e.prevent-default!
+ e.stop-immediate-propagation!
- @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
+ @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 398a26a80b..34d6efdf58 100644
--- a/src/web/app/desktop/tags/drive/nav-folder.tag
+++ b/src/web/app/desktop/tags/drive/nav-folder.tag
@@ -1,96 +1,97 @@
-mk-drive-browser-nav-folder(data-draghover={ draghover }, onclick={ onclick }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop })
- i.fa.fa-cloud(if={ folder == null })
- span { folder == null ? 'ドライブ' : folder.name }
+<mk-drive-browser-nav-folder data-draghover="{ draghover }" onclick="{ onclick }" ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }"><i class="fa fa-cloud" if="{ folder == null }"></i><span>{ folder == null ? 'ドライブ' : folder.name }</span>
+ <style type="stylus">
+ :scope
+ &[data-draghover]
+ background #eee
-style.
- &[data-draghover]
- background #eee
+ </style>
+ <script>
+ @mixin \api
-script.
- @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
- #@folder = @opts.folder
- @folder = if @opts.folder? and @opts.folder != '' then @opts.folder else null
- @browser = @parent
+ @hover = false
- @hover = false
+ @onclick = ~>
+ @browser.move @folder
- @onclick = ~>
- @browser.move @folder
+ @onmouseover = ~>
+ @hover = true
- @onmouseover = ~>
- @hover = true
+ @onmouseout = ~>
+ @hover = false
- @onmouseout = ~>
- @hover = false
+ @ondragover = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
- @ondragover = (e) ~>
- e.prevent-default!
- e.stop-propagation!
+ # このフォルダがルートかつカレントディレクトリならドロップ禁止
+ 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 @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
+ @ondragenter = ~>
+ if @folder != null or @browser.folder != null
+ @draghover = true
- @ondragenter = ~>
- if @folder != null or @browser.folder != null
- @draghover = true
+ @ondragleave = ~>
+ if @folder != null or @browser.folder != null
+ @draghover = false
- @ondragleave = ~>
- if @folder != null or @browser.folder != null
+ @ondrop = (e) ~>
+ e.stop-propagation!
@draghover = false
- @ondrop = (e) ~>
- e.stop-propagation!
- @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.data-transfer.files.length > 0
+ Array.prototype.for-each.call e.data-transfer.files, (file) ~>
+ @browser.upload file, @folder
+ return false
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
- return false
+ # データ取得
+ data = e.data-transfer.get-data 'text'
+ if !data?
+ return false
- # パース
- obj = JSON.parse data
+ # パース
+ 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
+ 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
- # (ドライブの)フォルダーだったら
- 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
+ # (ドライブの)フォルダーだったら
+ 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 5d18bc0473..34731bb797 100644
--- a/src/web/app/desktop/tags/ellipsis-icon.tag
+++ b/src/web/app/desktop/tags/ellipsis-icon.tag
@@ -1,34 +1,41 @@
-mk-ellipsis-icon
- div
- div
- div
+<mk-ellipsis-icon>
+ <div></div>
+ <div></div>
+ <div></div>
+ <style type="stylus">
+ :scope
+ display block
+ width 70px
+ margin 0 auto
+ text-align center
-style.
- display block
- width 70px
- margin 0 auto
- text-align center
+ > div
+ display inline-block
+ width 18px
+ height 18px
+ background-color rgba(0, 0, 0, 0.3)
+ border-radius 100%
+ animation bounce 1.4s infinite ease-in-out both
- > div
- display inline-block
- width 18px
- height 18px
- background-color rgba(0, 0, 0, 0.3)
- border-radius 100%
- animation bounce 1.4s infinite ease-in-out both
+ &:nth-child(1)
+ animation-delay 0s
- &:nth-child(1)
- animation-delay 0s
+ &:nth-child(2)
+ margin 0 6px
+ animation-delay 0.16s
- &:nth-child(2)
- margin 0 6px
- animation-delay 0.16s
+ &:nth-child(3)
+ animation-delay 0.32s
- &:nth-child(3)
- animation-delay 0.32s
+ @keyframes bounce
+ 0%, 80%, 100%
+ transform scale(0)
+ 40%
+ transform scale(1)
- @keyframes bounce
- 0%, 80%, 100%
- transform scale(0)
- 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 41bd1f0e12..300a5fe035 100644
--- a/src/web/app/desktop/tags/follow-button.tag
+++ b/src/web/app/desktop/tags/follow-button.tag
@@ -1,127 +1,124 @@
-mk-follow-button
- button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following },
- onclick={ onclick },
- disabled={ wait },
- title={ user.is_following ? 'フォロー解除' : 'フォローする' })
- i.fa.fa-minus(if={ !wait && user.is_following })
- i.fa.fa-plus(if={ !wait && !user.is_following })
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ wait })
- div.init(if={ init }): i.fa.fa-spinner.fa-pulse.fa-fw
+<mk-follow-button>
+ <button class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }" if="{ !init }" onclick="{ onclick }" disabled="{ wait }" title="{ user.is_following ? 'フォロー解除' : 'フォローする' }"><i class="fa fa-minus" if="{ !wait &amp;&amp; user.is_following }"></i><i class="fa fa-plus" if="{ !wait &amp;&amp; !user.is_following }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ wait }"></i></button>
+ <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > button
+ > .init
+ display block
+ cursor pointer
+ padding 0
+ margin 0
+ width 32px
+ height 32px
+ font-size 1em
+ outline none
+ border-radius 4px
- > button
- > .init
- display block
- cursor pointer
- padding 0
- margin 0
- width 32px
- height 32px
- font-size 1em
- outline none
- border-radius 4px
+ *
+ pointer-events none
- *
- pointer-events none
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- &:focus
- &:after
- content ""
- pointer-events none
- position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ &.follow
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
- &.follow
- color #888
- background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
- border solid 1px #e2e2e2
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
- &:hover
- background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
- border-color #dcdcdc
+ &:active
+ background #ececec
+ border-color #dcdcdc
- &:active
- background #ececec
- border-color #dcdcdc
+ &.unfollow
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
- &.unfollow
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- border solid 1px lighten($theme-color, 15%)
+ &:not(:disabled)
+ font-weight bold
- &:not(:disabled)
- font-weight bold
+ &:hover:not(:disabled)
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- &:hover:not(:disabled)
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:active:not(:disabled)
+ background $theme-color
+ border-color $theme-color
- &:active:not(:disabled)
- background $theme-color
- border-color $theme-color
+ &.wait
+ cursor wait !important
+ opacity 0.7
- &.wait
- cursor wait !important
- opacity 0.7
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
+ @mixin \stream
-script.
- @mixin \api
- @mixin \is-promise
- @mixin \stream
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ @init = true
+ @wait = false
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @init = true
- @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
-
- @on \unmount ~>
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
-
- @on-stream-follow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ @on \mount ~>
+ @user-promise.then (user) ~>
+ @user = user
+ @init = false
+ @update!
+ @stream.on \follow @on-stream-follow
+ @stream.on \unfollow @on-stream-unfollow
- @on-stream-unfollow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ @on \unmount ~>
+ @stream.off \follow @on-stream-follow
+ @stream.off \unfollow @on-stream-unfollow
- @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
+ @on-stream-follow = (user) ~>
+ if user.id == @user.id
+ @user = user
@update!
- else
- @api \following/create do
- user_id: @user.id
- .then ~>
- @user.is_following = true
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
+
+ @on-stream-unfollow = (user) ~>
+ if user.id == @user.id
+ @user = user
@update!
+
+ @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!
+ </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 9b75a251e0..6e8e40a2b1 100644
--- a/src/web/app/desktop/tags/following-setuper.tag
+++ b/src/web/app/desktop/tags/following-setuper.tag
@@ -1,163 +1,163 @@
-mk-following-setuper
- p.title 気になるユーザーをフォロー:
- div.users(if={ !loading && users.length > 0 })
- div.user(each={ users })
- a.avatar-anchor(href={ CONFIG.url + '/' + username })
- img.avatar(src={ avatar_url + '?thumbnail&size=42' }, alt='', data-user-preview={ id })
- div.body
- a.name(href={ CONFIG.url + '/' + username }, target='_blank', data-user-preview={ id }) { name }
- p.username @{ username }
- mk-follow-button(user={ this })
- p.empty(if={ !loading && users.length == 0 })
- | おすすめのユーザーは見つかりませんでした。
- p.loading(if={ loading })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
- a.refresh(onclick={ refresh }) もっと見る
- button.close(onclick={ close }, title='閉じる'): i.fa.fa-times
-
-style.
- display block
- padding 24px
- background #fff
-
- > .title
- margin 0 0 12px 0
- font-size 1em
- font-weight bold
- color #888
-
- > .users
- &:after
- content ""
+<mk-following-setuper>
+ <p class="title">気になるユーザーをフォロー:</p>
+ <div class="users" if="{ !loading &amp;&amp; users.length &gt; 0 }">
+ <div class="user" each="{ users }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + username }"><img class="avatar" src="{ avatar_url + '?thumbnail&amp;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>
+ </div>
+ <mk-follow-button user="{ this }"></mk-follow-button>
+ </div>
+ </div>
+ <p class="empty" if="{ !loading &amp;&amp; users.length == 0 }">おすすめのユーザーは見つかりませんでした。</p>
+ <p class="loading" if="{ loading }"><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>
+ <style type="stylus">
+ :scope
display block
- clear both
-
- > .user
- padding 16px
- width 238px
- float left
-
- &:after
- content ""
- display block
- clear both
+ padding 24px
+ background #fff
- > .avatar-anchor
- display block
- float left
- margin 0 12px 0 0
+ > .title
+ margin 0 0 12px 0
+ font-size 1em
+ font-weight bold
+ color #888
- > .avatar
+ > .users
+ &:after
+ content ""
display block
- width 42px
- height 42px
- margin 0
- border-radius 8px
- vertical-align bottom
+ clear both
- > .body
- float left
- width calc(100% - 54px)
+ > .user
+ padding 16px
+ width 238px
+ float left
- > .name
- margin 0
- font-size 16px
- line-height 24px
- color #555
+ &:after
+ content ""
+ display block
+ clear both
- > .username
- margin 0
- font-size 15px
- line-height 16px
- color #ccc
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 12px 0 0
- > mk-follow-button
- position absolute
- top 16px
- right 16px
+ > .avatar
+ display block
+ width 42px
+ height 42px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- > .empty
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > .body
+ float left
+ width calc(100% - 54px)
- > .loading
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > .name
+ margin 0
+ font-size 16px
+ line-height 24px
+ color #555
- > i
- margin-right 4px
+ > .username
+ margin 0
+ font-size 15px
+ line-height 16px
+ color #ccc
- > .refresh
- display block
- margin 0 8px 0 0
- text-align right
- font-size 0.9em
- color #999
+ > mk-follow-button
+ position absolute
+ top 16px
+ right 16px
- > .close
- cursor pointer
- display block
- position absolute
- top 6px
- right 6px
- z-index 1
- margin 0
- padding 0
- font-size 1.2em
- color #999
- border none
- outline none
- background transparent
+ > .empty
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- &:hover
- color #555
+ > .loading
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- &:active
- color #222
+ > i
+ margin-right 4px
- > i
- padding 14px
+ > .refresh
+ display block
+ margin 0 8px 0 0
+ text-align right
+ font-size 0.9em
+ color #999
-script.
- @mixin \api
- @mixin \user-preview
+ > .close
+ cursor pointer
+ display block
+ position absolute
+ top 6px
+ right 6px
+ z-index 1
+ margin 0
+ padding 0
+ font-size 1.2em
+ color #999
+ border none
+ outline none
+ background transparent
- @users = null
- @loading = true
+ &:hover
+ color #555
- @limit = 6users
- @page = 0
+ &:active
+ color #222
- @on \mount ~>
- @load!
+ > i
+ padding 14px
+
+ </style>
+ <script>
+ @mixin \api
+ @mixin \user-preview
- @load = ~>
- @loading = true
@users = null
- @update!
+ @loading = true
+
+ @limit = 6users
+ @page = 0
- @api \users/recommendation do
- limit: @limit
- offset: @limit * @page
- .then (users) ~>
- @loading = false
- @users = users
+ @on \mount ~>
+ @load!
+
+ @load = ~>
+ @loading = true
+ @users = null
@update!
- .catch (err, text-status) ->
- console.error err
- @refresh = ~>
- if @users.length < @limit
- @page = 0
- else
- @page++
- @load!
+ @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++
+ @load!
- @close = ~>
- @unmount!
+ @close = ~>
+ @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
index a11f4a3640..d43e68ea90 100644
--- a/src/web/app/desktop/tags/go-top.tag
+++ b/src/web/app/desktop/tags/go-top.tag
@@ -1,15 +1,14 @@
-mk-go-top
- button.hidden(title='一番上へ')
- i.fa.fa-angle-up
+<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
-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
+ @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/broadcast.tag b/src/web/app/desktop/tags/home-widgets/broadcast.tag
index 0e21adec48..dda71218ab 100644
--- a/src/web/app/desktop/tags/home-widgets/broadcast.tag
+++ b/src/web/app/desktop/tags/home-widgets/broadcast.tag
@@ -1,75 +1,83 @@
-mk-broadcast-home-widget
- div.icon
- svg(height='32', version='1.1', viewBox='0 0 32 32', width='32')
- path.tower(d='M16.04,11.24c1.79,0,3.239-1.45,3.239-3.24S17.83,4.76,16.04,4.76c-1.79,0-3.24,1.45-3.24,3.24 C12.78,9.78,14.24,11.24,16.04,11.24z M16.04,13.84c-0.82,0-1.66-0.2-2.4-0.6L7.34,29.98h2.98l1.72-2h8l1.681,2H24.7L18.42,13.24 C17.66,13.64,16.859,13.84,16.04,13.84z M16.02,14.8l2.02,7.2h-4L16.02,14.8z M12.04,25.98l2-2h4l2,2H12.04z')
- path.wave.a(d='M4.66,1.04c-0.508-0.508-1.332-0.508-1.84,0c-1.86,1.92-2.8,4.44-2.8,6.94c0,2.52,0.94,5.04,2.8,6.96 c0.5,0.52,1.32,0.52,1.82,0s0.5-1.36,0-1.88C3.28,11.66,2.6,9.82,2.6,7.98S3.28,4.3,4.64,2.9C5.157,2.391,5.166,1.56,4.66,1.04z')
- path.wave.b(d='M9.58,12.22c0.5-0.5,0.5-1.34,0-1.84C8.94,9.72,8.62,8.86,8.62,8s0.32-1.72,0.96-2.38c0.5-0.52,0.5-1.34,0-1.84 C9.346,3.534,9.02,3.396,8.68,3.4c-0.32,0-0.66,0.12-0.9,0.38C6.64,4.94,6.08,6.48,6.08,8s0.58,3.06,1.7,4.22 C8.28,12.72,9.1,12.72,9.58,12.22z')
- path.wave.c(d='M22.42,3.78c-0.5,0.5-0.5,1.34,0,1.84c0.641,0.66,0.96,1.52,0.96,2.38s-0.319,1.72-0.96,2.38c-0.5,0.52-0.5,1.34,0,1.84 c0.487,0.497,1.285,0.505,1.781,0.018c0.007-0.006,0.013-0.012,0.02-0.018c1.139-1.16,1.699-2.7,1.699-4.22s-0.561-3.06-1.699-4.22 c-0.494-0.497-1.297-0.5-1.794-0.007C22.424,3.775,22.422,3.778,22.42,3.78z')
- path.wave.d(d='M29.18,1.06c-0.479-0.502-1.273-0.522-1.775-0.044c-0.016,0.015-0.029,0.029-0.045,0.044c-0.5,0.52-0.5,1.36,0,1.88 c1.361,1.4,2.041,3.24,2.041,5.08s-0.68,3.66-2.041,5.08c-0.5,0.52-0.5,1.36,0,1.88c0.509,0.508,1.332,0.508,1.841,0 c1.86-1.92,2.8-4.44,2.8-6.96C31.99,5.424,30.98,2.931,29.18,1.06z')
+<mk-broadcast-home-widget>
+ <div class="icon">
+ <svg height="32" version="1.1" viewBox="0 0 32 32" width="32">
+ <path class="tower" d="M16.04,11.24c1.79,0,3.239-1.45,3.239-3.24S17.83,4.76,16.04,4.76c-1.79,0-3.24,1.45-3.24,3.24 C12.78,9.78,14.24,11.24,16.04,11.24z M16.04,13.84c-0.82,0-1.66-0.2-2.4-0.6L7.34,29.98h2.98l1.72-2h8l1.681,2H24.7L18.42,13.24 C17.66,13.64,16.859,13.84,16.04,13.84z M16.02,14.8l2.02,7.2h-4L16.02,14.8z M12.04,25.98l2-2h4l2,2H12.04z"></path>
+ <path class="wave a" d="M4.66,1.04c-0.508-0.508-1.332-0.508-1.84,0c-1.86,1.92-2.8,4.44-2.8,6.94c0,2.52,0.94,5.04,2.8,6.96 c0.5,0.52,1.32,0.52,1.82,0s0.5-1.36,0-1.88C3.28,11.66,2.6,9.82,2.6,7.98S3.28,4.3,4.64,2.9C5.157,2.391,5.166,1.56,4.66,1.04z"></path>
+ <path class="wave b" d="M9.58,12.22c0.5-0.5,0.5-1.34,0-1.84C8.94,9.72,8.62,8.86,8.62,8s0.32-1.72,0.96-2.38c0.5-0.52,0.5-1.34,0-1.84 C9.346,3.534,9.02,3.396,8.68,3.4c-0.32,0-0.66,0.12-0.9,0.38C6.64,4.94,6.08,6.48,6.08,8s0.58,3.06,1.7,4.22 C8.28,12.72,9.1,12.72,9.58,12.22z"></path>
+ <path class="wave c" d="M22.42,3.78c-0.5,0.5-0.5,1.34,0,1.84c0.641,0.66,0.96,1.52,0.96,2.38s-0.319,1.72-0.96,2.38c-0.5,0.52-0.5,1.34,0,1.84 c0.487,0.497,1.285,0.505,1.781,0.018c0.007-0.006,0.013-0.012,0.02-0.018c1.139-1.16,1.699-2.7,1.699-4.22s-0.561-3.06-1.699-4.22 c-0.494-0.497-1.297-0.5-1.794-0.007C22.424,3.775,22.422,3.778,22.42,3.78z"></path>
+ <path class="wave d" d="M29.18,1.06c-0.479-0.502-1.273-0.522-1.775-0.044c-0.016,0.015-0.029,0.029-0.045,0.044c-0.5,0.52-0.5,1.36,0,1.88 c1.361,1.4,2.041,3.24,2.041,5.08s-0.68,3.66-2.041,5.08c-0.5,0.52-0.5,1.36,0,1.88c0.509,0.508,1.332,0.508,1.841,0 c1.86-1.92,2.8-4.44,2.8-6.96C31.99,5.424,30.98,2.931,29.18,1.06z"></path>
+ </svg>
+ </div>
+ <h1>開発者募集中!</h1>
+ <p><a href="https://github.com/syuilo/misskey" target="_blank">Misskeyはオープンソースで開発されています。リポジトリはこちら。</a></p>
+ <style type="stylus">
+ :scope
+ display block
+ padding 10px 10px 10px 50px
+ background transparent
+ border-color #4078c0 !important
- h1 開発者募集中!
- p: a(href='https://github.com/syuilo/misskey', target='_blank') Misskeyはオープンソースで開発されています。リポジトリはこちら。
+ &:after
+ content ""
+ display block
+ clear both
-style.
- display block
- padding 10px 10px 10px 50px
- background transparent
- border-color #4078c0 !important
+ > .icon
+ display block
+ float left
+ margin-left -40px
- &:after
- content ""
- display block
- clear both
+ > svg
+ fill currentColor
+ color #4078c0
- > .icon
- display block
- float left
- margin-left -40px
+ > .wave
+ opacity 1
- > svg
- fill currentColor
- color #4078c0
-
- > .wave
- opacity 1
+ &.a
+ animation wave 20s ease-in-out 2.1s infinite
+ &.b
+ animation wave 20s ease-in-out 2s infinite
+ &.c
+ animation wave 20s ease-in-out 2s infinite
+ &.d
+ animation wave 20s ease-in-out 2.1s infinite
- &.a
- animation wave 20s ease-in-out 2.1s infinite
- &.b
- animation wave 20s ease-in-out 2s infinite
- &.c
- animation wave 20s ease-in-out 2s infinite
- &.d
- animation wave 20s ease-in-out 2.1s infinite
+ @keyframes wave
+ 0%
+ opacity 1
+ 1.5%
+ opacity 0
+ 3.5%
+ opacity 0
+ 5%
+ opacity 1
+ 6.5%
+ opacity 0
+ 8.5%
+ opacity 0
+ 10%
+ opacity 1
- @keyframes wave
- 0%
- opacity 1
- 1.5%
- opacity 0
- 3.5%
- opacity 0
- 5%
- opacity 1
- 6.5%
- opacity 0
- 8.5%
- opacity 0
- 10%
- opacity 1
+ > h1
+ margin 0
+ font-size 0.95em
+ font-weight normal
+ color #4078c0
- > h1
- margin 0
- font-size 0.95em
- font-weight normal
- color #4078c0
+ > p
+ display block
+ z-index 1
+ margin 0
+ font-size 0.7em
+ color #555
- > p
- display block
- z-index 1
- margin 0
- font-size 0.7em
- color #555
+ a
+ color #555
+
+
+
+
- a
- color #555
+ </style>
+</mk-broadcast-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/calendar.tag b/src/web/app/desktop/tags/home-widgets/calendar.tag
index 87c65729d3..affa55c96b 100644
--- a/src/web/app/desktop/tags/home-widgets/calendar.tag
+++ b/src/web/app/desktop/tags/home-widgets/calendar.tag
@@ -1,147 +1,148 @@
-mk-calendar-home-widget(data-special={ special })
- div.calendar(data-is-holiday={ is-holiday })
- p.month-and-year
- span.year { year }年
- span.month { month }月
- p.day { day }日
- p.week-day { week-day }曜日
- div.info
- div
- p
- | 今日:
- b { day-p.to-fixed(1) }%
- div.meter
- div.val(style={ 'width:' + day-p + '%' })
+<mk-calendar-home-widget data-special="{ special }">
+ <div class="calendar" data-is-holiday="{ isHoliday }">
+ <p class="month-and-year"><span class="year">{ year }年</span><span class="month">{ month }月</span></p>
+ <p class="day">{ day }日</p>
+ <p class="week-day">{ weekDay }曜日</p>
+ </div>
+ <div class="info">
+ <div>
+ <p>今日:<b>{ dayP.toFixed(1) }%</b></p>
+ <div class="meter">
+ <div class="val" style="{ 'width:' + dayP + '%' }"></div>
+ </div>
+ </div>
+ <div>
+ <p>今月:<b>{ monthP.toFixed(1) }%</b></p>
+ <div class="meter">
+ <div class="val" style="{ 'width:' + monthP + '%' }"></div>
+ </div>
+ </div>
+ <div>
+ <p>今年:<b>{ yearP.toFixed(1) }%</b></p>
+ <div class="meter">
+ <div class="val" style="{ 'width:' + yearP + '%' }"></div>
+ </div>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ padding 16px 0
+ color #777
+ background #fff
- div
- p
- | 今月:
- b { month-p.to-fixed(1) }%
- div.meter
- div.val(style={ 'width:' + month-p + '%' })
+ &[data-special='on-new-years-day']
+ border-color #ef95a0 !important
- div
- p
- | 今年:
- b { year-p.to-fixed(1) }%
- div.meter
- div.val(style={ 'width:' + year-p + '%' })
+ &:after
+ content ""
+ display block
+ clear both
-style.
- display block
- padding 16px 0
- color #777
- background #fff
+ > .calendar
+ float left
+ width 60%
+ text-align center
- &[data-special='on-new-years-day']
- border-color #ef95a0 !important
+ &[data-is-holiday]
+ > .day
+ color #ef95a0
- &:after
- content ""
- display block
- clear both
+ > p
+ margin 0
+ line-height 18px
+ font-size 14px
- > .calendar
- float left
- width 60%
- text-align center
+ > span
+ margin 0 4px
- &[data-is-holiday]
- > .day
- color #ef95a0
+ > .day
+ margin 10px 0
+ line-height 32px
+ font-size 28px
- > p
- margin 0
- line-height 18px
- font-size 14px
+ > .info
+ display block
+ float left
+ width 40%
+ padding 0 16px 0 0
- > span
- margin 0 4px
+ > div
+ margin-bottom 8px
- > .day
- margin 10px 0
- line-height 32px
- font-size 28px
+ &:last-child
+ margin-bottom 4px
- > .info
- display block
- float left
- width 40%
- padding 0 16px 0 0
+ > p
+ margin 0 0 2px 0
+ font-size 12px
+ line-height 18px
+ color #888
- > div
- margin-bottom 8px
+ > b
+ margin-left 2px
- &:last-child
- margin-bottom 4px
+ > .meter
+ width 100%
+ overflow hidden
+ background #eee
+ border-radius 8px
- > p
- margin 0 0 2px 0
- font-size 12px
- line-height 18px
- color #888
+ > .val
+ height 4px
+ background $theme-color
- > b
- margin-left 2px
+ &:nth-child(1)
+ > .meter > .val
+ background #f7796c
- > .meter
- width 100%
- overflow hidden
- background #eee
- border-radius 8px
+ &:nth-child(2)
+ > .meter > .val
+ background #a1de41
- > .val
- height 4px
- background $theme-color
+ &:nth-child(3)
+ > .meter > .val
+ background #41ddde
- &:nth-child(1)
- > .meter > .val
- background #f7796c
+ </style>
+ <script>
+ @draw = ~>
+ now = new Date!
+ nd = now.get-date!
+ nm = now.get-month!
+ ny = now.get-full-year!
- &:nth-child(2)
- > .meter > .val
- background #a1de41
+ @year = ny
+ @month = nm + 1
+ @day = nd
+ @week-day = [\日 \月 \火 \水 \木 \金 \土][now.get-day!]
- &:nth-child(3)
- > .meter > .val
- background #41ddde
+ @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)
-script.
- @draw = ~>
- now = new Date!
- nd = now.get-date!
- nm = now.get-month!
- ny = now.get-full-year!
+ @day-p = @day-numer / @day-denom * 100
+ @month-p = @month-numer / @month-denom * 100
+ @year-p = @year-numer / @year-denom * 100
- @year = ny
- @month = nm + 1
- @day = nd
- @week-day = [\日 \月 \火 \水 \木 \金 \土][now.get-day!]
+ @is-holiday =
+ (now.get-day! == 0 or now.get-day! == 6)
- @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)
+ @special =
+ | nm == 0 and nd == 1 => \on-new-years-day
+ | _ => false
- @day-p = @day-numer / @day-denom * 100
- @month-p = @month-numer / @month-denom * 100
- @year-p = @year-numer / @year-denom * 100
+ @update!
- @is-holiday =
- (now.get-day! == 0 or now.get-day! == 6)
+ @draw!
- @special =
- | nm == 0 and nd == 1 => \on-new-years-day
- | _ => false
+ @on \mount ~>
+ @clock = set-interval @draw, 1000ms
- @update!
-
- @draw!
-
- @on \mount ~>
- @clock = set-interval @draw, 1000ms
-
- @on \unmount ~>
- clear-interval @clock
+ @on \unmount ~>
+ clear-interval @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 a41bd9f8a4..01d9b20ea2 100644
--- a/src/web/app/desktop/tags/home-widgets/donation.tag
+++ b/src/web/app/desktop/tags/home-widgets/donation.tag
@@ -1,37 +1,36 @@
-mk-donation-home-widget
- article
- h1
- i.fa.fa-heart
- | 寄付のお願い
- p
- | Misskeyの運営にはドメイン、サーバー等のコストが掛かります。
- | Misskeyは広告を掲載したりしないため、 収入を皆様からの寄付に頼っています。
- | もしご興味があれば、
- a(href='/syuilo', data-user-preview='@syuilo') @syuilo
- | までご連絡ください。ご協力ありがとうございます。
-
-style.
- display block
- background #fff
- border-color #ead8bb !important
+<mk-donation-home-widget>
+ <article>
+ <h1><i class="fa fa-heart"></i>寄付のお願い</h1>
+ <p>
+ Misskeyの運営にはドメイン、サーバー等のコストが掛かります。
+ Misskeyは広告を掲載したりしないため、 収入を皆様からの寄付に頼っています。
+ もしご興味があれば、<a href="/syuilo" data-user-preview="@syuilo">@syuilo</a>までご連絡ください。ご協力ありがとうございます。
+ </p>
+ </article>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
+ border-color #ead8bb !important
- > article
- padding 20px
+ > article
+ padding 20px
- > h1
- margin 0 0 5px 0
- font-size 1em
- color #888
+ > h1
+ margin 0 0 5px 0
+ font-size 1em
+ color #888
- > i
- margin-right 0.25em
+ > i
+ margin-right 0.25em
- > p
- display block
- z-index 1
- margin 0
- font-size 0.8em
- color #999
+ > p
+ display block
+ z-index 1
+ margin 0
+ font-size 0.8em
+ color #999
-script.
- @mixin \user-preview
+ </style>
+ <script>@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 0f0cd0269d..81ceff6179 100644
--- a/src/web/app/desktop/tags/home-widgets/mentions.tag
+++ b/src/web/app/desktop/tags/home-widgets/mentions.tag
@@ -1,117 +1,112 @@
-mk-mentions-home-widget
- header
- span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') }) すべて
- span(data-is-active={ mode == 'following' }, onclick={ set-mode.bind(this, 'following') }) フォロー中
- div.loading(if={ is-loading })
- mk-ellipsis-icon
- p.empty(if={ is-empty })
- i.fa.fa-comments-o
- span(if={ mode == 'all' }) あなた宛ての投稿はありません。
- span(if={ mode == 'following' }) あなたがフォローしているユーザーからの言及はありません。
- mk-timeline@timeline
- <yield to="footer">
- i.fa.fa-moon-o(if={ !parent.more-loading })
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
- </yield>
-
-style.
- display block
- background #fff
+<mk-mentions-home-widget>
+ <header><span data-is-active="{ mode == 'all' }" onclick="{ setMode.bind(this, 'all') }">すべて</span><span data-is-active="{ mode == 'following' }" onclick="{ setMode.bind(this, 'following') }">フォロー中</span></header>
+ <div class="loading" if="{ isLoading }">
+ <mk-ellipsis-icon></mk-ellipsis-icon>
+ </div>
+ <p class="empty" if="{ isEmpty }"><i class="fa fa-comments-o"></i><span if="{ mode == 'all' }">あなた宛ての投稿はありません。</span><span if="{ mode == 'following' }">あなたがフォローしているユーザーからの言及はありません。</span></p>
+ <mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
- > header
- padding 8px 16px
- border-bottom solid 1px #eee
+ > header
+ padding 8px 16px
+ border-bottom solid 1px #eee
- > span
- margin-right 16px
- line-height 27px
- font-size 18px
- color #555
+ > span
+ margin-right 16px
+ line-height 27px
+ font-size 18px
+ color #555
- &:not([data-is-active])
- color $theme-color
- cursor pointer
+ &:not([data-is-active])
+ color $theme-color
+ cursor pointer
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration underline
- > .loading
- padding 64px 0
+ > .loading
+ padding 64px 0
- > .empty
- display block
- margin 0 auto
- padding 32px
- max-width 400px
- text-align center
- color #999
+ > .empty
+ display block
+ margin 0 auto
+ padding 32px
+ max-width 400px
+ text-align center
+ color #999
- > i
- display block
- margin-bottom 16px
- font-size 3em
- color #ccc
+ > i
+ display block
+ margin-bottom 16px
+ font-size 3em
+ color #ccc
-script.
- @mixin \i
- @mixin \api
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @mode = \all
+ @is-loading = true
+ @is-empty = false
+ @more-loading = false
+ @mode = \all
- @on \mount ~>
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ @on \mount ~>
+ document.add-event-listener \keydown @on-document-keydown
+ window.add-event-listener \scroll @on-scroll
- @fetch ~>
- @trigger \loaded
+ @fetch ~>
+ @trigger \loaded
- @on \unmount ~>
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ @on \unmount ~>
+ document.remove-event-listener \keydown @on-document-keydown
+ window.remove-event-listener \scroll @on-scroll
- @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!
+ @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!
- @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!
+ @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!
- @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
+ @more = ~>
+ if @more-loading or @is-loading or @refs.timeline.posts.length == 0
+ return
+ @more-loading = true
@update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
+ @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
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 8
- @more!
+ @on-scroll = ~>
+ current = window.scroll-y + window.inner-height
+ if current > document.body.offset-height - 8
+ @more!
- @set-mode = (mode) ~>
- @update do
- mode: mode
- @fetch!
+ @set-mode = (mode) ~>
+ @update do
+ mode: mode
+ @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 5b8e7e1b3c..7e153bc234 100644
--- a/src/web/app/desktop/tags/home-widgets/nav.tag
+++ b/src/web/app/desktop/tags/home-widgets/nav.tag
@@ -1,23 +1,21 @@
-mk-nav-home-widget
- a(href={ CONFIG.urls.about }) Misskeyについて
- i ・
- a(href={ CONFIG.urls.about + '/status' }) ステータス
- i ・
- a(href='https://github.com/syuilo/misskey') リポジトリ
- i ・
- a(href={ CONFIG.urls.dev }) 開発者
- i ・
- a(href='https://twitter.com/misskey_xyz', target='_blank') Follow us on <i class="fa fa-twitter"></i>
+<mk-nav-home-widget><a href="{ CONFIG.urls.about }">Misskeyについて</a><i>・</i><a href="{ CONFIG.urls.about + '/status' }">ステータス</a><i>・</i><a href="https://github.com/syuilo/misskey">リポジトリ</a><i>・</i><a href="{ CONFIG.urls.dev }">開発者</a><i>・</i><a href="https://twitter.com/misskey_xyz" target="_blank">Follow us on <i class="fa fa-twitter"></i></a>
+ <style type="stylus">
+ :scope
+ display block
+ padding 16px
+ font-size 12px
+ color #aaa
+ background #fff
-style.
- display block
- padding 16px
- font-size 12px
- color #aaa
- background #fff
+ a
+ color #999
- a
- color #999
+ i
+ color #ccc
- 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 588a765d02..43baa01439 100644
--- a/src/web/app/desktop/tags/home-widgets/notifications.tag
+++ b/src/web/app/desktop/tags/home-widgets/notifications.tag
@@ -1,49 +1,50 @@
-mk-notifications-home-widget
- p.title
- i.fa.fa-bell-o
- | 通知
- button(onclick={ settings }, title='通知の設定'): i.fa.fa-cog
- mk-notifications
+<mk-notifications-home-widget>
+ <p class="title"><i class="fa fa-bell-o"></i>通知</p>
+ <button onclick="{ settings }" title="通知の設定"><i class="fa fa-cog"></i></button>
+ <mk-notifications></mk-notifications>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > .title
+ z-index 1
+ margin 0
+ padding 0 16px
+ line-height 42px
+ font-size 0.9em
+ font-weight bold
+ color #888
+ box-shadow 0 1px rgba(0, 0, 0, 0.07)
- > .title
- z-index 1
- margin 0
- padding 0 16px
- line-height 42px
- font-size 0.9em
- font-weight bold
- color #888
- box-shadow 0 1px rgba(0, 0, 0, 0.07)
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ > button
+ position absolute
+ z-index 2
+ top 0
+ right 0
+ padding 0
+ width 42px
+ font-size 0.9em
+ line-height 42px
+ color #ccc
- > button
- position absolute
- z-index 2
- top 0
- right 0
- padding 0
- width 42px
- font-size 0.9em
- line-height 42px
- color #ccc
+ &:hover
+ color #aaa
- &:hover
- color #aaa
+ &:active
+ color #999
- &:active
- color #999
+ > mk-notifications
+ max-height 300px
+ overflow auto
- > mk-notifications
- max-height 300px
- overflow auto
-
-script.
- @settings = ~>
- w = riot.mount document.body.append-child document.create-element \mk-settings-window .0
- w.switch \notification
+ </style>
+ <script>
+ @settings = ~>
+ w = riot.mount document.body.append-child document.create-element \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 b972706574..245427badf 100644
--- a/src/web/app/desktop/tags/home-widgets/photo-stream.tag
+++ b/src/web/app/desktop/tags/home-widgets/photo-stream.tag
@@ -1,86 +1,87 @@
-mk-photo-stream-home-widget
- p.title
- i.fa.fa-camera
- | フォトストリーム
- p.initializing(if={ initializing })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
- div.stream(if={ !initializing && images.length > 0 })
- virtual(each={ image in images })
- div.img(style={ 'background-image: url(' + image.url + '?thumbnail&size=256)' })
- p.empty(if={ !initializing && images.length == 0 })
- | 写真はありません
+<mk-photo-stream-home-widget>
+ <p class="title"><i class="fa fa-camera"></i>フォトストリーム</p>
+ <p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <div class="stream" if="{ !initializing &amp;&amp; images.length &gt; 0 }">
+ <virtual each="{ image in images }">
+ <div class="img" style="{ 'background-image: url(' + image.url + '?thumbnail&amp;size=256)' }"></div>
+ </virtual>
+ </div>
+ <p class="empty" if="{ !initializing &amp;&amp; images.length == 0 }">写真はありません</p>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > .title
+ z-index 1
+ margin 0
+ padding 0 16px
+ line-height 42px
+ font-size 0.9em
+ font-weight bold
+ color #888
+ box-shadow 0 1px rgba(0, 0, 0, 0.07)
- > .title
- z-index 1
- margin 0
- padding 0 16px
- line-height 42px
- font-size 0.9em
- font-weight bold
- color #888
- box-shadow 0 1px rgba(0, 0, 0, 0.07)
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ > .stream
+ display -webkit-flex
+ display -moz-flex
+ display -ms-flex
+ display flex
+ justify-content center
+ flex-wrap wrap
+ padding 8px
- > .stream
- display -webkit-flex
- display -moz-flex
- display -ms-flex
- display flex
- justify-content center
- flex-wrap wrap
- padding 8px
+ > .img
+ flex 1 1 33%
+ width 33%
+ height 80px
+ background-position center center
+ background-size cover
+ background-clip content-box
+ border solid 2px transparent
- > .img
- flex 1 1 33%
- width 33%
- height 80px
- background-position center center
- background-size cover
- background-clip content-box
- border solid 2px transparent
+ > .initializing
+ > .empty
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- > .initializing
- > .empty
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \stream
-script.
- @mixin \api
- @mixin \stream
+ @images = []
+ @initializing = true
- @images = []
- @initializing = true
+ @on \mount ~>
+ @stream.on \drive_file_created @on-stream-drive-file-created
- @on \mount ~>
- @stream.on \drive_file_created @on-stream-drive-file-created
+ @api \drive/stream do
+ type: 'image/*'
+ limit: 9images
+ .then (images) ~>
+ @initializing = false
+ @images = images
+ @update!
- @api \drive/stream do
- type: 'image/*'
- limit: 9images
- .then (images) ~>
- @initializing = false
- @images = images
- @update!
+ @on \unmount ~>
+ @stream.off \drive_file_created @on-stream-drive-file-created
- @on \unmount ~>
- @stream.off \drive_file_created @on-stream-drive-file-created
-
- @on-stream-drive-file-created = (file) ~>
- if /^image\/.+$/.test file.type
- @images.unshift file
- if @images.length > 9
- @images.pop!
- @update!
+ @on-stream-drive-file-created = (file) ~>
+ if /^image\/.+$/.test file.type
+ @images.unshift file
+ if @images.length > 9
+ @images.pop!
+ @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 ae8d43c645..24a0035c4c 100644
--- a/src/web/app/desktop/tags/home-widgets/profile.tag
+++ b/src/web/app/desktop/tags/home-widgets/profile.tag
@@ -1,55 +1,56 @@
-mk-profile-home-widget
- div.banner(style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' }, onclick={ set-banner })
- img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, onclick={ set-avatar }, alt='avatar', data-user-preview={ I.id })
- a.name(href={ CONFIG.url + '/' + I.username }) { I.name }
- p.username @{ I.username }
+<mk-profile-home-widget>
+ <div class="banner" style="{ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&amp;size=256)' : '' }" onclick="{ setBanner }"></div><img class="avatar" src="{ I.avatar_url + '?thumbnail&amp;size=64' }" onclick="{ setAvatar }" alt="avatar" data-user-preview="{ I.id }"/><a class="name" href="{ CONFIG.url + '/' + I.username }">{ I.name }</a>
+ <p class="username">@{ I.username }</p>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > .banner
+ height 100px
+ background-color #f5f5f5
+ background-size cover
+ background-position center
- > .banner
- height 100px
- background-color #f5f5f5
- background-size cover
- background-position center
+ > .avatar
+ display block
+ position absolute
+ top 76px
+ left 16px
+ width 58px
+ height 58px
+ margin 0
+ border solid 3px #fff
+ border-radius 8px
+ vertical-align bottom
- > .avatar
- display block
- position absolute
- top 76px
- left 16px
- width 58px
- height 58px
- margin 0
- border solid 3px #fff
- border-radius 8px
- vertical-align bottom
+ > .name
+ display block
+ margin 10px 0 0 92px
+ line-height 16px
+ font-weight bold
+ color #555
- > .name
- display block
- margin 10px 0 0 92px
- line-height 16px
- font-weight bold
- color #555
+ > .username
+ display block
+ margin 4px 0 8px 92px
+ line-height 16px
+ font-size 0.9em
+ color #999
- > .username
- display block
- margin 4px 0 8px 92px
- line-height 16px
- font-size 0.9em
- color #999
+ </style>
+ <script>
+ @mixin \i
+ @mixin \user-preview
+ @mixin \update-avatar
+ @mixin \update-banner
-script.
- @mixin \i
- @mixin \user-preview
- @mixin \update-avatar
- @mixin \update-banner
+ @set-avatar = ~>
+ @update-avatar @I, (i) ~>
+ @update-i i
- @set-avatar = ~>
- @update-avatar @I, (i) ~>
- @update-i i
-
- @set-banner = ~>
- @update-banner @I, (i) ~>
- @update-i i
+ @set-banner = ~>
+ @update-banner @I, (i) ~>
+ @update-i 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 b9095fb2d2..bfd9d32e52 100644
--- a/src/web/app/desktop/tags/home-widgets/rss-reader.tag
+++ b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
@@ -1,94 +1,94 @@
-mk-rss-reader-home-widget
- p.title
- i.fa.fa-rss-square
- | RSS
- button(onclick={ settings }, title='設定'): i.fa.fa-cog
- div.feed(if={ !initializing })
- virtual(each={ item in items })
- a(href={ item.link }, target='_blank') { item.title }
- p.initializing(if={ initializing })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
-
-style.
- display block
- background #fff
+<mk-rss-reader-home-widget>
+ <p class="title"><i class="fa fa-rss-square"></i>RSS</p>
+ <button onclick="{ settings }" title="設定"><i class="fa fa-cog"></i></button>
+ <div class="feed" if="{ !initializing }">
+ <virtual each="{ item in items }"><a href="{ item.link }" target="_blank">{ item.title }</a></virtual>
+ </div>
+ <p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
- > .title
- margin 0
- padding 0 16px
- line-height 42px
- font-size 0.9em
- font-weight bold
- color #888
- box-shadow 0 1px rgba(0, 0, 0, 0.07)
+ > .title
+ margin 0
+ padding 0 16px
+ line-height 42px
+ font-size 0.9em
+ font-weight bold
+ color #888
+ box-shadow 0 1px rgba(0, 0, 0, 0.07)
- > i
- margin-right 4px
+ > i
+ margin-right 4px
- > button
- position absolute
- top 0
- right 0
- padding 0
- width 42px
- font-size 0.9em
- line-height 42px
- color #ccc
+ > button
+ position absolute
+ top 0
+ right 0
+ padding 0
+ width 42px
+ font-size 0.9em
+ line-height 42px
+ color #ccc
- &:hover
- color #aaa
+ &:hover
+ color #aaa
- &:active
- color #999
+ &:active
+ color #999
- > .feed
- padding 12px 16px
- font-size 0.9em
+ > .feed
+ padding 12px 16px
+ font-size 0.9em
- > a
- display block
- padding 4px 0
- color #666
- border-bottom dashed 1px #eee
+ > a
+ display block
+ padding 4px 0
+ color #666
+ border-bottom dashed 1px #eee
- &:last-child
- border-bottom none
+ &:last-child
+ border-bottom none
- > .initializing
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > .initializing
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- > i
- margin-right 4px
+ > i
+ margin-right 4px
-script.
- @mixin \api
- @mixin \NotImplementedException
+ </style>
+ <script>
+ @mixin \api
+ @mixin \NotImplementedException
- @url = 'http://news.yahoo.co.jp/pickup/rss.xml'
- @items = []
- @initializing = true
+ @url = 'http://news.yahoo.co.jp/pickup/rss.xml'
+ @items = []
+ @initializing = true
- @on \mount ~>
- @fetch!
- @clock = set-interval @fetch, 60000ms
+ @on \mount ~>
+ @fetch!
+ @clock = set-interval @fetch, 60000ms
- @on \unmount ~>
- clear-interval @clock
+ @on \unmount ~>
+ clear-interval @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
+ @fetch = ~>
+ @api CONFIG.url + '/api:rss' do
+ url: @url
+ .then (feed) ~>
+ @items = feed.rss.channel.item
+ @initializing = false
+ @update!
+ .catch (err) ->
+ console.error err
- @settings = ~>
- @NotImplementedException!
+ @settings = ~>
+ @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 ea2746d1ed..2bd9d104da 100644
--- a/src/web/app/desktop/tags/home-widgets/timeline.tag
+++ b/src/web/app/desktop/tags/home-widgets/timeline.tag
@@ -1,113 +1,111 @@
-mk-timeline-home-widget
- mk-following-setuper(if={ no-following })
- div.loading(if={ is-loading })
- mk-ellipsis-icon
- p.empty(if={ is-empty })
- i.fa.fa-comments-o
- | 自分の投稿や、自分がフォローしているユーザーの投稿が表示されます。
- mk-timeline@timeline
- <yield to="footer">
- i.fa.fa-moon-o(if={ !parent.more-loading })
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
- </yield>
+<mk-timeline-home-widget>
+ <mk-following-setuper if="{ noFollowing }"></mk-following-setuper>
+ <div class="loading" if="{ isLoading }">
+ <mk-ellipsis-icon></mk-ellipsis-icon>
+ </div>
+ <p class="empty" if="{ isEmpty }"><i class="fa fa-comments-o"></i>自分の投稿や、自分がフォローしているユーザーの投稿が表示されます。</p>
+ <mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > mk-following-setuper
+ border-bottom solid 1px #eee
- > mk-following-setuper
- border-bottom solid 1px #eee
+ > .loading
+ padding 64px 0
- > .loading
- padding 64px 0
+ > .empty
+ display block
+ margin 0 auto
+ padding 32px
+ max-width 400px
+ text-align center
+ color #999
- > .empty
- display block
- margin 0 auto
- padding 32px
- max-width 400px
- text-align center
- color #999
+ > i
+ display block
+ margin-bottom 16px
+ font-size 3em
+ color #ccc
- > i
- display block
- margin-bottom 16px
- font-size 3em
- color #ccc
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
+ @mixin \stream
-script.
- @mixin \i
- @mixin \api
- @mixin \stream
+ @is-loading = true
+ @is-empty = false
+ @more-loading = false
+ @no-following = @I.following_count == 0
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @no-following = @I.following_count == 0
+ @on \mount ~>
+ @stream.on \post @on-stream-post
+ @stream.on \follow @on-stream-follow
+ @stream.on \unfollow @on-stream-unfollow
- @on \mount ~>
- @stream.on \post @on-stream-post
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ document.add-event-listener \keydown @on-document-keydown
+ window.add-event-listener \scroll @on-scroll
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ @load ~>
+ @trigger \loaded
- @load ~>
- @trigger \loaded
+ @on \unmount ~>
+ @stream.off \post @on-stream-post
+ @stream.off \follow @on-stream-follow
+ @stream.off \unfollow @on-stream-unfollow
- @on \unmount ~>
- @stream.off \post @on-stream-post
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ document.remove-event-listener \keydown @on-document-keydown
+ window.remove-event-listener \scroll @on-scroll
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ @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!
- @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!
+ @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!
- @load = (cb) ~>
- @api \posts/timeline
- .then (posts) ~>
- @is-loading = false
- @is-empty = posts.length == 0
+ @more = ~>
+ if @more-loading or @is-loading or @refs.timeline.posts.length == 0
+ return
+ @more-loading = true
@update!
- @refs.timeline.set-posts posts
- if cb? then cb!
- .catch (err) ~>
- console.error err
- if cb? then cb!
+ @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
- @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
+ @on-stream-post = (post) ~>
+ @is-empty = false
@update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
-
- @on-stream-post = (post) ~>
- @is-empty = false
- @update!
- @refs.timeline.add-post post
+ @refs.timeline.add-post post
- @on-stream-follow = ~>
- @load!
+ @on-stream-follow = ~>
+ @load!
- @on-stream-unfollow = ~>
- @load!
+ @on-stream-unfollow = ~>
+ @load!
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 8
- @more!
+ @on-scroll = ~>
+ current = window.scroll-y + window.inner-height
+ if current > document.body.offset-height - 8
+ @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 9c1aa33ec0..d85da0d295 100644
--- a/src/web/app/desktop/tags/home-widgets/tips.tag
+++ b/src/web/app/desktop/tags/home-widgets/tips.tag
@@ -1,70 +1,71 @@
-mk-tips-home-widget
- p@tip
- i.fa.fa-lightbulb-o
- span@text
+<mk-tips-home-widget>
+ <p ref="tip"><i class="fa fa-lightbulb-o"></i><span ref="text"></span></p>
+ <style type="stylus">
+ :scope
+ display block
+ background transparent !important
+ border none !important
+ overflow visible !important
-style.
- display block
- background transparent !important
- border none !important
- overflow visible !important
+ > p
+ display block
+ margin 0
+ padding 0 12px
+ text-align center
+ font-size 0.7em
+ color #999
- > p
- display block
- margin 0
- padding 0 12px
- text-align center
- font-size 0.7em
- color #999
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ kbd
+ display inline
+ padding 0 6px
+ margin 0 2px
+ font-size 1em
+ font-family inherit
+ border solid 1px #999
+ border-radius 2px
- kbd
- display inline
- padding 0 6px
- margin 0 2px
- font-size 1em
- font-family inherit
- border solid 1px #999
- border-radius 2px
+ </style>
+ <script>
+ @tips = [
+ '<kbd>t</kbd>でタイムラインにフォーカスできます'
+ '<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます'
+ '投稿フォームにはファイルをドラッグ&ドロップできます'
+ '投稿フォームにクリップボードにある画像データをペーストできます'
+ 'ドライブにファイルをドラッグ&ドロップしてアップロードできます'
+ 'ドライブでファイルをドラッグしてフォルダ移動できます'
+ 'ドライブでフォルダをドラッグしてフォルダ移動できます'
+ 'ホームをカスタマイズできます(準備中)'
+ 'MisskeyはMIT Licenseです'
+ ]
-script.
- @tips = [
- '<kbd>t</kbd>でタイムラインにフォーカスできます'
- '<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます'
- '投稿フォームにはファイルをドラッグ&ドロップできます'
- '投稿フォームにクリップボードにある画像データをペーストできます'
- 'ドライブにファイルをドラッグ&ドロップしてアップロードできます'
- 'ドライブでファイルをドラッグしてフォルダ移動できます'
- 'ドライブでフォルダをドラッグしてフォルダ移動できます'
- 'ホームをカスタマイズできます(準備中)'
- 'MisskeyはMIT Licenseです'
- ]
+ @on \mount ~>
+ @set!
+ @clock = set-interval @change, 20000ms
- @on \mount ~>
- @set!
- @clock = set-interval @change, 20000ms
+ @on \unmount ~>
+ clear-interval @clock
- @on \unmount ~>
- clear-interval @clock
+ @set = ~>
+ @refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
+ @update!
- @set = ~>
- @refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
- @update!
+ @change = ~>
+ Velocity @refs.tip, {
+ opacity: 0
+ } {
+ duration: 500ms
+ easing: \linear
+ complete: @set
+ }
- @change = ~>
- Velocity @refs.tip, {
- opacity: 0
- } {
- duration: 500ms
- easing: \linear
- complete: @set
- }
-
- Velocity @refs.tip, {
- opacity: 1
- } {
- duration: 500ms
- easing: \linear
- }
+ Velocity @refs.tip, {
+ opacity: 1
+ } {
+ duration: 500ms
+ 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 bfb90da065..bcf770ddab 100644
--- a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
+++ b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
@@ -1,154 +1,152 @@
-mk-user-recommendation-home-widget
- p.title
- i.fa.fa-users
- | おすすめユーザー
- button(onclick={ refresh }, title='他を見る'): i.fa.fa-refresh
- div.user(if={ !loading && users.length != 0 }, each={ _user in users })
- a.avatar-anchor(href={ CONFIG.url + '/' + _user.username })
- img.avatar(src={ _user.avatar_url + '?thumbnail&size=42' }, alt='', data-user-preview={ _user.id })
- div.body
- a.name(href={ CONFIG.url + '/' + _user.username }, data-user-preview={ _user.id }) { _user.name }
- p.username @{ _user.username }
- mk-follow-button(user={ _user })
- p.empty(if={ !loading && users.length == 0 })
- | いません!
- p.loading(if={ loading })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
+<mk-user-recommendation-home-widget>
+ <p class="title"><i class="fa fa-users"></i>おすすめユーザー</p>
+ <button onclick="{ refresh }" title="他を見る"><i class="fa fa-refresh"></i></button>
+ <div class="user" if="{ !loading &amp;&amp; users.length != 0 }" each="{ _user in users }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + _user.username }"><img class="avatar" src="{ _user.avatar_url + '?thumbnail&amp;size=42' }" alt="" data-user-preview="{ _user.id }"/></a>
+ <div class="body"><a class="name" href="{ CONFIG.url + '/' + _user.username }" data-user-preview="{ _user.id }">{ _user.name }</a>
+ <p class="username">@{ _user.username }</p>
+ </div>
+ <mk-follow-button user="{ _user }"></mk-follow-button>
+ </div>
+ <p class="empty" if="{ !loading &amp;&amp; users.length == 0 }">いません!</p>
+ <p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > .title
+ margin 0
+ padding 0 16px
+ line-height 42px
+ font-size 0.9em
+ font-weight bold
+ color #888
+ border-bottom solid 1px #eee
- > .title
- margin 0
- padding 0 16px
- line-height 42px
- font-size 0.9em
- font-weight bold
- color #888
- border-bottom solid 1px #eee
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ > button
+ position absolute
+ z-index 2
+ top 0
+ right 0
+ padding 0
+ width 42px
+ font-size 0.9em
+ line-height 42px
+ color #ccc
- > button
- position absolute
- z-index 2
- top 0
- right 0
- padding 0
- width 42px
- font-size 0.9em
- line-height 42px
- color #ccc
+ &:hover
+ color #aaa
- &:hover
- color #aaa
+ &:active
+ color #999
- &:active
- color #999
+ > .user
+ padding 16px
+ border-bottom solid 1px #eee
- > .user
- padding 16px
- border-bottom solid 1px #eee
+ &:last-child
+ border-bottom none
- &:last-child
- border-bottom none
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 12px 0 0
- > .avatar-anchor
- display block
- float left
- margin 0 12px 0 0
+ > .avatar
+ display block
+ width 42px
+ height 42px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- > .avatar
- display block
- width 42px
- height 42px
- margin 0
- border-radius 8px
- vertical-align bottom
+ > .body
+ float left
+ width calc(100% - 54px)
+
+ > .name
+ margin 0
+ font-size 16px
+ line-height 24px
+ color #555
- > .body
- float left
- width calc(100% - 54px)
+ > .username
+ display block
+ margin 0
+ font-size 15px
+ line-height 16px
+ color #ccc
- > .name
+ > mk-follow-button
+ position absolute
+ top 16px
+ right 16px
+
+ > .empty
margin 0
- font-size 16px
- line-height 24px
- color #555
+ padding 16px
+ text-align center
+ color #aaa
- > .username
- display block
+ > .loading
margin 0
- font-size 15px
- line-height 16px
- color #ccc
+ padding 16px
+ text-align center
+ color #aaa
- > mk-follow-button
- position absolute
- top 16px
- right 16px
+ > i
+ margin-right 4px
- > .empty
- margin 0
- padding 16px
- text-align center
- color #aaa
+ </style>
+ <script>
+ @mixin \api
+ @mixin \user-preview
- > .loading
- margin 0
- padding 16px
- text-align center
- color #aaa
+ @users = null
+ @loading = true
- > i
- margin-right 4px
+ @limit = 3users
+ @page = 0
-script.
- @mixin \api
- @mixin \user-preview
+ @on \mount ~>
+ @fetch!
+ @clock = set-interval ~>
+ if @users.length < @limit
+ @fetch true
+ , 60000ms
- @users = null
- @loading = true
+ @on \unmount ~>
+ clear-interval @clock
- @limit = 3users
- @page = 0
+ @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
- @on \mount ~>
- @fetch!
- @clock = set-interval ~>
+ @refresh = ~>
if @users.length < @limit
- @fetch true
- , 60000ms
-
- @on \unmount ~>
- clear-interval @clock
-
- @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!
+ @page = 0
+ else
+ @page++
+ @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 1ae856a6b2..6d4a308ac2 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -1,86 +1,91 @@
-mk-home
- div.main
- div.left@left
- main
- mk-timeline-home-widget@tl(if={ mode == 'timeline' })
- mk-mentions-home-widget@tl(if={ mode == 'mentions' })
- div.right@right
- mk-detect-slow-internet-connection-notice
+<mk-home>
+ <div class="main">
+ <div class="left" ref="left"></div>
+ <main>
+ <mk-timeline-home-widget ref="tl" if="{ mode == 'timeline' }"></mk-timeline-home-widget>
+ <mk-mentions-home-widget ref="tl" if="{ mode == 'mentions' }"></mk-mentions-home-widget>
+ </main>
+ <div class="right" ref="right"></div>
+ </div>
+ <mk-detect-slow-internet-connection-notice></mk-detect-slow-internet-connection-notice>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > .main
+ margin 0 auto
+ max-width 1200px
- > .main
- margin 0 auto
- max-width 1200px
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ > *
+ float left
- > *
- float left
+ > *
+ display block
+ //border solid 1px #eaeaea
+ border solid 1px rgba(0, 0, 0, 0.075)
+ border-radius 6px
+ overflow hidden
- > *
- display block
- //border solid 1px #eaeaea
- border solid 1px rgba(0, 0, 0, 0.075)
- border-radius 6px
- overflow hidden
+ &:not(:last-child)
+ margin-bottom 16px
- &:not(:last-child)
- margin-bottom 16px
+ > main
+ padding 16px
+ width calc(100% - 275px * 2)
- > main
- padding 16px
- width calc(100% - 275px * 2)
+ > *:not(main)
+ width 275px
- > *:not(main)
- width 275px
+ > .left
+ padding 16px 0 16px 16px
- > .left
- padding 16px 0 16px 16px
+ > .right
+ padding 16px 16px 16px 0
- > .right
- padding 16px 16px 16px 0
+ @media (max-width 1100px)
+ > *:not(main)
+ display none
- @media (max-width 1100px)
- > *:not(main)
- display none
-
- > main
- float none
- width 100%
- max-width 700px
- margin 0 auto
+ > main
+ float none
+ width 100%
+ max-width 700px
+ margin 0 auto
-script.
- @mixin \i
- @mode = @opts.mode || \timeline
+ </style>
+ <script>
+ @mixin \i
+ @mode = @opts.mode || \timeline
- # https://github.com/riot/riot/issues/2080
- if @mode == '' then @mode = \timeline
+ # https://github.com/riot/riot/issues/2080
+ if @mode == '' then @mode = \timeline
- @home = []
+ @home = []
- @on \mount ~>
- @refs.tl.on \loaded ~>
- @trigger \loaded
+ @on \mount ~>
+ @refs.tl.on \loaded ~>
+ @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
- data: widget.data
- .0)
- catch e
- # noop
+ @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
+ data: widget.data
+ .0)
+ catch e
+ # noop
- @on \unmount ~>
- @home.for-each (widget) ~>
- widget.unmount!
+ @on \unmount ~>
+ @home.for-each (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 6a3885d7c7..41ec876621 100644
--- a/src/web/app/desktop/tags/image-dialog.tag
+++ b/src/web/app/desktop/tags/image-dialog.tag
@@ -1,73 +1,75 @@
-mk-image-dialog
- div.bg@bg(onclick={ close })
- img@img(src={ image.url }, alt={ image.name }, title={ image.name }, onclick={ close })
+<mk-image-dialog>
+ <div class="bg" ref="bg" onclick="{ close }"></div><img ref="img" src="{ image.url }" alt="{ image.name }" title="{ image.name }" onclick="{ close }"/>
+ <style type="stylus">
+ :scope
+ display block
+ position fixed
+ z-index 2048
+ top 0
+ left 0
+ width 100%
+ height 100%
+ opacity 0
-style.
- display block
- position fixed
- z-index 2048
- top 0
- left 0
- width 100%
- height 100%
- opacity 0
+ > .bg
+ display block
+ position fixed
+ z-index 1
+ top 0
+ left 0
+ width 100%
+ height 100%
+ background rgba(0, 0, 0, 0.7)
- > .bg
- display block
- position fixed
- z-index 1
- top 0
- left 0
- width 100%
- height 100%
- background rgba(0, 0, 0, 0.7)
+ > img
+ position fixed
+ z-index 2
+ top 0
+ right 0
+ bottom 0
+ left 0
+ max-width 100%
+ max-height 100%
+ margin auto
+ cursor zoom-out
- > img
- position fixed
- z-index 2
- top 0
- right 0
- bottom 0
- left 0
- max-width 100%
- max-height 100%
- margin auto
- cursor zoom-out
+ </style>
+ <script>
+ @image = @opts.image
-script.
- @image = @opts.image
+ @on \mount ~>
+ Velocity @root, {
+ opacity: 1
+ } {
+ duration: 100ms
+ easing: \linear
+ }
- @on \mount ~>
- Velocity @root, {
- opacity: 1
- } {
- duration: 100ms
- easing: \linear
- }
+ #Velocity @img, {
+ # scale: 1
+ # opacity: 1
+ #} {
+ # duration: 200ms
+ # easing: \ease-out
+ #}
- #Velocity @img, {
- # scale: 1
- # opacity: 1
- #} {
- # duration: 200ms
- # easing: \ease-out
- #}
+ @close = ~>
+ Velocity @root, {
+ opacity: 0
+ } {
+ duration: 100ms
+ easing: \linear
+ complete: ~> @unmount!
+ }
- @close = ~>
- Velocity @root, {
- opacity: 0
- } {
- duration: 100ms
- easing: \linear
- complete: ~> @unmount!
- }
-
- #Velocity @img, {
- # scale: 0.9
- # opacity: 0
- #} {
- # duration: 200ms
- # easing: \ease-in
- # complete: ~>
- # @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 a9939d67c4..c08c8d6926 100644
--- a/src/web/app/desktop/tags/images-viewer.tag
+++ b/src/web/app/desktop/tags/images-viewer.tag
@@ -1,43 +1,45 @@
-mk-images-viewer
- div.image@view(onmousemove={ mousemove }, style={ 'background-image: url(' + image.url + '?thumbnail' }, onclick={ click })
- img(src={ image.url + '?thumbnail&size=512' }, alt={ image.name }, title={ image.name })
-
-style.
- display block
- padding 8px
- overflow hidden
- box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
- border-radius 4px
+<mk-images-viewer>
+ <div class="image" ref="view" onmousemove="{ mousemove }" style="{ 'background-image: url(' + image.url + '?thumbnail' }" onclick="{ click }"><img src="{ image.url + '?thumbnail&amp;size=512' }" alt="{ image.name }" title="{ image.name }"/></div>
+ <style type="stylus">
+ :scope
+ display block
+ padding 8px
+ overflow hidden
+ box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
+ border-radius 4px
- > .image
- cursor zoom-in
+ > .image
+ cursor zoom-in
- > img
- display block
- max-height 256px
- max-width 100%
- margin 0 auto
+ > img
+ display block
+ max-height 256px
+ max-width 100%
+ margin 0 auto
- &:hover
- > img
- visibility hidden
+ &:hover
+ > img
+ visibility hidden
- &:not(:hover)
- background-image none !important
+ &:not(:hover)
+ background-image none !important
-script.
- @images = @opts.images
- @image = @images.0
+ </style>
+ <script>
+ @images = @opts.images
+ @image = @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 + '%'
+ @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 + '%'
- @click = ~>
- dialog = document.body.append-child document.create-element \mk-image-dialog
- riot.mount dialog, do
- image: @image
+ @click = ~>
+ dialog = document.body.append-child document.create-element \mk-image-dialog
+ riot.mount dialog, do
+ image: @image
+ </script>
+</mk-images-viewer>
diff --git a/src/web/app/desktop/tags/input-dialog.tag b/src/web/app/desktop/tags/input-dialog.tag
index 62ec4f5177..a71ee58623 100644
--- a/src/web/app/desktop/tags/input-dialog.tag
+++ b/src/web/app/desktop/tags/input-dialog.tag
@@ -1,156 +1,157 @@
-mk-input-dialog
- mk-window@window(is-modal={ true }, width={ '500px' })
- <yield to="header">
- i.fa.fa-i-cursor
- | { parent.title }
- </yield>
- <yield to="content">
- div.body
- input@text(oninput={ parent.update }, onkeydown={ parent.on-keydown }, placeholder={ parent.placeholder })
- div.action
- button.cancel(onclick={ parent.cancel }) キャンセル
- button.ok(disabled={ !parent.allow-empty && refs.text.value.length == 0 }, onclick={ parent.ok }) 決定
- </yield>
+<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 &amp;&amp; refs.text.value.length == 0 }" onclick="{ parent.ok }">決定</button>
+ </div></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
+ > .body
+ padding 16px
- [data-yield='content']
- > .body
- padding 16px
+ > input
+ display block
+ padding 8px
+ margin 0
+ width 100%
+ max-width 100%
+ min-width 100%
+ font-size 1em
+ color #333
+ background #fff
+ outline none
+ border solid 1px rgba($theme-color, 0.1)
+ border-radius 4px
+ transition border-color .3s ease
- > input
- display block
- padding 8px
- margin 0
- width 100%
- max-width 100%
- min-width 100%
- font-size 1em
- color #333
- background #fff
- outline none
- border solid 1px rgba($theme-color, 0.1)
- border-radius 4px
- transition border-color .3s ease
+ &:hover
+ border-color rgba($theme-color, 0.2)
+ transition border-color .1s ease
- &:hover
- border-color rgba($theme-color, 0.2)
- transition border-color .1s ease
+ &:focus
+ color $theme-color
+ border-color rgba($theme-color, 0.5)
+ transition border-color 0s ease
- &:focus
- color $theme-color
- border-color rgba($theme-color, 0.5)
- transition border-color 0s ease
+ &::-webkit-input-placeholder
+ color rgba($theme-color, 0.3)
- &::-webkit-input-placeholder
- color rgba($theme-color, 0.3)
+ > .action
+ height 72px
+ background lighten($theme-color, 95%)
- > .action
- height 72px
- background lighten($theme-color, 95%)
-
- .ok
- .cancel
- display block
- position absolute
- bottom 16px
- cursor pointer
- padding 0
- margin 0
- width 120px
- height 40px
- font-size 1em
- outline none
- border-radius 4px
-
- &:focus
- &:after
- content ""
- pointer-events none
+ .ok
+ .cancel
+ display block
position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ bottom 16px
+ cursor pointer
+ padding 0
+ margin 0
+ width 120px
+ height 40px
+ font-size 1em
+ outline none
+ border-radius 4px
- &:disabled
- opacity 0.7
- cursor default
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- .ok
- right 16px
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- border solid 1px lighten($theme-color, 15%)
+ &:disabled
+ opacity 0.7
+ cursor default
- &:not(:disabled)
- font-weight bold
+ .ok
+ right 16px
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
- &:hover:not(:disabled)
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:not(:disabled)
+ font-weight bold
- &:active:not(:disabled)
- background $theme-color
- border-color $theme-color
+ &:hover:not(:disabled)
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- .cancel
- right 148px
- color #888
- background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
- border solid 1px #e2e2e2
+ &:active:not(:disabled)
+ background $theme-color
+ border-color $theme-color
- &:hover
- background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
- border-color #dcdcdc
+ .cancel
+ right 148px
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
- &:active
- background #ececec
- border-color #dcdcdc
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
-script.
- @done = false
+ &:active
+ background #ececec
+ border-color #dcdcdc
- @title = @opts.title
- @placeholder = @opts.placeholder
- @default = @opts.default
- @allow-empty = if @opts.allow-empty? then @opts.allow-empty else true
+ </style>
+ <script>
+ @done = false
- @on \mount ~>
- @text = @refs.window.refs.text
- if @default?
- @text.value = @default
- @text.focus!
+ @title = @opts.title
+ @placeholder = @opts.placeholder
+ @default = @opts.default
+ @allow-empty = if @opts.allow-empty? then @opts.allow-empty else true
- @refs.window.on \closing ~>
- if @done
- @opts.on-ok @text.value
- else
- if @opts.on-cancel?
- @opts.on-cancel!
+ @on \mount ~>
+ @text = @refs.window.refs.text
+ if @default?
+ @text.value = @default
+ @text.focus!
- @refs.window.on \closed ~>
- @unmount!
+ @refs.window.on \closing ~>
+ if @done
+ @opts.on-ok @text.value
+ else
+ if @opts.on-cancel?
+ @opts.on-cancel!
- @cancel = ~>
- @done = false
- @refs.window.close!
+ @refs.window.on \closed ~>
+ @unmount!
+
+ @cancel = ~>
+ @done = false
+ @refs.window.close!
- @ok = ~>
- if not @allow-empty and @text.value == '' then return
- @done = true
- @refs.window.close!
+ @ok = ~>
+ if not @allow-empty and @text.value == '' then return
+ @done = true
+ @refs.window.close!
- @on-keydown = (e) ~>
- if e.which == 13 # Enter
- e.prevent-default!
- e.stop-propagation!
- @ok!
+ @on-keydown = (e) ~>
+ if e.which == 13 # Enter
+ e.prevent-default!
+ e.stop-propagation!
+ @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 1058de22e0..ecf1e04d2e 100644
--- a/src/web/app/desktop/tags/list-user.tag
+++ b/src/web/app/desktop/tags/list-user.tag
@@ -1,100 +1,98 @@
-mk-list-user
- a.avatar-anchor(href={ CONFIG.url + '/' + user.username })
- img.avatar(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.main
- header
- div.left
- a.name(href={ CONFIG.url + '/' + user.username })
- | { user.name }
- span.username
- | @{ user.username }
- div.body
- p.followed(if={ user.is_followed }) フォローされています
- div.bio { user.bio }
- mk-follow-button(user={ user })
-
-style.
- display block
- margin 0
- padding 16px
- font-size 16px
-
- &:after
- content ""
- display block
- clear both
-
- > .avatar-anchor
- display block
- float left
- margin 0 16px 0 0
-
- > .avatar
+<mk-list-user><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="main">
+ <header>
+ <div class="left"><a class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</a><span class="username">@{ user.username }</span></div>
+ </header>
+ <div class="body">
+ <p class="followed" if="{ user.is_followed }">フォローされています</p>
+ <div class="bio">{ user.bio }</div>
+ </div>
+ </div>
+ <mk-follow-button user="{ user }"></mk-follow-button>
+ <style type="stylus">
+ :scope
display block
- width 58px
- height 58px
margin 0
- border-radius 8px
- vertical-align bottom
-
- > .main
- float left
- width calc(100% - 74px)
-
- > header
- margin-bottom 2px
- white-space nowrap
+ padding 16px
+ font-size 16px
&:after
content ""
display block
clear both
- > .left
+ > .avatar-anchor
+ display block
float left
+ margin 0 16px 0 0
- > .name
- display inline
+ > .avatar
+ display block
+ width 58px
+ height 58px
margin 0
- padding 0
- color #777
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ border-radius 8px
+ vertical-align bottom
- &:hover
- text-decoration underline
+ > .main
+ float left
+ width calc(100% - 74px)
- > .username
- text-align left
- margin 0 0 0 8px
- color #ccc
+ > header
+ margin-bottom 2px
+ white-space nowrap
- > .body
- > .followed
- display inline-block
- margin 0 0 4px 0
- padding 2px 8px
- vertical-align top
- font-size 10px
- color #71afc7
- background #eefaff
- border-radius 4px
+ &:after
+ content ""
+ display block
+ clear both
- > .bio
- cursor default
- display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 1.1em
- color #717171
+ > .left
+ float left
+
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #777
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
+
+ &:hover
+ text-decoration underline
+
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #ccc
+
+ > .body
+ > .followed
+ display inline-block
+ margin 0 0 4px 0
+ padding 2px 8px
+ vertical-align top
+ font-size 10px
+ color #71afc7
+ background #eefaff
+ border-radius 4px
+
+ > .bio
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 1.1em
+ color #717171
- > mk-follow-button
- position absolute
- top 16px
- right 16px
+ > mk-follow-button
+ position absolute
+ top 16px
+ right 16px
-script.
- @user = @opts.user
+ </style>
+ <script>@user = @opts.user</script>
+</mk-list-user>
diff --git a/src/web/app/desktop/tags/messaging/form.tag b/src/web/app/desktop/tags/messaging/form.tag
index 12eb0cb40f..b521eb2fd3 100644
--- a/src/web/app/desktop/tags/messaging/form.tag
+++ b/src/web/app/desktop/tags/messaging/form.tag
@@ -1,162 +1,161 @@
-mk-messaging-form
- textarea@text(onkeypress={ onkeypress }, onpaste={ onpaste }, placeholder='ここにメッセージを入力')
- div.files
- mk-uploader@uploader
- button.send(onclick={ send }, disabled={ sending }, title='メッセージを送信')
- i.fa.fa-paper-plane(if={ !sending })
- i.fa.fa-spinner.fa-spin(if={ sending })
- button.attach-from-local(type='button', title='PCから画像を添付する')
- i.fa.fa-upload
- button.attach-from-drive(type='button', title='アルバムから画像を添付する')
- i.fa.fa-folder-open
- input(name='file', type='file', accept='image/*')
+<mk-messaging-form>
+ <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>
+ <input name="file" type="file" accept="image/*"/>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > textarea
+ cursor auto
+ display block
+ width 100%
+ min-width 100%
+ max-width 100%
+ height 64px
+ margin 0
+ padding 8px
+ font-size 1em
+ color #000
+ outline none
+ border none
+ border-top solid 1px #eee
+ border-radius 0
+ box-shadow none
+ background transparent
- > textarea
- cursor auto
- display block
- width 100%
- min-width 100%
- max-width 100%
- height 64px
- margin 0
- padding 8px
- font-size 1em
- color #000
- outline none
- border none
- border-top solid 1px #eee
- border-radius 0
- box-shadow none
- background transparent
+ > .send
+ position absolute
+ bottom 0
+ right 0
+ margin 0
+ padding 10px 14px
+ line-height 1em
+ font-size 1em
+ color #aaa
+ transition color 0.1s ease
- > .send
- position absolute
- bottom 0
- right 0
- margin 0
- padding 10px 14px
- line-height 1em
- font-size 1em
- color #aaa
- transition color 0.1s ease
+ &:hover
+ color $theme-color
- &:hover
- color $theme-color
+ &:active
+ color darken($theme-color, 10%)
+ transition color 0s ease
- &:active
- color darken($theme-color, 10%)
- transition color 0s ease
+ .files
+ display block
+ margin 0
+ padding 0 8px
+ list-style none
- .files
- display block
- margin 0
- padding 0 8px
- list-style none
+ &:after
+ content ''
+ display block
+ clear both
- &:after
- content ''
- display block
- clear both
+ > li
+ display block
+ float left
+ margin 4px
+ padding 0
+ width 64px
+ height 64px
+ background-color #eee
+ background-repeat no-repeat
+ background-position center center
+ background-size cover
+ cursor move
- > li
- display block
- float left
- margin 4px
- padding 0
- width 64px
- height 64px
- background-color #eee
- background-repeat no-repeat
- background-position center center
- background-size cover
- cursor move
+ &:hover
+ > .remove
+ display block
- &:hover
- > .remove
- display block
+ > .remove
+ display none
+ position absolute
+ right -6px
+ top -6px
+ margin 0
+ padding 0
+ background transparent
+ outline none
+ border none
+ border-radius 0
+ box-shadow none
+ cursor pointer
- > .remove
- display none
- position absolute
- right -6px
- top -6px
+ .attach-from-local
+ .attach-from-drive
margin 0
- padding 0
- background transparent
- outline none
- border none
- border-radius 0
- box-shadow none
- cursor pointer
+ padding 10px 14px
+ line-height 1em
+ font-size 1em
+ font-weight normal
+ text-decoration none
+ color #aaa
+ transition color 0.1s ease
- .attach-from-local
- .attach-from-drive
- margin 0
- padding 10px 14px
- line-height 1em
- font-size 1em
- font-weight normal
- text-decoration none
- color #aaa
- transition color 0.1s ease
+ &:hover
+ color $theme-color
- &:hover
- color $theme-color
+ &:active
+ color darken($theme-color, 10%)
+ transition color 0s ease
- &:active
- color darken($theme-color, 10%)
- transition color 0s ease
+ input[type=file]
+ display none
- input[type=file]
- display none
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @user = @opts.user
- @user = @opts.user
+ @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!
- @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!
+ @onkeypress = (e) ~>
+ if (e.which == 10 || e.which == 13) && e.ctrl-key
+ @send!
- @onkeypress = (e) ~>
- if (e.which == 10 || e.which == 13) && e.ctrl-key
- @send!
+ @select-file = ~>
+ @refs.file.click!
- @select-file = ~>
- @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
+ event: event
+ event.one \selected (files) ~>
+ files.for-each @add-file
- @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
- event: event
- event.one \selected (files) ~>
- files.for-each @add-file
+ @send = ~>
+ @sending = true
+ @api \messaging/messages/create do
+ user_id: @user.id
+ text: @refs.text.value
+ .then (message) ~>
+ @clear!
+ .catch (err) ~>
+ console.error err
+ .then ~>
+ @sending = false
+ @update!
- @send = ~>
- @sending = true
- @api \messaging/messages/create do
- user_id: @user.id
- text: @refs.text.value
- .then (message) ~>
- @clear!
- .catch (err) ~>
- console.error err
- .then ~>
- @sending = false
+ @clear = ~>
+ @refs.text.value = ''
+ @files = []
@update!
-
- @clear = ~>
- @refs.text.value = ''
- @files = []
- @update!
+ </script>
+</mk-messaging-form>
diff --git a/src/web/app/desktop/tags/messaging/index.tag b/src/web/app/desktop/tags/messaging/index.tag
index 9f57500b83..eeb92fc3f0 100644
--- a/src/web/app/desktop/tags/messaging/index.tag
+++ b/src/web/app/desktop/tags/messaging/index.tag
@@ -1,302 +1,301 @@
-mk-messaging
- div.search
- div.form
- label(for='search-input')
- i.fa.fa-search
- input@search-input(type='search', oninput={ search }, placeholder='ユーザーを探す')
- div.result
- ol.users(if={ search-result.length > 0 })
- li(each={ user in search-result })
- a(onclick={ user._click })
- img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='')
- span.name { user.name }
- span.username @{ user.username }
- div.main
- div.history(if={ history.length > 0 })
- virtual(each={ history })
- a.user(data-is-me={ is_me }, data-is-read={ is_read }, onclick={ _click }): div
- img.avatar(src={ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' }, alt='')
- header
- span.name { is_me ? recipient.name : user.name }
- span.username { '@' + (is_me ? recipient.username : user.username ) }
- mk-time(time={ created_at })
- div.body
- p.text
- span.me(if={ is_me }) あなた:
- | { text }
- p.no-history(if={ history.length == 0 })
- | 履歴はありません。
- br
- | ユーザーを検索して、いつでもメッセージを送受信できます。
-
-style.
- display block
-
- > .search
- display block
- position absolute
- top 0
- left 0
- z-index 1
- width 100%
- background #fff
- box-shadow 0 0px 2px rgba(0, 0, 0, 0.2)
-
- > .form
- padding 8px
- background #f7f7f7
+<mk-messaging>
+ <div class="search">
+ <div class="form">
+ <label for="search-input"><i class="fa fa-search"></i></label>
+ <input ref="searchInput" type="search" oninput="{ search }" placeholder="ユーザーを探す"/>
+ </div>
+ <div class="result">
+ <ol class="users" if="{ searchResult.length &gt; 0 }">
+ <li each="{ user in searchResult }"><a onclick="{ user._click }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&amp;size=32' }" alt=""/><span class="name">{ user.name }</span><span class="username">@{ user.username }</span></a></li>
+ </ol>
+ </div>
+ </div>
+ <div class="main">
+ <div class="history" if="{ history.length &gt; 0 }">
+ <virtual each="{ history }"><a class="user" data-is-me="{ is_me }" data-is-read="{ is_read }" onclick="{ _click }">
+ <div><img class="avatar" src="{ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&amp;size=64' }" alt=""/>
+ <header><span class="name">{ is_me ? recipient.name : user.name }</span><span class="username">{ '@' + (is_me ? recipient.username : user.username ) }</span>
+ <mk-time time="{ created_at }"></mk-time>
+ </header>
+ <div class="body">
+ <p class="text"><span class="me" if="{ is_me }">あなた:</span>{ text }</p>
+ </div>
+ </div></a></virtual>
+ </div>
+ <p class="no-history" if="{ history.length == 0 }">履歴はありません。<br/>ユーザーを検索して、いつでもメッセージを送受信できます。</p>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
- > label
+ > .search
display block
position absolute
top 0
- left 8px
+ left 0
z-index 1
- height 100%
- width 38px
- pointer-events none
-
- > i
- display block
- position absolute
- top 0
- right 0
- bottom 0
- left 0
- width 1em
- height 1em
- margin auto
- color #555
-
- > input
- margin 0
- padding 0 12px 0 38px
width 100%
- font-size 1em
- line-height 38px
- color #000
- outline none
- border solid 1px #eee
- border-radius 5px
- box-shadow none
- transition color 0.5s ease, border 0.5s ease
-
- &:hover
- border solid 1px #ddd
- transition border 0.2s ease
+ background #fff
+ box-shadow 0 0px 2px rgba(0, 0, 0, 0.2)
- &:focus
- color darken($theme-color, 20%)
- border solid 1px $theme-color
- transition color 0, border 0
+ > .form
+ padding 8px
+ background #f7f7f7
- > .result
- display block
- top 0
- left 0
- z-index 2
- width 100%
- margin 0
- padding 0
- background #fff
+ > label
+ display block
+ position absolute
+ top 0
+ left 8px
+ z-index 1
+ height 100%
+ width 38px
+ pointer-events none
- > .users
- margin 0
- padding 0
- list-style none
+ > i
+ display block
+ position absolute
+ top 0
+ right 0
+ bottom 0
+ left 0
+ width 1em
+ height 1em
+ margin auto
+ color #555
- > li
- > a
- display inline-block
- z-index 1
+ > input
+ margin 0
+ padding 0 12px 0 38px
width 100%
- padding 8px 32px
- vertical-align top
- white-space nowrap
- overflow hidden
- color rgba(0, 0, 0, 0.8)
- text-decoration none
- transition none
+ font-size 1em
+ line-height 38px
+ color #000
+ outline none
+ border solid 1px #eee
+ border-radius 5px
+ box-shadow none
+ transition color 0.5s ease, border 0.5s ease
&:hover
- color #fff
- background $theme-color
+ border solid 1px #ddd
+ transition border 0.2s ease
+
+ &:focus
+ color darken($theme-color, 20%)
+ border solid 1px $theme-color
+ transition color 0, border 0
- .name
- color #fff
+ > .result
+ display block
+ top 0
+ left 0
+ z-index 2
+ width 100%
+ margin 0
+ padding 0
+ background #fff
- .username
- color #fff
+ > .users
+ margin 0
+ padding 0
+ list-style none
- &:active
- color #fff
- background darken($theme-color, 10%)
+ > li
+ > a
+ display inline-block
+ z-index 1
+ width 100%
+ padding 8px 32px
+ vertical-align top
+ white-space nowrap
+ overflow hidden
+ color rgba(0, 0, 0, 0.8)
+ text-decoration none
+ transition none
- .name
- color #fff
+ &:hover
+ color #fff
+ background $theme-color
- .username
- color #fff
+ .name
+ color #fff
- .avatar
- vertical-align middle
- min-width 32px
- min-height 32px
- max-width 32px
- max-height 32px
- margin 0 8px 0 0
- border-radius 6px
+ .username
+ color #fff
- .name
- margin 0 8px 0 0
- /*font-weight bold*/
- font-weight normal
- color rgba(0, 0, 0, 0.8)
+ &:active
+ color #fff
+ background darken($theme-color, 10%)
- .username
- font-weight normal
- color rgba(0, 0, 0, 0.3)
+ .name
+ color #fff
- > .main
- padding-top 56px
+ .username
+ color #fff
- > .history
+ .avatar
+ vertical-align middle
+ min-width 32px
+ min-height 32px
+ max-width 32px
+ max-height 32px
+ margin 0 8px 0 0
+ border-radius 6px
- > a
- display block
- padding 20px 30px
- text-decoration none
- background #fff
- border-bottom solid 1px #eee
+ .name
+ margin 0 8px 0 0
+ /*font-weight bold*/
+ font-weight normal
+ color rgba(0, 0, 0, 0.8)
- *
- pointer-events none
- user-select none
+ .username
+ font-weight normal
+ color rgba(0, 0, 0, 0.3)
- &:hover
- background #fafafa
+ > .main
+ padding-top 56px
- > .avatar
- filter saturate(200%)
+ > .history
- &:active
- background #eee
+ > a
+ display block
+ padding 20px 30px
+ text-decoration none
+ background #fff
+ border-bottom solid 1px #eee
- &[data-is-read]
- &[data-is-me]
- opacity 0.8
+ *
+ pointer-events none
+ user-select none
- &:not([data-is-me]):not([data-is-read])
- background-image url("/_/resources/desktop/unread.svg")
- background-repeat no-repeat
- background-position 0 center
+ &:hover
+ background #fafafa
- &:after
- content ""
- display block
- clear both
+ > .avatar
+ filter saturate(200%)
- > div
- max-width 500px
- margin 0 auto
+ &:active
+ background #eee
- > header
- margin-bottom 2px
- white-space nowrap
- overflow hidden
+ &[data-is-read]
+ &[data-is-me]
+ opacity 0.8
- > .name
- text-align left
- display inline
- margin 0
- padding 0
- font-size 1em
- color rgba(0, 0, 0, 0.9)
- font-weight bold
- transition all 0.1s ease
+ &:not([data-is-me]):not([data-is-read])
+ background-image url("/_/resources/desktop/unread.svg")
+ background-repeat no-repeat
+ background-position 0 center
- > .username
- text-align left
- margin 0 0 0 8px
- color rgba(0, 0, 0, 0.5)
+ &:after
+ content ""
+ display block
+ clear both
- > mk-time
- position absolute
- top 0
- right 0
- display inline
- color rgba(0, 0, 0, 0.5)
- font-size small
+ > div
+ max-width 500px
+ margin 0 auto
- > .avatar
- float left
- width 54px
- height 54px
- margin 0 16px 0 0
- border-radius 8px
- transition all 0.1s ease
+ > header
+ margin-bottom 2px
+ white-space nowrap
+ overflow hidden
- > .body
+ > .name
+ text-align left
+ display inline
+ margin 0
+ padding 0
+ font-size 1em
+ color rgba(0, 0, 0, 0.9)
+ font-weight bold
+ transition all 0.1s ease
- > .text
- display block
- margin 0 0 0 0
- padding 0
- overflow hidden
- word-wrap break-word
- font-size 1.1em
- color rgba(0, 0, 0, 0.8)
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color rgba(0, 0, 0, 0.5)
- .me
- color rgba(0, 0, 0, 0.4)
+ > mk-time
+ position absolute
+ top 0
+ right 0
+ display inline
+ color rgba(0, 0, 0, 0.5)
+ font-size small
- > .image
- display block
- max-width 100%
- max-height 512px
+ > .avatar
+ float left
+ width 54px
+ height 54px
+ margin 0 16px 0 0
+ border-radius 8px
+ transition all 0.1s ease
+
+ > .body
+
+ > .text
+ display block
+ margin 0 0 0 0
+ padding 0
+ overflow hidden
+ word-wrap break-word
+ font-size 1.1em
+ color rgba(0, 0, 0, 0.8)
- > .no-history
- margin 0
- padding 2em 1em
- text-align center
- color #999
- font-weight 500
+ .me
+ color rgba(0, 0, 0, 0.4)
-script.
- @mixin \i
- @mixin \api
+ > .image
+ display block
+ max-width 100%
+ max-height 512px
- @search-result = []
+ > .no-history
+ margin 0
+ padding 2em 1em
+ text-align center
+ color #999
+ font-weight 500
- @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
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
- @search = ~>
- q = @refs.search-input.value
- if q == ''
- @search-result = []
- else
- @api \users/search do
- query: q
- .then (users) ~>
- users.for-each (user) ~>
- user._click = ~>
- @trigger \navigate-user user
- @search-result = []
- @search-result = users
+ @search-result = []
+
+ @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
+
+ @search = ~>
+ q = @refs.search-input.value
+ if q == ''
+ @search-result = []
+ else
+ @api \users/search do
+ query: q
+ .then (users) ~>
+ users.for-each (user) ~>
+ user._click = ~>
+ @trigger \navigate-user user
+ @search-result = []
+ @search-result = users
+ @update!
+ .catch (err) ~>
+ console.error err
+ </script>
+</mk-messaging>
diff --git a/src/web/app/desktop/tags/messaging/message.tag b/src/web/app/desktop/tags/messaging/message.tag
index d7a2cc32a6..517689d132 100644
--- a/src/web/app/desktop/tags/messaging/message.tag
+++ b/src/web/app/desktop/tags/messaging/message.tag
@@ -1,227 +1,230 @@
-mk-messaging-message(data-is-me={ message.is_me })
- a.avatar-anchor(href={ CONFIG.url + '/' + message.user.username }, title={ message.user.username }, target='_blank')
- img.avatar(src={ message.user.avatar_url + '?thumbnail&size=64' }, alt='')
- div.content-container
- div.balloon
- p.read(if={ message.is_me && message.is_read }) 既読
- button.delete-button(if={ message.is_me }, title='メッセージを削除')
- img(src='/_/resources/desktop/messaging/delete.png', alt='Delete')
- div.content(if={ !message.is_deleted })
- div@text
- div.image(if={ message.file })
- img(src={ message.file.url }, alt='image', title={ message.file.name })
- div.content(if={ message.is_deleted })
- p.is-deleted このメッセージは削除されました
- footer
- mk-time(time={ message.created_at })
- i.fa.fa-pencil.is-edited(if={ message.is_edited })
+<mk-messaging-message data-is-me="{ message.is_me }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + message.user.username }" title="{ message.user.username }" target="_blank"><img class="avatar" src="{ message.user.avatar_url + '?thumbnail&amp;size=64' }" alt=""/></a>
+ <div class="content-container">
+ <div class="balloon">
+ <p class="read" if="{ message.is_me &amp;&amp; message.is_read }">既読</p>
+ <button class="delete-button" if="{ message.is_me }" title="メッセージを削除"><img src="/_/resources/desktop/messaging/delete.png" alt="Delete"/></button>
+ <div class="content" if="{ !message.is_deleted }">
+ <div ref="text"></div>
+ <div class="image" if="{ message.file }"><img src="{ message.file.url }" alt="image" title="{ message.file.name }"/></div>
+ </div>
+ <div class="content" if="{ message.is_deleted }">
+ <p class="is-deleted">このメッセージは削除されました</p>
+ </div>
+ </div>
+ <footer>
+ <mk-time time="{ message.created_at }"></mk-time><i class="fa fa-pencil is-edited" if="{ message.is_edited }"></i>
+ </footer>
+ </div>
+ <style type="stylus">
+ :scope
+ $me-balloon-color = #23A7B6
-style.
- $me-balloon-color = #23A7B6
-
- display block
- padding 10px 12px 10px 12px
- background-color transparent
-
- &:after
- content ""
- display block
- clear both
-
- > .avatar-anchor
- display block
-
- > .avatar
display block
- min-width 54px
- min-height 54px
- max-width 54px
- max-height 54px
- margin 0
- border-radius 8px
- transition all 0.1s ease
+ padding 10px 12px 10px 12px
+ background-color transparent
- > .content-container
- display block
- margin 0 12px
- padding 0
- max-width calc(100% - 78px)
-
- > .balloon
- display block
- float inherit
- margin 0
- padding 0
- max-width 100%
- min-height 38px
- border-radius 16px
-
- &:before
+ &:after
content ""
- pointer-events none
display block
- position absolute
- top 12px
-
- &:hover
- > .delete-button
- display block
+ clear both
- > .delete-button
- display none
- position absolute
- z-index 1
- top -4px
- right -4px
- margin 0
- padding 0
- cursor pointer
- outline none
- border none
- border-radius 0
- box-shadow none
- background transparent
+ > .avatar-anchor
+ display block
- > img
- vertical-align bottom
- width 16px
- height 16px
- cursor pointer
+ > .avatar
+ display block
+ min-width 54px
+ min-height 54px
+ max-width 54px
+ max-height 54px
+ margin 0
+ border-radius 8px
+ transition all 0.1s ease
- > .read
- user-select none
+ > .content-container
display block
- position absolute
- z-index 1
- bottom -4px
- left -12px
- margin 0
- color rgba(0, 0, 0, 0.5)
- font-size 11px
-
- > .content
+ margin 0 12px
+ padding 0
+ max-width calc(100% - 78px)
- > .is-deleted
+ > .balloon
display block
+ float inherit
margin 0
padding 0
- overflow hidden
- word-wrap break-word
- font-size 1em
- color rgba(0, 0, 0, 0.5)
+ max-width 100%
+ min-height 38px
+ border-radius 16px
- > [ref='text']
- display block
- margin 0
- padding 8px 16px
- overflow hidden
- word-wrap break-word
- font-size 1em
- color rgba(0, 0, 0, 0.8)
+ &:before
+ content ""
+ pointer-events none
+ display block
+ position absolute
+ top 12px
- &, *
- user-select text
- cursor auto
+ &:hover
+ > .delete-button
+ display block
- & + .file
- &.image
- > img
- border-radius 0 0 16px 16px
+ > .delete-button
+ display none
+ position absolute
+ z-index 1
+ top -4px
+ right -4px
+ margin 0
+ padding 0
+ cursor pointer
+ outline none
+ border none
+ border-radius 0
+ box-shadow none
+ background transparent
- > .file
- &.image
> img
+ vertical-align bottom
+ width 16px
+ height 16px
+ cursor pointer
+
+ > .read
+ user-select none
+ display block
+ position absolute
+ z-index 1
+ bottom -4px
+ left -12px
+ margin 0
+ color rgba(0, 0, 0, 0.5)
+ font-size 11px
+
+ > .content
+
+ > .is-deleted
display block
- max-width 100%
- max-height 512px
- border-radius 16px
+ margin 0
+ padding 0
+ overflow hidden
+ word-wrap break-word
+ font-size 1em
+ color rgba(0, 0, 0, 0.5)
- > footer
- display block
- clear both
- margin 0
- padding 2px
- font-size 10px
- color rgba(0, 0, 0, 0.4)
+ > [ref='text']
+ display block
+ margin 0
+ padding 8px 16px
+ overflow hidden
+ word-wrap break-word
+ font-size 1em
+ color rgba(0, 0, 0, 0.8)
- > .is-edited
- margin-left 4px
+ &, *
+ user-select text
+ cursor auto
- &:not([data-is-me='true'])
- > .avatar-anchor
- float left
+ & + .file
+ &.image
+ > img
+ border-radius 0 0 16px 16px
- > .content-container
- float left
+ > .file
+ &.image
+ > img
+ display block
+ max-width 100%
+ max-height 512px
+ border-radius 16px
- > .balloon
- background #eee
+ > footer
+ display block
+ clear both
+ margin 0
+ padding 2px
+ font-size 10px
+ color rgba(0, 0, 0, 0.4)
- &:before
- left -14px
- border-top solid 8px transparent
- border-right solid 8px #eee
- border-bottom solid 8px transparent
- border-left solid 8px transparent
+ > .is-edited
+ margin-left 4px
- > footer
- text-align left
+ &:not([data-is-me='true'])
+ > .avatar-anchor
+ float left
- &[data-is-me='true']
- > .avatar-anchor
- float right
+ > .content-container
+ float left
- > .content-container
- float right
+ > .balloon
+ background #eee
- > .balloon
- background $me-balloon-color
+ &:before
+ left -14px
+ border-top solid 8px transparent
+ border-right solid 8px #eee
+ border-bottom solid 8px transparent
+ border-left solid 8px transparent
- &:before
- right -14px
- left auto
- border-top solid 8px transparent
- border-right solid 8px transparent
- border-bottom solid 8px transparent
- border-left solid 8px $me-balloon-color
+ > footer
+ text-align left
- > .content
+ &[data-is-me='true']
+ > .avatar-anchor
+ float right
- > p.is-deleted
- color rgba(255, 255, 255, 0.5)
+ > .content-container
+ float right
- > [ref='text']
- &, *
- color #fff !important
+ > .balloon
+ background $me-balloon-color
- > footer
- text-align right
+ &:before
+ right -14px
+ left auto
+ border-top solid 8px transparent
+ border-right solid 8px transparent
+ border-bottom solid 8px transparent
+ border-left solid 8px $me-balloon-color
- &[data-is-deleted='true']
- > .content-container
- opacity 0.5
+ > .content
+
+ > p.is-deleted
+ color rgba(255, 255, 255, 0.5)
+
+ > [ref='text']
+ &, *
+ color #fff !important
+
+ > footer
+ text-align right
+
+ &[data-is-deleted='true']
+ > .content-container
+ opacity 0.5
-script.
- @mixin \i
- @mixin \text
+ </style>
+ <script>
+ @mixin \i
+ @mixin \text
- @message = @opts.message
- @message.is_me = @message.user.id == @I.id
+ @message = @opts.message
+ @message.is_me = @message.user.id == @I.id
- @on \mount ~>
- if @message.text?
- tokens = @analyze @message.text
+ @on \mount ~>
+ if @message.text?
+ tokens = @analyze @message.text
- @refs.text.innerHTML = @compile tokens
+ @refs.text.innerHTML = @compile tokens
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \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
+ # 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
+ </script>
+</mk-messaging-message>
diff --git a/src/web/app/desktop/tags/messaging/room-window.tag b/src/web/app/desktop/tags/messaging/room-window.tag
index 673b11419a..46a2297f2a 100644
--- a/src/web/app/desktop/tags/messaging/room-window.tag
+++ b/src/web/app/desktop/tags/messaging/room-window.tag
@@ -1,26 +1,25 @@
-mk-messaging-room-window
- mk-window@window(is-modal={ false }, width={ '500px' }, height={ '560px' })
- <yield to="header">
- i.fa.fa-comments
- | メッセージ: { parent.user.name }
- </yield>
- <yield to="content">
- mk-messaging-room(user={ parent.user })
- </yield>
+<mk-messaging-room-window>
+ <mk-window ref="window" is-modal="{ false }" width="{ '500px' }" height="{ '560px' }"><yield to="header"><i class="fa fa-comments"></i>メッセージ: { parent.user.name }</yield>
+<yield to="content">
+ <mk-messaging-room user="{ parent.user }"></mk-messaging-room></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
+ > mk-messaging-room
+ height 100%
- [data-yield='content']
- > mk-messaging-room
- height 100%
+ </style>
+ <script>
+ @user = @opts.user
-script.
- @user = @opts.user
-
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ @on \mount ~>
+ @refs.window.on \closed ~>
+ @unmount!
+ </script>
+</mk-messaging-room-window>
diff --git a/src/web/app/desktop/tags/messaging/room.tag b/src/web/app/desktop/tags/messaging/room.tag
index ca396d7418..929e62fc3a 100644
--- a/src/web/app/desktop/tags/messaging/room.tag
+++ b/src/web/app/desktop/tags/messaging/room.tag
@@ -1,227 +1,227 @@
-mk-messaging-room
- div.stream@stream
- p.initializing(if={ init })
- i.fa.fa-spinner.fa-spin
- | 読み込み中
- p.empty(if={ !init && messages.length == 0 })
- i.fa.fa-info-circle
- | このユーザーとまだ会話したことがありません
- virtual(each={ message, i in messages })
- mk-messaging-message(message={ message })
- p.date(if={ i != messages.length - 1 && message._date != messages[i + 1]._date })
- span { messages[i + 1]._datetext }
+<mk-messaging-room>
+ <div class="stream" ref="stream">
+ <p class="initializing" if="{ init }"><i class="fa fa-spinner fa-spin"></i>読み込み中</p>
+ <p class="empty" if="{ !init &amp;&amp; messages.length == 0 }"><i class="fa fa-info-circle"></i>このユーザーとまだ会話したことがありません</p>
+ <virtual each="{ message, i in messages }">
+ <mk-messaging-message message="{ message }"></mk-messaging-message>
+ <p class="date" if="{ i != messages.length - 1 &amp;&amp; message._date != messages[i + 1]._date }"><span>{ messages[i + 1]._datetext }</span></p>
+ </virtual>
+ </div>
+ <div class="typings"></div>
+ <footer>
+ <div ref="notifications"></div>
+ <div class="grippie" title="ドラッグしてフォームの広さを調整"></div>
+ <mk-messaging-form user="{ user }"></mk-messaging-form>
+ </footer>
+ <style type="stylus">
+ :scope
+ display block
- div.typings
- footer
- div@notifications
- div.grippie(title='ドラッグしてフォームの広さを調整')
- mk-messaging-form(user={ user })
+ > .stream
+ position absolute
+ top 0
+ left 0
+ width 100%
+ height calc(100% - 100px)
+ overflow auto
-style.
- display block
+ > .empty
+ width 100%
+ margin 0
+ padding 16px 8px 8px 8px
+ text-align center
+ font-size 0.8em
+ color rgba(0, 0, 0, 0.4)
- > .stream
- position absolute
- top 0
- left 0
- width 100%
- height calc(100% - 100px)
- overflow auto
+ i
+ margin-right 4px
- > .empty
- width 100%
- margin 0
- padding 16px 8px 8px 8px
- text-align center
- font-size 0.8em
- color rgba(0, 0, 0, 0.4)
+ > .no-history
+ display block
+ margin 0
+ padding 16px
+ text-align center
+ font-size 0.8em
+ color rgba(0, 0, 0, 0.4)
- i
- margin-right 4px
+ i
+ margin-right 4px
- > .no-history
- display block
- margin 0
- padding 16px
- text-align center
- font-size 0.8em
- color rgba(0, 0, 0, 0.4)
+ > .message
+ // something
- i
- margin-right 4px
+ > .date
+ display block
+ margin 8px 0
+ text-align center
- > .message
- // something
+ &:before
+ content ''
+ display block
+ position absolute
+ height 1px
+ width 90%
+ top 16px
+ left 0
+ right 0
+ margin 0 auto
+ background rgba(0, 0, 0, 0.1)
- > .date
- display block
- margin 8px 0
- text-align center
+ > span
+ display inline-block
+ margin 0
+ padding 0 16px
+ //font-weight bold
+ line-height 32px
+ color rgba(0, 0, 0, 0.3)
+ background #fff
- &:before
- content ''
- display block
+ > footer
position absolute
- height 1px
- width 90%
- top 16px
- left 0
- right 0
+ z-index 2
+ bottom 0
+ width 600px
+ max-width 100%
margin 0 auto
- background rgba(0, 0, 0, 0.1)
+ padding 0
+ background rgba(255, 255, 255, 0.95)
+ background-clip content-box
- > span
- display inline-block
- margin 0
- padding 0 16px
- //font-weight bold
- line-height 32px
- color rgba(0, 0, 0, 0.3)
- background #fff
-
- > footer
- position absolute
- z-index 2
- bottom 0
- width 600px
- max-width 100%
- margin 0 auto
- padding 0
- background rgba(255, 255, 255, 0.95)
- background-clip content-box
+ > [ref='notifications']
+ position absolute
+ top -48px
+ width 100%
+ padding 8px 0
+ text-align center
- > [ref='notifications']
- position absolute
- top -48px
- width 100%
- padding 8px 0
- text-align center
+ > p
+ display inline-block
+ margin 0
+ padding 0 12px 0 28px
+ cursor pointer
+ line-height 32px
+ font-size 12px
+ color $theme-color-foreground
+ background $theme-color
+ border-radius 16px
+ transition opacity 1s ease
- > p
- display inline-block
- margin 0
- padding 0 12px 0 28px
- cursor pointer
- line-height 32px
- font-size 12px
- color $theme-color-foreground
- background $theme-color
- border-radius 16px
- transition opacity 1s ease
+ > i
+ position absolute
+ top 0
+ left 10px
+ line-height 32px
+ font-size 16px
- > i
- position absolute
- top 0
- left 10px
- line-height 32px
- font-size 16px
+ > .grippie
+ height 10px
+ margin-top -10px
+ background transparent
+ cursor ns-resize
- > .grippie
- height 10px
- margin-top -10px
- background transparent
- cursor ns-resize
+ &:hover
+ //background rgba(0, 0, 0, 0.1)
- &:hover
- //background rgba(0, 0, 0, 0.1)
+ &:active
+ //background rgba(0, 0, 0, 0.2)
- &:active
- //background rgba(0, 0, 0, 0.2)
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
+ @mixin \messaging-stream
-script.
- @mixin \i
- @mixin \api
- @mixin \messaging-stream
+ @user = @opts.user
+ @init = true
+ @sending = false
+ @messages = []
- @user = @opts.user
- @init = true
- @sending = false
- @messages = []
+ @connection = new @MessagingStreamConnection @I, @user.id
- @connection = new @MessagingStreamConnection @I, @user.id
+ @on \mount ~>
+ @connection.event.on \message @on-message
+ @connection.event.on \read @on-read
- @on \mount ~>
- @connection.event.on \message @on-message
- @connection.event.on \read @on-read
+ document.add-event-listener \visibilitychange @on-visibilitychange
- document.add-event-listener \visibilitychange @on-visibilitychange
-
- @api \messaging/messages do
- user_id: @user.id
- .then (messages) ~>
- @init = false
- @messages = messages.reverse!
- @update!
- @scroll-to-bottom!
- .catch (err) ~>
- console.error err
+ @api \messaging/messages do
+ user_id: @user.id
+ .then (messages) ~>
+ @init = false
+ @messages = messages.reverse!
+ @update!
+ @scroll-to-bottom!
+ .catch (err) ~>
+ console.error err
- @on \unmount ~>
- @connection.event.off \message @on-message
- @connection.event.off \read @on-read
- @connection.close!
+ @on \unmount ~>
+ @connection.event.off \message @on-message
+ @connection.event.off \read @on-read
+ @connection.close!
- document.remove-event-listener \visibilitychange @on-visibilitychange
+ document.remove-event-listener \visibilitychange @on-visibilitychange
- @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 + '日'
+ @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 + '日'
- @on-message = (message) ~>
- is-bottom = @is-bottom!
+ @on-message = (message) ~>
+ is-bottom = @is-bottom!
- @messages.push message
- if message.user_id != @I.id and not document.hidden
- @connection.socket.send JSON.stringify do
- type: \read
- id: message.id
- @update!
+ @messages.push message
+ if message.user_id != @I.id and not document.hidden
+ @connection.socket.send JSON.stringify do
+ type: \read
+ id: message.id
+ @update!
- if is-bottom
- # Scroll to bottom
- @scroll-to-bottom!
- else if message.user_id != @I.id
- # Notify
- @notify '新しいメッセージがあります'
+ if is-bottom
+ # Scroll to bottom
+ @scroll-to-bottom!
+ else if message.user_id != @I.id
+ # Notify
+ @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!
+ @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!
- @is-bottom = ~>
- current = @refs.stream.scroll-top + @refs.stream.offset-height
- max = @refs.stream.scroll-height
- current > (max - 32)
+ @is-bottom = ~>
+ current = @refs.stream.scroll-top + @refs.stream.offset-height
+ max = @refs.stream.scroll-height
+ current > (max - 32)
- @scroll-to-bottom = ~>
- @refs.stream.scroll-top = @refs.stream.scroll-height
+ @scroll-to-bottom = ~>
+ @refs.stream.scroll-top = @refs.stream.scroll-height
- @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
+ @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
- set-timeout ~>
- n.style.opacity = 0
set-timeout ~>
- n.parent-node.remove-child n
- , 1000ms
- , 4000ms
+ n.style.opacity = 0
+ set-timeout ~>
+ n.parent-node.remove-child n
+ , 1000ms
+ , 4000ms
- @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
- id: message.id
+ @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
+ id: message.id
+ </script>
+</mk-messaging-room>
diff --git a/src/web/app/desktop/tags/messaging/window.tag b/src/web/app/desktop/tags/messaging/window.tag
index b6979b6244..17ebfd2280 100644
--- a/src/web/app/desktop/tags/messaging/window.tag
+++ b/src/web/app/desktop/tags/messaging/window.tag
@@ -1,29 +1,28 @@
-mk-messaging-window
- mk-window@window(is-modal={ false }, width={ '500px' }, height={ '560px' })
- <yield to="header">
- i.fa.fa-comments
- | メッセージ
- </yield>
- <yield to="content">
- mk-messaging@index
- </yield>
+<mk-messaging-window>
+ <mk-window ref="window" is-modal="{ false }" width="{ '500px' }" height="{ '560px' }"><yield to="header"><i class="fa fa-comments"></i>メッセージ</yield>
+<yield to="content">
+ <mk-messaging ref="index"></mk-messaging></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
+ > mk-messaging
+ height 100%
- [data-yield='content']
- > mk-messaging
- height 100%
+ </style>
+ <script>
+ @on \mount ~>
+ @refs.window.on \closed ~>
+ @unmount!
-script.
- @on \mount ~>
- @refs.window.on \closed ~>
- @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
- user: user
+ @refs.window.refs.index.on \navigate-user (user) ~>
+ w = document.body.append-child document.create-element \mk-messaging-room-window
+ riot.mount w, do
+ 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 d47815a89b..b8f03fb6f2 100644
--- a/src/web/app/desktop/tags/notifications.tag
+++ b/src/web/app/desktop/tags/notifications.tag
@@ -1,226 +1,199 @@
-mk-notifications
- div.notifications(if={ notifications.length != 0 })
- virtual(each={ notification, i in notifications })
- div.notification(class={ notification.type })
- mk-time(time={ notification.created_at })
-
- div.main(if={ notification.type == 'like' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id })
- img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
- div.text
- p
- i.fa.fa-thumbs-o-up
- a(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id }) { notification.user.name }
- a.post-ref(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'repost' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
- div.text
- p
- i.fa.fa-retweet
- a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
- a.post-ref(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post.repost) }
-
- div.main(if={ notification.type == 'quote' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
- div.text
- p
- i.fa.fa-quote-left
- a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
- a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'follow' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id })
- img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
- div.text
- p
- i.fa.fa-user-plus
- a(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id }) { notification.user.name }
-
- div.main(if={ notification.type == 'reply' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
- div.text
- p
- i.fa.fa-reply
- a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
- a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'mention' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
- div.text
- p
- i.fa.fa-at
- a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
- a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
+<mk-notifications>
+ <div class="notifications" if="{ notifications.length != 0 }">
+ <virtual each="{ notification, i in notifications }">
+ <div class="notification { notification.type }">
+ <mk-time time="{ notification.created_at }"></mk-time>
+ <div class="main" if="{ notification.type == 'like' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&amp;size=48' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-thumbs-o-up"></i><a href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }">{ notification.user.name }</a></p><a class="post-ref" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'repost' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=48' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-retweet"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-ref" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post.repost) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'quote' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=48' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-quote-left"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'follow' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&amp;size=48' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-user-plus"></i><a href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }">{ notification.user.name }</a></p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'reply' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=48' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-reply"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'mention' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=48' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-at"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ </div>
+ <p class="date" if="{ i != notifications.length - 1 &amp;&amp; notification._date != notifications[i + 1]._date }"><span><i class="fa fa-angle-up"></i>{ notification._datetext }</span><span><i class="fa fa-angle-down"></i>{ notifications[i + 1]._datetext }</span></p>
+ </virtual>
+ </div>
+ <p class="empty" if="{ notifications.length == 0 &amp;&amp; !loading }">ありません!</p>
+ <p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
- p.date(if={ i != notifications.length - 1 && notification._date != notifications[i + 1]._date })
- span
- i.fa.fa-angle-up
- | { notification._datetext }
- span
- i.fa.fa-angle-down
- | { notifications[i + 1]._datetext }
+ > .notifications
+ > .notification
+ margin 0
+ padding 16px
+ font-size 0.9em
+ border-bottom solid 1px rgba(0, 0, 0, 0.05)
- p.empty(if={ notifications.length == 0 && !loading })
- | ありません!
- p.loading(if={ loading })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
+ &:last-child
+ border-bottom none
-style.
- display block
+ > mk-time
+ display inline
+ position absolute
+ top 16px
+ right 12px
+ vertical-align top
+ color rgba(0, 0, 0, 0.6)
+ font-size small
- > .notifications
- > .notification
- margin 0
- padding 16px
- font-size 0.9em
- border-bottom solid 1px rgba(0, 0, 0, 0.05)
+ > .main
+ word-wrap break-word
- &:last-child
- border-bottom none
+ &:after
+ content ""
+ display block
+ clear both
- > mk-time
- display inline
- position absolute
- top 16px
- right 12px
- vertical-align top
- color rgba(0, 0, 0, 0.6)
- font-size small
+ .avatar-anchor
+ display block
+ float left
- > .main
- word-wrap break-word
+ img
+ min-width 36px
+ min-height 36px
+ max-width 36px
+ max-height 36px
+ border-radius 6px
- &:after
- content ""
- display block
- clear both
+ .text
+ float right
+ width calc(100% - 36px)
+ padding-left 8px
- .avatar-anchor
- display block
- float left
+ p
+ margin 0
- img
- min-width 36px
- min-height 36px
- max-width 36px
- max-height 36px
- border-radius 6px
+ i
+ margin-right 4px
- .text
- float right
- width calc(100% - 36px)
- padding-left 8px
+ .post-preview
+ color rgba(0, 0, 0, 0.7)
- p
- margin 0
+ .post-ref
+ color rgba(0, 0, 0, 0.7)
- i
- margin-right 4px
+ &:before, &:after
+ font-family FontAwesome
+ font-size 1em
+ font-weight normal
+ font-style normal
+ display inline-block
+ margin-right 3px
- .post-preview
- color rgba(0, 0, 0, 0.7)
+ &:before
+ content "\f10d"
- .post-ref
- color rgba(0, 0, 0, 0.7)
+ &:after
+ content "\f10e"
- &:before, &:after
- font-family FontAwesome
- font-size 1em
- font-weight normal
- font-style normal
- display inline-block
- margin-right 3px
+ &.like
+ .text p i
+ color #FFAC33
- &:before
- content "\f10d"
+ &.repost, &.quote
+ .text p i
+ color #77B255
- &:after
- content "\f10e"
+ &.follow
+ .text p i
+ color #53c7ce
- &.like
- .text p i
- color #FFAC33
+ &.reply, &.mention
+ .text p i
+ color #555
- &.repost, &.quote
- .text p i
- color #77B255
+ > .date
+ display block
+ margin 0
+ line-height 32px
+ text-align center
+ font-size 0.8em
+ color #aaa
+ background #fdfdfd
+ border-bottom solid 1px rgba(0, 0, 0, 0.05)
- &.follow
- .text p i
- color #53c7ce
+ span
+ margin 0 16px
- &.reply, &.mention
- .text p i
- color #555
+ i
+ margin-right 8px
- > .date
- display block
- margin 0
- line-height 32px
- text-align center
- font-size 0.8em
- color #aaa
- background #fdfdfd
- border-bottom solid 1px rgba(0, 0, 0, 0.05)
+ > .empty
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- span
- margin 0 16px
+ > .loading
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- i
- margin-right 8px
+ > i
+ margin-right 4px
- > .empty
- margin 0
- padding 16px
- text-align center
- color #aaa
+ </style>
+ <script>
+ @mixin \api
+ @mixin \stream
+ @mixin \user-preview
+ @mixin \get-post-summary
- > .loading
- margin 0
- padding 16px
- text-align center
- color #aaa
+ @notifications = []
+ @loading = true
- > i
- margin-right 4px
+ @on \mount ~>
+ @api \i/notifications
+ .then (notifications) ~>
+ @notifications = notifications
+ @loading = false
+ @update!
+ .catch (err, text-status) ->
+ console.error err
-script.
- @mixin \api
- @mixin \stream
- @mixin \user-preview
- @mixin \get-post-summary
+ @stream.on \notification @on-notification
- @notifications = []
- @loading = true
+ @on \unmount ~>
+ @stream.off \notification @on-notification
- @on \mount ~>
- @api \i/notifications
- .then (notifications) ~>
- @notifications = notifications
- @loading = false
+ @on-notification = (notification) ~>
+ @notifications.unshift notification
@update!
- .catch (err, text-status) ->
- console.error err
-
- @stream.on \notification @on-notification
-
- @on \unmount ~>
- @stream.off \notification @on-notification
-
- @on-notification = (notification) ~>
- @notifications.unshift notification
- @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 + '日'
+ @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 + '日'
+ </script>
+</mk-notifications>
diff --git a/src/web/app/desktop/tags/pages/entrance.tag b/src/web/app/desktop/tags/pages/entrance.tag
index 5e18f616a3..4e1c5277a3 100644
--- a/src/web/app/desktop/tags/pages/entrance.tag
+++ b/src/web/app/desktop/tags/pages/entrance.tag
@@ -1,77 +1,80 @@
-mk-entrance
- main
- img(src='/_/resources/title.svg', alt='Misskey')
-
- mk-entrance-signin(if={ mode == 'signin' })
- mk-entrance-signup(if={ mode == 'signup' })
- div.introduction(if={ mode == 'introduction' })
- mk-introduction
- button(onclick={ signin }) わかった
-
- mk-forkit
-
- footer
- mk-copyright
-
- // ↓ https://github.com/riot/riot/issues/2134 (将来的)
- style(data-disable-scope).
+<mk-entrance>
+ <main><img src="/_/resources/title.svg" alt="Misskey"/>
+ <mk-entrance-signin if="{ mode == 'signin' }"></mk-entrance-signin>
+ <mk-entrance-signup if="{ mode == 'signup' }"></mk-entrance-signup>
+ <div class="introduction" if="{ mode == 'introduction' }">
+ <mk-introduction></mk-introduction>
+ <button onclick="{ signin }">わかった</button>
+ </div>
+ </main>
+ <mk-forkit></mk-forkit>
+ <footer>
+ <mk-copyright></mk-copyright>
+ </footer>
+ <!-- ↓ https://github.com/riot/riot/issues/2134 (将来的)-->
+ <style data-disable-scope="data-disable-scope">
#wait {
right: auto;
left: 15px;
}
-style.
- display block
- height 100%
-
- > main
- display block
-
- > img
+ </style>
+ <style type="stylus">
+ :scope
display block
- width 160px
- height 170px
- margin 0 auto
- pointer-events none
- user-select none
+ height 100%
- > .introduction
- max-width 360px
- margin 0 auto
- color #777
+ > main
+ display block
- > mk-introduction
- padding 32px
- background #fff
- box-shadow 0 4px 16px rgba(0, 0, 0, 0.2)
+ > img
+ display block
+ width 160px
+ height 170px
+ margin 0 auto
+ pointer-events none
+ user-select none
- > button
- display block
- margin 16px auto 0 auto
- color #666
+ > .introduction
+ max-width 360px
+ margin 0 auto
+ color #777
- &:hover
- text-decoration underline
+ > mk-introduction
+ padding 32px
+ background #fff
+ box-shadow 0 4px 16px rgba(0, 0, 0, 0.2)
- > footer
- > mk-copyright
- margin 0
- text-align center
- line-height 64px
- font-size 10px
- color rgba(#000, 0.5)
+ > button
+ display block
+ margin 16px auto 0 auto
+ color #666
-script.
- @mode = \signin
+ &:hover
+ text-decoration underline
- @signup = ~>
- @mode = \signup
- @update!
+ > footer
+ > mk-copyright
+ margin 0
+ text-align center
+ line-height 64px
+ font-size 10px
+ color rgba(#000, 0.5)
- @signin = ~>
+ </style>
+ <script>
@mode = \signin
- @update!
- @introduction = ~>
- @mode = \introduction
- @update!
+ @signup = ~>
+ @mode = \signup
+ @update!
+
+ @signin = ~>
+ @mode = \signin
+ @update!
+
+ @introduction = ~>
+ @mode = \introduction
+ @update!
+ </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 8ff39bc296..26bdb6898a 100644
--- a/src/web/app/desktop/tags/pages/entrance/signin.tag
+++ b/src/web/app/desktop/tags/pages/entrance/signin.tag
@@ -1,128 +1,130 @@
-mk-entrance-signin
- a.help(href={ CONFIG.urls.about + '/help' }, title='お困りですか?'): i.fa.fa-question
- div.form
- h1
- img(if={ user }, src={ user.avatar_url + '?thumbnail&size=32' })
- p { user ? user.name : 'アカウント' }
- mk-signin@signin
- div.divider: span or
- button.signup(onclick={ parent.signup }) 新規登録
- a.introduction(onclick={ introduction }) Misskeyについて
-
-style.
- display block
- width 290px
- margin 0 auto
- text-align center
+<mk-entrance-signin><a class="help" href="{ CONFIG.urls.about + '/help' }" title="お困りですか?"><i class="fa fa-question"></i></a>
+ <div class="form">
+ <h1><img if="{ user }" src="{ user.avatar_url + '?thumbnail&amp;size=32' }"/>
+ <p>{ user ? user.name : 'アカウント' }</p>
+ </h1>
+ <mk-signin ref="signin"></mk-signin>
+ </div>
+ <div class="divider"><span>or</span></div>
+ <button class="signup" onclick="{ parent.signup }">新規登録</button><a class="introduction" onclick="{ introduction }">Misskeyについて</a>
+ <style type="stylus">
+ :scope
+ display block
+ width 290px
+ margin 0 auto
+ text-align center
- &:hover
- > .help
- opacity 1
+ &:hover
+ > .help
+ opacity 1
- > .help
- cursor pointer
- display block
- position absolute
- top 0
- right 0
- z-index 1
- margin 0
- padding 0
- font-size 1.2em
- color #999
- border none
- outline none
- background transparent
- opacity 0
- transition opacity 0.1s ease
+ > .help
+ cursor pointer
+ display block
+ position absolute
+ top 0
+ right 0
+ z-index 1
+ margin 0
+ padding 0
+ font-size 1.2em
+ color #999
+ border none
+ outline none
+ background transparent
+ opacity 0
+ transition opacity 0.1s ease
- &:hover
- color #444
+ &:hover
+ color #444
- &:active
- color #222
+ &:active
+ color #222
- > i
- padding 14px
+ > i
+ padding 14px
- > .form
- padding 10px 28px 16px 28px
- background #fff
- box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
+ > .form
+ padding 10px 28px 16px 28px
+ background #fff
+ box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
- > h1
- display block
- margin 0
- padding 0
- height 54px
- line-height 54px
- text-align center
- text-transform uppercase
- font-size 1em
- font-weight bold
- color rgba(0, 0, 0, 0.5)
- border-bottom solid 1px rgba(0, 0, 0, 0.1)
+ > h1
+ display block
+ margin 0
+ padding 0
+ height 54px
+ line-height 54px
+ text-align center
+ text-transform uppercase
+ font-size 1em
+ font-weight bold
+ color rgba(0, 0, 0, 0.5)
+ border-bottom solid 1px rgba(0, 0, 0, 0.1)
- > p
- display inline
- margin 0
- padding 0
+ > p
+ display inline
+ margin 0
+ padding 0
- > img
- display inline-block
- top 10px
- width 32px
- height 32px
- margin-right 8px
- border-radius 100%
+ > img
+ display inline-block
+ top 10px
+ width 32px
+ height 32px
+ margin-right 8px
+ border-radius 100%
- &[src='']
- display none
+ &[src='']
+ display none
- > .divider
- padding 16px 0
- text-align center
+ > .divider
+ padding 16px 0
+ text-align center
- &:after
- content ""
- display block
- position absolute
- top 50%
- width 100%
- height 1px
- border-top solid 1px rgba(0, 0, 0, 0.1)
+ &:after
+ content ""
+ display block
+ position absolute
+ top 50%
+ width 100%
+ height 1px
+ border-top solid 1px rgba(0, 0, 0, 0.1)
- > *
- z-index 1
- padding 0 8px
- color rgba(0, 0, 0, 0.5)
- background #fdfdfd
+ > *
+ z-index 1
+ padding 0 8px
+ color rgba(0, 0, 0, 0.5)
+ background #fdfdfd
- > .signup
- width 100%
- line-height 56px
- font-size 1em
- color #fff
- background $theme-color
- border-radius 64px
+ > .signup
+ width 100%
+ line-height 56px
+ font-size 1em
+ color #fff
+ background $theme-color
+ border-radius 64px
- &:hover
- background lighten($theme-color, 5%)
+ &:hover
+ background lighten($theme-color, 5%)
- &:active
- background darken($theme-color, 5%)
+ &:active
+ background darken($theme-color, 5%)
- > .introduction
- display inline-block
- margin-top 16px
- font-size 12px
- color #666
+ > .introduction
+ display inline-block
+ margin-top 16px
+ font-size 12px
+ color #666
-script.
- @on \mount ~>
- @refs.signin.on \user (user) ~>
- @update do
- user: user
+ </style>
+ <script>
+ @on \mount ~>
+ @refs.signin.on \user (user) ~>
+ @update do
+ user: user
- @introduction = ~>
- @parent.introduction!
+ @introduction = ~>
+ @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 1b585f7000..2452b7d793 100644
--- a/src/web/app/desktop/tags/pages/entrance/signup.tag
+++ b/src/web/app/desktop/tags/pages/entrance/signup.tag
@@ -1,44 +1,51 @@
-mk-entrance-signup
- mk-signup
- button.cancel(type='button', onclick={ parent.signin }, title='キャンセル'): i.fa.fa-times
+<mk-entrance-signup>
+ <mk-signup></mk-signup>
+ <button class="cancel" type="button" onclick="{ parent.signin }" title="キャンセル"><i class="fa fa-times"></i></button>
+ <style type="stylus">
+ :scope
+ display block
+ width 368px
+ margin 0 auto
-style.
- display block
- width 368px
- margin 0 auto
+ &:hover
+ > .cancel
+ opacity 1
- &:hover
- > .cancel
- opacity 1
+ > mk-signup
+ padding 18px 32px 0 32px
+ background #fff
+ box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
- > mk-signup
- padding 18px 32px 0 32px
- background #fff
- box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
+ > .cancel
+ cursor pointer
+ display block
+ position absolute
+ top 0
+ right 0
+ z-index 1
+ margin 0
+ padding 0
+ font-size 1.2em
+ color #999
+ border none
+ outline none
+ box-shadow none
+ background transparent
+ opacity 0
+ transition opacity 0.1s ease
- > .cancel
- cursor pointer
- display block
- position absolute
- top 0
- right 0
- z-index 1
- margin 0
- padding 0
- font-size 1.2em
- color #999
- border none
- outline none
- box-shadow none
- background transparent
- opacity 0
- transition opacity 0.1s ease
+ &:hover
+ color #555
- &:hover
- color #555
+ &:active
+ color #222
- &:active
- color #222
+ > i
+ padding 14px
- > 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 5d419a5802..3a0e713d30 100644
--- a/src/web/app/desktop/tags/pages/home.tag
+++ b/src/web/app/desktop/tags/pages/home.tag
@@ -1,51 +1,56 @@
-mk-home-page
- mk-ui@ui(page={ page }): mk-home@home(mode={ parent.opts.mode })
+<mk-home-page>
+ <mk-ui ref="ui" page="{ page }">
+ <mk-home ref="home" mode="{ parent.opts.mode }"></mk-home>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ background-position center center
+ background-attachment fixed
+ background-size cover
- background-position center center
- background-attachment fixed
- background-size cover
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
+ @mixin \ui-progress
+ @mixin \stream
+ @mixin \get-post-summary
-script.
- @mixin \i
- @mixin \api
- @mixin \ui-progress
- @mixin \stream
- @mixin \get-post-summary
+ @unread-count = 0
- @unread-count = 0
+ @page = switch @opts.mode
+ | \timelie => \home
+ | \mentions => \mentions
+ | _ => \home
- @page = switch @opts.mode
- | \timelie => \home
- | \mentions => \mentions
- | _ => \home
+ @on \mount ~>
+ @refs.ui.refs.home.on \loaded ~>
+ @Progress.done!
- @on \mount ~>
- @refs.ui.refs.home.on \loaded ~>
- @Progress.done!
-
- document.title = 'Misskey'
- if @I.data.wallpaper
- @api \drive/files/show do
- file_id: @I.data.wallpaper
- .then (file) ~>
- @root.style.background-image = 'url(' + file.url + ')'
- @Progress.start!
- @stream.on \post @on-stream-post
- document.add-event-listener \visibilitychange @window-on-visibilitychange, false
+ document.title = 'Misskey'
+ if @I.data.wallpaper
+ @api \drive/files/show do
+ file_id: @I.data.wallpaper
+ .then (file) ~>
+ @root.style.background-image = 'url(' + file.url + ')'
+ @Progress.start!
+ @stream.on \post @on-stream-post
+ document.add-event-listener \visibilitychange @window-on-visibilitychange, false
- @on \unmount ~>
- @stream.off \post @on-stream-post
- document.remove-event-listener \visibilitychange @window-on-visibilitychange
+ @on \unmount ~>
+ @stream.off \post @on-stream-post
+ document.remove-event-listener \visibilitychange @window-on-visibilitychange
- @on-stream-post = (post) ~>
- if document.hidden and post.user_id !== @I.id
- @unread-count++
- document.title = '(' + @unread-count + ') ' + @get-post-summary post
+ @on-stream-post = (post) ~>
+ if document.hidden and post.user_id !== @I.id
+ @unread-count++
+ document.title = '(' + @unread-count + ') ' + @get-post-summary post
- @window-on-visibilitychange = ~>
- if !document.hidden
- @unread-count = 0
- document.title = 'Misskey'
+ @window-on-visibilitychange = ~>
+ if !document.hidden
+ @unread-count = 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 fe23cc6fa4..e3db8c0f70 100644
--- a/src/web/app/desktop/tags/pages/not-found.tag
+++ b/src/web/app/desktop/tags/pages/not-found.tag
@@ -1,46 +1,54 @@
-mk-not-found
- mk-ui
- main
- h1 Not Found
- img(src='/_/resources/rogge.jpg', alt='')
- div.mask
+<mk-not-found>
+ <mk-ui>
+ <main>
+ <h1>Not Found</h1><img src="/_/resources/rogge.jpg" alt=""/>
+ <div class="mask"></div>
+ </main>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ main
+ display block
+ width 600px
+ margin 32px auto
- 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)
- > 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
- > 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
+
+
+
+
- > .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 81ab9ce006..f355770d38 100644
--- a/src/web/app/desktop/tags/pages/post.tag
+++ b/src/web/app/desktop/tags/pages/post.tag
@@ -1,25 +1,32 @@
-mk-post-page
- mk-ui@ui: main: mk-post-detail@detail(post={ parent.post })
+<mk-post-page>
+ <mk-ui ref="ui">
+ <main>
+ <mk-post-detail ref="detail" post="{ parent.post }"></mk-post-detail>
+ </main>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ main
+ padding 16px
- main
- padding 16px
+ > mk-post-detail
+ margin 0 auto
- > mk-post-detail
- margin 0 auto
+ </style>
+ <script>
+ @mixin \ui-progress
-script.
- @mixin \ui-progress
+ @post = @opts.post
- @post = @opts.post
+ @on \mount ~>
+ @Progress.start!
- @on \mount ~>
- @Progress.start!
+ @refs.ui.refs.detail.on \post-fetched ~>
+ @Progress.set 0.5
- @refs.ui.refs.detail.on \post-fetched ~>
- @Progress.set 0.5
-
- @refs.ui.refs.detail.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.detail.on \loaded ~>
+ @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 a7878ddc0f..a3b3bafd99 100644
--- a/src/web/app/desktop/tags/pages/search.tag
+++ b/src/web/app/desktop/tags/pages/search.tag
@@ -1,14 +1,19 @@
-mk-search-page
- mk-ui@ui: mk-search@search(query={ parent.opts.query })
+<mk-search-page>
+ <mk-ui ref="ui">
+ <mk-search ref="search" query="{ parent.opts.query }"></mk-search>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui-progress
-script.
- @mixin \ui-progress
+ @on \mount ~>
+ @Progress.start!
- @on \mount ~>
- @Progress.start!
-
- @refs.ui.refs.search.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.search.on \loaded ~>
+ @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 d41093c298..d6587e8132 100644
--- a/src/web/app/desktop/tags/pages/user.tag
+++ b/src/web/app/desktop/tags/pages/user.tag
@@ -1,20 +1,25 @@
-mk-user-page
- mk-ui@ui: mk-user@user(user={ parent.user }, page={ parent.opts.page })
+<mk-user-page>
+ <mk-ui ref="ui">
+ <mk-user ref="user" user="{ parent.user }" page="{ parent.opts.page }"></mk-user>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui-progress
-script.
- @mixin \ui-progress
+ @user = @opts.user
- @user = @opts.user
+ @on \mount ~>
+ @Progress.start!
- @on \mount ~>
- @Progress.start!
+ @refs.ui.refs.user.on \user-fetched (user) ~>
+ @Progress.set 0.5
+ document.title = user.name + ' | Misskey'
- @refs.ui.refs.user.on \user-fetched (user) ~>
- @Progress.set 0.5
- document.title = user.name + ' | Misskey'
-
- @refs.ui.refs.user.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.user.on \loaded ~>
+ @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 b7aa745737..8b6411c12a 100644
--- a/src/web/app/desktop/tags/post-detail-sub.tag
+++ b/src/web/app/desktop/tags/post-detail-sub.tag
@@ -1,141 +1,140 @@
-mk-post-detail-sub(title={ title })
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
- img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id })
- div.main
- header
- div.left
- a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id })
- | { post.user.name }
- span.username
- | @{ post.user.username }
- div.right
- a.time(href={ url })
- mk-time(time={ post.created_at })
- div.body
- div.text@text
- div.media(if={ post.media })
- virtual(each={ file in post.media })
- img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name })
-
-style.
- display block
- margin 0
- padding 20px 32px
- background #fdfdfd
-
- &:after
- content ""
- display block
- clear both
-
- &:hover
- > .main > footer > button
- color #888
-
- > .avatar-anchor
- display block
- float left
- margin 0 16px 0 0
-
- > .avatar
+<mk-post-detail-sub title="{ title }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar" data-user-preview="{ post.user_id }"/></a>
+ <div class="main">
+ <header>
+ <div class="left"><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a><span class="username">@{ post.user.username }</span></div>
+ <div class="right"><a class="time" href="{ url }">
+ <mk-time time="{ post.created_at }"></mk-time></a></div>
+ </header>
+ <div class="body">
+ <div class="text" ref="text"></div>
+ <div class="media" if="{ post.media }">
+ <virtual each="{ file in post.media }"><img src="{ file.url + '?thumbnail&amp;size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual>
+ </div>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
display block
- width 44px
- height 44px
margin 0
- border-radius 4px
- vertical-align bottom
-
- > .main
- float left
- width calc(100% - 60px)
-
- > header
- margin-bottom 4px
- white-space nowrap
+ padding 20px 32px
+ background #fdfdfd
&:after
content ""
display block
clear both
- > .left
+ &:hover
+ > .main > footer > button
+ color #888
+
+ > .avatar-anchor
+ display block
float left
+ margin 0 16px 0 0
- > .name
- display inline
+ > .avatar
+ display block
+ width 44px
+ height 44px
margin 0
- padding 0
- color #777
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ border-radius 4px
+ vertical-align bottom
- &:hover
- text-decoration underline
+ > .main
+ float left
+ width calc(100% - 60px)
- > .username
- text-align left
- margin 0 0 0 8px
- color #ccc
+ > header
+ margin-bottom 4px
+ white-space nowrap
- > .right
- float right
+ &:after
+ content ""
+ display block
+ clear both
- > .time
- font-size 0.9em
- color #c0c0c0
+ > .left
+ float left
- > .body
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #777
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- > .text
- cursor default
- display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 1em
- color #717171
+ &:hover
+ text-decoration underline
- > mk-url-preview
- margin-top 8px
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #ccc
- > .media
- > img
- display block
- max-width 100%
+ > .right
+ float right
+
+ > .time
+ font-size 0.9em
+ color #c0c0c0
+
+ > .body
+
+ > .text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 1em
+ color #717171
+
+ > mk-url-preview
+ margin-top 8px
+
+ > .media
+ > img
+ display block
+ max-width 100%
-script.
- @mixin \api
- @mixin \text
- @mixin \date-stringify
- @mixin \user-preview
+ </style>
+ <script>
+ @mixin \api
+ @mixin \text
+ @mixin \date-stringify
+ @mixin \user-preview
- @post = @opts.post
+ @post = @opts.post
- @url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
+ @url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
- @title = @date-stringify @post.created_at
+ @title = @date-stringify @post.created_at
- @on \mount ~>
- if @post.text?
- tokens = @analyze @post.text
- @refs.text.innerHTML = @compile tokens
+ @on \mount ~>
+ if @post.text?
+ tokens = @analyze @post.text
+ @refs.text.innerHTML = @compile tokens
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \MK-URL
+ riot.mount e
- @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!
+ @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!
+ </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 e071b7c704..c395a44328 100644
--- a/src/web/app/desktop/tags/post-detail.tag
+++ b/src/web/app/desktop/tags/post-detail.tag
@@ -1,415 +1,409 @@
-mk-post-detail(title={ title })
-
- div.fetching(if={ fetching })
- mk-ellipsis-icon
-
- div.main(if={ !fetching })
-
- button.read-more(if={ p.reply_to && p.reply_to.reply_to_id && context == null }, title='会話をもっと読み込む', onclick={ load-context }, disabled={ loading-context })
- i.fa.fa-ellipsis-v(if={ !loading-context })
- i.fa.fa-spinner.fa-pulse(if={ loading-context })
-
- div.context
- virtual(each={ post in context })
- mk-post-detail-sub(post={ post })
-
- div.reply-to(if={ p.reply_to })
- mk-post-detail-sub(post={ p.reply_to })
-
- div.repost(if={ is-repost })
- p
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=32' }, alt='avatar')
- i.fa.fa-retweet
- a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name }
- | がRepost
+<mk-post-detail title="{ title }">
+ <div class="fetching" if="{ fetching }">
+ <mk-ellipsis-icon></mk-ellipsis-icon>
+ </div>
+ <div class="main" if="{ !fetching }">
+ <button class="read-more" if="{ p.reply_to &amp;&amp; p.reply_to.reply_to_id &amp;&amp; context == null }" title="会話をもっと読み込む" onclick="{ loadContext }" disabled="{ loadingContext }"><i class="fa fa-ellipsis-v" if="{ !loadingContext }"></i><i class="fa fa-spinner fa-pulse" if="{ loadingContext }"></i></button>
+ <div class="context">
+ <virtual each="{ post in context }">
+ <mk-post-detail-sub post="{ post }"></mk-post-detail-sub>
+ </virtual>
+ </div>
+ <div class="reply-to" if="{ p.reply_to }">
+ <mk-post-detail-sub post="{ p.reply_to }"></mk-post-detail-sub>
+ </div>
+ <div class="repost" if="{ isRepost }">
+ <p><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=32' }" alt="avatar"/></a><i class="fa fa-retweet"></i><a class="name" href="{ CONFIG.url + '/' + post.user.username }">{ post.user.name }</a>がRepost</p>
+ </div>
+ <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + p.user.username }"><img class="avatar" src="{ p.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar" data-user-preview="{ p.user.id }"/></a>
+ <header><a class="name" href="{ CONFIG.url + '/' + p.user.username }" data-user-preview="{ p.user.id }">{ p.user.name }</a><span class="username">@{ p.user.username }</span><a class="time" href="{ url }">
+ <mk-time time="{ p.created_at }"></mk-time></a></header>
+ <div class="body">
+ <div class="text" ref="text"></div>
+ <div class="media" if="{ p.media }">
+ <virtual each="{ file in p.media }"><img src="{ file.url + '?thumbnail&amp;size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual>
+ </div>
+ </div>
+ <footer>
+ <button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i>
+ <p class="count" if="{ p.replies_count &gt; 0 }">{ p.replies_count }</p>
+ </button>
+ <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i>
+ <p class="count" if="{ p.repost_count &gt; 0 }">{ p.repost_count }</p>
+ </button>
+ <button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i>
+ <p class="count" if="{ p.likes_count &gt; 0 }">{ p.likes_count }</p>
+ </button>
+ <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button>
+ </footer>
+ <div class="reposts-and-likes">
+ <div class="reposts" if="{ reposts &amp;&amp; reposts.length &gt; 0 }">
+ <header><a>{ p.repost_count }</a>
+ <p>Repost</p>
+ </header>
+ <ol class="users">
+ <li class="user" each="{ reposts }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }" title="{ user.name }" data-user-preview="{ user.id }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&amp;size=32' }" alt=""/></a></li>
+ </ol>
+ </div>
+ <div class="likes" if="{ likes &amp;&amp; likes.length &gt; 0 }">
+ <header><a>{ p.likes_count }</a>
+ <p>いいね</p>
+ </header>
+ <ol class="users">
+ <li class="user" each="{ likes }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + username }" title="{ name }" data-user-preview="{ id }"><img class="avatar" src="{ avatar_url + '?thumbnail&amp;size=32' }" alt=""/></a></li>
+ </ol>
+ </div>
+ </div>
+ </article>
+ <div class="replies">
+ <virtual each="{ post in replies }">
+ <mk-post-detail-sub post="{ post }"></mk-post-detail-sub>
+ </virtual>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
+ width 640px
+ overflow hidden
+ background #fff
+ border solid 1px rgba(0, 0, 0, 0.1)
+ border-radius 8px
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username })
- img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ p.user.id })
- header
- a.name(href={ CONFIG.url + '/' + p.user.username }, data-user-preview={ p.user.id })
- | { p.user.name }
- span.username
- | @{ p.user.username }
- a.time(href={ url })
- mk-time(time={ p.created_at })
- div.body
- div.text@text
- div.media(if={ p.media })
- virtual(each={ file in p.media })
- img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name })
- footer
- button(onclick={ reply }, title='返信')
- i.fa.fa-reply
- p.count(if={ p.replies_count > 0 }) { p.replies_count }
- button(onclick={ repost }, title='Repost')
- i.fa.fa-retweet
- p.count(if={ p.repost_count > 0 }) { p.repost_count }
- button(class={ liked: p.is_liked }, onclick={ like }, title='善哉')
- i.fa.fa-thumbs-o-up
- p.count(if={ p.likes_count > 0 }) { p.likes_count }
- button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h
- div.reposts-and-likes
- div.reposts(if={ reposts && reposts.length > 0 })
- header
- a { p.repost_count }
- p Repost
- ol.users
- li.user(each={ reposts })
- a.avatar-anchor(href={ CONFIG.url + '/' + user.username }, title={ user.name }, data-user-preview={ user.id })
- img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='')
- div.likes(if={ likes && likes.length > 0 })
- header
- a { p.likes_count }
- p いいね
- ol.users
- li.user(each={ likes })
- a.avatar-anchor(href={ CONFIG.url + '/' + username }, title={ name }, data-user-preview={ id })
- img.avatar(src={ avatar_url + '?thumbnail&size=32' }, alt='')
+ > .fetching
+ padding 64px 0
- div.replies
- virtual(each={ post in replies })
- mk-post-detail-sub(post={ post })
+ > .main
-style.
- display block
- margin 0
- padding 0
- width 640px
- overflow hidden
- background #fff
- border solid 1px rgba(0, 0, 0, 0.1)
- border-radius 8px
+ > .read-more
+ display block
+ margin 0
+ padding 10px 0
+ width 100%
+ font-size 1em
+ text-align center
+ color #999
+ cursor pointer
+ background #fafafa
+ outline none
+ border none
+ border-bottom solid 1px #eef0f2
+ border-radius 6px 6px 0 0
- > .fetching
- padding 64px 0
+ &:hover
+ background #f6f6f6
- > .main
+ &:active
+ background #f0f0f0
- > .read-more
- display block
- margin 0
- padding 10px 0
- width 100%
- font-size 1em
- text-align center
- color #999
- cursor pointer
- background #fafafa
- outline none
- border none
- border-bottom solid 1px #eef0f2
- border-radius 6px 6px 0 0
+ &:disabled
+ color #ccc
- &:hover
- background #f6f6f6
+ > .context
+ > *
+ border-bottom 1px solid #eef0f2
- &:active
- background #f0f0f0
+ > .repost
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
- &:disabled
- color #ccc
+ > p
+ margin 0
+ padding 16px 32px
- > .context
- > *
- border-bottom 1px solid #eef0f2
+ .avatar-anchor
+ display inline-block
- > .repost
- color #9dbb00
- background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+ .avatar
+ vertical-align bottom
+ min-width 28px
+ min-height 28px
+ max-width 28px
+ max-height 28px
+ margin 0 8px 0 0
+ border-radius 6px
- > p
- margin 0
- padding 16px 32px
+ i
+ margin-right 4px
- .avatar-anchor
- display inline-block
+ .name
+ font-weight bold
- .avatar
- vertical-align bottom
- min-width 28px
- min-height 28px
- max-width 28px
- max-height 28px
- margin 0 8px 0 0
- border-radius 6px
+ & + article
+ padding-top 8px
- i
- margin-right 4px
+ > .reply-to
+ border-bottom 1px solid #eef0f2
- .name
- font-weight bold
+ > article
+ padding 28px 32px 18px 32px
- & + article
- padding-top 8px
+ &:after
+ content ""
+ display block
+ clear both
- > .reply-to
- border-bottom 1px solid #eef0f2
+ &:hover
+ > .main > footer > button
+ color #888
- > article
- padding 28px 32px 18px 32px
+ > .avatar-anchor
+ display block
+ width 60px
+ height 60px
- &:after
- content ""
- display block
- clear both
+ > .avatar
+ display block
+ width 60px
+ height 60px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- &:hover
- > .main > footer > button
- color #888
+ > header
+ position absolute
+ top 28px
+ left 108px
+ width calc(100% - 108px)
- > .avatar-anchor
- display block
- width 60px
- height 60px
+ > .name
+ display inline-block
+ margin 0
+ line-height 24px
+ color #777
+ font-size 18px
+ font-weight 700
+ text-align left
+ text-decoration none
- > .avatar
- display block
- width 60px
- height 60px
- margin 0
- border-radius 8px
- vertical-align bottom
+ &:hover
+ text-decoration underline
- > header
- position absolute
- top 28px
- left 108px
- width calc(100% - 108px)
+ > .username
+ display block
+ text-align left
+ margin 0
+ color #ccc
- > .name
- display inline-block
- margin 0
- line-height 24px
- color #777
- font-size 18px
- font-weight 700
- text-align left
- text-decoration none
+ > .time
+ position absolute
+ top 0
+ right 32px
+ font-size 1em
+ color #c0c0c0
- &:hover
- text-decoration underline
+ > .body
+ padding 8px 0
- > .username
- display block
- text-align left
- margin 0
- color #ccc
+ > .text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 1.5em
+ color #717171
- > .time
- position absolute
- top 0
- right 32px
- font-size 1em
- color #c0c0c0
+ > mk-url-preview
+ margin-top 8px
- > .body
- padding 8px 0
+ > .media
+ > img
+ display block
+ max-width 100%
- > .text
- cursor default
- display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 1.5em
- color #717171
+ > footer
+ font-size 1.2em
- > mk-url-preview
- margin-top 8px
+ > button
+ margin 0 28px 0 0
+ padding 8px
+ background transparent
+ border none
+ font-size 1em
+ color #ddd
+ cursor pointer
- > .media
- > img
- display block
- max-width 100%
+ &:hover
+ color #666
- > footer
- font-size 1.2em
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
- > button
- margin 0 28px 0 0
- padding 8px
- background transparent
- border none
- font-size 1em
- color #ddd
- cursor pointer
+ &.liked
+ color $theme-color
- &:hover
- color #666
-
- > .count
- display inline
- margin 0 0 0 8px
- color #999
+ > .reposts-and-likes
+ display flex
+ justify-content center
+ padding 0
+ margin 16px 0
- &.liked
- color $theme-color
+ &:empty
+ display none
- > .reposts-and-likes
- display flex
- justify-content center
- padding 0
- margin 16px 0
+ > .reposts
+ > .likes
+ display flex
+ flex 1 1
+ padding 0
+ border-top solid 1px #F2EFEE
- &:empty
- display none
+ > header
+ flex 1 1 80px
+ max-width 80px
+ padding 8px 5px 0px 10px
- > .reposts
- > .likes
- display flex
- flex 1 1
- padding 0
- border-top solid 1px #F2EFEE
+ > a
+ display block
+ font-size 1.5em
+ line-height 1.4em
- > header
- flex 1 1 80px
- max-width 80px
- padding 8px 5px 0px 10px
+ > p
+ display block
+ margin 0
+ font-size 0.7em
+ line-height 1em
+ font-weight normal
+ color #a0a2a5
- > a
- display block
- font-size 1.5em
- line-height 1.4em
+ > .users
+ display block
+ flex 1 1
+ margin 0
+ padding 10px 10px 10px 5px
+ list-style none
- > p
- display block
- margin 0
- font-size 0.7em
- line-height 1em
- font-weight normal
- color #a0a2a5
+ > .user
+ display block
+ float left
+ margin 4px
+ padding 0
- > .users
- display block
- flex 1 1
- margin 0
- padding 10px 10px 10px 5px
- list-style none
+ > .avatar-anchor
+ display:block
- > .user
- display block
- float left
- margin 4px
- padding 0
+ > .avatar
+ vertical-align bottom
+ width 24px
+ height 24px
+ border-radius 4px
- > .avatar-anchor
- display:block
+ > .reposts + .likes
+ margin-left 16px
- > .avatar
- vertical-align bottom
- width 24px
- height 24px
- border-radius 4px
+ > .replies
+ > *
+ border-top 1px solid #eef0f2
- > .reposts + .likes
- margin-left 16px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \text
+ @mixin \user-preview
+ @mixin \date-stringify
+ @mixin \NotImplementedException
- > .replies
- > *
- border-top 1px solid #eef0f2
+ @fetching = true
+ @loading-context = false
+ @content = null
+ @post = null
-script.
- @mixin \api
- @mixin \text
- @mixin \user-preview
- @mixin \date-stringify
- @mixin \NotImplementedException
+ @on \mount ~>
- @fetching = true
- @loading-context = false
- @content = null
- @post = null
+ @api \posts/show do
+ post_id: @opts.post
+ .then (post) ~>
+ @fetching = false
+ @post = post
+ @trigger \loaded
- @on \mount ~>
+ @is-repost = @post.repost?
+ @p = if @is-repost then @post.repost else @post
- @api \posts/show do
- post_id: @opts.post
- .then (post) ~>
- @fetching = false
- @post = post
- @trigger \loaded
+ @title = @date-stringify @p.created_at
- @is-repost = @post.repost?
- @p = if @is-repost then @post.repost else @post
+ @update!
- @title = @date-stringify @p.created_at
+ if @p.text?
+ tokens = @analyze @p.text
+ @refs.text.innerHTML = @compile tokens
- @update!
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \MK-URL
+ riot.mount e
- if @p.text?
- tokens = @analyze @p.text
- @refs.text.innerHTML = @compile tokens
+ # 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
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ # Get likes
+ @api \posts/likes do
+ post_id: @p.id
+ limit: 8
+ .then (likes) ~>
+ @likes = likes
+ @update!
- # 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
+ # Get reposts
+ @api \posts/reposts do
+ post_id: @p.id
+ limit: 8
+ .then (reposts) ~>
+ @reposts = reposts
+ @update!
- # Get likes
- @api \posts/likes do
- post_id: @p.id
- limit: 8
- .then (likes) ~>
- @likes = likes
- @update!
+ # Get replies
+ @api \posts/replies do
+ post_id: @p.id
+ limit: 8
+ .then (replies) ~>
+ @replies = replies
+ @update!
- # Get reposts
- @api \posts/reposts do
- post_id: @p.id
- limit: 8
- .then (reposts) ~>
- @reposts = reposts
@update!
- # Get replies
- @api \posts/replies do
- post_id: @p.id
- limit: 8
- .then (replies) ~>
- @replies = replies
- @update!
+ @reply = ~>
+ form = document.body.append-child document.create-element \mk-post-form-window
+ riot.mount form, do
+ reply: @p
- @update!
+ @repost = ~>
+ form = document.body.append-child document.create-element \mk-repost-form-window
+ riot.mount form, do
+ post: @p
- @reply = ~>
- form = document.body.append-child document.create-element \mk-post-form-window
- riot.mount form, do
- reply: @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!
- @repost = ~>
- form = document.body.append-child document.create-element \mk-repost-form-window
- riot.mount form, do
- post: @p
+ @load-context = ~>
+ @loading-context = true
- @like = ~>
- if @p.is_liked
- @api \posts/likes/delete do
- post_id: @p.id
- .then ~>
- @p.is_liked = false
+ # Get context
+ @api \posts/context do
+ post_id: @p.reply_to_id
+ .then (context) ~>
+ @context = context.reverse!
+ @loading-context = false
@update!
- else
- @api \posts/likes/create do
- post_id: @p.id
- .then ~>
- @p.is_liked = true
- @update!
-
- @load-context = ~>
- @loading-context = true
-
- # Get context
- @api \posts/context do
- post_id: @p.reply_to_id
- .then (context) ~>
- @context = context.reverse!
- @loading-context = false
- @update!
+ </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 8727777944..753dea1adb 100644
--- a/src/web/app/desktop/tags/post-form-window.tag
+++ b/src/web/app/desktop/tags/post-form-window.tag
@@ -1,60 +1,55 @@
-mk-post-form-window
+<mk-post-form-window>
+ <mk-window ref="window" is-modal="{ true }" colored="{ true }"><yield to="header"><span if="{ !parent.opts.reply }">新規投稿</span><span if="{ parent.opts.reply }">返信</span><span class="files" if="{ parent.files.length != 0 }">添付: { parent.files.length }ファイル</span><span class="uploading-files" if="{ parent.uploadingFiles.length != 0 }">{ parent.uploadingFiles.length }個のファイルをアップロード中
+ <mk-ellipsis></mk-ellipsis></span></yield>
+<yield to="content">
+ <div class="ref" if="{ parent.opts.reply }">
+ <mk-post-preview post="{ parent.opts.reply }"></mk-post-preview>
+ </div>
+ <div class="body">
+ <mk-post-form ref="form" reply="{ parent.opts.reply }"></mk-post-form>
+ </div></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
- mk-window@window(is-modal={ true }, colored={ true })
+ [data-yield='header']
+ > .files
+ > .uploading-files
+ margin-left 8px
+ opacity 0.8
- <yield to="header">
- span(if={ !parent.opts.reply }) 新規投稿
- span(if={ parent.opts.reply }) 返信
- span.files(if={ parent.files.length != 0 }) 添付: { parent.files.length }ファイル
- span.uploading-files(if={ parent.uploading-files.length != 0 })
- | { parent.uploading-files.length }個のファイルをアップロード中
- mk-ellipsis
- </yield>
+ &:before
+ content '('
- <yield to="content">
- div.ref(if={ parent.opts.reply })
- mk-post-preview(post={ parent.opts.reply })
- div.body
- mk-post-form@form(reply={ parent.opts.reply })
- </yield>
+ &:after
+ content ')'
-style.
- > mk-window
+ [data-yield='content']
+ > .ref
+ > mk-post-preview
+ margin 16px 22px
- [data-yield='header']
- > .files
- > .uploading-files
- margin-left 8px
- opacity 0.8
+ </style>
+ <script>
+ @uploading-files = []
+ @files = []
- &:before
- content '('
+ @on \mount ~>
+ @refs.window.refs.form.focus!
- &:after
- content ')'
+ @refs.window.on \closed ~>
+ @unmount!
- [data-yield='content']
- > .ref
- > mk-post-preview
- margin 16px 22px
+ @refs.window.refs.form.on \post ~>
+ @refs.window.close!
-script.
- @uploading-files = []
- @files = []
+ @refs.window.refs.form.on \change-uploading-files (files) ~>
+ @uploading-files = files
+ @update!
- @on \mount ~>
- @refs.window.refs.form.focus!
-
- @refs.window.on \closed ~>
- @unmount!
-
- @refs.window.refs.form.on \post ~>
- @refs.window.close!
-
- @refs.window.refs.form.on \change-uploading-files (files) ~>
- @uploading-files = files
- @update!
-
- @refs.window.refs.form.on \change-files (files) ~>
- @files = files
- @update!
+ @refs.window.refs.form.on \change-files (files) ~>
+ @files = files
+ @update!
+ </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 2248587885..3950d6cb07 100644
--- a/src/web/app/desktop/tags/post-form.tag
+++ b/src/web/app/desktop/tags/post-form.tag
@@ -1,430 +1,434 @@
-mk-post-form(ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop })
- textarea@text(disabled={ wait }, class={ withfiles: files.length != 0 }, oninput={ update }, onkeydown={ onkeydown }, onpaste={ onpaste }, placeholder={ opts.reply ? 'この投稿への返信...' : 'いまどうしてる?' })
- div.attaches(if={ files.length != 0 })
- ul.files@attaches
- li.file(each={ files })
- div.img(style='background-image: url({ url + "?thumbnail&size=64" })', title={ name })
- img.remove(onclick={ _remove }, src='/_/resources/desktop/remove.png', title='添付取り消し', alt='')
- li.add(if={ files.length < 4 }, title='PCからファイルを添付', onclick={ select-file }): i.fa.fa-plus
- p.remain
- | 残り{ 4 - files.length }
- mk-uploader@uploader
- button@upload(title='PCからファイルを添付', onclick={ select-file }): i.fa.fa-upload
- button@drive(title='ドライブからファイルを添付', onclick={ select-file-from-drive }): i.fa.fa-cloud
- p.text-count(class={ over: refs.text.value.length > 300 }) のこり{ 300 - refs.text.value.length }文字
- button@submit(class={ wait: wait }, disabled={ wait || (refs.text.value.length == 0 && files.length == 0) }, onclick={ post })
- | { wait ? '投稿中' : opts.reply ? '返信' : '投稿' }
- mk-ellipsis(if={ wait })
- input@file(type='file', accept='image/*', multiple, tabindex='-1', onchange={ change-file })
- div.dropzone(if={ draghover })
-
-style.
- display block
- padding 16px
- background lighten($theme-color, 95%)
-
- &:after
- content ""
- display block
- clear both
-
- > .attaches
- margin 0
- padding 0
- background lighten($theme-color, 98%)
- border solid 1px rgba($theme-color, 0.1)
- border-top none
- border-radius 0 0 4px 4px
- transition border-color .3s ease
-
- > .remain
+<mk-post-form ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }">
+ <textarea class="{ withfiles: files.length != 0 }" 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 }">
+ <div class="img" style="background-image: url({ url + &quot;?thumbnail&amp;size=64&quot; })" title="{ name }"></div><img class="remove" onclick="{ _remove }" src="/_/resources/desktop/remove.png" title="添付取り消し" alt=""/>
+ </li>
+ <li class="add" if="{ files.length &lt; 4 }" title="PCからファイルを添付" onclick="{ selectFile }"><i class="fa fa-plus"></i></li>
+ </ul>
+ <p class="remain">残り{ 4 - files.length }</p>
+ </div>
+ <mk-uploader ref="uploader"></mk-uploader>
+ <button ref="upload" title="PCからファイルを添付" onclick="{ selectFile }"><i class="fa fa-upload"></i></button>
+ <button ref="drive" title="ドライブからファイルを添付" onclick="{ selectFileFromDrive }"><i class="fa fa-cloud"></i></button>
+ <p class="text-count { over: refs.text.value.length &gt; 300 }">のこり{ 300 - refs.text.value.length }文字</p>
+ <button class="{ wait: wait }" ref="submit" disabled="{ wait || (refs.text.value.length == 0 &amp;&amp; files.length == 0) }" onclick="{ post }">{ wait ? '投稿中' : opts.reply ? '返信' : '投稿' }
+ <mk-ellipsis if="{ wait }"></mk-ellipsis>
+ </button>
+ <input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" onchange="{ changeFile }"/>
+ <div class="dropzone" if="{ draghover }"></div>
+ <style type="stylus">
+ :scope
display block
- position absolute
- top 8px
- right 8px
- margin 0
- padding 0
- color rgba($theme-color, 0.4)
-
- > .files
- display block
- margin 0
- padding 4px
- list-style none
+ padding 16px
+ background lighten($theme-color, 95%)
&:after
content ""
display block
clear both
- > .file
- display block
- float left
- margin 4px
+ > .attaches
+ margin 0
padding 0
- cursor move
+ background lighten($theme-color, 98%)
+ border solid 1px rgba($theme-color, 0.1)
+ border-top none
+ border-radius 0 0 4px 4px
+ transition border-color .3s ease
- &:hover > .remove
+ > .remain
display block
-
- > .img
- width 64px
- height 64px
- background-size cover
- background-position center center
-
- > .remove
- display none
position absolute
- top -6px
- right -6px
- width 16px
- height 16px
- cursor pointer
+ top 8px
+ right 8px
+ margin 0
+ padding 0
+ color rgba($theme-color, 0.4)
- > .add
- display block
- float left
- margin 4px
- padding 0
- border dashed 2px rgba($theme-color, 0.2)
- cursor pointer
+ > .files
+ display block
+ margin 0
+ padding 4px
+ list-style none
- &:hover
- border-color rgba($theme-color, 0.3)
+ &:after
+ content ""
+ display block
+ clear both
- > i
- color rgba($theme-color, 0.4)
+ > .file
+ display block
+ float left
+ margin 4px
+ padding 0
+ cursor move
- > i
- display block
- width 60px
- height 60px
- line-height 60px
- text-align center
- font-size 1.2em
- color rgba($theme-color, 0.2)
+ &:hover > .remove
+ display block
- > mk-uploader
- margin 8px 0 0 0
- padding 8px
- border solid 1px rgba($theme-color, 0.2)
- border-radius 4px
+ > .img
+ width 64px
+ height 64px
+ background-size cover
+ background-position center center
- [ref='file']
- display none
+ > .remove
+ display none
+ position absolute
+ top -6px
+ right -6px
+ width 16px
+ height 16px
+ cursor pointer
- [ref='text']
- display block
- padding 12px
- margin 0
- width 100%
- max-width 100%
- min-width 100%
- min-height calc(16px + 12px + 12px)
- font-size 16px
- color #333
- background #fff
- outline none
- border solid 1px rgba($theme-color, 0.1)
- border-radius 4px
- transition border-color .3s ease
+ > .add
+ display block
+ float left
+ margin 4px
+ padding 0
+ border dashed 2px rgba($theme-color, 0.2)
+ cursor pointer
- &:hover
- border-color rgba($theme-color, 0.2)
- transition border-color .1s ease
+ &:hover
+ border-color rgba($theme-color, 0.3)
- &:focus
- color $theme-color
- border-color rgba($theme-color, 0.5)
- transition border-color 0s ease
+ > i
+ color rgba($theme-color, 0.4)
- &:disabled
- opacity 0.5
+ > i
+ display block
+ width 60px
+ height 60px
+ line-height 60px
+ text-align center
+ font-size 1.2em
+ color rgba($theme-color, 0.2)
- &::-webkit-input-placeholder
- color rgba($theme-color, 0.3)
+ > mk-uploader
+ margin 8px 0 0 0
+ padding 8px
+ border solid 1px rgba($theme-color, 0.2)
+ border-radius 4px
- &.withfiles
- border-bottom solid 1px rgba($theme-color, 0.1) !important
- border-radius 4px 4px 0 0
+ [ref='file']
+ display none
- &:hover + .attaches
- border-color rgba($theme-color, 0.2)
- transition border-color .1s ease
+ [ref='text']
+ display block
+ padding 12px
+ margin 0
+ width 100%
+ max-width 100%
+ min-width 100%
+ min-height calc(16px + 12px + 12px)
+ font-size 16px
+ color #333
+ background #fff
+ outline none
+ border solid 1px rgba($theme-color, 0.1)
+ border-radius 4px
+ transition border-color .3s ease
- &:focus + .attaches
- border-color rgba($theme-color, 0.5)
- transition border-color 0s ease
+ &:hover
+ border-color rgba($theme-color, 0.2)
+ transition border-color .1s ease
- .text-count
- pointer-events none
- display block
- position absolute
- bottom 16px
- right 138px
- margin 0
- line-height 40px
- color rgba($theme-color, 0.5)
+ &:focus
+ color $theme-color
+ border-color rgba($theme-color, 0.5)
+ transition border-color 0s ease
- &.over
- color #ec3828
+ &:disabled
+ opacity 0.5
- [ref='submit']
- display block
- position absolute
- bottom 16px
- right 16px
- cursor pointer
- padding 0
- margin 0
- width 110px
- height 40px
- font-size 1em
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- outline none
- border solid 1px lighten($theme-color, 15%)
- border-radius 4px
+ &::-webkit-input-placeholder
+ color rgba($theme-color, 0.3)
- &:not(:disabled)
- font-weight bold
+ &.withfiles
+ border-bottom solid 1px rgba($theme-color, 0.1) !important
+ border-radius 4px 4px 0 0
- &:hover:not(:disabled)
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:hover + .attaches
+ border-color rgba($theme-color, 0.2)
+ transition border-color .1s ease
- &:active:not(:disabled)
- background $theme-color
- border-color $theme-color
+ &:focus + .attaches
+ border-color rgba($theme-color, 0.5)
+ transition border-color 0s ease
- &:focus
- &:after
- content ""
+ .text-count
pointer-events none
+ display block
position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ bottom 16px
+ right 138px
+ margin 0
+ line-height 40px
+ color rgba($theme-color, 0.5)
- &:disabled
- opacity 0.7
- cursor default
+ &.over
+ color #ec3828
- &.wait
- background linear-gradient(
- 45deg,
- darken($theme-color, 10%) 25%,
- $theme-color 25%,
- $theme-color 50%,
- darken($theme-color, 10%) 50%,
- darken($theme-color, 10%) 75%,
- $theme-color 75%,
- $theme-color
- )
- background-size 32px 32px
- animation stripe-bg 1.5s linear infinite
- opacity 0.7
- cursor wait
+ [ref='submit']
+ display block
+ position absolute
+ bottom 16px
+ right 16px
+ cursor pointer
+ padding 0
+ margin 0
+ width 110px
+ height 40px
+ font-size 1em
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ outline none
+ border solid 1px lighten($theme-color, 15%)
+ border-radius 4px
- @keyframes stripe-bg
- from {background-position: 0 0;}
- to {background-position: -64px 32px;}
+ &:not(:disabled)
+ font-weight bold
- [ref='upload']
- [ref='drive']
- display inline-block
- cursor pointer
- padding 0
- margin 8px 4px 0 0
- width 40px
- height 40px
- font-size 1em
- color rgba($theme-color, 0.5)
- background transparent
- outline none
- border solid 1px transparent
- border-radius 4px
+ &:hover:not(:disabled)
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- &:hover
- background transparent
- border-color rgba($theme-color, 0.3)
+ &:active:not(:disabled)
+ background $theme-color
+ border-color $theme-color
- &:active
- color rgba($theme-color, 0.6)
- background linear-gradient(to bottom, lighten($theme-color, 80%) 0%, lighten($theme-color, 90%) 100%)
- border-color rgba($theme-color, 0.5)
- box-shadow 0 2px 4px rgba(0, 0, 0, 0.15) inset
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- &:focus
- &:after
- content ""
- pointer-events none
- position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ &:disabled
+ opacity 0.7
+ cursor default
- > .dropzone
- position absolute
- left 0
- top 0
- width 100%
- height 100%
- border dashed 2px rgba($theme-color, 0.5)
- pointer-events none
+ &.wait
+ background linear-gradient(
+ 45deg,
+ darken($theme-color, 10%) 25%,
+ $theme-color 25%,
+ $theme-color 50%,
+ darken($theme-color, 10%) 50%,
+ darken($theme-color, 10%) 75%,
+ $theme-color 75%,
+ $theme-color
+ )
+ background-size 32px 32px
+ animation stripe-bg 1.5s linear infinite
+ opacity 0.7
+ cursor wait
-script.
- @mixin \api
- @mixin \notify
- @mixin \autocomplete
- @mixin \sortable
+ @keyframes stripe-bg
+ from {background-position: 0 0;}
+ to {background-position: -64px 32px;}
- @wait = false
- @uploadings = []
- @files = []
- @autocomplete = null
+ [ref='upload']
+ [ref='drive']
+ display inline-block
+ cursor pointer
+ padding 0
+ margin 8px 4px 0 0
+ width 40px
+ height 40px
+ font-size 1em
+ color rgba($theme-color, 0.5)
+ background transparent
+ outline none
+ border solid 1px transparent
+ border-radius 4px
- @in-reply-to-post = @opts.reply
+ &:hover
+ background transparent
+ border-color rgba($theme-color, 0.3)
- # https://github.com/riot/riot/issues/2080
- if @in-reply-to-post == '' then @in-reply-to-post = null
+ &:active
+ color rgba($theme-color, 0.6)
+ background linear-gradient(to bottom, lighten($theme-color, 80%) 0%, lighten($theme-color, 90%) 100%)
+ border-color rgba($theme-color, 0.5)
+ box-shadow 0 2px 4px rgba(0, 0, 0, 0.15) inset
- @on \mount ~>
- @refs.uploader.on \uploaded (file) ~>
- @add-file file
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- @refs.uploader.on \change-uploads (uploads) ~>
- @trigger \change-uploading-files uploads
+ > .dropzone
+ position absolute
+ left 0
+ top 0
+ width 100%
+ height 100%
+ border dashed 2px rgba($theme-color, 0.5)
+ pointer-events none
- @autocomplete = new @Autocomplete @refs.text
- @autocomplete.attach!
+ </style>
+ <script>
+ @mixin \api
+ @mixin \notify
+ @mixin \autocomplete
+ @mixin \sortable
- @on \unmount ~>
- @autocomplete.detach!
+ @wait = false
+ @uploadings = []
+ @files = []
+ @autocomplete = null
- @focus = ~>
- @refs.text.focus!
+ @in-reply-to-post = @opts.reply
- @clear = ~>
- @refs.text.value = ''
- @files = []
- @trigger \change-files
- @update!
+ # https://github.com/riot/riot/issues/2080
+ if @in-reply-to-post == '' then @in-reply-to-post = null
- @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
+ @on \mount ~>
+ @refs.uploader.on \uploaded (file) ~>
+ @add-file file
- @ondragenter = (e) ~>
- @draghover = true
+ @refs.uploader.on \change-uploads (uploads) ~>
+ @trigger \change-uploading-files uploads
- @ondragleave = (e) ~>
- @draghover = false
+ @autocomplete = new @Autocomplete @refs.text
+ @autocomplete.attach!
- @ondrop = (e) ~>
- e.prevent-default!
- e.stop-propagation!
- @draghover = false
+ @on \unmount ~>
+ @autocomplete.detach!
- # ファイルだったら
- if e.data-transfer.files.length > 0
- Array.prototype.for-each.call e.data-transfer.files, (file) ~>
- @upload file
- return false
+ @focus = ~>
+ @refs.text.focus!
- # データ取得
- data = e.data-transfer.get-data 'text'
- if !data?
+ @clear = ~>
+ @refs.text.value = ''
+ @files = []
+ @trigger \change-files
+ @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
- try
- # パース
- obj = JSON.parse data
+ @ondragenter = (e) ~>
+ @draghover = true
+
+ @ondragleave = (e) ~>
+ @draghover = false
- # (ドライブの)ファイルだったら
- if obj.type == \file
- @add-file obj.file
- catch
- # ignore
+ @ondrop = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
+ @draghover = false
- return false
+ # ファイルだったら
+ if e.data-transfer.files.length > 0
+ Array.prototype.for-each.call e.data-transfer.files, (file) ~>
+ @upload file
+ return false
- @onkeydown = (e) ~>
- if (e.which == 10 || e.which == 13) && (e.ctrl-key || e.meta-key)
- @post!
+ # データ取得
+ data = e.data-transfer.get-data 'text'
+ if !data?
+ return false
- @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!
+ try
+ # パース
+ obj = JSON.parse data
- @select-file = ~>
- @refs.file.click!
+ # (ドライブの)ファイルだったら
+ if obj.type == \file
+ @add-file obj.file
+ catch
+ # ignore
- @select-file-from-drive = ~>
- browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
- i = riot.mount browser, do
- multiple: true
- i[0].one \selected (files) ~>
- files.for-each @add-file
+ return false
- @change-file = ~>
- files = @refs.file.files
- for i from 0 to files.length - 1
- file = files.item i
- @upload file
+ @onkeydown = (e) ~>
+ if (e.which == 10 || e.which == 13) && (e.ctrl-key || e.meta-key)
+ @post!
- @upload = (file) ~>
- @refs.uploader.upload file
+ @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!
- @add-file = (file) ~>
- file._remove = ~>
- @files = @files.filter (x) -> x.id != file.id
- @trigger \change-files @files
- @update!
+ @select-file = ~>
+ @refs.file.click!
- @files.push file
- @trigger \change-files @files
- @update!
+ @select-file-from-drive = ~>
+ browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
+ i = riot.mount browser, do
+ multiple: true
+ i[0].one \selected (files) ~>
+ files.for-each @add-file
- new @Sortable @refs.attaches, do
- draggable: \.file
- animation: 150ms
+ @change-file = ~>
+ files = @refs.file.files
+ for i from 0 to files.length - 1
+ file = files.item i
+ @upload file
- @post = (e) ~>
- @wait = true
+ @upload = (file) ~>
+ @refs.uploader.upload file
- files = if @files? and @files.length > 0
- then @files.map (f) -> f.id
- else undefined
+ @add-file = (file) ~>
+ file._remove = ~>
+ @files = @files.filter (x) -> x.id != file.id
+ @trigger \change-files @files
+ @update!
- @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
- .then (data) ~>
- @trigger \post
- @notify if @in-reply-to-post? then '返信しました!' else '投稿しました!'
- .catch (err) ~>
- console.error err
- @notify '投稿できませんでした'
- .then ~>
- @wait = false
+ @files.push file
+ @trigger \change-files @files
@update!
+
+ new @Sortable @refs.attaches, do
+ draggable: \.file
+ animation: 150ms
+
+ @post = (e) ~>
+ @wait = true
+
+ files = if @files? and @files.length > 0
+ then @files.map (f) -> f.id
+ else 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
+ .then (data) ~>
+ @trigger \post
+ @notify if @in-reply-to-post? then '返信しました!' else '投稿しました!'
+ .catch (err) ~>
+ console.error err
+ @notify '投稿できませんでした'
+ .then ~>
+ @wait = false
+ @update!
+ </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 f17b152801..4035261782 100644
--- a/src/web/app/desktop/tags/post-preview.tag
+++ b/src/web/app/desktop/tags/post-preview.tag
@@ -1,94 +1,93 @@
-mk-post-preview(title={ title })
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
- img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id })
- div.main
- header
- a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id })
- | { post.user.name }
- span.username
- | @{ post.user.username }
- a.time(href={ CONFIG.url + '/' + post.user.username + '/' + post.id })
- mk-time(time={ post.created_at })
- div.body
- mk-sub-post-content.text(post={ post })
-
-style.
- display block
- margin 0
- padding 0
- font-size 0.9em
- background #fff
+<mk-post-preview title="{ title }">
+ <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar" data-user-preview="{ post.user_id }"/></a>
+ <div class="main">
+ <header><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="time" href="{ CONFIG.url + '/' + post.user.username + '/' + post.id }">
+ <mk-time time="{ post.created_at }"></mk-time></a></header>
+ <div class="body">
+ <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content>
+ </div>
+ </div>
+ </article>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
+ font-size 0.9em
+ background #fff
- > article
+ > article
- &:after
- content ""
- display block
- clear both
+ &:after
+ content ""
+ display block
+ clear both
- &:hover
- > .main > footer > button
- color #888
+ &:hover
+ > .main > footer > button
+ color #888
- > .avatar-anchor
- display block
- float left
- margin 0 16px 0 0
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 16px 0 0
- > .avatar
- display block
- width 52px
- height 52px
- margin 0
- border-radius 8px
- vertical-align bottom
+ > .avatar
+ display block
+ width 52px
+ height 52px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- > .main
- float left
- width calc(100% - 68px)
+ > .main
+ float left
+ width calc(100% - 68px)
- > header
- margin-bottom 4px
- white-space nowrap
+ > header
+ margin-bottom 4px
+ white-space nowrap
- > .name
- display inline
- margin 0
- padding 0
- color #607073
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #607073
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration underline
- > .username
- text-align left
- margin 0 0 0 8px
- color #d1d8da
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #d1d8da
- > .time
- position absolute
- top 0
- right 0
- color #b2b8bb
+ > .time
+ position absolute
+ top 0
+ right 0
+ color #b2b8bb
- > .body
+ > .body
- > .text
- cursor default
- margin 0
- padding 0
- font-size 1.1em
- color #717171
+ > .text
+ cursor default
+ margin 0
+ padding 0
+ font-size 1.1em
+ color #717171
-script.
- @mixin \date-stringify
- @mixin \user-preview
+ </style>
+ <script>
+ @mixin \date-stringify
+ @mixin \user-preview
- @post = @opts.post
+ @post = @opts.post
- @title = @date-stringify @post.created_at
+ @title = @date-stringify @post.created_at
+ </script>
+</mk-post-preview>
diff --git a/src/web/app/desktop/tags/post-status-graph.tag b/src/web/app/desktop/tags/post-status-graph.tag
index ffb081e4f3..c6cdb53b47 100644
--- a/src/web/app/desktop/tags/post-status-graph.tag
+++ b/src/web/app/desktop/tags/post-status-graph.tag
@@ -1,72 +1,75 @@
-mk-post-status-graph
- canvas@canv(width={ opts.width }, height={ opts.height })
+<mk-post-status-graph>
+ <canvas ref="canv" width="{ opts.width }" height="{ opts.height }"></canvas>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > canvas
+ margin 0 auto
- > canvas
- margin 0 auto
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
-script.
- @mixin \api
- @mixin \is-promise
+ @post = null
+ @post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post
- @post = null
- @post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post
+ @on \mount ~>
+ post <~ @post-promise.then
+ @post = post
+ @update!
- @on \mount ~>
- post <~ @post-promise.then
- @post = post
- @update!
-
- @api \aggregation/posts/like do
- post_id: @post.id
- limit: 30days
- .then (likes) ~>
- likes = likes.reverse!
-
- @api \aggregation/posts/repost do
+ @api \aggregation/posts/like do
post_id: @post.id
limit: 30days
- .then (repost) ~>
- repost = repost.reverse!
+ .then (likes) ~>
+ likes = likes.reverse!
- @api \aggregation/posts/reply do
+ @api \aggregation/posts/repost do
post_id: @post.id
limit: 30days
- .then (replies) ~>
- replies = replies.reverse!
+ .then (repost) ~>
+ repost = repost.reverse!
+
+ @api \aggregation/posts/reply do
+ post_id: @post.id
+ limit: 30days
+ .then (replies) ~>
+ replies = replies.reverse!
- new Chart @refs.canv, do
- type: \bar
- data:
- labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
- datasets: [
- {
- label: \いいね
- type: \line
- data: likes.map (x) ~> x.count
- line-tension: 0
- border-width: 2
- fill: true
- background-color: 'rgba(247, 121, 108, 0.2)'
- point-background-color: \#fff
- point-radius: 4
- point-border-width: 2
- border-color: \#F7796C
- },
- {
- label: \返信
- type: \bar
- data: replies.map (x) ~> x.count
- background-color: \#555
- },
- {
- label: \Repost
- type: \bar
- data: repost.map (x) ~> x.count
- background-color: \#a2d61e
- }
- ]
- options:
- responsive: false
+ new Chart @refs.canv, do
+ type: \bar
+ data:
+ labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
+ datasets: [
+ {
+ label: \いいね
+ type: \line
+ data: likes.map (x) ~> x.count
+ line-tension: 0
+ border-width: 2
+ fill: true
+ background-color: 'rgba(247, 121, 108, 0.2)'
+ point-background-color: \#fff
+ point-radius: 4
+ point-border-width: 2
+ border-color: \#F7796C
+ },
+ {
+ label: \返信
+ type: \bar
+ data: replies.map (x) ~> x.count
+ background-color: \#555
+ },
+ {
+ label: \Repost
+ type: \bar
+ data: repost.map (x) ~> x.count
+ background-color: \#a2d61e
+ }
+ ]
+ options:
+ responsive: false
+ </script>
+</mk-post-status-graph>
diff --git a/src/web/app/desktop/tags/progress-dialog.tag b/src/web/app/desktop/tags/progress-dialog.tag
index 7c042686e6..48b04d3442 100644
--- a/src/web/app/desktop/tags/progress-dialog.tag
+++ b/src/web/app/desktop/tags/progress-dialog.tag
@@ -1,92 +1,94 @@
-mk-progress-dialog
- mk-window@window(is-modal={ false }, can-close={ false }, width={ '500px' })
- <yield to="header">
- | { parent.title }
- mk-ellipsis
- </yield>
- <yield to="content">
- div.body
- p.init(if={ isNaN(parent.value) })
- | 待機中
- mk-ellipsis
- p.percentage(if={ !isNaN(parent.value) }) { Math.floor((parent.value / parent.max) * 100) }
- progress(if={ !isNaN(parent.value) && parent.value < parent.max }, value={ isNaN(parent.value) ? 0 : parent.value }, max={ parent.max })
- div.progress.waiting(if={ parent.value >= parent.max })
- </yield>
+<mk-progress-dialog>
+ <mk-window ref="window" is-modal="{ false }" can-close="{ false }" width="{ '500px' }">
+ <yield to="header">{ parent.title }
+ <mk-ellipsis></mk-ellipsis></yield>
+<yield to="content">
+ <div class="body">
+ <p class="init" if="{ isNaN(parent.value) }">待機中
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <p class="percentage" if="{ !isNaN(parent.value) }">{ Math.floor((parent.value / parent.max) * 100) }</p>
+ <progress if="{ !isNaN(parent.value) &amp;&amp; parent.value &lt; parent.max }" value="{ isNaN(parent.value) ? 0 : parent.value }" max="{ parent.max }"></progress>
+ <div class="progress waiting" if="{ parent.value &gt;= parent.max }"></div>
+ </div></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > mk-window
+ [data-yield='content']
- > mk-window
- [data-yield='content']
+ > .body
+ padding 18px 24px 24px 24px
- > .body
- padding 18px 24px 24px 24px
+ > .init
+ display block
+ margin 0
+ text-align center
+ color rgba(#000, 0.7)
- > .init
- display block
- margin 0
- text-align center
- color rgba(#000, 0.7)
+ > .percentage
+ display block
+ margin 0 0 4px 0
+ text-align center
+ line-height 16px
+ color rgba($theme-color, 0.7)
- > .percentage
- display block
- margin 0 0 4px 0
- text-align center
- line-height 16px
- color rgba($theme-color, 0.7)
+ &:after
+ content '%'
- &:after
- content '%'
+ > progress
+ > .progress
+ display block
+ margin 0
+ width 100%
+ height 10px
+ background transparent
+ border none
+ border-radius 4px
+ overflow hidden
- > progress
- > .progress
- display block
- margin 0
- width 100%
- height 10px
- background transparent
- border none
- border-radius 4px
- overflow hidden
+ &::-webkit-progress-value
+ background $theme-color
- &::-webkit-progress-value
- background $theme-color
+ &::-webkit-progress-bar
+ background rgba($theme-color, 0.1)
- &::-webkit-progress-bar
- background rgba($theme-color, 0.1)
+ > .progress
+ background linear-gradient(
+ 45deg,
+ lighten($theme-color, 30%) 25%,
+ $theme-color 25%,
+ $theme-color 50%,
+ lighten($theme-color, 30%) 50%,
+ lighten($theme-color, 30%) 75%,
+ $theme-color 75%,
+ $theme-color
+ )
+ background-size 32px 32px
+ animation progress-dialog-tag-progress-waiting 1.5s linear infinite
- > .progress
- background linear-gradient(
- 45deg,
- lighten($theme-color, 30%) 25%,
- $theme-color 25%,
- $theme-color 50%,
- lighten($theme-color, 30%) 50%,
- lighten($theme-color, 30%) 75%,
- $theme-color 75%,
- $theme-color
- )
- background-size 32px 32px
- animation progress-dialog-tag-progress-waiting 1.5s linear infinite
+ @keyframes progress-dialog-tag-progress-waiting
+ from {background-position: 0 0;}
+ to {background-position: -64px 32px;}
- @keyframes progress-dialog-tag-progress-waiting
- from {background-position: 0 0;}
- to {background-position: -64px 32px;}
+ </style>
+ <script>
+ @title = @opts.title
+ @value = parse-int @opts.value, 10
+ @max = parse-int @opts.max, 10
-script.
- @title = @opts.title
- @value = parse-int @opts.value, 10
- @max = parse-int @opts.max, 10
+ @on \mount ~>
+ @refs.window.on \closed ~>
+ @unmount!
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
+ @update-progress = (value, max) ~>
+ @value = parse-int value, 10
+ @max = parse-int max, 10
+ @update!
- @update-progress = (value, max) ~>
- @value = parse-int value, 10
- @max = parse-int max, 10
- @update!
-
- @close = ~>
- @refs.window.close!
+ @close = ~>
+ @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 40012f951f..a1008b475b 100644
--- a/src/web/app/desktop/tags/repost-form-window.tag
+++ b/src/web/app/desktop/tags/repost-form-window.tag
@@ -1,38 +1,36 @@
-mk-repost-form-window
- mk-window@window(is-modal={ true }, colored={ true })
- <yield to="header">
- i.fa.fa-retweet
- | この投稿をRepostしますか?
- </yield>
- <yield to="content">
- mk-repost-form@form(post={ parent.opts.post })
- </yield>
+<mk-repost-form-window>
+ <mk-window ref="window" is-modal="{ true }" colored="{ true }"><yield to="header"><i class="fa fa-retweet"></i>この投稿をRepostしますか?</yield>
+<yield to="content">
+ <mk-repost-form ref="form" post="{ parent.opts.post }"></mk-repost-form></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ </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!
-script.
-
- @on-document-keydown = (e) ~>
- tag = e.target.tag-name.to-lower-case!
- if tag != \input and tag != \textarea
- if e.which == 27 # Esc
+ @on \mount ~>
+ @refs.window.refs.form.on \cancel ~>
@refs.window.close!
- @on \mount ~>
- @refs.window.refs.form.on \cancel ~>
- @refs.window.close!
-
- @refs.window.refs.form.on \posted ~>
- @refs.window.close!
+ @refs.window.refs.form.on \posted ~>
+ @refs.window.close!
- document.add-event-listener \keydown @on-document-keydown
+ document.add-event-listener \keydown @on-document-keydown
- @refs.window.on \closed ~>
- @unmount!
+ @refs.window.on \closed ~>
+ @unmount!
- @on \unmount ~>
- document.remove-event-listener \keydown @on-document-keydown
+ @on \unmount ~>
+ document.remove-event-listener \keydown @on-document-keydown
+ </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 37fbad251d..0352cffc1b 100644
--- a/src/web/app/desktop/tags/repost-form.tag
+++ b/src/web/app/desktop/tags/repost-form.tag
@@ -1,140 +1,144 @@
-mk-repost-form
- mk-post-preview(post={ opts.post })
- div.form(if={ quote })
- textarea@text(disabled={ wait }, placeholder='この投稿を引用...')
- footer
- a.quote(if={ !quote }, onclick={ onquote }) 引用する...
- button.cancel(onclick={ cancel }) キャンセル
- button.ok(onclick={ ok }) Repost
+<mk-repost-form>
+ <mk-post-preview post="{ opts.post }"></mk-post-preview>
+ <div class="form" if="{ quote }">
+ <textarea ref="text" disabled="{ wait }" placeholder="この投稿を引用..."></textarea>
+ </div>
+ <footer><a class="quote" if="{ !quote }" onclick="{ onquote }">引用する...</a>
+ <button class="cancel" onclick="{ cancel }">キャンセル</button>
+ <button class="ok" onclick="{ ok }">Repost</button>
+ </footer>
+ <style type="stylus">
+ :scope
-style.
+ > mk-post-preview
+ margin 16px 22px
- > mk-post-preview
- margin 16px 22px
+ > .form
+ [ref='text']
+ display block
+ padding 12px
+ margin 0
+ width 100%
+ max-width 100%
+ min-width 100%
+ min-height calc(1em + 12px + 12px)
+ font-size 1em
+ color #333
+ background #fff
+ outline none
+ border solid 1px rgba($theme-color, 0.1)
+ border-radius 4px
+ transition border-color .3s ease
- > .form
- [ref='text']
- display block
- padding 12px
- margin 0
- width 100%
- max-width 100%
- min-width 100%
- min-height calc(1em + 12px + 12px)
- font-size 1em
- color #333
- background #fff
- outline none
- border solid 1px rgba($theme-color, 0.1)
- border-radius 4px
- transition border-color .3s ease
+ &:hover
+ border-color rgba($theme-color, 0.2)
+ transition border-color .1s ease
- &:hover
- border-color rgba($theme-color, 0.2)
- transition border-color .1s ease
+ &:focus
+ color $theme-color
+ border-color rgba($theme-color, 0.5)
+ transition border-color 0s ease
- &:focus
- color $theme-color
- border-color rgba($theme-color, 0.5)
- transition border-color 0s ease
+ &:disabled
+ opacity 0.5
- &:disabled
- opacity 0.5
+ &::-webkit-input-placeholder
+ color rgba($theme-color, 0.3)
- &::-webkit-input-placeholder
- color rgba($theme-color, 0.3)
+ > div
+ padding 16px
- > div
- padding 16px
+ > footer
+ height 72px
+ background lighten($theme-color, 95%)
- > footer
- height 72px
- background lighten($theme-color, 95%)
-
- > .quote
- position absolute
- bottom 16px
- left 28px
- line-height 40px
-
- button
- display block
- position absolute
- bottom 16px
- cursor pointer
- padding 0
- margin 0
- width 120px
- height 40px
- font-size 1em
- outline none
- border-radius 4px
+ > .quote
+ position absolute
+ bottom 16px
+ left 28px
+ line-height 40px
- &:focus
- &:after
- content ""
- pointer-events none
+ button
+ display block
position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ bottom 16px
+ cursor pointer
+ padding 0
+ margin 0
+ width 120px
+ height 40px
+ font-size 1em
+ outline none
+ border-radius 4px
+
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- > .cancel
- right 148px
- color #888
- background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
- border solid 1px #e2e2e2
+ > .cancel
+ right 148px
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
- &:hover
- background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
- border-color #dcdcdc
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
- &:active
- background #ececec
- border-color #dcdcdc
+ &:active
+ background #ececec
+ border-color #dcdcdc
- > .ok
- right 16px
- font-weight bold
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- border solid 1px lighten($theme-color, 15%)
+ > .ok
+ right 16px
+ font-weight bold
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
- &:hover
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:hover
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- &:active
- background $theme-color
- border-color $theme-color
+ &:active
+ background $theme-color
+ border-color $theme-color
-script.
- @mixin \api
- @mixin \notify
+ </style>
+ <script>
+ @mixin \api
+ @mixin \notify
- @wait = false
- @quote = false
+ @wait = false
+ @quote = false
- @cancel = ~>
- @trigger \cancel
+ @cancel = ~>
+ @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!
+ @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!
- @onquote = ~>
- @quote = true
+ @onquote = ~>
+ @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 9862ff6e4e..2d999e84ca 100644
--- a/src/web/app/desktop/tags/search-posts.tag
+++ b/src/web/app/desktop/tags/search-posts.tag
@@ -1,88 +1,86 @@
-mk-search-posts
- div.loading(if={ is-loading })
- mk-ellipsis-icon
- p.empty(if={ is-empty })
- i.fa.fa-search
- | 「{ query }」に関する投稿は見つかりませんでした。
- mk-timeline@timeline
- <yield to="footer">
- i.fa.fa-moon-o(if={ !parent.more-loading })
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
- </yield>
-
-style.
- display block
- background #fff
+<mk-search-posts>
+ <div class="loading" if="{ isLoading }">
+ <mk-ellipsis-icon></mk-ellipsis-icon>
+ </div>
+ <p class="empty" if="{ isEmpty }"><i class="fa fa-search"></i>「{ query }」に関する投稿は見つかりませんでした。</p>
+ <mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
- > .loading
- padding 64px 0
+ > .loading
+ padding 64px 0
- > .empty
- display block
- margin 0 auto
- padding 32px
- max-width 400px
- text-align center
- color #999
+ > .empty
+ display block
+ margin 0 auto
+ padding 32px
+ max-width 400px
+ text-align center
+ color #999
- > i
- display block
- margin-bottom 16px
- font-size 3em
- color #ccc
+ > i
+ display block
+ margin-bottom 16px
+ font-size 3em
+ color #ccc
-script.
- @mixin \api
- @mixin \get-post-summary
+ </style>
+ <script>
+ @mixin \api
+ @mixin \get-post-summary
- @query = @opts.query
- @is-loading = true
- @is-empty = false
- @more-loading = false
- @page = 0
+ @query = @opts.query
+ @is-loading = true
+ @is-empty = false
+ @more-loading = false
+ @page = 0
- @on \mount ~>
- document.add-event-listener \keydown @on-document-keydown
- window.add-event-listener \scroll @on-scroll
+ @on \mount ~>
+ document.add-event-listener \keydown @on-document-keydown
+ window.add-event-listener \scroll @on-scroll
- @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
+ @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
- @on \unmount ~>
- document.remove-event-listener \keydown @on-document-keydown
- window.remove-event-listener \scroll @on-scroll
+ @on \unmount ~>
+ document.remove-event-listener \keydown @on-document-keydown
+ window.remove-event-listener \scroll @on-scroll
- @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!
+ @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!
- @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++
+ @more = ~>
+ if @more-loading or @is-loading or @timeline.posts.length == 0
+ return
+ @more-loading = true
@update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
+ @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
- @on-scroll = ~>
- current = window.scroll-y + window.inner-height
- if current > document.body.offset-height - 16 # 遊び
- @more!
+ @on-scroll = ~>
+ current = window.scroll-y + window.inner-height
+ if current > document.body.offset-height - 16 # 遊び
+ @more!
+ </script>
+</mk-search-posts>
diff --git a/src/web/app/desktop/tags/search.tag b/src/web/app/desktop/tags/search.tag
index aec426ac79..1a9703016d 100644
--- a/src/web/app/desktop/tags/search.tag
+++ b/src/web/app/desktop/tags/search.tag
@@ -1,28 +1,32 @@
-mk-search
- header
- h1 { query }
- mk-search-posts@posts(query={ query })
+<mk-search>
+ <header>
+ <h1>{ query }</h1>
+ </header>
+ <mk-search-posts ref="posts" query="{ query }"></mk-search-posts>
+ <style type="stylus">
+ :scope
+ display block
+ padding-bottom 32px
-style.
- display block
- padding-bottom 32px
+ > header
+ width 100%
+ max-width 600px
+ margin 0 auto
+ color #555
- > header
- width 100%
- max-width 600px
- margin 0 auto
- color #555
+ > mk-search-posts
+ max-width 600px
+ margin 0 auto
+ border solid 1px rgba(0, 0, 0, 0.075)
+ border-radius 6px
+ overflow hidden
- > mk-search-posts
- max-width 600px
- margin 0 auto
- border solid 1px rgba(0, 0, 0, 0.075)
- border-radius 6px
- overflow hidden
+ </style>
+ <script>
+ @query = @opts.query
-script.
- @query = @opts.query
-
- @on \mount ~>
- @refs.posts.on \loaded ~>
- @trigger \loaded
+ @on \mount ~>
+ @refs.posts.on \loaded ~>
+ @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 5042944837..3293abb220 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
@@ -1,160 +1,161 @@
-mk-select-file-from-drive-window
- mk-window@window(is-modal={ true }, width={ '800px' }, height={ '500px' })
- <yield to="header">
- mk-raw(content={ parent.title })
- span.count(if={ parent.multiple && parent.file.length > 0 }) ({ parent.file.length }ファイル選択中)
- </yield>
- <yield to="content">
- mk-drive-browser@browser(multiple={ parent.multiple })
- div
- button.upload(title='PCからドライブにファイルをアップロード', onclick={ parent.upload }): i.fa.fa-upload
- button.cancel(onclick={ parent.close }) キャンセル
- button.ok(disabled={ parent.multiple && parent.file.length == 0 }, onclick={ parent.ok }) 決定
- </yield>
+<mk-select-file-from-drive-window>
+ <mk-window ref="window" is-modal="{ true }" width="{ '800px' }" height="{ '500px' }"><yield to="header">
+ <mk-raw content="{ parent.title }"></mk-raw><span class="count" if="{ parent.multiple &amp;&amp; parent.file.length &gt; 0 }">({ parent.file.length }ファイル選択中)</span></yield>
+<yield to="content">
+ <mk-drive-browser ref="browser" multiple="{ parent.multiple }"></mk-drive-browser>
+ <div>
+ <button class="upload" title="PCからドライブにファイルをアップロード" onclick="{ parent.upload }"><i class="fa fa-upload"></i></button>
+ <button class="cancel" onclick="{ parent.close }">キャンセル</button>
+ <button class="ok" disabled="{ parent.multiple &amp;&amp; parent.file.length == 0 }" onclick="{ parent.ok }">決定</button>
+ </div></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > mk-raw
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > mk-raw
- > i
- margin-right 4px
+ .count
+ margin-left 8px
+ opacity 0.7
- .count
- margin-left 8px
- opacity 0.7
+ [data-yield='content']
+ > mk-drive-browser
+ height calc(100% - 72px)
- [data-yield='content']
- > mk-drive-browser
- height calc(100% - 72px)
+ > div
+ height 72px
+ background lighten($theme-color, 95%)
- > div
- height 72px
- background lighten($theme-color, 95%)
+ .upload
+ display inline-block
+ position absolute
+ top 8px
+ left 16px
+ cursor pointer
+ padding 0
+ margin 8px 4px 0 0
+ width 40px
+ height 40px
+ font-size 1em
+ color rgba($theme-color, 0.5)
+ background transparent
+ outline none
+ border solid 1px transparent
+ border-radius 4px
- .upload
- display inline-block
- position absolute
- top 8px
- left 16px
- cursor pointer
- padding 0
- margin 8px 4px 0 0
- width 40px
- height 40px
- font-size 1em
- color rgba($theme-color, 0.5)
- background transparent
- outline none
- border solid 1px transparent
- border-radius 4px
+ &:hover
+ background transparent
+ border-color rgba($theme-color, 0.3)
- &:hover
- background transparent
- border-color rgba($theme-color, 0.3)
+ &:active
+ color rgba($theme-color, 0.6)
+ background transparent
+ border-color rgba($theme-color, 0.5)
+ box-shadow 0 2px 4px rgba(darken($theme-color, 50%), 0.15) inset
- &:active
- color rgba($theme-color, 0.6)
- background transparent
- border-color rgba($theme-color, 0.5)
- box-shadow 0 2px 4px rgba(darken($theme-color, 50%), 0.15) inset
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- &:focus
- &:after
- content ""
- pointer-events none
+ .ok
+ .cancel
+ display block
position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
+ bottom 16px
+ cursor pointer
+ padding 0
+ margin 0
+ width 120px
+ height 40px
+ font-size 1em
+ outline none
+ border-radius 4px
- .ok
- .cancel
- display block
- position absolute
- bottom 16px
- cursor pointer
- padding 0
- margin 0
- width 120px
- height 40px
- font-size 1em
- outline none
- border-radius 4px
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
- &:focus
- &:after
- content ""
- pointer-events none
- position absolute
- top -5px
- right -5px
- bottom -5px
- left -5px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 8px
-
- &:disabled
- opacity 0.7
- cursor default
+ &:disabled
+ opacity 0.7
+ cursor default
- .ok
- right 16px
- color $theme-color-foreground
- background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
- border solid 1px lighten($theme-color, 15%)
+ .ok
+ right 16px
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
- &:not(:disabled)
- font-weight bold
+ &:not(:disabled)
+ font-weight bold
- &:hover:not(:disabled)
- background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
- border-color $theme-color
+ &:hover:not(:disabled)
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
- &:active:not(:disabled)
- background $theme-color
- border-color $theme-color
+ &:active:not(:disabled)
+ background $theme-color
+ border-color $theme-color
- .cancel
- right 148px
- color #888
- background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
- border solid 1px #e2e2e2
+ .cancel
+ right 148px
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
- &:hover
- background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
- border-color #dcdcdc
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
- &:active
- background #ececec
- border-color #dcdcdc
+ &:active
+ background #ececec
+ border-color #dcdcdc
-script.
- @file = []
+ </style>
+ <script>
+ @file = []
- @multiple = if @opts.multiple? then @opts.multiple else false
- @title = @opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
+ @multiple = if @opts.multiple? then @opts.multiple else false
+ @title = @opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
- @on \mount ~>
- @refs.window.refs.browser.on \selected (file) ~>
- @file = file
- @ok!
+ @on \mount ~>
+ @refs.window.refs.browser.on \selected (file) ~>
+ @file = file
+ @ok!
- @refs.window.refs.browser.on \change-selection (files) ~>
- @file = files
- @update!
+ @refs.window.refs.browser.on \change-selection (files) ~>
+ @file = files
+ @update!
- @refs.window.on \closed ~>
- @unmount!
+ @refs.window.on \closed ~>
+ @unmount!
- @close = ~>
- @refs.window.close!
+ @close = ~>
+ @refs.window.close!
- @upload = ~>
- @refs.window.refs.browser.select-local-file!
+ @upload = ~>
+ @refs.window.refs.browser.select-local-file!
- @ok = ~>
- @trigger \selected @file
- @refs.window.close!
+ @ok = ~>
+ @trigger \selected @file
+ @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 68c9c310df..a8fc2a69ee 100644
--- a/src/web/app/desktop/tags/set-avatar-suggestion.tag
+++ b/src/web/app/desktop/tags/set-avatar-suggestion.tag
@@ -1,44 +1,46 @@
-mk-set-avatar-suggestion(onclick={ set })
- p
- b アバターを設定
- | してみませんか?
- button(onclick={ close }): i.fa.fa-times
-
-style.
- display block
- cursor pointer
- color #fff
- background #a8cad0
+<mk-set-avatar-suggestion onclick="{ set }">
+ <p><b>アバターを設定</b>してみませんか?
+ <button onclick="{ close }"><i class="fa fa-times"></i></button>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
+ cursor pointer
+ color #fff
+ background #a8cad0
- &:hover
- background #70abb5
+ &:hover
+ background #70abb5
- > p
- display block
- margin 0 auto
- padding 8px
- max-width 1024px
+ > p
+ display block
+ margin 0 auto
+ padding 8px
+ max-width 1024px
- > a
- font-weight bold
- color #fff
+ > a
+ font-weight bold
+ color #fff
- > button
- position absolute
- top 0
- right 0
- padding 8px
- color #fff
+ > button
+ position absolute
+ top 0
+ right 0
+ padding 8px
+ color #fff
-script.
- @mixin \i
- @mixin \update-avatar
+ </style>
+ <script>
+ @mixin \i
+ @mixin \update-avatar
- @set = ~>
- @update-avatar @I, (i) ~>
- @update-i i
+ @set = ~>
+ @update-avatar @I, (i) ~>
+ @update-i i
- @close = (e) ~>
- e.prevent-default!
- e.stop-propagation!
- @unmount!
+ @close = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
+ @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 bff0385803..ab4bbda047 100644
--- a/src/web/app/desktop/tags/set-banner-suggestion.tag
+++ b/src/web/app/desktop/tags/set-banner-suggestion.tag
@@ -1,44 +1,46 @@
-mk-set-banner-suggestion(onclick={ set })
- p
- b バナーを設定
- | してみませんか?
- button(onclick={ close }): i.fa.fa-times
-
-style.
- display block
- cursor pointer
- color #fff
- background #a8cad0
+<mk-set-banner-suggestion onclick="{ set }">
+ <p><b>バナーを設定</b>してみませんか?
+ <button onclick="{ close }"><i class="fa fa-times"></i></button>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
+ cursor pointer
+ color #fff
+ background #a8cad0
- &:hover
- background #70abb5
+ &:hover
+ background #70abb5
- > p
- display block
- margin 0 auto
- padding 8px
- max-width 1024px
+ > p
+ display block
+ margin 0 auto
+ padding 8px
+ max-width 1024px
- > a
- font-weight bold
- color #fff
+ > a
+ font-weight bold
+ color #fff
- > button
- position absolute
- top 0
- right 0
- padding 8px
- color #fff
+ > button
+ position absolute
+ top 0
+ right 0
+ padding 8px
+ color #fff
-script.
- @mixin \i
- @mixin \update-banner
+ </style>
+ <script>
+ @mixin \i
+ @mixin \update-banner
- @set = ~>
- @update-banner @I, (i) ~>
- @update-i i
+ @set = ~>
+ @update-banner @I, (i) ~>
+ @update-i i
- @close = (e) ~>
- e.prevent-default!
- e.stop-propagation!
- @unmount!
+ @close = (e) ~>
+ e.prevent-default!
+ e.stop-propagation!
+ @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 e259848718..6013f89673 100644
--- a/src/web/app/desktop/tags/settings-window.tag
+++ b/src/web/app/desktop/tags/settings-window.tag
@@ -1,26 +1,25 @@
-mk-settings-window
- mk-window@window(is-modal={ true }, width={ '700px' }, height={ '550px' })
- <yield to="header">
- i.fa.fa-cog
- | 設定
- </yield>
- <yield to="content">
- mk-settings
- </yield>
+<mk-settings-window>
+ <mk-window ref="window" is-modal="{ true }" width="{ '700px' }" height="{ '550px' }"><yield to="header"><i class="fa fa-cog"></i>設定</yield>
+<yield to="content">
+ <mk-settings></mk-settings></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > i
+ margin-right 4px
-style.
- > mk-window
- [data-yield='header']
- > i
- margin-right 4px
+ [data-yield='content']
+ overflow auto
- [data-yield='content']
- overflow auto
+ </style>
+ <script>
+ @on \mount ~>
+ @refs.window.on \closed ~>
+ @unmount!
-script.
- @on \mount ~>
- @refs.window.on \closed ~>
- @unmount!
-
- @close = ~>
- @refs.window.close!
+ @close = ~>
+ @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 ac47fbf792..7e7811df21 100644
--- a/src/web/app/desktop/tags/settings.tag
+++ b/src/web/app/desktop/tags/settings.tag
@@ -1,271 +1,266 @@
-mk-settings
- div.nav
- p(class={ active: page == 'account' }, onmousedown={ set-page.bind(null, 'account') })
- i.fa.fa-fw.fa-user
- | アカウント
- p(class={ active: page == 'web' }, onmousedown={ set-page.bind(null, 'web') })
- i.fa.fa-fw.fa-desktop
- | Web
- p(class={ active: page == 'notification' }, onmousedown={ set-page.bind(null, 'notification') })
- i.fa.fa-fw.fa-bell-o
- | 通知
- p(class={ active: page == 'drive' }, onmousedown={ set-page.bind(null, 'drive') })
- i.fa.fa-fw.fa-cloud
- | ドライブ
- p(class={ active: page == 'apps' }, onmousedown={ set-page.bind(null, 'apps') })
- i.fa.fa-fw.fa-puzzle-piece
- | アプリ
- p(class={ active: page == 'signin' }, onmousedown={ set-page.bind(null, 'signin') })
- i.fa.fa-fw.fa-sign-in
- | ログイン履歴
- p(class={ active: page == 'password' }, onmousedown={ set-page.bind(null, 'password') })
- i.fa.fa-fw.fa-unlock-alt
- | パスワード
- p(class={ active: page == 'api' }, onmousedown={ set-page.bind(null, 'api') })
- i.fa.fa-fw.fa-key
- | API
-
- div.pages
- section.account(show={ page == 'account' })
- h1 アカウント
- label.avatar
- p アバター
- img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- button.style-normal(onclick={ avatar }) 画像を選択
- label
- p 名前
- input@account-name(type='text', value={ I.name })
- label
- p 場所
- input@account-location(type='text', value={ I.location })
- label
- p 自己紹介
- textarea@account-bio { I.bio }
- label
- p 誕生日
- input@account-birthday(type='date', value={ I.birthday })
- button.style-primary(onclick={ update-account }) 保存
-
- section.web(show={ page == 'web' })
- h1 デザイン
- label
- p 壁紙
- button.style-normal(onclick={ wallpaper }) 画像を選択
- section.web(show={ page == 'web' })
- h1 その他
- label.checkbox
- input(type='checkbox', checked={ I.data.cache }, onclick={ update-cache })
- p 読み込みを高速化する
- p API通信時に新鮮なユーザー情報をキャッシュすることでフェッチのオーバーヘッドを無くします。(実験的)
- label.checkbox
- input(type='checkbox', checked={ I.data.debug }, onclick={ update-debug })
- p 開発者モード
- p デバッグ等の開発者モードを有効にします。
- label.checkbox
- input(type='checkbox', checked={ I.data.nya }, onclick={ update-nya })
- p <i>な</i>を<i>にゃ</i>に変換する
- p 攻撃的な投稿が多少和らぐ可能性があります。
-
- section.signin(show={ page == 'signin' })
- h1 ログイン履歴
- mk-signin-history
-
- section.api(show={ page == 'api' })
- h1 API
- p
- | Token:
- code { I.token }
- p APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。
- p アカウントを乗っ取られてしまう可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。
- p
- | 万が一このトークンが漏れたりその可能性がある場合は
- button.regenerate(onclick={ regenerate-token }) トークンを再生成
- | できます。(副作用として、ログインしているすべてのデバイスでログアウトが発生します)
-
-style.
- display block
+<mk-settings>
+ <div class="nav">
+ <p class="{ active: page == 'account' }" onmousedown="{ setPage.bind(null, 'account') }"><i class="fa fa-fw fa-user"></i>アカウント</p>
+ <p class="{ active: page == 'web' }" onmousedown="{ setPage.bind(null, 'web') }"><i class="fa fa-fw fa-desktop"></i>Web</p>
+ <p class="{ active: page == 'notification' }" onmousedown="{ setPage.bind(null, 'notification') }"><i class="fa fa-fw fa-bell-o"></i>通知</p>
+ <p class="{ active: page == 'drive' }" onmousedown="{ setPage.bind(null, 'drive') }"><i class="fa fa-fw fa-cloud"></i>ドライブ</p>
+ <p class="{ active: page == 'apps' }" onmousedown="{ setPage.bind(null, 'apps') }"><i class="fa fa-fw fa-puzzle-piece"></i>アプリ</p>
+ <p class="{ active: page == 'signin' }" onmousedown="{ setPage.bind(null, 'signin') }"><i class="fa fa-fw fa-sign-in"></i>ログイン履歴</p>
+ <p class="{ active: page == 'password' }" onmousedown="{ setPage.bind(null, 'password') }"><i class="fa fa-fw fa-unlock-alt"></i>パスワード</p>
+ <p class="{ active: page == 'api' }" onmousedown="{ setPage.bind(null, 'api') }"><i class="fa fa-fw fa-key"></i>API</p>
+ </div>
+ <div class="pages">
+ <section class="account" show="{ page == 'account' }">
+ <h1>アカウント</h1>
+ <label class="avatar">
+ <p>アバター</p><img class="avatar" src="{ I.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <button class="style-normal" onclick="{ avatar }">画像を選択</button>
+ </label>
+ <label>
+ <p>名前</p>
+ <input ref="accountName" type="text" value="{ I.name }"/>
+ </label>
+ <label>
+ <p>場所</p>
+ <input ref="accountLocation" type="text" value="{ I.location }"/>
+ </label>
+ <label>
+ <p>自己紹介</p>
+ <textarea ref="accountBio">{ I.bio }</textarea>
+ </label>
+ <label>
+ <p>誕生日</p>
+ <input ref="accountBirthday" type="date" value="{ I.birthday }"/>
+ </label>
+ <button class="style-primary" onclick="{ updateAccount }">保存</button>
+ </section>
+ <section class="web" show="{ page == 'web' }">
+ <h1>デザイン</h1>
+ <label>
+ <p>壁紙</p>
+ <button class="style-normal" onclick="{ wallpaper }">画像を選択</button>
+ </label>
+ </section>
+ <section class="web" show="{ page == 'web' }">
+ <h1>その他</h1>
+ <label class="checkbox">
+ <input type="checkbox" checked="{ I.data.cache }" onclick="{ updateCache }"/>
+ <p>読み込みを高速化する</p>
+ <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>
+ </label>
+ </section>
+ <section class="signin" show="{ page == 'signin' }">
+ <h1>ログイン履歴</h1>
+ <mk-signin-history></mk-signin-history>
+ </section>
+ <section class="api" show="{ page == 'api' }">
+ <h1>API</h1>
+ <p>Token:<code>{ I.token }</code></p>
+ <p>APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。</p>
+ <p>アカウントを乗っ取られてしまう可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。</p>
+ <p>万が一このトークンが漏れたりその可能性がある場合は
+ <button class="regenerate" onclick="{ regenerateToken }">トークンを再生成</button>できます。(副作用として、ログインしているすべてのデバイスでログアウトが発生します)
+ </p>
+ </section>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
- input:not([type])
- input[type='text']
- input[type='password']
- input[type='email']
- textarea
- padding 8px
- width 100%
- font-size 16px
- color #55595c
- border solid 1px #dadada
- border-radius 4px
+ input:not([type])
+ input[type='text']
+ input[type='password']
+ input[type='email']
+ textarea
+ padding 8px
+ width 100%
+ font-size 16px
+ color #55595c
+ border solid 1px #dadada
+ border-radius 4px
- &:hover
- border-color #aeaeae
+ &:hover
+ border-color #aeaeae
- &:focus
- border-color #aeaeae
+ &:focus
+ border-color #aeaeae
- > .nav
- position absolute
- top 0
- left 0
- width 200px
- height 100%
- padding 16px 0 0 0
- border-right solid 1px #ddd
+ > .nav
+ position absolute
+ top 0
+ left 0
+ width 200px
+ height 100%
+ padding 16px 0 0 0
+ border-right solid 1px #ddd
- > p
- display block
- padding 10px 16px
- margin 0
- color #666
- cursor pointer
+ > p
+ display block
+ padding 10px 16px
+ margin 0
+ color #666
+ cursor pointer
- -ms-user-select none
- -moz-user-select none
- -webkit-user-select none
- user-select none
+ -ms-user-select none
+ -moz-user-select none
+ -webkit-user-select none
+ user-select none
- transition margin-left 0.2s ease
+ transition margin-left 0.2s ease
- > i
- margin-right 4px
+ > i
+ margin-right 4px
- &:hover
- color #555
+ &:hover
+ color #555
- &.active
- margin-left 8px
- color $theme-color !important
+ &.active
+ margin-left 8px
+ color $theme-color !important
- > .pages
- position absolute
- top 0
- left 200px
- width calc(100% - 200px)
+ > .pages
+ position absolute
+ top 0
+ left 200px
+ width calc(100% - 200px)
- > section
- padding 32px
+ > section
+ padding 32px
- // & + section
- // margin-top 16px
+ // & + section
+ // margin-top 16px
- h1
- display block
- margin 0
- padding 0 0 8px 0
- font-size 1em
- color #555
- border-bottom solid 1px #eee
+ h1
+ display block
+ margin 0
+ padding 0 0 8px 0
+ font-size 1em
+ color #555
+ border-bottom solid 1px #eee
- label
- display block
- margin 16px 0
+ label
+ display block
+ margin 16px 0
- &:after
- content ""
- display block
- clear both
+ &:after
+ content ""
+ display block
+ clear both
- > p
- margin 0 0 8px 0
- font-weight bold
- color #373a3c
+ > p
+ margin 0 0 8px 0
+ font-weight bold
+ color #373a3c
- &.checkbox
- > input
- position absolute
- top 0
- left 0
+ &.checkbox
+ > input
+ position absolute
+ top 0
+ left 0
- &:checked + p
- color $theme-color
+ &:checked + p
+ color $theme-color
- > p
- width calc(100% - 32px)
- margin 0 0 0 32px
- font-weight bold
+ > p
+ width calc(100% - 32px)
+ margin 0 0 0 32px
+ font-weight bold
- &:last-child
- font-weight normal
- color #999
+ &:last-child
+ font-weight normal
+ color #999
- &.account
- > .general
- > .avatar
- > img
- display block
- float left
- width 64px
- height 64px
- border-radius 4px
+ &.account
+ > .general
+ > .avatar
+ > img
+ display block
+ float left
+ width 64px
+ height 64px
+ border-radius 4px
- > button
- float left
- margin-left 8px
+ > button
+ float left
+ margin-left 8px
- &.api
- code
- padding 4px
- background #eee
+ &.api
+ code
+ padding 4px
+ background #eee
- .regenerate
- display inline
- color $theme-color
+ .regenerate
+ display inline
+ color $theme-color
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration underline
-script.
- @mixin \i
- @mixin \api
- @mixin \dialog
- @mixin \update-avatar
- @mixin \update-wallpaper
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
+ @mixin \dialog
+ @mixin \update-avatar
+ @mixin \update-wallpaper
- @page = \account
+ @page = \account
- @set-page = (page) ~>
- @page = page
+ @set-page = (page) ~>
+ @page = page
- @avatar = ~>
- @update-avatar @I, (i) ~>
- @update-i i
+ @avatar = ~>
+ @update-avatar @I, (i) ~>
+ @update-i i
- @wallpaper = ~>
- @update-wallpaper @I, (i) ~>
- @update-i i
+ @wallpaper = ~>
+ @update-wallpaper @I, (i) ~>
+ @update-i i
- @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) ~>
- @update-i i
- alert \ok
- .catch (err) ~>
- console.error err
+ @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) ~>
+ @update-i i
+ alert \ok
+ .catch (err) ~>
+ console.error err
- @update-cache = ~>
- @I.data.cache = !@I.data.cache
- @api \i/appdata/set do
- data: JSON.stringify do
- cache: @I.data.cache
- .then ~>
- @update-i!
+ @update-cache = ~>
+ @I.data.cache = !@I.data.cache
+ @api \i/appdata/set do
+ data: JSON.stringify do
+ cache: @I.data.cache
+ .then ~>
+ @update-i!
- @update-debug = ~>
- @I.data.debug = !@I.data.debug
- @api \i/appdata/set do
- data: JSON.stringify do
- debug: @I.data.debug
- .then ~>
- @update-i!
+ @update-debug = ~>
+ @I.data.debug = !@I.data.debug
+ @api \i/appdata/set do
+ data: JSON.stringify do
+ debug: @I.data.debug
+ .then ~>
+ @update-i!
- @update-nya = ~>
- @I.data.nya = !@I.data.nya
- @api \i/appdata/set do
- data: JSON.stringify do
- nya: @I.data.nya
- .then ~>
- @update-i!
+ @update-nya = ~>
+ @I.data.nya = !@I.data.nya
+ @api \i/appdata/set do
+ data: JSON.stringify do
+ nya: @I.data.nya
+ .then ~>
+ @update-i!
+ </script>
+</mk-settings>
diff --git a/src/web/app/desktop/tags/signin-history.tag b/src/web/app/desktop/tags/signin-history.tag
index 311f8bfeda..bd6006965f 100644
--- a/src/web/app/desktop/tags/signin-history.tag
+++ b/src/web/app/desktop/tags/signin-history.tag
@@ -1,73 +1,75 @@
-mk-signin-history
- div.records(if={ history.length != 0 })
- div(each={ history })
- mk-time(time={ created_at })
- header
- i.fa.fa-check(if={ success })
- i.fa.fa-times(if={ !success })
- span.ip { ip }
- pre: code { JSON.stringify(headers, null, ' ') }
+<mk-signin-history>
+ <div class="records" if="{ history.length != 0 }">
+ <div each="{ history }">
+ <mk-time time="{ created_at }"></mk-time>
+ <header><i class="fa fa-check" if="{ success }"></i><i class="fa fa-times" if="{ !success }"></i><span class="ip">{ ip }</span></header>
+ <pre><code>{ JSON.stringify(headers, null, ' ') }</code></pre>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > .records
+ > div
+ padding 16px 0 0 0
+ border-bottom solid 1px #eee
- > .records
- > div
- padding 16px 0 0 0
- border-bottom solid 1px #eee
+ > header
- > header
+ > i
+ margin-right 8px
- > i
- margin-right 8px
+ &.fa-check
+ color #0fda82
- &.fa-check
- color #0fda82
+ &.fa-times
+ color #ff3100
- &.fa-times
- color #ff3100
+ > .ip
+ display inline-block
+ color #444
+ background #f8f8f8
- > .ip
- display inline-block
- color #444
- background #f8f8f8
+ > mk-time
+ position absolute
+ top 16px
+ right 0
+ color #777
- > mk-time
- position absolute
- top 16px
- right 0
- color #777
+ > pre
+ overflow auto
+ max-height 100px
- > pre
- overflow auto
- max-height 100px
+ > code
+ white-space pre-wrap
+ word-break break-all
+ color #4a535a
- > code
- white-space pre-wrap
- word-break break-all
- color #4a535a
+ </style>
+ <script>
+ @mixin \api
+ @mixin \stream
-script.
- @mixin \api
- @mixin \stream
+ @history = []
+ @fetching = true
- @history = []
- @fetching = true
+ @on \mount ~>
+ @api \i/signin_history
+ .then (history) ~>
+ @history = history
+ @fetching = false
+ @update!
+ .catch (err) ~>
+ console.error err
- @on \mount ~>
- @api \i/signin_history
- .then (history) ~>
- @history = history
- @fetching = false
- @update!
- .catch (err) ~>
- console.error err
-
- @stream.on \signin @on-signin
+ @stream.on \signin @on-signin
- @on \unmount ~>
- @stream.off \signin @on-signin
+ @on \unmount ~>
+ @stream.off \signin @on-signin
- @on-signin = (signin) ~>
- @history.unshift signin
- @update!
+ @on-signin = (signin) ~>
+ @history.unshift signin
+ @update!
+ </script>
+</mk-signin-history>
diff --git a/src/web/app/desktop/tags/stream-indicator.tag b/src/web/app/desktop/tags/stream-indicator.tag
index 2eb5889ca6..4046f5fec4 100644
--- a/src/web/app/desktop/tags/stream-indicator.tag
+++ b/src/web/app/desktop/tags/stream-indicator.tag
@@ -1,59 +1,54 @@
-mk-stream-indicator
- p(if={ state == 'initializing' })
- i.fa.fa-spinner.fa-spin
- span
- | 接続中
- mk-ellipsis
- p(if={ state == 'reconnecting' })
- i.fa.fa-spinner.fa-spin
- span
- | 切断されました 接続中
- mk-ellipsis
- p(if={ state == 'connected' })
- i.fa.fa-check
- span 接続完了
+<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 type="stylus">
+ :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)
-style.
- 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
- > p
- display block
- margin 0
+ > i
+ margin-right 0.25em
- > i
- margin-right 0.25em
+ </style>
+ <script>
+ @mixin \stream
-script.
- @mixin \stream
+ @on \before-mount ~>
+ @state = @get-stream-state!
- @on \before-mount ~>
- @state = @get-stream-state!
+ if @state == \connected
+ @root.style.opacity = 0
- 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 \connected ~>
- @state = @get-stream-state!
- @update!
- set-timeout ~>
+ @stream-state-ev.on \closed ~>
+ @state = @get-stream-state!
+ @update!
Velocity @root, {
- opacity: 0
- } 200ms \linear
- , 1000ms
-
- @stream-state-ev.on \closed ~>
- @state = @get-stream-state!
- @update!
- Velocity @root, {
- opacity: 1
- } 0ms
+ 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 976a6f398f..5b4497fda6 100644
--- a/src/web/app/desktop/tags/sub-post-content.tag
+++ b/src/web/app/desktop/tags/sub-post-content.tag
@@ -1,37 +1,38 @@
-mk-sub-post-content
- div.body
- a.reply(if={ post.reply_to_id }): i.fa.fa-reply
- span@text
- a.quote(if={ post.repost_id }, href={ '/post:' + post.repost_id }) RP: ...
- details(if={ post.media })
- summary ({ post.media.length }枚の画像)
- mk-images-viewer(images={ post.media })
+<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>
+ <details if="{ post.media }">
+ <summary>({ post.media.length }枚の画像)</summary>
+ <mk-images-viewer images="{ post.media }"></mk-images-viewer>
+ </details>
+ <style type="stylus">
+ :scope
+ display block
+ word-wrap break-word
-style.
- display block
- word-wrap break-word
+ > .body
+ > .reply
+ margin-right 6px
+ color #717171
- > .body
- > .reply
- margin-right 6px
- color #717171
+ > .quote
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
- > .quote
- margin-left 4px
- font-style oblique
- color #a0bf46
+ </style>
+ <script>
+ @mixin \text
+ @mixin \user-preview
-script.
- @mixin \text
- @mixin \user-preview
+ @post = @opts.post
- @post = @opts.post
+ @on \mount ~>
+ if @post.text?
+ tokens = @analyze @post.text
+ @refs.text.innerHTML = @compile tokens, false
- @on \mount ~>
- if @post.text?
- tokens = @analyze @post.text
- @refs.text.innerHTML = @compile tokens, false
-
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \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 39b1ad7f71..a9a13e9f9c 100644
--- a/src/web/app/desktop/tags/timeline-post-sub.tag
+++ b/src/web/app/desktop/tags/timeline-post-sub.tag
@@ -1,95 +1,99 @@
-mk-timeline-post-sub(title={ title })
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
- img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id })
- div.main
- header
- a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id })
- | { post.user.name }
- span.username
- | @{ post.user.username }
- a.created-at(href={ CONFIG.url + '/' + post.user.username + '/' + post.id })
- mk-time(time={ post.created_at })
- div.body
- mk-sub-post-content.text(post={ post })
+<mk-timeline-post-sub title="{ title }">
+ <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar" data-user-preview="{ post.user_id }"/></a>
+ <div class="main">
+ <header><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="created-at" href="{ CONFIG.url + '/' + post.user.username + '/' + post.id }">
+ <mk-time time="{ post.created_at }"></mk-time></a></header>
+ <div class="body">
+ <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content>
+ </div>
+ </div>
+ </article>
+ <script>
+ @mixin \date-stringify
+ @mixin \user-preview
-script.
- @mixin \date-stringify
- @mixin \user-preview
+ @post = @opts.post
- @post = @opts.post
+ @title = @date-stringify @post.created_at
- @title = @date-stringify @post.created_at
+ </script>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
+ font-size 0.9em
-style.
- display block
- margin 0
- padding 0
- font-size 0.9em
+ > article
+ padding 16px
- > article
- padding 16px
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ &:hover
+ > .main > footer > button
+ color #888
- &:hover
- > .main > footer > button
- color #888
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 14px 0 0
- > .avatar-anchor
- display block
- float left
- margin 0 14px 0 0
+ > .avatar
+ display block
+ width 52px
+ height 52px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
+
+ > .main
+ float left
+ width calc(100% - 66px)
+
+ > header
+ margin-bottom 4px
+ white-space nowrap
+ line-height 21px
- > .avatar
- display block
- width 52px
- height 52px
- margin 0
- border-radius 8px
- vertical-align bottom
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #607073
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- > .main
- float left
- width calc(100% - 66px)
+ &:hover
+ text-decoration underline
- > header
- margin-bottom 4px
- white-space nowrap
- line-height 21px
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #d1d8da
- > .name
- display inline
- margin 0
- padding 0
- color #607073
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ > .created-at
+ position absolute
+ top 0
+ right 0
+ color #b2b8bb
- &:hover
- text-decoration underline
+ > .body
- > .username
- text-align left
- margin 0 0 0 8px
- color #d1d8da
+ > .text
+ cursor default
+ margin 0
+ padding 0
+ font-size 1.1em
+ color #717171
- > .created-at
- position absolute
- top 0
- right 0
- color #b2b8bb
+
- > .body
+
- > .text
- cursor default
- margin 0
- padding 0
- font-size 1.1em
- color #717171
+ </style>
+</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 8b90f0d013..77d695c365 100644
--- a/src/web/app/desktop/tags/timeline-post.tag
+++ b/src/web/app/desktop/tags/timeline-post.tag
@@ -1,376 +1,332 @@
-mk-timeline-post(tabindex='-1', title={ title }, onkeydown={ on-key-down })
-
- div.reply-to(if={ p.reply_to })
- mk-timeline-post-sub(post={ p.reply_to })
-
- div.repost(if={ is-repost })
- p
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=32' }, alt='avatar')
- i.fa.fa-retweet
- a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }) { post.user.name }
- | がRepost
- mk-time(time={ post.created_at })
-
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username })
- img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ p.user.id })
- div.main
- header
- a.name(href={ CONFIG.url + '/' + p.user.username }, data-user-preview={ p.user.id })
- | { p.user.name }
- span.username
- | @{ p.user.username }
- a.created-at(href={ url })
- mk-time(time={ p.created_at })
- div.body
- div.text
- a.reply(if={ p.reply_to }): i.fa.fa-reply
- span@text
- a.quote(if={ p.repost != null }) RP:
- div.media(if={ p.media })
- mk-images-viewer(images={ p.media })
- div.repost(if={ p.repost })
- i.fa.fa-quote-right.fa-flip-horizontal
- mk-post-preview.repost(post={ p.repost })
- footer
- button(onclick={ reply }, title='返信')
- i.fa.fa-reply
- p.count(if={ p.replies_count > 0 }) { p.replies_count }
- button(onclick={ repost }, title='Repost')
- i.fa.fa-retweet
- p.count(if={ p.repost_count > 0 }) { p.repost_count }
- button(class={ liked: p.is_liked }, onclick={ like }, title='善哉')
- i.fa.fa-thumbs-o-up
- p.count(if={ p.likes_count > 0 }) { p.likes_count }
- button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h
- button(onclick={ toggle-detail }, title='詳細')
- i.fa.fa-caret-down(if={ !is-detail-opened })
- i.fa.fa-caret-up(if={ is-detail-opened })
- div.detail(if={ is-detail-opened })
- mk-post-status-graph(width='462', height='130', post={ p })
-
-style.
- display block
- margin 0
- padding 0
- background #fff
-
- &:focus
- z-index 1
-
- &:after
- content ""
- pointer-events none
- position absolute
- top 2px
- right 2px
- bottom 2px
- left 2px
- border 2px solid rgba($theme-color, 0.3)
- border-radius 4px
-
- > .repost
- color #9dbb00
- background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
-
- > p
+<mk-timeline-post tabindex="-1" title="{ title }" onkeydown="{ onKeyDown }">
+ <div class="reply-to" if="{ p.reply_to }">
+ <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 }" data-user-preview="{ post.user_id }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=32' }" alt="avatar"/></a><i class="fa fa-retweet"></i><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ 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&amp;size=64' }" alt="avatar" data-user-preview="{ p.user.id }"/></a>
+ <div class="main">
+ <header><a class="name" href="{ CONFIG.url + '/' + p.user.username }" data-user-preview="{ p.user.id }">{ p.user.name }</a><span class="username">@{ p.user.username }</span><a class="created-at" href="{ url }">
+ <mk-time time="{ p.created_at }"></mk-time></a></header>
+ <div class="body">
+ <div class="text"><a class="reply" if="{ p.reply_to }"><i class="fa fa-reply"></i></a><span ref="text"></span><a class="quote" if="{ p.repost != null }">RP:</a></div>
+ <div class="media" if="{ p.media }">
+ <mk-images-viewer images="{ p.media }"></mk-images-viewer>
+ </div>
+ <div class="repost" if="{ p.repost }"><i class="fa fa-quote-right fa-flip-horizontal"></i>
+ <mk-post-preview class="repost" post="{ p.repost }"></mk-post-preview>
+ </div>
+ </div>
+ <footer>
+ <button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i>
+ <p class="count" if="{ p.replies_count &gt; 0 }">{ p.replies_count }</p>
+ </button>
+ <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i>
+ <p class="count" if="{ p.repost_count &gt; 0 }">{ p.repost_count }</p>
+ </button>
+ <button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i>
+ <p class="count" if="{ p.likes_count &gt; 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>
+ </footer>
+ </div>
+ </article>
+ <div class="detail" if="{ isDetailOpened }">
+ <mk-post-status-graph width="462" height="130" post="{ p }"></mk-post-status-graph>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
margin 0
- padding 16px 32px
- line-height 28px
+ padding 0
+ background #fff
- .avatar-anchor
- display inline-block
+ &:focus
+ z-index 1
- .avatar
- vertical-align bottom
- width 28px
- height 28px
- margin 0 8px 0 0
- border-radius 6px
-
- i
- margin-right 4px
-
- .name
- font-weight bold
-
- > mk-time
- position absolute
- top 16px
- right 32px
- font-size 0.9em
- line-height 28px
-
- & + article
- padding-top 8px
-
- > .reply-to
- padding 0 16px
- background rgba(0, 0, 0, 0.0125)
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top 2px
+ right 2px
+ bottom 2px
+ left 2px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 4px
- > mk-post-preview
- background transparent
+ > .repost
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
- > article
- padding 28px 32px 18px 32px
+ > p
+ margin 0
+ padding 16px 32px
+ line-height 28px
- &:after
- content ""
- display block
- clear both
+ .avatar-anchor
+ display inline-block
- &:hover
- > .main > footer > button
- color #888
+ .avatar
+ vertical-align bottom
+ width 28px
+ height 28px
+ margin 0 8px 0 0
+ border-radius 6px
- > .avatar-anchor
- display block
- float left
- margin 0 16px 0 0
+ i
+ margin-right 4px
- > .avatar
- display block
- width 58px
- height 58px
- margin 0
- border-radius 8px
- vertical-align bottom
+ .name
+ font-weight bold
- > .main
- float left
- width calc(100% - 74px)
+ > mk-time
+ position absolute
+ top 16px
+ right 32px
+ font-size 0.9em
+ line-height 28px
- > header
- margin-bottom 4px
- white-space nowrap
- line-height 24px
+ & + article
+ padding-top 8px
- > .name
- display inline
- margin 0
- padding 0
- color #777
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ > .reply-to
+ padding 0 16px
+ background rgba(0, 0, 0, 0.0125)
- &:hover
- text-decoration underline
+ > mk-post-preview
+ background transparent
- > .username
- text-align left
- margin 0 0 0 8px
- color #ccc
+ > article
+ padding 28px 32px 18px 32px
- > .created-at
- position absolute
- top 0
- right 0
- font-size 0.9em
- color #c0c0c0
+ &:after
+ content ""
+ display block
+ clear both
- > .body
+ &:hover
+ > .main > footer > button
+ color #888
- > .text
- cursor default
+ > .avatar-anchor
display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 1.1em
- color #717171
-
- mk-url-preview
- margin-top 8px
+ float left
+ margin 0 16px 0 0
- > .reply
- margin-right 8px
- color #717171
+ > .avatar
+ display block
+ width 58px
+ height 58px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- > .quote
- margin-left 4px
- font-style oblique
- color #a0bf46
+ > .main
+ float left
+ width calc(100% - 74px)
- > .media
- > img
- display block
- max-width 100%
+ > header
+ margin-bottom 4px
+ white-space nowrap
+ line-height 24px
- > .repost
- margin 8px 0
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #777
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- > i:first-child
- position absolute
- top -8px
- left -8px
- z-index 1
- color #c0dac6
- font-size 28px
- background #fff
+ &:hover
+ text-decoration underline
- > mk-post-preview
- padding 16px
- border dashed 1px #c0dac6
- border-radius 8px
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #ccc
- > footer
- > button
- margin 0 28px 0 0
- padding 0 8px
- line-height 32px
- font-size 1em
- color #ddd
- background transparent
- border none
- cursor pointer
+ > .created-at
+ position absolute
+ top 0
+ right 0
+ font-size 0.9em
+ color #c0c0c0
- &:hover
- color #666
+ > .body
- > .count
- display inline
- margin 0 0 0 8px
- color #999
+ > .text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 1.1em
+ color #717171
- &.liked
- color $theme-color
+ mk-url-preview
+ margin-top 8px
- &:last-child
- position absolute
- right 0
- margin 0
+ > .reply
+ margin-right 8px
+ color #717171
- > .detail
- padding-top 4px
- background rgba(0, 0, 0, 0.0125)
+ > .quote
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
-style(theme='dark').
- background #0D0D0D
+ > .media
+ > img
+ display block
+ max-width 100%
- > article
+ > .repost
+ margin 8px 0
- &:hover
- > .main > footer > button
- color #eee
+ > i:first-child
+ position absolute
+ top -8px
+ left -8px
+ z-index 1
+ color #c0dac6
+ font-size 28px
+ background #fff
- > .main
- > header
- > .left
- > .name
- color #9e9c98
+ > mk-post-preview
+ padding 16px
+ border dashed 1px #c0dac6
+ border-radius 8px
- > .username
- color #41403f
+ > footer
+ > button
+ margin 0 28px 0 0
+ padding 0 8px
+ line-height 32px
+ font-size 1em
+ color #ddd
+ background transparent
+ border none
+ cursor pointer
- > .right
- > .time
- color #4e4d4b
+ &:hover
+ color #666
- > .body
- > .text
- color #9e9c98
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
- > footer
- > button
- color #9e9c98
+ &.liked
+ color $theme-color
- &:hover
- color #fff
+ &:last-child
+ position absolute
+ right 0
+ margin 0
- > .count
- color #eee
+ > .detail
+ padding-top 4px
+ background rgba(0, 0, 0, 0.0125)
-script.
- @mixin \api
- @mixin \text
- @mixin \date-stringify
- @mixin \user-preview
- @mixin \NotImplementedException
+ </style>
+ <script>
+ @mixin \api
+ @mixin \text
+ @mixin \date-stringify
+ @mixin \user-preview
+ @mixin \NotImplementedException
- @post = @opts.post
- @is-repost = @post.repost? and !@post.text?
- @p = if @is-repost then @post.repost else @post
+ @post = @opts.post
+ @is-repost = @post.repost? and !@post.text?
+ @p = if @is-repost then @post.repost else @post
- @title = @date-stringify @p.created_at
+ @title = @date-stringify @p.created_at
- @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
- @is-detail-opened = false
+ @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
+ @is-detail-opened = false
- @on \mount ~>
- if @p.text?
- tokens = if @p._highlight?
- then @analyze @p._highlight
- else @analyze @p.text
+ @on \mount ~>
+ if @p.text?
+ tokens = if @p._highlight?
+ then @analyze @p._highlight
+ else @analyze @p.text
- @refs.text.innerHTML = if @p._highlight?
- then @compile tokens, true, false
- else @compile tokens
+ @refs.text.innerHTML = if @p._highlight?
+ then @compile tokens, true, false
+ else @compile tokens
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \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
+ # 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
- @reply = ~>
- form = document.body.append-child document.create-element \mk-post-form-window
- riot.mount form, do
- reply: @p
+ @reply = ~>
+ form = document.body.append-child document.create-element \mk-post-form-window
+ riot.mount form, do
+ reply: @p
- @repost = ~>
- form = document.body.append-child document.create-element \mk-repost-form-window
- riot.mount form, do
- post: @p
+ @repost = ~>
+ form = document.body.append-child document.create-element \mk-repost-form-window
+ riot.mount form, do
+ post: @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!
+ @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!
- @toggle-detail = ~>
- @is-detail-opened = !@is-detail-opened
- @update!
+ @toggle-detail = ~>
+ @is-detail-opened = !@is-detail-opened
+ @update!
- @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
+ @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
- if should-be-cancel
- e.prevent-default!
+ if should-be-cancel
+ e.prevent-default!
- function focus(el, fn)
- target = fn el
- if target?
- if target.has-attribute \tabindex
- target.focus!
- else
- focus target, fn
+ function focus(el, fn)
+ target = fn el
+ if target?
+ if target.has-attribute \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 dfd1b7c14e..ce6c00d0ba 100644
--- a/src/web/app/desktop/tags/timeline.tag
+++ b/src/web/app/desktop/tags/timeline.tag
@@ -1,86 +1,79 @@
-mk-timeline
- virtual(each={ post, i in posts })
- mk-timeline-post(post={ post })
- p.date(if={ i != posts.length - 1 && post._date != posts[i + 1]._date })
- span
- i.fa.fa-angle-up
- | { post._datetext }
- span
- i.fa.fa-angle-down
- | { posts[i + 1]._datetext }
- footer(data-yield='footer')
- | <yield from="footer"/>
+<mk-timeline>
+ <virtual each="{ post, i in posts }">
+ <mk-timeline-post post="{ post }"></mk-timeline-post>
+ <p class="date" if="{ i != posts.length - 1 &amp;&amp; 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>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > mk-timeline-post
+ border-bottom solid 1px #eaeaea
- > mk-timeline-post
- border-bottom solid 1px #eaeaea
+ &:first-child
+ border-top-left-radius 4px
+ border-top-right-radius 4px
- &:first-child
- border-top-left-radius 4px
- border-top-right-radius 4px
+ &:last-of-type
+ border-bottom none
- &:last-of-type
- border-bottom none
+ > .date
+ display block
+ margin 0
+ line-height 32px
+ font-size 14px
+ text-align center
+ color #aaa
+ background #fdfdfd
+ border-bottom solid 1px #eaeaea
- > .date
- display block
- margin 0
- line-height 32px
- font-size 14px
- text-align center
- color #aaa
- background #fdfdfd
- border-bottom solid 1px #eaeaea
+ span
+ margin 0 16px
- span
- margin 0 16px
+ i
+ margin-right 8px
- i
- margin-right 8px
+ > footer
+ padding 16px
+ text-align center
+ color #ccc
+ border-top solid 1px #eaeaea
+ border-bottom-left-radius 4px
+ border-bottom-right-radius 4px
- > footer
- padding 16px
- text-align center
- color #ccc
- border-top solid 1px #eaeaea
- border-bottom-left-radius 4px
- border-bottom-right-radius 4px
-
-style(theme='dark').
- > mk-timeline-post
- border-bottom-color #222221
+ </style>
+ <script>
+ @posts = []
-script.
- @posts = []
+ @set-posts = (posts) ~>
+ @posts = posts
+ @update!
- @set-posts = (posts) ~>
- @posts = posts
- @update!
+ @prepend-posts = (posts) ~>
+ posts.for-each (post) ~>
+ @posts.push post
+ @update!
- @prepend-posts = (posts) ~>
- posts.for-each (post) ~>
- @posts.push post
+ @add-post = (post) ~>
+ @posts.unshift post
@update!
- @add-post = (post) ~>
- @posts.unshift post
- @update!
-
- @clear = ~>
- @posts = []
- @update!
+ @clear = ~>
+ @posts = []
+ @update!
- @focus = ~>
- @root.children.0.focus!
+ @focus = ~>
+ @root.children.0.focus!
- @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 + '日'
+ @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 + '日'
- @tail = ~>
- @posts[@posts.length - 1]
+ @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 ffb1eeec00..47351b5262 100644
--- a/src/web/app/desktop/tags/ui-header-account.tag
+++ b/src/web/app/desktop/tags/ui-header-account.tag
@@ -1,219 +1,212 @@
-mk-ui-header-account
- button.header(data-active={ is-open.toString() }, onclick={ toggle })
- span.username
- | { I.username }
- i.fa.fa-angle-down(if={ !is-open })
- i.fa.fa-angle-up(if={ is-open })
- img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.menu(if={ is-open })
- ul
- li: a(href={ '/' + I.username })
- i.fa.fa-user
- | プロフィール
- i.fa.fa-angle-right
- li(onclick={ drive }): p
- i.fa.fa-cloud
- | ドライブ
- i.fa.fa-angle-right
- li: a(href='/i>mentions')
- i.fa.fa-at
- | あなた宛て
- i.fa.fa-angle-right
- ul
- li(onclick={ settings }): p
- i.fa.fa-cog
- | 設定
- i.fa.fa-angle-right
- ul
- li(onclick={ signout }): p
- i(class='fa fa-power-off')
- | サインアウト
- i.fa.fa-angle-right
+<mk-ui-header-account>
+ <button class="header" data-active="{ isOpen.toString() }" onclick="{ toggle }"><span class="username">{ I.username }<i class="fa fa-angle-down" if="{ !isOpen }"></i><i class="fa fa-angle-up" if="{ isOpen }"></i></span><img class="avatar" src="{ I.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></button>
+ <div class="menu" if="{ isOpen }">
+ <ul>
+ <li><a href="{ '/' + I.username }"><i class="fa fa-user"></i>プロフィール<i class="fa fa-angle-right"></i></a></li>
+ <li onclick="{ drive }">
+ <p><i class="fa fa-cloud"></i>ドライブ<i class="fa fa-angle-right"></i></p>
+ </li>
+ <li><a href="/i&gt;mentions"><i class="fa fa-at"></i>あなた宛て<i class="fa fa-angle-right"></i></a></li>
+ </ul>
+ <ul>
+ <li onclick="{ settings }">
+ <p><i class="fa fa-cog"></i>設定<i class="fa fa-angle-right"></i></p>
+ </li>
+ </ul>
+ <ul>
+ <li onclick="{ signout }">
+ <p><i class="fa fa-power-off"></i>サインアウト<i class="fa fa-angle-right"></i></p>
+ </li>
+ </ul>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ float left
-style.
- display block
- float left
+ > .header
+ display block
+ margin 0
+ padding 0
+ color #9eaba8
+ border none
+ background transparent
+ cursor pointer
- > .header
- display block
- margin 0
- padding 0
- color #9eaba8
- border none
- background transparent
- cursor pointer
+ *
+ pointer-events none
- *
- pointer-events none
+ &:hover
+ color darken(#9eaba8, 20%)
- &:hover
- color darken(#9eaba8, 20%)
+ &:active
+ color darken(#9eaba8, 30%)
- &:active
- color darken(#9eaba8, 30%)
+ &[data-active='true']
+ color darken(#9eaba8, 20%)
- &[data-active='true']
- color darken(#9eaba8, 20%)
+ > .avatar
+ $saturate = 150%
+ filter saturate($saturate)
+ -webkit-filter saturate($saturate)
+ -moz-filter saturate($saturate)
+ -ms-filter saturate($saturate)
- > .avatar
- $saturate = 150%
- filter saturate($saturate)
- -webkit-filter saturate($saturate)
- -moz-filter saturate($saturate)
- -ms-filter saturate($saturate)
+ > .username
+ display block
+ float left
+ margin 0 12px 0 16px
+ max-width 16em
+ line-height 48px
+ font-weight bold
+ font-family Meiryo, sans-serif
+ text-decoration none
- > .username
- display block
- float left
- margin 0 12px 0 16px
- max-width 16em
- line-height 48px
- font-weight bold
- font-family Meiryo, sans-serif
- text-decoration none
+ i
+ margin-left 8px
- i
- margin-left 8px
+ > .avatar
+ display block
+ float left
+ min-width 32px
+ max-width 32px
+ min-height 32px
+ max-height 32px
+ margin 8px 8px 8px 0
+ border-radius 4px
+ transition filter 100ms ease
- > .avatar
- display block
- float left
- min-width 32px
- max-width 32px
- min-height 32px
- max-height 32px
- margin 8px 8px 8px 0
- border-radius 4px
- transition filter 100ms ease
+ > .menu
+ display block
+ position absolute
+ top 56px
+ right -2px
+ width 230px
+ font-size 0.8em
+ background #fff
+ border-radius 4px
+ box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
- > .menu
- display block
- position absolute
- top 56px
- right -2px
- width 230px
- font-size 0.8em
- background #fff
- border-radius 4px
- box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
+ &:before
+ content ""
+ pointer-events none
+ display block
+ position absolute
+ top -28px
+ right 12px
+ border-top solid 14px transparent
+ border-right solid 14px transparent
+ border-bottom solid 14px rgba(0, 0, 0, 0.1)
+ border-left solid 14px transparent
- &:before
- content ""
- pointer-events none
- display block
- position absolute
- top -28px
- right 12px
- border-top solid 14px transparent
- border-right solid 14px transparent
- border-bottom solid 14px rgba(0, 0, 0, 0.1)
- border-left solid 14px transparent
+ &:after
+ content ""
+ pointer-events none
+ display block
+ position absolute
+ top -27px
+ right 12px
+ border-top solid 14px transparent
+ border-right solid 14px transparent
+ border-bottom solid 14px #fff
+ border-left solid 14px transparent
- &:after
- content ""
- pointer-events none
- display block
- position absolute
- top -27px
- right 12px
- border-top solid 14px transparent
- border-right solid 14px transparent
- border-bottom solid 14px #fff
- border-left solid 14px transparent
+ ul
+ display block
+ margin 10px 0
+ padding 0
+ list-style none
- ul
- display block
- margin 10px 0
- padding 0
- list-style none
+ & + ul
+ padding-top 10px
+ border-top solid 1px #eee
- & + ul
- padding-top 10px
- border-top solid 1px #eee
+ > li
+ display block
+ margin 0
+ padding 0
- > li
- display block
- margin 0
- padding 0
+ > a
+ > p
+ display block
+ z-index 1
+ padding 0 28px
+ margin 0
+ line-height 40px
+ color #868C8C
+ cursor pointer
- > a
- > p
- display block
- z-index 1
- padding 0 28px
- margin 0
- line-height 40px
- color #868C8C
- cursor pointer
+ *
+ pointer-events none
- *
- pointer-events none
+ > i:first-of-type
+ margin-right 6px
- > i:first-of-type
- margin-right 6px
+ > i:last-of-type
+ display block
+ position absolute
+ top 0
+ right 8px
+ z-index 1
+ padding 0 20px
+ font-size 1.2em
+ line-height 40px
- > i:last-of-type
- display block
- position absolute
- top 0
- right 8px
- z-index 1
- padding 0 20px
- font-size 1.2em
- line-height 40px
+ &:hover, &:active
+ text-decoration none
+ background $theme-color
+ color $theme-color-foreground
- &:hover, &:active
- text-decoration none
- background $theme-color
- color $theme-color-foreground
+ </style>
+ <script>
+ @mixin \i
+ @mixin \signout
-script.
- @mixin \i
- @mixin \signout
+ @is-open = false
- @is-open = false
+ @on \before-unmount ~>
+ @close!
- @on \before-unmount ~>
- @close!
+ @toggle = ~>
+ if @is-open
+ @close!
+ else
+ @open!
- @toggle = ~>
- if @is-open
- @close!
- else
- @open!
+ @open = ~>
+ @is-open = true
+ @update!
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.add-event-listener \mousedown @mousedown
- @open = ~>
- @is-open = true
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
+ @close = ~>
+ @is-open = false
+ @update!
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.remove-event-listener \mousedown @mousedown
- @close = ~>
- @is-open = false
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
+ @mousedown = (e) ~>
+ e.prevent-default!
+ if (!contains @root, e.target) and (@root != e.target)
+ @close!
+ return false
- @mousedown = (e) ~>
- e.prevent-default!
- if (!contains @root, e.target) and (@root != e.target)
+ @drive = ~>
@close!
- return false
-
- @drive = ~>
- @close!
- riot.mount document.body.append-child document.create-element \mk-drive-browser-window
+ riot.mount document.body.append-child document.create-element \mk-drive-browser-window
- @settings = ~>
- @close!
- riot.mount document.body.append-child document.create-element \mk-settings-window
+ @settings = ~>
+ @close!
+ riot.mount document.body.append-child document.create-element \mk-settings-window
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
+ 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 987907a684..da50d8401f 100644
--- a/src/web/app/desktop/tags/ui-header-clock.tag
+++ b/src/web/app/desktop/tags/ui-header-clock.tag
@@ -1,82 +1,87 @@
-mk-ui-header-clock
- div.header
- time@time
- div.content
- mk-analog-clock
+<mk-ui-header-clock>
+ <div class="header">
+ <time ref="time"></time>
+ </div>
+ <div class="content">
+ <mk-analog-clock></mk-analog-clock>
+ </div>
+ <style type="stylus">
+ :scope
+ display inline-block
+ overflow visible
-style.
- display inline-block
- overflow visible
+ > .header
+ padding 0 12px
+ text-align center
+ font-size 0.5em
- > .header
- padding 0 12px
- text-align center
- font-size 0.5em
+ &, *
+ cursor: default
- &, *
- cursor: default
+ &:hover
+ background #899492
- &:hover
- background #899492
+ & + .content
+ visibility visible
- & + .content
- visibility visible
+ > time
+ color #fff !important
- > time
- color #fff !important
+ *
+ color #fff !important
- *
- color #fff !important
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ > time
+ display table-cell
+ vertical-align middle
+ height 48px
+ color #9eaba8
- > time
- display table-cell
- vertical-align middle
- height 48px
- color #9eaba8
+ > .yyyymmdd
+ opacity 0.7
- > .yyyymmdd
- opacity 0.7
+ > .content
+ visibility hidden
+ display block
+ position absolute
+ top auto
+ right 0
+ z-index 3
+ margin 0
+ padding 0
+ width 256px
+ background #899492
- > .content
- visibility hidden
- display block
- position absolute
- top auto
- right 0
- z-index 3
- margin 0
- padding 0
- width 256px
- background #899492
+ </style>
+ <script>
+ @draw = ~>
+ now = new Date!
-script.
- @draw = ~>
- 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>"
- 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>"
+ hh = (\0 + now.get-hours!).slice -2
+ mm = (\0 + now.get-minutes!).slice -2
+ hhmm = "<span class='hhmm'>#hh:#mm</span>"
- hh = (\0 + now.get-hours!).slice -2
- mm = (\0 + now.get-minutes!).slice -2
- hhmm = "<span class='hhmm'>#hh:#mm</span>"
+ if now.get-seconds! % 2 == 0
+ hhmm .= replace \: '<span style=\'visibility:visible\'>:</span>'
+ else
+ hhmm .= replace \: '<span style=\'visibility:hidden\'>:</span>'
- 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"
- @refs.time.innerHTML = "#yyyymmdd<br>#hhmm"
+ @on \mount ~>
+ @draw!
+ @clock = set-interval @draw, 1000ms
- @on \mount ~>
- @draw!
- @clock = set-interval @draw, 1000ms
-
- @on \unmount ~>
- clear-interval @clock
+ @on \unmount ~>
+ clear-interval @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 153c3137b4..8844307ae9 100644
--- a/src/web/app/desktop/tags/ui-header-nav.tag
+++ b/src/web/app/desktop/tags/ui-header-nav.tag
@@ -1,113 +1,113 @@
-mk-ui-header-nav: ul(if={ SIGNIN })
- li.home(class={ active: page == 'home' }): a(href={ CONFIG.url })
- i.fa.fa-home
- p ホーム
- li.messaging: a(onclick={ messaging })
- i.fa.fa-comments
- p メッセージ
- i.fa.fa-circle(if={ has-unread-messaging-messages })
- li.info: a(href='https://twitter.com/misskey_xyz', target='_blank')
- i.fa.fa-info
- p お知らせ
- li.tv: a(href='https://misskey.tk', target='_blank')
- i.fa.fa-television
- p MisskeyTV™
+<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 type="stylus">
+ :scope
+ display inline-block
+ margin 0
+ padding 0
+ line-height 3rem
+ vertical-align top
-style.
- display inline-block
- margin 0
- padding 0
- line-height 3rem
- vertical-align top
+ > ul
+ display inline-block
+ margin 0
+ padding 0
+ vertical-align top
+ line-height 3rem
+ list-style none
- > ul
- display inline-block
- margin 0
- padding 0
- vertical-align top
- line-height 3rem
- list-style none
+ > li
+ display inline-block
+ vertical-align top
+ height 48px
+ line-height 48px
- > li
- display inline-block
- vertical-align top
- height 48px
- line-height 48px
+ &.active
+ > a
+ border-bottom solid 3px $theme-color
- &.active
- > a
- border-bottom solid 3px $theme-color
+ > a
+ display inline-block
+ z-index 1
+ height 100%
+ padding 0 24px
+ font-size 1em
+ font-variant small-caps
+ color #9eaba8
+ text-decoration none
+ transition none
+ cursor pointer
- > a
- display inline-block
- z-index 1
- height 100%
- padding 0 24px
- font-size 1em
- font-variant small-caps
- color #9eaba8
- text-decoration none
- transition none
- cursor pointer
+ *
+ pointer-events none
- *
- pointer-events none
+ &:hover
+ color darken(#9eaba8, 20%)
+ text-decoration 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
-script.
- @mixin \i
- @mixin \api
- @mixin \stream
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
+ @mixin \stream
- @page = @opts.page
+ @page = @opts.page
- @on \mount ~>
- @stream.on \read_all_messaging_messages @on-read-all-messaging-messages
- @stream.on \unread_messaging_message @on-unread-messaging-message
+ @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
- @api \messaging/unread
- .then (count) ~>
- if count.count > 0
- @has-unread-messaging-messages = true
- @update!
+ # Fetch count of unread messaging messages
+ @api \messaging/unread
+ .then (count) ~>
+ if count.count > 0
+ @has-unread-messaging-messages = true
+ @update!
- @on \unmount ~>
- @stream.off \read_all_messaging_messages @on-read-all-messaging-messages
- @stream.off \unread_messaging_message @on-unread-messaging-message
+ @on \unmount ~>
+ @stream.off \read_all_messaging_messages @on-read-all-messaging-messages
+ @stream.off \unread_messaging_message @on-unread-messaging-message
- @on-read-all-messaging-messages = ~>
- @has-unread-messaging-messages = false
- @update!
+ @on-read-all-messaging-messages = ~>
+ @has-unread-messaging-messages = false
+ @update!
- @on-unread-messaging-message = ~>
- @has-unread-messaging-messages = true
- @update!
+ @on-unread-messaging-message = ~>
+ @has-unread-messaging-messages = true
+ @update!
- @messaging = ~>
- riot.mount document.body.append-child document.create-element \mk-messaging-window
+ @messaging = ~>
+ riot.mount document.body.append-child document.create-element \mk-messaging-window
+ </script>
+ </ul>
+</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 495aad5004..05d4f4c2cd 100644
--- a/src/web/app/desktop/tags/ui-header-notifications.tag
+++ b/src/web/app/desktop/tags/ui-header-notifications.tag
@@ -1,111 +1,114 @@
-mk-ui-header-notifications
- button.header(data-active={ is-open }, onclick={ toggle })
- i.fa.fa-bell-o
- div.notifications(if={ is-open })
- mk-notifications
-
-style.
- display block
- float left
+<mk-ui-header-notifications>
+ <button class="header" data-active="{ isOpen }" onclick="{ toggle }"><i class="fa fa-bell-o"></i></button>
+ <div class="notifications" if="{ isOpen }">
+ <mk-notifications></mk-notifications>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ float left
- > .header
- display block
- margin 0
- padding 0
- width 32px
- color #9eaba8
- border none
- background transparent
- cursor pointer
+ > .header
+ display block
+ margin 0
+ padding 0
+ width 32px
+ color #9eaba8
+ border none
+ background transparent
+ cursor pointer
- *
- pointer-events none
+ *
+ pointer-events none
- &:hover
- color darken(#9eaba8, 20%)
+ &:hover
+ color darken(#9eaba8, 20%)
- &:active
- color darken(#9eaba8, 30%)
+ &:active
+ color darken(#9eaba8, 30%)
- &[data-active='true']
- color darken(#9eaba8, 20%)
+ &[data-active='true']
+ color darken(#9eaba8, 20%)
- > i
- font-size 1.2em
- line-height 48px
+ > i
+ font-size 1.2em
+ line-height 48px
- > .notifications
- display block
- position absolute
- top 56px
- right -72px
- width 300px
- background #fff
- border-radius 4px
- box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
+ > .notifications
+ display block
+ position absolute
+ top 56px
+ right -72px
+ width 300px
+ background #fff
+ border-radius 4px
+ box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
- &:before
- content ""
- pointer-events none
- display block
- position absolute
- top -28px
- right 74px
- border-top solid 14px transparent
- border-right solid 14px transparent
- border-bottom solid 14px rgba(0, 0, 0, 0.1)
- border-left solid 14px transparent
+ &:before
+ content ""
+ pointer-events none
+ display block
+ position absolute
+ top -28px
+ right 74px
+ border-top solid 14px transparent
+ border-right solid 14px transparent
+ border-bottom solid 14px rgba(0, 0, 0, 0.1)
+ border-left solid 14px transparent
- &:after
- content ""
- pointer-events none
- display block
- position absolute
- top -27px
- right 74px
- border-top solid 14px transparent
- border-right solid 14px transparent
- border-bottom solid 14px #fff
- border-left solid 14px transparent
+ &:after
+ content ""
+ pointer-events none
+ display block
+ position absolute
+ top -27px
+ right 74px
+ border-top solid 14px transparent
+ border-right solid 14px transparent
+ border-bottom solid 14px #fff
+ border-left solid 14px transparent
- > mk-notifications
- max-height 350px
- font-size 1rem
- overflow auto
+ > mk-notifications
+ max-height 350px
+ font-size 1rem
+ overflow auto
-script.
- @is-open = false
+ </style>
+ <script>
+ @is-open = false
- @toggle = ~>
- if @is-open
- @close!
- else
- @open!
+ @toggle = ~>
+ if @is-open
+ @close!
+ else
+ @open!
- @open = ~>
- @is-open = true
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.add-event-listener \mousedown @mousedown
+ @open = ~>
+ @is-open = true
+ @update!
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.add-event-listener \mousedown @mousedown
- @close = ~>
- @is-open = false
- @update!
- all = document.query-selector-all 'body *'
- Array.prototype.for-each.call all, (el) ~>
- el.remove-event-listener \mousedown @mousedown
+ @close = ~>
+ @is-open = false
+ @update!
+ all = document.query-selector-all 'body *'
+ Array.prototype.for-each.call all, (el) ~>
+ el.remove-event-listener \mousedown @mousedown
- @mousedown = (e) ~>
- e.prevent-default!
- if (!contains @root, e.target) and (@root != e.target)
- @close!
- return false
+ @mousedown = (e) ~>
+ e.prevent-default!
+ if (!contains @root, e.target) and (@root != e.target)
+ @close!
+ return false
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
+ 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-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 558c987619..79f836408a 100644
--- a/src/web/app/desktop/tags/ui-header-post-button.tag
+++ b/src/web/app/desktop/tags/ui-header-post-button.tag
@@ -1,39 +1,41 @@
-mk-ui-header-post-button
- button(onclick={ post }, title='新規投稿')
- i.fa.fa-pencil-square-o
+<mk-ui-header-post-button>
+ <button onclick="{ post }" title="新規投稿"><i class="fa fa-pencil-square-o"></i></button>
+ <style type="stylus">
+ :scope
+ display inline-block
+ padding 8px
+ height 100%
+ vertical-align top
-style.
- display inline-block
- padding 8px
- height 100%
- vertical-align top
+ > button
+ display inline-block
+ margin 0
+ padding 0 10px
+ height 100%
+ font-size 1.2em
+ font-weight normal
+ text-decoration none
+ color $theme-color-foreground
+ background $theme-color !important
+ outline none
+ border none
+ border-radius 2px
+ transition background 0.1s ease
+ cursor pointer
- > button
- display inline-block
- margin 0
- padding 0 10px
- height 100%
- font-size 1.2em
- font-weight normal
- text-decoration none
- color $theme-color-foreground
- background $theme-color !important
- outline none
- border none
- border-radius 2px
- transition background 0.1s ease
- cursor pointer
+ *
+ pointer-events none
- *
- pointer-events none
+ &:hover
+ background lighten($theme-color, 10%) !important
- &:hover
- background lighten($theme-color, 10%) !important
+ &:active
+ background darken($theme-color, 10%) !important
+ transition background 0s ease
- &:active
- background darken($theme-color, 10%) !important
- transition background 0s ease
-
-script.
- @post = (e) ~>
- @parent.parent.open-post-form!
+ </style>
+ <script>
+ @post = (e) ~>
+ @parent.parent.open-post-form!
+ </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 24e4e44989..8803384938 100644
--- a/src/web/app/desktop/tags/ui-header-search.tag
+++ b/src/web/app/desktop/tags/ui-header-search.tag
@@ -1,37 +1,41 @@
-mk-ui-header-search
- form.search(onsubmit={ onsubmit })
- input@q(type='search', placeholder!='&#xf002; 検索')
- div.result
+<mk-ui-header-search>
+ <form class="search" onsubmit="{ onsubmit }">
+ <input ref="q" type="search" placeholder="&#xf002; 検索"/>
+ <div class="result"></div>
+ </form>
+ <style type="stylus">
+ :scope
-style.
+ > form
+ display block
+ float left
- > form
- display block
- float left
+ > input
+ user-select text
+ cursor auto
+ margin 0
+ padding 6px 18px
+ width 14em
+ height 48px
+ font-size 1em
+ line-height calc(48px - 12px)
+ background transparent
+ outline none
+ //border solid 1px #ddd
+ border none
+ border-radius 0
+ transition color 0.5s ease, border 0.5s ease
+ font-family FontAwesome, sans-serif
- > input
- user-select text
- cursor auto
- margin 0
- padding 6px 18px
- width 14em
- height 48px
- font-size 1em
- line-height calc(48px - 12px)
- background transparent
- outline none
- //border solid 1px #ddd
- border none
- border-radius 0
- transition color 0.5s ease, border 0.5s ease
- font-family FontAwesome, sans-serif
+ &::-webkit-input-placeholder
+ color #9eaba8
- &::-webkit-input-placeholder
- color #9eaba8
+ </style>
+ <script>
+ @mixin \page
-script.
- @mixin \page
-
- @onsubmit = (e) ~>
- e.prevent-default!
- @page '/search:' + @refs.q.value
+ @onsubmit = (e) ~>
+ e.prevent-default!
+ @page '/search:' + @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 b02817cd84..4ec0ba183a 100644
--- a/src/web/app/desktop/tags/ui-header.tag
+++ b/src/web/app/desktop/tags/ui-header.tag
@@ -1,85 +1,85 @@
-mk-ui-header
- mk-donation(if={ SIGNIN && !I.data.no_donation })
- mk-special-message
- div.main
- div.backdrop
- div.main: div.container
- div.left
- mk-ui-header-nav(page={ opts.page })
- div.right
- mk-ui-header-search
- mk-ui-header-account(if={ SIGNIN })
- mk-ui-header-notifications(if={ SIGNIN })
- mk-ui-header-post-button(if={ SIGNIN })
- mk-ui-header-clock
-
-style.
- display block
- position fixed
- top 0
- z-index 1024
- width 100%
- box-shadow 0 1px 1px rgba(0, 0, 0, 0.075)
-
- > .main
-
- > .backdrop
- position absolute
+<mk-ui-header>
+ <mk-donation if="{ SIGNIN &amp;&amp; !I.data.no_donation }"></mk-donation>
+ <mk-special-message></mk-special-message>
+ <div class="main">
+ <div class="backdrop"></div>
+ <div class="main">
+ <div class="container">
+ <div class="left">
+ <mk-ui-header-nav page="{ opts.page }"></mk-ui-header-nav>
+ </div>
+ <div class="right">
+ <mk-ui-header-search></mk-ui-header-search>
+ <mk-ui-header-account if="{ SIGNIN }"></mk-ui-header-account>
+ <mk-ui-header-notifications if="{ SIGNIN }"></mk-ui-header-notifications>
+ <mk-ui-header-post-button if="{ SIGNIN }"></mk-ui-header-post-button>
+ <mk-ui-header-clock></mk-ui-header-clock>
+ </div>
+ </div>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ position fixed
top 0
- z-index 1023
+ z-index 1024
width 100%
- height 48px
- backdrop-filter blur(12px)
- //background-color rgba(255, 255, 255, 0.75)
- background #fff
+ box-shadow 0 1px 1px rgba(0, 0, 0, 0.075)
- &:after
- content ""
- display block
- width 100%
- height 48px
- background-image url(/_/resources/desktop/header-logo.svg)
- background-size 64px
- background-position center
- background-repeat no-repeat
+ > .main
- > .main
- z-index 1024
- margin 0
- padding 0
- background-clip content-box
- font-size 0.9rem
- user-select none
+ > .backdrop
+ position absolute
+ top 0
+ z-index 1023
+ width 100%
+ height 48px
+ backdrop-filter blur(12px)
+ //background-color rgba(255, 255, 255, 0.75)
+ background #fff
- > .container
- width 100%
- max-width 1300px
- margin 0 auto
+ &:after
+ content ""
+ display block
+ width 100%
+ height 48px
+ background-image url(/_/resources/desktop/header-logo.svg)
+ background-size 64px
+ background-position center
+ background-repeat no-repeat
- &:after
- content ""
- display block
- clear both
+ > .main
+ z-index 1024
+ margin 0
+ padding 0
+ background-clip content-box
+ font-size 0.9rem
+ user-select none
- > .left
- float left
- height 3rem
+ > .container
+ width 100%
+ max-width 1300px
+ margin 0 auto
- > .right
- float right
- height 48px
+ &:after
+ content ""
+ display block
+ clear both
- @media (max-width 1100px)
- > mk-ui-header-search
- display none
+ > .left
+ float left
+ height 3rem
-style(theme='dark').
- box-shadow 0 1px 0 #222221
+ > .right
+ float right
+ height 48px
- > .main
+ @media (max-width 1100px)
+ > mk-ui-header-search
+ display none
- > .backdrop
- background #0D0D0D
+ </style>
-script.
- @mixin \i
+ <script>@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 6e5f948b88..aacf23cf50 100644
--- a/src/web/app/desktop/tags/ui-notification.tag
+++ b/src/web/app/desktop/tags/ui-notification.tag
@@ -1,41 +1,44 @@
-mk-ui-notification
- p { opts.message }
+<mk-ui-notification>
+ <p>{ opts.message }</p>
+ <style type="stylus">
+ :scope
+ display block
+ position fixed
+ z-index 10000
+ top -64px
+ left 0
+ right 0
+ margin 0 auto
+ width 500px
+ color rgba(#000, 0.6)
+ background rgba(#fff, 0.9)
+ border-radius 0 0 8px 8px
+ box-shadow 0 2px 4px rgba(#000, 0.2)
-style.
- display block
- position fixed
- z-index 10000
- top -64px
- left 0
- right 0
- margin 0 auto
- width 500px
- color rgba(#000, 0.6)
- background rgba(#fff, 0.9)
- border-radius 0 0 8px 8px
- box-shadow 0 2px 4px rgba(#000, 0.2)
+ > p
+ margin 0
+ line-height 64px
+ text-align center
- > p
- margin 0
- line-height 64px
- text-align center
-
-script.
- @on \mount ~>
- Velocity @root, {
- top: \0px
- } {
- duration: 500ms
- easing: \ease-out
- }
-
- set-timeout ~>
+ </style>
+ <script>
+ @on \mount ~>
Velocity @root, {
- top: \-64px
+ top: \0px
} {
duration: 500ms
easing: \ease-out
- complete: ~>
- @unmount!
}
- , 6000ms
+
+ set-timeout ~>
+ Velocity @root, {
+ top: \-64px
+ } {
+ duration: 500ms
+ easing: \ease-out
+ complete: ~>
+ @unmount!
+ }
+ , 6000ms
+ </script>
+</mk-ui-notification>
diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag
index 6bced1f9e4..713db21d91 100644
--- a/src/web/app/desktop/tags/ui.tag
+++ b/src/web/app/desktop/tags/ui.tag
@@ -1,37 +1,37 @@
-mk-ui
- div.global@global
- mk-ui-header@header(page={ opts.page })
+<mk-ui>
+ <div class="global" ref="global">
+ <mk-ui-header ref="header" page="{ opts.page }"></mk-ui-header>
+ <mk-set-avatar-suggestion if="{ SIGNIN &amp;&amp; I.avatar_id == null }"></mk-set-avatar-suggestion>
+ <mk-set-banner-suggestion if="{ SIGNIN &amp;&amp; I.banner_id == null }"></mk-set-banner-suggestion>
+ <div class="content"><yield /></div>
+ </div>
+ <mk-stream-indicator></mk-stream-indicator>
+ <style type="stylus">
+ :scope
+ display block
- mk-set-avatar-suggestion(if={ SIGNIN && I.avatar_id == null })
- mk-set-banner-suggestion(if={ SIGNIN && I.banner_id == null })
+ </style>
+ <script>
+ @mixin \i
- div.content
- <yield />
+ @open-post-form = ~>
+ riot.mount document.body.append-child document.create-element \mk-post-form-window
- mk-stream-indicator
+ @set-root-layout = ~>
+ @root.style.padding-top = @refs.header.root.client-height + \px
-style.
- display block
+ @on \mount ~>
+ @set-root-layout!
+ document.add-event-listener \keydown @onkeydown
-script.
- @mixin \i
+ @on \unmount ~>
+ document.remove-event-listener \keydown @onkeydown
- @open-post-form = ~>
- riot.mount document.body.append-child document.create-element \mk-post-form-window
-
- @set-root-layout = ~>
- @root.style.padding-top = @refs.header.root.client-height + \px
-
- @on \mount ~>
- @set-root-layout!
- document.add-event-listener \keydown @onkeydown
-
- @on \unmount ~>
- document.remove-event-listener \keydown @onkeydown
-
- @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!
+ @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!
+ </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 d18b04446c..c6899be46b 100644
--- a/src/web/app/desktop/tags/user-followers-window.tag
+++ b/src/web/app/desktop/tags/user-followers-window.tag
@@ -1,22 +1,19 @@
-mk-user-followers-window
- mk-window(is-modal={ false }, width={ '400px' }, height={ '550px' })
- <yield to="header">
- img(src={ parent.user.avatar_url + '?thumbnail&size=64' }, alt='')
- | { parent.user.name }のフォロワー
- </yield>
- <yield to="content">
- mk-user-followers(user={ parent.user })
- </yield>
+<mk-user-followers-window>
+ <mk-window is-modal="{ false }" width="{ '400px' }" height="{ '550px' }"><yield to="header"><img src="{ parent.user.avatar_url + '?thumbnail&amp;size=64' }" alt=""/>{ parent.user.name }のフォロワー</yield>
+<yield to="content">
+ <mk-user-followers user="{ parent.user }"></mk-user-followers></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > img
+ display inline-block
+ vertical-align bottom
+ height calc(100% - 10px)
+ margin 5px
+ border-radius 4px
-style.
- > mk-window
- [data-yield='header']
- > img
- display inline-block
- vertical-align bottom
- height calc(100% - 10px)
- margin 5px
- border-radius 4px
-
-script.
- @user = @opts.user
+ </style>
+ <script>@user = @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 52f9f43836..9f96b00177 100644
--- a/src/web/app/desktop/tags/user-followers.tag
+++ b/src/web/app/desktop/tags/user-followers.tag
@@ -1,19 +1,22 @@
-mk-user-followers
- mk-users-list(fetch={ fetch }, count={ user.followers_count }, you-know-count={ user.followers_you_know_count }, no-users={ 'フォロワーはいないようです。' })
+<mk-user-followers>
+ <mk-users-list fetch="{ fetch }" count="{ user.followers_count }" you-know-count="{ user.followers_you_know_count }" no-users="{ 'フォロワーはいないようです。' }"></mk-users-list>
+ <style type="stylus">
+ :scope
+ display block
+ height 100%
-style.
- display block
- height 100%
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @user = @opts.user
- @user = @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
+ @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
+ </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 91f94f08d3..343820d4e0 100644
--- a/src/web/app/desktop/tags/user-following-window.tag
+++ b/src/web/app/desktop/tags/user-following-window.tag
@@ -1,22 +1,19 @@
-mk-user-following-window
- mk-window(is-modal={ false }, width={ '400px' }, height={ '550px' })
- <yield to="header">
- img(src={ parent.user.avatar_url + '?thumbnail&size=64' }, alt='')
- | { parent.user.name }のフォロー
- </yield>
- <yield to="content">
- mk-user-following(user={ parent.user })
- </yield>
+<mk-user-following-window>
+ <mk-window is-modal="{ false }" width="{ '400px' }" height="{ '550px' }"><yield to="header"><img src="{ parent.user.avatar_url + '?thumbnail&amp;size=64' }" alt=""/>{ parent.user.name }のフォロー</yield>
+<yield to="content">
+ <mk-user-following user="{ parent.user }"></mk-user-following></yield>
+ </mk-window>
+ <style type="stylus">
+ :scope
+ > mk-window
+ [data-yield='header']
+ > img
+ display inline-block
+ vertical-align bottom
+ height calc(100% - 10px)
+ margin 5px
+ border-radius 4px
-style.
- > mk-window
- [data-yield='header']
- > img
- display inline-block
- vertical-align bottom
- height calc(100% - 10px)
- margin 5px
- border-radius 4px
-
-script.
- @user = @opts.user
+ </style>
+ <script>@user = @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 0a39f2e4b8..87b88b6cd2 100644
--- a/src/web/app/desktop/tags/user-following.tag
+++ b/src/web/app/desktop/tags/user-following.tag
@@ -1,19 +1,22 @@
-mk-user-following
- mk-users-list(fetch={ fetch }, count={ user.following_count }, you-know-count={ user.following_you_know_count }, no-users={ 'フォロー中のユーザーはいないようです。' })
+<mk-user-following>
+ <mk-users-list fetch="{ fetch }" count="{ user.following_count }" you-know-count="{ user.following_you_know_count }" no-users="{ 'フォロー中のユーザーはいないようです。' }"></mk-users-list>
+ <style type="stylus">
+ :scope
+ display block
+ height 100%
-style.
- display block
- height 100%
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @user = @opts.user
- @user = @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
+ @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
+ </script>
+</mk-user-following>
diff --git a/src/web/app/desktop/tags/user-friends-graph.tag b/src/web/app/desktop/tags/user-friends-graph.tag
index 47c3a15613..13c0bc2c38 100644
--- a/src/web/app/desktop/tags/user-friends-graph.tag
+++ b/src/web/app/desktop/tags/user-friends-graph.tag
@@ -1,64 +1,67 @@
-mk-user-friends-graph
- canvas@canv(width='750', height='250')
+<mk-user-friends-graph>
+ <canvas ref="canv" width="750" height="250"></canvas>
+ <style type="stylus">
+ :scope
+ display block
+ width 750px
+ height 250px
-style.
- display block
- width 750px
- height 250px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
-script.
- @mixin \api
- @mixin \is-promise
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ @on \mount ~>
+ user <~ @user-promise.then
+ @user = user
+ @update!
- @on \mount ~>
- user <~ @user-promise.then
- @user = user
- @update!
-
- @api \aggregation/users/followers do
- user_id: @user.id
- limit: 30days
- .then (followers) ~>
- followers = followers.reverse!
-
- @api \aggregation/users/following do
+ @api \aggregation/users/followers do
user_id: @user.id
limit: 30days
- .then (following) ~>
- following = following.reverse!
+ .then (followers) ~>
+ followers = followers.reverse!
+
+ @api \aggregation/users/following do
+ user_id: @user.id
+ limit: 30days
+ .then (following) ~>
+ following = following.reverse!
- new Chart @refs.canv, do
- type: \line
- data:
- labels: following.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
- datasets: [
- {
- label: \フォロー
- data: following.map (x) ~> x.count
- line-tension: 0
- border-width: 2
- fill: true
- background-color: 'rgba(127, 221, 64, 0.2)'
- point-background-color: \#fff
- point-radius: 4
- point-border-width: 2
- border-color: \#7fdd40
- },
- {
- label: \フォロワー
- data: followers.map (x) ~> x.count
- line-tension: 0
- border-width: 2
- fill: true
- background-color: 'rgba(255, 99, 132, 0.2)'
- point-background-color: \#fff
- point-radius: 4
- point-border-width: 2
- border-color: \#FF6384
- }
- ]
- options:
- responsive: false
+ new Chart @refs.canv, do
+ type: \line
+ data:
+ labels: following.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
+ datasets: [
+ {
+ label: \フォロー
+ data: following.map (x) ~> x.count
+ line-tension: 0
+ border-width: 2
+ fill: true
+ background-color: 'rgba(127, 221, 64, 0.2)'
+ point-background-color: \#fff
+ point-radius: 4
+ point-border-width: 2
+ border-color: \#7fdd40
+ },
+ {
+ label: \フォロワー
+ data: followers.map (x) ~> x.count
+ line-tension: 0
+ border-width: 2
+ fill: true
+ background-color: 'rgba(255, 99, 132, 0.2)'
+ point-background-color: \#fff
+ point-radius: 4
+ point-border-width: 2
+ border-color: \#FF6384
+ }
+ ]
+ options:
+ responsive: false
+ </script>
+</mk-user-friends-graph>
diff --git a/src/web/app/desktop/tags/user-graphs.tag b/src/web/app/desktop/tags/user-graphs.tag
index f7f0fcd5e0..28643cd90b 100644
--- a/src/web/app/desktop/tags/user-graphs.tag
+++ b/src/web/app/desktop/tags/user-graphs.tag
@@ -1,36 +1,40 @@
-mk-user-graphs
- section
- h1 投稿
- mk-user-posts-graph(user={ opts.user })
+<mk-user-graphs>
+ <section>
+ <h1>投稿</h1>
+ <mk-user-posts-graph user="{ opts.user }"></mk-user-posts-graph>
+ </section>
+ <section>
+ <h1>フォロー/フォロワー</h1>
+ <mk-user-friends-graph user="{ opts.user }"></mk-user-friends-graph>
+ </section>
+ <section>
+ <h1>いいね</h1>
+ <mk-user-likes-graph user="{ opts.user }"></mk-user-likes-graph>
+ </section>
+ <style type="stylus">
+ :scope
+ display block
- section
- h1 フォロー/フォロワー
- mk-user-friends-graph(user={ opts.user })
+ > section
+ margin 16px 0
+ background #fff
+ border solid 1px rgba(0, 0, 0, 0.1)
+ border-radius 4px
- section
- h1 いいね
- mk-user-likes-graph(user={ opts.user })
+ > h1
+ margin 0 0 8px 0
+ padding 0 16px
+ line-height 40px
+ font-size 1em
+ color #666
+ border-bottom solid 1px #eee
-style.
- display block
+ > *:not(h1)
+ margin 0 auto 16px auto
- > section
- margin 16px 0
- background #fff
- border solid 1px rgba(0, 0, 0, 0.1)
- border-radius 4px
-
- > h1
- margin 0 0 8px 0
- padding 0 16px
- line-height 40px
- font-size 1em
- color #666
- border-bottom solid 1px #eee
-
- > *:not(h1)
- margin 0 auto 16px auto
-
-script.
- @on \mount ~>
- @trigger \loaded
+ </style>
+ <script>
+ @on \mount ~>
+ @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 5abd79ff1c..7b4ebfb847 100644
--- a/src/web/app/desktop/tags/user-header.tag
+++ b/src/web/app/desktop/tags/user-header.tag
@@ -1,143 +1,142 @@
-mk-user-header(data-is-dark-background={ user.banner_url != null })
- div.banner@banner(style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }, onclick={ on-update-banner })
- img.avatar(src={ user.avatar_url + '?thumbnail&size=150' }, alt='avatar')
- div.title
- p.name(href={ CONFIG.url + '/' + user.username }) { user.name }
- p.username @{ user.username }
- p.location(if={ user.location })
- i.fa.fa-map-marker
- | { user.location }
- footer
- a(href={ '/' + user.username }) 投稿
- a(href={ '/' + user.username + '/media' }) メディア
- a(href={ '/' + user.username + '/graphs' }) グラフ
- button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h
+<mk-user-header data-is-dark-background="{ user.banner_url != null }">
+ <div class="banner" ref="banner" style="{ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&amp;size=1024)' : '' }" onclick="{ onUpdateBanner }"></div><img class="avatar" src="{ user.avatar_url + '?thumbnail&amp;size=150' }" alt="avatar"/>
+ <div class="title">
+ <p class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</p>
+ <p class="username">@{ user.username }</p>
+ <p class="location" if="{ user.location }"><i class="fa fa-map-marker"></i>{ user.location }</p>
+ </div>
+ <footer><a href="{ '/' + user.username }">投稿</a><a href="{ '/' + user.username + '/media' }">メディア</a><a href="{ '/' + user.username + '/graphs' }">グラフ</a>
+ <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button>
+ </footer>
+ <style type="stylus">
+ :scope
+ $footer-height = 58px
-style.
- $footer-height = 58px
-
- display block
- background #fff
+ display block
+ background #fff
- &[data-is-dark-background]
- > .banner
- background-color #383838
+ &[data-is-dark-background]
+ > .banner
+ background-color #383838
- > .title
- color #fff
- background linear-gradient(transparent, rgba(0, 0, 0, 0.7))
+ > .title
+ color #fff
+ background linear-gradient(transparent, rgba(0, 0, 0, 0.7))
- > .name
- text-shadow 0 0 8px #000
+ > .name
+ text-shadow 0 0 8px #000
- > .banner
- height 280px
- background-color #f5f5f5
- background-size cover
- background-position center
+ > .banner
+ height 280px
+ background-color #f5f5f5
+ background-size cover
+ background-position center
- > .avatar
- display block
- position absolute
- bottom 16px
- left 16px
- z-index 2
- width 150px
- height 150px
- margin 0
- border solid 3px #fff
- border-radius 8px
- box-shadow 1px 1px 3px rgba(0, 0, 0, 0.2)
+ > .avatar
+ display block
+ position absolute
+ bottom 16px
+ left 16px
+ z-index 2
+ width 150px
+ height 150px
+ margin 0
+ border solid 3px #fff
+ border-radius 8px
+ box-shadow 1px 1px 3px rgba(0, 0, 0, 0.2)
- > .title
- position absolute
- bottom $footer-height
- left 0
- width 100%
- padding 0 0 8px 195px
- color #656565
- font-family '游ゴシック', 'YuGothic', 'ヒラギノ角ゴ ProN W3', 'Hiragino Kaku Gothic ProN', 'Meiryo', 'メイリオ', sans-serif
+ > .title
+ position absolute
+ bottom $footer-height
+ left 0
+ width 100%
+ padding 0 0 8px 195px
+ color #656565
+ font-family '游ゴシック', 'YuGothic', 'ヒラギノ角ゴ ProN W3', 'Hiragino Kaku Gothic ProN', 'Meiryo', 'メイリオ', sans-serif
- > .name
- display block
- margin 0
- line-height 40px
- font-weight bold
- font-size 2em
+ > .name
+ display block
+ margin 0
+ line-height 40px
+ font-weight bold
+ font-size 2em
- > .username
- > .location
- display inline-block
- margin 0 16px 0 0
- line-height 20px
- opacity 0.8
+ > .username
+ > .location
+ display inline-block
+ margin 0 16px 0 0
+ line-height 20px
+ opacity 0.8
- > i
- margin-right 4px
+ > i
+ margin-right 4px
- > footer
- z-index 1
- height $footer-height
- padding-left 195px
- background #fff
+ > footer
+ z-index 1
+ height $footer-height
+ padding-left 195px
+ background #fff
- > a
- display inline-block
- margin 0
- width 100px
- line-height $footer-height
- color #555
+ > a
+ display inline-block
+ margin 0
+ width 100px
+ line-height $footer-height
+ color #555
- > button
- display block
- position absolute
- top 0
- right 0
- margin 8px
- padding 0
- width $footer-height - 16px
- line-height $footer-height - 16px - 2px
- font-size 1.2em
- color #777
- border solid 1px #eee
- border-radius 4px
+ > button
+ display block
+ position absolute
+ top 0
+ right 0
+ margin 8px
+ padding 0
+ width $footer-height - 16px
+ line-height $footer-height - 16px - 2px
+ font-size 1.2em
+ color #777
+ border solid 1px #eee
+ border-radius 4px
- &:hover
- color #555
- border solid 1px #ddd
+ &:hover
+ color #555
+ border solid 1px #ddd
-script.
- @mixin \i
- @mixin \update-banner
- @mixin \NotImplementedException
+ </style>
+ <script>
+ @mixin \i
+ @mixin \update-banner
+ @mixin \NotImplementedException
- @user = @opts.user
+ @user = @opts.user
- @on \mount ~>
- window.add-event-listener \load @scroll
- window.add-event-listener \scroll @scroll
- window.add-event-listener \resize @scroll
+ @on \mount ~>
+ window.add-event-listener \load @scroll
+ window.add-event-listener \scroll @scroll
+ window.add-event-listener \resize @scroll
- @on \unmount ~>
- window.remove-event-listener \load @scroll
- window.remove-event-listener \scroll @scroll
- window.remove-event-listener \resize @scroll
+ @on \unmount ~>
+ window.remove-event-listener \load @scroll
+ window.remove-event-listener \scroll @scroll
+ window.remove-event-listener \resize @scroll
- @scroll = ~>
- top = window.scroll-y
- height = 280px
+ @scroll = ~>
+ top = window.scroll-y
+ height = 280px
- pos = 50 - ((top / height) * 50)
- @refs.banner.style.background-position = 'center ' + pos + '%'
+ pos = 50 - ((top / height) * 50)
+ @refs.banner.style.background-position = 'center ' + pos + '%'
- blur = top / 32
- if blur <= 10
- @refs.banner.style.filter = 'blur(' + blur + 'px)'
+ blur = top / 32
+ if blur <= 10
+ @refs.banner.style.filter = 'blur(' + blur + 'px)'
- @on-update-banner = ~>
- if not @SIGNIN or @I.id != @user.id
- return
+ @on-update-banner = ~>
+ if not @SIGNIN or @I.id != @user.id
+ return
- @update-banner @I, (i) ~>
- @user.banner_url = i.banner_url
- @update!
+ @update-banner @I, (i) ~>
+ @user.banner_url = i.banner_url
+ @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 4bf0260ff6..602ce1b9c9 100644
--- a/src/web/app/desktop/tags/user-home.tag
+++ b/src/web/app/desktop/tags/user-home.tag
@@ -1,40 +1,45 @@
-mk-user-home
- div.side
- mk-user-profile(user={ user })
- mk-user-photos(user={ user })
- main
- mk-user-timeline@tl(user={ user })
+<mk-user-home>
+ <div class="side">
+ <mk-user-profile user="{ user }"></mk-user-profile>
+ <mk-user-photos user="{ user }"></mk-user-photos>
+ </div>
+ <main>
+ <mk-user-timeline ref="tl" user="{ user }"></mk-user-timeline>
+ </main>
+ <style type="stylus">
+ :scope
+ display flex
+ justify-content center
-style.
- display flex
- justify-content center
+ > *
+ > *
+ display block
+ //border solid 1px #eaeaea
+ border solid 1px rgba(0, 0, 0, 0.075)
+ border-radius 6px
+ overflow hidden
- > *
- > *
- display block
- //border solid 1px #eaeaea
- border solid 1px rgba(0, 0, 0, 0.075)
- border-radius 6px
- overflow hidden
+ &:not(:last-child)
+ margin-bottom 16px
- &:not(:last-child)
- margin-bottom 16px
+ > main
+ flex 1 1 560px
+ max-width 560px
+ margin 0
+ padding 16px 0 16px 16px
- > main
- flex 1 1 560px
- max-width 560px
- margin 0
- padding 16px 0 16px 16px
+ > .side
+ flex 1 1 270px
+ max-width 270px
+ margin 0
+ padding 16px 0 16px 0
- > .side
- flex 1 1 270px
- max-width 270px
- margin 0
- padding 16px 0 16px 0
+ </style>
+ <script>
+ @user = @opts.user
-script.
- @user = @opts.user
-
- @on \mount ~>
- @refs.tl.on \loaded ~>
- @trigger \loaded
+ @on \mount ~>
+ @refs.tl.on \loaded ~>
+ @trigger \loaded
+ </script>
+</mk-user-home>
diff --git a/src/web/app/desktop/tags/user-likes-graph.tag b/src/web/app/desktop/tags/user-likes-graph.tag
index e9d1428713..1c2759a3a1 100644
--- a/src/web/app/desktop/tags/user-likes-graph.tag
+++ b/src/web/app/desktop/tags/user-likes-graph.tag
@@ -1,39 +1,42 @@
-mk-user-likes-graph
- canvas@canv(width='750', height='250')
+<mk-user-likes-graph>
+ <canvas ref="canv" width="750" height="250"></canvas>
+ <style type="stylus">
+ :scope
+ display block
+ width 750px
+ height 250px
-style.
- display block
- width 750px
- height 250px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
-script.
- @mixin \api
- @mixin \is-promise
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ @on \mount ~>
+ user <~ @user-promise.then
+ @user = user
+ @update!
- @on \mount ~>
- user <~ @user-promise.then
- @user = user
- @update!
+ @api \aggregation/users/like do
+ user_id: @user.id
+ limit: 30days
+ .then (likes) ~>
+ likes = likes.reverse!
- @api \aggregation/users/like do
- user_id: @user.id
- limit: 30days
- .then (likes) ~>
- likes = likes.reverse!
-
- new Chart @refs.canv, do
- type: \bar
- data:
- labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
- datasets: [
- {
- label: \いいねした数
- data: likes.map (x) ~> x.count
- background-color: \#F7796C
- }
- ]
- options:
- responsive: false
+ new Chart @refs.canv, do
+ type: \bar
+ data:
+ labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
+ datasets: [
+ {
+ label: \いいねした数
+ data: likes.map (x) ~> x.count
+ background-color: \#F7796C
+ }
+ ]
+ options:
+ responsive: false
+ </script>
+</mk-user-likes-graph>
diff --git a/src/web/app/desktop/tags/user-photos.tag b/src/web/app/desktop/tags/user-photos.tag
index 61a840ee61..eb79113e41 100644
--- a/src/web/app/desktop/tags/user-photos.tag
+++ b/src/web/app/desktop/tags/user-photos.tag
@@ -1,85 +1,86 @@
-mk-user-photos
- p.title
- i.fa.fa-camera
- | フォト
- p.initializing(if={ initializing })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
- div.stream(if={ !initializing && images.length > 0 })
- virtual(each={ image in images })
- div.img(style={ 'background-image: url(' + image.url + '?thumbnail&size=256)' })
- p.empty(if={ !initializing && images.length == 0 })
- | 写真はありません
+<mk-user-photos>
+ <p class="title"><i class="fa fa-camera"></i>フォト</p>
+ <p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <div class="stream" if="{ !initializing &amp;&amp; images.length &gt; 0 }">
+ <virtual each="{ image in images }">
+ <div class="img" style="{ 'background-image: url(' + image.url + '?thumbnail&amp;size=256)' }"></div>
+ </virtual>
+ </div>
+ <p class="empty" if="{ !initializing &amp;&amp; images.length == 0 }">写真はありません</p>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > .title
+ z-index 1
+ margin 0
+ padding 0 16px
+ line-height 42px
+ font-size 0.9em
+ font-weight bold
+ color #888
+ box-shadow 0 1px rgba(0, 0, 0, 0.07)
- > .title
- z-index 1
- margin 0
- padding 0 16px
- line-height 42px
- font-size 0.9em
- font-weight bold
- color #888
- box-shadow 0 1px rgba(0, 0, 0, 0.07)
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ > .stream
+ display -webkit-flex
+ display -moz-flex
+ display -ms-flex
+ display flex
+ justify-content center
+ flex-wrap wrap
+ padding 8px
- > .stream
- display -webkit-flex
- display -moz-flex
- display -ms-flex
- display flex
- justify-content center
- flex-wrap wrap
- padding 8px
+ > .img
+ flex 1 1 33%
+ width 33%
+ height 80px
+ background-position center center
+ background-size cover
+ background-clip content-box
+ border solid 2px transparent
- > .img
- flex 1 1 33%
- width 33%
- height 80px
- background-position center center
- background-size cover
- background-clip content-box
- border solid 2px transparent
+ > .initializing
+ > .empty
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- > .initializing
- > .empty
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
-script.
- @mixin \api
- @mixin \is-promise
+ @images = []
+ @initializing = true
- @images = []
- @initializing = true
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.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
+ @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!
+ </script>
+</mk-user-photos>
diff --git a/src/web/app/desktop/tags/user-posts-graph.tag b/src/web/app/desktop/tags/user-posts-graph.tag
index 75f4ac4a67..61070c3818 100644
--- a/src/web/app/desktop/tags/user-posts-graph.tag
+++ b/src/web/app/desktop/tags/user-posts-graph.tag
@@ -1,68 +1,71 @@
-mk-user-posts-graph
- canvas@canv(width='750', height='250')
+<mk-user-posts-graph>
+ <canvas ref="canv" width="750" height="250"></canvas>
+ <style type="stylus">
+ :scope
+ display block
+ width 750px
+ height 250px
-style.
- display block
- width 750px
- height 250px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
-script.
- @mixin \api
- @mixin \is-promise
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ @on \mount ~>
+ user <~ @user-promise.then
+ @user = user
+ @update!
- @on \mount ~>
- user <~ @user-promise.then
- @user = user
- @update!
-
- @api \aggregation/users/post do
- user_id: @user.id
- limit: 30days
- .then (data) ~>
- data = data.reverse!
- new Chart @refs.canv, do
- type: \line
- data:
- labels: data.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
- datasets: [
- {
- label: \投稿
- data: data.map (x) ~> x.posts
- line-tension: 0
- point-radius: 0
- background-color: \#555
- border-color: \transparent
- },
- {
- label: \Repost
- data: data.map (x) ~> x.reposts
- line-tension: 0
- point-radius: 0
- background-color: \#a2d61e
- border-color: \transparent
- },
- {
- label: \返信
- data: data.map (x) ~> x.replies
- line-tension: 0
- point-radius: 0
- background-color: \#F7796C
- border-color: \transparent
- }
- ]
- options:
- responsive: false
- scales:
- x-axes: [
+ @api \aggregation/users/post do
+ user_id: @user.id
+ limit: 30days
+ .then (data) ~>
+ data = data.reverse!
+ new Chart @refs.canv, do
+ type: \line
+ data:
+ labels: data.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
+ datasets: [
{
- stacked: true
- }
- ]
- y-axes: [
+ label: \投稿
+ data: data.map (x) ~> x.posts
+ line-tension: 0
+ point-radius: 0
+ background-color: \#555
+ border-color: \transparent
+ },
+ {
+ label: \Repost
+ data: data.map (x) ~> x.reposts
+ line-tension: 0
+ point-radius: 0
+ background-color: \#a2d61e
+ border-color: \transparent
+ },
{
- stacked: true
+ label: \返信
+ data: data.map (x) ~> x.replies
+ line-tension: 0
+ point-radius: 0
+ background-color: \#F7796C
+ border-color: \transparent
}
]
+ options:
+ responsive: false
+ scales:
+ x-axes: [
+ {
+ stacked: true
+ }
+ ]
+ y-axes: [
+ {
+ stacked: true
+ }
+ ]
+ </script>
+</mk-user-posts-graph>
diff --git a/src/web/app/desktop/tags/user-preview.tag b/src/web/app/desktop/tags/user-preview.tag
index f299e6236e..ed1d868781 100644
--- a/src/web/app/desktop/tags/user-preview.tag
+++ b/src/web/app/desktop/tags/user-preview.tag
@@ -1,143 +1,148 @@
-mk-user-preview
- virtual(if={ user != null })
- div.banner(style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=512)' : '' })
- a.avatar(href={ CONFIG.url + '/' + user.username }, target='_blank'): img(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.title
- p.name { user.name }
- p.username @{ user.username }
- div.bio { user.bio }
- div.status
- div
- p 投稿
- a { user.posts_count }
- div
- p フォロー
- a { user.following_count }
- div
- p フォロワー
- a { user.followers_count }
- mk-follow-button(if={ SIGNIN && user.id != I.id }, user={ user-promise })
-
-style.
- display block
- position absolute
- z-index 2048
- width 250px
- background #fff
- background-clip content-box
- border solid 1px rgba(0, 0, 0, 0.1)
- border-radius 4px
- overflow hidden
-
- // https://github.com/riot/riot/issues/2081
- > virtual
- display block
- position relative
-
- > .banner
- height 84px
- background-color #f5f5f5
- background-size cover
- background-position center
-
- > .avatar
+<mk-user-preview>
+ <virtual if="{ user != null }">
+ <div class="banner" style="{ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&amp;size=512)' : '' }"></div><a class="avatar" href="{ CONFIG.url + '/' + user.username }" target="_blank"><img src="{ user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="title">
+ <p class="name">{ user.name }</p>
+ <p class="username">@{ user.username }</p>
+ </div>
+ <div class="bio">{ user.bio }</div>
+ <div class="status">
+ <div>
+ <p>投稿</p><a>{ user.posts_count }</a>
+ </div>
+ <div>
+ <p>フォロー</p><a>{ user.following_count }</a>
+ </div>
+ <div>
+ <p>フォロワー</p><a>{ user.followers_count }</a>
+ </div>
+ </div>
+ <mk-follow-button if="{ SIGNIN &amp;&amp; user.id != I.id }" user="{ userPromise }"></mk-follow-button>
+ </virtual>
+ <style type="stylus">
+ :scope
display block
position absolute
- top 62px
- left 13px
+ z-index 2048
+ width 250px
+ background #fff
+ background-clip content-box
+ border solid 1px rgba(0, 0, 0, 0.1)
+ border-radius 4px
+ overflow hidden
- > img
+ // https://github.com/riot/riot/issues/2081
+ > virtual
display block
- width 58px
- height 58px
- margin 0
- border solid 3px #fff
- border-radius 8px
+ position relative
- > .title
- display block
- padding 8px 0 8px 85px
+ > .banner
+ height 84px
+ background-color #f5f5f5
+ background-size cover
+ background-position center
- > .name
- display block
- margin 0
- font-weight bold
- line-height 16px
- color #656565
+ > .avatar
+ display block
+ position absolute
+ top 62px
+ left 13px
- > .username
- display block
- margin 0
- line-height 16px
- font-size 0.8em
- color #999
+ > img
+ display block
+ width 58px
+ height 58px
+ margin 0
+ border solid 3px #fff
+ border-radius 8px
- > .bio
- padding 0 16px
- font-size 0.7em
- color #555
+ > .title
+ display block
+ padding 8px 0 8px 85px
- > .status
- padding 8px 16px
+ > .name
+ display block
+ margin 0
+ font-weight bold
+ line-height 16px
+ color #656565
- > div
- display inline-block
- width 33%
+ > .username
+ display block
+ margin 0
+ line-height 16px
+ font-size 0.8em
+ color #999
- > p
- margin 0
+ > .bio
+ padding 0 16px
font-size 0.7em
- color #aaa
+ color #555
- > a
- font-size 1em
- color $theme-color
+ > .status
+ padding 8px 16px
- > mk-follow-button
- position absolute
- top 92px
- right 8px
+ > div
+ display inline-block
+ width 33%
+
+ > p
+ margin 0
+ font-size 0.7em
+ color #aaa
+
+ > a
+ font-size 1em
+ color $theme-color
+
+ > mk-follow-button
+ position absolute
+ top 92px
+ right 8px
-script.
- @mixin \i
- @mixin \api
+ </style>
+ <script>
+ @mixin \i
+ @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
+ @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
- @on \mount ~>
- @user-promise.then (user) ~>
- @user = user
- @update!
+ @on \mount ~>
+ @user-promise.then (user) ~>
+ @user = user
+ @update!
- Velocity @root, {
- opacity: 0
- 'margin-top': \-8px
- } 0ms
- Velocity @root, {
- opacity: 1
- 'margin-top': 0
- } {
- duration: 200ms
- easing: \ease-out
- }
+ Velocity @root, {
+ opacity: 0
+ 'margin-top': \-8px
+ } 0ms
+ Velocity @root, {
+ opacity: 1
+ 'margin-top': 0
+ } {
+ duration: 200ms
+ easing: \ease-out
+ }
- @close = ~>
- Velocity @root, {
- opacity: 0
- 'margin-top': \-8px
- } {
- duration: 200ms
- easing: \ease-out
- complete: ~> @unmount!
- }
+ @close = ~>
+ Velocity @root, {
+ opacity: 0
+ 'margin-top': \-8px
+ } {
+ duration: 200ms
+ easing: \ease-out
+ complete: ~> @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 adb685845c..1079282ed3 100644
--- a/src/web/app/desktop/tags/user-profile.tag
+++ b/src/web/app/desktop/tags/user-profile.tag
@@ -1,86 +1,83 @@
-mk-user-profile
- div.friend-form(if={ SIGNIN && I.id != user.id })
- mk-big-follow-button(user={ user })
- p.followed(if={ user.is_followed }) フォローされています
- div.bio(if={ user.bio != '' }) { user.bio }
- div.birthday(if={ user.birthday }): p
- i.fa.fa-birthday-cake
- | { user.birthday.replace('-', '年').replace('-', '月') + '日' }
- div.friends
- p.following
- i.fa.fa-angle-right
- a(onclick={ show-following }) { user.following_count }
- | 人を
- b フォロー
- p.followers
- i.fa.fa-angle-right
- a(onclick={ show-followers }) { user.followers_count }
- | 人の
- b フォロワー
+<mk-user-profile>
+ <div class="friend-form" if="{ SIGNIN &amp;&amp; I.id != user.id }">
+ <mk-big-follow-button user="{ user }"></mk-big-follow-button>
+ <p class="followed" if="{ user.is_followed }">フォローされています</p>
+ </div>
+ <div class="bio" if="{ user.bio != '' }">{ user.bio }</div>
+ <div class="birthday" if="{ user.birthday }">
+ <p><i class="fa fa-birthday-cake"></i>{ user.birthday.replace('-', '年').replace('-', '月') + '日' }</p>
+ </div>
+ <div class="friends">
+ <p class="following"><i class="fa fa-angle-right"></i><a onclick="{ showFollowing }">{ user.following_count }</a>人を<b>フォロー</b></p>
+ <p class="followers"><i class="fa fa-angle-right"></i><a onclick="{ showFollowers }">{ user.followers_count }</a>人の<b>フォロワー</b></p>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > *:first-child
+ border-top none !important
- > *:first-child
- border-top none !important
+ > .friend-form
+ padding 16px
+ border-top solid 1px #eee
- > .friend-form
- padding 16px
- border-top solid 1px #eee
+ > mk-big-follow-button
+ width 100%
- > mk-big-follow-button
- width 100%
+ > .followed
+ margin 12px 0 0 0
+ padding 0
+ text-align center
+ line-height 24px
+ font-size 0.8em
+ color #71afc7
+ background #eefaff
+ border-radius 4px
- > .followed
- margin 12px 0 0 0
- padding 0
- text-align center
- line-height 24px
- font-size 0.8em
- color #71afc7
- background #eefaff
- border-radius 4px
+ > .bio
+ padding 16px
+ color #555
+ border-top solid 1px #eee
- > .bio
- padding 16px
- color #555
- border-top solid 1px #eee
+ > .birthday
+ padding 16px
+ color #555
+ border-top solid 1px #eee
- > .birthday
- padding 16px
- color #555
- border-top solid 1px #eee
+ > p
+ margin 0
- > p
- margin 0
+ > i
+ margin-right 8px
- > i
- margin-right 8px
+ > .friends
+ padding 16px
+ color #555
+ border-top solid 1px #eee
- > .friends
- padding 16px
- color #555
- border-top solid 1px #eee
+ > p
+ margin 8px 0
- > p
- margin 8px 0
+ > i
+ margin-left 8px
+ margin-right 8px
- > i
- margin-left 8px
- margin-right 8px
+ </style>
+ <script>
+ @mixin \i
-script.
- @mixin \i
+ @user = @opts.user
- @user = @opts.user
+ @show-following = ~>
+ window = document.body.append-child document.create-element \mk-user-following-window
+ riot.mount window, do
+ user: @user
- @show-following = ~>
- window = document.body.append-child document.create-element \mk-user-following-window
- riot.mount window, do
- user: @user
-
- @show-followers = ~>
- window = document.body.append-child document.create-element \mk-user-followers-window
- riot.mount window, do
- user: @user
+ @show-followers = ~>
+ window = document.body.append-child document.create-element \mk-user-followers-window
+ riot.mount window, do
+ user: @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 ced90e2e84..89eb53933a 100644
--- a/src/web/app/desktop/tags/user-timeline.tag
+++ b/src/web/app/desktop/tags/user-timeline.tag
@@ -1,142 +1,138 @@
-mk-user-timeline
- header
- span(data-is-active={ mode == 'default' }, onclick={ set-mode.bind(this, 'default') }) 投稿
- span(data-is-active={ mode == 'with-replies' }, onclick={ set-mode.bind(this, 'with-replies') }) 投稿と返信
- div.loading(if={ is-loading })
- mk-ellipsis-icon
- p.empty(if={ is-empty })
- i.fa.fa-comments-o
- | このユーザーはまだ何も投稿していないようです。
- mk-timeline@timeline
- <yield to="footer">
- i.fa.fa-moon-o(if={ !parent.more-loading })
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
- </yield>
+<mk-user-timeline>
+ <header><span data-is-active="{ mode == 'default' }" onclick="{ setMode.bind(this, 'default') }">投稿</span><span data-is-active="{ mode == 'with-replies' }" onclick="{ setMode.bind(this, 'with-replies') }">投稿と返信</span></header>
+ <div class="loading" if="{ isLoading }">
+ <mk-ellipsis-icon></mk-ellipsis-icon>
+ </div>
+ <p class="empty" if="{ isEmpty }"><i class="fa fa-comments-o"></i>このユーザーはまだ何も投稿していないようです。</p>
+ <mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > header
+ padding 8px 16px
+ border-bottom solid 1px #eee
- > header
- padding 8px 16px
- border-bottom solid 1px #eee
+ > span
+ margin-right 16px
+ line-height 27px
+ font-size 18px
+ color #555
- > span
- margin-right 16px
- line-height 27px
- font-size 18px
- color #555
+ &:not([data-is-active])
+ color $theme-color
+ cursor pointer
- &:not([data-is-active])
- color $theme-color
- cursor pointer
+ &:hover
+ text-decoration underline
- &:hover
- text-decoration underline
+ > .loading
+ padding 64px 0
- > .loading
- padding 64px 0
+ > .empty
+ display block
+ margin 0 auto
+ padding 32px
+ max-width 400px
+ text-align center
+ color #999
- > .empty
- display block
- margin 0 auto
- padding 32px
- max-width 400px
- text-align center
- color #999
+ > i
+ display block
+ margin-bottom 16px
+ font-size 3em
+ color #ccc
- > i
- display block
- margin-bottom 16px
- font-size 3em
- color #ccc
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
+ @mixin \get-post-summary
-script.
- @mixin \api
- @mixin \is-promise
- @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
- @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
+ @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
- @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
+ @user-promise.then (user) ~>
+ @user = user
+ @update!
- @user-promise.then (user) ~>
- @user = user
- @update!
+ @fetch ~>
+ @trigger \loaded
- @fetch ~>
- @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
- @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
+ @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!
- @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!
+ @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!
- @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
+ @more = ~>
+ if @more-loading or @is-loading or @refs.timeline.posts.length == 0
+ return
+ @more-loading = true
@update!
- @refs.timeline.set-posts posts
- if cb? then cb!
- .catch (err) ~>
- console.error err
- if cb? then cb!
+ @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
- @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
+ @on-stream-post = (post) ~>
+ @is-empty = false
@update!
- @refs.timeline.prepend-posts posts
- .catch (err) ~>
- console.error err
-
- @on-stream-post = (post) ~>
- @is-empty = false
- @update!
- @refs.timeline.add-post post
+ @refs.timeline.add-post post
- if document.hidden
- @unread-count++
- document.title = '(' + @unread-count + ') ' + @get-post-summary post
+ 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'
+ @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!
+ @on-scroll = ~>
+ current = window.scroll-y + window.inner-height
+ if current > document.body.offset-height - 16 # 遊び
+ @more!
- @set-mode = (mode) ~>
- @update do
- mode: mode
- @fetch!
+ @set-mode = (mode) ~>
+ @update do
+ mode: mode
+ @fetch!
+ </script>
+</mk-user-timeline>
diff --git a/src/web/app/desktop/tags/user.tag b/src/web/app/desktop/tags/user.tag
index 4d022e68c4..777d9caee7 100644
--- a/src/web/app/desktop/tags/user.tag
+++ b/src/web/app/desktop/tags/user.tag
@@ -1,45 +1,51 @@
-mk-user
- div.user(if={ !fetching })
- header
- mk-user-header(user={ user })
- div.body
- mk-user-home(if={ page == 'home' }, user={ user })
- mk-user-graphs(if={ page == 'graphs' }, user={ user })
+<mk-user>
+ <div class="user" if="{ !fetching }">
+ <header>
+ <mk-user-header user="{ user }"></mk-user-header>
+ </header>
+ <div class="body">
+ <mk-user-home if="{ page == 'home' }" user="{ user }"></mk-user-home>
+ <mk-user-graphs if="{ page == 'graphs' }" user="{ user }"></mk-user-graphs>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > .user
+ > header
+ max-width 560px + 270px
+ margin 0 auto
+ padding 0 16px
- > .user
- > header
- max-width 560px + 270px
- margin 0 auto
- padding 0 16px
+ > mk-user-header
+ border solid 1px rgba(0, 0, 0, 0.075)
+ border-top none
+ border-radius 0 0 6px 6px
+ overflow hidden
- > mk-user-header
- border solid 1px rgba(0, 0, 0, 0.075)
- border-top none
- border-radius 0 0 6px 6px
- overflow hidden
+ > .body
+ max-width 560px + 270px
+ margin 0 auto
+ padding 0 16px
- > .body
- max-width 560px + 270px
- margin 0 auto
- padding 0 16px
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @username = @opts.user
+ @page = if @opts.page? then @opts.page else \home
+ @fetching = true
+ @user = null
- @username = @opts.user
- @page = if @opts.page? then @opts.page else \home
- @fetching = true
- @user = null
-
- @on \mount ~>
- @api \users/show do
- username: @username
- .then (user) ~>
- @fetching = false
- @user = user
- @update!
- @trigger \loaded
+ @on \mount ~>
+ @api \users/show do
+ username: @username
+ .then (user) ~>
+ @fetching = false
+ @user = user
+ @update!
+ @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 9ae96eed9f..e2b0ef1332 100644
--- a/src/web/app/desktop/tags/users-list.tag
+++ b/src/web/app/desktop/tags/users-list.tag
@@ -1,139 +1,134 @@
-mk-users-list
- nav: div
- span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') })
- | すべて
- span { opts.count }
- // ↓ https://github.com/riot/riot/issues/2080
- span(if={ SIGNIN && opts.you-know-count != '' }, data-is-active={ mode == 'iknow' }, onclick={ set-mode.bind(this, 'iknow') })
- | 知り合い
- span { opts.you-know-count }
+<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 &amp;&amp; opts.youKnowCount != '' }" data-is-active="{ mode == 'iknow' }" onclick="{ setMode.bind(this, 'iknow') }">知り合い<span>{ opts.youKnowCount }</span></span>
+ </div>
+ </nav>
+ <div class="users" if="{ !fetching &amp;&amp; users.length != 0 }">
+ <div each="{ users }">
+ <mk-list-user user="{ this }"></mk-list-user>
+ </div>
+ </div>
+ <button class="more" if="{ !fetching &amp;&amp; next != null }" onclick="{ more }" disabled="{ moreFetching }"><span if="{ !moreFetching }">もっと</span><span if="{ moreFetching }">読み込み中
+ <mk-ellipsis></mk-ellipsis></span></button>
+ <p class="no" if="{ !fetching &amp;&amp; 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>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
+ height 100%
+ background #fff
- div.users(if={ !fetching && users.length != 0 })
- div(each={ users }): mk-list-user(user={ this })
+ > nav
+ z-index 1
+ box-shadow 0 1px 0 rgba(#000, 0.1)
- button.more(if={ !fetching && next != null }, onclick={ more }, disabled={ more-fetching })
- span(if={ !more-fetching }) もっと
- span(if={ more-fetching })
- | 読み込み中
- mk-ellipsis
+ > div
+ display flex
+ justify-content center
+ margin 0 auto
+ max-width 600px
- p.no(if={ !fetching && users.length == 0 })
- | { opts.no-users }
- p.fetching(if={ fetching })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
+ > span
+ display block
+ flex 1 1
+ text-align center
+ line-height 52px
+ font-size 14px
+ color #657786
+ border-bottom solid 2px transparent
+ cursor pointer
-style.
- display block
- height 100%
- background #fff
+ *
+ pointer-events none
- > nav
- z-index 1
- box-shadow 0 1px 0 rgba(#000, 0.1)
+ &[data-is-active]
+ font-weight bold
+ color $theme-color
+ border-color $theme-color
+ cursor default
- > div
- display flex
- justify-content center
- margin 0 auto
- max-width 600px
+ > span
+ display inline-block
+ margin-left 4px
+ padding 2px 5px
+ font-size 12px
+ line-height 1
+ color #888
+ background #eee
+ border-radius 20px
- > span
- display block
- flex 1 1
- text-align center
- line-height 52px
- font-size 14px
- color #657786
- border-bottom solid 2px transparent
- cursor pointer
-
- *
- pointer-events none
-
- &[data-is-active]
- font-weight bold
- color $theme-color
- border-color $theme-color
- cursor default
+ > .users
+ height calc(100% - 54px)
+ overflow auto
- > span
- display inline-block
- margin-left 4px
- padding 2px 5px
- font-size 12px
- line-height 1
- color #888
- background #eee
- border-radius 20px
+ > *
+ border-bottom solid 1px rgba(0, 0, 0, 0.05)
- > .users
- height calc(100% - 54px)
- overflow auto
+ > *
+ max-width 600px
+ margin 0 auto
- > *
- border-bottom solid 1px rgba(0, 0, 0, 0.05)
-
- > *
- max-width 600px
- margin 0 auto
-
- > .no
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > .no
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- > .fetching
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > .fetching
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- > i
- margin-right 4px
+ > i
+ margin-right 4px
-script.
- @mixin \i
+ </style>
+ <script>
+ @mixin \i
- @limit = 30users
- @mode = \all
+ @limit = 30users
+ @mode = \all
- @fetching = true
- @more-fetching = false
+ @fetching = true
+ @more-fetching = false
- @on \mount ~>
- @fetch ~>
- @trigger \loaded
+ @on \mount ~>
+ @fetch ~>
+ @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!
+ @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!
- @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!
+ @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!
- @set-mode = (mode) ~>
- @update do
- mode: mode
+ @set-mode = (mode) ~>
+ @update do
+ mode: mode
- @fetch!
+ @fetch!
+ </script>
+</mk-users-list>
diff --git a/src/web/app/desktop/tags/window.tag b/src/web/app/desktop/tags/window.tag
index 9732a6c552..750df64df0 100644
--- a/src/web/app/desktop/tags/window.tag
+++ b/src/web/app/desktop/tags/window.tag
@@ -1,515 +1,519 @@
-mk-window(data-flexible={ is-flexible }, data-colored={ opts.colored }, ondragover={ ondragover })
- div.bg@bg(show={ is-modal }, onclick={ bg-click })
- div.main@main(tabindex='-1', data-is-modal={ is-modal }, onmousedown={ on-body-mousedown }, onkeydown={ on-keydown })
- div.body
- header@header(onmousedown={ on-header-mousedown })
- h1(data-yield='header')
- | <yield from="header"/>
- button.close(if={ can-close }, onmousedown={ repel-move }, onclick={ close }, title='閉じる'): i.fa.fa-times
- div.content(data-yield='content')
- | <yield from="content"/>
- div.handle.top(if={ can-resize }, onmousedown={ on-top-handle-mousedown })
- div.handle.right(if={ can-resize }, onmousedown={ on-right-handle-mousedown })
- div.handle.bottom(if={ can-resize }, onmousedown={ on-bottom-handle-mousedown })
- div.handle.left(if={ can-resize }, onmousedown={ on-left-handle-mousedown })
- div.handle.top-left(if={ can-resize }, onmousedown={ on-top-left-handle-mousedown })
- div.handle.top-right(if={ can-resize }, onmousedown={ on-top-right-handle-mousedown })
- div.handle.bottom-right(if={ can-resize }, onmousedown={ on-bottom-right-handle-mousedown })
- div.handle.bottom-left(if={ can-resize }, onmousedown={ on-bottom-left-handle-mousedown })
+<mk-window data-flexible="{ isFlexible }" data-colored="{ opts.colored }" ondragover="{ ondragover }">
+ <div class="bg" ref="bg" show="{ isModal }" onclick="{ bgClick }"></div>
+ <div class="main" ref="main" tabindex="-1" data-is-modal="{ isModal }" onmousedown="{ onBodyMousedown }" onkeydown="{ onKeydown }">
+ <div class="body">
+ <header ref="header" onmousedown="{ onHeaderMousedown }">
+ <h1 data-yield="header"><yield from="header"/></h1>
+ <button class="close" if="{ canClose }" onmousedown="{ repelMove }" onclick="{ close }" title="閉じる"><i class="fa fa-times"></i></button>
+ </header>
+ <div class="content" data-yield="content"><yield from="content"/></div>
+ </div>
+ <div class="handle top" if="{ canResize }" onmousedown="{ onTopHandleMousedown }"></div>
+ <div class="handle right" if="{ canResize }" onmousedown="{ onRightHandleMousedown }"></div>
+ <div class="handle bottom" if="{ canResize }" onmousedown="{ onBottomHandleMousedown }"></div>
+ <div class="handle left" if="{ canResize }" onmousedown="{ onLeftHandleMousedown }"></div>
+ <div class="handle top-left" if="{ canResize }" onmousedown="{ onTopLeftHandleMousedown }"></div>
+ <div class="handle top-right" if="{ canResize }" onmousedown="{ onTopRightHandleMousedown }"></div>
+ <div class="handle bottom-right" if="{ canResize }" onmousedown="{ onBottomRightHandleMousedown }"></div>
+ <div class="handle bottom-left" if="{ canResize }" onmousedown="{ onBottomLeftHandleMousedown }"></div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > .bg
+ display block
+ position fixed
+ z-index 2048
+ top 0
+ left 0
+ width 100%
+ height 100%
+ background rgba(0, 0, 0, 0.7)
+ opacity 0
+ pointer-events none
- > .bg
- display block
- position fixed
- z-index 2048
- top 0
- left 0
- width 100%
- height 100%
- background rgba(0, 0, 0, 0.7)
- opacity 0
- pointer-events none
+ > .main
+ display block
+ position fixed
+ z-index 2048
+ top 15%
+ left 0
+ margin 0
+ opacity 0
+ pointer-events none
- > .main
- display block
- position fixed
- z-index 2048
- top 15%
- left 0
- margin 0
- opacity 0
- pointer-events none
+ &:focus
+ &:not([data-is-modal])
+ > .body
+ box-shadow 0 0 0px 1px rgba($theme-color, 0.5), 0 2px 6px 0 rgba(0, 0, 0, 0.2)
- &:focus
- &:not([data-is-modal])
- > .body
- box-shadow 0 0 0px 1px rgba($theme-color, 0.5), 0 2px 6px 0 rgba(0, 0, 0, 0.2)
+ > .handle
+ $size = 8px
- > .handle
- $size = 8px
+ position absolute
- position absolute
+ &.top
+ top -($size)
+ left 0
+ width 100%
+ height $size
+ cursor ns-resize
- &.top
- top -($size)
- left 0
- width 100%
- height $size
- cursor ns-resize
+ &.right
+ top 0
+ right -($size)
+ width $size
+ height 100%
+ cursor ew-resize
- &.right
- top 0
- right -($size)
- width $size
- height 100%
- cursor ew-resize
+ &.bottom
+ bottom -($size)
+ left 0
+ width 100%
+ height $size
+ cursor ns-resize
- &.bottom
- bottom -($size)
- left 0
- width 100%
- height $size
- cursor ns-resize
+ &.left
+ top 0
+ left -($size)
+ width $size
+ height 100%
+ cursor ew-resize
- &.left
- top 0
- left -($size)
- width $size
- height 100%
- cursor ew-resize
+ &.top-left
+ top -($size)
+ left -($size)
+ width $size * 2
+ height $size * 2
+ cursor nwse-resize
- &.top-left
- top -($size)
- left -($size)
- width $size * 2
- height $size * 2
- cursor nwse-resize
+ &.top-right
+ top -($size)
+ right -($size)
+ width $size * 2
+ height $size * 2
+ cursor nesw-resize
- &.top-right
- top -($size)
- right -($size)
- width $size * 2
- height $size * 2
- cursor nesw-resize
+ &.bottom-right
+ bottom -($size)
+ right -($size)
+ width $size * 2
+ height $size * 2
+ cursor nwse-resize
- &.bottom-right
- bottom -($size)
- right -($size)
- width $size * 2
- height $size * 2
- cursor nwse-resize
+ &.bottom-left
+ bottom -($size)
+ left -($size)
+ width $size * 2
+ height $size * 2
+ cursor nesw-resize
- &.bottom-left
- bottom -($size)
- left -($size)
- width $size * 2
- height $size * 2
- cursor nesw-resize
+ > .body
+ height 100%
+ overflow hidden
+ background #fff
+ border-radius 6px
+ box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2)
- > .body
- height 100%
- overflow hidden
- background #fff
- border-radius 6px
- box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2)
+ > header
+ z-index 128
+ overflow hidden
+ cursor move
+ background #fff
+ border-radius 6px 6px 0 0
+ box-shadow 0 1px 0 rgba(#000, 0.1)
- > header
- z-index 128
- overflow hidden
- cursor move
- background #fff
- border-radius 6px 6px 0 0
- box-shadow 0 1px 0 rgba(#000, 0.1)
+ &, *
+ user-select none
- &, *
- user-select none
+ > h1
+ pointer-events none
+ display block
+ margin 0
+ height 40px
+ text-align center
+ font-size 1em
+ line-height 40px
+ font-weight normal
+ color #666
- > h1
- pointer-events none
- display block
- margin 0
- height 40px
- text-align center
- font-size 1em
- line-height 40px
- font-weight normal
- color #666
+ > .close
+ cursor pointer
+ display block
+ position absolute
+ top 0
+ right 0
+ z-index 1
+ margin 0
+ padding 0
+ font-size 1.2em
+ color rgba(#000, 0.4)
+ border none
+ outline none
+ background transparent
- > .close
- cursor pointer
- display block
- position absolute
- top 0
- right 0
- z-index 1
- margin 0
- padding 0
- font-size 1.2em
- color rgba(#000, 0.4)
- border none
- outline none
- background transparent
+ &:hover
+ color rgba(#000, 0.6)
- &:hover
- color rgba(#000, 0.6)
+ &:active
+ color darken(#000, 30%)
- &:active
- color darken(#000, 30%)
+ > i
+ padding 0
+ width 40px
+ line-height 40px
- > i
- padding 0
- width 40px
- line-height 40px
+ > .content
+ height 100%
- > .content
- height 100%
+ &:not([flexible])
+ > .main > .body > .content
+ height calc(100% - 40px)
- &:not([flexible])
- > .main > .body > .content
- height calc(100% - 40px)
+ &[data-colored]
- &[data-colored]
+ > .main > .body
- > .main > .body
+ > header
+ box-shadow 0 1px 0 rgba($theme-color, 0.1)
- > header
- box-shadow 0 1px 0 rgba($theme-color, 0.1)
+ > h1
+ color #d0b4ac
- > h1
- color #d0b4ac
+ > .close
+ color rgba($theme-color, 0.4)
- > .close
- color rgba($theme-color, 0.4)
+ &:hover
+ color rgba($theme-color, 0.6)
- &:hover
- color rgba($theme-color, 0.6)
+ &:active
+ color darken($theme-color, 30%)
- &:active
- color darken($theme-color, 30%)
+ </style>
+ <script>
+ @min-height = 40px
+ @min-width = 200px
-script.
- @min-height = 40px
- @min-width = 200px
+ @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
- @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
+ @on \mount ~>
+ @refs.main.style.width = @opts.width || \530px
+ @refs.main.style.height = @opts.height || \auto
- @on \mount ~>
- @refs.main.style.width = @opts.width || \530px
- @refs.main.style.height = @opts.height || \auto
+ @refs.main.style.top = \15%
+ @refs.main.style.left = (window.inner-width / 2) - (@refs.main.offset-width / 2) + \px
- @refs.main.style.top = \15%
- @refs.main.style.left = (window.inner-width / 2) - (@refs.main.offset-width / 2) + \px
+ @refs.header.add-event-listener \contextmenu (e) ~>
+ e.prevent-default!
- @refs.header.add-event-listener \contextmenu (e) ~>
- e.prevent-default!
+ window.add-event-listener \resize @on-browser-resize
- window.add-event-listener \resize @on-browser-resize
+ @open!
- @open!
+ @on \unmount ~>
+ window.remove-event-listener \resize @on-browser-resize
- @on \unmount ~>
- window.remove-event-listener \resize @on-browser-resize
+ @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
- @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
+ if position.left < 0
+ @refs.main.style.left = 0
- if position.left < 0
- @refs.main.style.left = 0
+ if position.top < 0
+ @refs.main.style.top = 0
- if position.top < 0
- @refs.main.style.top = 0
+ if position.left + window-width > browser-width
+ @refs.main.style.left = browser-width - window-width + \px
- if position.left + window-width > browser-width
- @refs.main.style.left = browser-width - window-width + \px
+ if position.top + window-height > browser-height
+ @refs.main.style.top = browser-height - window-height + \px
- if position.top + window-height > browser-height
- @refs.main.style.top = browser-height - window-height + \px
+ @open = ~>
+ @trigger \opening
- @open = ~>
- @trigger \opening
+ @top!
- @top!
+ if @is-modal
+ @refs.bg.style.pointer-events = \auto
+ Velocity @refs.bg, \finish true
+ Velocity @refs.bg, {
+ opacity: 1
+ } {
+ queue: false
+ duration: 100ms
+ easing: \linear
+ }
- if @is-modal
- @refs.bg.style.pointer-events = \auto
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
+ @refs.main.style.pointer-events = \auto
+ Velocity @refs.main, \finish true
+ Velocity @refs.main, {scale: 1.1} 0ms
+ Velocity @refs.main, {
opacity: 1
+ scale: 1
} {
queue: false
- duration: 100ms
- easing: \linear
+ duration: 200ms
+ easing: \ease-out
}
- @refs.main.style.pointer-events = \auto
- Velocity @refs.main, \finish true
- Velocity @refs.main, {scale: 1.1} 0ms
- Velocity @refs.main, {
- opacity: 1
- scale: 1
- } {
- queue: false
- duration: 200ms
- easing: \ease-out
- }
+ #@refs.main.focus!
- #@refs.main.focus!
+ set-timeout ~>
+ @trigger \opened
+ , 300ms
- set-timeout ~>
- @trigger \opened
- , 300ms
+ @close = ~>
+ @trigger \closing
- @close = ~>
- @trigger \closing
+ if @is-modal
+ @refs.bg.style.pointer-events = \none
+ Velocity @refs.bg, \finish true
+ Velocity @refs.bg, {
+ opacity: 0
+ } {
+ queue: false
+ duration: 300ms
+ easing: \linear
+ }
- if @is-modal
- @refs.bg.style.pointer-events = \none
- Velocity @refs.bg, \finish true
- Velocity @refs.bg, {
+ @refs.main.style.pointer-events = \none
+ Velocity @refs.main, \finish true
+ Velocity @refs.main, {
opacity: 0
+ scale: 0.8
} {
queue: false
duration: 300ms
- easing: \linear
+ easing: [ 0.5, -0.5, 1, 0.5 ]
}
- @refs.main.style.pointer-events = \none
- Velocity @refs.main, \finish true
- Velocity @refs.main, {
- opacity: 0
- scale: 0.8
- } {
- queue: false
- duration: 300ms
- easing: [ 0.5, -0.5, 1, 0.5 ]
- }
+ set-timeout ~>
+ @trigger \closed
+ , 300ms
- set-timeout ~>
- @trigger \closed
- , 300ms
+ # 最前面へ移動します
+ @top = ~>
+ z = 0
- # 最前面へ移動します
- @top = ~>
- 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
- 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
+ if z > 0
+ @refs.main.style.z-index = z + 1
+ if @is-modal then @refs.bg.style.z-index = z + 1
- if z > 0
- @refs.main.style.z-index = z + 1
- if @is-modal then @refs.bg.style.z-index = z + 1
+ @repel-move = (e) ~>
+ e.stop-propagation!
+ return true
- @repel-move = (e) ~>
- e.stop-propagation!
- return true
-
- @bg-click = ~>
- if @can-close
- @close!
+ @bg-click = ~>
+ if @can-close
+ @close!
- @on-body-mousedown = (e) ~>
- @top!
- true
+ @on-body-mousedown = (e) ~>
+ @top!
+ true
- # ヘッダー掴み時
- @on-header-mousedown = (e) ~>
- e.prevent-default!
+ # ヘッダー掴み時
+ @on-header-mousedown = (e) ~>
+ e.prevent-default!
- if not contains @refs.main, document.active-element
- @refs.main.focus!
+ if not contains @refs.main, document.active-element
+ @refs.main.focus!
- position = @refs.main.get-bounding-client-rect!
+ position = @refs.main.get-bounding-client-rect!
- 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
+ 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
- # 動かした時
- drag-listen (me) ~>
- move-left = me.client-x - move-base-x
- move-top = me.client-y - move-base-y
+ # 動かした時
+ drag-listen (me) ~>
+ move-left = me.client-x - move-base-x
+ move-top = me.client-y - move-base-y
- # 上はみ出し
- if move-top < 0
- move-top = 0
+ # 上はみ出し
+ if move-top < 0
+ move-top = 0
- # 左はみ出し
- if move-left < 0
- move-left = 0
+ # 左はみ出し
+ if move-left < 0
+ move-left = 0
- # 下はみ出し
- if move-top + window-height > browser-height
- move-top = browser-height - window-height
+ # 下はみ出し
+ if move-top + window-height > browser-height
+ move-top = browser-height - window-height
- # 右はみ出し
- if move-left + window-width > browser-width
- move-left = browser-width - window-width
+ # 右はみ出し
+ if move-left + window-width > browser-width
+ move-left = browser-width - window-width
- @refs.main.style.left = move-left + \px
- @refs.main.style.top = move-top + \px
+ @refs.main.style.left = move-left + \px
+ @refs.main.style.top = move-top + \px
- # 上ハンドル掴み時
- @on-top-handle-mousedown = (e) ~>
- e.prevent-default!
+ # 上ハンドル掴み時
+ @on-top-handle-mousedown = (e) ~>
+ e.prevent-default!
- base = e.client-y
- height = parse-int((get-computed-style @refs.main, '').height, 10)
- top = parse-int((get-computed-style @refs.main, '').top, 10)
+ base = e.client-y
+ height = parse-int((get-computed-style @refs.main, '').height, 10)
+ top = parse-int((get-computed-style @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
+ # 動かした時
+ 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
- # 右ハンドル掴み時
- @on-right-handle-mousedown = (e) ~>
- e.prevent-default!
+ # 右ハンドル掴み時
+ @on-right-handle-mousedown = (e) ~>
+ e.prevent-default!
- 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
+ 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
- # 動かした時
- 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
+ # 動かした時
+ 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
- # 下ハンドル掴み時
- @on-bottom-handle-mousedown = (e) ~>
- e.prevent-default!
+ # 下ハンドル掴み時
+ @on-bottom-handle-mousedown = (e) ~>
+ e.prevent-default!
- 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
+ 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
- # 動かした時
- 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
+ # 動かした時
+ 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
- # 左ハンドル掴み時
- @on-left-handle-mousedown = (e) ~>
- e.prevent-default!
+ # 左ハンドル掴み時
+ @on-left-handle-mousedown = (e) ~>
+ e.prevent-default!
- base = e.client-x
- width = parse-int((get-computed-style @refs.main, '').width, 10)
- left = parse-int((get-computed-style @refs.main, '').left, 10)
+ base = e.client-x
+ width = parse-int((get-computed-style @refs.main, '').width, 10)
+ left = parse-int((get-computed-style @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
+ # 動かした時
+ 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
- # 左上ハンドル掴み時
- @on-top-left-handle-mousedown = (e) ~>
- @on-top-handle-mousedown e
- @on-left-handle-mousedown e
+ # 左上ハンドル掴み時
+ @on-top-left-handle-mousedown = (e) ~>
+ @on-top-handle-mousedown e
+ @on-left-handle-mousedown e
- # 右上ハンドル掴み時
- @on-top-right-handle-mousedown = (e) ~>
- @on-top-handle-mousedown e
- @on-right-handle-mousedown e
+ # 右上ハンドル掴み時
+ @on-top-right-handle-mousedown = (e) ~>
+ @on-top-handle-mousedown e
+ @on-right-handle-mousedown e
- # 右下ハンドル掴み時
- @on-bottom-right-handle-mousedown = (e) ~>
- @on-bottom-handle-mousedown e
- @on-right-handle-mousedown e
+ # 右下ハンドル掴み時
+ @on-bottom-right-handle-mousedown = (e) ~>
+ @on-bottom-handle-mousedown e
+ @on-right-handle-mousedown e
- # 左下ハンドル掴み時
- @on-bottom-left-handle-mousedown = (e) ~>
- @on-bottom-handle-mousedown e
- @on-left-handle-mousedown e
+ # 左下ハンドル掴み時
+ @on-bottom-left-handle-mousedown = (e) ~>
+ @on-bottom-handle-mousedown e
+ @on-left-handle-mousedown e
- # 高さを適用
- @apply-transform-height = (height) ~>
- @refs.main.style.height = height + \px
+ # 高さを適用
+ @apply-transform-height = (height) ~>
+ @refs.main.style.height = height + \px
- # 幅を適用
- @apply-transform-width = (width) ~>
- @refs.main.style.width = width + \px
+ # 幅を適用
+ @apply-transform-width = (width) ~>
+ @refs.main.style.width = width + \px
- # Y座標を適用
- @apply-transform-top = (top) ~>
- @refs.main.style.top = top + \px
+ # Y座標を適用
+ @apply-transform-top = (top) ~>
+ @refs.main.style.top = top + \px
- # X座標を適用
- @apply-transform-left = (left) ~>
- @refs.main.style.left = left + \px
+ # X座標を適用
+ @apply-transform-left = (left) ~>
+ @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 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 drag-clear fn
- window.remove-event-listener \mousemove fn
- window.remove-event-listener \mouseleave drag-clear
- window.remove-event-listener \mouseup drag-clear
+ function drag-clear fn
+ window.remove-event-listener \mousemove fn
+ window.remove-event-listener \mouseleave drag-clear
+ window.remove-event-listener \mouseup drag-clear
- @ondragover = (e) ~>
- e.data-transfer.drop-effect = \none
+ @ondragover = (e) ~>
+ e.data-transfer.drop-effect = \none
- @on-keydown = (e) ~>
- if e.which == 27 # Esc
- if @can-close
- e.prevent-default!
- e.stop-propagation!
- @close!
+ @on-keydown = (e) ~>
+ if e.which == 27 # Esc
+ if @can-close
+ e.prevent-default!
+ e.stop-propagation!
+ @close!
- function contains(parent, child)
- node = child.parent-node
- while node?
- if node == parent
- return true
- node = node.parent-node
- return false
+ 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 443bf2bfff..c74a43d151 100644
--- a/src/web/app/dev/tags/new-app-form.tag
+++ b/src/web/app/dev/tags/new-app-form.tag
@@ -1,260 +1,243 @@
-mk-new-app-form
- form(onsubmit={ onsubmit }, autocomplete='off')
- section.name: label
- p.caption
- | アプリケーション名
- input@name(
- type='text'
- placeholder='ex) Misskey for iOS'
- autocomplete='off'
- required)
-
- section.nid: label
- p.caption
- | Named ID
- input@nid(
- type='text'
- pattern='^[a-zA-Z0-9\-]{3,30}$'
- placeholder='ex) misskey-for-ios'
- autocomplete='off'
- required
- onkeyup={ on-change-nid })
-
- p.info(if={ nid-state == 'wait' }, style='color:#999')
- i.fa.fa-fw.fa-spinner.fa-pulse
- | 確認しています...
- p.info(if={ nid-state == 'ok' }, style='color:#3CB7B5')
- i.fa.fa-fw.fa-check
- | 利用できます
- p.info(if={ nid-state == 'unavailable' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 既に利用されています
- p.info(if={ nid-state == 'error' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 通信エラー
- p.info(if={ nid-state == 'invalid-format' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | a~z、A~Z、0~9、-(ハイフン)が使えます
- p.info(if={ nid-state == 'min-range' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 3文字以上でお願いします!
- p.info(if={ nid-state == 'max-range' }, style='color:#FF1161')
- i.fa.fa-fw.fa-exclamation-triangle
- | 30文字以内でお願いします
+<mk-new-app-form>
+ <form onsubmit="{ onsubmit }" autocomplete="off">
+ <section class="name">
+ <label>
+ <p class="caption">アプリケーション名</p>
+ <input ref="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required="required"/>
+ </label>
+ </section>
+ <section class="nid">
+ <label>
+ <p class="caption">Named ID</p>
+ <input ref="nid" type="text" pattern="^[a-zA-Z0-9-]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required="required" onkeyup="{ onChangeNid }"/>
+ <p class="info" if="{ nidState == 'wait' }" style="color:#999"><i class="fa fa-fw fa-spinner fa-pulse"></i>確認しています...</p>
+ <p class="info" if="{ nidState == 'ok' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>利用できます</p>
+ <p class="info" if="{ nidState == 'unavailable' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>既に利用されています</p>
+ <p class="info" if="{ nidState == 'error' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>通信エラー</p>
+ <p class="info" if="{ nidState == 'invalid-format' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>a~z、A~Z、0~9、-(ハイフン)が使えます</p>
+ <p class="info" if="{ nidState == 'min-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>3文字以上でお願いします!</p>
+ <p class="info" if="{ nidState == 'max-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>30文字以内でお願いします</p>
+ </label>
+ </section>
+ <section class="description">
+ <label>
+ <p class="caption">アプリの概要</p>
+ <textarea ref="description" placeholder="ex) Misskey iOSクライアント。" autocomplete="off" required="required"></textarea>
+ </label>
+ </section>
+ <section class="callback">
+ <label>
+ <p class="caption">コールバックURL (オプション)</p>
+ <input ref="cb" type="url" placeholder="ex) https://your.app.example.com/callback.php" autocomplete="off"/>
+ </label>
+ </section>
+ <section class="permission">
+ <p class="caption">権限</p>
+ <div ref="permission">
+ <label>
+ <input type="checkbox" value="account-read"/>
+ <p>アカウントの情報を見る。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="account-write"/>
+ <p>アカウントの情報を操作する。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="post-write"/>
+ <p>投稿する。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="like-write"/>
+ <p>いいねしたりいいね解除する。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="following-write"/>
+ <p>フォローしたりフォロー解除する。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="drive-read"/>
+ <p>ドライブを見る。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="drive-write"/>
+ <p>ドライブを操作する。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="notification-read"/>
+ <p>通知を見る。</p>
+ </label>
+ <label>
+ <input type="checkbox" value="notification-write"/>
+ <p>通知を操作する。</p>
+ </label>
+ </div>
+ <p><i class="fa fa-exclamation-triangle"></i>アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。</p>
+ </section>
+ <button onclick="{ onsubmit }">アプリ作成</button>
+ </form>
+ <style type="stylus">
+ :scope
+ display block
+ overflow hidden
- section.description: label
- p.caption
- | アプリの概要
- textarea@description(
- placeholder='ex) Misskey iOSクライアント。'
- autocomplete='off'
- required)
+ > form
- section.callback: label
- p.caption
- | コールバックURL (オプション)
- input@cb(
- type='url'
- placeholder='ex) https://your.app.example.com/callback.php'
- autocomplete='off')
+ section
+ display block
+ margin 16px 0
- section.permission
- p.caption
- | 権限
- div@permission
- label
- input(type='checkbox', value='account-read')
- p アカウントの情報を見る。
- label
- input(type='checkbox', value='account-write')
- p アカウントの情報を操作する。
- label
- input(type='checkbox', value='post-write')
- p 投稿する。
- label
- input(type='checkbox', value='like-write')
- p いいねしたりいいね解除する。
- label
- input(type='checkbox', value='following-write')
- p フォローしたりフォロー解除する。
- label
- input(type='checkbox', value='drive-read')
- p ドライブを見る。
- label
- input(type='checkbox', value='drive-write')
- p ドライブを操作する。
- label
- input(type='checkbox', value='notification-read')
- p 通知を見る。
- label
- input(type='checkbox', value='notification-write')
- p 通知を操作する。
- p
- i.fa.fa-exclamation-triangle
- | アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。
+ .caption
+ margin 0 0 4px 0
+ color #616161
+ font-size 0.95em
- button(onclick={ onsubmit })
- | アプリ作成
+ > i
+ margin-right 0.25em
+ color #96adac
-style.
- display block
- overflow hidden
+ .info
+ display block
+ margin 4px 0
+ font-size 0.8em
- > form
+ > i
+ margin-right 0.3em
- section
- display block
- margin 16px 0
+ section.permission
+ div
+ padding 8px 0
+ max-height 160px
+ overflow auto
+ background #fff
+ border solid 1px #cecece
+ border-radius 4px
- .caption
- margin 0 0 4px 0
- color #616161
- font-size 0.95em
+ label
+ display block
+ padding 0 12px
+ line-height 32px
+ cursor pointer
- > i
- margin-right 0.25em
- color #96adac
+ &:hover
+ > p
+ color #999
- .info
- display block
- margin 4px 0
- font-size 0.8em
+ [type='checkbox']:checked + p
+ color #000
- > i
- margin-right 0.3em
+ [type='checkbox']
+ margin-right 4px
- section.permission
- div
- padding 8px 0
- max-height 160px
- overflow auto
- background #fff
- border solid 1px #cecece
- border-radius 4px
+ [type='checkbox']:checked + p
+ color #111
- label
- display block
- padding 0 12px
- line-height 32px
- cursor pointer
+ > p
+ display inline
+ color #aaa
+ user-select none
- &:hover
- > p
+ > p:last-child
+ margin 6px
+ font-size 0.8em
color #999
- [type='checkbox']:checked + p
- color #000
-
- [type='checkbox']
- margin-right 4px
-
- [type='checkbox']:checked + p
- color #111
-
- > p
- display inline
- color #aaa
- user-select none
+ > i
+ margin-right 4px
- > p:last-child
- margin 6px
- font-size 0.8em
- color #999
+ [type=text]
+ [type=url]
+ textarea
+ user-select text
+ display inline-block
+ cursor auto
+ padding 8px 12px
+ margin 0
+ width 100%
+ font-size 1em
+ color #333
+ background #fff
+ outline none
+ border solid 1px #cecece
+ border-radius 4px
- > i
- margin-right 4px
+ &:hover
+ border-color #bbb
- [type=text]
- [type=url]
- textarea
- user-select text
- display inline-block
- cursor auto
- padding 8px 12px
- margin 0
- width 100%
- font-size 1em
- color #333
- background #fff
- outline none
- border solid 1px #cecece
- border-radius 4px
+ &:focus
+ border-color $theme-color
- &:hover
- border-color #bbb
+ &:disabled
+ opacity 0.5
- &:focus
- border-color $theme-color
-
- &:disabled
- opacity 0.5
-
- > button
- margin 20px 0 32px 0
- width 100%
- font-size 1em
- color #111
- border-radius 3px
-
-script.
- @mixin \api
+ > button
+ margin 20px 0 32px 0
+ width 100%
+ font-size 1em
+ color #111
+ border-radius 3px
- @nid-state = null
+ </style>
+ <script>
+ @mixin \api
- @on-change-nid = ~>
- nid = @refs.nid.value
+ @nid-state = null
- if nid == ''
- @nid-state = null
- @update!
- return
+ @on-change-nid = ~>
+ nid = @refs.nid.value
- err = switch
- | not nid.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
- | nid.length < 3chars => \min-range
- | nid.length > 30chars => \max-range
- | _ => null
+ if nid == ''
+ @nid-state = null
+ @update!
+ return
- if err?
- @nid-state = err
- @update!
- else
- @nid-state = \wait
- @update!
+ err = switch
+ | not nid.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
+ | nid.length < 3chars => \min-range
+ | nid.length > 30chars => \max-range
+ | _ => null
- @api \app/name_id/available do
- name_id: nid
- .then (result) ~>
- if result.available
- @nid-state = \ok
- else
- @nid-state = \unavailable
+ if err?
+ @nid-state = err
@update!
- .catch (err) ~>
- @nid-state = \error
+ else
+ @nid-state = \wait
@update!
- @onsubmit = ~>
- name = @refs.name.value
- nid = @refs.nid.value
- description = @refs.description.value
- cb = @refs.cb.value
- permission = []
+ @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!
- @refs.permission.query-selector-all \input .for-each (el) ~>
- if el.checked then permission.push el.value
+ @onsubmit = ~>
+ name = @refs.name.value
+ nid = @refs.nid.value
+ description = @refs.description.value
+ cb = @refs.cb.value
+ permission = []
- locker = document.body.append-child document.create-element \mk-locker
+ @refs.permission.query-selector-all \input .for-each (el) ~>
+ if el.checked then 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 'アプリの作成に失敗しました。再度お試しください。'
+ locker = document.body.append-child document.create-element \mk-locker
+
+ @api \app/create do
+ name: name
+ name_id: nid
+ description: description
+ callback_url: cb
+ permission: permission.join \,
+ .then ~>
+ location.href = '/apps'
+ .catch ~>
+ alert 'アプリの作成に失敗しました。再度お試しください。'
- locker.parent-node.remove-child locker
+ locker.parent-node.remove-child 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 aa9ba68f3f..4311f11565 100644
--- a/src/web/app/dev/tags/pages/app.tag
+++ b/src/web/app/dev/tags/pages/app.tag
@@ -1,24 +1,30 @@
-mk-app-page
- p(if={ fetching }) 読み込み中
- main(if={ !fetching })
- header
- h1 { app.name }
- div.body
- p App Secret
- input(value={ app.secret }, readonly)
+<mk-app-page>
+ <p if="{ fetching }">読み込み中</p>
+ <main if="{ !fetching }">
+ <header>
+ <h1>{ app.name }</h1>
+ </header>
+ <div class="body">
+ <p>App Secret</p>
+ <input value="{ app.secret }" readonly="readonly"/>
+ </div>
+ </main>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @fetching = true
- @fetching = true
-
- @on \mount ~>
- @api \app/show do
- app_id: @opts.app
- .then (app) ~>
- @app = app
- @fetching = false
- @update!
+ @on \mount ~>
+ @api \app/show do
+ app_id: @opts.app
+ .then (app) ~>
+ @app = app
+ @fetching = false
+ @update!
+ </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 f46a9d3282..b7eb441faa 100644
--- a/src/web/app/dev/tags/pages/apps.tag
+++ b/src/web/app/dev/tags/pages/apps.tag
@@ -1,26 +1,30 @@
-mk-apps-page
- h1 アプリを管理
- a(href='/app/new') アプリ作成
- div.apps
- p(if={ fetching }) 読み込み中
- virtual(if={ !fetching })
- p(if={ apps.length == 0 }) アプリなし
- ul(if={ apps.length > 0 })
- li(each={ app in apps })
- a(href={ '/app/' + app.id })
- p.name { app.name }
+<mk-apps-page>
+ <h1>アプリを管理</h1><a href="/app/new">アプリ作成</a>
+ <div class="apps">
+ <p if="{ fetching }">読み込み中</p>
+ <virtual if="{ !fetching }">
+ <p if="{ apps.length == 0 }">アプリなし</p>
+ <ul if="{ apps.length &gt; 0 }">
+ <li each="{ app in apps }"><a href="{ '/app/' + app.id }">
+ <p class="name">{ app.name }</p></a></li>
+ </ul>
+ </virtual>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @fetching = true
- @fetching = true
-
- @on \mount ~>
- @api \my/apps
- .then (apps) ~>
- @fetching = false
- @apps = apps
- @update!
+ @on \mount ~>
+ @api \my/apps
+ .then (apps) ~>
+ @fetching = false
+ @apps = apps
+ @update!
+ </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 7bc57fbb00..6be52e61ba 100644
--- a/src/web/app/dev/tags/pages/index.tag
+++ b/src/web/app/dev/tags/pages/index.tag
@@ -1,5 +1,11 @@
-mk-index
- a(href='/apps') アプリ
+<mk-index><a href="/apps">アプリ</a>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+
+
+
+
+ </style>
+</mk-index>
diff --git a/src/web/app/dev/tags/pages/new-app.tag b/src/web/app/dev/tags/pages/new-app.tag
index 8c19e39f4b..f255b84328 100644
--- a/src/web/app/dev/tags/pages/new-app.tag
+++ b/src/web/app/dev/tags/pages/new-app.tag
@@ -1,33 +1,42 @@
-mk-new-app-page
- main
- header
- h1 新しいアプリを作成
- p MisskeyのAPIを利用したアプリケーションを作成できます。
- mk-new-app-form
+<mk-new-app-page>
+ <main>
+ <header>
+ <h1>新しいアプリを作成</h1>
+ <p>MisskeyのAPIを利用したアプリケーションを作成できます。</p>
+ </header>
+ <mk-new-app-form></mk-new-app-form>
+ </main>
+ <style type="stylus">
+ :scope
+ display block
+ padding 64px 0
-style.
- display block
- padding 64px 0
+ > main
+ width 100%
+ max-width 700px
+ margin 0 auto
- > main
- width 100%
- max-width 700px
- margin 0 auto
+ > header
+ margin 0 0 16px 0
+ padding 0 0 16px 0
+ border-bottom solid 1px #282827
- > header
- margin 0 0 16px 0
- padding 0 0 16px 0
- border-bottom solid 1px #282827
+ > h1
+ margin 0 0 12px 0
+ padding 0
+ line-height 32px
+ font-size 32px
+ font-weight normal
+ color #000
- > h1
- margin 0 0 12px 0
- padding 0
- line-height 32px
- font-size 32px
- font-weight normal
- color #000
+ > p
+ margin 0
+ line-height 16px
+ color #9a9894
- > p
- margin 0
- line-height 16px
- color #9a9894
+
+
+
+
+ </style>
+</mk-new-app-page>
diff --git a/src/web/app/mobile/tags/drive-selector.tag b/src/web/app/mobile/tags/drive-selector.tag
index 442299026e..f4fd24326f 100644
--- a/src/web/app/mobile/tags/drive-selector.tag
+++ b/src/web/app/mobile/tags/drive-selector.tag
@@ -1,75 +1,78 @@
-mk-drive-selector
- div.body
- header
- h1
- | ファイルを選択
- span.count(if={ files.length > 0 }) ({ files.length })
- button.close(onclick={ cancel }): i.fa.fa-times
- button.ok(onclick={ ok }): i.fa.fa-check
- mk-drive@browser(select={ true }, multiple={ opts.multiple })
+<mk-drive-selector>
+ <div class="body">
+ <header>
+ <h1>ファイルを選択<span class="count" if="{ files.length &gt; 0 }">({ files.length })</span></h1>
+ <button class="close" onclick="{ cancel }"><i class="fa fa-times"></i></button>
+ <button class="ok" onclick="{ ok }"><i class="fa fa-check"></i></button>
+ </header>
+ <mk-drive ref="browser" select="{ true }" multiple="{ opts.multiple }"></mk-drive>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
-
- > .body
- position fixed
- z-index 2048
- top 0
- left 0
- right 0
- margin 0 auto
- width 100%
- max-width 500px
- height 100%
- overflow hidden
- background #fff
- box-shadow 0 0 16px rgba(#000, 0.3)
+ > .body
+ position fixed
+ z-index 2048
+ top 0
+ left 0
+ right 0
+ margin 0 auto
+ width 100%
+ max-width 500px
+ height 100%
+ overflow hidden
+ background #fff
+ box-shadow 0 0 16px rgba(#000, 0.3)
- > header
- border-bottom solid 1px #eee
+ > header
+ border-bottom solid 1px #eee
- > h1
- margin 0
- padding 0
- text-align center
- line-height 42px
- font-size 1em
- font-weight normal
+ > h1
+ margin 0
+ padding 0
+ text-align center
+ line-height 42px
+ font-size 1em
+ font-weight normal
- > .count
- margin-left 4px
- opacity 0.5
+ > .count
+ margin-left 4px
+ opacity 0.5
- > .close
- position absolute
- top 0
- left 0
- line-height 42px
- width 42px
+ > .close
+ position absolute
+ top 0
+ left 0
+ line-height 42px
+ width 42px
- > .ok
- position absolute
- top 0
- right 0
- line-height 42px
- width 42px
+ > .ok
+ position absolute
+ top 0
+ right 0
+ line-height 42px
+ width 42px
- > mk-drive
- height calc(100% - 42px)
- overflow scroll
+ > mk-drive
+ height calc(100% - 42px)
+ overflow scroll
-script.
- @files = []
+ </style>
+ <script>
+ @files = []
- @on \mount ~>
- @refs.browser.on \change-selected (files) ~>
- @files = files
- @update!
+ @on \mount ~>
+ @refs.browser.on \change-selected (files) ~>
+ @files = files
+ @update!
- @cancel = ~>
- @trigger \canceled
- @unmount!
+ @cancel = ~>
+ @trigger \canceled
+ @unmount!
- @ok = ~>
- @trigger \selected @files
- @unmount!
+ @ok = ~>
+ @trigger \selected @files
+ @unmount!
+ </script>
+</mk-drive-selector>
diff --git a/src/web/app/mobile/tags/drive.tag b/src/web/app/mobile/tags/drive.tag
index fcc78d1e68..005f16d58f 100644
--- a/src/web/app/mobile/tags/drive.tag
+++ b/src/web/app/mobile/tags/drive.tag
@@ -1,338 +1,342 @@
-mk-drive
- nav
- p(onclick={ go-root })
- i.fa.fa-cloud
- | ドライブ
- virtual(each={ folder in hierarchy-folders })
- span: i.fa.fa-angle-right
- p(onclick={ _move }) { folder.name }
- span(if={ folder != null }): i.fa.fa-angle-right
- p(if={ folder != null }) { folder.name }
- div.browser(if={ file == null }, class={ loading: loading })
- div.folders(if={ folders.length > 0 })
- virtual(each={ folder in folders })
- mk-drive-folder(folder={ folder })
- p(if={ more-folders })
- | もっと読み込む
- div.files(if={ files.length > 0 })
- virtual(each={ file in files })
- mk-drive-file(file={ file })
- p(if={ more-files })
- | もっと読み込む
- div.empty(if={ files.length == 0 && folders.length == 0 && !loading })
- p(if={ !folder == null })
- | ドライブには何もありません。
- p(if={ folder != null })
- | このフォルダーは空です
- div.loading(if={ loading }).
+<mk-drive>
+ <nav>
+ <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>
+ </virtual><span if="{ folder != null }"><i class="fa fa-angle-right"></i></span>
+ <p if="{ folder != null }">{ folder.name }</p>
+ </nav>
+ <div class="browser { loading: loading }" if="{ file == null }">
+ <div class="folders" if="{ folders.length &gt; 0 }">
+ <virtual each="{ folder in folders }">
+ <mk-drive-folder folder="{ folder }"></mk-drive-folder>
+ </virtual>
+ <p if="{ moreFolders }">もっと読み込む</p>
+ </div>
+ <div class="files" if="{ files.length &gt; 0 }">
+ <virtual each="{ file in files }">
+ <mk-drive-file file="{ file }"></mk-drive-file>
+ </virtual>
+ <p if="{ moreFiles }">もっと読み込む</p>
+ </div>
+ <div class="empty" if="{ files.length == 0 &amp;&amp; folders.length == 0 &amp;&amp; !loading }">
+ <p if="{ !folder == null }">ドライブには何もありません。</p>
+ <p if="{ folder != null }">このフォルダーは空です</p>
+ </div>
+ <div class="loading" if="{ loading }">
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
</div>
- mk-drive-file-viewer(if={ file != null }, file={ file })
+ </div>
+ </div>
+ <mk-drive-file-viewer if="{ file != null }" file="{ file }"></mk-drive-file-viewer>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ > nav
+ display block
+ width 100%
+ padding 10px 12px
+ overflow auto
+ white-space nowrap
+ font-size 0.9em
+ color #555
+ background #fff
+ border-bottom solid 1px #dfdfdf
- > nav
- display block
- width 100%
- padding 10px 12px
- overflow auto
- white-space nowrap
- font-size 0.9em
- color #555
- background #fff
- border-bottom solid 1px #dfdfdf
+ > p
+ display inline
+ margin 0
+ padding 0
- > p
- display inline
- margin 0
- padding 0
+ &:last-child
+ font-weight bold
- &:last-child
- font-weight bold
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ > span
+ margin 0 8px
+ opacity 0.5
- > span
- margin 0 8px
- opacity 0.5
+ > .browser
+ &.loading
+ opacity 0.5
- > .browser
- &.loading
- opacity 0.5
+ > .folders
+ > mk-drive-folder
+ border-bottom solid 1px #eee
- > .folders
- > mk-drive-folder
- border-bottom solid 1px #eee
+ > .files
+ > mk-drive-file
+ border-bottom solid 1px #eee
- > .files
- > mk-drive-file
- border-bottom solid 1px #eee
+ > .empty
+ padding 16px
+ text-align center
+ color #999
+ pointer-events none
- > .empty
- padding 16px
- text-align center
- color #999
- pointer-events none
+ > p
+ margin 0
- > p
- margin 0
+ > .loading
+ .spinner
+ margin 100px auto
+ width 40px
+ height 40px
+ text-align center
- > .loading
- .spinner
- margin 100px auto
- width 40px
- height 40px
- text-align center
+ animation sk-rotate 2.0s infinite linear
- animation sk-rotate 2.0s infinite linear
+ .dot1, .dot2
+ width 60%
+ height 60%
+ display inline-block
+ position absolute
+ top 0
+ background-color rgba(0, 0, 0, 0.3)
+ border-radius 100%
- .dot1, .dot2
- width 60%
- height 60%
- display inline-block
- position absolute
- top 0
- background-color rgba(0, 0, 0, 0.3)
- border-radius 100%
+ animation sk-bounce 2.0s infinite ease-in-out
- animation sk-bounce 2.0s infinite ease-in-out
+ .dot2
+ top auto
+ bottom 0
+ animation-delay -1.0s
- .dot2
- top auto
- bottom 0
- animation-delay -1.0s
+ @keyframes sk-rotate { 100% { transform: rotate(360deg); }}
- @keyframes sk-rotate { 100% { transform: rotate(360deg); }}
+ @keyframes sk-bounce {
+ 0%, 100% {
+ transform: scale(0.0);
+ } 50% {
+ transform: scale(1.0);
+ }
+ }
- @keyframes sk-bounce {
- 0%, 100% {
- transform: scale(0.0);
- } 50% {
- transform: scale(1.0);
- }
- }
+ </style>
+ <script>
+ @mixin \api
+ @mixin \stream
-script.
- @mixin \api
- @mixin \stream
-
- @files = []
- @folders = []
- @hierarchy-folders = []
- @selected-files = []
-
- # 現在の階層(フォルダ)
- # * null でルートを表す
- @folder = null
+ @files = []
+ @folders = []
+ @hierarchy-folders = []
+ @selected-files = []
- @file = null
+ # 現在の階層(フォルダ)
+ # * null でルートを表す
+ @folder = null
- @is-select-mode = @opts.select? and @opts.select
- @multiple = if @opts.multiple? then @opts.multiple else false
+ @file = null
- @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
+ @is-select-mode = @opts.select? and @opts.select
+ @multiple = if @opts.multiple? then @opts.multiple else false
- # Riotのバグでnullを渡しても""になる
- # https://github.com/riot/riot/issues/2080
- #if @opts.folder?
- if @opts.folder? and @opts.folder != ''
- @cd @opts.folder
- else
- @load!
+ @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
- @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 @opts.folder?
+ if @opts.folder? and @opts.folder != ''
+ @cd @opts.folder
+ else
+ @load!
- @on-stream-drive-file-created = (file) ~>
- @add-file file, true
+ @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
- @on-stream-drive-file-updated = (file) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- @remove-file file
- else
+ @on-stream-drive-file-created = (file) ~>
@add-file file, true
- @on-stream-drive-folder-created = (folder) ~>
- @add-folder folder, 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
- @on-stream-drive-folder-updated = (folder) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- @remove-folder folder
- else
+ @on-stream-drive-folder-created = (folder) ~>
@add-folder folder, true
- @_move = (ev) ~>
- @move ev.item.folder
-
- @move = (target-folder) ~>
- @cd target-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
- @cd = (target-folder, is-move) ~>
- if target-folder? and typeof target-folder == \object
- target-folder = target-folder.id
+ @_move = (ev) ~>
+ @move ev.item.folder
- if target-folder == null
- @go-root!
- return
+ @move = (target-folder) ~>
+ @cd target-folder, true
- @loading = true
- @update!
+ @cd = (target-folder, is-move) ~>
+ if target-folder? and typeof target-folder == \object
+ target-folder = target-folder.id
- @api \drive/folders/show do
- folder_id: target-folder
- .then (folder) ~>
- @folder = folder
- @hierarchy-folders = []
+ if target-folder == null
+ @go-root!
+ return
- x = (f) ~>
- @hierarchy-folders.unshift f
- if f.parent?
- x f.parent
+ @loading = true
+ @update!
- if folder.parent?
- x folder.parent
+ @api \drive/folders/show do
+ folder_id: target-folder
+ .then (folder) ~>
+ @folder = folder
+ @hierarchy-folders = []
- @update!
- if is-move then @trigger \move @folder
- @trigger \cd @folder
- @load!
- .catch (err, text-status) ->
- console.error err
+ x = (f) ~>
+ @hierarchy-folders.unshift f
+ if f.parent?
+ x f.parent
- @add-folder = (folder, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != folder.parent_id
- return
+ if folder.parent?
+ x folder.parent
- if (@folders.some (f) ~> f.id == folder.id)
- return
+ @update!
+ if is-move then @trigger \move @folder
+ @trigger \cd @folder
+ @load!
+ .catch (err, text-status) ->
+ console.error err
- if unshift
- @folders.unshift folder
- else
- @folders.push folder
+ @add-folder = (folder, unshift = false) ~>
+ current = if @folder? then @folder.id else null
+ if current != folder.parent_id
+ return
- @update!
+ if (@folders.some (f) ~> f.id == folder.id)
+ return
- @add-file = (file, unshift = false) ~>
- current = if @folder? then @folder.id else null
- if current != file.folder_id
- return
+ if unshift
+ @folders.unshift folder
+ else
+ @folders.push folder
- 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
- @files.unshift file
- else
- @files.push file
+ @add-file = (file, unshift = false) ~>
+ current = if @folder? then @folder.id else null
+ if current != file.folder_id
+ return
+
+ if (@files.some (f) ~> f.id == file.id)
+ exist = (@files.map (f) -> f.id).index-of file.id
+ @files[exist] = file
+ @update!
+ return
- @update!
+ if unshift
+ @files.unshift file
+ else
+ @files.push file
- @remove-folder = (folder) ~>
- if typeof folder == \object
- folder = folder.id
- @folders = @folders.filter (f) -> f.id != folder
- @update!
+ @update!
- @remove-file = (file) ~>
- if typeof file == \object
- file = file.id
- @files = @files.filter (f) -> f.id != file
- @update!
+ @remove-folder = (folder) ~>
+ if typeof folder == \object
+ folder = folder.id
+ @folders = @folders.filter (f) -> f.id != folder
+ @update!
- @go-root = ~>
- if @folder != null
- @folder = null
- @hierarchy-folders = []
+ @remove-file = (file) ~>
+ if typeof file == \object
+ file = file.id
+ @files = @files.filter (f) -> f.id != file
@update!
- @trigger \move-root
- @load!
- @load = ~>
- @folders = []
- @files = []
- @more-folders = false
- @more-files = false
- @loading = true
- @update!
+ @go-root = ~>
+ if @folder != null
+ @folder = null
+ @hierarchy-folders = []
+ @update!
+ @trigger \move-root
+ @load!
+
+ @load = ~>
+ @folders = []
+ @files = []
+ @more-folders = false
+ @more-files = false
+ @loading = true
+ @update!
- @trigger \begin-load
+ @trigger \begin-load
- load-folders = null
- load-files = null
+ load-folders = null
+ load-files = null
- folders-max = 20
- files-max = 20
+ folders-max = 20
+ files-max = 20
- # フォルダ一覧取得
- @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
+ # フォルダ一覧取得
+ @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
- # ファイル一覧取得
- @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
+ # ファイル一覧取得
+ @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
- flag = false
- complete = ~>
- if flag
- load-folders.for-each (folder) ~>
- @add-folder folder
- load-files.for-each (file) ~>
- @add-file file
- @loading = false
- @update!
+ flag = false
+ complete = ~>
+ if flag
+ load-folders.for-each (folder) ~>
+ @add-folder folder
+ load-files.for-each (file) ~>
+ @add-file file
+ @loading = false
+ @update!
- @trigger \loaded
- else
- flag := true
- @trigger \load-mid
+ @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)
+ @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
- @selected-files.push file
- @update!
- @trigger \change-selected @selected-files
- else
- @file = file
- @update!
- @trigger \open-file @file
+ @file = file
+ @update!
+ @trigger \open-file @file
+ </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 8ce89a06f4..ac426278b3 100644
--- a/src/web/app/mobile/tags/drive/file-viewer.tag
+++ b/src/web/app/mobile/tags/drive/file-viewer.tag
@@ -1,8 +1,9 @@
-mk-drive-file-viewer
- p.name { file.name }
+<mk-drive-file-viewer>
+ <p class="name">{ file.name }</p>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
-
-script.
- @file = @opts.file
+ </style>
+ <script>@file = @opts.file</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 ec271441a5..3a2aa87731 100644
--- a/src/web/app/mobile/tags/drive/file.tag
+++ b/src/web/app/mobile/tags/drive/file.tag
@@ -1,130 +1,137 @@
-mk-drive-file(onclick={ onclick }, data-is-selected={ is-selected })
- div.container
- div.thumbnail(style={ 'background-image: url(' + file.url + '?thumbnail&size=128)' })
- div.body
- p.name { file.name }
- //
- if file.tags.length > 0
- ul.tags
- each tag in file.tags
- li.tag(style={background: tag.color, color: contrast(tag.color)})= tag.name
- footer
- p.type
- mk-file-type-icon(file={ file })
- | { file.type }
- p.separator
- p.data-size { bytes-to-size(file.datasize) }
- p.separator
- p.created-at
- i.fa.fa-clock-o
- mk-time(time={ file.created_at })
+<mk-drive-file onclick="{ onclick }" data-is-selected="{ isSelected }">
+ <div class="container">
+ <div class="thumbnail" style="{ 'background-image: url(' + file.url + '?thumbnail&amp;size=128)' }"></div>
+ <div class="body">
+ <p class="name">{ file.name }</p>
+ <!--
+ if file.tags.length > 0
+ ul.tags
+ each tag in file.tags
+ li.tag(style="{background: tag.color, color: contrast(tag.color)}")= tag.name
+ -->
+ <footer>
+ <p class="type">
+ <mk-file-type-icon file="{ file }"></mk-file-type-icon>{ file.type }
+ </p>
+ <p class="separator"></p>
+ <p class="data-size">{ bytesToSize(file.datasize) }</p>
+ <p class="separator"></p>
+ <p class="created-at"><i class="fa fa-clock-o"></i>
+ <mk-time time="{ file.created_at }"></mk-time>
+ </p>
+ </footer>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ &, *
+ user-select none
- &, *
- user-select none
+ *
+ pointer-events none
- *
- pointer-events none
+ > .container
+ max-width 500px
+ margin 0 auto
+ padding 16px
- > .container
- max-width 500px
- margin 0 auto
- padding 16px
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ > .thumbnail
+ display block
+ float left
+ width 64px
+ height 64px
+ background-size cover
+ background-position center center
- > .thumbnail
- display block
- float left
- width 64px
- height 64px
- background-size cover
- background-position center center
-
- > .body
- display block
- float left
- width calc(100% - 74px)
- margin-left 10px
+ > .body
+ display block
+ float left
+ width calc(100% - 74px)
+ margin-left 10px
- > .name
- display block
- margin 0
- padding 0
- font-size 0.9em
- font-weight bold
- color #555
- text-overflow ellipsis
- word-wrap break-word
+ > .name
+ display block
+ margin 0
+ padding 0
+ font-size 0.9em
+ font-weight bold
+ color #555
+ text-overflow ellipsis
+ word-wrap break-word
- > .tags
- display block
- margin 4px 0 0 0
- padding 0
- list-style none
- font-size 0.5em
+ > .tags
+ display block
+ margin 4px 0 0 0
+ padding 0
+ list-style none
+ font-size 0.5em
- > .tag
- display inline-block
- margin 0 5px 0 0
- padding 1px 5px
- border-radius 2px
+ > .tag
+ display inline-block
+ margin 0 5px 0 0
+ padding 1px 5px
+ border-radius 2px
- > footer
- display block
- margin 4px 0 0 0
- font-size 0.7em
+ > footer
+ display block
+ margin 4px 0 0 0
+ font-size 0.7em
- > .separator
- display inline
- margin 0
- padding 0 4px
- color #CDCDCD
+ > .separator
+ display inline
+ margin 0
+ padding 0 4px
+ color #CDCDCD
- > .type
- display inline
- margin 0
- padding 0
- color #9D9D9D
+ > .type
+ display inline
+ margin 0
+ padding 0
+ color #9D9D9D
- > mk-file-type-icon
- margin-right 4px
+ > mk-file-type-icon
+ margin-right 4px
- > .data-size
- display inline
- margin 0
- padding 0
- color #9D9D9D
+ > .data-size
+ display inline
+ margin 0
+ padding 0
+ color #9D9D9D
- > .created-at
- display inline
- margin 0
- padding 0
- color #BDBDBD
+ > .created-at
+ display inline
+ margin 0
+ padding 0
+ color #BDBDBD
- > i
- margin-right 2px
+ > i
+ margin-right 2px
- &[data-is-selected]
- background $theme-color
+ &[data-is-selected]
+ background $theme-color
- &, *
- color #fff !important
+ &, *
+ color #fff !important
-script.
- @mixin \bytes-to-size
+ </style>
+ <script>
+ @mixin \bytes-to-size
- @browser = @parent
- @file = @opts.file
- @is-selected = @browser.selected-files.some (f) ~> f.id == @file.id
+ @browser = @parent
+ @file = @opts.file
+ @is-selected = @browser.selected-files.some (f) ~> f.id == @file.id
- @browser.on \change-selected (selects) ~>
- @is-selected = selects.some (f) ~> f.id == @file.id
+ @browser.on \change-selected (selects) ~>
+ @is-selected = selects.some (f) ~> f.id == @file.id
- @onclick = ~>
- @browser.choose-file @file
+ @onclick = ~>
+ @browser.choose-file @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 ef3a72ea93..5a13686d4f 100644
--- a/src/web/app/mobile/tags/drive/folder.tag
+++ b/src/web/app/mobile/tags/drive/folder.tag
@@ -1,45 +1,46 @@
-mk-drive-folder(onclick={ onclick })
- div.container
- p.name
- i.fa.fa-folder
- | { folder.name }
- i.fa.fa-angle-right
-
-style.
- display block
- color #777
+<mk-drive-folder onclick="{ onclick }">
+ <div class="container">
+ <p class="name"><i class="fa fa-folder"></i>{ folder.name }</p><i class="fa fa-angle-right"></i>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ color #777
- &, *
- user-select none
+ &, *
+ user-select none
- *
- pointer-events none
+ *
+ pointer-events none
- > .container
- max-width 500px
- margin 0 auto
- padding 16px
+ > .container
+ max-width 500px
+ margin 0 auto
+ padding 16px
- > .name
- display block
- margin 0
- padding 0
+ > .name
+ display block
+ margin 0
+ padding 0
- > i
- margin-right 6px
+ > i
+ margin-right 6px
- > i
- position absolute
- top 0
- bottom 0
- right 8px
- margin auto 0 auto 0
- width 1em
- height 1em
+ > i
+ position absolute
+ top 0
+ bottom 0
+ right 8px
+ margin auto 0 auto 0
+ width 1em
+ height 1em
-script.
- @browser = @parent
- @folder = @opts.folder
+ </style>
+ <script>
+ @browser = @parent
+ @folder = @opts.folder
- @onclick = ~>
- @browser.move @folder
+ @onclick = ~>
+ @browser.move @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 7cedbbee88..d44fd3b79b 100644
--- a/src/web/app/mobile/tags/follow-button.tag
+++ b/src/web/app/mobile/tags/follow-button.tag
@@ -1,108 +1,105 @@
-mk-follow-button
- button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following },
- onclick={ onclick },
- disabled={ wait })
- i.fa.fa-minus(if={ !wait && user.is_following })
- i.fa.fa-plus(if={ !wait && !user.is_following })
- i.fa.fa-spinner.fa-pulse.fa-fw(if={ wait })
- | { user.is_following ? 'フォロー解除' : 'フォロー' }
- div.init(if={ init }): i.fa.fa-spinner.fa-pulse.fa-fw
+<mk-follow-button>
+ <button class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }" if="{ !init }" onclick="{ onclick }" disabled="{ wait }"><i class="fa fa-minus" if="{ !wait &amp;&amp; user.is_following }"></i><i class="fa fa-plus" if="{ !wait &amp;&amp; !user.is_following }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ wait }"></i>{ user.is_following ? 'フォロー解除' : 'フォロー' }</button>
+ <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > button
+ > .init
+ display block
+ user-select none
+ cursor pointer
+ padding 0 16px
+ margin 0
+ height inherit
+ font-size 16px
+ outline none
+ border solid 1px $theme-color
+ border-radius 4px
- > button
- > .init
- display block
- user-select none
- cursor pointer
- padding 0 16px
- margin 0
- height inherit
- font-size 16px
- outline none
- border solid 1px $theme-color
- border-radius 4px
+ *
+ pointer-events none
- *
- pointer-events none
+ &.follow
+ color $theme-color
+ background transparent
- &.follow
- color $theme-color
- background transparent
+ &:hover
+ background rgba($theme-color, 0.1)
- &:hover
- background rgba($theme-color, 0.1)
+ &:active
+ background rgba($theme-color, 0.2)
- &:active
- background rgba($theme-color, 0.2)
+ &.unfollow
+ color $theme-color-foreground
+ background $theme-color
- &.unfollow
- color $theme-color-foreground
- background $theme-color
+ &.wait
+ cursor wait !important
+ opacity 0.7
- &.wait
- cursor wait !important
- opacity 0.7
+ &.init
+ cursor wait !important
+ opacity 0.7
- &.init
- cursor wait !important
- opacity 0.7
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \is-promise
+ @mixin \stream
-script.
- @mixin \api
- @mixin \is-promise
- @mixin \stream
+ @user = null
+ @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
+ @init = true
+ @wait = false
- @user = null
- @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
- @init = true
- @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
-
- @on \unmount ~>
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
-
- @on-stream-follow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ @on \mount ~>
+ @user-promise.then (user) ~>
+ @user = user
+ @init = false
+ @update!
+ @stream.on \follow @on-stream-follow
+ @stream.on \unfollow @on-stream-unfollow
- @on-stream-unfollow = (user) ~>
- if user.id == @user.id
- @user = user
- @update!
+ @on \unmount ~>
+ @stream.off \follow @on-stream-follow
+ @stream.off \unfollow @on-stream-unfollow
- @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
+ @on-stream-follow = (user) ~>
+ if user.id == @user.id
+ @user = user
@update!
- else
- @api \following/create do
- user_id: @user.id
- .then ~>
- @user.is_following = true
- .catch (err) ->
- console.error err
- .then ~>
- @wait = false
+
+ @on-stream-unfollow = (user) ~>
+ if user.id == @user.id
+ @user = user
@update!
+
+ @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!
+ </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 1754bb2b07..6ad7270cef 100644
--- a/src/web/app/mobile/tags/home-timeline.tag
+++ b/src/web/app/mobile/tags/home-timeline.tag
@@ -1,40 +1,43 @@
-mk-home-timeline
- mk-timeline@timeline(init={ init }, more={ more }, empty={ '表示する投稿がありません。誰かしらをフォローするなどしましょう。' })
+<mk-home-timeline>
+ <mk-timeline ref="timeline" init="{ init }" more="{ more }" empty="{ '表示する投稿がありません。誰かしらをフォローするなどしましょう。' }"></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \api
+ @mixin \stream
-script.
- @mixin \api
- @mixin \stream
+ @init = new Promise (res, rej) ~>
+ @api \posts/timeline
+ .then (posts) ~>
+ res posts
+ @trigger \loaded
- @init = new Promise (res, rej) ~>
- @api \posts/timeline
- .then (posts) ~>
- res posts
- @trigger \loaded
+ @on \mount ~>
+ @stream.on \post @on-stream-post
+ @stream.on \follow @on-stream-follow
+ @stream.on \unfollow @on-stream-unfollow
- @on \mount ~>
- @stream.on \post @on-stream-post
- @stream.on \follow @on-stream-follow
- @stream.on \unfollow @on-stream-unfollow
+ @on \unmount ~>
+ @stream.off \post @on-stream-post
+ @stream.off \follow @on-stream-follow
+ @stream.off \unfollow @on-stream-unfollow
- @on \unmount ~>
- @stream.off \post @on-stream-post
- @stream.off \follow @on-stream-follow
- @stream.off \unfollow @on-stream-unfollow
+ @more = ~>
+ @api \posts/timeline do
+ max_id: @refs.timeline.tail!.id
- @more = ~>
- @api \posts/timeline do
- max_id: @refs.timeline.tail!.id
+ @on-stream-post = (post) ~>
+ @is-empty = false
+ @update!
+ @refs.timeline.add-post post
- @on-stream-post = (post) ~>
- @is-empty = false
- @update!
- @refs.timeline.add-post post
+ @on-stream-follow = ~>
+ @fetch!
- @on-stream-follow = ~>
- @fetch!
-
- @on-stream-unfollow = ~>
- @fetch!
+ @on-stream-unfollow = ~>
+ @fetch!
+ </script>
+</mk-home-timeline>
diff --git a/src/web/app/mobile/tags/home.tag b/src/web/app/mobile/tags/home.tag
index ebcf8f0bb2..e34d678126 100644
--- a/src/web/app/mobile/tags/home.tag
+++ b/src/web/app/mobile/tags/home.tag
@@ -1,17 +1,20 @@
-mk-home
- mk-home-timeline@tl
+<mk-home>
+ <mk-home-timeline ref="tl"></mk-home-timeline>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ > mk-home-timeline
+ max-width 600px
+ margin 0 auto
- > mk-home-timeline
- max-width 600px
- margin 0 auto
+ @media (min-width 500px)
+ padding 16px
- @media (min-width 500px)
- padding 16px
-
-script.
- @on \mount ~>
- @refs.tl.on \loaded ~>
- @trigger \loaded
+ </style>
+ <script>
+ @on \mount ~>
+ @refs.tl.on \loaded ~>
+ @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 f9d774a124..12bb8e345d 100644
--- a/src/web/app/mobile/tags/images-viewer.tag
+++ b/src/web/app/mobile/tags/images-viewer.tag
@@ -1,25 +1,27 @@
-mk-images-viewer
- div.image@view(onclick={ click })
- img@img(src={ image.url + '?thumbnail&size=512' }, alt={ image.name }, title={ image.name })
-
-style.
- display block
- padding 8px
- overflow hidden
- box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
- border-radius 4px
+<mk-images-viewer>
+ <div class="image" ref="view" onclick="{ click }"><img ref="img" src="{ image.url + '?thumbnail&amp;size=512' }" alt="{ image.name }" title="{ image.name }"/></div>
+ <style type="stylus">
+ :scope
+ display block
+ padding 8px
+ overflow hidden
+ box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
+ border-radius 4px
- > .image
+ > .image
- > img
- display block
- max-height 256px
- max-width 100%
- margin 0 auto
+ > img
+ display block
+ max-height 256px
+ max-width 100%
+ margin 0 auto
-script.
- @images = @opts.images
- @image = @images.0
+ </style>
+ <script>
+ @images = @opts.images
+ @image = @images.0
- @click = ~>
- window.open @image.url
+ @click = ~>
+ window.open @image.url
+ </script>
+</mk-images-viewer>
diff --git a/src/web/app/mobile/tags/notification-preview.tag b/src/web/app/mobile/tags/notification-preview.tag
index ee936df7ab..c6b7414a81 100644
--- a/src/web/app/mobile/tags/notification-preview.tag
+++ b/src/web/app/mobile/tags/notification-preview.tag
@@ -1,117 +1,109 @@
-mk-notification-preview(class={ notification.type })
- div.main(if={ notification.type == 'like' })
- img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-thumbs-o-up
- | { notification.user.name }
- p.post-ref { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'repost' })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-retweet
- | { notification.post.user.name }
- p.post-ref { get-post-summary(notification.post.repost) }
-
- div.main(if={ notification.type == 'quote' })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-quote-left
- | { notification.post.user.name }
- p.post-preview { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'follow' })
- img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-user-plus
- | { notification.user.name }
-
- div.main(if={ notification.type == 'reply' })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-reply
- | { notification.post.user.name }
- p.post-preview { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'mention' })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-at
- | { notification.post.user.name }
- p.post-preview { get-post-summary(notification.post) }
+<mk-notification-preview class="{ notification.type }">
+ <div class="main" if="{ notification.type == 'like' }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <div class="text">
+ <p><i class="fa fa-thumbs-o-up"></i>{ notification.user.name }</p>
+ <p class="post-ref">{ getPostSummary(notification.post) }</p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'repost' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <div class="text">
+ <p><i class="fa fa-retweet"></i>{ notification.post.user.name }</p>
+ <p class="post-ref">{ getPostSummary(notification.post.repost) }</p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'quote' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <div class="text">
+ <p><i class="fa fa-quote-left"></i>{ notification.post.user.name }</p>
+ <p class="post-preview">{ getPostSummary(notification.post) }</p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'follow' }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <div class="text">
+ <p><i class="fa fa-user-plus"></i>{ notification.user.name }</p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'reply' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <div class="text">
+ <p><i class="fa fa-reply"></i>{ notification.post.user.name }</p>
+ <p class="post-preview">{ getPostSummary(notification.post) }</p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'mention' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/>
+ <div class="text">
+ <p><i class="fa fa-at"></i>{ notification.post.user.name }</p>
+ <p class="post-preview">{ getPostSummary(notification.post) }</p>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 8px
+ color #fff
-style.
- display block
- margin 0
- padding 8px
- color #fff
+ > .main
+ word-wrap break-word
- > .main
- word-wrap break-word
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ img
+ display block
+ float left
+ min-width 36px
+ min-height 36px
+ max-width 36px
+ max-height 36px
+ border-radius 6px
- img
- display block
- float left
- min-width 36px
- min-height 36px
- max-width 36px
- max-height 36px
- border-radius 6px
+ .text
+ float right
+ width calc(100% - 36px)
+ padding-left 8px
- .text
- float right
- width calc(100% - 36px)
- padding-left 8px
+ p
+ margin 0
- p
- margin 0
+ i
+ margin-right 4px
- i
- margin-right 4px
+ .post-ref
- .post-ref
+ &:before, &:after
+ font-family FontAwesome
+ font-size 1em
+ font-weight normal
+ font-style normal
+ display inline-block
+ margin-right 3px
- &:before, &:after
- font-family FontAwesome
- font-size 1em
- font-weight normal
- font-style normal
- display inline-block
- margin-right 3px
+ &:before
+ content "\f10d"
- &:before
- content "\f10d"
+ &:after
+ content "\f10e"
- &:after
- content "\f10e"
+ &.like
+ .text p i
+ color #FFAC33
- &.like
- .text p i
- color #FFAC33
+ &.repost, &.quote
+ .text p i
+ color #77B255
- &.repost, &.quote
- .text p i
- color #77B255
+ &.follow
+ .text p i
+ color #53c7ce
- &.follow
- .text p i
- color #53c7ce
-
- &.reply, &.mention
- .text p i
- color #fff
+ &.reply, &.mention
+ .text p i
+ color #fff
-script.
- @mixin \get-post-summary
- @notification = @opts.notification
+ </style>
+ <script>
+ @mixin \get-post-summary
+ @notification = @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 afcc7441b4..155ebf2930 100644
--- a/src/web/app/mobile/tags/notification.tag
+++ b/src/web/app/mobile/tags/notification.tag
@@ -1,142 +1,122 @@
-mk-notification(class={ notification.type })
- mk-time(time={ notification.created_at })
-
- div.main(if={ notification.type == 'like' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username })
- img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-thumbs-o-up
- a(href={ CONFIG.url + '/' + notification.user.username }) { notification.user.name }
- a.post-ref(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'repost' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-retweet
- a(href={ CONFIG.url + '/' + notification.post.user.username }) { notification.post.user.name }
- a.post-ref(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post.repost) }
-
- div.main(if={ notification.type == 'quote' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-quote-left
- a(href={ CONFIG.url + '/' + notification.post.user.username }) { notification.post.user.name }
- a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'follow' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username })
- img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-user-plus
- a(href={ CONFIG.url + '/' + notification.user.username }) { notification.user.name }
-
- div.main(if={ notification.type == 'reply' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-reply
- a(href={ CONFIG.url + '/' + notification.post.user.username }) { notification.post.user.name }
- a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
- div.main(if={ notification.type == 'mention' })
- a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username })
- img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.text
- p
- i.fa.fa-at
- a(href={ CONFIG.url + '/' + notification.post.user.username }) { notification.post.user.name }
- a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
-
-style.
- display block
- margin 0
- padding 16px
+<mk-notification class="{ notification.type }">
+ <mk-time time="{ notification.created_at }"></mk-time>
+ <div class="main" if="{ notification.type == 'like' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.user.username }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-thumbs-o-up"></i><a href="{ CONFIG.url + '/' + notification.user.username }">{ notification.user.name }</a></p><a class="post-ref" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'repost' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-retweet"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ notification.post.user.name }</a></p><a class="post-ref" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post.repost) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'quote' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-quote-left"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'follow' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.user.username }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-user-plus"></i><a href="{ CONFIG.url + '/' + notification.user.username }">{ notification.user.name }</a></p>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'reply' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-reply"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <div class="main" if="{ notification.type == 'mention' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="text">
+ <p><i class="fa fa-at"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 16px
- > mk-time
- display inline
- position absolute
- top 16px
- right 12px
- vertical-align top
- color rgba(0, 0, 0, 0.6)
- font-size 12px
+ > mk-time
+ display inline
+ position absolute
+ top 16px
+ right 12px
+ vertical-align top
+ color rgba(0, 0, 0, 0.6)
+ font-size 12px
- > .main
- word-wrap break-word
+ > .main
+ word-wrap break-word
- &:after
- content ""
- display block
- clear both
+ &:after
+ content ""
+ display block
+ clear both
- .avatar-anchor
- display block
- float left
+ .avatar-anchor
+ display block
+ float left
- img
- min-width 36px
- min-height 36px
- max-width 36px
- max-height 36px
- border-radius 6px
+ img
+ min-width 36px
+ min-height 36px
+ max-width 36px
+ max-height 36px
+ border-radius 6px
- .text
- float right
- width calc(100% - 36px)
- padding-left 8px
+ .text
+ float right
+ width calc(100% - 36px)
+ padding-left 8px
- p
- margin 0
+ p
+ margin 0
- i
- margin-right 4px
+ i
+ margin-right 4px
- .post-preview
- color rgba(0, 0, 0, 0.7)
+ .post-preview
+ color rgba(0, 0, 0, 0.7)
- .post-ref
- color rgba(0, 0, 0, 0.7)
+ .post-ref
+ color rgba(0, 0, 0, 0.7)
- &:before, &:after
- font-family FontAwesome
- font-size 1em
- font-weight normal
- font-style normal
- display inline-block
- margin-right 3px
+ &:before, &:after
+ font-family FontAwesome
+ font-size 1em
+ font-weight normal
+ font-style normal
+ display inline-block
+ margin-right 3px
- &:before
- content "\f10d"
+ &:before
+ content "\f10d"
- &:after
- content "\f10e"
+ &:after
+ content "\f10e"
- &.like
- .text p i
- color #FFAC33
+ &.like
+ .text p i
+ color #FFAC33
- &.repost, &.quote
- .text p i
- color #77B255
+ &.repost, &.quote
+ .text p i
+ color #77B255
- &.follow
- .text p i
- color #53c7ce
+ &.follow
+ .text p i
+ color #53c7ce
- &.reply, &.mention
- .text p i
- color #555
+ &.reply, &.mention
+ .text p i
+ color #555
- .post-preview
- color rgba(0, 0, 0, 0.7)
+ .post-preview
+ color rgba(0, 0, 0, 0.7)
-script.
- @mixin \get-post-summary
- @notification = @opts.notification
+ </style>
+ <script>
+ @mixin \get-post-summary
+ @notification = @opts.notification
+ </script>
+</mk-notification>
diff --git a/src/web/app/mobile/tags/notifications.tag b/src/web/app/mobile/tags/notifications.tag
index 7510d59967..9ebe1dc5c8 100644
--- a/src/web/app/mobile/tags/notifications.tag
+++ b/src/web/app/mobile/tags/notifications.tag
@@ -1,98 +1,93 @@
-mk-notifications
- div.notifications(if={ notifications.length != 0 })
- virtual(each={ notification, i in notifications })
- mk-notification(notification={ notification })
+<mk-notifications>
+ <div class="notifications" if="{ notifications.length != 0 }">
+ <virtual each="{ notification, i in notifications }">
+ <mk-notification notification="{ notification }"></mk-notification>
+ <p class="date" if="{ i != notifications.length - 1 &amp;&amp; notification._date != notifications[i + 1]._date }"><span><i class="fa fa-angle-up"></i>{ notification._datetext }</span><span><i class="fa fa-angle-down"></i>{ notifications[i + 1]._datetext }</span></p>
+ </virtual>
+ </div>
+ <p class="empty" if="{ notifications.length == 0 &amp;&amp; !loading }">ありません!</p>
+ <p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
+ <mk-ellipsis></mk-ellipsis>
+ </p>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
- p.date(if={ i != notifications.length - 1 && notification._date != notifications[i + 1]._date })
- span
- i.fa.fa-angle-up
- | { notification._datetext }
- span
- i.fa.fa-angle-down
- | { notifications[i + 1]._datetext }
+ > .notifications
+ margin 0 auto
+ max-width 500px
- p.empty(if={ notifications.length == 0 && !loading })
- | ありません!
- p.loading(if={ loading })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
+ > mk-notification
+ border-bottom solid 1px rgba(0, 0, 0, 0.05)
-style.
- display block
- background #fff
+ &:last-child
+ border-bottom none
- > .notifications
- margin 0 auto
- max-width 500px
+ > .date
+ display block
+ margin 0
+ line-height 32px
+ text-align center
+ font-size 0.8em
+ color #aaa
+ background #fdfdfd
+ border-bottom solid 1px rgba(0, 0, 0, 0.05)
- > mk-notification
- border-bottom solid 1px rgba(0, 0, 0, 0.05)
+ span
+ margin 0 16px
- &:last-child
- border-bottom none
+ i
+ margin-right 8px
- > .date
- display block
- margin 0
- line-height 32px
- text-align center
- font-size 0.8em
- color #aaa
- background #fdfdfd
- border-bottom solid 1px rgba(0, 0, 0, 0.05)
+ > .empty
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- span
- margin 0 16px
+ > .loading
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- i
- margin-right 8px
+ > i
+ margin-right 4px
- > .empty
- margin 0
- padding 16px
- text-align center
- color #aaa
+ </style>
+ <script>
+ @mixin \api
+ @mixin \stream
+ @mixin \get-post-summary
- > .loading
- margin 0
- padding 16px
- text-align center
- color #aaa
+ @notifications = []
+ @loading = true
- > i
- margin-right 4px
+ @on \mount ~>
+ @api \i/notifications
+ .then (notifications) ~>
+ @notifications = notifications
+ @loading = false
+ @update!
+ @trigger \loaded
+ .catch (err, text-status) ->
+ console.error err
-script.
- @mixin \api
- @mixin \stream
- @mixin \get-post-summary
+ @stream.on \notification @on-notification
- @notifications = []
- @loading = true
+ @on \unmount ~>
+ @stream.off \notification @on-notification
- @on \mount ~>
- @api \i/notifications
- .then (notifications) ~>
- @notifications = notifications
- @loading = false
+ @on-notification = (notification) ~>
+ @notifications.unshift notification
@update!
- @trigger \loaded
- .catch (err, text-status) ->
- console.error err
-
- @stream.on \notification @on-notification
-
- @on \unmount ~>
- @stream.off \notification @on-notification
-
- @on-notification = (notification) ~>
- @notifications.unshift notification
- @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 + '日'
+ @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 + '日'
+ </script>
+</mk-notifications>
diff --git a/src/web/app/mobile/tags/notify.tag b/src/web/app/mobile/tags/notify.tag
index 9dd93ccf25..e50a1ef6c1 100644
--- a/src/web/app/mobile/tags/notify.tag
+++ b/src/web/app/mobile/tags/notify.tag
@@ -1,35 +1,38 @@
-mk-notify
- mk-notification-preview(notification={ opts.notification })
+<mk-notify>
+ <mk-notification-preview notification="{ opts.notification }"></mk-notification-preview>
+ <style type="stylus">
+ :scope
+ display block
+ position fixed
+ z-index 1024
+ bottom -64px
+ left 0
+ width 100%
+ height 64px
+ pointer-events none
+ -webkit-backdrop-filter blur(2px)
+ backdrop-filter blur(2px)
+ background-color rgba(#000, 0.5)
-style.
- display block
- position fixed
- z-index 1024
- bottom -64px
- left 0
- width 100%
- height 64px
- pointer-events none
- -webkit-backdrop-filter blur(2px)
- backdrop-filter blur(2px)
- background-color rgba(#000, 0.5)
-
-script.
- @on \mount ~>
- Velocity @root, {
- bottom: \0px
- } {
- duration: 500ms
- easing: \ease-out
- }
-
- set-timeout ~>
+ </style>
+ <script>
+ @on \mount ~>
Velocity @root, {
- bottom: \-64px
+ bottom: \0px
} {
duration: 500ms
easing: \ease-out
- complete: ~>
- @unmount!
}
- , 6000ms
+
+ set-timeout ~>
+ Velocity @root, {
+ bottom: \-64px
+ } {
+ duration: 500ms
+ easing: \ease-out
+ complete: ~>
+ @unmount!
+ }
+ , 6000ms
+ </script>
+</mk-notify>
diff --git a/src/web/app/mobile/tags/page/drive.tag b/src/web/app/mobile/tags/page/drive.tag
index 9bef7e6648..02287cecde 100644
--- a/src/web/app/mobile/tags/page/drive.tag
+++ b/src/web/app/mobile/tags/page/drive.tag
@@ -1,46 +1,51 @@
-mk-drive-page
- mk-ui@ui: mk-drive@browser(folder={ parent.opts.folder }, file={ parent.opts.file })
+<mk-drive-page>
+ <mk-ui ref="ui">
+ <mk-drive ref="browser" folder="{ parent.opts.folder }" file="{ parent.opts.file }"></mk-drive>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
-script.
- @mixin \ui
- @mixin \ui-progress
-
- @on \mount ~>
- document.title = 'Misskey Drive'
- @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
+ @on \mount ~>
+ document.title = 'Misskey Drive'
+ @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
- @refs.ui.refs.browser.on \begin-load ~>
- @Progress.start!
+ @refs.ui.refs.browser.on \begin-load ~>
+ @Progress.start!
- @refs.ui.refs.browser.on \loaded-mid ~>
- @Progress.set 0.5
+ @refs.ui.refs.browser.on \loaded-mid ~>
+ @Progress.set 0.5
- @refs.ui.refs.browser.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.browser.on \loaded ~>
+ @Progress.done!
- @refs.ui.refs.browser.on \move-root ~>
- @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
+ @refs.ui.refs.browser.on \move-root ~>
+ @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
- # Rewrite URL
- history.push-state null null '/i/drive'
+ # Rewrite URL
+ history.push-state null null '/i/drive'
- @refs.ui.refs.browser.on \cd (folder) ~>
- # TODO: escape html characters in folder.name
- @ui.trigger \title '<i class="fa fa-folder-open"></i>' + folder.name
+ @refs.ui.refs.browser.on \cd (folder) ~>
+ # TODO: escape html characters in folder.name
+ @ui.trigger \title '<i class="fa fa-folder-open"></i>' + folder.name
- @refs.ui.refs.browser.on \move (folder) ~>
- # Rewrite URL
- history.push-state null null '/i/drive/folder/' + folder.id
+ @refs.ui.refs.browser.on \move (folder) ~>
+ # Rewrite URL
+ history.push-state null null '/i/drive/folder/' + folder.id
- @refs.ui.refs.browser.on \open-file (file) ~>
- # TODO: escape html characters in file.name
- @ui.trigger \title '<mk-file-type-icon class="icon"></mk-file-type-icon>' + file.name
+ @refs.ui.refs.browser.on \open-file (file) ~>
+ # TODO: escape html characters in file.name
+ @ui.trigger \title '<mk-file-type-icon class="icon"></mk-file-type-icon>' + file.name
- # Rewrite URL
- history.push-state null null '/i/drive/file/' + file.id
+ # Rewrite URL
+ history.push-state null null '/i/drive/file/' + file.id
- riot.mount \mk-file-type-icon do
- file: file
+ riot.mount \mk-file-type-icon do
+ file: file
+ </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 67d8bc9bbf..85910e8e89 100644
--- a/src/web/app/mobile/tags/page/entrance.tag
+++ b/src/web/app/mobile/tags/page/entrance.tag
@@ -1,57 +1,60 @@
-mk-entrance
- main
- img(src='/_/resources/title.svg', alt='Misskey')
-
- mk-entrance-signin(if={ mode == 'signin' })
- mk-entrance-signup(if={ mode == 'signup' })
- div.introduction(if={ mode == 'introduction' })
- mk-introduction
- button(onclick={ signin }) わかった
-
- footer
- mk-copyright
-
-style.
- display block
- height 100%
-
- > main
- display block
-
- > img
+<mk-entrance>
+ <main><img src="/_/resources/title.svg" alt="Misskey"/>
+ <mk-entrance-signin if="{ mode == 'signin' }"></mk-entrance-signin>
+ <mk-entrance-signup if="{ mode == 'signup' }"></mk-entrance-signup>
+ <div class="introduction" if="{ mode == 'introduction' }">
+ <mk-introduction></mk-introduction>
+ <button onclick="{ signin }">わかった</button>
+ </div>
+ </main>
+ <footer>
+ <mk-copyright></mk-copyright>
+ </footer>
+ <style type="stylus">
+ :scope
display block
- width 130px
- height 120px
- margin 0 auto
+ height 100%
- > .introduction
- max-width 300px
- margin 0 auto
- color #666
-
- > button
+ > main
display block
- margin 16px auto 0 auto
- > footer
- > mk-copyright
- margin 0
- text-align center
- line-height 64px
- font-size 10px
- color rgba(#000, 0.5)
+ > img
+ display block
+ width 130px
+ height 120px
+ margin 0 auto
+
+ > .introduction
+ max-width 300px
+ margin 0 auto
+ color #666
-script.
- @mode = \signin
+ > button
+ display block
+ margin 16px auto 0 auto
- @signup = ~>
- @mode = \signup
- @update!
+ > footer
+ > mk-copyright
+ margin 0
+ text-align center
+ line-height 64px
+ font-size 10px
+ color rgba(#000, 0.5)
- @signin = ~>
+ </style>
+ <script>
@mode = \signin
- @update!
- @introduction = ~>
- @mode = \introduction
- @update!
+ @signup = ~>
+ @mode = \signup
+ @update!
+
+ @signin = ~>
+ @mode = \signin
+ @update!
+
+ @introduction = ~>
+ @mode = \introduction
+ @update!
+ </script>
+</mk-entrance>
diff --git a/src/web/app/mobile/tags/page/entrance/signin.tag b/src/web/app/mobile/tags/page/entrance/signin.tag
index 484c414e8e..0c5efe620f 100644
--- a/src/web/app/mobile/tags/page/entrance/signin.tag
+++ b/src/web/app/mobile/tags/page/entrance/signin.tag
@@ -1,45 +1,51 @@
-mk-entrance-signin
- mk-signin
- div.divider: span or
- button.signup(onclick={ parent.signup }) 新規登録
- a.introduction(onclick={ parent.introduction }) Misskeyについて
+<mk-entrance-signin>
+ <mk-signin></mk-signin>
+ <div class="divider"><span>or</span></div>
+ <button class="signup" onclick="{ parent.signup }">新規登録</button><a class="introduction" onclick="{ parent.introduction }">Misskeyについて</a>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0 auto
+ padding 0 8px
+ max-width 350px
+ text-align center
-style.
- display block
- margin 0 auto
- padding 0 8px
- max-width 350px
- text-align center
+ > .signup
+ padding 16px
+ width 100%
+ font-size 1em
+ color #fff
+ background $theme-color
+ border-radius 3px
- > .signup
- padding 16px
- width 100%
- font-size 1em
- color #fff
- background $theme-color
- border-radius 3px
+ > .divider
+ padding 16px 0
+ text-align center
- > .divider
- padding 16px 0
- text-align center
+ &:after
+ content ""
+ display block
+ position absolute
+ top 50%
+ width 100%
+ height 1px
+ border-top solid 1px rgba(0, 0, 0, 0.1)
- &:after
- content ""
- display block
- position absolute
- top 50%
- width 100%
- height 1px
- border-top solid 1px rgba(0, 0, 0, 0.1)
+ > *
+ z-index 1
+ padding 0 8px
+ color rgba(0, 0, 0, 0.5)
+ background #fdfdfd
- > *
- z-index 1
- padding 0 8px
- color rgba(0, 0, 0, 0.5)
- background #fdfdfd
+ > .introduction
+ display inline-block
+ margin-top 16px
+ font-size 12px
+ color #666
+
+
+
+
- > .introduction
- display inline-block
- margin-top 16px
- font-size 12px
- color #666
+ </style>
+</mk-entrance-signin>
diff --git a/src/web/app/mobile/tags/page/entrance/signup.tag b/src/web/app/mobile/tags/page/entrance/signup.tag
index a28f85e634..77dff97511 100644
--- a/src/web/app/mobile/tags/page/entrance/signup.tag
+++ b/src/web/app/mobile/tags/page/entrance/signup.tag
@@ -1,35 +1,42 @@
-mk-entrance-signup
- mk-signup
- button.cancel(type='button', onclick={ parent.signin }, title='キャンセル'): i.fa.fa-times
+<mk-entrance-signup>
+ <mk-signup></mk-signup>
+ <button class="cancel" type="button" onclick="{ parent.signin }" title="キャンセル"><i class="fa fa-times"></i></button>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0 auto
+ padding 0 8px
+ max-width 350px
-style.
- display block
- margin 0 auto
- padding 0 8px
- max-width 350px
+ > .cancel
+ cursor pointer
+ display block
+ position absolute
+ top 0
+ right 0
+ z-index 1
+ margin 0
+ padding 0
+ font-size 1.2em
+ color #999
+ border none
+ outline none
+ box-shadow none
+ background transparent
+ transition opacity 0.1s ease
- > .cancel
- cursor pointer
- display block
- position absolute
- top 0
- right 0
- z-index 1
- margin 0
- padding 0
- font-size 1.2em
- color #999
- border none
- outline none
- box-shadow none
- background transparent
- transition opacity 0.1s ease
+ &:hover
+ color #555
- &:hover
- color #555
+ &:active
+ color #222
- &:active
- color #222
+ > i
+ padding 14px
- > 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 c8d7729652..eb53be6601 100644
--- a/src/web/app/mobile/tags/page/home.tag
+++ b/src/web/app/mobile/tags/page/home.tag
@@ -1,40 +1,45 @@
-mk-home-page
- mk-ui@ui: mk-home@home
+<mk-home-page>
+ <mk-ui ref="ui">
+ <mk-home ref="home"></mk-home>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \i
+ @mixin \ui
+ @mixin \ui-progress
+ @mixin \stream
+ @mixin \get-post-summary
-script.
- @mixin \i
- @mixin \ui
- @mixin \ui-progress
- @mixin \stream
- @mixin \get-post-summary
+ @unread-count = 0
- @unread-count = 0
-
- @on \mount ~>
- document.title = 'Misskey'
- @ui.trigger \title '<i class="fa fa-home"></i>ホーム'
+ @on \mount ~>
+ document.title = 'Misskey'
+ @ui.trigger \title '<i class="fa fa-home"></i>ホーム'
- @Progress.start!
+ @Progress.start!
- @stream.on \post @on-stream-post
- document.add-event-listener \visibilitychange @window-on-visibilitychange, false
+ @stream.on \post @on-stream-post
+ document.add-event-listener \visibilitychange @window-on-visibilitychange, false
- @refs.ui.refs.home.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.home.on \loaded ~>
+ @Progress.done!
- @on \unmount ~>
- @stream.off \post @on-stream-post
- document.remove-event-listener \visibilitychange @window-on-visibilitychange
+ @on \unmount ~>
+ @stream.off \post @on-stream-post
+ document.remove-event-listener \visibilitychange @window-on-visibilitychange
- @on-stream-post = (post) ~>
- if document.hidden and post.user_id !== @I.id
- @unread-count++
- document.title = '(' + @unread-count + ') ' + @get-post-summary post
+ @on-stream-post = (post) ~>
+ if document.hidden and post.user_id !== @I.id
+ @unread-count++
+ document.title = '(' + @unread-count + ') ' + @get-post-summary post
- @window-on-visibilitychange = ~>
- if !document.hidden
- @unread-count = 0
- document.title = 'Misskey'
+ @window-on-visibilitychange = ~>
+ if !document.hidden
+ @unread-count = 0
+ document.title = 'Misskey'
+ </script>
+</mk-home-page>
diff --git a/src/web/app/mobile/tags/page/new-post.tag b/src/web/app/mobile/tags/page/new-post.tag
index 21e00fc1f9..1b6f73875c 100644
--- a/src/web/app/mobile/tags/page/new-post.tag
+++ b/src/web/app/mobile/tags/page/new-post.tag
@@ -1,5 +1,12 @@
-mk-new-post-page
- mk-post-form@form
+<mk-new-post-page>
+ <mk-post-form ref="form"></mk-post-form>
+ <style type="stylus">
+ :scope
+ display block
-style.
- 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 9fb34dcd75..666a076cb2 100644
--- a/src/web/app/mobile/tags/page/notifications.tag
+++ b/src/web/app/mobile/tags/page/notifications.tag
@@ -1,18 +1,23 @@
-mk-notifications-page
- mk-ui@ui: mk-notifications@notifications
+<mk-notifications-page>
+ <mk-ui ref="ui">
+ <mk-notifications ref="notifications"></mk-notifications>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
-script.
- @mixin \ui
- @mixin \ui-progress
+ @on \mount ~>
+ document.title = 'Misskey | 通知'
+ @ui.trigger \title '<i class="fa fa-bell-o"></i>通知'
- @on \mount ~>
- document.title = 'Misskey | 通知'
- @ui.trigger \title '<i class="fa fa-bell-o"></i>通知'
+ @Progress.start!
- @Progress.start!
-
- @refs.ui.refs.notifications.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.notifications.on \loaded ~>
+ @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 1dc74d267a..40ba429ec4 100644
--- a/src/web/app/mobile/tags/page/post.tag
+++ b/src/web/app/mobile/tags/page/post.tag
@@ -1,31 +1,38 @@
-mk-post-page
- mk-ui@ui: main: mk-post-detail@post(post={ parent.post })
+<mk-post-page>
+ <mk-ui ref="ui">
+ <main>
+ <mk-post-detail ref="post" post="{ parent.post }"></mk-post-detail>
+ </main>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ main
+ background #fff
- main
- background #fff
+ > mk-post-detail
+ width 100%
+ max-width 500px
+ margin 0 auto
- > mk-post-detail
- width 100%
- max-width 500px
- margin 0 auto
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
-script.
- @mixin \ui
- @mixin \ui-progress
+ @post = @opts.post
- @post = @opts.post
+ @on \mount ~>
+ document.title = 'Misskey'
+ @ui.trigger \title '<i class="fa fa-sticky-note-o"></i>投稿'
- @on \mount ~>
- document.title = 'Misskey'
- @ui.trigger \title '<i class="fa fa-sticky-note-o"></i>投稿'
+ @Progress.start!
- @Progress.start!
+ @refs.ui.refs.post.on \post-fetched ~>
+ @Progress.set 0.5
- @refs.ui.refs.post.on \post-fetched ~>
- @Progress.set 0.5
-
- @refs.ui.refs.post.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.post.on \loaded ~>
+ @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 20de271f73..9dd1d4e92a 100644
--- a/src/web/app/mobile/tags/page/search.tag
+++ b/src/web/app/mobile/tags/page/search.tag
@@ -1,19 +1,24 @@
-mk-search-page
- mk-ui@ui: mk-search@search(query={ parent.opts.query })
+<mk-search-page>
+ <mk-ui ref="ui">
+ <mk-search ref="search" query="{ parent.opts.query }"></mk-search>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
-script.
- @mixin \ui
- @mixin \ui-progress
+ @on \mount ~>
+ document.title = '検索: ' + @opts.query + ' | Misskey'
+ # TODO: クエリをHTMLエスケープ
+ @ui.trigger \title '<i class="fa fa-search"></i>' + @opts.query
- @on \mount ~>
- document.title = '検索: ' + @opts.query + ' | Misskey'
- # TODO: クエリをHTMLエスケープ
- @ui.trigger \title '<i class="fa fa-search"></i>' + @opts.query
+ @Progress.start!
- @Progress.start!
-
- @refs.ui.refs.search.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.search.on \loaded ~>
+ @Progress.done!
+ </script>
+</mk-search-page>
diff --git a/src/web/app/mobile/tags/page/user-followers.tag b/src/web/app/mobile/tags/page/user-followers.tag
index e7e9a6fd1e..9809f7085f 100644
--- a/src/web/app/mobile/tags/page/user-followers.tag
+++ b/src/web/app/mobile/tags/page/user-followers.tag
@@ -1,31 +1,36 @@
-mk-user-followers-page
- mk-ui@ui: mk-user-followers@list(if={ !parent.fetching }, user={ parent.user })
+<mk-user-followers-page>
+ <mk-ui ref="ui">
+ <mk-user-followers ref="list" if="{ !parent.fetching }" user="{ parent.user }"></mk-user-followers>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
+ @mixin \api
-script.
- @mixin \ui
- @mixin \ui-progress
- @mixin \api
+ @fetching = true
+ @user = null
- @fetching = true
- @user = null
+ @on \mount ~>
+ @Progress.start!
- @on \mount ~>
- @Progress.start!
+ @api \users/show do
+ username: @opts.user
+ .then (user) ~>
+ @user = user
+ @fetching = false
- @api \users/show do
- username: @opts.user
- .then (user) ~>
- @user = user
- @fetching = false
+ document.title = user.name + 'のフォロワー | Misskey'
+ # TODO: ユーザー名をエスケープ
+ @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロー'
- document.title = user.name + 'のフォロワー | Misskey'
- # TODO: ユーザー名をエスケープ
- @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロー'
+ @update!
- @update!
-
- @refs.ui.refs.list.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.list.on \loaded ~>
+ @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 a74ba97b72..71070eb0da 100644
--- a/src/web/app/mobile/tags/page/user-following.tag
+++ b/src/web/app/mobile/tags/page/user-following.tag
@@ -1,31 +1,36 @@
-mk-user-following-page
- mk-ui@ui: mk-user-following@list(if={ !parent.fetching }, user={ parent.user })
+<mk-user-following-page>
+ <mk-ui ref="ui">
+ <mk-user-following ref="list" if="{ !parent.fetching }" user="{ parent.user }"></mk-user-following>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
+ @mixin \api
-script.
- @mixin \ui
- @mixin \ui-progress
- @mixin \api
+ @fetching = true
+ @user = null
- @fetching = true
- @user = null
+ @on \mount ~>
+ @Progress.start!
- @on \mount ~>
- @Progress.start!
+ @api \users/show do
+ username: @opts.user
+ .then (user) ~>
+ @user = user
+ @fetching = false
- @api \users/show do
- username: @opts.user
- .then (user) ~>
- @user = user
- @fetching = false
+ document.title = user.name + 'のフォロー | Misskey'
+ # TODO: ユーザー名をエスケープ
+ @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロー'
- document.title = user.name + 'のフォロー | Misskey'
- # TODO: ユーザー名をエスケープ
- @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'のフォロー'
+ @update!
- @update!
-
- @refs.ui.refs.list.on \loaded ~>
- @Progress.done!
+ @refs.ui.refs.list.on \loaded ~>
+ @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 9667abfd14..f6106c95cc 100644
--- a/src/web/app/mobile/tags/page/user.tag
+++ b/src/web/app/mobile/tags/page/user.tag
@@ -1,20 +1,25 @@
-mk-user-page
- mk-ui@ui: mk-user@user(user={ parent.user }, page={ parent.opts.page })
+<mk-user-page>
+ <mk-ui ref="ui">
+ <mk-user ref="user" user="{ parent.user }" page="{ parent.opts.page }"></mk-user>
+ </mk-ui>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \ui-progress
-script.
- @mixin \ui
- @mixin \ui-progress
+ @user = @opts.user
- @user = @opts.user
+ @on \mount ~>
+ @Progress.start!
- @on \mount ~>
- @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
+ @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
+ </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 c7eb091ce6..b8d8ec3d8d 100644
--- a/src/web/app/mobile/tags/post-detail.tag
+++ b/src/web/app/mobile/tags/post-detail.tag
@@ -1,415 +1,409 @@
-mk-post-detail
-
- div.fetching(if={ fetching })
- mk-ellipsis-icon
-
- div.main(if={ !fetching })
-
- button.read-more(if={ p.reply_to && p.reply_to.reply_to_id && context == null }, onclick={ load-context }, disabled={ loading-context })
- i.fa.fa-ellipsis-v(if={ !loading-context })
- i.fa.fa-spinner.fa-pulse(if={ loading-context })
-
- div.context
- virtual(each={ post in context })
- mk-post-preview(post={ post })
-
- div.reply-to(if={ p.reply_to })
- mk-post-preview(post={ p.reply_to })
-
- div.repost(if={ is-repost })
- p
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=32' }, alt='avatar')
- i.fa.fa-retweet
- a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name }
- | がRepost
-
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username })
- img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- header
- a.name(href={ CONFIG.url + '/' + p.user.username })
- | { p.user.name }
- span.username
- | @{ p.user.username }
- div.body
- div.text@text
- div.media(if={ p.media })
- virtual(each={ file in p.media })
- img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name })
- a.time(href={ url })
- mk-time(time={ p.created_at }, mode='detail')
- footer
- button(onclick={ reply }, title='返信')
- i.fa.fa-reply
- p.count(if={ p.replies_count > 0 }) { p.replies_count }
- button(onclick={ repost }, title='Repost')
- i.fa.fa-retweet
- p.count(if={ p.repost_count > 0 }) { p.repost_count }
- button(class={ liked: p.is_liked }, onclick={ like }, title='善哉')
- i.fa.fa-thumbs-o-up
- p.count(if={ p.likes_count > 0 }) { p.likes_count }
- button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h
- div.reposts-and-likes
- div.reposts(if={ reposts && reposts.length > 0 })
- header
- a { p.repost_count }
- p Repost
- ol.users
- li.user(each={ reposts })
- a.avatar-anchor(href={ CONFIG.url + '/' + user.username }, title={ user.name })
- img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='')
- div.likes(if={ likes && likes.length > 0 })
- header
- a { p.likes_count }
- p いいね
- ol.users
- li.user(each={ likes })
- a.avatar-anchor(href={ CONFIG.url + '/' + username }, title={ name })
- img.avatar(src={ avatar_url + '?thumbnail&size=32' }, alt='')
+<mk-post-detail>
+ <div class="fetching" if="{ fetching }">
+ <mk-ellipsis-icon></mk-ellipsis-icon>
+ </div>
+ <div class="main" if="{ !fetching }">
+ <button class="read-more" if="{ p.reply_to &amp;&amp; p.reply_to.reply_to_id &amp;&amp; context == null }" onclick="{ loadContext }" disabled="{ loadingContext }"><i class="fa fa-ellipsis-v" if="{ !loadingContext }"></i><i class="fa fa-spinner fa-pulse" if="{ loadingContext }"></i></button>
+ <div class="context">
+ <virtual each="{ post in context }">
+ <mk-post-preview post="{ post }"></mk-post-preview>
+ </virtual>
+ </div>
+ <div class="reply-to" if="{ p.reply_to }">
+ <mk-post-preview post="{ p.reply_to }"></mk-post-preview>
+ </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&amp;size=32' }" alt="avatar"/></a><i class="fa fa-retweet"></i><a class="name" href="{ CONFIG.url + '/' + post.user.username }">{ post.user.name }</a>がRepost</p>
+ </div>
+ <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + p.user.username }"><img class="avatar" src="{ p.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <header><a class="name" href="{ CONFIG.url + '/' + p.user.username }">{ p.user.name }</a><span class="username">@{ p.user.username }</span></header>
+ <div class="body">
+ <div class="text" ref="text"></div>
+ <div class="media" if="{ p.media }">
+ <virtual each="{ file in p.media }"><img src="{ file.url + '?thumbnail&amp;size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual>
+ </div>
+ </div><a class="time" href="{ url }">
+ <mk-time time="{ p.created_at }" mode="detail"></mk-time></a>
+ <footer>
+ <button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i>
+ <p class="count" if="{ p.replies_count &gt; 0 }">{ p.replies_count }</p>
+ </button>
+ <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i>
+ <p class="count" if="{ p.repost_count &gt; 0 }">{ p.repost_count }</p>
+ </button>
+ <button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i>
+ <p class="count" if="{ p.likes_count &gt; 0 }">{ p.likes_count }</p>
+ </button>
+ <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button>
+ </footer>
+ <div class="reposts-and-likes">
+ <div class="reposts" if="{ reposts &amp;&amp; reposts.length &gt; 0 }">
+ <header><a>{ p.repost_count }</a>
+ <p>Repost</p>
+ </header>
+ <ol class="users">
+ <li class="user" each="{ reposts }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }" title="{ user.name }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&amp;size=32' }" alt=""/></a></li>
+ </ol>
+ </div>
+ <div class="likes" if="{ likes &amp;&amp; likes.length &gt; 0 }">
+ <header><a>{ p.likes_count }</a>
+ <p>いいね</p>
+ </header>
+ <ol class="users">
+ <li class="user" each="{ likes }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + username }" title="{ name }"><img class="avatar" src="{ avatar_url + '?thumbnail&amp;size=32' }" alt=""/></a></li>
+ </ol>
+ </div>
+ </div>
+ </article>
+ <div class="replies">
+ <virtual each="{ post in replies }">
+ <mk-post-detail-sub post="{ post }"></mk-post-detail-sub>
+ </virtual>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
- div.replies
- virtual(each={ post in replies })
- mk-post-detail-sub(post={ post })
+ > .fetching
+ padding 64px 0
-style.
- display block
- margin 0
- padding 0
+ > .main
- > .fetching
- padding 64px 0
+ > .read-more
+ display block
+ margin 0
+ padding 10px 0
+ width 100%
+ font-size 1em
+ text-align center
+ color #999
+ cursor pointer
+ background #fafafa
+ outline none
+ border none
+ border-bottom solid 1px #eef0f2
+ border-radius 6px 6px 0 0
+ box-shadow none
- > .main
+ &:hover
+ background #f6f6f6
- > .read-more
- display block
- margin 0
- padding 10px 0
- width 100%
- font-size 1em
- text-align center
- color #999
- cursor pointer
- background #fafafa
- outline none
- border none
- border-bottom solid 1px #eef0f2
- border-radius 6px 6px 0 0
- box-shadow none
+ &:active
+ background #f0f0f0
- &:hover
- background #f6f6f6
+ &:disabled
+ color #ccc
- &:active
- background #f0f0f0
+ > .context
+ > *
+ border-bottom 1px solid #eef0f2
- &:disabled
- color #ccc
+ > .repost
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
- > .context
- > *
- border-bottom 1px solid #eef0f2
+ > p
+ margin 0
+ padding 16px 32px
- > .repost
- color #9dbb00
- background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+ .avatar-anchor
+ display inline-block
- > p
- margin 0
- padding 16px 32px
+ .avatar
+ vertical-align bottom
+ min-width 28px
+ min-height 28px
+ max-width 28px
+ max-height 28px
+ margin 0 8px 0 0
+ border-radius 6px
- .avatar-anchor
- display inline-block
+ i
+ margin-right 4px
- .avatar
- vertical-align bottom
- min-width 28px
- min-height 28px
- max-width 28px
- max-height 28px
- margin 0 8px 0 0
- border-radius 6px
+ .name
+ font-weight bold
- i
- margin-right 4px
+ & + article
+ padding-top 8px
- .name
- font-weight bold
+ > .reply-to
+ border-bottom 1px solid #eef0f2
- & + article
- padding-top 8px
+ > article
+ padding 14px 16px 9px 16px
- > .reply-to
- border-bottom 1px solid #eef0f2
+ @media (min-width 500px)
+ padding 28px 32px 18px 32px
- > article
- padding 14px 16px 9px 16px
+ &:after
+ content ""
+ display block
+ clear both
- @media (min-width 500px)
- padding 28px 32px 18px 32px
+ &:hover
+ > .main > footer > button
+ color #888
- &:after
- content ""
- display block
- clear both
+ > .avatar-anchor
+ display block
- &:hover
- > .main > footer > button
- color #888
+ > .avatar
+ display block
+ width 54px
+ height 54px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- > .avatar-anchor
- display block
+ @media (min-width 500px)
+ width 60px
+ height 60px
- > .avatar
- display block
- width 54px
- height 54px
- margin 0
- border-radius 8px
- vertical-align bottom
+ > header
+ position absolute
+ top 18px
+ left 80px
+ width calc(100% - 80px)
- @media (min-width 500px)
- width 60px
- height 60px
+ @media (min-width 500px)
+ top 28px
+ left 108px
+ width calc(100% - 108px)
- > header
- position absolute
- top 18px
- left 80px
- width calc(100% - 80px)
+ > .name
+ display inline-block
+ margin 0
+ color #777
+ font-size 16px
+ font-weight bold
+ text-align left
+ text-decoration none
- @media (min-width 500px)
- top 28px
- left 108px
- width calc(100% - 108px)
+ &:hover
+ text-decoration underline
- > .name
- display inline-block
- margin 0
- color #777
- font-size 16px
- font-weight bold
- text-align left
- text-decoration none
+ > .username
+ display block
+ text-align left
+ margin 0
+ color #ccc
- &:hover
- text-decoration underline
+ > .body
+ padding 8px 0
- > .username
- display block
- text-align left
- margin 0
- color #ccc
+ > .text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 16px
+ color #717171
- > .body
- padding 8px 0
+ @media (min-width 500px)
+ font-size 24px
- > .text
- cursor default
- display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 16px
- color #717171
+ > mk-url-preview
+ margin-top 8px
- @media (min-width 500px)
- font-size 24px
+ > .media
+ > img
+ display block
+ max-width 100%
- > mk-url-preview
- margin-top 8px
+ > .time
+ font-size 16px
+ color #c0c0c0
- > .media
- > img
- display block
- max-width 100%
+ > footer
+ font-size 1.2em
- > .time
- font-size 16px
- color #c0c0c0
+ > button
+ margin 0 28px 0 0
+ padding 8px
+ background transparent
+ border none
+ box-shadow none
+ font-size 1em
+ color #ddd
+ cursor pointer
- > footer
- font-size 1.2em
+ &:hover
+ color #666
- > button
- margin 0 28px 0 0
- padding 8px
- background transparent
- border none
- box-shadow none
- font-size 1em
- color #ddd
- cursor pointer
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
- &:hover
- color #666
+ &.liked
+ color $theme-color
- > .count
- display inline
- margin 0 0 0 8px
- color #999
+ > .reposts-and-likes
+ display flex
+ justify-content center
+ padding 0
+ margin 16px 0
- &.liked
- color $theme-color
+ &:empty
+ display none
- > .reposts-and-likes
- display flex
- justify-content center
- padding 0
- margin 16px 0
+ > .reposts
+ > .likes
+ display flex
+ flex 1 1
+ padding 0
+ border-top solid 1px #F2EFEE
- &:empty
- display none
+ > header
+ flex 1 1 80px
+ max-width 80px
+ padding 8px 5px 0px 10px
- > .reposts
- > .likes
- display flex
- flex 1 1
- padding 0
- border-top solid 1px #F2EFEE
+ > a
+ display block
+ font-size 1.5em
+ line-height 1.4em
- > header
- flex 1 1 80px
- max-width 80px
- padding 8px 5px 0px 10px
+ > p
+ display block
+ margin 0
+ font-size 0.7em
+ line-height 1em
+ font-weight normal
+ color #a0a2a5
- > a
- display block
- font-size 1.5em
- line-height 1.4em
+ > .users
+ display block
+ flex 1 1
+ margin 0
+ padding 10px 10px 10px 5px
+ list-style none
- > p
- display block
- margin 0
- font-size 0.7em
- line-height 1em
- font-weight normal
- color #a0a2a5
+ > .user
+ display block
+ float left
+ margin 4px
+ padding 0
- > .users
- display block
- flex 1 1
- margin 0
- padding 10px 10px 10px 5px
- list-style none
+ > .avatar-anchor
+ display:block
- > .user
- display block
- float left
- margin 4px
- padding 0
+ > .avatar
+ vertical-align bottom
+ width 24px
+ height 24px
+ border-radius 4px
- > .avatar-anchor
- display:block
+ > .reposts + .likes
+ margin-left 16px
- > .avatar
- vertical-align bottom
- width 24px
- height 24px
- border-radius 4px
+ > .replies
+ > *
+ border-top 1px solid #eef0f2
- > .reposts + .likes
- margin-left 16px
+ </style>
+ <script>
+ @mixin \api
+ @mixin \text
+ @mixin \get-post-summary
+ @mixin \open-post-form
- > .replies
- > *
- border-top 1px solid #eef0f2
+ @fetching = true
+ @loading-context = false
+ @content = null
+ @post = null
-script.
- @mixin \api
- @mixin \text
- @mixin \get-post-summary
- @mixin \open-post-form
+ @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!
- @fetching = true
- @loading-context = false
- @content = null
- @post = null
+ if @p.text?
+ tokens = @analyze @p.text
+ @refs.text.innerHTML = @compile tokens
- @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!
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \MK-URL
+ riot.mount e
- if @p.text?
- tokens = @analyze @p.text
- @refs.text.innerHTML = @compile tokens
+ # 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
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ # Get likes
+ @api \posts/likes do
+ post_id: @p.id
+ limit: 8
+ .then (likes) ~>
+ @likes = likes
+ @update!
- # 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
+ # Get reposts
+ @api \posts/reposts do
+ post_id: @p.id
+ limit: 8
+ .then (reposts) ~>
+ @reposts = reposts
+ @update!
- # Get likes
- @api \posts/likes do
- post_id: @p.id
- limit: 8
- .then (likes) ~>
- @likes = likes
- @update!
+ # Get replies
+ @api \posts/replies do
+ post_id: @p.id
+ limit: 8
+ .then (replies) ~>
+ @replies = replies
+ @update!
- # Get reposts
- @api \posts/reposts do
- post_id: @p.id
- limit: 8
- .then (reposts) ~>
- @reposts = reposts
- @update!
+ @reply = ~>
+ @open-post-form do
+ reply: @p
- # Get replies
- @api \posts/replies do
- post_id: @p.id
- limit: 8
- .then (replies) ~>
- @replies = replies
- @update!
+ @repost = ~>
+ text = window.prompt '「' + @summary + '」をRepost'
+ if text?
+ @api \posts/create do
+ repost_id: @p.id
+ text: if text == '' then undefined else text
- @reply = ~>
- @open-post-form do
- reply: @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!
- @repost = ~>
- text = window.prompt '「' + @summary + '」をRepost'
- if text?
- @api \posts/create do
- repost_id: @p.id
- text: if text == '' then undefined else text
+ @load-context = ~>
+ @loading-context = true
- @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
+ # Get context
+ @api \posts/context do
+ post_id: @p.reply_to_id
+ .then (context) ~>
+ @context = context.reverse!
+ @loading-context = false
@update!
-
- @load-context = ~>
- @loading-context = true
-
- # Get context
- @api \posts/context do
- post_id: @p.reply_to_id
- .then (context) ~>
- @context = context.reverse!
- @loading-context = false
- @update!
+ </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 759a0820b8..838de1fc48 100644
--- a/src/web/app/mobile/tags/post-form.tag
+++ b/src/web/app/mobile/tags/post-form.tag
@@ -1,254 +1,264 @@
-mk-post-form
- header: div
- button.cancel(onclick={ cancel }): i.fa.fa-times
- div
- span.text-count(class={ over: refs.text.value.length > 300 }) { 300 - refs.text.value.length }
- button.submit(onclick={ post }) 投稿
- div.form
- mk-post-preview(if={ opts.reply }, post={ opts.reply })
- textarea@text(disabled={ wait }, oninput={ update }, onkeypress={ onkeypress }, onpaste={ onpaste }, placeholder={ opts.reply ? 'この投稿への返信...' : 'いまどうしてる?' })
- div.attaches(if={ files.length != 0 })
- ul.files@attaches
- li.file(each={ files })
- div.img(style='background-image: url({ url + "?thumbnail&size=64" })', title={ name })
- li.add(if={ files.length < 4 }, title='PCからファイルを添付', onclick={ select-file }): i.fa.fa-plus
- mk-uploader@uploader
- button@upload(onclick={ select-file }): i.fa.fa-upload
- button@drive(onclick={ select-file-from-drive }): i.fa.fa-cloud
- input@file(type='file', accept='image/*', multiple, onchange={ change-file })
+<mk-post-form>
+ <header>
+ <div>
+ <button class="cancel" onclick="{ cancel }"><i class="fa fa-times"></i></button>
+ <div><span class="text-count { over: refs.text.value.length &gt; 300 }">{ 300 - refs.text.value.length }</span>
+ <button class="submit" onclick="{ post }">投稿</button>
+ </div>
+ </div>
+ </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>
+ <div class="attaches" if="{ files.length != 0 }">
+ <ul class="files" ref="attaches">
+ <li class="file" each="{ files }">
+ <div class="img" style="background-image: url({ url + &quot;?thumbnail&amp;size=64&quot; })" title="{ name }"></div>
+ </li>
+ <li class="add" if="{ files.length &lt; 4 }" title="PCからファイルを添付" onclick="{ selectFile }"><i class="fa fa-plus"></i></li>
+ </ul>
+ </div>
+ <mk-uploader ref="uploader"></mk-uploader>
+ <button ref="upload" onclick="{ selectFile }"><i class="fa fa-upload"></i></button>
+ <button ref="drive" onclick="{ selectFileFromDrive }"><i class="fa fa-cloud"></i></button>
+ <input ref="file" type="file" accept="image/*" multiple="multiple" onchange="{ changeFile }"/>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ padding-top 50px
-style.
- display block
- padding-top 50px
+ > header
+ position fixed
+ z-index 1000
+ top 0
+ left 0
+ width 100%
+ height 50px
+ background #fff
- > header
- position fixed
- z-index 1000
- top 0
- left 0
- width 100%
- height 50px
- background #fff
+ > div
+ max-width 500px
+ margin 0 auto
- > div
- max-width 500px
- margin 0 auto
+ > .cancel
+ width 50px
+ line-height 50px
+ font-size 24px
+ color #555
- > .cancel
- width 50px
- line-height 50px
- font-size 24px
- color #555
+ > div
+ position absolute
+ top 0
+ right 0
- > div
- position absolute
- top 0
- right 0
+ > .text-count
+ line-height 50px
+ color #657786
- > .text-count
- line-height 50px
- color #657786
+ > .submit
+ margin 8px
+ padding 0 16px
+ line-height 34px
+ color $theme-color-foreground
+ background $theme-color
+ border-radius 4px
- > .submit
- margin 8px
- padding 0 16px
- line-height 34px
- color $theme-color-foreground
- background $theme-color
- border-radius 4px
+ &:disabled
+ opacity 0.7
- &:disabled
- opacity 0.7
+ > .form
+ max-width 500px
+ margin 0 auto
- > .form
- max-width 500px
- margin 0 auto
+ > mk-post-preview
+ padding 16px
- > mk-post-preview
- padding 16px
+ > .attaches
- > .attaches
+ > .files
+ display block
+ margin 0
+ padding 4px
+ list-style none
- > .files
- display block
- margin 0
- padding 4px
- list-style none
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ > .file
+ display block
+ float left
+ margin 4px
+ padding 0
+ cursor move
- > .file
- display block
- float left
- margin 4px
- padding 0
- cursor move
+ &:hover > .remove
+ display block
- &:hover > .remove
- display block
+ > .img
+ width 64px
+ height 64px
+ background-size cover
+ background-position center center
- > .img
- width 64px
- height 64px
- background-size cover
- background-position center center
+ > .remove
+ display none
+ position absolute
+ top -6px
+ right -6px
+ width 16px
+ height 16px
+ cursor pointer
- > .remove
- display none
- position absolute
- top -6px
- right -6px
- width 16px
- height 16px
- cursor pointer
+ > .add
+ display block
+ float left
+ margin 4px
+ padding 0
+ border dashed 2px rgba($theme-color, 0.2)
+ cursor pointer
- > .add
- display block
- float left
- margin 4px
- padding 0
- border dashed 2px rgba($theme-color, 0.2)
- cursor pointer
+ &:hover
+ border-color rgba($theme-color, 0.3)
- &:hover
- border-color rgba($theme-color, 0.3)
+ > i
+ color rgba($theme-color, 0.4)
- > i
- color rgba($theme-color, 0.4)
+ > i
+ display block
+ width 60px
+ height 60px
+ line-height 60px
+ text-align center
+ font-size 1.2em
+ color rgba($theme-color, 0.2)
- > i
- display block
- width 60px
- height 60px
- line-height 60px
- text-align center
- font-size 1.2em
- color rgba($theme-color, 0.2)
+ > mk-uploader
+ margin 8px 0 0 0
+ padding 8px
- > mk-uploader
- margin 8px 0 0 0
- padding 8px
+ > [ref='file']
+ display none
- > [ref='file']
- display none
+ > [ref='text']
+ display block
+ padding 12px
+ margin 0
+ width 100%
+ max-width 100%
+ min-width 100%
+ min-height 80px
+ font-size 16px
+ color #333
+ border none
+ border-bottom solid 1px #ddd
+ border-radius 0
- > [ref='text']
- display block
- padding 12px
- margin 0
- width 100%
- max-width 100%
- min-width 100%
- min-height 80px
- font-size 16px
- color #333
- border none
- border-bottom solid 1px #ddd
- border-radius 0
+ &:disabled
+ opacity 0.5
- &:disabled
- opacity 0.5
+ > [ref='upload']
+ > [ref='drive']
+ display inline-block
+ padding 0
+ margin 0
+ width 48px
+ height 48px
+ font-size 20px
+ color #657786
+ background transparent
+ outline none
+ border none
+ border-radius 0
+ box-shadow none
- > [ref='upload']
- > [ref='drive']
- display inline-block
- padding 0
- margin 0
- width 48px
- height 48px
- font-size 20px
- color #657786
- background transparent
- outline none
- border none
- border-radius 0
- box-shadow none
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @wait = false
+ @uploadings = []
+ @files = []
- @wait = false
- @uploadings = []
- @files = []
+ @on \mount ~>
+ @refs.uploader.on \uploaded (file) ~>
+ @add-file file
- @on \mount ~>
- @refs.uploader.on \uploaded (file) ~>
- @add-file file
+ @refs.uploader.on \change-uploads (uploads) ~>
+ @trigger \change-uploading-files uploads
- @refs.uploader.on \change-uploads (uploads) ~>
- @trigger \change-uploading-files uploads
+ @refs.text.focus!
- @refs.text.focus!
+ @onkeypress = (e) ~>
+ if (e.char-code == 10 || e.char-code == 13) && e.ctrl-key
+ @post!
+ else
+ return true
- @onkeypress = (e) ~>
- if (e.char-code == 10 || e.char-code == 13) && e.ctrl-key
- @post!
- else
+ @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
- @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
+ @select-file = ~>
+ @refs.file.click!
- @select-file = ~>
- @refs.file.click!
+ @select-file-from-drive = ~>
+ browser = document.body.append-child document.create-element \mk-drive-selector
+ browser = riot.mount browser, do
+ multiple: true
+ .0
+ browser.on \selected (files) ~>
+ files.for-each @add-file
- @select-file-from-drive = ~>
- browser = document.body.append-child document.create-element \mk-drive-selector
- browser = riot.mount browser, do
- multiple: true
- .0
- browser.on \selected (files) ~>
- files.for-each @add-file
+ @change-file = ~>
+ files = @refs.file.files
+ for i from 0 to files.length - 1
+ file = files.item i
+ @upload file
- @change-file = ~>
- files = @refs.file.files
- for i from 0 to files.length - 1
- file = files.item i
- @upload file
+ @upload = (file) ~>
+ @refs.uploader.upload file
- @upload = (file) ~>
- @refs.uploader.upload file
+ @add-file = (file) ~>
+ file._remove = ~>
+ @files = @files.filter (x) -> x.id != file.id
+ @trigger \change-files @files
+ @update!
- @add-file = (file) ~>
- file._remove = ~>
- @files = @files.filter (x) -> x.id != file.id
+ @files.push file
@trigger \change-files @files
@update!
- @files.push file
- @trigger \change-files @files
- @update!
+ @post = ~>
+ @wait = true
- @post = ~>
- @wait = true
+ files = if @files? and @files.length > 0
+ then @files.map (f) -> f.id
+ else undefined
- files = if @files? and @files.length > 0
- then @files.map (f) -> f.id
- else undefined
+ @api \posts/create do
+ text: @refs.text.value
+ media_ids: files
+ reply_to_id: if @opts.reply? then @opts.reply.id else undefined
+ .then (data) ~>
+ @trigger \post
+ @unmount!
+ .catch (err) ~>
+ console.error err
+ #@opts.ui.trigger \notification 'Error!'
+ @wait = false
+ @update!
- @api \posts/create do
- text: @refs.text.value
- media_ids: files
- reply_to_id: if @opts.reply? then @opts.reply.id else undefined
- .then (data) ~>
- @trigger \post
+ @cancel = ~>
+ @trigger \cancel
@unmount!
- .catch (err) ~>
- console.error err
- #@opts.ui.trigger \notification 'Error!'
- @wait = false
- @update!
-
- @cancel = ~>
- @trigger \cancel
- @unmount!
+ </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 e15b2be244..71faab2b85 100644
--- a/src/web/app/mobile/tags/post-preview.tag
+++ b/src/web/app/mobile/tags/post-preview.tag
@@ -1,89 +1,86 @@
-mk-post-preview
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
- img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.main
- header
- a.name(href={ CONFIG.url + '/' + post.user.username })
- | { post.user.name }
- span.username
- | @{ post.user.username }
- a.time(href={ CONFIG.url + '/' + post.user.username + '/' + post.id })
- mk-time(time={ post.created_at })
- div.body
- mk-sub-post-content.text(post={ post })
-
-style.
- display block
- margin 0
- padding 0
- font-size 0.9em
- background #fff
+<mk-post-preview>
+ <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="main">
+ <header><a class="name" href="{ CONFIG.url + '/' + post.user.username }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="time" href="{ CONFIG.url + '/' + post.user.username + '/' + post.id }">
+ <mk-time time="{ post.created_at }"></mk-time></a></header>
+ <div class="body">
+ <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content>
+ </div>
+ </div>
+ </article>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
+ font-size 0.9em
+ background #fff
- > article
+ > article
- &:after
- content ""
- display block
- clear both
+ &:after
+ content ""
+ display block
+ clear both
- &:hover
- > .main > footer > button
- color #888
+ &:hover
+ > .main > footer > button
+ color #888
- > .avatar-anchor
- display block
- float left
- margin 0 12px 0 0
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 12px 0 0
- > .avatar
- display block
- width 48px
- height 48px
- margin 0
- border-radius 8px
- vertical-align bottom
+ > .avatar
+ display block
+ width 48px
+ height 48px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- > .main
- float left
- width calc(100% - 60px)
+ > .main
+ float left
+ width calc(100% - 60px)
- > header
- margin-bottom 4px
- white-space nowrap
+ > header
+ margin-bottom 4px
+ white-space nowrap
- > .name
- display inline
- margin 0
- padding 0
- color #607073
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #607073
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration underline
- > .username
- text-align left
- margin 0 0 0 8px
- color #d1d8da
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #d1d8da
- > .time
- position absolute
- top 0
- right 0
- color #b2b8bb
+ > .time
+ position absolute
+ top 0
+ right 0
+ color #b2b8bb
- > .body
+ > .body
- > .text
- cursor default
- margin 0
- padding 0
- font-size 1.1em
- color #717171
+ > .text
+ cursor default
+ margin 0
+ padding 0
+ font-size 1.1em
+ color #717171
-script.
- @post = @opts.post
+ </style>
+ <script>@post = @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 4b1b12af27..c22d794b5b 100644
--- a/src/web/app/mobile/tags/search-posts.tag
+++ b/src/web/app/mobile/tags/search-posts.tag
@@ -1,29 +1,32 @@
-mk-search-posts
- mk-timeline(init={ init }, more={ more }, empty={ '「' + query + '」に関する投稿は見つかりませんでした。' })
+<mk-search-posts>
+ <mk-timeline init="{ init }" more="{ more }" empty="{ '「' + query + '」に関する投稿は見つかりませんでした。' }"></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
-style.
- display block
- background #fff
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @max = 30
+ @offset = 0
- @max = 30
- @offset = 0
+ @query = @opts.query
+ @with-media = @opts.with-media
- @query = @opts.query
- @with-media = @opts.with-media
+ @init = new Promise (res, rej) ~>
+ @api \posts/search do
+ query: @query
+ .then (posts) ~>
+ res posts
+ @trigger \loaded
- @init = new Promise (res, rej) ~>
- @api \posts/search do
- query: @query
- .then (posts) ~>
- res posts
- @trigger \loaded
-
- @more = ~>
- @offset += @max
- @api \posts/search do
- query: @query
- max: @max
- offset: @offset
+ @more = ~>
+ @offset += @max
+ @api \posts/search do
+ query: @query
+ max: @max
+ offset: @offset
+ </script>
+</mk-search-posts>
diff --git a/src/web/app/mobile/tags/search.tag b/src/web/app/mobile/tags/search.tag
index bf2299cc9b..bb0744147f 100644
--- a/src/web/app/mobile/tags/search.tag
+++ b/src/web/app/mobile/tags/search.tag
@@ -1,12 +1,15 @@
-mk-search
- mk-search-posts@posts(query={ query })
+<mk-search>
+ <mk-search-posts ref="posts" query="{ query }"></mk-search-posts>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @query = @opts.query
-script.
- @query = @opts.query
-
- @on \mount ~>
- @refs.posts.on \loaded ~>
- @trigger \loaded
+ @on \mount ~>
+ @refs.posts.on \loaded ~>
+ @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
index 2eb5889ca6..4046f5fec4 100644
--- a/src/web/app/mobile/tags/stream-indicator.tag
+++ b/src/web/app/mobile/tags/stream-indicator.tag
@@ -1,59 +1,54 @@
-mk-stream-indicator
- p(if={ state == 'initializing' })
- i.fa.fa-spinner.fa-spin
- span
- | 接続中
- mk-ellipsis
- p(if={ state == 'reconnecting' })
- i.fa.fa-spinner.fa-spin
- span
- | 切断されました 接続中
- mk-ellipsis
- p(if={ state == 'connected' })
- i.fa.fa-check
- span 接続完了
+<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 type="stylus">
+ :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)
-style.
- 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
- > p
- display block
- margin 0
+ > i
+ margin-right 0.25em
- > i
- margin-right 0.25em
+ </style>
+ <script>
+ @mixin \stream
-script.
- @mixin \stream
+ @on \before-mount ~>
+ @state = @get-stream-state!
- @on \before-mount ~>
- @state = @get-stream-state!
+ if @state == \connected
+ @root.style.opacity = 0
- 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 \connected ~>
- @state = @get-stream-state!
- @update!
- set-timeout ~>
+ @stream-state-ev.on \closed ~>
+ @state = @get-stream-state!
+ @update!
Velocity @root, {
- opacity: 0
- } 200ms \linear
- , 1000ms
-
- @stream-state-ev.on \closed ~>
- @state = @get-stream-state!
- @update!
- Velocity @root, {
- opacity: 1
- } 0ms
+ 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 595f63d794..0f015fddfd 100644
--- a/src/web/app/mobile/tags/sub-post-content.tag
+++ b/src/web/app/mobile/tags/sub-post-content.tag
@@ -1,36 +1,37 @@
-mk-sub-post-content
- div.body
- a.reply(if={ post.reply_to_id }): i.fa.fa-reply
- span@text
- a.quote(if={ post.repost_id }, href={ '/post:' + post.repost_id }) RP: ...
- details(if={ post.media })
- summary ({ post.media.length }枚の画像)
- mk-images-viewer(images={ post.media })
+<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>
+ <details if="{ post.media }">
+ <summary>({ post.media.length }枚の画像)</summary>
+ <mk-images-viewer images="{ post.media }"></mk-images-viewer>
+ </details>
+ <style type="stylus">
+ :scope
+ display block
+ word-wrap break-word
-style.
- display block
- word-wrap break-word
+ > .body
+ > .reply
+ margin-right 6px
+ color #717171
- > .body
- > .reply
- margin-right 6px
- color #717171
+ > .quote
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
- > .quote
- margin-left 4px
- font-style oblique
- color #a0bf46
+ </style>
+ <script>
+ @mixin \text
-script.
- @mixin \text
+ @post = @opts.post
- @post = @opts.post
+ @on \mount ~>
+ if @post.text?
+ tokens = @analyze @post.text
+ @refs.text.innerHTML = @compile tokens, false
- @on \mount ~>
- if @post.text?
- tokens = @analyze @post.text
- @refs.text.innerHTML = @compile tokens, false
-
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \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 920503ebcc..e6f9df2be6 100644
--- a/src/web/app/mobile/tags/timeline-post-sub.tag
+++ b/src/web/app/mobile/tags/timeline-post-sub.tag
@@ -1,99 +1,96 @@
-mk-timeline-post-sub
- article
- a.avatar-anchor(href={ '/' + post.user.username })
- img.avatar(src={ post.user.avatar_url + '?thumbnail&size=96' }, alt='avatar')
- div.main
- header
- a.name(href={ '/' + post.user.username })
- | { post.user.name }
- span.username
- | @{ post.user.username }
- a.created-at(href={ '/' + post.user.username + '/' + post.id })
- mk-time(time={ post.created_at })
- div.body
- mk-sub-post-content.text(post={ post })
-
-style.
- display block
- margin 0
- padding 0
- font-size 0.9em
+<mk-timeline-post-sub>
+ <article><a class="avatar-anchor" href="{ '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&amp;size=96' }" alt="avatar"/></a>
+ <div class="main">
+ <header><a class="name" href="{ '/' + post.user.username }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="created-at" href="{ '/' + post.user.username + '/' + post.id }">
+ <mk-time time="{ post.created_at }"></mk-time></a></header>
+ <div class="body">
+ <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content>
+ </div>
+ </div>
+ </article>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
+ font-size 0.9em
- > article
- padding 16px
+ > article
+ padding 16px
- &:after
- content ""
- display block
- clear both
+ &:after
+ content ""
+ display block
+ clear both
- &:hover
- > .main > footer > button
- color #888
+ &:hover
+ > .main > footer > button
+ color #888
- > .avatar-anchor
- display block
- float left
- margin 0 10px 0 0
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 10px 0 0
- @media (min-width 500px)
- margin-right 16px
+ @media (min-width 500px)
+ margin-right 16px
- > .avatar
- display block
- width 44px
- height 44px
- margin 0
- border-radius 8px
- vertical-align bottom
+ > .avatar
+ display block
+ width 44px
+ height 44px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
- @media (min-width 500px)
- width 52px
- height 52px
+ @media (min-width 500px)
+ width 52px
+ height 52px
- > .main
- float left
- width calc(100% - 54px)
+ > .main
+ float left
+ width calc(100% - 54px)
- @media (min-width 500px)
- width calc(100% - 68px)
+ @media (min-width 500px)
+ width calc(100% - 68px)
- > header
- margin-bottom 4px
- white-space nowrap
+ > header
+ margin-bottom 4px
+ white-space nowrap
- > .name
- display inline
- margin 0
- padding 0
- color #607073
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #607073
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration underline
- > .username
- text-align left
- margin 0 0 0 8px
- color #d1d8da
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #d1d8da
- > .created-at
- position absolute
- top 0
- right 0
- color #b2b8bb
+ > .created-at
+ position absolute
+ top 0
+ right 0
+ color #b2b8bb
- > .body
+ > .body
- > .text
- cursor default
- margin 0
- padding 0
- font-size 1.1em
- color #717171
+ > .text
+ cursor default
+ margin 0
+ padding 0
+ font-size 1.1em
+ color #717171
-script.
- @post = @opts.post
+ </style>
+ <script>@post = @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 a71fab26f0..3037b4bef3 100644
--- a/src/web/app/mobile/tags/timeline-post.tag
+++ b/src/web/app/mobile/tags/timeline-post.tag
@@ -1,296 +1,291 @@
-mk-timeline-post(class={ repost: is-repost })
-
- div.reply-to(if={ p.reply_to })
- mk-timeline-post-sub(post={ p.reply_to })
-
- div.repost(if={ is-repost })
- p
- a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- i.fa.fa-retweet
- a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name }
- | がRepost
- mk-time(time={ post.created_at })
-
- article
- a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username })
- img.avatar(src={ p.user.avatar_url + '?thumbnail&size=96' }, alt='avatar')
- div.main
- header
- a.name(href={ CONFIG.url + '/' + p.user.username })
- | { p.user.name }
- span.username
- | @{ p.user.username }
- a.created-at(href={ url })
- mk-time(time={ p.created_at })
- div.body
- div.text
- a.reply(if={ p.reply_to }): i.fa.fa-reply
- soan@text
- a.quote(if={ p.repost != null }) RP:
- div.media(if={ p.media })
- mk-images-viewer(images={ p.media })
- div.repost(if={ p.repost })
- i.fa.fa-quote-right.fa-flip-horizontal
- mk-post-preview.repost(post={ p.repost })
- footer
- button(onclick={ reply })
- i.fa.fa-reply
- p.count(if={ p.replies_count > 0 }) { p.replies_count }
- button(onclick={ repost }, title='Repost')
- i.fa.fa-retweet
- p.count(if={ p.repost_count > 0 }) { p.repost_count }
- button(class={ liked: p.is_liked }, onclick={ like })
- i.fa.fa-thumbs-o-up
- p.count(if={ p.likes_count > 0 }) { p.likes_count }
-
-style.
- display block
- margin 0
- padding 0
- font-size 12px
+<mk-timeline-post class="{ repost: isRepost }">
+ <div class="reply-to" if="{ p.reply_to }">
+ <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&amp;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&amp;size=96' }" alt="avatar"/></a>
+ <div class="main">
+ <header><a class="name" href="{ CONFIG.url + '/' + p.user.username }">{ p.user.name }</a><span class="username">@{ p.user.username }</span><a class="created-at" href="{ url }">
+ <mk-time time="{ p.created_at }"></mk-time></a></header>
+ <div class="body">
+ <div class="text"><a class="reply" if="{ p.reply_to }"><i class="fa fa-reply"></i></a>
+ <soan ref="text"></soan><a class="quote" if="{ p.repost != null }">RP:</a>
+ </div>
+ <div class="media" if="{ p.media }">
+ <mk-images-viewer images="{ p.media }"></mk-images-viewer>
+ </div>
+ <div class="repost" if="{ p.repost }"><i class="fa fa-quote-right fa-flip-horizontal"></i>
+ <mk-post-preview class="repost" post="{ p.repost }"></mk-post-preview>
+ </div>
+ </div>
+ <footer>
+ <button onclick="{ reply }"><i class="fa fa-reply"></i>
+ <p class="count" if="{ p.replies_count &gt; 0 }">{ p.replies_count }</p>
+ </button>
+ <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i>
+ <p class="count" if="{ p.repost_count &gt; 0 }">{ p.repost_count }</p>
+ </button>
+ <button class="{ liked: p.is_liked }" onclick="{ like }"><i class="fa fa-thumbs-o-up"></i>
+ <p class="count" if="{ p.likes_count &gt; 0 }">{ p.likes_count }</p>
+ </button>
+ </footer>
+ </div>
+ </article>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 0
+ font-size 12px
- @media (min-width 350px)
- font-size 14px
+ @media (min-width 350px)
+ font-size 14px
- @media (min-width 500px)
- font-size 16px
+ @media (min-width 500px)
+ font-size 16px
- > .repost
- color #9dbb00
- background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+ > .repost
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
- > p
- margin 0
- padding 8px 16px
- line-height 28px
+ > p
+ margin 0
+ padding 8px 16px
+ line-height 28px
- @media (min-width 500px)
- padding 16px
+ @media (min-width 500px)
+ padding 16px
- .avatar-anchor
- display inline-block
+ .avatar-anchor
+ display inline-block
- .avatar
- vertical-align bottom
- width 28px
- height 28px
- margin 0 8px 0 0
- border-radius 6px
+ .avatar
+ vertical-align bottom
+ width 28px
+ height 28px
+ margin 0 8px 0 0
+ border-radius 6px
- i
- margin-right 4px
+ i
+ margin-right 4px
- .name
- font-weight bold
+ .name
+ font-weight bold
- > mk-time
- position absolute
- top 8px
- right 16px
- font-size 0.9em
- line-height 28px
+ > mk-time
+ position absolute
+ top 8px
+ right 16px
+ font-size 0.9em
+ line-height 28px
- @media (min-width 500px)
- top 16px
+ @media (min-width 500px)
+ top 16px
- & + article
- padding-top 8px
+ & + article
+ padding-top 8px
- > .reply-to
- background rgba(0, 0, 0, 0.0125)
+ > .reply-to
+ background rgba(0, 0, 0, 0.0125)
- > mk-post-preview
- background transparent
+ > mk-post-preview
+ background transparent
- > article
- padding 14px 16px 9px 16px
+ > article
+ padding 14px 16px 9px 16px
- &:after
- content ""
- display block
- clear both
+ &:after
+ content ""
+ display block
+ clear both
- > .avatar-anchor
- display block
- float left
- margin 0 10px 0 0
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 10px 0 0
- @media (min-width 500px)
- margin-right 16px
+ @media (min-width 500px)
+ margin-right 16px
- > .avatar
- display block
- width 48px
- height 48px
- margin 0
- border-radius 6px
- vertical-align bottom
+ > .avatar
+ display block
+ width 48px
+ height 48px
+ margin 0
+ border-radius 6px
+ vertical-align bottom
- @media (min-width 500px)
- width 58px
- height 58px
- border-radius 8px
+ @media (min-width 500px)
+ width 58px
+ height 58px
+ border-radius 8px
- > .main
- float left
- width calc(100% - 58px)
+ > .main
+ float left
+ width calc(100% - 58px)
- @media (min-width 500px)
- width calc(100% - 74px)
+ @media (min-width 500px)
+ width calc(100% - 74px)
- > header
- white-space nowrap
+ > header
+ white-space nowrap
- @media (min-width 500px)
- margin-bottom 2px
+ @media (min-width 500px)
+ margin-bottom 2px
- > .name
- display inline
- margin 0
- padding 0
- color #777
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #777
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- &:hover
- text-decoration underline
+ &:hover
+ text-decoration underline
- > .username
- text-align left
- margin 0 0 0 8px
- color #ccc
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #ccc
- > .created-at
- position absolute
- top 0
- right 0
- font-size 0.9em
- color #c0c0c0
+ > .created-at
+ position absolute
+ top 0
+ right 0
+ font-size 0.9em
+ color #c0c0c0
- > .body
+ > .body
- > .text
- cursor default
- display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 1.1em
- color #717171
+ > .text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 1.1em
+ color #717171
- mk-url-preview
- margin-top 8px
+ mk-url-preview
+ margin-top 8px
- > .reply
- margin-right 8px
- color #717171
+ > .reply
+ margin-right 8px
+ color #717171
- > .quote
- margin-left 4px
- font-style oblique
- color #a0bf46
+ > .quote
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
- > .media
- > img
- display block
- max-width 100%
+ > .media
+ > img
+ display block
+ max-width 100%
- > .repost
- margin 8px 0
+ > .repost
+ margin 8px 0
- > i:first-child
- position absolute
- top -8px
- left -8px
- z-index 1
- color #c0dac6
- font-size 28px
- background #fff
+ > i:first-child
+ position absolute
+ top -8px
+ left -8px
+ z-index 1
+ color #c0dac6
+ font-size 28px
+ background #fff
- > mk-post-preview
- padding 16px
- border dashed 1px #c0dac6
- border-radius 8px
+ > mk-post-preview
+ padding 16px
+ border dashed 1px #c0dac6
+ border-radius 8px
- > footer
- > button
- margin 0 28px 0 0
- padding 8px
- background transparent
- border none
- box-shadow none
- font-size 1em
- color #ddd
- cursor pointer
+ > footer
+ > button
+ margin 0 28px 0 0
+ padding 8px
+ background transparent
+ border none
+ box-shadow none
+ font-size 1em
+ color #ddd
+ cursor pointer
- &:hover
- color #666
+ &:hover
+ color #666
- > .count
- display inline
- margin 0 0 0 8px
- color #999
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
- &.liked
- color $theme-color
+ &.liked
+ color $theme-color
-script.
- @mixin \api
- @mixin \text
- @mixin \get-post-summary
- @mixin \open-post-form
+ </style>
+ <script>
+ @mixin \api
+ @mixin \text
+ @mixin \get-post-summary
+ @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
+ @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
- @on \mount ~>
- if @p.text?
- tokens = if @p._highlight?
- then @analyze @p._highlight
- else @analyze @p.text
+ @on \mount ~>
+ if @p.text?
+ tokens = if @p._highlight?
+ then @analyze @p._highlight
+ else @analyze @p.text
- @refs.text.innerHTML = if @p._highlight?
- then @compile tokens, true, false
- else @compile tokens
+ @refs.text.innerHTML = if @p._highlight?
+ then @compile tokens, true, false
+ else @compile tokens
- @refs.text.children.for-each (e) ~>
- if e.tag-name == \MK-URL
- riot.mount e
+ @refs.text.children.for-each (e) ~>
+ if e.tag-name == \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
+ # 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
- @reply = ~>
- @open-post-form do
- reply: @p
+ @reply = ~>
+ @open-post-form do
+ reply: @p
- @repost = ~>
- text = window.prompt '「' + @summary + '」をRepost'
- if text?
- @api \posts/create do
- repost_id: @p.id
- text: if text == '' then undefined else text
+ @repost = ~>
+ text = window.prompt '「' + @summary + '」をRepost'
+ if text?
+ @api \posts/create do
+ repost_id: @p.id
+ text: if text == '' then undefined else 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!
+ @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!
+ </script>
+</mk-timeline-post>
diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag
index 7114824872..cef05d54a0 100644
--- a/src/web/app/mobile/tags/timeline.tag
+++ b/src/web/app/mobile/tags/timeline.tag
@@ -1,128 +1,120 @@
-mk-timeline
- div.init(if={ init })
- i.fa.fa-spinner.fa-pulse
- | 読み込んでいます
- div.empty(if={ !init && posts.length == 0 })
- i.fa.fa-comments-o
- | { opts.empty || '表示するものがありません' }
- virtual(each={ post, i in posts })
- mk-timeline-post(post={ post })
- p.date(if={ i != posts.length - 1 && post._date != posts[i + 1]._date })
- span
- i.fa.fa-angle-up
- | { post._datetext }
- span
- i.fa.fa-angle-down
- | { posts[i + 1]._datetext }
- footer(if={ !init })
- button(if={ can-fetch-more }, onclick={ more }, disabled={ fetching })
- span(if={ !fetching }) もっとみる
- span(if={ fetching })
- | 読み込み中
- mk-ellipsis
+<mk-timeline>
+ <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse"></i>読み込んでいます</div>
+ <div class="empty" if="{ !init &amp;&amp; posts.length == 0 }"><i class="fa fa-comments-o"></i>{ opts.empty || '表示するものがありません' }</div>
+ <virtual each="{ post, i in posts }">
+ <mk-timeline-post post="{ post }"></mk-timeline-post>
+ <p class="date" if="{ i != posts.length - 1 &amp;&amp; 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 if="{ !init }">
+ <button if="{ canFetchMore }" onclick="{ more }" disabled="{ fetching }"><span if="{ !fetching }">もっとみる</span><span if="{ fetching }">読み込み中
+ <mk-ellipsis></mk-ellipsis></span></button>
+ </footer>
+ <style type="stylus">
+ :scope
+ display block
+ background #fff
+ background-clip content-box
+ overflow hidden
-style.
- display block
- background #fff
- background-clip content-box
- overflow hidden
+ > .init
+ padding 64px 0
+ text-align center
+ color #999
- > .init
- padding 64px 0
- text-align center
- color #999
+ > i
+ margin-right 4px
- > i
- margin-right 4px
+ > .empty
+ margin 0 auto
+ padding 32px
+ max-width 400px
+ text-align center
+ color #999
- > .empty
- margin 0 auto
- padding 32px
- max-width 400px
- text-align center
- color #999
+ > i
+ display block
+ margin-bottom 16px
+ font-size 3em
+ color #ccc
- > i
- display block
- margin-bottom 16px
- font-size 3em
- color #ccc
+ > mk-timeline-post
+ border-bottom solid 1px #eaeaea
- > mk-timeline-post
- border-bottom solid 1px #eaeaea
+ &:last-of-type
+ border-bottom none
- &:last-of-type
- border-bottom none
+ > .date
+ display block
+ margin 0
+ line-height 32px
+ text-align center
+ font-size 0.9em
+ color #aaa
+ background #fdfdfd
+ border-bottom solid 1px #eaeaea
- > .date
- display block
- margin 0
- line-height 32px
- text-align center
- font-size 0.9em
- color #aaa
- background #fdfdfd
- border-bottom solid 1px #eaeaea
+ span
+ margin 0 16px
- span
- margin 0 16px
+ i
+ margin-right 8px
- i
- margin-right 8px
+ > footer
+ text-align center
+ border-top solid 1px #eaeaea
+ border-bottom-left-radius 4px
+ border-bottom-right-radius 4px
- > footer
- text-align center
- border-top solid 1px #eaeaea
- border-bottom-left-radius 4px
- border-bottom-right-radius 4px
+ > button
+ margin 0
+ padding 16px
+ width 100%
+ color $theme-color
- > button
- margin 0
- padding 16px
- width 100%
- color $theme-color
+ &:disabled
+ opacity 0.7
- &:disabled
- opacity 0.7
+ </style>
+ <script>
+ @posts = []
+ @init = true
+ @fetching = false
+ @can-fetch-more = true
-script.
- @posts = []
- @init = true
- @fetching = false
- @can-fetch-more = true
+ @on \mount ~>
+ @opts.init.then (posts) ~>
+ @init = false
+ @set-posts posts
- @on \mount ~>
- @opts.init.then (posts) ~>
- @init = false
- @set-posts 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 + '日'
- @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 + '日'
+ @more = ~>
+ if @init or @fetching or @posts.length == 0 then return
+ @fetching = true
+ @update!
+ @opts.more!.then (posts) ~>
+ @fetching = false
+ @prepend-posts posts
- @more = ~>
- if @init or @fetching or @posts.length == 0 then return
- @fetching = true
- @update!
- @opts.more!.then (posts) ~>
- @fetching = false
- @prepend-posts posts
+ @set-posts = (posts) ~>
+ @posts = posts
+ @update!
- @set-posts = (posts) ~>
- @posts = posts
- @update!
+ @prepend-posts = (posts) ~>
+ posts.for-each (post) ~>
+ @posts.push post
+ @update!
- @prepend-posts = (posts) ~>
- posts.for-each (post) ~>
- @posts.push post
+ @add-post = (post) ~>
+ @posts.unshift post
@update!
- @add-post = (post) ~>
- @posts.unshift post
- @update!
-
- @tail = ~>
- @posts[@posts.length - 1]
+ @tail = ~>
+ @posts[@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 7105d065f8..273b03213e 100644
--- a/src/web/app/mobile/tags/ui-header.tag
+++ b/src/web/app/mobile/tags/ui-header.tag
@@ -1,98 +1,103 @@
-mk-ui-header
- mk-special-message
- div.main
- div.backdrop
- div.content
- button.nav#hamburger: i.fa.fa-bars
- h1@title Misskey
- button.post(onclick={ post }): i.fa.fa-pencil
+<mk-ui-header>
+ <mk-special-message></mk-special-message>
+ <div class="main">
+ <div class="backdrop"></div>
+ <div class="content">
+ <button class="nav" id="hamburger"><i class="fa fa-bars"></i></button>
+ <h1 ref="title">Misskey</h1>
+ <button class="post" onclick="{ post }"><i class="fa fa-pencil"></i></button>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ $height = 48px
-style.
- $height = 48px
-
- display block
- position fixed
- top 0
- z-index 1024
- width 100%
- box-shadow 0 1px 0 rgba(#000, 0.075)
-
- > .main
- color rgba(#000, 0.6)
-
- > .backdrop
- position absolute
+ display block
+ position fixed
top 0
- z-index 1023
+ z-index 1024
width 100%
- height $height
- -webkit-backdrop-filter blur(12px)
- backdrop-filter blur(12px)
- background-color rgba(#fff, 0.75)
+ box-shadow 0 1px 0 rgba(#000, 0.075)
- > .content
- z-index 1024
+ > .main
+ color rgba(#000, 0.6)
+
+ > .backdrop
+ position absolute
+ top 0
+ z-index 1023
+ width 100%
+ height $height
+ -webkit-backdrop-filter blur(12px)
+ backdrop-filter blur(12px)
+ background-color rgba(#fff, 0.75)
+
+ > .content
+ z-index 1024
- > h1
- display block
- margin 0 auto
- padding 0
- width 100%
- max-width calc(100% - 112px)
- text-align center
- font-size 1.1em
- font-weight normal
- line-height $height
- white-space nowrap
- overflow hidden
- text-overflow ellipsis
+ > h1
+ display block
+ margin 0 auto
+ padding 0
+ width 100%
+ max-width calc(100% - 112px)
+ text-align center
+ font-size 1.1em
+ font-weight normal
+ line-height $height
+ white-space nowrap
+ overflow hidden
+ text-overflow ellipsis
- > i
- margin-right 8px
+ > i
+ margin-right 8px
- > img
- display inline-block
- vertical-align bottom
- width ($height - 16px)
- height ($height - 16px)
- margin 8px
- border-radius 6px
+ > img
+ display inline-block
+ vertical-align bottom
+ width ($height - 16px)
+ height ($height - 16px)
+ margin 8px
+ border-radius 6px
- > .nav
- display block
- position absolute
- top 0
- left 0
- width $height
- font-size 1.4em
- line-height $height
- border-right solid 1px rgba(#000, 0.1)
+ > .nav
+ display block
+ position absolute
+ top 0
+ left 0
+ width $height
+ font-size 1.4em
+ line-height $height
+ border-right solid 1px rgba(#000, 0.1)
- > i
- transition all 0.2s ease
+ > i
+ transition all 0.2s ease
- > .post
- display block
- position absolute
- top 0
- right 0
- width $height
- text-align center
- font-size 1.4em
- color inherit
- line-height $height
- border-left solid 1px rgba(#000, 0.1)
+ > .post
+ display block
+ position absolute
+ top 0
+ right 0
+ width $height
+ text-align center
+ font-size 1.4em
+ color inherit
+ line-height $height
+ border-left solid 1px rgba(#000, 0.1)
-script.
- @mixin \ui
- @mixin \open-post-form
+ </style>
+ <script>
+ @mixin \ui
+ @mixin \open-post-form
- @on \mount ~>
- @opts.ready!
+ @on \mount ~>
+ @opts.ready!
- @ui.one \title (title) ~>
- if @refs.title?
- @refs.title.innerHTML = title
+ @ui.one \title (title) ~>
+ if @refs.title?
+ @refs.title.innerHTML = title
- @post = ~>
- @open-post-form!
+ @post = ~>
+ @open-post-form!
+ </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 2c551b30ad..de9c17cc8f 100644
--- a/src/web/app/mobile/tags/ui-nav.tag
+++ b/src/web/app/mobile/tags/ui-nav.tag
@@ -1,169 +1,151 @@
-mk-ui-nav
- div.body: div.content
- a.me(if={ SIGNIN }, href={ CONFIG.url + '/' + I.username })
- img.avatar(src={ I.avatar_url + '?thumbnail&size=128' }, alt='avatar')
- p.name { I.name }
- div.links
- ul
- li.post: a(href='/i/post')
- i.icon.fa.fa-pencil-square-o
- | 新規投稿
- i.angle.fa.fa-angle-right
- ul
- li.home: a(href='/')
- i.icon.fa.fa-home
- | ホーム
- i.angle.fa.fa-angle-right
- li.mentions: a(href='/i/mentions')
- i.icon.fa.fa-at
- | あなた宛て
- i.angle.fa.fa-angle-right
- li.notifications: a(href='/i/notifications')
- i.icon.fa.fa-bell-o
- | 通知
- i.angle.fa.fa-angle-right
- li.messaging: a
- i.icon.fa.fa-comments-o
- | メッセージ
- i.angle.fa.fa-angle-right
- ul
- li.settings: a(onclick={ search })
- i.icon.fa.fa-search
- | 検索
- i.angle.fa.fa-angle-right
- ul
- li.settings: a(href='/i/drive')
- i.icon.fa.fa-cloud
- | ドライブ
- i.angle.fa.fa-angle-right
- li.settings: a(href='/i/upload')
- i.icon.fa.fa-upload
- | アップロード
- i.angle.fa.fa-angle-right
- ul
- li.settings: a(href='/i/settings')
- i.icon.fa.fa-cog
- | 設定
- i.angle.fa.fa-angle-right
- p.about
- a Misskeyについて
-
-style.
- display block
- position fixed
- top 0
- left 0
- z-index -1
- width 240px
- color #fff
- background #313538
- visibility hidden
+<mk-ui-nav>
+ <div class="body">
+ <div class="content"><a class="me" if="{ SIGNIN }" href="{ CONFIG.url + '/' + I.username }"><img class="avatar" src="{ I.avatar_url + '?thumbnail&amp;size=128' }" alt="avatar"/>
+ <p class="name">{ I.name }</p></a>
+ <div class="links">
+ <ul>
+ <li class="post"><a href="/i/post"><i class="icon fa fa-pencil-square-o"></i>新規投稿<i class="angle fa fa-angle-right"></i></a></li>
+ </ul>
+ <ul>
+ <li class="home"><a href="/"><i class="icon fa fa-home"></i>ホーム<i class="angle fa fa-angle-right"></i></a></li>
+ <li class="mentions"><a href="/i/mentions"><i class="icon fa fa-at"></i>あなた宛て<i class="angle fa fa-angle-right"></i></a></li>
+ <li class="notifications"><a href="/i/notifications"><i class="icon fa fa-bell-o"></i>通知<i class="angle fa fa-angle-right"></i></a></li>
+ <li class="messaging"><a><i class="icon fa fa-comments-o"></i>メッセージ<i class="angle fa fa-angle-right"></i></a></li>
+ </ul>
+ <ul>
+ <li class="settings"><a onclick="{ search }"><i class="icon fa fa-search"></i>検索<i class="angle fa fa-angle-right"></i></a></li>
+ </ul>
+ <ul>
+ <li class="settings"><a href="/i/drive"><i class="icon fa fa-cloud"></i>ドライブ<i class="angle fa fa-angle-right"></i></a></li>
+ <li class="settings"><a href="/i/upload"><i class="icon fa fa-upload"></i>アップロード<i class="angle fa fa-angle-right"></i></a></li>
+ </ul>
+ <ul>
+ <li class="settings"><a href="/i/settings"><i class="icon fa fa-cog"></i>設定<i class="angle fa fa-angle-right"></i></a></li>
+ </ul>
+ </div>
+ <p class="about"><a>Misskeyについて</a></p>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ position fixed
+ top 0
+ left 0
+ z-index -1
+ width 240px
+ color #fff
+ background #313538
+ visibility hidden
- .body
- height 100%
- overflow hidden
+ .body
+ height 100%
+ overflow hidden
- .content
- min-height 100%
+ .content
+ min-height 100%
- .me
- display block
- margin 0
- padding 16px
+ .me
+ display block
+ margin 0
+ padding 16px
- .avatar
- display inline
- max-width 64px
- border-radius 32px
- vertical-align middle
+ .avatar
+ display inline
+ max-width 64px
+ border-radius 32px
+ vertical-align middle
- .name
- display block
- margin 0 16px
- position absolute
- top 0
- left 80px
- padding 0
- width calc(100% - 112px)
- color #fff
- line-height 96px
- overflow hidden
- text-overflow ellipsis
- white-space nowrap
+ .name
+ display block
+ margin 0 16px
+ position absolute
+ top 0
+ left 80px
+ padding 0
+ width calc(100% - 112px)
+ color #fff
+ line-height 96px
+ overflow hidden
+ text-overflow ellipsis
+ white-space nowrap
- ul
- display block
- margin 16px 0
- padding 0
- list-style none
+ ul
+ display block
+ margin 16px 0
+ padding 0
+ list-style none
- &:first-child
- margin-top 0
+ &:first-child
+ margin-top 0
- li
- display block
- font-size 1em
- line-height 1em
- border-top solid 1px rgba(0, 0, 0, 0.2)
- background #353A3E
- background-clip content-box
+ li
+ display block
+ font-size 1em
+ line-height 1em
+ border-top solid 1px rgba(0, 0, 0, 0.2)
+ background #353A3E
+ background-clip content-box
- &:last-child
- border-bottom solid 1px rgba(0, 0, 0, 0.2)
+ &:last-child
+ border-bottom solid 1px rgba(0, 0, 0, 0.2)
- a
- display block
- padding 0 20px
- line-height 3rem
- line-height calc(1rem + 30px)
- color #eee
- text-decoration none
+ a
+ display block
+ padding 0 20px
+ line-height 3rem
+ line-height calc(1rem + 30px)
+ color #eee
+ text-decoration none
- > .icon
- margin-right 0.5em
+ > .icon
+ margin-right 0.5em
- > .angle
- position absolute
- top 0
- right 0
- padding 0 20px
- font-size 1.2em
- line-height calc(1rem + 30px)
- color #ccc
+ > .angle
+ position absolute
+ top 0
+ right 0
+ padding 0 20px
+ font-size 1.2em
+ line-height calc(1rem + 30px)
+ color #ccc
- > .unread-count
- position absolute
- height calc(0.9em + 10px)
- line-height calc(0.9em + 10px)
- top 0
- bottom 0
- right 38px
- margin auto 0
- padding 0px 8px
- min-width 2em
- font-size 0.9em
- text-align center
- color #fff
- background rgba(255, 255, 255, 0.1)
- border-radius 1em
+ > .unread-count
+ position absolute
+ height calc(0.9em + 10px)
+ line-height calc(0.9em + 10px)
+ top 0
+ bottom 0
+ right 38px
+ margin auto 0
+ padding 0px 8px
+ min-width 2em
+ font-size 0.9em
+ text-align center
+ color #fff
+ background rgba(255, 255, 255, 0.1)
+ border-radius 1em
- .about
- margin 1em 1em 2em 1em
- text-align center
- font-size 0.6em
- opacity 0.3
+ .about
+ margin 1em 1em 2em 1em
+ text-align center
+ font-size 0.6em
+ opacity 0.3
- a
- color #fff
+ a
+ color #fff
-script.
- @mixin \i
- @mixin \page
+ </style>
+ <script>
+ @mixin \i
+ @mixin \page
- @on \mount ~>
- @opts.ready!
+ @on \mount ~>
+ @opts.ready!
- @search = ~>
- query = window.prompt \検索
- if query? and query != ''
- @page '/search:' + query
+ @search = ~>
+ query = window.prompt \検索
+ if query? and query != ''
+ @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 81dfac80ca..966cfb4255 100644
--- a/src/web/app/mobile/tags/ui.tag
+++ b/src/web/app/mobile/tags/ui.tag
@@ -1,50 +1,51 @@
-mk-ui
- div.global@global
- mk-ui-header@header(ready={ ready })
- mk-ui-nav@nav(ready={ ready })
+<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>
+ <div class="content" ref="main"><yield /></div>
+ </div>
+ <mk-stream-indicator></mk-stream-indicator>
+ <style type="stylus">
+ :scope
+ display block
- div.content@main
- <yield />
+ > .global
+ > .content
+ background #fff
- mk-stream-indicator
+ </style>
+ <script>
+ @mixin \stream
-style.
- display block
+ @ready-count = 0
- > .global
- > .content
- background #fff
+ #@ui.on \notification (text) ~>
+ # alert text
-script.
- @mixin \stream
+ @on \mount ~>
+ @stream.on \notification @on-stream-notification
+ @ready!
- @ready-count = 0
+ @on \unmount ~>
+ @stream.off \notification @on-stream-notification
+ @slide.slide-close!
- #@ui.on \notification (text) ~>
- # alert text
+ @ready = ~>
+ @ready-count++
- @on \mount ~>
- @stream.on \notification @on-stream-notification
- @ready!
+ if @ready-count == 2
+ @slide = SpSlidemenu @refs.main, @refs.nav.root, \#hamburger {direction: \left}
+ @init-view-position!
- @on \unmount ~>
- @stream.off \notification @on-stream-notification
- @slide.slide-close!
+ @init-view-position = ~>
+ top = @refs.header.root.offset-height
+ @refs.main.style.padding-top = top + \px
+ @refs.nav.root.style.margin-top = top + \px
+ @refs.nav.root.query-selector '.body > .content' .style.padding-bottom = top + \px
- @ready = ~>
- @ready-count++
-
- if @ready-count == 2
- @slide = SpSlidemenu @refs.main, @refs.nav.root, \#hamburger {direction: \left}
- @init-view-position!
-
- @init-view-position = ~>
- top = @refs.header.root.offset-height
- @refs.main.style.padding-top = top + \px
- @refs.nav.root.style.margin-top = top + \px
- @refs.nav.root.query-selector '.body > .content' .style.padding-bottom = top + \px
-
- @on-stream-notification = (notification) ~>
- el = document.body.append-child document.create-element \mk-notify
- riot.mount el, do
- notification: notification
+ @on-stream-notification = (notification) ~>
+ el = document.body.append-child document.create-element \mk-notify
+ riot.mount el, do
+ 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 7004398268..00d11f3970 100644
--- a/src/web/app/mobile/tags/user-followers.tag
+++ b/src/web/app/mobile/tags/user-followers.tag
@@ -1,22 +1,25 @@
-mk-user-followers
- mk-users-list@list(fetch={ fetch }, count={ user.followers_count }, you-know-count={ user.followers_you_know_count }, no-users={ 'フォロワーはいないようです。' })
+<mk-user-followers>
+ <mk-users-list ref="list" fetch="{ fetch }" count="{ user.followers_count }" you-know-count="{ user.followers_you_know_count }" no-users="{ 'フォロワーはいないようです。' }"></mk-users-list>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @user = @opts.user
- @user = @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
- @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
-
- @on \mount ~>
- @refs.list.on \loaded ~>
- @trigger \loaded
+ @on \mount ~>
+ @refs.list.on \loaded ~>
+ @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 c122acd607..bbfa547c79 100644
--- a/src/web/app/mobile/tags/user-following.tag
+++ b/src/web/app/mobile/tags/user-following.tag
@@ -1,22 +1,25 @@
-mk-user-following
- mk-users-list@list(fetch={ fetch }, count={ user.following_count }, you-know-count={ user.following_you_know_count }, no-users={ 'フォロー中のユーザーはいないようです。' })
+<mk-user-following>
+ <mk-users-list ref="list" fetch="{ fetch }" count="{ user.following_count }" you-know-count="{ user.following_you_know_count }" no-users="{ 'フォロー中のユーザーはいないようです。' }"></mk-users-list>
+ <style type="stylus">
+ :scope
+ display block
-style.
- display block
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @user = @opts.user
- @user = @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
- @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
-
- @on \mount ~>
- @refs.list.on \loaded ~>
- @trigger \loaded
+ @on \mount ~>
+ @refs.list.on \loaded ~>
+ @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 56bd93825c..7b00043a1c 100644
--- a/src/web/app/mobile/tags/user-preview.tag
+++ b/src/web/app/mobile/tags/user-preview.tag
@@ -1,92 +1,89 @@
-mk-user-preview
- a.avatar-anchor(href={ CONFIG.url + '/' + user.username })
- img.avatar(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
- div.main
- header
- a.name(href={ CONFIG.url + '/' + user.username })
- | { user.name }
- span.username
- | @{ user.username }
- div.body
- div.bio { user.bio }
+<mk-user-preview><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&amp;size=64' }" alt="avatar"/></a>
+ <div class="main">
+ <header><a class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</a><span class="username">@{ user.username }</span></header>
+ <div class="body">
+ <div class="bio">{ user.bio }</div>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
+ margin 0
+ padding 16px
+ font-size 12px
-style.
- display block
- margin 0
- padding 16px
- font-size 12px
+ @media (min-width 350px)
+ font-size 14px
- @media (min-width 350px)
- font-size 14px
+ @media (min-width 500px)
+ font-size 16px
- @media (min-width 500px)
- font-size 16px
+ &:after
+ content ""
+ display block
+ clear both
- &:after
- content ""
- display block
- clear both
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 10px 0 0
- > .avatar-anchor
- display block
- float left
- margin 0 10px 0 0
+ @media (min-width 500px)
+ margin-right 16px
- @media (min-width 500px)
- margin-right 16px
+ > .avatar
+ display block
+ width 48px
+ height 48px
+ margin 0
+ border-radius 6px
+ vertical-align bottom
- > .avatar
- display block
- width 48px
- height 48px
- margin 0
- border-radius 6px
- vertical-align bottom
+ @media (min-width 500px)
+ width 58px
+ height 58px
+ border-radius 8px
- @media (min-width 500px)
- width 58px
- height 58px
- border-radius 8px
+ > .main
+ float left
+ width calc(100% - 58px)
- > .main
- float left
- width calc(100% - 58px)
+ @media (min-width 500px)
+ width calc(100% - 74px)
- @media (min-width 500px)
- width calc(100% - 74px)
+ > header
+ @media (min-width 500px)
+ margin-bottom 2px
- > header
- @media (min-width 500px)
- margin-bottom 2px
+ > .name
+ display inline
+ margin 0
+ padding 0
+ color #777
+ font-size 1em
+ font-weight 700
+ text-align left
+ text-decoration none
- > .name
- display inline
- margin 0
- padding 0
- color #777
- font-size 1em
- font-weight 700
- text-align left
- text-decoration none
+ &:hover
+ text-decoration underline
- &:hover
- text-decoration underline
+ > .username
+ text-align left
+ margin 0 0 0 8px
+ color #ccc
- > .username
- text-align left
- margin 0 0 0 8px
- color #ccc
+ > .body
- > .body
-
- > .bio
- cursor default
- display block
- margin 0
- padding 0
- word-wrap break-word
- font-size 1.1em
- color #717171
+ > .bio
+ cursor default
+ display block
+ margin 0
+ padding 0
+ word-wrap break-word
+ font-size 1.1em
+ color #717171
-script.
- @user = @opts.user
+ </style>
+ <script>@user = @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 848405d24e..354c0790c2 100644
--- a/src/web/app/mobile/tags/user-timeline.tag
+++ b/src/web/app/mobile/tags/user-timeline.tag
@@ -1,28 +1,31 @@
-mk-user-timeline
- mk-timeline@timeline(init={ init }, more={ more }, empty={ with-media ? 'メディア付き投稿はありません。' : 'このユーザーはまだ投稿していないようです。' })
+<mk-user-timeline>
+ <mk-timeline ref="timeline" init="{ init }" more="{ more }" empty="{ withMedia ? 'メディア付き投稿はありません。' : 'このユーザーはまだ投稿していないようです。' }"></mk-timeline>
+ <style type="stylus">
+ :scope
+ display block
+ max-width 600px
+ margin 0 auto
+ background #fff
-style.
- display block
- max-width 600px
- margin 0 auto
- background #fff
+ </style>
+ <script>
+ @mixin \api
-script.
- @mixin \api
+ @user = @opts.user
+ @with-media = @opts.with-media
- @user = @opts.user
- @with-media = @opts.with-media
+ @init = new Promise (res, rej) ~>
+ @api \users/posts do
+ user_id: @user.id
+ with_media: @with-media
+ .then (posts) ~>
+ res posts
+ @trigger \loaded
- @init = new Promise (res, rej) ~>
- @api \users/posts do
- user_id: @user.id
- with_media: @with-media
- .then (posts) ~>
- res posts
- @trigger \loaded
-
- @more = ~>
- @api \users/posts do
- user_id: @user.id
- with_media: @with-media
- max_id: @refs.timeline.tail!.id
+ @more = ~>
+ @api \users/posts do
+ user_id: @user.id
+ with_media: @with-media
+ max_id: @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 1ecbc3d99e..bce6c883f5 100644
--- a/src/web/app/mobile/tags/user.tag
+++ b/src/web/app/mobile/tags/user.tag
@@ -1,201 +1,189 @@
-mk-user
- div.user(if={ !fetching })
- header
- div.banner(style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' })
- div.body
- div.top
- a.avatar: img(src={ user.avatar_url + '?thumbnail&size=160' }, alt='avatar')
- mk-follow-button(if={ SIGNIN && I.id != user.id }, user={ user })
+<mk-user>
+ <div class="user" if="{ !fetching }">
+ <header>
+ <div class="banner" style="{ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&amp;size=1024)' : '' }"></div>
+ <div class="body">
+ <div class="top"><a class="avatar"><img src="{ user.avatar_url + '?thumbnail&amp;size=160' }" alt="avatar"/></a>
+ <mk-follow-button if="{ SIGNIN &amp;&amp; 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>
+ </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('-', '月') + '日' }</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>
+ <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>
+ </header>
+ <div class="body">
+ <mk-user-timeline if="{ page == 'posts' }" user="{ user }"></mk-user-timeline>
+ <mk-user-timeline if="{ page == 'media' }" user="{ user }" with-media="{ true }"></mk-user-timeline>
+ <mk-user-graphs if="{ page == 'graphs' }" user="{ user }"></mk-user-graphs>
+ </div>
+ </div>
+ <style type="stylus">
+ :scope
+ display block
- div.title
- h1 { user.name }
- span.username @{ user.username }
- span.followed(if={ user.is_followed }) フォローされています
+ > .user
+ > header
+ > .banner
+ padding-bottom 33.3%
+ background-color #f5f5f5
+ background-size cover
+ background-position center
- div.bio { user.bio }
+ > .body
+ padding 8px
+ margin 0 auto
+ max-width 600px
- div.info
- p.location(if={ user.location })
- i.fa.fa-map-marker
- | { user.location }
- p.birthday(if={ user.birthday })
- i.fa.fa-birthday-cake
- | { user.birthday.replace('-', '年').replace('-', '月') + '日' }
+ > .top
+ &:after
+ content ''
+ display block
+ clear both
- div.friends
- a(href='{ user.username }/following')
- b { user.following_count }
- i フォロー
- a(href='{ user.username }/followers')
- b { user.followers_count }
- i フォロワー
- nav
- a(data-is-active={ page == 'posts' }, onclick={ go-posts }) 投稿
- a(data-is-active={ page == 'media' }, onclick={ go-media }) メディア
- a(data-is-active={ page == 'graphs' }, onclick={ go-graphs }) グラフ
- a(data-is-active={ page == 'likes' }, onclick={ go-likes }) いいね
+ > .avatar
+ display block
+ float left
+ width 25%
+ height 40px
- div.body
- mk-user-timeline(if={ page == 'posts' }, user={ user })
- mk-user-timeline(if={ page == 'media' }, user={ user }, with-media={ true })
- mk-user-graphs(if={ page == 'graphs' }, user={ user })
+ > img
+ display block
+ position absolute
+ left -2px
+ bottom -2px
+ width 100%
+ border 2px solid #fff
+ border-radius 6px
-style.
- display block
+ @media (min-width 500px)
+ left -4px
+ bottom -4px
+ border 4px solid #fff
+ border-radius 12px
- > .user
- > header
- > .banner
- padding-bottom 33.3%
- background-color #f5f5f5
- background-size cover
- background-position center
+ > mk-follow-button
+ float right
+ height 40px
- > .body
- padding 8px
- margin 0 auto
- max-width 600px
+ > .title
+ margin 8px 0
- > .top
- &:after
- content ''
- display block
- clear both
+ > h1
+ margin 0
+ line-height 22px
+ font-size 20px
+ color #222
- > .avatar
- display block
- float left
- width 25%
- height 40px
+ > .username
+ display inline-block
+ line-height 20px
+ font-size 16px
+ font-weight bold
+ color #657786
- > img
- display block
- position absolute
- left -2px
- bottom -2px
- width 100%
- border 2px solid #fff
- border-radius 6px
-
- @media (min-width 500px)
- left -4px
- bottom -4px
- border 4px solid #fff
- border-radius 12px
-
- > mk-follow-button
- float right
- height 40px
+ > .followed
+ margin-left 8px
+ padding 2px 4px
+ font-size 12px
+ color #657786
+ background #f8f8f8
+ border-radius 4px
- > .title
- margin 8px 0
+ > .bio
+ margin 8px 0
+ color #333
- > h1
- margin 0
- line-height 22px
- font-size 20px
- color #222
+ > .info
+ margin 8px 0
- > .username
- display inline-block
- line-height 20px
- font-size 16px
- font-weight bold
- color #657786
+ > p
+ display inline
+ margin 0 16px 0 0
+ color #555
- > .followed
- margin-left 8px
- padding 2px 4px
- font-size 12px
- color #657786
- background #f8f8f8
- border-radius 4px
+ > i
+ margin-right 4px
- > .bio
- margin 8px 0
- color #333
+ > .friends
+ > a
+ color #657786
- > .info
- margin 8px 0
+ &:first-child
+ margin-right 16px
- > p
- display inline
- margin 0 16px 0 0
- color #555
+ > b
+ margin-right 4px
+ font-size 16px
+ color #14171a
- > i
- margin-right 4px
+ > i
+ font-size 14px
- > .friends
- > a
- color #657786
+ > nav
+ display flex
+ justify-content center
+ margin 0 auto
+ max-width 600px
+ border-bottom solid 1px #ddd
- &:first-child
- margin-right 16px
-
- > b
- margin-right 4px
- font-size 16px
- color #14171a
-
- > i
+ > a
+ display block
+ flex 1 1
+ text-align center
+ line-height 52px
font-size 14px
+ text-decoration none
+ color #657786
+ border-bottom solid 2px transparent
- > nav
- display flex
- justify-content center
- margin 0 auto
- max-width 600px
- border-bottom solid 1px #ddd
+ &[data-is-active]
+ font-weight bold
+ color $theme-color
+ border-color $theme-color
- > a
- display block
- flex 1 1
- text-align center
- line-height 52px
- font-size 14px
- text-decoration none
- color #657786
- border-bottom solid 2px transparent
+ > .body
+ @media (min-width 500px)
+ padding 16px 0 0 0
- &[data-is-active]
- font-weight bold
- color $theme-color
- border-color $theme-color
+ </style>
+ <script>
+ @mixin \i
+ @mixin \api
- > .body
- @media (min-width 500px)
- padding 16px 0 0 0
+ @username = @opts.user
+ @page = if @opts.page? then @opts.page else \posts
+ @fetching = true
-script.
- @mixin \i
- @mixin \api
+ @on \mount ~>
+ @api \users/show do
+ username: @username
+ .then (user) ~>
+ @fetching = false
+ @user = user
+ @trigger \loaded user
+ @update!
- @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
+ @go-posts = ~>
+ @page = \posts
@update!
- @go-posts = ~>
- @page = \posts
- @update!
-
- @go-media = ~>
- @page = \media
- @update!
+ @go-media = ~>
+ @page = \media
+ @update!
- @go-graphs = ~>
- @page = \graphs
- @update!
+ @go-graphs = ~>
+ @page = \graphs
+ @update!
- @go-likes = ~>
- @page = \likes
- @update!
+ @go-likes = ~>
+ @page = \likes
+ @update!
+ </script>
+</mk-user>
diff --git a/src/web/app/mobile/tags/users-list.tag b/src/web/app/mobile/tags/users-list.tag
index 3e29a0a4cc..f64f196e46 100644
--- a/src/web/app/mobile/tags/users-list.tag
+++ b/src/web/app/mobile/tags/users-list.tag
@@ -1,125 +1,116 @@
-mk-users-list
- nav
- span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') })
- | すべて
- span { opts.count }
- // ↓ https://github.com/riot/riot/issues/2080
- span(if={ SIGNIN && opts.you-know-count != '' }, data-is-active={ mode == 'iknow' }, onclick={ set-mode.bind(this, 'iknow') })
- | 知り合い
- span { opts.you-know-count }
-
- div.users(if={ !fetching && users.length != 0 })
- mk-user-preview(each={ users }, user={ this })
-
- button.more(if={ !fetching && next != null }, onclick={ more }, disabled={ more-fetching })
- span(if={ !more-fetching }) もっと
- span(if={ more-fetching })
- | 読み込み中
- mk-ellipsis
-
- p.no(if={ !fetching && users.length == 0 })
- | { opts.no-users }
- p.fetching(if={ fetching })
- i.fa.fa-spinner.fa-pulse.fa-fw
- | 読み込んでいます
- mk-ellipsis
-
-style.
- display block
- background #fff
-
- > nav
- display flex
- justify-content center
- margin 0 auto
- max-width 600px
- border-bottom solid 1px #ddd
-
- > span
+<mk-users-list>
+ <nav><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 &amp;&amp; opts.youKnowCount != '' }" data-is-active="{ mode == 'iknow' }" onclick="{ setMode.bind(this, 'iknow') }">知り合い<span>{ opts.youKnowCount }</span></span>
+ </nav>
+ <div class="users" if="{ !fetching &amp;&amp; users.length != 0 }">
+ <mk-user-preview each="{ users }" user="{ this }"></mk-user-preview>
+ </div>
+ <button class="more" if="{ !fetching &amp;&amp; next != null }" onclick="{ more }" disabled="{ moreFetching }"><span if="{ !moreFetching }">もっと</span><span if="{ moreFetching }">読み込み中
+ <mk-ellipsis></mk-ellipsis></span></button>
+ <p class="no" if="{ !fetching &amp;&amp; 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>
+ </p>
+ <style type="stylus">
+ :scope
display block
- flex 1 1
- text-align center
- line-height 52px
- font-size 14px
- color #657786
- border-bottom solid 2px transparent
+ background #fff
- &[data-is-active]
- font-weight bold
- color $theme-color
- border-color $theme-color
+ > nav
+ display flex
+ justify-content center
+ margin 0 auto
+ max-width 600px
+ border-bottom solid 1px #ddd
- > span
- display inline-block
- margin-left 4px
- padding 2px 5px
- font-size 12px
- line-height 1
- color #888
- background #eee
- border-radius 20px
+ > span
+ display block
+ flex 1 1
+ text-align center
+ line-height 52px
+ font-size 14px
+ color #657786
+ border-bottom solid 2px transparent
- > .users
- > *
- max-width 600px
- margin 0 auto
- border-bottom solid 1px rgba(0, 0, 0, 0.05)
+ &[data-is-active]
+ font-weight bold
+ color $theme-color
+ border-color $theme-color
- > .no
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > span
+ display inline-block
+ margin-left 4px
+ padding 2px 5px
+ font-size 12px
+ line-height 1
+ color #888
+ background #eee
+ border-radius 20px
- > .fetching
- margin 0
- padding 16px
- text-align center
- color #aaa
+ > .users
+ > *
+ max-width 600px
+ margin 0 auto
+ border-bottom solid 1px rgba(0, 0, 0, 0.05)
- > i
- margin-right 4px
+ > .no
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
-script.
- @mixin \i
+ > .fetching
+ margin 0
+ padding 16px
+ text-align center
+ color #aaa
- @limit = 30users
- @mode = \all
+ > i
+ margin-right 4px
- @fetching = true
- @more-fetching = false
+ </style>
+ <script>
+ @mixin \i
- @on \mount ~>
- @fetch ~>
- @trigger \loaded
+ @limit = 30users
+ @mode = \all
- @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!
-
- @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!
- @set-mode = (mode) ~>
- @update do
- mode: mode
+ @on \mount ~>
+ @fetch ~>
+ @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!
+
+ @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!
+
+ @set-mode = (mode) ~>
+ @update do
+ mode: mode
- @fetch!
+ @fetch!
+ </script>
+</mk-users-list>