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

@ -106,21 +106,21 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@session = @opts.session this.session = this.opts.session
@app = @session.app this.app = @session.app
@cancel = ~> cancel() {
@api \auth/deny do this.api 'auth/deny' do
token: @session.token token: @session.token
.then ~> .then =>
@trigger \denied this.trigger('denied');
@accept = ~> accept() {
@api \auth/accept do this.api 'auth/accept' do
token: @session.token token: @session.token
.then ~> .then =>
@trigger \accepted this.trigger('accepted');
</script> </script>
</mk-form> </mk-form>

View file

@ -88,48 +88,48 @@
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
@mixin \api this.mixin('api');
@state = null this.state = null
@fetching = true this.fetching = true
@token = window.location.href.split \/ .pop! this.token = window.location.href.split '/' .pop!
@on \mount ~> this.on('mount', () => {
if not @SIGNIN then return if not @SIGNIN then return
# Fetch session // Fetch session
@api \auth/session/show do this.api 'auth/session/show' do
token: @token token: @token
.then (session) ~> .then (session) =>
@session = session this.session = session
@fetching = false this.fetching = false
# 既に連携していた場合 // 既に連携していた場合
if @session.app.is_authorized if @session.app.is_authorized
@api \auth/accept do this.api 'auth/accept' do
token: @session.token token: @session.token
.then ~> .then =>
@accepted! @accepted!
else else
@state = \waiting this.state = 'waiting'
@update! this.update();
@refs.form.on \denied ~> this.refs.form.on('denied', () => {
@state = \denied this.state = 'denied'
@update! this.update();
@refs.form.on \accepted @accepted this.refs.form.on 'accepted' @accepted
.catch (error) ~> .catch (error) =>
@fetching = false this.fetching = false
@state = \fetch-session-error this.state = 'fetch-session-error'
@update! this.update();
@accepted = ~> accepted() {
@state = \accepted this.state = 'accepted'
@update! this.update();
if @session.app.callback_url if @session.app.callback_url
location.href = @session.app.callback_url + '?token=' + @session.token location.href = @session.app.callback_url + '?token=' + @session.token

View file

@ -21,6 +21,6 @@
text-decoration underline text-decoration underline
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
</script> </script>
</mk-api-info> </mk-api-info>

View file

@ -17,18 +17,18 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@apps = [] this.apps = []
@fetching = true this.fetching = true
@on \mount ~> this.on('mount', () => {
@api \i/authorized_apps this.api 'i/authorized_apps'
.then (apps) ~> .then (apps) =>
@apps = apps this.apps = apps
@fetching = false this.fetching = false
@update! this.update();
.catch (err) ~> .catch (err) =>
console.error err console.error err
</script> </script>
</mk-authorized-apps> </mk-authorized-apps>

View file

@ -57,8 +57,8 @@
</style> </style>
<script> <script>
@retry = ~> retry() {
@unmount! this.unmount();
@opts.retry! this.opts.retry!
</script> </script>
</mk-core-error> </mk-core-error>

View file

@ -5,6 +5,6 @@
display inline display inline
</style> </style>
<script> <script>
@kind = @opts.type.split \/ .0 this.kind = this.opts.type.split '/' .0
</script> </script>
</mk-file-type-icon> </mk-file-type-icon>

View file

@ -2,9 +2,15 @@
<textarea ref="text" onkeypress={ onkeypress } onpaste={ onpaste } placeholder="ここにメッセージを入力"></textarea> <textarea ref="text" onkeypress={ onkeypress } onpaste={ onpaste } placeholder="ここにメッセージを入力"></textarea>
<div class="files"></div> <div class="files"></div>
<mk-uploader ref="uploader"></mk-uploader> <mk-uploader ref="uploader"></mk-uploader>
<button class="send" onclick={ send } disabled={ sending } title="メッセージを送信"><i class="fa fa-paper-plane" if={ !sending }></i><i class="fa fa-spinner fa-spin" if={ sending }></i></button> <button class="send" onclick={ send } disabled={ sending } title="メッセージを送信">
<button class="attach-from-local" type="button" title="PCから画像を添付する"><i class="fa fa-upload"></i></button> <i class="fa fa-paper-plane" if={ !sending }></i><i class="fa fa-spinner fa-spin" if={ sending }></i>
<button class="attach-from-drive" type="button" title="アルバムから画像を添付する"><i class="fa fa-folder-open"></i></button> </button>
<button class="attach-from-local" type="button" title="PCから画像を添付する">
<i class="fa fa-upload"></i>
</button>
<button class="attach-from-drive" type="button" title="アルバムから画像を添付する">
<i class="fa fa-folder-open"></i>
</button>
<input name="file" type="file" accept="image/*"/> <input name="file" type="file" accept="image/*"/>
<style> <style>
:scope :scope
@ -111,49 +117,56 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@onpaste = (e) ~> onpaste(e) {
data = e.clipboard-data const data = e.clipboardData;
items = data.items const items = data.items;
for i from 0 to items.length - 1 for (let i = 0; i < items.length; i++) {
item = items[i] const item = items[i];
switch (item.kind) if (item.kind == 'file') {
| \file => this.upload(item.getAsFile());
@upload item.get-as-file! }
}
}
@onkeypress = (e) ~> onkeypress(e) {
if (e.which == 10 || e.which == 13) && e.ctrl-key if ((e.which == 10 || e.which == 13) && e.ctrlKey) {
@send! this.send();
}
}
@select-file = ~> selectFile() {
@refs.file.click! this.refs.file.click();
}
@select-file-from-drive = ~> selectFileFromDrive() {
browser = document.body.append-child document.create-element \mk-select-file-from-drive-window const browser = document.body.appendChild(document.createElement('mk-select-file-from-drive-window'));
event = riot.observable! const event = riot.observable();
riot.mount browser, do riot.mount(browser, {
multiple: true multiple: true,
event: event event: event
event.one \selected (files) ~> });
files.for-each @add-file event.one('selected', files => {
files.forEach(this.addFile);
});
@send = ~> send() {
@sending = true this.sending = true
@api \messaging/messages/create do this.api 'messaging/messages/create' do
user_id: @opts.user.id user_id: this.opts.user.id
text: @refs.text.value text: this.refs.text.value
.then (message) ~> .then (message) =>
@clear! @clear!
.catch (err) ~> .catch (err) =>
console.error err console.error err
.then ~> .then =>
@sending = false this.sending = false
@update! this.update();
@clear = ~> clear() {
@refs.text.value = '' this.refs.text.value = ''
@files = [] this.files = []
@update! this.update();
</script> </script>
</mk-messaging-form> </mk-messaging-form>

View file

@ -286,72 +286,72 @@
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
@mixin \api this.mixin('api');
@search-result = [] this.search-result = []
@on \mount ~> this.on('mount', () => {
@api \messaging/history this.api 'messaging/history'
.then (history) ~> .then (history) =>
@is-loading = false this.is-loading = false
history.for-each (message) ~> history.for-each (message) =>
message.is_me = message.user_id == @I.id message.is_me = message.user_id == @I.id
message._click = ~> message._click = =>
if message.is_me if message.is_me
@trigger \navigate-user message.recipient this.trigger 'navigate-user' message.recipient
else else
@trigger \navigate-user message.user this.trigger 'navigate-user' message.user
@history = history this.history = history
@update! this.update();
.catch (err) ~> .catch (err) =>
console.error err console.error err
@search = ~> search() {
q = @refs.search.value q = this.refs.search.value
if q == '' if q == ''
@search-result = [] this.search-result = []
else else
@api \users/search do this.api 'users/search' do
query: q query: q
max: 5 max: 5
.then (users) ~> .then (users) =>
users.for-each (user) ~> users.for-each (user) =>
user._click = ~> user._click = =>
@trigger \navigate-user user this.trigger 'navigate-user' user
@search-result = [] this.search-result = []
@search-result = users this.search-result = users
@update! this.update();
.catch (err) ~> .catch (err) =>
console.error err console.error err
@on-search-keydown = (e) ~> on-search-keydown(e) {
key = e.which key = e.which
switch (key) switch (key)
| 9, 40 => # Key[TAB] or Key[↓] | 9, 40 => // Key[TAB] or Key[↓]
e.prevent-default! e.prevent-default!
e.stop-propagation! e.stop-propagation!
@refs.search-result.child-nodes[0].focus! this.refs.search-result.child-nodes[0].focus();
@on-search-result-keydown = (i, e) ~> on-search-result-keydown(i, e) {
key = e.which key = e.which
switch (key) switch (key)
| 10, 13 => # Key[ENTER] | 10, 13 => // Key[ENTER]
e.prevent-default! e.prevent-default!
e.stop-propagation! e.stop-propagation!
@search-result[i]._click! @search-result[i]._click!
| 27 => # Key[ESC] | 27 => // Key[ESC]
e.prevent-default! e.prevent-default!
e.stop-propagation! e.stop-propagation!
@refs.search.focus! this.refs.search.focus();
| 38 => # Key[↑] | 38 => // Key[↑]
e.prevent-default! e.prevent-default!
e.stop-propagation! e.stop-propagation!
(@refs.search-result.child-nodes[i].previous-element-sibling || @refs.search-result.child-nodes[@search-result.length - 1]).focus! (this.refs.search-result.child-nodes[i].previous-element-sibling || this.refs.search-result.child-nodes[@search-result.length - 1]).focus();
| 9, 40 => # Key[TAB] or Key[↓] | 9, 40 => // Key[TAB] or Key[↓]
e.prevent-default! e.prevent-default!
e.stop-propagation! e.stop-propagation!
(@refs.search-result.child-nodes[i].next-element-sibling || @refs.search-result.child-nodes[0]).focus! (this.refs.search-result.child-nodes[i].next-element-sibling || this.refs.search-result.child-nodes[0]).focus();
</script> </script>
</mk-messaging> </mk-messaging>

View file

@ -203,27 +203,27 @@
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
@mixin \text this.mixin('text');
@message = @opts.message this.message = this.opts.message
@message.is_me = @message.user.id == @I.id @message.is_me = @message.user.id == @I.id
@on \mount ~> this.on('mount', () => {
if @message.text? if @message.text?
tokens = @analyze @message.text tokens = @analyze @message.text
@refs.text.innerHTML = @compile tokens this.refs.text.innerHTML = @compile tokens
@refs.text.children.for-each (e) ~> this.refs.text.children.for-each (e) =>
if e.tag-name == \MK-URL if e.tag-name == 'MK-URL'
riot.mount e riot.mount e
# URLをプレビュー // URLをプレビュー
tokens tokens
.filter (t) -> t.type == \link .filter (t) -> t.type == 'link'
.map (t) ~> .map (t) =>
@preview = @refs.text.append-child document.create-element \mk-url-preview this.preview = this.refs.text.appendChild document.createElement 'mk-url-preview'
riot.mount @preview, do riot.mount @preview, do
url: t.content url: t.content
</script> </script>

View file

@ -124,101 +124,101 @@
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
@mixin \api this.mixin('api');
@mixin \messaging-stream this.mixin('messaging-stream');
@user = @opts.user this.user = this.opts.user
@init = true this.init = true
@sending = false this.sending = false
@messages = [] this.messages = []
@connection = new @MessagingStreamConnection @I, @user.id this.connection = new @MessagingStreamConnection @I, @user.id
@on \mount ~> this.on('mount', () => {
@connection.event.on \message @on-message @connection.event.on 'message' this.on-message
@connection.event.on \read @on-read @connection.event.on 'read' this.on-read
document.add-event-listener \visibilitychange @on-visibilitychange document.add-event-listener 'visibilitychange' this.on-visibilitychange
@api \messaging/messages do this.api 'messaging/messages' do
user_id: @user.id user_id: @user.id
.then (messages) ~> .then (messages) =>
@init = false this.init = false
@messages = messages.reverse! this.messages = messages.reverse!
@update! this.update();
@scroll-to-bottom! @scroll-to-bottom!
.catch (err) ~> .catch (err) =>
console.error err console.error err
@on \unmount ~> this.on('unmount', () => {
@connection.event.off \message @on-message @connection.event.off 'message' this.on-message
@connection.event.off \read @on-read @connection.event.off 'read' this.on-read
@connection.close! @connection.close!
document.remove-event-listener \visibilitychange @on-visibilitychange document.remove-event-listener 'visibilitychange' this.on-visibilitychange
@on \update ~> this.on('update', () => {
@messages.for-each (message) ~> @messages.for-each (message) =>
date = (new Date message.created_at).get-date! date = (new Date message.created_at).get-date!
month = (new Date message.created_at).get-month! + 1 month = (new Date message.created_at).get-month! + 1
message._date = date message._date = date
message._datetext = month + '月 ' + date + '日' message._datetext = month + '月 ' + date + '日'
@on-message = (message) ~> on-message(message) {
is-bottom = @is-bottom! is-bottom = @is-bottom!
@messages.push message @messages.push message
if message.user_id != @I.id and not document.hidden if message.user_id != @I.id and not document.hidden
@connection.socket.send JSON.stringify do @connection.socket.send JSON.stringify do
type: \read type: 'read'
id: message.id id: message.id
@update! this.update();
if is-bottom if is-bottom
# Scroll to bottom // Scroll to bottom
@scroll-to-bottom! @scroll-to-bottom!
else if message.user_id != @I.id else if message.user_id != @I.id
# Notify // Notify
@notify '新しいメッセージがあります' @notify '新しいメッセージがあります'
@on-read = (ids) ~> on-read(ids) {
if not Array.isArray ids then ids = [ids] if not Array.isArray ids then ids = [ids]
ids.for-each (id) ~> ids.for-each (id) =>
if (@messages.some (x) ~> x.id == id) if (@messages.some (x) => x.id == id)
exist = (@messages.map (x) -> x.id).index-of id exist = (@messages.map (x) -> x.id).index-of id
@messages[exist].is_read = true @messages[exist].is_read = true
@update! this.update();
@is-bottom = ~> is-bottom() {
current = @root.scroll-top + @root.offset-height current = this.root.scroll-top + this.root.offset-height
max = @root.scroll-height max = this.root.scroll-height
current > (max - 32) current > (max - 32)
@scroll-to-bottom = ~> scroll-to-bottom() {
@root.scroll-top = @root.scroll-height this.root.scroll-top = this.root.scroll-height
@notify = (message) ~> notify(message) {
n = document.create-element \p n = document.createElement 'p'
n.inner-HTML = '<i class="fa fa-arrow-circle-down"></i>' + message n.inner-HTML = '<i class="fa fa-arrow-circle-down"></i>' + message
n.onclick = ~> n.onclick = =>
@scroll-to-bottom! @scroll-to-bottom!
n.parent-node.remove-child n n.parent-node.remove-child n
@refs.notifications.append-child n this.refs.notifications.appendChild n
set-timeout ~> setTimeout =>
n.style.opacity = 0 n.style.opacity = 0
set-timeout ~> setTimeout =>
n.parent-node.remove-child n n.parent-node.remove-child n
, 1000ms , 1000ms
, 4000ms , 4000ms
@on-visibilitychange = ~> on-visibilitychange() {
if document.hidden then return if document.hidden then return
@messages.for-each (message) ~> @messages.for-each (message) =>
if message.user_id != @I.id and not message.is_read if message.user_id != @I.id and not message.is_read
@connection.socket.send JSON.stringify do @connection.socket.send JSON.stringify do
type: \read type: 'read'
id: message.id id: message.id
</script> </script>
</mk-messaging-room> </mk-messaging-room>

View file

@ -5,14 +5,14 @@
</style> </style>
<script> <script>
@on \mount ~> this.on('mount', () => {
# バグ? https://github.com/riot/riot/issues/2103 // バグ? https://github.com/riot/riot/issues/2103
#value = @opts.value #value = this.opts.value
value = @opts.riot-value value = this.opts.riot-value
max = @opts.max max = this.opts.max
if max? then if value > max then value = max if max? then if value > max then value = max
@root.innerHTML = value.to-locale-string! this.root.innerHTML = value.to-locale-string!
</script> </script>
</mk-number> </mk-number>

View file

@ -86,24 +86,24 @@
</style> </style>
<script> <script>
@choices = ['', ''] this.choices = ['', '']
@oninput = (i, e) ~> oninput(i, e) {
@choices[i] = e.target.value @choices[i] = e.target.value
@add = ~> add() {
@choices.push '' @choices.push ''
@update! this.update();
@refs.choices.child-nodes[@choices.length - 1].child-nodes[0].focus! this.refs.choices.child-nodes[@choices.length - 1].child-nodes[0].focus();
@remove = (i) ~> remove(i) {
@choices = @choices.filter((_, _i) -> _i != i) this.choices = @choices.filter((_, _i) -> _i != i)
@update! this.update();
@destroy = ~> destroy() {
@opts.ondestroy! this.opts.ondestroy!
@get = ~> get() {
return { return {
choices: @choices.filter (choice) -> choice != '' choices: @choices.filter (choice) -> choice != ''
} }

View file

@ -68,23 +68,23 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@post = @opts.post this.post = this.opts.post
@poll = @post.poll this.poll = @post.poll
@total = @poll.choices.reduce ((a, b) -> a + b.votes), 0 this.total = @poll.choices.reduce ((a, b) -> a + b.votes), 0
@is-voted = @poll.choices.some (c) -> c.is_voted this.is-voted = @poll.choices.some (c) -> c.is_voted
@result = @is-voted this.result = @is-voted
@toggle-result = ~> toggle-result() {
@result = !@result this.result = !@result
@vote = (id) ~> vote(id) {
if (@poll.choices.some (c) -> c.is_voted) then return if (@poll.choices.some (c) -> c.is_voted) then return
@api \posts/polls/vote do this.api 'posts/polls/vote' do
post_id: @post.id post_id: @post.id
choice: id choice: id
.then ~> .then =>
@poll.choices.for-each (c) -> @poll.choices.for-each (c) ->
if c.id == id if c.id == id
c.votes++ c.votes++

View file

@ -4,5 +4,5 @@
display inline display inline
</style> </style>
<script>@root.innerHTML = @opts.content</script> <script>this.root.innerHTML = this.opts.content</script>
</mk-raw> </mk-raw>

View file

@ -14,13 +14,13 @@
</style> </style>
<script> <script>
@on \mount ~> this.on('mount', () => {
text = @root.innerHTML text = this.root.innerHTML
@root.innerHTML = '' this.root.innerHTML = ''
(text.split '').for-each (c, i) ~> (text.split '').for-each (c, i) =>
ce = document.create-element \span ce = document.createElement 'span'
ce.innerHTML = c ce.innerHTML = c
ce.style.animation-delay = (i / 10) + 's' ce.style.animationDelay = (i / 10) + 's'
@root.append-child ce this.root.appendChild ce
</script> </script>
</mk-ripple-string> </mk-ripple-string>

View file

@ -48,28 +48,28 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@mixin \stream this.mixin('stream');
@history = [] this.history = []
@fetching = true this.fetching = true
@on \mount ~> this.on('mount', () => {
@api \i/signin_history this.api 'i/signin_history'
.then (history) ~> .then (history) =>
@history = history this.history = history
@fetching = false this.fetching = false
@update! this.update();
.catch (err) ~> .catch (err) =>
console.error err console.error err
@stream.on \signin @on-signin @stream.on 'signin' this.on-signin
@on \unmount ~> this.on('unmount', () => {
@stream.off \signin @on-signin @stream.off 'signin' this.on-signin
@on-signin = (signin) ~> on-signin(signin) {
@history.unshift signin @history.unshift signin
@update! this.update();
</script> </script>
</mk-signin-history> </mk-signin-history>

View file

@ -97,41 +97,41 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@user = null this.user = null
@signing = false this.signing = false
@oninput = ~> oninput() {
@api \users/show do this.api 'users/show' do
username: @refs.username.value username: this.refs.username.value
.then (user) ~> .then (user) =>
@user = user this.user = user
@trigger \user user this.trigger 'user' user
@update! this.update();
@onsubmit = (e) ~> onsubmit(e) {
e.prevent-default! e.prevent-default!
if @refs.username.value == '' if this.refs.username.value == ''
@refs.username.focus! this.refs.username.focus();
return false return false
if @refs.password.value == '' if this.refs.password.value == ''
@refs.password.focus! this.refs.password.focus();
return false return false
@signing = true this.signing = true
@update! this.update();
@api \signin do this.api 'signin' do
username: @refs.username.value username: this.refs.username.value
password: @refs.password.value password: this.refs.password.value
.then ~> .then =>
location.reload! location.reload!
.catch ~> .catch =>
alert 'something happened' alert 'something happened'
@signing = false this.signing = false
@update! this.update();
false false
</script> </script>

View file

@ -174,117 +174,117 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@mixin \get-password-strength this.mixin('get-password-strength');
@username-state = null this.username-state = null
@password-strength = '' this.password-strength = ''
@password-retype-state = null this.password-retype-state = null
@recaptchaed = false this.recaptchaed = false
window.on-recaptchaed = ~> window.on-recaptchaed = =>
@recaptchaed = true this.recaptchaed = true
@update! this.update();
window.on-recaptcha-expired = ~> window.on-recaptcha-expired = =>
@recaptchaed = false this.recaptchaed = false
@update! this.update();
@on \mount ~> this.on('mount', () => {
head = (document.get-elements-by-tag-name \head).0 head = (document.get-elements-by-tag-name 'head).0'
script = document.create-element \script script = document.createElement 'script'
..set-attribute \src \https://www.google.com/recaptcha/api.js ..set-attribute 'src' \https://www.google.com/recaptcha/api.js
head.append-child script head.appendChild script
@on-change-username = ~> on-change-username() {
username = @refs.username.value username = this.refs.username.value
if username == '' if username == ''
@username-state = null this.username-state = null
@update! this.update();
return return
err = switch err = switch
| not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format | not username.match /^[a-zA-Z0-9\-]+$/ => 'invalid-format'
| username.length < 3chars => \min-range | username.length < 3chars => 'min-range'
| username.length > 20chars => \max-range | username.length > 20chars => 'max-range'
| _ => null | _ => null
if err? if err?
@username-state = err this.username-state = err
@update! this.update();
else else
@username-state = \wait this.username-state = 'wait'
@update! this.update();
@api \username/available do this.api 'username/available' do
username: username username: username
.then (result) ~> .then (result) =>
if result.available if result.available
@username-state = \ok this.username-state = 'ok'
else else
@username-state = \unavailable this.username-state = 'unavailable'
@update! this.update();
.catch (err) ~> .catch (err) =>
@username-state = \error this.username-state = 'error'
@update! this.update();
@on-change-password = ~> on-change-password() {
password = @refs.password.value password = this.refs.password.value
if password == '' if password == ''
@password-strength = '' this.password-strength = ''
return return
strength = @get-password-strength password strength = @get-password-strength password
if strength > 0.3 if strength > 0.3
@password-strength = \medium this.password-strength = 'medium'
if strength > 0.7 if strength > 0.7
@password-strength = \high this.password-strength = 'high'
else else
@password-strength = \low this.password-strength = 'low'
@update! this.update();
@refs.password-metar.style.width = (strength * 100) + \% this.refs.password-metar.style.width = (strength * 100) + '%'
@on-change-password-retype = ~> on-change-password-retype() {
password = @refs.password.value password = this.refs.password.value
retyped-password = @refs.password-retype.value retyped-password = this.refs.password-retype.value
if retyped-password == '' if retyped-password == ''
@password-retype-state = null this.password-retype-state = null
return return
if password == retyped-password if password == retyped-password
@password-retype-state = \match this.password-retype-state = 'match'
else else
@password-retype-state = \not-match this.password-retype-state = 'not-match'
@onsubmit = (e) ~> onsubmit(e) {
e.prevent-default! e.prevent-default!
username = @refs.username.value username = this.refs.username.value
password = @refs.password.value password = this.refs.password.value
locker = document.body.append-child document.create-element \mk-locker locker = document.body.appendChild document.createElement 'mk-locker'
@api \signup do this.api 'signup' do
username: username username: username
password: password password: password
'g-recaptcha-response': grecaptcha.get-response! 'g-recaptcha-response': grecaptcha.get-response!
.then ~> .then =>
@api \signin do this.api 'signin' do
username: username username: username
password: password password: password
.then ~> .then =>
location.href = CONFIG.url location.href = CONFIG.url
.catch ~> .catch =>
alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。' alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
grecaptcha.reset! grecaptcha.reset!
@recaptchaed = false this.recaptchaed = false
locker.parent-node.remove-child locker locker.parent-node.remove-child locker

View file

@ -21,7 +21,7 @@
</style> </style>
<script> <script>
now = new Date! now = new Date!
@d = now.get-date! this.d = now.get-date!
@m = now.get-month! + 1 this.m = now.get-month! + 1
</script> </script>
</mk-special-message> </mk-special-message>

View file

@ -1,31 +1,31 @@
<mk-time> <mk-time>
<time datetime={ opts.time }><span if={ mode == 'relative' }>{ relative }</span><span if={ mode == 'absolute' }>{ absolute }</span><span if={ mode == 'detail' }>{ absolute } ({ relative })</span></time> <time datetime={ opts.time }><span if={ mode == 'relative' }>{ relative }</span><span if={ mode == 'absolute' }>{ absolute }</span><span if={ mode == 'detail' }>{ absolute } ({ relative })</span></time>
<script> <script>
@time = new Date @opts.time this.time = new Date this.opts.time
@mode = @opts.mode || \relative this.mode = this.opts.mode || 'relative'
@tickid = null this.tickid = null
@absolute = this.absolute =
@time.get-full-year! + \年 + @time.get-full-year! + '年' +
@time.get-month! + 1 + \月 + @time.get-month! + 1 + '月' +
@time.get-date! + \日 + @time.get-date! + '日' +
' ' + ' ' +
@time.get-hours! + \時 + @time.get-hours! + '時' +
@time.get-minutes! + \分 @time.get-minutes! + '分'
@on \mount ~> this.on('mount', () => {
if @mode == \relative or @mode == \detail if @mode == 'relative' or @mode == 'detail'
@tick! @tick!
@tickid = set-interval @tick, 1000ms this.tickid = set-interval @tick, 1000ms
@on \unmount ~> this.on('unmount', () => {
if @mode == \relative or @mode == \detail if @mode == 'relative' or @mode == 'detail'
clear-interval @tickid clear-interval @tickid
@tick = ~> tick() {
now = new Date! now = new Date!
ago = (now - @time) / 1000ms ago = (now - @time) / 1000ms
@relative = switch this.relative = switch
| ago >= 31536000s => ~~(ago / 31536000s) + '年前' | ago >= 31536000s => ~~(ago / 31536000s) + '年前'
| ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月前' | ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月前'
| ago >= 604800s => ~~(ago / 604800s) + '週間前' | ago >= 604800s => ~~(ago / 604800s) + '週間前'
@ -36,6 +36,6 @@
| ago >= 0s => 'たった今' | ago >= 0s => 'たった今'
| ago < 0s => '未来' | ago < 0s => '未来'
| _ => 'なぞのじかん' | _ => 'なぞのじかん'
@update! this.update();
</script> </script>
</mk-time> </mk-time>

View file

@ -24,6 +24,6 @@
color #8899a6 color #8899a6
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
</script> </script>
</mk-twitter-setting> </mk-twitter-setting>

View file

@ -140,55 +140,55 @@
</style> </style>
<script> <script>
@mixin \i this.mixin('i');
@uploads = [] this.uploads = []
@upload = (file, folder) ~> upload(file, folder) {
id = Math.random! id = Math.random!
ctx = ctx =
id: id id: id
name: file.name || \untitled name: file.name || 'untitled'
progress: undefined progress: undefined
@uploads.push ctx @uploads.push ctx
@trigger \change-uploads @uploads this.trigger 'change-uploads' @uploads
@update! this.update();
reader = new FileReader! reader = new FileReader!
reader.onload = (e) ~> reader.onload = (e) =>
ctx.img = e.target.result ctx.img = e.target.result
@update! this.update();
reader.read-as-data-URL file reader.read-as-data-URL file
data = new FormData! data = new FormData!
data.append \i @I.token data.append 'i' @I.token
data.append \file file data.append 'file' file
if folder? if folder?
data.append \folder_id folder data.append 'folder_id' folder
xhr = new XMLHttpRequest! xhr = new XMLHttpRequest!
xhr.open \POST CONFIG.apiUrl + '/drive/files/create' true xhr.open 'POST' CONFIG.apiUrl + '/drive/files/create' true
xhr.onload = (e) ~> xhr.onload = (e) =>
drive-file = JSON.parse e.target.response drive-file = JSON.parse e.target.response
@trigger \uploaded drive-file this.trigger 'uploaded' drive-file
@uploads = @uploads.filter (x) -> x.id != id this.uploads = @uploads.filter (x) -> x.id != id
@trigger \change-uploads @uploads this.trigger 'change-uploads' @uploads
@update! this.update();
xhr.upload.onprogress = (e) ~> xhr.upload.onprogress = (e) =>
if e.length-computable if e.length-computable
if ctx.progress == undefined if ctx.progress == undefined
ctx.progress = {} ctx.progress = {}
ctx.progress.max = e.total ctx.progress.max = e.total
ctx.progress.value = e.loaded ctx.progress.value = e.loaded
@update! this.update();
xhr.send data xhr.send data
</script> </script>

View file

@ -91,22 +91,22 @@
</style> </style>
<script> <script>
@mixin \api this.mixin('api');
@url = @opts.url this.url = this.opts.url
@loading = true this.loading = true
@on \mount ~> this.on('mount', () => {
fetch CONFIG.url + '/api:url?url=' + @url fetch CONFIG.url + '/api:url?url=' + @url
.then (res) ~> .then (res) =>
info <~ res.json!.then info <~ res.json!.then
@title = info.title this.title = info.title
@description = info.description this.description = info.description
@thumbnail = info.thumbnail this.thumbnail = info.thumbnail
@icon = info.icon this.icon = info.icon
@sitename = info.sitename this.sitename = info.sitename
@loading = false this.loading = false
@update! this.update();
</script> </script>
</mk-url-preview> </mk-url-preview>

View file

@ -30,19 +30,19 @@
</style> </style>
<script> <script>
@url = @opts.href this.url = this.opts.href
@on \before-mount ~> this.on('before-mount', () => {
parser = document.create-element \a parser = document.createElement 'a'
parser.href = @url parser.href = @url
@schema = parser.protocol this.schema = parser.protocol
@hostname = parser.hostname this.hostname = parser.hostname
@port = parser.port this.port = parser.port
@pathname = parser.pathname this.pathname = parser.pathname
@query = parser.search this.query = parser.search
@hash = parser.hash this.hash = parser.hash
@update! this.update();
</script> </script>
</mk-url> </mk-url>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,19 +28,19 @@
</style> </style>
<script> <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 ~> this.on('mount', () => {
@refs.window.on \closed ~> this.refs.window.on('closed', () => {
@unmount! this.unmount();
@api \drive .then (info) ~> this.api 'drive' .then (info) =>
@update do @update do
usage: info.usage / info.capacity * 100 usage: info.usage / info.capacity * 100
@close = ~> close() {
@refs.window.close! this.refs.window.close!
</script> </script>
</mk-drive-browser-window> </mk-drive-browser-window>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -83,11 +83,11 @@
</style> </style>
<script> <script>
@mixin \date-stringify this.mixin('date-stringify');
@mixin \user-preview 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> </script>
</mk-post-preview> </mk-post-preview>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,12 +9,12 @@
</div> </div>
</article> </article>
<script> <script>
@mixin \date-stringify this.mixin('date-stringify');
@mixin \user-preview 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> </script>
<style> <style>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

Some files were not shown because too many files have changed in this diff Show more