Initial commit 🍀

This commit is contained in:
syuilo
2016-12-29 07:49:51 +09:00
commit b3f42e62af
405 changed files with 31017 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
riot = require \riot
spinner = null
pending = 0
net = riot.observable!
riot.mixin \net do
net: net
log = (riot.mixin \log).log
module.exports = (i, endpoint, data) ->
pending++
if i? and typeof i == \object then i = i.token
body = []
# append user token when signed in
if i? then body.push "i=#i"
for k, v of data
if v != undefined
v = encodeURIComponent v
body.push "#k=#v"
opts =
method: \POST
headers:
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
body: body.join \&
if endpoint == \signin
opts.credentials = \include
ep = if (endpoint.index-of '://') > -1
then endpoint
else "#{CONFIG.api.url}/#{endpoint}"
if pending == 1
spinner := document.create-element \div
..set-attribute \id \wait
document.body.append-child spinner
new Promise (resolve, reject) ->
timer = set-timeout ->
net.trigger \detected-slow-network
, 5000ms
log "API: #{ep}"
fetch ep, opts
.then (res) ->
pending--
clear-timeout timer
if pending == 0
spinner.parent-node.remove-child spinner
if res.status == 200
res.json!.then resolve
else if res.status == 204
resolve!
else
res.json!.then (err) ->
reject err.error
.catch reject

View File

@@ -0,0 +1,6 @@
module.exports = function(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0Byte';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + sizes[i];
}

View File

@@ -0,0 +1,9 @@
module.exports = ->
fetch \/api:meta
.then (res) ~>
meta <~ res.json!.then
if meta.commit.hash != VERSION
if window.confirm '新しいMisskeyのバージョンがあります。更新しますか\r\n(このメッセージが繰り返し表示される場合は、サーバーにデータがまだ届いていない可能性があるので、少し時間を置いてから再度お試しください)'
location.reload true
.catch ~>
# ignore

View File

@@ -0,0 +1,14 @@
module.exports = (date) ->
if typeof date == \string then date = new Date date
text =
date.get-full-year! + \年 +
date.get-month! + \月 +
date.get-date! + \日 +
' ' +
date.get-hours! + \時 +
date.get-minutes! + \分 +
' ' +
"(#{[\日 \月 \火 \水 \木 \金 \土][date.get-day!]})"
return text

View File

@@ -0,0 +1,27 @@
uuid = require './uuid.js'
home =
left: [ \profile \calendar \rss-reader \photo-stream ]
right: [ \broadcast \notifications \user-recommendation \donation \nav \tips ]
module.exports = ~>
home-data = []
home.left.for-each (widget) ~>
home-data.push do
name: widget
id: uuid!
place: \left
home.right.for-each (widget) ~>
home-data.push do
name: widget
id: uuid!
place: \right
data =
cache: true
debug: false
home: home-data
return data

View File

@@ -0,0 +1,26 @@
get-post-summary = (post) ~>
summary = if post.text? then post.text else ''
# メディアが添付されているとき
if post.media?
summary += " (#{post.media.length}枚の画像)"
# 返信のとき
if post.reply_to_id?
if post.reply_to?
reply-summary = get-post-summary post.reply_to
summary += " RE: #{reply-summary}"
else
summary += " RE: ..."
# Repostのとき
if post.repost_id?
if post.repost?
repost-summary = get-post-summary post.repost
summary += " RP: #{repost-summary}"
else
summary += " RP: ..."
return summary.trim!
module.exports = get-post-summary

View File

@@ -0,0 +1,16 @@
riot = require \riot
module.exports = (me) ->
riot.mixin \i do
init: ->
@I = me
@SIGNIN = me?
if @SIGNIN
@on \mount ~> me.on \updated @update
@on \unmount ~> me.off \updated @update
update-i: (data) ->
if data?
Object.assign me, data
me.trigger \updated

View File

@@ -0,0 +1 @@
module.exports = (x) -> typeof x.then == \function

View File

@@ -0,0 +1,16 @@
NProgress = require 'NProgress'
NProgress.configure do
trickle-speed: 500ms
show-spinner: false
root = document.get-elements-by-tag-name \html .0
module.exports =
start: ~>
root.class-list.add \progress
NProgress.start!
done: ~>
root.class-list.remove \progress
NProgress.done!
set: (val) ~>
NProgress.set val

View File

@@ -0,0 +1,18 @@
riot = require \riot
logs = []
ev = riot.observable!
function log(msg)
logs.push do
date: new Date!
message: msg
ev.trigger \log
riot.mixin \log do
logs: logs
log: log
log-event: ev
module.exports = log

View File

@@ -0,0 +1,34 @@
# Stream
#================================
ReconnectingWebSocket = require 'reconnecting-websocket'
riot = require 'riot'
class Connection
(me, otherparty) ~>
@event = riot.observable!
@me = me
host = CONFIG.api.url.replace \http \ws
@socket = new ReconnectingWebSocket "#{host}/messaging?otherparty=#{otherparty}"
@socket.add-event-listener \open @on-open
@socket.add-event-listener \message @on-message
on-open: ~>
@socket.send JSON.stringify do
i: @me.token
on-message: (message) ~>
try
message = JSON.parse message.data
if message.type?
@event.trigger message.type, message.body
catch
# ignore
close: ~>
@socket.remove-event-listener \open @on-open
@socket.remove-event-listener \message @on-message
@socket.close!
module.exports = Connection

View File

@@ -0,0 +1,4 @@
module.exports = ->
local-storage.remove-item \me
document.cookie = "i=; domain=.#{CONFIG.host}; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
location.href = \/

View File

@@ -0,0 +1,42 @@
# Stream
#================================
ReconnectingWebSocket = require \reconnecting-websocket
riot = require \riot
module.exports = (me) ~>
state = \initializing
state-ev = riot.observable!
event = riot.observable!
socket = new ReconnectingWebSocket CONFIG.api.url.replace \http \ws
socket.onopen = ~>
state := \connected
state-ev.trigger \connected
socket.send JSON.stringify do
i: me.token
socket.onclose = ~>
state := \reconnecting
state-ev.trigger \closed
socket.onmessage = (message) ~>
try
message = JSON.parse message.data
if message.type?
event.trigger message.type, message.body
catch
# ignore
get-state = ~> state
event.on \i_updated (data) ~>
Object.assign me, data
me.trigger \updated
{
state-ev
get-state
event
}

View File

@@ -0,0 +1,30 @@
module.exports = function(tokens, canBreak, escape) {
if (canBreak == null) {
canBreak = true;
}
if (escape == null) {
escape = true;
}
return tokens.map(function(token) {
switch (token.type) {
case 'text':
if (escape) {
return token.content
.replace(/>/g, '&gt;')
.replace(/</g, '&lt;')
.replace(/(\r\n|\n|\r)/g, canBreak ? '<br>' : ' ');
} else {
return token.content
.replace(/(\r\n|\n|\r)/g, canBreak ? '<br>' : ' ');
}
case 'bold':
return '<strong>' + token.bold + '</strong>';
case 'link':
return '<mk-url href="' + token.content + '" target="_blank"></mk-url>';
case 'mention':
return '<a href="' + CONFIG.url + '/' + token.username + '" target="_blank" data-user-preview="' + token.content + '">' + token.content + '</a>';
case 'hashtag': // TODO
return '<a>' + token.content + '</a>';
}
}).join('');
}

View File

@@ -0,0 +1,12 @@
module.exports = function () {
var uuid = '', i, random;
for (i = 0; i < 32; i++) {
random = Math.random() * 16 | 0;
if (i == 8 || i == 12 || i == 16 || i == 20) {
uuid += '-'
}
uuid += (i == 12 ? 4 : (i == 16 ? (random & 3 | 8) : random)).toString(16);
}
return uuid;
}