This commit is contained in:
syuilo
2017-01-12 05:55:38 +09:00
parent 8b273e215f
commit 520299c2b4
169 changed files with 14582 additions and 14865 deletions

View File

@@ -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)
> header
border-bottom solid 1px #eee
> h1
margin 0
padding 0
text-align center
line-height 42px
font-size 1em
font-weight normal
> .count
margin-left 4px
opacity 0.5
> .close
position absolute
> .body
position fixed
z-index 2048
top 0
left 0
line-height 42px
width 42px
> .ok
position absolute
top 0
right 0
line-height 42px
width 42px
margin 0 auto
width 100%
max-width 500px
height 100%
overflow hidden
background #fff
box-shadow 0 0 16px rgba(#000, 0.3)
> mk-drive
height calc(100% - 42px)
overflow scroll
> header
border-bottom solid 1px #eee
script.
@files = []
> h1
margin 0
padding 0
text-align center
line-height 42px
font-size 1em
font-weight normal
@on \mount ~>
@refs.browser.on \change-selected (files) ~>
@files = files
@update!
> .count
margin-left 4px
opacity 0.5
@cancel = ~>
@trigger \canceled
@unmount!
> .close
position absolute
top 0
left 0
line-height 42px
width 42px
@ok = ~>
@trigger \selected @files
@unmount!
> .ok
position absolute
top 0
right 0
line-height 42px
width 42px
> mk-drive
height calc(100% - 42px)
overflow scroll
</style>
<script>
@files = []
@on \mount ~>
@refs.browser.on \change-selected (files) ~>
@files = files
@update!
@cancel = ~>
@trigger \canceled
@unmount!
@ok = ~>
@trigger \selected @files
@unmount!
</script>
</mk-drive-selector>

View File

@@ -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 = []
@files = []
@folders = []
@hierarchy-folders = []
@selected-files = []
# 現在の階層(フォルダ)
# * null でルートを表す
@folder = null
# 現在の階層(フォルダ)
# * null でルートを表す
@folder = null
@file = null
@file = null
@is-select-mode = @opts.select? and @opts.select
@multiple = if @opts.multiple? then @opts.multiple else false
@is-select-mode = @opts.select? and @opts.select
@multiple = if @opts.multiple? then @opts.multiple else false
@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 \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
# Riotのバグでnullを渡しても""になる
# https://github.com/riot/riot/issues/2080
#if @opts.folder?
if @opts.folder? and @opts.folder != ''
@cd @opts.folder
else
@load!
# Riotのバグでnullを渡しても""になる
# https://github.com/riot/riot/issues/2080
#if @opts.folder?
if @opts.folder? and @opts.folder != ''
@cd @opts.folder
else
@load!
@on \unmount ~>
@stream.off \drive_file_created @on-stream-drive-file-created
@stream.off \drive_file_updated @on-stream-drive-file-updated
@stream.off \drive_folder_created @on-stream-drive-folder-created
@stream.off \drive_folder_updated @on-stream-drive-folder-updated
@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-created = (file) ~>
@add-file file, true
@on-stream-drive-file-updated = (file) ~>
current = if @folder? then @folder.id else null
if current != file.folder_id
@remove-file file
else
@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
@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
@move = (target-folder) ~>
@cd target-folder, true
@_move = (ev) ~>
@move ev.item.folder
@cd = (target-folder, is-move) ~>
if target-folder? and typeof target-folder == \object
target-folder = target-folder.id
@move = (target-folder) ~>
@cd target-folder, true
if target-folder == null
@go-root!
return
@cd = (target-folder, is-move) ~>
if target-folder? and typeof target-folder == \object
target-folder = target-folder.id
@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
if folder.parent?
x folder.parent
if target-folder == null
@go-root!
return
@loading = true
@update!
if is-move then @trigger \move @folder
@trigger \cd @folder
@load!
.catch (err, text-status) ->
console.error err
@add-folder = (folder, unshift = false) ~>
current = if @folder? then @folder.id else null
if current != folder.parent_id
return
@api \drive/folders/show do
folder_id: target-folder
.then (folder) ~>
@folder = folder
@hierarchy-folders = []
if (@folders.some (f) ~> f.id == folder.id)
return
x = (f) ~>
@hierarchy-folders.unshift f
if f.parent?
x f.parent
if unshift
@folders.unshift folder
else
@folders.push folder
if folder.parent?
x folder.parent
@update!
@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
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-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!
@trigger \move-root
@load!
@load = ~>
@folders = []
@files = []
@more-folders = false
@more-files = false
@loading = true
@update!
@trigger \begin-load
load-folders = null
load-files = null
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/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!
if is-move then @trigger \move @folder
@trigger \cd @folder
@load!
.catch (err, text-status) ->
console.error err
@trigger \loaded
else
flag := true
@trigger \load-mid
@add-folder = (folder, unshift = false) ~>
current = if @folder? then @folder.id else null
if current != folder.parent_id
return
@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)
if (@folders.some (f) ~> f.id == folder.id)
return
if unshift
@folders.unshift folder
else
@selected-files.push file
@folders.push folder
@update!
@trigger \change-selected @selected-files
else
@file = 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
if unshift
@files.unshift file
else
@files.push file
@update!
@trigger \open-file @file
@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!
@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
load-folders = null
load-files = null
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/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!
@trigger \loaded
else
flag := true
@trigger \load-mid
@choose-file = (file) ~>
if @is-select-mode
exist = @selected-files.some (f) ~> f.id == file.id
if exist
@selected-files = (@selected-files.filter (f) ~> f.id != file.id)
else
@selected-files.push file
@update!
@trigger \change-selected @selected-files
else
@file = file
@update!
@trigger \open-file @file
</script>
</mk-drive>

View File

@@ -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>

View File

@@ -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 })
style.
display block
&, *
user-select none
*
pointer-events none
> .container
max-width 500px
margin 0 auto
padding 16px
&:after
content ""
<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
clear both
> .thumbnail
display block
float left
width 64px
height 64px
background-size cover
background-position center center
&, *
user-select none
> .body
display block
float left
width calc(100% - 74px)
margin-left 10px
*
pointer-events none
> .name
display block
margin 0
padding 0
font-size 0.9em
font-weight bold
color #555
text-overflow ellipsis
word-wrap break-word
> .container
max-width 500px
margin 0 auto
padding 16px
> .tags
display block
margin 4px 0 0 0
padding 0
list-style none
font-size 0.5em
&:after
content ""
display block
clear both
> .tag
display inline-block
margin 0 5px 0 0
padding 1px 5px
border-radius 2px
> .thumbnail
display block
float left
width 64px
height 64px
background-size cover
background-position center center
> footer
display block
margin 4px 0 0 0
font-size 0.7em
> .body
display block
float left
width calc(100% - 74px)
margin-left 10px
> .separator
display inline
margin 0
padding 0 4px
color #CDCDCD
> .name
display block
margin 0
padding 0
font-size 0.9em
font-weight bold
color #555
text-overflow ellipsis
word-wrap break-word
> .type
display inline
margin 0
padding 0
color #9D9D9D
> .tags
display block
margin 4px 0 0 0
padding 0
list-style none
font-size 0.5em
> mk-file-type-icon
margin-right 4px
> .tag
display inline-block
margin 0 5px 0 0
padding 1px 5px
border-radius 2px
> .data-size
display inline
margin 0
padding 0
color #9D9D9D
> footer
display block
margin 4px 0 0 0
font-size 0.7em
> .created-at
display inline
margin 0
padding 0
color #BDBDBD
> .separator
display inline
margin 0
padding 0 4px
color #CDCDCD
> i
margin-right 2px
> .type
display inline
margin 0
padding 0
color #9D9D9D
&[data-is-selected]
background $theme-color
> mk-file-type-icon
margin-right 4px
&, *
color #fff !important
> .data-size
display inline
margin 0
padding 0
color #9D9D9D
script.
@mixin \bytes-to-size
> .created-at
display inline
margin 0
padding 0
color #BDBDBD
@browser = @parent
@file = @opts.file
@is-selected = @browser.selected-files.some (f) ~> f.id == @file.id
> i
margin-right 2px
@browser.on \change-selected (selects) ~>
@is-selected = selects.some (f) ~> f.id == @file.id
&[data-is-selected]
background $theme-color
@onclick = ~>
@browser.choose-file @file
&, *
color #fff !important
</style>
<script>
@mixin \bytes-to-size
@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
@onclick = ~>
@browser.choose-file @file
</script>
</mk-drive-file>

View File

@@ -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
&, *
user-select none
*
pointer-events none
> .container
max-width 500px
margin 0 auto
padding 16px
> .name
<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
margin 0
padding 0
color #777
> i
margin-right 6px
&, *
user-select none
> i
position absolute
top 0
bottom 0
right 8px
margin auto 0 auto 0
width 1em
height 1em
*
pointer-events none
script.
@browser = @parent
@folder = @opts.folder
> .container
max-width 500px
margin 0 auto
padding 16px
@onclick = ~>
@browser.move @folder
> .name
display block
margin 0
padding 0
> i
margin-right 6px
> i
position absolute
top 0
bottom 0
right 8px
margin auto 0 auto 0
width 1em
height 1em
</style>
<script>
@browser = @parent
@folder = @opts.folder
@onclick = ~>
@browser.move @folder
</script>
</mk-drive-folder>

View File

@@ -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-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
@on \mount ~>
@user-promise.then (user) ~>
@user = user
@init = false
@update!
else
@api \following/create do
user_id: @user.id
.then ~>
@user.is_following = true
.catch (err) ->
console.error err
.then ~>
@wait = false
@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-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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
> .image
> img
<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
max-height 256px
max-width 100%
margin 0 auto
padding 8px
overflow hidden
box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
border-radius 4px
script.
@images = @opts.images
@image = @images.0
> .image
@click = ~>
window.open @image.url
> img
display block
max-height 256px
max-width 100%
margin 0 auto
</style>
<script>
@images = @opts.images
@image = @images.0
@click = ~>
window.open @image.url
</script>
</mk-images-viewer>

View File

@@ -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) }
style.
display block
margin 0
padding 8px
color #fff
> .main
word-wrap break-word
&: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
.text
float right
width calc(100% - 36px)
padding-left 8px
p
<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
i
margin-right 4px
.post-ref
&:before, &:after
font-family FontAwesome
font-size 1em
font-weight normal
font-style normal
display inline-block
margin-right 3px
&:before
content "\f10d"
&:after
content "\f10e"
&.like
.text p i
color #FFAC33
&.repost, &.quote
.text p i
color #77B255
&.follow
.text p i
color #53c7ce
&.reply, &.mention
.text p i
padding 8px
color #fff
script.
@mixin \get-post-summary
@notification = @opts.notification
> .main
word-wrap break-word
&: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
.text
float right
width calc(100% - 36px)
padding-left 8px
p
margin 0
i
margin-right 4px
.post-ref
&:before, &:after
font-family FontAwesome
font-size 1em
font-weight normal
font-style normal
display inline-block
margin-right 3px
&:before
content "\f10d"
&:after
content "\f10e"
&.like
.text p i
color #FFAC33
&.repost, &.quote
.text p i
color #77B255
&.follow
.text p i
color #53c7ce
&.reply, &.mention
.text p i
color #fff
</style>
<script>
@mixin \get-post-summary
@notification = @opts.notification
</script>
</mk-notification-preview>

View File

@@ -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-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
&:after
content ""
display block
clear both
.avatar-anchor
display block
float left
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
p
<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
i
margin-right 4px
> mk-time
display inline
position absolute
top 16px
right 12px
vertical-align top
color rgba(0, 0, 0, 0.6)
font-size 12px
.post-preview
color rgba(0, 0, 0, 0.7)
> .main
word-wrap break-word
.post-ref
color rgba(0, 0, 0, 0.7)
&:after
content ""
display block
clear both
&:before, &:after
font-family FontAwesome
font-size 1em
font-weight normal
font-style normal
display inline-block
margin-right 3px
.avatar-anchor
display block
float left
&:before
content "\f10d"
img
min-width 36px
min-height 36px
max-width 36px
max-height 36px
border-radius 6px
&:after
content "\f10e"
.text
float right
width calc(100% - 36px)
padding-left 8px
&.like
.text p i
color #FFAC33
p
margin 0
&.repost, &.quote
.text p i
color #77B255
i
margin-right 4px
&.follow
.text p i
color #53c7ce
.post-preview
color rgba(0, 0, 0, 0.7)
&.reply, &.mention
.text p i
color #555
.post-ref
color rgba(0, 0, 0, 0.7)
.post-preview
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
script.
@mixin \get-post-summary
@notification = @opts.notification
&:before
content "\f10d"
&:after
content "\f10e"
&.like
.text p i
color #FFAC33
&.repost, &.quote
.text p i
color #77B255
&.follow
.text p i
color #53c7ce
&.reply, &.mention
.text p i
color #555
.post-preview
color rgba(0, 0, 0, 0.7)
</style>
<script>
@mixin \get-post-summary
@notification = @opts.notification
</script>
</mk-notification>

View File

@@ -1,98 +1,93 @@
mk-notifications
div.notifications(if={ notifications.length != 0 })
virtual(each={ notification, i in notifications })
mk-notification(notification={ notification })
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 }
p.empty(if={ notifications.length == 0 && !loading })
| ありません!
p.loading(if={ loading })
i.fa.fa-spinner.fa-pulse.fa-fw
| 読み込んでいます
mk-ellipsis
style.
display block
background #fff
> .notifications
margin 0 auto
max-width 500px
> mk-notification
border-bottom solid 1px rgba(0, 0, 0, 0.05)
&:last-child
border-bottom none
> .date
<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
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)
background #fff
span
margin 0 16px
> .notifications
margin 0 auto
max-width 500px
i
margin-right 8px
> mk-notification
border-bottom solid 1px rgba(0, 0, 0, 0.05)
> .empty
margin 0
padding 16px
text-align center
color #aaa
&:last-child
border-bottom none
> .loading
margin 0
padding 16px
text-align center
color #aaa
> .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)
> i
margin-right 4px
span
margin 0 16px
script.
@mixin \api
@mixin \stream
@mixin \get-post-summary
i
margin-right 8px
@notifications = []
@loading = true
> .empty
margin 0
padding 16px
text-align center
color #aaa
@on \mount ~>
@api \i/notifications
.then (notifications) ~>
@notifications = notifications
@loading = false
> .loading
margin 0
padding 16px
text-align center
color #aaa
> i
margin-right 4px
</style>
<script>
@mixin \api
@mixin \stream
@mixin \get-post-summary
@notifications = []
@loading = true
@on \mount ~>
@api \i/notifications
.then (notifications) ~>
@notifications = notifications
@loading = false
@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!
@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>

View File

@@ -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>

View File

@@ -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>ドライブ'
@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 ~>
@Progress.done!
@refs.ui.refs.browser.on \move-root ~>
@on \mount ~>
document.title = 'Misskey Drive'
@ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
# Rewrite URL
history.push-state null null '/i/drive'
@refs.ui.refs.browser.on \begin-load ~>
@Progress.start!
@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 \loaded-mid ~>
@Progress.set 0.5
@refs.ui.refs.browser.on \move (folder) ~>
# Rewrite URL
history.push-state null null '/i/drive/folder/' + folder.id
@refs.ui.refs.browser.on \loaded ~>
@Progress.done!
@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 \move-root ~>
@ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ'
# Rewrite URL
history.push-state null null '/i/drive/file/' + file.id
# Rewrite URL
history.push-state null null '/i/drive'
riot.mount \mk-file-type-icon do
file: file
@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 \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
riot.mount \mk-file-type-icon do
file: file
</script>
</mk-drive-page>

View File

@@ -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
script.
@mode = \signin
> .introduction
max-width 300px
margin 0 auto
color #666
@signup = ~>
@mode = \signup
@update!
> button
display block
margin 16px auto 0 auto
@signin = ~>
> footer
> mk-copyright
margin 0
text-align center
line-height 64px
font-size 10px
color rgba(#000, 0.5)
</style>
<script>
@mode = \signin
@update!
@introduction = ~>
@mode = \introduction
@update!
@signup = ~>
@mode = \signup
@update!
@signin = ~>
@mode = \signin
@update!
@introduction = ~>
@mode = \introduction
@update!
</script>
</mk-entrance>

View File

@@ -1,45 +1,51 @@
mk-entrance-signin
mk-signin
div.divider: span or
button.signup(onclick={ parent.signup }) 新規登録
a.introduction(onclick={ parent.introduction }) Misskeyについて
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
> .divider
padding 16px 0
text-align center
&:after
content ""
<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
position absolute
top 50%
width 100%
height 1px
border-top solid 1px rgba(0, 0, 0, 0.1)
> *
z-index 1
margin 0 auto
padding 0 8px
color rgba(0, 0, 0, 0.5)
background #fdfdfd
max-width 350px
text-align center
> .introduction
display inline-block
margin-top 16px
font-size 12px
color #666
> .signup
padding 16px
width 100%
font-size 1em
color #fff
background $theme-color
border-radius 3px
> .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)
> *
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
</style>
</mk-entrance-signin>

View File

@@ -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>

View File

@@ -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>ホーム'
@Progress.start!
@stream.on \post @on-stream-post
document.add-event-listener \visibilitychange @window-on-visibilitychange, false
@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-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
@on \mount ~>
document.title = 'Misskey'
@ui.trigger \title '<i class="fa fa-home"></i>ホーム'
@Progress.start!
@stream.on \post @on-stream-post
document.add-event-listener \visibilitychange @window-on-visibilitychange, false
@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-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'
</script>
</mk-home-page>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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='')
div.replies
virtual(each={ post in replies })
mk-post-detail-sub(post={ post })
style.
display block
margin 0
padding 0
> .fetching
padding 64px 0
> .main
> .read-more
<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 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
padding 0
&:hover
background #f6f6f6
> .fetching
padding 64px 0
&:active
background #f0f0f0
> .main
&:disabled
color #ccc
> .context
> *
border-bottom 1px solid #eef0f2
> .repost
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
> p
margin 0
padding 16px 32px
.avatar-anchor
display inline-block
.avatar
vertical-align bottom
min-width 28px
min-height 28px
max-width 28px
max-height 28px
margin 0 8px 0 0
border-radius 6px
i
margin-right 4px
.name
font-weight bold
& + article
padding-top 8px
> .reply-to
border-bottom 1px solid #eef0f2
> article
padding 14px 16px 9px 16px
@media (min-width 500px)
padding 28px 32px 18px 32px
&:after
content ""
display block
clear both
&:hover
> .main > footer > button
color #888
> .avatar-anchor
display block
> .avatar
display block
width 54px
height 54px
margin 0
border-radius 8px
vertical-align bottom
@media (min-width 500px)
width 60px
height 60px
> header
position absolute
top 18px
left 80px
width calc(100% - 80px)
@media (min-width 500px)
top 28px
left 108px
width calc(100% - 108px)
> .name
display inline-block
margin 0
color #777
font-size 16px
font-weight bold
text-align left
text-decoration none
&:hover
text-decoration underline
> .username
display block
text-align left
margin 0
color #ccc
> .body
padding 8px 0
> .text
cursor default
> .read-more
display block
margin 0
padding 0
word-wrap break-word
font-size 16px
color #717171
@media (min-width 500px)
font-size 24px
> mk-url-preview
margin-top 8px
> .media
> img
display block
max-width 100%
> .time
font-size 16px
color #c0c0c0
> footer
font-size 1.2em
> button
margin 0 28px 0 0
padding 8px
background transparent
border none
box-shadow none
padding 10px 0
width 100%
font-size 1em
color #ddd
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
&:hover
color #666
background #f6f6f6
> .count
display inline
margin 0 0 0 8px
color #999
&:active
background #f0f0f0
&.liked
color $theme-color
&:disabled
color #ccc
> .reposts-and-likes
display flex
justify-content center
padding 0
margin 16px 0
> .context
> *
border-bottom 1px solid #eef0f2
&:empty
display none
> .repost
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
> .reposts
> .likes
display flex
flex 1 1
padding 0
border-top solid 1px #F2EFEE
> p
margin 0
padding 16px 32px
.avatar-anchor
display inline-block
.avatar
vertical-align bottom
min-width 28px
min-height 28px
max-width 28px
max-height 28px
margin 0 8px 0 0
border-radius 6px
i
margin-right 4px
.name
font-weight bold
& + article
padding-top 8px
> .reply-to
border-bottom 1px solid #eef0f2
> article
padding 14px 16px 9px 16px
@media (min-width 500px)
padding 28px 32px 18px 32px
&:after
content ""
display block
clear both
&:hover
> .main > footer > button
color #888
> .avatar-anchor
display block
> .avatar
display block
width 54px
height 54px
margin 0
border-radius 8px
vertical-align bottom
@media (min-width 500px)
width 60px
height 60px
> header
flex 1 1 80px
max-width 80px
padding 8px 5px 0px 10px
position absolute
top 18px
left 80px
width calc(100% - 80px)
> a
@media (min-width 500px)
top 28px
left 108px
width calc(100% - 108px)
> .name
display inline-block
margin 0
color #777
font-size 16px
font-weight bold
text-align left
text-decoration none
&:hover
text-decoration underline
> .username
display block
font-size 1.5em
line-height 1.4em
text-align left
margin 0
color #ccc
> p
> .body
padding 8px 0
> .text
cursor default
display block
margin 0
font-size 0.7em
line-height 1em
font-weight normal
color #a0a2a5
> .users
display block
flex 1 1
margin 0
padding 10px 10px 10px 5px
list-style none
> .user
display block
float left
margin 4px
padding 0
word-wrap break-word
font-size 16px
color #717171
> .avatar-anchor
display:block
@media (min-width 500px)
font-size 24px
> .avatar
vertical-align bottom
width 24px
height 24px
border-radius 4px
> mk-url-preview
margin-top 8px
> .reposts + .likes
margin-left 16px
> .media
> img
display block
max-width 100%
> .replies
> *
border-top 1px solid #eef0f2
> .time
font-size 16px
color #c0c0c0
script.
@mixin \api
@mixin \text
@mixin \get-post-summary
@mixin \open-post-form
> footer
font-size 1.2em
@fetching = true
@loading-context = false
@content = null
@post = null
> button
margin 0 28px 0 0
padding 8px
background transparent
border none
box-shadow none
font-size 1em
color #ddd
cursor pointer
@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!
&:hover
color #666
if @p.text?
tokens = @analyze @p.text
@refs.text.innerHTML = @compile tokens
> .count
display inline
margin 0 0 0 8px
color #999
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
riot.mount e
&.liked
color $theme-color
# 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
> .reposts-and-likes
display flex
justify-content center
padding 0
margin 16px 0
# Get likes
@api \posts/likes do
post_id: @p.id
limit: 8
.then (likes) ~>
@likes = likes
&:empty
display none
> .reposts
> .likes
display flex
flex 1 1
padding 0
border-top solid 1px #F2EFEE
> header
flex 1 1 80px
max-width 80px
padding 8px 5px 0px 10px
> a
display block
font-size 1.5em
line-height 1.4em
> p
display block
margin 0
font-size 0.7em
line-height 1em
font-weight normal
color #a0a2a5
> .users
display block
flex 1 1
margin 0
padding 10px 10px 10px 5px
list-style none
> .user
display block
float left
margin 4px
padding 0
> .avatar-anchor
display:block
> .avatar
vertical-align bottom
width 24px
height 24px
border-radius 4px
> .reposts + .likes
margin-left 16px
> .replies
> *
border-top 1px solid #eef0f2
</style>
<script>
@mixin \api
@mixin \text
@mixin \get-post-summary
@mixin \open-post-form
@fetching = true
@loading-context = false
@content = null
@post = null
@on \mount ~>
@api \posts/show do
post_id: @opts.post
.then (post) ~>
@post = post
@is-repost = @post.repost?
@p = if @is-repost then @post.repost else @post
@summary = @get-post-summary @p
@trigger \loaded
@fetching = false
@update!
# Get reposts
@api \posts/reposts do
post_id: @p.id
limit: 8
.then (reposts) ~>
@reposts = reposts
if @p.text?
tokens = @analyze @p.text
@refs.text.innerHTML = @compile tokens
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
riot.mount e
# URLをプレビュー
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 likes
@api \posts/likes do
post_id: @p.id
limit: 8
.then (likes) ~>
@likes = likes
@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 = ~>
@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
@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!
@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!
# Get replies
@api \posts/replies do
post_id: @p.id
limit: 8
.then (replies) ~>
@replies = replies
@update!
@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
@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!
@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>

View File

@@ -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
> div
max-width 500px
margin 0 auto
> .cancel
width 50px
line-height 50px
font-size 24px
color #555
> div
position absolute
> header
position fixed
z-index 1000
top 0
right 0
left 0
width 100%
height 50px
background #fff
> .text-count
line-height 50px
color #657786
> div
max-width 500px
margin 0 auto
> .submit
margin 8px
padding 0 16px
line-height 34px
color $theme-color-foreground
background $theme-color
border-radius 4px
> .cancel
width 50px
line-height 50px
font-size 24px
color #555
> div
position absolute
top 0
right 0
> .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
&:disabled
opacity 0.7
> .form
max-width 500px
margin 0 auto
> mk-post-preview
padding 16px
> .attaches
> .files
display block
margin 0
padding 4px
list-style none
&:after
content ""
display block
clear both
> .file
display block
float left
margin 4px
padding 0
cursor move
&:hover > .remove
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
> .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)
> 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)
> mk-uploader
margin 8px 0 0 0
padding 8px
> [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
&:disabled
opacity 0.7
opacity 0.5
> .form
max-width 500px
margin 0 auto
> mk-post-preview
padding 16px
> .attaches
> .files
display block
margin 0
padding 4px
list-style none
&:after
content ""
display block
clear both
> .file
display block
float left
margin 4px
> [ref='upload']
> [ref='drive']
display inline-block
padding 0
cursor move
margin 0
width 48px
height 48px
font-size 20px
color #657786
background transparent
outline none
border none
border-radius 0
box-shadow none
&:hover > .remove
display block
</style>
<script>
@mixin \api
> .img
width 64px
height 64px
background-size cover
background-position center center
@wait = false
@uploadings = []
@files = []
> .remove
display none
position absolute
top -6px
right -6px
width 16px
height 16px
cursor pointer
@on \mount ~>
@refs.uploader.on \uploaded (file) ~>
@add-file file
> .add
display block
float left
margin 4px
padding 0
border dashed 2px rgba($theme-color, 0.2)
cursor pointer
@refs.uploader.on \change-uploads (uploads) ~>
@trigger \change-uploading-files uploads
&:hover
border-color rgba($theme-color, 0.3)
@refs.text.focus!
> i
color rgba($theme-color, 0.4)
@onkeypress = (e) ~>
if (e.char-code == 10 || e.char-code == 13) && e.ctrl-key
@post!
else
return true
> 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
> [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
&: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
script.
@mixin \api
@wait = false
@uploadings = []
@files = []
@on \mount ~>
@refs.uploader.on \uploaded (file) ~>
@add-file file
@refs.uploader.on \change-uploads (uploads) ~>
@trigger \change-uploading-files uploads
@refs.text.focus!
@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>

View File

@@ -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
> article
&:after
content ""
<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
clear both
margin 0
padding 0
font-size 0.9em
background #fff
&:hover
> .main > footer > button
color #888
> article
> .avatar-anchor
display block
float left
margin 0 12px 0 0
&:after
content ""
display block
clear both
> .avatar
display block
width 48px
height 48px
margin 0
border-radius 8px
vertical-align bottom
&:hover
> .main > footer > button
color #888
> .main
float left
width calc(100% - 60px)
> .avatar-anchor
display block
float left
margin 0 12px 0 0
> header
margin-bottom 4px
white-space nowrap
> .avatar
display block
width 48px
height 48px
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% - 60px)
&:hover
text-decoration underline
> header
margin-bottom 4px
white-space nowrap
> .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
> .time
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
> .time
position absolute
top 0
right 0
color #b2b8bb
script.
@post = @opts.post
> .body
> .text
cursor default
margin 0
padding 0
font-size 1.1em
color #717171
</style>
<script>@post = @opts.post</script>
</mk-post-preview>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
> article
padding 16px
&:after
content ""
<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
clear both
margin 0
padding 0
font-size 0.9em
&:hover
> .main > footer > button
color #888
> article
padding 16px
> .avatar-anchor
display block
float left
margin 0 10px 0 0
&:after
content ""
display block
clear both
@media (min-width 500px)
margin-right 16px
&:hover
> .main > footer > button
color #888
> .avatar
display block
width 44px
height 44px
margin 0
border-radius 8px
vertical-align bottom
> .avatar-anchor
display block
float left
margin 0 10px 0 0
@media (min-width 500px)
width 52px
height 52px
@media (min-width 500px)
margin-right 16px
> .main
float left
width calc(100% - 54px)
> .avatar
display block
width 44px
height 44px
margin 0
border-radius 8px
vertical-align bottom
@media (min-width 500px)
width calc(100% - 68px)
@media (min-width 500px)
width 52px
height 52px
> header
margin-bottom 4px
white-space nowrap
> .main
float left
width calc(100% - 54px)
> .name
display inline
margin 0
padding 0
color #607073
font-size 1em
font-weight 700
text-align left
text-decoration none
@media (min-width 500px)
width calc(100% - 68px)
&:hover
text-decoration underline
> header
margin-bottom 4px
white-space nowrap
> .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
script.
@post = @opts.post
> .body
> .text
cursor default
margin 0
padding 0
font-size 1.1em
color #717171
</style>
<script>@post = @opts.post</script>
</mk-timeline-post-sub>

View File

@@ -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
@media (min-width 350px)
font-size 14px
@media (min-width 500px)
font-size 16px
> .repost
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
> p
<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 8px 16px
line-height 28px
padding 0
font-size 12px
@media (min-width 350px)
font-size 14px
@media (min-width 500px)
padding 16px
font-size 16px
.avatar-anchor
display inline-block
> .repost
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
.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 8px
right 16px
font-size 0.9em
line-height 28px
@media (min-width 500px)
top 16px
& + article
padding-top 8px
> .reply-to
background rgba(0, 0, 0, 0.0125)
> mk-post-preview
background transparent
> article
padding 14px 16px 9px 16px
&:after
content ""
display block
clear both
> .avatar-anchor
display block
float left
margin 0 10px 0 0
@media (min-width 500px)
margin-right 16px
> .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
> .main
float left
width calc(100% - 58px)
@media (min-width 500px)
width calc(100% - 74px)
> header
white-space nowrap
@media (min-width 500px)
margin-bottom 2px
> .name
display inline
> p
margin 0
padding 0
color #777
font-size 1em
font-weight 700
text-align left
text-decoration none
padding 8px 16px
line-height 28px
&:hover
text-decoration underline
> .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
> .body
> .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
> .reply
margin-right 8px
color #717171
> .quote
margin-left 4px
font-style oblique
color #a0bf46
> .media
> img
display block
max-width 100%
> .repost
margin 8px 0
> i:first-child
position absolute
top -8px
left -8px
z-index 1
color #c0dac6
font-size 28px
background #fff
> mk-post-preview
@media (min-width 500px)
padding 16px
border dashed 1px #c0dac6
border-radius 8px
> footer
> button
margin 0 28px 0 0
padding 8px
.avatar-anchor
display inline-block
.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 8px
right 16px
font-size 0.9em
line-height 28px
@media (min-width 500px)
top 16px
& + article
padding-top 8px
> .reply-to
background rgba(0, 0, 0, 0.0125)
> mk-post-preview
background transparent
border none
box-shadow none
font-size 1em
color #ddd
cursor pointer
&:hover
color #666
> article
padding 14px 16px 9px 16px
> .count
display inline
margin 0 0 0 8px
color #999
&:after
content ""
display block
clear both
&.liked
color $theme-color
> .avatar-anchor
display block
float left
margin 0 10px 0 0
script.
@mixin \api
@mixin \text
@mixin \get-post-summary
@mixin \open-post-form
@media (min-width 500px)
margin-right 16px
@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
> .avatar
display block
width 48px
height 48px
margin 0
border-radius 6px
vertical-align bottom
@on \mount ~>
if @p.text?
tokens = if @p._highlight?
then @analyze @p._highlight
else @analyze @p.text
@media (min-width 500px)
width 58px
height 58px
border-radius 8px
@refs.text.innerHTML = if @p._highlight?
then @compile tokens, true, false
else @compile tokens
> .main
float left
width calc(100% - 58px)
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
riot.mount e
@media (min-width 500px)
width calc(100% - 74px)
# 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
> header
white-space nowrap
@reply = ~>
@open-post-form do
reply: @p
@media (min-width 500px)
margin-bottom 2px
@repost = ~>
text = window.prompt '「' + @summary + '」をRepost'
if text?
@api \posts/create do
repost_id: @p.id
text: if text == '' then undefined else text
> .name
display inline
margin 0
padding 0
color #777
font-size 1em
font-weight 700
text-align left
text-decoration none
@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!
&:hover
text-decoration underline
> .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
> .body
> .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
> .reply
margin-right 8px
color #717171
> .quote
margin-left 4px
font-style oblique
color #a0bf46
> .media
> img
display block
max-width 100%
> .repost
margin 8px 0
> 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
> 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
> .count
display inline
margin 0 0 0 8px
color #999
&.liked
color $theme-color
</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
@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.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
@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
@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>

View File

@@ -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
style.
display block
background #fff
background-clip content-box
overflow hidden
> .init
padding 64px 0
text-align center
color #999
> i
margin-right 4px
> .empty
margin 0 auto
padding 32px
max-width 400px
text-align center
color #999
> i
<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
margin-bottom 16px
font-size 3em
color #ccc
background #fff
background-clip content-box
overflow hidden
> mk-timeline-post
border-bottom solid 1px #eaeaea
> .init
padding 64px 0
text-align center
color #999
&:last-of-type
border-bottom none
> i
margin-right 4px
> .date
display block
margin 0
line-height 32px
text-align center
font-size 0.9em
color #aaa
background #fdfdfd
border-bottom solid 1px #eaeaea
> .empty
margin 0 auto
padding 32px
max-width 400px
text-align center
color #999
span
margin 0 16px
> i
display block
margin-bottom 16px
font-size 3em
color #ccc
i
margin-right 8px
> mk-timeline-post
border-bottom solid 1px #eaeaea
> footer
text-align center
border-top solid 1px #eaeaea
border-bottom-left-radius 4px
border-bottom-right-radius 4px
&:last-of-type
border-bottom none
> button
margin 0
padding 16px
width 100%
color $theme-color
> .date
display block
margin 0
line-height 32px
text-align center
font-size 0.9em
color #aaa
background #fdfdfd
border-bottom solid 1px #eaeaea
&:disabled
opacity 0.7
span
margin 0 16px
script.
@posts = []
@init = true
@fetching = false
@can-fetch-more = true
i
margin-right 8px
@on \mount ~>
@opts.init.then (posts) ~>
@init = false
@set-posts posts
> footer
text-align center
border-top solid 1px #eaeaea
border-bottom-left-radius 4px
border-bottom-right-radius 4px
@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 + '日'
> button
margin 0
padding 16px
width 100%
color $theme-color
@more = ~>
if @init or @fetching or @posts.length == 0 then return
@fetching = true
@update!
@opts.more!.then (posts) ~>
@fetching = false
@prepend-posts posts
&:disabled
opacity 0.7
@set-posts = (posts) ~>
@posts = posts
@update!
</style>
<script>
@posts = []
@init = true
@fetching = false
@can-fetch-more = true
@prepend-posts = (posts) ~>
posts.for-each (post) ~>
@posts.push post
@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 + '日'
@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!
@add-post = (post) ~>
@posts.unshift post
@update!
@prepend-posts = (posts) ~>
posts.for-each (post) ~>
@posts.push post
@update!
@tail = ~>
@posts[@posts.length - 1]
@add-post = (post) ~>
@posts.unshift post
@update!
@tail = ~>
@posts[@posts.length - 1]
</script>
</mk-timeline>

View File

@@ -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
width 100%
height $height
-webkit-backdrop-filter blur(12px)
backdrop-filter blur(12px)
background-color rgba(#fff, 0.75)
> .content
z-index 1024
width 100%
box-shadow 0 1px 0 rgba(#000, 0.075)
> 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
> .main
color rgba(#000, 0.6)
> i
margin-right 8px
> .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)
> img
display inline-block
vertical-align bottom
width ($height - 16px)
height ($height - 16px)
margin 8px
border-radius 6px
> .content
z-index 1024
> .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)
> 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
transition all 0.2s ease
> i
margin-right 8px
> .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)
> img
display inline-block
vertical-align bottom
width ($height - 16px)
height ($height - 16px)
margin 8px
border-radius 6px
script.
@mixin \ui
@mixin \open-post-form
> .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)
@on \mount ~>
@opts.ready!
> i
transition all 0.2s ease
@ui.one \title (title) ~>
if @refs.title?
@refs.title.innerHTML = title
> .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 = ~>
@open-post-form!
</style>
<script>
@mixin \ui
@mixin \open-post-form
@on \mount ~>
@opts.ready!
@ui.one \title (title) ~>
if @refs.title?
@refs.title.innerHTML = title
@post = ~>
@open-post-form!
</script>
</mk-ui-header>

View File

@@ -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
.body
height 100%
overflow hidden
.content
min-height 100%
.me
display block
margin 0
padding 16px
.avatar
display inline
max-width 64px
border-radius 32px
vertical-align middle
.name
<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
margin 0 16px
position absolute
position fixed
top 0
left 80px
padding 0
width calc(100% - 112px)
left 0
z-index -1
width 240px
color #fff
line-height 96px
overflow hidden
text-overflow ellipsis
white-space nowrap
background #313538
visibility hidden
ul
display block
margin 16px 0
padding 0
list-style none
.body
height 100%
overflow hidden
&:first-child
margin-top 0
.content
min-height 100%
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)
a
.me
display block
padding 0 20px
line-height 3rem
line-height calc(1rem + 30px)
color #eee
text-decoration none
margin 0
padding 16px
> .icon
margin-right 0.5em
.avatar
display inline
max-width 64px
border-radius 32px
vertical-align middle
> .angle
.name
display block
margin 0 16px
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
left 80px
padding 0
width calc(100% - 112px)
color #fff
background rgba(255, 255, 255, 0.1)
border-radius 1em
line-height 96px
overflow hidden
text-overflow ellipsis
white-space nowrap
.about
margin 1em 1em 2em 1em
text-align center
font-size 0.6em
opacity 0.3
ul
display block
margin 16px 0
padding 0
list-style none
a
color #fff
&:first-child
margin-top 0
script.
@mixin \i
@mixin \page
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
@on \mount ~>
@opts.ready!
&:last-child
border-bottom solid 1px rgba(0, 0, 0, 0.2)
@search = ~>
query = window.prompt \検索
if query? and query != ''
@page '/search:' + query
a
display block
padding 0 20px
line-height 3rem
line-height calc(1rem + 30px)
color #eee
text-decoration none
> .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
> .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
a
color #fff
</style>
<script>
@mixin \i
@mixin \page
@on \mount ~>
@opts.ready!
@search = ~>
query = window.prompt \検索
if query? and query != ''
@page '/search:' + query
</script>
</mk-ui-nav>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 }
style.
display block
margin 0
padding 16px
font-size 12px
@media (min-width 350px)
font-size 14px
@media (min-width 500px)
font-size 16px
&:after
content ""
display block
clear both
> .avatar-anchor
display block
float left
margin 0 10px 0 0
@media (min-width 500px)
margin-right 16px
> .avatar
<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
width 48px
height 48px
margin 0
border-radius 6px
vertical-align bottom
padding 16px
font-size 12px
@media (min-width 350px)
font-size 14px
@media (min-width 500px)
width 58px
height 58px
border-radius 8px
font-size 16px
> .main
float left
width calc(100% - 58px)
@media (min-width 500px)
width calc(100% - 74px)
> 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
&:hover
text-decoration underline
> .username
text-align left
margin 0 0 0 8px
color #ccc
> .body
> .bio
cursor default
&:after
content ""
display block
margin 0
padding 0
word-wrap break-word
font-size 1.1em
color #717171
clear both
script.
@user = @opts.user
> .avatar-anchor
display block
float left
margin 0 10px 0 0
@media (min-width 500px)
margin-right 16px
> .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
> .main
float left
width calc(100% - 58px)
@media (min-width 500px)
width calc(100% - 74px)
> 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
&:hover
text-decoration underline
> .username
text-align left
margin 0 0 0 8px
color #ccc
> .body
> .bio
cursor default
display block
margin 0
padding 0
word-wrap break-word
font-size 1.1em
color #717171
</style>
<script>@user = @opts.user</script>
</mk-user-preview>

View File

@@ -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>

View File

@@ -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
> .followed
margin-left 8px
padding 2px 4px
font-size 12px
color #657786
background #f8f8f8
border-radius 4px
> .bio
margin 8px 0
color #333
> .info
margin 8px 0
> p
display inline
margin 0 16px 0 0
color #555
> i
margin-right 4px
> .friends
> a
color #657786
&:first-child
margin-right 16px
> b
margin-right 4px
font-size 16px
color #14171a
> i
font-size 14px
> nav
display flex
justify-content center
margin 0 auto
max-width 600px
border-bottom solid 1px #ddd
> a
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
> .title
margin 8px 0
> h1
margin 0
line-height 22px
font-size 20px
color #222
> .username
display inline-block
line-height 20px
font-size 16px
font-weight bold
color #657786
> .followed
margin-left 8px
padding 2px 4px
font-size 12px
color #657786
background #f8f8f8
border-radius 4px
> .bio
margin 8px 0
color #333
> .info
margin 8px 0
> p
display inline
margin 0 16px 0 0
color #555
> i
margin-right 4px
> .friends
> a
color #657786
&:first-child
margin-right 16px
> b
margin-right 4px
font-size 16px
color #14171a
> i
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>

View File

@@ -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!
@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!
</script>
</mk-users-list>