Initial commit 🍀
This commit is contained in:
51
src/web/app/dev/router.ls
Normal file
51
src/web/app/dev/router.ls
Normal file
@@ -0,0 +1,51 @@
|
||||
# Router
|
||||
#================================
|
||||
|
||||
route = require \page
|
||||
page = null
|
||||
|
||||
module.exports = (me) ~>
|
||||
|
||||
# Routing
|
||||
#--------------------------------
|
||||
|
||||
route \/ index
|
||||
route \/apps apps
|
||||
route \/app/new new-app
|
||||
route \/app/:app app
|
||||
route \* not-found
|
||||
|
||||
# Handlers
|
||||
#--------------------------------
|
||||
|
||||
function index
|
||||
mount document.create-element \mk-index
|
||||
|
||||
function apps
|
||||
mount document.create-element \mk-apps-page
|
||||
|
||||
function new-app
|
||||
mount document.create-element \mk-new-app-page
|
||||
|
||||
function app ctx
|
||||
document.create-element \mk-app-page
|
||||
..set-attribute \app ctx.params.app
|
||||
.. |> mount
|
||||
|
||||
function not-found
|
||||
mount document.create-element \mk-not-found
|
||||
|
||||
# Exec
|
||||
#--------------------------------
|
||||
|
||||
route!
|
||||
|
||||
# Mount
|
||||
#================================
|
||||
|
||||
riot = require \riot
|
||||
|
||||
function mount content
|
||||
if page? then page.unmount!
|
||||
body = document.get-element-by-id \app
|
||||
page := riot.mount body.append-child content .0
|
||||
15
src/web/app/dev/script.js
Normal file
15
src/web/app/dev/script.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Developer Center
|
||||
*/
|
||||
|
||||
require('./tags.ls');
|
||||
const boot = require('../boot.ls');
|
||||
const route = require('./router.ls');
|
||||
|
||||
/**
|
||||
* Boot
|
||||
*/
|
||||
boot(me => {
|
||||
// Start routing
|
||||
route(me);
|
||||
});
|
||||
10
src/web/app/dev/style.styl
Normal file
10
src/web/app/dev/style.styl
Normal file
@@ -0,0 +1,10 @@
|
||||
@import "../base"
|
||||
|
||||
html
|
||||
background-color #fff
|
||||
|
||||
#init
|
||||
background #100f0f
|
||||
|
||||
> p
|
||||
color $theme-color
|
||||
5
src/web/app/dev/tags.ls
Normal file
5
src/web/app/dev/tags.ls
Normal file
@@ -0,0 +1,5 @@
|
||||
require './tags/pages/index.tag'
|
||||
require './tags/pages/apps.tag'
|
||||
require './tags/pages/app.tag'
|
||||
require './tags/pages/new-app.tag'
|
||||
require './tags/new-app-form.tag'
|
||||
260
src/web/app/dev/tags/new-app-form.tag
Normal file
260
src/web/app/dev/tags/new-app-form.tag
Normal file
@@ -0,0 +1,260 @@
|
||||
mk-new-app-form
|
||||
form(onsubmit={ onsubmit }, autocomplete='off')
|
||||
section.name: label
|
||||
p.caption
|
||||
| アプリケーション名
|
||||
input@name(
|
||||
type='text'
|
||||
placeholder='ex) Misskey for iOS'
|
||||
autocomplete='off'
|
||||
required)
|
||||
|
||||
section.nid: label
|
||||
p.caption
|
||||
| Named ID
|
||||
input@nid(
|
||||
type='text'
|
||||
pattern='^[a-zA-Z0-9\-]{3,30}$'
|
||||
placeholder='ex) misskey-for-ios'
|
||||
autocomplete='off'
|
||||
required
|
||||
onkeyup={ on-change-nid })
|
||||
|
||||
p.info(if={ nid-state == 'wait' }, style='color:#999')
|
||||
i.fa.fa-fw.fa-spinner.fa-pulse
|
||||
| 確認しています...
|
||||
p.info(if={ nid-state == 'ok' }, style='color:#3CB7B5')
|
||||
i.fa.fa-fw.fa-check
|
||||
| 利用できます
|
||||
p.info(if={ nid-state == 'unavailable' }, style='color:#FF1161')
|
||||
i.fa.fa-fw.fa-exclamation-triangle
|
||||
| 既に利用されています
|
||||
p.info(if={ nid-state == 'error' }, style='color:#FF1161')
|
||||
i.fa.fa-fw.fa-exclamation-triangle
|
||||
| 通信エラー
|
||||
p.info(if={ nid-state == 'invalid-format' }, style='color:#FF1161')
|
||||
i.fa.fa-fw.fa-exclamation-triangle
|
||||
| a~z、A~Z、0~9、-(ハイフン)が使えます
|
||||
p.info(if={ nid-state == 'min-range' }, style='color:#FF1161')
|
||||
i.fa.fa-fw.fa-exclamation-triangle
|
||||
| 3文字以上でお願いします!
|
||||
p.info(if={ nid-state == 'max-range' }, style='color:#FF1161')
|
||||
i.fa.fa-fw.fa-exclamation-triangle
|
||||
| 30文字以内でお願いします
|
||||
|
||||
section.description: label
|
||||
p.caption
|
||||
| アプリの概要
|
||||
textarea@description(
|
||||
placeholder='ex) Misskey iOSクライアント。'
|
||||
autocomplete='off'
|
||||
required)
|
||||
|
||||
section.callback: label
|
||||
p.caption
|
||||
| コールバックURL (オプション)
|
||||
input@cb(
|
||||
type='url'
|
||||
placeholder='ex) https://your.app.example.com/callback.php'
|
||||
autocomplete='off')
|
||||
|
||||
section.permission
|
||||
p.caption
|
||||
| 権限
|
||||
div@permission
|
||||
label
|
||||
input(type='checkbox', value='account-read')
|
||||
p アカウントの情報を見る。
|
||||
label
|
||||
input(type='checkbox', value='account-write')
|
||||
p アカウントの情報を操作する。
|
||||
label
|
||||
input(type='checkbox', value='post-write')
|
||||
p 投稿する。
|
||||
label
|
||||
input(type='checkbox', value='like-write')
|
||||
p いいねしたりいいね解除する。
|
||||
label
|
||||
input(type='checkbox', value='following-write')
|
||||
p フォローしたりフォロー解除する。
|
||||
label
|
||||
input(type='checkbox', value='drive-read')
|
||||
p ドライブを見る。
|
||||
label
|
||||
input(type='checkbox', value='drive-write')
|
||||
p ドライブを操作する。
|
||||
label
|
||||
input(type='checkbox', value='notification-read')
|
||||
p 通知を見る。
|
||||
label
|
||||
input(type='checkbox', value='notification-write')
|
||||
p 通知を操作する。
|
||||
p
|
||||
i.fa.fa-exclamation-triangle
|
||||
| アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。
|
||||
|
||||
button(onclick={ onsubmit })
|
||||
| アプリ作成
|
||||
|
||||
style.
|
||||
display block
|
||||
overflow hidden
|
||||
|
||||
> form
|
||||
|
||||
section
|
||||
display block
|
||||
margin 16px 0
|
||||
|
||||
.caption
|
||||
margin 0 0 4px 0
|
||||
color #616161
|
||||
font-size 0.95em
|
||||
|
||||
> i
|
||||
margin-right 0.25em
|
||||
color #96adac
|
||||
|
||||
.info
|
||||
display block
|
||||
margin 4px 0
|
||||
font-size 0.8em
|
||||
|
||||
> i
|
||||
margin-right 0.3em
|
||||
|
||||
section.permission
|
||||
div
|
||||
padding 8px 0
|
||||
max-height 160px
|
||||
overflow auto
|
||||
background #fff
|
||||
border solid 1px #cecece
|
||||
border-radius 4px
|
||||
|
||||
label
|
||||
display block
|
||||
padding 0 12px
|
||||
line-height 32px
|
||||
cursor pointer
|
||||
|
||||
&:hover
|
||||
> p
|
||||
color #999
|
||||
|
||||
[type='checkbox']:checked + p
|
||||
color #000
|
||||
|
||||
[type='checkbox']
|
||||
margin-right 4px
|
||||
|
||||
[type='checkbox']:checked + p
|
||||
color #111
|
||||
|
||||
> p
|
||||
display inline
|
||||
color #aaa
|
||||
user-select none
|
||||
|
||||
> p:last-child
|
||||
margin 6px
|
||||
font-size 0.8em
|
||||
color #999
|
||||
|
||||
> i
|
||||
margin-right 4px
|
||||
|
||||
[type=text]
|
||||
[type=url]
|
||||
textarea
|
||||
user-select text
|
||||
display inline-block
|
||||
cursor auto
|
||||
padding 8px 12px
|
||||
margin 0
|
||||
width 100%
|
||||
font-size 1em
|
||||
color #333
|
||||
background #fff
|
||||
outline none
|
||||
border solid 1px #cecece
|
||||
border-radius 4px
|
||||
|
||||
&:hover
|
||||
border-color #bbb
|
||||
|
||||
&:focus
|
||||
border-color $theme-color
|
||||
|
||||
&:disabled
|
||||
opacity 0.5
|
||||
|
||||
> button
|
||||
margin 20px 0 32px 0
|
||||
width 100%
|
||||
font-size 1em
|
||||
color #111
|
||||
border-radius 3px
|
||||
|
||||
script.
|
||||
@mixin \api
|
||||
|
||||
@nid-state = null
|
||||
|
||||
@on-change-nid = ~>
|
||||
nid = @refs.nid.value
|
||||
|
||||
if nid == ''
|
||||
@nid-state = null
|
||||
@update!
|
||||
return
|
||||
|
||||
err = switch
|
||||
| not nid.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
|
||||
| nid.length < 3chars => \min-range
|
||||
| nid.length > 30chars => \max-range
|
||||
| _ => null
|
||||
|
||||
if err?
|
||||
@nid-state = err
|
||||
@update!
|
||||
else
|
||||
@nid-state = \wait
|
||||
@update!
|
||||
|
||||
@api \app/name_id/available do
|
||||
name_id: nid
|
||||
.then (result) ~>
|
||||
if result.available
|
||||
@nid-state = \ok
|
||||
else
|
||||
@nid-state = \unavailable
|
||||
@update!
|
||||
.catch (err) ~>
|
||||
@nid-state = \error
|
||||
@update!
|
||||
|
||||
@onsubmit = ~>
|
||||
name = @refs.name.value
|
||||
nid = @refs.nid.value
|
||||
description = @refs.description.value
|
||||
cb = @refs.cb.value
|
||||
permission = []
|
||||
|
||||
@refs.permission.query-selector-all \input .for-each (el) ~>
|
||||
if el.checked then permission.push el.value
|
||||
|
||||
locker = document.body.append-child document.create-element \mk-locker
|
||||
|
||||
@api \app/create do
|
||||
name: name
|
||||
name_id: nid
|
||||
description: description
|
||||
callback_url: cb
|
||||
permission: permission.join \,
|
||||
.then ~>
|
||||
location.href = '/apps'
|
||||
.catch ~>
|
||||
alert 'アプリの作成に失敗しました。再度お試しください。'
|
||||
|
||||
locker.parent-node.remove-child locker
|
||||
24
src/web/app/dev/tags/pages/app.tag
Normal file
24
src/web/app/dev/tags/pages/app.tag
Normal file
@@ -0,0 +1,24 @@
|
||||
mk-app-page
|
||||
p(if={ fetching }) 読み込み中
|
||||
main(if={ !fetching })
|
||||
header
|
||||
h1 { app.name }
|
||||
div.body
|
||||
p App Secret
|
||||
input(value={ app.secret }, readonly)
|
||||
|
||||
style.
|
||||
display block
|
||||
|
||||
script.
|
||||
@mixin \api
|
||||
|
||||
@fetching = true
|
||||
|
||||
@on \mount ~>
|
||||
@api \app/show do
|
||||
app_id: @opts.app
|
||||
.then (app) ~>
|
||||
@app = app
|
||||
@fetching = false
|
||||
@update!
|
||||
26
src/web/app/dev/tags/pages/apps.tag
Normal file
26
src/web/app/dev/tags/pages/apps.tag
Normal file
@@ -0,0 +1,26 @@
|
||||
mk-apps-page
|
||||
h1 アプリを管理
|
||||
a(href='/app/new') アプリ作成
|
||||
div.apps
|
||||
p(if={ fetching }) 読み込み中
|
||||
virtual(if={ !fetching })
|
||||
p(if={ apps.length == 0 }) アプリなし
|
||||
ul(if={ apps.length > 0 })
|
||||
li(each={ app in apps })
|
||||
a(href={ '/app/' + app.id })
|
||||
p.name { app.name }
|
||||
|
||||
style.
|
||||
display block
|
||||
|
||||
script.
|
||||
@mixin \api
|
||||
|
||||
@fetching = true
|
||||
|
||||
@on \mount ~>
|
||||
@api \my/apps
|
||||
.then (apps) ~>
|
||||
@fetching = false
|
||||
@apps = apps
|
||||
@update!
|
||||
5
src/web/app/dev/tags/pages/index.tag
Normal file
5
src/web/app/dev/tags/pages/index.tag
Normal file
@@ -0,0 +1,5 @@
|
||||
mk-index
|
||||
a(href='/apps') アプリ
|
||||
|
||||
style.
|
||||
display block
|
||||
33
src/web/app/dev/tags/pages/new-app.tag
Normal file
33
src/web/app/dev/tags/pages/new-app.tag
Normal file
@@ -0,0 +1,33 @@
|
||||
mk-new-app-page
|
||||
main
|
||||
header
|
||||
h1 新しいアプリを作成
|
||||
p MisskeyのAPIを利用したアプリケーションを作成できます。
|
||||
mk-new-app-form
|
||||
|
||||
style.
|
||||
display block
|
||||
padding 64px 0
|
||||
|
||||
> main
|
||||
width 100%
|
||||
max-width 700px
|
||||
margin 0 auto
|
||||
|
||||
> header
|
||||
margin 0 0 16px 0
|
||||
padding 0 0 16px 0
|
||||
border-bottom solid 1px #282827
|
||||
|
||||
> h1
|
||||
margin 0 0 12px 0
|
||||
padding 0
|
||||
line-height 32px
|
||||
font-size 32px
|
||||
font-weight normal
|
||||
color #000
|
||||
|
||||
> p
|
||||
margin 0
|
||||
line-height 16px
|
||||
color #9a9894
|
||||
5
src/web/app/dev/view.pug
Normal file
5
src/web/app/dev/view.pug
Normal file
@@ -0,0 +1,5 @@
|
||||
extends ../base
|
||||
|
||||
block head
|
||||
link(rel='stylesheet', href='/_/resources/dev/style.css')
|
||||
script(src='/_/resources/dev/script.js', async, defer)
|
||||
Reference in New Issue
Block a user