1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-05-05 08:55:56 +02:00
This commit is contained in:
syuilo
2017-02-20 09:53:57 +09:00
parent 6a4ea35e28
commit 204ad535c0
164 changed files with 2979 additions and 2966 deletions

View File

@@ -9,29 +9,29 @@
</style>
<script>
@on \mount ~>
this.on('mount', () => {
@draw!
@clock = set-interval @draw, 1000ms
this.clock = set-interval @draw, 1000ms
@on \unmount ~>
this.on('unmount', () => {
clear-interval @clock
@draw = ~>
draw() {
now = new Date!
s = now.get-seconds!
m = now.get-minutes!
h = now.get-hours!
vec2 = (x, y) ->
@x = x
@y = y
this.x = x
this.y = y
ctx = @refs.canvas.get-context \2d
canv-w = @refs.canvas.width
canv-h = @refs.canvas.height
ctx = this.refs.canvas.get-context '2d'
canv-w = this.refs.canvas.width
canv-h = this.refs.canvas.height
ctx.clear-rect 0, 0, canv-w, canv-h
# 背景
// 背景
center = (Math.min (canv-w / 2), (canv-h / 2))
line-start = center * 0.90
line-end-short = center * 0.87
@@ -56,12 +56,12 @@
(canv-h / 2) + uv.y * line-end-short
ctx.stroke!
#
//
angle = Math.PI * (m + s / 60) / 30
length = (Math.min canv-w, canv-h) / 2.6
uv = new vec2 (Math.sin angle), (-Math.cos angle)
ctx.begin-path!
ctx.stroke-style = \#ffffff
ctx.stroke-style = '#ffffff'
ctx.line-width = 2
ctx.move-to do
(canv-w / 2) - uv.x * length / 5
@@ -71,12 +71,12 @@
(canv-h / 2) + uv.y * length
ctx.stroke!
#
//
angle = Math.PI * (h % 12 + m / 60) / 6
length = (Math.min canv-w, canv-h) / 4
uv = new vec2 (Math.sin angle), (-Math.cos angle)
ctx.begin-path!
#ctx.stroke-style = \#ffffff
#ctx.stroke-style = '#ffffff'
ctx.stroke-style = CONFIG.theme-color
ctx.line-width = 2
ctx.move-to do
@@ -87,7 +87,7 @@
(canv-h / 2) + uv.y * length
ctx.stroke!
#
//
angle = Math.PI * s / 30
length = (Math.min canv-w, canv-h) / 2.6
uv = new vec2 (Math.sin angle), (-Math.cos angle)

View File

@@ -80,101 +80,101 @@
</style>
<script>
@mixin \api
this.mixin('api');
@q = @opts.q
@textarea = @opts.textarea
@loading = true
@users = []
@select = -1
this.q = this.opts.q
this.textarea = this.opts.textarea
this.loading = true
this.users = []
this.select = -1
@on \mount ~>
@textarea.add-event-listener \keydown @on-keydown
this.on('mount', () => {
@textarea.add-event-listener 'keydown' this.on-keydown
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.add-event-listener \mousedown @mousedown
Array.prototype.for-each.call all, (el) =>
el.add-event-listener 'mousedown' @mousedown
@api \users/search_by_username do
this.api 'users/search_by_username' do
query: @q
limit: 30users
.then (users) ~>
@users = users
@loading = false
@update!
.catch (err) ~>
.then (users) =>
this.users = users
this.loading = false
this.update();
.catch (err) =>
console.error err
@on \unmount ~>
@textarea.remove-event-listener \keydown @on-keydown
this.on('unmount', () => {
@textarea.remove-event-listener 'keydown' this.on-keydown
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.remove-event-listener \mousedown @mousedown
Array.prototype.for-each.call all, (el) =>
el.remove-event-listener 'mousedown' @mousedown
@mousedown = (e) ~>
if (!contains @root, e.target) and (@root != e.target)
mousedown(e) {
if (!contains this.root, e.target) and (this.root != e.target)
@close!
@on-click = (e) ~>
on-click(e) {
@complete e.item
@on-keydown = (e) ~>
on-keydown(e) {
key = e.which
switch (key)
| 10, 13 => # Key[ENTER]
| 10, 13 => // Key[ENTER]
if @select != -1
e.prevent-default!
e.stop-propagation!
@complete @users[@select]
else
@close!
| 27 => # Key[ESC]
| 27 => // Key[ESC]
e.prevent-default!
e.stop-propagation!
@close!
| 38 => # Key[↑]
| 38 => // Key[↑]
if @select != -1
e.prevent-default!
e.stop-propagation!
@select-prev!
else
@close!
| 9, 40 => # Key[TAB] or Key[↓]
| 9, 40 => // Key[TAB] or Key[↓]
e.prevent-default!
e.stop-propagation!
@select-next!
| _ =>
@close!
@select-next = ~>
select-next() {
@select++
if @select >= @users.length
@select = 0
this.select = 0
@apply-select!
@select-prev = ~>
select-prev() {
@select--
if @select < 0
@select = @users.length - 1
this.select = @users.length - 1
@apply-select!
@apply-select = ~>
@refs.users.children.for-each (el) ~>
el.remove-attribute \data-selected
apply-select() {
this.refs.users.children.for-each (el) =>
el.remove-attribute 'data-selected'
@refs.users.children[@select].set-attribute \data-selected \true
@refs.users.children[@select].focus!
this.refs.users.children[@select].set-attribute 'data-selected' \true
this.refs.users.children[@select].focus();
@complete = (user) ~>
@opts.complete user
complete(user) {
this.opts.complete user
@close = ~>
@opts.close!
close() {
this.opts.close!
function contains(parent, child)
node = child.parent-node

View File

@@ -70,58 +70,58 @@
</style>
<script>
@mixin \api
@mixin \is-promise
@mixin \stream
this.mixin('api');
this.mixin('is-promise');
this.mixin('stream');
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
@init = true
@wait = false
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
this.init = true
this.wait = false
@on \mount ~>
@user-promise.then (user) ~>
@user = user
@init = false
@update!
@stream.on \follow @on-stream-follow
@stream.on \unfollow @on-stream-unfollow
this.on('mount', () => {
@user-promise.then (user) =>
this.user = user
this.init = false
this.update();
@stream.on 'follow' this.on-stream-follow
@stream.on 'unfollow' this.on-stream-unfollow
@on \unmount ~>
@stream.off \follow @on-stream-follow
@stream.off \unfollow @on-stream-unfollow
this.on('unmount', () => {
@stream.off 'follow' this.on-stream-follow
@stream.off 'unfollow' this.on-stream-unfollow
@on-stream-follow = (user) ~>
on-stream-follow(user) {
if user.id == @user.id
@user = user
@update!
this.user = user
this.update();
@on-stream-unfollow = (user) ~>
on-stream-unfollow(user) {
if user.id == @user.id
@user = user
@update!
this.user = user
this.update();
@onclick = ~>
@wait = true
onclick() {
this.wait = true
if @user.is_following
@api \following/delete do
this.api 'following/delete' do
user_id: @user.id
.then ~>
.then =>
@user.is_following = false
.catch (err) ->
console.error err
.then ~>
@wait = false
@update!
.then =>
this.wait = false
this.update();
else
@api \following/create do
this.api 'following/create' do
user_id: @user.id
.then ~>
.then =>
@user.is_following = true
.catch (err) ->
console.error err
.then ~>
@wait = false
@update!
.then =>
this.wait = false
this.update();
</script>
</mk-big-follow-button>

View File

@@ -94,39 +94,39 @@
</style>
<script>
@root.add-event-listener \contextmenu (e) ~>
this.root.add-event-listener 'contextmenu' (e) =>
e.prevent-default!
@mousedown = (e) ~>
mousedown(e) {
e.prevent-default!
if (!contains @root, e.target) and (@root != e.target)
if (!contains this.root, e.target) and (this.root != e.target)
@close!
return false
@open = (pos) ~>
open(pos) {
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.add-event-listener \mousedown @mousedown
@root.style.display = \block
@root.style.left = pos.x + \px
@root.style.top = pos.y + \px
Array.prototype.for-each.call all, (el) =>
el.add-event-listener 'mousedown' @mousedown
this.root.style.display = 'block'
this.root.style.left = pos.x + 'px'
this.root.style.top = pos.y + 'px'
Velocity @root, \finish true
Velocity @root, { opacity: 0 } 0ms
Velocity @root, {
Velocity this.root, 'finish' true
Velocity this.root, { opacity: 0 } 0ms
Velocity this.root, {
opacity: 1
} {
queue: false
duration: 100ms
easing: \linear
easing: 'linear'
}
@close = ~>
close() {
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.remove-event-listener \mousedown @mousedown
@trigger \closed
@unmount!
Array.prototype.for-each.call all, (el) =>
el.remove-event-listener 'mousedown' @mousedown
this.trigger('closed');
this.unmount();
function contains(parent, child)
node = child.parent-node

View File

@@ -158,31 +158,31 @@
</style>
<script>
@mixin \cropper
this.mixin('cropper');
@image = @opts.file
@title = @opts.title
@aspect-ratio = @opts.aspect-ratio
@cropper = null
this.image = this.opts.file
this.title = this.opts.title
this.aspect-ratio = this.opts.aspect-ratio
this.cropper = null
@on \mount ~>
@img = @refs.window.refs.img
@cropper = new @Cropper @img, do
this.on('mount', () => {
this.img = this.refs.window.refs.img
this.cropper = new @Cropper @img, do
aspect-ratio: @aspect-ratio
highlight: no
view-mode: 1
@ok = ~>
@cropper.get-cropped-canvas!.to-blob (blob) ~>
@trigger \cropped blob
@refs.window.close!
ok() {
@cropper.get-cropped-canvas!.to-blob (blob) =>
this.trigger 'cropped' blob
this.refs.window.close!
@skip = ~>
@trigger \skiped
@refs.window.close!
skip() {
this.trigger('skiped');
this.refs.window.close!
@cancel = ~>
@trigger \canceled
@refs.window.close!
cancel() {
this.trigger('canceled');
this.refs.window.close!
</script>
</mk-crop-window>

View File

@@ -79,34 +79,34 @@
</style>
<script>
@can-through = if opts.can-through? then opts.can-through else true
@opts.buttons.for-each (button) ~>
button._onclick = ~>
this.can-through = if opts.can-through? then opts.can-through else true
this.opts.buttons.for-each (button) =>
button._onclick = =>
if button.onclick?
button.onclick!
@close!
@on \mount ~>
@refs.header.innerHTML = @opts.title
@refs.body.innerHTML = @opts.text
this.on('mount', () => {
this.refs.header.innerHTML = this.opts.title
this.refs.body.innerHTML = this.opts.text
@refs.bg.style.pointer-events = \auto
Velocity @refs.bg, \finish true
Velocity @refs.bg, {
this.refs.bg.style.pointer-events = 'auto'
Velocity this.refs.bg, 'finish' true
Velocity this.refs.bg, {
opacity: 1
} {
queue: false
duration: 100ms
easing: \linear
easing: 'linear'
}
Velocity @refs.main, {
Velocity this.refs.main, {
opacity: 0
scale: 1.2
} {
duration: 0
}
Velocity @refs.main, {
Velocity this.refs.main, {
opacity: 1
scale: 1
} {
@@ -114,34 +114,34 @@
easing: [ 0, 0.5, 0.5, 1 ]
}
@close = ~>
@refs.bg.style.pointer-events = \none
Velocity @refs.bg, \finish true
Velocity @refs.bg, {
close() {
this.refs.bg.style.pointer-events = 'none'
Velocity this.refs.bg, 'finish' true
Velocity this.refs.bg, {
opacity: 0
} {
queue: false
duration: 300ms
easing: \linear
easing: 'linear'
}
@refs.main.style.pointer-events = \none
Velocity @refs.main, \finish true
Velocity @refs.main, {
this.refs.main.style.pointer-events = 'none'
Velocity this.refs.main, 'finish' true
Velocity this.refs.main, {
opacity: 0
scale: 0.8
} {
queue: false
duration: 300ms
easing: [ 0.5, -0.5, 1, 0.5 ]
complete: ~>
@unmount!
complete: =>
this.unmount();
}
@bg-click = ~>
bg-click() {
if @can-through
if @opts.on-through?
@opts.on-through!
if this.opts.on-through?
this.opts.on-through!
@close!
</script>
</mk-dialog>

View File

@@ -47,21 +47,21 @@
</style>
<script>
@mixin \api
@mixin \i
this.mixin('api');
this.mixin('i');
@close = (e) ~>
close(e) {
e.prevent-default!
e.stop-propagation!
@I.data.no_donation = true
@I.update!
@api \i/appdata/set do
this.api 'i/appdata/set' do
data: JSON.stringify do
no_donation: @I.data.no_donation
@unmount!
this.unmount();
@parent.parent.set-root-layout!
this.parent.parent.set-root-layout!
</script>
</mk-donation>

View File

@@ -13,26 +13,26 @@
</ul>
</mk-contextmenu>
<script>
@browser = @opts.browser
this.browser = this.opts.browser
@on \mount ~>
@refs.ctx.on \closed ~>
@trigger \closed
@unmount!
this.on('mount', () => {
this.refs.ctx.on('closed', () => {
this.trigger('closed');
this.unmount();
@open = (pos) ~>
@refs.ctx.open pos
open(pos) {
this.refs.ctx.open pos
@create-folder = ~>
create-folder() {
@browser.create-folder!
@refs.ctx.close!
this.refs.ctx.close!
@upload = ~>
upload() {
@browser.select-local-file!
@refs.ctx.close!
this.refs.ctx.close!
@url-upload = ~>
url-upload() {
@browser.url-upload!
@refs.ctx.close!
this.refs.ctx.close!
</script>
</mk-drive-browser-base-contextmenu>

View File

@@ -28,19 +28,19 @@
</style>
<script>
@mixin \api
this.mixin('api');
@folder = if @opts.folder? then @opts.folder else null
this.folder = if this.opts.folder? then this.opts.folder else null
@on \mount ~>
@refs.window.on \closed ~>
@unmount!
this.on('mount', () => {
this.refs.window.on('closed', () => {
this.unmount();
@api \drive .then (info) ~>
this.api 'drive' .then (info) =>
@update do
usage: info.usage / info.capacity * 100
@close = ~>
@refs.window.close!
close() {
this.refs.window.close!
</script>
</mk-drive-browser-window>

View File

@@ -238,211 +238,211 @@
</style>
<script>
@mixin \api
@mixin \dialog
@mixin \input-dialog
@mixin \stream
this.mixin('api');
this.mixin('dialog');
this.mixin('input-dialog');
this.mixin('stream');
@files = []
@folders = []
@hierarchy-folders = []
this.files = []
this.folders = []
this.hierarchy-folders = []
@uploads = []
this.uploads = []
# 現在の階層(フォルダ)
# * null でルートを表す
@folder = null
// 現在の階層(フォルダ)
// * null でルートを表す
this.folder = null
@multiple = if @opts.multiple? then @opts.multiple else false
this.multiple = if this.opts.multiple? then this.opts.multiple else false
# ドロップされようとしているか
@draghover = false
// ドロップされようとしているか
this.draghover = false
# 自信の所有するアイテムがドラッグをスタートさせたか
# (自分自身の階層にドロップできないようにするためのフラグ)
@is-drag-source = false
// 自信の所有するアイテムがドラッグをスタートさせたか
// (自分自身の階層にドロップできないようにするためのフラグ)
this.is-drag-source = false
@on \mount ~>
@refs.uploader.on \uploaded (file) ~>
this.on('mount', () => {
this.refs.uploader.on('uploaded', (file) => {
@add-file file, true
@refs.uploader.on \change-uploads (uploads) ~>
@uploads = uploads
@update!
this.refs.uploader.on('change-uploads', (uploads) => {
this.uploads = uploads
this.update();
@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
@stream.on 'drive_file_created' this.on-stream-drive-file-created
@stream.on 'drive_file_updated' this.on-stream-drive-file-updated
@stream.on 'drive_folder_created' this.on-stream-drive-folder-created
@stream.on 'drive_folder_updated' this.on-stream-drive-folder-updated
# Riotのバグでnullを渡しても""になる
# https://github.com/riot/riot/issues/2080
#if @opts.folder?
if @opts.folder? and @opts.folder != ''
@move @opts.folder
// Riotのバグでnullを渡しても""になる
// https://github.com/riot/riot/issues/2080
#if this.opts.folder?
if this.opts.folder? and this.opts.folder != ''
@move this.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
this.on('unmount', () => {
@stream.off 'drive_file_created' this.on-stream-drive-file-created
@stream.off 'drive_file_updated' this.on-stream-drive-file-updated
@stream.off 'drive_folder_created' this.on-stream-drive-folder-created
@stream.off 'drive_folder_updated' this.on-stream-drive-folder-updated
@on-stream-drive-file-created = (file) ~>
on-stream-drive-file-created(file) {
@add-file file, true
@on-stream-drive-file-updated = (file) ~>
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-created = (folder) ~>
on-stream-drive-folder-created(folder) {
@add-folder folder, true
@on-stream-drive-folder-updated = (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
@onmousedown = (e) ~>
if (contains @refs.folders-container, e.target) or (contains @refs.files-container, e.target)
onmousedown(e) {
if (contains this.refs.folders-container, e.target) or (contains this.refs.files-container, e.target)
return true
rect = @refs.main.get-bounding-client-rect!
rect = this.refs.main.get-bounding-client-rect!
left = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset
top = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset
left = e.page-x + this.refs.main.scroll-left - rect.left - window.page-x-offset
top = e.page-y + this.refs.main.scroll-top - rect.top - window.page-y-offset
move = (e) ~>
@refs.selection.style.display = \block
move = (e) =>
this.refs.selection.style.display = 'block'
cursor-x = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset
cursor-y = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset
cursor-x = e.page-x + this.refs.main.scroll-left - rect.left - window.page-x-offset
cursor-y = e.page-y + this.refs.main.scroll-top - rect.top - window.page-y-offset
w = cursor-x - left
h = cursor-y - top
if w > 0
@refs.selection.style.width = w + \px
@refs.selection.style.left = left + \px
this.refs.selection.style.width = w + 'px'
this.refs.selection.style.left = left + 'px'
else
@refs.selection.style.width = -w + \px
@refs.selection.style.left = cursor-x + \px
this.refs.selection.style.width = -w + 'px'
this.refs.selection.style.left = cursor-x + 'px'
if h > 0
@refs.selection.style.height = h + \px
@refs.selection.style.top = top + \px
this.refs.selection.style.height = h + 'px'
this.refs.selection.style.top = top + 'px'
else
@refs.selection.style.height = -h + \px
@refs.selection.style.top = cursor-y + \px
this.refs.selection.style.height = -h + 'px'
this.refs.selection.style.top = cursor-y + 'px'
up = (e) ~>
document.document-element.remove-event-listener \mousemove move
document.document-element.remove-event-listener \mouseup up
up = (e) =>
document.document-element.remove-event-listener 'mousemove' move
document.document-element.remove-event-listener 'mouseup' up
@refs.selection.style.display = \none
this.refs.selection.style.display = 'none'
document.document-element.add-event-listener \mousemove move
document.document-element.add-event-listener \mouseup up
document.document-element.add-event-listener 'mousemove' move
document.document-element.add-event-listener 'mouseup' up
@path-oncontextmenu = (e) ~>
path-oncontextmenu(e) {
e.prevent-default!
e.stop-immediate-propagation!
return false
@ondragover = (e) ~>
ondragover(e) {
e.prevent-default!
e.stop-propagation!
# ドラッグ元が自分自身の所有するアイテムかどうか
// ドラッグ元が自分自身の所有するアイテムかどうか
if !@is-drag-source
# ドラッグされてきたものがファイルだったら
if e.data-transfer.effect-allowed == \all
e.data-transfer.drop-effect = \copy
// ドラッグされてきたものがファイルだったら
if e.data-transfer.effect-allowed == 'all'
e.data-transfer.drop-effect = 'copy'
else
e.data-transfer.drop-effect = \move
@draghover = true
e.data-transfer.drop-effect = 'move'
this.draghover = true
else
# 自分自身にはドロップさせない
e.data-transfer.drop-effect = \none
// 自分自身にはドロップさせない
e.data-transfer.drop-effect = 'none'
return false
@ondragenter = (e) ~>
ondragenter(e) {
e.prevent-default!
if !@is-drag-source
@draghover = true
this.draghover = true
@ondragleave = (e) ~>
@draghover = false
ondragleave(e) {
this.draghover = false
@ondrop = (e) ~>
ondrop(e) {
e.prevent-default!
e.stop-propagation!
@draghover = false
this.draghover = false
# ドロップされてきたものがファイルだったら
// ドロップされてきたものがファイルだったら
if e.data-transfer.files.length > 0
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
Array.prototype.for-each.call e.data-transfer.files, (file) =>
@upload file, @folder
return false
# データ取得
// データ取得
data = e.data-transfer.get-data 'text'
if !data?
return false
# パース
// パース
obj = JSON.parse data
# (ドライブの)ファイルだったら
if obj.type == \file
// (ドライブの)ファイルだったら
if obj.type == 'file'
file = obj.id
if (@files.some (f) ~> f.id == file)
if (@files.some (f) => f.id == file)
return false
@remove-file file
@api \drive/files/update do
this.api 'drive/files/update' do
file_id: file
folder_id: if @folder? then @folder.id else null
.then ~>
# something
.catch (err, text-status) ~>
.then =>
// something
.catch (err, text-status) =>
console.error err
# (ドライブの)フォルダーだったら
else if obj.type == \folder
// (ドライブの)フォルダーだったら
else if obj.type == 'folder'
folder = obj.id
# 移動先が自分自身ならreject
// 移動先が自分自身ならreject
if @folder? and folder == @folder.id
return false
if (@folders.some (f) ~> f.id == folder)
if (@folders.some (f) => f.id == folder)
return false
@remove-folder folder
@api \drive/folders/update do
this.api 'drive/folders/update' do
folder_id: folder
parent_id: if @folder? then @folder.id else null
.then ~>
# something
.catch (err) ~>
.then =>
// something
.catch (err) =>
if err == 'detected-circular-definition'
@dialog do
'<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
'移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
[
text: \OK
text: 'OK'
]
return false
@oncontextmenu = (e) ~>
oncontextmenu(e) {
e.prevent-default!
e.stop-immediate-propagation!
ctx = document.body.append-child document.create-element \mk-drive-browser-base-contextmenu
ctx = document.body.appendChild document.createElement 'mk-drive-browser-base-contextmenu'
ctx = riot.mount ctx, do
browser: @
ctx = ctx.0
@@ -452,17 +452,17 @@
return false
@select-local-file = ~>
@refs.file-input.click!
select-local-file() {
this.refs.file-input.click!
@url-upload = ~>
url-upload() {
url <~ @input-dialog do
'URLアップロード'
'アップロードしたいファイルのURL'
null
if url? and url != ''
@api \drive/files/upload_from_url do
this.api 'drive/files/upload_from_url' do
url: url
folder_id: if @folder? then @folder.id else undefined
@@ -470,61 +470,61 @@
'<i class="fa fa-check"></i>アップロードをリクエストしました'
'アップロードが完了するまで時間がかかる場合があります。'
[
text: \OK
text: 'OK'
]
@create-folder = ~>
create-folder() {
name <~ @input-dialog do
'フォルダー作成'
'フォルダー名'
null
@api \drive/folders/create do
this.api 'drive/folders/create' do
name: name
folder_id: if @folder? then @folder.id else undefined
.then (folder) ~>
.then (folder) =>
@add-folder folder, true
@update!
.catch (err) ~>
this.update();
.catch (err) =>
console.error err
@change-file-input = ~>
files = @refs.file-input.files
change-file-input() {
files = this.refs.file-input.files
for i from 0 to files.length - 1
file = files.item i
@upload file, @folder
@upload = (file, folder) ~>
if folder? and typeof folder == \object
upload(file, folder) {
if folder? and typeof folder == 'object'
folder = folder.id
@refs.uploader.upload file, folder
this.refs.uploader.upload file, folder
@get-selection = ~>
get-selection() {
@files.filter (file) -> file._selected
@new-window = (folder-id) ~>
browser = document.body.append-child document.create-element \mk-drive-browser-window
new-window(folder-id) {
browser = document.body.appendChild document.createElement 'mk-drive-browser-window'
riot.mount browser, do
folder: folder-id
@move = (target-folder) ~>
if target-folder? and typeof target-folder == \object
move(target-folder) {
if target-folder? and typeof target-folder == 'object'
target-folder = target-folder.id
if target-folder == null
@go-root!
return
@loading = true
@update!
this.loading = true
this.update();
@api \drive/folders/show do
this.api 'drive/folders/show' do
folder_id: target-folder
.then (folder) ~>
@folder = folder
@hierarchy-folders = []
.then (folder) =>
this.folder = folder
this.hierarchy-folders = []
x = (f) ~>
x = (f) =>
@hierarchy-folders.unshift f
if f.parent?
x f.parent
@@ -532,20 +532,20 @@
if folder.parent?
x folder.parent
@update!
this.update();
@load!
.catch (err, text-status) ->
console.error err
@add-folder = (folder, unshift = false) ~>
add-folder(folder, unshift = false) {
current = if @folder? then @folder.id else null
if current != folder.parent_id
return
if (@folders.some (f) ~> f.id == folder.id)
if (@folders.some (f) => f.id == folder.id)
exist = (@folders.map (f) -> f.id).index-of folder.id
@folders[exist] = folder
@update!
this.update();
return
if unshift
@@ -553,17 +553,17 @@
else
@folders.push folder
@update!
this.update();
@add-file = (file, unshift = false) ~>
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)
if (@files.some (f) => f.id == file.id)
exist = (@files.map (f) -> f.id).index-of file.id
@files[exist] = file
@update!
this.update();
return
if unshift
@@ -571,34 +571,34 @@
else
@files.push file
@update!
this.update();
@remove-folder = (folder) ~>
if typeof folder == \object
remove-folder(folder) {
if typeof folder == 'object'
folder = folder.id
@folders = @folders.filter (f) -> f.id != folder
@update!
this.folders = @folders.filter (f) -> f.id != folder
this.update();
@remove-file = (file) ~>
if typeof file == \object
remove-file(file) {
if typeof file == 'object'
file = file.id
@files = @files.filter (f) -> f.id != file
@update!
this.files = @files.filter (f) -> f.id != file
this.update();
@go-root = ~>
go-root() {
if @folder != null
@folder = null
@hierarchy-folders = []
@update!
this.folder = null
this.hierarchy-folders = []
this.update();
@load!
@load = ~>
@folders = []
@files = []
@more-folders = false
@more-files = false
@loading = true
@update!
load() {
this.folders = []
this.files = []
this.more-folders = false
this.more-files = false
this.loading = true
this.update();
load-folders = null
load-files = null
@@ -606,41 +606,41 @@
folders-max = 30
files-max = 30
# フォルダ一覧取得
@api \drive/folders do
// フォルダ一覧取得
this.api 'drive/folders' do
folder_id: if @folder? then @folder.id else null
limit: folders-max + 1
.then (folders) ~>
.then (folders) =>
if folders.length == folders-max + 1
@more-folders = true
this.more-folders = true
folders.pop!
load-folders := folders
complete!
.catch (err, text-status) ~>
.catch (err, text-status) =>
console.error err
# ファイル一覧取得
@api \drive/files do
// ファイル一覧取得
this.api 'drive/files' do
folder_id: if @folder? then @folder.id else null
limit: files-max + 1
.then (files) ~>
.then (files) =>
if files.length == files-max + 1
@more-files = true
this.more-files = true
files.pop!
load-files := files
complete!
.catch (err, text-status) ~>
.catch (err, text-status) =>
console.error err
flag = false
complete = ~>
complete = =>
if flag
load-folders.for-each (folder) ~>
load-folders.for-each (folder) =>
@add-folder folder
load-files.for-each (file) ~>
load-files.for-each (file) =>
@add-file file
@loading = false
@update!
this.loading = false
this.update();
else
flag := true

View File

@@ -38,60 +38,60 @@
</ul>
</mk-contextmenu>
<script>
@mixin \api
@mixin \i
@mixin \update-avatar
@mixin \update-banner
@mixin \update-wallpaper
@mixin \input-dialog
@mixin \NotImplementedException
this.mixin('api');
this.mixin('i');
this.mixin('update-avatar');
this.mixin('update-banner');
this.mixin('update-wallpaper');
this.mixin('input-dialog');
this.mixin('NotImplementedException');
@browser = @opts.browser
@file = @opts.file
this.browser = this.opts.browser
this.file = this.opts.file
@on \mount ~>
@refs.ctx.on \closed ~>
@trigger \closed
@unmount!
this.on('mount', () => {
this.refs.ctx.on('closed', () => {
this.trigger('closed');
this.unmount();
@open = (pos) ~>
@refs.ctx.open pos
open(pos) {
this.refs.ctx.open pos
@rename = ~>
@refs.ctx.close!
rename() {
this.refs.ctx.close!
name <~ @input-dialog do
'ファイル名の変更'
'新しいファイル名を入力してください'
@file.name
@api \drive/files/update do
this.api 'drive/files/update' do
file_id: @file.id
name: name
.then ~>
# something
.catch (err) ~>
.then =>
// something
.catch (err) =>
console.error err
@copy-url = ~>
copy-url() {
@NotImplementedException!
@download = ~>
@refs.ctx.close!
download() {
this.refs.ctx.close!
@set-avatar = ~>
@refs.ctx.close!
set-avatar() {
this.refs.ctx.close!
@update-avatar @I, null, @file
@set-banner = ~>
@refs.ctx.close!
set-banner() {
this.refs.ctx.close!
@update-banner @I, null, @file
@set-wallpaper = ~>
@refs.ctx.close!
set-wallpaper() {
this.refs.ctx.close!
@update-wallpaper @I, null, @file
@add-app = ~>
add-app() {
@NotImplementedException!
</script>
</mk-drive-browser-file-contextmenu>

View File

@@ -144,40 +144,40 @@
</style>
<script>
@bytes-to-size = require '../../../common/scripts/bytes-to-size.js'
this.bytes-to-size = require('../../../common/scripts/bytes-to-size.js');
@mixin \i
this.mixin('i');
@file = @opts.file
@browser = @parent
this.file = this.opts.file
this.browser = this.parent
@title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
this.title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
@is-contextmenu-showing = false
this.is-contextmenu-showing = false
@onclick = ~>
onclick() {
if @browser.multiple
if @file._selected?
@file._selected = !@file._selected
else
@file._selected = true
@browser.trigger \change-selection @browser.get-selection!
@browser.trigger 'change-selection' @browser.get-selection!
else
if @file._selected
@browser.trigger \selected @file
@browser.trigger 'selected' @file
else
@browser.files.for-each (file) ~>
@browser.files.for-each (file) =>
file._selected = false
@file._selected = true
@browser.trigger \change-selection @file
@browser.trigger 'change-selection' @file
@oncontextmenu = (e) ~>
oncontextmenu(e) {
e.prevent-default!
e.stop-immediate-propagation!
@is-contextmenu-showing = true
@update!
ctx = document.body.append-child document.create-element \mk-drive-browser-file-contextmenu
this.is-contextmenu-showing = true
this.update();
ctx = document.body.appendChild document.createElement 'mk-drive-browser-file-contextmenu'
ctx = riot.mount ctx, do
browser: @browser
file: @file
@@ -185,25 +185,25 @@
ctx.open do
x: e.page-x - window.page-x-offset
y: e.page-y - window.page-y-offset
ctx.on \closed ~>
@is-contextmenu-showing = false
@update!
ctx.on('closed', () => {
this.is-contextmenu-showing = false
this.update();
return false
@ondragstart = (e) ~>
e.data-transfer.effect-allowed = \move
ondragstart(e) {
e.data-transfer.effect-allowed = 'move'
e.data-transfer.set-data 'text' JSON.stringify do
type: \file
type: 'file'
id: @file.id
file: @file
@is-dragging = true
this.is-dragging = true
# 親ブラウザに対して、ドラッグが開始されたフラグを立てる
# (=あなたの子供が、ドラッグを開始しましたよ)
// 親ブラウザに対して、ドラッグが開始されたフラグを立てる
// (=あなたの子供が、ドラッグを開始しましたよ)
@browser.is-drag-source = true
@ondragend = (e) ~>
@is-dragging = false
ondragend(e) {
this.is-dragging = false
@browser.is-drag-source = false
</script>
</mk-drive-browser-file>

View File

@@ -18,49 +18,49 @@
</ul>
</mk-contextmenu>
<script>
@mixin \api
@mixin \input-dialog
this.mixin('api');
this.mixin('input-dialog');
@browser = @opts.browser
@folder = @opts.folder
this.browser = this.opts.browser
this.folder = this.opts.folder
@open = (pos) ~>
@refs.ctx.open pos
open(pos) {
this.refs.ctx.open pos
@refs.ctx.on \closed ~>
@trigger \closed
@unmount!
this.refs.ctx.on('closed', () => {
this.trigger('closed');
this.unmount();
@move = ~>
move() {
@browser.move @folder.id
@refs.ctx.close!
this.refs.ctx.close!
@new-window = ~>
new-window() {
@browser.new-window @folder.id
@refs.ctx.close!
this.refs.ctx.close!
@create-folder = ~>
create-folder() {
@browser.create-folder!
@refs.ctx.close!
this.refs.ctx.close!
@upload = ~>
upload() {
@browser.select-lcoal-file!
@refs.ctx.close!
this.refs.ctx.close!
@rename = ~>
@refs.ctx.close!
rename() {
this.refs.ctx.close!
name <~ @input-dialog do
'フォルダ名の変更'
'新しいフォルダ名を入力してください'
@folder.name
@api \drive/folders/update do
this.api 'drive/folders/update' do
folder_id: @folder.id
name: name
.then ~>
# something
.catch (err) ~>
.then =>
// something
.catch (err) =>
console.error err
</script>
</mk-drive-browser-folder-contextmenu>

View File

@@ -50,124 +50,124 @@
</style>
<script>
@mixin \api
@mixin \dialog
this.mixin('api');
this.mixin('dialog');
@folder = @opts.folder
@browser = @parent
this.folder = this.opts.folder
this.browser = this.parent
@title = @folder.name
@hover = false
@draghover = false
@is-contextmenu-showing = false
this.title = @folder.name
this.hover = false
this.draghover = false
this.is-contextmenu-showing = false
@onclick = ~>
onclick() {
@browser.move @folder
@onmouseover = ~>
@hover = true
onmouseover() {
this.hover = true
@onmouseout = ~>
@hover = false
onmouseout() {
this.hover = false
@ondragover = (e) ~>
ondragover(e) {
e.prevent-default!
e.stop-propagation!
# 自分自身がドラッグされていない場合
// 自分自身がドラッグされていない場合
if !@is-dragging
# ドラッグされてきたものがファイルだったら
if e.data-transfer.effect-allowed == \all
e.data-transfer.drop-effect = \copy
// ドラッグされてきたものがファイルだったら
if e.data-transfer.effect-allowed == 'all'
e.data-transfer.drop-effect = 'copy'
else
e.data-transfer.drop-effect = \move
e.data-transfer.drop-effect = 'move'
else
# 自分自身にはドロップさせない
e.data-transfer.drop-effect = \none
// 自分自身にはドロップさせない
e.data-transfer.drop-effect = 'none'
return false
@ondragenter = ~>
ondragenter() {
if !@is-dragging
@draghover = true
this.draghover = true
@ondragleave = ~>
@draghover = false
ondragleave() {
this.draghover = false
@ondrop = (e) ~>
ondrop(e) {
e.stop-propagation!
@draghover = false
this.draghover = false
# ファイルだったら
// ファイルだったら
if e.data-transfer.files.length > 0
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
Array.prototype.for-each.call e.data-transfer.files, (file) =>
@browser.upload file, @folder
return false
# データ取得
// データ取得
data = e.data-transfer.get-data 'text'
if !data?
return false
# パース
// パース
obj = JSON.parse data
# (ドライブの)ファイルだったら
if obj.type == \file
// (ドライブの)ファイルだったら
if obj.type == 'file'
file = obj.id
@browser.remove-file file
@api \drive/files/update do
this.api 'drive/files/update' do
file_id: file
folder_id: @folder.id
.then ~>
# something
.catch (err, text-status) ~>
.then =>
// something
.catch (err, text-status) =>
console.error err
# (ドライブの)フォルダーだったら
else if obj.type == \folder
// (ドライブの)フォルダーだったら
else if obj.type == 'folder'
folder = obj.id
# 移動先が自分自身ならreject
// 移動先が自分自身ならreject
if folder == @folder.id
return false
@browser.remove-folder folder
@api \drive/folders/update do
this.api 'drive/folders/update' do
folder_id: folder
parent_id: @folder.id
.then ~>
# something
.catch (err) ~>
.then =>
// something
.catch (err) =>
if err == 'detected-circular-definition'
@dialog do
'<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
'移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
[
text: \OK
text: 'OK'
]
return false
@ondragstart = (e) ~>
e.data-transfer.effect-allowed = \move
ondragstart(e) {
e.data-transfer.effect-allowed = 'move'
e.data-transfer.set-data 'text' JSON.stringify do
type: \folder
type: 'folder'
id: @folder.id
@is-dragging = true
this.is-dragging = true
# 親ブラウザに対して、ドラッグが開始されたフラグを立てる
# (=あなたの子供が、ドラッグを開始しましたよ)
// 親ブラウザに対して、ドラッグが開始されたフラグを立てる
// (=あなたの子供が、ドラッグを開始しましたよ)
@browser.is-drag-source = true
@ondragend = (e) ~>
@is-dragging = false
ondragend(e) {
this.is-dragging = false
@browser.is-drag-source = false
@oncontextmenu = (e) ~>
oncontextmenu(e) {
e.prevent-default!
e.stop-immediate-propagation!
@is-contextmenu-showing = true
@update!
ctx = document.body.append-child document.create-element \mk-drive-browser-folder-contextmenu
this.is-contextmenu-showing = true
this.update();
ctx = document.body.appendChild document.createElement 'mk-drive-browser-folder-contextmenu'
ctx = riot.mount ctx, do
browser: @browser
folder: @folder
@@ -175,9 +175,9 @@
ctx.open do
x: e.page-x - window.page-x-offset
y: e.page-y - window.page-y-offset
ctx.on \closed ~>
@is-contextmenu-showing = false
@update!
ctx.on('closed', () => {
this.is-contextmenu-showing = false
this.update();
return false
</script>

View File

@@ -6,90 +6,90 @@
</style>
<script>
@mixin \api
this.mixin('api');
# Riotのバグでnullを渡しても""になる
# https://github.com/riot/riot/issues/2080
#@folder = @opts.folder
@folder = if @opts.folder? and @opts.folder != '' then @opts.folder else null
@browser = @parent
// Riotのバグでnullを渡しても""になる
// https://github.com/riot/riot/issues/2080
#this.folder = this.opts.folder
this.folder = if this.opts.folder? and this.opts.folder != '' then this.opts.folder else null
this.browser = this.parent
@hover = false
this.hover = false
@onclick = ~>
onclick() {
@browser.move @folder
@onmouseover = ~>
@hover = true
onmouseover() {
this.hover = true
@onmouseout = ~>
@hover = false
onmouseout() {
this.hover = false
@ondragover = (e) ~>
ondragover(e) {
e.prevent-default!
e.stop-propagation!
# このフォルダがルートかつカレントディレクトリならドロップ禁止
// このフォルダがルートかつカレントディレクトリならドロップ禁止
if @folder == null and @browser.folder == null
e.data-transfer.drop-effect = \none
# ドラッグされてきたものがファイルだったら
else if e.data-transfer.effect-allowed == \all
e.data-transfer.drop-effect = \copy
e.data-transfer.drop-effect = 'none'
// ドラッグされてきたものがファイルだったら
else if e.data-transfer.effect-allowed == 'all'
e.data-transfer.drop-effect = 'copy'
else
e.data-transfer.drop-effect = \move
e.data-transfer.drop-effect = 'move'
return false
@ondragenter = ~>
ondragenter() {
if @folder != null or @browser.folder != null
@draghover = true
this.draghover = true
@ondragleave = ~>
ondragleave() {
if @folder != null or @browser.folder != null
@draghover = false
this.draghover = false
@ondrop = (e) ~>
ondrop(e) {
e.stop-propagation!
@draghover = false
this.draghover = false
# ファイルだったら
// ファイルだったら
if e.data-transfer.files.length > 0
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
Array.prototype.for-each.call e.data-transfer.files, (file) =>
@browser.upload file, @folder
return false
# データ取得
// データ取得
data = e.data-transfer.get-data 'text'
if !data?
return false
# パース
// パース
obj = JSON.parse data
# (ドライブの)ファイルだったら
if obj.type == \file
// (ドライブの)ファイルだったら
if obj.type == 'file'
file = obj.id
@browser.remove-file file
@api \drive/files/update do
this.api 'drive/files/update' do
file_id: file
folder_id: if @folder? then @folder.id else null
.then ~>
# something
.catch (err, text-status) ~>
.then =>
// something
.catch (err, text-status) =>
console.error err
# (ドライブの)フォルダーだったら
else if obj.type == \folder
// (ドライブの)フォルダーだったら
else if obj.type == 'folder'
folder = obj.id
# 移動先が自分自身ならreject
// 移動先が自分自身ならreject
if @folder? and folder == @folder.id
return false
@browser.remove-folder folder
@api \drive/folders/update do
this.api 'drive/folders/update' do
folder_id: folder
parent_id: if @folder? then @folder.id else null
.then ~>
# something
.catch (err, text-status) ~>
.then =>
// something
.catch (err, text-status) =>
console.error err
return false

View File

@@ -67,58 +67,58 @@
</style>
<script>
@mixin \api
@mixin \is-promise
@mixin \stream
this.mixin('api');
this.mixin('is-promise');
this.mixin('stream');
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
@init = true
@wait = false
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
this.init = true
this.wait = false
@on \mount ~>
@user-promise.then (user) ~>
@user = user
@init = false
@update!
@stream.on \follow @on-stream-follow
@stream.on \unfollow @on-stream-unfollow
this.on('mount', () => {
@user-promise.then (user) =>
this.user = user
this.init = false
this.update();
@stream.on 'follow' this.on-stream-follow
@stream.on 'unfollow' this.on-stream-unfollow
@on \unmount ~>
@stream.off \follow @on-stream-follow
@stream.off \unfollow @on-stream-unfollow
this.on('unmount', () => {
@stream.off 'follow' this.on-stream-follow
@stream.off 'unfollow' this.on-stream-unfollow
@on-stream-follow = (user) ~>
on-stream-follow(user) {
if user.id == @user.id
@user = user
@update!
this.user = user
this.update();
@on-stream-unfollow = (user) ~>
on-stream-unfollow(user) {
if user.id == @user.id
@user = user
@update!
this.user = user
this.update();
@onclick = ~>
@wait = true
onclick() {
this.wait = true
if @user.is_following
@api \following/delete do
this.api 'following/delete' do
user_id: @user.id
.then ~>
.then =>
@user.is_following = false
.catch (err) ->
console.error err
.then ~>
@wait = false
@update!
.then =>
this.wait = false
this.update();
else
@api \following/create do
this.api 'following/create' do
user_id: @user.id
.then ~>
.then =>
@user.is_following = true
.catch (err) ->
console.error err
.then ~>
@wait = false
@update!
.then =>
this.wait = false
this.update();
</script>
</mk-follow-button>

View File

@@ -123,41 +123,41 @@
</style>
<script>
@mixin \api
@mixin \user-preview
this.mixin('api');
this.mixin('user-preview');
@users = null
@loading = true
this.users = null
this.loading = true
@limit = 6users
@page = 0
this.limit = 6users
this.page = 0
@on \mount ~>
this.on('mount', () => {
@load!
@load = ~>
@loading = true
@users = null
@update!
load() {
this.loading = true
this.users = null
this.update();
@api \users/recommendation do
this.api 'users/recommendation' do
limit: @limit
offset: @limit * @page
.then (users) ~>
@loading = false
@users = users
@update!
.then (users) =>
this.loading = false
this.users = users
this.update();
.catch (err, text-status) ->
console.error err
@refresh = ~>
refresh() {
if @users.length < @limit
@page = 0
this.page = 0
else
@page++
@load!
@close = ~>
@unmount!
close() {
this.unmount();
</script>
</mk-following-setuper>

View File

@@ -1,14 +1,14 @@
<mk-go-top>
<button class="hidden" title="一番上へ"><i class="fa fa-angle-up"></i></button>
<script>
window.add-event-listener \load @on-scroll
window.add-event-listener \scroll @on-scroll
window.add-event-listener \resize @on-scroll
window.add-event-listener 'load' this.on-scroll
window.add-event-listener 'scroll' this.on-scroll
window.add-event-listener 'resize' this.on-scroll
@on-scroll = ~>
on-scroll() {
if $ window .scroll-top! > 500px
@remove-class \hidden
@remove-class 'hidden'
else
@add-class \hidden
@add-class 'hidden'
</script>
</mk-go-top>

View File

@@ -106,43 +106,43 @@
</style>
<script>
@draw = ~>
draw() {
now = new Date!
nd = now.get-date!
nm = now.get-month!
ny = now.get-full-year!
@year = ny
@month = nm + 1
@day = nd
@week-day = [\日 \月 \火 \水 \木 \金 \土][now.get-day!]
this.year = ny
this.month = nm + 1
this.day = nd
this.week-day = [\日 '月' \火 '水' \木 '金' \土][now.get-day!]
@day-numer = (now - (new Date ny, nm, nd))
@day-denom = 1000ms * 60s * 60m * 24h
@month-numer = (now - (new Date ny, nm, 1))
@month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1)
this.month-numer = (now - (new Date ny, nm, 1))
this.month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1)
@year-numer = (now - (new Date ny, 0, 1))
@year-denom = (new Date ny + 1, 0, 1) - (new Date ny, 0, 1)
@day-p = @day-numer / @day-denom * 100
@month-p = @month-numer / @month-denom * 100
this.month-p = @month-numer / @month-denom * 100
@year-p = @year-numer / @year-denom * 100
@is-holiday =
this.is-holiday =
(now.get-day! == 0 or now.get-day! == 6)
@special =
| nm == 0 and nd == 1 => \on-new-years-day
this.special =
| nm == 0 and nd == 1 => 'on-new-years-day'
| _ => false
@update!
this.update();
@draw!
@on \mount ~>
@clock = set-interval @draw, 1000ms
this.on('mount', () => {
this.clock = set-interval @draw, 1000ms
@on \unmount ~>
this.on('unmount', () => {
clear-interval @clock
</script>
</mk-calendar-home-widget>

View File

@@ -32,5 +32,5 @@
color #999
</style>
<script>@mixin \user-preview</script>
<script>this.mixin('user-preview');</script>
</mk-donation-home-widget>

View File

@@ -46,65 +46,65 @@
</style>
<script>
@mixin \i
@mixin \api
this.mixin('i');
this.mixin('api');
@is-loading = true
@is-empty = false
@more-loading = false
@mode = \all
this.is-loading = true
this.is-empty = false
this.more-loading = false
this.mode = 'all'
@on \mount ~>
document.add-event-listener \keydown @on-document-keydown
window.add-event-listener \scroll @on-scroll
this.on('mount', () => {
document.add-event-listener 'keydown' this.on-document-keydown
window.add-event-listener 'scroll' this.on-scroll
@fetch ~>
@trigger \loaded
@fetch =>
this.trigger('loaded');
@on \unmount ~>
document.remove-event-listener \keydown @on-document-keydown
window.remove-event-listener \scroll @on-scroll
this.on('unmount', () => {
document.remove-event-listener 'keydown' this.on-document-keydown
window.remove-event-listener 'scroll' this.on-scroll
@on-document-keydown = (e) ~>
on-document-keydown(e) {
tag = e.target.tag-name.to-lower-case!
if tag != \input and tag != \textarea
if e.which == 84 # t
@refs.timeline.focus!
if tag != 'input' and tag != 'textarea'
if e.which == 84 // t
this.refs.timeline.focus();
@fetch = (cb) ~>
@api \posts/mentions do
following: @mode == \following
.then (posts) ~>
@is-loading = false
@is-empty = posts.length == 0
@update!
@refs.timeline.set-posts posts
fetch(cb) {
this.api 'posts/mentions' do
following: @mode == 'following'
.then (posts) =>
this.is-loading = false
this.is-empty = posts.length == 0
this.update();
this.refs.timeline.set-posts posts
if cb? then cb!
.catch (err) ~>
.catch (err) =>
console.error err
if cb? then cb!
@more = ~>
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
more() {
if @more-loading or @is-loading or this.refs.timeline.posts.length == 0
return
@more-loading = true
@update!
@api \posts/mentions do
following: @mode == \following
max_id: @refs.timeline.tail!.id
.then (posts) ~>
@more-loading = false
@update!
@refs.timeline.prepend-posts posts
.catch (err) ~>
this.more-loading = true
this.update();
this.api 'posts/mentions' do
following: @mode == 'following'
max_id: this.refs.timeline.tail!.id
.then (posts) =>
this.more-loading = false
this.update();
this.refs.timeline.prepend-posts posts
.catch (err) =>
console.error err
@on-scroll = ~>
on-scroll() {
current = window.scroll-y + window.inner-height
if current > document.body.offset-height - 8
@more!
@set-mode = (mode) ~>
set-mode(mode) {
@update do
mode: mode
@fetch!

View File

@@ -43,8 +43,8 @@
</style>
<script>
@settings = ~>
w = riot.mount document.body.append-child document.create-element \mk-settings-window .0
w.switch \notification
settings() {
w = riot.mount document.body.appendChild document.createElement 'mk-settings-window' .0
w.switch 'notification'
</script>
</mk-notifications-home-widget>

View File

@@ -57,31 +57,31 @@
</style>
<script>
@mixin \api
@mixin \stream
this.mixin('api');
this.mixin('stream');
@images = []
@initializing = true
this.images = []
this.initializing = true
@on \mount ~>
@stream.on \drive_file_created @on-stream-drive-file-created
this.on('mount', () => {
@stream.on 'drive_file_created' this.on-stream-drive-file-created
@api \drive/stream do
this.api 'drive/stream' do
type: 'image/*'
limit: 9images
.then (images) ~>
@initializing = false
@images = images
@update!
.then (images) =>
this.initializing = false
this.images = images
this.update();
@on \unmount ~>
@stream.off \drive_file_created @on-stream-drive-file-created
this.on('unmount', () => {
@stream.off 'drive_file_created' this.on-stream-drive-file-created
@on-stream-drive-file-created = (file) ~>
on-stream-drive-file-created(file) {
if /^image\/.+$/.test file.type
@images.unshift file
if @images.length > 9
@images.pop!
@update!
this.update();
</script>
</mk-photo-stream-home-widget>

View File

@@ -41,15 +41,15 @@
</style>
<script>
@mixin \i
@mixin \user-preview
@mixin \update-avatar
@mixin \update-banner
this.mixin('i');
this.mixin('user-preview');
this.mixin('update-avatar');
this.mixin('update-banner');
@set-avatar = ~>
set-avatar() {
@update-avatar @I
@set-banner = ~>
set-banner() {
@update-banner @I
</script>
</mk-profile-home-widget>

View File

@@ -64,31 +64,31 @@
</style>
<script>
@mixin \api
@mixin \NotImplementedException
this.mixin('api');
this.mixin('NotImplementedException');
@url = 'http://news.yahoo.co.jp/pickup/rss.xml'
@items = []
@initializing = true
this.url = 'http://news.yahoo.co.jp/pickup/rss.xml'
this.items = []
this.initializing = true
@on \mount ~>
this.on('mount', () => {
@fetch!
@clock = set-interval @fetch, 60000ms
this.clock = set-interval @fetch, 60000ms
@on \unmount ~>
this.on('unmount', () => {
clear-interval @clock
@fetch = ~>
@api CONFIG.url + '/api:rss' do
fetch() {
this.api CONFIG.url + '/api:rss' do
url: @url
.then (feed) ~>
@items = feed.rss.channel.item
@initializing = false
@update!
.then (feed) =>
this.items = feed.rss.channel.item
this.initializing = false
this.update();
.catch (err) ->
console.error err
@settings = ~>
settings() {
@NotImplementedException!
</script>
</mk-rss-reader-home-widget>

View File

@@ -32,78 +32,78 @@
</style>
<script>
@mixin \i
@mixin \api
@mixin \stream
this.mixin('i');
this.mixin('api');
this.mixin('stream');
@is-loading = true
@is-empty = false
@more-loading = false
@no-following = @I.following_count == 0
this.is-loading = true
this.is-empty = false
this.more-loading = false
this.no-following = @I.following_count == 0
@on \mount ~>
@stream.on \post @on-stream-post
@stream.on \follow @on-stream-follow
@stream.on \unfollow @on-stream-unfollow
this.on('mount', () => {
@stream.on 'post' this.on-stream-post
@stream.on 'follow' this.on-stream-follow
@stream.on 'unfollow' this.on-stream-unfollow
document.add-event-listener \keydown @on-document-keydown
window.add-event-listener \scroll @on-scroll
document.add-event-listener 'keydown' this.on-document-keydown
window.add-event-listener 'scroll' this.on-scroll
@load ~>
@trigger \loaded
@load =>
this.trigger('loaded');
@on \unmount ~>
@stream.off \post @on-stream-post
@stream.off \follow @on-stream-follow
@stream.off \unfollow @on-stream-unfollow
this.on('unmount', () => {
@stream.off 'post' this.on-stream-post
@stream.off 'follow' this.on-stream-follow
@stream.off 'unfollow' this.on-stream-unfollow
document.remove-event-listener \keydown @on-document-keydown
window.remove-event-listener \scroll @on-scroll
document.remove-event-listener 'keydown' this.on-document-keydown
window.remove-event-listener 'scroll' this.on-scroll
@on-document-keydown = (e) ~>
on-document-keydown(e) {
tag = e.target.tag-name.to-lower-case!
if tag != \input and tag != \textarea
if e.which == 84 # t
@refs.timeline.focus!
if tag != 'input' and tag != 'textarea'
if e.which == 84 // t
this.refs.timeline.focus();
@load = (cb) ~>
@api \posts/timeline
.then (posts) ~>
@is-loading = false
@is-empty = posts.length == 0
@update!
@refs.timeline.set-posts posts
load(cb) {
this.api 'posts/timeline'
.then (posts) =>
this.is-loading = false
this.is-empty = posts.length == 0
this.update();
this.refs.timeline.set-posts posts
if cb? then cb!
.catch (err) ~>
.catch (err) =>
console.error err
if cb? then cb!
@more = ~>
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
more() {
if @more-loading or @is-loading or this.refs.timeline.posts.length == 0
return
@more-loading = true
@update!
@api \posts/timeline do
max_id: @refs.timeline.tail!.id
.then (posts) ~>
@more-loading = false
@update!
@refs.timeline.prepend-posts posts
.catch (err) ~>
this.more-loading = true
this.update();
this.api 'posts/timeline' do
max_id: this.refs.timeline.tail!.id
.then (posts) =>
this.more-loading = false
this.update();
this.refs.timeline.prepend-posts posts
.catch (err) =>
console.error err
@on-stream-post = (post) ~>
@is-empty = false
@update!
@refs.timeline.add-post post
on-stream-post(post) {
this.is-empty = false
this.update();
this.refs.timeline.add-post post
@on-stream-follow = ~>
on-stream-follow() {
@load!
@on-stream-unfollow = ~>
on-stream-unfollow() {
@load!
@on-scroll = ~>
on-scroll() {
current = window.scroll-y + window.inner-height
if current > document.body.offset-height - 8
@more!

View File

@@ -29,7 +29,7 @@
</style>
<script>
@tips = [
this.tips = [
'<kbd>t</kbd>でタイムラインにフォーカスできます'
'<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます'
'投稿フォームにはファイルをドラッグ&ドロップできます'
@@ -41,31 +41,31 @@
'MisskeyはMIT Licenseです'
]
@on \mount ~>
this.on('mount', () => {
@set!
@clock = set-interval @change, 20000ms
this.clock = set-interval @change, 20000ms
@on \unmount ~>
this.on('unmount', () => {
clear-interval @clock
@set = ~>
@refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
@update!
set() {
this.refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
this.update();
@change = ~>
Velocity @refs.tip, {
change() {
Velocity this.refs.tip, {
opacity: 0
} {
duration: 500ms
easing: \linear
easing: 'linear'
complete: @set
}
Velocity @refs.tip, {
Velocity this.refs.tip, {
opacity: 1
} {
duration: 500ms
easing: \linear
easing: 'linear'
}
</script>
</mk-tips-home-widget>

View File

@@ -109,42 +109,42 @@
</style>
<script>
@mixin \api
@mixin \user-preview
this.mixin('api');
this.mixin('user-preview');
@users = null
@loading = true
this.users = null
this.loading = true
@limit = 3users
@page = 0
this.limit = 3users
this.page = 0
@on \mount ~>
this.on('mount', () => {
@fetch!
@clock = set-interval ~>
this.clock = set-interval =>
if @users.length < @limit
@fetch true
, 60000ms
@on \unmount ~>
this.on('unmount', () => {
clear-interval @clock
@fetch = (quiet = false) ~>
@loading = true
@users = null
if not quiet then @update!
@api \users/recommendation do
fetch(quiet = false) {
this.loading = true
this.users = null
if not quiet then this.update();
this.api 'users/recommendation' do
limit: @limit
offset: @limit * @page
.then (users) ~>
@loading = false
@users = users
@update!
.then (users) =>
this.loading = false
this.users = users
this.update();
.catch (err, text-status) ->
console.error err
@refresh = ~>
refresh() {
if @users.length < @limit
@page = 0
this.page = 0
else
@page++
@fetch!

View File

@@ -58,33 +58,33 @@
</style>
<script>
@mixin \i
@mode = @opts.mode || \timeline
this.mixin('i');
this.mode = this.opts.mode || 'timeline'
# https://github.com/riot/riot/issues/2080
if @mode == '' then @mode = \timeline
// https://github.com/riot/riot/issues/2080
if @mode == '' then this.mode = 'timeline'
@home = []
this.home = []
@on \mount ~>
@refs.tl.on \loaded ~>
@trigger \loaded
this.on('mount', () => {
this.refs.tl.on('loaded', () => {
this.trigger('loaded');
@I.data.home.for-each (widget) ~>
@I.data.home.for-each (widget) =>
try
el = document.create-element \mk- + widget.name + \-home-widget
el = document.createElement 'mk-' + widget.name + '-home-widget'
switch widget.place
| \left => @refs.left.append-child el
| \right => @refs.right.append-child el
| 'left' => this.refs.left.appendChild el
| 'right' => this.refs.right.appendChild el
@home.push (riot.mount el, do
id: widget.id
data: widget.data
.0)
catch e
# noop
// noop
@on \unmount ~>
@home.for-each (widget) ~>
this.on('unmount', () => {
@home.for-each (widget) =>
widget.unmount!
</script>
</mk-home>

View File

@@ -35,41 +35,41 @@
</style>
<script>
@image = @opts.image
this.image = this.opts.image
@on \mount ~>
Velocity @root, {
this.on('mount', () => {
Velocity this.root, {
opacity: 1
} {
duration: 100ms
easing: \linear
easing: 'linear'
}
#Velocity @img, {
# scale: 1
# opacity: 1
// scale: 1
// opacity: 1
#} {
# duration: 200ms
# easing: \ease-out
// duration: 200ms
// easing: 'ease-out'
#}
@close = ~>
Velocity @root, {
close() {
Velocity this.root, {
opacity: 0
} {
duration: 100ms
easing: \linear
complete: ~> @unmount!
easing: 'linear'
complete: => this.unmount();
}
#Velocity @img, {
# scale: 0.9
# opacity: 0
// scale: 0.9
// opacity: 0
#} {
# duration: 200ms
# easing: \ease-in
# complete: ~>
# @unmount!
// duration: 200ms
// easing: 'ease-in'
// complete: =>
// this.unmount();
#}
</script>
</mk-image-dialog>

View File

@@ -26,19 +26,19 @@
</style>
<script>
@images = @opts.images
@image = @images.0
this.images = this.opts.images
this.image = @images.0
@mousemove = (e) ~>
rect = @refs.view.get-bounding-client-rect!
mousemove(e) {
rect = this.refs.view.get-bounding-client-rect!
mouse-x = e.client-x - rect.left
mouse-y = e.client-y - rect.top
xp = mouse-x / @refs.view.offset-width * 100
yp = mouse-y / @refs.view.offset-height * 100
@refs.view.style.background-position = xp + '% ' + yp + '%'
xp = mouse-x / this.refs.view.offset-width * 100
yp = mouse-y / this.refs.view.offset-height * 100
this.refs.view.style.background-position = xp + '% ' + yp + '%'
@click = ~>
dialog = document.body.append-child document.create-element \mk-image-dialog
click() {
dialog = document.body.appendChild document.createElement 'mk-image-dialog'
riot.mount dialog, do
image: @image
</script>

View File

@@ -116,40 +116,40 @@
</style>
<script>
@done = false
this.done = false
@title = @opts.title
@placeholder = @opts.placeholder
@default = @opts.default
@allow-empty = if @opts.allow-empty? then @opts.allow-empty else true
this.title = this.opts.title
this.placeholder = this.opts.placeholder
this.default = this.opts.default
this.allow-empty = if this.opts.allow-empty? then this.opts.allow-empty else true
@on \mount ~>
@text = @refs.window.refs.text
this.on('mount', () => {
this.text = this.refs.window.refs.text
if @default?
@text.value = @default
@text.focus!
@text.focus();
@refs.window.on \closing ~>
this.refs.window.on('closing', () => {
if @done
@opts.on-ok @text.value
this.opts.on-ok @text.value
else
if @opts.on-cancel?
@opts.on-cancel!
if this.opts.on-cancel?
this.opts.on-cancel!
@refs.window.on \closed ~>
@unmount!
this.refs.window.on('closed', () => {
this.unmount();
@cancel = ~>
@done = false
@refs.window.close!
cancel() {
this.done = false
this.refs.window.close!
@ok = ~>
ok() {
if not @allow-empty and @text.value == '' then return
@done = true
@refs.window.close!
this.done = true
this.refs.window.close!
@on-keydown = (e) ~>
if e.which == 13 # Enter
on-keydown(e) {
if e.which == 13 // Enter
e.prevent-default!
e.stop-propagation!
@ok!

View File

@@ -93,5 +93,5 @@
right 16px
</style>
<script>@user = @opts.user</script>
<script>this.user = this.opts.user</script>
</mk-list-user>

View File

@@ -19,10 +19,10 @@
</style>
<script>
@user = @opts.user
this.user = this.opts.user
@on \mount ~>
@refs.window.on \closed ~>
@unmount!
this.on('mount', () => {
this.refs.window.on('closed', () => {
this.unmount();
</script>
</mk-messaging-room-window>

View File

@@ -19,12 +19,12 @@
</style>
<script>
@on \mount ~>
@refs.window.on \closed ~>
@unmount!
this.on('mount', () => {
this.refs.window.on('closed', () => {
this.unmount();
@refs.window.refs.index.on \navigate-user (user) ~>
w = document.body.append-child document.create-element \mk-messaging-room-window
this.refs.window.refs.index.on('navigate-user', user => {
w = document.body.appendChild document.createElement 'mk-messaging-room-window'
riot.mount w, do
user: user
</script>

View File

@@ -177,34 +177,34 @@
</style>
<script>
@mixin \api
@mixin \stream
@mixin \user-preview
@mixin \get-post-summary
this.mixin('api');
this.mixin('stream');
this.mixin('user-preview');
this.mixin('get-post-summary');
@notifications = []
@loading = true
this.notifications = []
this.loading = true
@on \mount ~>
@api \i/notifications
.then (notifications) ~>
@notifications = notifications
@loading = false
@update!
this.on('mount', () => {
this.api 'i/notifications'
.then (notifications) =>
this.notifications = notifications
this.loading = false
this.update();
.catch (err, text-status) ->
console.error err
@stream.on \notification @on-notification
@stream.on 'notification' this.on-notification
@on \unmount ~>
@stream.off \notification @on-notification
this.on('unmount', () => {
@stream.off 'notification' this.on-notification
@on-notification = (notification) ~>
on-notification(notification) {
@notifications.unshift notification
@update!
this.update();
@on \update ~>
@notifications.for-each (notification) ~>
this.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

View File

@@ -63,18 +63,18 @@
</style>
<script>
@mode = \signin
this.mode = 'signin'
@signup = ~>
@mode = \signup
@update!
signup() {
this.mode = 'signup'
this.update();
@signin = ~>
@mode = \signin
@update!
signin() {
this.mode = 'signin'
this.update();
@introduction = ~>
@mode = \introduction
@update!
introduction() {
this.mode = 'introduction'
this.update();
</script>
</mk-entrance>

View File

@@ -119,12 +119,12 @@
</style>
<script>
@on \mount ~>
@refs.signin.on \user (user) ~>
this.on('mount', () => {
this.refs.signin.on('user', (user) => {
@update do
user: user
@introduction = ~>
@parent.introduction!
introduction() {
this.parent.introduction!
</script>
</mk-entrance-signin>

View File

@@ -8,40 +8,40 @@
</style>
<script>
@mixin \i
@mixin \api
@mixin \ui-progress
@mixin \stream
@mixin \get-post-summary
this.mixin('i');
this.mixin('api');
this.mixin('ui-progress');
this.mixin('stream');
this.mixin('get-post-summary');
@unread-count = 0
this.unread-count = 0
@page = switch @opts.mode
| \timelie => \home
| \mentions => \mentions
| _ => \home
this.page = switch this.opts.mode
| 'timelie' => 'home'
| 'mentions' => 'mentions'
| _ => 'home'
@on \mount ~>
@refs.ui.refs.home.on \loaded ~>
@Progress.done!
this.on('mount', () => {
this.refs.ui.refs.home.on('loaded', () => {
this.Progress.done();
document.title = 'Misskey'
@Progress.start!
@stream.on \post @on-stream-post
document.add-event-listener \visibilitychange @window-on-visibilitychange, false
this.Progress.start();
@stream.on 'post' this.on-stream-post
document.add-event-listener 'visibilitychange' @window-on-visibilitychange, false
@on \unmount ~>
@stream.off \post @on-stream-post
document.remove-event-listener \visibilitychange @window-on-visibilitychange
this.on('unmount', () => {
@stream.off 'post' this.on-stream-post
document.remove-event-listener 'visibilitychange' @window-on-visibilitychange
@on-stream-post = (post) ~>
on-stream-post(post) {
if document.hidden and post.user_id !== @I.id
@unread-count++
document.title = '(' + @unread-count + ') ' + @get-post-summary post
@window-on-visibilitychange = ~>
window-on-visibilitychange() {
if !document.hidden
@unread-count = 0
this.unread-count = 0
document.title = 'Misskey'
</script>
</mk-home-page>

View File

@@ -16,17 +16,17 @@
</style>
<script>
@mixin \ui-progress
this.mixin('ui-progress');
@post = @opts.post
this.post = this.opts.post
@on \mount ~>
@Progress.start!
this.on('mount', () => {
this.Progress.start();
@refs.ui.refs.detail.on \post-fetched ~>
@Progress.set 0.5
this.refs.ui.refs.detail.on('post-fetched', () => {
this.Progress.set(0.5);
@refs.ui.refs.detail.on \loaded ~>
@Progress.done!
this.refs.ui.refs.detail.on('loaded', () => {
this.Progress.done();
</script>
</mk-post-page>

View File

@@ -8,12 +8,12 @@
</style>
<script>
@mixin \ui-progress
this.mixin('ui-progress');
@on \mount ~>
@Progress.start!
this.on('mount', () => {
this.Progress.start();
@refs.ui.refs.search.on \loaded ~>
@Progress.done!
this.refs.ui.refs.search.on('loaded', () => {
this.Progress.done();
</script>
</mk-search-page>

View File

@@ -8,18 +8,18 @@
</style>
<script>
@mixin \ui-progress
this.mixin('ui-progress');
@user = @opts.user
this.user = this.opts.user
@on \mount ~>
@Progress.start!
this.on('mount', () => {
this.Progress.start();
@refs.ui.refs.user.on \user-fetched (user) ~>
@Progress.set 0.5
this.refs.ui.refs.user.on('user-fetched', (user) => {
this.Progress.set(0.5);
document.title = user.name + ' | Misskey'
@refs.ui.refs.user.on \loaded ~>
@Progress.done!
this.refs.ui.refs.user.on('loaded', () => {
this.Progress.done();
</script>
</mk-user-page>

View File

@@ -103,38 +103,38 @@
</style>
<script>
@mixin \api
@mixin \text
@mixin \date-stringify
@mixin \user-preview
this.mixin('api');
this.mixin('text');
this.mixin('date-stringify');
this.mixin('user-preview');
@post = @opts.post
this.post = this.opts.post
@url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
this.url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
@title = @date-stringify @post.created_at
this.title = @date-stringify @post.created_at
@on \mount ~>
this.on('mount', () => {
if @post.text?
tokens = @analyze @post.text
@refs.text.innerHTML = @compile tokens
this.refs.text.innerHTML = @compile tokens
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
this.refs.text.children.for-each (e) =>
if e.tag-name == 'MK-URL'
riot.mount e
@like = ~>
like() {
if @post.is_liked
@api \posts/likes/delete do
this.api 'posts/likes/delete' do
post_id: @post.id
.then ~>
.then =>
@post.is_liked = false
@update!
this.update();
else
@api \posts/likes/create do
this.api 'posts/likes/create' do
post_id: @post.id
.then ~>
.then =>
@post.is_liked = true
@update!
this.update();
</script>
</mk-post-detail-sub>

View File

@@ -329,108 +329,108 @@
</style>
<script>
@mixin \api
@mixin \text
@mixin \user-preview
@mixin \date-stringify
@mixin \NotImplementedException
this.mixin('api');
this.mixin('text');
this.mixin('user-preview');
this.mixin('date-stringify');
this.mixin('NotImplementedException');
@fetching = true
@loading-context = false
@content = null
@post = null
this.fetching = true
this.loading-context = false
this.content = null
this.post = null
@on \mount ~>
this.on('mount', () => {
@api \posts/show do
post_id: @opts.post
.then (post) ~>
@fetching = false
@post = post
@trigger \loaded
this.api 'posts/show' do
post_id: this.opts.post
.then (post) =>
this.fetching = false
this.post = post
this.trigger('loaded');
@is-repost = @post.repost?
@p = if @is-repost then @post.repost else @post
this.is-repost = @post.repost?
this.p = if @is-repost then @post.repost else @post
@title = @date-stringify @p.created_at
this.title = @date-stringify @p.created_at
@update!
this.update();
if @p.text?
tokens = @analyze @p.text
@refs.text.innerHTML = @compile tokens
this.refs.text.innerHTML = @compile tokens
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
this.refs.text.children.for-each (e) =>
if e.tag-name == 'MK-URL'
riot.mount e
# URLをプレビュー
// URLをプレビュー
tokens
.filter (t) -> t.type == \link
.map (t) ~>
@preview = @refs.text.append-child document.create-element \mk-url-preview
.filter (t) -> t.type == 'link'
.map (t) =>
this.preview = this.refs.text.appendChild document.createElement 'mk-url-preview'
riot.mount @preview, do
url: t.content
# Get likes
@api \posts/likes do
// Get likes
this.api 'posts/likes' do
post_id: @p.id
limit: 8
.then (likes) ~>
@likes = likes
@update!
.then (likes) =>
this.likes = likes
this.update();
# Get reposts
@api \posts/reposts do
// Get reposts
this.api 'posts/reposts' do
post_id: @p.id
limit: 8
.then (reposts) ~>
@reposts = reposts
@update!
.then (reposts) =>
this.reposts = reposts
this.update();
# Get replies
@api \posts/replies do
// Get replies
this.api 'posts/replies' do
post_id: @p.id
limit: 8
.then (replies) ~>
@replies = replies
@update!
.then (replies) =>
this.replies = replies
this.update();
@update!
this.update();
@reply = ~>
form = document.body.append-child document.create-element \mk-post-form-window
reply() {
form = document.body.appendChild document.createElement 'mk-post-form-window'
riot.mount form, do
reply: @p
@repost = ~>
form = document.body.append-child document.create-element \mk-repost-form-window
repost() {
form = document.body.appendChild document.createElement 'mk-repost-form-window'
riot.mount form, do
post: @p
@like = ~>
like() {
if @p.is_liked
@api \posts/likes/delete do
this.api 'posts/likes/delete' do
post_id: @p.id
.then ~>
.then =>
@p.is_liked = false
@update!
this.update();
else
@api \posts/likes/create do
this.api 'posts/likes/create' do
post_id: @p.id
.then ~>
.then =>
@p.is_liked = true
@update!
this.update();
@load-context = ~>
@loading-context = true
load-context() {
this.loading-context = true
# Get context
@api \posts/context do
// Get context
this.api 'posts/context' do
post_id: @p.reply_to_id
.then (context) ~>
@context = context.reverse!
@loading-context = false
@update!
.then (context) =>
this.context = context.reverse!
this.loading-context = false
this.update();
</script>
</mk-post-detail>

View File

@@ -32,24 +32,24 @@
</style>
<script>
@uploading-files = []
@files = []
this.uploading-files = []
this.files = []
@on \mount ~>
@refs.window.refs.form.focus!
this.on('mount', () => {
this.refs.window.refs.form.focus();
@refs.window.on \closed ~>
@unmount!
this.refs.window.on('closed', () => {
this.unmount();
@refs.window.refs.form.on \post ~>
@refs.window.close!
this.refs.window.refs.form.on('post', () => {
this.refs.window.close!
@refs.window.refs.form.on \change-uploading-files (files) ~>
@uploading-files = files
@update!
this.refs.window.refs.form.on('change-uploading-files', (files) => {
this.uploading-files = files
this.update();
@refs.window.refs.form.on \change-files (files) ~>
@files = files
@update!
this.refs.window.refs.form.on('change-files', (files) => {
this.files = files
this.update();
</script>
</mk-post-form-window>

View File

@@ -305,161 +305,161 @@
</style>
<script>
get-cat = require '../../common/scripts/get-cat'
get-cat = require('../../common/scripts/get-cat');
@mixin \api
@mixin \notify
@mixin \autocomplete
this.mixin('api');
this.mixin('notify');
this.mixin('autocomplete');
@wait = false
@uploadings = []
@files = []
@autocomplete = null
@poll = false
this.wait = false
this.uploadings = []
this.files = []
this.autocomplete = null
this.poll = false
@in-reply-to-post = @opts.reply
this.in-reply-to-post = this.opts.reply
# https://github.com/riot/riot/issues/2080
if @in-reply-to-post == '' then @in-reply-to-post = null
// https://github.com/riot/riot/issues/2080
if @in-reply-to-post == '' then this.in-reply-to-post = null
@on \mount ~>
@refs.uploader.on \uploaded (file) ~>
this.on('mount', () => {
this.refs.uploader.on('uploaded', (file) => {
@add-file file
@refs.uploader.on \change-uploads (uploads) ~>
@trigger \change-uploading-files uploads
this.refs.uploader.on('change-uploads', (uploads) => {
this.trigger 'change-uploading-files' uploads
@autocomplete = new @Autocomplete @refs.text
this.autocomplete = new @Autocomplete this.refs.text
@autocomplete.attach!
@on \unmount ~>
this.on('unmount', () => {
@autocomplete.detach!
@focus = ~>
@refs.text.focus!
focus() {
this.refs.text.focus();
@clear = ~>
@refs.text.value = ''
@files = []
@trigger \change-files
@update!
clear() {
this.refs.text.value = ''
this.files = []
this.trigger('change-files');
this.update();
@ondragover = (e) ~>
ondragover(e) {
e.stop-propagation!
@draghover = true
# ドラッグされてきたものがファイルだったら
if e.data-transfer.effect-allowed == \all
e.data-transfer.drop-effect = \copy
this.draghover = true
// ドラッグされてきたものがファイルだったら
if e.data-transfer.effect-allowed == 'all'
e.data-transfer.drop-effect = 'copy'
else
e.data-transfer.drop-effect = \move
e.data-transfer.drop-effect = 'move'
return false
@ondragenter = (e) ~>
@draghover = true
ondragenter(e) {
this.draghover = true
@ondragleave = (e) ~>
@draghover = false
ondragleave(e) {
this.draghover = false
@ondrop = (e) ~>
ondrop(e) {
e.prevent-default!
e.stop-propagation!
@draghover = false
this.draghover = false
# ファイルだったら
// ファイルだったら
if e.data-transfer.files.length > 0
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
Array.prototype.for-each.call e.data-transfer.files, (file) =>
@upload file
return false
# データ取得
// データ取得
data = e.data-transfer.get-data 'text'
if !data?
return false
try
# パース
// パース
obj = JSON.parse data
# (ドライブの)ファイルだったら
if obj.type == \file
// (ドライブの)ファイルだったら
if obj.type == 'file'
@add-file obj.file
catch
# ignore
// ignore
return false
@onkeydown = (e) ~>
if (e.which == 10 || e.which == 13) && (e.ctrl-key || e.meta-key)
onkeydown(e) {
if (e.which == 10 || e.which == 13) && (e.ctrlKey || e.meta-key)
@post!
@onpaste = (e) ~>
data = e.clipboard-data
onpaste(e) {
data = e.clipboardData
items = data.items
for i from 0 to items.length - 1
item = items[i]
switch (item.kind)
| \file =>
@upload item.get-as-file!
| 'file' =>
@upload item.getAsFile();
@select-file = ~>
@refs.file.click!
select-file() {
this.refs.file.click!
@select-file-from-drive = ~>
browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
select-file-from-drive() {
browser = document.body.appendChild document.createElement 'mk-select-file-from-drive-window'
i = riot.mount browser, do
multiple: true
i[0].one \selected (files) ~>
i[0].one 'selected' (files) =>
files.for-each @add-file
@change-file = ~>
files = @refs.file.files
change-file() {
files = this.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) {
this.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 = =>
this.files = @files.filter (x) -> x.id != file.id
this.trigger 'change-files' @files
this.update();
@files.push file
@trigger \change-files @files
@update!
this.trigger 'change-files' @files
this.update();
@add-poll = ~>
@poll = true
add-poll() {
this.poll = true
@on-poll-destroyed = ~>
on-poll-destroyed() {
@update do
poll: false
@post = (e) ~>
@wait = true
post(e) {
this.wait = true
files = if @files? and @files.length > 0
then @files.map (f) -> f.id
else undefined
@api \posts/create do
text: @refs.text.value
this.api 'posts/create' do
text: this.refs.text.value
media_ids: files
reply_to_id: if @in-reply-to-post? then @in-reply-to-post.id else undefined
poll: if @poll then @refs.poll.get! else undefined
.then (data) ~>
@trigger \post
poll: if @poll then this.refs.poll.get! else undefined
.then (data) =>
this.trigger('post');
@notify if @in-reply-to-post? then '返信しました!' else '投稿しました!'
.catch (err) ~>
.catch (err) =>
console.error err
@notify '投稿できませんでした'
.then ~>
@wait = false
@update!
.then =>
this.wait = false
this.update();
@cat = ~>
@refs.text.value = @refs.text.value + get-cat!
cat() {
this.refs.text.value = this.refs.text.value + get-cat!
</script>
</mk-post-form>

View File

@@ -83,11 +83,11 @@
</style>
<script>
@mixin \date-stringify
@mixin \user-preview
this.mixin('date-stringify');
this.mixin('user-preview');
@post = @opts.post
this.post = this.opts.post
@title = @date-stringify @post.created_at
this.title = @date-stringify @post.created_at
</script>
</mk-post-preview>

View File

@@ -9,64 +9,64 @@
</style>
<script>
@mixin \api
@mixin \is-promise
this.mixin('api');
this.mixin('is-promise');
@post = null
@post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post
this.post = null
this.post-promise = if @is-promise this.opts.post then this.opts.post else Promise.resolve this.opts.post
@on \mount ~>
this.on('mount', () => {
post <~ @post-promise.then
@post = post
@update!
this.post = post
this.update();
@api \aggregation/posts/like do
this.api 'aggregation/posts/like' do
post_id: @post.id
limit: 30days
.then (likes) ~>
.then (likes) =>
likes = likes.reverse!
@api \aggregation/posts/repost do
this.api 'aggregation/posts/repost' do
post_id: @post.id
limit: 30days
.then (repost) ~>
.then (repost) =>
repost = repost.reverse!
@api \aggregation/posts/reply do
this.api 'aggregation/posts/reply' do
post_id: @post.id
limit: 30days
.then (replies) ~>
.then (replies) =>
replies = replies.reverse!
new Chart @refs.canv, do
type: \bar
new Chart this.refs.canv, do
type: 'bar'
data:
labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
labels: likes.map (x, i) => if i % 3 == 2 then x.date.day + '日' else ''
datasets: [
{
label: \いいね
type: \line
data: likes.map (x) ~> x.count
label: 'いいね'
type: 'line'
data: likes.map (x) => x.count
line-tension: 0
border-width: 2
fill: true
background-color: 'rgba(247, 121, 108, 0.2)'
point-background-color: \#fff
point-background-color: '#fff'
point-radius: 4
point-border-width: 2
border-color: \#F7796C
border-color: '#F7796C'
},
{
label: \返信
type: \bar
data: replies.map (x) ~> x.count
background-color: \#555
label: '返信'
type: 'bar'
data: replies.map (x) => x.count
background-color: '#555'
},
{
label: \Repost
type: \bar
data: repost.map (x) ~> x.count
background-color: \#a2d61e
label: 'Repost'
type: 'bar'
data: repost.map (x) => x.count
background-color: '#a2d61e'
}
]
options:

View File

@@ -75,20 +75,20 @@
</style>
<script>
@title = @opts.title
@value = parse-int @opts.value, 10
@max = parse-int @opts.max, 10
this.title = this.opts.title
this.value = parse-int this.opts.value, 10
this.max = parse-int this.opts.max, 10
@on \mount ~>
@refs.window.on \closed ~>
@unmount!
this.on('mount', () => {
this.refs.window.on('closed', () => {
this.unmount();
@update-progress = (value, max) ~>
@value = parse-int value, 10
@max = parse-int max, 10
@update!
update-progress(value, max) {
this.value = parse-int value, 10
this.max = parse-int max, 10
this.update();
@close = ~>
@refs.window.close!
close() {
this.refs.window.close!
</script>
</mk-progress-dialog>

View File

@@ -12,25 +12,25 @@
</style>
<script>
@on-document-keydown = (e) ~>
on-document-keydown(e) {
tag = e.target.tag-name.to-lower-case!
if tag != \input and tag != \textarea
if e.which == 27 # Esc
@refs.window.close!
if tag != 'input' and tag != 'textarea'
if e.which == 27 // Esc
this.refs.window.close!
@on \mount ~>
@refs.window.refs.form.on \cancel ~>
@refs.window.close!
this.on('mount', () => {
this.refs.window.refs.form.on('cancel', () => {
this.refs.window.close!
@refs.window.refs.form.on \posted ~>
@refs.window.close!
this.refs.window.refs.form.on('posted', () => {
this.refs.window.close!
document.add-event-listener \keydown @on-document-keydown
document.add-event-listener 'keydown' this.on-document-keydown
@refs.window.on \closed ~>
@unmount!
this.refs.window.on('closed', () => {
this.unmount();
@on \unmount ~>
document.remove-event-listener \keydown @on-document-keydown
this.on('unmount', () => {
document.remove-event-listener 'keydown' this.on-document-keydown
</script>
</mk-repost-form-window>

View File

@@ -114,31 +114,31 @@
</style>
<script>
@mixin \api
@mixin \notify
this.mixin('api');
this.mixin('notify');
@wait = false
@quote = false
this.wait = false
this.quote = false
@cancel = ~>
@trigger \cancel
cancel() {
this.trigger('cancel');
@ok = ~>
@wait = true
@api \posts/create do
repost_id: @opts.post.id
text: if @quote then @refs.text.value else undefined
.then (data) ~>
@trigger \posted
ok() {
this.wait = true
this.api 'posts/create' do
repost_id: this.opts.post.id
text: if @quote then this.refs.text.value else undefined
.then (data) =>
this.trigger('posted');
@notify 'Repostしました'
.catch (err) ~>
.catch (err) =>
console.error err
@notify 'Repostできませんでした'
.then ~>
@wait = false
@update!
.then =>
this.wait = false
this.update();
@onquote = ~>
@quote = true
onquote() {
this.quote = true
</script>
</mk-repost-form>

View File

@@ -28,59 +28,59 @@
</style>
<script>
@mixin \api
@mixin \get-post-summary
this.mixin('api');
this.mixin('get-post-summary');
@query = @opts.query
@is-loading = true
@is-empty = false
@more-loading = false
@page = 0
this.query = this.opts.query
this.is-loading = true
this.is-empty = false
this.more-loading = false
this.page = 0
@on \mount ~>
document.add-event-listener \keydown @on-document-keydown
window.add-event-listener \scroll @on-scroll
this.on('mount', () => {
document.add-event-listener 'keydown' this.on-document-keydown
window.add-event-listener 'scroll' this.on-scroll
@api \posts/search do
this.api 'posts/search' do
query: @query
.then (posts) ~>
@is-loading = false
@is-empty = posts.length == 0
@update!
@refs.timeline.set-posts posts
@trigger \loaded
.catch (err) ~>
.then (posts) =>
this.is-loading = false
this.is-empty = posts.length == 0
this.update();
this.refs.timeline.set-posts posts
this.trigger('loaded');
.catch (err) =>
console.error err
@on \unmount ~>
document.remove-event-listener \keydown @on-document-keydown
window.remove-event-listener \scroll @on-scroll
this.on('unmount', () => {
document.remove-event-listener 'keydown' this.on-document-keydown
window.remove-event-listener 'scroll' this.on-scroll
@on-document-keydown = (e) ~>
on-document-keydown(e) {
tag = e.target.tag-name.to-lower-case!
if tag != \input and tag != \textarea
if e.which == 84 # t
@refs.timeline.focus!
if tag != 'input' and tag != 'textarea'
if e.which == 84 // t
this.refs.timeline.focus();
@more = ~>
more() {
if @more-loading or @is-loading or @timeline.posts.length == 0
return
@more-loading = true
@update!
@api \posts/search do
this.more-loading = true
this.update();
this.api 'posts/search' do
query: @query
page: @page + 1
.then (posts) ~>
@more-loading = false
.then (posts) =>
this.more-loading = false
@page++
@update!
@refs.timeline.prepend-posts posts
.catch (err) ~>
this.update();
this.refs.timeline.prepend-posts posts
.catch (err) =>
console.error err
@on-scroll = ~>
on-scroll() {
current = window.scroll-y + window.inner-height
if current > document.body.offset-height - 16 # 遊び
if current > document.body.offset-height - 16 // 遊び
@more!
</script>
</mk-search-posts>

View File

@@ -23,10 +23,10 @@
</style>
<script>
@query = @opts.query
this.query = this.opts.query
@on \mount ~>
@refs.posts.on \loaded ~>
@trigger \loaded
this.on('mount', () => {
this.refs.posts.on('loaded', () => {
this.trigger('loaded');
</script>
</mk-search>

View File

@@ -131,31 +131,31 @@
</style>
<script>
@file = []
this.file = []
@multiple = if @opts.multiple? then @opts.multiple else false
@title = @opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
this.multiple = if this.opts.multiple? then this.opts.multiple else false
this.title = this.opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
@on \mount ~>
@refs.window.refs.browser.on \selected (file) ~>
@file = file
this.on('mount', () => {
this.refs.window.refs.browser.on('selected', (file) => {
this.file = file
@ok!
@refs.window.refs.browser.on \change-selection (files) ~>
@file = files
@update!
this.refs.window.refs.browser.on('change-selection', (files) => {
this.file = files
this.update();
@refs.window.on \closed ~>
@unmount!
this.refs.window.on('closed', () => {
this.unmount();
@close = ~>
@refs.window.close!
close() {
this.refs.window.close!
@upload = ~>
@refs.window.refs.browser.select-local-file!
upload() {
this.refs.window.refs.browser.select-local-file!
@ok = ~>
@trigger \selected @file
@refs.window.close!
ok() {
this.trigger 'selected' @file
this.refs.window.close!
</script>
</mk-select-file-from-drive-window>

View File

@@ -31,15 +31,15 @@
</style>
<script>
@mixin \i
@mixin \update-avatar
this.mixin('i');
this.mixin('update-avatar');
@set = ~>
set() {
@update-avatar @I
@close = (e) ~>
close(e) {
e.prevent-default!
e.stop-propagation!
@unmount!
this.unmount();
</script>
</mk-set-avatar-suggestion>

View File

@@ -31,15 +31,15 @@
</style>
<script>
@mixin \i
@mixin \update-banner
this.mixin('i');
this.mixin('update-banner');
@set = ~>
set() {
@update-banner @I
@close = (e) ~>
close(e) {
e.prevent-default!
e.stop-propagation!
@unmount!
this.unmount();
</script>
</mk-set-banner-suggestion>

View File

@@ -15,11 +15,11 @@
</style>
<script>
@on \mount ~>
@refs.window.on \closed ~>
@unmount!
this.on('mount', () => {
this.refs.window.on('closed', () => {
this.unmount();
@close = ~>
@refs.window.close!
close() {
this.refs.window.close!
</script>
</mk-settings-window>

View File

@@ -198,45 +198,45 @@
</style>
<script>
@mixin \i
@mixin \api
@mixin \dialog
@mixin \update-avatar
this.mixin('i');
this.mixin('api');
this.mixin('dialog');
this.mixin('update-avatar');
@page = \account
this.page = 'account'
@set-page = (page) ~>
@page = page
set-page(page) {
this.page = page
@avatar = ~>
avatar() {
@update-avatar @I
@update-account = ~>
@api \i/update do
name: @refs.account-name.value
location: @refs.account-location.value
bio: @refs.account-bio.value
birthday: @refs.account-birthday.value
.then (i) ~>
alert \ok
.catch (err) ~>
update-account() {
this.api 'i/update' do
name: this.refs.account-name.value
location: this.refs.account-location.value
bio: this.refs.account-bio.value
birthday: this.refs.account-birthday.value
.then (i) =>
alert 'ok'
.catch (err) =>
console.error err
@update-cache = ~>
update-cache() {
@I.data.cache = !@I.data.cache
@api \i/appdata/set do
this.api 'i/appdata/set' do
data: JSON.stringify do
cache: @I.data.cache
@update-debug = ~>
update-debug() {
@I.data.debug = !@I.data.debug
@api \i/appdata/set do
this.api 'i/appdata/set' do
data: JSON.stringify do
debug: @I.data.debug
@update-nya = ~>
update-nya() {
@I.data.nya = !@I.data.nya
@api \i/appdata/set do
this.api 'i/appdata/set' do
data: JSON.stringify do
nya: @I.data.nya
</script>

View File

@@ -27,27 +27,27 @@
</style>
<script>
@mixin \stream
this.mixin('stream');
@on \before-mount ~>
@state = @get-stream-state!
this.on('before-mount', () => {
this.state = @get-stream-state!
if @state == \connected
@root.style.opacity = 0
if @state == 'connected'
this.root.style.opacity = 0
@stream-state-ev.on \connected ~>
@state = @get-stream-state!
@update!
set-timeout ~>
Velocity @root, {
@stream-state-ev.on('connected', () => {
this.state = @get-stream-state!
this.update();
setTimeout =>
Velocity this.root, {
opacity: 0
} 200ms \linear
} 200ms 'linear'
, 1000ms
@stream-state-ev.on \closed ~>
@state = @get-stream-state!
@update!
Velocity @root, {
@stream-state-ev.on('closed', () => {
this.state = @get-stream-state!
this.update();
Velocity this.root, {
opacity: 1
} 0ms
</script>

View File

@@ -28,18 +28,18 @@
</style>
<script>
@mixin \text
@mixin \user-preview
this.mixin('text');
this.mixin('user-preview');
@post = @opts.post
this.post = this.opts.post
@on \mount ~>
this.on('mount', () => {
if @post.text?
tokens = @analyze @post.text
@refs.text.innerHTML = @compile tokens, false
this.refs.text.innerHTML = @compile tokens, false
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
this.refs.text.children.for-each (e) =>
if e.tag-name == 'MK-URL'
riot.mount e
</script>
</mk-sub-post-content>

View File

@@ -9,12 +9,12 @@
</div>
</article>
<script>
@mixin \date-stringify
@mixin \user-preview
this.mixin('date-stringify');
this.mixin('user-preview');
@post = @opts.post
this.post = this.opts.post
@title = @date-stringify @post.created_at
this.title = @date-stringify @post.created_at
</script>
<style>

View File

@@ -312,83 +312,83 @@
</style>
<script>
@mixin \api
@mixin \text
@mixin \date-stringify
@mixin \user-preview
@mixin \NotImplementedException
this.mixin('api');
this.mixin('text');
this.mixin('date-stringify');
this.mixin('user-preview');
this.mixin('NotImplementedException');
@post = @opts.post
@is-repost = @post.repost? and !@post.text?
@p = if @is-repost then @post.repost else @post
this.post = this.opts.post
this.is-repost = @post.repost? and !@post.text?
this.p = if @is-repost then @post.repost else @post
@title = @date-stringify @p.created_at
this.title = @date-stringify @p.created_at
@url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
@is-detail-opened = false
this.url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
this.is-detail-opened = false
@on \mount ~>
this.on('mount', () => {
if @p.text?
tokens = if @p._highlight?
then @analyze @p._highlight
else @analyze @p.text
@refs.text.innerHTML = @refs.text.innerHTML.replace '<p class="dummy"></p>' if @p._highlight?
this.refs.text.innerHTML = this.refs.text.innerHTML.replace '<p class="dummy"></p>' if @p._highlight?
then @compile tokens, true, false
else @compile tokens
@refs.text.children.for-each (e) ~>
if e.tag-name == \MK-URL
this.refs.text.children.for-each (e) =>
if e.tag-name == 'MK-URL'
riot.mount e
# URLをプレビュー
// URLをプレビュー
tokens
.filter (t) -> t.type == \link
.map (t) ~>
@preview = @refs.text.append-child document.create-element \mk-url-preview
.filter (t) -> t.type == 'link'
.map (t) =>
this.preview = this.refs.text.appendChild document.createElement 'mk-url-preview'
riot.mount @preview, do
url: t.content
@reply = ~>
form = document.body.append-child document.create-element \mk-post-form-window
reply() {
form = document.body.appendChild document.createElement 'mk-post-form-window'
riot.mount form, do
reply: @p
@repost = ~>
form = document.body.append-child document.create-element \mk-repost-form-window
repost() {
form = document.body.appendChild document.createElement 'mk-repost-form-window'
riot.mount form, do
post: @p
@like = ~>
like() {
if @p.is_liked
@api \posts/likes/delete do
this.api 'posts/likes/delete' do
post_id: @p.id
.then ~>
.then =>
@p.is_liked = false
@update!
this.update();
else
@api \posts/likes/create do
this.api 'posts/likes/create' do
post_id: @p.id
.then ~>
.then =>
@p.is_liked = true
@update!
this.update();
@toggle-detail = ~>
@is-detail-opened = !@is-detail-opened
@update!
toggle-detail() {
this.is-detail-opened = !@is-detail-opened
this.update();
@on-key-down = (e) ~>
on-key-down(e) {
should-be-cancel = true
switch
| e.which == 38 or e.which == 74 or (e.which == 9 and e.shift-key) => # ↑, j or Shift+Tab
focus @root, (e) -> e.previous-element-sibling
| e.which == 40 or e.which == 75 or e.which == 9 => # ↓, k or Tab
focus @root, (e) -> e.next-element-sibling
| e.which == 81 or e.which == 69 => # q or e
| e.which == 38 or e.which == 74 or (e.which == 9 and e.shift-key) => // ↑, j or Shift+Tab
focus this.root, (e) -> e.previous-element-sibling
| e.which == 40 or e.which == 75 or e.which == 9 => // ↓, k or Tab
focus this.root, (e) -> e.next-element-sibling
| e.which == 81 or e.which == 69 => // q or e
@repost!
| e.which == 70 or e.which == 76 => # f or l
| e.which == 70 or e.which == 76 => // f or l
@like!
| e.which == 82 => # r
| e.which == 82 => // r
@reply!
| _ =>
should-be-cancel = false
@@ -399,8 +399,8 @@
function focus(el, fn)
target = fn el
if target?
if target.has-attribute \tabindex
target.focus!
if target.has-attribute 'tabindex'
target.focus();
else
focus target, fn
</script>

View File

@@ -44,36 +44,36 @@
</style>
<script>
@posts = []
this.posts = []
@set-posts = (posts) ~>
@posts = posts
@update!
set-posts(posts) {
this.posts = posts
this.update();
@prepend-posts = (posts) ~>
posts.for-each (post) ~>
prepend-posts(posts) {
posts.for-each (post) =>
@posts.push post
@update!
this.update();
@add-post = (post) ~>
add-post(post) {
@posts.unshift post
@update!
this.update();
@clear = ~>
@posts = []
@update!
clear() {
this.posts = []
this.update();
@focus = ~>
@root.children.0.focus!
focus() {
this.root.children.0.focus();
@on \update ~>
@posts.for-each (post) ~>
this.on('update', () => {
@posts.for-each (post) =>
date = (new Date post.created_at).get-date!
month = (new Date post.created_at).get-month! + 1
post._date = date
post._datetext = month + '月 ' + date + '日'
@tail = ~>
tail() {
@posts[@posts.length - 1]
</script>
</mk-timeline>

View File

@@ -159,47 +159,47 @@
</style>
<script>
@mixin \i
@mixin \signout
this.mixin('i');
this.mixin('signout');
@is-open = false
this.is-open = false
@on \before-unmount ~>
this.on('before-unmount', () => {
@close!
@toggle = ~>
toggle() {
if @is-open
@close!
else
@open!
@open = ~>
@is-open = true
@update!
open() {
this.is-open = true
this.update();
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.add-event-listener \mousedown @mousedown
Array.prototype.for-each.call all, (el) =>
el.add-event-listener 'mousedown' @mousedown
@close = ~>
@is-open = false
@update!
close() {
this.is-open = false
this.update();
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.remove-event-listener \mousedown @mousedown
Array.prototype.for-each.call all, (el) =>
el.remove-event-listener 'mousedown' @mousedown
@mousedown = (e) ~>
mousedown(e) {
e.prevent-default!
if (!contains @root, e.target) and (@root != e.target)
if (!contains this.root, e.target) and (this.root != e.target)
@close!
return false
@drive = ~>
drive() {
@close!
riot.mount document.body.append-child document.create-element \mk-drive-browser-window
riot.mount document.body.appendChild document.createElement 'mk-drive-browser-window'
@settings = ~>
settings() {
@close!
riot.mount document.body.append-child document.create-element \mk-settings-window
riot.mount document.body.appendChild document.createElement 'mk-settings-window'
function contains(parent, child)
node = child.parent-node

View File

@@ -58,7 +58,7 @@
</style>
<script>
@draw = ~>
draw() {
now = new Date!
yyyy = now.get-full-year!
@@ -71,17 +71,17 @@
hhmm = "<span class='hhmm'>#hh:#mm</span>"
if now.get-seconds! % 2 == 0
hhmm .= replace \: '<span style=\'visibility:visible\'>:</span>'
hhmm .= replace ':' '<span style=\'visibility:visible\'>:</span>'
else
hhmm .= replace \: '<span style=\'visibility:hidden\'>:</span>'
hhmm .= replace ':' '<span style=\'visibility:hidden\'>:</span>'
@refs.time.innerHTML = "#yyyymmdd<br>#hhmm"
this.refs.time.innerHTML = "#yyyymmdd<br>#hhmm"
@on \mount ~>
this.on('mount', () => {
@draw!
@clock = set-interval @draw, 1000ms
this.clock = set-interval @draw, 1000ms
@on \unmount ~>
this.on('unmount', () => {
clear-interval @clock
</script>
</mk-ui-header-clock>

View File

@@ -77,37 +77,37 @@
</style>
<script>
@mixin \i
@mixin \api
@mixin \stream
this.mixin('i');
this.mixin('api');
this.mixin('stream');
@page = @opts.page
this.page = this.opts.page
@on \mount ~>
@stream.on \read_all_messaging_messages @on-read-all-messaging-messages
@stream.on \unread_messaging_message @on-unread-messaging-message
this.on('mount', () => {
@stream.on 'read_all_messaging_messages' this.on-read-all-messaging-messages
@stream.on 'unread_messaging_message' this.on-unread-messaging-message
# Fetch count of unread messaging messages
@api \messaging/unread
.then (count) ~>
// Fetch count of unread messaging messages
this.api 'messaging/unread'
.then (count) =>
if count.count > 0
@has-unread-messaging-messages = true
@update!
this.has-unread-messaging-messages = true
this.update();
@on \unmount ~>
@stream.off \read_all_messaging_messages @on-read-all-messaging-messages
@stream.off \unread_messaging_message @on-unread-messaging-message
this.on('unmount', () => {
@stream.off 'read_all_messaging_messages' this.on-read-all-messaging-messages
@stream.off 'unread_messaging_message' this.on-unread-messaging-message
@on-read-all-messaging-messages = ~>
@has-unread-messaging-messages = false
@update!
on-read-all-messaging-messages() {
this.has-unread-messaging-messages = false
this.update();
@on-unread-messaging-message = ~>
@has-unread-messaging-messages = true
@update!
on-unread-messaging-message() {
this.has-unread-messaging-messages = true
this.update();
@messaging = ~>
riot.mount document.body.append-child document.create-element \mk-messaging-window
messaging() {
riot.mount document.body.appendChild document.createElement 'mk-messaging-window'
</script>
</ul>
</mk-ui-header-nav>

View File

@@ -75,31 +75,31 @@
</style>
<script>
@is-open = false
this.is-open = false
@toggle = ~>
toggle() {
if @is-open
@close!
else
@open!
@open = ~>
@is-open = true
@update!
open() {
this.is-open = true
this.update();
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.add-event-listener \mousedown @mousedown
Array.prototype.for-each.call all, (el) =>
el.add-event-listener 'mousedown' @mousedown
@close = ~>
@is-open = false
@update!
close() {
this.is-open = false
this.update();
all = document.query-selector-all 'body *'
Array.prototype.for-each.call all, (el) ~>
el.remove-event-listener \mousedown @mousedown
Array.prototype.for-each.call all, (el) =>
el.remove-event-listener 'mousedown' @mousedown
@mousedown = (e) ~>
mousedown(e) {
e.prevent-default!
if (!contains @root, e.target) and (@root != e.target)
if (!contains this.root, e.target) and (this.root != e.target)
@close!
return false

View File

@@ -35,7 +35,7 @@
</style>
<script>
@post = (e) ~>
@parent.parent.open-post-form!
post(e) {
this.parent.parent.open-post-form!
</script>
</mk-ui-header-post-button>

View File

@@ -32,10 +32,10 @@
</style>
<script>
@mixin \page
this.mixin('page');
@onsubmit = (e) ~>
onsubmit(e) {
e.prevent-default!
@page '/search:' + @refs.q.value
@page '/search:' + this.refs.q.value
</script>
</mk-ui-header-search>

View File

@@ -81,5 +81,5 @@
</style>
<script>@mixin \i</script>
<script>this.mixin('i');</script>
</mk-ui-header>

View File

@@ -22,22 +22,22 @@
</style>
<script>
@on \mount ~>
Velocity @root, {
top: \0px
this.on('mount', () => {
Velocity this.root, {
top: '0px'
} {
duration: 500ms
easing: \ease-out
easing: 'ease-out'
}
set-timeout ~>
Velocity @root, {
top: \-64px
setTimeout =>
Velocity this.root, {
top: '-64px'
} {
duration: 500ms
easing: \ease-out
complete: ~>
@unmount!
easing: 'ease-out'
complete: =>
this.unmount();
}
, 6000ms
</script>

View File

@@ -12,25 +12,25 @@
</style>
<script>
@mixin \i
this.mixin('i');
@open-post-form = ~>
riot.mount document.body.append-child document.create-element \mk-post-form-window
open-post-form() {
riot.mount document.body.appendChild document.createElement 'mk-post-form-window'
@set-root-layout = ~>
@root.style.padding-top = @refs.header.root.client-height + \px
set-root-layout() {
this.root.style.padding-top = this.refs.header.root.client-height + 'px'
@on \mount ~>
this.on('mount', () => {
@set-root-layout!
document.add-event-listener \keydown @onkeydown
document.add-event-listener 'keydown' this.onkeydown
@on \unmount ~>
document.remove-event-listener \keydown @onkeydown
this.on('unmount', () => {
document.remove-event-listener 'keydown' this.onkeydown
@onkeydown = (e) ~>
onkeydown(e) {
tag = e.target.tag-name.to-lower-case!
if tag != \input and tag != \textarea
if e.which == 80 or e.which == 78 # p or n
if tag != 'input' and tag != 'textarea'
if e.which == 80 or e.which == 78 // p or n
e.prevent-default!
@open-post-form!
</script>

View File

@@ -15,5 +15,5 @@
border-radius 4px
</style>
<script>@user = @opts.user</script>
<script>this.user = this.opts.user</script>
</mk-user-followers-window>

View File

@@ -7,12 +7,12 @@
</style>
<script>
@mixin \api
this.mixin('api');
@user = @opts.user
this.user = this.opts.user
@fetch = (iknow, limit, cursor, cb) ~>
@api \users/followers do
fetch(iknow, limit, cursor, cb) {
this.api 'users/followers' do
user_id: @user.id
iknow: iknow
limit: limit

View File

@@ -15,5 +15,5 @@
border-radius 4px
</style>
<script>@user = @opts.user</script>
<script>this.user = this.opts.user</script>
</mk-user-following-window>

View File

@@ -7,12 +7,12 @@
</style>
<script>
@mixin \api
this.mixin('api');
@user = @opts.user
this.user = this.opts.user
@fetch = (iknow, limit, cursor, cb) ~>
@api \users/following do
fetch(iknow, limit, cursor, cb) {
this.api 'users/following' do
user_id: @user.id
iknow: iknow
limit: limit

View File

@@ -8,57 +8,57 @@
</style>
<script>
@mixin \api
@mixin \is-promise
this.mixin('api');
this.mixin('is-promise');
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
@on \mount ~>
this.on('mount', () => {
user <~ @user-promise.then
@user = user
@update!
this.user = user
this.update();
@api \aggregation/users/followers do
this.api 'aggregation/users/followers' do
user_id: @user.id
limit: 30days
.then (followers) ~>
.then (followers) =>
followers = followers.reverse!
@api \aggregation/users/following do
this.api 'aggregation/users/following' do
user_id: @user.id
limit: 30days
.then (following) ~>
.then (following) =>
following = following.reverse!
new Chart @refs.canv, do
type: \line
new Chart this.refs.canv, do
type: 'line'
data:
labels: following.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
labels: following.map (x, i) => if i % 3 == 2 then x.date.day + '日' else ''
datasets: [
{
label: \フォロー
data: following.map (x) ~> x.count
label: 'フォロー'
data: following.map (x) => x.count
line-tension: 0
border-width: 2
fill: true
background-color: 'rgba(127, 221, 64, 0.2)'
point-background-color: \#fff
point-background-color: '#fff'
point-radius: 4
point-border-width: 2
border-color: \#7fdd40
border-color: '#7fdd40'
},
{
label: \フォロワー
data: followers.map (x) ~> x.count
label: 'フォロワー'
data: followers.map (x) => x.count
line-tension: 0
border-width: 2
fill: true
background-color: 'rgba(255, 99, 132, 0.2)'
point-background-color: \#fff
point-background-color: '#fff'
point-radius: 4
point-border-width: 2
border-color: \#FF6384
border-color: '#FF6384'
}
]
options:

View File

@@ -34,7 +34,7 @@
</style>
<script>
@on \mount ~>
@trigger \loaded
this.on('mount', () => {
this.trigger('loaded');
</script>
</mk-user-graphs>

View File

@@ -104,39 +104,39 @@
</style>
<script>
@mixin \i
@mixin \update-banner
@mixin \NotImplementedException
this.mixin('i');
this.mixin('update-banner');
this.mixin('NotImplementedException');
@user = @opts.user
this.user = this.opts.user
@on \mount ~>
window.add-event-listener \load @scroll
window.add-event-listener \scroll @scroll
window.add-event-listener \resize @scroll
this.on('mount', () => {
window.add-event-listener 'load' @scroll
window.add-event-listener 'scroll' @scroll
window.add-event-listener 'resize' @scroll
@on \unmount ~>
window.remove-event-listener \load @scroll
window.remove-event-listener \scroll @scroll
window.remove-event-listener \resize @scroll
this.on('unmount', () => {
window.remove-event-listener 'load' @scroll
window.remove-event-listener 'scroll' @scroll
window.remove-event-listener 'resize' @scroll
@scroll = ~>
scroll() {
top = window.scroll-y
height = 280px
pos = 50 - ((top / height) * 50)
@refs.banner.style.background-position = 'center ' + pos + '%'
this.refs.banner.style.background-position = 'center ' + pos + '%'
blur = top / 32
if blur <= 10
@refs.banner.style.filter = 'blur(' + blur + 'px)'
this.refs.banner.style.filter = 'blur(' + blur + 'px)'
@on-update-banner = ~>
on-update-banner() {
if not @SIGNIN or @I.id != @user.id
return
@update-banner @I, (i) ~>
@update-banner @I, (i) =>
@user.banner_url = i.banner_url
@update!
this.update();
</script>
</mk-user-header>

View File

@@ -35,10 +35,10 @@
</style>
<script>
@user = @opts.user
this.user = this.opts.user
@on \mount ~>
@refs.tl.on \loaded ~>
@trigger \loaded
this.on('mount', () => {
this.refs.tl.on('loaded', () => {
this.trigger('loaded');
</script>
</mk-user-home>

View File

@@ -8,32 +8,32 @@
</style>
<script>
@mixin \api
@mixin \is-promise
this.mixin('api');
this.mixin('is-promise');
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
@on \mount ~>
this.on('mount', () => {
user <~ @user-promise.then
@user = user
@update!
this.user = user
this.update();
@api \aggregation/users/like do
this.api 'aggregation/users/like' do
user_id: @user.id
limit: 30days
.then (likes) ~>
.then (likes) =>
likes = likes.reverse!
new Chart @refs.canv, do
type: \bar
new Chart this.refs.canv, do
type: 'bar'
data:
labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
labels: likes.map (x, i) => if i % 3 == 2 then x.date.day + '日' else ''
datasets: [
{
label: \いいねした数
data: likes.map (x) ~> x.count
background-color: \#F7796C
label: 'いいねした数'
data: likes.map (x) => x.count
background-color: '#F7796C'
}
]
options:

View File

@@ -57,30 +57,30 @@
</style>
<script>
@mixin \api
@mixin \is-promise
this.mixin('api');
this.mixin('is-promise');
@images = []
@initializing = true
this.images = []
this.initializing = true
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
@on \mount ~>
@user-promise.then (user) ~>
@user = user
@update!
this.on('mount', () => {
@user-promise.then (user) =>
this.user = user
this.update();
@api \users/posts do
this.api 'users/posts' do
user_id: @user.id
with_media: true
limit: 9posts
.then (posts) ~>
@initializing = false
posts.for-each (post) ~>
post.media.for-each (image) ~>
.then (posts) =>
this.initializing = false
posts.for-each (post) =>
post.media.for-each (image) =>
if @images.length < 9
@images.push image
@update!
this.update();
</script>
</mk-user-photos>

View File

@@ -8,50 +8,50 @@
</style>
<script>
@mixin \api
@mixin \is-promise
this.mixin('api');
this.mixin('is-promise');
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
@on \mount ~>
this.on('mount', () => {
user <~ @user-promise.then
@user = user
@update!
this.user = user
this.update();
@api \aggregation/users/post do
this.api 'aggregation/users/post' do
user_id: @user.id
limit: 30days
.then (data) ~>
.then (data) =>
data = data.reverse!
new Chart @refs.canv, do
type: \line
new Chart this.refs.canv, do
type: 'line'
data:
labels: data.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
labels: data.map (x, i) => if i % 3 == 2 then x.date.day + '日' else ''
datasets: [
{
label: \投稿
data: data.map (x) ~> x.posts
label: '投稿'
data: data.map (x) => x.posts
line-tension: 0
point-radius: 0
background-color: \#555
border-color: \transparent
background-color: '#555'
border-color: 'transparent'
},
{
label: \Repost
data: data.map (x) ~> x.reposts
label: 'Repost'
data: data.map (x) => x.reposts
line-tension: 0
point-radius: 0
background-color: \#a2d61e
border-color: \transparent
background-color: '#a2d61e'
border-color: 'transparent'
},
{
label: \返信
data: data.map (x) ~> x.replies
label: '返信'
data: data.map (x) => x.replies
line-tension: 0
point-radius: 0
background-color: \#F7796C
border-color: \transparent
background-color: '#F7796C'
border-color: 'transparent'
}
]
options:

View File

@@ -97,47 +97,47 @@
</style>
<script>
@mixin \i
@mixin \api
this.mixin('i');
this.mixin('api');
@u = @opts.user
@user = null
@user-promise =
if typeof @u == \string
new Promise (resolve, reject) ~>
@api \users/show do
user_id: if @u.0 == \@ then undefined else @u
username: if @u.0 == \@ then @u.substr 1 else undefined
.then (user) ~>
this.u = this.opts.user
this.user = null
this.user-promise =
if typeof @u == 'string'
new Promise (resolve, reject) =>
this.api 'users/show' do
user_id: if @u.0 == '@' then undefined else @u
username: if @u.0 == '@' then @u.substr 1 else undefined
.then (user) =>
resolve user
else
Promise.resolve @u
@on \mount ~>
@user-promise.then (user) ~>
@user = user
@update!
this.on('mount', () => {
@user-promise.then (user) =>
this.user = user
this.update();
Velocity @root, {
Velocity this.root, {
opacity: 0
'margin-top': \-8px
'margin-top': '-8px'
} 0ms
Velocity @root, {
Velocity this.root, {
opacity: 1
'margin-top': 0
} {
duration: 200ms
easing: \ease-out
easing: 'ease-out'
}
@close = ~>
Velocity @root, {
close() {
Velocity this.root, {
opacity: 0
'margin-top': \-8px
'margin-top': '-8px'
} {
duration: 200ms
easing: \ease-out
complete: ~> @unmount!
easing: 'ease-out'
complete: => this.unmount();
}
</script>
</mk-user-preview>

View File

@@ -80,19 +80,19 @@
</style>
<script>
@age = require \s-age
this.age = require 's-age'
@mixin \i
this.mixin('i');
@user = @opts.user
this.user = this.opts.user
@show-following = ~>
window = document.body.append-child document.create-element \mk-user-following-window
show-following() {
window = document.body.appendChild document.createElement 'mk-user-following-window'
riot.mount window, do
user: @user
@show-followers = ~>
window = document.body.append-child document.create-element \mk-user-followers-window
show-followers() {
window = document.body.appendChild document.createElement 'mk-user-followers-window'
riot.mount window, do
user: @user
</script>

View File

@@ -46,91 +46,91 @@
</style>
<script>
@mixin \api
@mixin \is-promise
@mixin \get-post-summary
this.mixin('api');
this.mixin('is-promise');
this.mixin('get-post-summary');
@user = null
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
@is-loading = true
@is-empty = false
@more-loading = false
@unread-count = 0
@mode = \default
this.user = null
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user
this.is-loading = true
this.is-empty = false
this.more-loading = false
this.unread-count = 0
this.mode = 'default'
@on \mount ~>
document.add-event-listener \visibilitychange @window-on-visibilitychange, false
document.add-event-listener \keydown @on-document-keydown
window.add-event-listener \scroll @on-scroll
this.on('mount', () => {
document.add-event-listener 'visibilitychange' @window-on-visibilitychange, false
document.add-event-listener 'keydown' this.on-document-keydown
window.add-event-listener 'scroll' this.on-scroll
@user-promise.then (user) ~>
@user = user
@update!
@user-promise.then (user) =>
this.user = user
this.update();
@fetch ~>
@trigger \loaded
@fetch =>
this.trigger('loaded');
@on \unmount ~>
document.remove-event-listener \visibilitychange @window-on-visibilitychange
document.remove-event-listener \keydown @on-document-keydown
window.remove-event-listener \scroll @on-scroll
this.on('unmount', () => {
document.remove-event-listener 'visibilitychange' @window-on-visibilitychange
document.remove-event-listener 'keydown' this.on-document-keydown
window.remove-event-listener 'scroll' this.on-scroll
@on-document-keydown = (e) ~>
on-document-keydown(e) {
tag = e.target.tag-name.to-lower-case!
if tag != \input and tag != \textarea
if e.which == 84 # t
@refs.timeline.focus!
if tag != 'input' and tag != 'textarea'
if e.which == 84 // t
this.refs.timeline.focus();
@fetch = (cb) ~>
@api \users/posts do
fetch(cb) {
this.api 'users/posts' do
user_id: @user.id
with_replies: @mode == \with-replies
.then (posts) ~>
@is-loading = false
@is-empty = posts.length == 0
@update!
@refs.timeline.set-posts posts
with_replies: @mode == 'with-replies'
.then (posts) =>
this.is-loading = false
this.is-empty = posts.length == 0
this.update();
this.refs.timeline.set-posts posts
if cb? then cb!
.catch (err) ~>
.catch (err) =>
console.error err
if cb? then cb!
@more = ~>
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
more() {
if @more-loading or @is-loading or this.refs.timeline.posts.length == 0
return
@more-loading = true
@update!
@api \users/posts do
this.more-loading = true
this.update();
this.api 'users/posts' do
user_id: @user.id
with_replies: @mode == \with-replies
max_id: @refs.timeline.tail!.id
.then (posts) ~>
@more-loading = false
@update!
@refs.timeline.prepend-posts posts
.catch (err) ~>
with_replies: @mode == 'with-replies'
max_id: this.refs.timeline.tail!.id
.then (posts) =>
this.more-loading = false
this.update();
this.refs.timeline.prepend-posts posts
.catch (err) =>
console.error err
@on-stream-post = (post) ~>
@is-empty = false
@update!
@refs.timeline.add-post post
on-stream-post(post) {
this.is-empty = false
this.update();
this.refs.timeline.add-post post
if document.hidden
@unread-count++
document.title = '(' + @unread-count + ') ' + @get-post-summary post
@window-on-visibilitychange = ~>
window-on-visibilitychange() {
if !document.hidden
@unread-count = 0
this.unread-count = 0
document.title = 'Misskey'
@on-scroll = ~>
on-scroll() {
current = window.scroll-y + window.inner-height
if current > document.body.offset-height - 16 # 遊び
if current > document.body.offset-height - 16 // 遊び
@more!
@set-mode = (mode) ~>
set-mode(mode) {
@update do
mode: mode
@fetch!

View File

@@ -32,20 +32,20 @@
</style>
<script>
@mixin \api
this.mixin('api');
@username = @opts.user
@page = if @opts.page? then @opts.page else \home
@fetching = true
@user = null
this.username = this.opts.user
this.page = if this.opts.page? then this.opts.page else 'home'
this.fetching = true
this.user = null
@on \mount ~>
@api \users/show do
this.on('mount', () => {
this.api 'users/show' do
username: @username
.then (user) ~>
@fetching = false
@user = user
@update!
@trigger \loaded
.then (user) =>
this.fetching = false
this.user = user
this.update();
this.trigger('loaded');
</script>
</mk-user>

View File

@@ -88,44 +88,44 @@
</style>
<script>
@mixin \i
this.mixin('i');
@limit = 30users
@mode = \all
this.limit = 30users
this.mode = 'all'
@fetching = true
@more-fetching = false
this.fetching = true
this.more-fetching = false
@on \mount ~>
@fetch ~>
@trigger \loaded
this.on('mount', () => {
@fetch =>
this.trigger('loaded');
@fetch = (cb) ~>
@fetching = true
@update!
obj <~ @opts.fetch do
@mode == \iknow
fetch(cb) {
this.fetching = true
this.update();
obj <~ this.opts.fetch do
@mode == 'iknow'
@limit
null
@users = obj.users
@next = obj.next
@fetching = false
@update!
this.users = obj.users
this.next = obj.next
this.fetching = false
this.update();
if cb? then cb!
@more = ~>
@more-fetching = true
@update!
obj <~ @opts.fetch do
@mode == \iknow
more() {
this.more-fetching = true
this.update();
obj <~ this.opts.fetch do
@mode == 'iknow'
@limit
@cursor
@users = @users.concat obj.users
@next = obj.next
@more-fetching = false
@update!
this.users = @users.concat obj.users
this.next = obj.next
this.more-fetching = false
this.update();
@set-mode = (mode) ~>
set-mode(mode) {
@update do
mode: mode

View File

@@ -192,101 +192,101 @@
</style>
<script>
@min-height = 40px
@min-width = 200px
this.min-height = 40px
this.min-width = 200px
@is-modal = if @opts.is-modal? then @opts.is-modal else false
@can-close = if @opts.can-close? then @opts.can-close else true
@is-flexible = !@opts.height?
@can-resize = not @is-flexible
this.is-modal = if this.opts.is-modal? then this.opts.is-modal else false
this.can-close = if this.opts.can-close? then this.opts.can-close else true
this.is-flexible = !this.opts.height?
this.can-resize = not @is-flexible
@on \mount ~>
@refs.main.style.width = @opts.width || \530px
@refs.main.style.height = @opts.height || \auto
this.on('mount', () => {
this.refs.main.style.width = this.opts.width || '530px'
this.refs.main.style.height = this.opts.height || 'auto'
@refs.main.style.top = \15%
@refs.main.style.left = (window.inner-width / 2) - (@refs.main.offset-width / 2) + \px
this.refs.main.style.top = '15%'
this.refs.main.style.left = (window.inner-width / 2) - (this.refs.main.offset-width / 2) + 'px'
@refs.header.add-event-listener \contextmenu (e) ~>
this.refs.header.add-event-listener 'contextmenu' (e) =>
e.prevent-default!
window.add-event-listener \resize @on-browser-resize
window.add-event-listener 'resize' this.on-browser-resize
@open!
@on \unmount ~>
window.remove-event-listener \resize @on-browser-resize
this.on('unmount', () => {
window.remove-event-listener 'resize' this.on-browser-resize
@on-browser-resize = ~>
position = @refs.main.get-bounding-client-rect!
on-browser-resize() {
position = this.refs.main.get-bounding-client-rect!
browser-width = window.inner-width
browser-height = window.inner-height
window-width = @refs.main.offset-width
window-height = @refs.main.offset-height
window-width = this.refs.main.offset-width
window-height = this.refs.main.offset-height
if position.left < 0
@refs.main.style.left = 0
this.refs.main.style.left = 0
if position.top < 0
@refs.main.style.top = 0
this.refs.main.style.top = 0
if position.left + window-width > browser-width
@refs.main.style.left = browser-width - window-width + \px
this.refs.main.style.left = browser-width - window-width + 'px'
if position.top + window-height > browser-height
@refs.main.style.top = browser-height - window-height + \px
this.refs.main.style.top = browser-height - window-height + 'px'
@open = ~>
@trigger \opening
open() {
this.trigger('opening');
@top!
if @is-modal
@refs.bg.style.pointer-events = \auto
Velocity @refs.bg, \finish true
Velocity @refs.bg, {
this.refs.bg.style.pointer-events = 'auto'
Velocity this.refs.bg, 'finish' true
Velocity this.refs.bg, {
opacity: 1
} {
queue: false
duration: 100ms
easing: \linear
easing: 'linear'
}
@refs.main.style.pointer-events = \auto
Velocity @refs.main, \finish true
Velocity @refs.main, {scale: 1.1} 0ms
Velocity @refs.main, {
this.refs.main.style.pointer-events = 'auto'
Velocity this.refs.main, 'finish' true
Velocity this.refs.main, {scale: 1.1} 0ms
Velocity this.refs.main, {
opacity: 1
scale: 1
} {
queue: false
duration: 200ms
easing: \ease-out
easing: 'ease-out'
}
#@refs.main.focus!
#this.refs.main.focus();
set-timeout ~>
@trigger \opened
setTimeout =>
this.trigger('opened');
, 300ms
@close = ~>
@trigger \closing
close() {
this.trigger('closing');
if @is-modal
@refs.bg.style.pointer-events = \none
Velocity @refs.bg, \finish true
Velocity @refs.bg, {
this.refs.bg.style.pointer-events = 'none'
Velocity this.refs.bg, 'finish' true
Velocity this.refs.bg, {
opacity: 0
} {
queue: false
duration: 300ms
easing: \linear
easing: 'linear'
}
@refs.main.style.pointer-events = \none
Velocity @refs.main, \finish true
Velocity @refs.main, {
this.refs.main.style.pointer-events = 'none'
Velocity this.refs.main, 'finish' true
Velocity this.refs.main, {
opacity: 0
scale: 0.8
} {
@@ -295,45 +295,45 @@
easing: [ 0.5, -0.5, 1, 0.5 ]
}
set-timeout ~>
@trigger \closed
setTimeout =>
this.trigger('closed');
, 300ms
# 最前面へ移動します
@top = ~>
// 最前面へ移動します
top() {
z = 0
ws = document.query-selector-all \mk-window
ws.for-each (w) !~>
if w == @root then return
ws = document.query-selector-all 'mk-window'
ws.for-each (w) !=>
if w == this.root then return
m = w.query-selector ':scope > .main'
mz = Number(document.default-view.get-computed-style m, null .z-index)
if mz > z then z := mz
if z > 0
@refs.main.style.z-index = z + 1
if @is-modal then @refs.bg.style.z-index = z + 1
this.refs.main.style.z-index = z + 1
if @is-modal then this.refs.bg.style.z-index = z + 1
@repel-move = (e) ~>
repel-move(e) {
e.stop-propagation!
return true
@bg-click = ~>
bg-click() {
if @can-close
@close!
@on-body-mousedown = (e) ~>
on-body-mousedown(e) {
@top!
true
# ヘッダー掴み時
@on-header-mousedown = (e) ~>
// ヘッダー掴み時
on-header-mousedown(e) {
e.prevent-default!
if not contains @refs.main, document.active-element
@refs.main.focus!
if not contains this.refs.main, document.active-element
this.refs.main.focus();
position = @refs.main.get-bounding-client-rect!
position = this.refs.main.get-bounding-client-rect!
click-x = e.client-x
click-y = e.client-y
@@ -341,168 +341,168 @@
move-base-y = click-y - position.top
browser-width = window.inner-width
browser-height = window.inner-height
window-width = @refs.main.offset-width
window-height = @refs.main.offset-height
window-width = this.refs.main.offset-width
window-height = this.refs.main.offset-height
# 動かした時
drag-listen (me) ~>
// 動かした時
drag-listen (me) =>
move-left = me.client-x - move-base-x
move-top = me.client-y - move-base-y
# 上はみ出し
// 上はみ出し
if move-top < 0
move-top = 0
# 左はみ出し
// 左はみ出し
if move-left < 0
move-left = 0
# 下はみ出し
// 下はみ出し
if move-top + window-height > browser-height
move-top = browser-height - window-height
# 右はみ出し
// 右はみ出し
if move-left + window-width > browser-width
move-left = browser-width - window-width
@refs.main.style.left = move-left + \px
@refs.main.style.top = move-top + \px
this.refs.main.style.left = move-left + 'px'
this.refs.main.style.top = move-top + 'px'
# 上ハンドル掴み時
@on-top-handle-mousedown = (e) ~>
// 上ハンドル掴み時
on-top-handle-mousedown(e) {
e.prevent-default!
base = e.client-y
height = parse-int((get-computed-style @refs.main, '').height, 10)
top = parse-int((get-computed-style @refs.main, '').top, 10)
height = parse-int((get-computed-style this.refs.main, '').height, 10)
top = parse-int((get-computed-style this.refs.main, '').top, 10)
# 動かした時
drag-listen (me) ~>
// 動かした時
drag-listen (me) =>
move = me.client-y - base
if top + move > 0
if height + -move > @min-height
@apply-transform-height height + -move
@apply-transform-top top + move
else # 最小の高さより小さくなろうとした時
else // 最小の高さより小さくなろうとした時
@apply-transform-height @min-height
@apply-transform-top top + (height - @min-height)
else # 上のはみ出し時
else // 上のはみ出し時
@apply-transform-height top + height
@apply-transform-top 0
# 右ハンドル掴み時
@on-right-handle-mousedown = (e) ~>
// 右ハンドル掴み時
on-right-handle-mousedown(e) {
e.prevent-default!
base = e.client-x
width = parse-int((get-computed-style @refs.main, '').width, 10)
left = parse-int((get-computed-style @refs.main, '').left, 10)
width = parse-int((get-computed-style this.refs.main, '').width, 10)
left = parse-int((get-computed-style this.refs.main, '').left, 10)
browser-width = window.inner-width
# 動かした時
drag-listen (me) ~>
// 動かした時
drag-listen (me) =>
move = me.client-x - base
if left + width + move < browser-width
if width + move > @min-width
@apply-transform-width width + move
else # 最小の幅より小さくなろうとした時
else // 最小の幅より小さくなろうとした時
@apply-transform-width @min-width
else # 右のはみ出し時
else // 右のはみ出し時
@apply-transform-width browser-width - left
# 下ハンドル掴み時
@on-bottom-handle-mousedown = (e) ~>
// 下ハンドル掴み時
on-bottom-handle-mousedown(e) {
e.prevent-default!
base = e.client-y
height = parse-int((get-computed-style @refs.main, '').height, 10)
top = parse-int((get-computed-style @refs.main, '').top, 10)
height = parse-int((get-computed-style this.refs.main, '').height, 10)
top = parse-int((get-computed-style this.refs.main, '').top, 10)
browser-height = window.inner-height
# 動かした時
drag-listen (me) ~>
// 動かした時
drag-listen (me) =>
move = me.client-y - base
if top + height + move < browser-height
if height + move > @min-height
@apply-transform-height height + move
else # 最小の高さより小さくなろうとした時
else // 最小の高さより小さくなろうとした時
@apply-transform-height @min-height
else # 下のはみ出し時
else // 下のはみ出し時
@apply-transform-height browser-height - top
# 左ハンドル掴み時
@on-left-handle-mousedown = (e) ~>
// 左ハンドル掴み時
on-left-handle-mousedown(e) {
e.prevent-default!
base = e.client-x
width = parse-int((get-computed-style @refs.main, '').width, 10)
left = parse-int((get-computed-style @refs.main, '').left, 10)
width = parse-int((get-computed-style this.refs.main, '').width, 10)
left = parse-int((get-computed-style this.refs.main, '').left, 10)
# 動かした時
drag-listen (me) ~>
// 動かした時
drag-listen (me) =>
move = me.client-x - base
if left + move > 0
if width + -move > @min-width
@apply-transform-width width + -move
@apply-transform-left left + move
else # 最小の幅より小さくなろうとした時
else // 最小の幅より小さくなろうとした時
@apply-transform-width @min-width
@apply-transform-left left + (width - @min-width)
else # 左のはみ出し時
else // 左のはみ出し時
@apply-transform-width left + width
@apply-transform-left 0
# 左上ハンドル掴み時
@on-top-left-handle-mousedown = (e) ~>
@on-top-handle-mousedown e
@on-left-handle-mousedown e
// 左上ハンドル掴み時
on-top-left-handle-mousedown(e) {
this.on-top-handle-mousedown e
this.on-left-handle-mousedown e
# 右上ハンドル掴み時
@on-top-right-handle-mousedown = (e) ~>
@on-top-handle-mousedown e
@on-right-handle-mousedown e
// 右上ハンドル掴み時
on-top-right-handle-mousedown(e) {
this.on-top-handle-mousedown e
this.on-right-handle-mousedown e
# 右下ハンドル掴み時
@on-bottom-right-handle-mousedown = (e) ~>
@on-bottom-handle-mousedown e
@on-right-handle-mousedown e
// 右下ハンドル掴み時
on-bottom-right-handle-mousedown(e) {
this.on-bottom-handle-mousedown e
this.on-right-handle-mousedown e
# 左下ハンドル掴み時
@on-bottom-left-handle-mousedown = (e) ~>
@on-bottom-handle-mousedown e
@on-left-handle-mousedown e
// 左下ハンドル掴み時
on-bottom-left-handle-mousedown(e) {
this.on-bottom-handle-mousedown e
this.on-left-handle-mousedown e
# 高さを適用
@apply-transform-height = (height) ~>
@refs.main.style.height = height + \px
// 高さを適用
apply-transform-height(height) {
this.refs.main.style.height = height + 'px'
# 幅を適用
@apply-transform-width = (width) ~>
@refs.main.style.width = width + \px
// 幅を適用
apply-transform-width(width) {
this.refs.main.style.width = width + 'px'
# Y座標を適用
@apply-transform-top = (top) ~>
@refs.main.style.top = top + \px
// Y座標を適用
apply-transform-top(top) {
this.refs.main.style.top = top + 'px'
# X座標を適用
@apply-transform-left = (left) ~>
@refs.main.style.left = left + \px
// X座標を適用
apply-transform-left(left) {
this.refs.main.style.left = left + 'px'
function drag-listen fn
window.add-event-listener \mousemove fn
window.add-event-listener \mouseleave drag-clear.bind null fn
window.add-event-listener \mouseup drag-clear.bind null fn
window.add-event-listener 'mousemove' fn
window.add-event-listener 'mouseleave' drag-clear.bind null fn
window.add-event-listener 'mouseup' drag-clear.bind null fn
function drag-clear fn
window.remove-event-listener \mousemove fn
window.remove-event-listener \mouseleave drag-clear
window.remove-event-listener \mouseup drag-clear
window.remove-event-listener 'mousemove' fn
window.remove-event-listener 'mouseleave' drag-clear
window.remove-event-listener 'mouseup' drag-clear
@ondragover = (e) ~>
e.data-transfer.drop-effect = \none
ondragover(e) {
e.data-transfer.drop-effect = 'none'
@on-keydown = (e) ~>
if e.which == 27 # Esc
on-keydown(e) {
if e.which == 27 // Esc
if @can-close
e.prevent-default!
e.stop-propagation!